diff --git a/src/engine/chipUtils.h b/src/engine/chipUtils.h index eccf9621f..7607193bb 100644 --- a/src/engine/chipUtils.h +++ b/src/engine/chipUtils.h @@ -31,7 +31,7 @@ template struct SharedChannel { int freq, baseFreq, baseNoteOverride, pitch, pitch2, arpOff; int ins, note; bool active, insChanged, freqChanged, fixedArp, keyOn, keyOff, portaPause, inPorta, volChanged; - T vol, macroVol, outVol, maxVol; + T vol, outVol; DivMacroInt std; void handleArp(int offset=0) { if (std.arp.had) { @@ -61,19 +61,6 @@ template struct SharedChannel { arpOff=0; baseNoteOverride=0; fixedArp=false; - if (active && !std.brokenOutVol()) { - if (which==NULL) { - if (macroVol!=maxVol) { - macroVol=maxVol; - volChanged=true; - } - } else if (which->std.volMacro.len==0) { - if (macroVol!=maxVol) { - macroVol=maxVol; - volChanged=true; - } - } - } } SharedChannel(T initVol): freq(0), @@ -92,11 +79,9 @@ template struct SharedChannel { keyOff(false), portaPause(false), inPorta(false), - volChanged(true), + volChanged(false), vol(initVol), - macroVol(initVol), outVol(initVol), - maxVol(initVol), std() {} }; diff --git a/src/engine/macroInt.cpp b/src/engine/macroInt.cpp index 1efbbe87f..557777cc8 100644 --- a/src/engine/macroInt.cpp +++ b/src/engine/macroInt.cpp @@ -43,6 +43,7 @@ void DivMacroStruct::prepare(DivInstrumentMacro& source, DivEngine* e) { mode=source.mode; type=(source.open>>1)&3; activeRelease=source.open&8; + linger=(source.macroType==DIV_MACRO_VOL && e->song.volMacroLinger); lfoPos=LFO_PHASE; } @@ -63,7 +64,7 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic } if (delay>0) { delay--; - had=false; + if (!linger) had=false; return; } if (began && source.delay>0) { @@ -97,6 +98,8 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic if (pos>=source.len) { if (source.loop=source.rel || source.rel>=source.len)) { pos=source.loop; + } else if (linger) { + pos--; } else { has=false; } @@ -137,7 +140,7 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic break; case 4: // end pos=0; - has=false; + if (!linger) has=false; break; } val=ADSR_LOW+((pos+(ADSR_HIGH-ADSR_LOW)*pos)>>8); @@ -250,11 +253,6 @@ void DivMacroInt::setEngine(DivEngine* eng) { e=eng; } -bool DivMacroInt::brokenOutVol() { - if (e==NULL) return false; - return e->song.brokenOutVol; -} - #define ADD_MACRO(m,s) \ if (!m.masked) { \ macroList[macroListLen]=&m; \ diff --git a/src/engine/macroInt.h b/src/engine/macroInt.h index f68df9ec1..28e605029 100644 --- a/src/engine/macroInt.h +++ b/src/engine/macroInt.h @@ -27,13 +27,14 @@ class DivEngine; struct DivMacroStruct { int pos, lastPos, lfoPos, delay; int val; - bool has, had, actualHad, finished, will, began, masked, activeRelease; + bool has, had, actualHad, finished, will, linger, began, masked, activeRelease; unsigned int mode, type; unsigned char macroType; void doMacro(DivInstrumentMacro& source, bool released, bool tick); void init() { pos=lastPos=lfoPos=mode=type=delay=0; has=had=actualHad=will=false; + linger=false; began=true; // TODO: test whether this breaks anything? val=0; @@ -50,6 +51,7 @@ struct DivMacroStruct { actualHad(false), finished(false), will(false), + linger(false), began(true), masked(false), activeRelease(false), @@ -107,12 +109,6 @@ class DivMacroInt { // state bool hasRelease; - /** - * get whether brokenOutVol is enabled. - * @return the value of brokenOutVol, or false if not bound to an engine. - */ - bool brokenOutVol(); - /** * set mask on macro. */ diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index c4d1ed067..a4e279dad 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -68,6 +68,17 @@ const char** DivPlatformAmiga::getRegisterSheet() { return regCheatSheetAmiga; } +#define writeAudDat(x) \ + chan[i].audDat=x; \ + if (i<3 && chan[i].useV) { \ + chan[i+1].outVol=(unsigned char)chan[i].audDat^0x80; \ + if (chan[i+1].outVol>64) chan[i+1].outVol=64; \ + } \ + if (i<3 && chan[i].useP) { \ + chan[i+1].freq=(unsigned char)chan[i].audDat^0x80; \ + if (chan[i+1].freq>6; + chan[i].writeVol=true; } double off=1.0; if (!chan[i].useWave && chan[i].sample>=0 && chan[i].samplesong.sampleLen) { @@ -505,9 +516,8 @@ void DivPlatformAmiga::tick(bool sysTick) { } for (int i=0; i<4; i++) { - if (chan[i].volChanged) { - chan[i].outVol=((chan[i].vol%65)*MIN(64,chan[i].macroVol))>>6; - chan[i].volChanged=false; + if (chan[i].writeVol) { + chan[i].writeVol=false; chWrite(i,8,chan[i].outVol); } if (chan[i].updateWave) { @@ -575,6 +585,10 @@ int DivPlatformAmiga::dispatch(DivCommand c) { chan[c.chan].active=true; chan[c.chan].keyOn=true; chan[c.chan].macroInit(ins); + if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) { + chan[c.chan].outVol=chan[c.chan].vol; + chan[c.chan].writeVol=true; + } if (chan[c.chan].useWave) { chan[c.chan].ws.init(ins,chan[c.chan].audLen<<1,255,chan[c.chan].insChanged); chan[c.chan].updateWave=true; @@ -601,12 +615,17 @@ int DivPlatformAmiga::dispatch(DivCommand c) { case DIV_CMD_VOLUME: if (chan[c.chan].vol!=c.value) { chan[c.chan].vol=c.value; - if (!parent->song.volMacroLinger) chan[c.chan].macroVol=chan[c.chan].maxVol; - chan[c.chan].volChanged=true; + if (!chan[c.chan].std.vol.has) { + chan[c.chan].outVol=c.value; + chan[c.chan].writeVol=true; + } } break; case DIV_CMD_GET_VOLUME: - return chan[c.chan].vol; + if (chan[c.chan].std.vol.has) { + return chan[c.chan].vol; + } + return chan[c.chan].outVol; break; case DIV_CMD_PITCH: chan[c.chan].pitch=c.value; diff --git a/src/engine/platform/amiga.h b/src/engine/platform/amiga.h index 97accae1f..a05a5994d 100644 --- a/src/engine/platform/amiga.h +++ b/src/engine/platform/amiga.h @@ -30,7 +30,7 @@ class DivPlatformAmiga: public DivDispatch { int audSub; unsigned char volPos; int sample, wave; - bool useWave, setPos, useV, useP, dmaOn, audDatClock, updateWave; + bool useWave, setPos, useV, useP, dmaOn, audDatClock, writeVol, updateWave; DivWaveSynth ws; Channel(): SharedChannel(64), @@ -49,6 +49,7 @@ class DivPlatformAmiga: public DivDispatch { useP(false), dmaOn(false), audDatClock(false), + writeVol(true), updateWave(true) {} }; Channel chan[4];