Re-split OPL4 PCM instruments due to hardware differences
- MultiPCM also has level direct, so it's remained in DivInstrumentMultiPCM. everything else don't support at MultiPCM is moved into DivInstrumentOPL4PCM. - MultiPCM can't modify ADSR envelope unless reading instrument from ROM, so I decided to remove ADSR envelope macros. these are moved into OPL4 PCM instrument. - Save/Load of MultiPCM level direct parameter is still disabled until main version update (for disallow crash). - Also, this PR fixes OPL4 VGM output.
This commit is contained in:
parent
ec5879f10b
commit
87ac12e143
11 changed files with 201 additions and 50 deletions
|
|
@ -938,7 +938,8 @@ void DivEngine::delUnusedSamples() {
|
|||
i->type==DIV_INS_C219 ||
|
||||
i->type==DIV_INS_NDS ||
|
||||
i->type==DIV_INS_GBA_DMA ||
|
||||
i->type==DIV_INS_GBA_MINMOD) {
|
||||
i->type==DIV_INS_GBA_MINMOD ||
|
||||
i->type==DIV_INS_OPL4_PCM) {
|
||||
if (i->amiga.initSample>=0 && i->amiga.initSample<song.sampleLen) {
|
||||
isUsed[i->amiga.initSample]=true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,9 +175,6 @@ bool DivInstrumentMultiPCM::operator==(const DivInstrumentMultiPCM& other) {
|
|||
_C(lfo) &&
|
||||
_C(vib) &&
|
||||
_C(am) &&
|
||||
_C(damp) &&
|
||||
_C(pseudoReverb) &&
|
||||
_C(lfoReset) &&
|
||||
_C(levelDirect)
|
||||
);
|
||||
}
|
||||
|
|
@ -270,6 +267,14 @@ bool DivInstrumentSID2::operator==(const DivInstrumentSID2& other) {
|
|||
);
|
||||
}
|
||||
|
||||
bool DivInstrumentOPL4PCM::operator==(const DivInstrumentOPL4PCM& other) {
|
||||
return (
|
||||
_C(damp) &&
|
||||
_C(pseudoReverb) &&
|
||||
_C(lfoReset)
|
||||
);
|
||||
}
|
||||
|
||||
#undef _C
|
||||
|
||||
#define CONSIDER(x,t) \
|
||||
|
|
@ -762,9 +767,6 @@ void DivInstrument::writeFeatureMP(SafeWriter* w) {
|
|||
w->writeC(multipcm.am);
|
||||
|
||||
/*
|
||||
w->writeC(multipcm.damp);
|
||||
w->writeC(multipcm.pseudoReverb);
|
||||
w->writeC(multipcm.lfoReset);
|
||||
w->writeC(multipcm.levelDirect);
|
||||
*/
|
||||
|
||||
|
|
@ -859,6 +861,16 @@ void DivInstrument::writeFeatureS2(SafeWriter* w) {
|
|||
FEATURE_END;
|
||||
}
|
||||
|
||||
void DivInstrument::writeFeatureOP(SafeWriter* w) {
|
||||
FEATURE_BEGIN("OP");
|
||||
|
||||
w->writeC(opl4pcm.damp);
|
||||
w->writeC(opl4pcm.pseudoReverb);
|
||||
w->writeC(opl4pcm.lfoReset);
|
||||
|
||||
FEATURE_END;
|
||||
}
|
||||
|
||||
void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bool insName) {
|
||||
size_t blockStartSeek=0;
|
||||
size_t blockEndSeek=0;
|
||||
|
|
@ -905,6 +917,7 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo
|
|||
bool featureEF=false;
|
||||
bool featurePN=false;
|
||||
bool featureS2=false;
|
||||
bool featureOP=false;
|
||||
|
||||
bool checkForWL=false;
|
||||
|
||||
|
|
@ -1148,6 +1161,12 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo
|
|||
feature64=true;
|
||||
featureS2=true;
|
||||
break;
|
||||
case DIV_INS_OPL4_PCM:
|
||||
featureSM=true;
|
||||
featureSL=true;
|
||||
featureMP=true;
|
||||
featureOP=true;
|
||||
break;
|
||||
case DIV_INS_MAX:
|
||||
break;
|
||||
case DIV_INS_NULL:
|
||||
|
|
@ -1204,6 +1223,9 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo
|
|||
if (sid2!=defaultIns.sid2) {
|
||||
featureS2=true;
|
||||
}
|
||||
if (opl4pcm!=defaultIns.opl4pcm) {
|
||||
featureOP=true;
|
||||
}
|
||||
}
|
||||
|
||||
// check ins name
|
||||
|
|
@ -1355,6 +1377,9 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo
|
|||
if (featureS2) {
|
||||
writeFeatureS2(w);
|
||||
}
|
||||
if (featureOP) {
|
||||
writeFeatureOP(w);
|
||||
}
|
||||
|
||||
if (fui && (featureSL || featureWL)) {
|
||||
w->write("EN",2);
|
||||
|
|
@ -2077,9 +2102,6 @@ void DivInstrument::readFeatureMP(SafeReader& reader, short version) {
|
|||
multipcm.am=reader.readC();
|
||||
|
||||
/*
|
||||
multipcm.damp=reader.readC();
|
||||
multipcm.pseudoReverb=reader.readC();
|
||||
multipcm.lfoReset=reader.readC();
|
||||
multipcm.levelDirect=reader.readC();
|
||||
*/
|
||||
|
||||
|
|
@ -2190,6 +2212,16 @@ void DivInstrument::readFeatureS2(SafeReader& reader, short version) {
|
|||
READ_FEAT_END;
|
||||
}
|
||||
|
||||
void DivInstrument::readFeatureOP(SafeReader& reader, short version) {
|
||||
READ_FEAT_BEGIN;
|
||||
|
||||
opl4pcm.damp=reader.readC();
|
||||
opl4pcm.pseudoReverb=reader.readC();
|
||||
opl4pcm.lfoReset=reader.readC();
|
||||
|
||||
READ_FEAT_END;
|
||||
}
|
||||
|
||||
|
||||
DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, bool fui, DivSong* song) {
|
||||
unsigned char featCode[2];
|
||||
|
|
@ -2265,6 +2297,8 @@ DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, b
|
|||
readFeaturePN(reader,version);
|
||||
} else if (memcmp(featCode,"S2",2)==0) { // SID2
|
||||
readFeatureS2(reader,version);
|
||||
} else if (memcmp(featCode,"OP",2)==0) { // OPL4 PCM
|
||||
readFeatureOP(reader,version);
|
||||
} else {
|
||||
if (song==NULL && (memcmp(featCode,"SL",2)==0 || (memcmp(featCode,"WL",2)==0))) {
|
||||
// nothing
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ enum DivInstrumentType: unsigned short {
|
|||
DIV_INS_GBA_MINMOD=61,
|
||||
DIV_INS_BIFURCATOR=62,
|
||||
DIV_INS_SID2=63, // coincidence!
|
||||
DIV_INS_OPL4_PCM=64,
|
||||
DIV_INS_MAX,
|
||||
DIV_INS_NULL
|
||||
};
|
||||
|
|
@ -608,7 +609,7 @@ struct DivInstrumentFDS {
|
|||
struct DivInstrumentMultiPCM {
|
||||
unsigned char ar, d1r, dl, d2r, rr, rc;
|
||||
unsigned char lfo, vib, am;
|
||||
bool damp, pseudoReverb, lfoReset, levelDirect;
|
||||
bool levelDirect;
|
||||
|
||||
bool operator==(const DivInstrumentMultiPCM& other);
|
||||
bool operator!=(const DivInstrumentMultiPCM& other) {
|
||||
|
|
@ -618,9 +619,6 @@ struct DivInstrumentMultiPCM {
|
|||
DivInstrumentMultiPCM():
|
||||
ar(15), d1r(15), dl(0), d2r(0), rr(15), rc(15),
|
||||
lfo(0), vib(0), am(0),
|
||||
damp(false),
|
||||
pseudoReverb(false),
|
||||
lfoReset(false),
|
||||
levelDirect(true) {
|
||||
}
|
||||
};
|
||||
|
|
@ -865,6 +863,21 @@ struct DivInstrumentSID2 {
|
|||
noiseMode(0) {}
|
||||
};
|
||||
|
||||
struct DivInstrumentOPL4PCM {
|
||||
bool damp, pseudoReverb, lfoReset;
|
||||
|
||||
bool operator==(const DivInstrumentOPL4PCM& other);
|
||||
bool operator!=(const DivInstrumentOPL4PCM& other) {
|
||||
return !(*this==other);
|
||||
}
|
||||
|
||||
DivInstrumentOPL4PCM():
|
||||
damp(false),
|
||||
pseudoReverb(false),
|
||||
lfoReset(false) {
|
||||
}
|
||||
};
|
||||
|
||||
struct DivInstrument {
|
||||
String name;
|
||||
DivInstrumentType type;
|
||||
|
|
@ -884,6 +897,7 @@ struct DivInstrument {
|
|||
DivInstrumentESFM esfm;
|
||||
DivInstrumentPowerNoise powernoise;
|
||||
DivInstrumentSID2 sid2;
|
||||
DivInstrumentOPL4PCM opl4pcm;
|
||||
|
||||
/**
|
||||
* these are internal functions.
|
||||
|
|
@ -911,6 +925,7 @@ struct DivInstrument {
|
|||
void writeFeatureEF(SafeWriter* w);
|
||||
void writeFeaturePN(SafeWriter* w);
|
||||
void writeFeatureS2(SafeWriter* w);
|
||||
void writeFeatureOP(SafeWriter* w);
|
||||
|
||||
void readFeatureNA(SafeReader& reader, short version);
|
||||
void readFeatureFM(SafeReader& reader, short version);
|
||||
|
|
@ -934,6 +949,7 @@ struct DivInstrument {
|
|||
void readFeatureEF(SafeReader& reader, short version);
|
||||
void readFeaturePN(SafeReader& reader, short version);
|
||||
void readFeatureS2(SafeReader& reader, short version);
|
||||
void readFeatureOP(SafeReader& reader, short version);
|
||||
|
||||
DivDataErrors readInsDataOld(SafeReader& reader, short version);
|
||||
DivDataErrors readInsDataNew(SafeReader& reader, short version, bool fui, DivSong* song);
|
||||
|
|
|
|||
|
|
@ -1711,7 +1711,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
chan[c.chan].freqChanged=true;
|
||||
chan[c.chan].note=c.value;
|
||||
}
|
||||
if (ins->type==DIV_INS_MULTIPCM) {
|
||||
if (ins->type==DIV_INS_OPL4_PCM) {
|
||||
chan[c.chan].lfo=ins->multipcm.lfo;
|
||||
chan[c.chan].vib=ins->multipcm.vib;
|
||||
chan[c.chan].am=ins->multipcm.am;
|
||||
|
|
@ -1721,10 +1721,10 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
chan[c.chan].d2r=ins->multipcm.d2r;
|
||||
chan[c.chan].rc=ins->multipcm.rc;
|
||||
chan[c.chan].rr=ins->multipcm.rr;
|
||||
chan[c.chan].damp=ins->multipcm.damp;
|
||||
chan[c.chan].pseudoReverb=ins->multipcm.pseudoReverb;
|
||||
chan[c.chan].levelDirect=ins->multipcm.levelDirect;
|
||||
chan[c.chan].lfoReset=ins->multipcm.lfoReset;
|
||||
chan[c.chan].damp=ins->opl4pcm.damp;
|
||||
chan[c.chan].pseudoReverb=ins->opl4pcm.pseudoReverb;
|
||||
chan[c.chan].lfoReset=ins->opl4pcm.lfoReset;
|
||||
} else {
|
||||
chan[c.chan].lfo=0;
|
||||
chan[c.chan].vib=0;
|
||||
|
|
|
|||
|
|
@ -1640,7 +1640,7 @@ void DivEngine::registerSystems() {
|
|||
{_("4OP 1"), _("FM 2"), _("4OP 3"), _("FM 4"), _("4OP 5"), _("FM 6"), _("4OP 7"), _("FM 8"), _("4OP 9"), _("FM 10"), _("4OP 11"), _("FM 12"), _("FM 13"), _("FM 14"), _("FM 15"), _("FM 16"), _("FM 17"), _("FM 18"), _("PCM 1"), _("PCM 2"), _("PCM 3"), _("PCM 4"), _("PCM 5"), _("PCM 6"), _("PCM 7"), _("PCM 8"), _("PCM 9"), _("PCM 10"), _("PCM 11"), _("PCM 12"), _("PCM 13"), _("PCM 14"), _("PCM 15"), _("PCM 16"), _("PCM 17"), _("PCM 18"), _("PCM 19"), _("PCM 20"), _("PCM 21"), _("PCM 22"), _("PCM 23"), _("PCM 24")},
|
||||
{"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15", "F16", "F17", "F18", "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9", "P10", "P11", "P12", "P13", "P14", "P15", "P16", "P17", "P18", "P19", "P20", "P21", "P22", "P23", "P24"},
|
||||
{DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
||||
{DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM},
|
||||
{DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM},
|
||||
{DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA},
|
||||
fmEffectHandlerMap,
|
||||
fmOPL4PostEffectHandlerMap
|
||||
|
|
@ -1653,7 +1653,7 @@ void DivEngine::registerSystems() {
|
|||
{_("4OP 1"), _("FM 2"), _("4OP 3"), _("FM 4"), _("4OP 5"), _("FM 6"), _("4OP 7"), _("FM 8"), _("4OP 9"), _("FM 10"), _("4OP 11"), _("FM 12"), _("FM 13"), _("FM 14"), _("FM 15"), _("Kick/FM 16"), _("Snare"), _("Tom"), _("Top"), _("HiHat"), _("PCM 1"), _("PCM 2"), _("PCM 3"), _("PCM 4"), _("PCM 5"), _("PCM 6"), _("PCM 7"), _("PCM 8"), _("PCM 9"), _("PCM 10"), _("PCM 11"), _("PCM 12"), _("PCM 13"), _("PCM 14"), _("PCM 15"), _("PCM 16"), _("PCM 17"), _("PCM 18"), _("PCM 19"), _("PCM 20"), _("PCM 21"), _("PCM 22"), _("PCM 23"), _("PCM 24")},
|
||||
{"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12", "F13", "F14", "F15", "BD", "SD", "TM", "TP", "HH", "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9", "P10", "P11", "P12", "P13", "P14", "P15", "P16", "P17", "P18", "P19", "P20", "P21", "P22", "P23", "P24"},
|
||||
{DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_OP, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_FM, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_NOISE, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
|
||||
{DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM, DIV_INS_MULTIPCM},
|
||||
{DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM, DIV_INS_OPL4_PCM},
|
||||
{DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_OPL, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA},
|
||||
fmOPLDrumsEffectHandlerMap,
|
||||
fmOPL4PostEffectHandlerMap
|
||||
|
|
|
|||
|
|
@ -615,6 +615,96 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
|||
w->writeC(0);
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_OPL4:
|
||||
case DIV_SYSTEM_OPL4_DRUMS:
|
||||
// disable envelope
|
||||
for (int i=0; i<6; i++) {
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x00|baseAddr2);
|
||||
w->writeC(0x80+i);
|
||||
w->writeC(0x0f);
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x00|baseAddr2);
|
||||
w->writeC(0x88+i);
|
||||
w->writeC(0x0f);
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x00|baseAddr2);
|
||||
w->writeC(0x90+i);
|
||||
w->writeC(0x0f);
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x01|baseAddr2);
|
||||
w->writeC(0x80+i);
|
||||
w->writeC(0x0f);
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x01|baseAddr2);
|
||||
w->writeC(0x88+i);
|
||||
w->writeC(0x0f);
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x01|baseAddr2);
|
||||
w->writeC(0x90+i);
|
||||
w->writeC(0x0f);
|
||||
}
|
||||
for (int i=0; i<24; i++) {
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x02|baseAddr2);
|
||||
w->writeC(0x80+i);
|
||||
w->writeC(0x00);
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x02|baseAddr2);
|
||||
w->writeC(0x98+i);
|
||||
w->writeC(0x00);
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x02|baseAddr2);
|
||||
w->writeC(0xb0+i);
|
||||
w->writeC(0x00);
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x02|baseAddr2);
|
||||
w->writeC(0xc8+i);
|
||||
w->writeC(0x00);
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x02|baseAddr2);
|
||||
w->writeC(0xe0+i);
|
||||
w->writeC(0x00);
|
||||
}
|
||||
// key off + freq reset
|
||||
for (int i=0; i<9; i++) {
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x00|baseAddr2);
|
||||
w->writeC(0xa0+i);
|
||||
w->writeC(0);
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x00|baseAddr2);
|
||||
w->writeC(0xb0+i);
|
||||
w->writeC(0);
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x01|baseAddr2);
|
||||
w->writeC(0xa0+i);
|
||||
w->writeC(0);
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x01|baseAddr2);
|
||||
w->writeC(0xb0+i);
|
||||
w->writeC(0);
|
||||
}
|
||||
for (int i=0; i<24; i++) {
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x02|baseAddr2);
|
||||
w->writeC(0x20+i);
|
||||
w->writeC(0);
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x02|baseAddr2);
|
||||
w->writeC(0x38+i);
|
||||
w->writeC(0);
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x02|baseAddr2);
|
||||
w->writeC(0x68+i);
|
||||
w->writeC(8);
|
||||
}
|
||||
// reset 4-op
|
||||
w->writeC(0xd0);
|
||||
w->writeC(0x01|baseAddr2);
|
||||
w->writeC(0x04);
|
||||
w->writeC(0x00);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -987,13 +1077,6 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case DIV_SYSTEM_OPL4:
|
||||
case DIV_SYSTEM_OPL4_DRUMS:
|
||||
w->writeC(0xd0|baseAddr2);
|
||||
w->writeC(write.addr>>8);
|
||||
w->writeC(write.addr&0xff);
|
||||
w->writeC(write.val);
|
||||
break;
|
||||
case DIV_SYSTEM_SCC:
|
||||
if (write.addr<0x80) {
|
||||
w->writeC(0xd2);
|
||||
|
|
@ -1096,6 +1179,13 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
|||
w->writeS_BE(baseAddr2S|(write.addr&0x1ff));
|
||||
w->writeC(write.val&0xff);
|
||||
break;
|
||||
case DIV_SYSTEM_OPL4:
|
||||
case DIV_SYSTEM_OPL4_DRUMS:
|
||||
w->writeC(0xd0);
|
||||
w->writeC(((write.addr>>8)&0x7f)|baseAddr2);
|
||||
w->writeC(write.addr&0xff);
|
||||
w->writeC(write.val);
|
||||
break;
|
||||
default:
|
||||
logW("write not handled!");
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue