Animationsdaten PKMN Kristall
aus RHWiki, der freien Romhacking-Enzyklopädie
| Inhaltsverzeichnis |
Einleitung
Hier wird die Struktur der Daten erklärt, wie sie verarbeitet werden und was im Endeffekt ausgegeben wird. Es wird vorausgesetzt, dass das Offset der Pokémon-Bildes bekannt ist, die Größe wie sie in den Pokémon-Daten definiert ist, und ob es sich um ein Bild im Kampf oder eines im Status handelt.
Offsets
Die Offsets der Tabellen sind wie folgt: (siehe Pointer )
| Pokémon < 0x98 | Pokémon >= 0x98 | Icognito | Ei | |
|---|---|---|---|---|
| 1. Tabelle | 34:4695 | 34:4695 | 34:6229 | 34:5696 |
| 2. Tabelle | 35:4000 | 36:4000 | 36:59A9 | 36:598B |
| 3. Tabelle | 34:64EF | 34:64EF | 34:7AD3 | 34:7ACF |
Die Offsets der speziellen Tabelle 1 sind wie folgt:
| Pokémon < 0x98 | Pokémon >= 0x98 | Icognito | Ei | |
|---|---|---|---|---|
| 1. Tabelle | 34:56A3 | 34:56A3 | 34:63D1 | 34:6222 |
Es handelt sich bei den Tabellen um Pointertabellen und jeder Pointer steht für ein Pokémon. Wichtig ist, dass der 0. Eintrag mit dem Pokémon der Nummer 1 korrespondiert. Gleiches gilt für die Icognitos. Das finale Offset der Daten ist dann worauf der 2-byte-Pointer zeigt in derselben Rombank. Dort, wo sich die Tabellenoffsets der Pokémon mit den Nummern >= 0x98 unterscheiden, ist natürlich der 0. Eintrag in der Pointertabelle der des 0x98. Pokémon und so weiter.
Für das Ei sind jeweils die finalen Offsets angegeben.
Die spezialen Tabelle 1 wird in der Statusanzeige der Pokémon verwendet und ihre Daten werden nach denen, der (normalen) Tabelle 1 verarbeitet, so dass eine längere Gesamtanimation entsteht.
Die ersten Daten
Die erste Tabelle beinhaltet spezielle Codes und Daten für die jeweiligen Codes. Der grundsätzliche Aufbau sieht wie folgt aus:
[Code][Daten]…[FF]
Es gibt bloß 4 feste Codes. Alle anderen Codes sind Eintragsnummer (sog. Indizes) in den zweiten Daten. Die Codes sind und ihr Datenbyte bedeutet:
Code Daten bedeuten 00 Zeigt das normale Bild und wartet xx Runden FF Beendet die Tabelle. Datenbyte kann, muss aber nicht vorhanden sein FE Setzt die Anzahl xx der Wiederholungen FD Startet Wiederholungen bei Eintragsnummer xx in der ersten Tabelle andere stellt den Index in den zweiten Daten dar. Es wird für xx Runden gewartet
Die Wiederholungen funktionieren, indem man irgendwann, zweckmäßigerweise aber eigentlich direkt, vor dem Teil, den man wiederholen möchte den FE-Code setzt und die Anzahl der Wiederholungen festlegt. Nun folgen Daten bis irgendwann das FD kommt und die Sache einleitet. Die Daten vom FD-Code müssen auf irgendeinen Eintrag hinter dem FE-Code-Eintrag zeigen, da es ansonsten dauerhaft in einer Schleife gefangen ist. Beispiel:
{[01][20]}{[02][1C]}{[FE][02]}{[03][08]}{[04][08]}{[FD][03]}{[FF]} Einträge
0 1 2 3 4 5 6 Eintragsnummern
Daraus folgt folgende Abfolge
Animation 01 und 20 Runden warten
Animation 02 und 1C Runden warten
Animation 03 und 08 Runden warten
Animation 04 und 08 Runden warten
Animation 03 und 08 Runden warten
Animation 04 und 08 Runden warten
Ende der Animation
Die zweiten Daten
Ein Code aus den ersten Daten ruft einen Eintrag in dieser Tabelle auf. Dabei ist zu beachten, dass der Code eine Nummer größer als der eigentliche Eintragsindex ist. Es gilt also Code -1 = eigentliche Eintragsnummer. Die Pointer in der 2. Tabelle zeigen auf noch eine Pointertabelle. Die Eintragsnummern korrespondieren mit den jeweiligen 2-byte-Pointern.
Die Pointer zeigen auf:
[Zähler][Tilenummer]*n n ist die Nummer der Tiles, die gesetzt werden. Jedoch ist es nicht Schlimm, wenn zuviele Tilenummern dastehen soweit diese keine anderen Daten beeinträchtigen.
Die Tilenummern sind die Tilenummern, die später auf dem "Standard-Pokémon-Bild verteilt werden. Desweiteren entsprechen sie den Tilenummern im originalen Bild und nicht den Tilenummern im späteren Ram (die anders sind da kleine Bilder vergrößert werden). Der Zähler stellt die Eintragsnummer in den dritten Daten dar.
Die dritten Daten
Die dritten Daten sind die einzigen, die eine Feste Eintragslänge in dem Sinne haben, neben den 2byte-Pointertabellen wohlgemerkt (die sind Standard 2 Bytes pro Pointer). Die Eintragslänge ist an die Bildbreite bzw Höhe gebunden. Es sind 4 Bytes Pro Eintrag, wenn die Bildhöhe 5 Tiles beträgt, 5 Bytes für 6 Tiles und 7 Bytes für 7 Tiles Höhe.
Die Daten geben die vertikale und horizontale Position im Bild an. Es werden dazu die Bits angeguckt und ein gesetztes Bit (=1) steht für "Spezial-Tile benutzen" und ein ungesetztes Bit (=0) steht für "Original-Tile benutzen". Es wird spaltenweise abgefragt, daher ergibt sich dann auch die x-Position im Bild, denn wenn eine Spalte abgefragt wurde, kommt die nächste dran. Das geht solange, bis 5 mal, 6 mal oder 7 mal abgefragt wurde - je nach Größe des Bildes. Für jedes gesetzte Bit wird eine Tilenummer aus den zweiten Daten genommen und auf das Bild gesetzt. Die Lesung der Bits ist von 0 zu 7 bei jedem Byte. Es ergibt sich daraus auch die feste Größe für die verschiedenen Bildhöhen, denn 7*7 Bits sind nur in 7 Bytes unterzubringen, während 6*6 Bits in 5 Bytes und 5*5 Bits in 4 Bytes passen.
Modellvorstellung solcher Daten für ein Bild von 6*6 Tiles:
Jeder Buchstabe steht für die Bit eines Bytes. xxxxxxxx yyyyyyyy zzzzzzzz aaaaaaaa bbbbbbbb Bits 76543210 76543210 76543210 76543210 76543210 Bitnummern Gedankliche Umordnung dieser in Spalten a 6 Bit (weil eine Spalte in unserem Beispiel 6 Tiles hat) (Bits von rechts nach links gelesen) xxxxxx Spalte 0 543210 yyyyxx Spalte 1 321076 zzyyyy Spalte 2 107654 zzzzzz Spalte 3 765432 aaaaaa Spalte 4 543210 bbbbaa Spalte 5 321076
Die Hälfte vom letzten Byte der Daten ist somit nutzlos. Es war auch klar, da 6*6 / 8 = 4,5 ergibt und und somit ein halbes Byte fehlt. Da es im Rom aber keine halben Bytes gibt, bleibt es einfach bloß unverwendet im 5. Byte.
Rekapitulation
Die ersten Daten sind für den gesamten Ablauf zuständig. Jetzt kommen aber noch aufgerufene Unterdaten in den zweiten Daten hinzu. Diese geben bloß immer für die ihnen übergebene Eintragsnummer die zu verwendende Zählung in den dritten Daten an und stellen die Tilenummern für die Tiles, die später ins Bild kommen. Die dritten Daten geben bloß die Position jedes Tiles anhand einer fortlaufenden Ja/Nein-Bestimmung an.
Beispiel Bisaknosp
Das Beispiel geht von den normalen Bildern aus, also nicht den "Extrabildern" in der Statusansicht.
Bisaknosp hat die Pokémon-Nummer 2. Daher sind die folgenden Tabellen zu verwenden:
| Bisaknosp | |
| 1. Tabelle | 34:4695 |
| 2. Tabelle | 35:4000 |
| 3. Tabelle | 34:64EF |
Das Originalbild von Bisaknosp. Der blaue Kreis zeigt auf das erste zusätzliche Tile, das für Animationen verwendet wird, Tile 0x24.
Wir kriegen das Offset der ersten Daten wie folgt:
0x02 - 0x01 = 0x01 (Die Eintragsnummer ist also 0x01)
0x01 * 0x02 = 0x02 (Das, was wir zum Tabellenoffset hinzuaddieren müssen um zum eigentlichen Eintrag zu kommen)
1. Tabelle hat die Pointer für die ersten Daten: 34:4695 + 0x02 = 34:4697 Der Pointer zeigt auf 34:489C. Dort sind also die ersten Daten. Sie sagen folgendes aus:
{[00][06]}{[01][08]}{[02][14]}{[01][06]}{[FF]} Einträge
0 1 2 3 Eintragsnummern
Daraus folgt folgende Abfolge
Originalbild zeigen und 06 Runden warten
Animation 00 und 08 Runden warten
Animation 01 und 14 Runden warten
Animation 00 und 06 Runden warten
Ende der Animation
Da 00 nur das Originalbild zeigt, ist es uninteressant.
Nun errechnen wir wie oben wieder das Offset der zweiten Daten mittels der Nummer des Pokémons. Das Offset ist 35:421E. Dort sehen wir 3 Einträge, nämlich [24][42][28][42][35][42] Das sind alles Pointer. Es war offensichtlich, dass es bloß 3 Einträge sind, weil der 0. Eintrag bereits genau auf das Byte nach dem 2. Eintrag pointet.
Wir wollen Animation 00 näher betrachten und gehen daher zu 35:4224. Dort sehen wir den Zähler, nämlich 0x00 und eine unbekannte Anzahl von Tilenummern, wir können uns jedoch schon denken, dass diese bei dem Offset aufhören, wo der 1. Eintrag der Pointerliste hinzeigt, bei 35:4228. Jedoch zu wissen, wo das Ende ist, ist nicht entscheidend.
Wir kriegen schnell das Offset der 3. Daten raus, das ist für Bisaknosp 34:66F9. Da Bisaknosp eine Bildhöhe von 6 Tiles hat und demnach jeder Eintrag dort bloß 5 Bytes lang ist und wir den 0. Eintrag wollen, betrachten wir also die ersten 5 Bytes, [00][00][C2][00][00].
Da insgesamt nur 3 Bit "belegt" sind, ist unsere Vermutung richtig, dass es bloß 3 Tilenummern gibt. Um deren Position jetzt rauszukriegen, werden wir abzählen. 2 Bytes = 16 Bits. Durch 6 (Zeilen) geteilt ergibt das 2 (Spalten) und 4 Bits (in der 3. Spalte) über. C2 ist in 11000010 in dual (binär). Also 2. Spalte (Zählung fängt bei 0 an) und 5. Tile von oben ist belegt (da das 0. bis 4. Tile frei sind und die erste 1 in C2 entscheidend ist. Jetzt sind wir in der 3. Spalte und das 4. und 5. Tile von oben sind "belegt". Der Rest des Bildes bleibt unverändert, da nur noch nicht gesetzt (=0) Bits kommen. Jetzt sehen wir uns wieder in den zweiten Daten um und finden heraus, dass es sich um die Tiles 0x24, 0x25 und 0x26 handelt. Es ergeben sich folgende Positionen für die Tiles:
0x24 bei X 2 und Y 5 0x25 bei X 3 und Y 4 0x26 bei X 3 und Y 5
Das entstandene Bild sieht so aus:
Die Koordinaten und die Rechnung werden durch optisches Gutaussehen bestätigt.
--Tauwasser 01:58, 8. Okt 2005 (CEST)

