Merge branch 'master' of https://github.com/tildearrow/furnace into es5506_alt
This commit is contained in:
commit
5a6cde65ed
21 changed files with 433 additions and 134 deletions
|
|
@ -115,7 +115,7 @@ const unsigned char dacLogTableAY[256]={
|
|||
|
||||
void DivPlatformAY8910::runDAC() {
|
||||
for (int i=0; i<3; i++) {
|
||||
if (chan[i].psgMode.dac && chan[i].dac.sample!=-1) {
|
||||
if (chan[i].active && chan[i].psgMode.dac && chan[i].dac.sample!=-1) {
|
||||
chan[i].dac.period+=chan[i].dac.rate;
|
||||
bool end=false;
|
||||
bool changed=false;
|
||||
|
|
@ -129,7 +129,7 @@ void DivPlatformAY8910::runDAC() {
|
|||
break;
|
||||
}
|
||||
unsigned char dacData=dacLogTableAY[(unsigned char)s->data8[chan[i].dac.pos]^0x80];
|
||||
chan[i].dac.out=MAX(0,dacData-(15-chan[i].outVol));
|
||||
chan[i].dac.out=(chan[i].active && !isMuted[i])?MAX(0,dacData-(15-chan[i].outVol)):0;
|
||||
if (prevOut!=chan[i].dac.out) {
|
||||
prevOut=chan[i].dac.out;
|
||||
changed=true;
|
||||
|
|
@ -264,7 +264,7 @@ void DivPlatformAY8910::tick(bool sysTick) {
|
|||
}
|
||||
if (chan[i].std.wave.had) {
|
||||
if (!chan[i].psgMode.dac) {
|
||||
chan[i].psgMode=(chan[i].std.wave.val+1)&7;
|
||||
chan[i].psgMode.val=(chan[i].std.wave.val+1)&7;
|
||||
if (isMuted[i]) {
|
||||
rWrite(0x08+i,0);
|
||||
} else if (intellivision && (chan[i].psgMode.getEnvelope())) {
|
||||
|
|
@ -336,8 +336,12 @@ void DivPlatformAY8910::tick(bool sysTick) {
|
|||
if (chan[i].keyOn) {
|
||||
//rWrite(16+i*5+1,((chan[i].duty&3)<<6)|(63-(ins->gb.soundLen&63)));
|
||||
//rWrite(16+i*5+2,((chan[i].vol<<4))|(ins->gb.envLen&7)|((ins->gb.envDir&1)<<3));
|
||||
if (chan[i].psgMode.val==0) {
|
||||
chan[i].psgMode.val=1;
|
||||
}
|
||||
}
|
||||
if (chan[i].keyOff) {
|
||||
chan[i].psgMode.val=0;
|
||||
rWrite(0x08+i,0);
|
||||
}
|
||||
rWrite((i)<<1,chan[i].freq&0xff);
|
||||
|
|
@ -543,7 +547,7 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
|
|||
case DIV_CMD_STD_NOISE_MODE:
|
||||
if (!chan[c.chan].psgMode.dac) {
|
||||
if (c.value<16) {
|
||||
chan[c.chan].psgMode=(c.value+1)&7;
|
||||
chan[c.chan].psgMode.val=(c.value+1)&7;
|
||||
if (isMuted[c.chan]) {
|
||||
rWrite(0x08+c.chan,0);
|
||||
} else if (chan[c.chan].active) {
|
||||
|
|
|
|||
|
|
@ -32,10 +32,15 @@ class DivPlatformAY8910: public DivDispatch {
|
|||
inline unsigned char regRemap(unsigned char reg) { return intellivision?AY8914RegRemap[reg&0x0f]:reg&0x0f; }
|
||||
struct Channel {
|
||||
struct PSGMode {
|
||||
unsigned char tone: 1;
|
||||
unsigned char noise: 1;
|
||||
unsigned char envelope: 1;
|
||||
unsigned char dac: 1;
|
||||
union {
|
||||
struct {
|
||||
unsigned char tone: 1;
|
||||
unsigned char noise: 1;
|
||||
unsigned char envelope: 1;
|
||||
unsigned char dac: 1;
|
||||
};
|
||||
unsigned char val=1;
|
||||
};
|
||||
|
||||
unsigned char getTone() {
|
||||
return dac?0:(tone<<0);
|
||||
|
|
@ -49,19 +54,8 @@ class DivPlatformAY8910: public DivDispatch {
|
|||
return dac?0:(envelope<<2);
|
||||
}
|
||||
|
||||
PSGMode& operator=(unsigned char s) {
|
||||
tone=(s>>0)&1;
|
||||
noise=(s>>1)&1;
|
||||
envelope=(s>>2)&1;
|
||||
dac=(s>>3)&1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PSGMode():
|
||||
tone(1),
|
||||
noise(0),
|
||||
envelope(0),
|
||||
dac(0) {}
|
||||
val(1) {}
|
||||
} psgMode;
|
||||
|
||||
struct DAC {
|
||||
|
|
|
|||
|
|
@ -110,8 +110,8 @@ const unsigned char dacLogTableAY8930[256]={
|
|||
};
|
||||
|
||||
void DivPlatformAY8930::runDAC() {
|
||||
for (int i=0; i<3; i++) {
|
||||
if (chan[i].psgMode.dac && chan[i].dac.sample!=-1) {
|
||||
for (int i=0; i<3; i++) {
|
||||
if (chan[i].active && chan[i].psgMode.dac && chan[i].dac.sample!=-1) {
|
||||
chan[i].dac.period+=chan[i].dac.rate;
|
||||
bool end=false;
|
||||
bool changed=false;
|
||||
|
|
@ -125,7 +125,7 @@ void DivPlatformAY8930::runDAC() {
|
|||
break;
|
||||
}
|
||||
unsigned char dacData=dacLogTableAY8930[(unsigned char)s->data8[chan[i].dac.pos]^0x80];
|
||||
chan[i].dac.out=MAX(0,dacData-(31-chan[i].outVol));
|
||||
chan[i].dac.out=(chan[i].active && !isMuted[i])?MAX(0,dacData-(31-chan[i].outVol)):0;
|
||||
if (prevOut!=chan[i].dac.out) {
|
||||
prevOut=chan[i].dac.out;
|
||||
changed=true;
|
||||
|
|
@ -254,7 +254,7 @@ void DivPlatformAY8930::tick(bool sysTick) {
|
|||
}
|
||||
if (chan[i].std.wave.had) {
|
||||
if (!chan[i].psgMode.dac) {
|
||||
chan[i].psgMode=(chan[i].std.wave.val+1)&7;
|
||||
chan[i].psgMode.val=(chan[i].std.wave.val+1)&7;
|
||||
if (isMuted[i]) {
|
||||
rWrite(0x08+i,0);
|
||||
} else {
|
||||
|
|
@ -333,12 +333,16 @@ void DivPlatformAY8930::tick(bool sysTick) {
|
|||
}
|
||||
if (chan[i].freq>65535) chan[i].freq=65535;
|
||||
if (chan[i].keyOn) {
|
||||
if (chan[i].psgMode.val==0) {
|
||||
chan[i].psgMode.val=1;
|
||||
}
|
||||
if (chan[i].insChanged) {
|
||||
if (!chan[i].std.ex1.will) immWrite(0x16+i,chan[i].duty);
|
||||
chan[i].insChanged=false;
|
||||
}
|
||||
}
|
||||
if (chan[i].keyOff) {
|
||||
chan[i].psgMode.val=0;
|
||||
rWrite(0x08+i,0);
|
||||
}
|
||||
rWrite((i)<<1,chan[i].freq&0xff);
|
||||
|
|
@ -537,7 +541,7 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
|
|||
case DIV_CMD_STD_NOISE_MODE:
|
||||
if (c.value<0x10) {
|
||||
if (!chan[c.chan].psgMode.dac) {
|
||||
chan[c.chan].psgMode=(c.value+1)&7;
|
||||
chan[c.chan].psgMode.val=(c.value+1)&7;
|
||||
if (isMuted[c.chan]) {
|
||||
rWrite(0x08+c.chan,0);
|
||||
} else if (chan[c.chan].active) {
|
||||
|
|
|
|||
|
|
@ -40,10 +40,15 @@ class DivPlatformAY8930: public DivDispatch {
|
|||
} envelope;
|
||||
|
||||
struct PSGMode {
|
||||
unsigned char tone: 1;
|
||||
unsigned char noise: 1;
|
||||
unsigned char envelope: 1;
|
||||
unsigned char dac: 1;
|
||||
union {
|
||||
struct {
|
||||
unsigned char tone: 1;
|
||||
unsigned char noise: 1;
|
||||
unsigned char envelope: 1;
|
||||
unsigned char dac: 1;
|
||||
};
|
||||
unsigned char val=1;
|
||||
};
|
||||
|
||||
unsigned char getTone() {
|
||||
return dac?0:(tone<<0);
|
||||
|
|
@ -57,19 +62,8 @@ class DivPlatformAY8930: public DivDispatch {
|
|||
return dac?0:(envelope<<2);
|
||||
}
|
||||
|
||||
PSGMode& operator=(unsigned char s) {
|
||||
tone=(s>>0)&1;
|
||||
noise=(s>>1)&1;
|
||||
envelope=(s>>2)&1;
|
||||
dac=(s>>3)&1;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PSGMode():
|
||||
tone(1),
|
||||
noise(0),
|
||||
envelope(0),
|
||||
dac(0) {}
|
||||
val(1) {}
|
||||
} psgMode;
|
||||
|
||||
struct DAC {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#define CHIP_FREQBASE 131072
|
||||
|
||||
#define rWrite(a,v) if (!skipRegisterWrites) {writes.emplace(a,v); if (dumpWrites) {addWrite(a,v);} }
|
||||
#define rWrite(a,v) if (!skipRegisterWrites) {writes.push(QueuedWrite(a,v)); if (dumpWrites) {addWrite(a,v);} }
|
||||
#define chWrite(c,a,v) {rWrite((a)+(c)*16,v)}
|
||||
#define sampleTableAddr(c) (sampleTableBase+(c)*4)
|
||||
#define waveTableAddr(c) (sampleTableBase+8*4+(c)*9*16)
|
||||
|
|
@ -94,19 +94,9 @@ void DivPlatformSNES::tick(bool sysTick) {
|
|||
unsigned char kon=0;
|
||||
unsigned char koff=0;
|
||||
for (int i=0; i<8; i++) {
|
||||
DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_AMIGA);
|
||||
bool hadGain=chan[i].std.vol.had || chan[i].std.ex1.had || chan[i].std.ex2.had;
|
||||
chan[i].std.next();
|
||||
if (ins->type==DIV_INS_AMIGA && chan[i].std.vol.had) {
|
||||
chWrite(i,7,MIN(127,chan[i].std.vol.val*2));
|
||||
} else if (!chan[i].useEnv && hadGain) {
|
||||
if (chan[i].std.ex1.val==0) {
|
||||
// direct gain
|
||||
chWrite(i,7,chan[i].std.vol.val);
|
||||
} else {
|
||||
// inc/dec
|
||||
chWrite(i,7,chan[i].std.ex2.val|((chan[i].std.ex1.val-1)<<5)|0x80);
|
||||
}
|
||||
if (chan[i].std.vol.had) {
|
||||
chan[i].outVol=VOL_SCALE_LOG(chan[i].vol&127,MIN(127,chan[i].std.vol.val),127);
|
||||
}
|
||||
if (chan[i].std.arp.had) {
|
||||
if (!chan[i].inPorta) {
|
||||
|
|
@ -123,6 +113,10 @@ void DivPlatformSNES::tick(bool sysTick) {
|
|||
chan[i].freqChanged=true;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.duty.had) {
|
||||
noiseFreq=chan[i].std.duty.val;
|
||||
writeControl=true;
|
||||
}
|
||||
if (chan[i].useWave && chan[i].std.wave.had) {
|
||||
if (chan[i].wave!=chan[i].std.wave.val || chan[i].ws.activeChanged()) {
|
||||
chan[i].wave=chan[i].std.wave.val;
|
||||
|
|
@ -146,7 +140,30 @@ void DivPlatformSNES::tick(bool sysTick) {
|
|||
int val=chan[i].std.panR.val&0x7f;
|
||||
chan[i].panR=(val<<1)|(val>>6);
|
||||
}
|
||||
if (chan[i].std.panL.had || chan[i].std.panR.had) {
|
||||
bool hasInverted=false;
|
||||
if (chan[i].std.ex1.had) {
|
||||
if (chan[i].invertL!=(bool)(chan[i].std.ex1.val&16)) {
|
||||
chan[i].invertL=chan[i].std.ex1.val&16;
|
||||
hasInverted=true;
|
||||
}
|
||||
if (chan[i].invertR!=(bool)(chan[i].std.ex1.val&8)) {
|
||||
chan[i].invertR=chan[i].std.ex1.val&8;
|
||||
hasInverted=true;
|
||||
}
|
||||
if (chan[i].pitchMod!=(bool)(chan[i].std.ex1.val&4)) {
|
||||
chan[i].pitchMod=chan[i].std.ex1.val&4;
|
||||
writePitchMod=true;
|
||||
}
|
||||
if (chan[i].echo!=(bool)(chan[i].std.ex1.val&2)) {
|
||||
chan[i].echo=chan[i].std.ex1.val&2;
|
||||
writeEcho=true;
|
||||
}
|
||||
if (chan[i].noise!=(bool)(chan[i].std.ex1.val&1)) {
|
||||
chan[i].noise=chan[i].std.ex1.val&1;
|
||||
writeNoise=true;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.vol.had || chan[i].std.panL.had || chan[i].std.panR.had || hasInverted) {
|
||||
writeOutVol(i);
|
||||
}
|
||||
if (chan[i].setPos) {
|
||||
|
|
@ -164,17 +181,12 @@ void DivPlatformSNES::tick(bool sysTick) {
|
|||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||
DivSample* s=parent->getSample(chan[i].sample);
|
||||
double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0;
|
||||
if (chan[i].useWave) off=(double)chan[i].wtLen/32.0;
|
||||
chan[i].freq=(unsigned int)(off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].pitch2,chipClock,CHIP_FREQBASE));
|
||||
if (chan[i].freq>16383) chan[i].freq=16383;
|
||||
if (chan[i].keyOn) {
|
||||
unsigned int start, end, loop;
|
||||
size_t tabAddr=sampleTableAddr(i);
|
||||
if (chan[i].useEnv) {
|
||||
chWrite(i,5,ins->snes.a|(ins->snes.d<<4)|0x80);
|
||||
chWrite(i,6,ins->snes.r|(ins->snes.s<<5));
|
||||
} else {
|
||||
chWrite(i,5,0);
|
||||
}
|
||||
unsigned short tabAddr=sampleTableAddr(i);
|
||||
if (chan[i].useWave) {
|
||||
start=waveTableAddr(i);
|
||||
loop=start;
|
||||
|
|
@ -193,9 +205,6 @@ void DivPlatformSNES::tick(bool sysTick) {
|
|||
sampleMem[tabAddr+1]=start>>8;
|
||||
sampleMem[tabAddr+2]=loop&0xff;
|
||||
sampleMem[tabAddr+3]=loop>>8;
|
||||
if (!hadGain) {
|
||||
chWrite(i,7,0x7f);
|
||||
}
|
||||
kon|=(1<<i);
|
||||
chan[i].keyOn=false;
|
||||
}
|
||||
|
|
@ -210,6 +219,53 @@ void DivPlatformSNES::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (writeControl) {
|
||||
unsigned char control=noiseFreq&0x1f;
|
||||
rWrite(0x6c,control);
|
||||
writeControl=false;
|
||||
}
|
||||
if (writeNoise) {
|
||||
unsigned char noiseBits=(
|
||||
(chan[0].noise?1:0)|
|
||||
(chan[1].noise?2:0)|
|
||||
(chan[2].noise?4:0)|
|
||||
(chan[3].noise?8:0)|
|
||||
(chan[4].noise?0x10:0)|
|
||||
(chan[5].noise?0x20:0)|
|
||||
(chan[6].noise?0x40:0)|
|
||||
(chan[7].noise?0x80:0)
|
||||
);
|
||||
rWrite(0x3d,noiseBits);
|
||||
writeNoise=false;
|
||||
}
|
||||
if (writePitchMod) {
|
||||
unsigned char pitchModBits=(
|
||||
(chan[0].pitchMod?1:0)|
|
||||
(chan[1].pitchMod?2:0)|
|
||||
(chan[2].pitchMod?4:0)|
|
||||
(chan[3].pitchMod?8:0)|
|
||||
(chan[4].pitchMod?0x10:0)|
|
||||
(chan[5].pitchMod?0x20:0)|
|
||||
(chan[6].pitchMod?0x40:0)|
|
||||
(chan[7].pitchMod?0x80:0)
|
||||
);
|
||||
rWrite(0x2d,pitchModBits);
|
||||
writePitchMod=false;
|
||||
}
|
||||
if (writeEcho) {
|
||||
unsigned char echoBits=(
|
||||
(chan[0].echo?1:0)|
|
||||
(chan[1].echo?2:0)|
|
||||
(chan[2].echo?4:0)|
|
||||
(chan[3].echo?8:0)|
|
||||
(chan[4].echo?0x10:0)|
|
||||
(chan[5].echo?0x20:0)|
|
||||
(chan[6].echo?0x40:0)|
|
||||
(chan[7].echo?0x80:0)
|
||||
);
|
||||
rWrite(0x4d,echoBits);
|
||||
writeEcho=false;
|
||||
}
|
||||
if (kon!=0) {
|
||||
rWrite(0x4c,kon);
|
||||
}
|
||||
|
|
@ -220,7 +276,7 @@ void DivPlatformSNES::tick(bool sysTick) {
|
|||
int DivPlatformSNES::dispatch(DivCommand c) {
|
||||
switch (c.cmd) {
|
||||
case DIV_CMD_NOTE_ON: {
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA);
|
||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_SNES);
|
||||
if (ins->amiga.useWave) {
|
||||
chan[c.chan].useWave=true;
|
||||
chan[c.chan].wtLen=ins->amiga.waveLen+1;
|
||||
|
|
@ -239,6 +295,32 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
|||
if (chan[c.chan].useWave || chan[c.chan].sample<0 || chan[c.chan].sample>=parent->song.sampleLen) {
|
||||
chan[c.chan].sample=-1;
|
||||
}
|
||||
if (chan[c.chan].insChanged) {
|
||||
chan[c.chan].state=ins->snes;
|
||||
}
|
||||
if (chan[c.chan].state.useEnv) {
|
||||
chWrite(c.chan,5,chan[c.chan].state.a|(chan[c.chan].state.d<<4)|0x80);
|
||||
chWrite(c.chan,6,chan[c.chan].state.r|(chan[c.chan].state.s<<5));
|
||||
} else {
|
||||
chWrite(c.chan,5,0);
|
||||
switch (chan[c.chan].state.gainMode) {
|
||||
case DivInstrumentSNES::GAIN_MODE_DIRECT:
|
||||
chWrite(c.chan,7,chan[c.chan].state.gain&127);
|
||||
break;
|
||||
case DivInstrumentSNES::GAIN_MODE_DEC_LINEAR:
|
||||
chWrite(c.chan,7,0x80|(chan[c.chan].state.gain&31));
|
||||
break;
|
||||
case DivInstrumentSNES::GAIN_MODE_INC_LINEAR:
|
||||
chWrite(c.chan,7,0xc0|(chan[c.chan].state.gain&31));
|
||||
break;
|
||||
case DivInstrumentSNES::GAIN_MODE_DEC_LOG:
|
||||
chWrite(c.chan,7,0xa0|(chan[c.chan].state.gain&31));
|
||||
break;
|
||||
case DivInstrumentSNES::GAIN_MODE_INC_INVLOG:
|
||||
chWrite(c.chan,7,0xe0|(chan[c.chan].state.gain&31));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].baseFreq=round(NOTE_FREQUENCY(c.value));
|
||||
chan[c.chan].freqChanged=true;
|
||||
|
|
@ -247,11 +329,6 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
|||
chan[c.chan].active=true;
|
||||
chan[c.chan].keyOn=true;
|
||||
chan[c.chan].macroInit(ins);
|
||||
if (ins->type==DIV_INS_SNES) {
|
||||
// initialize to max gain in case of direct gain mode macro without gain level macro
|
||||
chan[c.chan].std.vol.val=0x7f;
|
||||
chan[c.chan].useEnv=ins->snes.useEnv;
|
||||
}
|
||||
chan[c.chan].insChanged=false;
|
||||
break;
|
||||
}
|
||||
|
|
@ -277,12 +354,6 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
|||
writeOutVol(c.chan);
|
||||
}
|
||||
break;
|
||||
// case DIV_CMD_GLOBAL_VOLUME:
|
||||
// gblVolL=MIN(c.value,127);
|
||||
// gblVolR=MIN(c.value,127);
|
||||
// rWrite(0x0c,gblVolL);
|
||||
// rWrite(0x1c,gblVolR);
|
||||
// break;
|
||||
case DIV_CMD_GET_VOLUME:
|
||||
return chan[c.chan].vol;
|
||||
break;
|
||||
|
|
@ -326,7 +397,7 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
|||
}
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
if (chan[c.chan].active && c.value2) {
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA));
|
||||
if (parent->song.resetMacroOnPorta) chan[c.chan].macroInit(parent->getIns(chan[c.chan].ins,DIV_INS_SNES));
|
||||
}
|
||||
chan[c.chan].inPorta=c.value;
|
||||
break;
|
||||
|
|
@ -346,7 +417,7 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
|||
|
||||
void DivPlatformSNES::updateWave(int ch) {
|
||||
// Due to the overflow bug in hardware's resampler, the written amplitude here is half of maximum
|
||||
size_t pos=waveTableAddr(ch);
|
||||
unsigned short pos=waveTableAddr(ch);
|
||||
for (int i=0; i<chan[ch].wtLen/16; i++) {
|
||||
sampleMem[pos++]=0xb0;
|
||||
for (int j=0; j<8; j++) {
|
||||
|
|
@ -359,12 +430,13 @@ void DivPlatformSNES::updateWave(int ch) {
|
|||
}
|
||||
|
||||
void DivPlatformSNES::writeOutVol(int ch) {
|
||||
// TODO negative (inverted) panning support
|
||||
int outL=0;
|
||||
int outR=0;
|
||||
if (!isMuted[ch]) {
|
||||
outL=chan[ch].vol*chan[ch].panL/255;
|
||||
outR=chan[ch].vol*chan[ch].panR/255;
|
||||
outL=(globalVolL*((chan[ch].outVol*chan[ch].panL)/127))/127;
|
||||
outR=(globalVolR*((chan[ch].outVol*chan[ch].panR)/127))/127;
|
||||
if (chan[ch].invertL) outL=-outL;
|
||||
if (chan[ch].invertR) outR=-outR;
|
||||
}
|
||||
chWrite(ch,0,outL);
|
||||
chWrite(ch,1,outR);
|
||||
|
|
@ -380,8 +452,15 @@ void DivPlatformSNES::forceIns() {
|
|||
chan[i].insChanged=true;
|
||||
chan[i].freqChanged=true;
|
||||
chan[i].sample=-1;
|
||||
updateWave(i);
|
||||
if (chan[i].active && chan[i].useWave) {
|
||||
updateWave(i);
|
||||
}
|
||||
writeOutVol(i);
|
||||
}
|
||||
writeControl=true;
|
||||
writeNoise=true;
|
||||
writePitchMod=true;
|
||||
writeEcho=true;
|
||||
}
|
||||
|
||||
void* DivPlatformSNES::getChanState(int ch) {
|
||||
|
|
@ -414,9 +493,9 @@ void DivPlatformSNES::reset() {
|
|||
dsp.init(sampleMem);
|
||||
dsp.set_output(NULL,0);
|
||||
memset(regPool,0,128);
|
||||
// TODO more initial values
|
||||
// this can't be 0 or channel 1 won't play
|
||||
// this can't be 0x100 either as that's used by SPC700 page 1 and the stack
|
||||
// this may not even be 0x200 as some space will be taken by the playback routine and variables
|
||||
sampleTableBase=0x200;
|
||||
rWrite(0x5d,sampleTableBase>>8);
|
||||
rWrite(0x0c,127); // global volume left
|
||||
|
|
@ -430,6 +509,10 @@ void DivPlatformSNES::reset() {
|
|||
writeOutVol(i);
|
||||
chWrite(i,4,i); // source number
|
||||
}
|
||||
writeControl=false;
|
||||
writeNoise=false;
|
||||
writePitchMod=false;
|
||||
writeEcho=false;
|
||||
}
|
||||
|
||||
bool DivPlatformSNES::isStereo() {
|
||||
|
|
@ -493,7 +576,7 @@ void DivPlatformSNES::renderSamples() {
|
|||
int actualLength=MIN((int)(getSampleMemCapacity()-memPos)/9*9,length);
|
||||
if (actualLength>0) {
|
||||
s->offSNES=memPos;
|
||||
memcpy(&sampleMem[memPos],s->data8,actualLength);
|
||||
memcpy(&sampleMem[memPos],s->dataBRR,actualLength);
|
||||
memPos+=actualLength;
|
||||
}
|
||||
if (actualLength<length) {
|
||||
|
|
@ -506,6 +589,11 @@ void DivPlatformSNES::renderSamples() {
|
|||
sampleMemLen=memPos;
|
||||
}
|
||||
|
||||
void DivPlatformSNES::setFlags(unsigned int flags) {
|
||||
globalVolL=127-(flags&127);
|
||||
globalVolR=127-((flags>>8)&127);
|
||||
}
|
||||
|
||||
int DivPlatformSNES::init(DivEngine* p, int channels, int sugRate, unsigned int flags) {
|
||||
parent=p;
|
||||
dumpWrites=false;
|
||||
|
|
@ -517,6 +605,7 @@ int DivPlatformSNES::init(DivEngine* p, int channels, int sugRate, unsigned int
|
|||
sampleMemLen=0;
|
||||
chipClock=1024000;
|
||||
rate=chipClock/32;
|
||||
setFlags(flags);
|
||||
reset();
|
||||
return 8;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@ class DivPlatformSNES: public DivDispatch {
|
|||
int sample, wave, ins;
|
||||
int note;
|
||||
int panL, panR;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, useWave, setPos;
|
||||
signed char vol;
|
||||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, useWave, setPos, noise, echo, pitchMod, invertL, invertR;
|
||||
int vol, outVol;
|
||||
int wtLen;
|
||||
bool useEnv;
|
||||
DivInstrumentSNES state;
|
||||
DivMacroInt std;
|
||||
DivWaveSynth ws;
|
||||
void macroInit(DivInstrument* which) {
|
||||
|
|
@ -53,8 +53,8 @@ class DivPlatformSNES: public DivDispatch {
|
|||
wave(-1),
|
||||
ins(-1),
|
||||
note(0),
|
||||
panL(255),
|
||||
panR(255),
|
||||
panL(127),
|
||||
panR(127),
|
||||
active(false),
|
||||
insChanged(true),
|
||||
freqChanged(false),
|
||||
|
|
@ -63,15 +63,25 @@ class DivPlatformSNES: public DivDispatch {
|
|||
inPorta(false),
|
||||
useWave(false),
|
||||
setPos(false),
|
||||
noise(false),
|
||||
echo(false),
|
||||
pitchMod(false),
|
||||
invertL(false),
|
||||
invertR(false),
|
||||
vol(127),
|
||||
wtLen(16),
|
||||
useEnv(false) {}
|
||||
outVol(127),
|
||||
wtLen(16) {}
|
||||
};
|
||||
Channel chan[8];
|
||||
DivDispatchOscBuffer* oscBuf[8];
|
||||
bool isMuted[8];
|
||||
signed char gblVolL, gblVolR;
|
||||
signed char globalVolL, globalVolR;
|
||||
unsigned char noiseFreq;
|
||||
size_t sampleTableBase;
|
||||
bool writeControl;
|
||||
bool writeNoise;
|
||||
bool writePitchMod;
|
||||
bool writeEcho;
|
||||
|
||||
struct QueuedWrite {
|
||||
unsigned char addr;
|
||||
|
|
@ -101,6 +111,7 @@ class DivPlatformSNES: public DivDispatch {
|
|||
bool isStereo();
|
||||
void notifyInsChange(int ins);
|
||||
void notifyWaveChange(int wave);
|
||||
void setFlags(unsigned int flags);
|
||||
void notifyInsDeletion(void* ins);
|
||||
void poke(unsigned int addr, unsigned short val);
|
||||
void poke(std::vector<DivRegWrite>& wlist);
|
||||
|
|
|
|||
|
|
@ -803,7 +803,7 @@ void SPC_DSP::run( int clocks_remain )
|
|||
{
|
||||
loop:
|
||||
// GCC, why
|
||||
#ifdef __GNUC__
|
||||
#if defined(__GNUC__) && !defined(__clang__)
|
||||
#define PHASE( n ) if ( n && !--clocks_remain ) break; __attribute__ ((fallthrough)); case n:
|
||||
#else
|
||||
#define PHASE( n ) if ( n && !--clocks_remain ) break; case n:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue