Multichoices

Wir sammeln alle Infos der Bonusepisode von Pokémon Karmesin und Purpur für euch!

Zu der Infoseite von „Die Mo-Mo-Manie“
  • So, in letzter Zeit habe ich mich mal etwas mit Multichoices beschäftigt und habe mir gedacht vielleicht könnt ihr das ja auch brauchen. Also erstmal was werden wir hier machen? Zu allererst werden wir lernen wie man multichoices anwendet, hierbei gibt es ein kleines Beispiel in XSE. Danach werden wir den Text der Multichoices ändern und wenn wir dann noch nicht genug haben werden wir noch versuchen neue einzufügen.

    Fangen wir vorne an: Was brauchen wir?

    • Einen Hexeditor(ich verwende Next Soft Hex Editor MX)
    • Eine Rom(ich verwende FR Deutsch und empfehle euch für das Tutorial die selbe zu nehmen)
    • Einen Emulator zum testen(Ich verwende immer vba, bleibt aber euch überlassen)
    • EInen Scripteditor(hier XSE)
    • Ein Gehirn(Ich verwende SBirdTec Brain.exe, sehr Leistungsstark :D)


    Was sind Multichoices?


    Multichoices sind Auswahlmöglichkeiten wie "Ja/Nein" oder etwa beim Dialog im Fahrradladen. Mit Multichoices kann man dem ewigen "Ja/Nein" etwas entgehen, Multichoices haben höchstens 8 Auswahlmöglichkeiten, bei mehr(wir werden diese später ändern) crashed das Spiel.


    Wie verwendet man Multichoices?


    Hierzu gibt es in XSE einen Scriptbefehl: "multichoice", dieser funktioniert so:


    [multichoice][X Koordinate][Y Koordinate][Index][CloseOnB]


    multichoice leitet den Befehl ein, das ist wohl klar, X Koordinate bestimmt die Position in der X Achse(ein Koordinatensystem wird man kennen denke ich), Y dann natürlich die Y Achse. Es handelt sich bei der Position immer um die obere linke Ecke. Index bestimmt die Multichoice Box. Hierzu gibt es eine Liste:



    Diese Sollte man kennen sofern man einmal Pokemon gespielt hat denke ich^^ Also man setzt eine dieser Zahlen für Index ein(natürlich in Hex!) und bekommt das entsprechende ergebnis, der letzte Pararmeter "CloseOnB" bestimmt ob die Box geschlossen wird wenn man B drückt. er ist entweder 0 oder 1(wobei ich glaube das 1 dafür da ist um die Box bei b NICHT zu schließen was etwas verwirrend ist da 1 normalerweiße true ist)


    Ein Multichoices aufruf könnte demnach so aussehen:


    Das heißt es erscheint eine Box oben links in der Ecke mit dem Inhalt:


    Soviel zum Aufruf. Natürlich müssen wir den Inhalt auch verarbeiten. Hierzu müssen wir wissen dass der Rückgabewert wie so oft in LASTRESULT(auch bekannt unter 0x800D) gespeichert wird, also können wir einfach LASTRESULT abfragen:



    Ich habe hierzu keinen ganzen Script geschrieben. Scripting sollte man schon beherrschen wenn man Multichoices haben will. Zur erklärung es wird einfach Lastresult auf ergebnisse geprüft. 0x0 ist Auswahl 1 und so weiter. Zu beachten ist dass 0x7F benutzt wird wenn der Spieler die B-Taste drückt, natürlich nur sofern er auch B drücken darf.(CloseOnB, wir erinnern uns)
    Soviel zum Thema aufruf.


    Ändern von Multichoices


    So, natürlich wollen wir nicht bei den Nintendo vorgaben bleiben wir wollen unsere eigenen Multichoices. Hierzu gibt es einen Header(Eine Sammlung von Pointern wenn man so will), in Feuerrot BPRD(Deutsch) ist dieser an 3DF9A0, das ganze ist so Aufgebaut:


    [Pointer zu den Texten][Anzahl der Auswahlmöglichkeiten][nop][nop][nop]
    Der Pointer zu den Texten dient zur Anzeige des richtigen Textes(ein Pointer, umgedrehtes Offset und hinten 08 das wisst ihr hoffentlich :))
    Die Anzahl der Auswahlmöglichkeiten gibt an wie viele Möglichkeiten man hat und nop(hier 00) dient zur Trennung der einzelnen multichoices.

    Das rot markierte ist der Pointer. Das grüne die Anzahl der Choices und das gelbe sind die nop bytes. Der Header wurde von mir markiert wie man sieht.


    So aber wie ändern wir das ganze jetzt, nun wir werden wohl versuchen einfach mal einem dieser Pointer zu "folgen", also müssen wir uns das Offset bilden, der Pointer ist: 40F23D08. Das 08 kommt mal weg. Das restliche Offset müssen wir Byteverkehrt aufschreiben, also aus "ABCDEF" wird "EFCDAB", aus unserem Pointer wird also "3DF240", im Hexeditor einfach auf "Suchen - Gehe Zu" und dann dort das Offset eingeben. Hier finden wir zwei weitere Pointer die dann zu den jeweiligen Texten zeigen. eigentlich recht Hackerfreundlich wenn man das mal so sagt :)


    Also nochmal zu unserem Offset, dort steht: C0 78 41 08 00 00 00 00 C3 78 41 08 00 00 00 00, die 00 Bytes sind wieder nop. Mit geschultem auge erkennen wir zwei Pointer, einmal C0984108 und einmal C3784108, diese zeigen zu zwei Texten. Wenn wir also beide Offsets umdrehen können wir(mit Thingy or something like that) den Text ändern. Man beachte, man kann mit dieser Methode keine neuen Choices einfügen, man kann nur die Texte bearbeiten. Neue einfügen werden wir im nächsten Schritt.

    Neue Multichoices einfügen


    So, zu guter letzt wollen wir unsere eigenen Multichoices einbringen, wir fügen also ein index Nummer 0x41 ein. Glücklicherweiße war Nintendo so großzügig das ganze sehr Hackerfreundlich(wie bereits gesagt) aufzubauen. Wir müssen nur unsere Pointer anfügen, wir müssen keine ASM Routine ändern! Das machen wir indem wir in diesem Header(siehe Bild oben) einfach unten ein neues Feld für unsere Choices anfügen. Da haben wir nur leider ein Problem, da ist ganz einfach kein Platz mehr. Wir müssen den Header umpointen...


    Ok, keine Panik, das ganze geht eingeltich Recht einfach wenn man vorher ein Backup macht und den Anweißungen hier folgt^^, wir brauchen erstmal einen freihen Bereich. In meinem Beispiel das Offset 0x800000, dort ist Bereich frei(außer ihr habt dort was hingeschrieben,wie einen Script, dann müsst ihr euch selbst einen freihen bereich suchen.)


    Dorthin kopieren wir uns den Header, ich habe den Header markiert, er geht vom Offset 3DF9A0 bis zum Offset 3DFBA7, also markieren wir das, drücken Strg + C und gehen dann zu unserem freihen Offset, dort markieren wir die selbe Menge an Bytes(519) und drücken dann strg + v. Jetzt ist der Header dort. Jetzt müssen wir noch unser ursprüngliches Offset nehmen und den Pointer der darauf zeigt(es sind zwei) auf unser neues ändern. Unser altes offset war 3DF9A0, wir müssen es jetzt wieder Byteverkehrt aufschreiben und 08 diesmal anhängen, da kommt dann raus: A0F93D08, nach diesem Wert suchen wir in der Rom(finden wir genau zweimal, wieso weiß ich nicht eventuell hat das Intro einen eigenen Platz oder so. Wir werden einfach beide ändern. Wir müssen erstmal aus unserem neuen Offset einen Pointer machen. Ich habe 800000, also brauche ich 00008008, jetzt ersetze ich alle A0F93D08 mit 00008008 und die Rom greift auf den header an meinem Offset zu, wenn wir speichern und das Spiel starten, einen multichoice Script aufrufen und alles normal ist dann hat es funktioniert, an sonsten bitte PN an mich.


    So, jetzt können wir an den Header neues dranhängen, der Header hört auf mit "70F93D0805000000", daran hängen wir jetzt unsere Numero 0x41, ergo ein neuer Pointer, ein neues Offset... ihr solltet nach dem Header ein wenig platz lassen damit ihr in zur not immer weiter erweitern könnt ohne wieder umzupointen. Ich nehme für die neuen Multichoices einfach mal 0x800300, das sollte reichen. Erinnern wir uns an den Aufbau der Multichoices: [pointer][anzahl][nop][nop][nop]


    Mein Offset ist 0x800300, mein Pointer ist also 00038008, sollte mittlerweile klar sein. Meine Anzahl ist, hmm, sagen wir 3(sie darf nicht größer als 8 sein sonst crashed das Spiel), mein "Code" sieht also so aus:
    00038008 03 00 00 00


    Nun müssen wir noch Textpointer an das Offset 800300 schreiben, hierzu öffnen wir mal XSE, schreiben etwas wie:


    #dynamic 0x800400


    Dann haben wir genug Platz für die Pointer auch wenn es etwas Platzverschwendend ist. Danach schreiben wir unseren Text einfach so:



    Wenn wir das kompilieren sagt uns XSE an welche Offsets er das ganze geschrieben hat. Diese nehmen wir wieder alle und schreiben sie dann an das zuvor gewählte Offset(in meinem Fall 800300)


    XSE sagt mir folgende Offsets: 800400 80040A 800414


    Diese werden dann Byteverkehrt gedreht und wieder mit 08, ein Pointer eben :)
    Danach reihen wir sie wie folgt auf:


    00048008 00000000 0A048008 00000000 14048008 00000000


    Das ist unsere Pointerliste und die kommt an unser Offset 800300, der Text wurde geschrieben und "verkabelt" wir können nun "multichoice 0x0 0x0 0x41 0x0" verwenden und testen ob das ganze funktioniert hat.


    Ich hoffe ich konnte euch ein Stück meines Wissens vermachen, wenn es Probleme gibt einfach mich anschreiben :)


    mfg Sturmvogel