Grafikkomprimierung PKMN GSK

aus RHWiki, der freien Romhacking-Enzyklopädie

Die Komprimierung in Pokémon GSK ist eine Kombination aus RLE- und lz77-Komprimierung. Sie ist bytebasiert, d.h. es werden immer nur ganze Bytes betrachtet.

Inhaltsverzeichnis

Überblick

Die Komprimierung ist linear aufgebaut:

[Kontrollbyte][Daten]...

(Es folgt immer ein Datensegment auf ein Kontrollbyte)

Das Ende der Daten ist durch einen speziellen Kontrollcode festgelegt. Es gibt also zu Beginn keine Größenangabe, sondern die Daten beginnen direkt mit dem ersten Kontrollbyte.

Es gibt 8 Kontrollcodes, die bestimmen auf welche Weise nachfolgende Daten interpretiert werden sollen.

Detailierte Beschreibung

Jedes Kontrollbyte enthält in den Bits 5-7 einen Kontrollcode. Man erhält ihn über eine bitweise AND-Operation von 0xE0 (Hexadezimal) mit dem Kontrollbyte.

Auf diese Weise gibt es die Kontrollcodes 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0 und 0xE0 (Hexadezimal)

In den restlichen 5 Bits 0-4 ist für die Codes 0x00-0xC0 die Länge der jeweils dekomprimierten Daten definiert, für 0xE0 haben die 5 Bits eine gesonderte Bedeutung (siehe weiter unten).

Die dekomprimierten Daten werden in einen Speicher, auch Puffer genannt, geschrieben.

Kontrollcodes

Für jeden dieser Codes erhält man die Länge der Daten N über die bitweise AND-Operation des Kontrollcodes mit 0x1F (Hexadezimal).

Code 0x00

Bedeutet, dass die nachfolgenden Daten unkomprimiert sind. Kopiere dann einfach N+1 Anzahl nachfolgende Bytes in den Ausgabepuffer.

Bitweise Struktur:
[000][NNNNN] (N + 1)*[DDDDDDDD]

Ausgabe:
(N + 1)*[DDDDDDDD]

RLE-Codes

Die Codes 0x20 bis 0x60 wiederholen bestimmte Bytes mehrfach.

Code 0x20

RLE: Kopiere N+1 mal das selbe nachfolgende Byte in den Ausgabepuffer.

Bitweise Struktur:
[001][NNNNN][DDDDDDDD]

Ausgabe:
(N + 1)*[DDDDDDDD]

Code 0x40

RLE: Kopiere abwechselnd die nächsten beiden Bytes in den Ausgabepuffer, bis N+1 Bytes geschrieben sind.

Bitweise Struktur:
[010][NNNNN] [DDDDDDDD][EEEEEEEE]

Ausgabe:
(N / 2)*[DDDDDDDD][EEEEEEEE] + (N & 1)*[DDDDDDDD]
Hinweis: Bei (N / 2) wird das Ergebnis abgerundet. (N & 1) ist die bitweise AND-Operation.

Code 0x60

RLE: Schreibe N+1 mal 0x00 in den Ausgabepuffer. Dieser Code benötigt keine weiteren Bytes

Bitweise Struktur:
[011][NNNNN]

Ausgabe:
(N + 1)*[00000000]

lz77-Codes

Die Nachfolgenden Codes 0x80 bis 0xC0 recyceln Daten, die bereits dekomprimiert wurden.

Sie verwenden alle ein oder zwei weitere Bytes, um festzulegen von wo die Daten geholt werden sollen:

Nimm ein weiteres Byte A und betrachte dessen 7-tes Bit.
Ist das Bit 0, so folgt ein weiteres Byte. Die Bits 6-0 von A ergeben zusammen mit dem nächsten Byte das absolute Offset des Kopierbeginns im Ausgabepuffer. Ist das Bit 1, so geben die Bits 6-0 von A das relative Offset rückwärts von Ende des Ausgabepuffers an. Dabei ist das zuletzt geschriebene Byte 0, das davor 1 usw.

Vom berechneten Offset werden N+1 Bytes ans Ende des Ausgabepuffers kopiert.

Code 0x80

lz77: Kopiere die Bytes direkt ohne Veränderung.

Bitweise Struktur:
[100][NNNNN][0][SSSSSSS][SSSSSSSS]

Ausgabe:
(N + 1) Bytes von Offset SSS SSSS SSSS SSSS (Bit 6-0; 7-0) des Ausgabepuffers

Oder:

[100][NNNNN][1][RRRRRRR]

Ausgabe:
(N + 1) Bytes von (Aktuelles Offset - 1 - RRR RRRR) des Ausgabepuffers

Code 0xA0

lz77: Vertausche beim Kopieren von jedem Byte die Bitreihenfolge (Bit 7-0 -> Bit 0-7).

Bitweise Struktur:
[101][NNNNN][0][SSSSSSS][SSSSSSSS] oder
[101][NNNNN][1][RRRRRRR]

Sonst wie 0x80.

Code 0xC0

lz77: Kopiere die Bytes nicht vorwärts, sondern rückwärts.

Bitweise Struktur:
[110][NNNNN][0][SSSSSSS][SSSSSSSS] oder
[110][NNNNN][1][RRRRRRR]

Sonst wie 0x80.

Code 0xE0

Dieser Code ist kein eigenständiger Befehl, sondern mehr eine Erweiterung zu allen anderen. Er bewirkt, dass einer der anderen Befehle mit größerem N (Anzahl der Bytes) aufgerufen werden kann.

Die Bits 0-1 des Kontrollbytes ergeben zusammen mit dem nachfolgenden Byte das neue N. Es bewirkt im Prinzip für jeden Code eine größere Spanne/Reichweite von bis zu 0x0400 Bytes pro Kontrollcode.
Bits 2-4 ergeben den neuen Kontrollcode.

Bitweise Struktur:
[111][CCC][NN][NNNNNNNN]

Bewirkt:
CCC ist neuer Kontrollcode und NN NNNN NNNN neues N.
Fahre mit dem entsprechenden Kontrollcode fort.


Beispiel:

E4FE
[111][001][00][11111110]

Bedeutet:
Kontrollcode 0x20 mit N = 0x0FE
Rechnung: 0xE4 And 0x1C *0x08 = 0x20

Code 0xFF

Der Code 0xFF bedeutet das Ende der Daten. Er ist ein Spezialfall des Codes 0xE0

Beispiele

1. Beipiel:

0312345678
wird zu:
12345678
2. Beispiel:

01234567
wird zu:
23450000000000000000
3. Beispiel:

3AAE6144E2E38C05
wird zu:
AEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAE0000E2E3E2E3E200E2E3E2E3E200E2E3E2E3E200
| 27 mal 0xAE                                |2*00| 5*E2E3 || 13 Bytes von Pos-5     |

Format der Daten

Die dekomprimierten Daten liegen (Spezialfälle ausgeschlossen) im Standard-Gameboy-Grafikformat vor. Sie können mit Tile-Viewern betrachtet und geändert werden.

Tools

Zu dieser Komprimierung gibt es folgende Tools, die einem die Arbeit ungemein erleichtern:

Siehe auch

'Persönliche Werkzeuge