Jun 1, 2013

Just spending my Saturday studying Super Mario Bros. 3's code.

Update: I probably shouldn't be the one to say this considering my expertise or lack of it in the field, but wow -- Nintendo R&D had some sloppy programmers! SMB3's code is a mess.That said, they use some programming tricks I hadn't seen Konami use, such as using the BIT command to check if a byte is negative or zero. I read about that at NESdev, but this was my first time seeing it in use.

I was trying to crack the code for the Sun. I tried to crack the code straight away, but it was just so damned convoluted and confusing without any reference points. Things that looked like y values weren't, or things that were y values were y values for the wrong thing. S, I wasted hours just staring at code not knowing what I was looking at. Then I saw something in the code that set off a lightbulb over my head.

Byte #0665 was always set to 2 in the code I was looking at. Why was that? What was I looking at anyway? The epiphany came when I realized I was only focused on the Sun when it was swirling and swooping. Prior to that, the sun just followed the view around.

Perchance, could #0665 be a phase counter just like #05C1,X in CV3? I set a write breakpoint for #0665 and died (so I could restart the stage); #0665 got reset as I expected. I re-entered the stage and #0665 got set to 0, as I expected. I skipped to the next breakpoint. The code increased #0665 (good sign) aaaannnnd there weren't any sprites on the screen yet. In CV3, phase 0 was always reserved for loading sprites or invisibility timers (for Ghosts). There was no mistaking it, #0665 was a phase counter for the Sun. When I made the Sun aggro, it increased again.

I now had a grounding point (as I call it). Going through the list of variables that were set when #0665 was 0 (Nintendo's programmers handled phases in peculiar ways), I tried to track down what each of them did. Here's a list of the variables as I've found them. It won't be as in-depth as my CV3 list because I really don't care about SMB3, but some of you might.


#0017: Button held (copied variable, tracked)
#0018: Button pressd (copied variable, tracked)
#0075: Mario's horizontal screen (room_x & $FF00)
#007A: Sun's horizontal screen
#0087: Mario's vertical screen
#008C: Sun's vertical screen
#0090: Mario's x in room
#0095: Sun's x in room
?????: (some kind of counter for enemies)
#00A2: Mario's y in room
#00A7: Sun's y in room
#00AA: Mario's x in the view
#00B0: Sun's x in the view
#00B4: Mario's y in view
#00B9: Sun's y in view
#00BD: Mario's hspeed
#00C2: Sun's hspeed
#00CE: Death pause
#00D4: Sun's vspeed
#00D8: Mario_isjumping (boolean)
#00ED: Mario's Power-Up state
#00F1: Death pause
#00F5: Button pressed
#00F7: Button held
#00FD: view_xview
#03E2: Sun's object_index (?)
#03EF:
#0425: Sun's phase counter
#051C: Sun's attack timer (counts down while circling)
#0543: view_yview
#055D:
#056F:
#0583: Ceiling reached or something to do with ducking
#0587: Behind the scenes (when you duck on a white block)
#0593:
#05EE-#05F1: Timer
#0655:
#065D: if !#0665 then #065D=$FF
#0665: Some kind of phase thingy for Sun
#066D: Sun's image_index  !!(#0015 & $C)
#0675: Sun's sprite_index
#067D:
#0685:
#06AF:
#074C ?
#0752: Sun's fractional x
#0764: Sun's fractional y
#0779: Sun's horizontal direction
#077E: Sun's vertical direction
#0780: view scroll speed(?)
#0786:
#079A:
#07AC:
#07B1:
#7D80-#7D86: Items page 1
#7D87-#7D8D: Items page 2
#7D8E-#7D94: Items page 3
#7D95-#7D9B: Items page 4
        $00: Empty
        $01: Mushroom
        $02: Flower
        $03: Leaf
        $04: Frog Suit
        $05: Tanuki Suit
        $06: Brother Suit
        $07: Lakitu's Cloud
        $08: Pegasus Wing
        $09: Star
        $0A: Anchor
        $0B: Hammer
        $0C: Whistle
        $0D: Music Box
#7D9C-#7D9E: Bonus cards from end of stage
#7F50,X: Timer | $F0 remap (don't know the purpose of this)

No comments:

Post a Comment

©TheouAegis Productions™. Powered by Blogger.