{"id":25946930,"url":"https://github.com/p2-718na/gameboy-emulator","last_synced_at":"2026-05-28T13:31:19.990Z","repository":{"id":273743216,"uuid":"920714050","full_name":"P2-718na/gameboy-emulator","owner":"P2-718na","description":"A Game Boy emulator written in c++","archived":false,"fork":false,"pushed_at":"2025-03-03T15:54:16.000Z","size":553,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-03T16:42:56.571Z","etag":null,"topics":["cpp17","emulator-programming","gameboy","gameboy-emulator"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/P2-718na.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-01-22T16:41:37.000Z","updated_at":"2025-02-25T16:54:44.000Z","dependencies_parsed_at":"2025-02-08T00:22:09.955Z","dependency_job_id":"e33a96e8-ded5-4c89-bd83-9f607cc4aab4","html_url":"https://github.com/P2-718na/gameboy-emulator","commit_stats":null,"previous_names":["p2-718na/gameboy-emulator"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/P2-718na%2Fgameboy-emulator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/P2-718na%2Fgameboy-emulator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/P2-718na%2Fgameboy-emulator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/P2-718na%2Fgameboy-emulator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/P2-718na","download_url":"https://codeload.github.com/P2-718na/gameboy-emulator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241827168,"owners_count":20026601,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp17","emulator-programming","gameboy","gameboy-emulator"],"created_at":"2025-03-04T10:17:24.972Z","updated_at":"2026-05-28T13:31:19.983Z","avatar_url":"https://github.com/P2-718na.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gameboy-emulator\n[comment]: \u003c\u003e (Code coverage was added manually)\n[comment]: \u003c\u003e (TODO implement github action to do it programmatically)\n\u003cimg src=\"https://img.shields.io/badge/code%20coverage-70%25-green\"\u003e\n\u003cimg src=\"https://github.com/P2-718na/gameboy-emulator/actions/workflows/run-tests.yml/badge.svg\"\u003e\n\nThis is an implementation of the original Game Boy (DMG0) hardware written in C++.\nIt features a full CPU implementation and an approximate PPU implementation (no audio, yet). \nThis project can be run standalone (using the provided SFML-based graphical interface)\nor it can be incorporated in another project as a library. Here are some screenshots!\n\n| \u003cimg src=\"assets/markdown/red.png\"\u003e  | \u003cimg src=\"assets/markdown/tetris.png\" \u003e | \u003cimg src=\"assets/markdown/kirby.png\"\u003e | \u003cimg src=\"assets/markdown/world.png\"\u003e |\n|:------------------------------------:|:---------------------------------------:|:-------------------------------------:|:-------------------------------------:|\n\n\n## Features and Overview\nThe goal of this project was not to achieve perfect accuracy, but rather to\nobtain a functioning implementation that can be easily improved upon. I have\napproximated some aspects of the hardware and in some places\nI have valued code clarity above raw performance. I expect most (supported) ROMs\nto run fine in this emulator, possibly with some graphical glitches. Here is a brief\nlist of all the supported features. To understand the meaning of technical terms, please refer to [HARDWARE.md](HARDWARE.md).\n\n| Feature                      | Status  | Comment                                                                                                                                                                                                                                                    |\n|------------------------------|:-------:|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| CPU Instructions             |   🟢    | All CPU instructions have been implemented and they pass Blargg's `cpu_instrs` tests (see [Testing]).                                                                                                                                                      |\n| Interrupts and timers        |   🟢    | CPU interrupts and timer have been implemented. Interrupts do pass Blargg's tests; timers do not (see [Testing]).                                                                                                                                          |\n| Savegames                    |   🟢    | Although very basic, the implementation of savegames (battery-backed cartridges) works correctly. Games are saved whenever the emulator window is closed.                                                                                                  |\n| Performance                  |   🟢    | The DMG hardware is very simple and the emulator runs fast. Multithreading could be implemented easily to speed up performance even more. Profiler shows that the performance impact is uniformly spread out throughout the different Game Boy components. |\n| Graphics                     |   🟠    | PPU Timings are machine-cycle accurate, but there is no FIFO implementation. Each scanline gets drawn all at once. Expect some minor glitches.                                                                                                             |\n| Timing accuracy              |   🟠    | The time step of the emulator is one machine-cycle. CPU instructions are atomic but execution is still delayed by the correct amount of cycles.                                                                                                            | \n| ROM Loading                  |   🟠    | Only `MBC0`, `MBC1` and `MBC3` (without RTC hardware) cartridges are implemented. The code is set up to allow for easy addition of new cartridge types. Multicart ROMs are not supported!                                                                  |\n| Serial                       |   🟠    | Only basic serial reading was implemented for debugging purposes.                                                                                                                                                                                          |\n| Audio                        |   🔴    | No APU implementation yet.                                                                                                                                                                                                                                 |\n| Hardware bugs and edge cases |   🔴    | Most of the original hardware's edge cases and bugs have not been implemented. Regardless, official ROMs should not depend on them in the first place.                                                                                                     |\n| Savestates                   |   🔴    | The way the code is set up makes serializing the state a bit cumbersome. Regardless, I did not intend for savestates to be available in the first place.                                                                                                   |\n\n\n## Building\n### Dependencies\n\nThe emulator library does not use any external dependency, apart from the standard\nlibrary. To build the standalone program, however, you will need:\n- [Lyra](https://github.com/bfgroup/Lyra) (already bundled)\n- [Doctest](https://github.com/onqtam/doctest) (already bundled)\n- [SFML 2.6](http://www.sfml-dev.org/) (has to be installed manually)\n\nThe recommended way to build this code is by using [CMake](https://cmake.org/).\nWhen testing and when writing new code, one should compile using the `Debug` configuration,\nas it enables additional checks (`-fsanitize=\"address\"`, code asserts, ...), disables optimization\nand writes debugging symbols to the binary file. For the best performance, build using the `Release`\nconfiguration. Bear in mind that code asserts are _disabled_ in the latter, and they should not be relied\nupon to handle control flow.\n\n### Building the standalone emulator\n\n```shell\n# Clone the repo\ngit clone git@github.com:P2-718na/gameboy-emulator.git\n\n# Create and cd to build directory\ntake gameboy-emulator/build\n\n# Prepare build files. Use \"Debug\" instead of \"Release\" to build in debug mode.\ncmake .. -DCMAKE_BUILD_TYPE=Release\n\n# Build everything\nmake\n```\n\nThis will configure all the needed files. Two executables will be generated\n(see [Running] for additional information on what they do).\n\n```bash\n./emulator   # Run standalone emulator\n\n./test      # Run tests\n```\n\n### Building the emulator library\nAll the emulator code is contained in the `Gameboy` class and its dependencies. To use this\nin your own CMake project, make sure to\n1) add it as a source directory,\n2) link it to your target and\n3) add all the necessary include folders.\n```cmake\n# ...\n\nADD_SUBDIRECTORY(src)\n\n# ...\n\nTARGET_LINK_LIBRARIES(your_target Gameboy)\n\n# ...\n\nINCLUDE_DIRECTORIES(\n        \"${PROJECT_SOURCE_DIR}/src\"\n        \"${PROJECT_SOURCE_DIR}/src/Frontend\"\n        \"${PROJECT_SOURCE_DIR}/src/Gameboy\"\n        \"${PROJECT_SOURCE_DIR}/src/CPU\"\n        \"${PROJECT_SOURCE_DIR}/src/PPU\"\n        \"${PROJECT_SOURCE_DIR}/src/TimerController\"\n        \"${PROJECT_SOURCE_DIR}/src/AddressBus\"\n        \"${PROJECT_SOURCE_DIR}/src/Cartridge\"\n)\n\n# ...\n```\n\nTo learn how to use the `Gameboy` library, please refer to the [documentation]. \n\n\n### Building on different systems\n\nThe code was written on macOS Monterey (Apple clang 14.0.0) and it builds just fine on Linux.\nBuilding on Windows and other systems should be just a matter of installing SFML and running CMake.\n\n## Running\n### Standalone emulator\nThe standalone emulator should be called with exactly one parameter: the path to the ROM file to be loaded\n```bash\n./emulator rom-name.gb\n```\nif the ROM file is of a battery-backed cartridge, a save file will be generated (if not already present)\nin the same folder as the ROM, named `rom-name.gb.sav`. The save file will then be loaded\nautomatically every time the game is run, and it will be updated when the emulator is closed. Please bear in mind that\nthe ROM and the save file should be kept in the same folder and should respect the naming convention that was just\ndescribed here, in order to be loaded correctly. The save format is the same as of most other emulators (raw RAM data).\n\nRunning the emulator will open a window. Then, the user can interact with the emulator\nusing the following key bindings.\n\n|   Key   |       Game Boy button       |\n|:-------:|:---------------------------:|\n|  Space  |              A              |\n|  Shift  |              B              |\n|  Enter  |            Start            |\n| Escape  |           Select            |\n| W/A/S/D | \u0026uarr;/\u0026larr;/\u0026darr;/\u0026rarr; |\n|    K    |    Uncap emulation speed    |\n|    L    |   Write save file to disk   |\n\n## Code structure\n\nThe code follows the basic principles of Object-Oriented Programming.\nEach physical Game Boy component is implemented in its own separate class (`CPU`, `PPU`, `TimerController`).\nEach component has\na `machineClock()` method (to be called each clock cycle) and has access to the shared `AddressBus` and to the\nmain `Gameboy` instance. The `Cartridge` class is an interface used to implement different\ncartridge types. Finally, the `Frontend` class handles the interactions with the user and the environment.\nThe `Gameboy` class is to be intended as the public interface of the library, and additional documentation \nis available for it (see [Documentation]). The following table contains a summary of what each class does. \n\n| Class             | Description                                                                                                                                                                       |\n|-------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `Frontend`        | Handles loading of ROMs and save files, graphical output, user input, and clocks the emulator.                                                                                    |\n| `Gameboy`         | Container for all the Game Boy components. Handles interrupt requests and exposes methods that allow `Frontend` to read and change the status of the system (display, inputs...). |\n| `AddressBus`      | Handles reads and writes from RAM, ROM and registers. All components of the Game Boy should have access to this.                                                                  |\n| `Cartridge`       | Virtual base class that defines the interface that each cartridge type should have. Implementations of new cartridge hardware should be added as a derived class of this one.     |\n| `CPU`             | Represents the physical Game Boy processor. Reads and executes instructions from the Address Bus.                                                                                 |\n| `PPU`             | Represent the physical Game Boy graphics unit. Periodically updates the screen buffer and requests the necessary interrupts.                                                      |\n| `TimerController` | Represent the physical Game Boy timer hardware. Consists of a series of counters that increment at each clock cycle and eventually request interrupts.                            |\n\n## Testing\n\nIn this project I have implemented a comprehensive test routine by combining three main methods:\n\n1. **Unit Tests**,\n2. **Test ROMs**, and\n3. **Runtime Assertions**.\n\nFor detailed information about the testing process, please see [TESTING.md](TESTING.md).\n\n## Additional notes\n\n### Contributing\n\nIf you want to open a pull request, please see [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Hardware primer\n\nFor a quick introduction to the DMG0's hardware, and the list of all the references I used for this project, see\n[HARDWARE.md](HARDWARE.md)\n\n### Documentation\n\nDocumentation is automatically generated for the `Gameboy` library using Doxygen. The documentation for\nthe current version on `master` is available [here](https://p2-718na.github.io/gameboy-emulator/html/classgb_1_1Gameboy.html).\n\n### On code clarity\nI used several tools to make sure that my code is correct, clean and consistent.\nNamely:\n\n1. Clang-Format to check code formatting ([.clang-format][B]).\n2. Clang-Tidy to check for common bad-practice warnings\n   ([CLion default configuration][3]).\n\nI also run the code through _Valgrind Memcheck_ so to make sure that there are\nno memory-related errors in my code.\n\n--------------------------------------------------------------------------------\n\n[Doctest]: https://github.com/doctest/doctest\n\n[3]: https://confluence.jetbrains.com/display/CLION/Clang-Tidy+in+CLion%3A+default+configuration?_ga=2.184137826.59717557.1623227743-1021145942.1623227743\n[4]: https://google.github.io/styleguide/cppguide.html\n\n[B]: .clang-format\n\n[Building]: #building\n[Running]: #running\n[Testing]: #testing\n[Documentation]: https://p2-718na.github.io/gameboy-emulator/html/classgb_1_1Gameboy.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp2-718na%2Fgameboy-emulator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fp2-718na%2Fgameboy-emulator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fp2-718na%2Fgameboy-emulator/lists"}