News:

Don't forget to visit the main site! There's lots of helpful docs, patches, and more!

Main Menu

MZM General Disassembly Notes

Started by CanOfWorms, September 19, 2013, 12:53:54 AM

Previous topic - Next topic

CanOfWorms

Notes about Metroid Zero Mission as I poke around the code. Feel free to ask if you are confused about my notes, they may not be well detailed :v

[spoiler=Samus Info RAM data]
This is an extension of the notes found here
Samus's progress is tracked at 03001530 The format is:
0x0 - Max HP, halfword
0x2 - Max Missiles, halfword
0x4 - Max Super Missiles, byte
0x5 - Max Power Bombs, byte
0x6 - Current HP, halfword
0x8 - Current Missiles, halfword
0xa - Current Super Missiles, byte
0xb - Current Power Bombs, byte
0xc - Power up bitflags. The documented flags are:

0x1 - long beam collected
0x2 - ice beam collected
0x4 - wave beam collected
0x8 - plasma beam collected
0x10 - charge beam collected
0x20 - Nothing associated?
0x40 - Nothing associated?
0x80 - bombs collected

0x100 - long beam activated
0x200 - ice beam activated
0x400 -wave beam activated
0x800 -plasma beam activated
0x1000 - charge beam activated
0x2000 - Nothing associated? (would be 0x20 activated if it was associated with something.)
0x4000 - Nothing associated?
0x8000 - bombs activated
   
0x10000 - hi jump collected
0x20000 - speed booster collected
0x40000 - space jump collected
0x80000 - screw attack collected
0x100000 - varia suit collected
0x200000 - gravity suit collected
0x400000 - morph ball collected
0x800000 - power grip collected
   
0x1000000 - hi jump activated
0x2000000 - speed booster activated
0x4000000 - space jump activated
0x8000000 - screw attack activated
0x10000000 - varia suit activated
0x20000000 - gravity suit activated
0x40000000 - morph ball activated
0x80000000 - power grip activated

Note: The plasma beam, gravity suit and space can be active without having the power suit collected.
[/spoiler]

[spoiler=Door processing data]
0805ecc0 - updates door ID in WRAM (0805ecbc - loads the door exit into RAM)
080567e6 - updates room ID in WRAM

How the game determines doors/rooms:
0875faa8 is a table of 7 pointers corresponding to each area:
0 - Brinstar
1 - Kraid
2 - Norfair
3 - Ridley
4 - Tourian
5 - Crateria
6 - Chozodia

Each pointer points to a table of entries. Each entry is 12 bytes long and corresponds to a door. The formatting is:
0x0 - ?
0x1 - room number
0x2 - door hitbox, left X position (counted in tiles)
0x3 - door hitbox, right X position (counted in tiles)
0x4 - door hitbox, up Y position (counted in tiles)
0x5 - door hitbox, down Y position (counted in tiles)
0x6 - ID of the door exit
0x7 - ?
0x8 - ?
0x9 - ?
0xa - ?
0xb - ?
0xc - ?
the game determines a door's location in a room by looking at the hitbox position. Samus must touch the hitbox to start the room transition, otherwise you can't actually go through the door. The door data is read when a room is entered, after that the information is stored in RAM and read from RAM.
[/spoiler]

[spoiler=Zero Mission's Random Number Generator]
The random number ZM uses seems to be stored at 0300083C, and is usually updated every frame. Certain rooms will stop the game from updating the RNG, it's not clear what controls this yet. To calculate the next RN, the game uses data from 03000C77 and 03000002, which are both values that increase on a frame-by-frame basis. The actual random number is picked from a table at 082b0cac, which contains 32 entries (2 for each value from 0x0 to 0xf.)

The ASM offsets where this is done are:
0800cf76
0800d07e
0800d17c
0800d27a
[/spoiler]

Zhs2

Just a note that this exists and is vastly underused in case anybody wants to collaborate. (Post or PM me if you'd like to use it since I have to set trusted status in order for you to actually edit and I'll probably forget to check if you've registered. Damn bots.)

CanOfWorms

If someone wants to add the data to the wiki they can do it, I'm too lazy to do it myself :p

Disassembled part of the checksum function the game uses to validate saves:
http://pastebin.com/6vEhYbrm

This is how the game checks if save data is valid:
QuoteThe checksum function is located at 08074624, it takes input r0 = 0 when it's checking the save data. The format of the data at 02038000 is as follows:

02038000 + saveID*0x1220 + 80 is the start of a save slot's data, and saveID = 0,1 or 2. I'll refer to this offset as the SaveOffset. The game does 3 things to check if the save is valid.

1. The game adds all the words in the 0x1220 area and compares that to the value stored at [SaveOffset, 0x10]. These values should be equal in a valid save.
2. The game compares the words stored at [SaveOffset, 0x10] and [SaveOffset,0x14]. It checks if the words are bitflips of each other (i.e. [SaveOffset, 0x10] + [SaveOffset,0x14] = 0xFFFFFFFF)
3. There are 3 strings the game expects to find:
3a. The first string is at [SaveOffset,0], the game expects this string to be "ZERO_MISSION_010" (The exact byte sequence is the 16 bytes starting at 08411410.)
3b. The second string is at [SaveOffset,0x4F], the game expects this string to be "Planet Zebes" followed by the 4 bytes 0x2e, 0x2e, 0x2e, 0x20 (The exact sequence is at 08411420.)
3c. The third string is at [SaveOffset, 0x250], the game expects this string to be " - Samus Aran - "  (The exact sequence is at 08411430.)

If none of the strings match, the game will ignore the save data. If there is a partial match, the game will report the save data as corrupt. If the strings match, but 1 or 2 fail, the game also reports the data as
corrupt. Otherwise the game thinks the save data is valid.