diff --git a/msvc/libopl.vcproj b/msvc/libopl.vcproj index b0480b6c..316847c0 100644 --- a/msvc/libopl.vcproj +++ b/msvc/libopl.vcproj @@ -158,10 +158,6 @@ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > - - @@ -194,6 +190,10 @@ RelativePath="..\opl\opl_win32.c" > + + + + -#include -#include -//#include "dosbox.h" -#include "dbopl.h" - - -#define GCC_UNLIKELY(x) x - -#define TRUE 1 -#define FALSE 0 - -#ifndef PI -#define PI 3.14159265358979323846 -#endif - -#define OPLRATE ((double)(14318180.0 / 288.0)) -#define TREMOLO_TABLE 52 - -//Try to use most precision for frequencies -//Else try to keep different waves in synch -//#define WAVE_PRECISION 1 -#ifndef WAVE_PRECISION -//Wave bits available in the top of the 32bit range -//Original adlib uses 10.10, we use 10.22 -#define WAVE_BITS 10 -#else -//Need some extra bits at the top to have room for octaves and frequency multiplier -//We support to 8 times lower rate -//128 * 15 * 8 = 15350, 2^13.9, so need 14 bits -#define WAVE_BITS 14 -#endif -#define WAVE_SH ( 32 - WAVE_BITS ) -#define WAVE_MASK ( ( 1 << WAVE_SH ) - 1 ) - -//Use the same accuracy as the waves -#define LFO_SH ( WAVE_SH - 10 ) -//LFO is controlled by our tremolo 256 sample limit -#define LFO_MAX ( 256 << ( LFO_SH ) ) - - -//Maximum amount of attenuation bits -//Envelope goes to 511, 9 bits -#if (DBOPL_WAVE == WAVE_TABLEMUL ) -//Uses the value directly -#define ENV_BITS ( 9 ) -#else -//Add 3 bits here for more accuracy and would have to be shifted up either way -#define ENV_BITS ( 9 ) -#endif -//Limits of the envelope with those bits and when the envelope goes silent -#define ENV_MIN 0 -#define ENV_EXTRA ( ENV_BITS - 9 ) -#define ENV_MAX ( 511 << ENV_EXTRA ) -#define ENV_LIMIT ( ( 12 * 256) >> ( 3 - ENV_EXTRA ) ) -#define ENV_SILENT( _X_ ) ( (_X_) >= ENV_LIMIT ) - -//Attack/decay/release rate counter shift -#define RATE_SH 24 -#define RATE_MASK ( ( 1 << RATE_SH ) - 1 ) -//Has to fit within 16bit lookuptable -#define MUL_SH 16 - -//Check some ranges -#if ENV_EXTRA > 3 -#error Too many envelope bits -#endif - -static inline void Operator__SetState(Operator *self, Bit8u s ); -static inline Bit32u Chip__ForwardNoise(Chip *self); - -// C++'s template<> sure is useful sometimes. - -static Channel* Channel__BlockTemplate(Channel *self, Chip* chip, - Bit32u samples, Bit32s* output, - SynthMode mode ); -#define BLOCK_TEMPLATE(mode) \ - static Channel* Channel__BlockTemplate_ ## mode(Channel *self, Chip* chip, \ - Bit32u samples, Bit32s* output) \ - { \ - return Channel__BlockTemplate(self, chip, samples, output, mode); \ - } - -BLOCK_TEMPLATE(sm2AM) -BLOCK_TEMPLATE(sm2FM) -BLOCK_TEMPLATE(sm3AM) -BLOCK_TEMPLATE(sm3FM) -BLOCK_TEMPLATE(sm3FMFM) -BLOCK_TEMPLATE(sm3AMFM) -BLOCK_TEMPLATE(sm3FMAM) -BLOCK_TEMPLATE(sm3AMAM) -BLOCK_TEMPLATE(sm2Percussion) -BLOCK_TEMPLATE(sm3Percussion) - -//How much to substract from the base value for the final attenuation -static const Bit8u KslCreateTable[16] = { - //0 will always be be lower than 7 * 8 - 64, 32, 24, 19, - 16, 12, 11, 10, - 8, 6, 5, 4, - 3, 2, 1, 0, -}; - -#define M(_X_) ((Bit8u)( (_X_) * 2)) -static const Bit8u FreqCreateTable[16] = { - M(0.5), M(1 ), M(2 ), M(3 ), M(4 ), M(5 ), M(6 ), M(7 ), - M(8 ), M(9 ), M(10), M(10), M(12), M(12), M(15), M(15) -}; -#undef M - -//We're not including the highest attack rate, that gets a special value -static const Bit8u AttackSamplesTable[13] = { - 69, 55, 46, 40, - 35, 29, 23, 20, - 19, 15, 11, 10, - 9 -}; -//On a real opl these values take 8 samples to reach and are based upon larger tables -static const Bit8u EnvelopeIncreaseTable[13] = { - 4, 5, 6, 7, - 8, 10, 12, 14, - 16, 20, 24, 28, - 32, -}; - -#if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG ) -static Bit16u ExpTable[ 256 ]; -#endif - -#if ( DBOPL_WAVE == WAVE_HANDLER ) -//PI table used by WAVEHANDLER -static Bit16u SinTable[ 512 ]; -#endif - -#if ( DBOPL_WAVE > WAVE_HANDLER ) -//Layout of the waveform table in 512 entry intervals -//With overlapping waves we reduce the table to half it's size - -// | |//\\|____|WAV7|//__|/\ |____|/\/\| -// |\\//| | |WAV7| | \/| | | -// |06 |0126|17 |7 |3 |4 |4 5 |5 | - -//6 is just 0 shifted and masked - -static Bit16s WaveTable[ 8 * 512 ]; -//Distance into WaveTable the wave starts -static const Bit16u WaveBaseTable[8] = { - 0x000, 0x200, 0x200, 0x800, - 0xa00, 0xc00, 0x100, 0x400, - -}; -//Mask the counter with this -static const Bit16u WaveMaskTable[8] = { - 1023, 1023, 511, 511, - 1023, 1023, 512, 1023, -}; - -//Where to start the counter on at keyon -static const Bit16u WaveStartTable[8] = { - 512, 0, 0, 0, - 0, 512, 512, 256, -}; -#endif - -#if ( DBOPL_WAVE == WAVE_TABLEMUL ) -static Bit16u MulTable[ 384 ]; -#endif - -static Bit8u KslTable[ 8 * 16 ]; -static Bit8u TremoloTable[ TREMOLO_TABLE ]; -//Start of a channel behind the chip struct start -static Bit16u ChanOffsetTable[32]; -//Start of an operator behind the chip struct start -static Bit16u OpOffsetTable[64]; - -//The lower bits are the shift of the operator vibrato value -//The highest bit is right shifted to generate -1 or 0 for negation -//So taking the highest input value of 7 this gives 3, 7, 3, 0, -3, -7, -3, 0 -static const Bit8s VibratoTable[ 8 ] = { - 1 - 0x00, 0 - 0x00, 1 - 0x00, 30 - 0x00, - 1 - 0x80, 0 - 0x80, 1 - 0x80, 30 - 0x80 -}; - -//Shift strength for the ksl value determined by ksl strength -static const Bit8u KslShiftTable[4] = { - 31,1,2,0 -}; - -//Generate a table index and table shift value using input value from a selected rate -static void EnvelopeSelect( Bit8u val, Bit8u *index, Bit8u *shift ) { - if ( val < 13 * 4 ) { //Rate 0 - 12 - *shift = 12 - ( val >> 2 ); - *index = val & 3; - } else if ( val < 15 * 4 ) { //rate 13 - 14 - *shift = 0; - *index = val - 12 * 4; - } else { //rate 15 and up - *shift = 0; - *index = 12; - } -} - -#if ( DBOPL_WAVE == WAVE_HANDLER ) -/* - Generate the different waveforms out of the sine/exponetial table using handlers -*/ -static inline Bits MakeVolume( Bitu wave, Bitu volume ) { - Bitu total = wave + volume; - Bitu index = total & 0xff; - Bitu sig = ExpTable[ index ]; - Bitu exp = total >> 8; -#if 0 - //Check if we overflow the 31 shift limit - if ( exp >= 32 ) { - LOG_MSG( "WTF %d %d", total, exp ); - } -#endif - return (sig >> exp); -}; - -static Bits DB_FASTCALL WaveForm0( Bitu i, Bitu volume ) { - Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 - Bitu wave = SinTable[i & 511]; - return (MakeVolume( wave, volume ) ^ neg) - neg; -} -static Bits DB_FASTCALL WaveForm1( Bitu i, Bitu volume ) { - Bit32u wave = SinTable[i & 511]; - wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); - return MakeVolume( wave, volume ); -} -static Bits DB_FASTCALL WaveForm2( Bitu i, Bitu volume ) { - Bitu wave = SinTable[i & 511]; - return MakeVolume( wave, volume ); -} -static Bits DB_FASTCALL WaveForm3( Bitu i, Bitu volume ) { - Bitu wave = SinTable[i & 255]; - wave |= ( ( (i ^ 256 ) & 256) - 1) >> ( 32 - 12 ); - return MakeVolume( wave, volume ); -} -static Bits DB_FASTCALL WaveForm4( Bitu i, Bitu volume ) { - //Twice as fast - i <<= 1; - Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 - Bitu wave = SinTable[i & 511]; - wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); - return (MakeVolume( wave, volume ) ^ neg) - neg; -} -static Bits DB_FASTCALL WaveForm5( Bitu i, Bitu volume ) { - //Twice as fast - i <<= 1; - Bitu wave = SinTable[i & 511]; - wave |= ( ( (i ^ 512 ) & 512) - 1) >> ( 32 - 12 ); - return MakeVolume( wave, volume ); -} -static Bits DB_FASTCALL WaveForm6( Bitu i, Bitu volume ) { - Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 - return (MakeVolume( 0, volume ) ^ neg) - neg; -} -static Bits DB_FASTCALL WaveForm7( Bitu i, Bitu volume ) { - //Negative is reversed here - Bits neg = (( i >> 9) & 1) - 1; - Bitu wave = (i << 3); - //When negative the volume also runs backwards - wave = ((wave ^ neg) - neg) & 4095; - return (MakeVolume( wave, volume ) ^ neg) - neg; -} - -static const WaveHandler WaveHandlerTable[8] = { - WaveForm0, WaveForm1, WaveForm2, WaveForm3, - WaveForm4, WaveForm5, WaveForm6, WaveForm7 -}; - -#endif - -/* - Operator -*/ - -//We zero out when rate == 0 -static inline void Operator__UpdateAttack(Operator *self, const Chip* chip ) { - Bit8u rate = self->reg60 >> 4; - if ( rate ) { - Bit8u val = (rate << 2) + self->ksr; - self->attackAdd = chip->attackRates[ val ]; - self->rateZero &= ~(1 << ATTACK); - } else { - self->attackAdd = 0; - self->rateZero |= (1 << ATTACK); - } -} -static inline void Operator__UpdateDecay(Operator *self, const Chip* chip ) { - Bit8u rate = self->reg60 & 0xf; - if ( rate ) { - Bit8u val = (rate << 2) + self->ksr; - self->decayAdd = chip->linearRates[ val ]; - self->rateZero &= ~(1 << DECAY); - } else { - self->decayAdd = 0; - self->rateZero |= (1 << DECAY); - } -} -static inline void Operator__UpdateRelease(Operator *self, const Chip* chip ) { - Bit8u rate = self->reg80 & 0xf; - if ( rate ) { - Bit8u val = (rate << 2) + self->ksr; - self->releaseAdd = chip->linearRates[ val ]; - self->rateZero &= ~(1 << RELEASE); - if ( !(self->reg20 & MASK_SUSTAIN ) ) { - self->rateZero &= ~( 1 << SUSTAIN ); - } - } else { - self->rateZero |= (1 << RELEASE); - self->releaseAdd = 0; - if ( !(self->reg20 & MASK_SUSTAIN ) ) { - self->rateZero |= ( 1 << SUSTAIN ); - } - } -} - -static inline void Operator__UpdateAttenuation(Operator *self) { - Bit8u kslBase = (Bit8u)((self->chanData >> SHIFT_KSLBASE) & 0xff); - Bit32u tl = self->reg40 & 0x3f; - Bit8u kslShift = KslShiftTable[ self->reg40 >> 6 ]; - //Make sure the attenuation goes to the right bits - self->totalLevel = tl << ( ENV_BITS - 7 ); //Total level goes 2 bits below max - self->totalLevel += ( kslBase << ENV_EXTRA ) >> kslShift; -} - -static void Operator__UpdateFrequency(Operator *self) { - Bit32u freq = self->chanData & (( 1 << 10 ) - 1); - Bit32u block = (self->chanData >> 10) & 0xff; -#ifdef WAVE_PRECISION - block = 7 - block; - self->waveAdd = ( freq * self->freqMul ) >> block; -#else - self->waveAdd = ( freq << block ) * self->freqMul; -#endif - if ( self->reg20 & MASK_VIBRATO ) { - self->vibStrength = (Bit8u)(freq >> 7); - -#ifdef WAVE_PRECISION - self->vibrato = ( self->vibStrength * self->freqMul ) >> block; -#else - self->vibrato = ( self->vibStrength << block ) * self->freqMul; -#endif - } else { - self->vibStrength = 0; - self->vibrato = 0; - } -} - -static void Operator__UpdateRates(Operator *self, const Chip* chip ) { - //Mame seems to reverse this where enabling ksr actually lowers - //the rate, but pdf manuals says otherwise? - Bit8u newKsr = (Bit8u)((self->chanData >> SHIFT_KEYCODE) & 0xff); - if ( !( self->reg20 & MASK_KSR ) ) { - newKsr >>= 2; - } - if ( self->ksr == newKsr ) - return; - self->ksr = newKsr; - Operator__UpdateAttack( self, chip ); - Operator__UpdateDecay( self, chip ); - Operator__UpdateRelease( self, chip ); -} - -static inline Bit32s Operator__RateForward(Operator *self, Bit32u add ) { - Bit32s ret; // haleyjd: GNUisms out! - self->rateIndex += add; - ret = self->rateIndex >> RATE_SH; - self->rateIndex = self->rateIndex & RATE_MASK; - return ret; -} - -static Bits Operator__TemplateVolume(Operator *self, OperatorState yes) { - Bit32s vol = self->volume; - Bit32s change; - switch ( yes ) { - case OFF: - return ENV_MAX; - case ATTACK: - change = Operator__RateForward( self, self->attackAdd ); - if ( !change ) - return vol; - vol += ( (~vol) * change ) >> 3; - if ( vol < ENV_MIN ) { - self->volume = ENV_MIN; - self->rateIndex = 0; - Operator__SetState( self, DECAY ); - return ENV_MIN; - } - break; - case DECAY: - vol += Operator__RateForward( self, self->decayAdd ); - if ( GCC_UNLIKELY(vol >= self->sustainLevel) ) { - //Check if we didn't overshoot max attenuation, then just go off - if ( GCC_UNLIKELY(vol >= ENV_MAX) ) { - self->volume = ENV_MAX; - Operator__SetState( self, OFF ); - return ENV_MAX; - } - //Continue as sustain - self->rateIndex = 0; - Operator__SetState( self, SUSTAIN ); - } - break; - case SUSTAIN: - if ( self->reg20 & MASK_SUSTAIN ) { - return vol; - } - //In sustain phase, but not sustaining, do regular release - case RELEASE: - vol += Operator__RateForward( self, self->releaseAdd );; - if ( GCC_UNLIKELY(vol >= ENV_MAX) ) { - self->volume = ENV_MAX; - Operator__SetState( self, OFF ); - return ENV_MAX; - } - break; - } - self->volume = vol; - return vol; -} - -#define TEMPLATE_VOLUME(mode) \ - static Bits Operator__TemplateVolume ## mode(Operator *self) \ - { \ - return Operator__TemplateVolume(self, mode); \ - } - -TEMPLATE_VOLUME(OFF) -TEMPLATE_VOLUME(RELEASE) -TEMPLATE_VOLUME(SUSTAIN) -TEMPLATE_VOLUME(ATTACK) -TEMPLATE_VOLUME(DECAY) - -static const VolumeHandler VolumeHandlerTable[5] = { - &Operator__TemplateVolumeOFF, - &Operator__TemplateVolumeRELEASE, - &Operator__TemplateVolumeSUSTAIN, - &Operator__TemplateVolumeDECAY, - &Operator__TemplateVolumeATTACK, -}; - -static inline Bitu Operator__ForwardVolume(Operator *self) { - return self->currentLevel + (self->volHandler)(self); -} - - -static inline Bitu Operator__ForwardWave(Operator *self) { - self->waveIndex += self->waveCurrent; - return self->waveIndex >> WAVE_SH; -} - -static void Operator__Write20(Operator *self, const Chip* chip, Bit8u val ) { - Bit8u change = (self->reg20 ^ val ); - if ( !change ) - return; - self->reg20 = val; - //Shift the tremolo bit over the entire register, saved a branch, YES! - self->tremoloMask = (Bit8s)(val) >> 7; - self->tremoloMask &= ~(( 1 << ENV_EXTRA ) -1); - //Update specific features based on changes - if ( change & MASK_KSR ) { - Operator__UpdateRates( self, chip ); - } - //With sustain enable the volume doesn't change - if ( self->reg20 & MASK_SUSTAIN || ( !self->releaseAdd ) ) { - self->rateZero |= ( 1 << SUSTAIN ); - } else { - self->rateZero &= ~( 1 << SUSTAIN ); - } - //Frequency multiplier or vibrato changed - if ( change & (0xf | MASK_VIBRATO) ) { - self->freqMul = chip->freqMul[ val & 0xf ]; - Operator__UpdateFrequency(self); - } -} - -static void Operator__Write40(Operator *self, const Chip *chip, Bit8u val ) { - if (!(self->reg40 ^ val )) - return; - self->reg40 = val; - Operator__UpdateAttenuation( self ); -} - -static void Operator__Write60(Operator *self, const Chip* chip, Bit8u val ) { - Bit8u change = self->reg60 ^ val; - self->reg60 = val; - if ( change & 0x0f ) { - Operator__UpdateDecay( self, chip ); - } - if ( change & 0xf0 ) { - Operator__UpdateAttack( self, chip ); - } -} - -static void Operator__Write80(Operator *self, const Chip* chip, Bit8u val ) { - Bit8u change = (self->reg80 ^ val ); - Bit8u sustain; // haleyjd 09/09/10: GNUisms out! - if ( !change ) - return; - self->reg80 = val; - sustain = val >> 4; - //Turn 0xf into 0x1f - sustain |= ( sustain + 1) & 0x10; - self->sustainLevel = sustain << ( ENV_BITS - 5 ); - if ( change & 0x0f ) { - Operator__UpdateRelease( self, chip ); - } -} - -static void Operator__WriteE0(Operator *self, const Chip* chip, Bit8u val ) { - Bit8u waveForm; // haleyjd 09/09/10: GNUisms out! - if ( !(self->regE0 ^ val) ) - return; - //in opl3 mode you can always selet 7 waveforms regardless of waveformselect - waveForm = val & ( ( 0x3 & chip->waveFormMask ) | (0x7 & chip->opl3Active ) ); - self->regE0 = val; -#if( DBOPL_WAVE == WAVE_HANDLER ) - self->waveHandler = WaveHandlerTable[ waveForm ]; -#else - self->waveBase = WaveTable + WaveBaseTable[ waveForm ]; - self->waveStart = WaveStartTable[ waveForm ] << WAVE_SH; - self->waveMask = WaveMaskTable[ waveForm ]; -#endif -} - -static inline void Operator__SetState(Operator *self, Bit8u s ) { - self->state = s; - self->volHandler = VolumeHandlerTable[ s ]; -} - -static inline int Operator__Silent(Operator *self) { - if ( !ENV_SILENT( self->totalLevel + self->volume ) ) - return FALSE; - if ( !(self->rateZero & ( 1 << self->state ) ) ) - return FALSE; - return TRUE; -} - -static inline void Operator__Prepare(Operator *self, const Chip* chip ) { - self->currentLevel = self->totalLevel + (chip->tremoloValue & self->tremoloMask); - self->waveCurrent = self->waveAdd; - if ( self->vibStrength >> chip->vibratoShift ) { - Bit32s add = self->vibrato >> chip->vibratoShift; - //Sign extend over the shift value - Bit32s neg = chip->vibratoSign; - //Negate the add with -1 or 0 - add = ( add ^ neg ) - neg; - self->waveCurrent += add; - } -} - -static void Operator__KeyOn(Operator *self, Bit8u mask ) { - if ( !self->keyOn ) { - //Restart the frequency generator -#if( DBOPL_WAVE > WAVE_HANDLER ) - self->waveIndex = self->waveStart; -#else - self->waveIndex = 0; -#endif - self->rateIndex = 0; - Operator__SetState( self, ATTACK ); - } - self->keyOn |= mask; -} - -static void Operator__KeyOff(Operator *self, Bit8u mask ) { - self->keyOn &= ~mask; - if ( !self->keyOn ) { - if ( self->state != OFF ) { - Operator__SetState( self, RELEASE ); - } - } -} - -static inline Bits Operator__GetWave(Operator *self, Bitu index, Bitu vol ) { -#if( DBOPL_WAVE == WAVE_HANDLER ) - return self->waveHandler( index, vol << ( 3 - ENV_EXTRA ) ); -#elif( DBOPL_WAVE == WAVE_TABLEMUL ) - return(self->waveBase[ index & self->waveMask ] * MulTable[ vol >> ENV_EXTRA ]) >> MUL_SH; -#elif( DBOPL_WAVE == WAVE_TABLELOG ) - Bit32s wave = self->waveBase[ index & self->waveMask ]; - Bit32u total = ( wave & 0x7fff ) + vol << ( 3 - ENV_EXTRA ); - Bit32s sig = ExpTable[ total & 0xff ]; - Bit32u exp = total >> 8; - Bit32s neg = wave >> 16; - return((sig ^ neg) - neg) >> exp; -#else -#error "No valid wave routine" -#endif -} - -static inline Bits Operator__GetSample(Operator *self, Bits modulation ) { - Bitu vol = Operator__ForwardVolume(self); - if ( ENV_SILENT( vol ) ) { - //Simply forward the wave - self->waveIndex += self->waveCurrent; - return 0; - } else { - Bitu index = Operator__ForwardWave(self); - index += modulation; - return Operator__GetWave( self, index, vol ); - } -} - -static void Operator__Operator(Operator *self) { - self->chanData = 0; - self->freqMul = 0; - self->waveIndex = 0; - self->waveAdd = 0; - self->waveCurrent = 0; - self->keyOn = 0; - self->ksr = 0; - self->reg20 = 0; - self->reg40 = 0; - self->reg60 = 0; - self->reg80 = 0; - self->regE0 = 0; - Operator__SetState( self, OFF ); - self->rateZero = (1 << OFF); - self->sustainLevel = ENV_MAX; - self->currentLevel = ENV_MAX; - self->totalLevel = ENV_MAX; - self->volume = ENV_MAX; - self->releaseAdd = 0; -} - -/* - Channel -*/ - -static void Channel__Channel(Channel *self) { - Operator__Operator(&self->op[0]); - Operator__Operator(&self->op[1]); - self->old[0] = self->old[1] = 0; - self->chanData = 0; - self->regB0 = 0; - self->regC0 = 0; - self->maskLeft = -1; - self->maskRight = -1; - self->feedback = 31; - self->fourMask = 0; - self->synthHandler = Channel__BlockTemplate_sm2FM; -}; - -static inline Operator* Channel__Op( Channel *self, Bitu index ) { - return &( ( self + (index >> 1) )->op[ index & 1 ]); -} - -static void Channel__SetChanData(Channel *self, const Chip* chip, Bit32u data ) { - Bit32u change = self->chanData ^ data; - self->chanData = data; - Channel__Op( self, 0 )->chanData = data; - Channel__Op( self, 1 )->chanData = data; - //Since a frequency update triggered this, always update frequency - Operator__UpdateFrequency(Channel__Op( self, 0 )); - Operator__UpdateFrequency(Channel__Op( self, 1 )); - if ( change & ( 0xff << SHIFT_KSLBASE ) ) { - Operator__UpdateAttenuation(Channel__Op( self, 0 )); - Operator__UpdateAttenuation(Channel__Op( self, 1 )); - } - if ( change & ( 0xff << SHIFT_KEYCODE ) ) { - Operator__UpdateRates(Channel__Op( self, 0 ), chip); - Operator__UpdateRates(Channel__Op( self, 1 ), chip); - } -} - -static void Channel__UpdateFrequency(Channel *self, const Chip* chip, Bit8u fourOp ) { - //Extrace the frequency bits - Bit32u data = self->chanData & 0xffff; - Bit32u kslBase = KslTable[ data >> 6 ]; - Bit32u keyCode = ( data & 0x1c00) >> 9; - if ( chip->reg08 & 0x40 ) { - keyCode |= ( data & 0x100)>>8; /* notesel == 1 */ - } else { - keyCode |= ( data & 0x200)>>9; /* notesel == 0 */ - } - //Add the keycode and ksl into the highest bits of chanData - data |= (keyCode << SHIFT_KEYCODE) | ( kslBase << SHIFT_KSLBASE ); - Channel__SetChanData( self + 0, chip, data ); - if ( fourOp & 0x3f ) { - Channel__SetChanData( self + 1, chip, data ); - } -} - -static void Channel__WriteA0(Channel *self, const Chip* chip, Bit8u val ) { - Bit8u fourOp = chip->reg104 & chip->opl3Active & self->fourMask; - Bit32u change; // haleyjd 09/09/10: GNUisms out! - //Don't handle writes to silent fourop channels - if ( fourOp > 0x80 ) - return; - change = (self->chanData ^ val ) & 0xff; - if ( change ) { - self->chanData ^= change; - Channel__UpdateFrequency( self, chip, fourOp ); - } -} - -static void Channel__WriteB0(Channel *self, const Chip* chip, Bit8u val ) { - Bit8u fourOp = chip->reg104 & chip->opl3Active & self->fourMask; - Bitu change; // haleyjd 09/09/10: GNUisms out! - //Don't handle writes to silent fourop channels - if ( fourOp > 0x80 ) - return; - change = (self->chanData ^ ( val << 8 ) ) & 0x1f00; - if ( change ) { - self->chanData ^= change; - Channel__UpdateFrequency( self, chip, fourOp ); - } - //Check for a change in the keyon/off state - if ( !(( val ^ self->regB0) & 0x20)) - return; - self->regB0 = val; - if ( val & 0x20 ) { - Operator__KeyOn( Channel__Op(self, 0), 0x1 ); - Operator__KeyOn( Channel__Op(self, 1), 0x1 ); - if ( fourOp & 0x3f ) { - Operator__KeyOn( Channel__Op(self + 1, 0), 1 ); - Operator__KeyOn( Channel__Op(self + 1, 1), 1 ); - } - } else { - Operator__KeyOff( Channel__Op(self, 0), 0x1 ); - Operator__KeyOff( Channel__Op(self, 1), 0x1 ); - if ( fourOp & 0x3f ) { - Operator__KeyOff( Channel__Op(self + 1, 0), 1 ); - Operator__KeyOff( Channel__Op(self + 1, 1), 1 ); - } - } -} - -static void Channel__WriteC0(Channel *self, const Chip* chip, Bit8u val ) { - Bit8u change = val ^ self->regC0; - if ( !change ) - return; - self->regC0 = val; - self->feedback = ( val >> 1 ) & 7; - if ( self->feedback ) { - //We shift the input to the right 10 bit wave index value - self->feedback = 9 - self->feedback; - } else { - self->feedback = 31; - } - //Select the new synth mode - if ( chip->opl3Active ) { - //4-op mode enabled for this channel - if ( (chip->reg104 & self->fourMask) & 0x3f ) { - Channel* chan0, *chan1; - Bit8u synth; // haleyjd 09/09/10: GNUisms out! - //Check if it's the 2nd channel in a 4-op - if ( !(self->fourMask & 0x80 ) ) { - chan0 = self; - chan1 = self + 1; - } else { - chan0 = self - 1; - chan1 = self; - } - - synth = ( (chan0->regC0 & 1) << 0 )| (( chan1->regC0 & 1) << 1 ); - switch ( synth ) { - case 0: - chan0->synthHandler = Channel__BlockTemplate_sm3FMFM; - break; - case 1: - chan0->synthHandler = Channel__BlockTemplate_sm3AMFM; - break; - case 2: - chan0->synthHandler = Channel__BlockTemplate_sm3FMAM ; - break; - case 3: - chan0->synthHandler = Channel__BlockTemplate_sm3AMAM ; - break; - } - //Disable updating percussion channels - } else if ((self->fourMask & 0x40) && ( chip->regBD & 0x20) ) { - - //Regular dual op, am or fm - } else if ( val & 1 ) { - self->synthHandler = Channel__BlockTemplate_sm3AM; - } else { - self->synthHandler = Channel__BlockTemplate_sm3FM; - } - self->maskLeft = ( val & 0x10 ) ? -1 : 0; - self->maskRight = ( val & 0x20 ) ? -1 : 0; - //opl2 active - } else { - //Disable updating percussion channels - if ( (self->fourMask & 0x40) && ( chip->regBD & 0x20 ) ) { - - //Regular dual op, am or fm - } else if ( val & 1 ) { - self->synthHandler = Channel__BlockTemplate_sm2AM; - } else { - self->synthHandler = Channel__BlockTemplate_sm2FM; - } - } -} - -static void Channel__ResetC0(Channel *self, const Chip* chip ) { - Bit8u val = self->regC0; - self->regC0 ^= 0xff; - Channel__WriteC0( self, chip, val ); -}; - -static inline void Channel__GeneratePercussion(Channel *self, Chip* chip, - Bit32s* output, int opl3Mode ) { - Channel* chan = self; - - //BassDrum - Bit32s mod = (Bit32u)((self->old[0] + self->old[1])) >> self->feedback; - Bit32s sample; // haleyjd 09/09/10 - Bit32u noiseBit; - Bit32u c2; - Bit32u c5; - Bit32u phaseBit; - Bit32u hhVol; - Bit32u sdVol; - Bit32u tcVol; - - self->old[0] = self->old[1]; - self->old[1] = Operator__GetSample( Channel__Op(self, 0), mod ); - - //When bassdrum is in AM mode first operator is ignoed - if ( chan->regC0 & 1 ) { - mod = 0; - } else { - mod = self->old[0]; - } - sample = Operator__GetSample( Channel__Op(self, 1), mod ); - - //Precalculate stuff used by other outputs - noiseBit = Chip__ForwardNoise(chip) & 0x1; - c2 = Operator__ForwardWave(Channel__Op(self, 2)); - c5 = Operator__ForwardWave(Channel__Op(self, 5)); - phaseBit = (((c2 & 0x88) ^ ((c2<<5) & 0x80)) | ((c5 ^ (c5<<2)) & 0x20)) ? 0x02 : 0x00; - - //Hi-Hat - hhVol = Operator__ForwardVolume(Channel__Op(self, 2)); - if ( !ENV_SILENT( hhVol ) ) { - Bit32u hhIndex = (phaseBit<<8) | (0x34 << ( phaseBit ^ (noiseBit << 1 ))); - sample += Operator__GetWave( Channel__Op(self, 2), hhIndex, hhVol ); - } - //Snare Drum - sdVol = Operator__ForwardVolume( Channel__Op(self, 3) ); - if ( !ENV_SILENT( sdVol ) ) { - Bit32u sdIndex = ( 0x100 + (c2 & 0x100) ) ^ ( noiseBit << 8 ); - sample += Operator__GetWave( Channel__Op(self, 3), sdIndex, sdVol ); - } - //Tom-tom - sample += Operator__GetSample( Channel__Op(self, 4), 0 ); - - //Top-Cymbal - tcVol = Operator__ForwardVolume(Channel__Op(self, 5)); - if ( !ENV_SILENT( tcVol ) ) { - Bit32u tcIndex = (1 + phaseBit) << 8; - sample += Operator__GetWave( Channel__Op(self, 5), tcIndex, tcVol ); - } - sample <<= 1; - if ( opl3Mode ) { - output[0] += sample; - output[1] += sample; - } else { - output[0] += sample; - } -} - -Channel* Channel__BlockTemplate(Channel *self, Chip* chip, - Bit32u samples, Bit32s* output, - SynthMode mode ) { - Bitu i; - - switch( mode ) { - case sm2AM: - case sm3AM: - if ( Operator__Silent(Channel__Op(self, 0)) - && Operator__Silent(Channel__Op(self, 1))) { - self->old[0] = self->old[1] = 0; - return(self + 1); - } - break; - case sm2FM: - case sm3FM: - if ( Operator__Silent(Channel__Op(self, 1))) { - self->old[0] = self->old[1] = 0; - return (self + 1); - } - break; - case sm3FMFM: - if ( Operator__Silent(Channel__Op(self, 3))) { - self->old[0] = self->old[1] = 0; - return (self + 2); - } - break; - case sm3AMFM: - if ( Operator__Silent( Channel__Op(self, 0) ) - && Operator__Silent( Channel__Op(self, 3) )) { - self->old[0] = self->old[1] = 0; - return (self + 2); - } - break; - case sm3FMAM: - if ( Operator__Silent( Channel__Op(self, 1)) - && Operator__Silent( Channel__Op(self, 3))) { - self->old[0] = self->old[1] = 0; - return (self + 2); - } - break; - case sm3AMAM: - if ( Operator__Silent( Channel__Op(self, 0) ) - && Operator__Silent( Channel__Op(self, 2) ) - && Operator__Silent( Channel__Op(self, 3) )) { - self->old[0] = self->old[1] = 0; - return (self + 2); - } - break; - - default: - abort(); - } - //Init the operators with the the current vibrato and tremolo values - Operator__Prepare( Channel__Op( self, 0 ), chip ); - Operator__Prepare( Channel__Op( self, 1 ), chip ); - if ( mode > sm4Start ) { - Operator__Prepare( Channel__Op( self, 2 ), chip ); - Operator__Prepare( Channel__Op( self, 3 ), chip ); - } - if ( mode > sm6Start ) { - Operator__Prepare( Channel__Op( self, 4 ), chip ); - Operator__Prepare( Channel__Op( self, 5 ), chip ); - } - for ( i = 0; i < samples; i++ ) { - Bit32s mod; // haleyjd 09/09/10: GNUisms out! - Bit32s sample; - Bit32s out0; - - //Early out for percussion handlers - if ( mode == sm2Percussion ) { - Channel__GeneratePercussion( self, chip, output + i, FALSE ); - continue; //Prevent some unitialized value bitching - } else if ( mode == sm3Percussion ) { - Channel__GeneratePercussion( self, chip, output + i * 2, TRUE ); - continue; //Prevent some unitialized value bitching - } - - //Do unsigned shift so we can shift out all bits but still stay in 10 bit range otherwise - mod = (Bit32u)((self->old[0] + self->old[1])) >> self->feedback; - self->old[0] = self->old[1]; - self->old[1] = Operator__GetSample( Channel__Op(self, 0), mod ); - sample = 0; - out0 = self->old[0]; - if ( mode == sm2AM || mode == sm3AM ) { - sample = out0 + Operator__GetSample( Channel__Op(self, 1), 0 ); - } else if ( mode == sm2FM || mode == sm3FM ) { - sample = Operator__GetSample( Channel__Op(self, 1), out0 ); - } else if ( mode == sm3FMFM ) { - Bits next = Operator__GetSample( Channel__Op(self, 1), out0 ); - next = Operator__GetSample( Channel__Op(self, 2), next ); - sample = Operator__GetSample( Channel__Op(self, 3), next ); - } else if ( mode == sm3AMFM ) { - Bits next; // haleyjd 09/09/10: GNUisms out! - sample = out0; - next = Operator__GetSample( Channel__Op(self, 1), 0 ); - next = Operator__GetSample( Channel__Op(self, 2), next ); - sample += Operator__GetSample( Channel__Op(self, 3), next ); - } else if ( mode == sm3FMAM ) { - Bits next; // haleyjd 09/09/10: GNUisms out! - sample = Operator__GetSample( Channel__Op(self, 1), out0 ); - next = Operator__GetSample( Channel__Op(self, 2), 0 ); - sample += Operator__GetSample( Channel__Op(self, 3), next ); - } else if ( mode == sm3AMAM ) { - Bits next; // haleyjd 09/09/10: GNUisms out! - sample = out0; - next = Operator__GetSample( Channel__Op(self, 1), 0 ); - sample += Operator__GetSample( Channel__Op(self, 2), next ); - sample += Operator__GetSample( Channel__Op(self, 3), 0 ); - } - switch( mode ) { - case sm2AM: - case sm2FM: - output[ i ] += sample; - break; - case sm3AM: - case sm3FM: - case sm3FMFM: - case sm3AMFM: - case sm3FMAM: - case sm3AMAM: - output[ i * 2 + 0 ] += sample & self->maskLeft; - output[ i * 2 + 1 ] += sample & self->maskRight; - break; - default: - abort(); - } - } - switch( mode ) { - case sm2AM: - case sm2FM: - case sm3AM: - case sm3FM: - return ( self + 1 ); - case sm3FMFM: - case sm3AMFM: - case sm3FMAM: - case sm3AMAM: - return ( self + 2 ); - case sm2Percussion: - case sm3Percussion: - return( self + 3 ); - default: - abort(); - } - return 0; -} - -/* - Chip -*/ - -void Chip__Chip(Chip *self) { - int i; - - for (i=0; i<18; ++i) { - Channel__Channel(&self->chan[i]); - } - - self->reg08 = 0; - self->reg04 = 0; - self->regBD = 0; - self->reg104 = 0; - self->opl3Active = 0; -} - -static inline Bit32u Chip__ForwardNoise(Chip *self) { - Bitu count; - self->noiseCounter += self->noiseAdd; - count = self->noiseCounter >> LFO_SH; - self->noiseCounter &= WAVE_MASK; - for ( ; count > 0; --count ) { - //Noise calculation from mame - self->noiseValue ^= ( 0x800302 ) & ( 0 - (self->noiseValue & 1 ) ); - self->noiseValue >>= 1; - } - return self->noiseValue; -} - -static inline Bit32u Chip__ForwardLFO(Chip *self, Bit32u samples ) { - Bit32u todo; // haleyjd 09/09/10: GNUisms out!!!!!! - Bit32u count; - - //Current vibrato value, runs 4x slower than tremolo - self->vibratoSign = ( VibratoTable[ self->vibratoIndex >> 2] ) >> 7; - self->vibratoShift = ( VibratoTable[ self->vibratoIndex >> 2] & 7) + self->vibratoStrength; - self->tremoloValue = TremoloTable[ self->tremoloIndex ] >> self->tremoloStrength; - - //Check hom many samples there can be done before the value changes - todo = LFO_MAX - self->lfoCounter; - count = (todo + self->lfoAdd - 1) / self->lfoAdd; - if ( count > samples ) { - count = samples; - self->lfoCounter += count * self->lfoAdd; - } else { - self->lfoCounter += count * self->lfoAdd; - self->lfoCounter &= (LFO_MAX - 1); - //Maximum of 7 vibrato value * 4 - self->vibratoIndex = ( self->vibratoIndex + 1 ) & 31; - //Clip tremolo to the the table size - if ( self->tremoloIndex + 1 < TREMOLO_TABLE ) - ++self->tremoloIndex; - else - self->tremoloIndex = 0; - } - return count; -} - - -static void Chip__WriteBD(Chip *self, Bit8u val ) { - Bit8u change = self->regBD ^ val; - if ( !change ) - return; - self->regBD = val; - //TODO could do this with shift and xor? - self->vibratoStrength = (val & 0x40) ? 0x00 : 0x01; - self->tremoloStrength = (val & 0x80) ? 0x00 : 0x02; - if ( val & 0x20 ) { - //Drum was just enabled, make sure channel 6 has the right synth - if ( change & 0x20 ) { - if ( self->opl3Active ) { - self->chan[6].synthHandler - = Channel__BlockTemplate_sm3Percussion; - } else { - self->chan[6].synthHandler - = Channel__BlockTemplate_sm2Percussion; - } - } - //Bass Drum - if ( val & 0x10 ) { - Operator__KeyOn( &self->chan[6].op[0], 0x2 ); - Operator__KeyOn( &self->chan[6].op[1], 0x2 ); - } else { - Operator__KeyOff( &self->chan[6].op[0], 0x2 ); - Operator__KeyOff( &self->chan[6].op[1], 0x2 ); - } - //Hi-Hat - if ( val & 0x1 ) { - Operator__KeyOn( &self->chan[7].op[0], 0x2 ); - } else { - Operator__KeyOff( &self->chan[7].op[0], 0x2 ); - } - //Snare - if ( val & 0x8 ) { - Operator__KeyOn( &self->chan[7].op[1], 0x2 ); - } else { - Operator__KeyOff( &self->chan[7].op[1], 0x2 ); - } - //Tom-Tom - if ( val & 0x4 ) { - Operator__KeyOn( &self->chan[8].op[0], 0x2 ); - } else { - Operator__KeyOff( &self->chan[8].op[0], 0x2 ); - } - //Top Cymbal - if ( val & 0x2 ) { - Operator__KeyOn( &self->chan[8].op[1], 0x2 ); - } else { - Operator__KeyOff( &self->chan[8].op[1], 0x2 ); - } - //Toggle keyoffs when we turn off the percussion - } else if ( change & 0x20 ) { - //Trigger a reset to setup the original synth handler - Channel__ResetC0( &self->chan[6], self ); - Operator__KeyOff( &self->chan[6].op[0], 0x2 ); - Operator__KeyOff( &self->chan[6].op[1], 0x2 ); - Operator__KeyOff( &self->chan[7].op[0], 0x2 ); - Operator__KeyOff( &self->chan[7].op[1], 0x2 ); - Operator__KeyOff( &self->chan[8].op[0], 0x2 ); - Operator__KeyOff( &self->chan[8].op[1], 0x2 ); - } -} - - -#define REGOP( _FUNC_ ) \ - index = ( ( reg >> 3) & 0x20 ) | ( reg & 0x1f ); \ - if ( OpOffsetTable[ index ] ) { \ - Operator* regOp = (Operator*)( ((char *)self ) + OpOffsetTable[ index ] ); \ - Operator__ ## _FUNC_ (regOp, self, val); \ - } - -#define REGCHAN( _FUNC_ ) \ - index = ( ( reg >> 4) & 0x10 ) | ( reg & 0xf ); \ - if ( ChanOffsetTable[ index ] ) { \ - Channel* regChan = (Channel*)( ((char *)self ) + ChanOffsetTable[ index ] ); \ - Channel__ ## _FUNC_ (regChan, self, val); \ - } - -void Chip__WriteReg(Chip *self, Bit32u reg, Bit8u val ) { - Bitu index; - switch ( (reg & 0xf0) >> 4 ) { - case 0x00 >> 4: - if ( reg == 0x01 ) { - self->waveFormMask = ( val & 0x20 ) ? 0x7 : 0x0; - } else if ( reg == 0x104 ) { - //Only detect changes in lowest 6 bits - if ( !((self->reg104 ^ val) & 0x3f) ) - return; - //Always keep the highest bit enabled, for checking > 0x80 - self->reg104 = 0x80 | ( val & 0x3f ); - } else if ( reg == 0x105 ) { - int i; - - //MAME says the real opl3 doesn't reset anything on opl3 disable/enable till the next write in another register - if ( !((self->opl3Active ^ val) & 1 ) ) - return; - self->opl3Active = ( val & 1 ) ? 0xff : 0; - //Update the 0xc0 register for all channels to signal the switch to mono/stereo handlers - for ( i = 0; i < 18;i++ ) { - Channel__ResetC0( &self->chan[i], self ); - } - } else if ( reg == 0x08 ) { - self->reg08 = val; - } - case 0x10 >> 4: - break; - case 0x20 >> 4: - case 0x30 >> 4: - REGOP( Write20 ); - break; - case 0x40 >> 4: - case 0x50 >> 4: - REGOP( Write40 ); - break; - case 0x60 >> 4: - case 0x70 >> 4: - REGOP( Write60 ); - break; - case 0x80 >> 4: - case 0x90 >> 4: - REGOP( Write80 ); - break; - case 0xa0 >> 4: - REGCHAN( WriteA0 ); - break; - case 0xb0 >> 4: - if ( reg == 0xbd ) { - Chip__WriteBD( self, val ); - } else { - REGCHAN( WriteB0 ); - } - break; - case 0xc0 >> 4: - REGCHAN( WriteC0 ); - case 0xd0 >> 4: - break; - case 0xe0 >> 4: - case 0xf0 >> 4: - REGOP( WriteE0 ); - break; - } -} - -Bit32u Chip__WriteAddr(Chip *self, Bit32u port, Bit8u val ) { - switch ( port & 3 ) { - case 0: - return val; - case 2: - if ( self->opl3Active || (val == 0x05) ) - return 0x100 | val; - else - return val; - } - return 0; -} - -void Chip__GenerateBlock2(Chip *self, Bitu total, Bit32s* output ) { - while ( total > 0 ) { - Channel *ch; - int count; - - Bit32u samples = Chip__ForwardLFO( self, total ); - memset(output, 0, sizeof(Bit32s) * samples); - count = 0; - for ( ch = self->chan; ch < self->chan + 9; ) { - count++; - ch = (ch->synthHandler)( ch, self, samples, output ); - } - total -= samples; - output += samples; - } -} - -void Chip__GenerateBlock3(Chip *self, Bitu total, Bit32s* output ) { - while ( total > 0 ) { - int count; - Channel *ch; - - Bit32u samples = Chip__ForwardLFO( self, total ); - memset(output, 0, sizeof(Bit32s) * samples *2); - count = 0; - for ( ch = self->chan; ch < self->chan + 18; ) { - count++; - ch = (ch->synthHandler)( ch, self, samples, output ); - } - total -= samples; - output += samples * 2; - } -} - -void Chip__Setup(Chip *self, Bit32u rate ) { - double original = OPLRATE; - Bit32u i; - Bit32u freqScale; // haleyjd 09/09/10: GNUisms out! -// double original = rate; - double scale = original / (double)rate; - - //Noise counter is run at the same precision as general waves - self->noiseAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) ); - self->noiseCounter = 0; - self->noiseValue = 1; //Make sure it triggers the noise xor the first time - //The low frequency oscillation counter - //Every time his overflows vibrato and tremoloindex are increased - self->lfoAdd = (Bit32u)( 0.5 + scale * ( 1 << LFO_SH ) ); - self->lfoCounter = 0; - self->vibratoIndex = 0; - self->tremoloIndex = 0; - - //With higher octave this gets shifted up - //-1 since the freqCreateTable = *2 -#ifdef WAVE_PRECISION - double freqScale = ( 1 << 7 ) * scale * ( 1 << ( WAVE_SH - 1 - 10)); - for ( i = 0; i < 16; i++ ) { - self->freqMul[i] = (Bit32u)( 0.5 + freqScale * FreqCreateTable[ i ] ); - } -#else - freqScale = (Bit32u)( 0.5 + scale * ( 1 << ( WAVE_SH - 1 - 10))); - for ( i = 0; i < 16; i++ ) { - self->freqMul[i] = freqScale * FreqCreateTable[ i ]; - } -#endif - - //-3 since the real envelope takes 8 steps to reach the single value we supply - for ( i = 0; i < 76; i++ ) { - Bit8u index, shift; - EnvelopeSelect( i, &index, &shift ); - self->linearRates[i] = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH + ENV_EXTRA - shift - 3 ))); - } - //Generate the best matching attack rate - for ( i = 0; i < 62; i++ ) { - Bit8u index, shift; - Bit32s original; // haleyjd 09/09/10: GNUisms out! - Bit32s guessAdd; - Bit32s bestAdd; - Bit32u bestDiff; - Bit32u passes; - EnvelopeSelect( i, &index, &shift ); - //Original amount of samples the attack would take - original = (Bit32u)( (AttackSamplesTable[ index ] << shift) / scale); - - guessAdd = (Bit32u)( scale * (EnvelopeIncreaseTable[ index ] << ( RATE_SH - shift - 3 ))); - bestAdd = guessAdd; - bestDiff = 1 << 30; - - for ( passes = 0; passes < 16; passes ++ ) { - Bit32s volume = ENV_MAX; - Bit32s samples = 0; - Bit32u count = 0; - Bit32s diff; - Bit32u lDiff; - while ( volume > 0 && samples < original * 2 ) { - Bit32s change; // haleyjd 09/09/10 - count += guessAdd; - change = count >> RATE_SH; - count &= RATE_MASK; - if ( GCC_UNLIKELY(change) ) { // less than 1 % - volume += ( ~volume * change ) >> 3; - } - samples++; - - } - diff = original - samples; - lDiff = labs( diff ); - //Init last on first pass - if ( lDiff < bestDiff ) { - bestDiff = lDiff; - bestAdd = guessAdd; - if ( !bestDiff ) - break; - } - //Below our target - if ( diff < 0 ) { - //Better than the last time - Bit32s mul = ((original - diff) << 12) / original; - guessAdd = ((guessAdd * mul) >> 12); - guessAdd++; - } else if ( diff > 0 ) { - Bit32s mul = ((original - diff) << 12) / original; - guessAdd = (guessAdd * mul) >> 12; - guessAdd--; - } - } - self->attackRates[i] = bestAdd; - } - for ( i = 62; i < 76; i++ ) { - //This should provide instant volume maximizing - self->attackRates[i] = 8 << RATE_SH; - } - //Setup the channels with the correct four op flags - //Channels are accessed through a table so they appear linear here - self->chan[ 0].fourMask = 0x00 | ( 1 << 0 ); - self->chan[ 1].fourMask = 0x80 | ( 1 << 0 ); - self->chan[ 2].fourMask = 0x00 | ( 1 << 1 ); - self->chan[ 3].fourMask = 0x80 | ( 1 << 1 ); - self->chan[ 4].fourMask = 0x00 | ( 1 << 2 ); - self->chan[ 5].fourMask = 0x80 | ( 1 << 2 ); - - self->chan[ 9].fourMask = 0x00 | ( 1 << 3 ); - self->chan[10].fourMask = 0x80 | ( 1 << 3 ); - self->chan[11].fourMask = 0x00 | ( 1 << 4 ); - self->chan[12].fourMask = 0x80 | ( 1 << 4 ); - self->chan[13].fourMask = 0x00 | ( 1 << 5 ); - self->chan[14].fourMask = 0x80 | ( 1 << 5 ); - - //mark the percussion channels - self->chan[ 6].fourMask = 0x40; - self->chan[ 7].fourMask = 0x40; - self->chan[ 8].fourMask = 0x40; - - //Clear Everything in opl3 mode - Chip__WriteReg( self, 0x105, 0x1 ); - for ( i = 0; i < 512; i++ ) { - if ( i == 0x105 ) - continue; - Chip__WriteReg( self, i, 0xff ); - Chip__WriteReg( self, i, 0x0 ); - } - Chip__WriteReg( self, 0x105, 0x0 ); - //Clear everything in opl2 mode - for ( i = 0; i < 255; i++ ) { - Chip__WriteReg( self, i, 0xff ); - Chip__WriteReg( self, i, 0x0 ); - } -} - -static int doneTables = FALSE; -void DBOPL_InitTables( void ) { - int i, oct; - - if ( doneTables ) - return; - doneTables = TRUE; -#if ( DBOPL_WAVE == WAVE_HANDLER ) || ( DBOPL_WAVE == WAVE_TABLELOG ) - //Exponential volume table, same as the real adlib - for ( i = 0; i < 256; i++ ) { - //Save them in reverse - ExpTable[i] = (int)( 0.5 + ( pow(2.0, ( 255 - i) * ( 1.0 /256 ) )-1) * 1024 ); - ExpTable[i] += 1024; //or remove the -1 oh well :) - //Preshift to the left once so the final volume can shift to the right - ExpTable[i] *= 2; - } -#endif -#if ( DBOPL_WAVE == WAVE_HANDLER ) - //Add 0.5 for the trunc rounding of the integer cast - //Do a PI sinetable instead of the original 0.5 PI - for ( i = 0; i < 512; i++ ) { - SinTable[i] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 ); - } -#endif -#if ( DBOPL_WAVE == WAVE_TABLEMUL ) - //Multiplication based tables - for ( i = 0; i < 384; i++ ) { - int s = i * 8; - //TODO maybe keep some of the precision errors of the original table? - double val = ( 0.5 + ( pow(2.0, -1.0 + ( 255 - s) * ( 1.0 /256 ) )) * ( 1 << MUL_SH )); - MulTable[i] = (Bit16u)(val); - } - - //Sine Wave Base - for ( i = 0; i < 512; i++ ) { - WaveTable[ 0x0200 + i ] = (Bit16s)(sin( (i + 0.5) * (PI / 512.0) ) * 4084); - WaveTable[ 0x0000 + i ] = -WaveTable[ 0x200 + i ]; - } - //Exponential wave - for ( i = 0; i < 256; i++ ) { - WaveTable[ 0x700 + i ] = (Bit16s)( 0.5 + ( pow(2.0, -1.0 + ( 255 - i * 8) * ( 1.0 /256 ) ) ) * 4085 ); - WaveTable[ 0x6ff - i ] = -WaveTable[ 0x700 + i ]; - } -#endif -#if ( DBOPL_WAVE == WAVE_TABLELOG ) - //Sine Wave Base - for ( i = 0; i < 512; i++ ) { - WaveTable[ 0x0200 + i ] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 ); - WaveTable[ 0x0000 + i ] = ((Bit16s)0x8000) | WaveTable[ 0x200 + i]; - } - //Exponential wave - for ( i = 0; i < 256; i++ ) { - WaveTable[ 0x700 + i ] = i * 8; - WaveTable[ 0x6ff - i ] = ((Bit16s)0x8000) | i * 8; - } -#endif - - // | |//\\|____|WAV7|//__|/\ |____|/\/\| - // |\\//| | |WAV7| | \/| | | - // |06 |0126|27 |7 |3 |4 |4 5 |5 | - -#if (( DBOPL_WAVE == WAVE_TABLELOG ) || ( DBOPL_WAVE == WAVE_TABLEMUL )) - for ( i = 0; i < 256; i++ ) { - //Fill silence gaps - WaveTable[ 0x400 + i ] = WaveTable[0]; - WaveTable[ 0x500 + i ] = WaveTable[0]; - WaveTable[ 0x900 + i ] = WaveTable[0]; - WaveTable[ 0xc00 + i ] = WaveTable[0]; - WaveTable[ 0xd00 + i ] = WaveTable[0]; - //Replicate sines in other pieces - WaveTable[ 0x800 + i ] = WaveTable[ 0x200 + i ]; - //double speed sines - WaveTable[ 0xa00 + i ] = WaveTable[ 0x200 + i * 2 ]; - WaveTable[ 0xb00 + i ] = WaveTable[ 0x000 + i * 2 ]; - WaveTable[ 0xe00 + i ] = WaveTable[ 0x200 + i * 2 ]; - WaveTable[ 0xf00 + i ] = WaveTable[ 0x200 + i * 2 ]; - } -#endif - - //Create the ksl table - for ( oct = 0; oct < 8; oct++ ) { - int base = oct * 8; - for ( i = 0; i < 16; i++ ) { - int val = base - KslCreateTable[i]; - if ( val < 0 ) - val = 0; - //*4 for the final range to match attenuation range - KslTable[ oct * 16 + i ] = val * 4; - } - } - //Create the Tremolo table, just increase and decrease a triangle wave - for ( i = 0; i < TREMOLO_TABLE / 2; i++ ) { - Bit8u val = i << ENV_EXTRA; - TremoloTable[i] = val; - TremoloTable[TREMOLO_TABLE - 1 - i] = val; - } - //Create a table with offsets of the channels from the start of the chip - { // haleyjd 09/09/10: Driving me #$%^@ insane - Chip *chip = NULL; - for ( i = 0; i < 32; i++ ) { - Bitu index = i & 0xf; - Bitu blah; // haleyjd 09/09/10 - if ( index >= 9 ) { - ChanOffsetTable[i] = 0; - continue; - } - //Make sure the four op channels follow eachother - if ( index < 6 ) { - index = (index % 3) * 2 + ( index / 3 ); - } - //Add back the bits for highest ones - if ( i >= 16 ) - index += 9; - blah = (Bitu) ( &(chip->chan[ index ]) ); - ChanOffsetTable[i] = blah; - } - //Same for operators - for ( i = 0; i < 64; i++ ) { - Bitu chNum; // haleyjd 09/09/10 - Bitu opNum; - Bitu blah; - Channel* chan = NULL; - if ( i % 8 >= 6 || ( (i / 8) % 4 == 3 ) ) { - OpOffsetTable[i] = 0; - continue; - } - chNum = (i / 8) * 3 + (i % 8) % 3; - //Make sure we use 16 and up for the 2nd range to match the chanoffset gap - if ( chNum >= 12 ) - chNum += 16 - 12; - opNum = ( i % 8 ) / 3; - blah = (Bitu) ( &(chan->op[opNum]) ); - OpOffsetTable[i] = ChanOffsetTable[ chNum ] + blah; - } -#if 0 - //Stupid checks if table's are correct - for ( Bitu i = 0; i < 18; i++ ) { - Bit32u find = (Bit16u)( &(chip->chan[ i ]) ); - for ( Bitu c = 0; c < 32; c++ ) { - if ( ChanOffsetTable[c] == find ) { - find = 0; - break; - } - } - if ( find ) { - find = find; - } - } - for ( Bitu i = 0; i < 36; i++ ) { - Bit32u find = (Bit16u)( &(chip->chan[ i / 2 ].op[i % 2]) ); - for ( Bitu c = 0; c < 64; c++ ) { - if ( OpOffsetTable[c] == find ) { - find = 0; - break; - } - } - if ( find ) { - find = find; - } - } -#endif - } -} - -/* - -Bit32u Handler::WriteAddr( Bit32u port, Bit8u val ) { - return chip.WriteAddr( port, val ); - -} -void Handler::WriteReg( Bit32u addr, Bit8u val ) { - chip.WriteReg( addr, val ); -} - -void Handler::Generate( MixerChannel* chan, Bitu samples ) { - Bit32s buffer[ 512 * 2 ]; - if ( GCC_UNLIKELY(samples > 512) ) - samples = 512; - if ( !chip.opl3Active ) { - chip.GenerateBlock2( samples, buffer ); - chan->AddSamples_m32( samples, buffer ); - } else { - chip.GenerateBlock3( samples, buffer ); - chan->AddSamples_s32( samples, buffer ); - } -} - -void Handler::Init( Bitu rate ) { - InitTables(); - chip.Setup( rate ); -} -*/ - diff --git a/opl/dbopl.h b/opl/dbopl.h deleted file mode 100644 index 0021be25..00000000 --- a/opl/dbopl.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (C) 2002-2010 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - */ - -#include -#include "opl.h" - -//Use 8 handlers based on a small logatirmic wavetabe and an exponential table for volume -#define WAVE_HANDLER 10 -//Use a logarithmic wavetable with an exponential table for volume -#define WAVE_TABLELOG 11 -//Use a linear wavetable with a multiply table for volume -#define WAVE_TABLEMUL 12 - -//Select the type of wave generator routine -#define DBOPL_WAVE WAVE_TABLEMUL - -typedef struct _Chip Chip; -typedef struct _Operator Operator; -typedef struct _Channel Channel; - -#if (DBOPL_WAVE == WAVE_HANDLER) -typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume ); -#endif - -#define DB_FASTCALL - -typedef Bits (*VolumeHandler)(Operator *self); -typedef Channel* (*SynthHandler)(Channel *self, Chip* chip, Bit32u samples, Bit32s* output ); - -//Different synth modes that can generate blocks of data -typedef enum { - sm2AM, - sm2FM, - sm3AM, - sm3FM, - sm4Start, - sm3FMFM, - sm3AMFM, - sm3FMAM, - sm3AMAM, - sm6Start, - sm2Percussion, - sm3Percussion, -} SynthMode; - -//Shifts for the values contained in chandata variable -enum { - SHIFT_KSLBASE = 16, - SHIFT_KEYCODE = 24, -}; - -//Masks for operator 20 values -enum { - MASK_KSR = 0x10, - MASK_SUSTAIN = 0x20, - MASK_VIBRATO = 0x40, - MASK_TREMOLO = 0x80, -}; - -typedef enum { - OFF, - RELEASE, - SUSTAIN, - DECAY, - ATTACK, -} OperatorState; - -struct _Operator { - VolumeHandler volHandler; - -#if (DBOPL_WAVE == WAVE_HANDLER) - WaveHandler waveHandler; //Routine that generate a wave -#else - Bit16s* waveBase; - Bit32u waveMask; - Bit32u waveStart; -#endif - Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index - Bit32u waveAdd; //The base frequency without vibrato - Bit32u waveCurrent; //waveAdd + vibratao - - Bit32u chanData; //Frequency/octave and derived data coming from whatever channel controls this - Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove? - Bit32u vibrato; //Scaled up vibrato strength - Bit32s sustainLevel; //When stopping at sustain level stop here - Bit32s totalLevel; //totalLevel is added to every generated volume - Bit32u currentLevel; //totalLevel + tremolo - Bit32s volume; //The currently active volume - - Bit32u attackAdd; //Timers for the different states of the envelope - Bit32u decayAdd; - Bit32u releaseAdd; - Bit32u rateIndex; //Current position of the evenlope - - Bit8u rateZero; //Bits for the different states of the envelope having no changes - Bit8u keyOn; //Bitmask of different values that can generate keyon - //Registers, also used to check for changes - Bit8u reg20, reg40, reg60, reg80, regE0; - //Active part of the envelope we're in - Bit8u state; - //0xff when tremolo is enabled - Bit8u tremoloMask; - //Strength of the vibrato - Bit8u vibStrength; - //Keep track of the calculated KSR so we can check for changes - Bit8u ksr; -}; - -struct _Channel { - Operator op[2]; - SynthHandler synthHandler; - Bit32u chanData; //Frequency/octave and derived values - Bit32s old[2]; //Old data for feedback - - Bit8u feedback; //Feedback shift - Bit8u regB0; //Register values to check for changes - Bit8u regC0; - //This should correspond with reg104, bit 6 indicates a Percussion channel, bit 7 indicates a silent channel - Bit8u fourMask; - Bit8s maskLeft; //Sign extended values for both channel's panning - Bit8s maskRight; - -}; - -struct _Chip { - //This is used as the base counter for vibrato and tremolo - Bit32u lfoCounter; - Bit32u lfoAdd; - - - Bit32u noiseCounter; - Bit32u noiseAdd; - Bit32u noiseValue; - - //Frequency scales for the different multiplications - Bit32u freqMul[16]; - //Rates for decay and release for rate of this chip - Bit32u linearRates[76]; - //Best match attack rates for the rate of this chip - Bit32u attackRates[76]; - - //18 channels with 2 operators each - Channel chan[18]; - - Bit8u reg104; - Bit8u reg08; - Bit8u reg04; - Bit8u regBD; - Bit8u vibratoIndex; - Bit8u tremoloIndex; - Bit8s vibratoSign; - Bit8u vibratoShift; - Bit8u tremoloValue; - Bit8u vibratoStrength; - Bit8u tremoloStrength; - //Mask for allowed wave forms - Bit8u waveFormMask; - //0 or -1 when enabled - Bit8s opl3Active; - -}; - -/* -struct Handler : public Adlib::Handler { - DBOPL::Chip chip; - virtual Bit32u WriteAddr( Bit32u port, Bit8u val ); - virtual void WriteReg( Bit32u addr, Bit8u val ); - virtual void Generate( MixerChannel* chan, Bitu samples ); - virtual void Init( Bitu rate ); -}; -*/ - - -void Chip__Setup(Chip *self, Bit32u rate ); -void DBOPL_InitTables( void ); -void Chip__Chip(Chip *self); -void Chip__WriteReg(Chip *self, Bit32u reg, Bit8u val ); -void Chip__GenerateBlock2(Chip *self, Bitu total, Bit32s* output ); -void Chip__GenerateBlock3(Chip *self, Bitu total, Bit32s* output ); - -// haleyjd 09/09/10: Not standard C. -#ifdef _MSC_VER -#define inline __inline -#endif diff --git a/opl/opl.c b/opl/opl.c index 1cf40e83..0d256891 100644 --- a/opl/opl.c +++ b/opl/opl.c @@ -57,7 +57,6 @@ static opl_driver_t *driver = NULL; static int init_stage_reg_writes = 1; unsigned int opl_sample_rate = 22050; -opl_core_t opl_emu = OPL_CORE_NUKED; // // Init/shutdown code. @@ -180,10 +179,9 @@ void OPL_Shutdown(void) // Set the sample rate used for software OPL emulation. -void OPL_SetSampleRateAndCore(unsigned int rate, opl_core_t core) +void OPL_SetSampleRate(unsigned int rate) { opl_sample_rate = rate; - opl_emu = core; } void OPL_WritePort(opl_port_t port, unsigned int value) diff --git a/opl/opl.h b/opl/opl.h index 22c4bd45..deaa442d 100644 --- a/opl/opl.h +++ b/opl/opl.h @@ -21,15 +21,6 @@ #include -typedef uintptr_t Bitu; -typedef intptr_t Bits; -typedef uint32_t Bit32u; -typedef int32_t Bit32s; -typedef uint16_t Bit16u; -typedef int16_t Bit16s; -typedef uint8_t Bit8u; -typedef int8_t Bit8s; - typedef void (*opl_callback_t)(void *data); // Result from OPL_Init(), indicating what type of OPL chip was detected, @@ -48,12 +39,6 @@ typedef enum OPL_REGISTER_PORT_OPL3 = 2 } opl_port_t; -typedef enum -{ - OPL_CORE_NUKED, - OPL_CORE_DBOPL -} opl_core_t; - #define OPL_NUM_OPERATORS 21 #define OPL_NUM_VOICES 9 @@ -96,9 +81,9 @@ opl_init_result_t OPL_Init(unsigned int port_base); void OPL_Shutdown(void); -// Set the sample rate and the core used for software emulation. +// Set the sample rate used for software emulation. -void OPL_SetSampleRateAndCore(unsigned int rate, opl_core_t core); +void OPL_SetSampleRate(unsigned int rate); // Write to one of the OPL I/O ports: diff --git a/opl/opl3.c b/opl/opl3.c index ff2ae3be..090854bc 100644 --- a/opl/opl3.c +++ b/opl/opl3.c @@ -21,7 +21,7 @@ // OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): // OPL2 ROMs. // -// version: 1.6.2 +// version: 1.7 // // Changelog: // @@ -50,7 +50,7 @@ // Improved emulation output. // v1.6.1: // Simple YMF289(OPL3-L) emulation. -// v1.6.2: +// v1.7: // Version for Chocolate Doom. // @@ -64,17 +64,17 @@ // Channel types enum { - ch_2op = 0, - ch_4op = 1, - ch_4op2 = 2, - ch_drum = 3 + ch_2op = 0, + ch_4op = 1, + ch_4op2 = 2, + ch_drum = 3 }; // Envelope key types enum { - egk_norm = 0x01, - egk_drum = 0x02 + egk_norm = 0x01, + egk_drum = 0x02 }; @@ -83,22 +83,38 @@ enum { // static const Bit16u logsinrom[256] = { - 0x859, 0x6c3, 0x607, 0x58b, 0x52e, 0x4e4, 0x4a6, 0x471, 0x443, 0x41a, 0x3f5, 0x3d3, 0x3b5, 0x398, 0x37e, 0x365, - 0x34e, 0x339, 0x324, 0x311, 0x2ff, 0x2ed, 0x2dc, 0x2cd, 0x2bd, 0x2af, 0x2a0, 0x293, 0x286, 0x279, 0x26d, 0x261, - 0x256, 0x24b, 0x240, 0x236, 0x22c, 0x222, 0x218, 0x20f, 0x206, 0x1fd, 0x1f5, 0x1ec, 0x1e4, 0x1dc, 0x1d4, 0x1cd, - 0x1c5, 0x1be, 0x1b7, 0x1b0, 0x1a9, 0x1a2, 0x19b, 0x195, 0x18f, 0x188, 0x182, 0x17c, 0x177, 0x171, 0x16b, 0x166, - 0x160, 0x15b, 0x155, 0x150, 0x14b, 0x146, 0x141, 0x13c, 0x137, 0x133, 0x12e, 0x129, 0x125, 0x121, 0x11c, 0x118, - 0x114, 0x10f, 0x10b, 0x107, 0x103, 0x0ff, 0x0fb, 0x0f8, 0x0f4, 0x0f0, 0x0ec, 0x0e9, 0x0e5, 0x0e2, 0x0de, 0x0db, - 0x0d7, 0x0d4, 0x0d1, 0x0cd, 0x0ca, 0x0c7, 0x0c4, 0x0c1, 0x0be, 0x0bb, 0x0b8, 0x0b5, 0x0b2, 0x0af, 0x0ac, 0x0a9, - 0x0a7, 0x0a4, 0x0a1, 0x09f, 0x09c, 0x099, 0x097, 0x094, 0x092, 0x08f, 0x08d, 0x08a, 0x088, 0x086, 0x083, 0x081, - 0x07f, 0x07d, 0x07a, 0x078, 0x076, 0x074, 0x072, 0x070, 0x06e, 0x06c, 0x06a, 0x068, 0x066, 0x064, 0x062, 0x060, - 0x05e, 0x05c, 0x05b, 0x059, 0x057, 0x055, 0x053, 0x052, 0x050, 0x04e, 0x04d, 0x04b, 0x04a, 0x048, 0x046, 0x045, - 0x043, 0x042, 0x040, 0x03f, 0x03e, 0x03c, 0x03b, 0x039, 0x038, 0x037, 0x035, 0x034, 0x033, 0x031, 0x030, 0x02f, - 0x02e, 0x02d, 0x02b, 0x02a, 0x029, 0x028, 0x027, 0x026, 0x025, 0x024, 0x023, 0x022, 0x021, 0x020, 0x01f, 0x01e, - 0x01d, 0x01c, 0x01b, 0x01a, 0x019, 0x018, 0x017, 0x017, 0x016, 0x015, 0x014, 0x014, 0x013, 0x012, 0x011, 0x011, - 0x010, 0x00f, 0x00f, 0x00e, 0x00d, 0x00d, 0x00c, 0x00c, 0x00b, 0x00a, 0x00a, 0x009, 0x009, 0x008, 0x008, 0x007, - 0x007, 0x007, 0x006, 0x006, 0x005, 0x005, 0x005, 0x004, 0x004, 0x004, 0x003, 0x003, 0x003, 0x002, 0x002, 0x002, - 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000 + 0x859, 0x6c3, 0x607, 0x58b, 0x52e, 0x4e4, 0x4a6, 0x471, + 0x443, 0x41a, 0x3f5, 0x3d3, 0x3b5, 0x398, 0x37e, 0x365, + 0x34e, 0x339, 0x324, 0x311, 0x2ff, 0x2ed, 0x2dc, 0x2cd, + 0x2bd, 0x2af, 0x2a0, 0x293, 0x286, 0x279, 0x26d, 0x261, + 0x256, 0x24b, 0x240, 0x236, 0x22c, 0x222, 0x218, 0x20f, + 0x206, 0x1fd, 0x1f5, 0x1ec, 0x1e4, 0x1dc, 0x1d4, 0x1cd, + 0x1c5, 0x1be, 0x1b7, 0x1b0, 0x1a9, 0x1a2, 0x19b, 0x195, + 0x18f, 0x188, 0x182, 0x17c, 0x177, 0x171, 0x16b, 0x166, + 0x160, 0x15b, 0x155, 0x150, 0x14b, 0x146, 0x141, 0x13c, + 0x137, 0x133, 0x12e, 0x129, 0x125, 0x121, 0x11c, 0x118, + 0x114, 0x10f, 0x10b, 0x107, 0x103, 0x0ff, 0x0fb, 0x0f8, + 0x0f4, 0x0f0, 0x0ec, 0x0e9, 0x0e5, 0x0e2, 0x0de, 0x0db, + 0x0d7, 0x0d4, 0x0d1, 0x0cd, 0x0ca, 0x0c7, 0x0c4, 0x0c1, + 0x0be, 0x0bb, 0x0b8, 0x0b5, 0x0b2, 0x0af, 0x0ac, 0x0a9, + 0x0a7, 0x0a4, 0x0a1, 0x09f, 0x09c, 0x099, 0x097, 0x094, + 0x092, 0x08f, 0x08d, 0x08a, 0x088, 0x086, 0x083, 0x081, + 0x07f, 0x07d, 0x07a, 0x078, 0x076, 0x074, 0x072, 0x070, + 0x06e, 0x06c, 0x06a, 0x068, 0x066, 0x064, 0x062, 0x060, + 0x05e, 0x05c, 0x05b, 0x059, 0x057, 0x055, 0x053, 0x052, + 0x050, 0x04e, 0x04d, 0x04b, 0x04a, 0x048, 0x046, 0x045, + 0x043, 0x042, 0x040, 0x03f, 0x03e, 0x03c, 0x03b, 0x039, + 0x038, 0x037, 0x035, 0x034, 0x033, 0x031, 0x030, 0x02f, + 0x02e, 0x02d, 0x02b, 0x02a, 0x029, 0x028, 0x027, 0x026, + 0x025, 0x024, 0x023, 0x022, 0x021, 0x020, 0x01f, 0x01e, + 0x01d, 0x01c, 0x01b, 0x01a, 0x019, 0x018, 0x017, 0x017, + 0x016, 0x015, 0x014, 0x014, 0x013, 0x012, 0x011, 0x011, + 0x010, 0x00f, 0x00f, 0x00e, 0x00d, 0x00d, 0x00c, 0x00c, + 0x00b, 0x00a, 0x00a, 0x009, 0x009, 0x008, 0x008, 0x007, + 0x007, 0x007, 0x006, 0x006, 0x005, 0x005, 0x005, 0x004, + 0x004, 0x004, 0x003, 0x003, 0x003, 0x002, 0x002, 0x002, + 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000 }; // @@ -106,22 +122,38 @@ static const Bit16u logsinrom[256] = { // static const Bit16u exprom[256] = { - 0x000, 0x003, 0x006, 0x008, 0x00b, 0x00e, 0x011, 0x014, 0x016, 0x019, 0x01c, 0x01f, 0x022, 0x025, 0x028, 0x02a, - 0x02d, 0x030, 0x033, 0x036, 0x039, 0x03c, 0x03f, 0x042, 0x045, 0x048, 0x04b, 0x04e, 0x051, 0x054, 0x057, 0x05a, - 0x05d, 0x060, 0x063, 0x066, 0x069, 0x06c, 0x06f, 0x072, 0x075, 0x078, 0x07b, 0x07e, 0x082, 0x085, 0x088, 0x08b, - 0x08e, 0x091, 0x094, 0x098, 0x09b, 0x09e, 0x0a1, 0x0a4, 0x0a8, 0x0ab, 0x0ae, 0x0b1, 0x0b5, 0x0b8, 0x0bb, 0x0be, - 0x0c2, 0x0c5, 0x0c8, 0x0cc, 0x0cf, 0x0d2, 0x0d6, 0x0d9, 0x0dc, 0x0e0, 0x0e3, 0x0e7, 0x0ea, 0x0ed, 0x0f1, 0x0f4, - 0x0f8, 0x0fb, 0x0ff, 0x102, 0x106, 0x109, 0x10c, 0x110, 0x114, 0x117, 0x11b, 0x11e, 0x122, 0x125, 0x129, 0x12c, - 0x130, 0x134, 0x137, 0x13b, 0x13e, 0x142, 0x146, 0x149, 0x14d, 0x151, 0x154, 0x158, 0x15c, 0x160, 0x163, 0x167, - 0x16b, 0x16f, 0x172, 0x176, 0x17a, 0x17e, 0x181, 0x185, 0x189, 0x18d, 0x191, 0x195, 0x199, 0x19c, 0x1a0, 0x1a4, - 0x1a8, 0x1ac, 0x1b0, 0x1b4, 0x1b8, 0x1bc, 0x1c0, 0x1c4, 0x1c8, 0x1cc, 0x1d0, 0x1d4, 0x1d8, 0x1dc, 0x1e0, 0x1e4, - 0x1e8, 0x1ec, 0x1f0, 0x1f5, 0x1f9, 0x1fd, 0x201, 0x205, 0x209, 0x20e, 0x212, 0x216, 0x21a, 0x21e, 0x223, 0x227, - 0x22b, 0x230, 0x234, 0x238, 0x23c, 0x241, 0x245, 0x249, 0x24e, 0x252, 0x257, 0x25b, 0x25f, 0x264, 0x268, 0x26d, - 0x271, 0x276, 0x27a, 0x27f, 0x283, 0x288, 0x28c, 0x291, 0x295, 0x29a, 0x29e, 0x2a3, 0x2a8, 0x2ac, 0x2b1, 0x2b5, - 0x2ba, 0x2bf, 0x2c4, 0x2c8, 0x2cd, 0x2d2, 0x2d6, 0x2db, 0x2e0, 0x2e5, 0x2e9, 0x2ee, 0x2f3, 0x2f8, 0x2fd, 0x302, - 0x306, 0x30b, 0x310, 0x315, 0x31a, 0x31f, 0x324, 0x329, 0x32e, 0x333, 0x338, 0x33d, 0x342, 0x347, 0x34c, 0x351, - 0x356, 0x35b, 0x360, 0x365, 0x36a, 0x370, 0x375, 0x37a, 0x37f, 0x384, 0x38a, 0x38f, 0x394, 0x399, 0x39f, 0x3a4, - 0x3a9, 0x3ae, 0x3b4, 0x3b9, 0x3bf, 0x3c4, 0x3c9, 0x3cf, 0x3d4, 0x3da, 0x3df, 0x3e4, 0x3ea, 0x3ef, 0x3f5, 0x3fa + 0x000, 0x003, 0x006, 0x008, 0x00b, 0x00e, 0x011, 0x014, + 0x016, 0x019, 0x01c, 0x01f, 0x022, 0x025, 0x028, 0x02a, + 0x02d, 0x030, 0x033, 0x036, 0x039, 0x03c, 0x03f, 0x042, + 0x045, 0x048, 0x04b, 0x04e, 0x051, 0x054, 0x057, 0x05a, + 0x05d, 0x060, 0x063, 0x066, 0x069, 0x06c, 0x06f, 0x072, + 0x075, 0x078, 0x07b, 0x07e, 0x082, 0x085, 0x088, 0x08b, + 0x08e, 0x091, 0x094, 0x098, 0x09b, 0x09e, 0x0a1, 0x0a4, + 0x0a8, 0x0ab, 0x0ae, 0x0b1, 0x0b5, 0x0b8, 0x0bb, 0x0be, + 0x0c2, 0x0c5, 0x0c8, 0x0cc, 0x0cf, 0x0d2, 0x0d6, 0x0d9, + 0x0dc, 0x0e0, 0x0e3, 0x0e7, 0x0ea, 0x0ed, 0x0f1, 0x0f4, + 0x0f8, 0x0fb, 0x0ff, 0x102, 0x106, 0x109, 0x10c, 0x110, + 0x114, 0x117, 0x11b, 0x11e, 0x122, 0x125, 0x129, 0x12c, + 0x130, 0x134, 0x137, 0x13b, 0x13e, 0x142, 0x146, 0x149, + 0x14d, 0x151, 0x154, 0x158, 0x15c, 0x160, 0x163, 0x167, + 0x16b, 0x16f, 0x172, 0x176, 0x17a, 0x17e, 0x181, 0x185, + 0x189, 0x18d, 0x191, 0x195, 0x199, 0x19c, 0x1a0, 0x1a4, + 0x1a8, 0x1ac, 0x1b0, 0x1b4, 0x1b8, 0x1bc, 0x1c0, 0x1c4, + 0x1c8, 0x1cc, 0x1d0, 0x1d4, 0x1d8, 0x1dc, 0x1e0, 0x1e4, + 0x1e8, 0x1ec, 0x1f0, 0x1f5, 0x1f9, 0x1fd, 0x201, 0x205, + 0x209, 0x20e, 0x212, 0x216, 0x21a, 0x21e, 0x223, 0x227, + 0x22b, 0x230, 0x234, 0x238, 0x23c, 0x241, 0x245, 0x249, + 0x24e, 0x252, 0x257, 0x25b, 0x25f, 0x264, 0x268, 0x26d, + 0x271, 0x276, 0x27a, 0x27f, 0x283, 0x288, 0x28c, 0x291, + 0x295, 0x29a, 0x29e, 0x2a3, 0x2a8, 0x2ac, 0x2b1, 0x2b5, + 0x2ba, 0x2bf, 0x2c4, 0x2c8, 0x2cd, 0x2d2, 0x2d6, 0x2db, + 0x2e0, 0x2e5, 0x2e9, 0x2ee, 0x2f3, 0x2f8, 0x2fd, 0x302, + 0x306, 0x30b, 0x310, 0x315, 0x31a, 0x31f, 0x324, 0x329, + 0x32e, 0x333, 0x338, 0x33d, 0x342, 0x347, 0x34c, 0x351, + 0x356, 0x35b, 0x360, 0x365, 0x36a, 0x370, 0x375, 0x37a, + 0x37f, 0x384, 0x38a, 0x38f, 0x394, 0x399, 0x39f, 0x3a4, + 0x3a9, 0x3ae, 0x3b4, 0x3b9, 0x3bf, 0x3c4, 0x3c9, 0x3cf, + 0x3d4, 0x3da, 0x3df, 0x3e4, 0x3ea, 0x3ef, 0x3f5, 0x3fa }; // @@ -130,191 +162,248 @@ static const Bit16u exprom[256] = { // 1/2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 12, 12, 15, 15 // -static const Bit8u mt[16] = { 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30 }; +static const Bit8u mt[16] = { + 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30 +}; // // ksl table // -static const Bit8u kslrom[16] = { 0, 32, 40, 45, 48, 51, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64 }; +static const Bit8u kslrom[16] = { + 0, 32, 40, 45, 48, 51, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64 +}; -static const Bit8u kslshift[4] = { 8, 1, 2, 0 }; +static const Bit8u kslshift[4] = { + 8, 1, 2, 0 +}; // // envelope generator constants // static const Bit8u eg_incstep[3][4][8] = { - { { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 } }, - { { 0, 1, 0, 1, 0, 1, 0, 1 }, { 0, 1, 0, 1, 1, 1, 0, 1 }, { 0, 1, 1, 1, 0, 1, 1, 1 }, { 0, 1, 1, 1, 1, 1, 1, 1 } }, - { { 1, 1, 1, 1, 1, 1, 1, 1 }, { 2, 2, 1, 1, 1, 1, 1, 1 }, { 2, 2, 1, 1, 2, 2, 1, 1 }, { 2, 2, 2, 2, 2, 2, 1, 1 } } + { + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } + }, + { + { 0, 1, 0, 1, 0, 1, 0, 1 }, + { 0, 1, 0, 1, 1, 1, 0, 1 }, + { 0, 1, 1, 1, 0, 1, 1, 1 }, + { 0, 1, 1, 1, 1, 1, 1, 1 } + }, + { + { 1, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 1, 1, 2, 2, 1, 1 }, + { 2, 2, 2, 2, 2, 2, 1, 1 } + } }; static const Bit8u eg_incdesc[16] = { - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2 + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2 }; static const Bit8s eg_incsh[16] = { - 0, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, -1, -2 + 0, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, -1, -2 }; // // address decoding // -static const Bit8s ad_slot[0x20] = { 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, -1, -1, 12, 13, 14, 15, 16, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; -static const Bit8u ch_slot[18] = { 0, 1, 2, 6, 7, 8, 12, 13, 14, 18, 19, 20, 24, 25, 26, 30, 31, 32 }; +static const Bit8s ad_slot[0x20] = { + 0, 1, 2, 3, 4, 5, -1, -1, 6, 7, 8, 9, 10, 11, -1, -1, + 12, 13, 14, 15, 16, 17, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 +}; + +static const Bit8u ch_slot[18] = { + 0, 1, 2, 6, 7, 8, 12, 13, 14, 18, 19, 20, 24, 25, 26, 30, 31, 32 +}; // // Envelope generator // typedef Bit16s(*envelope_sinfunc)(Bit16u phase, Bit16u envelope); -typedef void(*envelope_genfunc)(opl_slot *slott); +typedef void(*envelope_genfunc)(opl3_slot *slott); -Bit16s envelope_calcexp(Bit32u level) { - if (level > 0x1fff) { +static Bit16s OPL3_EnvelopeCalcExp(Bit32u level) +{ + if (level > 0x1fff) + { level = 0x1fff; } return ((exprom[(level & 0xff) ^ 0xff] | 0x400) << 1) >> (level >> 8); } -Bit16s envelope_calcsin0(Bit16u phase, Bit16u envelope) { +static Bit16s OPL3_EnvelopeCalcSin0(Bit16u phase, Bit16u envelope) +{ Bit16u out = 0; Bit16u neg = 0; phase &= 0x3ff; - if (phase & 0x200) { + if (phase & 0x200) + { neg = ~0; } - if (phase & 0x100) { + if (phase & 0x100) + { out = logsinrom[(phase & 0xff) ^ 0xff]; } - else { + else + { out = logsinrom[phase & 0xff]; } - return envelope_calcexp(out + (envelope << 3)) ^ neg; + return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; } -Bit16s envelope_calcsin1(Bit16u phase, Bit16u envelope) { +static Bit16s OPL3_EnvelopeCalcSin1(Bit16u phase, Bit16u envelope) +{ Bit16u out = 0; phase &= 0x3ff; - if (phase & 0x200) { + if (phase & 0x200) + { out = 0x1000; } - else if (phase & 0x100) { + else if (phase & 0x100) + { out = logsinrom[(phase & 0xff) ^ 0xff]; } - else { + else + { out = logsinrom[phase & 0xff]; } - return envelope_calcexp(out + (envelope << 3)); + return OPL3_EnvelopeCalcExp(out + (envelope << 3)); } -Bit16s envelope_calcsin2(Bit16u phase, Bit16u envelope) { +static Bit16s OPL3_EnvelopeCalcSin2(Bit16u phase, Bit16u envelope) +{ Bit16u out = 0; phase &= 0x3ff; - if (phase & 0x100) { + if (phase & 0x100) + { out = logsinrom[(phase & 0xff) ^ 0xff]; } - else { + else + { out = logsinrom[phase & 0xff]; } - return envelope_calcexp(out + (envelope << 3)); + return OPL3_EnvelopeCalcExp(out + (envelope << 3)); } -Bit16s envelope_calcsin3(Bit16u phase, Bit16u envelope) { +static Bit16s OPL3_EnvelopeCalcSin3(Bit16u phase, Bit16u envelope) +{ Bit16u out = 0; phase &= 0x3ff; - if (phase & 0x100) { + if (phase & 0x100) + { out = 0x1000; } - else { + else + { out = logsinrom[phase & 0xff]; } - return envelope_calcexp(out + (envelope << 3)); + return OPL3_EnvelopeCalcExp(out + (envelope << 3)); } -Bit16s envelope_calcsin4(Bit16u phase, Bit16u envelope) { +static Bit16s OPL3_EnvelopeCalcSin4(Bit16u phase, Bit16u envelope) +{ Bit16u out = 0; Bit16u neg = 0; phase &= 0x3ff; - if ((phase & 0x300) == 0x100) { + if ((phase & 0x300) == 0x100) + { neg = ~0; } - if (phase & 0x200) { + if (phase & 0x200) + { out = 0x1000; } - else if (phase & 0x80) { + else if (phase & 0x80) + { out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; } - else { + else + { out = logsinrom[(phase << 1) & 0xff]; } - return envelope_calcexp(out + (envelope << 3)) ^ neg; + return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; } -Bit16s envelope_calcsin5(Bit16u phase, Bit16u envelope) { +static Bit16s OPL3_EnvelopeCalcSin5(Bit16u phase, Bit16u envelope) +{ Bit16u out = 0; phase &= 0x3ff; - if (phase & 0x200) { + if (phase & 0x200) + { out = 0x1000; } - else if (phase & 0x80) { + else if (phase & 0x80) + { out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; } - else { + else + { out = logsinrom[(phase << 1) & 0xff]; } - return envelope_calcexp(out + (envelope << 3)); + return OPL3_EnvelopeCalcExp(out + (envelope << 3)); } -Bit16s envelope_calcsin6(Bit16u phase, Bit16u envelope) { +static Bit16s OPL3_EnvelopeCalcSin6(Bit16u phase, Bit16u envelope) +{ Bit16u neg = 0; phase &= 0x3ff; - if (phase & 0x200) { + if (phase & 0x200) + { neg = ~0; } - return envelope_calcexp(envelope << 3) ^ neg; + return OPL3_EnvelopeCalcExp(envelope << 3) ^ neg; } -Bit16s envelope_calcsin7(Bit16u phase, Bit16u envelope) { +static Bit16s OPL3_EnvelopeCalcSin7(Bit16u phase, Bit16u envelope) +{ Bit16u out = 0; Bit16u neg = 0; phase &= 0x3ff; - if (phase & 0x200) { + if (phase & 0x200) + { neg = ~0; phase = (phase & 0x1ff) ^ 0x1ff; } out = phase << 3; - return envelope_calcexp(out + (envelope << 3)) ^ neg; + return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; } -envelope_sinfunc envelope_sin[8] = { - envelope_calcsin0, - envelope_calcsin1, - envelope_calcsin2, - envelope_calcsin3, - envelope_calcsin4, - envelope_calcsin5, - envelope_calcsin6, - envelope_calcsin7 +static const envelope_sinfunc envelope_sin[8] = { + OPL3_EnvelopeCalcSin0, + OPL3_EnvelopeCalcSin1, + OPL3_EnvelopeCalcSin2, + OPL3_EnvelopeCalcSin3, + OPL3_EnvelopeCalcSin4, + OPL3_EnvelopeCalcSin5, + OPL3_EnvelopeCalcSin6, + OPL3_EnvelopeCalcSin7 }; -void envelope_gen_off(opl_slot *slott); -void envelope_gen_attack(opl_slot *slott); -void envelope_gen_decay(opl_slot *slott); -void envelope_gen_sustain(opl_slot *slott); -void envelope_gen_release(opl_slot *slott); +void OPL3_EnvelopeGenOff(opl3_slot *slot); +void OPL3_EnvelopeGenAttack(opl3_slot *slot); +void OPL3_EnvelopeGenDecay(opl3_slot *slot); +void OPL3_EnvelopeGenSustain(opl3_slot *slot); +void OPL3_EnvelopeGenRelease(opl3_slot *slot); envelope_genfunc envelope_gen[5] = { - envelope_gen_off, - envelope_gen_attack, - envelope_gen_decay, - envelope_gen_sustain, - envelope_gen_release + OPL3_EnvelopeGenOff, + OPL3_EnvelopeGenAttack, + OPL3_EnvelopeGenDecay, + OPL3_EnvelopeGenSustain, + OPL3_EnvelopeGenRelease }; -enum envelope_gen_num { +enum envelope_gen_num +{ envelope_gen_num_off = 0, envelope_gen_num_attack = 1, envelope_gen_num_decay = 2, @@ -322,123 +411,156 @@ enum envelope_gen_num { envelope_gen_num_release = 4 }; -Bit8u envelope_calc_rate(opl_slot *slot, Bit8u reg_rate) { +static Bit8u OPL3_EnvelopeCalcRate(opl3_slot *slot, Bit8u reg_rate) +{ Bit8u rate; - if (reg_rate == 0x00) { + if (reg_rate == 0x00) + { return 0x00; } - rate = (reg_rate << 2) + (slot->reg_ksr ? slot->channel->ksv : (slot->channel->ksv >> 2)); - if (rate > 0x3c) { + rate = (reg_rate << 2) + + (slot->reg_ksr ? slot->channel->ksv : (slot->channel->ksv >> 2)); + if (rate > 0x3c) + { rate = 0x3c; } return rate; } -void envelope_update_ksl(opl_slot *slot) { - Bit16s ksl = (kslrom[slot->channel->f_num >> 6] << 2) - ((0x08 - slot->channel->block) << 5); - if (ksl < 0) { +static void OPL3_EnvelopeUpdateKSL(opl3_slot *slot) +{ + Bit16s ksl = (kslrom[slot->channel->f_num >> 6] << 2) + - ((0x08 - slot->channel->block) << 5); + if (ksl < 0) + { ksl = 0; } slot->eg_ksl = (Bit8u)ksl; } -void envelope_update_rate(opl_slot *slot) { - switch (slot->eg_gen) { +static void OPL3_EnvelopeUpdateRate(opl3_slot *slot) +{ + switch (slot->eg_gen) + { case envelope_gen_num_off: - slot->eg_rate = 0; - break; case envelope_gen_num_attack: - slot->eg_rate = envelope_calc_rate(slot, slot->reg_ar); + slot->eg_rate = OPL3_EnvelopeCalcRate(slot, slot->reg_ar); break; case envelope_gen_num_decay: - slot->eg_rate = envelope_calc_rate(slot, slot->reg_dr); + slot->eg_rate = OPL3_EnvelopeCalcRate(slot, slot->reg_dr); break; case envelope_gen_num_sustain: case envelope_gen_num_release: - slot->eg_rate = envelope_calc_rate(slot, slot->reg_rr); + slot->eg_rate = OPL3_EnvelopeCalcRate(slot, slot->reg_rr); break; } } -void envelope_gen_off(opl_slot *slot) { +static void OPL3_EnvelopeGenOff(opl3_slot *slot) +{ slot->eg_rout = 0x1ff; } -void envelope_gen_attack(opl_slot *slot) { - if (slot->eg_rout == 0x00) { +static void OPL3_EnvelopeGenAttack(opl3_slot *slot) +{ + if (slot->eg_rout == 0x00) + { slot->eg_gen = envelope_gen_num_decay; - envelope_update_rate(slot); + OPL3_EnvelopeUpdateRate(slot); return; } slot->eg_rout += ((~slot->eg_rout) * slot->eg_inc) >> 3; - if (slot->eg_rout < 0x00) { + if (slot->eg_rout < 0x00) + { slot->eg_rout = 0x00; } } -void envelope_gen_decay(opl_slot *slot) { - if (slot->eg_rout >= slot->reg_sl << 4) { +static void OPL3_EnvelopeGenDecay(opl3_slot *slot) +{ + if (slot->eg_rout >= slot->reg_sl << 4) + { slot->eg_gen = envelope_gen_num_sustain; - envelope_update_rate(slot); + OPL3_EnvelopeUpdateRate(slot); return; } slot->eg_rout += slot->eg_inc; } -void envelope_gen_sustain(opl_slot *slot) { - if (!slot->reg_type) { - envelope_gen_release(slot); +static void OPL3_EnvelopeGenSustain(opl3_slot *slot) +{ + if (!slot->reg_type) + { + OPL3_EnvelopeGenRelease(slot); } } -void envelope_gen_release(opl_slot *slot) { - if (slot->eg_rout >= 0x1ff) { +static void OPL3_EnvelopeGenRelease(opl3_slot *slot) +{ + if (slot->eg_rout >= 0x1ff) + { slot->eg_gen = envelope_gen_num_off; slot->eg_rout = 0x1ff; - envelope_update_rate(slot); + OPL3_EnvelopeUpdateRate(slot); return; } slot->eg_rout += slot->eg_inc; } -void envelope_calc(opl_slot *slot) { +static void OPL3_EnvelopeCalc(opl3_slot *slot) +{ Bit8u rate_h, rate_l; Bit8u inc = 0; rate_h = slot->eg_rate >> 2; rate_l = slot->eg_rate & 3; - if (eg_incsh[rate_h] > 0) { - if ((slot->chip->timer & ((1 << eg_incsh[rate_h]) - 1)) == 0) { - inc = eg_incstep[eg_incdesc[rate_h]][rate_l][((slot->chip->timer) >> eg_incsh[rate_h]) & 0x07]; + if (eg_incsh[rate_h] > 0) + { + if ((slot->chip->timer & ((1 << eg_incsh[rate_h]) - 1)) == 0) + { + inc = eg_incstep[eg_incdesc[rate_h]][rate_l] + [((slot->chip->timer)>> eg_incsh[rate_h]) & 0x07]; } } - else { - inc = eg_incstep[eg_incdesc[rate_h]][rate_l][slot->chip->timer & 0x07] << (-eg_incsh[rate_h]); + else + { + inc = eg_incstep[eg_incdesc[rate_h]][rate_l] + [slot->chip->timer & 0x07] << (-eg_incsh[rate_h]); } slot->eg_inc = inc; - slot->eg_out = slot->eg_rout + (slot->reg_tl << 2) + (slot->eg_ksl >> kslshift[slot->reg_ksl]) + *slot->trem; + slot->eg_out = slot->eg_rout + (slot->reg_tl << 2) + + (slot->eg_ksl >> kslshift[slot->reg_ksl]) + *slot->trem; envelope_gen[slot->eg_gen](slot); } -void eg_keyon(opl_slot *slot, Bit8u type) { - if (!slot->key) { +static void OPL3_EnvelopeKeyOn(opl3_slot *slot, Bit8u type) +{ + if (!slot->key) + { slot->eg_gen = envelope_gen_num_attack; - envelope_update_rate(slot); - if ((slot->eg_rate >> 2) == 0x0f) { + if ((slot->eg_rate >> 2) != 0x0f) + { + slot->eg_gen = envelope_gen_num_attack; + } + else + { slot->eg_gen = envelope_gen_num_decay; - envelope_update_rate(slot); slot->eg_rout = 0x00; } + OPL3_EnvelopeUpdateRate(slot); slot->pg_phase = 0x00; } slot->key |= type; } -void eg_keyoff(opl_slot *slot, Bit8u type) { - if (slot->key) { +static void OPL3_EnvelopeKeyOff(opl3_slot *slot, Bit8u type) +{ + if (slot->key) + { slot->key &= (~type); - if (!slot->key) { + if (!slot->key) + { slot->eg_gen = envelope_gen_num_release; - envelope_update_rate(slot); + OPL3_EnvelopeUpdateRate(slot); } } } @@ -447,27 +569,32 @@ void eg_keyoff(opl_slot *slot, Bit8u type) { // Phase Generator // -void pg_generate(opl_slot *slot) { +static void OPL3_PhaseGenerate(opl3_slot *slot) +{ Bit16u f_num; Bit32u basefreq; f_num = slot->channel->f_num; - if (slot->reg_vib) { + if (slot->reg_vib) + { Bit8s range; Bit8u vibpos; range = (f_num >> 7) & 7; vibpos = slot->chip->vibpos; - if (!(vibpos & 3)) { + if (!(vibpos & 3)) + { range = 0; } - else if (vibpos & 1) { + else if (vibpos & 1) + { range >>= 1; } range >>= slot->chip->vibshift; - if (vibpos & 4) { + if (vibpos & 4) + { range = -range; } f_num += range; @@ -480,8 +607,10 @@ void pg_generate(opl_slot *slot) { // Noise Generator // -void n_generate(opl_chip *chip) { - if (chip->noise & 0x01) { +static void OPL3_NoiseGenerate(opl3_chip *chip) +{ + if (chip->noise & 0x01) + { chip->noise ^= 0x800302; } chip->noise >>= 1; @@ -491,65 +620,80 @@ void n_generate(opl_chip *chip) { // Slot // -void slot_write20(opl_slot *slot, Bit8u data) { - if ((data >> 7) & 0x01) { +static void OPL3_SlotWrite20(opl3_slot *slot, Bit8u data) +{ + if ((data >> 7) & 0x01) + { slot->trem = &slot->chip->tremolo; } - else { + else + { slot->trem = (Bit8u*)&slot->chip->zeromod; } slot->reg_vib = (data >> 6) & 0x01; slot->reg_type = (data >> 5) & 0x01; slot->reg_ksr = (data >> 4) & 0x01; slot->reg_mult = data & 0x0f; - envelope_update_rate(slot); + OPL3_EnvelopeUpdateRate(slot); } -void slot_write40(opl_slot *slot, Bit8u data) { +static void OPL3_SlotWrite40(opl3_slot *slot, Bit8u data) +{ slot->reg_ksl = (data >> 6) & 0x03; slot->reg_tl = data & 0x3f; - envelope_update_ksl(slot); + OPL3_EnvelopeUpdateKSL(slot); } -void slot_write60(opl_slot *slot, Bit8u data) { +static void OPL3_SlotWrite60(opl3_slot *slot, Bit8u data) +{ slot->reg_ar = (data >> 4) & 0x0f; slot->reg_dr = data & 0x0f; - envelope_update_rate(slot); + OPL3_EnvelopeUpdateRate(slot); } -void slot_write80(opl_slot *slot, Bit8u data) { +static void OPL3_SlotWrite80(opl3_slot *slot, Bit8u data) +{ slot->reg_sl = (data >> 4) & 0x0f; - if (slot->reg_sl == 0x0f) { + if (slot->reg_sl == 0x0f) + { slot->reg_sl = 0x1f; } slot->reg_rr = data & 0x0f; - envelope_update_rate(slot); + OPL3_EnvelopeUpdateRate(slot); } -void slot_writee0(opl_slot *slot, Bit8u data) { +static void OPL3_SlotWriteE0(opl3_slot *slot, Bit8u data) +{ slot->reg_wf = data & 0x07; - if (slot->chip->newm == 0x00) { + if (slot->chip->newm == 0x00) + { slot->reg_wf &= 0x03; } } -void slot_generatephase(opl_slot *slot, Bit16u phase) { +static void OPL3_SlotGeneratePhase(opl3_slot *slot, Bit16u phase) +{ slot->out = envelope_sin[slot->reg_wf](phase, slot->eg_out); } -void slot_generate(opl_slot *slot) { - slot_generatephase(slot, (Bit16u)(slot->pg_phase >> 9) + *slot->mod); +static void OPL3_SlotGenerate(opl3_slot *slot) +{ + OPL3_SlotGeneratePhase(slot, (Bit16u)(slot->pg_phase >> 9) + *slot->mod); } -void slot_generatezm(opl_slot *slot) { - slot_generatephase(slot, 0); +static void OPL3_SlotGenerateZM(opl3_slot *slot) +{ + OPL3_SlotGeneratePhase(slot, 0); } -void slot_calcfb(opl_slot *slot) { - if (slot->channel->fb != 0x00) { +static void OPL3_SlotCalcFB(opl3_slot *slot) +{ + if (slot->channel->fb != 0x00) + { slot->fbmod = (slot->prout + slot->out) >> (0x09 - slot->channel->fb); } - else { + else + { slot->fbmod = 0; } slot->prout = slot->out; @@ -559,16 +703,18 @@ void slot_calcfb(opl_slot *slot) { // Channel // -void chan_setupalg(opl_channel *channel); +void OPL3_ChannelSetupAlg(opl3_channel *channel); -void chan_updaterhythm(opl_chip *chip, Bit8u data) { - opl_channel *channel6; - opl_channel *channel7; - opl_channel *channel8; +static void OPL3_ChannelUpdateRhythm(opl3_chip *chip, Bit8u data) +{ + opl3_channel *channel6; + opl3_channel *channel7; + opl3_channel *channel8; Bit8u chnum; chip->rhy = data & 0x3f; - if (chip->rhy & 0x20) { + if (chip->rhy & 0x20) + { channel6 = &chip->channel[6]; channel7 = &chip->channel[7]; channel8 = &chip->channel[8]; @@ -584,101 +730,125 @@ void chan_updaterhythm(opl_chip *chip, Bit8u data) { channel8->out[1] = &channel8->slots[0]->out; channel8->out[2] = &channel8->slots[1]->out; channel8->out[3] = &channel8->slots[1]->out; - for (chnum = 6; chnum < 9; chnum++) { + for (chnum = 6; chnum < 9; chnum++) + { chip->channel[chnum].chtype = ch_drum; } - chan_setupalg(channel6); + OPL3_ChannelSetupAlg(channel6); //hh - if (chip->rhy & 0x01) { - eg_keyon(channel7->slots[0], egk_drum); + if (chip->rhy & 0x01) + { + OPL3_EnvelopeKeyOn(channel7->slots[0], egk_drum); } - else { - eg_keyoff(channel7->slots[0], egk_drum); + else + { + OPL3_EnvelopeKeyOff(channel7->slots[0], egk_drum); } //tc - if (chip->rhy & 0x02) { - eg_keyon(channel8->slots[1], egk_drum); + if (chip->rhy & 0x02) + { + OPL3_EnvelopeKeyOn(channel8->slots[1], egk_drum); } - else { - eg_keyoff(channel8->slots[1], egk_drum); + else + { + OPL3_EnvelopeKeyOff(channel8->slots[1], egk_drum); } //tom - if (chip->rhy & 0x04) { - eg_keyon(channel8->slots[0], egk_drum); + if (chip->rhy & 0x04) + { + OPL3_EnvelopeKeyOn(channel8->slots[0], egk_drum); } - else { - eg_keyoff(channel8->slots[0], egk_drum); + else + { + OPL3_EnvelopeKeyOff(channel8->slots[0], egk_drum); } //sd - if (chip->rhy & 0x08) { - eg_keyon(channel7->slots[1], egk_drum); + if (chip->rhy & 0x08) + { + OPL3_EnvelopeKeyOn(channel7->slots[1], egk_drum); } - else { - eg_keyoff(channel7->slots[1], egk_drum); + else + { + OPL3_EnvelopeKeyOff(channel7->slots[1], egk_drum); } //bd - if (chip->rhy & 0x10) { - eg_keyon(channel6->slots[0], egk_drum); - eg_keyon(channel6->slots[1], egk_drum); + if (chip->rhy & 0x10) + { + OPL3_EnvelopeKeyOn(channel6->slots[0], egk_drum); + OPL3_EnvelopeKeyOn(channel6->slots[1], egk_drum); } - else { - eg_keyoff(channel6->slots[0], egk_drum); - eg_keyoff(channel6->slots[1], egk_drum); + else + { + OPL3_EnvelopeKeyOff(channel6->slots[0], egk_drum); + OPL3_EnvelopeKeyOff(channel6->slots[1], egk_drum); } } - else { - for (chnum = 6; chnum < 9; chnum++) { + else + { + for (chnum = 6; chnum < 9; chnum++) + { chip->channel[chnum].chtype = ch_2op; - chan_setupalg(&chip->channel[chnum]); + OPL3_ChannelSetupAlg(&chip->channel[chnum]); } } } -void chan_writea0(opl_channel *channel, Bit8u data) { - if (channel->chip->newm && channel->chtype == ch_4op2) { +static void OPL3_ChannelWriteA0(opl3_channel *channel, Bit8u data) +{ + if (channel->chip->newm && channel->chtype == ch_4op2) + { return; } channel->f_num = (channel->f_num & 0x300) | data; - channel->ksv = (channel->block << 1) | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); - envelope_update_ksl(channel->slots[0]); - envelope_update_ksl(channel->slots[1]); - envelope_update_rate(channel->slots[0]); - envelope_update_rate(channel->slots[1]); - if (channel->chip->newm && channel->chtype == ch_4op) { + channel->ksv = (channel->block << 1) + | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); + OPL3_EnvelopeUpdateKSL(channel->slots[0]); + OPL3_EnvelopeUpdateKSL(channel->slots[1]); + OPL3_EnvelopeUpdateRate(channel->slots[0]); + OPL3_EnvelopeUpdateRate(channel->slots[1]); + if (channel->chip->newm && channel->chtype == ch_4op) + { channel->pair->f_num = channel->f_num; channel->pair->ksv = channel->ksv; - envelope_update_ksl(channel->pair->slots[0]); - envelope_update_ksl(channel->pair->slots[1]); - envelope_update_rate(channel->pair->slots[0]); - envelope_update_rate(channel->pair->slots[1]); + OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]); + OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]); + OPL3_EnvelopeUpdateRate(channel->pair->slots[0]); + OPL3_EnvelopeUpdateRate(channel->pair->slots[1]); } } -void chan_writeb0(opl_channel *channel, Bit8u data) { - if (channel->chip->newm && channel->chtype == ch_4op2) { +static void OPL3_ChannelWriteB0(opl3_channel *channel, Bit8u data) +{ + if (channel->chip->newm && channel->chtype == ch_4op2) + { return; } channel->f_num = (channel->f_num & 0xff) | ((data & 0x03) << 8); channel->block = (data >> 2) & 0x07; - channel->ksv = (channel->block << 1) | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); - envelope_update_ksl(channel->slots[0]); - envelope_update_ksl(channel->slots[1]); - envelope_update_rate(channel->slots[0]); - envelope_update_rate(channel->slots[1]); - if (channel->chip->newm && channel->chtype == ch_4op) { + channel->ksv = (channel->block << 1) + | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); + OPL3_EnvelopeUpdateKSL(channel->slots[0]); + OPL3_EnvelopeUpdateKSL(channel->slots[1]); + OPL3_EnvelopeUpdateRate(channel->slots[0]); + OPL3_EnvelopeUpdateRate(channel->slots[1]); + if (channel->chip->newm && channel->chtype == ch_4op) + { channel->pair->f_num = channel->f_num; channel->pair->block = channel->block; channel->pair->ksv = channel->ksv; - envelope_update_ksl(channel->pair->slots[0]); - envelope_update_ksl(channel->pair->slots[1]); - envelope_update_rate(channel->pair->slots[0]); - envelope_update_rate(channel->pair->slots[1]); + OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]); + OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]); + OPL3_EnvelopeUpdateRate(channel->pair->slots[0]); + OPL3_EnvelopeUpdateRate(channel->pair->slots[1]); } } -void chan_setupalg(opl_channel *channel) { - if (channel->chtype == ch_drum) { - switch (channel->alg & 0x01) { +static void OPL3_ChannelSetupAlg(opl3_channel *channel) +{ + if (channel->chtype == ch_drum) + { + switch (channel->alg & 0x01) + { case 0x00: channel->slots[0]->mod = &channel->slots[0]->fbmod; channel->slots[1]->mod = &channel->slots[0]->out; @@ -690,15 +860,18 @@ void chan_setupalg(opl_channel *channel) { } return; } - if (channel->alg & 0x08) { + if (channel->alg & 0x08) + { return; } - if (channel->alg & 0x04) { + if (channel->alg & 0x04) + { channel->pair->out[0] = &channel->chip->zeromod; channel->pair->out[1] = &channel->chip->zeromod; channel->pair->out[2] = &channel->chip->zeromod; channel->pair->out[3] = &channel->chip->zeromod; - switch (channel->alg & 0x03) { + switch (channel->alg & 0x03) + { case 0x00: channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; channel->pair->slots[1]->mod = &channel->pair->slots[0]->out; @@ -741,8 +914,10 @@ void chan_setupalg(opl_channel *channel) { break; } } - else { - switch (channel->alg & 0x01) { + else + { + switch (channel->alg & 0x01) + { case 0x00: channel->slots[0]->mod = &channel->slots[0]->fbmod; channel->slots[1]->mod = &channel->slots[0]->out; @@ -763,270 +938,334 @@ void chan_setupalg(opl_channel *channel) { } } -void chan_writec0(opl_channel *channel, Bit8u data) { +static void OPL3_ChannelWriteC0(opl3_channel *channel, Bit8u data) +{ channel->fb = (data & 0x0e) >> 1; channel->con = data & 0x01; channel->alg = channel->con; - if (channel->chip->newm) { - if (channel->chtype == ch_4op) { + if (channel->chip->newm) + { + if (channel->chtype == ch_4op) + { channel->pair->alg = 0x04 | (channel->con << 1) | (channel->pair->con); channel->alg = 0x08; - chan_setupalg(channel->pair); + OPL3_ChannelSetupAlg(channel->pair); } - else if (channel->chtype == ch_4op2) { + else if (channel->chtype == ch_4op2) + { channel->alg = 0x04 | (channel->pair->con << 1) | (channel->con); channel->pair->alg = 0x08; - chan_setupalg(channel); + OPL3_ChannelSetupAlg(channel); } - else { - chan_setupalg(channel); + else + { + OPL3_ChannelSetupAlg(channel); } } - else { - chan_setupalg(channel); + else + { + OPL3_ChannelSetupAlg(channel); } - if (channel->chip->newm) { + if (channel->chip->newm) + { channel->cha = ((data >> 4) & 0x01) ? ~0 : 0; channel->chb = ((data >> 5) & 0x01) ? ~0 : 0; } - else { + else + { channel->cha = channel->chb = ~0; } } -void chan_generaterhythm1(opl_chip *chip) { - opl_channel *channel6; - opl_channel *channel7; - opl_channel *channel8; - Bit16u phase14; - Bit16u phase17; - Bit16u phase; - Bit16u phasebit; - - channel6 = &chip->channel[6]; - channel7 = &chip->channel[7]; - channel8 = &chip->channel[8]; - slot_generate(channel6->slots[0]); - phase14 = (channel7->slots[0]->pg_phase >> 9) & 0x3ff; - phase17 = (channel8->slots[1]->pg_phase >> 9) & 0x3ff; - phase = 0x00; - //hh tc phase bit - phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04) | (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00; - //hh - phase = (phasebit << 9) | (0x34 << ((phasebit ^ (chip->noise & 0x01) << 1))); - slot_generatephase(channel7->slots[0], phase); - //tt - slot_generatezm(channel8->slots[0]); -} - -void chan_generaterhythm2(opl_chip *chip) { - opl_channel *channel6; - opl_channel *channel7; - opl_channel *channel8; - Bit16u phase14; - Bit16u phase17; - Bit16u phase; - Bit16u phasebit; - - channel6 = &chip->channel[6]; - channel7 = &chip->channel[7]; - channel8 = &chip->channel[8]; - slot_generate(channel6->slots[1]); - phase14 = (channel7->slots[0]->pg_phase >> 9) & 0x3ff; - phase17 = (channel8->slots[1]->pg_phase >> 9) & 0x3ff; - phase = 0x00; - //hh tc phase bit - phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04) | (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00; - //sd - phase = (0x100 << ((phase14 >> 8) & 0x01)) ^ ((chip->noise & 0x01) << 8); - slot_generatephase(channel7->slots[1], phase); - //tc - phase = 0x100 | (phasebit << 9); - slot_generatephase(channel8->slots[1], phase); -} - -void chan_enable(opl_channel *channel) { - if (channel->chip->newm) { - if (channel->chtype == ch_4op) { - eg_keyon(channel->slots[0], egk_norm); - eg_keyon(channel->slots[1], egk_norm); - eg_keyon(channel->pair->slots[0], egk_norm); - eg_keyon(channel->pair->slots[1], egk_norm); +static void OPL3_ChannelKeyOn(opl3_channel *channel) +{ + if (channel->chip->newm) + { + if (channel->chtype == ch_4op) + { + OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); + OPL3_EnvelopeKeyOn(channel->pair->slots[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->pair->slots[1], egk_norm); } - else if (channel->chtype == ch_2op || channel->chtype == ch_drum) { - eg_keyon(channel->slots[0], egk_norm); - eg_keyon(channel->slots[1], egk_norm); + else if (channel->chtype == ch_2op || channel->chtype == ch_drum) + { + OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); } } - else { - eg_keyon(channel->slots[0], egk_norm); - eg_keyon(channel->slots[1], egk_norm); + else + { + OPL3_EnvelopeKeyOn(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOn(channel->slots[1], egk_norm); } } -void chan_disable(opl_channel *channel) { - if (channel->chip->newm) { - if (channel->chtype == ch_4op) { - eg_keyoff(channel->slots[0], egk_norm); - eg_keyoff(channel->slots[1], egk_norm); - eg_keyoff(channel->pair->slots[0], egk_norm); - eg_keyoff(channel->pair->slots[1], egk_norm); +static void OPL3_ChannelKeyOff(opl3_channel *channel) +{ + if (channel->chip->newm) + { + if (channel->chtype == ch_4op) + { + OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); + OPL3_EnvelopeKeyOff(channel->pair->slots[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->pair->slots[1], egk_norm); } - else if (channel->chtype == ch_2op || channel->chtype == ch_drum) { - eg_keyoff(channel->slots[0], egk_norm); - eg_keyoff(channel->slots[1], egk_norm); + else if (channel->chtype == ch_2op || channel->chtype == ch_drum) + { + OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); } } - else { - eg_keyoff(channel->slots[0], egk_norm); - eg_keyoff(channel->slots[1], egk_norm); + else + { + OPL3_EnvelopeKeyOff(channel->slots[0], egk_norm); + OPL3_EnvelopeKeyOff(channel->slots[1], egk_norm); } } -void chan_set4op(opl_chip *chip, Bit8u data) { +static void OPL3_ChannelSet4Op(opl3_chip *chip, Bit8u data) +{ Bit8u bit; Bit8u chnum; - for (bit = 0; bit < 6; bit++) { + for (bit = 0; bit < 6; bit++) + { chnum = bit; - if (bit >= 3) { + if (bit >= 3) + { chnum += 9 - 3; } - if ((data >> bit) & 0x01) { + if ((data >> bit) & 0x01) + { chip->channel[chnum].chtype = ch_4op; chip->channel[chnum + 3].chtype = ch_4op2; } - else { + else + { chip->channel[chnum].chtype = ch_2op; chip->channel[chnum + 3].chtype = ch_2op; } } } -Bit16s limshort(Bit32s a) { - if (a > 32767) { - a = 32767; +static Bit16s OPL3_ClipSample(Bit32s sample) +{ + if (sample > 32767) + { + sample = 32767; } - else if (a < -32768) { - a = -32768; + else if (sample < -32768) + { + sample = -32768; } - return (Bit16s)a; + return (Bit16s)sample; } -void chip_generate(opl_chip *chip, Bit16s *buff) { +static void OPL3_GenerateRhythm1(opl3_chip *chip) +{ + opl3_channel *channel6; + opl3_channel *channel7; + opl3_channel *channel8; + Bit16u phase14; + Bit16u phase17; + Bit16u phase; + Bit16u phasebit; + + channel6 = &chip->channel[6]; + channel7 = &chip->channel[7]; + channel8 = &chip->channel[8]; + OPL3_SlotGenerate(channel6->slots[0]); + phase14 = (channel7->slots[0]->pg_phase >> 9) & 0x3ff; + phase17 = (channel8->slots[1]->pg_phase >> 9) & 0x3ff; + phase = 0x00; + //hh tc phase bit + phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04) + | (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00; + //hh + phase = (phasebit << 9) + | (0x34 << ((phasebit ^ (chip->noise & 0x01) << 1))); + OPL3_SlotGeneratePhase(channel7->slots[0], phase); + //tt + OPL3_SlotGenerateZM(channel8->slots[0]); +} + +static void OPL3_GenerateRhythm2(opl3_chip *chip) +{ + opl3_channel *channel6; + opl3_channel *channel7; + opl3_channel *channel8; + Bit16u phase14; + Bit16u phase17; + Bit16u phase; + Bit16u phasebit; + + channel6 = &chip->channel[6]; + channel7 = &chip->channel[7]; + channel8 = &chip->channel[8]; + OPL3_SlotGenerate(channel6->slots[1]); + phase14 = (channel7->slots[0]->pg_phase >> 9) & 0x3ff; + phase17 = (channel8->slots[1]->pg_phase >> 9) & 0x3ff; + phase = 0x00; + //hh tc phase bit + phasebit = ((phase14 & 0x08) | (((phase14 >> 5) ^ phase14) & 0x04) + | (((phase17 >> 2) ^ phase17) & 0x08)) ? 0x01 : 0x00; + //sd + phase = (0x100 << ((phase14 >> 8) & 0x01)) ^ ((chip->noise & 0x01) << 8); + OPL3_SlotGeneratePhase(channel7->slots[1], phase); + //tc + phase = 0x100 | (phasebit << 9); + OPL3_SlotGeneratePhase(channel8->slots[1], phase); +} + +void OPL3_Generate(opl3_chip *chip, Bit16s *buf) +{ Bit8u ii; Bit8u jj; Bit16s accm; - buff[1] = limshort(chip->mixbuff[1]); + buf[1] = OPL3_ClipSample(chip->mixbuff[1]); - for (ii = 0; ii < 12; ii++) { - slot_calcfb(&chip->slot[ii]); - pg_generate(&chip->slot[ii]); - envelope_calc(&chip->slot[ii]); - slot_generate(&chip->slot[ii]); + for (ii = 0; ii < 12; ii++) + { + OPL3_SlotCalcFB(&chip->slot[ii]); + OPL3_PhaseGenerate(&chip->slot[ii]); + OPL3_EnvelopeCalc(&chip->slot[ii]); + OPL3_SlotGenerate(&chip->slot[ii]); } - for (ii = 12; ii < 15; ii++) { - slot_calcfb(&chip->slot[ii]); - pg_generate(&chip->slot[ii]); - envelope_calc(&chip->slot[ii]); + for (ii = 12; ii < 15; ii++) + { + OPL3_SlotCalcFB(&chip->slot[ii]); + OPL3_PhaseGenerate(&chip->slot[ii]); + OPL3_EnvelopeCalc(&chip->slot[ii]); } - if (chip->rhy & 0x20) { - chan_generaterhythm1(chip); + if (chip->rhy & 0x20) + { + OPL3_GenerateRhythm1(chip); } - else { - slot_generate(&chip->slot[12]); - slot_generate(&chip->slot[13]); - slot_generate(&chip->slot[14]); + else + { + OPL3_SlotGenerate(&chip->slot[12]); + OPL3_SlotGenerate(&chip->slot[13]); + OPL3_SlotGenerate(&chip->slot[14]); } chip->mixbuff[0] = 0; - for (ii = 0; ii < 18; ii++) { + for (ii = 0; ii < 18; ii++) + { accm = 0; - for (jj = 0; jj < 4; jj++) { + for (jj = 0; jj < 4; jj++) + { accm += *chip->channel[ii].out[jj]; } chip->mixbuff[0] += (Bit16s)(accm & chip->channel[ii].cha); } - for (ii = 15; ii < 18; ii++) { - slot_calcfb(&chip->slot[ii]); - pg_generate(&chip->slot[ii]); - envelope_calc(&chip->slot[ii]); + for (ii = 15; ii < 18; ii++) + { + OPL3_SlotCalcFB(&chip->slot[ii]); + OPL3_PhaseGenerate(&chip->slot[ii]); + OPL3_EnvelopeCalc(&chip->slot[ii]); } - if (chip->rhy & 0x20) { - chan_generaterhythm2(chip); + if (chip->rhy & 0x20) + { + OPL3_GenerateRhythm2(chip); } - else { - slot_generate(&chip->slot[15]); - slot_generate(&chip->slot[16]); - slot_generate(&chip->slot[17]); + else + { + OPL3_SlotGenerate(&chip->slot[15]); + OPL3_SlotGenerate(&chip->slot[16]); + OPL3_SlotGenerate(&chip->slot[17]); } - buff[0] = limshort(chip->mixbuff[0]); + buf[0] = OPL3_ClipSample(chip->mixbuff[0]); - for (ii = 18; ii < 33; ii++) { - slot_calcfb(&chip->slot[ii]); - pg_generate(&chip->slot[ii]); - envelope_calc(&chip->slot[ii]); - slot_generate(&chip->slot[ii]); + for (ii = 18; ii < 33; ii++) + { + OPL3_SlotCalcFB(&chip->slot[ii]); + OPL3_PhaseGenerate(&chip->slot[ii]); + OPL3_EnvelopeCalc(&chip->slot[ii]); + OPL3_SlotGenerate(&chip->slot[ii]); } chip->mixbuff[1] = 0; - for (ii = 0; ii < 18; ii++) { + for (ii = 0; ii < 18; ii++) + { accm = 0; - for (jj = 0; jj < 4; jj++) { + for (jj = 0; jj < 4; jj++) + { accm += *chip->channel[ii].out[jj]; } chip->mixbuff[1] += (Bit16s)(accm & chip->channel[ii].chb); } - for (ii = 33; ii < 36; ii++) { - slot_calcfb(&chip->slot[ii]); - pg_generate(&chip->slot[ii]); - envelope_calc(&chip->slot[ii]); - slot_generate(&chip->slot[ii]); + for (ii = 33; ii < 36; ii++) + { + OPL3_SlotCalcFB(&chip->slot[ii]); + OPL3_PhaseGenerate(&chip->slot[ii]); + OPL3_EnvelopeCalc(&chip->slot[ii]); + OPL3_SlotGenerate(&chip->slot[ii]); } - n_generate(chip); + OPL3_NoiseGenerate(chip); - if ((chip->timer & 0x3f) == 0x3f) { + if ((chip->timer & 0x3f) == 0x3f) + { chip->tremolopos = (chip->tremolopos + 1) % 210; - if (chip->tremolopos < 105) { - chip->tremolo = chip->tremolopos >> (2 + chip->tremoloshift); + if (chip->tremolopos < 105) + { + chip->tremolo = chip->tremolopos >> chip->tremoloshift; } - else { - chip->tremolo = (210 - chip->tremolopos) >> (2 + chip->tremoloshift); + else + { + chip->tremolo = (210 - chip->tremolopos) >> chip->tremoloshift; } } - if ((chip->timer & 0x3ff) == 0x3ff) { + if ((chip->timer & 0x3ff) == 0x3ff) + { chip->vibpos = (chip->vibpos + 1) & 7; } chip->timer++; + + while (chip->writebuf_cur != chip->writebuf_last + && chip->writebuf[chip->writebuf_cur].time <= chip->writebuf_samplecnt) + { + OPL3_WriteReg(chip, chip->writebuf[chip->writebuf_cur].reg, + chip->writebuf[chip->writebuf_cur].data); + chip->writebuf_cur = (chip->writebuf_cur + 1) % OPL_WRITEBUF_SIZE; + } + chip->writebuf_samplecnt++; } -void chip_generate_opl3l(opl_chip *chip, Bit16s *buffer) { - while (chip->samplecnt >= chip->rateratio) { +void OPL3_GenerateResampled(opl3_chip *chip, Bit16s *buf) +{ + while (chip->samplecnt >= chip->rateratio) + { chip->oldsamples[0] = chip->samples[0]; chip->oldsamples[1] = chip->samples[1]; - chip_generate(chip, chip->samples); + OPL3_Generate(chip, chip->samples); chip->samplecnt -= chip->rateratio; } - buffer[0] = (Bit16s)((chip->oldsamples[0] * (chip->rateratio - chip->samplecnt) + chip->samples[0] * chip->samplecnt) / chip->rateratio); - buffer[1] = (Bit16s)((chip->oldsamples[1] * (chip->rateratio - chip->samplecnt) + chip->samples[1] * chip->samplecnt) / chip->rateratio); + buf[0] = (Bit16s)((chip->oldsamples[0] * (chip->rateratio - chip->samplecnt) + + chip->samples[0] * chip->samplecnt) / chip->rateratio); + buf[1] = (Bit16s)((chip->oldsamples[1] * (chip->rateratio - chip->samplecnt) + + chip->samples[1] * chip->samplecnt) / chip->rateratio); chip->samplecnt += 1 << RSM_FRAC; } -void chip_reset(opl_chip *chip, Bit32u samplerate) { +void OPL3_Reset(opl3_chip *chip, Bit32u samplerate) +{ Bit8u slotnum; Bit8u channum; - memset(chip, 0, sizeof(opl_chip)); - for (slotnum = 0; slotnum < 36; slotnum++) { + memset(chip, 0, sizeof(opl3_chip)); + for (slotnum = 0; slotnum < 36; slotnum++) + { chip->slot[slotnum].chip = chip; chip->slot[slotnum].mod = &chip->zeromod; chip->slot[slotnum].eg_rout = 0x1ff; @@ -1034,15 +1273,18 @@ void chip_reset(opl_chip *chip, Bit32u samplerate) { chip->slot[slotnum].eg_gen = envelope_gen_num_off; chip->slot[slotnum].trem = (Bit8u*)&chip->zeromod; } - for (channum = 0; channum < 18; channum++) { + for (channum = 0; channum < 18; channum++) + { chip->channel[channum].slots[0] = &chip->slot[ch_slot[channum]]; chip->channel[channum].slots[1] = &chip->slot[ch_slot[channum] + 3]; chip->slot[ch_slot[channum]].channel = &chip->channel[channum]; chip->slot[ch_slot[channum] + 3].channel = &chip->channel[channum]; - if ((channum % 9) < 3) { + if ((channum % 9) < 3) + { chip->channel[channum].pair = &chip->channel[channum + 3]; } - else if ((channum % 9) < 6) { + else if ((channum % 9) < 6) + { chip->channel[channum].pair = &chip->channel[channum - 3]; } chip->channel[channum].chip = chip; @@ -1053,29 +1295,35 @@ void chip_reset(opl_chip *chip, Bit32u samplerate) { chip->channel[channum].chtype = ch_2op; chip->channel[channum].cha = ~0; chip->channel[channum].chb = ~0; - chan_setupalg(&chip->channel[channum]); + OPL3_ChannelSetupAlg(&chip->channel[channum]); } chip->noise = 0x306600; chip->rateratio = (samplerate << RSM_FRAC) / 49716; } -void chip_write(opl_chip *chip, Bit16u reg, Bit8u v) { +void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v) +{ Bit8u high = (reg >> 8) & 0x01; Bit8u regm = reg & 0xff; - switch (regm & 0xf0) { + switch (regm & 0xf0) + { case 0x00: - if (high) { - switch (regm & 0x0f) { + if (high) + { + switch (regm & 0x0f) + { case 0x04: - chan_set4op(chip, v); + OPL3_ChannelSet4Op(chip, v); break; case 0x05: chip->newm = v & 0x01; break; } } - else { - switch (regm & 0x0f) { + else + { + switch (regm & 0x0f) + { case 0x08: chip->nts = (v >> 6) & 0x01; break; @@ -1084,69 +1332,99 @@ void chip_write(opl_chip *chip, Bit16u reg, Bit8u v) { break; case 0x20: case 0x30: - if (ad_slot[regm & 0x1f] >= 0) { - slot_write20(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); + if (ad_slot[regm & 0x1f] >= 0) + { + OPL3_SlotWrite20(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); } break; case 0x40: case 0x50: - if (ad_slot[regm & 0x1f] >= 0) { - slot_write40(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); + if (ad_slot[regm & 0x1f] >= 0) + { + OPL3_SlotWrite40(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); } break; case 0x60: case 0x70: - if (ad_slot[regm & 0x1f] >= 0) { - slot_write60(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); + if (ad_slot[regm & 0x1f] >= 0) + { + OPL3_SlotWrite60(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); } break; case 0x80: case 0x90: - if (ad_slot[regm & 0x1f] >= 0) { - slot_write80(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v);; + if (ad_slot[regm & 0x1f] >= 0) + { + OPL3_SlotWrite80(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); } break; case 0xe0: case 0xf0: - if (ad_slot[regm & 0x1f] >= 0) { - slot_writee0(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); + if (ad_slot[regm & 0x1f] >= 0) + { + OPL3_SlotWriteE0(&chip->slot[18 * high + ad_slot[regm & 0x1f]], v); } break; case 0xa0: - if ((regm & 0x0f) < 9) { - chan_writea0(&chip->channel[9 * high + (regm & 0x0f)], v); + if ((regm & 0x0f) < 9) + { + OPL3_ChannelWriteA0(&chip->channel[9 * high + (regm & 0x0f)], v); } break; case 0xb0: - if (regm == 0xbd && !high) { - chip->tremoloshift = ((v >> 7) ^ 1) << 1; + if (regm == 0xbd && !high) + { + chip->tremoloshift = (((v >> 7) ^ 1) << 1) + 2; chip->vibshift = ((v >> 6) & 0x01) ^ 1; - chan_updaterhythm(chip, v); + OPL3_ChannelUpdateRhythm(chip, v); } - else if ((regm & 0x0f) < 9) { - chan_writeb0(&chip->channel[9 * high + (regm & 0x0f)], v); - if (v & 0x20) { - chan_enable(&chip->channel[9 * high + (regm & 0x0f)]); + else if ((regm & 0x0f) < 9) + { + OPL3_ChannelWriteB0(&chip->channel[9 * high + (regm & 0x0f)], v); + if (v & 0x20) + { + OPL3_ChannelKeyOn(&chip->channel[9 * high + (regm & 0x0f)]); } - else { - chan_disable(&chip->channel[9 * high + (regm & 0x0f)]); + else + { + OPL3_ChannelKeyOff(&chip->channel[9 * high + (regm & 0x0f)]); } } break; case 0xc0: - if ((regm & 0x0f) < 9) { - chan_writec0(&chip->channel[9 * high + (regm & 0x0f)], v); + if ((regm & 0x0f) < 9) + { + OPL3_ChannelWriteC0(&chip->channel[9 * high + (regm & 0x0f)], v); } break; } } +void OPL3_WriteRegBuffered(opl3_chip *chip, Bit16u reg, Bit8u v) +{ + Bit64u time1, time2; + chip->writebuf[chip->writebuf_last % OPL_WRITEBUF_SIZE].reg = reg; + chip->writebuf[chip->writebuf_last % OPL_WRITEBUF_SIZE].data = v; + time1 = chip->writebuf_lasttime + OPL_WRITEBUF_DELAY; + time2 = chip->writebuf_samplecnt; -void chip_update(opl_chip *chip, Bit16s* sndptr, Bit32u numsamples) { + if (time1 < time2) + { + time1 = time2; + } + + chip->writebuf[chip->writebuf_last % OPL_WRITEBUF_SIZE].time = time1; + chip->writebuf_lasttime = time1; + chip->writebuf_last = (chip->writebuf_last + 1) % OPL_WRITEBUF_SIZE; +} + +void OPL3_GenerateStream(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples) +{ Bit32u i; - for(i = 0; i < numsamples; i++) { - chip_generate_opl3l(chip, sndptr); + for(i = 0; i < numsamples; i++) + { + OPL3_GenerateResampled(chip, sndptr); sndptr += 2; } } diff --git a/opl/opl3.h b/opl/opl3.h index 0408483d..0c738af5 100644 --- a/opl/opl3.h +++ b/opl/opl3.h @@ -21,21 +21,35 @@ // OPLx decapsulated(Matthew Gambrell, Olli Niemitalo): // OPL2 ROMs. // -// version: 1.6.2 +// version: 1.7 // #ifndef OPL_OPL3_H #define OPL_OPL3_H -#include "opl.h" +#include -typedef struct _opl_slot opl_slot; -typedef struct _opl_channel opl_channel; -typedef struct _opl_chip opl_chip; +#define OPL_WRITEBUF_SIZE 1024 +#define OPL_WRITEBUF_DELAY 2 -struct _opl_slot { - opl_channel *channel; - opl_chip *chip; +typedef uintptr_t Bitu; +typedef intptr_t Bits; +typedef uint64_t Bit64u; +typedef int64_t Bit64s; +typedef uint32_t Bit32u; +typedef int32_t Bit32s; +typedef uint16_t Bit16u; +typedef int16_t Bit16s; +typedef uint8_t Bit8u; +typedef int8_t Bit8s; + +typedef struct _opl3_slot opl3_slot; +typedef struct _opl3_channel opl3_channel; +typedef struct _opl3_chip opl3_chip; + +struct _opl3_slot { + opl3_channel *channel; + opl3_chip *chip; Bit16s out; Bit16s fbmod; Bit16s *mod; @@ -63,10 +77,10 @@ struct _opl_slot { Bit32u timer; }; -struct _opl_channel { - opl_slot *slots[2]; - opl_channel *pair; - opl_chip *chip; +struct _opl3_channel { + opl3_slot *slots[2]; + opl3_channel *pair; + opl3_chip *chip; Bit16s *out[4]; Bit8u chtype; Bit16u f_num; @@ -78,9 +92,15 @@ struct _opl_channel { Bit16u cha, chb; }; -struct _opl_chip { - opl_channel channel[18]; - opl_slot slot[36]; +typedef struct _opl3_writebuf { + Bit64u time; + Bit16u reg; + Bit8u data; +} opl3_writebuf; + +struct _opl3_chip { + opl3_channel channel[18]; + opl3_slot slot[36]; Bit16u timer; Bit8u newm; Bit8u nts; @@ -98,10 +118,18 @@ struct _opl_chip { Bit32s samplecnt; Bit16s oldsamples[2]; Bit16s samples[2]; + + Bit64u writebuf_samplecnt; + Bit32u writebuf_cur; + Bit32u writebuf_last; + Bit64u writebuf_lasttime; + opl3_writebuf writebuf[OPL_WRITEBUF_SIZE]; }; - -void chip_reset(opl_chip *chip, Bit32u samplerate); -void chip_write(opl_chip *chip, Bit16u reg, Bit8u v); -void chip_update(opl_chip *chip, Bit16s* sndptr, Bit32u numsamples); +void OPL3_Generate(opl3_chip *chip, Bit16s *buf); +void OPL3_GenerateResampled(opl3_chip *chip, Bit16s *buf); +void OPL3_Reset(opl3_chip *chip, Bit32u samplerate); +void OPL3_WriteReg(opl3_chip *chip, Bit16u reg, Bit8u v); +void OPL3_WriteRegBuffered(opl3_chip *chip, Bit16u reg, Bit8u v); +void OPL3_GenerateStream(opl3_chip *chip, Bit16s *sndptr, Bit32u numsamples); #endif diff --git a/opl/opl_internal.h b/opl/opl_internal.h index 2f0a423b..452b8e3d 100644 --- a/opl/opl_internal.h +++ b/opl/opl_internal.h @@ -50,21 +50,9 @@ typedef struct opl_adjust_callbacks_func adjust_callbacks_func; } opl_driver_t; -typedef void (*opl_core_init_func)(unsigned int rate); -typedef void (*opl_core_write_func)(unsigned int reg, unsigned int data); -typedef void (*opl_core_fill_buffer_func)(int16_t *buffer, unsigned int nsamples); - -typedef struct -{ - opl_core_init_func init_func; - opl_core_write_func write_func; - opl_core_fill_buffer_func fill_buffer_func; -} opl_sdl_core_t; - // Sample rate to use when doing software emulation. extern unsigned int opl_sample_rate; -extern opl_core_t opl_emu; #endif /* #ifndef OPL_INTERNAL_H */ diff --git a/opl/opl_sdl.c b/opl/opl_sdl.c index e993a4ec..40449fef 100644 --- a/opl/opl_sdl.c +++ b/opl/opl_sdl.c @@ -25,7 +25,6 @@ #include "SDL.h" #include "SDL_mixer.h" -#include "dbopl.h" #include "opl3.h" #include "opl.h" @@ -71,8 +70,7 @@ static uint64_t pause_offset; // OPL software emulator structure. -static Chip opl_dbopl_chip; -static opl_chip opl_nuked_chip; +static opl3_chip opl_chip; static int opl_opl3mode; // Temporary mixing buffer used by the mixing callback. @@ -94,88 +92,6 @@ static int sdl_was_initialized = 0; static int mixing_freq, mixing_channels; static Uint16 mixing_format; -// OPL cores. - -opl_sdl_core_t *opl_sdl_core = NULL; - -static void OPL_Nuked_Init(unsigned int rate) -{ - chip_reset(&opl_nuked_chip, rate); -} - -static void OPL_Nuked_Write(unsigned int reg, unsigned int data) -{ - chip_write(&opl_nuked_chip, reg, data); -} - -static void OPL_Nuked_Fill_Buffer(int16_t *buffer, unsigned int nsamples) -{ - chip_update(&opl_nuked_chip, (Bit16s*)buffer, nsamples); -} - -opl_sdl_core_t opl_nuked_core = -{ - OPL_Nuked_Init, - OPL_Nuked_Write, - OPL_Nuked_Fill_Buffer -}; - -static void OPL_DBOPL_Init(unsigned int rate) -{ - DBOPL_InitTables(); - Chip__Chip(&opl_dbopl_chip); - Chip__Setup(&opl_dbopl_chip, mixing_freq); -} - -static void OPL_DBOPL_Write(unsigned int reg, unsigned int data) -{ - Chip__WriteReg(&opl_dbopl_chip, reg, data); -} - -static void OPL_DBOPL_Fill_Buffer(int16_t *buffer, unsigned int nsamples) -{ - unsigned int i; - - // This seems like a reasonable assumption. mix_buffer is - // 1 second long, which should always be much longer than the - // SDL mix buffer. - - assert(nsamples < mixing_freq); - - if (opl_opl3mode) - { - Chip__GenerateBlock3(&opl_dbopl_chip, nsamples, mix_buffer); - - // Mix into the destination buffer, doubling up into stereo. - - for (i=0; ifill_buffer_func(buffer + filled * 2, nsamples); + FillBuffer(buffer + filled * 2, nsamples); filled += nsamples; // Invoke callbacks for this point in time. @@ -417,18 +348,7 @@ static int OPL_SDL_Init(unsigned int port_base) // Create the emulator structure: - switch (opl_emu) - { - case OPL_CORE_NUKED: - default: - opl_sdl_core = &opl_nuked_core; - break; - case OPL_CORE_DBOPL: - opl_sdl_core = &opl_dbopl_core; - break; - } - - opl_sdl_core->init_func(mixing_freq); + OPL3_Reset(&opl_chip, mixing_freq); opl_opl3mode = 0; callback_mutex = SDL_CreateMutex(); @@ -520,7 +440,7 @@ static void WriteRegister(unsigned int reg_num, unsigned int value) opl_opl3mode = value & 0x01; default: - opl_sdl_core->write_func(reg_num, value); + OPL3_WriteRegBuffered(&opl_chip, reg_num, value); break; } } diff --git a/src/i_oplmusic.c b/src/i_oplmusic.c index 66f335ae..05f1a2b9 100644 --- a/src/i_oplmusic.c +++ b/src/i_oplmusic.c @@ -353,7 +353,6 @@ static unsigned int last_perc_count; char *snd_dmxoption = ""; int opl_io_port = 0x388; -int opl_core = OPL_CORE_NUKED; // If true, OPL sound channels are reversed to their correct arrangement // (as intended by the MIDI standard) rather than the backwards one @@ -1761,7 +1760,7 @@ static boolean I_OPL_InitMusic(void) char *dmxoption; opl_init_result_t chip_type; - OPL_SetSampleRateAndCore(snd_samplerate, (opl_core_t)opl_core); + OPL_SetSampleRate(snd_samplerate); chip_type = OPL_Init(opl_io_port); if (chip_type == OPL_INIT_NONE) diff --git a/src/i_sound.c b/src/i_sound.c index 4bb94642..759bd6b6 100644 --- a/src/i_sound.c +++ b/src/i_sound.c @@ -73,7 +73,6 @@ extern music_module_t music_opl_module; extern opl_driver_ver_t opl_drv_ver; extern int opl_io_port; -extern int opl_core; // For native music module: @@ -454,7 +453,6 @@ void I_BindSoundVariables(void) M_BindIntVariable("snd_samplerate", &snd_samplerate); M_BindIntVariable("snd_cachesize", &snd_cachesize); M_BindIntVariable("opl_io_port", &opl_io_port); - M_BindIntVariable("opl_core", &opl_core); M_BindIntVariable("snd_pitchshift", &snd_pitchshift); M_BindStringVariable("timidity_cfg_path", &timidity_cfg_path); diff --git a/src/m_config.c b/src/m_config.c index f0382e1f..61f90a53 100644 --- a/src/m_config.c +++ b/src/m_config.c @@ -838,13 +838,6 @@ static default_t extra_defaults_list[] = CONFIG_VARIABLE_INT_HEX(opl_io_port), - //! - // OPL emulator. A value of zero enables Nuked OPL core. A value of 1 - // enables DOSBox DBOPL core. - // - - CONFIG_VARIABLE_INT(opl_core), - //! // @game doom heretic strife // diff --git a/src/setup/sound.c b/src/setup/sound.c index 2f6e7d65..7001907c 100644 --- a/src/setup/sound.c +++ b/src/setup/sound.c @@ -74,19 +74,6 @@ static char *opltype_strings[] = "OPL3" }; -typedef enum -{ - OPLCORE_NUKED, - OPLMODE_DBOPL, - NUM_OPLCORES, -} oplcore_t; - -static char *oplcore_strings[] = -{ - "Nuked OPL", - "DOSBox DBOPL" -}; - static char *cfg_extension[] = { "cfg", NULL }; // Config file variables: @@ -127,7 +114,6 @@ static int snd_mport = 0; static int snd_sfxmode; static int snd_musicmode; static int snd_oplmode; -static int opl_core = OPLCORE_NUKED; static void UpdateSndDevices(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(data)) { @@ -209,8 +195,6 @@ static void UpdateExtraTable(TXT_UNCAST_ARG(widget), TXT_AddWidgets(extra_table, TXT_NewLabel("OPL type"), OPLTypeSelector(), - TXT_NewLabel("OPL emulator"), - TXT_NewDropdownList(&opl_core, oplcore_strings, 2), NULL); break; @@ -400,7 +384,6 @@ void BindSoundVariables(void) M_BindIntVariable("snd_cachesize", &snd_cachesize); M_BindIntVariable("opl_io_port", &opl_io_port); - M_BindIntVariable("opl_core", &opl_core); M_BindIntVariable("snd_pitchshift", &snd_pitchshift);