Merge branch 'master' of https://github.com/tildearrow/furnace into ymf289b

This commit is contained in:
cam900 2023-01-14 12:11:26 +09:00
commit 3d345af1b8
149 changed files with 2940 additions and 1763 deletions

View file

@ -159,13 +159,13 @@ const int orderedOpsL[4]={
#define ADDR_FREQH 0xb0
#define ADDR_LR_FB_ALG 0xc0
void DivPlatformOPL::acquire_nuked(short* bufL, short* bufR, size_t start, size_t len) {
static short o[2];
static int os[2];
void DivPlatformOPL::acquire_nuked(short** buf, size_t len) {
static short o[4];
static int os[4];
static ymfm::ymfm_output<2> aOut;
for (size_t h=start; h<start+len; h++) {
os[0]=0; os[1]=0;
for (size_t h=0; h<len; h++) {
os[0]=0; os[1]=0; os[2]=0; os[3]=0;
if (!writes.empty() && --delay<0) {
delay=1;
QueuedWrite& w=writes.front();
@ -194,11 +194,14 @@ void DivPlatformOPL::acquire_nuked(short* bufL, short* bufR, size_t start, size_
}
if (downsample) {
OPL3_GenerateResampled(&fm,o);
OPL3_Generate4ChResampled(&fm,o);
} else {
OPL3_Generate(&fm,o);
OPL3_Generate4Ch(&fm,o);
}
os[0]+=o[0]; os[1]+=o[1];
os[0]+=o[0];
os[1]+=o[1];
os[2]+=o[2];
os[3]+=o[3];
if (adpcmChan>=0) {
adpcmB->clock();
@ -225,6 +228,12 @@ void DivPlatformOPL::acquire_nuked(short* bufL, short* bufR, size_t start, size_
if (fm.channel[i].out[1]!=NULL) {
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[1];
}
if (fm.channel[i].out[2]!=NULL) {
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[2];
}
if (fm.channel[i].out[3]!=NULL) {
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[3];
}
oscBuf[i]->data[oscBuf[i]->needle]<<=1;
oscBuf[i]->needle++;
}
@ -244,6 +253,12 @@ void DivPlatformOPL::acquire_nuked(short* bufL, short* bufR, size_t start, size_
if (fm.channel[i].out[1]!=NULL) {
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[1];
}
if (fm.channel[i].out[2]!=NULL) {
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[2];
}
if (fm.channel[i].out[3]!=NULL) {
oscBuf[i]->data[oscBuf[i]->needle]+=*fm.channel[ch].out[3];
}
oscBuf[i]->data[oscBuf[i]->needle]<<=1;
oscBuf[i]->needle++;
}
@ -254,19 +269,36 @@ void DivPlatformOPL::acquire_nuked(short* bufL, short* bufR, size_t start, size_
if (os[1]<-32768) os[1]=-32768;
if (os[1]>32767) os[1]=32767;
if (os[2]<-32768) os[2]=-32768;
if (os[2]>32767) os[2]=32767;
if (os[3]<-32768) os[3]=-32768;
if (os[3]>32767) os[3]=32767;
bufL[h]=os[0];
if (oplType==3 || oplType==759) {
bufR[h]=os[1];
buf[0][h]=os[0];
if (totalOutputs>1) {
buf[1][h]=os[1];
}
if (totalOutputs>2) {
buf[2][h]=os[2];
}
if (totalOutputs>3) {
buf[3][h]=os[3];
}
if (totalOutputs==6) {
// placeholder for OPL4
buf[4][h]=0;
buf[5][h]=0;
}
}
}
void DivPlatformOPL::acquire(short* bufL, short* bufR, size_t start, size_t len) {
void DivPlatformOPL::acquire(short** buf, size_t len) {
//if (useYMFM) {
// acquire_ymfm(bufL,bufR,start,len);
// acquire_ymfm(buf,len);
//} else {
acquire_nuked(bufL,bufR,start,len);
acquire_nuked(buf,len);
//}
}
@ -314,13 +346,13 @@ void DivPlatformOPL::tick(bool sysTick) {
}
if (oplType==3 && chan[i].std.panL.had) {
chan[i].pan=((chan[i].std.panL.val&1)<<1)|((chan[i].std.panL.val&2)>>1);
chan[i].pan=((chan[i].std.panL.val&1)<<1)|((chan[i].std.panL.val&2)>>1)|((chan[i].std.panL.val&4)<<1)|((chan[i].std.panL.val&8)>>1);
}
if (chan[i].std.pitch.had) {
if (chan[i].std.pitch.mode) {
chan[i].pitch2+=chan[i].std.pitch.val;
CLAMP_VAR(chan[i].pitch2,-32768,32767);
CLAMP_VAR(chan[i].pitch2,-131071,131071);
} else {
chan[i].pitch2=chan[i].std.pitch.val;
}
@ -347,9 +379,9 @@ void DivPlatformOPL::tick(bool sysTick) {
rWrite(chanMap[i+1]+ADDR_LR_FB_ALG,((chan[i].state.alg>>1)&1)|(chan[i].state.fb<<1));
}
} else {
rWrite(chanMap[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&1)|(chan[i].state.fb<<1)|((chan[i].pan&3)<<4));
rWrite(chanMap[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&1)|(chan[i].state.fb<<1)|((chan[i].pan&15)<<4));
if (ops==4) {
rWrite(chanMap[i+1]+ADDR_LR_FB_ALG,((chan[i].state.alg>>1)&1)|(chan[i].state.fb<<1)|((chan[i].pan&3)<<4));
rWrite(chanMap[i+1]+ADDR_LR_FB_ALG,((chan[i].state.alg>>1)&1)|(chan[i].state.fb<<1)|((chan[i].pan&15)<<4));
}
}
}
@ -659,9 +691,9 @@ void DivPlatformOPL::muteChannel(int ch, bool mute) {
rWrite(chanMap[ch+1]+ADDR_LR_FB_ALG,((chan[ch].state.alg>>1)&1)|(chan[ch].state.fb<<1));
}
} else {
rWrite(chanMap[ch]+ADDR_LR_FB_ALG,(chan[ch].state.alg&1)|(chan[ch].state.fb<<1)|((chan[ch].pan&3)<<4));
rWrite(chanMap[ch]+ADDR_LR_FB_ALG,(chan[ch].state.alg&1)|(chan[ch].state.fb<<1)|((chan[ch].pan&15)<<4));
if (ops==4) {
rWrite(chanMap[ch+1]+ADDR_LR_FB_ALG,((chan[ch].state.alg>>1)&1)|(chan[ch].state.fb<<1)|((chan[ch].pan&3)<<4));
rWrite(chanMap[ch+1]+ADDR_LR_FB_ALG,((chan[ch].state.alg>>1)&1)|(chan[ch].state.fb<<1)|((chan[ch].pan&15)<<4));
}
}
}
@ -797,7 +829,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
rWrite(chanMap[ch]+ADDR_LR_FB_ALG,(chan[ch].state.alg&1)|(chan[ch].state.fb<<1));
} else {
oldWrites[chanMap[ch]+ADDR_LR_FB_ALG]=-1;
rWrite(chanMap[ch]+ADDR_LR_FB_ALG,(chan[ch].state.alg&1)|(chan[ch].state.fb<<1)|((chan[ch].pan&3)<<4));
rWrite(chanMap[ch]+ADDR_LR_FB_ALG,(chan[ch].state.alg&1)|(chan[ch].state.fb<<1)|((chan[ch].pan&15)<<4));
}
}
} else {
@ -847,10 +879,10 @@ int DivPlatformOPL::dispatch(DivCommand c) {
}
} else {
oldWrites[chanMap[c.chan]+ADDR_LR_FB_ALG]=-1;
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&3)<<4));
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
if (ops==4) {
oldWrites[chanMap[c.chan+1]+ADDR_LR_FB_ALG]=-1;
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&3)<<4));
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
}
}
}
@ -956,10 +988,11 @@ int DivPlatformOPL::dispatch(DivCommand c) {
case DIV_CMD_PANNING: {
if (oplType!=3) break;
if (c.chan==adpcmChan) break;
if (c.value==0 && c.value2==0) {
chan[c.chan].pan=3;
chan[c.chan].pan&=~3;
if (c.value==0 && c.value2==0 && compatPan) {
chan[c.chan].pan|=3;
} else {
chan[c.chan].pan=(c.value>0)|((c.value2>0)<<1);
chan[c.chan].pan|=(c.value>0)|((c.value2>0)<<1);
}
int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
if (isMuted[c.chan]) {
@ -968,9 +1001,36 @@ int DivPlatformOPL::dispatch(DivCommand c) {
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1));
}
} else {
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&3)<<4));
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
if (ops==4) {
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&3)<<4));
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
}
}
break;
}
case DIV_CMD_SURROUND_PANNING: {
if (oplType!=3) break;
if (c.chan==adpcmChan) break;
if (c.value==2) {
chan[c.chan].pan&=3;
if (c.value2>0) chan[c.chan].pan|=4;
} else if (c.value==3) {
if (c.value2>0) chan[c.chan].pan|=8;
} else {
break;
}
int ops=(slots[3][c.chan]!=255 && chan[c.chan].state.ops==4 && oplType==3)?4:2;
if (isMuted[c.chan]) {
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1));
if (ops==4) {
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1));
}
} else {
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
if (ops==4) {
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
}
}
break;
@ -1049,9 +1109,9 @@ int DivPlatformOPL::dispatch(DivCommand c) {
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1));
}
} else {
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&3)<<4));
rWrite(chanMap[c.chan]+ADDR_LR_FB_ALG,(chan[c.chan].state.alg&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
if (ops==4) {
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&3)<<4));
rWrite(chanMap[c.chan+1]+ADDR_LR_FB_ALG,((chan[c.chan].state.alg>>1)&1)|(chan[c.chan].state.fb<<1)|((chan[c.chan].pan&15)<<4));
}
}
break;
@ -1431,9 +1491,9 @@ void DivPlatformOPL::forceIns() {
rWrite(chanMap[i+1]+ADDR_LR_FB_ALG,((chan[i].state.alg>>1)&1)|(chan[i].state.fb<<1));
}
} else {
rWrite(chanMap[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&1)|(chan[i].state.fb<<1)|((chan[i].pan&3)<<4));
rWrite(chanMap[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&1)|(chan[i].state.fb<<1)|((chan[i].pan&15)<<4));
if (ops==4) {
rWrite(chanMap[i+1]+ADDR_LR_FB_ALG,((chan[i].state.alg>>1)&1)|(chan[i].state.fb<<1)|((chan[i].pan&3)<<4));
rWrite(chanMap[i+1]+ADDR_LR_FB_ALG,((chan[i].state.alg>>1)&1)|(chan[i].state.fb<<1)|((chan[i].pan&15)<<4));
}
}
*/
@ -1568,8 +1628,8 @@ void DivPlatformOPL::reset() {
immWrite(0xbd,(dam<<7)|(dvb<<6)|(properDrums<<5)|drumState);
}
bool DivPlatformOPL::isStereo() {
return (oplType==3 || oplType==759);
int DivPlatformOPL::getOutputCount() {
return totalOutputs;
}
bool DivPlatformOPL::keyOffAffectsArp(int ch) {
@ -1625,6 +1685,7 @@ void DivPlatformOPL::setOPLType(int type, bool drums) {
if (type==8950) {
adpcmChan=drums?11:9;
}
totalOutputs=1;
break;
case 3: case 4: case 759:
slotsNonDrums=slotsOPL3;
@ -1643,6 +1704,7 @@ void DivPlatformOPL::setOPLType(int type, bool drums) {
chipFreqBase=32768*684;
downsample=true;
}
totalOutputs=(type==4)?6:4;
break;
}
chipType=type;
@ -1681,6 +1743,8 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) {
rate=chipClock/36;
}*/
compatPan=false;
switch (chipType) {
default:
case 1: case 2: case 8950:
@ -1736,12 +1800,14 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) {
rate=chipClock/768;
chipRateBase=chipClock/684;
downsample=true;
totalOutputs=2; // Stereo output only
break;
default: // YMF262
chipFreqBase=32768*288;
rate=chipClock/288;
chipRateBase=rate;
downsample=false;
totalOutputs=4;
break;
}
reset();
@ -1768,6 +1834,7 @@ void DivPlatformOPL::setFlags(const DivConfig& flags) {
chipClock=rate*288;
break;
}
compatPan=flags.getBool("compatPan",false);
for (int i=0; i<20; i++) {
oscBuf[i]->rate=rate;