Skip to content

brennier/hagemu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

285 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Hagemu is a GameBoy emulator

This is an attempt to write a GameBoy emulator in C99. This is a personal project to learn more about computers and emulation. SDL3 is used to draw the pixels and handle input. Emscripten is used to compile the project into WebAssembly. At the moment, this project is still a work in progress.

You can run this emulator inside your web browser!

You can try out this emulator in your web browser at this link: https://hagemu.dev/

Disclaimers:

  • You need to use a keyboard or game controller. There is no key remapping or touch screen support at the moment.
  • To run a .gb file, please drag and drop the file directly onto the web page.

Tested games (no noticable glitches)

Most original gameboy games should run fine. If you find any glitches, please let me know. The following games have been tested:

  • Tetris
  • Dr. Mario
  • Super Mario Land
  • Metroid II
  • Zelda: Link's Awakening
  • Pokemon Red, Blue, and Yellow

Progress Report (click here to expand)

  • Finish the CPU
    • Parse opcodes
    • Implement double registers
    • Write functions for the opcodes
    • Set flags in the f register
    • Write the interrupt dispatch code
    • Add a clock and timer interrupts
    • Fix cycle timing of opcodes
    • Cycle-correct memory reads/writes
    • Pass Blargg's CPU test roms
      • cpu_instrs test
      • instr_timing test
      • mem_timing test
      • mem_timing_2 test
  • Finish the PPU (Picture Processing Unit)
    • Display tiles from VRAM
    • Draw tiles to window
    • Draw the background layer
    • Add window overlay
    • Implement the scroll registers SCX and SCY
    • Switch to a scanline based renderer
    • Update the scroll registers per scanline
    • Implement DMA transfers
    • Add sprites
    • Implement sprite attributes
    • Support for 8x16 sprite mode
    • Implement LCD STAT interrupts
    • Respond to the LCD control register (except for disabling the PPU)
    • Pass dmg-acid2 test rom
  • Finish the APU (Audio Processing Unit)
    • Setup sound and add an audio callback function
    • Synchronize the length, sweep, and envelope timers
    • Downsample from 2MHz to 48kHz
    • Implement a IIR butterworth low pass filter to cut down on audio aliasing
    • Synchronize the sample rates of the individual sound channels
    • Finish Master controls
      • Turn APU on/off
      • Mono volume control
      • Panning left/right per channel
      • Volume control left/right per channel
    • Finish channels 1 and 2 (pulse waves)
      • Turn DAC on/off
      • Basic volume
      • Correct frequency
      • Wave duty
      • Envelope
      • Reset trigger
      • Sweep (channel 1 only)
      • Length timer
    • Finish channel 3 (custom waveform)
      • Turn DAC on/off
      • Correct frequency
      • Basic volume
      • Read and output the custom wave data
      • Reset trigger
      • Length timer
    • Finish channel 4 (random noise)
      • Turn DAC on/off
      • Basic volume
      • Correct frequency
      • Linear-feedback shift register
      • Envelope
      • Reset trigger
      • Length timer
  • Implement support for various Memory Bank Controller (MBC) chips
    • Separate MBC code into its own file
    • MCB1 (Basic support)
    • MCB1 (Full support)
    • MCB3 (except for Real Time Clock)
    • Basic support for saving and loading .sav files
    • Real Time Clock support
  • Minor fixes
    • Separate the joypad logic from the Raylib library
    • Add support for gamepads
    • Test gamepad support
    • Calculate the half-carry as (a ^ b ^ result) & 0x10
    • Add 'inline' the CPU opcode functions
    • Rewrite the f register as separate bools
    • Fix glitch where a sprite partially clips if it's on the left or top border
    • Fix bug where window X Position is less than 7
    • Make the color palette settable instead of internal to the ppu
    • Fill the sound buffer directly instead of using a callback
    • Make the audio registers readable
    • Maybe use float instead of int16_t for audio bit depth
    • Maybe use RGBA8888 instead of RGBA5551 pixel format
    • Mute a sound channel if its frequency is above 20kHz
    • Add support for the VIN sound channel
    • Rewrite PPU to be more modular
    • Add option to blend frames
    • Emulate the timing of the DMA
    • Add support for disabling the PPU
    • Implement the STOP instruction
    • Test the HALT instruction
    • Add support for the serial data port
    • Pass Blargg's interrupt_time test
    • Run the Mooneye Test Suite
    • Make a cool logo
    • Add a custom boot rom
    • Use _Static_assert to ensure endianness
    • Use some profiling tools to find critical code blocks
    • Compile program using -O3 and -flto and -ffast-math
  • Known glitches
    • Pokemon Red corrupted save data
      • Fixed! My SRAM implementation was off-by-one
    • Pokemon Aka character constantly moves up
      • Fixed! The upper two bits of joypad register should always be 1
  • WebAssembly version
    • Get the WebAssembly version working
    • Add a simple front-end UI
    • Upload to my website (https://uezu.dev/projects/hagemu)
    • Automatically save and load .sav files using a local IndexedDB file system
    • Progressive Web Application support
      • Basic support
      • Add a service worker for caching and retrieving files without the internet
    • Rewrite the html index file from scratch
    • Automatically cache and load the last played game
    • Select file using a mobile browser
    • Touchscreen support
    • Download and upload save files
    • Put the loading bar where the canvas is
  • Add a UI
    • Drag and drop rom files onto the window
    • Select file using a file dialog window
    • Add custom shaders (mostly for a grid overlay)
    • Settings menu
      • Button mapping menu
      • Audio menu
      • Color palette menu
      • Save state menu
  • Add GBC functionality
    • Double speed mode
    • Extra work and video ram
    • HDMA features
    • Pass cgb-acid2
  • Future Refactoring Ideas
    • Separate the core from the interface
    • Switch from Raylib to SDL3
    • Synchronize the APU along with the CPU and PPU
    • Separate cart.c and joypad.c from mmu.c
    • Use CMake instead of make
    • Organize all state into a gameboy struct
    • Support save/load states
    • Rewrite the CPU so that it can tick 1 m-cycle per call
    • Rewrite the PPU using a pixel pusher renderer
    • Remove the union type punning of the CPU registers

Links for the future (click here to expand)

About

An original GameBoy emulator using C99 and SDL3

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors