0dmg

Learning Rust by building a partial Game Boy emulator.

This project is maintained by jeremyBanks

It has been hard to split up the Game Boy into different pieces, without those pieces all depending on each other. For now, it’s much simpler for reference/pointer management to put the entire Game Boy system state in a single struct. This sounds gross at first, but read on.

Different functionality is in different “traits” (a trait is like an interface). So the CPU trait includes methods for reading from registers, and the cpu module provides the CPU trait and implements it for GameBoy. (The implementation of a trait for a type can be separate from other methods for that type.)

So if you import GameBoy, by default only its .run() method is exposed. You need to manually choose to import traits, like this:

use emulator::cpu::CPU;

in order to expose other methods like .z_flag().

Traits can only contain methods, not fields, so this doesn’t encapsulate the data from each component. To do that, we also split up the struct’s data into sub-types that are defined alongside the traits in other modules.

pub struct GameBoy {
    cpu: CPUData,
    mem: MemoryData,
    aud: AudioData,
} 

This allows, for example, our cpu module to always keep all of the fields in CPUData private, while exposing its methods to anybody who imports it trait.

It’s a bit of a weird design partially born out of confusion, but it’s workable.