mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-23 13:05:11 +00:00
Neo Geo: implement ADPCM-B
This commit is contained in:
parent
efd78a23c0
commit
35e459d9e5
4 changed files with 177 additions and 18 deletions
|
@ -460,12 +460,12 @@ void DivEngine::renderSamples() {
|
||||||
memPos=(memPos+0xfffff)&0xf00000;
|
memPos=(memPos+0xfffff)&0xf00000;
|
||||||
}
|
}
|
||||||
if (memPos>=16777216) {
|
if (memPos>=16777216) {
|
||||||
logW("out of ADPCM memory for sample %d!\n",i);
|
logW("out of ADPCM-A memory for sample %d!\n",i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (memPos+paddedLen>=16777216) {
|
if (memPos+paddedLen>=16777216) {
|
||||||
memcpy(adpcmAMem+memPos,s->dataA,16777216-memPos);
|
memcpy(adpcmAMem+memPos,s->dataA,16777216-memPos);
|
||||||
logW("out of ADPCM memory for sample %d!\n",i);
|
logW("out of ADPCM-A memory for sample %d!\n",i);
|
||||||
} else {
|
} else {
|
||||||
memcpy(adpcmAMem+memPos,s->dataA,paddedLen);
|
memcpy(adpcmAMem+memPos,s->dataA,paddedLen);
|
||||||
}
|
}
|
||||||
|
@ -474,6 +474,31 @@ void DivEngine::renderSamples() {
|
||||||
}
|
}
|
||||||
adpcmAMemLen=memPos+256;
|
adpcmAMemLen=memPos+256;
|
||||||
|
|
||||||
|
// step 2: allocate ADPCM-B samples
|
||||||
|
if (adpcmBMem==NULL) adpcmBMem=new unsigned char[16777216];
|
||||||
|
|
||||||
|
memPos=0;
|
||||||
|
for (int i=0; i<song.sampleLen; i++) {
|
||||||
|
DivSample* s=song.sample[i];
|
||||||
|
int paddedLen=(s->lengthB+255)&(~0xff);
|
||||||
|
if ((memPos&0xf00000)!=((memPos+paddedLen)&0xf00000)) {
|
||||||
|
memPos=(memPos+0xfffff)&0xf00000;
|
||||||
|
}
|
||||||
|
if (memPos>=16777216) {
|
||||||
|
logW("out of ADPCM-B memory for sample %d!\n",i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (memPos+paddedLen>=16777216) {
|
||||||
|
memcpy(adpcmBMem+memPos,s->dataB,16777216-memPos);
|
||||||
|
logW("out of ADPCM-B memory for sample %d!\n",i);
|
||||||
|
} else {
|
||||||
|
memcpy(adpcmBMem+memPos,s->dataB,paddedLen);
|
||||||
|
}
|
||||||
|
s->offB=memPos;
|
||||||
|
memPos+=paddedLen;
|
||||||
|
}
|
||||||
|
adpcmBMemLen=memPos+256;
|
||||||
|
|
||||||
// step 4: allocate qsound pcm samples
|
// step 4: allocate qsound pcm samples
|
||||||
if (qsoundMem==NULL) qsoundMem=new unsigned char[16777216];
|
if (qsoundMem==NULL) qsoundMem=new unsigned char[16777216];
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,13 @@ const char* DivPlatformYM2610::getEffectName(unsigned char effect) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double DivPlatformYM2610::NOTE_ADPCMB(int note) {
|
||||||
|
DivInstrument* ins=parent->getIns(chan[13].ins);
|
||||||
|
if (ins->type!=DIV_INS_AMIGA) return 0;
|
||||||
|
double off=(double)(parent->getSample(ins->amiga.initSample)->centerRate)/8363.0;
|
||||||
|
return off*parent->calcBaseFreq((double)chipClock/144,65535,note,false);
|
||||||
|
}
|
||||||
|
|
||||||
void DivPlatformYM2610::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
void DivPlatformYM2610::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||||
static int os[2];
|
static int os[2];
|
||||||
|
|
||||||
|
@ -358,6 +365,38 @@ void DivPlatformYM2610::tick() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ADPCM-B
|
||||||
|
if (chan[13].furnacePCM) {
|
||||||
|
chan[13].std.next();
|
||||||
|
|
||||||
|
if (chan[13].std.hadVol) {
|
||||||
|
chan[13].outVol=(chan[13].vol*MIN(64,chan[13].std.vol))/64;
|
||||||
|
immWrite(0x1b,chan[13].outVol);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chan[13].std.hadArp) {
|
||||||
|
if (!chan[13].inPorta) {
|
||||||
|
if (chan[13].std.arpMode) {
|
||||||
|
chan[13].baseFreq=NOTE_ADPCMB(chan[13].std.arp);
|
||||||
|
} else {
|
||||||
|
chan[13].baseFreq=NOTE_ADPCMB(chan[13].note+(signed char)chan[13].std.arp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chan[13].freqChanged=true;
|
||||||
|
} else {
|
||||||
|
if (chan[13].std.arpMode && chan[13].std.finishedArp) {
|
||||||
|
chan[13].baseFreq=NOTE_ADPCMB(chan[13].note);
|
||||||
|
chan[13].freqChanged=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (chan[13].freqChanged) {
|
||||||
|
chan[13].freq=parent->calcFreq(chan[13].baseFreq,chan[13].pitch,false,4);
|
||||||
|
immWrite(0x19,chan[13].freq&0xff);
|
||||||
|
immWrite(0x1a,(chan[13].freq>>8)&0xff);
|
||||||
|
chan[13].freqChanged=false;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i=0; i<512; i++) {
|
for (int i=0; i<512; i++) {
|
||||||
if (pendingWrites[i]!=oldWrites[i]) {
|
if (pendingWrites[i]!=oldWrites[i]) {
|
||||||
immWrite(i,pendingWrites[i]&0xff);
|
immWrite(i,pendingWrites[i]&0xff);
|
||||||
|
@ -426,7 +465,59 @@ int DivPlatformYM2610::toFreq(int freq) {
|
||||||
int DivPlatformYM2610::dispatch(DivCommand c) {
|
int DivPlatformYM2610::dispatch(DivCommand c) {
|
||||||
switch (c.cmd) {
|
switch (c.cmd) {
|
||||||
case DIV_CMD_NOTE_ON: {
|
case DIV_CMD_NOTE_ON: {
|
||||||
if (c.chan>6) { // ADPCM
|
if (c.chan>12) { // ADPCM-B
|
||||||
|
DivInstrument* ins=parent->getIns(chan[c.chan].ins);
|
||||||
|
if (ins->type==DIV_INS_AMIGA) {
|
||||||
|
chan[c.chan].furnacePCM=true;
|
||||||
|
} else {
|
||||||
|
chan[c.chan].furnacePCM=false;
|
||||||
|
}
|
||||||
|
if (skipRegisterWrites) break;
|
||||||
|
if (chan[c.chan].furnacePCM) {
|
||||||
|
chan[c.chan].std.init(ins);
|
||||||
|
if (!chan[c.chan].std.willVol) {
|
||||||
|
chan[c.chan].outVol=chan[c.chan].vol;
|
||||||
|
}
|
||||||
|
DivSample* s=parent->getSample(ins->amiga.initSample);
|
||||||
|
immWrite(0x12,(s->offB>>8)&0xff);
|
||||||
|
immWrite(0x13,s->offB>>16);
|
||||||
|
int end=s->offB+s->lengthB-1;
|
||||||
|
immWrite(0x14,(end>>8)&0xff);
|
||||||
|
immWrite(0x15,end>>16);
|
||||||
|
immWrite(0x11,isMuted[c.chan]?0:(chan[c.chan].pan<<6));
|
||||||
|
immWrite(0x10,0x80); // start
|
||||||
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
|
chan[c.chan].note=c.value;
|
||||||
|
chan[c.chan].baseFreq=NOTE_ADPCMB(chan[c.chan].note);
|
||||||
|
chan[c.chan].freqChanged=true;
|
||||||
|
}
|
||||||
|
chan[c.chan].active=true;
|
||||||
|
chan[c.chan].keyOn=true;
|
||||||
|
} else {
|
||||||
|
chan[c.chan].std.init(NULL);
|
||||||
|
chan[c.chan].outVol=chan[c.chan].vol;
|
||||||
|
if ((12*sampleBank+c.value%12)>=parent->song.sampleLen) {
|
||||||
|
immWrite(0x10,0x01); // reset
|
||||||
|
immWrite(0x12,0);
|
||||||
|
immWrite(0x13,0);
|
||||||
|
immWrite(0x14,0);
|
||||||
|
immWrite(0x15,0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
DivSample* s=parent->getSample(12*sampleBank+c.value%12);
|
||||||
|
immWrite(0x12,(s->offB>>8)&0xff);
|
||||||
|
immWrite(0x13,s->offB>>16);
|
||||||
|
int end=s->offB+s->lengthB-1;
|
||||||
|
immWrite(0x14,(end>>8)&0xff);
|
||||||
|
immWrite(0x15,end>>16);
|
||||||
|
immWrite(0x11,isMuted[c.chan]?0:(chan[c.chan].pan<<6));
|
||||||
|
immWrite(0x10,0x80); // start
|
||||||
|
chan[c.chan].baseFreq=(((unsigned int)s->rate)<<16)/(chipClock/144);
|
||||||
|
chan[c.chan].freqChanged=true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c.chan>6) { // ADPCM-A
|
||||||
if (skipRegisterWrites) break;
|
if (skipRegisterWrites) break;
|
||||||
if ((12*sampleBank+c.value%12)>=parent->song.sampleLen) {
|
if ((12*sampleBank+c.value%12)>=parent->song.sampleLen) {
|
||||||
immWrite(0x100,0x80|(1<<(c.chan-7)));
|
immWrite(0x100,0x80|(1<<(c.chan-7)));
|
||||||
|
@ -511,6 +602,10 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_CMD_NOTE_OFF:
|
case DIV_CMD_NOTE_OFF:
|
||||||
|
if (c.chan>12) {
|
||||||
|
immWrite(0x10,0x01); // reset
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (c.chan>6) {
|
if (c.chan>6) {
|
||||||
immWrite(0x100,0x80|(1<<(c.chan-7)));
|
immWrite(0x100,0x80|(1<<(c.chan-7)));
|
||||||
break;
|
break;
|
||||||
|
@ -521,6 +616,10 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
||||||
chan[c.chan].std.init(NULL);
|
chan[c.chan].std.init(NULL);
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_NOTE_OFF_ENV:
|
case DIV_CMD_NOTE_OFF_ENV:
|
||||||
|
if (c.chan>12) {
|
||||||
|
immWrite(0x10,0x01); // reset
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (c.chan>6) {
|
if (c.chan>6) {
|
||||||
immWrite(0x100,0x80|(1<<(c.chan-7)));
|
immWrite(0x100,0x80|(1<<(c.chan-7)));
|
||||||
break;
|
break;
|
||||||
|
@ -542,7 +641,11 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
||||||
if (!chan[c.chan].std.hasVol) {
|
if (!chan[c.chan].std.hasVol) {
|
||||||
chan[c.chan].outVol=c.value;
|
chan[c.chan].outVol=c.value;
|
||||||
}
|
}
|
||||||
if (c.chan>6) { // ADPCM
|
if (c.chan>12) { // ADPCM-B
|
||||||
|
immWrite(0x1b,chan[c.chan].outVol);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (c.chan>6) { // ADPCM-A
|
||||||
immWrite(0x108+(c.chan-7),isMuted[c.chan]?0:((chan[c.chan].pan<<6)|chan[c.chan].vol));
|
immWrite(0x108+(c.chan-7),isMuted[c.chan]?0:((chan[c.chan].pan<<6)|chan[c.chan].vol));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -587,6 +690,10 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
||||||
chan[c.chan].pan=3;
|
chan[c.chan].pan=3;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (c.chan>12) {
|
||||||
|
immWrite(0x11,isMuted[c.chan]?0:(chan[c.chan].pan<<6));
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (c.chan>6) {
|
if (c.chan>6) {
|
||||||
immWrite(0x108+(c.chan-7),isMuted[c.chan]?0:((chan[c.chan].pan<<6)|chan[c.chan].vol));
|
immWrite(0x108+(c.chan-7),isMuted[c.chan]?0:((chan[c.chan].pan<<6)|chan[c.chan].vol));
|
||||||
break;
|
break;
|
||||||
|
@ -773,7 +880,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
if (c.chan>12) return 127;
|
if (c.chan>12) return 255;
|
||||||
if (c.chan>6) return 31;
|
if (c.chan>6) return 31;
|
||||||
if (c.chan>3) return 15;
|
if (c.chan>3) return 15;
|
||||||
return 127;
|
return 127;
|
||||||
|
@ -797,7 +904,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
||||||
|
|
||||||
void DivPlatformYM2610::muteChannel(int ch, bool mute) {
|
void DivPlatformYM2610::muteChannel(int ch, bool mute) {
|
||||||
isMuted[ch]=mute;
|
isMuted[ch]=mute;
|
||||||
if (ch>6) { // ADPCM
|
if (ch>6) { // ADPCM-A
|
||||||
immWrite(0x108+(ch-7),isMuted[ch]?0:((chan[ch].pan<<6)|chan[ch].vol));
|
immWrite(0x108+(ch-7),isMuted[ch]?0:((chan[ch].pan<<6)|chan[ch].vol));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -885,7 +992,7 @@ void DivPlatformYM2610::reset() {
|
||||||
for (int i=7; i<13; i++) {
|
for (int i=7; i<13; i++) {
|
||||||
chan[i].vol=0x1f;
|
chan[i].vol=0x1f;
|
||||||
}
|
}
|
||||||
chan[13].vol=0x7f;
|
chan[13].vol=0xff;
|
||||||
|
|
||||||
for (int i=0; i<512; i++) {
|
for (int i=0; i<512; i++) {
|
||||||
oldWrites[i]=-1;
|
oldWrites[i]=-1;
|
||||||
|
@ -916,7 +1023,8 @@ void DivPlatformYM2610::reset() {
|
||||||
immWrite(0x22,0x08);
|
immWrite(0x22,0x08);
|
||||||
|
|
||||||
// PCM volume
|
// PCM volume
|
||||||
immWrite(0x101,0x3f);
|
immWrite(0x101,0x3f); // A
|
||||||
|
immWrite(0x1b,0xff); // B
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DivPlatformYM2610::isStereo() {
|
bool DivPlatformYM2610::isStereo() {
|
||||||
|
|
|
@ -41,11 +41,32 @@ class DivPlatformYM2610: public DivDispatch {
|
||||||
int freq, baseFreq, pitch, note;
|
int freq, baseFreq, pitch, note;
|
||||||
unsigned char ins, psgMode, autoEnvNum, autoEnvDen;
|
unsigned char ins, psgMode, autoEnvNum, autoEnvDen;
|
||||||
signed char konCycles;
|
signed char konCycles;
|
||||||
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta;
|
bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, inPorta, furnacePCM;
|
||||||
int vol, outVol;
|
int vol, outVol;
|
||||||
unsigned char pan;
|
unsigned char pan;
|
||||||
DivMacroInt std;
|
DivMacroInt std;
|
||||||
Channel(): freqH(0), freqL(0), freq(0), baseFreq(0), pitch(0), note(0), ins(-1), psgMode(1), autoEnvNum(0), autoEnvDen(0), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), portaPause(false), inPorta(false), vol(0), outVol(15), pan(3) {}
|
Channel():
|
||||||
|
freqH(0),
|
||||||
|
freqL(0),
|
||||||
|
freq(0),
|
||||||
|
baseFreq(0),
|
||||||
|
pitch(0),
|
||||||
|
note(0),
|
||||||
|
ins(-1),
|
||||||
|
psgMode(1),
|
||||||
|
autoEnvNum(0),
|
||||||
|
autoEnvDen(0),
|
||||||
|
active(false),
|
||||||
|
insChanged(true),
|
||||||
|
freqChanged(false),
|
||||||
|
keyOn(false),
|
||||||
|
keyOff(false),
|
||||||
|
portaPause(false),
|
||||||
|
inPorta(false),
|
||||||
|
furnacePCM(false),
|
||||||
|
vol(0),
|
||||||
|
outVol(15),
|
||||||
|
pan(3) {}
|
||||||
};
|
};
|
||||||
Channel chan[14];
|
Channel chan[14];
|
||||||
bool isMuted[14];
|
bool isMuted[14];
|
||||||
|
@ -83,6 +104,7 @@ class DivPlatformYM2610: public DivDispatch {
|
||||||
|
|
||||||
int octave(int freq);
|
int octave(int freq);
|
||||||
int toFreq(int freq);
|
int toFreq(int freq);
|
||||||
|
double NOTE_ADPCMB(int note);
|
||||||
friend void putDispatchChan(void*,int,int);
|
friend void putDispatchChan(void*,int,int);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -255,6 +255,8 @@ bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effe
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define IS_YM2610 (sysOfChan[ch]==DIV_SYSTEM_YM2610 || sysOfChan[ch]==DIV_SYSTEM_YM2610_EXT || sysOfChan[ch]==DIV_SYSTEM_YM2610_FULL || sysOfChan[ch]==DIV_SYSTEM_YM2610_FULL_EXT)
|
||||||
|
|
||||||
bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char effectVal) {
|
bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char effectVal) {
|
||||||
switch (sysOfChan[ch]) {
|
switch (sysOfChan[ch]) {
|
||||||
case DIV_SYSTEM_YM2612:
|
case DIV_SYSTEM_YM2612:
|
||||||
|
@ -262,6 +264,8 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
|
||||||
case DIV_SYSTEM_YM2151:
|
case DIV_SYSTEM_YM2151:
|
||||||
case DIV_SYSTEM_YM2610:
|
case DIV_SYSTEM_YM2610:
|
||||||
case DIV_SYSTEM_YM2610_EXT:
|
case DIV_SYSTEM_YM2610_EXT:
|
||||||
|
case DIV_SYSTEM_YM2610_FULL:
|
||||||
|
case DIV_SYSTEM_YM2610_FULL_EXT:
|
||||||
switch (effect) {
|
switch (effect) {
|
||||||
case 0x10: // LFO or noise mode
|
case 0x10: // LFO or noise mode
|
||||||
if (sysOfChan[ch]==DIV_SYSTEM_YM2151) {
|
if (sysOfChan[ch]==DIV_SYSTEM_YM2151) {
|
||||||
|
@ -324,42 +328,42 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
|
||||||
dispatchCmd(DivCommand(DIV_CMD_FM_PM_DEPTH,ch,effectVal&127));
|
dispatchCmd(DivCommand(DIV_CMD_FM_PM_DEPTH,ch,effectVal&127));
|
||||||
break;
|
break;
|
||||||
case 0x20: // Neo Geo PSG mode
|
case 0x20: // Neo Geo PSG mode
|
||||||
if (sysOfChan[ch]==DIV_SYSTEM_YM2610 || sysOfChan[ch]==DIV_SYSTEM_YM2610_EXT) {
|
if (IS_YM2610) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x21: // Neo Geo PSG noise freq
|
case 0x21: // Neo Geo PSG noise freq
|
||||||
if (sysOfChan[ch]==DIV_SYSTEM_YM2610 || sysOfChan[ch]==DIV_SYSTEM_YM2610_EXT) {
|
if (IS_YM2610) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_FREQ,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_FREQ,ch,effectVal));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x22: // UNOFFICIAL: Neo Geo PSG envelope enable
|
case 0x22: // UNOFFICIAL: Neo Geo PSG envelope enable
|
||||||
if (sysOfChan[ch]==DIV_SYSTEM_YM2610 || sysOfChan[ch]==DIV_SYSTEM_YM2610_EXT) {
|
if (IS_YM2610) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_SET,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_SET,ch,effectVal));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x23: // UNOFFICIAL: Neo Geo PSG envelope period low
|
case 0x23: // UNOFFICIAL: Neo Geo PSG envelope period low
|
||||||
if (sysOfChan[ch]==DIV_SYSTEM_YM2610 || sysOfChan[ch]==DIV_SYSTEM_YM2610_EXT) {
|
if (IS_YM2610) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_LOW,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_LOW,ch,effectVal));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x24: // UNOFFICIAL: Neo Geo PSG envelope period high
|
case 0x24: // UNOFFICIAL: Neo Geo PSG envelope period high
|
||||||
if (sysOfChan[ch]==DIV_SYSTEM_YM2610 || sysOfChan[ch]==DIV_SYSTEM_YM2610_EXT) {
|
if (IS_YM2610) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_HIGH,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_HIGH,ch,effectVal));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x25: // UNOFFICIAL: Neo Geo PSG envelope slide up
|
case 0x25: // UNOFFICIAL: Neo Geo PSG envelope slide up
|
||||||
if (sysOfChan[ch]==DIV_SYSTEM_YM2610 || sysOfChan[ch]==DIV_SYSTEM_YM2610_EXT) {
|
if (IS_YM2610) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_SLIDE,ch,-effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_SLIDE,ch,-effectVal));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x26: // UNOFFICIAL: Neo Geo PSG envelope slide down
|
case 0x26: // UNOFFICIAL: Neo Geo PSG envelope slide down
|
||||||
if (sysOfChan[ch]==DIV_SYSTEM_YM2610 || sysOfChan[ch]==DIV_SYSTEM_YM2610_EXT) {
|
if (IS_YM2610) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_SLIDE,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_AY_ENVELOPE_SLIDE,ch,effectVal));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x29: // auto-envelope
|
case 0x29: // auto-envelope
|
||||||
if (sysOfChan[ch]==DIV_SYSTEM_YM2610 || sysOfChan[ch]==DIV_SYSTEM_YM2610_EXT) {
|
if (IS_YM2610) {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_AY_AUTO_ENVELOPE,ch,effectVal));
|
dispatchCmd(DivCommand(DIV_CMD_AY_AUTO_ENVELOPE,ch,effectVal));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue