diff --git a/src/engine/dispatchContainer.cpp b/src/engine/dispatchContainer.cpp index 3dcf17a8f..62daaafe0 100644 --- a/src/engine/dispatchContainer.cpp +++ b/src/engine/dispatchContainer.cpp @@ -150,6 +150,10 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do bbInLen=32768; switch (sys) { + case DIV_SYSTEM_YMU759: + dispatch=new DivPlatformOPL; + ((DivPlatformOPL*)dispatch)->setOPLType(759,false); + break; case DIV_SYSTEM_YM2612: dispatch=new DivPlatformGenesis; ((DivPlatformGenesis*)dispatch)->setYMFM(eng->getConfInt("ym2612Core",0)); diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index da4ca4e82..4400567eb 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -223,7 +223,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { } ds.customTempo=true; 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); @@ -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) { ins->type=DIV_INS_OPLL; } + if (ds.system[0]==DIV_SYSTEM_YMU759) { + ins->type=DIV_INS_OPL; + } if (ins->mode) { // FM ins->fm.alg=reader.readC(); @@ -573,6 +576,10 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { 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) { 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; diff --git a/src/engine/platform/opl.cpp b/src/engine/platform/opl.cpp index 84e8dd260..443ef81d6 100644 --- a/src/engine/platform/opl.cpp +++ b/src/engine/platform/opl.cpp @@ -560,6 +560,11 @@ int DivPlatformOPL::dispatch(DivCommand c) { chan[c.chan].std.release(); break; 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; if (!chan[c.chan].std.hasVol) { chan[c.chan].outVol=c.value; @@ -716,6 +721,7 @@ int DivPlatformOPL::dispatch(DivCommand c) { return 0; break; case DIV_CMD_GET_VOLMAX: + if (pretendYMU) return 127; return 63; break; case DIV_CMD_PRE_PORTA: @@ -868,6 +874,7 @@ void DivPlatformOPL::setYMFM(bool use) { } void DivPlatformOPL::setOPLType(int type, bool drums) { + pretendYMU=false; switch (type) { case 1: case 2: slotsNonDrums=slotsOPL2; @@ -879,7 +886,7 @@ void DivPlatformOPL::setOPLType(int type, bool drums) { melodicChans=drums?6:9; totalChans=drums?11:9; break; - case 3: + case 3: case 759: slotsNonDrums=slotsOPL3; slotsDrums=slotsOPL3Drums; slots=drums?slotsDrums:slotsNonDrums; @@ -888,9 +895,14 @@ void DivPlatformOPL::setOPLType(int type, bool drums) { chans=18; melodicChans=drums?15:18; totalChans=drums?20:18; + if (type==759) pretendYMU=true; break; } - oplType=type; + if (type==759) { + oplType=3; + } else { + oplType=type; + } properDrumsSys=drums; } diff --git a/src/engine/platform/opl.h b/src/engine/platform/opl.h index b8bd11d69..8f0994bb5 100644 --- a/src/engine/platform/opl.h +++ b/src/engine/platform/opl.h @@ -79,7 +79,7 @@ class DivPlatformOPL: public DivDispatch { unsigned char lfoValue; - bool useYMFM, update4OpMask; + bool useYMFM, update4OpMask, pretendYMU; short oldWrites[512]; short pendingWrites[512];