PDA

Просмотр полной версии : Изучение и моддинг Prince of Persia: Revelations/Rival Swords (WW/T2T)


BlackDaemon
11.08.2015, 22:46
Данная тема посвящена изучению ресурсов и небольшому моддингу для игр Prince of Persia: Revelations/Rival Swords (Warrior Within/The Two Thrones).

Прежде всего, хотелось бы поблагодарить тех, кто сделал этот моддинг возможным:

ErikPshat - за реверсинг, помощь и модифицированную версию Persian Rug с разблокированными скрытыми фичами.
riku.kh3 - за реверсинг, помощь и полезную утилиту, которая упаковывает ресурсы обратно в .bin
Turfster - автора Persian Rug.
Re-Education - за появление в нужном месте и в нужное время

Итак, начнём

Мод 1 - отключение эффекта свечения при попадании по песочным монстрам в Prince of Persia: Rival Swords/The Two Thrones

aoUwuIAAy80


Достаточно простой мод, его суть заключается в замене текстур, отвечающими за эффекты на прозрачные. Побочные эффекты - свечение кинжала при QTE и эффект свечения при превращения в тёмного принца тоже отключаются.

Текстуры, отвечающие за это находятся в Prince_Weapons_wow_ff05c7fe.bin
- Prince_Weapons_wow_ff05c7fe_130071D1
- Prince_Weapons_wow_ff05c7fe_1300278D

Достаём их оттуда через Persian Rug -> Bin анализатор -> Извлечь данные.

Структура текстур для PSP - первые 144 байта, и последние 4 байта в конце файла - служебная информация, её не трогаем. С помощью hex-редактора заменяем код текстуры 0x65 байтами для Prince_Weapons_wow_ff05c7fe_130071D1 и 0x00 байтами для Prince_Weapons_wow_ff05c7fe_1300278D.

Структура текстур для PS2 - первые 192 байта, и последние 36 байт в конце файла - служебная информация, её не трогаем. С помощью hex-редактора заменяем код текстуры 0x65 байтами для Prince_Weapons_wow_ff05c7fe_130071D1 и 0x00 байтами для Prince_Weapons_wow_ff05c7fe_1300278D.

Структура текстур для PS3 - первые 68 байт - служебная информация, её не трогаем. С помощью hex-редактора заменяем код текстуры 0x00 байтами.

Структура текстур для GC - первые 76 байт - служебная информация, её не трогаем. С помощью hex-редактора заменяем код текстуры 0x30 байтами. Отдельно ещё хочется упомянуть, что структура образа нестандартная, и придётся доставать бинарник вручную. В моём случае он занимает 188412 байт, и лежит в области 766767600-766956012 (US версия, GKME41).

Структура текстур для Xbox - первые 68 байт - служебная информация, её не трогаем. С помощью hex-редактора заменяем код текстуры 0xFFFFFF00 байтами для Prince_Weapons_wow_ff05c7fe_130071D1 и 0x00 байтами для Prince_Weapons_wow_ff05c7fe_1300278D.

Структура текстур для PC - первые 68 байт - служебная информация, её не трогаем. С помощью hex-редактора заменяем код текстуры 0xFFFFFF00 байтами для Prince_Weapons_wow_ff05c7fe_130071D1 и 0x00 байтами для Prince_Weapons_wow_ff05c7fe_1300278D.


Мод 2 - модифицирование оружия в Prince of Persia: Revelations/Warrior Within

xDARjrPNaQE


Учитывая, что ранее у меня уже были некоторые заготовки по оружию в виде редактора сэйвов для Revelations/Rival Swords (вот ссылка (https://drive.google.com/file/d/0B980do3iuJHveUFDRGM3Rm1hOXM/view?usp=sharing), если интересует) я решил копнуть это дело глубже. В данном случае - all_weapons_wow_ff0610da.bin, советую распаковать его полностью.
Прежде, чем приступить к разбору конкретных файлов, отвечающих за оружия и их свойства ознакомьтесь со следующим списком:
Axes:

01 - [83E5 0033] axe (Airyaman)
02 - [DF10 0016] axe (Allatum)
03 - [72E5 0033] axe (Natat)
04 - [91E5 0033] axe (Apaosa)
05 - [90E5 0033] axe (Vahishta)
06 - [79E5 0033] axe (Vidatu)
07 - [4338 0113] axe (Ahura)
08 - [3DE6 0033] axe (Drvaspa)
09 - [62E5 0033] axe (Apam)
10 - [78E5 0033] axe (Ereta)
11 - [305B 0113] axe (Mainyu)
12 - [93E5 0033] axe (Ahura)
13 - [7BE5 0033] axe (Bahram)
14 - [92E5 0033] axe (Spentas)

Daggers:

01 - [325B 0113] dagger (Khara)
02 - [345B 0113] dagger (Indra)
03 - [36E6 0033] dagger (Abathur)
04 - [3BE6 0033] dagger (Armaiti)
05 - [37E6 0033] dagger (Yazata)
06 - [3FE6 0033] dagger (Vahishta)

Maces:

01 - [3AE6 0033] mace (Peris)
02 - [50E6 0033] mace (Zend)
03 - [46E6 0033] mace (Vata)
04 - [4FE6 0033] mace (Sraosa)
05 - [8F5B 0113] mace (Menog)
06 - [1A38 0113] mace (Baga)
07 - [44E6 0033] mace (Yima)
08 - [39E6 0033] mace (Izha)

Swords:

01 - [DB10 0016] sword (Buyasta)
02 - [4EE6 0033] sword (Zarich)
03 - [4AE6 0033] sword (Haoma)
04 - [4BE6 0033] sword (Spenta)
05 - [3C5B 0113] sword (Yasht)
06 - [DD10 0016] sword (Vanant)
07 - [3CE6 0033] sword (Kerena)
08 - [3E5B 0113] sword (Camros)
09 - [51E6 0033] sword (Fravashis)
10 - [49E6 0033] sword (Tasan)
11 - [43E6 0033] sword (Asto)
12 - [48E6 0033] sword (Agas)
13 - [405B 0113] sword (Srosh)
14 - [4CE6 0033] sword (Rustam)
15 - [45E6 0033] sword (Mainyu)
16 - [385B 0113] sword (Mahre)
17 - [3A5B 0113] sword (Dena)
18 - [47E6 0033] sword (Asman)

Secret weapons:

01 - [3EE6 0033] secret (Teddy Bear)
02 - [35E6 0033] secret (Rayman Fist)
03 - [42E6 0033] secret (Pink Flamingo)
04 - [38E6 0033] secret (Hockey Stick)
05 - [41E6 0033] secret (Light Sword)

Undocumented:

[31E6 0033] sword (Kaileena's Sword)
[33E6 0033] sword (Shadee's Sword)
[40E6 0033] mace
[4DE6 0033] mace

Hidden and useless:

01 - [30E6 0033] sword (Eagle Sword)
02 - [4138 0113] sword (Wooden Stick)
03 - [0F35 0133] sword (Wooden Stick, breakable)
04 - [2DE6 0033] sword (Spider Sword)
05 - [2EE6 0033] sword (Serpent Sword)
06 - [1C38 0113] sword (Lion Sword, indestruct)
07 - sword (Lion Sword, breakable)
08 - [2FE6 0033] sword (Lion Sword, broken)
09 - [32E6 0033] sword (Scorpion Sword)
10 - [34E6 0033] sword (Water Sword)
В списке все коды оружия написаны как есть, когда я писал редактор сэйвов - в обратном порядке, как они отображаются в сэйвах и ресурсах игры, т.е. 41E6 0033 в памяти и названии файлов будет отображаться как 3300 E641. Головную боль ещё добавляет момент, что у разных категорий оружия файлы, отвечающие за их параметры тоже с разным размером, что усложняет разбор их структуры. Поэтому для начала я возьму наиболее похожие по параметрам оружия для изучения.

[B]Этап 1 - перенос специального эффекта с одного оружия на другое


Для этих целей нам подойдут "секретные оружия" - мишка [3EE6 0033] secret (Teddy Bear) и фламинго [42E6 0033] secret (Pink Flamingo). У мишки есть специальный эффект вампиризма, который лечит принца за удары по монстрам, вот мы его и перенесём на фламинго.

Отвечающие за это файлы объектов:
- all_weapons_wow_ff0610da_3300E63E
- all_weapons_wow_ff0610da_3300E642

Сравниваем содержание файлов (например, с пом. Total Commander)

Итак, в начале идёт блок с ID нашего оружия (выделен синим), далее идут указатели:
- 0xF4E50033 и 0xF8E50033 отвечают за 3D модель оружия (выделены серым)
- 0x17E50033 и 0x18E50033 отвечают за ссылку на текстуру оружия (выделены оранжевым)
- 0xC5E60033 и 0xC7E6033 отвечают за ссылку на файл с параметрами оружия (выделены красным), чтобы лишний раз не открывать файл-ссылку уменьшаем значение на 1, т.е. наши файлы с параметрами - all_weapons_wow_ff0610da_3300E6C4 и all_weapons_wow_ff0610da_3300E6C6.
- значение указателя, выделенного чёрным цветом я пока что не знаю.

***Можно заменить все 4 указателя с одного оружия на другое, и в этом случае оно станет аналогом "донора". Заменять указатели частично нельзя, игра не загрузится.***

Теперь, идём сравнивать файлы, отвечающие за свойства оружия:

Опять мы видим вначале блок, теперь он отвечает за ID параметров оружия (выделен синим), далее идёт ID оружия (выделен серым) и наш искомый блок, который отвечает за специальный эффект (выделен красным). Заменяем в файле параметров фламинго 0x01 на 0x03 и получаем фламинго с эффектом вампиризма.

Этап 2 - перенос эффекта неразрушимости (для оружия со специальным эффектом)


Возьмём для этих целей топоры [7BE5 0033] axe (Bahram) и [92E5 0033] axe (Spentas). Первый имеет специальный эффект повышенного урона, но быстро ломается, а второй неразрушимый, но в добавку имеет негативный эффект высасывания здоровья при ударе по монстрам. Файлы, отвечающие за параметры этих топоров:
- all_weapons_wow_ff0610da_3300E59B
- all_weapons_wow_ff0610da_3300E5AF

И смотрим их содержимое:

Нас интересует блок 0x3C9D955B - это специальное значение, которое отвечает за то, что оружие неразрушимо (выделен красным) и блок, 0x00, который отвечает за то, сколько урона получит оружие за каждый удар по монстру (выделен синим). Заменять надо оба, в противном случае оружие будет ломаться.

Этап 3 - перенос эффекта неразрушимости и специального эффекта на обычное оружие (WIP)


Усложняем задачу, и пробуем замоддить обычное оружие. В данном случае я взял [46E6 0033] mace (Vata) и [33E6 0033] sword (Shadee's Sword). В первом случае обычная булава, во втором - неразрушимый меч с негативным специальным эффектом высасывания здоровья при ударе по монстрам. Файлы, отвечающие за параметры для этого оружия:
- all_weapons_wow_ff0610da_3300E657
- all_weapons_wow_ff0610da_3300E6D9

Результаты первого и грубого сравнения:

Блок со специальным значением 0xCFB67969 отвечает за то, что на оружии есть специальный эффект (выделен синим). Далее идёт блок со специальным значением 0x3C9D955B, отвечающим за то, что на оружии есть эффект неразрушимости (выделен красным). Выяснилось, что за специальный эффект отвечает блок в 4 байта - 0x04000000 (выделен серым). Ну и блок 0x00, который активирует неразрушимый эффект (выделен чёрным).

Вроде всё работает, но если приглядеться к блокам в области 184-216, то можно заметить, что блок 0x9A3B0771 присутствует в другом оружии, но он чуть смещен. Как показала практика, блок 0xCFB67969 должен находиться на строго заданной позиции, в противном случае специальный эффект не будет работать. Попробовал подогнать расположение блоков, и методом тыка определил, что следует выбросить блок 0x070A54D6:

Сравнение после подгонки:

Этап 4 - перенос модели и текстуры c одного оружия на другое

bbbp744nFY0


Возвращаемся к объектам мишки и фламинго, а конкретнее к указателям на 3d модель оружия - блокам 0xF4E50033 и 0xF8E5033, в данном случае это файлы:
- all_weapons_wow_ff0610da_3300E5F4
- all_weapons_wow_ff0610da_3300E5F8

Открываем и сравниваем:

Первый блок отвечает за [(размер файла) - 12 байт] (выделен синим), далее идёт блок с ID 3d модели оружия (выделен серым). Всё, что после уже отвечает за модель оружия, это мы и будем переносить. Учитывая, что файл с моделью мишки занимает больше фламинго, мы будем переносить модель фламинго на мишку. Разницу в 452 байта заполняем нулями в конце файла.

Проверяем результат (слева то, что получилось, справа оригинал):

Модель мы заменили, а вот текстура осталась старая. Как оказалось, на файл с текстурой ведёт указатель на файл с ссылкой в блоках 0x17E50033 и 0x18E50033 (скриншот сравнения объектов оружия в первом этапе обновлён). Файлы, отвечающие за эти ссылки:
- all_weapons_wow_ff0610da_3300E517
- all_weapons_wow_ff0610da_3300E518

Смотрим, куда же ведут ссылки:

В конце файлов находятся искомые блоки 0x6CE40033 и 0x6DE40033, нам туда. Открываем соответствующие файлы:
- all_weapons_wow_ff0610da_3300E46C
- all_weapons_wow_ff0610da_3300E46D

Смотрим, что у нас внутри:

Вот и наконец-то добрались до текстуры. В первом блоке дважды дублируется ID текстуры (выделен серым), далее идёт блок, отвечающий за правильное наложение текстуры на модель (выделен красным). На 144-м байте начинается текстура, размером 8192 байта. Последние 4 байта в конце файла - служебная информация. Сначала надо заменить блок с параметрами, иначе текстура будет наложена неправильно, идём туда:

Первые 16 байт - размер файла, header magic и ID файла. Их не трогаем, а заменяем всё, что идёт дальше. Далее заменяем содержимое текстуры и проверяем результат (слева то, что получилось, справа оригинал):


Текстура заменилась, но цвет оружия какой-то странный. На данный момент известно, что корни проблемы растут где-то в районе ссылки на текстуру, если в ней заменить ID на текстуру оригинального оружия (0x6CE40033 на 0x6DE40033) то проблема с цветом пропадает.

Первые попытки перенести 3d модель топора из Rival Swords (The Two Thrones) в Revelations (Warrior Within):

Перенести топор оказалось непросто, т.к. у него очень большой размер модели - 3970 байт. По размеру модели подошёл
[31E6 0033] sword (Kaileena's Sword), но у него файл текстуры 4244 байта, а у топора 8340. Пришлось пойти на хитрость, и в ссылке на текстуру заменить ID на текстуру от мишки. Забавно, но после этого топор тоже стал "цветным". Текстуру одного оружия пришлось забить нулями, т.к. итоговый размер стал больше, чем исходный .bin файл :crazy:

Попробовал использовать ID текстуры фламинго и топор стал розовым :lol:

Пробуем ID текстуры от меча Kerena:

Это уже ближе к желаемому результату. Начинают закрадываться подозрения, что где-то ещё есть текстуры поверхности, которые рисуются при определённом ID текстуры.Rival Swords (The Two Thrones) тоже удалось замоддить:

Попробовал перенести оружие из GameCube версии Warrior Within на The Two Thrones, но увы, текстура из WW ни в какую не хочет нормально вставать на T2T - оружие отображается прозрачным с белой рябью. :( Видимо, формат текстур изменили.

PS2 версия The Two Thrones пропатчилась нормально:

Сделал небольшое видео и добавил его в заголовок 4-го этапа :beach:

Изучение структуры файлов монстров в Prince of Persia: Revelations/Warrior Within (WIP)


После небольшого опыта с моддингом оружия мне захотелось посмотреть, как устроена структуру файлов у монстров. Для начала наведём справки, какой .bin файл за какого монстра отвечает (для этого я посмотрел текстуры PC версии)
Assassin:
ACT_Enemy_Assassin_wow_ff0bbade
ACT_Enemy_Assassin_Ground_wow_ff0bef29

Bladedancer:
ACT_Enemy_Thief_wow_ff0b1139
ACT_Enemy_Thief_Ground_wow_ff0bfe7d

Executioner:
ACT_Enemy_Initiate_wow_ff033811

Imperial Guard (Kaileena's minion):
ACT_Enemy_Imperial_wow_ff0a69e4

Kaileena (boss):
ACT_Enemy_Mahasti_wow_ff036fc8

Kaileena (NPC):
ACT_Enemy_Mahasti_PunchBag_wow_ff0389fd

Keeper:
ACT_Enemy_Pirate_wow_ff03376f

Raider:
ACT_Enemy_Disciple_wow_ff033775

Scavenger:
ACT_Enemy_Horde_Normal_wow_ff036b79

Shadow:
ACT_Enemy_Shadow_Ground_wow_ff0bfe8a

Shahdee (boss):
ACT_Enemy_Kaleena_wow_ff036bce

Silhouette:
ACT_Enemy_Silhouette_wow_ff08178a

Spike Beast:
ACT_Enemy_Horde_Explosive_wow_ff0372e2Рассматривать будем монстров Disciple (Raider) и Initiate (Executioner):
- ACT_Enemy_Disciple_wow_ff033775
- ACT_Enemy_Initiate_wow_ff033811

Вытягиваем оттуда основной файл-объект:
- ACT_Enemy_Disciple_wow_ff033775_3207CC33 (ACT_Enemies_Disciple.gao)
- ACT_Enemy_Initiate_wow_ff033811_3207CC9B (ACT_Enemies_Initiate.gao)

Теперь посмотрим, чем отличаются файлы:

Итого у нас имеется 6 блоков для рассмотрения:
- 0x07380113 и 0x6CBA0031 отвечают за таблицу, в которой содержится количество объектов "скелета" модели монстра (голова, руки, ноги, и т.д...) (выделены фиолетовым):

Внутри мы видим блок, который отвечает за общее количество объектов "скелета" модели монстра (выделены синим), далее идёт индекс объекта (выделены красным), и какие-то параметры\данные (выделены серым).

- 0xC402001F и 0x66BA0031 отвечают за ссылку на 0xC502001F и 0x67BA0031, таблица, которая содержит ID объектов "скелета" модели монстра (выделены синим):

Объекты в таблице идут в строго-определённом порядке:
8C02001F - 1F00028C >B_Disciple_Yezidi.gao
8D02001F - 1F00028D >B_Disciple_Yezidi Pelvis.gao
8E02001F - 1F00028E >B_Disciple_Yezidi Spine.gao
8F02001F - 1F00028F >B_Disciple_Yezidi Spine1.gao
9002001F - 1F000290 >B_Disciple_Yezidi Neck.gao
9102001F - 1F000291 >B_Disciple_Yezidi Head.gao
9C02001F - 1F00029C >B_Disciple_Yezidi L Clavicle.gao
9D02001F - 1F00029D >B_Disciple_Yezidi L UpperArm.gao
9E02001F - 1F00029E >B_Disciple_Yezidi L Forearm.gao
9F02001F - 1F00029F >B_Disciple_Yezidi L Hand.gao
A502001F - 1F0002A5 >B_Disciple_Yezidi R Clavicle.gao
A602001F - 1F0002A6 >B_Disciple_Yezidi R UpperArm.gao
A702001F - 1F0002A7 >B_Disciple_Yezidi R Forearm.gao
A802001F - 1F0002A8 >B_Disciple_Yezidi R Hand.gao
B102001F - 1F0002B1 >B_Disciple_Yezidi L Thigh.gao
B202001F - 1F0002B2 >B_Disciple_Yezidi L Calf.gao
B302001F - 1F0002B3 >B_Disciple_Yezidi L Foot.gao
B402001F - 1F0002B4 >B_Disciple_Yezidi L Toe0.gao
B502001F - 1F0002B5 >B_Disciple_Yezidi R Thigh.gao
B602001F - 1F0002B6 >B_Disciple_Yezidi R Calf.gao
B702001F - 1F0002B7 >B_Disciple_Yezidi R Foot.gao
B802001F - 1F0002B8 >B_Disciple_Yezidi R Toe0.gao
A902001F - 1F0002A9 >B_Prince_Sword02.gao
1808001F - 1F000818 >B_Disciple_Yezidi_MOD_Flap_BU_Root.gao
2008001F - 1F000820 >B_Disciple_Yezidi_MOD_Jupe_LB_Root.gao
1E08001F - 1F00081E >B_Disciple_Yezidi_MOD_Jupe_RB_Root.gao
1908001F - 1F000819 >B_Disciple_Yezidi_MOD_Flap_BU.gao
1408001F - 1F000814 >B_Disciple_Yezidi_MOD_Flap_L_Root.gao
1508001F - 1F000815 >B_Disciple_Yezidi_MOD_Flap_L.gao
1608001F - 1F000816 >B_Disciple_Yezidi_MOD_Flap_R_Root.gao
1708001F - 1F000817 >B_Disciple_Yezidi_MOD_Flap_R.gao
2108001F - 1F000821 >B_Disciple_Yezidi_MOD_Jupe_LB.gao
1A08001F - 1F00081A >B_Disciple_Yezidi_MOD_Jupe_LF_Root.gao
1B08001F - 1F00081B >B_Disciple_Yezidi_MOD_Jupe_LF.gao
1F08001F - 1F00081F >B_Disciple_Yezidi_MOD_Jupe_RB.gao
1C08001F - 1F00081C >B_Disciple_Yezidi_MOD_Jupe_RF_Root.gao
1D08001F - 1F00081D >B_Disciple_Yezidi_MOD_Jupe_RF.gao4CBA0031 - 3100BA4C >B_Disciple_Yezidi.gao
4DBA0031 - 3100BA4D >B_Disciple_Yezidi Pelvis.gao
4EBA0031 - 3100BA4E >B_Disciple_Yezidi Spine.gao
4FBA0031 - 3100BA4F >B_Disciple_Yezidi Spine1.gao
50BA0031 - 3100BA50 >B_Disciple_Yezidi Neck.gao
51BA0031 - 3100BA51 >B_Disciple_Yezidi Head.gao
53BA0031 - 3100BA53 >B_Disciple_Yezidi L Clavicle.gao
54BA0031 - 3100BA54 >B_Disciple_Yezidi L UpperArm.gao
55BA0031 - 3100BA55 >B_Disciple_Yezidi L Forearm.gao
56BA0031 - 3100BA56 >B_Disciple_Yezidi L Hand.gao
57BA0031 - 3100BA57 >B_Disciple_Yezidi R Clavicle.gao
58BA0031 - 3100BA58 >B_Disciple_Yezidi R UpperArm.gao
59BA0031 - 3100BA59 >B_Disciple_Yezidi R Forearm.gao
5ABA0031 - 3100BA5A >B_Disciple_Yezidi R Hand.gao
5CBA0031 - 3100BA5C >B_Disciple_Yezidi L Thigh.gao
5DBA0031 - 3100BA5D >B_Disciple_Yezidi L Calf.gao
5EBA0031 - 3100BA5E >B_Disciple_Yezidi L Foot.gao
5FBA0031 - 3100BA5F >B_Disciple_Yezidi L Toe0.gao
60BA0031 - 3100BA60 >B_Disciple_Yezidi R Thigh.gao
61BA0031 - 3100BA61 >B_Disciple_Yezidi R Calf.gao
62BA0031 - 3100BA62 >B_Disciple_Yezidi R Foot.gao
63BA0031 - 3100BA63 >B_Disciple_Yezidi R Toe0.gao
5BBA0031 - 3100BA5B >B_Prince_Sword02.gao
28560130 - 30015628 >B_MOD_B_Loincloth_Root.gao
64BA0031 - 3100BA64 >B_MOD_B_Loincloth.gao
27560130 - 30015627 >B_MOD_F_Loincloth_Root.gao
65BA0031 - 3100BA65 >B_MOD_F_Loincloth.gao
26560130 - 30015626 >B_MOD_Head_Flap_Root.gao
52BA0031 - 3100BA52 >B_MOD_Head_Flap.gao- 0x39СС0732 и 0xA8760113 отвечают за огромную таблицу с ссылками на данные (около 190 ссылок), назначение неизвестно (выделены чёрным). В большинстве случаев данные полностью совпадают, или различаются на несколько байт.

- 0x35CC0732 и 0x98CC0732 отвечают за две ссылки - одинаковый для обоих монстров файл с данными (таблица?) 0x10CC0732, а также 0x34CC0732 и 0x97CC0732, которые отвечают за свойства монстров (выделены красным).

Структура напоминает файл с параметрами меча. Блок 0xFE340113 и 0xFD340113 отвечают за объекты ACT_Enemies_Disciple_Death.gao и ACT_Enemies_Initiate_Death.gao (выделены синим). Блок 0xB3400113 отвечает за объект ACT_SFX_Weapon_Slash.gao (выделен красным). Блок 0xF0720113 отвечает за объект ACT_Enemies_Death_FX.gao (выделен серым). Блок 0x51330113 отвечает за объект ACT_Weapon_Feet.gao (выделен оранжевым). Блоки выделенные фиолетовым предположительно отвечают за AI монстра. На такие мысли меня наводят дебаг сообщения в конце файлов:
ACT_Enemy_Disciple_wow_ff033775_3207CC1A
DISCIPLE:: Unknown Slice Method To Used

ACT_Enemy_Disciple_wow_ff033775_3207CC1C
AI Error: Actor is NOT online
AI Error: Not Done
DISCIPLE:: C_State_Disciple_Move_GoTo ; No Spot to go to
DISCIPLE:: PathFinding {ObstructionLaterOn} - Check if it's worth the trouble to reposition ourselve base on the new path

ACT_Enemy_Disciple_wow_ff033775_3207CC1D
DISCIPLE:: Cinematic is NO Longer Playing
DISCIPLE:: Cinematic InGame Playing
DISCIPLE:: Cinematic InGame Playing
DISCIPLE:: Cinematic Interruption
DISCIPLE:: Cinematic InGame Playing

ACT_Enemy_Disciple_wow_ff033775_3207CC19
AI Error: Not Done- 0x31CC0732 и 0x99CC0732 отвечают за ссылку на 0x4C230032, одинаковый файл для обоих монстров (выделены чёрным). Назначение неизвестно.
- 0x32CC0732 и 0x9ACC0732 отвечают за ссылку на 0x4E230032, одинаковый файл для обоих монстров (выделены чёрным). Назначение неизвестно.

Не найдя модель и текстуру я решил искать в обратном направлении - зная код текстуры я нашёл второй объект, который отвечает за "тушку" монстра:
- ACT_Enemy_Disciple_wow_ff033775_1F0002C1 (M_Disciple_Body.gao)
- ACT_Enemy_Initiate_wow_ff033811_3100BA4B (M_Initie.gao)

Открываем и сравниваем:

- 0x7F02001F и 0x24BA0031 отвечают за 3d модель монстра (выделены синим).
- 0xEB02001F и 0x1C570130 содержит 7 ссылок, первые 6 из них ведут на основную текстуру, и ещё одна ведёт на одинаковую текстуру для обоих монстров, предположительно отвечающую за эффекты крови (выделены красным). Открываем 0xEF02001F и 0x15570130, достаём оттуда основную текстуру - 0x8703001F и 0x9BB90031.

Далее идёт похожая таблица с объектами "скелета" модели монстра:

Как и в прошлый раз объекты расположены в строгом порядке:
1C000000
8D02001F - 1F00028D >B_Disciple_Yezidi Pelvis.gao
01000000
8E02001F - 1F00028E >B_Disciple_Yezidi Spine.gao
02000000
8F02001F - 1F00028F >B_Disciple_Yezidi Spine1.gao
03000000
9002001F - 1F000290 >B_Disciple_Yezidi Neck.gao
04000000
9102001F - 1F000291 >B_Disciple_Yezidi Head.gao
05000000
9C02001F - 1F00029C >B_Disciple_Yezidi L Clavicle.gao
06000000
9D02001F - 1F00029D >B_Disciple_Yezidi L UpperArm.gao
07000000
9E02001F - 1F00029E >B_Disciple_Yezidi L Forearm.gao
08000000
9F02001F - 1F00029F >B_Disciple_Yezidi L Hand.gao
09000000
A502001F - 1F0002A5 >B_Disciple_Yezidi R Clavicle.gao
0A000000
A602001F - 1F0002A6 >B_Disciple_Yezidi R UpperArm.gao
0B000000
A702001F - 1F0002A7 >B_Disciple_Yezidi R Forearm.gao
0C000000
A802001F - 1F0002A8 >B_Disciple_Yezidi R Hand.gao
0D000000
B102001F - 1F0002B1 >B_Disciple_Yezidi L Thigh.gao
0E000000
B202001F - 1F0002B2 >B_Disciple_Yezidi L Calf.gao
0F000000
B302001F - 1F0002B3 >B_Disciple_Yezidi L Foot.gao
10000000
B402001F - 1F0002B4 >B_Disciple_Yezidi L Toe0.gao
11000000
B502001F - 1F0002B5 >B_Disciple_Yezidi R Thigh.gao
12000000
B602001F - 1F0002B6 >B_Disciple_Yezidi R Calf.gao
13000000
B702001F - 1F0002B7 >B_Disciple_Yezidi R Foot.gao
14000000
B802001F - 1F0002B8 >B_Disciple_Yezidi R Toe0.gao
15000000
1908001F - 1F000819 >B_Disciple_Yezidi_MOD_Flap_BU.gao
1A000000
1508001F - 1F000815 >B_Disciple_Yezidi_MOD_Flap_L.gao
1C000000
1708001F - 1F000817 >B_Disciple_Yezidi_MOD_Flap_R.gao
1E000000
2108001F - 1F000821 >B_Disciple_Yezidi_MOD_Jupe_LB.gao
1F000000
1B08001F - 1F00081B >B_Disciple_Yezidi_MOD_Jupe_LF.gao
21000000
1F08001F - 1F00081F >B_Disciple_Yezidi_MOD_Jupe_RB.gao
22000000
1D08001F - 1F00081D >B_Disciple_Yezidi_MOD_Jupe_RF.gao
24000000
FFFFFFFF18000000
4DBA0031 - 3100BA4D >B_Disciple_Yezidi Pelvis.gao
01000000
4EBA0031 - 3100BA4E >B_Disciple_Yezidi Spine.gao
02000000
4FBA0031 - 3100BA4F >B_Disciple_Yezidi Spine1.gao
03000000
50BA0031 - 3100BA50 >B_Disciple_Yezidi Neck.gao
04000000
51BA0031 - 3100BA51 >B_Disciple_Yezidi Head.gao
05000000
53BA0031 - 3100BA53 >B_Disciple_Yezidi L Clavicle.gao
06000000
54BA0031 - 3100BA54 >B_Disciple_Yezidi L UpperArm.gao
07000000
55BA0031 - 3100BA55 >B_Disciple_Yezidi L Forearm.gao
08000000
56BA0031 - 3100BA56 >B_Disciple_Yezidi L Hand.gao
09000000
57BA0031 - 3100BA57 >B_Disciple_Yezidi R Clavicle.gao
0A000000
58BA0031 - 3100BA58 >B_Disciple_Yezidi R UpperArm.gao
0B000000
59BA0031 - 3100BA59 >B_Disciple_Yezidi R Forearm.gao
0C000000
5ABA0031 - 3100BA5A >B_Disciple_Yezidi R Hand.gao
0D000000
5CBA0031 - 3100BA5C >B_Disciple_Yezidi L Thigh.gao
0E000000
5DBA0031 - 3100BA5D >B_Disciple_Yezidi L Calf.gao
0F000000
5EBA0031 - 3100BA5E >B_Disciple_Yezidi L Foot.gao
10000000
5FBA0031 - 3100BA5F >B_Disciple_Yezidi L Toe0.gao
11000000
60BA0031 - 3100BA60 >B_Disciple_Yezidi R Thigh.gao
12000000
61BA0031 - 3100BA61 >B_Disciple_Yezidi R Calf.gao
13000000
62BA0031 - 3100BA62 >B_Disciple_Yezidi R Foot.gao
14000000
63BA0031 - 3100BA63 >B_Disciple_Yezidi R Toe0.gao
15000000
64BA0031 - 3100BA64 >B_MOD_B_Loincloth.gao
18000000
65BA0031 - 3100BA65 >B_MOD_B_Loincloth_Root.gao
1A000000
52BA0031 - 3100BA52 >B_MOD_Head_Flap.gao
1C000000
FFFFFFFFИ последняя таблица, которая отвечает за объекты со спец. эффектами (кровь при попадании, дезинтеграция монстра после сметри, и т.д..)

Для обоих монстров таблица одинаковая (http://pastie.org/private/3twige4hhsmw83ldy9sgag) (байты были перевёрнуты обратно для удобства поиска объектов через Persian Rug).

Мои первые попытки перенести модель и текстуру монстра Initiate (Executor) на Disciple (Raider) напоминают историю с мишкой и зелёным топором (слева то, что получилось, справа оригинал):

Upd: разобрался с текстурой, оказалось что я проворонил блок с параметрами, который отвечает за правильное наложение текстуры. Обновил скриншот в этапе переноса модели с текстурой оружия, и добавил описание. Также обновил описание блоков с объектами - это оказались объекты "скелета" модели монстра, последние сомнения по поводу их назначения развеяли попытки перенести модель монстра из Rival Swords (The Two Thrones) в Revelations (Warrior Within) и наоборот:

Мод 3 - модифицирование монстров в Prince of Persia: Revelations/Warrior Within (WIP)

xOwOr8MWAyY


Продолжение следует...


Буду наполнять тему по мере нахождения новой инфы :crazy:

SILENT-Pavel
13.08.2015, 01:19
Больше бы псп игр так разобрали, можно было бы делать тотальные конверсии игр.

BlackDaemon
13.08.2015, 02:11
SILENT-Pavel, я надеюсь, что в данном случае ресурсы других версий Prince of Persia: Warrior Within (Revelations) и Prince of Persia: The Two Thrones (Rival Swords) должны быть похожи, что даст возможность моддить их тоже :) PSP версию я взял из-за удобства, т.к. есть возможность редактировать сэйвы и быстро проверить необходимое оружие :D

BlackDaemon
01.05.2016, 11:13
Такс, пришло время для релиза обновленного редактора сэйвов :D Исходники выложу немного позже, т.к. их надо немного привести в надлежащий вид.

http://s019.radikal.ru/i618/1604/f2/9170c2a4a4cft.jpg (http://s019.radikal.ru/i618/1604/f2/9170c2a4a4cf.jpg) http://s019.radikal.ru/i620/1604/64/a354b41f3706t.jpg (http://s019.radikal.ru/i620/1604/64/a354b41f3706.jpg) http://s019.radikal.ru/i633/1604/b3/73993ed17033t.jpg (http://s019.radikal.ru/i633/1604/b3/73993ed17033.jpg)

2N2TnN-I24A

Новое в редакторе сэйвов для Warrior Within/Revelations:
- поддерживает сэйвы от версий PSP, PC и PS2 (частично, экспериментальная поддержка);
- изменение локации (включая сэйвпоинты, чекпоинты и сторигейты; также дополнительные уровни для PSP версии);
- изменение сюжетной линии.

Новое в редакторе сэйвов для The Two Thrones/Rival Swords:
- поддерживает сэйвы от версий PSP, PC и PS2 (частично, экспериментальная поддержка);
- изменение локации (включая сэйвпоинты и чекпоинты; также дополнительные уровни для PSP версии, в т.ч. скрытые тестовые/незавершённые уровни).

Возможности Timeline Patcher:
- отключение защиты проверки целостности сэйвов, PC (для исполняемого файла без защиты и сжатия);
- частичное отключение защиты проверки целостности сэйвов, PS2;
- изменение локации при запуске "New Game", PC (GOG версия WW - для исполняемого файла без сжатия, 5,533,696 bytes и для T2T NoCD от Reloaded);
- изменение локации при запуске "New Game", Xbox (бета-версия T2T, для возможности полностью "разблокировать" игру).

Project "Timeline" + Timeline Patcher (https://drive.google.com/file/d/0B980do3iuJHvNHk5VlUwb1lsNkU/view) и набор сэйвов (https://drive.google.com/file/d/0B980do3iuJHvVnVEdkw5eVJmaXM/view) для тестирования.

Для РС версии T2T также можно воспользоваться патчем от RhymeKidder (http://www.legendsworld.net/phpBB3/memberlist.php?mode=viewprofile&u=4066), в нём включена расчлелёнка, добавлена поддержка 16:9 разрешений а также убрана проверка целостности сэйвов (см. вложение, перезалил (http://www.legendsworld.net/phpBB3/viewtopic.php?f=7&t=13649&start=180#p76943) оригинальные архивы).
LegendsWorld

BlackDaemon
12.05.2018, 10:11
Глянул я на днях инфу по BF контейнеру (http://wiki.xentax.com/index.php/PoP-SoT_BF_1) и решил попробовать накалякать свой распаковщик/упаковщик. Увы, но желаемого результата достичь не получилось, тем не менее небольшой эффект такая замена дала. Засунул в РС версию T2T all_weapons_wow_ff0610da.bin (предпоследний файл в контейнере) большего размера (на 30720 байт), чем оригинальный, пропатчил в заголовке оффсеты по размеру и позиции. Частично игра даже стала загружаться, но часть данных при этом побилась (вылеты с определённым оружием при попытке загрузить сейв), т.е. нужно ещё что-то менять в этом шайтан-формате:crazy: Выкладываю тулзу "как есть", на случай, если кто-то заинтересуется в её доработке;)

https://i.imgur.com/NUfo0fX.png

BlackDaemon
13.05.2018, 03:18
В списке подозреваемых:

- таблица с позициями файлов вначале заголовка
https://i.imgur.com/hDDGGFI.png

- таблица с размером и названием файлов
https://i.imgur.com/EJiNnTI.png

- подозрительный файл size.grs, который в самом конце BF файла
https://i.imgur.com/a7T07cH.png


Для удобства немного выровнял первую таблицу, наблюдается некоторая "шаблонность" значений
https://i.imgur.com/p63cRVa.png


Upd:
Хорошая новость - "неизвестный блок" в первой таблице разгадан. Плохая - просматривается явная зависимость от блока с позицией файла:dash:
https://i.imgur.com/ugqGU6t.png

Upd2:
Можно откидывать неизвестный блок во второй таблице, пробовал обнулять значения, в том числе затирать названия файлов - на работоспособность игры это не влияет:D

Обнаружил связь "неизвестного блока" из первой таблицы с size.grs
https://i.imgur.com/ZYmyoK7.png

На скорую руку написал парсер size.grs и сделал сортировку по блоку с хэшем
https://i.imgur.com/VGjZq5N.png

Upd3:
Пролистывая список с крупными файлами заметил некоторое сходство "неизвестного блока" в size.grs с размером .bin файлов, но во всех случаях значение в нём меньше, чем размер файла...почему?
https://i.imgur.com/w9qj3JM.png

Upd4:
Разобрался с "неизвестным блоком" в size.grs - это размер данных внутри файла, без учёта нулей в конце.

BlackDaemon
21.05.2018, 01:10
Начал изучать запакованные файлы внутри BF. Вооружившись кодом PofP.bin.repacker от (http://www.pspx.ru/forum/showpost.php?p=1101380&postcount=345) dodther (http://www.pspx.ru/forum/member.php?u=44916) и обнаружил, что на файлах локаций код падает на аномальных блоках. Сравнивая распакованный файл через PersianRug обнаружилось следующее (на примере 310_Depths_wow_ff0e1efa.bin)

так выглядят обычные блоки (размер распакованного блока, размер запакованного блока, его данные)
https://i.imgur.com/aNtLlAm.png

а вот так выглядят аномальные
https://i.imgur.com/SUxibGU.png

Когда PersianRug находит такой блок (распакованный размер и размер запакованного блока одинаковые) - считывает следующие 2 байта, отнимает оттуда 17 байт, и копирует оставшиеся (в данном случае 253 - 17 = 236 байт) данных, остальное содержимое блока выкидывается. Разумеется, в таком запакованном файле обратно этого блока нет, что ставит крест на моддинге файлов локаций.

3,080,188 байт - оригинал
4,240,047 байт - распакованный
2,949,116 байт - запакованный обратно (с пом. psp_comp от RikuKH3)

Upd:
Залил примеры блоков во вложения.

BlackDaemon
22.05.2018, 17:33
Сегодня это наконец-то свершилось! После замены на all_weapons_wow_ff0610da.bin большего размера игра завелась как надо, без вылетов:yahoo:

https://i.imgur.com/yUqtTBD.jpg

https://i.imgur.com/KcwlkiQ.png

https://i.imgur.com/HjHmVU6.png

Залил новый билд утилиты, проблема с правильной распаковкой файлов локаций пока что не решена.

Upd:
Есть подозрение, что в этих аномальных блоках какая-то специфическая "plain data", пробовал эти блоки прогонять через lzo1x - на выходе выходит размер больше оригинального блока:crazy: Немного обновил в этом плане код, добавил пару проверок и копирование блока в его оригинальном виде туда и обратно.

По каким-то причинам 620_Courtyard_GFX_wow_ff0f3fd4.bin и 740_Well_TopWell_2_wow_ff0c1183.bin сжимаются сильнее оригинальных, хотя расжатые данные побайтно совпадают. Утилита RikuKH3 сжимает аналогично. :unknw:

Yoti
23.05.2018, 01:20
Утилита RikuKH3 сжимает аналогично.
Аналогично сильнее?

BlackDaemon
23.05.2018, 03:22
Yoti, да, md5 сжатых обратно файлов (моей утилитой и утилитой RikuKH3) совпадают. Самое забавное в этой ситуации то, что у сжатых файлов обратно данные в последнем блоке вписываются байт-в-байт (+4 байта зарезервировано для размера файла), потому отпадает необходимость выравнивать/забивать следующий блок до 2048 байт нулями.
https://i.imgur.com/OaA4TwV.png

620_Courtyard_GFX_wow_ff0f3fd4.bin:
оригинал - 61,436
расжатый - 90,844
сжатый обратно - 59,388

740_Well_TopWell_2_wow_ff0c1183.bin:
оригинал - 55,292
расжатый - 219,671
сжатый обратно - 53,244

Upd: прикрепил файлы.
Upd2: PersianRug падает смертью храбрых при попытке распаковать сжатые обратно файлы, моя утилита справляется:crazy:

BlackDaemon
29.05.2018, 07:36
Первые наброски по .bin формату
https://i.imgur.com/RCL9BNd.png

Функционал пока что очень примитивный, и утилита по-большей части годится в качестве вспомогательной для изучения формата.
-чтение .bin файла в (сжатом виде и без сжатия);
-распаковка содержимого .bin на отдельные файлы;
-обратная сборка распакованных файлов в .bin (примитивное копирование);
-чтение и распаковка текстур (PC версия);
-частичная запаковка текстур обратно (PC версия, кроме формата 8bit + палитра);
-поиск на наличие ID других файлов, и ID текущего файла в других.
-внешний файл (override.txt) для добавления доп. описания, и при необходимости, типа файла.

Из очевидных вещей пока в todo-списке задача разобраться с конвертацией текстур обратно в формат 8bit + палитра, что из себя представляет формат 3D-объектов, каким образом PersianRug с ним работает, и разобраться с этим (http://forum.xentax.com/viewtopic.php?p=43246&sid=77df23af85e280e45567ec4d8bc5f024#p43246).

BlackDaemon
25.06.2018, 12:41
По "просьбам трудящихся" на форуме princed (http://forum.princed.org/viewtopic.php?f=76&t=4224&p=24181#p24035) на скорую руку сделал CLI-вариант утилит, мб кому-то тоже пригодится :crazy:

Extract BF: -e <bf_file> <extracted_files_folder>
Decompress BIN files: -d <bf_file> <extracted_files_folder>
Compress BIN files: -c <bf_file> <extracted_files_folder>
Build BF: -b <bf_file> <extracted_files_folder> <new_bf_file>
Extract BIN: -e <bin_file> <extracted_files_folder>
Decode textures: -d <bin_file> <textures_folder>
Encode textures: -c <bin_file> <textures_folder>
Build BIN: -b <bin_file> <extracted_files_folder> <new_bin_file>

BlackDaemon
15.06.2019, 16:26
Пообщался я немного с автором IrisTool (https://www.youtube.com/watch?v=l3Knr59wdpA) (утилиты для просмотра ресурсов Beyond Good and Evil), он дал пищу для размышлений:
Parsing bin files are a very complex task. You can only parse those files correctly, if you read exactly the same as game does. Every chunk in bin files have a key, but game simply not uses them, because of binarized format. I can tell, how BGE works, but I have no idea, if it is true for POP games. (I believe, more or less true). Every map related bin file (ff00xxxx.bin, POP games have more meaningful filename, eg map name) starts with world list keys. (You can find same in the wol file with same name as bin). After game collected world keys, it starts read the first world chunk (starts with .wow chars). It can contain more keys, game stores them for further read. After first wow read, it reads second, then third, then etc. After last wow chunk it will read, the first key, what found in first wow chunk. You can not detect, what is the next chunk type, and how should be read (eg ints, bytes, structs, etc), if you are not following game logic. You have to reverse engineer every chunk type, if you want to parse bin files from the beginning to end. There are differences BGE and POP games, BGE only load only one bin file at a time, and loads another one on level change, POP games load several bin files same time. BGE stores textures in separate bin files (ff80xxxx.bin), every POP ff00xxxx bin file contain map data (geometry, bones, scripts, etc) and the second part of the a file contains textures. If you are parsing bin files, you should store how many textures should be read, otherwise there are no way to extract textures correctly. For BGE most of it's textures are paletted textures. It's very difficoult to read, because palettes are stored at different place, than index information. Can you extract every textures from the game?
I hope, you understand, why I don't want to do these things for POP games too. They changed file formats in every game, and POP games lives different life after the beginning.

rl_evader
28.08.2019, 17:28
(tl;dr как найти адерс значения сторигейта через чит энжин для Prince of Persia: Revelations?)
BlackDaemon, привет, зашел сюда по ссылке с твоего твич канала, почитав твой пост и посмотрев данное видео (https://www.youtube.com/watch?v=Rfm5Q9wYq8E) я понял что возможно ты сможешь мне чем то помочь. Где-то год назад я начал спидранить PoP:WW (ПК-версию) и узнав про некоторые механики загорелся идеей построить маршрут для спидрана PSP версии. Но все оказалось не так просто ( иначе я бы не написал сюда), изначально я решил протестировать старый маршрут (https://www.twitch.tv/videos/41505834?t=) и вот что из этого вышло (видео (https://www.youtube.com/watch?v=pCHvitJDIo8)), на 9:38 я активирую тригер в проходе, который (в пк версии) должен загрузить комнату с порталом, но вместо этого он выгрузил тронный зал. Я также пытался пройти в комнату с порталом без активации тригера в проходе, но закономерно ничего из этого не вышло(вместо комнаты была пустота). После череды неудачных попыток загрузить комнату с порталом у меня возникла мысль что возможно во время того как я пробрался в тронный зал с помощью глитчей я задел какой либо из сторигейтов. Скорее всего ты знаешь, но на всякий случай напишу, что в игре есть специальные тригеры (сторигейты), которые помогают игре отследить на каком моменте сюжета в данный момент находится игрок. Так вот, вернувшись в локацию, где происходит бой принца с Шади, я получил вот это (https://www.youtube.com/watch?v=57rjyvHDjO8), эта кнопка должна появляться на момент когда принц возвращается сюда в облике песчаного духа -пример (https://youtu.be/W-Z1ojYG6rg?list=PL_7kNUIjkDckaYgPj8jG23_Oby-ziU8Uv&t=5681). К сожалению этот баг получилось вызвать лишь единожды, после того как я несколько раз возвращался из тронного зала в эту локацию, кнопка больше не появлялась. Оставив надежды найти решение проблемы для этого маршрута, я решил попробовать актуальный (https://youtu.be/Uy7MAllkaK4?t=409) маршрут, где вместо того чтобы идти в тронный зал, мы с помощью глитча пробираемся в локацию с чекпоинтом и загружаем энд-гейм область. На этот раз у меня не возникло проблем с подгрузкой нужной мне локации и у меня получилось пройти дальше как показано здесь (https://youtu.be/Uy7MAllkaK4?t=432)(к сожалению у меня нет видео, где я делаю тоже самое с эмулятора), но зато возникла новая проблема. Краткая справка чтобы суть проблемы была ясна, на этом (https://youtu.be/GA8iRmHH1W8?t=436) фрагменте спидранер добегает до чекпоинта который находится в дверном проеме и убивается в яме с шипами, чтобы сторигейт переключился со 2-ого(2 ой сторигейт соответствует началу игры) на 58-ой( 58 это почти самый конец игры). Так вот, после повторений тех же манипуляций( а именно, я добежал до чекпоинта и убился) игра крашится когда я пытаюсь пойти либо дальше, либо вернуться назад (видео (https://www.youtube.com/watch?v=1wzYlkXx4v4)). Я опробовал еще довольно много способов, но все это не дало никакого прогресса и напоминало скорее танцы с бубном из-за отсутствия какого либо способа проверить на каком сторигейте я нахожусь. После этого я решил обратится к такой замечательной вещи как чит-энжин в которой я полный ноль(мой максимум найти значения хп/координат и поинтеры для него) и попытаться найти значение сторигейта. Впоследствии я узнал, что даже если я найду значение сторигейта, найти поинтеры на эмуляторе это крайне сложная задача( не для такого ламера как я) и я решил оставить это дело. И вот как раз по поводу проблемы нахождения этого значения я и хочу к тебе обратиться, я видел что ты сделал сейв эдитор для псп(!) версии на эмуляторе и возможно у тебя есть адрес значения сторигейтов. Если же такого не имеется, то буду премного благодарен любым гайдам по нахождению адреса значения на эмуляторе.

BlackDaemon
29.08.2019, 11:49
rl_evader, привет. К сожалению, с поиском и редактированием значений в памяти у меня тоже опыт на уровне начинающего, могу разве что скинуть список чекпоинтов и сторигейтов
AddLocation("010_Cale_TEC_Checkpoint01", "ALL", 0x60080004, 0x4A96074D);
AddLocation("010_Deck_TEC_Checkpoint01", "ALL", 0x324800A6, 0x4B96074D);
AddLocation("020_Beach_TEC_Savepoint", "ALL", 0xBB0F0133, 0x03280B2B);
AddLocation("020_Cliff_TEC_Checkpoint01", "ALL", 0x724700A6, 0x0428082B);
AddLocation("020_PassageTo040_TEC_Checkpoint02", "ALL", 0x1C5C0129, 0x0728082B);
AddLocation("035_Cliff_TEC_SavePointRef01", "ALL", 0x27CB013C, 0x28AC1308);
AddLocation("035_Grotte_TEC_Checkpoint01", "ALL", 0x44850029, 0x2EAC1308);
AddLocation("040_couloirA1HallToGuerite_TEC_Savepoint01", "ALL", 0x1FF21308, 0xB0FE1208);
AddLocation("040_couloirTo070_TEC_Checkpoint01", "ALL", 0x3CF21308, 0xA6FE1208);
AddLocation("040_GueriteINT_TEC_Checkpoint01", "ALL", 0x39F21308, 0xAEFE1208);
AddLocation("040_WARPGATE_TEC_SCT_SavePoint01@Sct_Checkpoint01", "ALL", 0x3E850011, 0xBF4A0011);
AddLocation("045_couloirA1HallToGuerite_TEC_Savepoint01", "ALL", 0xF5650192, 0xD7021308);
AddLocation("045_couloirB2HallToGuerite_TEC_SavePoint01", "ALL", 0xC5F21308, 0x84971308);
AddLocation("045_ExitToBonus_TEC_Checkpoint01", "ALL", 0x31191408, 0x6F971308);
AddLocation("045_WARPGATE_TEC_SCT_Savepoint01@Sct_Checkpoint01", "ALL", 0x4E850011, 0xC14A0011);
AddLocation("055_AccessRoom_TEC_Checkpoint01v9", "PSP", 0x8BC902A6, 0x4E0E0004);
AddLocation("055_AccessRoom_TEC_Savepoint_01", "ALL", 0x892100A6, 0x4E0E0004);
AddLocation("055_AccessRoom_PostSW_Checkpoint", "ALL", 0x68520133, 0x4E0E0004);
AddLocation("055_JctTo045_TEC_Checkpoint01", "ALL", 0xD8F21308, 0x440E0004);
AddLocation("055_JctToBonus_TEC_Checkpoint01", "ALL", 0x15C100A6, 0xD0890004);
AddLocation("055_JctTGT_Checkpoint_Easy_01", "PSP", 0xB70D0096, 0x3604009C);
AddLocation("055_LinkTo205B_TEC_Savepoint_01", "ALL", 0x410E01A6, 0x80290029);
AddLocation("065_HourglassRoom_TEC_Savepoint_01", "ALL", 0x7B1A0044, 0x2D17013C);
AddLocation("065_WARPGATE_TEC_SCT_Savepoint01@Sct_Checkpoint01", "ALL", 0x64850011, 0x50510011);
AddLocation("070_Corridor330B_TEC_checkpoint_01", "ALL", 0x0DCF013C, 0x1C12003B);
AddLocation("070_MainRoom_TEC_checkpoint_01", "ALL", 0x1ECF013C, 0x2612003B);
AddLocation("070_To040A_TEC_SavePoint_01", "ALL", 0x28CF013C, 0xD671003B);
AddLocation("070_WARPGATE_TEC_SCT_Savepoint01@Sct_Checkpoint01", "ALL", 0x85850011, 0x63580011);
AddLocation("075_Corridor055B_TEC_SavePoint001", "ALL", 0x2EE5013C, 0x2A12003B);
AddLocation("075_CorridorGauntletB_TEC_checkpoint_01", "ALL", 0x6692023C, 0x2834013C);
AddLocation("075_MainRoom_TEC_CheckPoint_01", "ALL", 0x7BD4013C, 0x3012003B);
AddLocation("085_Linker2CliffA_TEC_Checkpoint01", "ALL", 0x24CB013C, 0x7F310011);
AddLocation("085_Linker2UpgradeB_TEC_SCT_checkpoint_01", "ALL", 0xDA87023C, 0x6F49013C);
AddLocation("085_Linker2WarpA_TEC_CheckPoint_001", "ALL", 0xFD3E023C, 0x85310011);
AddLocation("085_LinkerTo075_TEC_SCT_savepoint01", "ALL", 0x5396023C, 0x89310011);
AddLocation("085_SacrificeRoom_LowerSection_TEC_Checkpoint01", "ALL", 0x13CB013C, 0xCB92023C);
AddLocation("085_SacrificeRoom_TEC_SCT_savepoint_01", "ALL", 0x5C96023C, 0xCB92023C);
AddLocation("085_WARPGATE_TEC_SCT_Savepoint01@Sct_Checkpoint01", "ALL", 0x96850011, 0x65580011);
AddLocation("100_WARPGATE_A_TEC_SCT_Savepoint01@Sct_Checkpoint01", "ALL", 0xA6850011, 0xBA941308);
AddLocation("100_WARPGATE_B_TEC_SCT_Savepoint01@Sct_Checkpoint01", "ALL", 0xD6850011, 0xF1580011);
AddLocation("105_Hall_TEC_Checkpoint01@Sct_Checkpoint01", "ALL", 0x77F21308, 0xB97D1308);
AddLocation("105_JonctionTo055_TEC_Savepoint01@Sct_Checkpoint01", "ALL", 0xA0311408, 0xBB7D1308);
AddLocation("105_WARPGATE_A_TEC_SCT_Savepoint01@Sct_Checkpoint01", "ALL", 0xB6850011, 0xF3580011);
AddLocation("105_WARPGATE_B_TEC_SCT_Savepoint01@Sct_Checkpoint01", "ALL", 0xC6850011, 0xF5580011);
AddLocation("120_To110_TEC_Savepoint01", "ALL", 0x64790029, 0x6AD7003C);
AddLocation("110_LoadingBalcony_TEC_SCT_savepoint01", "ALL", 0x20B0023C, 0x66D7003C);
AddLocation("110_LowerGarden_TEC_SCT_SavePointRef_01", "ALL", 0x51D4013C, 0x68D7003C);
AddLocation("115_ArmorRoom_TEC_SCT_checkpoint_01", "ALL", 0xD687023C, 0xC3E1003C);
AddLocation("115_LoadingBalcony_TEC_SCT_savepoint_01", "ALL", 0x13B0023C, 0x5DC5003C);
AddLocation("115_LowerGarden_TEC_SCT_CheckPoint01Trapeze", "ALL", 0xD0CE013C, 0x5FC5003C);
AddLocation("120_Main_TEC_Checkpoint01", "ALL", 0x562201A6, 0xC52C0029);
AddLocation("125_To105_TEC_Savepoint_01", "ALL", 0x1E790029, 0xB82B0029);
AddLocation("125_ToUpgrade01_SCT_CheckPoint", "ALL", 0xCEA30029, 0x712D0029);
AddLocation("125_VegGoal_TEC_Checkpoint01", "ALL", 0x1B790029, 0xB62B0029);
AddLocation("205_Entrance_TEC_Savepoint01", "ALL", 0xFD790029, 0x81290029);
AddLocation("205_JctTo215_TEC_Checkpoint01", "ALL", 0xFEDA0029, 0x5E2A0029);
AddLocation("205_MechTower_TEC_Checkpoint01", "ALL", 0x087A0029, 0x2C2A0029);
AddLocation("205_MechTower_TEC_Checkpoint02", "ALL", 0x0B7A0029, 0x2C2A0029);
AddLocation("210_TowerMec1_TEC_Checkpoint01", "ALL", 0xA1850029, 0xE30A0004);
AddLocation("210_WARPGATE_TEC_SCT_Savepoint01@Sct_Checkpoint01", "ALL", 0xC9930011, 0xC6580011);
//AddLocation("215_E3_TEC_Checkpoint01", "ALL", 0x275A0004, 0x77290004); //DEMO LOCATION, WORKING ONLY THROUGH "START NEW GAME" (checked on PC version)
AddLocation("215_ExitTo205_TEC_Savepoint01", "ALL", 0x547A0029, 0xA6090004);
AddLocation("215_ExitTo605_TEC_Savepoint01", "ALL", 0x357B0029, 0xA8090004);
AddLocation("215_TowerMec1_TEC_Checkpoint01", "ALL", 0xAA7A0029, 0xB2090004);
AddLocation("215_TowerMec1_TEC_Checkpoint02", "ALL", 0xBB7A0029, 0xB2090004);
AddLocation("215_WARPGATE_TEC_SCT_Savepoint01@Sct_Checkpoint01", "ALL", 0xD9930011, 0xC8580011);
AddLocation("230_ExitToMecpit_TEC_Checkpoint01", "ALL", 0x22900004, 0xD78E0004);
AddLocation("230_ExitToMecpit_TEC_Savepoint01", "ALL", 0x547B0029, 0xD78E0004);
AddLocation("230_TowerMec2_TEC_Checkpoint01", "ALL", 0x837B0029, 0xDD8E0004);
AddLocation("230_TowerMec2_TEC_Checkpoint02", "ALL", 0xB37B0029, 0xDD8E0004);
AddLocation("230_WARPGATE_TEC_SCT_Savepoint01@Sct_Checkpoint01", "ALL", 0xE9930011, 0xA9580011);
AddLocation("235_JctToBonus_SCT_Checkpoint", "ALL", 0xCAA30029, 0xE58E0004);
AddLocation("235_TowerMec2_TEC_Checkpoint01", "ALL", 0xCB840029, 0xEF8E0004);
AddLocation("235_TowerMec2_TEC_Checkpoint02", "ALL", 0xED840029, 0xEF8E0004);
AddLocation("235_TowerMec2_TEC_Checkpoint03", "ALL", 0x1C270129, 0xEF8E0004);
AddLocation("235_TowerMec2_TEC_Savepoint01", "ALL", 0x88840029, 0xEF8E0004);
AddLocation("235_WARPGATE_TEC_SCT_Savepoint01@Sct_Checkpoint01", "ALL", 0xFA930011, 0xAB580011);
AddLocation("330_CorrFrom100_SCT_Checkpoint_Easy_01", "PSP", 0x89DD019C, 0x0CFB003C);
AddLocation("330_CorrFrom100_SCT_Checkpoint_01", "PSP", 0xA5DD019C, 0x0CFB003C);
AddLocation("330_CorrFrom100_TEC_Checkpoint_01", "PSP", 0x25FC003C, 0x4127009C);
AddLocation("330_InsideA_SCT_Checkpoint_01", "PSP", 0xABDD019C, 0x0EFB003C);
AddLocation("330_OutsideA_SCT_Checkpoint_Easy_02", "PSP", 0xA8DD019C, 0x10FB003C);
AddLocation("330_OutsideB_SCT_Checkpoint_Easy_01", "PSP", 0xAEDD019C, 0x12FB003C);
AddLocation("400_catacombINT_TEC_Checkpoint01", "ALL", 0x97FC1308, 0x37051308);
//AddLocation("400_catacombINT_TEC_Checkpoint02", "ALL", 0x9BFC1308, 0x37051308); //NOT WORKING?
//AddLocation("400_catacombINT_TEC_Checkpoint03", "ALL", 0x9EFC1308, 0x37051308); //NOT WORKING?
//AddLocation("400_catacombINT_TEC_Checkpoint04", "ALL", 0xA1FC1308, 0x37051308); //NOT WORKING?
AddLocation("400_catacombINT_TEC_SavePoint01", "ALL", 0xA4FC1308, 0x37051308);
AddLocation("410_Rc01_TEC_Checkpoint01", "ALL", 0xD9010048, 0x310D0067);
AddLocation("410_Rc01_TEC_SavePoint01@Sct_Checkpoint01", "ALL", 0x787D1408, 0xCD3B1308);
AddLocation("410_WARPGATE_TEC_SCT_Savepoint01@Sct_Checkpoint01", "ALL", 0x00860011, 0x86580011);
AddLocation("415_ExitTo615_TEC_Savepoint", "ALL", 0x3A1B0044, 0xCDA51308);
AddLocation("415_ExitToBonus_TEC_Checkpoint01", "ALL", 0xB10900AD, 0xB17E0001);
AddLocation("415_Rc01_B_TEC_CheckPoint01", "ALL", 0xADFC1308, 0xE9D01308);
AddLocation("415_Rc01_B_TEC_Checkpoint01@Sct_Checkpoint01", "ALL", 0xCFA01408, 0xE9D01308);
AddLocation("415_Rc02_TEC_CheckPoint01", "ALL", 0xB0FC1308, 0x34521308);
AddLocation("415_Ss01_TEC_SavePoint01", "ALL", 0xFBFC1308, 0x38521308);
AddLocation("415_WARPGATE_TEC_SCT_Savepoint01@Sct_Checkpoint01", "ALL", 0xF0850011, 0x88580011);
AddLocation("425_BiblioHall_TEC_CheckPoint_01", "ALL", 0x860C023C, 0x151F0004);
AddLocation("425_ExitTo415_TEC_SavePoint_01", "ALL", 0x820C023C, 0x101F0004);
AddLocation("425_ExitTo435_TEC_CheckPoint_01", "ALL", 0xAE0C023C, 0x0E1F0004);
AddLocation("425_JctTo205_TEC_SavePoint_01", "ALL", 0xB80C023C, 0x0C1F0004);
AddLocation("425_JctToBonus_TEC_SCT_checkpoint_01", "ALL", 0xD387023C, 0x94890004);
AddLocation("605_Bridge_TEC_SavePoint_01", "ALL", 0x17E5013C, 0x26030023);
AddLocation("605_SanctEpe_Pont_TEC_CheckPoint01", "ALL", 0x25E5013C, 0x41030023);
AddLocation("615_Forge_TEC_Checkpoint01", "ALL", 0x3E1B0044, 0xCDA51308);
AddLocation("710_CorridorT09A_TEC_CheckpointV01_04", "ALL", 0x64EF003B, 0x6E480011);
AddLocation("710_CorridorT09A_TEC_SavePoint_Ftn01", "ALL", 0x812C013B, 0x6E480011);
AddLocation("710_MainRoom_TEC_CheckpointV01_02", "ALL", 0x65FE003B, 0x07B2013B);
AddLocation("710_MainRoom_TEC_CheckpointV02_02", "ALL", 0xFE22023B, 0x12B2013B);
AddLocation("710_MainRoom_TEC_CheckpointV03_02", "ALL", 0x0123023B, 0x14B2013B);
AddLocation("710_WARPGATE_715_TEC_SCT_Savepoint01@Sct_Checkpoint01", "ALL", 0xAA930011, 0x7B510011);
AddLocation("710_WARPGATE_THRONE_TEC_SCT_Savepoint01", "ALL", 0x75850011, 0x5E510011);
AddLocation("715_CorridorT09A_TEC_SavePoint_Ftn01", "ALL", 0xAF32013B, 0xCF490011);
AddLocation("715_MainRoom_TEC_Checkpointv01_02", "ALL", 0x54E5003B, 0xD6490011);
AddLocation("715_MainRoom_TEC_TmpCheckpoint03_v01@Sct_Checkpoint01", "ALL", 0x5EE5003B, 0xD6490011);
AddLocation("715_WARPGATE_TEC_SCT_Savepoint01@Sct_Checkpoint01", "ALL", 0xB9930011, 0x79510011);
AddLocation("805_Hallway02_SCT_Checkpoint@Sct_Checkpoint01", "PSP", 0x4A02009C, 0x7B00009C);
AddLocation("805_Hallway04_SCT_Checkpoint", "PSP", 0x4E02009C, 0x7F00009C);
AddLocation("805_Hallway04_TEC_SavePoint", "PSP", 0x092E009C, 0x7F00009C);
AddLocation("GGT_ExitHall_SCT_Checkpoint", "PSP", 0x990300F9, 0x8F03009B);
AddLocation("GGT_PW_Top_Checkpoint_01@Sct_Checkpoint01", "PSP", 0x7C160093, 0x7103009B);
AddLocation("GGT_PW_TOP_SCT_Checkpoint_Easy_01", "PSP", 0x67DD019C, 0x7103009B);
AddLocation("GGT_PW_TOP_SCT_Checkpoint_Easy_02", "PSP", 0x6ADD019C, 0x7103009B);
AddLocation("GGT_River_B_Checkpoint_01@Sct_Checkpoint01", "PSP", 0x85160093, 0x3504009B);
AddLocation("GGT_River_B_SCT_Checkpoint_Easy_01", "PSP", 0x73DD019C, 0x3504009B);
AddLocation("GGT_River_B_SCT_Checkpoint_Easy_02", "PSP", 0x76DD019C, 0x3504009B);
AddLocation("GGT_River_B_SCT_Checkpoint_Easy_03", "PSP", 0x79DD019C, 0x3504009B);
AddLocation("GGT_River_B_SCT_Checkpoint_Easy_04", "PSP", 0x7CDD019C, 0x3504009B);
AddLocation("GGT_StartHall_Checkpoint", "PSP", 0x342B009C, 0x7303009B);
AddLocation("MGT_Hub_TestStartpoint@Sct_Checkpoint01", "PSP", 0xC100009C, 0x7B090097);
AddLocation("MGT_Levers_Test_Startpoint@Sct_Checkpoint01", "PSP", 0x9601009C, 0x7C090097);
AddLocation("MGT_Passage_Main_Checkpoint_Easy_01", "PSP", 0xD10D0096, 0xB7000095);
//AddLocation("MGT_Passage_Main_Checkpoint_Easy_02", "PSP", 0xD50D0096, 0xB7000095); //NOT WORKING?
AddLocation("MGT_SCT_Checkpoint_Easy_01", "PSP", 0xDE0D0096, 0x7F090097);
AddLocation("MGT_SCT_Checkpoint_Easy_02", "PSP", 0xE20D0096, 0x7F090097);
AddLocation("TGT_Court_SCT_Checkpoint_01", "PSP", 0xC40D0096, 0x6101009C);
AddLocation("TGT_Court_SCT_Checkpoint@Sct_Checkpoint01", "PSP", 0x1412009C, 0x6101009C);
AddLocation("TGT_CourtEntrance_Checkpoint_Easy_01", "PSP", 0xBB0D0096, 0x7920009C);
AddLocation("TGT_CourtExit_Checkpoint_Easy_01", "PSP", 0xC70D0096, 0x7720009C);
//AddLocation("TGT_CourtToBalcony_Checkpoint_Easy_01", "PSP", 0xBE0D0096, 0xBF02009C); //NOT WORKING?
AddLocation("TGT_CourtToBalcony_SCT_Checkpoint@Sct_Checkpoint01", "PSP", 0x3C12009C, 0xBF02009C);
AddLocation("TGT_ExitSToCourt_SCT_Checkpoint@Sct_Checkpoint01", "PSP", 0x4A12009C, 0x9304009C);
AddLocation("TGT_TowerRoom02_SCT_Checkpoint@Sct_Checkpoint01", "PSP", 0x4012009C, 0xC402009C);

AddLocation("010_Deck_TEC_StoryGate01", "ALL", 0x7A27082B, 0x4B96074D);
AddLocation("020_Beach_TEC_StoryGate01", "ALL", 0x4828082B, 0x0328082B);
AddLocation("020_PassageTo040_TEC_StoryGateV02", "ALL", 0x3DC40033, 0x0728082B);
AddLocation("035_Cliff_TEC_StoryGateV01", "ALL", 0xCEAC1308, 0x28AC1308);
AddLocation("040_couloirTo070_TEC_StoryGateV02", "ALL", 0x5BC40033, 0xA6FE1208);
AddLocation("040_cWARPT01A_TEC_StoryGateV03", "ALL", 0x54C40033, 0xA8FE1208);
AddLocation("040_hall_TEC_StoryGateV01", "ALL", 0x32FF1208, 0xB0FE1208);
AddLocation("045_cWARPT01_TEC_StoryGateV01", "ALL", 0xDE021308, 0xD0021308);
AddLocation("045_cWARPT01_TEC_StoryGateV02", "ALL", 0xA9C80033, 0xD0021308);
AddLocation("045_ExitTo035_TEC_StoryGateV04", "ALL", 0xC3C80033, 0x84971308);
AddLocation("045_Hall_TEC_StoryGate_V03", "ALL", 0xBFC80033, 0xD7021308);
AddLocation("055_AccessRoom_TEC_StoryGateV01", "ALL", 0xE30E0004, 0x4E0E0004);
AddLocation("055_AccessRoom_TEC_StoryGateV03", "ALL", 0x06C40033, 0x4E0E0004);
AddLocation("055_AccessRoom_TEC_StoryGateV02", "ALL", 0x09C40033, 0x4E0E0004);
AddLocation("055_AccessRoom_TEC_StoryGateV04", "ALL", 0x0DC40033, 0x4E0E0004);
AddLocation("055_AccessRoom_TEC_StoryGateV07", "ALL", 0x10C40033, 0x4E0E0004);
AddLocation("055_AccessRoom_TEC_StoryGateV06", "ALL", 0x13C40033, 0x4E0E0004);
AddLocation("055_AccessRoom_TEC_StoryGateV09", "ALL", 0x17C40033, 0x4E0E0004);
AddLocation("055_AccessRoom_TEC_StoryGateV05", "ALL", 0x1AC40033, 0x4E0E0004);
AddLocation("055_AccessRoom_TEC_StoryGateV08", "ALL", 0x20C40033, 0x4E0E0004);
AddLocation("055_LinkTo205B_TEC_StoryGateV10", "ALL", 0x1DC40033, 0x80290029);
AddLocation("065_ExitTo055_TEC_StoryGateV02", "ALL", 0xFBC90033, 0x2B17013C);
AddLocation("065_ExitTo055_TEC_StoryGateV03", "ALL", 0xFEC90033, 0x2B17013C);
AddLocation("065_ExitTo055_TEC_StoryGateV04", "ALL", 0x01CA0033, 0x2B17013C);
AddLocation("065_ExitTo055_TEC_StoryGateV05", "ALL", 0x04CA0033, 0x2B17013C);
AddLocation("065_ExitTo055_TEC_StoryGateV01", "ALL", 0xD017013C, 0x2B17013C);
AddLocation("070_Corridor330B_TEC_StoryGateV02", "ALL", 0xA2C80033, 0x1C12003B);
AddLocation("070_CorridorT02B_TEC_StoryGateV01", "ALL", 0xD212003B, 0x2412003B);
AddLocation("075_MainRoom_TEC_StoryGateV01", "ALL", 0x8312003B, 0x3012003B);
AddLocation("085_Linker2WarpC_TEC_StoryGateV02", "ALL", 0x88C80033, 0x34470011);
AddLocation("085_LinkerTo075_TEC_StoryGate_V01", "ALL", 0x40320011, 0x89310011);
AddLocation("100_ExitTo120_TEC_StoryGateV02", "ALL", 0x54C90033, 0xB6941308);
AddLocation("100_ToWarpT05_TEC_StoryGateV01", "ALL", 0xE5941308, 0xBA941308);
AddLocation("100_ToWarpT06_TEC_StoryGateV03", "ALL", 0x58C90033, 0xBC941308);
AddLocation("105_ExitTo115_B_TEC_StoryGateV02", "ALL", 0x2DC80033, 0x81D31308);
AddLocation("105_Hall_TEC_StoryGateV04", "ALL", 0x38C80033, 0xB97D1308);
AddLocation("105_Hall_TEC_StoryGateV05", "ALL", 0x3CC80033, 0xB97D1308);
AddLocation("105_JonctionTo055_TEC_StoryGate01", "ALL", 0x607E1308, 0xBB7D1308);
AddLocation("105_JonctionTo055_TEC_StoryGateV06", "ALL", 0x2AC80033, 0xBB7D1308);
AddLocation("105_ToWarpT06_TEC_StoryGateV03", "ALL", 0x34C80033, 0xC17D1308);
AddLocation("110_CorrTo120_SCT_StoryGateV01", "ALL", 0xE72C0029, 0x6AD7003C);
AddLocation("110_LoadingBalcony_TEC_StoryGateV01", "ALL", 0xECD7003C, 0x66D7003C);
AddLocation("115_LoadingBalcony_TEC_StoryGateV01", "ALL", 0x6DC6003C, 0x5DC5003C);
AddLocation("115_LowerGarden_TEC_StoryGate_Goal01", "ALL", 0xF8C90033, 0x5FC5003C);
AddLocation("125_VegGoal_TEC_StoryGateV01", "ALL", 0xDB2B0029, 0xB62B0029);
AddLocation("125_VegGoal_TEC_StoryGateV02", "ALL", 0x0DC90033, 0xB62B0029);
AddLocation("205_Bridge_TEC_StoryGateV01", "ALL", 0xB92A0029, 0x80290029);
AddLocation("205_JctTo215_TEC_StoryGateV04", "ALL", 0xCEC80033, 0x5E2A0029);
AddLocation("205_JctTo235_TEC_StoryGateV02", "ALL", 0xD2C80033, 0x5F2A0029);
AddLocation("205_JctTo425_TEC_StoryGateV03", "ALL", 0xCAC80033, 0x602A0029);
AddLocation("210_WarpExit_TEC_StoryGateV01", "ALL", 0x530B0004, 0xE70A0004);
AddLocation("215_ExitTo605_TEC_StoryGateV02", "ALL", 0x26C40033, 0xA8090004);
AddLocation("215_TowerMec1_TEC_StoryGateV01", "ALL", 0x570B0004, 0xA6090004);
AddLocation("235_WarpExit_TEC_StoryGate01", "ALL", 0xC35E0029, 0xF38E0004);
AddLocation("400_couloirBTo020_TEC_StoryGateV01", "ALL", 0x97051308, 0x3B051308);
AddLocation("410_ExitTo400_TEC_StoryGateV01", "ALL", 0x443C1308, 0xC93B1308);
AddLocation("415_ExitTo615_TEC_StoryGateV02", "ALL", 0xBDCA0033, 0xCDA51308);
AddLocation("415_ToWarpExit_TEC_StoryGateV01", "ALL", 0x60521308, 0x52CA0001);
AddLocation("425_ExitTo415_TEC_StoryGateV01", "ALL", 0x7A1F0004, 0x101F0004);
AddLocation("425_ExitTo415_TEC_StoryGateV02", "ALL", 0xEFC80033, 0x101F0004);
AddLocation("605_Bridge_TEC_StoryGateV01", "ALL", 0xDF000023, 0x26030023);
AddLocation("615_Forge_TEC_StoryGateV01", "ALL", 0x4F0A0044, 0xCDA51308);
AddLocation("710_CorridorT08B_TEC_StoryGateV02", "ALL", 0x9EC90033, 0x6C480011);
AddLocation("710_CorridorT08B_TEC_StoryGateV01", "ALL", 0xB856003B, 0x6C480011);
AddLocation("710_CorridorT08B_TEC_StoryGateV03", "ALL", 0xB641013B, 0x6C480011);
AddLocation("715_CorridorT09C_TEC_StoryGateV01", "ALL", 0x4956003B, 0xD3490011);


По данным - название, тип (WW или Revelations для PSP), checkpointID, locationID. Значения здесь записаны в обратном порядке, т.е. для их поиска в памяти на примере
AddLocation("010_Deck_TEC_StoryGate01", "ALL", 0x7A27082B, 0x4B96074D);
меняем значения на 0x2B08277A и 0x4D07964B.

Всё это есть в обновлённом редакторе - Timeline 2, поддержка сейвов Revelations там есть тоже.

rl_evader
29.08.2019, 16:20
BlackDaemon, спасибо за ответ. Вчера протестировал timeline2 на пк версии принца и составил гугл-табличку (https://docs.google.com/spreadsheets/d/1hGh3AKeL_Fg0nHB-E-c7a694zqKr8H_dGiblzonbcWQ/edit?usp=sharing) со скринами местоположения всех сторигейтов, не знал что прога работает и с сейвами от псп-шного принца. Надо будет сделать аналогичную таблицу с местоположением сторигейтов в псп-версии, хотя судя потому что ты написал их положение одинаково для пк и псп версии. Скорее всего манипуляции со сторигейтами, которые применяются в спидране пк-версии принца, не работают на псп-версии или работают но не стабильно (получилось же каким то образом заспаунить эту кнопку (https://youtu.be/57rjyvHDjO8?t=43)).

BlackDaemon
29.08.2019, 16:27
rl_evader, возможно из-за дополнительных локаций как-то изменили порядок подгрузки/выгружения уровней, но это чисто "мысли вслух".

rl_evader
29.08.2019, 20:02
BlackDaemon, после нескольких часов танцев с бубном в тронном зале получилось снова вызвать этот (https://imgur.com/iS7vnoQ) баг, но на этот раз у меня даже остались сохранения (https://drive.google.com/open?id=1U16ssC-iix7Xa_0x719YF3FU2YRot5c6)(один сейв в мейнхолле, второй сейв прямо возле кнопки). Кнопка заспаунена в воздухе, поэтому чтобы нажать на нее надо свеситься с уступа и залезть обратно. К сожалению я так и не смог выцепить значение сторигейта в чит энжине, но я предполагаю что после манипуляций в тронном зале в этом (https://imgur.com/UxPCCpg) месте спаунится один из сторигейтов, который является причиной того что локация загружается вместе с кнопкой.

JakeMiles
19.04.2020, 15:18
BlackDaemon поддерживают ли твои утилиты, PS2 версию? А то пытался достать модельки из PS2 версии (SOT), с помощью твоих утилит и persian rug, BF Repacker вроде как достает файлы без каких либо проблем, persian rug при попытке извлечь 3Д меш, ругается на "Range check error", плагин для blender (io_scene_pop (https://github.com/kugelrund/io_scene_pop)) так же падает с ошибкой при попытке открыть bin файлы, там тоже ошибка касательно кол-ва байтов либо не возможность разобрать формат текстуры, но текстуры это последнее что мне интересно, больше всего хотелось бы достать 3Д меш из версии PS2.

BlackDaemon
20.04.2020, 08:18
JakeMiles, в текущей публичной версии - нет. В PS2 заголовок текстур длиннее - 180 байт (192, если учитывать с +12 служебными), к тому же там применяется свиззлинг текстур. Насчёт мешей не знаю, ибо до их разбора пока дело не дошло.

ЗЫ: я писал Sphere (автору io_scene_pop) насчёт PS2/PSP текстур, но у него желания допиливать скрипт нет, только если кто-то допилит и сделает pull-request :crazy:

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 я нашёл рабочий код на просторах сети - отсюда (https://gta.nick7.com/ps2/swizzling/), собственно взял c# декодер и недостающие массивы здесь (https://github.com/neko68k/FusionTool/blob/master/SubaSwizzle/PS2Textures.cpp). Немного переделал для удобства. По скрипту на питоне, к сожалению, пока ничем не могу помочь - не знаком с питоном, и на текущий момент понимаю только некоторые его части. Текстуры стандартно 8bit paletted, применяешь unSwizzle перед тем как его декодировать по палитре.

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/13eJfse9VLohU5FPuUAG1RTBLW0zXFpes/view?usp=sharing

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

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