GB use blargg's audio core correctly

Noise channel seems to be buggy in GBA mode (probably using uninitialized data somewhere).   Suddenly became very LOUD.  
Changed volume setting for now.

OpenGL is looking for glext which is not part of a standard windows build.  Probably should incldue it in dependencies if we are going to 
use it
This commit is contained in:
DJRobX 2007-11-08 11:42:08 +00:00
parent 17e8800d18
commit 6b947e0353
13 changed files with 672 additions and 1009 deletions

View File

@ -90,6 +90,7 @@ u32 busPrefetchCount = 0;
int cpuDmaTicksToUpdate = 0;
int cpuDmaCount = 0;
bool cpuDmaHack = false;
bool cpuDmaHack2 = false;
u32 cpuDmaLast = 0;
int dummyAddress = 0;
@ -2313,11 +2314,15 @@ void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32)
}
void CPUCheckDMA(int reason, int dmamask)
bool CPUCheckDMA(int reason, int dmamask)
{
bool res = false;
cpuDmaHack = 0;
// DMA 0
if((DM0CNT_H & 0x8000) && (dmamask & 1)) {
if(((DM0CNT_H >> 12) & 3) == reason) {
res = true;
u32 sourceIncrement = 4;
u32 destIncrement = 4;
switch((DM0CNT_H >> 7) & 3) {
@ -2375,6 +2380,8 @@ void CPUCheckDMA(int reason, int dmamask)
// DMA 1
if((DM1CNT_H & 0x8000) && (dmamask & 2)) {
if(((DM1CNT_H >> 12) & 3) == reason) {
res = true;
u32 sourceIncrement = 4;
u32 destIncrement = 4;
switch((DM1CNT_H >> 7) & 3) {
@ -2444,6 +2451,7 @@ void CPUCheckDMA(int reason, int dmamask)
// DMA 2
if((DM2CNT_H & 0x8000) && (dmamask & 4)) {
if(((DM2CNT_H >> 12) & 3) == reason) {
res = true;
u32 sourceIncrement = 4;
u32 destIncrement = 4;
switch((DM2CNT_H >> 7) & 3) {
@ -2514,6 +2522,7 @@ void CPUCheckDMA(int reason, int dmamask)
// DMA 3
if((DM3CNT_H & 0x8000) && (dmamask & 8)) {
if(((DM3CNT_H >> 12) & 3) == reason) {
res = true;
u32 sourceIncrement = 4;
u32 destIncrement = 4;
switch((DM3CNT_H >> 7) & 3) {
@ -2565,6 +2574,8 @@ void CPUCheckDMA(int reason, int dmamask)
}
}
}
cpuDmaHack = false;
return res;
}
void CPUUpdateRegister(u32 address, u16 value)
@ -3846,6 +3857,8 @@ void CPULoop(int ticks)
int timerOverflow = 0;
// variable used by the CPU core
cpuTotalTicks = 0;
if(cpuDmaHack2)
cpuNextEvent = 1;
cpuBreakLoop = false;
cpuNextEvent = CPUUpdateTicks();
if(cpuNextEvent > ticks)
@ -4044,7 +4057,7 @@ void CPULoop(int ticks)
IF |= 1;
UPDATE_REG(0x202, IF);
}
CPUCheckDMA(1, 0x0f);
cpuDmaHack2 = CPUCheckDMA(1, 0x0f);
if(frameCount >= framesToSkip) {
systemDrawScreen();
frameCount = 0;
@ -4164,7 +4177,7 @@ void CPULoop(int ticks)
DISPSTAT |= 2;
UPDATE_REG(0x04, DISPSTAT);
lcdTicks += 224;
CPUCheckDMA(2, 0x0f);
cpuDmaHack2 = CPUCheckDMA(2, 0x0f);
if(DISPSTAT & 16) {
IF |= 2;
UPDATE_REG(0x202, IF);
@ -4328,6 +4341,9 @@ void CPULoop(int ticks)
goto updateLoop;
}
// if(cpuDmaHack2)
// cpuNextEvent = 1;
if(IF && (IME & 1) && armIrqEnable) {
int res = IF & IE;
if(stopState)

View File

@ -116,7 +116,7 @@ extern void CPUWriteByte(u32, u8);
extern void CPUInit(const char *,bool);
extern void CPUReset();
extern void CPULoop(int);
extern void CPUCheckDMA(int,int);
extern bool CPUCheckDMA(int,int);
extern bool CPUIsGBAImage(const char *);
extern bool CPUIsZipFile(const char *);
#ifdef PROFILING

View File

@ -23,6 +23,7 @@
#include "System.h"
#include "Port.h"
#include "RTC.h"
#include "Sound.h"
extern bool cpuSramEnabled;
extern bool cpuFlashEnabled;
@ -31,6 +32,7 @@ extern bool cpuEEPROMSensorEnabled;
extern int lspeed;
extern void LinkSStop(void);
extern bool cpuDmaHack;
extern bool cpuDmaHack2;
extern u32 cpuDmaLast;
extern bool timer0On;
extern int timer0Ticks;
@ -94,12 +96,11 @@ static inline u32 CPUReadMemory(u32 address)
case 4:
if((address>=0x4000120||address<=0x4000126)&&lspeed)
LinkSStop();
if((address < 0x4000400) && ioReadable[address & 0x3fc]) {
if(ioReadable[(address & 0x3fc) + 2])
value = READ32LE(((u32 *)&ioMem[address & 0x3fC]));
value = soundRead32(address & 0x3fC);
else
value = READ16LE(((u16 *)&ioMem[address & 0x3fc]));
value = soundRead16(address & 0x3fc);
} else goto unreadable;
break;
case 5:
@ -145,7 +146,7 @@ static inline u32 CPUReadMemory(u32 address)
}
#endif
if(cpuDmaHack) {
if(cpuDmaHack || cpuDmaHack2) {
value = cpuDmaLast;
} else {
if(armState) {
@ -218,12 +219,11 @@ static inline u32 CPUReadHalfWord(u32 address)
value = READ16LE(((u16 *)&internalRAM[address & 0x7ffe]));
break;
case 4:
if((address>=0x4000120||address<=0x4000126)&&lspeed)
if((address>=0x4000120||address<=0x4000126)&&lspeed)
LinkSStop();
if((address < 0x4000400) && ioReadable[address & 0x3fe])
{
value = READ16LE(((u16 *)&ioMem[address & 0x3fe]));
value = soundRead16(address & 0x3fe);
if (((address & 0x3fe)>0xFF) && ((address & 0x3fe)<0x10E))
{
if (((address & 0x3fe) == 0x100) && timer0On)
@ -286,7 +286,7 @@ static inline u32 CPUReadHalfWord(u32 address)
armNextPC - 4 : armNextPC - 2);
}
#endif
if(cpuDmaHack) {
if(cpuDmaHack2 || cpuDmaHack) {
value = cpuDmaLast & 0xFFFF;
} else {
if(armState) {
@ -336,9 +336,8 @@ static inline u8 CPUReadByte(u32 address)
case 4:
if((address>=0x4000120||address<=0x4000126)&&lspeed)
LinkSStop();
if((address < 0x4000400) && ioReadable[address & 0x3ff])
return ioMem[address & 0x3ff];
return soundRead(address & 0x3ff);
else goto unreadable;
case 5:
return paletteRAM[address & 0x3ff];
@ -385,7 +384,7 @@ static inline u8 CPUReadByte(u32 address)
armNextPC - 4 : armNextPC - 2);
}
#endif
if(cpuDmaHack) {
if(cpuDmaHack || cpuDmaHack2) {
return cpuDmaLast & 0xFF;
} else {
if(armState) {

View File

@ -320,7 +320,7 @@ void Blip_Synth_::volume_unit( double new_unit )
factor *= 2.0;
}
if ( shift )
// if ( shift )
{
kernel_unit >>= shift;
assert( kernel_unit > 0 ); // fails if volume unit is too low

View File

@ -107,7 +107,7 @@ void Gb_Apu::reset(bool igba)
square1.reset();
square2.reset();
wave.reset(gba = igba);
noise.reset();
noise.reset(igba);
noise.bits = 1;
wave.wave_pos = 0;

View File

@ -172,6 +172,7 @@ void Gb_Square::run( gb_time_t time, gb_time_t end_time, int playing )
void Gb_Noise::run( gb_time_t time, gb_time_t end_time, int playing )
{
int amp = volume & playing;
int tap = 13 - (regs [3] & 8);
if ( bits >> tap & 2 )
amp = -amp;
@ -197,7 +198,7 @@ void Gb_Noise::run( gb_time_t time, gb_time_t end_time, int playing )
const blip_resampled_time_t resampled_period =
output->resampled_duration( period );
blip_resampled_time_t resampled_time = output->resampled_time( time );
unsigned bits = this->bits;
// unsigned bits = this->bits;
int delta = amp * 2;
do
@ -215,7 +216,7 @@ void Gb_Noise::run( gb_time_t time, gb_time_t end_time, int playing )
}
while ( time < end_time );
this->bits = bits;
//this->bits = bits;
last_amp = delta >> 1;
}
delay = time - end_time;
@ -227,7 +228,7 @@ void Gb_Wave::reset(bool gba)
{
volume_forced = 0;
wave_pos = 0;
wave_mode = gba;
wave_mode = (gba ? 1 : 0);
wave_size = 32;
wave_bank = 0;
memset( wave, 0, sizeof wave );
@ -270,6 +271,33 @@ inline void Gb_Wave::write_register( int reg, int data )
}
}
bool Gb_Noise::write_register( int reg, int data )
{
switch ( reg )
{
case 1:
length = 64 - (regs [1] & 0x3f);
break;
case 2:
if ( !(data >> 4) )
enabled = false;
break;
case 4:
if ( data & trigger )
{
env_delay = regs [2] & 7;
volume = regs [2] >> (4 + (gba ? 1 : 0));
enabled = true;
if ( length == 0 )
length = 64;
return true;
}
}
return false;
}
void Gb_Wave::run( gb_time_t time, gb_time_t end_time, int playing )
{
int volume_shift = (volume - 1) & 7; // volume = 0 causes shift = 7

View File

@ -57,10 +57,17 @@ struct Gb_Square : Gb_Env
struct Gb_Noise : Gb_Env
{
bool gba;
typedef Blip_Synth<blip_med_quality,1> Synth;
Synth const* synth;
unsigned bits;
bool write_register( int, int );
void reset(bool igba)
{
gba = igba;
Gb_Env::reset();
}
void run( gb_time_t, gb_time_t, int playing );
};

View File

@ -53,7 +53,7 @@ int lspeed = 0;
lserver ls;
lclient lc;
bool oncewait = false, after = false;
bool adapter = true;
bool adapter = false;
u8 rfu_cmd, rfu_qsend, rfu_qrecv;
int rfu_state, rfu_polarity, linktime2, counter, rfu_masterq;
int transferend, numtransfers = 0;

View File

@ -670,7 +670,7 @@ void soundDirectSoundATimer()
{
if(soundDSAEnabled) {
if(soundDSFifoACount <= 16) {
CPUCheckDMA(3, 2);
cpuDmaHack2 = CPUCheckDMA(3, 2);
if(soundDSFifoACount <= 16) {
soundEvent(FIFOA_L, (u16)0);
soundEvent(FIFOA_H, (u16)0);
@ -699,8 +699,7 @@ void soundDirectSoundBTimer()
{
if(soundDSBEnabled) {
if(soundDSFifoBCount <= 16) {
//cpuDmaHack2 =
CPUCheckDMA(3, 4);
cpuDmaHack2 = CPUCheckDMA(3, 4);
if(soundDSFifoBCount <= 16) {
soundEvent(FIFOB_L, (u16)0);
soundEvent(FIFOB_H, (u16)0);

View File

@ -998,7 +998,7 @@ void gbWriteMemory(register u16 address, register u8 value)
case 0x3d:
case 0x3e:
case 0x3f: {
gbMemory[address] = value;
SOUND_EVENT(address,value);
return;
}
@ -1783,6 +1783,11 @@ u8 gbReadMemory(register u16 address)
}
if(address >= 0xff00) {
if (address >= 0xFF10 && address <= 0xFF3F) {
return gbSoundRead(address);
}
switch(address & 0x00ff) {
case 0x00:
{
@ -3528,6 +3533,8 @@ static bool gbWriteSaveState(gzFile gzFile)
utilGzWrite(gzFile, gbPalette, 128 * sizeof(u16));
for (int i = 0xFF10; i <= 0xFF3F; i++) gbMemory[i] = gbReadMemory(i);
utilGzWrite(gzFile, &gbMemory[0x8000], 0x8000);
if(gbRamSize && gbRam) {
@ -3718,6 +3725,8 @@ static bool gbReadSaveState(gzFile gzFile)
utilGzRead(gzFile, &gbMemory[0x8000], 0x8000);
for (int i = 0xFF10; i <= 0xFF3F; i++) gbSoundEvent(i, gbMemory[i]);
if(gbRamSize && gbRam) {
if (version < 11)
utilGzRead(gzFile, gbRam, gbRamSize);

View File

@ -23,6 +23,9 @@
#include "gbGlobals.h"
#include "gbSound.h"
#include "../Gb_Apu/Multi_Buffer.h"
#include "../Gb_Apu/Gb_Apu.h"
extern u8 soundBuffer[6][735];
extern u16 soundFinalWave[1470];
extern int soundVolume;
@ -56,6 +59,9 @@ extern int soundBufferIndex;
int soundVIN = 0;
extern int soundDebug;
extern Multi_Buffer * apu_out;
extern Gb_Apu * apu;
extern int sound1On;
extern int sound1ATL;
int sound1ATLreload;
@ -132,7 +138,45 @@ extern bool soundLowPass;
extern bool soundReverse;
extern bool soundOffFlag;
bool gbDigitalSound = false;
u8 gbSoundRead(u16 address)
{
if (address < NR10 || address > 0xFF3F || !apu) return gbMemory[address];
if (address == NR51) return soundBalance;
int clock = (SOUND_CLOCK_TICKS - soundTicks) * 95 / (24 * (gbSpeed ? 2 : 1));
int ret = apu->read_register(clock, address);
switch ( address )
{
case NR10:
ret |= 0x80; break;
case NR11:
case NR21:
ret |= 0x3F; break;
case NR13:
case NR23:
case NR31:
case NR33:
ret = 0xFF; break;
case NR14:
case NR24:
case NR34:
case NR44:
ret |= 0xBF; break;
case NR30:
ret |= 0x7F; break;
case NR32:
ret |= 0x9F; break;
}
return ret;
}
void gbSoundEvent(register u16 address, register int data)
{
@ -146,481 +190,58 @@ void gbSoundEvent(register u16 address, register int data)
log("Sound event: %08lx %02x\n", address, data);
}
#endif
switch(address) {
case NR10:
gbMemory[address] = data | 0x80;
sound1SweepATL = sound1SweepATLReload = 344 * ((data >> 4) & 7);
sound1SweepSteps = data & 7;
sound1SweepUpDown = data & 0x08;
sound1SweepStep = 0;
break;
case NR11:
gbMemory[address] = data | 0x3f;
sound1Wave = soundWavePattern[data >> 6];
sound1ATL = sound1ATLreload = 172 * (64 - (data & 0x3f));
break;
case NR12:
sound1EnvelopeVolume = data >> 4;
sound1EnvelopeUpDown = data & 0x08;
sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (data & 7);
break;
case NR13:
gbMemory[address] = 0xff;
freq1low = data;
freq = ((((int)(freq1high & 7)) << 8) | freq1low);
sound1ATL = sound1ATLreload;
freq = 2048 - freq;
if(freq) {
sound1Skip = SOUND_MAGIC / freq;
} else
sound1Skip = 0;
break;
case NR14:
gbMemory[address] = data | 0xbf;
freq1high = data;
freq = ((((int)(freq1high & 7)) << 8) | freq1low);
freq = 2048 - freq;
sound1ATL = sound1ATLreload;
sound1Continue = data & 0x40;
if(freq) {
sound1Skip = SOUND_MAGIC / freq;
} else
sound1Skip = 0;
if(data & 0x80) {
gbMemory[NR52] |= 1;
sound1EnvelopeVolume = gbMemory[NR12] >> 4;
sound1EnvelopeUpDown = gbMemory[NR12] & 0x08;
sound1EnvelopeATLReload = sound1EnvelopeATL = 689 * (gbMemory[NR12] & 7);
sound1SweepATL = sound1SweepATLReload = 344 * ((gbMemory[NR10] >> 4) & 7);
sound1SweepSteps = gbMemory[NR10] & 7;
sound1SweepUpDown = gbMemory[NR10] & 0x08;
sound1SweepStep = 0;
sound1Index = 0;
sound1On = 1;
if (apu && address >= NR10 && address <= 0xFF3F)
{
int clock = (SOUND_CLOCK_TICKS - soundTicks) * 95 / (24 * (gbSpeed ? 2 : 1));
if (address == NR50)
{
apu->write_register(clock, address, data);
}
break;
case NR21:
gbMemory[address] = data | 0x3f;
sound2Wave = soundWavePattern[data >> 6];
sound2ATL = sound2ATLreload = 172 * (64 - (data & 0x3f));
break;
case NR22:
sound2EnvelopeVolume = data >> 4;
sound2EnvelopeUpDown = data & 0x08;
sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (data & 7);
break;
case NR23:
gbMemory[address] = 0xff;
freq2low = data;
freq = (((int)(freq2high & 7)) << 8) | freq2low;
sound2ATL = sound2ATLreload;
freq = 2048 - freq;
if(freq) {
sound2Skip = SOUND_MAGIC / freq;
} else
sound2Skip = 0;
break;
case NR24:
gbMemory[address] = data | 0xbf;
freq2high = data;
freq = (((int)(freq2high & 7)) << 8) | freq2low;
freq = 2048 - freq;
sound2ATL = sound2ATLreload;
sound2Continue = data & 0x40;
if(freq) {
sound2Skip = SOUND_MAGIC / freq;
} else
sound2Skip = 0;
if(data & 0x80) {
gbMemory[NR52] |= 2;
sound2EnvelopeVolume = gbMemory[NR22] >> 4;
sound2EnvelopeUpDown = gbMemory[NR22] & 0x08;
sound2ATL = sound2ATLreload;
sound2EnvelopeATLReload = sound2EnvelopeATL = 689 * (gbMemory[NR22] & 7);
sound2Index = 0;
sound2On = 1;
else if (address == NR51)
{
soundBalance = data;
apu->write_register(clock, address, data & soundEnableFlag);
}
break;
case NR30:
gbMemory[address] = data | 0x7f;
if(!(data & 0x80)) {
gbMemory[NR52] &= 0xfb;
sound3On = 0;
}
break;
case NR31:
gbMemory[address] = 0xff;
sound3ATL = sound3ATLreload = 172 * (256-data);
break;
case NR32:
gbMemory[address] = data | 0x9f;
sound3OutputLevel = (data >> 5) & 3;
break;
case NR33:
gbMemory[address] = 0xff;
freq3low = data;
freq = 2048 - (((int)(freq3high&7) << 8) | freq3low);
if(freq) {
sound3Skip = SOUND_MAGIC_2 / freq;
} else
sound3Skip = 0;
break;
case NR34:
gbMemory[address] = data | 0xbf;
freq3high = data;
freq = 2048 - (((int)(freq3high&7) << 8) | freq3low);
if(freq) {
sound3Skip = SOUND_MAGIC_2 / freq;
} else {
sound3Skip = 0;
}
sound3Continue = data & 0x40;
if((data & 0x80) && (gbMemory[NR30] & 0x80)) {
gbMemory[NR52] |= 4;
sound3ATL = sound3ATLreload;
sound3Index = 0;
sound3On = 1;
}
break;
case NR41:
sound4ATL = sound4ATLreload = 172 * (64 - (data & 0x3f));
break;
case NR42:
sound4EnvelopeVolume = data >> 4;
sound4EnvelopeUpDown = data & 0x08;
sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (data & 7);
break;
case NR43:
freq = freq4 = soundFreqRatio[data & 7];
sound4NSteps = data & 0x08;
sound4Skip = (freq << 8) / NOISE_MAGIC;
sound4Clock = data >> 4;
freq = freq / soundShiftClock[sound4Clock];
sound4ShiftSkip = (freq << 8) / NOISE_MAGIC;
break;
case NR44:
gbMemory[address] = data | 0xbf;
sound4Continue = data & 0x40;
if(data & 0x80) {
gbMemory[NR52] |= 8;
sound4EnvelopeVolume = gbMemory[NR42] >> 4;
sound4EnvelopeUpDown = gbMemory[NR42] & 0x08;
sound4ATL = sound4ATLreload;
sound4EnvelopeATLReload = sound4EnvelopeATL = 689 * (gbMemory[NR42] & 7);
sound4On = 1;
sound4Index = 0;
sound4ShiftIndex = 0;
if(sound4NSteps)
sound4ShiftRight = 0x7fff;
else
sound4ShiftRight = 0x7f;
apu->write_register(clock, address, data);
}
break;
case NR50:
soundVIN = data & 0x88;
soundLevel1 = data & 7;
soundLevel2 = (data >> 4) & 7;
break;
case NR51:
soundBalance = (data & soundEnableFlag);
break;
case NR52:
soundMasterOn = data & 0x80;
if(!(data & 0x80)) {
sound1On = 0;
sound2On = 0;
sound3On = 0;
sound4On = 0;
gbMemory[address] &= 0xf0;
}
gbMemory[address] = data & 0x80 | 0x70 | (gbMemory[address] & 0xf);
break;
}
gbDigitalSound = true;
if(sound1On && sound1EnvelopeVolume != 0)
gbDigitalSound = false;
if(sound2On && sound2EnvelopeVolume != 0)
gbDigitalSound = false;
if(sound3On && sound3OutputLevel != 0)
gbDigitalSound = false;
if(sound4On && sound4EnvelopeVolume != 0)
gbDigitalSound = false;
}
void gbSoundChannel1()
{
int vol = sound1EnvelopeVolume;
int freq = 0;
int value = 0;
if(sound1On && (sound1ATL || !sound1Continue)) {
sound1Index += soundQuality*sound1Skip;
sound1Index &= 0x1fffffff;
value = ((s8)sound1Wave[sound1Index>>24]) * vol;
}
soundBuffer[0][soundIndex] = value;
if(sound1On) {
if(sound1ATL) {
sound1ATL-=soundQuality;
if(sound1ATL <=0 && sound1Continue) {
gbMemory[NR52] &= 0xfe;
sound1On = 0;
}
}
if(sound1EnvelopeATL) {
sound1EnvelopeATL-=soundQuality;
if(sound1EnvelopeATL<=0) {
if(sound1EnvelopeUpDown) {
if(sound1EnvelopeVolume < 15)
sound1EnvelopeVolume++;
} else {
if(sound1EnvelopeVolume)
sound1EnvelopeVolume--;
}
sound1EnvelopeATL += sound1EnvelopeATLReload;
}
}
if(sound1SweepATL) {
sound1SweepATL-=soundQuality;
if(sound1SweepATL<=0) {
freq = (((int)(freq1high & 7)) << 8) | freq1low;
int updown = 1;
if(sound1SweepUpDown)
updown = -1;
int newfreq = 0;
if(sound1SweepSteps) {
newfreq = freq + updown * freq / (1 << sound1SweepSteps);
if(newfreq == freq)
newfreq = 0;
} else
newfreq = freq;
if(newfreq < 0) {
sound1SweepATL += sound1SweepATLReload;
} else if(newfreq > 2047) {
sound1SweepATL = 0;
sound1On = 0;
gbMemory[NR52] &= 0xfe;
} else {
sound1SweepATL += sound1SweepATLReload;
sound1Skip = SOUND_MAGIC/(2048 - newfreq);
freq1low = newfreq & 0xff;
freq1high = (freq1high & 0xf8) |((newfreq >> 8) & 7);
}
}
}
}
}
void gbSoundChannel2()
{
// int freq = 0;
int vol = sound2EnvelopeVolume;
int value = 0;
if(sound2On && (sound2ATL || !sound2Continue)) {
sound2Index += soundQuality*sound2Skip;
sound2Index &= 0x1fffffff;
value = ((s8)sound2Wave[sound2Index>>24]) * vol;
}
soundBuffer[1][soundIndex] = value;
if(sound2On) {
if(sound2ATL) {
sound2ATL-=soundQuality;
if(sound2ATL <= 0 && sound2Continue) {
gbMemory[NR52] &= 0xfd;
sound2On = 0;
}
}
if(sound2EnvelopeATL) {
sound2EnvelopeATL-=soundQuality;
if(sound2EnvelopeATL <= 0) {
if(sound2EnvelopeUpDown) {
if(sound2EnvelopeVolume < 15)
sound2EnvelopeVolume++;
} else {
if(sound2EnvelopeVolume)
sound2EnvelopeVolume--;
}
sound2EnvelopeATL += sound2EnvelopeATLReload;
}
}
}
}
void gbSoundChannel3()
{
int value = 0;
if(sound3On && (sound3ATL || !sound3Continue)) {
value = sound3Last;
sound3Index += soundQuality*sound3Skip;
sound3Index &= 0x1fffffff;
value = gbMemory[0xff30 + (sound3Index>>25)];
if( (sound3Index & 0x01000000)) {
value &= 0x0f;
} else {
value >>= 4;
}
value -= 8;
switch(sound3OutputLevel) {
case 0:
value = 0;
break;
case 1:
break;
case 2:
value = (value >> 1);
break;
case 3:
value = (value >> 2);
break;
}
sound3Last = value;
}
soundBuffer[2][soundIndex] = value;
if(sound3On) {
if(sound3ATL) {
sound3ATL-=soundQuality;
if(sound3ATL <= 0 && sound3Continue) {
gbMemory[NR52] &= 0xfb;
sound3On = 0;
}
}
}
}
void gbSoundChannel4()
{
int vol = sound4EnvelopeVolume;
int value = 0;
if(sound4Clock <= 0x0c) {
if(sound4On && (sound4ATL || !sound4Continue)) {
sound4Index += soundQuality*sound4Skip;
sound4ShiftIndex += soundQuality*sound4ShiftSkip;
if(sound4NSteps) {
while(sound4ShiftIndex > 0x1fffff) {
sound4ShiftRight = (((sound4ShiftRight << 6) ^
(sound4ShiftRight << 5)) & 0x40) |
(sound4ShiftRight >> 1);
sound4ShiftIndex -= 0x200000;
}
} else {
while(sound4ShiftIndex > 0x1fffff) {
sound4ShiftRight = (((sound4ShiftRight << 14) ^
(sound4ShiftRight << 13)) & 0x4000) |
(sound4ShiftRight >> 1);
sound4ShiftIndex -= 0x200000;
}
}
sound4Index &= 0x1fffff;
sound4ShiftIndex &= 0x1fffff;
value = ((sound4ShiftRight & 1)*2-1) * vol;
} else {
value = 0;
}
}
soundBuffer[3][soundIndex] = value;
if(sound4On) {
if(sound4ATL) {
sound4ATL-=soundQuality;
if(sound4ATL <= 0 && sound4Continue) {
gbMemory[NR52] &= 0xf7;
sound4On = 0;
}
}
if(sound4EnvelopeATL) {
sound4EnvelopeATL-=soundQuality;
if(sound4EnvelopeATL <= 0) {
if(sound4EnvelopeUpDown) {
if(sound4EnvelopeVolume < 15)
sound4EnvelopeVolume++;
} else {
if(sound4EnvelopeVolume)
sound4EnvelopeVolume--;
}
sound4EnvelopeATL += sound4EnvelopeATLReload;
}
}
}
}
void gbSoundMix()
{
int res = 0;
if(soundBalance & 16) {
res += ((s8)soundBuffer[0][soundIndex]);
}
if(soundBalance & 32) {
res += ((s8)soundBuffer[1][soundIndex]);
}
if(soundBalance & 64) {
res += ((s8)soundBuffer[2][soundIndex]);
}
if(soundBalance & 128) {
res += ((s8)soundBuffer[3][soundIndex]);
blip_sample_t out[2] = {0, 0};
if ( ! apu_out ) return;
while (!apu_out->read_samples(&out[0], 2))
{
int ticks = SOUND_CLOCK_TICKS * 95 / (24 * (gbSpeed ? 2 : 1));
bool was_stereo = apu->end_frame( ticks );
apu_out->end_frame( ticks, was_stereo );
}
if(gbDigitalSound)
res *= soundLevel1*256;
else
res *= soundLevel1*60;
res = out[0];
//res = (res * 7 * 60) >> 8;
if(soundEcho) {
res *= 2;
@ -664,25 +285,7 @@ void gbSoundMix()
else
soundFinalWave[soundBufferIndex++] = res;
res = 0;
if(soundBalance & 1) {
res += ((s8)soundBuffer[0][soundIndex]);
}
if(soundBalance & 2) {
res += ((s8)soundBuffer[1][soundIndex]);
}
if(soundBalance & 4) {
res += ((s8)soundBuffer[2][soundIndex]);
}
if(soundBalance & 8) {
res += ((s8)soundBuffer[3][soundIndex]);
}
if(gbDigitalSound)
res *= soundLevel2*256;
else
res *= soundLevel2*60;
res = out[1];
if(soundEcho) {
res *= 2;
@ -734,10 +337,10 @@ void gbSoundTick()
{
if(systemSoundOn) {
if(soundMasterOn) {
gbSoundChannel1();
/*gbSoundChannel1();
gbSoundChannel2();
gbSoundChannel3();
gbSoundChannel4();
gbSoundChannel4();*/
gbSoundMix();
} else {
@ -775,7 +378,7 @@ void gbSoundReset()
soundLevel2 = 7;
soundVIN = 0;
sound1On = 0;
/*sound1On = 0;
sound1ATL = 0;
sound1Skip = 0;
sound1Index = 0;
@ -821,53 +424,48 @@ void gbSoundReset()
sound4EnvelopeVolume = 0;
sound4EnvelopeATL = 0;
sound4EnvelopeUpDown = 0;
sound4EnvelopeATLReload = 0;
sound4EnvelopeATLReload = 0;*/
// don't translate
if(soundDebug) {
log("*** Sound Init ***\n");
}
gbSoundEvent(0xff10, 0x80);
gbSoundEvent(0xff11, 0xbf);
gbSoundEvent(0xff12, 0xf3);
gbSoundEvent(0xff14, 0xbf);
gbSoundEvent(0xff16, 0x3f);
gbSoundEvent(0xff17, 0x00);
gbSoundEvent(0xff19, 0xbf);
if (apu_out)
{
apu_out->clear();
apu->reset(false);
gbSoundEvent(0xff1a, 0x7f);
gbSoundEvent(0xff1b, 0xff);
gbSoundEvent(0xff1c, 0xbf);
gbSoundEvent(0xff1e, 0xbf);
extern const BOOST::uint8_t sound_data[Gb_Apu::end_addr - Gb_Apu::start_addr + 1];
gbSoundEvent(0xff20, 0xff);
gbSoundEvent(0xff21, 0x00);
gbSoundEvent(0xff22, 0x00);
gbSoundEvent(0xff23, 0xbf);
gbSoundEvent(0xff24, 0x77);
gbSoundEvent(0xff25, 0xf3);
int addr = 0;
if (gbHardware & 0x4)
gbSoundEvent(0xff26, 0xf0);
else
gbSoundEvent(0xff26, 0xf1);
while (addr < 0x30) {
apu->write_register( 0, 0xFF10 + addr, sound_data [ addr ] );
addr++;
}
}
// don't translate
if(soundDebug) {
log("*** Sound Init Complete ***\n");
}
sound1On = 0;
/*sound1On = 0;
sound2On = 0;
sound3On = 0;
sound4On = 0;
sound4On = 0;*/
if (apu)
{
int addr = 0xff30;
while(addr < 0xff40) {
gbMemory[addr++] = 0x00;
gbMemory[addr++] = 0xff;
/*gbMemory[addr++] = 0x00;
gbMemory[addr++] = 0xff;*/
gbSoundEvent(addr++, 0x00);
gbSoundEvent(addr++, 0xFF);
}
}
memset(soundFinalWave, 0x00, soundBufferLen);

View File

@ -22,6 +22,7 @@
#define NR12 0xff12
#define NR13 0xff13
#define NR14 0xff14
#define NR20 0xff15
#define NR21 0xff16
#define NR22 0xff17
#define NR23 0xff18
@ -31,6 +32,7 @@
#define NR32 0xff1c
#define NR33 0xff1d
#define NR34 0xff1e
#define NR40 0xff1f
#define NR41 0xff20
#define NR42 0xff21
#define NR43 0xff22
@ -54,6 +56,8 @@ extern void gbSoundReadGame(int,gzFile);
extern void gbSoundEvent(register u16, register int);
extern void gbSoundSetQuality(int);
extern u8 gbSoundRead(u16 address);
extern int soundTicks;
extern int soundQuality;
extern int SOUND_CLOCK_TICKS;

View File

@ -32,7 +32,10 @@
// OpenGL
#include <gl/GL.h> // main include file
#ifdef HAS_GLEXT
#include <gl/glext.h>
#endif
typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALFARPROC)( int );
extern int Init_2xSaI(u32);