From cd6d70bce5e25d2982c1e750f6aca27a6d5ea03e Mon Sep 17 00:00:00 2001 From: Asnivor Date: Sat, 26 Jan 2019 20:27:07 +0000 Subject: [PATCH] Linux WonderSwan - now working --- Assets/libbizswan.dll.so | Bin 0 -> 174744 bytes wonderswan/blip/Blip_Buffer.h | 852 ++++++++++++++-------------------- wonderswan/mingw/Makefile | 4 +- wonderswan/system.cpp | 482 +++++++++---------- 4 files changed, 599 insertions(+), 739 deletions(-) create mode 100755 Assets/libbizswan.dll.so diff --git a/Assets/libbizswan.dll.so b/Assets/libbizswan.dll.so new file mode 100755 index 0000000000000000000000000000000000000000..af775c6f0658cab1190fded233410798989d31d4 GIT binary patch literal 174744 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%0DSQpFp)Nv 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 literal 0 HcmV?d00001 diff --git a/wonderswan/blip/Blip_Buffer.h b/wonderswan/blip/Blip_Buffer.h index a8e90ee053..49a156a3f6 100644 --- a/wonderswan/blip/Blip_Buffer.h +++ b/wonderswan/blip/Blip_Buffer.h @@ -1,498 +1,354 @@ -// Band-limited sound synthesis buffer -// Various changes and hacks for use in Mednafen. - -#ifdef __GNUC__ - #define blip_inline inline __attribute__((always_inline)) -#else - #define blip_inline inline -#endif - -#include -#include - -// Blip_Buffer 0.4.1 -#ifndef BLIP_BUFFER_H -#define BLIP_BUFFER_H - -// Internal -typedef int32_t blip_long; -typedef uint32_t blip_ulong; -typedef int64_t blip_s64; -typedef uint64_t blip_u64; - -// Time unit at source clock rate -typedef blip_long blip_time_t; - -// Output samples are 16-bit signed, with a range of -32768 to 32767 -typedef short blip_sample_t; -enum { blip_sample_max = 32767 }; - -class Blip_Buffer { -public: - typedef const char* blargg_err_t; - - // Set output sample rate and buffer length in milliseconds (1/1000 sec, defaults - // to 1/4 second), then clear buffer. Returns NULL on success, otherwise if there - // isn't enough memory, returns error without affecting current buffer setup. - blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 ); - - // Set number of source time units per second - void clock_rate( long ); - - // End current time frame of specified duration and make its samples available - // (along with any still-unread samples) for reading with read_samples(). Begins - // a new time frame at the end of the current frame. - void end_frame( blip_time_t time ); - - // Read at most 'max_samples' out of buffer into 'dest', removing them from from - // the buffer. Returns number of samples actually read and removed. If stereo is - // true, increments 'dest' one extra time after writing each sample, to allow - // easy interleving of two channels into a stereo output buffer. - long read_samples( blip_sample_t* dest, long max_samples, int stereo = 0 ); - -// Additional optional features - - // Current output sample rate - long sample_rate() const; - - // Length of buffer, in milliseconds - int length() const; - - // Number of source time units per second - long clock_rate() const; - - // Set frequency high-pass filter frequency, where higher values reduce bass more - void bass_freq( int frequency ); - - // Number of samples delay from synthesis to samples read out - int output_latency() const; - - // Remove all available samples and clear buffer to silence. If 'entire_buffer' is - // false, just clears out any samples waiting rather than the entire buffer. - void clear( int entire_buffer = 1 ); - - // Number of samples available for reading with read_samples() - long samples_avail() const; - - // Remove 'count' samples from those waiting to be read - void remove_samples( long count ); - -// Experimental features - - // Count number of clocks needed until 'count' samples will be available. - // If buffer can't even hold 'count' samples, returns number of clocks until - // buffer becomes full. - blip_time_t count_clocks( long count ) const; - - // Number of raw samples that can be mixed within frame of specified duration. - long count_samples( blip_time_t duration ) const; - - // Mix 'count' samples from 'buf' into buffer. - void mix_samples( blip_sample_t const* buf, long count ); - - // not documented yet - void set_modified() { modified_ = 1; } - int clear_modified() { int b = modified_; modified_ = 0; return b; } - typedef blip_u64 blip_resampled_time_t; - void remove_silence( long count ); - blip_resampled_time_t resampled_duration( int t ) const { return t * factor_; } - blip_resampled_time_t resampled_time( blip_time_t t ) const { return t * factor_ + offset_; } - blip_resampled_time_t clock_rate_factor( long clock_rate ) const; -public: - Blip_Buffer(); - ~Blip_Buffer(); - - // Deprecated - typedef blip_resampled_time_t resampled_time_t; - blargg_err_t sample_rate( long r ) { return set_sample_rate( r ); } - blargg_err_t sample_rate( long r, int msec ) { return set_sample_rate( r, msec ); } -private: - // noncopyable - Blip_Buffer( const Blip_Buffer& ); - Blip_Buffer& operator = ( const Blip_Buffer& ); -public: - typedef blip_time_t buf_t_; - blip_u64 factor_; - blip_resampled_time_t offset_; - buf_t_* buffer_; - blip_long buffer_size_; - blip_long reader_accum_; - int bass_shift_; -private: - long sample_rate_; - long clock_rate_; - int bass_freq_; - int length_; - int modified_; - friend class Blip_Reader; -}; - -#ifdef HAVE_CONFIG_H - #include "config.h" -#endif - -#define BLIP_BUFFER_ACCURACY 32 -#define BLIP_PHASE_BITS 8 - -// Number of bits in resample ratio fraction. Higher values give a more accurate ratio -// but reduce maximum buffer size. -//#ifndef BLIP_BUFFER_ACCURACY -// #define BLIP_BUFFER_ACCURACY 16 -//#endif - -// Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in -// noticeable broadband noise when synthesizing high frequency square waves. -// Affects size of Blip_Synth objects since they store the waveform directly. -//#ifndef BLIP_PHASE_BITS -// #if BLIP_BUFFER_FAST -// #define BLIP_PHASE_BITS 8 -// #else -// #define BLIP_PHASE_BITS 6 -// #endif -//#endif - - // Internal - typedef blip_u64 blip_resampled_time_t; - int const blip_widest_impulse_ = 16; - int const blip_buffer_extra_ = blip_widest_impulse_ + 2; - int const blip_res = 1 << BLIP_PHASE_BITS; - class blip_eq_t; - - class Blip_Synth_Fast_ { - public: - Blip_Buffer* buf; - int last_amp; - int delta_factor; - - void volume_unit( double ); - Blip_Synth_Fast_(); - void treble_eq( blip_eq_t const& ) { } - }; - - class Blip_Synth_ { - public: - Blip_Buffer* buf; - int last_amp; - int delta_factor; - - void volume_unit( double ); - Blip_Synth_( short* impulses, int width ); - void treble_eq( blip_eq_t const& ); - private: - double volume_unit_; - short* const impulses; - int const width; - blip_long kernel_unit; - int impulses_size() const { return blip_res / 2 * width + 1; } - void adjust_impulse(); - }; - -// Quality level. Start with blip_good_quality. -const int blip_med_quality = 8; -const int blip_good_quality = 12; -const int blip_high_quality = 16; - -// Range specifies the greatest expected change in amplitude. Calculate it -// by finding the difference between the maximum and minimum expected -// amplitudes (max - min). -template -class Blip_Synth { -public: - // Set overall volume of waveform - void volume( double v ) { impl.volume_unit( v * (1.0 / (range < 0 ? -range : range)) ); } - - // Configure low-pass filter (see blip_buffer.txt) - void treble_eq( blip_eq_t const& eq ) { impl.treble_eq( eq ); } - - // Get/set Blip_Buffer used for output - Blip_Buffer* output() const { return impl.buf; } - void output( Blip_Buffer* b ) { impl.buf = b; impl.last_amp = 0; } - - // Update amplitude of waveform at given time. Using this requires a separate - // Blip_Synth for each waveform. - void update( blip_time_t time, int amplitude ); - -// Low-level interface - - // Add an amplitude transition of specified delta, optionally into specified buffer - // rather than the one set with output(). Delta can be positive or negative. - // The actual change in amplitude is delta * (volume / range) - void offset( blip_time_t, int delta, Blip_Buffer* ) const; - void offset( blip_time_t t, int delta ) const { offset( t, delta, impl.buf ); } - - // Works directly in terms of fractional output samples. Contact author for more info. - void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const; - - // Same as offset(), except code is inlined for higher performance - void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const { - offset_resampled( t * buf->factor_ + buf->offset_, delta, buf ); - } - void offset_inline( blip_time_t t, int delta ) const { - offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf ); - } - -private: -#if BLIP_BUFFER_FAST - Blip_Synth_Fast_ impl; -#else - Blip_Synth_ impl; - typedef short imp_t; - imp_t impulses [blip_res * (quality / 2) + 1]; -public: - Blip_Synth() : impl( impulses, quality ) { } -#endif -}; - -// Low-pass equalization parameters -class blip_eq_t { -public: - // Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce - // treble, small positive values (0 to 5.0) increase treble. - blip_eq_t( double treble_db = 0 ); - - // See blip_buffer.txt - blip_eq_t( double treble, long rolloff_freq, long sample_rate, long cutoff_freq = 0 ); - -private: - double treble; - long rolloff_freq; - long sample_rate; - long cutoff_freq; - void generate( float* out, int count ) const; - friend class Blip_Synth_; -}; - -int const blip_sample_bits = 30; - -// Dummy Blip_Buffer to direct sound output to, for easy muting without -// having to stop sound code. -class Silent_Blip_Buffer : public Blip_Buffer { - buf_t_ buf [blip_buffer_extra_ + 1]; -public: - // The following cannot be used (an assertion will fail if attempted): - blargg_err_t set_sample_rate( long samples_per_sec, int msec_length ); - blip_time_t count_clocks( long count ) const; - void mix_samples( blip_sample_t const* buf, long count ); - - Silent_Blip_Buffer(); -}; - - #if defined (__GNUC__) || _MSC_VER >= 1100 - #define BLIP_RESTRICT __restrict - #else - #define BLIP_RESTRICT - #endif - -// Optimized reading from Blip_Buffer, for use in custom sample output - -// Begin reading from buffer. Name should be unique to the current block. -#define BLIP_READER_BEGIN( name, blip_buffer ) \ - const Blip_Buffer::buf_t_* BLIP_RESTRICT name##_reader_buf = (blip_buffer).buffer_;\ - blip_long name##_reader_accum = (blip_buffer).reader_accum_ - -// Get value to pass to BLIP_READER_NEXT() -#define BLIP_READER_BASS( blip_buffer ) ((blip_buffer).bass_shift_) - -// Constant value to use instead of BLIP_READER_BASS(), for slightly more optimal -// code at the cost of having no bass control -int const blip_reader_default_bass = 9; - -// Current sample -#define BLIP_READER_READ( name ) (name##_reader_accum >> (blip_sample_bits - 16)) - -// Current raw sample in full internal resolution -#define BLIP_READER_READ_RAW( name ) (name##_reader_accum) - -// Advance to next sample -#define BLIP_READER_NEXT( name, bass ) \ - (void) (name##_reader_accum += *name##_reader_buf++ - (name##_reader_accum >> (bass))) - -// End reading samples from buffer. The number of samples read must now be removed -// using Blip_Buffer::remove_samples(). -#define BLIP_READER_END( name, blip_buffer ) \ - (void) ((blip_buffer).reader_accum_ = name##_reader_accum) - - -// Compatibility with older version -const long blip_unscaled = 65535; -const int blip_low_quality = blip_med_quality; -const int blip_best_quality = blip_high_quality; - -// Deprecated; use BLIP_READER macros as follows: -// Blip_Reader r; r.begin( buf ); -> BLIP_READER_BEGIN( r, buf ); -// int bass = r.begin( buf ) -> BLIP_READER_BEGIN( r, buf ); int bass = BLIP_READER_BASS( buf ); -// r.read() -> BLIP_READER_READ( r ) -// r.read_raw() -> BLIP_READER_READ_RAW( r ) -// r.next( bass ) -> BLIP_READER_NEXT( r, bass ) -// r.next() -> BLIP_READER_NEXT( r, blip_reader_default_bass ) -// r.end( buf ) -> BLIP_READER_END( r, buf ) -class Blip_Reader { -public: - int begin( Blip_Buffer& ); - blip_long read() const { return accum >> (blip_sample_bits - 16); } - blip_long read_raw() const { return accum; } - void next( int bass_shift = 9 ) { accum += *buf++ - (accum >> bass_shift); } - void end( Blip_Buffer& b ) { b.reader_accum_ = accum; } - -private: - const Blip_Buffer::buf_t_* buf; - blip_long accum; -}; - -// End of public interface - -#include - -template -blip_inline void Blip_Synth::offset_resampled( blip_resampled_time_t time, - int delta, Blip_Buffer* blip_buf ) const -{ - // Fails if time is beyond end of Blip_Buffer, due to a bug in caller code or the - // need for a longer buffer as set by set_sample_rate(). - assert( (blip_long) (time >> BLIP_BUFFER_ACCURACY) < blip_buf->buffer_size_ ); - delta *= impl.delta_factor; - blip_long* BLIP_RESTRICT buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY); - int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1)); - -#if BLIP_BUFFER_FAST - blip_long left = buf [0] + delta; - - // Kind of crappy, but doing shift after multiply results in overflow. - // Alternate way of delaying multiply by delta_factor results in worse - // sub-sample resolution. - blip_long right = (delta >> BLIP_PHASE_BITS) * phase; - left -= right; - right += buf [1]; - - buf [0] = left; - buf [1] = right; -#else - - int const fwd = (blip_widest_impulse_ - quality) / 2; - int const rev = fwd + quality - 2; - int const mid = quality / 2 - 1; - - imp_t const* BLIP_RESTRICT imp = impulses + blip_res - phase; - - #if defined (_M_IX86) || defined (_M_IA64) || defined (__i486__) || \ - defined (__x86_64__) || defined (__ia64__) || defined (__i386__) - - // straight forward implementation resulted in better code on GCC for x86 - - #define ADD_IMP( out, in ) \ - buf [out] += (blip_long) imp [blip_res * (in)] * delta - - #define BLIP_FWD( i ) {\ - ADD_IMP( fwd + i, i );\ - ADD_IMP( fwd + 1 + i, i + 1 );\ - } - #define BLIP_REV( r ) {\ - ADD_IMP( rev - r, r + 1 );\ - ADD_IMP( rev + 1 - r, r );\ - } - - BLIP_FWD( 0 ) - if ( quality > 8 ) BLIP_FWD( 2 ) - if ( quality > 12 ) BLIP_FWD( 4 ) - { - ADD_IMP( fwd + mid - 1, mid - 1 ); - ADD_IMP( fwd + mid , mid ); - imp = impulses + phase; - } - if ( quality > 12 ) BLIP_REV( 6 ) - if ( quality > 8 ) BLIP_REV( 4 ) - BLIP_REV( 2 ) - - ADD_IMP( rev , 1 ); - ADD_IMP( rev + 1, 0 ); - - #else - - // for RISC processors, help compiler by reading ahead of writes - - #define BLIP_FWD( i ) {\ - blip_long t0 = i0 * delta + buf [fwd + i];\ - blip_long t1 = imp [blip_res * (i + 1)] * delta + buf [fwd + 1 + i];\ - i0 = imp [blip_res * (i + 2)];\ - buf [fwd + i] = t0;\ - buf [fwd + 1 + i] = t1;\ - } - #define BLIP_REV( r ) {\ - blip_long t0 = i0 * delta + buf [rev - r];\ - blip_long t1 = imp [blip_res * r] * delta + buf [rev + 1 - r];\ - i0 = imp [blip_res * (r - 1)];\ - buf [rev - r] = t0;\ - buf [rev + 1 - r] = t1;\ - } - - blip_long i0 = *imp; - BLIP_FWD( 0 ) - if ( quality > 8 ) BLIP_FWD( 2 ) - if ( quality > 12 ) BLIP_FWD( 4 ) - { - blip_long t0 = i0 * delta + buf [fwd + mid - 1]; - blip_long t1 = imp [blip_res * mid] * delta + buf [fwd + mid ]; - imp = impulses + phase; - i0 = imp [blip_res * mid]; - buf [fwd + mid - 1] = t0; - buf [fwd + mid ] = t1; - } - if ( quality > 12 ) BLIP_REV( 6 ) - if ( quality > 8 ) BLIP_REV( 4 ) - BLIP_REV( 2 ) - - blip_long t0 = i0 * delta + buf [rev ]; - blip_long t1 = *imp * delta + buf [rev + 1]; - buf [rev ] = t0; - buf [rev + 1] = t1; - #endif - -#endif -} - -#undef BLIP_FWD -#undef BLIP_REV - -template -#if BLIP_BUFFER_FAST - blip_inline -#endif -void Blip_Synth::offset( blip_time_t t, int delta, Blip_Buffer* buf ) const -{ - offset_resampled( t * buf->factor_ + buf->offset_, delta, buf ); -} - -template -#if BLIP_BUFFER_FAST - blip_inline -#endif -void Blip_Synth::update( blip_time_t t, int amp ) -{ - int delta = amp - impl.last_amp; - impl.last_amp = amp; - offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf ); -} - -blip_inline blip_eq_t::blip_eq_t( double t ) : - treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), cutoff_freq( 0 ) { } -blip_inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) : - treble( t ), rolloff_freq( rf ), sample_rate( sr ), cutoff_freq( cf ) { } - -blip_inline int Blip_Buffer::length() const { return length_; } -blip_inline long Blip_Buffer::samples_avail() const { return (long) (offset_ >> BLIP_BUFFER_ACCURACY); } -blip_inline long Blip_Buffer::sample_rate() const { return sample_rate_; } -blip_inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; } -blip_inline long Blip_Buffer::clock_rate() const { return clock_rate_; } -blip_inline void Blip_Buffer::clock_rate( long cps ) { factor_ = clock_rate_factor( clock_rate_ = cps ); } - -blip_inline int Blip_Reader::begin( Blip_Buffer& blip_buf ) -{ - buf = blip_buf.buffer_; - accum = blip_buf.reader_accum_; - return blip_buf.bass_shift_; -} - -int const blip_max_length = 0; -int const blip_default_length = 250; - -#endif + +// Band-limited sound synthesis and buffering + +// Blip_Buffer 0.4.0 + +#ifndef BLIP_BUFFER_H +#define BLIP_BUFFER_H + +// Time unit at source clock rate +typedef long blip_time_t; + +// Output samples are 16-bit signed, with a range of -32768 to 32767 +typedef short blip_sample_t; +enum { blip_sample_max = 32767 }; + +class Blip_Buffer { +public: + typedef const char* blargg_err_t; + + // Set output sample rate and buffer length in milliseconds (1/1000 sec, defaults + // to 1/4 second), then clear buffer. Returns NULL on success, otherwise if there + // isn't enough memory, returns error without affecting current buffer setup. + blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 ); + + // Set number of source time units per second + void clock_rate( long ); + + // End current time frame of specified duration and make its samples available + // (along with any still-unread samples) for reading with read_samples(). Begins + // a new time frame at the end of the current frame. + void end_frame( blip_time_t time ); + + // Read at most 'max_samples' out of buffer into 'dest', removing them from from + // the buffer. Returns number of samples actually read and removed. If stereo is + // true, increments 'dest' one extra time after writing each sample, to allow + // easy interleving of two channels into a stereo output buffer. + long read_samples( blip_sample_t* dest, long max_samples, int stereo = 0 ); + +// Additional optional features + + // Current output sample rate + long sample_rate() const; + + // Length of buffer, in milliseconds + int length() const; + + // Number of source time units per second + long clock_rate() const; + + // Set frequency high-pass filter frequency, where higher values reduce bass more + void bass_freq( int frequency ); + + // Number of samples delay from synthesis to samples read out + int output_latency() const; + + // Remove all available samples and clear buffer to silence. If 'entire_buffer' is + // false, just clears out any samples waiting rather than the entire buffer. + void clear( int entire_buffer = 1 ); + + // Number of samples available for reading with read_samples() + long samples_avail() const; + + // Remove 'count' samples from those waiting to be read + void remove_samples( long count ); + +// Experimental features + + // Number of raw samples that can be mixed within frame of specified duration. + long count_samples( blip_time_t duration ) const; + + // Mix 'count' samples from 'buf' into buffer. + void mix_samples( blip_sample_t const* buf, long count ); + + // Count number of clocks needed until 'count' samples will be available. + // If buffer can't even hold 'count' samples, returns number of clocks until + // buffer becomes full. + blip_time_t count_clocks( long count ) const; + + // not documented yet + typedef unsigned long blip_resampled_time_t; + void remove_silence( long count ); + blip_resampled_time_t resampled_duration( int t ) const { return t * factor_; } + blip_resampled_time_t resampled_time( blip_time_t t ) const { return t * factor_ + offset_; } + blip_resampled_time_t clock_rate_factor( long clock_rate ) const; +public: + Blip_Buffer(); + ~Blip_Buffer(); + + // Deprecated + typedef blip_resampled_time_t resampled_time_t; + blargg_err_t sample_rate( long r ) { return set_sample_rate( r ); } + blargg_err_t sample_rate( long r, int msec ) { return set_sample_rate( r, msec ); } +private: + // noncopyable + Blip_Buffer( const Blip_Buffer& ); + Blip_Buffer& operator = ( const Blip_Buffer& ); +public: + typedef long buf_t_; + unsigned long factor_; + blip_resampled_time_t offset_; + buf_t_* buffer_; + long buffer_size_; +private: + long reader_accum; + int bass_shift; + long sample_rate_; + long clock_rate_; + int bass_freq_; + int length_; + friend class Blip_Reader; +}; + +#ifdef HAVE_CONFIG_H + #include "config.h" +#endif + +// Number of bits in resample ratio fraction. Higher values give a more accurate ratio +// but reduce maximum buffer size. +#ifndef BLIP_BUFFER_ACCURACY + #define BLIP_BUFFER_ACCURACY 16 +#endif + +// Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in +// noticeable broadband noise when synthesizing high frequency square waves. +// Affects size of Blip_Synth objects since they store the waveform directly. +#ifndef BLIP_PHASE_BITS + #define BLIP_PHASE_BITS 6 +#endif + + // Internal + typedef unsigned long blip_resampled_time_t; + int const blip_widest_impulse_ = 16; + int const blip_res = 1 << BLIP_PHASE_BITS; + class blip_eq_t; + + class Blip_Synth_ { + double volume_unit_; + short* const impulses; + int const width; + long kernel_unit; + int impulses_size() const { return blip_res / 2 * width + 1; } + void adjust_impulse(); + public: + Blip_Buffer* buf; + int last_amp; + int delta_factor; + + Blip_Synth_( short* impulses, int width ); + void treble_eq( blip_eq_t const& ); + void volume_unit( double ); + }; + +// Quality level. Start with blip_good_quality. +const int blip_med_quality = 8; +const int blip_good_quality = 12; +const int blip_high_quality = 16; + +// Range specifies the greatest expected change in amplitude. Calculate it +// by finding the difference between the maximum and minimum expected +// amplitudes (max - min). +template +class Blip_Synth { +public: + // Set overall volume of waveform + void volume( double v ) { impl.volume_unit( v * (1.0 / (range < 0 ? -range : range)) ); } + + // Configure low-pass filter (see notes.txt) + void treble_eq( blip_eq_t const& eq ) { impl.treble_eq( eq ); } + + // Get/set Blip_Buffer used for output + Blip_Buffer* output() const { return impl.buf; } + void output( Blip_Buffer* b ) { impl.buf = b; impl.last_amp = 0; } + + // Update amplitude of waveform at given time. Using this requires a separate + // Blip_Synth for each waveform. + void update( blip_time_t time, int amplitude ); + +// Low-level interface + + // Add an amplitude transition of specified delta, optionally into specified buffer + // rather than the one set with output(). Delta can be positive or negative. + // The actual change in amplitude is delta * (volume / range) + void offset( blip_time_t, int delta, Blip_Buffer* ) const; + void offset( blip_time_t t, int delta ) const { offset( t, delta, impl.buf ); } + + // Works directly in terms of fractional output samples. Contact author for more. + void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const; + + // Same as offset(), except code is inlined for higher performance + void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const { + offset_resampled( t * buf->factor_ + buf->offset_, delta, buf ); + } + void offset_inline( blip_time_t t, int delta ) const { + offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf ); + } + +public: + Blip_Synth() : impl( impulses, quality ) { } +private: + typedef short imp_t; + imp_t impulses [blip_res * (quality / 2) + 1]; + Blip_Synth_ impl; +}; + +// Low-pass equalization parameters +class blip_eq_t { +public: + // Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce + // treble, small positive values (0 to 5.0) increase treble. + blip_eq_t( double treble_db = 0 ); + + // See notes.txt + blip_eq_t( double treble, long rolloff_freq, long sample_rate, long cutoff_freq = 0 ); + +private: + double treble; + long rolloff_freq; + long sample_rate; + long cutoff_freq; + void generate( float* out, int count ) const; + friend class Blip_Synth_; +}; + +int const blip_sample_bits = 30; + +// Optimized inline sample reader for custom sample formats and mixing of Blip_Buffer samples +class Blip_Reader { +public: + // Begin reading samples from buffer. Returns value to pass to next() (can + // be ignored if default bass_freq is acceptable). + int begin( Blip_Buffer& ); + + // Current sample + long read() const { return accum >> (blip_sample_bits - 16); } + + // Current raw sample in full internal resolution + long read_raw() const { return accum; } + + // Advance to next sample + void next( int bass_shift = 9 ) { accum += *buf++ - (accum >> bass_shift); } + + // End reading samples from buffer. The number of samples read must now be removed + // using Blip_Buffer::remove_samples(). + void end( Blip_Buffer& b ) { b.reader_accum = accum; } + +private: + const Blip_Buffer::buf_t_* buf; + long accum; +}; + + +// End of public interface + + +#include + +// Compatibility with older version +const long blip_unscaled = 65535; +const int blip_low_quality = blip_med_quality; +const int blip_best_quality = blip_high_quality; + +#define BLIP_FWD( i ) { \ + long t0 = i0 * delta + buf [fwd + i]; \ + long t1 = imp [blip_res * (i + 1)] * delta + buf [fwd + 1 + i]; \ + i0 = imp [blip_res * (i + 2)]; \ + buf [fwd + i] = t0; \ + buf [fwd + 1 + i] = t1; } + +#define BLIP_REV( r ) { \ + long t0 = i0 * delta + buf [rev - r]; \ + long t1 = imp [blip_res * r] * delta + buf [rev + 1 - r]; \ + i0 = imp [blip_res * (r - 1)]; \ + buf [rev - r] = t0; \ + buf [rev + 1 - r] = t1; } + +template +inline void Blip_Synth::offset_resampled( blip_resampled_time_t time, + int delta, Blip_Buffer* blip_buf ) const +{ + // Fails if time is beyond end of Blip_Buffer, due to a bug in caller code or the + // need for a longer buffer as set by set_sample_rate(). + assert( (long) (time >> BLIP_BUFFER_ACCURACY) < blip_buf->buffer_size_ ); + delta *= impl.delta_factor; + int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1)); + imp_t const* imp = impulses + blip_res - phase; + long* buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY); + long i0 = *imp; + + int const fwd = (blip_widest_impulse_ - quality) / 2; + int const rev = fwd + quality - 2; + + BLIP_FWD( 0 ) + if ( quality > 8 ) BLIP_FWD( 2 ) + if ( quality > 12 ) BLIP_FWD( 4 ) + { + int const mid = quality / 2 - 1; + long t0 = i0 * delta + buf [fwd + mid - 1]; + long t1 = imp [blip_res * mid] * delta + buf [fwd + mid]; + imp = impulses + phase; + i0 = imp [blip_res * mid]; + buf [fwd + mid - 1] = t0; + buf [fwd + mid] = t1; + } + if ( quality > 12 ) BLIP_REV( 6 ) + if ( quality > 8 ) BLIP_REV( 4 ) + BLIP_REV( 2 ) + + long t0 = i0 * delta + buf [rev]; + long t1 = *imp * delta + buf [rev + 1]; + buf [rev] = t0; + buf [rev + 1] = t1; +} + +#undef BLIP_FWD +#undef BLIP_REV + +template +void Blip_Synth::offset( blip_time_t t, int delta, Blip_Buffer* buf ) const +{ + offset_resampled( t * buf->factor_ + buf->offset_, delta, buf ); +} + +template +void Blip_Synth::update( blip_time_t t, int amp ) +{ + int delta = amp - impl.last_amp; + impl.last_amp = amp; + offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf ); +} + +inline blip_eq_t::blip_eq_t( double t ) : + treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), cutoff_freq( 0 ) { } +inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) : + treble( t ), rolloff_freq( rf ), sample_rate( sr ), cutoff_freq( cf ) { } + +inline int Blip_Buffer::length() const { return length_; } +inline long Blip_Buffer::samples_avail() const { return (long) (offset_ >> BLIP_BUFFER_ACCURACY); } +inline long Blip_Buffer::sample_rate() const { return sample_rate_; } +inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; } +inline long Blip_Buffer::clock_rate() const { return clock_rate_; } +inline void Blip_Buffer::clock_rate( long cps ) { factor_ = clock_rate_factor( clock_rate_ = cps ); } + +inline int Blip_Reader::begin( Blip_Buffer& blip_buf ) +{ + buf = blip_buf.buffer_; + accum = blip_buf.reader_accum; + return blip_buf.bass_shift; +} + +int const blip_max_length = 0; +int const blip_default_length = 250; + +#endif + diff --git a/wonderswan/mingw/Makefile b/wonderswan/mingw/Makefile index da7f3d57cf..c31b85f9ea 100644 --- a/wonderswan/mingw/Makefile +++ b/wonderswan/mingw/Makefile @@ -11,7 +11,7 @@ else $(error Unknown arch) endif -CXXFLAGS = -Wall -DLSB_FIRST -I.. -Wno-multichar -O3 -Wzero-as-null-pointer-constant -std=gnu++11 -fomit-frame-pointer -fno-exceptions -flto +CXXFLAGS = -Wall -DLSB_FIRST -I.. -Wno-multichar -O3 -Wzero-as-null-pointer-constant -std=gnu++11 -fomit-frame-pointer -fno-exceptions -flto -fPIC TARGET = bizswan.dll LDFLAGS_32 = -static -static-libgcc -static-libstdc++ @@ -32,7 +32,7 @@ SRCS = \ ../system.cpp \ ../tcache.cpp \ ../v30mz.cpp \ - ../Blip/Blip_Buffer.cpp + ../blip/Blip_Buffer.cpp OBJS = $(SRCS:.cpp=.o) diff --git a/wonderswan/system.cpp b/wonderswan/system.cpp index 28928d0a29..9d7c05eb28 100644 --- a/wonderswan/system.cpp +++ b/wonderswan/system.cpp @@ -17,35 +17,39 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "system.h" -#include -#include -#include -#include - -#define EXPORT extern "C" __declspec(dllexport) - + +#include "system.h" +#include +#include +#include +#include + +#ifdef _WIN32 +#define EXPORT extern "C" __declspec(dllexport) +#elif __linux__ +#define EXPORT extern "C" +#endif + namespace MDFN_IEN_WSWAN { - - // maybe change? - int Debug::puts ( const char * str ) - { - return std::puts(str); - } - int Debug::printf ( const char * format, ... ) - { - va_list args; - va_start(args, format); - int ret = vprintf(format, args); - va_end(args); - return ret; - } - -#include "start.inc" - - void System::Reset() + + // maybe change? + int Debug::puts ( const char * str ) + { + return std::puts(str); + } + int Debug::printf ( const char * format, ... ) + { + va_list args; + va_start(args, format); + int ret = vprintf(format, args); + va_end(args); + return ret; + } + +#include "start.inc" + + void System::Reset() { cpu.reset(); memory.Reset(); @@ -62,8 +66,8 @@ namespace MDFN_IEN_WSWAN } cpu.set_reg(NEC_SS,0); - cpu.set_reg(NEC_SP,0x2000); - } + cpu.set_reg(NEC_SP,0x2000); + } bool System::Advance(uint32 buttons, bool novideo, uint32 *surface, int16 *soundbuff, int &soundbuffsize) { @@ -86,7 +90,7 @@ namespace MDFN_IEN_WSWAN cpu.timestamp = 0; return memory.Lagged; } - + // Source: http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 // Rounds up to the nearest power of 2. static inline uint32 round_up_pow2(uint32 v) @@ -103,7 +107,7 @@ namespace MDFN_IEN_WSWAN return(v); } - + bool System::Load(const uint8 *data, int length, const SyncSettings &settings) { uint32 real_rom_size; @@ -202,211 +206,211 @@ namespace MDFN_IEN_WSWAN Reset(); return true; - } - - // this is more than just being defensive; these classes do - // in some cases rely on zero filled constuct state - void *System::operator new(std::size_t size) - { - void *p = ::operator new(size); - std::memset(p, 0, size); - return p; - } - - System::System() - { - gfx.sys = this; - memory.sys = this; - eeprom.sys = this; - rtc.sys = this; - sound.sys = this; - cpu.sys = this; - interrupt.sys = this; - } - - System::~System() - { - } - - int System::SaveRamSize() const - { - return eeprom.ieeprom_size + eeprom.eeprom_size + memory.sram_size; - } - - bool System::SaveRamLoad(const uint8 *data, int size) - { - if (size != SaveRamSize()) - return false; - - #define LOAD(sz,ptr) { if (sz) { std::memcpy((ptr), data, (sz)); data += (sz); } } - - LOAD(eeprom.ieeprom_size, eeprom.iEEPROM); - LOAD(eeprom.eeprom_size, eeprom.wsEEPROM); - LOAD(memory.sram_size, memory.wsSRAM); - - #undef LOAD - - return true; - } - - bool System::SaveRamSave(uint8 *dest, int maxsize) const - { - if (maxsize != SaveRamSize()) - return false; - - #define SAVE(sz,ptr) { if (sz) { std::memcpy(dest, (ptr), (sz)); dest += (sz); } } - - SAVE(eeprom.ieeprom_size, eeprom.iEEPROM); - SAVE(eeprom.eeprom_size, eeprom.wsEEPROM); - SAVE(memory.sram_size, memory.wsSRAM); - - #undef SAVE - - return true; - } - - void System::PutSettings(const Settings &s) - { - gfx.SetLayerEnableMask(s.LayerMask); - gfx.SetBWPalette(s.BWPalette); - gfx.SetColorPalette(s.ColorPalette); - } - - uint32 System::GetNECReg(int which) const - { - return cpu.get_reg(which); - } - - bool System::GetMemoryArea(int index, const char *&name, int &size, uint8 *&data) - { - bool ret = true; - switch (index) - { - case 0: name = "RAM"; size = 65536; data = memory.wsRAM; break; - case 1: name = "ROM"; size = memory.rom_size; data = memory.wsCartROM; break; - case 2: name = "SRAM"; size = memory.sram_size; data = memory.wsSRAM; break; - case 3: name = "iEEPROM"; size = eeprom.ieeprom_size; data = eeprom.iEEPROM; break; - case 4: name = "EEPROM"; size = eeprom.eeprom_size; data = eeprom.wsEEPROM; break; - default: ret = false; break; - } - return ret; - } - - SYNCFUNC(System) - { - SSS(gfx); - SSS(memory); - SSS(eeprom); - SSS(rtc); - SSS(sound); - SSS(cpu); - SSS(interrupt); - - NSS(rotate); - NSS(oldbuttons); - } - - EXPORT System *bizswan_new() - { - return new System(); - } - - EXPORT void bizswan_delete(System *s) - { - delete s; - } - - EXPORT void bizswan_reset(System *s) - { - s->Reset(); - } - - EXPORT int bizswan_advance(System *s, uint32 buttons, bool novideo, uint32 *surface, int16 *soundbuff, int *soundbuffsize, int *IsRotated) - { - int ret = s->Advance(buttons, novideo, surface, soundbuff, *soundbuffsize); - *IsRotated = s->rotate; - return ret; - } - - EXPORT int bizswan_load(System *s, const uint8 *data, int length, const SyncSettings *settings, int *IsRotated) - { - bool ret = s->Load(data, length, *settings); - *IsRotated = s->rotate; - return ret; - } - - EXPORT int bizswan_saveramsize(System *s) - { - return s->SaveRamSize(); - } - - EXPORT int bizswan_saveramload(System *s, const uint8 *data, int size) - { - return s->SaveRamLoad(data, size); - } - - EXPORT int bizswan_saveramsave(System *s, uint8 *dest, int maxsize) - { - return s->SaveRamSave(dest, maxsize); - } - - EXPORT void bizswan_putsettings(System *s, const Settings *settings) - { - s->PutSettings(*settings); - } - - EXPORT uint32 bizswan_getnecreg(System *s, int which) - { - return s->GetNECReg(which); - } - - EXPORT int bizswan_getmemoryarea(System *s, int index, const char **name, int *size, uint8 **data) - { - return s->GetMemoryArea(index, *name, *size, *data); - } - - EXPORT int bizswan_binstatesize(System *s) - { - NewStateDummy dummy; - s->SyncState(&dummy); - return dummy.GetLength(); - } - - EXPORT int bizswan_binstatesave(System *s, char *data, int length) - { - NewStateExternalBuffer saver(data, length); - s->SyncState(&saver); - return !saver.Overflow() && saver.GetLength() == length; - } - - EXPORT int bizswan_binstateload(System *s, const char *data, int length) - { - NewStateExternalBuffer loader(const_cast(data), length); - s->SyncState(&loader); - return !loader.Overflow() && loader.GetLength() == length; - } - - EXPORT void bizswan_txtstatesave(System *s, FPtrs *ff) - { - NewStateExternalFunctions saver(ff); - s->SyncState(&saver); - } - - EXPORT void bizswan_txtstateload(System *s, FPtrs *ff) - { - NewStateExternalFunctions loader(ff); - s->SyncState(&loader); - } - - EXPORT void bizswan_setmemorycallbacks(System *s, void (*rcb)(uint32), void (*ecb)(uint32), void (*wcb)(uint32)) - { - s->cpu.ReadHook = rcb; - s->cpu.WriteHook = wcb; - s->cpu.ExecHook = ecb; - } - - EXPORT void bizswan_setbuttoncallback(System *s, void (*bcb)()) - { - s->memory.ButtonHook = bcb; - } -} + } + + // this is more than just being defensive; these classes do + // in some cases rely on zero filled constuct state + void *System::operator new(std::size_t size) + { + void *p = ::operator new(size); + std::memset(p, 0, size); + return p; + } + + System::System() + { + gfx.sys = this; + memory.sys = this; + eeprom.sys = this; + rtc.sys = this; + sound.sys = this; + cpu.sys = this; + interrupt.sys = this; + } + + System::~System() + { + } + + int System::SaveRamSize() const + { + return eeprom.ieeprom_size + eeprom.eeprom_size + memory.sram_size; + } + + bool System::SaveRamLoad(const uint8 *data, int size) + { + if (size != SaveRamSize()) + return false; + + #define LOAD(sz,ptr) { if (sz) { std::memcpy((ptr), data, (sz)); data += (sz); } } + + LOAD(eeprom.ieeprom_size, eeprom.iEEPROM); + LOAD(eeprom.eeprom_size, eeprom.wsEEPROM); + LOAD(memory.sram_size, memory.wsSRAM); + + #undef LOAD + + return true; + } + + bool System::SaveRamSave(uint8 *dest, int maxsize) const + { + if (maxsize != SaveRamSize()) + return false; + + #define SAVE(sz,ptr) { if (sz) { std::memcpy(dest, (ptr), (sz)); dest += (sz); } } + + SAVE(eeprom.ieeprom_size, eeprom.iEEPROM); + SAVE(eeprom.eeprom_size, eeprom.wsEEPROM); + SAVE(memory.sram_size, memory.wsSRAM); + + #undef SAVE + + return true; + } + + void System::PutSettings(const Settings &s) + { + gfx.SetLayerEnableMask(s.LayerMask); + gfx.SetBWPalette(s.BWPalette); + gfx.SetColorPalette(s.ColorPalette); + } + + uint32 System::GetNECReg(int which) const + { + return cpu.get_reg(which); + } + + bool System::GetMemoryArea(int index, const char *&name, int &size, uint8 *&data) + { + bool ret = true; + switch (index) + { + case 0: name = "RAM"; size = 65536; data = memory.wsRAM; break; + case 1: name = "ROM"; size = memory.rom_size; data = memory.wsCartROM; break; + case 2: name = "SRAM"; size = memory.sram_size; data = memory.wsSRAM; break; + case 3: name = "iEEPROM"; size = eeprom.ieeprom_size; data = eeprom.iEEPROM; break; + case 4: name = "EEPROM"; size = eeprom.eeprom_size; data = eeprom.wsEEPROM; break; + default: ret = false; break; + } + return ret; + } + + SYNCFUNC(System) + { + SSS(gfx); + SSS(memory); + SSS(eeprom); + SSS(rtc); + SSS(sound); + SSS(cpu); + SSS(interrupt); + + NSS(rotate); + NSS(oldbuttons); + } + + EXPORT System *bizswan_new() + { + return new System(); + } + + EXPORT void bizswan_delete(System *s) + { + delete s; + } + + EXPORT void bizswan_reset(System *s) + { + s->Reset(); + } + + EXPORT int bizswan_advance(System *s, uint32 buttons, bool novideo, uint32 *surface, int16 *soundbuff, int *soundbuffsize, int *IsRotated) + { + int ret = s->Advance(buttons, novideo, surface, soundbuff, *soundbuffsize); + *IsRotated = s->rotate; + return ret; + } + + EXPORT int bizswan_load(System *s, const uint8 *data, int length, const SyncSettings *settings, int *IsRotated) + { + bool ret = s->Load(data, length, *settings); + *IsRotated = s->rotate; + return ret; + } + + EXPORT int bizswan_saveramsize(System *s) + { + return s->SaveRamSize(); + } + + EXPORT int bizswan_saveramload(System *s, const uint8 *data, int size) + { + return s->SaveRamLoad(data, size); + } + + EXPORT int bizswan_saveramsave(System *s, uint8 *dest, int maxsize) + { + return s->SaveRamSave(dest, maxsize); + } + + EXPORT void bizswan_putsettings(System *s, const Settings *settings) + { + s->PutSettings(*settings); + } + + EXPORT uint32 bizswan_getnecreg(System *s, int which) + { + return s->GetNECReg(which); + } + + EXPORT int bizswan_getmemoryarea(System *s, int index, const char **name, int *size, uint8 **data) + { + return s->GetMemoryArea(index, *name, *size, *data); + } + + EXPORT int bizswan_binstatesize(System *s) + { + NewStateDummy dummy; + s->SyncState(&dummy); + return dummy.GetLength(); + } + + EXPORT int bizswan_binstatesave(System *s, char *data, int length) + { + NewStateExternalBuffer saver(data, length); + s->SyncState(&saver); + return !saver.Overflow() && saver.GetLength() == length; + } + + EXPORT int bizswan_binstateload(System *s, const char *data, int length) + { + NewStateExternalBuffer loader(const_cast(data), length); + s->SyncState(&loader); + return !loader.Overflow() && loader.GetLength() == length; + } + + EXPORT void bizswan_txtstatesave(System *s, FPtrs *ff) + { + NewStateExternalFunctions saver(ff); + s->SyncState(&saver); + } + + EXPORT void bizswan_txtstateload(System *s, FPtrs *ff) + { + NewStateExternalFunctions loader(ff); + s->SyncState(&loader); + } + + EXPORT void bizswan_setmemorycallbacks(System *s, void (*rcb)(uint32), void (*ecb)(uint32), void (*wcb)(uint32)) + { + s->cpu.ReadHook = rcb; + s->cpu.WriteHook = wcb; + s->cpu.ExecHook = ecb; + } + + EXPORT void bizswan_setbuttoncallback(System *s, void (*bcb)()) + { + s->memory.ButtonHook = bcb; + } +}