News:

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

Main Menu

Compression/Decompression Used in SM

Started by dewhi100, November 06, 2016, 09:34:23 AM

Previous topic - Next topic

dewhi100

Can anyone explain how the compression format in SM works for levels, items, tile tables, palettes, gfx, etc.? And/or point to existing documentation.

sylandro

Hi, some days ago I was looking for this info myself and couldn't find anything documented, so I had to experiment by hand (and also reading guides to hack other games, like SMW).

I'm not sure if this is exactly what you're looking for, but it's what i've gathered on compressed tilemaps (not compressed tiles).

The first step is to find the addresses where the tilemaps are compressed. Some are documented, and for the rest you'll have to use the debugger yourself (it helps if you know which bank they're on).

Apart from the wiki, I'd recommend checking old.metroidconstruction.com and PJBoy's dropbox https://www.dropbox.com/sh/yf40lgey6k67z38/AACq3Rc_CDZDfB6w4LrBeMu2a/ROM%20data/Super%20Metroid?dl=0 for additional documents. There's interesting stuff there.

Once you have located the tilemap, copy its bytes to a new file using a hex editor and save it. A .bin extension seems to be the convention.

Then, use Lunar Compress http://fusoya.eludevisibility.org/lc/index.html to decompress the file you created. Since Super Metroid uses the LZ5 algorithm, these are the proper command line arguments:

decomp.exe compressed.bin decompressed.bin 0 4 0

Now, you can edit the decompressed.bin file with a hex editor and you'll have the full decompressed tilemap.

Each address corresponds to a location on the screen, starting from the top left corner(0x0).

Each lower byte value corresponds to a specific 8x8 tile that's loaded from code. You can fiddle with the debugger to find this. For example, if you were editing the 'file select' screen, the letter A would be xxE0, B would be xxE1 and so on.

I think the high byte value corresponds to the palette, but I'm not sure. In my example 00xx paints the tile white, and 04xx paints it gray.

Once you've made your edit, you recompress it with Lunar Compress:

recomp.exe editedfile.bin newfile.bin 0 4 0

To reinsert in into the ROM, I use xkas, point to the address where the old tilemap was, and insert the new one there:


org $978DF4
incbin Options.bin


I think some times you'll have to move the whole tilemap somewhere else and repoint it through ASM (due to size? I'm not sure). I'll leave that to you.

Oh, there is a tool called JSM that edits some tilemaps and has a nice GUI. Search for it on the forums. Also, it appears that Black Flacon was working on an editor to specifically do this, but sadly was never finished.

PS: This is my first post and I just started hacking a couple of weeks ago, so there's a chance there's an easier way to do this. As you can see, I have not completely learned this yet. I just wanted to share my experience.

personitis

You may find Lunar Compress and this document useful. ROM Hacking dot net is a pretty solid resource so there may be more things scattered about as well.

dewhi100


P.JBoy

The Super Metroid compression does have some reasonably extensive documentation, this document gives a high-level view of the commands and this document at $80B0FF gives the implementation. It is essentially a hybrid differential RLE+LZ compression
...

interdpth

Hello,

A great fellow named @MathOnNapkins helped me reverse engineer it so it could be implemented in what would've been my Super Metroid editor.

I'll reply back when I get in contact with him, source for the compression library isn't up anymore and I can't find cheesy source.

dewhi100

Cool. All I'm looking for is a way to read/write to the rooms and tile tables data.