Hacking with C

From en64 wiki
Jump to navigation Jump to search

General Discussion

  First of all, as noted in it's respective toolchain section, the differences of n64tree and the GNU toolchain is one is for Windows and the other for *nix users. Making code in assembly can be cool and all, but can be tedious and time-consuming; wasting an ever increasing number of hours in the long run if you're truly investing your time making modifications or codes out of MIPS. Granted, knowing MIPS obviously can be of much avail when it comes to hacking with Nemu64 or an identical program. Just to provide another benefit of hacking: spinout's toolmode code for Zelda: Ocarina of Time! As you can tell, by reading that page, the code essentially a level editor, limited, but is a good poc as well as a practical tool, nonetheless. It's a benefit because, rather than having to completely type up your own program to do such a thing, you're grabbing resources from the game itself! Thus, you need not declare this and that, make all these functions, but rather, utilize the games resources to make an actor placement program in a much shorter period of time (take a look at how small the source is). A con to all this though is that due to the current toolchains we're limited to using, you may (not too often) create a code that doesn't work on emulators outside of Nemu64 due to HLE compatibility issues. E.g. Project64 is optimized to the compiler they used back in the late 90s rather than the actual mips spec.


  Sadly, people have neglected to elaborate to the public how to go about using toolchains to make codes and mods. Long time hackers will simply direct you to tutorialspoint or an identical website to learn the high-level programming languages which is C. Moreover, recently some have made a few tutorials/guides explaining the usage and setup process of the available toolchains (which can be located below). Mind you, they're not too in-depth/elaborate, but they're better than nothing, that's for sure. Ultimately, I intend on being as informative as I can with how to make mods and codes with them once I get a much better understanding. Included along with that, I dream of "revising" the scripts to function for other Nintendo 64 games as well. Again, that will all come with time once I understand them much better... Enough of my jaw jabbering though! To give a basic rundown on these tools. The GCC is a compiler system covering many programming languages high and low. In our case, we're downloading and installing mips-gcc which doesn't pay any mind to Nintendo 64 games being games, but instead looks at is a "MIPS machine," the architecture which it just so happens to support. Sadly, the hacks you see are targeted for Ocarina of Time and Majora's Mask work. With that said, as long as you include all the correct components that make the codes, you can use any of toolchains linked! Heck, you could even just download the newest version of C, mips-gcc and move the files below over and use it for your own toolchain. You just need the required prerequisites and direct your makefile to the proper directories so it knows where the tools are located, of course.


  However, if you're savvy enough, or work off the information found in the archives here, you can convert the tools over with not too much effort (after finding the desired functions and related misc, that is) and create your own personal header file (if you're really good, you gain a good understanding of the game and have multiple headers) for whatever specific game it is that you're reverse engineering! From there, functions in the header(s) are then linked inside of the ".x" file. If I understand correctly: the ".x file (linker script)" follows the ld command language which is basically a collection of command statements that bosses around the GCC, but more can be read with a simple "gcc linker script" search with your favorite search engine. As a continuation, some examples of things you'd document and make headers out of: animations, levels and any/all structs. However the ABI (Audio Binary Interface) and GBI (Graphics Binary Interface) headers can be used between games of identical ucodes (like the F3DEX ones that are used with Super Mario 64 codes. They can be used for games with like microcodes) which are just C macros. Anyway, creating (of finding if they're out there) is how you get around to making incredibly cool modifications and codes for the games you love. It is reasons like this, why we, as a community, aim to map out as many functions as we possibly can.

Required files for a mips-gcc toolchain and their purposes

Overall, the code/mod folder normally is comprised:

  • makefile (can be converted to auto-make if you know what you're doing)
  • source file (your mod's/code's code -- .c)
  • header file (function prototypes/signatures -- mapped structs -- .h)
  • hook file (is a hack to get the code itself called -- .txt)
  • n64.ld (this tells the linker the memory layout and sections of the game -- .ld)
  • linker script (.x)
  • bin2code This is the normal GS code creator (BINCODE)
  • nemucheat This is the Nemu GS code creator.(CHEAT)


Elaborations

More on headers
  To help wrapping your head around the purpose of headers: When I say "struct," I'm talking about what you'd call a data structure (for an elaboration to what a data structure is). First and foremost, go here for help with understanding what an actor or map is. Anyway, be it animations, objects or levels. For example with a specific level structure for a game would include where padding is located, terrain type, collision, etc. An object struct would ideally contain such things like animation type, geographic layout (same as a level would given that they're both wavefront objects), it's size in X, Y, Z, it's interaction with other specific objects or effects or levels, health mater, etc. How do you make such structures for a header file or multiple ones? First of all, you can put as many as you want in a header, but it's best to be organized and separate resources depending on their types/purposes. You'd make such headers by first locating addresses for functions, variables, etc in RAM and once you've collected enough, and know the size, start and end locations of the struct, you can then create it and post it on your header file (being vague and roughly speaking, at least), but you also must include pointers to said structures. You're basically reverse engineering how certain "things" are programmed/how the look before being compiled into the game that you play. As discussed above, the GBI and ABI are just a set of MACROS, and so would certain things like level or character values.

More on hooks:
  In addition to elaborating on what purpose the hook serves: A hook is just a redirection and then resumption of the program flow with your own code running in between. Simply put, it's essentially a "hack" to get your code called. There are other methods to insert a hook than the GameShark method that the current toolchains provide. Normally, you "hook" to a JAL or J instruction by replacing something superfluous/or something that 'won't be missed,' such as a null pointer, and making sure you're not disrupting any arguments or general program flow, obviously. Where you place the hook also depends on what you're looking to do, how often and when you want it to get called. As spoken about in the Noob Portal, you hook to a routine that is checked constantly if you're code needs up dated often like when trying to rewrite a value that is being written to from another location.   A hook "takes away" program flow from the game's code for your own code, and must be done diligently in order to maintain the stack/not lose registers. In some cases, even registers that normally don't need to be saved (aren't preserved across function calls) might need preserving due to the routine being hooked from not expect control flow to go elsewhere, but that wouldn't be a good hook; a good hook is one that replaces a regular jump meaning, using registers and the stack normally. Essentially, just replace a useless pointer (JAL/JR as mentioned above) and have it point to your function, then call the original function and you should be good. Even if a pointer is considered "useless," but isn't null, it can alter program flow drastically if it's in an area where most of the registers are volatile! Also, a hook normally is made out of MIPS rather than C, which can be difficult, but there are exceptions.

More on n64.ld and linker scripts
More infomation into
  As discussed above, when looking at the linker scripts internals for SM64 or Zelda: OoT, you can see it follows the ld command language (read from n64.ld) which is basically a collection of command statements that bosses around the GCC. As stated, it's just basically saying where the RAM entry point is, what data segments the game uses along with further information. That's what I mean by "memory model." It must know the layout of the program/game it's dealing with in the first place of course.

Injecting into ROM

For /actual/ code injection
As you'll notice, some of the sources below are compiled alongside a tool called "z64hook" as well as "rominsert" in the "helper/" directory. They're both just examples/tools for how you could get code running in ROM.

  • z64hook: is merely a hook for ocarina of time hacks; it transfers a large chunk of ROM to RAM upon boot, and places hooks from within the game to execute hacks from (as an alternative to the typical "hook.txt" file you're used to when making GameShark codes). Hence 'plural' "hooks" in the above statement, it sets multiple hooks to work with more than just one hack (addresses can be manipulated in the source).
  • rominsert: is nothing but essentially "put file x at position y in file z"; nothing less, nothing more.

Examples/Sources

Excellent examples

  • toolmode: Hack for the Debugger's version of OoT Master Quest that allows the user to make changes in-game and save those changes to the gamesave, so they appear the next time the user goes to the area the made the changes in.
  • z64-actors: Actors from the Debugger's build of OoT Master Quest that are or are being re-written in C.
    • En_Bird Beta bird. Successfully re-written in C, though the animation plays a bit fast. A branch of it flies in a broken circle.
    • En_Dodojr Baby dodongo. Very little progress thus far, only a few functions successfully work in C.
  • z64actor: Not to be confused with z64-actors, this is a hack for the 1.0 version of OoT that can spawn actors on demand.
  • z64vr: A hack for the Debugger's version of OoT Master Quest that replaces all vowels in in-game dialog to "o"s. (The greatest code ever!)
  • z_snippets: A folder with a few other examples.


n64tree code sources
God Mode
Bombarrows

Guides

(All of the following guides use the Windows build)
Installing MinGW on Windows Vista (if you encounter issues)
Windows installation tutorial
An installation and coding tutorial for Ocarina of Time (MSYS+MinGW) (brief linkerscript explanation)
Basic example and explanation with conditional statements (missing part 1, but the concept is above, essentially)
Installing n64tree on the Windows operating system (images are absent).