game boy progress, part 5

now with almost accurate arpeggios.
This commit is contained in:
tildearrow 2021-05-28 00:36:25 -05:00
parent c6e42739fc
commit 83ce4f0ebe
7 changed files with 54 additions and 10 deletions

View file

@ -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
}; };

View file

@ -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 {

View file

@ -169,12 +169,10 @@ 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:
return chan[c.chan].vol; return chan[c.chan].vol;
@ -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;
} }

View file

@ -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;

View file

@ -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:

View file

@ -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;
} }

View file

@ -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;
} }
} }