cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

Gb_Apu.h (5912B)


      1// Nintendo Game Boy sound hardware emulator with save state support
      2
      3// Gb_Snd_Emu 0.2.0
      4#ifndef GB_APU_H
      5#define GB_APU_H
      6
      7#include "Gb_Oscs.h"
      8
      9struct gb_apu_state_t;
     10
     11class Gb_Apu {
     12public:
     13// Basics
     14
     15	// Clock rate that sound hardware runs at.
     16	enum { clock_rate = 4194304 * GB_APU_OVERCLOCK };
     17
     18	// Sets buffer(s) to generate sound into. If left and right are NULL, output is mono.
     19	// If all are NULL, no output is generated but other emulation still runs.
     20	// If chan is specified, only that channel's output is changed, otherwise all are.
     21	enum { osc_count = 4 }; // 0: Square 1, 1: Square 2, 2: Wave, 3: Noise
     22	void set_output( Blip_Buffer* center, Blip_Buffer* left = NULL, Blip_Buffer* right = NULL,
     23			int chan = osc_count );
     24
     25	// Resets hardware to initial power on state BEFORE boot ROM runs. Mode selects
     26	// sound hardware. Additional AGB wave features are enabled separately.
     27	enum mode_t {
     28		mode_dmg,   // Game Boy monochrome
     29		mode_cgb,   // Game Boy Color
     30		mode_agb    // Game Boy Advance
     31	};
     32	void reset( mode_t mode = mode_cgb, bool agb_wave = false );
     33
     34	// Reads and writes must be within the start_addr to end_addr range, inclusive.
     35	// Addresses outside this range are not mapped to the sound hardware.
     36	enum { start_addr = 0xFF10 };
     37	enum { end_addr   = 0xFF3F };
     38	enum { register_count = end_addr - start_addr + 1 };
     39
     40	// Times are specified as the number of clocks since the beginning of the
     41	// current time frame.
     42
     43	// Emulates CPU write of data to addr at specified time.
     44	void write_register( blip_time_t time, unsigned addr, int data );
     45
     46	// Emulates CPU read from addr at specified time.
     47	int read_register( blip_time_t time, unsigned addr );
     48
     49	// Emulates sound hardware up to specified time, ends current time frame, then
     50	// starts a new frame at time 0.
     51	void end_frame( blip_time_t frame_length );
     52
     53// Sound adjustments
     54
     55	// Sets overall volume, where 1.0 is normal.
     56	void volume( double );
     57
     58	// If true, reduces clicking by disabling DAC biasing. Note that this reduces
     59	// emulation accuracy, since the clicks are authentic.
     60	void reduce_clicks( bool reduce = true );
     61
     62	// Sets treble equalization.
     63	void treble_eq( blip_eq_t const& );
     64
     65	// Treble and bass values for various hardware.
     66	enum {
     67		speaker_treble =  -47, // speaker on system
     68		speaker_bass   = 2000,
     69		dmg_treble     =    0, // headphones on each system
     70		dmg_bass       =   30,
     71		cgb_treble     =    0,
     72		cgb_bass       =  300, // CGB has much less bass
     73		agb_treble     =    0,
     74		agb_bass       =   30
     75	};
     76
     77	// Sets frame sequencer rate, where 1.0 is normal. Meant for adjusting the
     78	// tempo in a game music player.
     79	void set_tempo( double );
     80
     81// Save states
     82
     83	// Saves full emulation state to state_out. Data format is portable and
     84	// includes some extra space to avoid expansion in case more state needs
     85	// to be stored in the future.
     86	void save_state( gb_apu_state_t* state_out );
     87
     88	// Loads state. You should call reset() BEFORE this.
     89	blargg_err_t load_state( gb_apu_state_t const& in );
     90
     91public:
     92	Gb_Apu();
     93
     94	// Use set_output() in place of these
     95	BLARGG_DEPRECATED void output    (        Blip_Buffer* c                                 ) { set_output( c, c, c    ); }
     96	BLARGG_DEPRECATED void output    (        Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r ) { set_output( c, l, r    ); }
     97	BLARGG_DEPRECATED void osc_output( int i, Blip_Buffer* c                                 ) { set_output( c, c, c, i ); }
     98	BLARGG_DEPRECATED void osc_output( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r ) { set_output( c, l, r, i ); }
     99
    100private:
    101	// noncopyable
    102	Gb_Apu( const Gb_Apu& );
    103	Gb_Apu& operator = ( const Gb_Apu& );
    104
    105	Gb_Osc*     oscs [osc_count];
    106	blip_time_t last_time;          // time sound emulator has been run to
    107	blip_time_t frame_period;       // clocks between each frame sequencer step
    108	double      volume_;
    109	bool        reduce_clicks_;
    110
    111	Gb_Sweep_Square square1;
    112	Gb_Square       square2;
    113	Gb_Wave         wave;
    114	Gb_Noise        noise;
    115	blip_time_t     frame_time;     // time of next frame sequencer action
    116	int             frame_phase;    // phase of next frame sequencer step
    117	enum { regs_size = register_count + 0x10 };
    118	BOOST::uint8_t  regs [regs_size];// last values written to registers
    119
    120	// large objects after everything else
    121	Gb_Osc::Good_Synth  good_synth;
    122	Gb_Osc::Med_Synth   med_synth;
    123
    124	void reset_lengths();
    125	void reset_regs();
    126	int calc_output( int osc ) const;
    127	void apply_stereo();
    128	void apply_volume();
    129	void synth_volume( int );
    130	void run_until_( blip_time_t );
    131	void run_until( blip_time_t );
    132	void silence_osc( Gb_Osc& );
    133	void write_osc( int index, int reg, int old_data, int data );
    134	const char* save_load( gb_apu_state_t*, bool save );
    135	void save_load2( gb_apu_state_t*, bool save );
    136	friend class Gb_Apu_Tester;
    137};
    138
    139// Format of save state. Should be stable across versions of the library,
    140// with earlier versions properly opening later save states. Includes some
    141// room for expansion so the state size shouldn't increase.
    142struct gb_apu_state_t
    143{
    144#if GB_APU_CUSTOM_STATE
    145	// Values stored as plain int so your code can read/write them easily.
    146	// Structure can NOT be written to disk, since format is not portable.
    147	typedef int val_t;
    148#else
    149	// Values written in portable little-endian format, allowing structure
    150	// to be written directly to disk.
    151	typedef unsigned char val_t [4];
    152#endif
    153
    154	enum { format0 = 0x50414247 };
    155
    156	val_t format;   // format of all following data
    157	val_t version;  // later versions just add fields to end
    158
    159	unsigned char regs [0x40];
    160	val_t frame_time;
    161	val_t frame_phase;
    162
    163	val_t sweep_freq;
    164	val_t sweep_delay;
    165	val_t sweep_enabled;
    166	val_t sweep_neg;
    167	val_t noise_divider;
    168	val_t wave_buf;
    169
    170	val_t delay      [4];
    171	val_t length_ctr [4];
    172	val_t phase      [4];
    173	val_t enabled    [4];
    174
    175	val_t env_delay   [3];
    176	val_t env_volume  [3];
    177	val_t env_enabled [3];
    178
    179	val_t unused  [13]; // for future expansion
    180};
    181
    182#endif