# Red Viper runs the Virtual Boy on a 3DS with a dynamic recompiler

> Red Viper is a C emulator for the Nintendo Virtual Boy that runs on the 3DS, using a dynamic recompiler with busywait detection and a hardware accelerated renderer to hit full speed on the console's limited hardware. It is a continuation of mrdanielps's r3Ddragon, which was itself based on Reality Boy.

**skyfloogle/red-viper** — A Virtual Boy emulator for the 3DS

- Repository: https://github.com/skyfloogle/red-viper
- Stars: 1,047 · Forks: 32
- Language: C
- License: not declared
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/skyfloogle-red-viper

## A three-generation lineage of Virtual Boy emulation

Red Viper describes itself as a Virtual Boy emulator for the Nintendo 3DS continuing mrdanielps's work on r3Ddragon, which is itself based on Reality Boy / Red Dragon. That lineage is the first thing to understand about the project, because it explains the architecture and the licence at once.

Reality Boy was David Tucker's emulator from 1997 to 2008, and it is the ancestor that everything else is built on. r3Ddragon ported it to the 3DS. Red Viper continues that work with a performance rewrite.

The performance approach is stated plainly. It uses a dynamic recompiler with busywait detection and a hardware-accelerated renderer to achieve high performance on the 3DS's limited hardware.

A dynamic recompiler is the reason this emulator runs at full speed. The Virtual Boy is an unusual machine, a 32-bit RISC CPU from Nintendo paired with two custom chips, the Virtual Boy's own DSP and the PICA200 GPU, and a straight interpreter is far too slow to run it. A dynamic recompiler translates blocks of guest code into host code as they run, which turns the emulation problem into a compilation problem, and the busywait detection handles the other half, because the Virtual Boy's software spends a lot of time spinning on a hardware status register and a recompiler that does not detect those spins will generate enormous amounts of useless code.

The claim that comes with it is that all officially licensed games are playable at full speed, even on the original 3DS. Even on the original is the part that matters, since the New 3DS has more clock cycles available and would be the easy case.

The repository layout reflects the lineage and the port. There is a source/ directory, an include/ directory, a gfx/ directory, a resources/ directory, a romfs/ directory, a tools/ directory, a scripts/ directory, a .ccls file for the compilation database, and a Makefile.linux alongside the main Makefile.

## What the emulator adds over the hardware it emulates

The feature list is a mix of emulation fidelity and conveniences the original hardware never had.

3D support is the headline, and it comes with a subtlety. The Virtual Boy had a depth slider, the IPD, which shifted the display plane, and a game could use it to move the image. On the 3DS the depth slider does something different, and the FAQ explains the problem in detail. The Virtual Boy wasn't designed with a depth slider, so games can't have their depth scaled in the way 3DS games can. The alternative is to shift the entire image backwards or forwards, similar to how the Virtual Boy's IPD slider works. The default setting, 3DS mode, starts at a neutral level and pushes the image further back as you move the slider up, keeping the metaphor fairly similar to how most 3DS games work. Alternatively, Virtual Boy IPD mode unlocks the full range, from closest to furthest.

That is a genuine design problem rather than a missing feature, and the FAQ answers it the way a designer would, by choosing which metaphor to preserve.

The rest of the list is quality of life. Game saves and savestates are supported. The 3DS display runs at 50Hz, like the Virtual Boy, which matters because the Virtual Boy's software was written against that refresh rate and running it at 60Hz would change the timing of the games. Fully customizable button mapping, including New 3DS inputs and the Circle Pad Pro, which is the accessory that adds a second stick. A virtual right D-Pad or A/B buttons on the touch screen, so the controls the Virtual Boy lacked can be on the lower screen. Configurable color palettes, for the Virtual Boy's red and black display. And local wireless multiplayer, which the Virtual Boy supported with a link cable and the 3DS does with its own wireless.

The feature list also notes that all officially licensed games are playable at full speed, which is the compatibility statement that matters in practice.

## Installation needs a modded 3DS, and a recompiler needs Luma

The installation requirements are stated in one line, and the FAQ explains why the second one exists.

A modded 3DS is needed, and once that is sorted you can install it using Universal Updater. There is also a QR code you can scan with FBI, and the latest release can be manually downloaded as a 3DSX, which can be loaded with Homebrew Launcher, or as a CIA, which can be installed to the HOME Menu with FBI. ROMs can be placed in any desired location on the SD card, and the emulator will remember the location of the last ROM you loaded.

The FAQ is where the reason for the mod is given, and it is a real constraint rather than a formality.

Can I use a flashcart, like Gateway 3DS? Red Viper uses a dynamic recompiler, which requires functionality only available when Luma is installed. Flashcarts cannot provide this, and therefore unfortunately cannot run Red Viper.

So the dynamic recompiler, the thing that makes the emulator fast, needs a custom firmware environment. That is a hard dependency and it excludes flashcart users entirely.

There is a second FAQ entry that is a troubleshooting note for a specific error. If you get the DSP firmware error, try updating your Luma3DS installation, which the author tested with v13.0.2, and once it is updated you may need to dump your DSP firmware.

The usage rules are simple. ROM files must use the .vb extension to be recognized, they may be archived in .zip files, and they may be placed anywhere on the SD card because the emulator has a file browser and remembers the most recently used directory. The README points at Planet Virtual Boy's homebrew section for games, which is the homebrew home for the platform.

## The performance overlay tells you which chip is the bottleneck

There is a developer option that shows a performance breakdown, and the FAQ's explanation of the numbers is one of the more useful pieces of documentation in the project.

It displays the time taken for All processing in one frame, DRC processing for CPU emulation, Citro3D processing for CPU graphics, and PICA200 processing for GPU graphics. It also displays the memory usage of the DRC cache, which increases over time then resets.

The acronyms are the actual hardware blocks of the Virtual Boy. The DRC is the Virtual Boy's custom CPU, the dual RISC core, and Citro3D is the chip that did the 2D drawing, the sprite and tile compositor, while the PICA200 is the GPU that did the 3D, the polygon hardware that made the Virtual Boy's famous red and black effect possible.

So the overlay is a per-chip timing breakdown, and it tells an emulator developer immediately whether a slow game is slow because of the CPU emulation, the 2D layer, the 3D layer, or the recompiler's cache behaviour. That last one is why the memory figure is there, since DRC cache growth that never resets is a sign of a recompiler problem rather than a guest program problem.

There is a rationale for the units too. As this is a developer option at heart, frametimes are displayed in milliseconds rather than FPS, as the former is much easier to reason about in this context. The target is usually 20ms, though some games only draw every other frame, so rendering has more leeway there.

The 20 millisecond target is the 3DS at 50Hz, which is exactly the refresh rate the feature list says the display runs at, and the note about every other frame is the classic Virtual Boy behaviour, since a game that waits two frames to compose a scene has twice the budget for each frame but half the number of them.

## Building it, and four optimisation levels

The build requires devkitPro, the 3DS toolchain, and one extra package.

```bash
> pacman -S 3ds-zlib
```

And the repository has submodules that have to be fetched.

```bash
> git submodule init
> git submodule update
```

Then there are four make targets, and the difference between them is only in the compiler flags, which is a useful thing to see spelled out.

The make release target is the default, and adds -O3 to CFLAGS. The make testing target also adds -O3 but outputs basic debug info to a connected debugger. The make debug target adds -g -O0, so it builds without optimizations and is easier to debug. The make slowdebug target also adds -g -O0 but outputs a lot of debug information, which will slow emulation down but might be helpful to debug game-specific issues.

That last one is the interesting flag for anyone working on this code. In a dynamic recompiler, a game-specific bug is usually in the translation of one guest instruction sequence, and the usual way to find it is to see what the recompiler generated. A build with heavy debug output and no optimisation is slow but shows you the generated code, which is the only way to debug the compiler rather than the emulated program.

The Makefile itself is a devkitPro one, so it includes the 3ds_rules from DEVKITARM, and it fails early with a clear message if DEVKITARM is not set in the environment.

```make
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
```

The version is assembled from three variables, VERSION_MAJOR, VERSION_MINOR and VERSION_MICRO, giving v1.3.4 in the current tree, and the target name and the build directory are derived from the environment.

## Where Red Viper is the wrong choice

The first wrong case is a stock 3DS. The emulator needs a modded console with Luma, and the reason is the dynamic recompiler, which requires functionality only available when Luma is installed. There is no unmodded path, and a flashcart does not work either. So the console requirement is not a formality but a hard dependency of the fastest code path.

The second wrong case is a user who wants to play the Virtual Boy library on a modern platform. There are Virtual Boy emulators that run on a desktop, on a phone and in a browser, and they do not require modifying hardware. Red Viper is for the specific case of playing on a 3DS, and if that is not the requirement the whole cost of a modded console buys nothing.

The third wrong case is a developer who wants to write an emulator rather than read one. This is a port of a 1997 emulator with a 3DS performance layer on top, and the code paths that matter are the ones the original author wrote. A dynamic recompiler written from scratch with the same goals would be a different project, and the value here is in the specific technique of busywait detection inside a recompiler, not in the Virtual Boy emulation itself.

The fourth wrong case is a legal grey area. The emulator ships no games, and the README points to homebrew for the Virtual Boy platform, but the emulator will run any .vb file you give it, and the responsibility for what you put on the card is yours.

## How it differs from a desktop Virtual Boy emulator

The comparison worth making is with the other Virtual Boy emulators, and the difference in approach is the platform constraint rather than the emulation.

A desktop emulator runs on a machine with a gigabyte of RAM and a CPU that can interpret a 32-bit RISC core at a hundred times the required speed. The accuracy problems of a Virtual Boy emulator are therefore solvable, and the interesting work is in the PICA200's polygon rendering, which is what produces the red and black stereoscopic effect, and in the timing of the two display buffers.

Red Viper has none of that headroom. A 3DS has far less RAM and a much weaker GPU, and the display is two 400 by 240 screens with the lower one a touch screen. The 3DS display runs at 50Hz, like the Virtual Boy, to preserve the timing the software expects, which is a constraint the desktop emulator does not have to respect.

So the interesting engineering in Red Viper is not the Virtual Boy emulation, which is inherited, but the three problems the 3DS creates. The first is speed, solved with the dynamic recompiler and the busywait detection. The second is the renderer, solved with hardware acceleration, and the 3DS GPU is good enough to draw the polygon effects that the Virtual Boy's PICA200 produced. The third is input, solved with the touch screen standing in for the D-Pad and the buttons the Virtual Boy did not have, and the Circle Pad Pro and New 3DS controls being mapped in.

That third problem is the one that has no equivalent in a desktop emulator, and the depth slider discussion is the clearest illustration. The 3DS has a depth control, the Virtual Boy had a different one, and the emulator has to decide which metaphor to honour, and it decides to honour the 3DS one by default while keeping the Virtual Boy behaviour available. A desktop emulator has no such problem, because it has no depth slider to reconcile.

The fourth difference is the lineage, and it shows in the licence. The code is a port of Reality Boy, whose original licence is included in the README, and it is swap ware with the condition that you send along your new program or other interesting tidbits you wrote, which the author might be interested in. Some of the code is distributed under the MIT License, and you have to check the source files to see which applies where.

## Conclusion

Red Viper fits a 3DS owner with a modded console who wants the Virtual Boy library playable at full speed with 3D support, savestates and local wireless multiplayer, and it fits a developer who wants to read a dynamic recompiler implementation in C. It does not fit someone without a modded 3DS, since the emulator needs Luma for the functionality the recompiler depends on, and it does not fit a flashcart user. Before installing, note that the ROMs must be your own and the files need the .vb extension, and that the current release is v1.3.4 from 2026-09-19 with the last push on the same day.

## FAQ

### What is Red Viper and what hardware does it need?

It is a Virtual Boy emulator for the Nintendo 3DS, continuing mrdanielps's r3Ddragon which was based on Reality Boy. It requires a modded 3DS with Luma installed, because the dynamic recompiler it uses depends on functionality only Luma provides, and flashcarts cannot run it.

### How do I install Red Viper on a 3DS?

With Universal Updater, or by scanning the QR code with FBI, or by downloading the release manually as a 3DSX loadable with Homebrew Launcher or as a CIA installable to the HOME Menu with FBI. ROM files go anywhere on the SD card and the emulator has a file browser that remembers the last directory used.

### What does the Red Viper performance overlay show?

The time taken for All processing in one frame, DRC processing for CPU emulation, Citro3D processing for CPU graphics and PICA200 processing for GPU graphics, plus the memory usage of the DRC cache which increases over time then resets. Frametimes are shown in milliseconds rather than FPS, with a target of usually 20ms.

### How do I build Red Viper from source?

Set up devkitPro, install the extra dependency with pacman -S 3ds-zlib, fetch the submodules with git submodule init and git submodule update, then pick a make target: release for -O3, testing for -O3 with basic debug info, debug for -g -O0, or slowdebug for -g -O0 with heavy debug output for diagnosing game-specific issues.

### What licence does Red Viper use?

Some of the code is under the MIT License, which you have to check per source file, but since it is a port of Reality Boy the original readme is included, and Reality Boy is copyright David Tucker 1997 to 2008 with a swap ware condition: you may use the code as long as you do not make money from it and you acknowledge the original author, and you should send along your new program or other tidbits you wrote.

## Sources

- [Issues](https://github.com/skyfloogle/red-viper/issues)
- [README](https://github.com/skyfloogle/red-viper/blob/master/README.md)
- [Releases](https://github.com/skyfloogle/red-viper/releases)
- [skyfloogle/red-viper on GitHub](https://github.com/skyfloogle/red-viper)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/skyfloogle-red-viper
