summaryrefslogtreecommitdiff
path: root/plugins/gme/game-music-emu-0.6pre/gme/Sms_Apu.h
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/gme/game-music-emu-0.6pre/gme/Sms_Apu.h')
-rw-r--r--plugins/gme/game-music-emu-0.6pre/gme/Sms_Apu.h128
1 files changed, 128 insertions, 0 deletions
diff --git a/plugins/gme/game-music-emu-0.6pre/gme/Sms_Apu.h b/plugins/gme/game-music-emu-0.6pre/gme/Sms_Apu.h
new file mode 100644
index 00000000..1da4da30
--- /dev/null
+++ b/plugins/gme/game-music-emu-0.6pre/gme/Sms_Apu.h
@@ -0,0 +1,128 @@
+// Sega Master System SN76489 PSG sound chip emulator
+
+// Sms_Snd_Emu 0.1.2
+#ifndef SMS_APU_H
+#define SMS_APU_H
+
+#include "blargg_common.h"
+#include "Blip_Buffer.h"
+
+struct sms_apu_state_t;
+
+class Sms_Apu {
+public:
+// Basics
+
+ // Sets buffer(s) to generate sound into, or 0 to mute. If only center is not 0,
+ // 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 Game Gear left/right assignment byte
+ void write_ggstereo( blip_time_t t, int data );
+
+ // Emulates to time t, then writes data
+ void write_data( blip_time_t t, 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
+
+ // Resets sound chip and sets noise feedback bits and width
+ void reset( unsigned noise_feedback = 0, int noise_width = 0 );
+
+ // Same as set_output(), but for a particular channel
+ // 0: Square 1, 1: Square 2, 2: Square 3, 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& );
+
+ // 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( sms_apu_state_t* state_out );
+
+ // Loads state. You should call reset() BEFORE this.
+ blargg_err_t load_state( sms_apu_state_t const& in );
+
+private:
+ // noncopyable
+ Sms_Apu( const Sms_Apu& );
+ Sms_Apu& operator = ( const Sms_Apu& );
+
+// Implementation
+public:
+ Sms_Apu();
+ ~Sms_Apu() { }
+ BLARGG_DISABLE_NOTHROW
+
+ // Use set_output() instead
+ BLARGG_DEPRECATED( void output ( Blip_Buffer* c ) { set_output( c, c, c ); } )
+ BLARGG_DEPRECATED( void output ( Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r ) { set_output( c, l, 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 ); } )
+
+private:
+ struct Osc
+ {
+ Blip_Buffer* outputs [4]; // NULL, right, left, center
+ Blip_Buffer* output;
+ int last_amp;
+
+ int volume;
+ int period;
+ int delay;
+ unsigned phase;
+ };
+
+ Osc oscs [osc_count];
+ int ggstereo;
+ int latch;
+
+ blip_time_t last_time;
+ int min_tone_period;
+ unsigned noise_feedback;
+ unsigned looped_feedback;
+ Blip_Synth_Fast fast_synth;
+ Blip_Synth_Norm norm_synth;
+
+ int calc_output( int i ) const;
+ void run_until( blip_time_t );
+ const char* save_load( sms_apu_state_t*, bool save );
+ friend class Sms_Apu_Tester;
+};
+
+struct sms_apu_state_t
+{
+ // If SMS_APU_CUSTOM_STATE is 1, values are stored as normal integers,
+ // so your code can then save and load them however it likes. Otherwise,
+ // they are 4-byte arrays in little-endian format, making entire
+ // structure suitable for direct storage on disk.
+
+#if SMS_APU_CUSTOM_STATE
+ typedef int val_t;
+#else
+ typedef unsigned char val_t [4];
+#endif
+
+ enum { format0 = 0x50414D53 };
+
+ val_t format;
+ val_t version;
+ val_t latch;
+ val_t ggstereo;
+ val_t periods [4];
+ val_t volumes [4];
+ val_t delays [4];
+ val_t phases [4];
+
+ val_t unused [12]; // for future expansion
+};
+
+#endif