GameBoy Emulator in WASM

jamil201 pts0 comments

GitHub - victorgomes/gb: Leiksveinn GameBoy · GitHub

/" data-turbo-transient="true" />

Skip to content

Search or jump to...

Search code, repositories, users, issues, pull requests...

-->

Search

Clear

Search syntax tips

Provide feedback

--><br>We read every piece of feedback, and take your input very seriously.

Include my email address so I can be contacted

Cancel

Submit feedback

Saved searches

Use saved searches to filter your results more quickly

-->

Name

Query

To see all available qualifiers, see our documentation.

Cancel

Create saved search

Sign in

/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up

Appearance settings

Resetting focus

You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.

Dismiss alert

{{ message }}

victorgomes

gb

Public

Notifications<br>You must be signed in to change notification settings

Fork

Star

main

BranchesTags

Go to file

CodeOpen more actions menu

Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit

History<br>1 Commit<br>1 Commit

include

include

src

src

tests

tests

web

web

.clang-format

.clang-format

.gitignore

.gitignore

ARCHITECTURE.md

ARCHITECTURE.md

LICENSE

LICENSE

Makefile

Makefile

README.md

README.md

TODO.md

TODO.md

gb.png

gb.png

View all files

Repository files navigation

Leiksveinn GameBoy — a Game Boy (DMG-01 / Color) emulator

A small, readable Game Boy (Color) emulator written in C with SDL3. The design favors a<br>flat, globally-visible machine state and direct code over deep abstraction, so it<br>stays easy to read and hack on. See ARCHITECTURE.md for how the<br>pieces fit together, and TODO.md for the remaining gaps.

Features

Full SM83 CPU (validated against the SM83 single-step tests, 500/500 files, and Blargg).

Dot-driven pixel-FIFO PPU (background, window, sprites); renders dmg-acid2 pixel-perfect.

All four APU channels + mixer; passes Blargg dmg_sound 12/12.

Accurate timing: an M-cycle bus with T-cycle interrupt sampling. Passes Blargg<br>mem_timing / instr_timing and 66/75 of the Mooneye acceptance suite (the<br>remaining 9 need non-DMG hardware models).

Game Boy Color (CGB): colour palettes + tile attributes, VRAM/WRAM banking,<br>double-speed, and HDMA — CGB games (e.g. Pokémon Crystal) run in colour; DMG<br>games are unaffected and get a compatibility colourisation on CGB. Model is taken<br>from the cart header or forced with --cgb / --dmg / --agb.

Mappers: ROM-only, MBC1 (incl. MBC1M multicart), MBC2, MBC3/MBC30 (live RTC),<br>MBC5, MMM01, HuC1, HuC3 (RTC), BANDAI TAMA5 (RTC), and the Game Boy Camera.

Battery SRAM and RTC persisted to .sav (VBA/BGB/mGBA-compatible footer).

Full-machine save states, screenshots, fast-forward, and an FPS overlay.

Two-player split-screen play over a local link cable (--split).

Game Boy Printer (--printer); each print is saved as a BMP.

Loads ROMs straight from .zip archives.

Runs natively (SDL3) and in the browser (WebAssembly, make web) — the web<br>build is an installable, offline PWA with an on-screen phone shell.

Build

Requires a C23 compiler and SDL3.

brew install sdl3 pkgconf # macOS (Linux: apt install libsdl3-dev / dnf install SDL3-devel)<br>make # produces ./gb<br>make DEBUG=1 # AddressSanitizer + UBSan build<br>make clean

SDL3 ships no *-config script, so the Makefile locates it via pkg-config (hence<br>pkgconf). The Game Boy Camera shoots from a real webcam through SDL3's<br>cross-platform camera API (macOS / Linux / Windows); with no camera or permission it<br>falls back to a synthetic test image.

Web build (optional)

make web # needs the Emscripten SDK (emcc) on PATH; writes web/gb.js<br>open web/index.html # runs straight from file:// — no server needed

The wasm is base64-embedded into a single gb.js, so the page works from the<br>filesystem. Battery saves and save states are kept in the browser's IndexedDB.<br>Served over https:// (or localhost) it is an installable, offline PWA : a<br>service worker precaches the app shell, and there is an on-screen Game Boy shell<br>(touch D-pad + face buttons, a navigable menu, fast-forward) so it plays on a phone.<br>The Game Boy Camera uses the browser webcam via getUserMedia (which needs a secure<br>context), falling back to the synthetic scene when access isn't granted. The link<br>cable (--split) is native-only.

Run

./gb path/to/rom.gb # run a ROM (a .zip containing one .gb also works)<br>./gb # no ROM: just show the DMG test pattern<br>./gb rom.gb --printer # attach a Game Boy Printer (each print → a BMP)<br>./gb rom.gb --split [rom2] # two-player split screen over the link cable<br>./gb rom.gb --boot dmg_boot.bin # boot through the (optional) DMG boot ROM

Headless mode (no window/audio) is handy for CI and quick checks:

SDL_VIDEODRIVER=dummy SDL_AUDIODRIVER=dummy \<br>./gb rom.gb --screenshot out.bmp --frames 600 # run 600 frames, dump a BMP, exit

Game ROMs are not included...

game sdl3 search window commit from

Related Articles