|
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.
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
|
|
|
|
PARTNEREK
|
|
RETRO_hun 4.1
Fejlesztette: Takács Ferenc
2015-2024
|