Nintendo has come out with a new tool, called, wideNES, to let you relive your childhood days. Only this time, you can record the screen while playing in real-time, gradually building up a map of the different levels explored. The new tool wideNES, is a feature of ANESE, which is an NES emulator developed by Daniel Prilik.
What’s great about wideNES is the fact that it syncs the action on-screen to the generated map, thereby, allowing players to see ahead of the levels by “peeking past the edge of the NES’s screen”. Also, this mapping technique is not applicable to only a few games i.e. it enables the wideNES to work with a wide range of NES games.
Let’s look at how wideNES works.
Back in the 80s, the NES (Nintendo entertainment system) used MOS 6502 CPU. It also used a powerful graphics coprocessor called the Picture Processing Unit (PPU) in conjunction with the 6502 CPU. The wideNES also makes use of PPU.
PPU is an integrated circuit in the NES which generates video signals from graphics data stored in memory. The chip is known for using very little memory to store graphical data. In wideNES, the CPU updates the PPU on what has changed throughout the game using Memory Mapped I/O. This process comprises of setting up new sprite positions ( Great for moving objects: player, enemies, projectiles), new level data, and new viewport offsets.
With wideNES running in an emulator, it’s easy to track the values written to the PPUSCROLL register (controls viewport X/Y offset) i.e. it’s easy to measure how much of the screen has been scrolled between two frames.
But, there’s a limitation to this technique as you can’t get a complete map of the game unless the player manually explores the entire game.
Scrolling past 256
The NES is an 8-bit system and in this, the PPUSCROLL register accepts only 8-bit values. This limited the maximum scroll-offset in NES to just 255px. So, on scrolling past 255, PPUSCROLL register would become 0, explaining why Smart Mario Bros would bounce-back to the start on Mario moving too far right.
With wideNES, scrolling past 256 is possible as it completely ignores the PPUCTRL register, and simply looks at the PPUSCROLL delta between frames. So, in case the PPUSCROLL unexpectedly jumps up to ~256, it indicates that the player character has moved left/up a screen, whereas if the PPUSCROLL jumps down to ~0, then that means the player has moved right/down a screen.
However, this approach does not work for games that have static-UI elements such as HUDs, Masks, and Status Bars at the edges of the screen. To solve this issue, wideNES implements several rules which detect and mask-off static screen elements automatically.
Most NES games are split into many smaller “scenes” with doors or transition screens that move between them. The wideNES uses perceptual hashing to detect whenever a scene changes. Perceptual hash functions work on keeping the similar inputs “close” to one another in the output space making them perfect for detecting similar images. But, perceptual hashes can also get incredibly complex with some being able to detect similar images even if few of the images have been rotated, scaled, stretched, and color shifted.
But, wideNES doesn’t need a complex hash function as each frame is always the exact same size.
Now, work is still being done on improving wideNES core and on improving ANESE’s wideNES implementation. For now, you can explore the ANESE emulator and take the trip down the memory lane!
For more information, check out the official wideNES blog post.