Описание: АРХИВНАЯ ТЕМА 2005 года |
Поиск в теме | Версия для печати |
alex_231 |
Отправлено: 10 Февраля, 2016 - 07:48:08
|
Chief-Net
Покинул форум
Сообщений всего: 4688
Дата рег-ции: Окт. 2014
|
alex_231
Цитата:...а как вы например приходите к выводу - что и как в игре пожато... Как находите алгоритм сжатия или в словарной системе как разбираетесь - какой там алгоритм - я вот беру игру - и не могу определить, что да как в ней пожато или как слова из словаря вызываются в игре (?)... Что делать - какой план работ должет быть, этапы так сказать поиска решений...
Для каждой игры по своему, но нужно знание ассемблера, или наличие программиста (со знанием ассемблера)
А для поиска словаря и работы с ним где-то я видел доку, по-моему на мэджиктиме.
Как игра называется, которую ты переводишь?
Может чем помогу, всё равно пока перевожу тексты, дома делать практически нечего.
----- Делая выбор, отбрось простое решение и выбери правильное...
|
|
|
chiefexb |
Отправлено: 10 Февраля, 2016 - 07:48:56
|
Призрак
Покинул форум
Сообщений всего: 680
Дата рег-ции: Окт. 2014
|
chiefexb
Цитата:
У меня вот что в игре есть, пусть там например такой текст:
Вышел Ваня погулять
Чтоб врагам накостылять
Этот Ваня очень крут
Носит он с собою кнут
Так вот - я нахожу и перевожу без проблем следующее
--------- Ваня погулять
--------- накостылять
--------- очень крут
--------- собою кнут
надо смотреть РОМ в hex-редакторе как правило там будет подобное:
CODE:F601 Ваня погулять
F602 F603накостылять
F604 F605 очень крут
F606 F607 собою кнут
И ГДЕ ТО В РОМЕ ЕСТЬ ПОДОБНОЕ:
CODE:вышелFFчтобFFврагамFFэтотFFваняFFноситFFон
Это словарная система система как искать словарь: как правило словарь и текст закодированны одной кодировкой поискать слова "вышел", "чтоб", и т. д.
Я так нашел в Adventure in Magic kingdom
словарь.
Далее я начал переводить фразы заменяя слова словаря на нужные мне по тексту слова, но тут нужно знание поинтеров. Иначе толку от словарного сжатия. Я вбил в этот словарь много длинных слов и получил выгрыш в месте.
как вбивал текст:
в моем случае коду слова предшествовали байты f6(f7)проанализировав словарь и текст я пришел к выводу, что коды слова так и идут попарядку, т.е. не указатель на место в роме а просто первое, второе слово. А байт f6 -вывод слова с пробелом, f7-без пробела. и начал вбивать перевод в Gold finger.
|
|
|
alex_231 |
Отправлено: 10 Февраля, 2016 - 08:19:20
|
Chief-Net
Покинул форум
Сообщений всего: 4688
Дата рег-ции: Окт. 2014
|
alex_231
Да, товарищи, решил вынести на всеобщее обозрение вопрос темы:
на восьмибитных консолях, я лично, кроме пресловутого RLE-сжатия никакого другого алгоритма не видел, только на Sega Master System оно немного посложнее, а на NES вообще - проще пареной репы.
P.S.: по желанию, могу описать оба алгоритма, спрашивайте, если кому надо.
----- Делая выбор, отбрось простое решение и выбери правильное...
|
|
|
alex_231 |
Отправлено: 10 Февраля, 2016 - 08:20:41
|
Chief-Net
Покинул форум
Сообщений всего: 4688
Дата рег-ции: Окт. 2014
|
alex_231
Да, я видел текст в Dragon Warrior 2, даже нашел, где находятся запакованные тексты (но не записал и пока не полностью разобрался в коде).
Bee 52(U).nes - говорите, погляжу.
DTE алгоритм довольно прост, у меня в скриптере для Chrono Trigger используется алгоритм MTE (что по сути одно и то же, то есть закодировав MTE, можно не кодировать DTE).
С собой нет, но показать могу (попозже).
----- Делая выбор, отбрось простое решение и выбери правильное...
|
|
|
alex_231 |
Отправлено: 10 Февраля, 2016 - 09:39:55
|
Chief-Net
Покинул форум
Сообщений всего: 4688
Дата рег-ции: Окт. 2014
|
alex_231
Нет, там хранится таблица MTE, а текст в районе $14C00
Извлечение:
CODE://Названия домов
memo2.Lines.add('{Названия домов}');
label6.caption:='Извлечение Названия домов';
refresh;
dialogpoint:=456194; //адрес первого поинтера (не используется,так на всякий случай)
dicbuf:=1; //номер буфера (чисто для ориентации)
dicrow:=7; //номер таблицы в буфере
diccol:=62978; //адрес поинтера в таблице (в буфере)
decpoint:=(ord(buf1[dicrow,diccol+2])+2)*256+ord(buf1[dicrow,diccol+1])+1; //адрес начала текста в таблице (в буфере)
s:=''; //обнуление строки
for i:=1 to 111 do begin // всего 111 сообщений в блоке
progressbar1.position:=progressbar1.position+1;
s:=buf1[dicrow,decpoint]; //ну это так для страховки
st:=''; //обнуление подстроки
while ord(s[1])<>0 do begin
s:=buf1[dicrow,decpoint];
if ord(s[1])<160 then st:=st+dictionary[ord(s[1])] else //dictionary - таблица MTE (от 0 до 159, в соответствии с кодами)
st:=st+coder(s); //coder - функция применения таблицы кодировки (перевод в английский)
inc(decpoint,1);
end;
decpoint:=(ord(buf1[dicrow,diccol+2+(2*i)])+2)*256+ord(buf1[dicrow,diccol+1+(2*i)])+1; //вычисляется адрес для следующего сообщения
memo2.Lines.add(st);
end;
Возвращение:
CODE:full:
msgscount:=1; //счетчик сообщений
setlength(msgs,msgscount); //msgs - массив встречавшихся ранее сообщений
case dicbuf of //dicbuf - номер буфера
1: decpoint:=(ord(buf1[dicrow,diccol+2])+2)*256+ord(buf1[dicrow,diccol+1])+1; //адрес (глобальный) первого сообщения для первого буфера (он остается тот же, что и раньше)
...
8: decpoint:=(ord(buf8[dicrow,diccol+2])+2)*256+ord(buf8[dicrow,diccol+1])+1; //адрес (глобальный) первого сообщения для восьмого буфера (он остается тот же, что и раньше)
end;
n:=0; //локальный индикатор использования таблицы MTE, используется ниже (должен быть Boolean, но как-то я об этом тогда не подумал)
fullbeg:
case dicbuf of
1:buf1[dicrow,diccol+1]:=chr((decpoint-1)mod 256); //записывается старший байт поинтера
.
.
8:buf8[dicrow,diccol+1]:=chr((decpoint-1)mod 256);
end;
case dicbuf of
1:buf1[dicrow,diccol+2]:=chr(trunc(((decpoint-1)/256)-2)); //записывается младший байт поинтера
.
.
8:buf8[dicrow,diccol+2]:=chr(trunc(((decpoint-1)/256)-2));
end;
if memo3.lines.strings[rowcount]<>'' then begin //если строка в memo не пустая, то начинается обработка
msgsind:=0; //локальный индикатор повторяющегося сообщения
for i:=1 to msgscount do begin
if (msgsind=0)and(memo3.lines.strings[rowcount]=msgs[i-1]) then begin
msint:=i; //номер уже использованного сообщения, которое вводится повторно
case dicbuf of
1:buf1[dicrow,diccol+1]:=buf1[dicrow,diccol-((msgscount-i)*2)+1]; //записывается старший байт поинтера из уже записанного ранее
.
.
8:buf8[dicrow,diccol+1]:=buf8[dicrow,diccol-((msgscount-i)*2)+1];
end;
case dicbuf of
1:buf1[dicrow,diccol+2]:=buf1[dicrow,diccol-((msgscount-i)*2)+2]; //записывается младший байт поинтера из уже записанного ранее
.
.
8:buf8[dicrow,diccol+2]:=buf8[dicrow,diccol-((msgscount-i)*2)+2];
end;
msgsind:=1; //есть повторение
end;
end;
if msgsind=1 then begin
msgs[msgscount-1]:=msgs[msint];
inc(msgscount);
setlength(msgs,msgscount);
end;
if msgsind=0 then begin
s:=memo3.lines.strings[rowcount]; //rowcount - номер строки в memo
msgs[msgscount-1]:=s;
inc(msgscount);
setlength(msgs,msgscount);
i:=1;
while i<=length(s) do begin
if s[i]='<' then begin //обработка управляющих кодов, выделенных <ХХ>
case dicbuf of
1:buf1[dicrow,decpoint]:=chr(strtoint(copy(s,i+1,2)));
.
.
8:buf8[dicrow,decpoint]:=chr(strtoint(copy(s,i+1,2)));
end;
inc(decpoint);
if decpoint>65536 then begin //размер таблицы в буфере 65536
decpoint:=1;
inc(dicrow);
if dicrow>8 then begin
dicrow:=1;
inc(dicbuf);
end;
end;
inc(i,4);
end else begin
for j:=1 to 159 do begin //обработка словаря MTE
if (n=0)and(pos(dictionary[j],s)=i)then
begin
n:=1;
p:=j;
l:=length(dictionary[j]);
delete(s,i,l);
insert(chr(p),s,i);
{end else
if (n=0)and(pos('...',s)=i)then
begin
n:=1;
p:=241;
l:=3;
delete(s,i,l);
insert(chr(p),s,i);}
end;
end;
if n=1 then begin
n:=0;
inc(i);
case dicbuf of
1:buf1[dicrow,decpoint]:=chr(p);
.
.
8:buf8[dicrow,decpoint]:=chr(p);
end;
inc(decpoint);
if decpoint>65536 then begin
decpoint:=1;
inc(dicrow);
if dicrow>8 then begin
dicrow:=1;
inc(dicbuf);
end;
end;
end else begin
case dicbuf of
1:buf1[dicrow,decpoint]:=decoder(s[i])[1];
.
.
8:buf8[dicrow,decpoint]:=decoder(s[i])[1];
end;
inc(decpoint);
if decpoint>65536 then begin
decpoint:=1;
inc(dicrow);
if dicrow>8 then begin
dicrow:=1;
inc(dicbuf);
end;
end;
inc(i);
end;
end;
end;
case dicbuf of
1:buf1[dicrow,decpoint]:=chr(0);
.
.
8:buf8[dicrow,decpoint]:=chr(0);
end;
inc(decpoint);
if decpoint>65536 then begin
decpoint:=1;
inc(dicrow);
if dicrow>8 then begin
dicrow:=1;
inc(dicbuf);
end;
end;
end;
end else begin
case dicbuf of
1:buf1[dicrow,diccol+1]:=chr((decpoint-2)mod 256);
.
.
8:buf8[dicrow,diccol+1]:=chr((decpoint-2)mod 256);
end;
case dicbuf of
1:buf1[dicrow,diccol+2]:=chr(trunc(((decpoint-2)/256)-2));
.
.
8:buf8[dicrow,diccol+2]:=chr(trunc(((decpoint-2)/256)-2));
end;
end;
inc(rowcount);
inc(diccol,2);
progressbar1.position:=rowcount;
if memo3.lines.strings[rowcount]='' then goto fullbeg;
if memo3.lines.strings[rowcount][1]='{' then
goto beg else goto fullbeg;
en:
end;
Я тут кое-что лишнее повырезал, а то много слишком получается, а кое-где не успел описание написать, завтра дополню, если что не понятно.
----- Делая выбор, отбрось простое решение и выбери правильное...
|
|
|
|
Поиск в теме | Версия для печати |
Страниц (1): [1] |
Сейчас эту тему просматривают: 1 (гостей: 1, зарегистрированных: 0) |
« Экстрим хакинг » |
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
|
|
|