Hallo Gaor,
es freut mich, dass Du mitmachen möchtest. Die Lernkurve in diesem Projekt ist sehr steil,
mit der Zeit erschließt sich der Sinn, vor allem wenn man das Spiel schonmal gespielt hat
und eine grobe Vorstellung davon hat, wie es funktionieren könnte.
Das Kampfsystem ist aber schon eine harte Nummer, da Kampflogik und Grafikausgabe
nicht klar getrennt sind.
Mein Wissen zu FIG_LIST_HEAD:
Es handelt sich um das erste Element einer doppelt verketteten Liste.
Welche Informationen in der Liste gespeichert sind weiß ich nicht vollständig,
aber ich vermute es könnte sich um Beschreibungen der Darstellung handeln.
Die Charakterbögen der Gegner sind auf jeden Fall woanders (ENEMY_SHEETS) gespeichert.
Die Funktion FIG_set_0e(fight_id, val) z.B. such in dieser Liste nach einem Element,
in welchem die fight_id (ptr + 0x10) mit der übergebenen fight_id übereinstimmt.
Wenn das Erste gefunden wurde, wird die Stelle (ptr + 0x0e) mit dem übergebenen Wert val überschrieben
und die Stelle (ptr + 0x12) auf 1 gesetzt.
EDIT: Die Funktion FIG_draw_figures() in der gleichen Datei iteriert über alle Listenelemente und
zeichnet sie nur auf dem Bildschirm, wenn (ptr + 0x12) gleich 1 ist.
Entweder es bedeutet es, dass die Figur auf dem Spielfeld ist (presence flag) oder
die Figur hat sich bewegt und muss neu gezeichnet werden (update/refresh flag).
Ein Anfang wäre die vollständige Datenstruktur dieser Listenelemente im Wiki aufzustellen und
die Datentypen und Bedeutungen Schritt für Schritt nachzutragen.
Ein Anfang:
Die Größe eines Listenelements ist 35/0x33 Byte:
Adresse Typ Bedeutung
0x00 s16 ???
0x02 s8 Sprite Nummer
0x03 s8 X-Koordinate (auf Schachbrett)
0x04 s8 Y-Koordinate (auf Schachbrett)
0x05 s8 ???
0x06 s8 ???
0x07 s8 ???
0x08 s8 ???
0x09 s8 ???
0x0a s8 ???
0x0b s8 ???
0x0c s8 ???
0x0d s8 ???
0x0e s8 ???
0x0f s8 ???
0x10 s8 Kampf ID {-1 = ungültig}
0x11 s8 ???
0x12 s8 ??? presence flag
0x13 s8 ???
0x14 s8 ??? object_id
0x15 s8 ???
0x16 s8 ???
0x17 ptr* Grafiksprite
0x1b ptr* nächstes Listenelement
0x1f ptr* vorheriges Listenelement
Wenn etwas noch nicht klar ist kann es später nachgetragen werden.
Die Datentypen kannst Du daran erkennen, mit welcher Funktion darauf zugegriffen wird:
host_readbs() => b [Byte] s [signed]
host_readb() => b [Byte] [unsigned]
host_readws() => w [word/short] s [signed]
host_readds() => d [doubleword/long] s [signed]
Wenn es machbar ist, sind auch mögliche Werte der einzelnen Einträge interessant.
Jetzt kann gesucht werden, wann diese Funktionen aufgerufen werden.
Oder man verändert die Funktionen gezielt und beobachtet was passiert.
printf() ist auf jeden Fall sehr hilfreich.
Ja, ich habe direkt mit dem Dungeon-Handler für die Zwingfeste angefangen.
Den ersten Level habe ich schon fertig bekommen, es fehlen also noch vier Level.
Würdest Du Gaor einen Wiki-Account anlegen?
Das ist korrekt!
Das wäre die einfachste Variante.
Alternativ nehme ich auch Patches oder (die Krönung) wäre mit Git.
(01.02.2016, 00:30)gaor schrieb: Nachdem ich nun so ein bisschen drin bin, dachte ich, ich kann vielleicht auch ein bisschen mithelfen, und fand auch direkt klare Handlungsanweisungen von HenneNWH in einem früheren Beitrag (http://www.crystals-dsa-foren.de/showthr...#pid142632). Aber es ist ja ein Wahnsinn, sich da so weit einzuarbeiten, dass man wirklich mal eine lokale Variable "versteht"!
Assembler in C übersetzen ist schon mühsam genug, aber dann noch verstehen, was der Code wirklich tut ...!? Ich bin schon ziemlich beeindruckt davon, dass es doch so viele Funktionen und globale Variablen sind, die bereits "entschlüsselt" werden konnten. Ich dachte, ich fange mal mit dem Kampfsystem an, und versuche zu verstehen, wie das funktioniert - konkret wollte ich den Sinn von FIG_LIST_HEAD und der dort gespeicherten Werte verstehen. Da scheinen ja recht zentrale Daten des aktuellen Kampfes gespeichert zu sein. Gibt es irgendeine Stelle, an der ihr sowas dokumentieren würdet?
Ich muss echt sagen, dass ich nach Stunden des Code-Durchstöberns immer noch nicht viel verstehe. Was zur Hölle macht denn beispielsweise die Funktion `FIG_set_12_13` (oder `FIG_reset_12_13`) in seg006?! Da geht's offensichtlich um den an Stelle 0x12 gespeicherten Wert und der kann die Werte 0,1,2,3 annehmen, aber was bedeutet das? In der Funktion `FIG_set_0e` hat jemand kommentiert, es handle sich um eine "presence flag". Was auch immer das ist: Habt ihr das herausgefunden, indem ihr entsprechende DEBUG-logs hinzugefügt habt und das Spiel so lange gespielt habt, bis ihr entsprechenden Output generieren konntet? Oder wie würdet ihr bei sowas generell vorgehen?
es freut mich, dass Du mitmachen möchtest. Die Lernkurve in diesem Projekt ist sehr steil,
mit der Zeit erschließt sich der Sinn, vor allem wenn man das Spiel schonmal gespielt hat
und eine grobe Vorstellung davon hat, wie es funktionieren könnte.
Das Kampfsystem ist aber schon eine harte Nummer, da Kampflogik und Grafikausgabe
nicht klar getrennt sind.
Mein Wissen zu FIG_LIST_HEAD:
Es handelt sich um das erste Element einer doppelt verketteten Liste.
Welche Informationen in der Liste gespeichert sind weiß ich nicht vollständig,
aber ich vermute es könnte sich um Beschreibungen der Darstellung handeln.
Die Charakterbögen der Gegner sind auf jeden Fall woanders (ENEMY_SHEETS) gespeichert.
Die Funktion FIG_set_0e(fight_id, val) z.B. such in dieser Liste nach einem Element,
in welchem die fight_id (ptr + 0x10) mit der übergebenen fight_id übereinstimmt.
Wenn das Erste gefunden wurde, wird die Stelle (ptr + 0x0e) mit dem übergebenen Wert val überschrieben
und die Stelle (ptr + 0x12) auf 1 gesetzt.
EDIT: Die Funktion FIG_draw_figures() in der gleichen Datei iteriert über alle Listenelemente und
zeichnet sie nur auf dem Bildschirm, wenn (ptr + 0x12) gleich 1 ist.
Entweder es bedeutet es, dass die Figur auf dem Spielfeld ist (presence flag) oder
die Figur hat sich bewegt und muss neu gezeichnet werden (update/refresh flag).
Ein Anfang wäre die vollständige Datenstruktur dieser Listenelemente im Wiki aufzustellen und
die Datentypen und Bedeutungen Schritt für Schritt nachzutragen.
Ein Anfang:
Die Größe eines Listenelements ist 35/0x33 Byte:
Adresse Typ Bedeutung
0x00 s16 ???
0x02 s8 Sprite Nummer
0x03 s8 X-Koordinate (auf Schachbrett)
0x04 s8 Y-Koordinate (auf Schachbrett)
0x05 s8 ???
0x06 s8 ???
0x07 s8 ???
0x08 s8 ???
0x09 s8 ???
0x0a s8 ???
0x0b s8 ???
0x0c s8 ???
0x0d s8 ???
0x0e s8 ???
0x0f s8 ???
0x10 s8 Kampf ID {-1 = ungültig}
0x11 s8 ???
0x12 s8 ??? presence flag
0x13 s8 ???
0x14 s8 ??? object_id
0x15 s8 ???
0x16 s8 ???
0x17 ptr* Grafiksprite
0x1b ptr* nächstes Listenelement
0x1f ptr* vorheriges Listenelement
Wenn etwas noch nicht klar ist kann es später nachgetragen werden.
Die Datentypen kannst Du daran erkennen, mit welcher Funktion darauf zugegriffen wird:
host_readbs() => b [Byte] s [signed]
host_readb() => b [Byte] [unsigned]
host_readws() => w [word/short] s [signed]
host_readds() => d [doubleword/long] s [signed]
Wenn es machbar ist, sind auch mögliche Werte der einzelnen Einträge interessant.
Jetzt kann gesucht werden, wann diese Funktionen aufgerufen werden.
Oder man verändert die Funktionen gezielt und beobachtet was passiert.
printf() ist auf jeden Fall sehr hilfreich.
(01.02.2016, 08:29)Obi-Wahn schrieb:(26.01.2016, 10:02)HenneNWH schrieb: Das könnte an diesem Wochenende passiert sein.
Ist etwas passiert?
Ja, ich habe direkt mit dem Dungeon-Handler für die Zwingfeste angefangen.
Den ersten Level habe ich schon fertig bekommen, es fehlen also noch vier Level.
Würdest Du Gaor einen Wiki-Account anlegen?
(01.02.2016, 23:34)Rabenaas schrieb: Wenn ich raten soll, dann würde ich sagen, Henne hat das meiste durch Code Review herausgefunden. Allerdings ist die Methode, einfach printf's einzufügen, auch erfolgversprechend. Dokumentieren würde ich das im Quelltext, und den dann hier zum Einbau hochladen.
Das ist korrekt!
Das wäre die einfachste Variante.
Alternativ nehme ich auch Patches oder (die Krönung) wäre mit Git.