game boy progress, part 5
now with almost accurate arpeggios.
This commit is contained in:
parent
c6e42739fc
commit
83ce4f0ebe
|
@ -31,6 +31,13 @@ enum DivDispatchCmds {
|
||||||
DIV_CMD_STD_NOISE_FREQ,
|
DIV_CMD_STD_NOISE_FREQ,
|
||||||
DIV_CMD_STD_NOISE_MODE,
|
DIV_CMD_STD_NOISE_MODE,
|
||||||
|
|
||||||
|
DIV_CMD_WAVE,
|
||||||
|
|
||||||
|
DIV_CMD_GB_SWEEP_TIME,
|
||||||
|
DIV_CMD_GB_SWEEP_DIR,
|
||||||
|
|
||||||
|
DIV_ALWAYS_SET_VOLUME,
|
||||||
|
|
||||||
DIV_CMD_MAX
|
DIV_CMD_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ struct DivChannelState {
|
||||||
int vibratoDepth, vibratoRate, vibratoPos, vibratoDir, vibratoFine;
|
int vibratoDepth, vibratoRate, vibratoPos, vibratoDir, vibratoFine;
|
||||||
int tremoloDepth, tremoloRate, tremoloPos;
|
int tremoloDepth, tremoloRate, tremoloPos;
|
||||||
unsigned char arp, arpStage, arpTicks;
|
unsigned char arp, arpStage, arpTicks;
|
||||||
bool doNote, legato, portaStop, keyOn, nowYouCanStop, stopOnOff;
|
bool doNote, legato, portaStop, keyOn, nowYouCanStop, stopOnOff, arpYield;
|
||||||
|
|
||||||
DivChannelState():
|
DivChannelState():
|
||||||
note(-1),
|
note(-1),
|
||||||
|
@ -40,7 +40,7 @@ struct DivChannelState {
|
||||||
arp(0),
|
arp(0),
|
||||||
arpStage(-1),
|
arpStage(-1),
|
||||||
arpTicks(1),
|
arpTicks(1),
|
||||||
doNote(false), legato(false), portaStop(false), keyOn(false), nowYouCanStop(true), stopOnOff(false) {}
|
doNote(false), legato(false), portaStop(false), keyOn(false), nowYouCanStop(true), stopOnOff(false), arpYield(false) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DivEngine {
|
class DivEngine {
|
||||||
|
|
|
@ -169,11 +169,9 @@ int DivPlatformGB::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_VOLUME:
|
case DIV_CMD_VOLUME:
|
||||||
if (chan[c.chan].vol!=c.value) {
|
chan[c.chan].vol=c.value;
|
||||||
chan[c.chan].vol=c.value;
|
if (c.chan==2) {
|
||||||
if (c.chan==2) {
|
rWrite(16+c.chan*5+2,gbVolMap[chan[c.chan].vol]);
|
||||||
rWrite(16+c.chan*5+2,gbVolMap[chan[c.chan].vol]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLUME:
|
case DIV_CMD_GET_VOLUME:
|
||||||
|
@ -183,6 +181,12 @@ int DivPlatformGB::dispatch(DivCommand c) {
|
||||||
chan[c.chan].pitch=c.value;
|
chan[c.chan].pitch=c.value;
|
||||||
chan[c.chan].freqChanged=true;
|
chan[c.chan].freqChanged=true;
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_WAVE:
|
||||||
|
if (c.chan!=2) break;
|
||||||
|
chan[c.chan].wave=c.value;
|
||||||
|
updateWave();
|
||||||
|
chan[c.chan].freqChanged=true;
|
||||||
|
break;
|
||||||
case DIV_CMD_NOTE_PORTA: {
|
case DIV_CMD_NOTE_PORTA: {
|
||||||
int destFreq=round(FREQ_BASE/pow(2.0f,((float)c.value2/12.0f)));
|
int destFreq=round(FREQ_BASE/pow(2.0f,((float)c.value2/12.0f)));
|
||||||
bool return2=false;
|
bool return2=false;
|
||||||
|
@ -225,6 +229,9 @@ int DivPlatformGB::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
return 15;
|
return 15;
|
||||||
break;
|
break;
|
||||||
|
case DIV_ALWAYS_SET_VOLUME:
|
||||||
|
return 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -312,6 +312,9 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DIV_ALWAYS_SET_VOLUME:
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
return 127;
|
return 127;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -170,6 +170,9 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
return 127;
|
return 127;
|
||||||
break;
|
break;
|
||||||
|
case DIV_ALWAYS_SET_VOLUME:
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
case DIV_CMD_PRE_PORTA:
|
case DIV_CMD_PRE_PORTA:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -147,6 +147,9 @@ int DivPlatformSMS::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
return 15;
|
return 15;
|
||||||
break;
|
break;
|
||||||
|
case DIV_ALWAYS_SET_VOLUME:
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,14 @@ const char* cmdName[DIV_CMD_MAX]={
|
||||||
"ARCADE_LFO",
|
"ARCADE_LFO",
|
||||||
|
|
||||||
"STD_NOISE_FREQ",
|
"STD_NOISE_FREQ",
|
||||||
"STD_NOISE_MODE"
|
"STD_NOISE_MODE",
|
||||||
|
|
||||||
|
"WAVE",
|
||||||
|
|
||||||
|
"GB_SWEEP_TIME",
|
||||||
|
"GB_SWEEP_DIR",
|
||||||
|
|
||||||
|
"ALWAYS_SET_VOLUME"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* formatNote(unsigned char note, unsigned char octave) {
|
const char* formatNote(unsigned char note, unsigned char octave) {
|
||||||
|
@ -83,6 +90,15 @@ bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effe
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case DIV_SYSTEM_GB:
|
||||||
|
switch (effect) {
|
||||||
|
case 0x10: // select waveform
|
||||||
|
dispatchCmd(DivCommand(DIV_CMD_WAVE,ch,effectVal));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -176,11 +192,14 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
||||||
chan[i].arp=0;
|
chan[i].arp=0;
|
||||||
}
|
}
|
||||||
chan[i].doNote=true;
|
chan[i].doNote=true;
|
||||||
|
if (chan[i].arp!=0) {
|
||||||
|
chan[i].arpYield=true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// volume
|
// volume
|
||||||
if (pat->data[curRow][3]!=-1) {
|
if (pat->data[curRow][3]!=-1) {
|
||||||
if ((MIN(chan[i].volMax,chan[i].volume)>>8)!=pat->data[curRow][3]) {
|
if (dispatchCmd(DivCommand(DIV_ALWAYS_SET_VOLUME,i)) || (MIN(chan[i].volMax,chan[i].volume)>>8)!=pat->data[curRow][3]) {
|
||||||
chan[i].volume=pat->data[curRow][3]<<8;
|
chan[i].volume=pat->data[curRow][3]<<8;
|
||||||
dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8));
|
dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8));
|
||||||
}
|
}
|
||||||
|
@ -473,7 +492,7 @@ void DivEngine::nextTick() {
|
||||||
dispatchCmd(DivCommand(DIV_CMD_NOTE_OFF,i));
|
dispatchCmd(DivCommand(DIV_CMD_NOTE_OFF,i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chan[i].arp!=0 && chan[i].portaSpeed<1) {
|
if (chan[i].arp!=0 && !chan[i].arpYield && chan[i].portaSpeed<1) {
|
||||||
if (--chan[i].arpTicks<1) {
|
if (--chan[i].arpTicks<1) {
|
||||||
chan[i].arpTicks=song.arpLen;
|
chan[i].arpTicks=song.arpLen;
|
||||||
chan[i].arpStage++;
|
chan[i].arpStage++;
|
||||||
|
@ -490,6 +509,8 @@ void DivEngine::nextTick() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
chan[i].arpYield=false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue