3 ms·
I did the work ~7 years ago so my memory is a bit fuzzy. You can see the source of the level map dumper here: https://gitlab.com/mcmapper/mcmapper/-/blob/master
by coldpie 5y ago
I did the work ~7 years ago so my memory is a bit fuzzy. You can see the source of the level map dumper here: https://gitlab.com/mcmapper/mcmapper/-/blob/master/main.c https://gitlab.com/mcmapper/mcmapper/-/blob/master/main.c
The high-level procedure was to load up a level, visually scan the RAM contents (the NES only had 2kb of RAM) for the level layout, and confirm that that section of RAM contained the level tilemap by tweaking values and observing that something changed in-game. Once I knew where the level was loaded into RAM, I set a write watchpoint on that RAM location, then re-loaded the level, which would break at the instruction which wrote that tile value into that location of RAM.
The NES CPU is single-threaded and has only three registers, so it's relatively easy to trace execution. The emulator I used (FCEUX-DSP, although I think Mesen is a better experience today) has a feature where it traces CPU execution, including register values, to a text file. So you can follow the trace of the level loading process and examine the disassembly in parallel and figure out what the code is doing. E.g. reading these values from ROM, performing these transformations on it (i.e. reverse-engineering their compression algorithm), and then storing the tile values into RAM at the watchpoint discussed earlier.
Then there's a similar process for loading palettes and graphics data into the PPU[1], how in-game enemies are stored, various level flags that affect how the tile data is presented, how the MMC3 mapper works[2], etc. Once that's all understood you can reproduce that algorithm in a new C program reading the data right out of the ROM image to create those PNG images you see on TCRF.
Yes, it was a lot of work :) great learning experience though.
Another group has been working on a level editor for M.C. Kids. I think they did their reverse-engineering work independent from mine: https://github.com/pgrimsrud/MCKids_Editor https://github.com/pgrimsrud/MCKids_Editor
This guy has a great series of YouTube videos demonstrating these techniques: https://www.youtube.com/c/DisplacedGamers/videos https://www.youtube.com/c/DisplacedGamers/videos
And I wrote up a pair of blog posts earlier this year about doing a similar procedure to hack Super Monkey Ball for Gamecube: https://www.smokingonabike.com/2021/01/17/hacking-super-monkey-ball-part-1-banana-bunch-values/ https://www.smokingonabike.com/2021/01/17/hacking-super-monk... Which also got some discussion here on HN: https://news.ycombinator.com/item?id=26315368 https://news.ycombinator.com/item?id=26315368
[1] https://wiki.nesdev.org/w/index.php/PPU https://wiki.nesdev.org/w/index.php/PPU
[2] https://wiki.nesdev.org/w/index.php/MMC3 https://wiki.nesdev.org/w/index.php/MMC3
- matheusmoreira 5y agoThat's amazing. These insights taught me a lot. Thank you so much. I asked because I remember reading documentation on the Super Metroid save file format. There's map data in the game state as well but it wasn't documented. Always wondered what it would take to reverse engineer that... I'm gonna try it with one of my favorite NES games. If they have level dumpers, I've never seen them... I know one which has a complete disassembly though.
- coldpie 5y agoI really encourage you to try it! NES is a great platform to start RE. It's a lot of work, but really fun once you start making breakthroughs :) Keep copious notes!!