From fda2ca06453b1ac769261a41b195ff73b5b786e8 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 30 Aug 2023 02:17:16 -0500 Subject: [PATCH] introduce p r e - e f f e c t s the ultimate fix to #1439 --- src/engine/engine.h | 9 +++++-- src/engine/playback.cpp | 37 ++++++++++++++++++++++++++ src/engine/sysDef.cpp | 59 ++++++++++++++++++++++++----------------- 3 files changed, 79 insertions(+), 26 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index 8df2652d..57696e94 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -283,6 +283,7 @@ struct DivSysDef { DivInstrumentType chanInsType[DIV_MAX_CHANS][2]; const EffectHandlerMap effectHandlers; const EffectHandlerMap postEffectHandlers; + const EffectHandlerMap preEffectHandlers; DivSysDef( const char* sysName, const char* sysNameJ, unsigned char fileID, unsigned char fileID_DMF, int chans, bool isFMChip, bool isSTDChip, unsigned int vgmVer, bool compound, unsigned int formatMask, const char* desc, @@ -292,7 +293,8 @@ struct DivSysDef { std::initializer_list chInsType1, std::initializer_list chInsType2={}, const EffectHandlerMap fxHandlers_={}, - const EffectHandlerMap postFxHandlers_={}): + const EffectHandlerMap postFxHandlers_={}, + const EffectHandlerMap preFxHandlers_={}): name(sysName), nameJ(sysNameJ), description(desc), @@ -305,7 +307,8 @@ struct DivSysDef { vgmVersion(vgmVer), sampleFormatMask(formatMask), effectHandlers(fxHandlers_), - postEffectHandlers(postFxHandlers_) { + postEffectHandlers(postFxHandlers_), + preEffectHandlers(preFxHandlers_) { memset(chanNames,0,DIV_MAX_CHANS*sizeof(void*)); memset(chanShortNames,0,DIV_MAX_CHANS*sizeof(void*)); memset(chanTypes,0,DIV_MAX_CHANS*sizeof(int)); @@ -484,6 +487,7 @@ class DivEngine { // MIDI stuff std::function midiCallback=[](const TAMidiMessage&) -> int {return -2;}; + void processRowPre(int i); void processRow(int i, bool afterDelay); void nextOrder(); void nextRow(); @@ -492,6 +496,7 @@ class DivEngine { bool nextTick(bool noAccum=false, bool inhibitLowLat=false); bool perSystemEffect(int ch, unsigned char effect, unsigned char effectVal); bool perSystemPostEffect(int ch, unsigned char effect, unsigned char effectVal); + bool perSystemPreEffect(int ch, unsigned char effect, unsigned char effectVal); void recalcChans(); void reset(); void playSub(bool preserveDrift, int goalRow=0); diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 13bc57ee..2306f057 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -407,6 +407,38 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char return dispatchCmd(DivCommand(handler.dispatchCmd,ch,val,val2)); } +bool DivEngine::perSystemPreEffect(int ch, unsigned char effect, unsigned char effectVal) { + DivSysDef* sysDef=sysDefs[sysOfChan[ch]]; + if (sysDef==NULL) return false; + auto iter=sysDef->preEffectHandlers.find(effect); + if (iter==sysDef->preEffectHandlers.end()) return false; + EffectHandler handler=iter->second; + int val=0; + int val2=0; + try { + val=handler.val?handler.val(effect,effectVal):effectVal; + val2=handler.val2?handler.val2(effect,effectVal):0; + } catch (DivDoNotHandleEffect& e) { + return false; + } + // wouldn't this cause problems if it were to return 0? + return dispatchCmd(DivCommand(handler.dispatchCmd,ch,val,val2)); +} + +void DivEngine::processRowPre(int i) { + int whatOrder=curOrder; + int whatRow=curRow; + DivPattern* pat=curPat[i].getPattern(curOrders->ord[i][whatOrder],false); + for (int j=0; jdata[whatRow][4+(j<<1)]; + short effectVal=pat->data[whatRow][5+(j<<1)]; + + if (effectVal==-1) effectVal=0; + effectVal&=255; + perSystemPreEffect(i,effect,effectVal); + } +} + void DivEngine::processRow(int i, bool afterDelay) { int whatOrder=afterDelay?chan[i].delayOrder:curOrder; int whatRow=afterDelay?chan[i].delayRow:curRow; @@ -1135,6 +1167,11 @@ void DivEngine::nextRow() { prevRow=curRow; } + for (int i=0; i