Ä

TECHNIKAI HÁTTÉRINFÓK





ALAPFOGALMAK
BYTE (BÁJT)

Eredendően minden adat a bináris számrendszer nulláiból és egyeseiből áll és a hardver eképpen is értelmezi. Ezen a 8 biten minden egyes bit 0 és 1 állapota valamilyen vezérlőnek, beállításnak, pillanatnyi állapotnak felel meg. A tizenhatos számrendszer, avagy a hexadecimális értékrend tagjaiban a 255 különböző bináris lehetőség kerül egyetlen számban kifejezésre.

1 bájtos értéket felírhatunk 00-tól FF-ig.
Ha az értékre az mondjuk, hogy 2 bájtos, akkor az két olyan bájtból áll, melynek tagjai külön-külön 00-tól FF-ig felírhatók.

Félbájt:
Ha vesszük az 1B hexa értéket, akkor az 1 és a B egyenként egy félbájt.
Továbbá....
Felsőbbrendű bájtnak hívjuk azt, ami a tízesek helyén áll. A példában ez az 1.
Alsóbbrendű bájtnak hívjuk azt, ami az egyesek helyén szerepel. A példában ez a B.

A hexa tagjai a következők:
00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F

A fenti értékek az általunk használt decimális, azaz tízes számrendszerben:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15

Ahogy a tízes számrendszer tagjai ismétlődnek a 9 után, úgy a tizenhatosé is ismétlésbe kezd a 0F után. Tehát az 1B, a B6, vagy az FF mind decimális jelentéssel bíró értékek, továbbá reprezentálnak egy 8-bites bináris kombinációt.


PÉLDA

Hex 00 = Bin 00000000 = Dec 0
Hex FF = Bin 11111111 = Dec 255
Hex 1B = Bin 00011011 = Dec 27
Hex B6 = Bin 10110110 = Dec 182

STRING (KARAKTERLÁNC)

A számítógép számára minden adat egyetlen hosszú egyenes, egy úgynevezett bitfolyam.

Több, egymás után következő bájtra szokás azt mondani, hogy egy karakterlánc, avagy egy string. A számítógép számára minden adat egyetlen hosszú egyenes.

OFFSET (MEMÓRIACÍM / HELYI ÉRTÉK)

Egy kijelölt adat offsetje azt jelenti, hogy a string legelejétől ennyi bájtra helyezkedik el. Az offsetet mindig hexában fejezzük ki, tehát ami 10, 11 vagy 12 bájtra helyezkedik el a fájl elejétől, azt úgy számoljuk, hogy A, B és C.


PÉLDA

00 EB 72 44 44 44 45 B9 AD A0 85 AD A0 85 98 9B
A2 A2 A7 87 81 88 A5 86 83 84 92 97 95 9C 9A 99
FF 00 12 20 91 8F 67 68 93 96 9D 8D 84 9C

Ebben a példában a "00" érték a 00 offseten áll.
A "45" érték a 06 offseten.
A "9D" érték 2A offseten áll, ami decimálisba átváltva a 42. bájtot jelenti.

WORD (SZÓ)

Egy szó 2 bájtból áll, de önmagában nem mutat sehova. Hogy valódi jelentését megkapjuk, meg kell szoroznunk 2-vel.


PÉLDA A SNES VRAM-KEZELŐ RENDSZERÉBŐL

Ha a VRAM-ból azt olvassuk, hogy az adott képi anyag a 4000. offsetnél kezdődik, akkor a hivatkozás, ami ezt definiálhatja a 2000 lesz, hiszen a hexában felírt 2000-nek a duplája a 4000. Ugyanígy, ha a VRAM-ból kiolvasott érték az B000. offseten szerepel, akkor annak a hivatkozása a programban 5800-ként fog szerepelni, hiszen a B000-nak a duplája az 5800.

LITTLE-ENDIAN

Azt jelenti, hogy egy vonatkozó több bájtos adat tagjait fel kell cserélni, és a hagyományos balról jobbra olvasás helyett jobbról balra kell kiolvasni.


PÉLDA

Mondjuk egy tömörítésbe deifniált fájlméretet akarunk elolvasni. A leírt adat 80 05, de mivel tudjuk, hogy a little-endian tárolás miatt "visszafelé" kell kiolvasnunk, azt kapjuk, hogy 05 80, ami azt jelenti, hogy a kicsomagolt fájl majd 580 bájt lesz.

POINTER (MEMÓRIAHIVATKOZÁS)

Olyan little-endianban tárolt, minimum 2 bájtos érték, ami közvetlenül egy memóriacímre, azaz memória offsetre hivatkozik. Fontos megjegyezni, hogy ezt a memóriát úgy értjük, mint RAM. Tehát ROM alapú memóriára ilyen jellegű pointer nem mutat. A hivatkozott RAM cím azonban lehet processzormemória (CPU RAM, System RAM), munkamemória (WRAM), de videómemória (VRAM) is.

A hivatkozás általában valamilyen adatállomány kezdőértékére mutat, pl.: szöveges tartalom, textúra adatok, hangadat, vagy a program futásához szükséges algoritmus.

Függően attól, hogy hány bites rendszert nézünk, egy pointer lehet 3, vagy 4 bájtos is, de mindig little-endianban tárolva, azaz visszafelé kell kiolvasni.

Tudni kell, hogy magából a pointerből nem lehet kiolvasni, hogy az milyen memóriára hivatkozik, de egy adott munka esetében az kontextuálisan adott. Más szóval, ha egy VRAM-ba beírt adat pointerét keressük, akkor tudjuk, az adott pointer arra hivatott, hogy a VRAM-ba írjon.


Példa 2 bájtos pointerre:
05 89

Azt jelenti, hogy egy bizonyos memória 8905-ös memóriacíménél kezdődik a hivatkozott adat.

Példa 3 bájtos pointerre:
1B 42 01

Azt jelenti, hogy egy bizonyos memória 01421B-s memóriacíménél kezdődik a hivatkozott adat.

Példa 4 bájtos pointerre:
CC 61 38 02

Azt jelenti, hogy egy bizonyos memória 023861CC-s memóriacíménél kezdődik a hivatkozott adat.

TABLE (KARAKTERTÁBLA)

A hex értékek visszafejtésekor karaktertáblát hozunk létre, melyben meghatározzuk, hogy egy-egy érték mit jelent az adott memóriaterületen.

Egy ilyen tábla grafikus szerkesztések és szöveges szerkesztések esetén válik igazán fontossá, hiszen ennek a táblának a megfejtésével válnak láthatóvá a fordítandó szövegek.


PÉLDA

Karaktertábla
érték jelentés érték jelentés
80 8E N
81 A 8F O
82 B 90 P
83 C 91 Q
84 D 92 R
85 E 93 S
86 F 94 T
87 G 95 U
88 H 96 V
89 I 97 W
8A J 98 X
8B K 99 Y
8C L 9A Z
8D M 9B .

Visszafejtett karaktertábla nélkül:
81 9A 80 81 8C 8D 81 80 90 89 92 8F 93 9B

Visszafejtett karaktertáblával:
AZ ALMA PIROS.

NAMETABLE (MINTATÁBLA)

Olyan, mint egy szabásminta, egy tervrajz, ami alapján a program a képernyőre rajzolja a grafikákat. Voltaképpen, a karaktertáblával megtalált szöveg is egy mintatábla, hiszen a hardver számára a karakterek is csak grafikák.

RAW (SZÓ SZERINTI BÁJT, NYERS BÁJT)

Azt jelenti, hogy a kiolvasandó értéknek nincs másodlagos jelentése. Úgy kell beírni a memóriába, ahogyan az szerepel.

TILE, TILESET (MOZAIK, MOZAIKSZETT)

A 8 és 16 bites rendszerek 2D-s játékainak a képernyője 8x8 pixel felbontású csempékből, avagy mozaikdarabkákból tevődik össze.

Rendereléskor minden hex érték reprezentál egy bizonyos mozaikot, ami azt jelenti, hogy 255 db ilyen mozaikgrafika áll rendelkezésünkre egy időben a kép megalkotásakor. A palettát, amin ezt a 255 lehetőséget felkínálják, úgy hívjuk, hogy mozaikszett.

ADATTÖMÖRÍTÉS

Egy hardver számára minden adat egyforma és csak az éppen futó program határozza meg, hogy egy-egy adat mondjuk a képernyőre való kiírásért felelős portra lesz irányítva, ezzel adva egy jelentést, mint pixelalkotó érték, vagy mondjuk a hangért felelős portra, ahol jelenthet akár egy ütemértéket is.

Ebből kiindulva, bármilyen adat tömörítésre kerülhet.

A tömörítés lényege az ismétlődések, más szóval, redundanciák felismerése és azok hivatkozási pontok általi kiszorítása.

A hivatkozási pont egy koncepció, amire számtalan, de eltérő hatékonyságú megoldás létezik.

Egy tömörítés sikeres visszafejtésének a kulcsa a hivatkozási pontok működésének a megfejtése.

ÁLTALÁNOS TÖMÖRÍTÉSEK
RLE

Teljes nevén Run-Length Encoding. Működése szerint egy adott operátorkódban meghatározza, hogy a soron következő bájt nyers, vagy tömörített. Ha tömörített, akkor az operátorkód az ismétlés mértékét is tárolja.

Az RLE tömörítést többféleképpen is alkalmazhatják, ezért a visszafejtett operátorkódok játékról játékra különbözhetnek.


PÉLDA AZ ÁLTALÁNOS MŰKÖDÉSI ELVRE

Példánkban az operátorkódok a következőképpen oszlanak el:

00-7F: RLE tömörítés
80-FF: nyers bájt

Tömörített karakterlánc:
84 45 B2 87 88 93 04 00 07 02

Kicsomagolt állomány:
45 B2 87 88 93 00 00 00 00 00 02 02 02 02 02 02
02 02

84 = nyers opkód, esetünkben 5 bájt hossznyi stringet értelmez szó szerint.

45 B2 87 88 93 = szó szerint értelmezendő bájtok.

04 = RLE operátor, mely esetünkben 5 bájtnyi hosszan ismételi meg a soron következő bájtot.

00 = ezt a bájtot ismételjük meg 5 alkalommal

07 = RLE operátor, mely esetünkben 8 bájtnyi hosszan ismételi meg a soron következő bájtot.

02 = ezt a bájtot ismételjük meg 8 alkalommal

LZ

Teljes nevén Lempel-Ziv. Egy korábban a memóriába írt bájtcsoportra hivatkozva tömörít. Az algoritmus két bájtból tevődik össze: az első azt mutatja, hogy a képzeletbeli kurzor jelenlegi helyétől mennyit kell visszafelé lépni az LZ mintavételi ablakban, ahonnan a kiolvasás történhet; a második érték pedig azt jelenti, hogy a kiolvasás hány bájt hosszan történjen. LZ tömörítést minimum 3 bájt tömörítése esetén érdemes használni. Ez alatt nem beszélhetünk tömörítésről, hiszen az LZ hivatkozás maga elvisz 2 bájtot.

Ha a "kiolvasandó hossz" nagyobb, mint amennyi kicsomagolt adat rendelkezésünkre áll a "hivatkozás" által megjelölt ponttól, akkor először elvégezzük az attól a ponttól rendelkezésre álló állomány kiolvasását, majd annak végeztével ismét a "hivatkozás" pontra lépünk és kezdjük elölről a kiolvasás. Addig ismételjük ezt a folyamatot, míg a "kiolvasandó hossz" értékének eleget nem teszünk.

LZ mintavételi ablak:
Az adatok kicsomagolása során nem csak a kívánt helyre kerül beírásra a kicsomagolt adat, hanem az LZ mintavételi ablakba is, ami voltaképpen felfogható egyfajta LZ memóriának. Ennek az LZ memóriának a mérete LZ variánsoként változhat.

Az LZ tömörítést többféleképpen is alkalmazhatják, ezért a visszafejtett operátorkódok játékról játékra különbözhetnek.


PÉLDA AZ ÁLTALÁNOS MŰKÖDÉSI ELVRE

A kicsomagolt adat eddigi állapota:
00 EB 72 44 44 44 45 B9 AD A0 85 AD A0 85 98 9B
A2 A2 A7 87 81 88 A5 86 83 84 92 97 95 9C 9A 99
FF 00 12 20 91 8F 67 68 93 96 9D 8D

A 10 bájt hoszú LZ memória:
9A 99 FF 00 12 20 91 8F 67 68 93 96 9D 8D 84 9C


Az LZ hivatkozás:
0A 04

A kicsomagolt adat ezután:
00 EB 72 44 44 44 45 B9 AD A0 85 AD A0 85 98 9B
A2 A2 A7 87 81 88 A5 86 83 84 92 97 95 9C 9A 99
FF 00 12 20 91 8F 67 68 93 96 9D 8D 91 8F 67 68

A példában "0A", azaz 10 értéket léptünk visszafelé a kurzortól az LZ memóriában, majd onnantól kezdve "04", azaz 4 bájt hosszúságban kiolvastuk. Ez volt a "91 8F 67 68".

LZSS

Egy LZ variáns. Leggyakrabban Super Nintendo játékokban alkalmazták. Tömörítettek vele grafikát és mintatáblát is egyaránt.

Az első két bájt a tömörített állomány méretét definiálja little-endianban. Az utána következő bájt egy maszkbájt, amely egyesével meghatározza, hogy az utána kiolvasott 8 bájt nyers érték, vagy LZ hivatkozás. Az LZ hivatkozást ilyenkor egyetlen tényezőnek tekinti. Az LZ memória alapesetben FF, tehát 255 bájt hosszú. Hogy megismerjük a maszkbájt jelentését, át kell váltanunk binárisba, de mivel tudjuk, hogy ez is little-endianban van, visszafelé kell kiolvasni. Így láthatjuk, hogy a soron következő 8 bájtot miképp fogja értelmezni. Összesen 255 különböző maszkbájt létezik, tehát 00-tól FF-ig terjedően lefed minden kombinációt.

Az LZSS tömörítést többféleképpen is alkalmazhatják, ezért a visszafejtett operátorkódok játékról játékra különbözhetnek.


PÉLDA AZ ÁLTALÁNOS MŰKÖDÉSI ELVRE

A tömörített állomány:
12 00 FF 00 EB 72 44 44 44 45 B9 F7 AD A0 85 03
03 98 9B A2 A2

Kicsomagolás után:
00 EB 72 44 44 44 45 B9 AD A0 85 AD A0 85 98 9B
A2 A2

A példában az első két bájt definiálja az adathalmaz méretét a kicsomagolás után, ami 12 bájt. Utána következik a maszkbájt.

Az FF binárisba átválta 11111111. Azt jelenti, hogy a következő 8 bájtot szót szerint kell érteni, tehát nem tömörítettek.
Az F7 binárisba átválta 11110111. De mivel little-endian, ezért meg kell fordítani, így jön ki az, hogy 11101111. Tehát, az F7 utáni első három bájt, az "AD A0 85" szó szerinti bájtok. De a negyedik, a "03 03" az egy LZ hivatkozás. Miután a program feldolgozta azt, a soron következő bájtok, azaz a "98 9B A2 A2" szintén nyers értékek.

SPECIFIKUS TÖMÖRÍTÉSEK
KONAMI RLE v1

Alkalmazva:
Contra (NES)
Super Contra (NES)

Operátor kódok:
00-7F: RLE opkód, soron következő bájtot az opkód által meghatározott hosszban ismételi meg
81-FE: nyers bájtok következnek az opkód által meghatározott hosszban
FF: tömörített állomány vége


PÉLDA

Tömörített adat:
21 01 85 80 82 84 88 82 80 FF

Kicsomagolt adat:
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 80 82 84 88 82 80

21 = RLE opkód, a következő bájtot 21 alkalommal (azaz dec 33) ismételje meg

01 = ezt ismételjes 21 alkalommal

85 = nyers opkód, a következő 6 bájt szó szerinti

80 82 84 88 82 80 = a szó szerint értelmezendő bájtok

FF = tömörítési folyamat vége

KONAMI RLE v2

Alkalmazva:
Castlevania (NES)

Operátor kódok:
00-7F: RLE opkód, soron következő bájtot az opkód által meghatározott hosszban ismételi meg
81-BF: nyers bájtok következnek az opkód által meghatározott hosszban
C1-FE: mozaiklánc opkód, a soron következő bájt egy pointer a VRAM mozaikszettjére, ahonnan az opkódban meghatározott hosszban olvas ki egy mozaikláncot
FF: tömörített állomány vége


PÉLDA

Tömörített adat:
21 01 85 80 82 84 88 82 80 C6 12 FF

Kicsomagolt adat:
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 80 82 84 88 82 80 12 13 14 15 16 17

21 = RLE opkód, a következő bájtot 21 alkalommal (azaz dec 33) ismételje meg

01 = ezt ismételjes 21 alkalommal

85 = nyers opkód, a következő 6 bájt szó szerinti

80 82 84 88 82 80 = a szó szerint értelmezendő bájtok

C6 = mozaiklánc kód, ami 6 mozaik hosszan olvas ki grafikus adatot a VRAM-ból

12 = az iménti 6 mozaiklánc kiolvasását a 12 hex értéken álló mozaiknál kezdje

FF = tömörítési folyamat vége

TOSE LZSS

Alkalmazva:
Dragon Ball Z: Hyper Dimension (SNES)

A játék az LZSS tömörítés elvét követi a maszkbájtokkal és a fájlméret definiálással, de az LZ hivatkozóbájtok értelmezése egyedi. Továbbá, a hossz kiolvasás 3 bájttól indul, azaz, ha a "kiolvasandó hossz" félbájt 0, akkor 3 bájtot fog kiolvasni; ha a félbájt 1, akkor 4 bájtot; ha a félbájt 2, akkor 5 bájtot, és így tovább. A "kiolvasandó hossz" fálbájthoz fejben adjunk hozzá hármat és megkapjuk a kicsomagolni kívánt string hosszát.


PÉLDA

Ami más játékban 25 04, az ebben az esetben 54 02.

Az LZ memóriacím: 025.
A kiolvasandó hossz: 4.

Értelmezése a következő:

Az LZ mintavételi ablaka elméletileg 0FFF hosszú, ami 4095 bájt, de a kiolvasott hossz nem lehet több F-nél, azaz 10 bájtnál.
Az LZ hivatkozás tagjai felcserélődnek, és az LZ memóriacím kerül a második tagba, úgy, hogy oda a 3 félbájt első két félbájtja kerül. A cím utolsó félbájtját az első tag első félbájtjába írjuk. Az első tag második félbájtja a kiolvasandó hossz.

5 = 025 utolsó félbájtja

4 = kiolvasandó hossz

0 = 025 első félbájtja

2 = 025 második félbájtja

Ebben a példában a "kiolvasandó hossz" 4, tehát a kicsomagolt string 4+3=7 bájt hosszú lesz.

PROBE LZ

Alkalmazva:
Alien 3 (SNES)

LZ variáns.

Operátorkódok:
00-7F: nyers bájtok
80-FF: LZ tömörítés

FF 00: ez a bájtpár azt jelenti, hogy vége a tömörített állománynak

A nyers opkódhoz hozzá kell adni 1-et, hogy megkapjuk a ténylegesen kiolvasott string hosszát. Tehát, ha a nyers kód 04, akkor 5 bájtot fog kiolvasni; ha 05, akkor 6 bájtot, és így tovább. Ez azt jelenti, hogy legfeljebb 80 bájt hosszúsági szó szerinti stringet tudunk egyszerre meghatározni.

Az LZ hivatkozás FF-től visszafelé számolva érvényes. Ha egy bájtot mozog vissza a kurzor, akkor FF, ha kettőt, akkor FE, ha hármat, akkor FD, és így tovább, egészen 80-ig. Ez azt is jelenti, hogy az LZ memóriába összesen 80 bájt fér, tehát a kurzor jelenlegi helyzetétől mindig legfeljebb 80 bájt távolságig tudunk hivatkozni.


PÉLDA

Tömörített állomány:

06 00 00 1C 3C 02 42 40 FF 05 00 00 FF 05 09 3C
00 42 00 40 00 40 0E 40 02 F7 03 00 3C

Kicsomagolt állomány:

00 00 1C 3C 02 42 40 40 40 40 40 40 00 00 00 00
00 00 3C 00 42 00 40 00 40 0E 40 02 00 42 00 3C

06 = a következő 7 bájt szó szerint értendő

00 00 1C 3C 02 42 40 = nyers bájtok

FF 05 = LZ tömörítés. Az FF miatt egy értéket visszalépünk a kicsomagolt állományban és onnantól számolt 5 bájt hosszú stringet kiolvasunk és hozzáadjuk azt a kicsomagolt állományunk végére. Esetünkben, a hivatkozási ponttól csak egyetlen kicsomagolt "40" bájt áll rendelkezésre. Ez azt jelenti, hogy akkor ezt olvassuk be 5-ször.

00 = a következő 1 bájt szó szerint értendő

00 = nyers bájtok

FF 05 = LZ tömörítés. Az FF miatt egy értéket visszalépünk a kicsomagolt állományban és onnantól számolt 5 bájt hosszú stringet kiolvasunk és hozzáadjuk azt a kicsomagolt állományunk végére. Esetünkben, a hivatkozási ponttól csak egyetlen kicsomagolt "00" bájt áll rendelkezésre. Ez azt jelenti, hogy akkor ezt olvassuk be 5-ször.

09 = a következő 10 bájt szó szerint értendő (decimálisban 10, hexában 0A)

3C 00 42 00 40 00 40 0E 40 02 = nyers bájtok

F7 03 = LZ tömörítés. Az F7 miatt 7 értéket visszalépünk a kicsomagolt állományban és onnantól számolt 3 bájt hosszú stringet kiolvasunk és hozzáadjuk azt a kicsomagolt állományunk végére. Esetünkben ez a "00 42 00" string.

00 = a következő 1 bájt szó szerint értendő

03 = nyers bájtok

KONAMI LZ+RLE

Alkalmazva:
Teenage Mutant Ninja Turtles IV: Turtles in Time (SNES)

A Konami korábbi RLE tömörítésének egy LZ algoritmussal bővített, továbbfejlesztett változata.

Tehát az első két bájt a kitömörített állomány hosszát adja little-endianban, majd az operátorkód következik, ami lehet LZ hossz-, szó szerinti, szókonverter, ismétlődés vagy nullérték definíció.

Az LZ mintavételi ablak mérete 03FF bájt hosszú, de nem halad együtt a kurzorral. Helyette rögtön az elején lefoglal 03FF méretű területet az addig kicsomagolt állományból, és ha a folyamat átlépi ezt a kezdeti 03FF hosszt, akkor a mintavételi ablak továbbugrik a következő 03FF méretű területre a kicsomagolt állományban és minden LZ hivatkozás onnantól kezdve arra lesz érvényes, amíg az LZ mintavételi ablak, azaz az LZ memória nem ugrik tovább a következő 03FF területre.

Továbbá, a program 3DF-től kezdi számolni a hivatkozást, a 3FF átlépése után a hivatkozási értéket 000-tól kell számolni, ami 3DE-ig tart. Ezért a hivatkozás pontos meghatározásához szükséges lehet egy képlet alkalmazása. Egy adott mintavételi ablak hivatkozását tehát a következőképpen határozzuk meg:

DF + "STRoff" - ("LZmb" * 100) = "LZptr"

STRoff (String offset):
A tömöríteni kívánt string keződoffsetje.

LZmb (LZ memory bank):
LZ memóriabank. A Konami tömörítésében az LZ memória négy memóriabankot tartalmaz, és minden bank 255, azaz FF memóriacímmel rendelkezik. A memóriabank sorszámával számolunk.

000-0FF = 0. memóriabank
100-1FF = 1. memóriabank
200-2FF = 2. memóriabank
300-3FF = 3. memóriabank

LZptr (LZ pointer):
LZ hivatkozás, ami a képlet eredménye.

Továbbá, a kiolvasandó hossz definíciója LZ memóriabankonként különbözik. Az alábbi táblázatban szerepel az összes lehetséges érték a memóriabank és a kiolvasandó hossz viszonyában.

kiolvasandó
hossz
LZ memóriabank
0 1 2 3
02 00 01 02 03
03 04 05 06 07
04 08 09 0A 0B
05 0C 0D 0E 0F
06 10 11 12 13
07 14 15 16 17
08 18 19 1A 1B
09 1C 1D 1E 1F
0A 20 21 22 23
0B 24 25 26 27
0C 28 29 2A 2B
0D 2C 2D 2E 2F
0E 30 31 32 33
0F 34 35 36 37
10 38 39 3A 3B
11 3C 3D 3E 3F
12 40 41 42 43
13 44 45 46 47
14 48 49 4A 4B
15 4C 4D 4E 4F
16 50 51 52 53
17 54 55 56 57
18 58 59 5A 5B
19 5C 5D 5E 5F
1A 60 61 62 63
1B 64 65 66 67
1C 68 69 6A 6B
1D 6C 6D 6E 6F
1E 70 71 72 73
1F 74 75 76 77
20 78 79 7A 7B
21 7C 7D 7E 7F

Operátorkódok és működésük:

00-7F = LZ tömörítés

Meghatározza a kiolvasandó hosszt. Az utána következő érték a hivatkozási érték, egy mutatópont az LZ mintavételi ablakra. A 00 két bájt hossz kiolvasására mutat, a 7F pedig 33 bájt kiolvasására. Tehát az LZ hosszban megadott értékhez 2-t hozzá kell adni, hogy megkapjuk a valós kitömörített hosszt.

80-9F = Szó szerinti bájtok

Egyben annak hosszát is jelöli. A 9F-fel maximum 31 bájt hosszan olvasható ki egy nyers karakterlánc.

A0-BF = Szókonverter

Szóvá konvertálja az utána lévő értékeket és egyben meghatározza az ez alá eső string hosszát. Működése szerint az ezt követő értékeket nyersként olvassa be, azzal a csavarral, hogy az értékek közé beszúr egy 00-s bájtot. További bonyodalom, hogy maga az A0 kapásból 4 bájt hosszan értelmez, tehát minden a szókonverterben megadott értékhez hozzá kell adni 4-et, hogy megkapjuk a valós kicsomagolt hosszt.

C0-DF = RLE tömörítés

Egyben meghatározza a bájtismétlés hosszát is. A C0 alapból 2 bájtot ismétel, tehát a RLE hossz meghatározásánál 2-t hozzá kell adjunk, hogy megkapjuk a valós kitömörített hosszt.

E0-FE = nullérték

Meghatározza, hogy hány bájt hosszan szúrjon be 00-s bájtokat. Az E0 alapból 2 bájtot szúr be, tehát nullhossz meghatározásánál 2-t hozzá kell adjunk, hogy megkapjuk a valós kitömörített hosszt, a következő kivétellel:

FF FF = 64 bájt hosszan szúr be 00-s értéket


PÉLDA

Tömörített adat:

E0 83 1C 3C 02 42 C4 40 E3 A0 3C 42 40 40 80 0E 0F EF

Kicsomagolt adat:

00 00 1C 3C 02 42 40 40 40 40 40 40 00 00 00 00
00 00 3C 00 42 00 40 00 40 0E 00 00 00 3C 00 42

Jelentés:

E0 = nullérték, két nullbájt beszúrása

83 = nyers operátorkód, a következő 4 bájt szó szerint értendő

1C 3C 02 42 = szó szerinti bájtok

C4 = RLE operátor, a soron következő bájtot 6 bájt hosszan csomagolja ki

40 = ezt írja be hatszor az előző RLE operátorkód

E3 = nullérték, öt nullbájt beszúrása

A0 = szókonverter, a soron következő 4 bájtot szóvá konvertálja nullértékek beszúrásával

3C 42 40 40 = ezt a karakterláncot konvertálja szóvá az előző operátorkód

80 = nyers operátorkód, a következő 1 bájt szó szerint értendő

0E = szó szerinti bájtok

0F EF = LZ operátorkód, amiben a 0F az 5 bájtnyi hosszan való kicsomagolás jelenti a 3. LZ memóriabankból, az EF pedig ennek a 3. LZ memóriabank EF offsetjétől való kiolvasást jelent, az imént megadott hosszúsággal




ELÉRHETŐSÉGEK > HIVATALOS FORDÍTÁSAIM
§ retrohun.games@gmail.com
` facebook.hu/retrohun
| youtube.com/@retrohun
> LOGO GALÉRIA
> TECHNIKAI HÁTTÉRINFÓK
> HOGYAN TÁMOGATHATLAK?

PARTNEREK


The_Reaper_CooL

Szemigi

Magyarítások Portál

Pii89

RETRO_hun 4.1
Fejlesztette: Takács Ferenc
2015-2024