Mercurial > audlegacy-plugins
diff src/console/Sms_Apu.cxx @ 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/Sms_Apu.cxx Wed Nov 29 14:42:11 2006 -0800 +++ b/src/console/Sms_Apu.cxx Thu Nov 30 19:54:33 2006 -0800 @@ -1,5 +1,4 @@ - -// Sms_Snd_Emu 0.1.3. http://www.slack.net/~ant/ +// Sms_Snd_Emu 0.1.4. http://www.slack.net/~ant/ #include "Sms_Apu.h" @@ -9,22 +8,22 @@ version 2.1 of the License, or (at your option) any later version. This module is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for -more details. You should have received a copy of the GNU Lesser General -Public License along with this module; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include BLARGG_SOURCE_BEGIN +#include "blargg_source.h" // Sms_Osc Sms_Osc::Sms_Osc() { - output = NULL; - outputs [0] = NULL; // always stays NULL - outputs [1] = NULL; - outputs [2] = NULL; - outputs [3] = NULL; + output = 0; + outputs [0] = 0; // always stays NULL + outputs [1] = 0; + outputs [2] = 0; + outputs [3] = 0; } void Sms_Osc::reset() @@ -45,7 +44,7 @@ Sms_Osc::reset(); } -void Sms_Square::run( sms_time_t time, sms_time_t end_time ) +void Sms_Square::run( blip_time_t time, blip_time_t end_time ) { if ( !volume || period <= 128 ) { @@ -99,17 +98,17 @@ // Sms_Noise -static const int noise_periods [3] = { 0x100, 0x200, 0x400 }; +static int const noise_periods [3] = { 0x100, 0x200, 0x400 }; inline void Sms_Noise::reset() { period = &noise_periods [0]; shifter = 0x8000; - tap = 12; + feedback = 0x9000; Sms_Osc::reset(); } -void Sms_Noise::run( sms_time_t time, sms_time_t end_time ) +void Sms_Noise::run( blip_time_t time, blip_time_t end_time ) { int amp = volume; if ( shifter & 1 ) @@ -137,9 +136,9 @@ do { - int changed = (shifter + 1) & 2; // set if prev and next bits differ - shifter = (((shifter << 15) ^ (shifter << tap)) & 0x8000) | (shifter >> 1); - if ( changed ) + int changed = shifter + 1; + shifter = (feedback & -(shifter & 1)) ^ (shifter >> 1); + if ( changed & 2 ) // true if bits 0 and 1 differ { delta = -delta; synth.offset_inline( time, delta, output ); @@ -203,19 +202,32 @@ osc_output( i, center, left, right ); } -void Sms_Apu::reset() +void Sms_Apu::reset( unsigned feedback, int noise_width ) { - stereo_found = false; last_time = 0; latch = 0; + if ( !feedback || !noise_width ) + { + feedback = 0x0009; + noise_width = 16; + } + // convert to "Galios configuration" + looped_feedback = 1 << (noise_width - 1); + noise_feedback = 0; + while ( noise_width-- ) + { + noise_feedback = (noise_feedback << 1) | (feedback & 1); + feedback >>= 1; + } + squares [0].reset(); squares [1].reset(); squares [2].reset(); noise.reset(); } -void Sms_Apu::run_until( sms_time_t end_time ) +void Sms_Apu::run_until( blip_time_t end_time ) { require( end_time >= last_time ); // end_time must not be before previous time @@ -227,9 +239,7 @@ Sms_Osc& osc = *oscs [i]; if ( osc.output ) { - if ( osc.output != osc.outputs [3] ) - stereo_found = true; // playing on side output - + osc.output->set_modified(); if ( i < 3 ) squares [i].run( last_time, end_time ); else @@ -241,20 +251,16 @@ } } -bool Sms_Apu::end_frame( sms_time_t end_time ) +void Sms_Apu::end_frame( blip_time_t end_time ) { if ( end_time > last_time ) run_until( end_time ); assert( last_time >= end_time ); last_time -= end_time; - - bool result = stereo_found; - stereo_found = false; - return result; } -void Sms_Apu::write_ggstereo( sms_time_t time, int data ) +void Sms_Apu::write_ggstereo( blip_time_t time, int data ) { require( (unsigned) data <= 0xFF ); @@ -270,18 +276,21 @@ if ( osc.output != old_output && osc.last_amp ) { if ( old_output ) + { + old_output->set_modified(); square_synth.offset( time, -osc.last_amp, old_output ); + } osc.last_amp = 0; } } } -static const unsigned char volumes [16] = { - // volumes [i] = 64 * pow( 1.26, 15 - i ) / pow( 1.26, 15 ) +// volumes [i] = 64 * pow( 1.26, 15 - i ) / pow( 1.26, 15 ) +static unsigned char const volumes [16] = { 64, 50, 39, 31, 24, 19, 15, 12, 9, 7, 5, 4, 3, 2, 1, 0 }; -void Sms_Apu::write_data( sms_time_t time, int data ) +void Sms_Apu::write_data( blip_time_t time, int data ) { require( (unsigned) data <= 0xFF ); @@ -311,9 +320,7 @@ else noise.period = &squares [2].period; - int const tap_disabled = 16; - noise.tap = (data & 0x04) ? 12 : tap_disabled; + noise.feedback = (data & 0x04) ? noise_feedback : looped_feedback; noise.shifter = 0x8000; } } -