История русской локализации Tales of Rebirth (PS2). Глава 5. Разбор дополнительных файлов и начало работы с оверлеями
Пока Рейнджер был занят написанием кода по моему заказу, я искал остальные не найденные тексты, которые относились преимущественно к части игрового меню (хроника, различные описания, руководство, названия предметов и врагов, открытия, магазины и многое другое). Таким образом, через просмотр оперативной памяти эмулятора во время игрового процесса я обнаружил текст в следующих файлах:
а) 11190.bin – хроника (краткое описание всех событий игры).
б) 11181.pak3 – меню (заголовки, кнопки, настройки и многое другое).
в) 00013.pak3 – различный текст, который отображается в сражениях (в том числе и диалоги, которые появляются на движке боевой системы).
г) 11217.bin – энциклопедия (описания врагов, руководство и история сражений).
д) SLPS_254.50 – заголовки, кнопки, имена, названия и описания (сценки, враги, тактика, скрытые характеристики, приёмы, предметы, сплавка, рецепты, титулы, открытия и локации), а также другие различные тексты, которые не используются в игровом процессе.
По мере того, как RangerRus обновлял приложение ToR toolkit, я подкидывал ему вышеперечисленные файлы, которые тоже просил разобрать. С 11190.bin особо проблем не было, так как это самый обычный текстовик: в головной части находятся поинтеры, а всё, что ниже – это склейка строк с разделителем {00} между ними.
Перед тем как приступить к описанию следующих файлов, нужно рассказать об отдельных особенных файлах, которые частенько встречаются в нашем деле фанатских локализаций. Речь пойдёт об оверлеях (overlays). Чтобы получше объяснить, что это и для чего, пожалуй, стоит немного рассказать о характеристиках консолей старого поколения. PS1 на борту имела 2 МБ оперативной памяти и 1 МБ видеопамяти, а уже более старший брат PS2 обладал 32 МБ и 4 МБ видеопамяти. В рабочем режиме консоли сначала загружают данные в оперативную память. Для разного рода игр PlayStation 1-2 этого могло хватать, но для более сложных этого было уже недостаточно. Поэтому в качестве решения была придумана система разделениях одной программы на отдельные сегменты (оверлеи), где каждая часть является отдельным файлом. Во время игрового процесса, по мере необходимости, главный исполняемый файл может подгружать и выгружать нужные оверлеи. К примеру, если вы исследуете какую-то локацию в игре, то в оперативной памяти находится главный исполняемый файл и составляющие, а как только вы вступаете в битву, то система будет выгружать часть ненужных данных и подгружать оверлей, отвечающий за все скрипты, которые необходимы в этой части игрового процесса.
Именно таким типом файлов и является 11217.bin. Этот файл служит запуском и просмотром всей энциклопедии. Соответственно, среди всех этих данных оверлея и лежит текст описаний врагов, всего руководства и историй сражений. В первой 1/5 части файла находится основной код, а чуть ниже – поинтеры, которые записаны не прямыми указателями к строкам, а с учётом расположения этого файла в оперативной памяти консоли. Это означает, что для работы с этими поинтерами нужно высчитать разницу между фактическим расположением строк и расположением в оперативной памяти. Иногда эту разницу называют "поправкой". В нашем случае поправка для многих оверлеев в Tales of Rebirth (PS2) является числовым значением 2D8900. Высчитать эту разницу можно двумя способами. Первый способ для продвинутых пользователей, которые понимают, как работать с отладчиком эмулятора PCSX2. В тот момент я даже близко не понимал, что это за функционал и как к нему подступиться. Поэтому пришлось пойти по более простому пути. Второй способ заключается в том, что, зная месторасположение поинтеров и области текста, вы запоминаете смещение первого символа из области текста, а потом ищете поинтер с наименьшим значением адреса из всего набора поинтеров. Затем берём значение наименьшего поинтера и вычитаем из него значение фактического адреса первого символа из области текста. В итоге мы получаем число, которое и будет являться той самой поправкой.
Внимание!!! Иногда с помощью второго способа высчитывания вы можете сразу не найти корректное число поправки. Если так случилось, то вам, скорее всего, попалась ситуация с расположением строк в обратно порядке. Это когда строки в файле располагаются от последнего к первому. В таком случае вам нужно начать поиски не сверху вниз, а с самого низа к верху. Если даже в этом случае вам не улыбнулась удача, то, скорее всего, вы столкнулись с ситуацией, когда строки в области текста не идут по старшинству от меньшего к большему и наоборот, а просто имеют хаотичный порядок. В этом случае корректное высчитывание поправки может затянуться на очень долгое время. Тогда больше ничего не остаётся, кроме как методом тыка пробовать вычитать значения в произвольном порядке.
Это далеко не всё, что следует рассказать об этом типе файлов. На приведённом изображении выше я наглядно показал, что помимо основных областей, в хвосте файла есть область с дополнительным кодом и условно пустая область, заполненная нулевыми значениями. Работать обычным образом с такой структурой не представляется возможным и, разумеется, это накладывает множество ограничений. В первую очередь нужно сразу понять, что ничего лишнего стирать в оверлеях нельзя. Потому что это код, который в процессе работы может что-то переписывать среди своих данных. Именно поэтому пустую область исполняемых файлов использовать так просто нельзя, потому что если вы всё же попытаетесь записать туда какие-то данные, то вы рискуете нарушить обычный порядок вещей, который был задуман разработчикам. В самом худшем случае это может привести к зависаниям и вылетам, либо просто повлечёт за собой удаление текста во время игрового процесса. Без понимания принципа работы системы не так уж просто найти причину пропадания текста. Именно поэтому в пустые области оверлеев нельзя размещать любые данные. Следующее ограничение вытекает из принципа самого устройства оверлеев. Раз уж мы не можем ничего прописывать в пустые области, то не можем и увеличивать в размерах сам файл. Так как запись оверлея в оперативную память жёстко привязана к определённому смещению, а значит, после записи этого файла в оперативную память следуют какие-то другие не менее важные данные. Область работы исполняемого файла и оверлеев – это особая область работы с кодом в оперативной памяти на консоли, в которой слишком узкие рамки. Это не тот тип файлов, которые можно спокойно расширять (как, например, файлы с диалогами). Следовательно, мы подходим к тому, что записывать новые данные мы можем только в ограниченную область текста оверлея. В нашем случае у файла 11217.bin это диапазон: 6B70 – 134FE. Когда мы только начинали работать с текстом этого файла, я даже и не подозревал, что нам не хватит места на весь объём переведённого текста. В демонстрационных релизах локализации мне приходилось сокращать часть строк, чтобы текст умещался. Но это не было решением проблемы. Потому что сокращать приходилось очень много. Впоследствии эту проблему нам помог решить программист Ethanol, которому пришлось переписать приличную часть кода игры, чтобы чтение половины текста происходило не из оверлея, а совсем из другого места, но об этом я расскажу гораздо позже в другой главе, когда дело дойдёт до описания реверс-инжиниринга. В итоге на тот момент я попросил Рейнджера написать алгоритм, который высчитывает количество знаков переведённого текста. Если общее значение превышает число под отведённое пространство в оверлее, то программа об этом уведомляет. Таким образом это было лишь временное решение, чтобы уже можно было проверять изменения в игре.
Следующие файлы 11181.pak3 и 00013.pak3 оказались ещё одним типом контейнеров. Внутри 11181.pak3 находился такой же обычный бинарный файл с текстом, как и описанный мной выше 11190.bin. В контейнере он шестой по счёту. Здесь располагался текст отдельной части меню (заголовки, кнопки, настройки и многое другое). Я попросил Рейнджера сделать распаковку и запаковку текста без работы с самими контейнером по отдельности. А вот описанию контейнера 00013.pak3 уделю побольше внимания. Внутри находятся три оверлея, которые подгружаются во время сражений. Последний из них содержит нужный нам текст для перевода. Структура этого файла выглядит примерно так:
- Основной код (~80%)
- Поинтеры
- Дополнительная область с кодом
- Поинтеры
- Дополнительная область с кодом
- Поинтеры
- Дополнительная область с кодом
- Область текста
- Дополнительная область с кодом
- Область текста
- Поинтеры
- Дополнительная область с кодом
- Область текста
- Дополнительная область с кодом
- Поинтеры
- Дополнительная область с кодом
- Пустая область (~10%)
Как видите, здесь очень много областей разного типа, распределённых на части. Тем не менее с этим файлом мы справились, и проблем он нам особо не доставил, потому что огромная часть текста этого файла используется только в режиме отладки (debug mode) для нужд разработчиков. Часть строк я спокойно сокращал, чтобы уместился весь наш перевод. Это можно делать без проблем, потому что большая часть функционала режима отладки из кода Tales of Rebirth была удалена, в отличие от других игр серии, например, Tales of Eternia и Tales of Phantasia. И поэтому в этой игре он вообще никак не задействуется. Но мы ещё вернёмся к этому файлу и остальным оверлеям в 00013.pak3, так как здесь тоже придётся проделать некоторые манипуляции во время реверс-инжиниринга. Ведь этот оверлей содержит в себе определённые ограничения, с которыми я столкнусь чуть позже, и это будет очень сильно мешать созданию качественной локализации этой игры.
Что же касается всех остальных текстов игрового меню, которые находились в исполняемом файле SLPS_254.50, то RangerRus не захотел связываться с поиском всех поинтеров этого файла, объяснив это тем, что поиск будет слишком проблемным и долгим. Поэтому он предложил сделать так: выписать начало и конец всех смещений с полезным текстом; сделать их извлечение и обратную упаковку. Разумеется, я отказался, так это автоматически накладывало бы слишком жёсткое ограничение по количеству символов на 1 строку. Работать без изменения поинтеров – ужасная затея. Представьте себе ситуацию, когда для одной строки выделено 3 байта, а слово в этой строке "Axe". Без изменения поинтеров мы можем уместить только 3 символа на русском языке. А теперь помножьте это на 100, 1000 и более случаев с разного рода уникальных ситуаций. Вот примерно о таком хаосе и идёт речь, если пытаться переводить текст игры без изменения поинтеров.
Об этой проблеме того времени и как она решалась я расскажу в следующей главе. Ведь в конце концов нам всё же удастся дотянуться до всего и изменить почти всё, что будет нужно для локализации.
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Страница русской локализации Tales of Rebirth:
https://temple-tales.ru/translations_torps2.html
⭐ Наше основное сообщество по переводам ВКонтакте:
https://vk.com/temple_of_tales_translations
✨ Наше сообщество по конкурсам ВКонтакте:
https://vk.com/temple_of_tales_quiz
🎵 Наше музыкальное сообщество ВКонтакте:
https://vk.com/temple_of_tales_music
Наш телеграм-канал:
https://t.me/temple_tales
Наш Discord:
https://discord.gg/hsbhqPyCW2
Наш YouTube канал:
https://www.youtube.com/@temple-tales