Chief-NET

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Chief-NET » Экстрим хакинг » Сжатие в NES


Сжатие в NES

Сообщений 21 страница 28 из 28

21

Да, я видел текст в Dragon Warrior 2, даже нашел, где находятся запакованные тексты (но не записал и пока не полностью разобрался в коде).

Bee 52(U).nes - говорите, погляжу.

DTE алгоритм довольно прост, у меня в скриптере для Chrono Trigger используется алгоритм MTE (что по сути одно и то же, то есть закодировав MTE, можно не кодировать DTE).
С собой нет, но показать могу (попозже).

Отредактировано Alex_231 (2006-03-13 10:50:39)

22

даже нашел, где находятся запакованные тексты

Это ты про байты в районе $B4B9?

С собой нет, но показать могу (попозже).

Вот это было бы здорово! :lol:

23

Нет, там хранится таблица MTE, а текст в районе $14C00

Извлечение:

Код:
//Названия домов
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;

Возвращение:

Код:
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;

Я тут кое-что лишнее повырезал, а то много слишком получается, а кое-где не успел описание написать, завтра дополню, если что не понятно.

Отредактировано Alex_231 (2006-03-15 11:55:18)

24

:o  Вот это ни хрена себе! Честно говоря, думал будет несколько проще...
Мне в этом месяца три разбираться...
Большое спасибо!

25

Да тут, вроде, ничего сложного нет, просто много различных условий и все.

26

Нда, я просто раньше имел дело с чистым паскалем и с соответствующей спецификой программ - в области прикладной математики... :)

27

А это чистый паскаль просто построенный а объектах Win

28

Ты видел на текст в Dragon Warrior 2? :huh:

А теперь я полностью разобрался в алгоритме сжатия текста, пишу программу (точнее дописываю, так как она уже частично вынимать умеет, осталось поинтеры обработать).


Вы здесь » Chief-NET » Экстрим хакинг » Сжатие в NES