Home

Awesome

Build License: MIT

<p align="center"> <img src="/resource/logo.png" width="420px"> </p>

About

CAMLBOY is a Game Boy emulator that runs in the browser. It is written in OCaml and compiled to JavaScript using js_of_ocaml.

Try it out in our demo page!

Accompanied blog posts

Screenshots

<div align="center"> <img src="/resource/screenshot/pokemon-aka.gif" height="500"/> </div> <div align="center"> <img src="/resource/screenshot/tetris-opening.gif"/> <img src="/resource/screenshot/zelda-opening.gif"/> <img src="/resource/screenshot/kirby-opening.gif"/> <img src="/resource/screenshot/donkykong-opening.gif"/> </div>

Project goals and non-goals

Goals

Stretch goals

Non-goals

Current state

Benchmark results

We ran the first 1500 frames of Tobu Tobu Girl in headless mode (i.e., without UI) for ten times each and calculated the average FPS. The error bars represent the standard deviation. See benchmark.md for details about the environment/commands used for the benchmark.1

<div align="center"> <figure> <img src="resource/benchmark-result.png" /> </figure> <div> <figure> <img src="/resource/screenshot/benchmark-60fps.gif" /> </figure> <div><i>First 1500 frames of Tobu Tobu Girl (in 60FPS)</i></div> </div> <div> <figure> <img src="/resource/screenshot/benchmark-nothrottle.gif" /> </figure> <div><i>First 1500 frames of Tobu Tobu Girl (in 1000FPS)</i></div> </div> </div>

Architecture diagram

Here is a rough sketch of the various modules and their relationship. You can find details in the accompanied blog post.

<div align="center"> <img src="/resource/diagram/camlboy_architecture.png" height="500"/> </div>

Directory Structure

TODO

How to run

Prerequisite

Install opam, OCaml's package manager, if you haven't yet.

Basic setup

# Clone repository
git clone https://github.com/linoscope/CAMLBOY.git
# cd into repository
cd CAMLBOY
# Create local switch for the repository
opam switch create . ocaml-base-compiler.4.13.1
eval $(opam env)
# Install system packages required by opam packages (SDL, etc)
opam pin add camlboy.dev . --no-action
opam depext camlboy
# Install opam dependencies
opam install . --deps-only --with-test

How to run with UI

Run with SDL2 UI

# Build
$ dune build
# Usage: main.exe [--mode {default|withtrace|no-throttle}] <rom_path>
# For example:
$ dune exec bin/sdl2/main.exe -- resource/games/tobu.gb

Run with js_of_ocaml UI

# Build
$ dune build
# Serve `_build/default/bin/web` using some server. For example, run the following with python:
$ python -m http.server 8000 --directory _build/default/bin/web
# Now open `localhost:8000` in the browser

How to run benchmarks in headless mode

Benchmark for native build

# Usage: bench.exe [--frames <frames>] <rom_path>
# For example:
$ dune exec bin/sdl2/bench.exe -- resource/games/tobu.gb --frames 1500
ROM path: resource/games/tobu.gb
  Frames: 1500
Duration: 1.453315
     FPS: 1032.123098

Benchmark for js_of_ocaml build

First, follow the steps in "How to run with UI - js_of_ocaml frontend" above. Now open http://localhost:8000/bench.html?frames=<frames>&rom_path=<rom_path>. For example, if you open http://localhost:8000/bench.html?frames=1500&rom_path=./tobu.gb you should see something like this:

web-bench-example

How to run tests

# Run all tests:
$ dune runtest
# Run unit tests only:
$ dune runtest test/unit_tests/
# Run integration tests (tests that use test ROMs):
$ dune runtest test/rom_tests/

Resources

Source of built-in game ROMs:

Footnotes

  1. Note that we can not use this benchmark to compare the FPS with other Game Boy emulators. This is because the performance of an emulator depends significantly on how accurate it is and how much functionality it has. For example, CALMBOY does not implement the APU (Audio Processing Unit), so there is no point in comparing its FPS with emulators with APU support.