diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index ab1e6688c..c39ed19b2 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -71,10 +71,12 @@ void DivPlatformGB::tick() { if (chan[i].baseFreq>255) chan[i].baseFreq=255; if (chan[i].baseFreq<0) chan[i].baseFreq=0; } else { - if (chan[i].std.arpMode) { - chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].std.arp+24)/12.0f))); - } else { - chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp-12)/12.0f))); + if (!chan[i].inPorta) { + if (chan[i].std.arpMode) { + chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].std.arp+24)/12.0f))); + } else { + chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].note+chan[i].std.arp-12)/12.0f))); + } } } chan[i].freqChanged=true; @@ -211,7 +213,10 @@ int DivPlatformGB::dispatch(DivCommand c) { } } chan[c.chan].freqChanged=true; - if (return2) return 2; + if (return2) { + chan[c.chan].inPorta=false; + return 2; + } break; } case DIV_CMD_STD_NOISE_MODE: @@ -235,6 +240,7 @@ int DivPlatformGB::dispatch(DivCommand c) { break; case DIV_CMD_PRE_PORTA: chan[c.chan].std.init(parent->getIns(chan[c.chan].ins)); + chan[c.chan].inPorta=c.value; break; case DIV_CMD_GB_SWEEP_DIR: chan[c.chan].sweep&=0xf7; diff --git a/src/engine/platform/gb.h b/src/engine/platform/gb.h index 37b807cf8..404017d44 100644 --- a/src/engine/platform/gb.h +++ b/src/engine/platform/gb.h @@ -9,7 +9,7 @@ class DivPlatformGB: public DivDispatch { struct Channel { int freq, baseFreq, pitch; unsigned char ins, note, duty, sweep; - bool active, insChanged, freqChanged, sweepChanged, keyOn, keyOff; + bool active, insChanged, freqChanged, sweepChanged, keyOn, keyOff, inPorta; signed char vol, outVol, wave; DivMacroInt std; Channel(): @@ -26,6 +26,7 @@ class DivPlatformGB: public DivDispatch { sweepChanged(false), keyOn(false), keyOff(false), + inPorta(false), vol(15), wave(-1) {} }; diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 8671031e7..0cdcd7209 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -274,7 +274,7 @@ void DivEngine::processRow(int i, bool afterDelay) { chan[i].portaStop=true; chan[i].doNote=false; chan[i].stopOnOff=true; - dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i)); + dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,true)); } break; case 0x04: // vibrato @@ -493,6 +493,8 @@ void DivEngine::nextTick() { if (chan[i].portaSpeed>0) { if (dispatchCmd(DivCommand(DIV_CMD_NOTE_PORTA,i,chan[i].portaSpeed,chan[i].portaNote))==2 && chan[i].portaStop) { chan[i].portaSpeed=0; + chan[i].note=chan[i].portaNote; + dispatchCmd(DivCommand(DIV_CMD_LEGATO,i,chan[i].note)); } } if (chan[i].cut>0) {