supersonic.asm$D430 · car.bin

Super Sonic Bros.

Sonic the Hedgehog running through the original Super Mario Bros. levels with Sonic 1's physics. SMB's own code runs on a 6502 interpreter, with Sonic hooked in over Mario's routines.

run/play/supersonic/
↗ new tab

// Bring your own ROMs: it reads Super Mario Bros. (NES) and Sonic the Hedgehog (Genesis) files locally in your browser.

README.mdsupersonic/index.mdx

Sonic replaces Mario in all 32 levels of Super Mario Bros. He has momentum, rolling, a spin-ball jump and the spin dash, using Sonic 1’s physics constants scaled down from the Genesis’s 320-pixel screen to the NES’s 256. Everything else (levels, enemies, items, music, timer, warp zones, castles) is exactly SMB, because it’s SMB’s own code running.

You need your own SMB (NES) and Sonic the Hedgehog (Genesis) ROMs. They’re read in the browser and cached locally; nothing from either game is in the repository.

How it works

SMB runs on a small 6502 interpreter, with no emulation of the NES video or audio hardware. The game’s writes to the PPU and APU registers are recorded instead. The renderer draws the recorded nametables and sprites in three layers and composites Sonic between them at full display resolution, so his Genesis art stays sharp. An AudioWorklet synthesizes the pulse, triangle and noise channels from the APU writes.

Sonic is wired in with hooks, native functions that run instead of or around specific SMB routines:

SMB routine Hook
PlayerMovementSubs Sonic physics replaces Mario’s walking and jumping
PlayerBGCollision Sonic moves in small substeps, and SMB’s own collision runs on each
EColl The spin attack: a curled-up Sonic defeats enemies like a star would
ScrollHandler The camera looks further ahead at speed
UpdScrollVar Runs the level renderer more than once a frame when Sonic outruns it

Routine and RAM addresses come from assembling the community SMB disassembly, which matches the original ROM byte for byte. Sonic’s sprites, including the Nemesis-compressed shield and stars, are decoded from the Genesis ROM using offsets from the Sonic Retro disassembly.

The mushroom becomes a shield, the fire flower a fire shield, and the star gives Sonic’s invincibility sparkles. Water levels keep SMB’s swimming, since Sonic can’t swim.

Running it

Serve the folder with any static server, then pick both ROMs:

python3 -m http.server 8000