How my codes work

Introduction

On this page you will find information about how I made some of my codes for Super Mario 64 on the N64. In turn this will give you a good idea about how parts of the game work.

In this section I will talk about how some of my codes work which will help to explain a bit about the game's coding as some of my cheats alter that.

Control and use portals in Bob-omb battlefield

There are two main parts to this code; patching the game to remove the overlays and Mario transparency as well as making the warps look like portals and running a mini program to place one of two warps in front of Mario. I will go onto detail for the NTSC version of the code but the PAL version works the same.

So, for the first part of the code with comments as to what each line of the code does:

8124DF84 1000 Warp Mario as soon as he gets to the warp

8124AC8E 0001 Really quick overlay when warp

8125A6BC 0000 Warp immediately

8125A6BE 0000

8125A670 0000 Remove Mario transparency when first warp

8125A672 0000

8125A74C 0000 Mario not transparent at end of warp

8125A74E 0000

8034CDEB 0025 Warp 1: face camera

8134CDFC 800F Warp 1: use '0' graphic

8134CDFE 9E10

8134CE14 4080 Warp 1: increase X size

8134CE18 4080 Warp 1: increase Y size

8034D04B 0025 Warp 2: face camera

8134D05C 800F Warp 2: use '0' graphic

8134D05E 9E10

8134D074 4080 Warp 2: increase X size

8134D078 4080 Warp 2: increase Y size

8124ACE0 0000 Change overlay to black

8124ACE2 0000

When Mario warps there is a delay, he turns transparent and then the screen goes white. After warping the screen returns and Mario loses his transparency (actually he starts off transparent again).

The zero colourful character, as used on the HUD and for when you collect a red coin (but of course, the numbers other than zero) looked to me like a portal from the game Portal. The idea was to try to patch the warps so they were more like portals from Portal that you could just walk through; I've got close to that.

The next part is the mini program for placing the warps, which starts at address 8033D2D0 in the NTSC code. Below the listing is given with the instruction value first and then the assembler version to the right then comments (if any).

3C048034 LUI A0,0X8034

948AAFA0 LHU T2 0XAFA0(A0) Get 1P D-pad and other buttons state

3C048035 LUI A0,0X8035

24080800 LI T0,0X00000800

11480005 BEQ T2,T0,DPAD_PRESSED D-pad up pressed?

24080400 LI T0,0X00000400

11480003 BEQ T2,T0,DPAD_PRESSED D-pad down pressed?

24840260 ADDIU A0,A0,0X0260 Modify warp 2 position instead of warp 1 position

1000000C BEQ R0,R0,EXIT No button pressed, exit

00000000 NOP

3C058034 LUI A1,0X8034 DPAD_PRESSED

C4A4B1AC LWC1 F4,0XB1AC(A1) Get Mario X position

3C064300 LUI A2,0X4300 How much to offset (128)

44863000 MTC1 A2,F6

46062100 ADD.S F4,F4,F6 Add offset (128)

E484CE88 SWC1 F4,0XCE88(A0) Set warp X position to Mario X position + offset

C4A4B1B0 LWC1 F4,0XB1B0(A1) Get Mario Y position

46062100 ADD.S F4,F4,F6 Add offset

E484CE8C SWC1 F4,0XCE8C(A0) Set warp Y position to Mario Y position + offset

C4A4B1B4 LWC1 F4,0XB1B4(A1) Get Mario Z position

E484CE90 SWC1 F4,0XCE90(A0) Set warp Z position to Mario Z position

03E00008 JR RA EXIT

Basically, if D-pad up or down are pressed Mario's X, Y and Z position are looked up and an offset is added to the X and Y position and then applied to either warp 1 or warp 2. Adding an offset to the Y position makes sure the portal can fully be seen and the offset on the X position places it in front of Mario (not on the Z axis as I first thought). The selection between the two warps is simply done by adding an offset to a start address.

Lastly, Mario's behaviour script is modified so that the above code is called:

810EE060 8033 Call asm code

810EE062 D2D0

Certain yellow coins home in on Mario

(Added: 28/5/11)

The code:

PAL

810E1214 802C

810E1216 53B4

812C53C8 0C0A

812C53CA 2F58

812C53CC 0000

812C53CE 0000

812C53D0 1000

812C53D2 0020

812C53D4 0000

812C53D6 0000

812C4BB8 0000

812C4BBA 0000

NTSC

810EBB54 802F

810EBB56 496C

812F4978 0C0A

812F497A AE18

812F497C 0000

812F497E 0000

812F4980 1000

812F4982 002C

812F4984 0000

812F4986 0000

812F3FF8 0000

812F3FFA 0000

How the code works:

PAL Version:

1-up mushroom that homes in on Mario behaviour/GFX ID: 0x13004148/0xD4

Part of behaviour script (for updating 1-up):

800E49B4 0C000000 802C53B4

Yellow coin (from Goomba, big breakable box and wooden posts) behaviour/GFX ID: 0x1300091C/0x74

Part of behaviour script (for updating coin):

800E1210 0C000000 8028BD60 -> 0C000000 802C53B4 (this change makes the coin use the homing in 1-up behaviour)

Homing in 1-up behaviour coding:

802C53B4: LUI V1, 0x8033

802C53B8: ADDIU V1, V1, 0xED90

802C53BC: LW A3, 0x0000 (V1)

802C53C0: ADDIU SP, SP, 0xFFE8

802C53C4: SW RA, 0x0014 (SP)

802C53C8: LW V0, 0x014C (A3) -> 0C0A2F58 JAL 8028BD60 Call the coin behaviour coding so that it still acts like a coin

802C53CC: ADDIU AT, R0, 0x0001 -> 00000000 NOP (Nothing in the delay slot)

802C53D0: BEQL V0, R0, 0x802C53F4 -> 10000020 BEQ R0,R0,0x802C5454 Jump to the homing in coding

802C53D4: LH T6, 0x0002 (A3) -> 00000000 NOP (Nothing in the delay slot)

802C5454: JAL 0x802C4AC4

802C5458: NOP

802C545C: JAL 0x802B8AAC

802C5460: NOP

802C5464: BEQ R0, R0, 0x802C54FC

802C5468: LW RA, 0x0014 (SP)

802C54FC: ADDIU SP, SP, 0x0018

802C5500: JR RA

802C5504: NOP

So far, the yellow coins will home in on Mario but will increase his lives as well as coin total. So next, we need to patch the homing in 1-up behaviour coding so that it is used just for homing in on Mario.

802C4BB8: JAL 0x802C48EC -> 00000000 NOP Disable function which increases Mario's lives and plays sound.

802C4BBC: SWC1 F8, 0x00B8 (V1)

802C4BC0: LW RA, 0x001C (SP)

802C4BC4: LW S0, 0x0018 (SP)

802C4BC8: ADDIU SP, SP, 0x0030

802C4BCC: JR RA

802C4BD0: NOP

Note that if you get a homing in 1-up it will keep following or circling around Mario until it fades.

Press D-pad to start or stop screen shake (version 1.0)

(Added: 26/6/9)

Pressing D-pad up will start screen shake and D-pad down to stop screen shake.

PAL (UK)

810E3720 8030 //Replace function call in Mario behaviour script to call our code

810E3722 AF00

D0309260 0008 //Press D-pad up to start screen shake

8030B000 0001

D0309260 0004 //Press D-pad down to stop screen shake

8030B000 0000

8030AF00 27BDFFE8 ADDIU SP,SP,0XFFE8

8030AF04 AFBF0014 SW RA,0X0014(SP)

8030AF08 3C048031 LUI A0,0x8031

8030AF0C 0C0E0221 JAL 0x80380884 //Shake screen

8030AF10 9084B000 LBU A0,0XB000(A0) //How much to shake screen

8030AF14 8FBF0014 LW RA,0X0014(SP)

8030AF18 27BD0018 ADDIU SP,SP,0X0018

8030AF1C 03E00008 JR RA

8030B000 How much to shake screen

NTSC (USA)

810EE060 8033 //Replace function call in Mario behaviour script to call our code

810EE062 D2D0

D033AFA0 0008 //Press D-pad up to start screen shake

8033D3D0 0001

D033AFA0 0004 //Press D-pad down to stop screen shake

8033D3D0 0000

8033D2D0 27BDFFE8 ADDIU SP,SP,0XFFE8

8033D2D4 AFBF0014 SW RA,0X0014(SP)

8033D2D8 3C048034 LUI A0,0x8034

8033D2DC 0C0A943F JAL 0x802A50FC //Shake screen

8033D2E0 9084D3D0 LBU A0,0XD3D0(A0) //How much to shake screen

8033D2E4 8FBF0014 LW RA,0X0014(SP)

8033D2E8 27BD0018 ADDIU SP,SP,0X0018

8033D2EC 03E00008 JR RA

8033D3D0 How much to shake screen

Passing a value of zero to the function that shakes the screen doesn't shake the screen or stops it if it was shaking. A value of one causes the screen to shake so it was a simple matter of using two button activators to write zeero or one to the variable that is passed to the function that determines if the screen should shake.

D-pad tree remote control

For this hack I created a new behaviour which allows you to move an object using the D-pad and is quite simple, however, it requires many codes. A problem I did encounter was how to force the game to execute my code that would work both on a real N64 and an emulator. The solution was to change the function call address in the tree behaviour script to my program and this can be done with other objects.

Have a look at the PAL coding I created for the remote control:

3C098033 LUI T1,0X8033

8D29ED90 LW T1,0X8032ED90 Get pointer to object

C52000A0 LWC1 F0,0X00A0(T1) Get object X position

C52600A4 LWC1 F6,0X00A4(T1) Get object Y position

C52400A8 LWC1 F4,0X00A8(T1) Get object Z position

3C084200 LUI TO,0X4200 How fast to move object

44881000 MTC1 T0,F2

3C0A8031 LUI T2,0X8031

814A9260 LB T2 0X80309260 Get 1P D-pad state

24080001 LI T0,0X00000001

1148000D BEQ T2,T0,DPAD_RIGHT

24080002 LI TO,0X00000002

1148000A BEQ T2,T0,DPAD_LEFT

24080008 LI T0,0X00000008

1148000C BEQ T2,T0,DPAD_UP

24080004 LI T0,0X00000004

1148000B BEQ T2,T0,DPAD_DOWN

24080006 LI T0,0X00000006

1148000C BEQ T2,TO,DPAD_LEFT-DOWN

24080009 LI TO,0X00000009

1148000B BEQ T2,T0,DPAD_RIGHT-UP

00000000 NOP

03E00008 JR RA

46001087 NEG.S F2,F2 DPAD_LEFT

46020000 ADD.S F0,F0,F2 DPAD_RIGHT

E52000A0 SWC1 F0,0X00A0(T1) Update object X position

03E00008 JR RA

46001087 NEG.S F2,F2 DPAD_UP

46022100 ADD.S F4,F4,F2 DPAD_DOWN

E52400A8 SWC1 F4,0X00A8(T1) Update object Z position

03E00008 JR RA

46001087 NEG.S F2,F2 DPAD_LEFT-DOWN

46023180 ADD.S F6,F6,F2 DPAD_RIGHT-UP

E52600A4 SWC1 F6,0X00A4(T1) Update object Y position

03E00008 JR RA

Put simply, the behaviour checks the D-pad and then updates the object's position if a direction button was pressed. I also sneakily only used add instructions but negated (made negative) the value to add when needing to subtract.

Sparkling and invincible Mario

I had a request so that Mario always sparkles and had tried to trigger such an effect but at the time I could not do such a thing. But now I have been swapping Mario's first 0x0C behaviour call in his behaviour script with other objects' behaviour calls I found that the Koopa shell behaviour call causes Mario to constantly sparkle since the game is none the wiser. Unfortunately this is just a side effect since using the Koopa shell behaviour call for Mario does not do anything else, so no walking on water for example.

As nice as it was to see Mario looking more super than usual I thought about adding to the code, such as to make him invincible. After studing the neon code that makes Mario flicker I realised that it was actually a timer used by the game after Mario is hit by a bad guy during which time he can not be hurt by enemies.

Let's look at, for the PAL game, how the code updates the invincible flag (assuming that Mario is currently flickering) depending on the timer and then I'll show you how I patched it to make sure that no baddies can do him damage.

First the game gets the value of the flicker timer:

8024A314 lh v0, 0x0026(a0) 'v0=(80309456)

Next the code updates the register t8 depending on if the flicker value is less than zero or not:

8024A318 sltu t8, r0, v0 't8=1

The contents of register t8 is transferred to register v0:

8024A31C or v0, t8, r0 'v0=t8=1

And to finish off the invincible flag is written to with the value of register v0:

8024A320 sh v0, 0x9532(at) '(80309530)=1

Basically, the above coding sets the invincible flag if the flicker timer value is higher than zero or clears it if it's zero. You might think that I could have just used a code to force the invincible flag to always be set (equal one) but that is not possible due to the game's coding constantly changing it. The solution was to change the sltu instruction so that the result is always one:

8024A318 slti t8, r0, 0x0001

Anyone still awake at this point may realize that the just mentioned alternation seems pointless since we know that zero will always be less than one but that's exactly as was needed to force the invincible flag to always be set.

All content of this and related pages is copyright (c) James S. 2003-2013

New: Control and use portals in Bob-omb battlefield

You can email me at james.boshikoopa@gmail.com

To return to the main page please click here.