• Stars
    star
    444
  • Rank 97,624 (Top 2 %)
  • Language
    C++
  • License
    MIT License
  • Created about 4 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A gameboy emulator in several different languages

RosettaBoy

C C++ Go Nim PHP Python Rust Zig

Trying to implement a gameboy emulator in a bunch of languages for my own amusement and education; also giving people an opportunity to compare the same code written in different languages, similar to Rosetta Code but with a non-trivial codebase :)

The main goals are:

  • Readability of the code
  • Consistency across langauges
  • Idiomatic use of language features
  • Basic playability

Notably, 100% accuracy is not a goal - if Tetris works perfectly then I'm happy, if other games require more obscure hardware features, then I'll weigh up whether or not the feature is worth the complexity.

Also yes, "consistent across languages" and "idiomatic" can be at odds - there are subjective compromises to be made, but for the most part that doesn't seem to be a huge problem. Rust uses Result, Python uses Exception, Go uses error - but so far it's always been pretty obvious that eg NewCart() in go and Cart::new() in rust are doing fundamentally the same thing in the same way.

So far all the implementations follow a fairly standard layout, with each module teaching me how to do a new thing. In fact they're all so similar, I wrote one copy of the documentation for all the implementations:

  • main: exception handling
  • args: argument parsing
  • cpu: CPU emulation
  • gpu: graphical processing
  • apu: audio processing
  • buttons: user input
  • cart: binary file I/O and parsing
  • clock: timing / sleeping
  • consts: lists of constant values
  • errors: standard errors / exceptions / etc
  • ram: array access where some array values are special

Pull requests to translate into new languages, or fleshing out existing languages, are very welcome :)

Dev Guide

I want to keep the build processes as simple as possible:

  • cd into the directory for any implementation
  • ./build.sh to build the standard version with release-mode compiler flags
  • ./rosettaboy-release [...] to run games

Ideally the build script should also fetch (if needed) any dependencies, the only assumption I want to make is that the user has the standard language dev kits installed (eg we assume anyone who wants to work on the Rust version will have Cargo installed; anyone who wants to work on Python will have virtualenv + pip; etc)

If you have either Nix or Docker available, you can run ./utils/shell.sh to create and run an environment with all necessary dev tools pre-installed. β€” ./build.sh && ./rosettaboy-release --headless --silent should be able to pass tests for all languages.

If you prefer Docker, you can use ./utils/shell-docker.sh instead.

If you prefer Nix, you can manually run nix develop or nix-shell instead. When run with an implementation as an argument, e.g. nix develop .#py, it will only provide what is needed for that language, and when run in the project root it will provide everything needed for all languages. Alternatively, there is also an integration with nix-direnv.

Benchmarks

Warning: These implementations aren't 100% in-sync, so take numbers with a large grain of salt. For example, as of this writing, the PHP version is using a stub SDL mock instead of calling the real C library, because I couldn't find an SDL library that worked.

If somebody knows how to measure CPU instructions instead of clock time, that seems fairer; especially if we can get the measurement included automatically via github actions. Pull requests welcome :)

Running on an M1 Macbook Pro, using (to my knowledge) the latest version of each compiler, with standard "release mode" flags (see each language's build.sh for exactly which flags are used):

$ ./all.py bench | ./utils/sort.py
  nim / lto    : Emulated 16438 frames in 10.00s (1643fps)
   rs / lto    : Emulated 16029 frames in 10.00s (1603fps)
  cpp / lto    : Emulated 15064 frames in 10.00s (1506fps)
    c / lto    : Emulated 15054 frames in 10.00s (1505fps)
   rs / release: Emulated 13904 frames in 10.00s (1390fps)
    c / release: Emulated 13368 frames in 10.00s (1337fps)
  cpp / release: Emulated 12967 frames in 10.00s (1297fps)
  nim / release: Emulated 11860 frames in 10.00s (1185fps)
  zig / release: Emulated  8844 frames in 10.00s (884fps)
  zig / safe   : Emulated  7206 frames in 10.00s (721fps)
    c / debug  : Emulated  5914 frames in 10.00s (591fps)
  cpp / debug  : Emulated  5663 frames in 10.00s (566fps)
   go / release: Emulated  5029 frames in 10.00s (503fps)
  pxd / release: Emulated  3610 frames in 10.00s (361fps)
  nim / debug  : Emulated  2587 frames in 10.00s (258fps)
   rs / debug  : Emulated  1808 frames in 10.01s (181fps)
   py / mypyc  : Emulated   789 frames in 10.01s (79fps)
  php / opcache: Emulated   655 frames in 10.00s (65fps)
  php / release: Emulated   257 frames in 10.02s (26fps)
   py / release: Emulated   165 frames in 10.02s (16fps)

Also if you spot some bit of code that is weirdly slow and making your favourite language look bad, pull requests to fix that might be welcome too, but "simplicity and consistency" are going to take priority (eg an "add an inline flag to this function" would be great but "replace python's CPU interpreter with a JIT compiler written as a C extension module" would probably be rejected[0])

[0] That said if somebody wanted to come up with a separate "python but all the slow parts are replaced with C modules like they would be in a real app" implementation, that could be interesting...

More Repositories

1

pgosquery

Like Facebook's OSQuery, but for Postgres
Python
447
star
2

shimmie2

Shish's official Shimmie code repository
PHP
353
star
3

context2

Golang flame chart viewer
Go
69
star
4

sikulpy

A reimplementation of the Sikuli API for CPython
Python
30
star
5

mic2midi

Whistle / Hum / Sing into a microphone, generate MIDI signals to drive a sequencer
Python
21
star
6

devtools-py

A Python client for Chrome's DevTools protocol / a headless chrome control library
Python
15
star
7

pyge

A game archive extraction tool written in Python, designed to make it easy to support new formats
Python
14
star
8

eve-mlp

Mobile Launch Platform for EVE Online
Python
12
star
9

cview3

AJAX comic viewer
JavaScript
12
star
10

clearskies-gui

A simple GUI for clearskies
Python
10
star
11

firehose

GPG-based chat network, resistant to traffic analysis
Python
10
star
12

esphome-projects

8
star
13

apache2rrd

Makes pretty graphs out of apache (or similar) log files
Python
7
star
14

Git-Flow-Eclipse

TODO: an eclipse plugin for easy git-flow based development ("TODO" as in "doesn't do anything useful yet")
Java
5
star
15

shimmie2-utils

Various utility scripts for Shimmie2
PHP
4
star
16

sqliteshelf

Allows an SQLite database to be used as a python dictionary with persistant storage
Python
4
star
17

ugh

A tinder client for people who think that tinder is awful
Python
4
star
18

csb

A curses-based browser for SQL databases
Python
4
star
19

context-apis

A collection of libraries for creating .ctxt files
Python
3
star
20

travmap

Travian Mapping Tool
PHP
3
star
21

rav

random avatar host
Python
3
star
22

lemonade

A somewhat fruity Ascii Demo Engine. Compilation of demos requires perl and 7-zip; playback requires perl, GNU tail and zcat (or compatible).
Perl
3
star
23

wp_deusex

Deus Ex Theme for Wordpress
PHP
2
star
24

guts

A proof-of-concept sparkleshare back-end
C#
2
star
25

eventtracer-py

Event Tracing for Python
Python
2
star
26

shm-cached

A shimmie cache daemon
Rust
2
star
27

link

See what you've got in common
Python
2
star
28

git-extras

A few somewhat hacky third-party git commands
Python
2
star
29

kuri2d

A simple game loosely based on Kurushi
C
2
star
30

spawn-fcgi.php

A shim to host FastCGI webapps on a PHP webhost
PHP
2
star
31

cinema

For watching with friends
TypeScript
2
star
32

sharedraw

A shared doodlepad, demonstrating python UDP networking
Python
2
star
33

shimmie1

Shish's Image Board, ancient edition
PHP
2
star
34

patch-archive

Various patches to third-party software
1
star
35

seagame

A game, involving the sea
Erlang
1
star
36

filemon

See what apps are making use of a given file
Python
1
star
37

microhtml

A tiny PHP HTML generating library
PHP
1
star
38

sdog

systemd-style process monitor
Python
1
star
39

shimpy

A direct translation of shimmie to python
Python
1
star
40

divetools2

a website with some scuba notes
TypeScript
1
star
41

tidydns

Tiny Dynamic DNS
Python
1
star
42

orpen

Drop-dead simple VPN
Python
1
star
43

votabo

Python
1
star
44

context

Python .ctxt viewer
Python
1
star
45

chunker

Yet another P2P file sync app, mostly abandoned
Python
1
star
46

slek3

Shish's Linux Enhancement Kit (aka shish's dotfiles)
Python
1
star
47

python-clearskies

A python library for communicating with the ClearSkies daemon
Python
1
star
48

java4k

A java game in 4KB (or less)
Java
1
star
49

packetstats

Packet sniffing and statsing
Rust
1
star
50

browserslist-logs

Turn webserver access logs into a browserslist file
TypeScript
1
star
51

std-solver

An experiment in solving Spot-the-Difference games
Python
1
star
52

travis-py35-opencv3

A docker recipe to build a Travis-CI environment with Python 3.5 and OpenCV 3.2 included
Shell
1
star
53

hyperapp-navigation

A polished version of the abandoned @hyperapp/navigation
HTML
1
star
54

commentonthis

Comment on This!
Python
1
star
55

microcrud

A tiny library for managing create / read / update / delete operations
PHP
1
star
56

shimmie2fe

Mobile-friendly Shimmie Frontend
TypeScript
1
star
57

zelda

Apache log file compressor
Python
1
star