This is an old revision of the document!


Console compatibility with SM64 ROM hacks

(add info here)

Issues

Misaligned decompressed MIO0 blocks

In SM64, the game will load up scripts & models using level script commands for each level. Level script command 0x17 is used from copying uncompressed data from the ROM into RAM, and the commands 0x18 & 0x1A are used to read compressed MIO0 data from the ROM and then decompress the data into RAM. The MIO0 compression was necessary to make SM64 fit within an 8MB cartridge. Since ROM hackers don't really need to worry about file sizes (up to 64MB), we use ROM extenders to decompress the data into another place in the ROM file and convert all of the 0x18 level commands into 0x17 commands.

The problem with early extender tools, like VL-Tone's original SM64 ROM extender, is that the addresses where the decompressed data was stored was in a bad alignment. The N64 requires a 2-byte alignment for ROM addresses, and an 8-byte alignment for RAM addresses when copying data. This means that if the start/end ROM addresses within the 0x17/0x18/0x1A commands were odd, then copying data from ROM to RAM would fail. This creates the white screen freeze after a file is selected.

For example, here are some load commands from the first hub area in SM64 The Green Stars:

17 0C 00 12 003CF0D0 003D0DC0 // Load Segment 0x12 from ROM 0x003CF0D0 to 0x003D0DC0
17 0C 01 07 00E0BB07 00E84C1F // Load Segment 0x07 from ROM 0x00E0BB07 to 0x00E84C1F
17 0C 00 0B 00DA2785 00DA951D // Load Segment 0x0B from ROM 0x00DA2785 to 0x00DA951D
17 0C 01 0E 01C90000 01D50068 // Load Segment 0x0E from ROM 0x01C90000 to 0x01D50068
1A 0C 00 09 00D2320D 00D31321 // Load Segment 0x09 from MIO0 at ROM 0x00D2320D to 0x00D31321

The segments 0x07, 0xB, and 0x09 will fail to load on console, since the ROM address values are odd. Segments 0x12 and 0xE will load just fine, since the ROM address values are even.

How to fix it?

To fix this issue, we will have to look through the entire ROM file and adjust every 0x17/0x18/0x1A level script commands that have odd ROM address values. Thankfully, some people have made tools to do this automatically like queueRAM's sm64compress tool.

If you want to make your own tool that will implement this fix, then just follow these steps:

1.) Look through all of the levels scripts to find 0x17/0x18/0x1A commands
2.) Test if either the ROM start address or ROM end address is odd.
3.) Adjust bytes if true.
  3a.) If both the start & end addresses are odd, then move the entire bank over by 1 byte.
  3b.) If only the end address is odd, then just increment the end address by 1.
  3c.) If only the start address is odd, then move the entire bank by 1 byte and also increment the end address by 1.
Note: Banks can be used multiple times, so you will have to remember which addresses you've already adjusted.

Improper use of Fast3D's SetCombine (0xFC) command

(add info here)


Warping triangles

Some versions of the SM64 Editor, like v1.9.3S, will have warping polygons when the player is moving around the level. This issue was caused by Skelux setting the camera frustum's far value to be a negative number (0x9696 = -26,986) in the Geometry Layout Command 0xA (Set Camera Frustum).

How to fix it?

This issue can be fixed by changing the camera's far value back to being a positive number. The largest possible positive number is 0x7FFF (‭32767‬).


RCVI Hack

The RCVI hack is an option in the SM64 editor, under the “ROM Settings” tab, that can potentially reduce lag in emulators. The hack simply changes two bytes at ROM offset 0xF00C2 from  02 0D  to  08 34 . However, this hack prevents the game from working properly on console. It produces the strange visual artifacts seen in the image above on boot.

How to fix it?

To fix this issue, you only need to revert the two bytes back to normal. Just change the two bytes at ROM offset 0xF00C2 to  02 0D . Once that is done, make sure to use a program like n64crc.exe to recalculate the ROM's checksum.


Trying to write to the framebuffer's area of memory (8038F800-803FFFFF)

Older versions of the SM64 Editor moved the music pointer to address 0x803E0000. The problem with using that address is that the region from 0x8038F800 to 0x803FFFFF is constantly being overwritten with the game's framebuffer, so any data that gets stored within that region will be erased immediately. Some graphic plugins for Project64, like jabo's, have the option of writing the framebuffer to memory turned off by default, which is probably why this was not caught earlier.

How to fix it?

Later versions of the SM64 Editor will put the music memory pool in extended memory, which is safe to use. Please do not store data within 0x8038F800-0x803FFFFF if you want your hack to be compatible.


The Project64 problem

Project64 is a popular, and performance friendly, Nintendo 64 emulator that was initially created back in 2001. While it is highly compatible with most of the N64 library when it comes to casual players, it is not cycle accurate and depends on plugins for graphics and audio. This fact makes it easy for us, as ROM hackers using the emulator, to unknowingly create the issues seen above. It is not so much the emulator itself that is the main problem, but rather the fact that most SM64 hackers will only use Project64 that creates these problems.

See Also

References