OPL: pretend to be YMU and enable SOME emulation?

This commit is contained in:
tildearrow 2022-03-15 00:33:57 -05:00
parent 8355aa0175
commit a65df5cdab
4 changed files with 27 additions and 4 deletions

View file

@ -150,6 +150,10 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
bbInLen=32768; bbInLen=32768;
switch (sys) { switch (sys) {
case DIV_SYSTEM_YMU759:
dispatch=new DivPlatformOPL;
((DivPlatformOPL*)dispatch)->setOPLType(759,false);
break;
case DIV_SYSTEM_YM2612: case DIV_SYSTEM_YM2612:
dispatch=new DivPlatformGenesis; dispatch=new DivPlatformGenesis;
((DivPlatformGenesis*)dispatch)->setYMFM(eng->getConfInt("ym2612Core",0)); ((DivPlatformGenesis*)dispatch)->setYMFM(eng->getConfInt("ym2612Core",0));

View file

@ -223,7 +223,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
} }
ds.customTempo=true; ds.customTempo=true;
ds.timeBase=0; ds.timeBase=0;
addWarning("Yamaha YMU759 emulation is not currently possible!"); addWarning("Yamaha YMU759 emulation is incomplete! please migrate your song to the OPL3 system.");
} }
logI("reading pattern matrix (%d)...\n",ds.ordersLen); logI("reading pattern matrix (%d)...\n",ds.ordersLen);
@ -277,6 +277,9 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
if ((ds.system[0]==DIV_SYSTEM_SMS_OPLL || ds.system[0]==DIV_SYSTEM_NES_VRC7) && ins->type==DIV_INS_FM) { if ((ds.system[0]==DIV_SYSTEM_SMS_OPLL || ds.system[0]==DIV_SYSTEM_NES_VRC7) && ins->type==DIV_INS_FM) {
ins->type=DIV_INS_OPLL; ins->type=DIV_INS_OPLL;
} }
if (ds.system[0]==DIV_SYSTEM_YMU759) {
ins->type=DIV_INS_OPL;
}
if (ins->mode) { // FM if (ins->mode) { // FM
ins->fm.alg=reader.readC(); ins->fm.alg=reader.readC();
@ -573,6 +576,10 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
pat->data[k][1]-=2; pat->data[k][1]-=2;
} }
} }
if (ds.system[0]==DIV_SYSTEM_YMU759 && pat->data[k][0]!=0) {
// apparently YMU759 is stored 2 octaves lower
pat->data[k][1]+=2;
}
if (pat->data[k][0]==0 && pat->data[k][1]!=0) { if (pat->data[k][0]==0 && pat->data[k][1]!=0) {
logD("what? %d:%d:%d note %d octave %d\n",i,j,k,pat->data[k][0],pat->data[k][1]); logD("what? %d:%d:%d note %d octave %d\n",i,j,k,pat->data[k][0],pat->data[k][1]);
pat->data[k][0]=12; pat->data[k][0]=12;

View file

@ -560,6 +560,11 @@ int DivPlatformOPL::dispatch(DivCommand c) {
chan[c.chan].std.release(); chan[c.chan].std.release();
break; break;
case DIV_CMD_VOLUME: { case DIV_CMD_VOLUME: {
if (pretendYMU) {
c.value=pow(((double)c.value/127.0),0.5)*63.0;
if (c.value<0) c.value=0;
if (c.value>63) c.value=63;
}
chan[c.chan].vol=c.value; chan[c.chan].vol=c.value;
if (!chan[c.chan].std.hasVol) { if (!chan[c.chan].std.hasVol) {
chan[c.chan].outVol=c.value; chan[c.chan].outVol=c.value;
@ -716,6 +721,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
return 0; return 0;
break; break;
case DIV_CMD_GET_VOLMAX: case DIV_CMD_GET_VOLMAX:
if (pretendYMU) return 127;
return 63; return 63;
break; break;
case DIV_CMD_PRE_PORTA: case DIV_CMD_PRE_PORTA:
@ -868,6 +874,7 @@ void DivPlatformOPL::setYMFM(bool use) {
} }
void DivPlatformOPL::setOPLType(int type, bool drums) { void DivPlatformOPL::setOPLType(int type, bool drums) {
pretendYMU=false;
switch (type) { switch (type) {
case 1: case 2: case 1: case 2:
slotsNonDrums=slotsOPL2; slotsNonDrums=slotsOPL2;
@ -879,7 +886,7 @@ void DivPlatformOPL::setOPLType(int type, bool drums) {
melodicChans=drums?6:9; melodicChans=drums?6:9;
totalChans=drums?11:9; totalChans=drums?11:9;
break; break;
case 3: case 3: case 759:
slotsNonDrums=slotsOPL3; slotsNonDrums=slotsOPL3;
slotsDrums=slotsOPL3Drums; slotsDrums=slotsOPL3Drums;
slots=drums?slotsDrums:slotsNonDrums; slots=drums?slotsDrums:slotsNonDrums;
@ -888,9 +895,14 @@ void DivPlatformOPL::setOPLType(int type, bool drums) {
chans=18; chans=18;
melodicChans=drums?15:18; melodicChans=drums?15:18;
totalChans=drums?20:18; totalChans=drums?20:18;
if (type==759) pretendYMU=true;
break; break;
} }
oplType=type; if (type==759) {
oplType=3;
} else {
oplType=type;
}
properDrumsSys=drums; properDrumsSys=drums;
} }

View file

@ -79,7 +79,7 @@ class DivPlatformOPL: public DivDispatch {
unsigned char lfoValue; unsigned char lfoValue;
bool useYMFM, update4OpMask; bool useYMFM, update4OpMask, pretendYMU;
short oldWrites[512]; short oldWrites[512];
short pendingWrites[512]; short pendingWrites[512];