Словарная система (MTE/DTE)
Автор Guyver   
10.05.2008 г.

СЛОВАРНАЯ СИСТЕМА MTE/DTE (автор: alex_231)

Что же такое MTE?

МТЕ
– система кодирования, в которой несколько значимых символов кодируются одним байтом (реже – двумя). В состав МТЕ входят (если можно так выразиться): словарь, содержащий комбинации кодируемых символов и, собственно, таблица кодов МТЕ.

Так как же искать словарь и таблицу?
Начнём с таблицы.

В начале нам нужно найти хоть какой-нибудь текст из игры, в котором используется оптимизация, это довольно сложно, потому как слова обычно «разорваны» в самых непредсказуемых местах, но всё же, это возможно (в крайнем случае, можно воспользоваться корруптором).

Предположим, текст найден (желательно, чтобы текст этот был как можно ближе к началу игры), теперь начинается «метод народного тыка»:

явный символ текста заменяется неиспользуемым (в таблице шрифта) кодом, затем запускается игра и в месте, где должен был быть символ, выводится значение неиспользуемого кода, его нужно запомнить или записать (лучше всего в формате стандартной таблицы), затем этот код увеличивается или уменьшается (по желанию) на 1 и снова проверяется результат. Так можно найти всю таблицу МТЕ, но это довольно долго. После трёх-четырёх удачных попыток можно выбрать самое длинное «слово» и попробовать найти его в РОМ-е хекс-редактором. Если «слово» найдено, а рядом с ним видны остальные (полученные перебором) «слова», то словарь у нас в кармане, осталось только разобраться, в каком виде он хранится в РОМ-е и можно дописывать таблицу МТЕ.

Теперь словарь.


Словарь может храниться в виде:

- строки текста, не имеющей никаких видимых разделителей;
- строк, разделённых спец. символами;
- строк, имеющих поинтеры (указатели).

Первый вариант предполагает наличие в роме таблицы длин «слов» словаря (в случае, когда длина не является постоянной), её можно найти в хекс-редакторе, следующим образом:

1) берутся 3-4 «слова», идущих подряд (например, «кот», «ёж», «слон» и «дверь»)
2) высчитываются их длины (3, 2, 4, 5)
3) ищется последовательность байт длин (03020405)
если искомая последовательность не найдена, можно попробовать найти другим способом, исходя из предположения, что длина «слов» не превышает 15 символов: ищется прямая последовательность длин (3245).

Второй вариант – самый простой, можно смело менять длину «слов» в словаре, не выходя за границы словаря.

Третий вариант – тоже не очень сложен, но здесь кроме самих «слов» нужно учитывать поинтеры. Так же прямо в словаре может быть указана длина «слов», что намного облегчает работу.

После того как найден словарь, составить по нему таблицу не составит особого труда.

DTE – частный случай МТЕ, когда длина ВСЕХ слов в словаре равна двум, и не может быть изменена.

А теперь немного практики.

Под рукой у меня есть только РОМ Chrono_Trigger_(U)_[!].smc, поэтому покажу на его примере один из вариантов МТЕ.

Коды для таблицы шрифта можно вычислить в любом тайловом редакторе, поддерживающем формат 2bpp planar (gameboy). Для этого достаточно перейти на адрес h3F8E60. Скажу только, что коды символов начинаются с кода hA0. (Вообще-то там два шрифта, но, поскольку, в игре есть элементы изображаемые обоими шрифтами, коды шрифта диалогов совпадают с кодами указанного шрифта.)

Таблица шрифта есть, загружаем РОМ в хекс-редактор (я использую Translhextion) и применяем таблицу.
Теперь ищем текст. Как? Руками и глазами естественно, но можно попробовать искать, используя таблицу (Alt+F), хотя такой вариант не всегда помогает.

Для нашего РОМ-а можно попробовать найти слово «Guardia» из названий локаций. Оно находится по адресу h6F273. Визуально мы можем определить, что этот блок начинается с адреса h6F200. Теперь выбираем жертву: слово «Guardia» встречается дважды, но в первом случае в словосочетании «Guardia F{38}{3F}t», а во втором – в «Guardia C{61}tle». Скорее всего, :-) это - «Guardia Forest» и «Guardia Castle» соответственно. Из этого следует, что коды h38=or, h3F=es и h61=as. Но этого мало, попробуем подставить вместо буквы «G» в «Guardia» в первом случае (так как до леса ближе идти, чем до замка) коды h3E, h40 и h41 по очереди и проверить результат с каждым из них. У нас получилось:

h3E=ere
h40=thi
h41=e th

Теперь можно попробовать найти саму таблицу:

Используя таблицу, ищем «e th», так как это «слово» вряд ли будет встречаться в РОМ-е в явном виде (вне таблицы). С первого раза находим искомую комбинацию, но что это, слово не заканчивается символом «h», и имеет вид «e the», а вот дальше (после кода h04) идёт уже наше «слово». (Для верности можете проверить весь РОМ на наличие этого «слова», но кроме этих двух вам не удастся ничего найти.)
Поздравляю, словарь найден.

«Но он не соответствует порядку кодов» - скажете вы. Да, но об этом далее.

Разберём формат словаря.

Если посмотреть на найденное «слово», то видно, что перед ним стоит код h04 и длина слова – тоже 4, посмотрим предыдущее слово «e the», перед ним стоит код h05. Да предположение подтвердилось – в словаре указана длина «слов».

Но как же быть с порядком кодов?
Посмотрим, где начинается словарь:

h1FD00 – {04}your
А выше этого адреса находится странная структура, в которой на нечетных адресах стоят коды hFB и hFC (забегая вперёд, скажу, что это – таблица поинтеров для словаря). Структура эта начинается с адреса h1EFC00 байтами {4A}{FB} проверим, а вдруг это – поинтеры.

Запишем число hFB4A, прибавим хедер (h200), получаем hFD4A, смотрим, что находится по этому адресу: {03}the – трёхбуквенное слово (первое в таблице) в соответствии с кодом длины. Так и есть, это – таблица поинтеров.

Как же узнать коды «слов»?
Теперь подсчитаем количество «слов» в словаре: оно равно количеству поинтеров в таблице, выделим таблицу поинтеров, получилось 256 байт, делим на 2, получаем 128 поинтеров и «слов».

Здесь нужно сказать, что коды словаря соответствуют порядку поинтеров в таблице.

Наименьший код, который нам известен – {38} = or, ищем в таблице «слово» {02}or. Оно находится по адресу h1EFDB0, считаем поинтер: hFDB0-h200=hFBB0 => {B0}{FB}, ищем в таблице, находим по адресу h1EFC2E. Выделяем весь диапазон от начала таблицы до найденного поинтера (его не выделяем), получаем 46 байт, или 23 поинтера, отнимаем h17 от h38 (23=h17), получаем h21, это и есть код «слова» по первому поинтеру. Таким образом:

h21=the

А дальнейшее – дело техники, сопоставить коды с поинтерами и по поинтерам выписать «слова» не вызовет особых трудностей.

Желаю удачи, надеюсь, этот документ хоть кому-нибудь поможет.
Последнее обновление ( 26.01.2010 г. )