[Pokémon FireRed Version] Pokémon Sovereign of the Skies - Source Code

  • Nachdem mittlerweile der (managed) source code Ordner von Pokémon SotS immer mehr anwächst, dachte ich es könnte für den ein oder anderen vielleicht ganz interessant sein, was so Codetechnisch hinter diesem Projekt steckt - Weswegen ich mich entschieden habe den Source Code zu veröffentlichen. [Eigentlich hat Wodka mich gezwungen]
    Das ganze ist ohne Anspruch auf Vollständigkeit oder Funktionalität zu verstehen, einige Elemente, die Inhalte aus dem Spiel verraten würden, z.B. Sprites, wurden entfernt. Der Code ist kompilierbar, allerdings auf einigen Ebenen von Pokémon SotS abhängig und deswegen so nicht auf eine BPRE Rom anwendbar.


    Solltet ihr einzelne Elemente des Codes verwenden wollen, bitte dies zu kreditieren, bzw. entsprechend in eurem Projekt vermerken.


    Das wars auch schon, wer ein bisschen ASM und C versteht, wird das meiste zumindest lesen können, der Code ist allerdings auch nicht unbedingt durchdokumentiert. Zu finden das Ganze unter https://github.com/SBird1337/source_of_the_sovereign/


    ~Sturmvogel


    Let the old ways live and prosper in the hearts of our young



  • This one is really awesome! I've tried to configure it on my own and successfully inserted it into a bpre ROM(obviously, not functioning lol)
    My question is: (in main.asm)
    1.

    Code
    1. .open "base/bpre0.gba","built/Pokemon SotS.gba",0x08000000


    Why should we open bpre0.gba here? I guess only the latter part is essential
    2.
    As you didn't assign the offset of insertion in linker.ld, will .importobj do some similar work according to the offset assigned by .org? (i.e. link the object with the offset, and objcopy)

  • Well the tool used to insert the linked code is called armips, which is an assembler different from as. The problem is that the tool is not as popular and does not have all the features as and the gcc toolchain have, which is why i am compiling using GCC first, linking with LD and then inserting using armips. What armips can do, is interact with files and write code directly into them, which is why I use .open "base/bpre0.gba" - obviously I did not include a ROM into the git repository. The changes made in main.asm are then written to it (basically everything in patches/*.asm) and then the actual code, the text and data section are written to 0x09750000 which is what .importobj does. It can dynamically write the whole sections if and only if the files were linked using the --relocatable flag in LD, which is what I did if you take a look at the makefile.


    Just as a warning: This is the source code for an actual WIP project. So not only is the code WIP, but it is also written in order to function with Sovereign of the Skies and some of the code will be dependent on it and therefore wreck a vanilla rom. Still I thought it to be useful just to take a look on how one can insert code and manage a whole project structure with the arm toolchain as well as how some stuff is done.


    ~Sturmvogel


    Let the old ways live and prosper in the hearts of our young


  • At first, thank you for your reply. I have already got a binary of armips v0.8(I don't have a VS2015 to compile it on my own) and added it to my path (grit as well).

    What armips can do, is interact with files and write code directly into them, which is why I use .open "base/bpre0.gba" - obviously I did not include a ROM into the git repository. The changes made in main.asm are then written to it (basically everything in patches/*.asm) and then the actual code, the text and data section are written to 0x09750000 which is what .importobj does. It can dynamically write the whole sections if and only if the files were linked using the --relocatable flag in LD, which is what I did if you take a look at the makefile.


    I now see that you've use the parameter of relocatable so this problem no longer exists. Then I have some other questions:
    1. Although I don't understand some parts in the makefile (like the shell, wildcard, etc), I can see that you've compiled the .s, .S and .c files (wait... why you separate the asm source files into .s and .S?) and linked them together to create linked.o. In other parts, you don't handle the source files(except for the main.asm and all that in /patches). My question is:

    Code
    1. .org 0x081DD0F4
    2. LDR R1, =music_override|1
    3. BX R1

    For this one, how can armips know where music_override is? At that stage, the linked.o is even not imported.
    2. Now we assume that the first question is solved, so the armips can see all the files. But:
    How can you judge the relative offsets of different functions in one source code file?

    Quote

    Just as a warning: This is the source code for an actual WIP project. So not only is the code WIP, but it is also written in order to function with Sovereign of the Skies and some of the code will be dependent on it and therefore wreck a vanilla rom. Still I thought it to be useful just to take a look on how one can insert code and manage a whole project structure with the arm toolchain as well as how some stuff is done.


    Yes, I've read your thread carefully after finding the fact that inserting it into a clean bpre won't work. This way to make a hack is great indeed, as we don't need to manage the offsets and hooks via a hex editor, which can remarkably decrease the risk of misoperation.

  • armips just accepts non-existant symbols to begin with, every compiler does, at least until linking stage. So what happens is the following:


    armips goes to 0x081DD0F4 (0x1DD0F4) and creates a symbolic link to music_override|1 - since the symbol does not exist this link stays symbolic for now. It also writes the branch ex to r1 of course. After all the patch files are handled, armips copies the text section and all the other sections that were outputted by LD in linked.o - it then starts linking, which is where the integrated linker has to assign static offsets to all the source code in the text section it just copied from linked.o and it has to resolve any remaining symbolic link it created on its own. If it can't it will throw an error at this stage.


    In fact, thats nothing armips per se does, but its how a linker must work in order to work properly with different source files. If you take a look at some of the source code there will always be referenced global symbols that might not have yet been created but will be written to the relocatatable object files just as-is (As names)


    As for your second question I don't quite understand what you mean by that. I kinda feel like the above answered that as well?


    ~Sturmvogel


    Let the old ways live and prosper in the hearts of our young


  • armips just accepts non-existant symbols to begin with, every compiler does, at least until linking stage. So what happens is the following:


    OK, I think I've understood what you mean. My second question should be not important now lol.
    At this stage I can't ask more questions, and I will try this format after the exams. Thank you very much for your help!