PSPx форум

PSPx форум (https://www.pspx.ru/forum/index.php)
-   Русификация игр и софта для PSP (https://www.pspx.ru/forum/forumdisplay.php?f=190)
-   -   Изучение и моддинг Prince of Persia: Revelations/Rival Swords (WW/T2T) (https://www.pspx.ru/forum/showthread.php?t=105741)

JakeMiles 21.04.2020 19:11

BlackDaemon, спасибо за быстрый ответ. Чтобы быть понятнее я приложу конкретный пример, не для кого не секрет что во времена эры PS2, ПК порты не славились качеством, но с прицем я был почему то уверен что с ним всё в порядке (явно от того что не имел консоль), как оказалось я ошибался и тех. исполнение ПК версии Пески Времени полны огрехов, недоделок и халтуры, я могу простить то что, на пк хуже эффекты песка, он не такой густой и не рассеивается по помещению, лучшие эффекты света и т.п. Но то что я увидел поиграв чуть дальше, вызвало у меня минишок, за что они так с Фарой, нет я знал что скининг и риг у юбисофт "легендарные", но тут я просто шокирован, кривые и небрежные сгибы лица, на стыках частей модели, лицо, шея, глаза, порой даже не надо подбирать ракурс камеры, видны шели, часть волос вообше стабильно показывает бекграунд мыслей фары, сначало я подумал возможно игра старая, такая оптимизация (Z-cull и всё такое), но после того как я получил модель (меш) с помощью PersianRug я понял, и опечалился, да это халтура от юбисофт, а не оптимизация такая, модель имеет те же самые проблемы, что и в игре, кривые то ли нормали, то ли вертексы. Сообственно приложу примеры этого чуда из магаражди:

https://imgur.com/a/JlSNtzj

Сверху пример из ПК версии, затем из PS2 (скриншоты сделаны в эмуляторе так что некое раздвоение обьекта, это баг).

Я понимаю что заменить только меш (текстурные развертки по моим наблюдениям дампов эмуля и риперов текстур совпадают) из PS2 в ПК версию, почти невозможно, либо крайне сложно, поэтому хотелось бы просто получить меш нормальной Фары, а не грустную из ПК версии.

Про io_scene_pop, заметил такой баг, что в некоторых случиях плагин (python скрипт) не читает (либо пропускает) 3D Mesh Data, опять же проблемы есть у Farah_wow_ff030677.bin, по каким то причинам, он не хочет или умышленно пропускает 3D Mesh Data тела Фары, Farah.gao и M_Farah_Body.gao имеют вид Bounding box, другие же составные часть модели персонажа есть на сцене. Хотя в PersianRug 1A001ED7 (1069593) 3D Mesh Data - экспортируется без проблем. В других же случаях вместо Меша тела на сцену импортируется так называемый shadow mesh (низкополигональная версия той же модели для построения теней), но это как говорится несовершенство плагина для блендер. Возможно посмотрю что там с Py файлами скрипта, возможно пойму как заставить плагин не пропускать и читать все 3D Mesh Data, но это если я смогу разобратся.

На счёт Swizzle текстур, я поискал и как я понял это фича из опен гл. есть какие то примеры и документация, но не уверен в ёё полезности, хотя я нуб в этом плане. На Xentax встречал темы и примеры, по этой теме, правда я незнаю возможно ли что алгоритмы свизл текстур быть разными у разных движков, и конкретные примеры с просторов не помогут.

В любом случае спасибо за понимание, хотелось бы помочь в допиливании твоих утилит.

BlackDaemon 22.04.2020 05:21

JakeMiles, обычное дело для портов :) По unSwizzle я нашёл рабочий код на просторах сети - отсюда, собственно взял c# декодер и недостающие массивы здесь. Немного переделал для удобства. По скрипту на питоне, к сожалению, пока ничем не могу помочь - не знаком с питоном, и на текущий момент понимаю только некоторые его части. Текстуры стандартно 8bit paletted, применяешь unSwizzle перед тем как его декодировать по палитре.

PS2Decoder
Код:

using System;

namespace PS2DecoderTest
{
    public class PS2Decoder
    {
        public static int[] block4 = new int[32]
        {
            0,  2,  8, 10,
            1,  3,  9, 11,
            4,  6, 12, 14,
            5,  7, 13, 15,
          16, 18, 24, 26,
          17, 19, 25, 27,
          20, 22, 28, 30,
          21, 23, 29, 31
        };

        public static int[,] columnWord4 = new int[,]
        {
            {
                0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,
                2,  3,  6,  7, 10, 11, 14, 15,  2,  3,  6,  7, 10, 11, 14, 15,  2,  3,  6,  7, 10, 11, 14, 15,  2,  3,  6,  7, 10, 11, 14, 15,

                8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,
              10, 11, 14, 15,  2,  3,  6,  7,  10, 11, 14, 15,  2,  3,  6,  7,  10, 11, 14, 15,  2,  3,  6,  7,  10, 11, 14, 15,  2,  3,  6,  7
            },
            {
                8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,
              10, 11, 14, 15,  2,  3,  6,  7,  10, 11, 14, 15,  2,  3,  6,  7,  10, 11, 14, 15,  2,  3,  6,  7,  10, 11, 14, 15,  2,  3,  6,  7,

                0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,
                2,  3,  6,  7, 10, 11, 14, 15,  2,  3,  6,  7, 10, 11, 14, 15,  2,  3,  6,  7, 10, 11, 14, 15,  2,  3,  6,  7, 10, 11, 14, 15
            }
        };

        public static int[] columnByte4 = new int[128]
        {
            0, 0, 0, 0, 0, 0, 0, 0,  2, 2, 2, 2, 2, 2, 2, 2,  4, 4, 4, 4, 4, 4, 4, 4,  6, 6, 6, 6, 6, 6, 6, 6,
            0, 0, 0, 0, 0, 0, 0, 0,  2, 2, 2, 2, 2, 2, 2, 2,  4, 4, 4, 4, 4, 4, 4, 4,  6, 6, 6, 6, 6, 6, 6, 6,

            1, 1, 1, 1, 1, 1, 1, 1,  3, 3, 3, 3, 3, 3, 3, 3,  5, 5, 5, 5, 5, 5, 5, 5,  7, 7, 7, 7, 7, 7, 7, 7,
            1, 1, 1, 1, 1, 1, 1, 1,  3, 3, 3, 3, 3, 3, 3, 3,  5, 5, 5, 5, 5, 5, 5, 5,  7, 7, 7, 7, 7, 7, 7, 7
        };

        public static int[] block8 = new int[32]
        {
            0,  1,  4,  5, 16, 17, 20, 21,
            2,  3,  6,  7, 18, 19, 22, 23,
            8,  9, 12, 13, 24, 25, 28, 29,
          10, 11, 14, 15, 26, 27, 30, 31
        };

        public static int[,] columnWord8 = new int[,]
        {
            {
                0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,
                2,  3,  6,  7, 10, 11, 14, 15,  2,  3,  6,  7, 10, 11, 14, 15,

                8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,
              10, 11, 14, 15,  2,  3,  6,  7,  10, 11, 14, 15,  2,  3,  6,  7
            },
            {
                8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,
              10, 11, 14, 15,  2,  3,  6,  7,  10, 11, 14, 15,  2,  3,  6,  7,

                0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,
                2,  3,  6,  7, 10, 11, 14, 15,  2,  3,  6,  7, 10, 11, 14, 15
            }
        };

        public static int[] columnByte8 = new int[64]
        {
            0, 0, 0, 0, 0, 0, 0, 0,  2, 2, 2, 2, 2, 2, 2, 2,
            0, 0, 0, 0, 0, 0, 0, 0,  2, 2, 2, 2, 2, 2, 2, 2,

            1, 1, 1, 1, 1, 1, 1, 1,  3, 3, 3, 3, 3, 3, 3, 3,
            1, 1, 1, 1, 1, 1, 1, 1,  3, 3, 3, 3, 3, 3, 3, 3
        };

        public static int[] block32 = new int[32]
        {
            0,  1,  4,  5, 16, 17, 20, 21,
            2,  3,  6,  7, 18, 19, 22, 23,
            8,  9, 12, 13, 24, 25, 28, 29,
          10, 11, 14, 15, 26, 27, 30, 31
        };

        public static int[] columnWord32 = new int[16]
        {
            0,  1,  4,  5,  8,  9, 12, 13,
            2,  3,  6,  7, 10, 11, 14, 15
        };

        public static int[] block16 = new int[32]
        {
            0,  2,  8, 10,
            1,  3,  9, 11,
            4,  6, 12, 14,
            5,  7, 13, 15,
          16, 18, 24, 26,
          17, 19, 25, 27,
          20, 22, 28, 30,
          21, 23, 29, 31
        };

        public static int[] columnWord16 = new int[32]
        {
            0,  1,  4,  5,  8,  9, 12, 13,  0,  1,  4,  5,  8,  9, 12, 13,
            2,  3,  6,  7, 10, 11, 14, 15,  2,  3,  6,  7, 10, 11, 14, 15
        };

        public static int[] columnHalf16 = new int[32]
        {
            0, 0, 0, 0, 0, 0, 0, 0,  1, 1, 1, 1, 1, 1, 1, 1,
            0, 0, 0, 0, 0, 0, 0, 0,  1, 1, 1, 1, 1, 1, 1, 1
        };

        public static byte[] gsmem = new byte[1024 * 1024];

        public static void readTexPSMT4(int dbp, int dbw, int dsax, int dsay, int rrw, int rrh, ref byte[] data)
        {
            dbw = dbw >> 1;
            int index = 0;
            int num2 = dbp * 0x40;
            bool flag = false;
            for (int i = dsay; i < (dsay + rrh); i++)
            {
                for (int j = dsax; j < (dsax + rrw); j++)
                {
                    int num5 = j / 0x80;
                    int num6 = i / 0x80;
                    int num7 = num5 + (num6 * dbw);
                    int num8 = j - (num5 * 0x80);
                    int num9 = i - (num6 * 0x80);
                    int num10 = num8 / 0x20;
                    int num11 = num9 / 0x10;
                    int num12 = block4[num10 + (num11 * 4)];
                    int num13 = num8 - (num10 * 0x20);
                    int num14 = num9 - (num11 * 0x10);
                    int num15 = num14 / 4;
                    int num16 = num13;
                    int num17 = num14 - (num15 * 4);
                    int num18 = columnWord4[num15 & 1, num16 + (num17 * 0x20)];
                    int num19 = columnByte4[num16 + (num17 * 0x20)];
                    int num20 = ((((num2 + (num7 * 0x800)) + (num12 * 0x40)) + (num15 * 0x10)) + num18) * 4;
                    byte num21 = data[index];
                    byte num22 = gsmem[num20 + (num19 >> 1)];
                    if ((num19 & 1) != 0)
                    {
                        if (flag)
                        {
                            data[index] = (byte)((num21 & 15) | (num22 & 240));
                        }
                        else
                        {
                            data[index] = (byte)((num21 & 240) | ((num22 >> 4) & 15));
                        }
                    }
                    else if (flag)
                    {
                        data[index] = (byte)((num21 & 15) | ((num22 << 4) & 240));
                    }
                    else
                    {
                        data[index] = (byte)((num21 & 240) | (num22 & 15));
                    }
                    if (flag)
                    {
                        index++;
                    }
                    flag = !flag;
                }
            }
        }

        public static void readTexPSMT8(int dbp, int dbw, int dsax, int dsay, int rrw, int rrh, ref byte[] data)
        {
            dbw = dbw >> 1;
            int index = 0;
            int num2 = dbp * 0x40;
            for (int i = dsay; i < (dsay + rrh); i++)
            {
                for (int j = dsax; j < (dsax + rrw); j++)
                {
                    int num5 = j / 0x80;
                    int num6 = i / 0x40;
                    int num7 = num5 + (num6 * dbw);
                    int num8 = j - (num5 * 0x80);
                    int num9 = i - (num6 * 0x40);
                    int num10 = num8 / 0x10;
                    int num11 = num9 / 0x10;
                    int num12 = block8[num10 + (num11 * 8)];
                    int num13 = num8 - (num10 * 0x10);
                    int num14 = num9 - (num11 * 0x10);
                    int num15 = num14 / 4;
                    int num16 = num13;
                    int num17 = num14 - (num15 * 4);
                    int num18 = columnWord8[num15 & 1, num16 + (num17 * 0x10)];
                    int num19 = columnByte8[num16 + (num17 * 0x10)];
                    int num20 = ((((num2 + (num7 * 0x800)) + (num12 * 0x40)) + (num15 * 0x10)) + num18) * 4;
                    data[index] = gsmem[num20 + num19];
                    index++;
                }
            }
        }

        public static void writeTexPSMCT32(int dbp, int dbw, int dsax, int dsay, int rrw, int rrh, byte[] data)
        {
            int index = 0;
            int num2 = dbp * 0x40;
            for (int i = dsay; i < (dsay + rrh); i++)
            {
                for (int j = dsax; j < (dsax + rrw); j++)
                {
                    int num5 = j / 0x40;
                    int num6 = i / 0x20;
                    int num7 = num5 + (num6 * dbw);
                    int num8 = j - (num5 * 0x40);
                    int num9 = i - (num6 * 0x20);
                    int num10 = num8 / 8;
                    int num11 = num9 / 8;
                    int num12 = block32[num10 + (num11 * 8)];
                    int num13 = num8 - (num10 * 8);
                    int num14 = num9 - (num11 * 8);
                    int num15 = num14 / 2;
                    int num16 = num13;
                    int num17 = num14 - (num15 * 2);
                    int num18 = columnWord32[num16 + (num17 * 8)];
                    int num19 = ((((num2 + (num7 * 0x800)) + (num12 * 0x40)) + (num15 * 0x10)) + num18) * 4;
                    gsmem[num19] = data[index];
                    gsmem[num19 + 1] = data[index + 1];
                    gsmem[num19 + 2] = data[index + 2];
                    gsmem[num19 + 3] = data[index + 3];
                    index += 4;
                }
            }
        }

        public static void writeTexPSMCT16(int dbp, int dbw, int dsax, int dsay, int rrw, int rrh, byte[] data)
        {
            int index = 0;
            int num2 = dbp * 0x40;
            for (int i = dsay; i < (dsay + rrh); i++)
            {
                for (int j = dsax; j < (dsax + rrw); j++)
                {
                    int num5 = j / 0x40;
                    int num6 = i / 0x40;
                    int num7 = num5 + (num6 * dbw);
                    int num8 = j - (num5 * 0x40);
                    int num9 = i - (num6 * 0x40);
                    int num10 = num8 / 0x10;
                    int num11 = num9 / 8;
                    int num12 = block16[num10 + (num11 * 4)];
                    int num13 = num8 - (num10 * 0x10);
                    int num14 = num9 - (num11 * 8);
                    int num15 = num14 / 2;
                    int num16 = num13;
                    int num17 = num14 - (num15 * 2);
                    int num18 = columnWord16[num16 + (num17 * 0x10)];
                    int num19 = columnHalf16[num16 + (num17 * 0x10)];
                    int num20 = ((((num2 + (num7 * 0x800)) + (num12 * 0x40)) + (num15 * 0x10)) + num18) * 4;
                    gsmem[num20 + num19] = data[index];
                    gsmem[(num20 + num19) + 1] = data[index + 1];
                    index += 2;
                }
            }
        }

        public static byte[] Unswizzle(byte[] data, int width, int height, int BitsPerPixel)
        {
            byte[] buffer = new byte[data.Length];
            gsmem = new byte[0x400000];
            //if (this.textureInfo.BitsPerPixel == 8)
            if (BitsPerPixel == 8)
            {
                int rrw = width / 2;
                int rrh = height / 2;
                writeTexPSMCT32(0, rrw / 0x40, 0, 0, rrw, rrh, data);
                readTexPSMT8(0, width / 0x40, 0, 0, width, height, ref buffer);
            }
            //else if (this.textureInfo.BitsPerPixel == 4)
            else if (BitsPerPixel == 4)
            {
                int num3 = width / 2;
                int num4 = height / 2;
                writeTexPSMCT16(0, num3 / 0x40, 0, 0, num3, num4, data);
                readTexPSMT4(0, width / 0x40, 0, 0, width, height, ref buffer);
                byte[] buffer2 = new byte[data.Length];
                int[] numArray = new int[] { 5, 4, 7, 6, 1, 0, 3, 2 };
                int[] numArray2 = new int[] { 2, 3, 0, 1 };
                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        int index = j - (8 * (j / 8));
                        int num8 = i - (4 * (i / 4));
                        byte num9 = buffer[(i * (width / 2)) + (j / 2)];
                        if ((j & 1) == 0)
                        {
                            num9 = (byte)(num9 & 240);
                            num9 = (byte)(num9 >> 4);
                        }
                        else
                        {
                            num9 = (byte)(num9 & 15);
                        }
                        int num10 = numArray[index];
                        int num11 = numArray2[num8];
                        int num12 = num10 + (8 * (j / 8));
                        int num13 = num11 + (4 * (i / 4));
                        if ((num12 & 1) == 0)
                        {
                            buffer2[(num13 * (width / 2)) + (num12 / 2)] = (byte)(buffer2[(num13 * (width / 2)) + (num12 / 2)] & 15);
                            num9 = (byte)(num9 << 4);
                            buffer2[(num13 * (width / 2)) + (num12 / 2)] = (byte)(buffer2[(num13 * (width / 2)) + (num12 / 2)] | num9);
                        }
                        else
                        {
                            buffer2[(num13 * (width / 2)) + (num12 / 2)] = (byte)(buffer2[(num13 * (width / 2)) + (num12 / 2)] & 240);
                            buffer2[(num13 * (width / 2)) + (num12 / 2)] = (byte)(buffer2[(num13 * (width / 2)) + (num12 / 2)] | num9);
                        }
                    }
                }
                buffer = buffer2;
            }
            gsmem = null;
            GC.Collect();
            return buffer;
        }
    }
}


Pavel_Pt 22.09.2023 14:37

Всем привет. Кто-нибудь знает , как заменить модель принца из Prince of Persia The Two Thrones на ту модель , которая была в Prince of Persia Warrior Within?

YuriiM 11.08.2024 22:53

Очистил лицензионный Акелловский prince.bf ПК версии от мусора акеллы.
Теперь его можно пересобирать и вносить изменения, либо просто распаковать и перенести перевод на чей либо мод:
https://drive.google.com/file/d/13eJ...ew?usp=sharing

Так же перенес перевод на североамериканскую версию prince.bf, на которую есть POP2.EXE без защиты:
https://drive.google.com/file/d/16rW...ew?usp=sharing

Кому интересно, моя portable ПК сборка на основе североамериканской версии игры:
https://archive.org/download/prince-...usa-textakella


Текущее время: 06:22. Часовой пояс GMT +3.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2025, vBulletin Solutions, Inc. Перевод: zCarot
PSPx Forum - Сообщество фанатов игровых консолей.