Mercurial > audlegacy-plugins
diff src/console/Classic_Emu.h @ 316:fb513e10174e trunk
[svn] - merge libconsole-blargg into mainline libconsole:
+ obsoletes plugins-ugly:sapplug
| author | nenolod |
|---|---|
| date | Thu, 30 Nov 2006 19:54:33 -0800 |
| parents | 3da1b8942b8b |
| children | 986f098da058 |
line wrap: on
line diff
--- a/src/console/Classic_Emu.h Wed Nov 29 14:42:11 2006 -0800 +++ b/src/console/Classic_Emu.h Thu Nov 30 19:54:33 2006 -0800 @@ -1,41 +1,42 @@ +// Common aspects of emulators which use Blip_Buffer for sound output -// Classic game music emulator interface base class for emulators which use Blip_Buffer -// for sound output. - -// Game_Music_Emu 0.3.0 - +// Game_Music_Emu 0.5.1 #ifndef CLASSIC_EMU_H #define CLASSIC_EMU_H +#include "blargg_common.h" +#include "Blip_Buffer.h" #include "Music_Emu.h" -class Blip_Buffer; -class blip_eq_t; -typedef long blip_time_t; class Classic_Emu : public Music_Emu { public: Classic_Emu(); ~Classic_Emu(); - blargg_err_t set_sample_rate( long sample_rate ); void set_buffer( Multi_Buffer* ); - void mute_voices( int ); - void play( long, sample_t* ); - void start_track( int track ); - void set_equalizer( equalizer_t const& ); -public: - // deprecated - blargg_err_t init( long rate ) { return set_sample_rate( rate ); } protected: - virtual blargg_err_t setup_buffer( long clock_rate ); + // Services + enum { wave_type = 0x100, noise_type = 0x200, mixed_type = wave_type | noise_type }; + void set_voice_types( int const* t ) { voice_types = t; } + blargg_err_t setup_buffer( long clock_rate ); + long clock_rate() const { return clock_rate_; } + + // Overridable virtual void set_voice( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right ) = 0; - virtual blip_time_t run( int msec, bool* added_stereo ); - virtual blip_time_t run_clocks( blip_time_t, bool* added_stereo ); virtual void update_eq( blip_eq_t const& ) = 0; + virtual blargg_err_t start_track_( int track ) = 0; + virtual blargg_err_t run_clocks( blip_time_t& time_io, int msec ) = 0; +protected: + blargg_err_t set_sample_rate_( long sample_rate ); + void mute_voices_( int ); + void set_equalizer_( equalizer_t const& ); + blargg_err_t play_( long, sample_t* ); private: Multi_Buffer* buf; - Multi_Buffer* stereo_buffer; - long clock_rate; + Multi_Buffer* stereo_buffer; // NULL if using custom buffer + long clock_rate_; + unsigned buf_changed_count; + int const* voice_types; }; inline void Classic_Emu::set_buffer( Multi_Buffer* new_buf ) @@ -44,5 +45,72 @@ buf = new_buf; } +// ROM data handler, used by several Classic_Emu derivitives. Loads file data +// with padding on both sides, allowing direct use in bank mapping. The main purpose +// is to allow all file data to be loaded with only one read() call (for efficiency). + +class Rom_Data_ { +public: + typedef unsigned char byte; +protected: + enum { pad_extra = 8 }; + blargg_vector<byte> rom; + long file_size_; + blargg_long rom_addr; + blargg_long mask; + blargg_long size_; // TODO: eliminate + + blargg_err_t load_rom_data_( Data_Reader& in, int header_size, void* header_out, + int fill, long pad_size ); + void set_addr_( long addr, int unit ); +}; + +template<int unit> +class Rom_Data : public Rom_Data_ { + enum { pad_size = unit + pad_extra }; +public: + // Load file data, using already-loaded header 'h' if not NULL. Copy header + // from loaded file data into *out and fill unmapped bytes with 'fill'. + blargg_err_t load( Data_Reader& in, int header_size, void* header_out, int fill ) + { + return load_rom_data_( in, header_size, header_out, fill, pad_size ); + } + + // Size of file data read in (excluding header) + long file_size() const { return file_size_; } + + // Pointer to beginning of file data + byte* begin() const { return rom.begin() + pad_size; } + + // Set address that file data should start at + void set_addr( long addr ) { set_addr_( addr, unit ); } + + // Free data + void clear() { rom.clear(); } + + // Size of data + start addr, rounded to a multiple of unit + long size() const { return size_; } + + // Pointer to unmapped page filled with same value + byte* unmapped() { return rom.begin(); } + + // Mask address to nearest power of two greater than size() + blargg_long mask_addr( blargg_long addr ) const + { + #ifdef check + check( addr <= mask ); + #endif + return addr & mask; + } + + // Pointer to page starting at addr. Returns unmapped() if outside data. + byte* at_addr( blargg_long addr ) + { + blargg_ulong offset = mask_addr( addr ) - rom_addr; + if ( offset > blargg_ulong (rom.size() - pad_size) ) + offset = 0; // unmapped + return &rom [offset]; + } +}; + #endif -
