Learn how Super Mario 64 for the N64 works, discover what was hidden that may have been used in the final game, and how the game can be modified to be played in a different way. Also, I will help you with making your own codes for Super Mario 64.
Not counting any alpha or beta versions there were four main versions of Super Mario 64; the original Japanese, USA (commonly known as NTSC although the Japanese versions are also NTSC), European (a.k.a. PAL), and the second Japanese version which goes by the name of Shindou Edition and features rumble pack support. There was also a version for the 64DD to demo the hardware, a release for the iQue Player and Virtual console adaptations.
Below you can see a photo of the four versions of SM64 on the N64; first Japanese version top left, the USA version top right, European version bottom left and Shindou version bottom right.
The first Japanese release is the least complete version as it lacks the speech of the later versions and has a number of major bugs whereas the Shindou edition adds to the enhancements of the USA and European versions support for rumble pak as well as further bug fixes. The rumble pak really does make a difference to the game as it vibrates when Mario long jumps, hits a wall, slides down a tree, and so on.
Much of my findings come from using an actual N64 and various cheat devices such as an X-plorer 64 and Equalizer cheat code cartridge, and more recently, emulators-notably Nemu. My intimate understanding of SM64 shows in the codes that I have created, some of which have never been done before. You can check out the codes I have done at Super Mario 64 codes page.
Please read on to learn my findings and discover how Mario's first 3D platform game works while discovering some secrets.
A superb game, one of Nintendo's very first 3D games for their Nintendo 64 console, was apparently created at the same time as The Legend of Zelda: Ocarina of Time, which supposedly runs on a (heavily) modified Super Mario 64 game engine (as did later N64 games by Nintendo). This game showed that Mario worked well in 3D and did away with a lot of the linear limitations of most other games at the time.
In any level (Bob-omb Battlefield, Wet dry world, outside or inside the castle, etc) the game can handle a maximum of 240 objects. An object can be visible such as Mario or a box, or it may lack graphics and be used 'behind the scenes' such as an activator object (as to activate a 1-up when you climb a tree, for example).
Whenever you enter a level there will be a minimum number of objects set up including, of course, Mario. These objects will occupy a number of the available 240 'slots' leaving many more slots for objects that are added on the fly as the game is played. For example, if you stomp a Goomba or break open certain boxes coins will be added; they will use some of the previously unused slots. The game will crash if all the slots are used up, but normally that isn't a problem, but by using various codes that increase how many objects are spawned the game can slow down or even crash.
Every object uses 608 bytes for its 'object structure' but this does not include additional memory that the object may need, such as graphics data. These 240 object structures are doubly linked lists; each structure points to both the next and previous slot (the game was most likely programmed in either C or C++).
An object structure is fundamental for an object's existence in the game world, it contains data that determines how the object looks, how it behaves and also remembers what it's currently doing (example, an object's world position variable stores its position in 3D space). By modifying the object structures it's possible to force objects to behave how they wouldn't normally, within limits. Leaving a level and re-entering it, however, will reset your changes unless you have codes set up (as opposed to just using a memory editor such as the Equalizer cartridge provides).
Each structure uses 608 (0x260) bytes, so all 240 objects in a level occupy a total of 145,920 (0x23A00) bytes. The first object structure is located in RAM at address 8030B0B8 for the PAL game and 8033D488 for the NTSC game.
For the time, the animation featured in Super Mario 64 wasn't half bad, but have you ever wondered how the objects are brought to life? Examples of objects that are animated in this game are Mario, Goombas, Bowser and even the flags on top of the castle. If the object is animated, in its object structure, it will have a pointer to its animation data. This data for one thing, determines how many frames are in the animation and if the animation is played once or repeated. For example, the castle flags are continually animated as they seemingly blow in the wind.
In the animated object's structure is a frame counter which starts at zero for the first frame and then stops at one less than the total number of frames. If the animation is set to repeat it will start at zero again and count up.
For every frame an object can perform one or more transformations, such as translation or rotation. The object as a whole could be affected or individual parts such as arms or legs; it is generally easier to rotate limbs than to translate them. Each value uses two bytes and is an integer, this means that less precise control over the characters that would be possible with floating-point data, yet f/p values would take up more bytes.
Using Peach's animation as an example, she can be moved and rotated, and her dress (the skirt part), her hair, her arms and her earrings can be rotated to pose her. Peach has no legs, just like Zelda in Ocarina of Time, since her dress covers where her legs would be and her dress isn't flexible enough to expose them even if she had any legs.
Below is a screenshot showing one of the castle flags I had moved down to the ground level to get a better look at. Those four flags are a good place to start to study the animation in SM64 as they are only made of a few segments and have only the one animation that is repeated.
If an object blinks, like Mario or Peach, that is NOT part of their animation, which was done perhaps to simplify things. An object appears to blink by changing the texture used for its eyes, which is much like how mouth animation was done in earlier games.
Mario has the most animations and the game seems to keep track of what Mario is doing by his animation. This means, if you were to swap animations it glitches up the game since it thinks Mario is doing something else.
Please go to SM64 Exposed Animation Values.
Please go to SM64 Exposed Beta.
Probably the most famous beta graphic in this game that was never removed was the Blarrg and I was fortunate enough to find it in Lethal Lava Land, Wing Mario over the Rainbow and Bowser in the Fire sea. There are very few animations in the lava filled level and I knew where the two bully animations were; the Blarrg's animation of him jumping up and opening his mouth was after the bully animations.
Now I knew the values used for Blarrg's animation it wasn't too difficult to find that same animation in Bowser in the Fire sea and Wing Mario over the Rainbow, by searching for the values that belong to the animation data.
Although a few variables in an object structure determine how an object behaves (e.g., if it can be climbed like a tree) it is the behaviour scripts that really make an object come to life. The behaviour scripts are a list of instructions that place certain values in the object's variables and also calls functions that do a lot of the hard work.
These behaviour scripts, along with the graphic ID (with the exception of some behaviours that do not require a graphic ID) are used to create an object. They are also the values to be used with my spawn code. These values remain the same between the different versions of the game since they are used to calculate the actual addresses of the data needed for spawning objects.
Please go to SM64 Exposed Behaviour Values.
When the game is paused or if you are reading a sign or talking to someone, no objects are updated according to their behaviour. A variable located near the first object is used to pause the objects when reading sign or talking to someone.
A code I did patches the game program so that the varaible's value can be modified without the game altering it, giving control over the objects so that you can freeze or unfreeze them when you want. Note that basic abilities including climbing an object or reading it like a sign are not updated (but can be initialized) by the behaviour scripts, so they are unaffected. In other words, even with all objects apart from Mario in a frozen state you can still climb trees, talk to Koopa the Quick, etc. In fact, while the objects are paused some interaction still takes place, such as collecting coins although they don't vanish until you unfreeze the objects.
Another side effect of freezing the objects is that some will not appear as Mario moves through a course until you unfreeze them. The reason for that is due to objects not being initialized until they are at least a certain distance from Mario.
You might think that it wouldn't be too difficult to keep the objects paused as you go from one level to another. Unfortunately, this is not possibe for two main reasons. Firstly, the star select screen uses objects so they will not appear and thus you can't enter a level (unless you used the level select) with the objects frozen. The other problem is that if no objects are updated according to their behaviours they will not get initialized when you enter a course which caues probems.
Please go to SM64 Exposed Behind the Scenes.
Please go to SM64 Exposed Colours.
Super Mario 64 is a little strange in the way it handles text, considering the game was most likely programmed in C, not all of the text are null terminated strings. The ASCII text in memory are error messages, the credits and the level select names (despite them showing up as colourful text), and some other strings.
The colourful text such as the number or lives remaining or 'PAUSE' that is displayed when you...um...pause the game uses a simple approach to handling the individual characters of a string, which has advantages over ASCII, namely that 0-9 and A-F are in ascending order which is handy for when outputting numbers.
First, here are the values you'll need (in hex) to create your own colourful strings when the ASCII standard isn't used. Take note that some characters are missing for some strange reason (surely not much space was saved by leaving them out):
To try out editing a string, the 'PAUSE' text is located at address 0x802FDB78 in the PAL game. If you have a different region of the game simply do a 16-bit search for 0x190A (you may have to convert to decimal). This is what you'll get:
0X802FDB78 19 0A 1E 1C 0E FF
Which spells out PAUSE (the 0xFF is the terminating character since 0x00 is used for the number zero). Change these values and if the game is paused the changes will have imediate effect. Note: If you move the terminating character to the left the string will shrink but the opposite doesn't work even if you add more characters; it may be that the bytes that follow the 0xFF are used for other reasons and this explains why going into that area causes problems.
You may be wondering what's so wonderful about modifying text. Well apart from the amusing words you can come up with there are more practical uses such as for when you write your own programs and insert them into the game's execution. You'll need a convenient way to show data as the game is being played rather than having to use a memory editor.
Here are some addresses of more English strings (foreign strings follow the English ones):
To find other strings, take two adjacent characters on even boundaries (the first two characters are ideal, like 'PA' for PAUSE), convert to the hex values (0x19 and 0x0A for 'PA') and convert to decimal to use in the 16-bit search (if need be). Once you've found a possible address you'll know if it's the string by looking at the values that follow and by modifying them.
The level select uses the colourful text even though there's the problem of the few missing letters coupled with the strange names makes reading them difficult. It's weird since the level select names are actually stored in the RAM in ASCII so why not display them correctly by using the normal text?
While helping someome with editing the colourful text in the SM64 ROM we found that the Z colourful character is missing in the USA ROM but is in the PAL ROM. I should add that in the NTSC game the colourful V character also does not exist.
Now let's look at the colourful character values used by the text functions that accept the ASCII standard.
0x2A cross (used for lives for example)
Other values will result in blank or glitched up characters. It can be seen that the PAL game has more colourful characters than the NTSC game as the PAL version supports English, French and German languages. Starting at address 0x80305C98 in the RAM for the PAL game are the strings TIME, TEMPS and ZEIT which is Time in English (d'oh!), French and German.
In both Japanese versions of the game all the colorful characters are there which is a little odd that they couldn't be in all versions.
Please go to SM64 Exposed Create Your Own Codes.
When Nintendo were developing SM64 they used various debug displays to report the state of different variables. These debug displays can be enabled again and more information about them can be found below.
Debug Display 1
Most people know the debug dislay that's shown to the right of the screen all the time once enabled. It shows various bits of information most of which is to do with Mario, but nothing great.
Debug Display 2 (added: 5/9/8)
I've found a second debug dislay that is much better than the first; since finding it in the PAL version I have also activated it in the USA NTSC game and both Japanese versions. Like with the other debug display it is enabled by setting a flag (PAL 8030AE93 NTSC 8033D263). But, there is also another variable used (PAL 802FD054 NTSC 80330E94) to select 1 of 6 different debug displays on the left of the screen (using values 0 to 5), with the object number (don't forget the J colourful character is missing in non-Japanese versions) displayed most of the time.
What's so interesting about this second debug display is not only does it serve as a better form of debug, unlike the first debug display it is only shown when Mario is updated as it is actually part of the Mario behaviour and that is how I found it. You can have this debug display on at the same time as the first one (see Debug Display 1), although in some levels more information is shown at the right of the screen for this second debug so that would get in the way of the first debug display.
Please note that some of the values are in decimal, others are in hex. We need to work out what a lot of the debug data means, the most obvious of which is the OBJ value, most likely reffering to the object that is currently being updated, and is usually the Mario object.
In the NTSC and Japanese versions there is extra information shown when the MAPINFO data is being displayed. Since the Japanese SM64 has all the colourful characters the debug display appears as was intended but for all other versions, especially the NTSC game, the debug is harder to read.
A couple of NTSC screens of the debug display can be seen above, this is what is shown:
The second debug display is shown below, from the original Japanese version, and appears the same as it does in the Japanese Shindou edition.
The DPRINT is possibly the debug function used to display the colourful text on the screen and is a typical C language function.
MD, SP and FG appear in some levels, the MD could be mode and relates to what a Chuk-ya is doing and SP is its speed. FG doesn't seem to change, is different in each regional version, and is such a large value that it doesn't all fit on the screen (the numbers overlap at the right of the screen). SInce MD, SP and FG all appear together when in a course that has a Chuk-ya and they vanish when you defeat the Chuk-ya, the three values must all be to do with the Chuk-ya.
If you spawn a Chuk-ya (for example, using my spawn code), the MD, SP and FG appear for each Chuk-ya, although there is room on screen only for a few lots of these values. MD, SP and FG will also show up if you spawn a Chuk-ya in levels that don't normally have them, so it must be part of the Chuk-ya behaviour to display those debug values.
I have investigated the FG value; first I moved the Chuk-ya related values to the left (which can ony be done by altering the coding) so that the full FG value can be seen. It's a huge value and is in decimal since the M appears at the beginning of the value (i.e. minus) and in memory the FG string is fg %d, the d means decimal.
The FG value, when converted to hex is 64-bit and the bottom 32-bits looks like a pointer. By tracing through the game's coding I found that FG is a return address, in other words, is where the game continues when it has finished executing a certain function. So, the FG value may have been used so they know where in memory a part of the program that was causing problems in stored and this value will always stay constant while playing the game (although it will be different for each version of SM64).
There does remain a couple of unanswered questions, starting with why 64-bits is needed when 32-bit is the right amount for a pointer address. I do know that there is a bug in the display function that if a hex value is too long (32-bit or more) it will crash the game (a problem I was able to work around with my memory editor code) so they had to show the value in decimal form. Lastly, FG may possible stand for something like Function Goto, but I could be wrong.
It seems very likely that ANGY is Mario's Y angle, that is, his Y rotation so you'll see the value change as Mario turns around. WX, WY, and WZ must be Mario's world position.
When in the castle, Big Boo's Haunt, or Hazy Maze Cave and the second debug display is usually showing only the object number, AREAINFO appears, the value of which changes as you open a door and go to different rooms.
ACTION and MODE show up when you are in Tall, tall mountain and are to do with what the monkey is doing. If you select the Mystery of the monkey cage star, ACTION and MODE appears two times, the two values for both monkeys.
Strangely, when you fight King Bob-omb when the second debug display is active, a zero appears at the right of the screen when he picks up and throws Mario, similar to what a Chuk-ya does.
Both EFFECTINFO and ENEMYINFO values don't seem to change, but by altering the variables they display it can be worked out what they are used for. From tests, the B0 of ENEMYINFO is possibly the height of the star from the object that creates it (such as King Bob-omb) yet it is normally zero. Since the value is used by more than one object, it may have been used only for testing and that explains why it is now not used.
When you are in Lethal lava land, and second debug display is usually just showing the object number, NUMBER will also appear, two times at the left of the screen and is to do with the metal cage-like platforms that help you across the lava. This NUMBER value is from offset 0xF8 from the start of the object; so it's likely to do with what the object is currently doing. In theory the function that displays the debug NUMBER could be applied to any object.
WALL is another; like NUMBER, the function that displays the WALL value could be used with any behaviour, however, the game continually stores zero to the WALL variable as to disable it. WALL could possibly be to do with wall collision but as it seems the code no longer exists to update the WALL value, we may never know for sure exactly what it was used for.
There is even more debug text that is in the USA and Japanese versions but not in the PAL SM64. They are BOUND, TOUCH, TAKEOFF, DIVE, S WATER, U WATER, B WATER, SKY and OUT SCOPE. There is a variable when written to will display combinations of the these debug strings along with the value so they may have been used to report what Mario was doing yet the coding to update the variable seems to no longer exist.
NULLBG and a value show up when certain objects are spawned, such as fire, the value seems to be how many of the objects were created in a certain amount of time. BG could possible stand for Behaviour/Graphic and the NULL may be reference to objects that when spawned do not require a graphic ID value (i.e. it is zero), or behaviours that spawn multiple objects with their own, different, behaviour and graphic ID values.
Spawn debug mode
Here's irony for you; I was working on a better version of my spawn code and I needed a way to disable the Mario behaviour so that I could use more buttons on the controller. I checked the Mario behaviour script which has three function calls that are always executed, the first of which helps out with the second debug display and the second updates Mario. When I removed the third function call to see what affect it would have on the game it did nothing which was the case for the second debug display.
Looking through the code for the third function call I noticed that it checked the type of (second) debug display and if another flag was set. I satisfied both conditions but nothing happened until I looked at more of the coding-it checked the D-pad. To my surprise and delight pressing D-pad right spawned a normal Koopa shell, D-pad left a bouncing box and D-pad down a Koopa shell you can pick up but only works if you spawn it in the water. D-pad up isn't used and interestingly the spawned objects appear in front of Mario, something that would help me with my own spawn code.
So, Nintendo had used a very limited spawn debug mode which not only reveals more of what they used to test SM64 but could also help out with making codes. If you have the second debug display on and the type of display is number 3 (as partly needed to enable the spawn mode) whenever you spawn an item using the D-pad NULLBG appears.
Although SM64 does not use the 4MB expansion pack it is possible to make use of it which would allow for adding new behaviours, bigger worlds, more objects and other improvments. But due to the way the memory is split into segments loading and using data in the expansion pack memory can be tricky.
A simple way to make use of the expansion pack memory is to use Gameshark codes to place values in the extra memory and then patch the game's coding to use the data that has been put into the expansion pack memory. If you're using a real N64 and cheat device like a Gameshark then you will need to find an area of the expansion pack that is not use by the cheat cartridge.
I will now explain how I added a new behaviour to the game by making use of the expansion pack memory. The values are for the PAL game but the details can be applied to other versions.
If you look at the segment table in the RAM you will notice that a couple of the segment addresses are usually zero, one of which is the address of segment 0x0B. The first thing to do is change the segment 0x0B address to the start of the expansion pack memory:
803096F4 00000000 -> 00400000
Remember that the 8 at the start of an address is missing in the segment start address table but is added by the game when a segment/offset value is converted to an actual address.
Next we put a simple behaviour script at the start of the expansion pack memory:
This behaviour script just calls a function at address 0x80400100, which is also put into the expansion pack memory:
80400100 lui a0, 0x8031
80400104 lb a1, 0x94DD(a0) Get the number of lives Mario has
80400108 addiu a1,a1,0x0001 Increase lives
8040010C sb a1, 0x94DD(a0) Update lives
80400110 lui a0,0x8033
80400114 lw a0, 0xED90(a0) Get pointer to object
80400118 sh r0, 0x0074(a0) Remove object
8040011C jr ra
The above function increases Mario's lives by one.
Lastly, change the preset behaviour of the signposts to use the new behaviour script that's in the expansion pack, which is now segment 0x0B:
802FDE38 130032E0 -> 0B000000
Now, every time you go into a level that has signposts Mario's lives will increase by how many signposts there are. Note that the signposts won't be visible since even if the new behaviour didn't remove them there is no initilization that the signposts would normally use.
All objects in all levels
A big limitation with SM64 is that only common graphics can be used in all levels including Mario, coins and stars. By making use of the expansion pack it would be possible to have objects such as Peach and Yoshi in all levels. I have done a test using Nemu and a save state which now contains Peach and other objects that can be used in every course.
Using Nemu I set up breakpoints (so that the game stopped at certain times) during the loading of the castle graphics and then changed various values so that the whole of segment 5 was loaded into the expansion pack memory. Segment 5 contains amongst other things, Peach's graphics and animation but not the graphic structure so I had to then get the game to load that also into the expansion pack.
The problem is that for the graphics to be used that's in the expansion pack the start address of segment 5 has to be changed otherwise it would try to use the data that's only loaded in the castle grounds. This means having to change the sement 5 start address whenever you enter or exit a course.
Note: this FAQ should be helpful for other games as well, not just SM64.
Q. What exactly do codes do?
A. The most common type of codes simply place a certain value in the memory (RAM) where the game stores variables such as lives, health, etc. For example, you loose a life so the game subtracts one from Mario's lives and then stores the result in memory. But a code can then puts back a different value so that Mario always has a fixed number of lives.
Q. What do I need to be able to use codes?
A. If you have an actual, real N64 you will need a cheat code cartridge of which there are quite a few including Gameshark, Action Replay, Xplorer64 and Equalizer. The other option is to use an emulator that has built in Gameshark code support such as Project64 or Nemu64. Using a real N64 has the advantage that the game will be in its original form but on the downside you will have to enter the codes using a controller which can be very time consuming. Another problem with a real N64 is that cheat code cartridges use the expansion pack which may be needed by the game. With emulators, however, you can copy and paste codes and the expansion pack is free to be used by the game. But the emulator can only emulate so it will never be exactly like on a real N64.
Q. What is the difference between Action Replay and Gameshark codes?
A. They both use the same type of codes as does xplorer64 and Equalizer (which is based on the Action replay). I often use the term Gameshark when talking about codes since Gameshark seems to be the most recognised cheat device.
Q. Can a code harm my game?
A. No, the worse a code can do is wipe a save file and that's quite unlikely. The only definite way to damage a game cartridge is to remove or put the cartridge into the N64 while the power is on (which is why I advise against so-called cartridge tilting).
Q. What is PAL and NTSC?
A. These refer to the game region (where in the world the game was designed for) and have a similar use when we talk about video formats, which is appropriate as the game systems output the audio and visual data in a specific way depending on the region.
PAL and NTSC are important when it comes to codes as there are changes to the game from one region to another and these changes mean either a code won't work at all or will have to be changed to work. So you must use the right version of the code; PAL codes if you have the PAL game or NTSC codes if you have the NTSC game.
If you do not know if you have the PAL or NTSC game then there are a number of ways to check. If you are using a real N64 then it goes by where you got the game from; PAL for the UK/Europe and NTSC for the USA. If you are using an emulator then you can check the country data stored in the ROM (for example, if using Project64 load the ROM and then go to File->Rom Info...).
There are two Japanese versions of SM64; the original Japanese version and the second Japanese version which goes by the name of Shindou Edition. On my site I use JAP ORG for the original Japanese version and JAP SE for the Shindou Edition. If you have the original Japanese version then you must use JAP ORG codes or if you have the Shindou Edition you must use JAP SE codes. Others sites may use different naming for the Japanese versions.
Q. Will a code from one region or version work on another?
A. Not normally, just as a code for a game won't do the same thing on another game. As well as the regional differences, often there are different versions for the same region (such as Mario Kart 64 and The legend of Zelda: Ocarina of time).
Q. Can a code be converted for use on another region or version?
A. Often yes, by adding or subtracting the difference between the address part of the code (the left hand side). However, for some codes this will not work so you'll need to use a different approach such as using a memory editor.
Q. Will codes for N64 SM64 work on the DS version?
A. No; firstly, you've got 2 different pieces of hardware and while the DS version of SM64 is similar to the N64 version it's different in many ways. But without even those differences, the DS Action Replay codes are in a different format to the N64 codes. It is possible, however, to convert some N64 codes to DS codes. Also, DS codes won't work on the N64.
Q. Can you make a code to do xxxxxx?
A. Although what you can do with a code is quite limited I never say never; codes I've said I would not be able to do, later I have been able to do as I learn more about how the game works.
Q. Is Luigi in SM64?
A. Luigi is NOT in SM64 for the N64 but we can get close through modifications of Mario (change his colours, make hime taller, etc.)
Q. What beta items/objects are unused but are still in SM64?
A. They are the Yoshi egg, Boo key, key display (only the Japanese versions have the key character), the Blarrg baddy and, the level select and debug although not actually beta.
Q. What is an emulator?
A. An emulator attempts to behave like the original game system and usually runs on a computer, and can offer extra features such as for creating codes without the need for a cheat cartridge. Examples of N64 emulators are Nemu64 and Project64 but there are many more.
Because an emulator may not exactly display a game as it would on the real game system, certain cheats may behave differently on the emulator than on the original hardware. Advantages of emulators are that the quality can actually be better than the original system that's being emulated and you can easily take screenshots.
Q. What is a ROM?
A. When we are talking about an emulator, a ROM is the copy of the game cartridge, CD, DVD, etc as a software file, to be loaded by an emulator. The general rule is they you are only allowed to download a ROM if you own the original game on cartidge or CD, etc.
ROM is short for Read Only Memory and is any type of memory that cannot be changed after it is created (so game ROMs that are software files aren't really ROMs).
Q. I've just entered a long code, why doesn't it work?
A. Some cheat cartridges and emulators don't like long codes, so if you've checked that you entered every digit of the code correctly, try splitting the code in half and turning on both halves as if they were a single code.
Q. Does a code have to be entered exactly?
A. Yes, although if you do make a mistake when typing a code, by chance you may discover another cheat.
Q. When I use certain code combinations, nothing happens or not as expected. Why?
A. Some codes can conflict with each other and having too many codes on at the same time can cause problems or even crash the game. Try turning on less codes or different combinations. A few of my codes won't work if used together since they use the same memory.
Q. I've activated a code but it does nothing, what am I doing wrong?
A. If you've checked that you entered the code correctly it may be that it uses an activator. This requires you to press a certain button or combination of buttons to trigger the cheat.
Q. Why do some codes say that they must be activated before the title screen appears?
A. This is usually only necessary with emulators, which cache (backup) the game's coding that the cheat modifies. If the emulator caches the game's coding before the cheat has altered it the emulator will use the unmodified coding and so the cheat will have no affect. I have found with SM64 that any codes that alter the game's coding should be turned on as soon as possible, at the latest at the file select screen.
Q. Is cartridge tilting safe?
No. Cartridge tilting causes glitches, game saves to be erased and can harm your N64. Some people claim the cartridge and console will be fine but the fact is by cartridge tilting there is good chance damage will be done. A much safer way which has similar effects to cartridge tilting (i.e. glitches) is by using an emulator; load a save state from a different game or different version of the game.
Q. How do size modifiers work?
A. Every object-be in Mario, a coin or a Goomba, has its own set of size modifiers - three size modifiers- that scale the object along the X, Y and Z axis. So, for example, if the Mario 3D model was originally designed to be 3 units high, in SM64 the game can make him 7 units high or 1 units high. Using these size modifiers, the game and through the use of codes, we can squash objects, make them taller and so on.
Q. Why do some codes only work in certain levels/stars?
A. Partly because of the N64's limited memory and also due to a design choice made by Nintendo. In every level there are only certain graphics and other data loaded. All the game object graphics can be divided into 3 types; the common graphics (Mario, coins, etc.) are always in memory and at the same place in memory. Then there are the quite common graphics (Goomba, cannon, etc) that are in most levels but at different places in memory depending on the level. Then there are the not common graphics (penguin, Koopa, etc) that are only in a few levels and are at different places in memory depending on the level. Since codes alter what's in the memory we have to have different codes for each level if we want to do certain things, such as to make Mario look like Koopa. The other complication is that depending on what star you select before entering the level will change where the Mario object is in memory. This is why Play as codes, for example, only work for certain stars.
Q. How do I make codes?
A. Please go to https://sites.google.com/site/jamesskingdom/Home/video-game-secrets-by-james-s/super-mario-64-exposed/sm64-exposed-create-your-own-codes
Please go to SM64 Exposed ASM Functions.
The objects in Super Mario 64 can look very simple such as the trees and the coins, or they can have a complicated 3D apperance such as Mario. Nintendo used numerous tricks to make sure that the game ran smoothly; many of the objects are 2D like the trees, coins, 1-up mushrooms and so on but always face the camera to appear more 3D (known as billboarding). The coins do not actually rotate but appear to by cycling through several pre-rendered frames (textures) of the coin at different angles.
The Mario graphic is without doubt the most complicated, although Bowser is not far away. Of course normally only one object has the Mario graphic (two when mirror Mario is visible), but if too many objects were to use the Mario graphic the game would crash.
What has always puzzled me although nothing major is why the programmers went to the trouble of having coins and other objects with and without shadows. Did Nintendo really go to so much trouble to not have shadows except where absolutely necessary such as for objects that move (an e.g. is that the only boxes to have shadows are those that jump and can move). Fortunately having a graphic without a shadow is simply a matter of bypassing the shadow value in the graphic structure.
The graphic structure is what I call the values that describe what an object looks like including such information as its starting size (a single value for X, Y and Z; the size modifiers in any object that uses a graphic can then adjust the graphic's size even more and in each of the three directions). Also, the graphic structures have details about the type of shadow (if any) and how the (if any) sub parts of the graphic are positioned accordingly like the head, torso, legs, arms, and so on.
Although nothing new where 3D graphics are concerned, you may be surprised that the graphic structures can contain pointers to functions to use that typically would adjust a graphic in some way. For example, part of the coin behaviour updates a variable in the coin object to remember what coin animation frame (texture) to use. The function call in the coin graphic structure then copies the coin object frame variable to the coin graphic structure as a temporary variable (a pointer to each object that use the graphic is also copied to the graphic structure).
Something I've wanted to do for ages but I didn't know if it was possible is to use scenery graphics for objects like Mario, coins, doors, etc. As can be seen when using my Attack of the big Goomba castles I changed the signposts to look like the castle and surrounding area and then used the (big) Goomba behaviour.
For most of the levels the scenery graphics are actually objects but with other courses including inside and outside the castle, and Bob-omb battlefield the scenery is nothing to do with the objects (i.e., it cannot move or be sized like the objects). Since the graphic structures used by the objects contain segment/offset values for what graphics to use, these values can be changed to use scenery graphics (but remember that the scenery graphics will only be loaded for the one level).
Changing the signposts to look like the castle worked well since the signposts are made up of two parts; the post and the actual sign. So I swapped the sign part with the castle graphics and the post part with the grass and hills area. The signposts still use the signpost graphic structure but that has been modified to use different graphics for the post and sign parts.
The levels are made up of several layers, for example, outside the castle the castle is one layer, the surrounding area is another. Then there are the fences, tree shadows, castle windows and castle door way as more layers-and let's not forget the castle tower but that is an object.
Most likely the reason for splitting up the level scenery graphics is so it's more manageable and let's not forget the objects also are made up of many parts like the signposts. But for some objects such as Mario who is animated he has to be made up of lots of parts (Head, torso, legs, and so on) so they can be moved independently of each other.
Please go to SM64 Exposed Graphic Values.
Super Mario 64 reinvented the Mario universe and introduced the concept of earning stars to progress in the game. But just how many stars had Nintendo originally intend for the player to collect? The DS remake features a lot more stars, though some were dropped from the N64 version.
No more than 99 stars?
Further proof: the amount of stars stored in RAM is then converted to text form for the colourful text, which is the number of digits followed by the codes for the numbers (see above). For the PAL game, If the star total has 1 or 2 digits it's stored at address 0x8005C185 but for 3-5 digits the text is at address 0x8005C141. Did Nintendo suddenly realise that they could do 100 or more stars and had to use 2 addresses?
Please go to How my codes work.
How Bullet Bill works (update: 3/06/08)
Most Mario fans will recall many Bullet Bills fired at Mario from many directions but in Super Mario 64 there is only one Bullet Bill blaster near where the tower is located in Whomp's fortress. I assumed that the blaster spawned a Bullet Bill whenever Mario neared it but I couldn't find the coding that did such a thing. Have a look at this screen capture:
I removed the Bullet Bill blaster object yet the Bullet Bill still fired itself and after it was 'destroyed' it returned to its starting position. This means that the blaster simply hides the Bullet Bill until it fires itself; the reason this was done was perhaps due to there only being one Bullet Bill ever needed.
Global behaviour changes (update: 2/06/08)
If you want a simple way to swap objects for all levels then all you need to do is modify the list of object values that can be found in the RAM. Study the following values from the PAL game:
Above is the global control for the signposts which controls how the object looks and how it reacts to Mario and other objects. We can break the data down into important values:
130032E0 is the pointer to the start of the behaviour script for a signpost, so it controls what behaviour is to be used.
007C is the graphic ID for a signpost, that is, what it looks like.
0000 is extra values used by the behaviour, such as the Goombas as can be seen below:
Can you see that the only variation for the three Goomba types is the end value which tells the Goomba behaviour if it should be tiny, normal or big. The changes do not happen until you go to another level or re-enter the same course.
Whomps fall from the sky in Bob-omb Battlefield (update: 30/05/08)
You know those water bombs that fall from the sky in Bob-omb Battlefield, well, they don't come out of that cannon higher up that a Bob-omb guards. They are actually spawned when Mario nears an invisible object which acts like a trigger.
Trying out different ideas to replace the water bombs such as yellow coins I settled on a Whomp since you can have their graphics in Bob-omb Battlefield but they aren't normally in the level as an actual object.
The following is the ASM for the PAL game that determins what is spawned when Mario gets into the danger area:
802D3670 li t4, 0x13004BA8
To get Whomps to appear instead of water bombs it's a simple mater of changing the behaviour value (first line) and the graphic ID (second line). There are two interesting things to note; the Whomp bounces somewhat when he lands and only one Whomp shows up for each bomb area.
Force Mario to always face the camera (update: 19/05/08)
If an object is 3D but you trick the game into thinking it is 2D, it will have the affect so that the object always faces the camera. The problem is that you would need a code for every course and star unless the coding was altered which is what I did.
Take a look at this coding for the PAL game:
8024D5F0 lh t7, 0x0002(v0)
The variable at offset 0x0002 in an object's structure enables or disables billboarding, 0x0021 is used for 3D objects like Mario and 0x0025 is for 2D objects such as the trees. What I needed to do was easily write the 0x0025 to Mario's object structure at offset 0x0002.
To do that I created a code that used 0x0005 instead of 0xffef and swaped the andi instruction for an ori command. In other words, 0x0021 is loaded and combined with the value 0x0005 which results in the number 0x0025.
Spawning items from Goombas (update: 18/05/08)
One of my goals was to change what items can be spawned from item boxes and other objects such as Goombas and now I can do that having had looked at the behaviour coding for a Goomba. There are two main values used for spawning a yellow coin from a Goomba and they are the graphic ID and the pointer to the behaviour script for the yellow coin.
Because I had found the global item box item type table in the RAM I recognised certain values used in the Goomba's behaviour coding. First Have a look at this instructions for the PAL game:
8037E0B8 li t6, 0x00000074
The 0x00000074 is the graphic ID for a yellow coin, if you alter this value the coin that comes out of a Goomba will look different but it will behave like the usual coin.
The next important command used for spawning also for the PAL game:
8037E0C4 addiu a3, a3, 0x09A4
The register a3 is set to the value 0x09A4 but that's only the bottom half of the pointer to behaviour, however, all we need to do is modify the lower half which is the offset and keep the segment value the same.
By changing both the graphic ID and pointer to behaviour you can spawn any item from a Goomba like my 'Goombas give Bob-ombs' code.
Global changes (update: 17/05/08)
Wouldn't it be great if you could, for example, force the game to give out loads of coins instead of one like from the Goombas-well, you can! This was something I've wanted to do for a long time and eventually I worked out how but not without looking at the coding and being sneaky.
First of all I checked to see if the Goomba's behaviour script wrote to the variable in a Goomba's object structure during initialization to set how many coins a Goomba releases when it's killed. There was no such instruction so I then checked the behaviour call to ASM in the Goomba's beaviour script and found this (PAL):
8037F38C 80A90007 lb t1, 0x0007(A1)
A byte is loaded from an offset of the location pointed to by register A1 and then stored at offset 0x198 in every Goomba's object structure, i.e., how many coins it gives out. By changing the instruction that loads the value or the store instruction you could easily force Goombas to give out no coins by using r0 (which always equals zero) but I wanted to create a code that will force more than one coin to come out of a Goomba.
If I had been using Nemu at the time I could have easily found out where A1 pointed to but with only my Equalizer I decided to be sneaky by changing the store instruction so that it dumped the value of A1 to the variable at offset 0x198 in every Goomba's object structure (and making sure not to stomp a Goomba).
Now I knew that A1 pointed to 0x802FEE70 in the RAM and at offset 0x0007 from that was the value 0x01. By changing that byte it would have the global affect that all Goombas would pay Mario as many yellow coins as you wanted, although too high values will crash the game as there won't be enough free object structures.
This find is not only useful but interesting as the pay out value is only a byte, perhaps to save on memory and also as even values that can be stored within only 8 bits if too high will bring the game to a halt.
Please go to SM64 N64 Item Box.
Please go to SM64 Exposed Mario's Moves.
Please go to SM64 Exposed Messages
You may know that during the credits you can control the camera using a second controller which suggests that it's possible to add, if only limited, multiplayer to SM64. The truth is, as long as the controller is plugged in, the game will update the controller data stored in the RAM, but of course only take notice of that data for the second controller while the credits are being shown.
A problem I had was although emulators would read the second controller my N64 wouldn't but I realized what was going wrong. For some reason, if you enter the Equalizer's in-game menu and then return to the game, the second controller is deactivated as if it had been unplugged.
To do a simple 2-player, I patched the spawn debug mode so that it responded to the second controller instead of the first. In the PAL version a pointer to the location of the controller data is loaded just once, but in the NTSC game the pointer is loaded each time a d-pad button is checked (i.e. three times). Here is the first time the controller data pointer is loaded for the NTSC game for the spawn debug mode:
0x802CB298 lui t9, 0x8033
To change it so that the second controller is used instead, just change the 0xD5E4 to 0xD5E8. Note that code activators use the controller data directly rather than look up the pointer first since that's not possible without using the codes to make a mini program.
Nintendo made sure to save as much memory as possible and keep the game running smoothly by using polygons only were necessary. Examples are the fact that Peach has no legs (her dress hides that area) and the pendulum in the clock in the castle has no back to it since you never normally see that side.
As well as that, any hidden polygons of non transparent objects like Mario, are removed. This can be shown by removing polygons of an object facing the camera and you will see right through the object; you won't see the back polygons.
The Rooms of Darkness
Nintendo used many tricks to lower the amount of memory and CPU time that Super Mario 64 needed to work, one of which can be seen in the castle. Any room you're not in is put into darkness by the game (think of it as something switching out the lights when Mario leaves a room) though you can't normally see that happening. This is done because anything black doesn't need to be drawn, thus lowering the number of polygons that need to be rendered. This was actually a common trick used in 3D games, hence why so many video games were set in buildings.
One way to see the rooms put into darkness is to turn off a door's graphics or just move it out of the way (it's fun walking through a door that doesn't lead to anywhere). The 'lights' will still be activated as you approach a room but before then you will see a room of darkness.
The above picture shows the door that leads into the mirror room is missing, or appears to be, by turning off its graphics. This shows that the room has been put in darkness so it doesn't need to be drawn, it's not enough just to hide it with the door, since sprite and scenery graphics are handled differently.
There's something strange about Lakitu's cloud, for one thing it's a separate object to the actual cameraman. The white object against the black is Lakitu's cloud (which is still animated) yet Lakitu himself doesn't appear until the 'lights' are turned on.
The colouful text in SM64 is limited in that it has missing letters and few special characters, presumably because each of the colourful characters takes up more memory than the normal text, that is used for the signpost and other object messages. The normal text uses the same codes as the colourful text and therefore is backwards compatible (but not the other way because the colourful text has missing characters). Here are the codes for the normal text, you can use the same search technique for finding strings as suggested for colourful text trings.
0x50 Arrow Up
0x51 Arrow Down
0x52 Arrow Left
0x53 Arrow Right
0xFE [New Line]
Note: Arrow Up, Down, Left and Right are the actual graphical symboles used to represent the N64 controller's camera buttons. The A, B, C, Z and R refer to the controller's buttons and are bigger than the normal letters.
File Save: D
To better understand how the game saves your progress, what follows is the addresses containing the saved variables for file save D, like what stars you've collected, for the PAL game:
0x80203058 [Byte] Secret stars.
Moving and sizing the screen
In the ending cut-scene there is a border at the top and bottom of the screen and in the end credits the screen appears to move and change size. There is a special function that allows the screen to be moved and its sized to be changed, although it doesn't actually affect the screen, more of a window on the world. So, if you were to make the screen smaller, or move it, you would see less of the game world.
The function uses several input values, one of which appears to be a pointer to where certain screen values are stored to set its size, position and other attributes. Note that the function must be called every frame otherwise the screen will return to its normal size.
When the screen is in the window mode, the area of the screen that is not showing the game world, that is the border, can be any colour you want. In the end movie and credits it is black, most likely to hide the fact that the text characters are on a black background that would show up if the border colour was not black. That and the tradition of having black borders in movie sequences.
The function that allows you to set the screen attributes requires that you specify the colour of the unused area of the screen when using window mode, as RGB. The red and green colour amount are placed into two seprate registers but the blue colour amount strangely has to be put on the stack before calling the function, although that may be due to how Nintendo's compiler converted from C to machine code. The colour values are then combined by the function and stored to memory.
There is an extra value to be passed to the function, one with a bit of mystery about it. In the NTSC game the value is stored to memory but in the PAL version it is never used by the function suggesting that it is an unused feature. Also, elsehwere in the game's code this unknown feature is disabled by writing zero to it, however, if the code is patched you can write to the variable without the game changing it. But, placing any value other than zero there seriously messes up the screen display, either showing darkness or zoming in greatly on the game world is a strange way.
Below is a screenshot of a code of mine that makes uses of the window mode, and also changes how red the border is depending on how much health Mario has (i.e. bright red for full health down to dark red for no health). This picture is from the PAL game running on Project64, but it works on a real N64 as well.
Unfortunately, the NTSC game has a black border at the top and bottom of the screen that's fixed and unaffected by the window mode.
It seems so natural when we are playing the game that we don't notice it much but as you move through a level various objects appear and disappear depending on which objects can be seen within the field of view. This becomes more apparent if we use a code (see https://sites.google.com/site/jamesskingdom/Home/game-codes-by-james-s/super-mario-64-codes#TOC-Camera-codes) that stops the camera from following Mario.
In the picture below, Mario is just about visible in the distance while the camera waits at the start of the level, but the cannon and Bob-omb buddies have vanished. The reason this happens is because it's behaving normally as already explained, it only looks strange because the camera hasn't moved, yet the objects you would expect to see have gone.
As Mario moves even further away from the camera, the boxes and signposts will also disappear; if the camera had moved with Mario those objects wouldn't be seen.
This code also messes up the demos; because the camera does not move the scenery stays where it is and so collisions still occur between Mario and the scenery, but Mario 'thinks' he is somewhere else. So, to summarise, the objects appear and disappear depending on Mario's position in the level but what part of the scenery can be seen depends on the camera's position.
You may notice that some far away objects cannot be seen even though they should be visible. This is likely because of performance reasons; the more objects on screen (especially 3D animated objects) the more chance the game will slow down.
Using my camera on any object code, if the camera is put on another object such as Koopa the Quick we can watch him get to the mountain top. Interestingly, certain objects don't appear like they would if the camera had been following Mario.
Nintendo divided up the memory (RAM) into segments that contain related data, for example, there is a segment for the behaviour scripts. Theses segments are referenced using a number; to get at data stored within a segment an offset is added to the segment number. Using segment/offset addressing the actual address of where the data is located does not need to be known and thus the segment/offset values stay the same between different versions of the game (or at least they do for the UK and USA SM64).
The actual address is calculated from the segment/offset values using a table of segment start addresses. This table contains the start address of every segment so it's very simple to use the segment number to act as an index to load the start address of a segment. Interestingly, the segment start addresses in the table lack the 8 at the beginning (e.g., 0x000E0840 instead of 0x800E0840).
A good example of how segment/offset addressing is used is for specifying the behaviour of an object that is to be spawned. This behaviour value is actually an indication of where in memory the start of the behaviour script the spawned object is to use.
Wouldn't it be great if you could have what music you wanted in the levels, well, that's what I did with my D-pad music select. I traced through the coding of the level command that changes the music for a course and found the variable that changes the music. But there were two problems, one being that some areas were unaffected and the other, most strangely, that it worked on both Nemu and Project64 but not on my N64 using an Equalizer.
To fix that, I patched the coding were it loaded the music track number from the level command so that it instead used the music value from a variable. This meant the code worked for a real N64 as well as an emulator and you only have to press a d-pad direction once before going into a level instead of having to hold the button until the level loads. Note that there are still situations where the music cannot be changed with the D-pad music select code such as at the star select screen.
Let's look at how I patched the coding, for the NTSC game. On the left is the original code and on the right the change I have made:
0x80380350 LW T3, 0xBE28(T3) -> LUI T3, 0x8034
0x80380360 LH T4, 0x0004(T3) -> LH T4, 0xD3D0(T3)
In the original code the game would look up the location of the music level command and then load the music track number from the command as a 16-bit value. My modification simply adjusted that so the music number is loaded from memory at address 0x8033D3D0 which is where the D-pad activators place the music value.
Every object has its own size modifiers (as floating-point values) stored in its object structure; some objects use the individual X, Y and Z size modifiers, others use a single size variable for sizing along the three dimensions equally, stored elsewhere. Also, some graphic structures have a size modifier that affects all objects that use the graphic structure.
With objects including Mario their size is constantly updated by their behaviour, meaning it's not possible to use their size modifiers in the object structures (as the game will just overwrite what you put there). Instead, you need to alter the game's coding which on the plus side will affect the object's size for all levels.
I created a code that patches the coding loaded into the RAM so that different values are used for the X, Y, and Z size modifiers in Mario's object structure. When it came to do the NTSC version I realised how difficult it would be due to the differences in coding between the two versions. I couldn't add a set value to the address or search for certain opcodes for specific instructions.
Fortunately I found the coding used by the NTSC game by using Nemu's hacking plugins and discovered that the NTSC SM64 is actually simpler to patch than the PAL game. Here is a comparison of the code side-by-side for the PAL game on the left and NTSC version on the right:
8024C7E4 MFC1 A1, F0 Mario's X size 802535BC LUI A1, 0x3F80
In the PAL game a single value is used which is copied to 3 different registers but in the NTSC game three separate values are used. This makes sense since Nintendo saw that it was better that one value be used rather than three since the values are the same. What's interesting is that it suggests that Nintendo had planned that Mario could be sized differently and the simplest way to have Luigi in SM64 would be to change a few visual details about Mario and then alter his size.
By increasing or decreasing Mario's size strange things happen when Mario picks up a box or Bob-omb when he's a different size to normal (such as by using a code).
The larger Mario picks up a Bob-omb that patrols near Chain chomp, and behold its body parts split like Rayman! A box when picked up changes size to reflect Mario's size modification. Note that this only happens if the size modifier in the game coding's is modified, not if the size modifier is changed in the Mario graphic structure.
The most likely reason that we get this odd side effect is because objects Mario pick up need to be transformed in the same way as Mario so that the object moves and rotates with Mario. Thus, Mario's transformations are applied to the object Mario is carrying with which includes the increased size.
Even if you're not familiar with the coding used by N64 games please try to follow and understand it. Although the game was probably programmed in C, we can still look at the assembler (ASM) that is produced from the C coding. This ASM is for the PAL game and thus the instructions and addresses will differ for the NTSC game (due to bug fixes, etc).
Add 1 red coin
Start with no coins
Please go to SM64 Level Select
The N64 uses a 64-bit RISC MIPS processor that is part of the MIPS family that was used in other devices including the Playstation 1 and Playstation 2 (different bit power, with the N64 in the middle). Nintendo were obviously so impressed by the MIPS processor that they named the rabbit in SM64 that you have to catch MIPS.
It is unlikely that Nintendo programed SM64 using the MIPS' native language (machine code), instead they would have used C or C++ which was then converted to the machine code that the MIPS actually uses. We can view and modify the machine code but we would use assembler which is a more easier to understand than just numbers. Some of my codes actually change the game's coding that is loaded into the memory (RAM) so that more advanced cheats are possible.
Compared to other processors, the MIPS assembler is somewhat simpler to work with, however, working so low level is difficult and not ideal for everyone. In this section I will talk about how the MIPS processor works to help your understanding of how SM64 comes to life and it will also be useful for anyone who wants to make advanced codes
First, let me put something to you: is Super Mario 64 really 64-bit? The answer is NO-let me explain. Super Mario 64 is 64-bit in that it is running on a 64-bit processor but coding wise it is actually more 32-bit. For one thing, pointers (variables that remember where something is in memory) only need to be 32-bit and this is the case for many of the other variables. This is also true for other N64 games, especially those ported from the Playstation 1 (which is 32-bit). The advantage of using 32-bit variables is that they take up half the space of 64-bit variables and can be processed quicker, however, 32-bit variables cannot deal with as high or as accurate values as 64-bit variables.
Many of the MIPS' instructions can load or store different size variables which are known as byte (8-bit), half word (16-bit), word (32-bit) and double word (64-bit). Other instructions can use immediate data stored with the instruction (as opposed to a variable), but is limited to 16-bit which is the reason why N64 Gameshark codes have the 16-bit limit to simplify how the cheats are converted to MIPS coding. The reason why immediate data is limited to 16-bit is so that all instructions use 32-bits each, so the other 16-bit determines what the instruction is.
Another thing to be aware of is that when using anything other than a byte (i.e., half word, word or double word) the variable must be located starting at an even address. You can test that using a Gameshark code such of the 81 type using an odd address-the game will crash.
Not everything is stored in the memory (RAM), temporary values are copied to the MIPS processor's registers which are variables that are inside the actual processor and thus can be accessed quicker than the external memory where all the other values are stored such as Mario's lives, and so on. One of the MIPS' registers isn't actually a variabe, it is called r0 and always equals zero. If you need to clear a variable to zero-including registers-rather than have to load zero as an immediate value you can just use r0 which saves time and memory and can make patching easier.
A pointer is a 32-bit (word) variable whose value is the address of something in memory, such as graphics and audio information, variables like position, speed, etc, and even other pointers. Pointers are important as they tell the game where data is stored in memory and as a way of the game keeping track of what it is processing.
Examples of pointers are the pointer to the Mario object (where the Mario object is in memory changes from one level to another), the pointer to each object as it is being updated (including the Mario object), and the pointer to the part of the behaviour script being executed.
Mario is a special exception compared to the other objects and it's no surprise as he's who the player controls. All the objects are updated constantly (although not at times such as when the game is paused), but often the game must reference the Mario object like when Mario looses health due to hitting a baddy, so that's where the Mario object pointer is needed.
Usually a register is loaded with a pointer value from memory (RAM) and an offset is added to get at a variable or other data, the result of which is another address (this is very common when processing the objects). This is not to be confused with segment/offset addressing which although is sort of a pointer it isn't an actual address (which is calculated from the segment/offset value).
Functions are simply a group of instructions that perform a set task, anything from copying a value from place to another, displaying values on the screen, to spawning objects. Functions remove the need to repeat coding whenever a job needs to be done again, instead the function is called and thus the code exists only once in memory.
A function may need information about what it is supposed to do, for example, a function that dislays a message on the screen will need to know where the text is stored in memory and where it should appear on the screen. These parameters are passed to the function through the processor's registers although the function can also look at variables in memory which will treated as parameters.
Also, a function can return a value, in a register or a variable in the main memory (RAM). If you had a function that added two or more numbers the result would be the return value. But just as a function doesn't have to have input parameters it doesn't have to return a value.
Most function calls in MIPS assembler take on the form of a jal (jump and link) instruction such as jal 0x802523C8. The address of the function MUST be even and divisible by 4 (each instruction is 4 bytes long). When a function is called using jal, the return address is placed in the register ra. At the end of the function you will usually see jr ra so that the processor continues after where the function was called.
When you look at MIPS assembler you may become confused at the way branches and jumps are handled, thanks to what is known as the delay slot. If a branch is encountered, even if it isn't taken (the condition fails) or the processor comes across a function call (a jal), the following instruction will always be executed before the jumps occurs.
Let's look at an example for the NTSC (USA) version of SM64:
802E5780 lui a2, 0x1300
The behaviour value of the yellow coin (0x13003068) to be spawned is loaded into register a2. The spawn function also needs two other parameters, one of which is a pointer to the parent object (the object whose behaviour spawns the object so that it can be positioned accordingly), which is what a0 is used for (the value was previously saved to the stack and is then retrieved). Lastly, the yellow coin GFX ID (0x0074) is loaded into a1 (note the use of r0, i.e. a1=0+0x0074), but the instruction is after the jal. Thanks to the delay slot, however, register a1 will contain the GFX ID value and then the spawn function will be called.
After the spawn function has finished, the MIPS processor will continue executing from address 0x802E5794. The addiu a1, r0, 0x0074 could have been placed before the jal but a nop (do nothing) would have to be placed after the jal, that is, in the delay slot.
Nowadays, realistic reflections are nothing to get excited about but in the 'olden days' reflections were created by using actual 3D space. That is, beyond the mirror in Super Mario 64 in the castle is valid 3D space that you can explore. The N64 is actually capable of reflections mapped onto the surface of a polygon but there are several reasons why Nintendo used a simpler way of creating the reflections:
1. It was easier at the time, especially as SM64 was an early N64 game.
2. Some things (such as paintings) musn't be reflected, so a surface reflection wouldn't work because it would (presumably) reflect everything.
3. Because Nintendo originally planned for Mario to go into the mirror world, if the DS remake is anything to go by (where you get a star).
Nevertheless, there is a certain strangness about the mirror world. To get past the mirror, you can move a door between the mirror or just alter Mario's position using a code. As can be seen in the picture below, the real Mario is on the right in the 'mirror' world where Lakitu appears as just a cloud.
There is very little collision (most likely because Mirror Mario who's now on the other side would just copy the real Mario) and you can return to the real world simply by walking through the mirror. Also, you can't get to the reflected door (if moved up it functions as a door that you just walk through), you can go through some of the walls, and in the mirror Lakitu appears only as a cloud, probably because there is only one Lakitu ever seen.
Other information is that the mirror's only shiny on the real side and there is a black area beyond one of the mirror walls that could possibly have been used for the DS version star room.
Interesting, any change in Mario's graphics are mirrored perfectly which suggests to me that another playable character was likely for the original Super Mario 64, as in the DS version adds three playable characters. You can make Mario look like a door and his mirrored version will copy, and even the cap powers are 'reflected', again this can be seen in the DS version with Luigi or using a code in the N64 version.
There's plenty of fun to be had with textures, a lot of the hacks you see are to do with altering the apperance of the objects in the game. SM64 handles the textures using a command that usually starts with 0xFD10, if you change the texture values in the RAM you can quickly modify the way the game looks (which is what the codes do). But please be aware that not all textures are normally available in every level, but common graphics like Mario's are.
What if you wanted, for example, to change Mario's eyes to those of Peach's or another object? That's actually easy to do if you remember that Mario and other objects appear to blink because the game cycles through different phases of the eyes, i.e. open, half closed, completely closed.
At the time, and for some while other, it was easy to use different textures to give the apperance that a character blinks or to show emotion. When Mario dies he has crosses over his eyes which is also simply a change of texture. In the case of SM64, both of Mario's eyes are a single texture so he wouldn't be able to shut just one eye.
If you're outside the castle and you want to swap Mario's eyes for Peach's then you first need to look for the texture commands for Mario's eyes:
FD10000004003090 (Mario's eyes open wide)
FD10000004004090 (Mario's eyes closed)
FD10000004003890 (Mario's eyes 3/4 shut)
See the end values change for each texture, those numbers 'point' to where the texture is located in memory (as a segment/offset value) so you need to change only them. When you have found them you need to change them to use Peach's eye textures (Peach actually has one more eye blink texture than Mario but that isn't used here):
FD10000005000A28 (Peach's eyes open wide)
FD10000005002228 (Peach's eyes closed)
FD10000005001A28 (Peach's eyes 3/4 shut)
Although this does work, because of the difference between the Mario and Peach model, you can only see one of the Peach eye.
(pic to be added)
Shame it doesn't quite work out and another problem is that Peach's graphic can only be accessed outside the castle. So if you wanted to totally change Mario's eyes to Peach's for all levels you'd have to find a way to load Peach's graphics all the time.
At the title screen, behind the Mario head, normally you will see the pattern of squares that read SUPER MARIO 64 but after a game over they will be displayed as (not surprisingly) GAME OVER. Due to the limited size of the textures, each square is actually made up of smaller textures. Since the game needs to select what set of textures to use for the background, there is a list of segment/offset values to choose what textures to use. The values and the RAM addresses are the same for both the PAL (UK) and NTSC (USA) game:
The first set of texture values are for the SUPER MARIO 64 background and the second set of texture values are for the GAME OVER background. Each texture value in order is for the top, second from top, second from bottom and bottom part of the square.
Stored in the RAM while playing SM64 are the object structures which are simply an area of memory dedicated to each object that stores its position, rotation, and so on as well as defining how it looks. These object structures appear to be doubly-linked lists since the game was most likely programmed in either C or C++ and each object structure contains a pointer to the next and previous structure. Just think of a structure as a collection of variables bound to a particular object, each of the 240 objects that can be in a single level have this structure stored in the RAM one after another.
Each structure uses 608 (0x260) bytes, so all 240 objects in a level occupy a total of 145,920 (0x23A00) bytes. The first object structure is located in RAM at address 8030B0B8 for the UK (PAL) game and 8033D488 for the USA (NTSC) game.
Please go to SM64 Exposed Object Variables.
To learn about the individual objects please go to SM64 Exposed The Objects in Detail.
So, during the opening sequence Peach reads a letter to Mario inviting him over for some cake; there are some interesting points about what happens during that introduction.
* After Peach vanishes, the Peach object turns into the pipe Mario comes out of. Why they didn't use a different object for the pipe is a little strange but it may be due to the way objects are spawned.
Stored in the RAM there is always a list of pointers to the graphics structures for each object. This is so the game knows where the graphics are stored especially as some of the common graphics move about in memory from level to level. A few of these pointers are actually invalid (the game doesn't update the pointers for certain graphics) for some courses but as for the rest, the game alters the values to reflect the new position of the graphics from level to level, with the exception of the common graphics which always live at the same place in memory.
Let me make this clear by dividing the graphics into three types:
(1) The very common graphic objects such as the coins, stars and Mario are in all or most levels and live at the same place in memory, not far from the start of the RAM.
(2) The not so common graphic items are Goombas, bat, Bob-ombs and so on and are loaded into memory at a different position depending on the level. A lot of these objects are actually unused in some levels including the cannon and common baddies.
(3) Lastly is the more uncommon graphics that move about in memory from course to course and include beta and unsed objects such as Blarrg and (except in Hazy Maze Cave) the sea creature (Dorrie).
By checking each graphic pointer value you'll find some very familiar objects and some that weren't used in a particular level but there may have been plans to use them. And as for the common graphics, you can easily swap them so you could have a butterfly that looks like a star, for example, and the change will remain for all the levels that have those graphics.
Now I will tell you about the unused and beta graphics in each level, please be aware that if the graphics are available then so are the associated animations.
In Wet-dry world some of the unused graphics are Bullet Bill, a Yoshi egg and the owl. Also, there's a Thwomp, a small Cheep-cheep and the spike bomb we know from the Bowser fights (the spike bomb was to be used in at least one of the water levels as a mine but was removed as an actual object).
(pics to be added)
Now onto The Princess' secret slide where we find Lakitu the cameraman, Boo, and MIPS the rabbit (a bit dangerous to try and catch it in this level). Most strange is the wing cap switch; could the secret slide have been the original home for the cap button? Note, like a lot of objects in SM64, the main part of the switch and its bottom are separate graphic objects. A few other graphics are flyguy and very interesting, Toad.
(pics to be added)
Now for a strange graphic in the Tower Wing cap course: a solid red box. Not very interesting but maybe that's how the unactivated wing cap boxes would have looked like before Nintendo decided on the version we are more familiar with, either that or it is missing some textures perhaps.
(pics to be added)
Does this ring any bells-Bullet Bill, a Yoshi egg and owl-but in Tick Tock clock.
(pics to be added)
The Cheep-cheep fish graphic is in Jolly Roger Bay, the spike bomb and the green spider pond skater, probably as they belong to the water set of graphics.
(pics to be added)
And surprise, surprise the spike bomb is also available in Dire, Dire Docks, as well as the green spider and Chuk-ya.
(pics to be added)
The piranha plant and Whomp graphics are both loaded into memory when in Bob-omb Battlefield, possible they were to be used in that level or it may just be due to the course being similiar to Whomp's fortress.
(pics to be added)
In Cool, cool mountain I found the graphics of a small and large blue ice bully; you may remember the big ice bully from Snowman's land. What's strange is that there are two separate graphics when they could have just resized one of them. The only other find worthy of mention is the handbag baddy that can be found in Snowman's land but its graphics can also be used in Cool, cool mountain.
(pics to be added)
Who's the creature you'd least expect to see in Hazy Maze cave...the monkey! And another baddy from Tall, tall mountain whose graphic can be used in Hazy maze cave is that cloud with a face.
(pics to be added)
We know that a Blarrg creature was to be in Lethal Lava land and its gaphics have not been removed in the released game, he is joined by the sea creature (Dorrie) we know from Hazy Maze cave.
(pics to be added)
This was a shock to find-the Blarrg graphic-in the Wing Mario over the Rainbow level along with the cavern beast (Dorrie). There's a lava theme here as there is also the graphic of the bat (can be seen in Hazy maze cave but also available in Lethal lava land), and a small and big lava bully.
(pics to be added)
Onto The Secret Aquarium course there are water creatures and other objects used in the bigger water levels, such as the manta ray, eel and shark graphic. Two more unused graphcs in The Secret Aquarium are the Cheep-cheep and spike bomb.
(pics to be added)
Where else could there possibly be unused lava themed creatures-Bowser in the Fire sea! There is the Blarrg, big lava bully, bat and the Dorrie sea creature.
(pics to be added)
There is much mystery about Big Boo's haunt and these three items are no exceptions, they are a key quite different to the Bowser key, the sea creature (Dorrie) and the cage that is the same as the one you use to get to the ghost level. It seems that the key you would get from a Boo judging by a beta picture, possibly the key was to be used to get to the second floor of the ghost house.
(pics to be added)
There are several unused graphics in the Rainbow ride course which are Wiggler (who is split up into two parts) and the large Cheep-cheep like fish. Both of these objects we know from Tiny-huge Island so maybe Wiggler was to be found in Rainbow ride originally. But even Nintendo wouldn't have had that huge fish swimming about in the air so Rainbow ride or whatever it started out as could have had water in it.
(pics to be added)
In Tiny-huge island there are two unused graphics which are Chain-chomp and Whomp. Think about it, the Tiny-huge island course has the same music as Bob-omb Battlefield and similiar enemies.
(pics to be added)
The only unsed graphic in Snowman's land that's worth talking about is a small ice bully.
(pics to be added)
Here's two very eye opening graphics in Whomp's fortress, and they are the Yoshi egg and a wind-up baddy that we know from Tick tock clock. What is the connection between Wet-dry World, Tick tock clock and Whomp's fortress that all have the Yoshi egg?
Considering Whomp's fortress uses the Bob-omb battlefield music it may not be so much of a surprise to find graphics from that course which are Chain-chomp, and koopa with and without his shell. The wooden post is not so interesting but the Koopa flag is: was there to be a race to where you find King Whomp similiar to King Bob-omb in Bob-omb battlefield?
(pics to be added)
In Vanish Cap Under the Moat you can use some of the graphics from outside the castle: the pipe and green tree.The other graphics, such as Peach and the castle tower, crash the game if used despite their structures appearing valid (there must be other data missing). This may not be significant but it suggests that this course may have been quite different.
(pics to be added)
Now onto the courtyard with the Boos there are many unused graphics that crash the game if you try to use them and most curious is a white square that brought the game to a halt within seconds so I took the screenshot as quickly as I could. Along with the strange graphic is Toad who wouldn't look out of place except for those Boos in the way so perhaps that's why there are just signposts instead.
Considering that the cage is an unused graphic in Big Boo's haunt I should have expected to find some of Big Boo's haunt graphics unused in the courtyard. There is the small key, chair, piano and book baddies and the ordinary book.
(pics to be added)
In the Cavern of the Metal Cap where you activate the metal cap boxes, the unused graphics are those available in Hazy Maze Cave so they probably weren't intended to be used. But they can be used if you wanted to and a couple of them are the bat and the spider.
(pics to be added)
Something that features in many of the courses is water and Wet-dry World is known for its adjustable water level. Here I show you what happens when you mess with the water by removing it and as for Wet-dry world, it's possble to flood it to a super level!
The position of the water switches in Wet-dry world do not affect how high or low the water level changes but there is a varible in the RAM that does set the water level. For the PAL game this variable is located at address 0x8032EDBA and for NTSC 0x8036118A. This variable has the value of 0x0400 when you enter the course (assuming a normal jump into the painting), 0x0028 for the lowest water level and 0x0A00 for the highest water level.
But if you alter this value using a code to a very high value such as 0x3200 you get a water level that reaches for the sky.
(pics to be added)
Now for removing the water in different levels and this can be done by setting the water pointer to null which lives at address 0x8032EDB4 for the PAL game and 0x80361184 for the NTSC version. If you disable the water in Tiny-huge island the killer fish continues to swim, but on the sand, and if he tries to eat Mario he will end up head first into the sand.
(pics to be added)
As for Hazy Maze Cave, getting rid of the water doesn't affect Dorrie who swims about normally and with no water in The Secret Aquarium you can walk about at the bottom and the fish swim as usual but also making it impossible to get the high up red coins (unless you had wing cap).
(pics to be added)
In Tall, tall mountain if you null the pointer to water the waterfall remains but you just walk through it as if it weren't there. As can be seen in the screenshot below, in the Cavern of the Metal cap even with the water pointer cleared to zero the water remains but you can walk in it at the bottom as if you had the metal cap:
(pics to be added)
All content of this and related pages is copyright (c) James S. 2007-2016
New: SM64 Exposed Mario's Moves page
SM64 Exposed Beta page
Update: Item box
Update: The Textures
Press D-pad to start or stop screen shake (How my codes work)
Coin Colours (Colours).
Update: The Objects in detail
Update: Item Box
Behind the Scenes.
Create Your Own Codes.
Work elevator (Hazy maze cave).
Screen special effects.
Animation pointer values (Animation).
Sound and music.
Expansion pack memory update: All objects in all levels
Spawn debug mode (Debug).
The MIPS processor: Pointers.
Create your own codes.
The mystery of the Ü-solved!
You can email me at email@example.com
Why not have a look at the Super Mario 64 codes page.
People who have helped me out.
MegaMario2007: code ideas and for doing requests for me.
Frauber (messiaen): code ideas and other help.
VL-TONE: his SM64 docs have helped a lot.
And thanks to others for their requests and ideas.