Add instrument for OPL4 PCM, Macros and Effects
TODO: Phase reset, Keyon/off
This commit is contained in:
parent
221fa5aa42
commit
65f48cc574
|
@ -263,6 +263,22 @@ enum DivDispatchCmds {
|
||||||
DIV_CMD_BIFURCATOR_STATE_LOAD,
|
DIV_CMD_BIFURCATOR_STATE_LOAD,
|
||||||
DIV_CMD_BIFURCATOR_PARAMETER,
|
DIV_CMD_BIFURCATOR_PARAMETER,
|
||||||
|
|
||||||
|
DIV_CMD_OPL4_PCM_MIX_FM, // (value)
|
||||||
|
DIV_CMD_OPL4_PCM_MIX_PCM, // (value)
|
||||||
|
DIV_CMD_OPL4_PCM_LFO, // (value)
|
||||||
|
DIV_CMD_OPL4_PCM_VIB, // (value)
|
||||||
|
DIV_CMD_OPL4_PCM_AM, // (value)
|
||||||
|
DIV_CMD_OPL4_PCM_AR, // (value)
|
||||||
|
DIV_CMD_OPL4_PCM_D1R, // (value)
|
||||||
|
DIV_CMD_OPL4_PCM_DL, // (value)
|
||||||
|
DIV_CMD_OPL4_PCM_D2R, // (value)
|
||||||
|
DIV_CMD_OPL4_PCM_RC, // (value)
|
||||||
|
DIV_CMD_OPL4_PCM_RR, // (value)
|
||||||
|
DIV_CMD_OPL4_PCM_DAMP, // (value)
|
||||||
|
DIV_CMD_OPL4_PCM_PSEUDO_REVERB, // (value)
|
||||||
|
DIV_CMD_OPL4_PCM_LFO_RESET, // (value)
|
||||||
|
DIV_CMD_OPL4_PCM_LEVEL_DIRECT, // (value)
|
||||||
|
|
||||||
DIV_CMD_MAX
|
DIV_CMD_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -938,7 +938,8 @@ void DivEngine::delUnusedSamples() {
|
||||||
i->type==DIV_INS_C219 ||
|
i->type==DIV_INS_C219 ||
|
||||||
i->type==DIV_INS_NDS ||
|
i->type==DIV_INS_NDS ||
|
||||||
i->type==DIV_INS_GBA_DMA ||
|
i->type==DIV_INS_GBA_DMA ||
|
||||||
i->type==DIV_INS_GBA_MINMOD) {
|
i->type==DIV_INS_GBA_MINMOD ||
|
||||||
|
i->type==DIV_INS_OPL4PCM) {
|
||||||
if (i->amiga.initSample>=0 && i->amiga.initSample<song.sampleLen) {
|
if (i->amiga.initSample>=0 && i->amiga.initSample<song.sampleLen) {
|
||||||
isUsed[i->amiga.initSample]=true;
|
isUsed[i->amiga.initSample]=true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,6 +178,15 @@ bool DivInstrumentMultiPCM::operator==(const DivInstrumentMultiPCM& other) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DivInstrumentOPL4PCM::operator==(const DivInstrumentOPL4PCM& other) {
|
||||||
|
return (
|
||||||
|
_C(damp) &&
|
||||||
|
_C(pseudoReverb) &&
|
||||||
|
_C(lfoReset) &&
|
||||||
|
_C(levelDirect)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
bool DivInstrumentWaveSynth::operator==(const DivInstrumentWaveSynth& other) {
|
bool DivInstrumentWaveSynth::operator==(const DivInstrumentWaveSynth& other) {
|
||||||
return (
|
return (
|
||||||
_C(wave1) &&
|
_C(wave1) &&
|
||||||
|
@ -848,6 +857,17 @@ void DivInstrument::writeFeatureS2(SafeWriter* w) {
|
||||||
FEATURE_END;
|
FEATURE_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DivInstrument::writeFeatureO4(SafeWriter* w) {
|
||||||
|
FEATURE_BEGIN("O4");
|
||||||
|
|
||||||
|
w->writeC(opl4pcm.damp);
|
||||||
|
w->writeC(opl4pcm.pseudoReverb);
|
||||||
|
w->writeC(opl4pcm.lfoReset);
|
||||||
|
w->writeC(opl4pcm.levelDirect);
|
||||||
|
|
||||||
|
FEATURE_END;
|
||||||
|
}
|
||||||
|
|
||||||
void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bool insName) {
|
void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bool insName) {
|
||||||
size_t blockStartSeek=0;
|
size_t blockStartSeek=0;
|
||||||
size_t blockEndSeek=0;
|
size_t blockEndSeek=0;
|
||||||
|
@ -894,6 +914,7 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo
|
||||||
bool featureEF=false;
|
bool featureEF=false;
|
||||||
bool featurePN=false;
|
bool featurePN=false;
|
||||||
bool featureS2=false;
|
bool featureS2=false;
|
||||||
|
bool featureO4=false;
|
||||||
|
|
||||||
bool checkForWL=false;
|
bool checkForWL=false;
|
||||||
|
|
||||||
|
@ -1137,6 +1158,12 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo
|
||||||
feature64=true;
|
feature64=true;
|
||||||
featureS2=true;
|
featureS2=true;
|
||||||
break;
|
break;
|
||||||
|
case DIV_INS_OPL4PCM:
|
||||||
|
featureSM=true;
|
||||||
|
featureSL=true;
|
||||||
|
featureMP=true;
|
||||||
|
featureO4=true;
|
||||||
|
break;
|
||||||
case DIV_INS_MAX:
|
case DIV_INS_MAX:
|
||||||
break;
|
break;
|
||||||
case DIV_INS_NULL:
|
case DIV_INS_NULL:
|
||||||
|
@ -1193,6 +1220,9 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo
|
||||||
if (sid2!=defaultIns.sid2) {
|
if (sid2!=defaultIns.sid2) {
|
||||||
featureS2=true;
|
featureS2=true;
|
||||||
}
|
}
|
||||||
|
if (opl4pcm!=defaultIns.opl4pcm) {
|
||||||
|
featureO4=true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check ins name
|
// check ins name
|
||||||
|
@ -1344,6 +1374,9 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo
|
||||||
if (featureS2) {
|
if (featureS2) {
|
||||||
writeFeatureS2(w);
|
writeFeatureS2(w);
|
||||||
}
|
}
|
||||||
|
if (featureO4) {
|
||||||
|
writeFeatureO4(w);
|
||||||
|
}
|
||||||
|
|
||||||
if (fui && (featureSL || featureWL)) {
|
if (fui && (featureSL || featureWL)) {
|
||||||
w->write("EN",2);
|
w->write("EN",2);
|
||||||
|
@ -2172,6 +2205,17 @@ void DivInstrument::readFeatureS2(SafeReader& reader, short version) {
|
||||||
READ_FEAT_END;
|
READ_FEAT_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DivInstrument::readFeatureO4(SafeReader& reader, short version) {
|
||||||
|
READ_FEAT_BEGIN;
|
||||||
|
|
||||||
|
opl4pcm.damp=reader.readC();
|
||||||
|
opl4pcm.pseudoReverb=reader.readC();
|
||||||
|
opl4pcm.lfoReset=reader.readC();
|
||||||
|
opl4pcm.levelDirect=reader.readC();
|
||||||
|
|
||||||
|
READ_FEAT_END;
|
||||||
|
}
|
||||||
|
|
||||||
DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, bool fui, DivSong* song) {
|
DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, bool fui, DivSong* song) {
|
||||||
unsigned char featCode[2];
|
unsigned char featCode[2];
|
||||||
bool volIsCutoff=false;
|
bool volIsCutoff=false;
|
||||||
|
@ -2246,6 +2290,8 @@ DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, b
|
||||||
readFeaturePN(reader,version);
|
readFeaturePN(reader,version);
|
||||||
} else if (memcmp(featCode,"S2",2)==0) { // SID2
|
} else if (memcmp(featCode,"S2",2)==0) { // SID2
|
||||||
readFeatureS2(reader,version);
|
readFeatureS2(reader,version);
|
||||||
|
} else if (memcmp(featCode,"O4",2)==0) { // OPL4 PCM
|
||||||
|
readFeatureO4(reader,version);
|
||||||
} else {
|
} else {
|
||||||
if (song==NULL && (memcmp(featCode,"SL",2)==0 || (memcmp(featCode,"WL",2)==0))) {
|
if (song==NULL && (memcmp(featCode,"SL",2)==0 || (memcmp(featCode,"WL",2)==0))) {
|
||||||
// nothing
|
// nothing
|
||||||
|
|
|
@ -94,6 +94,7 @@ enum DivInstrumentType: unsigned short {
|
||||||
DIV_INS_GBA_MINMOD=61,
|
DIV_INS_GBA_MINMOD=61,
|
||||||
DIV_INS_BIFURCATOR=62,
|
DIV_INS_BIFURCATOR=62,
|
||||||
DIV_INS_SID2=63, // coincidence!
|
DIV_INS_SID2=63, // coincidence!
|
||||||
|
DIV_INS_OPL4PCM=64,
|
||||||
DIV_INS_MAX,
|
DIV_INS_MAX,
|
||||||
DIV_INS_NULL
|
DIV_INS_NULL
|
||||||
};
|
};
|
||||||
|
@ -620,6 +621,22 @@ struct DivInstrumentMultiPCM {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DivInstrumentOPL4PCM {
|
||||||
|
bool damp, pseudoReverb, lfoReset, levelDirect;
|
||||||
|
|
||||||
|
bool operator==(const DivInstrumentOPL4PCM& other);
|
||||||
|
bool operator!=(const DivInstrumentOPL4PCM& other) {
|
||||||
|
return !(*this==other);
|
||||||
|
}
|
||||||
|
|
||||||
|
DivInstrumentOPL4PCM():
|
||||||
|
damp(false),
|
||||||
|
pseudoReverb(false),
|
||||||
|
lfoReset(false),
|
||||||
|
levelDirect(true) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
enum DivWaveSynthEffects {
|
enum DivWaveSynthEffects {
|
||||||
DIV_WS_NONE=0,
|
DIV_WS_NONE=0,
|
||||||
// one waveform effects
|
// one waveform effects
|
||||||
|
@ -879,6 +896,7 @@ struct DivInstrument {
|
||||||
DivInstrumentESFM esfm;
|
DivInstrumentESFM esfm;
|
||||||
DivInstrumentPowerNoise powernoise;
|
DivInstrumentPowerNoise powernoise;
|
||||||
DivInstrumentSID2 sid2;
|
DivInstrumentSID2 sid2;
|
||||||
|
DivInstrumentOPL4PCM opl4pcm;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* these are internal functions.
|
* these are internal functions.
|
||||||
|
@ -906,6 +924,7 @@ struct DivInstrument {
|
||||||
void writeFeatureEF(SafeWriter* w);
|
void writeFeatureEF(SafeWriter* w);
|
||||||
void writeFeaturePN(SafeWriter* w);
|
void writeFeaturePN(SafeWriter* w);
|
||||||
void writeFeatureS2(SafeWriter* w);
|
void writeFeatureS2(SafeWriter* w);
|
||||||
|
void writeFeatureO4(SafeWriter* w);
|
||||||
|
|
||||||
void readFeatureNA(SafeReader& reader, short version);
|
void readFeatureNA(SafeReader& reader, short version);
|
||||||
void readFeatureFM(SafeReader& reader, short version);
|
void readFeatureFM(SafeReader& reader, short version);
|
||||||
|
@ -929,6 +948,7 @@ struct DivInstrument {
|
||||||
void readFeatureEF(SafeReader& reader, short version);
|
void readFeatureEF(SafeReader& reader, short version);
|
||||||
void readFeaturePN(SafeReader& reader, short version);
|
void readFeaturePN(SafeReader& reader, short version);
|
||||||
void readFeatureS2(SafeReader& reader, short version);
|
void readFeatureS2(SafeReader& reader, short version);
|
||||||
|
void readFeatureO4(SafeReader& reader, short version);
|
||||||
|
|
||||||
DivDataErrors readInsDataOld(SafeReader& reader, short version);
|
DivDataErrors readInsDataOld(SafeReader& reader, short version);
|
||||||
DivDataErrors readInsDataNew(SafeReader& reader, short version, bool fui, DivSong* song);
|
DivDataErrors readInsDataNew(SafeReader& reader, short version, bool fui, DivSong* song);
|
||||||
|
|
|
@ -1002,9 +1002,10 @@ void DivPlatformOPL::tick(bool sysTick) {
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan[i].std.phaseReset.had) {
|
if (chan[i].std.phaseReset.had) { // TODO: not working
|
||||||
if (chan[i].std.phaseReset.val==1 && chan[i].active) {
|
if (chan[i].std.phaseReset.val==1 && chan[i].active) {
|
||||||
chan[i].keyOn=true;
|
chan[i].keyOn=true;
|
||||||
|
chan[i].writeCtrl=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1014,78 +1015,51 @@ void DivPlatformOPL::tick(bool sysTick) {
|
||||||
chan[i].writeCtrl=true;
|
chan[i].writeCtrl=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].std.ex1.had) {
|
||||||
DivSample* s=parent->getSample(chan[i].sample);
|
chan[i].lfo=chan[i].std.ex1.val&0x7;
|
||||||
unsigned char ctrl=0;
|
rWrite(PCM_ADDR_LFO_VIB+PCM_REG(i),(chan[i].lfo<<3)|(chan[i].vib));
|
||||||
double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0;
|
|
||||||
chan[i].freq=(int)(off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,(524288*768)));
|
|
||||||
if (chan[i].freq<0x400) chan[i].freq=0x400;
|
|
||||||
if (chan[i].freq>0x4000000) chan[i].freq=0x4000000;
|
|
||||||
if (chan[i].freq>=0x2000000) {
|
|
||||||
chan[i].freqH=15;
|
|
||||||
} else if (chan[i].freq>=0x1000000) {
|
|
||||||
chan[i].freqH=14;
|
|
||||||
} else if (chan[i].freq>=0x800000) {
|
|
||||||
chan[i].freqH=13;
|
|
||||||
} else if (chan[i].freq>=0x400000) {
|
|
||||||
chan[i].freqH=12;
|
|
||||||
} else if (chan[i].freq>=0x200000) {
|
|
||||||
chan[i].freqH=11;
|
|
||||||
} else if (chan[i].freq>=0x100000) {
|
|
||||||
chan[i].freqH=10;
|
|
||||||
} else if (chan[i].freq>=0x80000) {
|
|
||||||
chan[i].freqH=9;
|
|
||||||
} else if (chan[i].freq>=0x40000) {
|
|
||||||
chan[i].freqH=8;
|
|
||||||
} else if (chan[i].freq>=0x20000) {
|
|
||||||
chan[i].freqH=7;
|
|
||||||
} else if (chan[i].freq>=0x10000) {
|
|
||||||
chan[i].freqH=6;
|
|
||||||
} else if (chan[i].freq>=0x8000) {
|
|
||||||
chan[i].freqH=5;
|
|
||||||
} else if (chan[i].freq>=0x4000) {
|
|
||||||
chan[i].freqH=4;
|
|
||||||
} else if (chan[i].freq>=0x2000) {
|
|
||||||
chan[i].freqH=3;
|
|
||||||
} else if (chan[i].freq>=0x1000) {
|
|
||||||
chan[i].freqH=2;
|
|
||||||
} else if (chan[i].freq>=0x800) {
|
|
||||||
chan[i].freqH=1;
|
|
||||||
} else {
|
|
||||||
chan[i].freqH=0;
|
|
||||||
}
|
|
||||||
chan[i].freqL=(chan[i].freq>>chan[i].freqH)&0x3ff;
|
|
||||||
chan[i].freqH=8^chan[i].freqH;
|
|
||||||
ctrl|=(chan[i].active?0x80:0)|(chan[i].damp?0x40:0)|(isMuted[i]?8:(chan[i].pan&0xf));
|
|
||||||
unsigned int waveNum=chan[i].sample;
|
|
||||||
if (ramSize<=0x200000) {
|
|
||||||
waveNum=MIN(waveNum,0x7f)|0x180;
|
|
||||||
}
|
|
||||||
if (chan[i].keyOn) {
|
|
||||||
rWrite(PCM_ADDR_KEY_DAMP_LFORST_CH_PAN+PCM_REG(i),ctrl&~0x80); // force keyoff first
|
|
||||||
rWrite(PCM_ADDR_WAVE_H_FN_L+PCM_REG(i),((chan[i].freqL&0x7f)<<1)|((waveNum>>8)&1));
|
|
||||||
rWrite(PCM_ADDR_WAVE_L+PCM_REG(i),waveNum&0xff);
|
|
||||||
if (!chan[i].std.vol.had) {
|
|
||||||
chan[i].outVol=chan[i].vol;
|
|
||||||
immWrite(PCM_ADDR_TL+(PCM_REG(i)),((0x7f-chan[i].outVol)<<1)|(chan[i].levelDirect?1:0));
|
|
||||||
}
|
|
||||||
chan[i].writeCtrl=true;
|
|
||||||
chan[i].keyOn=false;
|
|
||||||
}
|
|
||||||
if (chan[i].keyOff) {
|
|
||||||
chan[i].writeCtrl=true;
|
|
||||||
chan[i].keyOff=false;
|
|
||||||
}
|
|
||||||
if (chan[i].freqChanged) {
|
|
||||||
rWrite(PCM_ADDR_WAVE_H_FN_L+PCM_REG(i),((chan[i].freqL&0x7f)<<1)|((waveNum>>8)&1));
|
|
||||||
rWrite(PCM_ADDR_FN_H_PR_OCT+PCM_REG(i),((chan[i].freqH&0xf)<<4)|(chan[i].pseudoReverb?0x08:0x00)|((chan[i].freqL>>7)&0x7));
|
|
||||||
chan[i].freqChanged=false;
|
|
||||||
}
|
|
||||||
if (chan[i].writeCtrl) {
|
|
||||||
rWrite(PCM_ADDR_KEY_DAMP_LFORST_CH_PAN+PCM_REG(i),ctrl);
|
|
||||||
chan[i].writeCtrl=false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (chan[i].std.fms.had) {
|
||||||
|
chan[i].vib=chan[i].std.fms.val&0x7;
|
||||||
|
rWrite(PCM_ADDR_LFO_VIB+PCM_REG(i),(chan[i].lfo<<3)|(chan[i].vib));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chan[i].std.ams.had) {
|
||||||
|
chan[i].am=chan[i].std.ams.val&0x7;
|
||||||
|
rWrite(PCM_ADDR_AM+PCM_REG(i),chan[i].am);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chan[i].std.ex2.had) {
|
||||||
|
chan[i].ar=chan[i].std.ex2.val&0xf;
|
||||||
|
rWrite(PCM_ADDR_AR_D1R+PCM_REG(i),(chan[i].ar<<4)|(chan[i].d1r));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chan[i].std.ex3.had) {
|
||||||
|
chan[i].d1r=chan[i].std.ex3.val&0xf;
|
||||||
|
rWrite(PCM_ADDR_AR_D1R+PCM_REG(i),(chan[i].ar<<4)|(chan[i].d1r));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chan[i].std.ex4.had) {
|
||||||
|
chan[i].dl=chan[i].std.ex4.val&0xf;
|
||||||
|
rWrite(PCM_ADDR_DL_D2R+PCM_REG(i),(chan[i].dl<<4)|(chan[i].d2r));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chan[i].std.ex5.had) {
|
||||||
|
chan[i].d2r=chan[i].std.ex5.val&0xf;
|
||||||
|
rWrite(PCM_ADDR_DL_D2R+PCM_REG(i),(chan[i].dl<<4)|(chan[i].d2r));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chan[i].std.ex6.had) {
|
||||||
|
chan[i].rc=chan[i].std.ex6.val&0xf;
|
||||||
|
rWrite(PCM_ADDR_RC_RR+PCM_REG(i),(chan[i].rc<<4)|(chan[i].rr));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chan[i].std.ex7.had) {
|
||||||
|
chan[i].rr=chan[i].std.ex7.val&0xf;
|
||||||
|
rWrite(PCM_ADDR_RC_RR+PCM_REG(i),(chan[i].rc<<4)|(chan[i].rr));
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
int ops=(slots[3][i]!=255 && chan[i].state.ops==4 && oplType==3)?4:2;
|
int ops=(slots[3][i]!=255 && chan[i].state.ops==4 && oplType==3)?4:2;
|
||||||
chan[i].std.next();
|
chan[i].std.next();
|
||||||
|
@ -1360,7 +1334,83 @@ void DivPlatformOPL::tick(bool sysTick) {
|
||||||
bool updateDrums=false;
|
bool updateDrums=false;
|
||||||
for (int i=0; i<totalChans; i++) {
|
for (int i=0; i<totalChans; i++) {
|
||||||
if (PCM_CHECK(i)) { // OPL4 PCM
|
if (PCM_CHECK(i)) { // OPL4 PCM
|
||||||
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
|
DivSample* s=parent->getSample(chan[i].sample);
|
||||||
|
unsigned char ctrl=0;
|
||||||
|
double off=(s->centerRate>=1)?((double)s->centerRate/8363.0):1.0;
|
||||||
|
chan[i].freq=(int)(off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,2,chan[i].pitch2,chipClock,(524288*768)));
|
||||||
|
if (chan[i].freq<0x400) chan[i].freq=0x400;
|
||||||
|
if (chan[i].freq>0x4000000) chan[i].freq=0x4000000;
|
||||||
|
if (chan[i].freq>=0x2000000) {
|
||||||
|
chan[i].freqH=15;
|
||||||
|
} else if (chan[i].freq>=0x1000000) {
|
||||||
|
chan[i].freqH=14;
|
||||||
|
} else if (chan[i].freq>=0x800000) {
|
||||||
|
chan[i].freqH=13;
|
||||||
|
} else if (chan[i].freq>=0x400000) {
|
||||||
|
chan[i].freqH=12;
|
||||||
|
} else if (chan[i].freq>=0x200000) {
|
||||||
|
chan[i].freqH=11;
|
||||||
|
} else if (chan[i].freq>=0x100000) {
|
||||||
|
chan[i].freqH=10;
|
||||||
|
} else if (chan[i].freq>=0x80000) {
|
||||||
|
chan[i].freqH=9;
|
||||||
|
} else if (chan[i].freq>=0x40000) {
|
||||||
|
chan[i].freqH=8;
|
||||||
|
} else if (chan[i].freq>=0x20000) {
|
||||||
|
chan[i].freqH=7;
|
||||||
|
} else if (chan[i].freq>=0x10000) {
|
||||||
|
chan[i].freqH=6;
|
||||||
|
} else if (chan[i].freq>=0x8000) {
|
||||||
|
chan[i].freqH=5;
|
||||||
|
} else if (chan[i].freq>=0x4000) {
|
||||||
|
chan[i].freqH=4;
|
||||||
|
} else if (chan[i].freq>=0x2000) {
|
||||||
|
chan[i].freqH=3;
|
||||||
|
} else if (chan[i].freq>=0x1000) {
|
||||||
|
chan[i].freqH=2;
|
||||||
|
} else if (chan[i].freq>=0x800) {
|
||||||
|
chan[i].freqH=1;
|
||||||
|
} else {
|
||||||
|
chan[i].freqH=0;
|
||||||
|
}
|
||||||
|
chan[i].freqL=(chan[i].freq>>chan[i].freqH)&0x3ff;
|
||||||
|
chan[i].freqH=8^chan[i].freqH;
|
||||||
|
ctrl|=(chan[i].active?0x80:0)|(chan[i].damp?0x40:0)|(chan[i].lfoReset?0x20:0)|(chan[i].ch?0x10:0)|(isMuted[i]?8:(chan[i].pan&0xf));
|
||||||
|
unsigned int waveNum=chan[i].sample;
|
||||||
|
if (ramSize<=0x200000) {
|
||||||
|
waveNum=CLAMP(waveNum,0,0x7f)|0x180;
|
||||||
|
}
|
||||||
|
if (chan[i].keyOn) {
|
||||||
|
rWrite(PCM_ADDR_KEY_DAMP_LFORST_CH_PAN+PCM_REG(i),ctrl&~0x80); // force keyoff first
|
||||||
|
rWrite(PCM_ADDR_WAVE_H_FN_L+PCM_REG(i),((chan[i].freqL&0x7f)<<1)|((waveNum>>8)&1));
|
||||||
|
rWrite(PCM_ADDR_WAVE_L+PCM_REG(i),waveNum&0xff);
|
||||||
|
rWrite(PCM_ADDR_LFO_VIB+PCM_REG(i),(chan[i].lfo<<3)|(chan[i].vib));
|
||||||
|
rWrite(PCM_ADDR_AR_D1R+PCM_REG(i),(chan[i].ar<<4)|(chan[i].d1r));
|
||||||
|
rWrite(PCM_ADDR_DL_D2R+PCM_REG(i),(chan[i].dl<<4)|(chan[i].d2r));
|
||||||
|
rWrite(PCM_ADDR_RC_RR+PCM_REG(i),(chan[i].rc<<4)|(chan[i].rr));
|
||||||
|
rWrite(PCM_ADDR_AM+PCM_REG(i),chan[i].am);
|
||||||
|
if (!chan[i].std.vol.had) {
|
||||||
|
chan[i].outVol=chan[i].vol;
|
||||||
|
immWrite(PCM_ADDR_TL+(PCM_REG(i)),((0x7f-chan[i].outVol)<<1)|(chan[i].levelDirect?1:0));
|
||||||
|
}
|
||||||
|
chan[i].writeCtrl=true;
|
||||||
|
chan[i].keyOn=false;
|
||||||
|
}
|
||||||
|
if (chan[i].keyOff) {
|
||||||
|
chan[i].writeCtrl=true;
|
||||||
|
chan[i].keyOff=false;
|
||||||
|
}
|
||||||
|
if (chan[i].freqChanged) {
|
||||||
|
rWrite(PCM_ADDR_WAVE_H_FN_L+PCM_REG(i),((chan[i].freqL&0x7f)<<1)|((waveNum>>8)&1));
|
||||||
|
rWrite(PCM_ADDR_FN_H_PR_OCT+PCM_REG(i),((chan[i].freqH&0xf)<<4)|(chan[i].pseudoReverb?0x08:0x00)|((chan[i].freqL>>7)&0x7));
|
||||||
|
chan[i].freqChanged=false;
|
||||||
|
}
|
||||||
|
if (chan[i].writeCtrl) {
|
||||||
|
rWrite(PCM_ADDR_KEY_DAMP_LFORST_CH_PAN+PCM_REG(i),ctrl);
|
||||||
|
chan[i].writeCtrl=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (chan[i].freqChanged) {
|
if (chan[i].freqChanged) {
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,octave(chan[i].baseFreq)*2,chan[i].pitch2,chipClock,CHIP_FREQBASE);
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,octave(chan[i].baseFreq)*2,chan[i].pitch2,chipClock,CHIP_FREQBASE);
|
||||||
|
@ -1655,6 +1705,35 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
||||||
chan[c.chan].freqChanged=true;
|
chan[c.chan].freqChanged=true;
|
||||||
chan[c.chan].note=c.value;
|
chan[c.chan].note=c.value;
|
||||||
}
|
}
|
||||||
|
if (ins->type==DIV_INS_OPL4PCM) {
|
||||||
|
chan[c.chan].lfo=ins->multipcm.lfo;
|
||||||
|
chan[c.chan].vib=ins->multipcm.vib;
|
||||||
|
chan[c.chan].am=ins->multipcm.am;
|
||||||
|
chan[c.chan].ar=ins->multipcm.ar;
|
||||||
|
chan[c.chan].d1r=ins->multipcm.d1r;
|
||||||
|
chan[c.chan].dl=ins->multipcm.dl;
|
||||||
|
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->opl4pcm.damp;
|
||||||
|
chan[c.chan].pseudoReverb=ins->opl4pcm.pseudoReverb;
|
||||||
|
chan[c.chan].levelDirect=ins->opl4pcm.levelDirect;
|
||||||
|
chan[c.chan].lfoReset=ins->opl4pcm.lfoReset;
|
||||||
|
} else {
|
||||||
|
chan[c.chan].lfo=0;
|
||||||
|
chan[c.chan].vib=0;
|
||||||
|
chan[c.chan].am=0;
|
||||||
|
chan[c.chan].ar=15;
|
||||||
|
chan[c.chan].d1r=15;
|
||||||
|
chan[c.chan].dl=0;
|
||||||
|
chan[c.chan].d2r=0;
|
||||||
|
chan[c.chan].rc=15;
|
||||||
|
chan[c.chan].rr=15;
|
||||||
|
chan[c.chan].damp=false;
|
||||||
|
chan[c.chan].pseudoReverb=false;
|
||||||
|
chan[c.chan].levelDirect=true;
|
||||||
|
chan[c.chan].lfoReset=false;
|
||||||
|
}
|
||||||
chan[c.chan].active=true;
|
chan[c.chan].active=true;
|
||||||
chan[c.chan].keyOn=true;
|
chan[c.chan].keyOn=true;
|
||||||
chan[c.chan].macroInit(ins);
|
chan[c.chan].macroInit(ins);
|
||||||
|
@ -1852,6 +1931,7 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PANNING: {
|
case DIV_CMD_PANNING: {
|
||||||
if (PCM_CHECK(c.chan)) {
|
if (PCM_CHECK(c.chan)) {
|
||||||
|
chan[c.chan].ch=false;
|
||||||
chan[c.chan].pan=8^MIN(parent->convertPanSplitToLinearLR(c.value,c.value2,15)+1,15);
|
chan[c.chan].pan=8^MIN(parent->convertPanSplitToLinearLR(c.value,c.value2,15)+1,15);
|
||||||
chan[c.chan].freqChanged=true;
|
chan[c.chan].freqChanged=true;
|
||||||
chan[c.chan].writeCtrl=true;
|
chan[c.chan].writeCtrl=true;
|
||||||
|
@ -1880,6 +1960,12 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_CMD_SURROUND_PANNING: {
|
case DIV_CMD_SURROUND_PANNING: {
|
||||||
|
if (PCM_CHECK(c.chan)) {
|
||||||
|
chan[c.chan].ch=true;
|
||||||
|
chan[c.chan].freqChanged=true;
|
||||||
|
chan[c.chan].writeCtrl=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (oplType!=3) break;
|
if (oplType!=3) break;
|
||||||
if (c.chan==adpcmChan) break;
|
if (c.chan==adpcmChan) break;
|
||||||
|
|
||||||
|
@ -2331,9 +2417,99 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_CMD_FM_HARD_RESET:
|
case DIV_CMD_FM_HARD_RESET:
|
||||||
|
if (PCM_CHECK(c.chan)) break;
|
||||||
if (c.chan==adpcmChan) break;
|
if (c.chan==adpcmChan) break;
|
||||||
chan[c.chan].hardReset=c.value;
|
chan[c.chan].hardReset=c.value;
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_OPL4_PCM_MIX_FM:
|
||||||
|
if (chipType==4) {
|
||||||
|
rWrite(PCM_ADDR_MIX_FM,(CLAMP((0x70-(c.value&0x70)),0,0x70)>>1)|(CLAMP((7-(c.value&7)),0,7)));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIV_CMD_OPL4_PCM_MIX_PCM:
|
||||||
|
if (chipType==4) {
|
||||||
|
rWrite(PCM_ADDR_MIX_PCM,(CLAMP((0x70-(c.value&0x70)),0,0x70)>>1)|(CLAMP((7-(c.value&7)),0,7)));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIV_CMD_OPL4_PCM_LFO:
|
||||||
|
if (PCM_CHECK(c.chan)) {
|
||||||
|
chan[c.chan].lfo=c.value&7;
|
||||||
|
rWrite(PCM_ADDR_LFO_VIB+PCM_REG(c.chan),(chan[c.chan].lfo<<3)|(chan[c.chan].vib));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIV_CMD_OPL4_PCM_VIB:
|
||||||
|
if (PCM_CHECK(c.chan)) {
|
||||||
|
chan[c.chan].vib=c.value&7;
|
||||||
|
rWrite(PCM_ADDR_LFO_VIB+PCM_REG(c.chan),(chan[c.chan].lfo<<3)|(chan[c.chan].vib));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIV_CMD_OPL4_PCM_AM:
|
||||||
|
if (PCM_CHECK(c.chan)) {
|
||||||
|
chan[c.chan].am=c.value&7;
|
||||||
|
rWrite(PCM_ADDR_AM+PCM_REG(c.chan),chan[c.chan].am);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIV_CMD_OPL4_PCM_AR:
|
||||||
|
if (PCM_CHECK(c.chan)) {
|
||||||
|
chan[c.chan].ar=c.value&0xf;
|
||||||
|
rWrite(PCM_ADDR_AR_D1R+PCM_REG(c.chan),(chan[c.chan].ar<<4)|(chan[c.chan].d1r));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIV_CMD_OPL4_PCM_D1R:
|
||||||
|
if (PCM_CHECK(c.chan)) {
|
||||||
|
chan[c.chan].d1r=c.value&0xf;
|
||||||
|
rWrite(PCM_ADDR_AR_D1R+PCM_REG(c.chan),(chan[c.chan].ar<<4)|(chan[c.chan].d1r));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIV_CMD_OPL4_PCM_DL:
|
||||||
|
if (PCM_CHECK(c.chan)) {
|
||||||
|
chan[c.chan].dl=c.value&0xf;
|
||||||
|
rWrite(PCM_ADDR_DL_D2R+PCM_REG(c.chan),(chan[c.chan].dl<<4)|(chan[c.chan].d2r));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIV_CMD_OPL4_PCM_D2R:
|
||||||
|
if (PCM_CHECK(c.chan)) {
|
||||||
|
chan[c.chan].d2r=c.value&0xf;
|
||||||
|
rWrite(PCM_ADDR_DL_D2R+PCM_REG(c.chan),(chan[c.chan].dl<<4)|(chan[c.chan].d2r));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIV_CMD_OPL4_PCM_RC:
|
||||||
|
if (PCM_CHECK(c.chan)) {
|
||||||
|
chan[c.chan].rc=c.value&0xf;
|
||||||
|
rWrite(PCM_ADDR_RC_RR+PCM_REG(c.chan),(chan[c.chan].rc<<4)|(chan[c.chan].rr));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIV_CMD_OPL4_PCM_RR:
|
||||||
|
if (PCM_CHECK(c.chan)) {
|
||||||
|
chan[c.chan].rr=c.value&0xf;
|
||||||
|
rWrite(PCM_ADDR_RC_RR+PCM_REG(c.chan),(chan[c.chan].rc<<4)|(chan[c.chan].rr));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIV_CMD_OPL4_PCM_DAMP:
|
||||||
|
if (PCM_CHECK(c.chan)) {
|
||||||
|
chan[c.chan].damp=c.value&1;
|
||||||
|
chan[c.chan].freqChanged=true;
|
||||||
|
chan[c.chan].writeCtrl=true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIV_CMD_OPL4_PCM_PSEUDO_REVERB:
|
||||||
|
if (PCM_CHECK(c.chan)) {
|
||||||
|
chan[c.chan].pseudoReverb=c.value&1;
|
||||||
|
chan[c.chan].freqChanged=true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIV_CMD_OPL4_PCM_LFO_RESET:
|
||||||
|
if (PCM_CHECK(c.chan)) {
|
||||||
|
chan[c.chan].lfoReset=c.value&1;
|
||||||
|
chan[c.chan].freqChanged=true;
|
||||||
|
chan[c.chan].writeCtrl=true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DIV_CMD_OPL4_PCM_LEVEL_DIRECT:
|
||||||
|
if (PCM_CHECK(c.chan)) {
|
||||||
|
immWrite(PCM_ADDR_TL+PCM_REG(c.chan),((0x7f-chan[c.chan].outVol)<<1)|(chan[c.chan].levelDirect?1:0));
|
||||||
|
}
|
||||||
|
break;
|
||||||
case DIV_CMD_MACRO_OFF:
|
case DIV_CMD_MACRO_OFF:
|
||||||
chan[c.chan].std.mask(c.value,true);
|
chan[c.chan].std.mask(c.value,true);
|
||||||
break;
|
break;
|
||||||
|
@ -3019,6 +3195,7 @@ void DivPlatformOPL::renderSamples(int sysID) {
|
||||||
case DIV_SAMPLE_DEPTH_8BIT:
|
case DIV_SAMPLE_DEPTH_8BIT:
|
||||||
bitDepth=0;
|
bitDepth=0;
|
||||||
break;
|
break;
|
||||||
|
// TODO: 12 bit PCM
|
||||||
case DIV_SAMPLE_DEPTH_16BIT:
|
case DIV_SAMPLE_DEPTH_16BIT:
|
||||||
bitDepth=2;
|
bitDepth=2;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -61,7 +61,8 @@ class DivPlatformOPL: public DivDispatch {
|
||||||
unsigned int freqH, freqL;
|
unsigned int freqH, freqL;
|
||||||
int sample, fixedFreq;
|
int sample, fixedFreq;
|
||||||
bool furnacePCM, fourOp, hardReset, writeCtrl;
|
bool furnacePCM, fourOp, hardReset, writeCtrl;
|
||||||
bool levelDirect, damp, pseudoReverb;
|
bool levelDirect, damp, pseudoReverb, lfoReset, ch;
|
||||||
|
int lfo, vib, am, ar, d1r, d2r, dl, rc, rr;
|
||||||
int pan;
|
int pan;
|
||||||
int macroVolMul;
|
int macroVolMul;
|
||||||
Channel():
|
Channel():
|
||||||
|
@ -77,6 +78,17 @@ class DivPlatformOPL: public DivDispatch {
|
||||||
levelDirect(true),
|
levelDirect(true),
|
||||||
damp(false),
|
damp(false),
|
||||||
pseudoReverb(false),
|
pseudoReverb(false),
|
||||||
|
lfoReset(false),
|
||||||
|
ch(false),
|
||||||
|
lfo(0),
|
||||||
|
vib(0),
|
||||||
|
am(0),
|
||||||
|
ar(15),
|
||||||
|
d1r(15),
|
||||||
|
d2r(0),
|
||||||
|
dl(0),
|
||||||
|
rc(15),
|
||||||
|
rr(15),
|
||||||
pan(3),
|
pan(3),
|
||||||
macroVolMul(64) {
|
macroVolMul(64) {
|
||||||
state.ops=2;
|
state.ops=2;
|
||||||
|
@ -208,7 +220,6 @@ class DivPlatformOPL: public DivDispatch {
|
||||||
void renderSamples(int chipID);
|
void renderSamples(int chipID);
|
||||||
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
|
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
|
||||||
void quit();
|
void quit();
|
||||||
YMF278& getChip();
|
|
||||||
DivPlatformOPL():
|
DivPlatformOPL():
|
||||||
pcmMemory(0x400000),
|
pcmMemory(0x400000),
|
||||||
pcm(pcmMemory) {}
|
pcm(pcmMemory) {}
|
||||||
|
|
|
@ -261,7 +261,23 @@ const char* cmdName[]={
|
||||||
"MINMOD_ECHO",
|
"MINMOD_ECHO",
|
||||||
|
|
||||||
"BIFURCATOR_STATE_LOAD",
|
"BIFURCATOR_STATE_LOAD",
|
||||||
"BIFURCATOR_PARAMETER"
|
"BIFURCATOR_PARAMETER",
|
||||||
|
|
||||||
|
"OPL4_MIX_FM",
|
||||||
|
"OPL4_MIX_PCM",
|
||||||
|
"OPL4_LFO",
|
||||||
|
"OPL4_VIB",
|
||||||
|
"OPL4_AM",
|
||||||
|
"OPL4_AR",
|
||||||
|
"OPL4_D1R",
|
||||||
|
"OPL4_DL",
|
||||||
|
"OPL4_D2R",
|
||||||
|
"OPL4_RR",
|
||||||
|
"OPL4_RC",
|
||||||
|
"OPL4_DAMP",
|
||||||
|
"OPL4_PSEUDO_REVERB",
|
||||||
|
"OPL4_LFO_RESET",
|
||||||
|
"OPL4_LEVEL_DIRECT"
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert((sizeof(cmdName)/sizeof(void*))==DIV_CMD_MAX,"update cmdName!");
|
static_assert((sizeof(cmdName)/sizeof(void*))==DIV_CMD_MAX,"update cmdName!");
|
||||||
|
|
|
@ -599,6 +599,25 @@ void DivEngine::registerSystems() {
|
||||||
{0x5b, {DIV_CMD_FM_KSR, _("5Bxy: Set whether key will scale envelope (x: operator from 1 to 4 (0 for all ops); y: enabled)"), effectOpVal<4>, effectValAnd<1>}},
|
{0x5b, {DIV_CMD_FM_KSR, _("5Bxy: Set whether key will scale envelope (x: operator from 1 to 4 (0 for all ops); y: enabled)"), effectOpVal<4>, effectValAnd<1>}},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EffectHandlerMap fmOPL4PostEffectHandlerMap(fmOPLPostEffectHandlerMap);
|
||||||
|
fmOPL4PostEffectHandlerMap.insert({
|
||||||
|
{0x1e, {DIV_CMD_OPL4_PCM_MIX_FM, _("1Exy: FM global level (left, right; 0 to 7)"), effectVal}},
|
||||||
|
{0x1f, {DIV_CMD_OPL4_PCM_MIX_PCM, _("1Fxy: PCM global level (left, right; 0 to 7)"), effectVal}},
|
||||||
|
{0x20, {DIV_CMD_OPL4_PCM_LFO, _("20xx: PCM LFO Rate (0 to 7)"), effectValAnd<7>}},
|
||||||
|
{0x21, {DIV_CMD_OPL4_PCM_VIB, _("21xx: PCM LFO PM Depth (0 to 7)"), effectValAnd<7>}},
|
||||||
|
{0x22, {DIV_CMD_OPL4_PCM_AM, _("22xx: PCM LFO AM Depth (0 to 7)"), effectValAnd<7>}},
|
||||||
|
{0x23, {DIV_CMD_OPL4_PCM_AR, _("23xx: PCM Attack Rate (0 to 15)"), effectValAnd<15>}},
|
||||||
|
{0x24, {DIV_CMD_OPL4_PCM_D1R, _("24xx: PCM Decay 1 Rate (0 to 15)"), effectValAnd<15>}},
|
||||||
|
{0x25, {DIV_CMD_OPL4_PCM_DL, _("25xx: PCM Decay Level (0 to 15)"), effectValAnd<15>}},
|
||||||
|
{0x26, {DIV_CMD_OPL4_PCM_D2R, _("26xx: PCM Decay 2 Rate (0 to 15)"), effectValAnd<15>}},
|
||||||
|
{0x27, {DIV_CMD_OPL4_PCM_RC, _("27xx: PCM Release Rate (0 to 15)"), effectValAnd<15>}},
|
||||||
|
{0x28, {DIV_CMD_OPL4_PCM_RR, _("28xx: PCM Rate Correction (0 to 15)"), effectValAnd<15>}},
|
||||||
|
{0x2c, {DIV_CMD_OPL4_PCM_DAMP, _("2Cxx: PCM Damp"), effectValAnd<1>}},
|
||||||
|
{0x2d, {DIV_CMD_OPL4_PCM_PSEUDO_REVERB, _("2Dxx: PCM Pseudo Reverb"), effectValAnd<1>}},
|
||||||
|
{0x2e, {DIV_CMD_OPL4_PCM_LFO_RESET, _("2Exx: PCM LFO Reset"), effectValAnd<1>}},
|
||||||
|
{0x2f, {DIV_CMD_OPL4_PCM_LEVEL_DIRECT, _("2Fxx: PCM Level Direct"), effectValAnd<1>}},
|
||||||
|
});
|
||||||
|
|
||||||
EffectHandlerMap c64PostEffectHandlerMap={
|
EffectHandlerMap c64PostEffectHandlerMap={
|
||||||
{0x10, {DIV_CMD_WAVE, _("10xx: Set waveform (bit 0: triangle; bit 1: saw; bit 2: pulse; bit 3: noise)")}},
|
{0x10, {DIV_CMD_WAVE, _("10xx: Set waveform (bit 0: triangle; bit 1: saw; bit 2: pulse; bit 3: noise)")}},
|
||||||
{0x11, {DIV_CMD_C64_CUTOFF, _("11xx: Set coarse cutoff (not recommended; use 4xxx instead)")}},
|
{0x11, {DIV_CMD_C64_CUTOFF, _("11xx: Set coarse cutoff (not recommended; use 4xxx instead)")}},
|
||||||
|
@ -1616,28 +1635,28 @@ void DivEngine::registerSystems() {
|
||||||
// to Grauw: feel free to change this to 24 during development of OPL4's PCM part.
|
// to Grauw: feel free to change this to 24 during development of OPL4's PCM part.
|
||||||
// TODO: add 12-bit and 16-bit big-endian sample formats
|
// TODO: add 12-bit and 16-bit big-endian sample formats
|
||||||
sysDefs[DIV_SYSTEM_OPL4]=new DivSysDef(
|
sysDefs[DIV_SYSTEM_OPL4]=new DivSysDef(
|
||||||
_("Yamaha YMF278B (OPL4)"), NULL, 0xae, 0, 42, true, true, 0, false, (1U<<DIV_SAMPLE_DEPTH_8BIT)|(1U<<DIV_SAMPLE_DEPTH_16BIT), 0, 0,
|
_("Yamaha YMF278B (OPL4)"), NULL, 0xae, 0, 42, true, true, 0x151, false, (1U<<DIV_SAMPLE_DEPTH_8BIT)|(1U<<DIV_SAMPLE_DEPTH_16BIT), 0, 0,
|
||||||
_("like OPL3, but this time it also has a 24-channel version of MultiPCM."),
|
_("like OPL3, but this time it also has a 24-channel version of MultiPCM."),
|
||||||
{_("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")},
|
{_("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", "P8", "P10", "P11", "P12", "P13", "P14", "P15", "P16", "P17", "P18", "P19", "P20", "P21", "P22", "P23", "P24"},
|
{"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", "P8", "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_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_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM},
|
||||||
{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},
|
{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,
|
fmEffectHandlerMap,
|
||||||
fmOPLPostEffectHandlerMap
|
fmOPL4PostEffectHandlerMap
|
||||||
);
|
);
|
||||||
|
|
||||||
// TODO: same here
|
// TODO: same here
|
||||||
sysDefs[DIV_SYSTEM_OPL4_DRUMS]=new DivSysDef(
|
sysDefs[DIV_SYSTEM_OPL4_DRUMS]=new DivSysDef(
|
||||||
_("Yamaha YMF278B (OPL4) with drums"), NULL, 0xaf, 0, 44, true, true, 0, false, (1U<<DIV_SAMPLE_DEPTH_8BIT)|(1U<<DIV_SAMPLE_DEPTH_16BIT), 0, 0,
|
_("Yamaha YMF278B (OPL4) with drums"), NULL, 0xaf, 0, 44, true, true, 0x151, false, (1U<<DIV_SAMPLE_DEPTH_8BIT)|(1U<<DIV_SAMPLE_DEPTH_16BIT), 0, 0,
|
||||||
_("the OPL4 but with drums mode turned on."),
|
_("the OPL4 but with drums mode turned on."),
|
||||||
{_("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")},
|
{_("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", "P8", "P10", "P11", "P12", "P13", "P14", "P15", "P16", "P17", "P18", "P19", "P20", "P21", "P22", "P23", "P24"},
|
{"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", "P8", "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_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_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM, DIV_INS_OPL4PCM},
|
||||||
{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},
|
{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,
|
fmOPLDrumsEffectHandlerMap,
|
||||||
fmOPLPostEffectHandlerMap
|
fmOPL4PostEffectHandlerMap
|
||||||
);
|
);
|
||||||
|
|
||||||
EffectHandlerMap es5506PreEffectHandlerMap={
|
EffectHandlerMap es5506PreEffectHandlerMap={
|
||||||
|
|
|
@ -1043,7 +1043,8 @@ void FurnaceGUI::doAction(int what) {
|
||||||
i==DIV_INS_K053260 ||
|
i==DIV_INS_K053260 ||
|
||||||
i==DIV_INS_C140 ||
|
i==DIV_INS_C140 ||
|
||||||
i==DIV_INS_C219 ||
|
i==DIV_INS_C219 ||
|
||||||
i==DIV_INS_NDS) {
|
i==DIV_INS_NDS ||
|
||||||
|
i==DIV_INS_OPL4PCM) {
|
||||||
makeInsTypeList.push_back(i);
|
makeInsTypeList.push_back(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1572,7 +1573,8 @@ void FurnaceGUI::doAction(int what) {
|
||||||
i==DIV_INS_C219 ||
|
i==DIV_INS_C219 ||
|
||||||
i==DIV_INS_NDS ||
|
i==DIV_INS_NDS ||
|
||||||
i==DIV_INS_GBA_DMA ||
|
i==DIV_INS_GBA_DMA ||
|
||||||
i==DIV_INS_GBA_MINMOD) {
|
i==DIV_INS_GBA_MINMOD ||
|
||||||
|
i==DIV_INS_OPL4PCM) {
|
||||||
makeInsTypeList.push_back(i);
|
makeInsTypeList.push_back(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -351,6 +351,7 @@ enum FurnaceGUIColors {
|
||||||
GUI_COLOR_INSTR_GBA_MINMOD,
|
GUI_COLOR_INSTR_GBA_MINMOD,
|
||||||
GUI_COLOR_INSTR_BIFURCATOR,
|
GUI_COLOR_INSTR_BIFURCATOR,
|
||||||
GUI_COLOR_INSTR_SID2,
|
GUI_COLOR_INSTR_SID2,
|
||||||
|
GUI_COLOR_INSTR_OPL4PCM,
|
||||||
GUI_COLOR_INSTR_UNKNOWN,
|
GUI_COLOR_INSTR_UNKNOWN,
|
||||||
|
|
||||||
GUI_COLOR_CHANNEL_BG,
|
GUI_COLOR_CHANNEL_BG,
|
||||||
|
|
|
@ -184,6 +184,7 @@ const char* insTypes[DIV_INS_MAX+1][3]={
|
||||||
{"GBA MinMod",ICON_FA_VOLUME_UP,ICON_FUR_INS_GBA_MINMOD},
|
{"GBA MinMod",ICON_FA_VOLUME_UP,ICON_FUR_INS_GBA_MINMOD},
|
||||||
{"Bifurcator",ICON_FA_LINE_CHART,ICON_FUR_INS_BIFURCATOR},
|
{"Bifurcator",ICON_FA_LINE_CHART,ICON_FUR_INS_BIFURCATOR},
|
||||||
{"SID2",ICON_FA_KEYBOARD_O,ICON_FUR_INS_SID2},
|
{"SID2",ICON_FA_KEYBOARD_O,ICON_FUR_INS_SID2},
|
||||||
|
{"OPL4 PCM",ICON_FA_KEYBOARD_O,ICON_FUR_INS_SID2},
|
||||||
{NULL,ICON_FA_QUESTION,ICON_FA_QUESTION}
|
{NULL,ICON_FA_QUESTION,ICON_FA_QUESTION}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1012,6 +1013,7 @@ const FurnaceGUIColorDef guiColors[GUI_COLOR_MAX]={
|
||||||
D(GUI_COLOR_INSTR_GBA_MINMOD,"",ImVec4(0.5f,0.45f,0.7f,1.0f)),
|
D(GUI_COLOR_INSTR_GBA_MINMOD,"",ImVec4(0.5f,0.45f,0.7f,1.0f)),
|
||||||
D(GUI_COLOR_INSTR_BIFURCATOR,"",ImVec4(0.8925f,0.8925f,0.8925f,1.0f)),
|
D(GUI_COLOR_INSTR_BIFURCATOR,"",ImVec4(0.8925f,0.8925f,0.8925f,1.0f)),
|
||||||
D(GUI_COLOR_INSTR_SID2,"",ImVec4(0.6f,0.75f,1.0f,1.0f)),
|
D(GUI_COLOR_INSTR_SID2,"",ImVec4(0.6f,0.75f,1.0f,1.0f)),
|
||||||
|
D(GUI_COLOR_INSTR_OPL4PCM,"",ImVec4(1.0f,0.8f,0.1f,1.0f)),
|
||||||
D(GUI_COLOR_INSTR_UNKNOWN,"",ImVec4(0.3f,0.3f,0.3f,1.0f)),
|
D(GUI_COLOR_INSTR_UNKNOWN,"",ImVec4(0.3f,0.3f,0.3f,1.0f)),
|
||||||
|
|
||||||
D(GUI_COLOR_CHANNEL_BG,"",ImVec4(0.4f,0.6f,0.8f,1.0f)),
|
D(GUI_COLOR_CHANNEL_BG,"",ImVec4(0.4f,0.6f,0.8f,1.0f)),
|
||||||
|
|
|
@ -6205,7 +6205,8 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
ins->type==DIV_INS_C219 ||
|
ins->type==DIV_INS_C219 ||
|
||||||
ins->type==DIV_INS_NDS ||
|
ins->type==DIV_INS_NDS ||
|
||||||
ins->type==DIV_INS_GBA_DMA ||
|
ins->type==DIV_INS_GBA_DMA ||
|
||||||
ins->type==DIV_INS_GBA_MINMOD) {
|
ins->type==DIV_INS_GBA_MINMOD ||
|
||||||
|
ins->type==DIV_INS_OPL4PCM) {
|
||||||
insTabSample(ins);
|
insTabSample(ins);
|
||||||
}
|
}
|
||||||
if (ins->type==DIV_INS_N163) if (ImGui::BeginTabItem("Namco 163")) {
|
if (ins->type==DIV_INS_N163) if (ImGui::BeginTabItem("Namco 163")) {
|
||||||
|
@ -6437,8 +6438,8 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
}
|
}
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
if (ins->type==DIV_INS_MULTIPCM) {
|
if (ins->type==DIV_INS_MULTIPCM || ins->type==DIV_INS_OPL4PCM) {
|
||||||
if (ImGui::BeginTabItem("MultiPCM")) {
|
if (ImGui::BeginTabItem(ins->type==DIV_INS_OPL4PCM?"OPL4 PCM":"MultiPCM")) {
|
||||||
ImVec2 sliderSize=ImVec2(20.0f*dpiScale,128.0*dpiScale);
|
ImVec2 sliderSize=ImVec2(20.0f*dpiScale,128.0*dpiScale);
|
||||||
if (ImGui::BeginTable("MultiPCMADSRParams",7,ImGuiTableFlags_NoHostExtendX)) {
|
if (ImGui::BeginTable("MultiPCMADSRParams",7,ImGuiTableFlags_NoHostExtendX)) {
|
||||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
|
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,sliderSize.x);
|
||||||
|
@ -6519,6 +6520,12 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
P(CWSliderScalar(_("AM Depth"),ImGuiDataType_U8,&ins->multipcm.am,&_ZERO,&_SEVEN)); rightClickable
|
P(CWSliderScalar(_("AM Depth"),ImGuiDataType_U8,&ins->multipcm.am,&_ZERO,&_SEVEN)); rightClickable
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
if (ins->type==DIV_INS_OPL4PCM) {
|
||||||
|
P(ImGui::Checkbox(_("Damp"),&ins->opl4pcm.damp));
|
||||||
|
P(ImGui::Checkbox(_("Pseudo Reverb"),&ins->opl4pcm.pseudoReverb));
|
||||||
|
P(ImGui::Checkbox(_("Level Direct"),&ins->opl4pcm.levelDirect));
|
||||||
|
P(ImGui::Checkbox(_("LFO Reset"),&ins->opl4pcm.lfoReset));
|
||||||
|
}
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7503,6 +7510,22 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
macroList.push_back(FurnaceGUIMacroDesc(_("Noise Mode"),&ins->std.fmsMacro,0,3,64,uiColors[GUI_COLOR_MACRO_NOISE]));
|
macroList.push_back(FurnaceGUIMacroDesc(_("Noise Mode"),&ins->std.fmsMacro,0,3,64,uiColors[GUI_COLOR_MACRO_NOISE]));
|
||||||
macroList.push_back(FurnaceGUIMacroDesc(_("Wave Mix"),&ins->std.amsMacro,0,3,64,uiColors[GUI_COLOR_MACRO_OTHER]));
|
macroList.push_back(FurnaceGUIMacroDesc(_("Wave Mix"),&ins->std.amsMacro,0,3,64,uiColors[GUI_COLOR_MACRO_OTHER]));
|
||||||
break;
|
break;
|
||||||
|
case DIV_INS_OPL4PCM:
|
||||||
|
macroList.push_back(FurnaceGUIMacroDesc(_("Volume"),&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
|
||||||
|
macroList.push_back(FurnaceGUIMacroDesc(_("Arpeggio"),&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val));
|
||||||
|
macroList.push_back(FurnaceGUIMacroDesc(_("Panning"),&ins->std.panLMacro,-7,7,45,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL));
|
||||||
|
macroList.push_back(FurnaceGUIMacroDesc(_("Pitch"),&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode));
|
||||||
|
macroList.push_back(FurnaceGUIMacroDesc(_("Phase Reset"),&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
|
||||||
|
macroList.push_back(FurnaceGUIMacroDesc(_("LFO speed"),&ins->std.ex1Macro,0,7,160,uiColors[GUI_COLOR_MACRO_OTHER]));
|
||||||
|
macroList.push_back(FurnaceGUIMacroDesc(_("LFO vibrato depth"),&ins->std.fmsMacro,0,7,160,uiColors[GUI_COLOR_MACRO_PITCH]));
|
||||||
|
macroList.push_back(FurnaceGUIMacroDesc(_("LFO AM depth"),&ins->std.amsMacro,0,7,160,uiColors[GUI_COLOR_MACRO_VOLUME]));
|
||||||
|
macroList.push_back(FurnaceGUIMacroDesc(_("AR"),&ins->std.ex2Macro,0,15,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
|
||||||
|
macroList.push_back(FurnaceGUIMacroDesc(_("D1R"),&ins->std.ex3Macro,0,15,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
|
||||||
|
macroList.push_back(FurnaceGUIMacroDesc(_("DL"),&ins->std.ex4Macro,0,15,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
|
||||||
|
macroList.push_back(FurnaceGUIMacroDesc(_("D2R"),&ins->std.ex5Macro,0,15,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
|
||||||
|
macroList.push_back(FurnaceGUIMacroDesc(_("Rate correction"),&ins->std.ex6Macro,0,15,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
|
||||||
|
macroList.push_back(FurnaceGUIMacroDesc(_("RR"),&ins->std.ex7Macro,0,15,160,uiColors[GUI_COLOR_MACRO_ENVELOPE]));
|
||||||
|
break;
|
||||||
|
|
||||||
case DIV_INS_MAX:
|
case DIV_INS_MAX:
|
||||||
case DIV_INS_NULL:
|
case DIV_INS_NULL:
|
||||||
|
|
|
@ -4107,6 +4107,7 @@ void FurnaceGUI::drawSettings() {
|
||||||
UI_COLOR_CONFIG(GUI_COLOR_INSTR_GBA_MINMOD,_("GBA MinMod"));
|
UI_COLOR_CONFIG(GUI_COLOR_INSTR_GBA_MINMOD,_("GBA MinMod"));
|
||||||
UI_COLOR_CONFIG(GUI_COLOR_INSTR_BIFURCATOR,_("Bifurcator"));
|
UI_COLOR_CONFIG(GUI_COLOR_INSTR_BIFURCATOR,_("Bifurcator"));
|
||||||
UI_COLOR_CONFIG(GUI_COLOR_INSTR_SID2,_("SID2"));
|
UI_COLOR_CONFIG(GUI_COLOR_INSTR_SID2,_("SID2"));
|
||||||
|
UI_COLOR_CONFIG(GUI_COLOR_INSTR_OPL4PCM,_("OPL4 PCM"));
|
||||||
UI_COLOR_CONFIG(GUI_COLOR_INSTR_UNKNOWN,_("Other/Unknown"));
|
UI_COLOR_CONFIG(GUI_COLOR_INSTR_UNKNOWN,_("Other/Unknown"));
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue