diff --git a/src/engine/chipUtils.h b/src/engine/chipUtils.h index 7607193bb..eccf9621f 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, outVol; + T vol, macroVol, outVol, maxVol; DivMacroInt std; void handleArp(int offset=0) { if (std.arp.had) { @@ -61,6 +61,19 @@ 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), @@ -79,9 +92,11 @@ template struct SharedChannel { keyOff(false), portaPause(false), inPorta(false), - volChanged(false), + volChanged(true), vol(initVol), + macroVol(initVol), outVol(initVol), + maxVol(initVol), std() {} }; diff --git a/src/engine/macroInt.cpp b/src/engine/macroInt.cpp index 557777cc8..1efbbe87f 100644 --- a/src/engine/macroInt.cpp +++ b/src/engine/macroInt.cpp @@ -43,7 +43,6 @@ 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; } @@ -64,7 +63,7 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic } if (delay>0) { delay--; - if (!linger) had=false; + had=false; return; } if (began && source.delay>0) { @@ -98,8 +97,6 @@ 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; } @@ -140,7 +137,7 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic break; case 4: // end pos=0; - if (!linger) has=false; + has=false; break; } val=ADSR_LOW+((pos+(ADSR_HIGH-ADSR_LOW)*pos)>>8); @@ -253,6 +250,11 @@ 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 28e605029..f68df9ec1 100644 --- a/src/engine/macroInt.h +++ b/src/engine/macroInt.h @@ -27,14 +27,13 @@ class DivEngine; struct DivMacroStruct { int pos, lastPos, lfoPos, delay; int val; - bool has, had, actualHad, finished, will, linger, began, masked, activeRelease; + bool has, had, actualHad, finished, will, 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; @@ -51,7 +50,6 @@ struct DivMacroStruct { actualHad(false), finished(false), will(false), - linger(false), began(true), masked(false), activeRelease(false), @@ -109,6 +107,12 @@ 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 a4e279dad..c4d1ed067 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -68,17 +68,6 @@ 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; + chan[i].macroVol=chan[i].std.vol.val; + chan[i].volChanged=true; } double off=1.0; if (!chan[i].useWave && chan[i].sample>=0 && chan[i].samplesong.sampleLen) { @@ -516,8 +505,9 @@ void DivPlatformAmiga::tick(bool sysTick) { } for (int i=0; i<4; i++) { - if (chan[i].writeVol) { - chan[i].writeVol=false; + if (chan[i].volChanged) { + chan[i].outVol=((chan[i].vol%65)*MIN(64,chan[i].macroVol))>>6; + chan[i].volChanged=false; chWrite(i,8,chan[i].outVol); } if (chan[i].updateWave) { @@ -585,10 +575,6 @@ 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; @@ -615,17 +601,12 @@ int DivPlatformAmiga::dispatch(DivCommand c) { case DIV_CMD_VOLUME: if (chan[c.chan].vol!=c.value) { chan[c.chan].vol=c.value; - if (!chan[c.chan].std.vol.has) { - chan[c.chan].outVol=c.value; - chan[c.chan].writeVol=true; - } + if (!parent->song.volMacroLinger) chan[c.chan].macroVol=chan[c.chan].maxVol; + chan[c.chan].volChanged=true; } break; case DIV_CMD_GET_VOLUME: - if (chan[c.chan].std.vol.has) { - return chan[c.chan].vol; - } - return chan[c.chan].outVol; + return chan[c.chan].vol; 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 a05a5994d..97accae1f 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, writeVol, updateWave; + bool useWave, setPos, useV, useP, dmaOn, audDatClock, updateWave; DivWaveSynth ws; Channel(): SharedChannel(64), @@ -49,7 +49,6 @@ class DivPlatformAmiga: public DivDispatch { useP(false), dmaOn(false), audDatClock(false), - writeVol(true), updateWave(true) {} }; Channel chan[4];