An unfinished art project, this served mostly as an early learning exercise for WebAssembly, Rust's procedural macros, and Super Metroid's unique binary format.
There are a lot of facets to this project:
Firstly, I decoded individual sprites out of the ROM. This required delving into 20-year-old txt file documentation, not to mention weekends neck deep in hex editors, which is unironically and enthusiastically my idea of a good time. These documents proved crucial:
- SNES and GB sprite storage formats FDwR (Frank Dwayne),
- Qwertie's SNES Documentation Qwertie (David Piepgrass),
Bitplanes, in particular, were common enough that I published a library to crates.io. Bitplanes are a way to store low-depth color data (like the 4 bit colors of Super Metroid) into packed bytes, without wasting bits.
Next, I extracted poses and animations from the ROM. This defines how pose animations loop or string into other poses (such as a landing from falling pose turning into a standing pose). This was mostly reverse engineered from the ROM (and I can still see those hex patterns in my head right now). A closely related step was to encode the poses in a state machine, driven by controller inputs.
This project taught me how to use procedural macros. I started out
include!ing the entire 3MB ROM file into the binaries I compiled, but this would have been unsuitable for Arduino or WebAssembly use. Instead, a procedural macro lets me precompute all of the animations, palettes, and poses at compile time. The ROM is still loaded, it just never becomes a dependency of the binary.
Oh hey, speaking of WebAssembly, there she is in the browser! In the corner down there.
f falls while jumping,
l lands while falling or spinjumping,