summaryrefslogtreecommitdiff
path: root/plugins/gme/game-music-emu-0.6pre/gme/Gb_Apu.h
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/gme/game-music-emu-0.6pre/gme/Gb_Apu.h')
-rw-r--r--plugins/gme/game-music-emu-0.6pre/gme/Gb_Apu.h193
1 files changed, 193 insertions, 0 deletions
diff --git a/plugins/gme/game-music-emu-0.6pre/gme/Gb_Apu.h b/plugins/gme/game-music-emu-0.6pre/gme/Gb_Apu.h
new file mode 100644
index 00000000..f7ffb037
--- /dev/null
+++ b/plugins/gme/game-music-emu-0.6pre/gme/Gb_Apu.h
@@ -0,0 +1,193 @@
+// Nintendo Game Boy sound hardware emulator with save state support
+
+// Gb_Snd_Emu 0.1.4
+#ifndef GB_APU_H
+#define GB_APU_H
+
+#include "Gb_Oscs.h"
+
+struct gb_apu_state_t;
+
+class Gb_Apu {
+public:
+// Basics
+
+ // Sets buffer(s) to generate sound into, or NULL to mute. If only center is not NULL,
+ // output is mono.
+ void set_output( Blip_Buffer* center, Blip_Buffer* left = NULL, Blip_Buffer* right = NULL );
+
+ // Emulates to time t, then writes data to addr
+ void write_register( blip_time_t t, int addr, int data );
+
+ // Emulates to time t, then subtracts t from the current time.
+ // OK if previous write call had time slightly after t.
+ void end_frame( blip_time_t t );
+
+// More features
+
+ // Clock rate sound hardware runs at
+ enum { clock_rate = 4194304 * GB_APU_OVERCLOCK };
+
+ // Registers are at io_addr to io_addr+io_size-1
+ enum { io_addr = 0xFF10 };
+ enum { io_size = 0x30 };
+
+ // Emulates to time t, then reads from addr
+ int read_register( blip_time_t t, int addr );
+
+ // Resets hardware to state after power, BEFORE boot ROM runs. Mode selects
+ // sound hardware. If agb_wave is true, enables AGB's extra wave features.
+ enum mode_t {
+ mode_dmg, // Game Boy monochrome
+ mode_cgb, // Game Boy Color
+ mode_agb // Game Boy Advance
+ };
+ void reset( mode_t mode = mode_cgb, bool agb_wave = false );
+
+ // Same as set_output(), but for a particular channel
+ // 0: Square 1, 1: Square 2, 2: Wave, 3: Noise
+ enum { osc_count = 4 }; // 0 <= chan < osc_count
+ void set_output( int chan, Blip_Buffer* center,
+ Blip_Buffer* left = NULL, Blip_Buffer* right = NULL );
+
+ // Sets overall volume, where 1.0 is normal
+ void volume( double );
+
+ // Sets treble equalization
+ void treble_eq( blip_eq_t const& );
+
+ // Treble and bass values for various hardware.
+ enum {
+ speaker_treble = -47, // speaker on system
+ speaker_bass = 2000,
+ dmg_treble = 0, // headphones on each system
+ dmg_bass = 30,
+ cgb_treble = 0,
+ cgb_bass = 300, // CGB has much less bass
+ agb_treble = 0,
+ agb_bass = 30
+ };
+
+ // If true, reduces clicking by disabling DAC biasing. Note that this reduces
+ // emulation accuracy, since the clicks are authentic.
+ void reduce_clicks( bool reduce = true );
+
+ // Sets frame sequencer rate, where 1.0 is normal. Meant for adjusting the
+ // tempo in a music player.
+ void set_tempo( double );
+
+ // Saves full emulation state to state_out. Data format is portable and
+ // includes some extra space to avoid expansion in case more state needs
+ // to be stored in the future.
+ void save_state( gb_apu_state_t* state_out );
+
+ // Loads state. You should call reset() BEFORE this.
+ blargg_err_t load_state( gb_apu_state_t const& in );
+
+private:
+ // noncopyable
+ Gb_Apu( const Gb_Apu& );
+ Gb_Apu& operator = ( const Gb_Apu& );
+
+// Implementation
+public:
+ Gb_Apu();
+
+ // Use set_output() in place of these
+ BLARGG_DEPRECATED( void output ( Blip_Buffer* c ); )
+ BLARGG_DEPRECATED( void output ( Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r ); )
+ BLARGG_DEPRECATED( void osc_output( int i, Blip_Buffer* c ) { set_output( i, c, c, c ); } )
+ BLARGG_DEPRECATED( void osc_output( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r ) { set_output( i, c, l, r ); } )
+
+ BLARGG_DEPRECATED_TEXT( enum { start_addr = 0xFF10 }; )
+ BLARGG_DEPRECATED_TEXT( enum { end_addr = 0xFF3F }; )
+ BLARGG_DEPRECATED_TEXT( enum { register_count = end_addr - start_addr + 1 }; )
+
+private:
+ Gb_Osc* oscs [osc_count];
+ blip_time_t last_time; // time sound emulator has been run to
+ blip_time_t frame_period; // clocks between each frame sequencer step
+ double volume_;
+ bool reduce_clicks_;
+
+ Gb_Sweep_Square square1;
+ Gb_Square square2;
+ Gb_Wave wave;
+ Gb_Noise noise;
+ blip_time_t frame_time; // time of next frame sequencer action
+ int frame_phase; // phase of next frame sequencer step
+ enum { regs_size = io_size + 0x10 };
+ BOOST::uint8_t regs [regs_size];// last values written to registers
+
+ // large objects after everything else
+ Blip_Synth_Norm norm_synth;
+ Blip_Synth_Fast fast_synth;
+
+ void reset_lengths();
+ void reset_regs();
+ int calc_output( int osc ) const;
+ void apply_stereo();
+ void apply_volume();
+ void synth_volume( int );
+ void run_until_( blip_time_t );
+ void run_until( blip_time_t );
+ void silence_osc( Gb_Osc& );
+ void write_osc( int reg, int old_data, int data );
+ const char* save_load( gb_apu_state_t*, bool save );
+ void save_load2( gb_apu_state_t*, bool save );
+ friend class Gb_Apu2;
+};
+
+// Format of save state. Should be stable across versions of the library,
+// with earlier versions properly opening later save states. Includes some
+// room for expansion so the state size shouldn't increase.
+struct gb_apu_state_t
+{
+#if GB_APU_CUSTOM_STATE
+ // Values stored as plain int so your code can read/write them easily.
+ // Structure can NOT be written to disk, since format is not portable.
+ typedef int val_t;
+#else
+ // Values written in portable little-endian format, allowing structure
+ // to be written directly to disk.
+ typedef unsigned char val_t [4];
+#endif
+
+ enum { format0 = 0x50414247 }; // 'GBAP'
+
+ val_t format; // format of all following data
+ val_t version; // later versions just add fields to end
+
+ unsigned char regs [0x40];
+ val_t frame_time;
+ val_t frame_phase;
+
+ val_t sweep_freq;
+ val_t sweep_delay;
+ val_t sweep_enabled;
+ val_t sweep_neg;
+ val_t noise_divider;
+ val_t wave_buf;
+
+ val_t delay [4];
+ val_t length_ctr [4];
+ val_t phase [4];
+ val_t enabled [4];
+
+ val_t env_delay [3];
+ val_t env_volume [3];
+ val_t env_enabled [3];
+
+ val_t unused [13]; // for future expansion
+};
+
+inline void Gb_Apu::set_output( Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r )
+{
+ for ( int i = osc_count; --i >= 0; )
+ set_output( i, c, l, r );
+}
+
+BLARGG_DEPRECATED_TEXT( inline void Gb_Apu::output( Blip_Buffer* c ) { set_output( c, c, c ); } )
+BLARGG_DEPRECATED_TEXT( inline void Gb_Apu::output( Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r ) { set_output( c, l, r ); } )
+
+#endif