Changing button mapping in GoldenEye 007 (N64)

Started by Ohrami, May 22, 2022, 11:31:06 PM

Previous topic - Next topic

Ohrami

I want to change the button mapping in GoldenEye but have absolutely no experience in ROM hacking. If anyone else has done this or knows someone who has done this (changed button mapping in GoldenEye) I would appreciate the assistance. Furthermore, if anyone can show me basic guides that would show me how I can learn how to do this myself (it's all I want to do) then I would appreciate it.

FAST6191

Three approaches, maybe four in some technical sense.

1) Change your emulator settings.

2) Hard remap controls. Take your soldering iron, slice things up, throw wires around. Done. Works on anything that works with the controller, no need for cheats/flash carts/mods but naturally needs the controller. 2a) expands this to also include turbo and macros via something like a teensy++ or arduino (take signal in, put signal sequence out being their reason for being/taught in the first lessons in how to use).

3) You hack some software. This is mostly what you are asking about but I have to note the others. In later devices, and naturally the PC, this is also available at system level but this is very much not the case for the N64.

4) is sometimes there are man in the middle devices/controller adapters that will come with an element of programmability. Don't know what exists for N64 in this arena but likely to be expensive and only work for the one controller at a time.


Software hacks then... only one of them is easy and that is not quite available to you just yet at time of writing but probably will be within a year or so*.
Said easy one is once there is a decompilation available (and Goldeneye is one of the big targets) then you can fiddle with that. If you have seen the stuff done for Mario 64 and Zelda then same idea and scope for less time invested coders to play around and do massive changes. Find the control settings in those, follow a guide to getting a means to compile it going on (more annoying than some compilation but less than others and plenty were doing things for the Mario 64 that otherwise did not know coding) and remapping becomes... if you made it to a site like this and wrote a post like that then you can handle that by brute force if you had to (though would suggest analysis). A note though in that your new compilation, even if made with N64 vintage tools, might not be the same as the stock ROM so can be harder to get existing hacks going on with it, at least not without remaking them or essentially porting them to your new version (should be easier than porting hacks between different regions of a ROM but only just).

*most decompilations are also seemingly aiming at being fully commented and labelled where you only need it enough to compile again and preferably any control aspects documented. I have not looked into Goldeneye properly at this stage (I know it is happening though, granted as soon as Mario 64 fell it was fairly obvious that someone somewhere was going for this) and whether there is something public you might be able to play with (if you are asking this sort of question then fear of leaks means you probably won't get access to anything private).

After that we are into traditional control hacking, with likely some bonus perks for this game but more on that shortly. This will necessarily involve you learning some assembly, which is the final boss in ROM hacking (text, graphics, levels... usually pale before this) but this is the easier side of that.

There are three approaches to software based control hacks.

i) You edit the debounce area.

ii) You edit the checks themselves

iii) If available then some games have some more abstract options (possibly the case here).

Debouncing if you are unfamiliar. Switches, aka buttons, are mechanical devices and not binary. When pressed they can oscillate between pressed and not pressed (or even enough resistance to get it into the forbidden zone in your classic voltage logic levels from electronics courses) and this happens on timeframes that bother things usefully measured in megahertz -- if two actions happen because of one press and the first action happens but the second a few instructions later does not fire because it changed when the player would not have done anything different then you get bad controls which is the death of most games. If you have ever had a mouse start double clicking on you without you wanting it too then this is switch bounce when it turns into a failure mode.
To that end once per frame in well coded games the state of the controls are copied from where the hardware says they are to some area of general memory and everything operates off that.

Find something that reads this state (usually a big long run of binary as switch is either pressed or it isn't so no sense burning dozens of individual bytes when you need one bit per) and twiddle one to be another and you have your hack. Sometimes viewed as the cruder option it never the less works.

Changing the check themselves... what goes and fetches the debounced area (or memory area in the case of non debounced games) will go out looking for specific conditions to happen (more likely though is boolean logic for things -- blank everything else with say an AND and a 1 in the suitable place with everything else zero and if what I care about is high/low** then react accordingly). Change this check to look for another bit and you have your hack. If doing say C stick inversions then easy enough to make a positive analogue number negative or change the range if it is a range (if range is say between 0 and 200 then to invert 25 you take it from 200 instead, works just as well when it is 175 you need to turn into 25). This is considered cleaner than the debounce method as debounce might be game wide (or at least game mode if say menu uses separate code) where this will be action specific, though it also means it is action specific so if there are 50 different actions all using a button you get to edit all of them where the debounce crowd might be done and playing long before you get done.

**I don't know if you saw the "a press" speedruns of Mario 64m, https://www.youtube.com/watch?v=kpk2tdsPh0A for a nice intro, they note that you can press and hold to achieve different effects. Technically this puts us into edge logic (as in rising edge and falling edge or positive edge and negative edge) but the principle is still the same and you are still going to be setting breakpoints to watch for anything going to grab the debounced area (or control area of memory).

The third case is afforded when the games themselves have some measure of control customisation, even limited ones. Goldeneye is pretty famous for this even if it is not basically infinite PC like customisation (few things on consoles are but it does change things). Here the games themselves have their own abstraction layer that different things can react to depending upon setup, and it might well be at some level you can tweak without code editing as thus what many control editors if you find such a thing for some game are likely using (though some might know the code and be able to react accordingly or have their own setup like this on top of code edits).
It might be that specific schemes are all there is, or it might be that it is basically PC a like but the devs crushed it down to some ones they thought sensible or amusing.
You can try watching what happens when you change control schemes with standard cheat searches but most likely you will have to get your hands dirty with reverse engineering the code like the others on this part even if ultimately it is a list of mappings somewhere you can causally tweak with a hex editor.
Mappings like this existing at all can trouble some aspects of the other areas by making them a bit more abstract than the basic case, though again it will all have to read the memory state or debounced section at some point, or do something as a result you can key in on***, and at that point all of that amounts to not a lot.

***Press z to shoot bullet necessarily means the bullet counter goes down as a result. Find the bullet counter (don't use the moonraker laser or melee attacks) via normal cheat search methods ( https://web.archive.org/web/20080309104350/http://etk.scener.org/?op=tutorial https://doc.kodewerx.org/hacking_n64.html ) and whatever altered the counter here will be able to work backwards to where it read the control state to know to do it in the first place (this is called tracing in case you were unaware).

Whether you go another step further and alter any in game tutorials or button prompts is up to you but at that point we are into text/graphics/level/audio/whatever hacking so I will leave that for now.


Ohrami

Thanks a lot for the extremely detailed response. It was actually more than I was expecting. Point 1 would not be possible for me since I want this on original hardware. Point 2 is doable and acceptable for my applications, but it's actually complicated by the fact that I want to make it so that inputs that were performed on controller port 1 are read by the game as inputs from controller port 2. I know this is possible using hard control remapping, but I'm not sure how I would do it. It seemed like option 3 may in fact be a simpler option, and I figured it's even possible somebody already did this (hacked the game to allow button remapping, or just remapped buttons in a different hack), so I could just copy what others had done.

You said that for the traditional control hacking methods, I'll need to learn assembly. Precisely what about assembly should I learn, and how can I view the game's assembly instructions in a way that will allow me to determine precisely what affects what? Note that I have no programming experience at all, and I'm aware that assembly is quite low-level and not at all simple, but perhaps learning to change a few instructions may be just simple enough for me to manage it with some assistance.

KingMike

"My watch says 30 chickens" Google, 2018

FAST6191

A curious choice of action (troll hack, some kind of screen swap without being a screen swap, want to leave a steering wheel in whatever or broken port are my usual guesses for why there). One of the more interesting aspects of Goldeneye though is that there are control schemes that read the second controller for a single player (ostensibly making it a twin stick game, or in the case of my friends and I an exercise in frustration for co-op that not even bomberman rivals), which might be useful in this.
If on hardware then you also have the option of making some kind of multi way switch do things for you as well.

Equally if it is less remapping and more straight input swap then you might be able to a bit more creative and change where the debounce section is read from to be from port 2 or whatever (without looking then most consoles with multiple input options have the same thing just another however many bytes on and that is far more basic -- might even be as simple as setting a break on read for the area you want, noting the instruction and changing its read destination by whatever means are good).

Control hacks possibly have been done but they are not as common as some think they might be, especially when most people doing N64 will be doing emulation.

As above the N64 uses MIPS, a rarer tweak on it than some other things you might encounter but common enough. Still it is r3400i if you want the specific thing
http://www.emulationzone.org/consoles/n64/tech.htm https://people.cs.clemson.edu/~mark/R4300i.pdf
It is close enough to the modern day that out there might be something to learn assembly directly from (trying that for something like the 6502 and z80 popular on older devices still gets far more tricky to ensure it teaches modern thought on programming).
https://www.plantation-productions.com/Webster/ https://stuff.pypt.lt/ggt80x86a/asm1.htm then being for the PC but will teach you ideas worth knowing such that I usually tell people to get the basics there and then move sideways -- the instruction mnemonics might change but you are going to be doing maths, cleaning up the memory registers to use them for something else aka housekeeping and changing where you execute next depending upon previous parameters so you just learn the versions for that CPU and any notable quirks.

You can view code with a disassembler (though as noted above the N64 is amenable to decompilation as well if you are really bored, unless it was trivial* then I don't think I have ever seen a ROM hacker go directly for the decompiler for a more basic hack like this). Finding instructions is kind of the whole trick. Still the tool you want is a debugging emulator, or debugger in a pinch. These will feature a concept called breakpoints.
Three main classes of breakpoint.
Break on read (BPR). Will say hold up something read the section you told me to watch, here is what it is and what the state of the system was at the time.
Break on write (BPW) Same but for writing instead.
Break on execute (BOE/BPE). If the CPU reads this area and uses it for an instruction then it will do the hold on now thing. Run to line is a specialist case of this.
Those being the main three things memory will do (and what most computer security starts by considering) means they are common to any self respecting debugging emulator/debugger.

Some will feature break on access as well to combine those to save you doing multiple inputs.

Log versions of said same usually exist so you can read later. Code logging is a more advanced thing that not all emulators will feature but it is useful too -- the general idea is it notes down new things it sees so do everything but what you want to look at (move, idle, let the music play, let background animations roll...), then the new last thing done will be what you want to look at. https://fceux.com/web/help/CodeDataLogger.html

*the game being written in some high level and/or easily decompiled things like lua, java, python or C#.

https://www.romhacking.net/documents/361/ is for an old command line GBA emulator but the principles it covers apply to just about everything, and where it does not (some modern PC stuff) it is just another minor level of abstraction to go through.
Also while it is showcasing an incredibly primitive take on the concept and misses a few ideas I might have elaborated upon (justifiably though as it is not relevant to the specific point) then this video https://www.youtube.com/watch?v=WH3ja70_okA is one of the more succinct demonstrations of playing with a debugger to solve a goal I have ever seen.

I don't know what we are suggesting for N64 debuggers these days -- if the base emulators don't feature it or feature weak ones (sometimes they will include GDB stubs to do things like https://wrongbaud.github.io/posts/ghidra-debugger/ ) then there is usually a fork, and it can pay to go see what the tool assisted speedrunners (it is kind of essential to do such things) and homebrew devs are using (and there are some, see some of the fun with mario 64).