From f0f0b7fcd6e43749965251a723a44c552e77e6ad Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 17 Jul 2024 04:11:24 -0500 Subject: [PATCH] implement DCxx effect delayed mute --- src/engine/engine.cpp | 2 ++ src/engine/engine.h | 3 ++- src/engine/fileOps/xm.cpp | 18 +++++++++++++++++- src/engine/playback.cpp | 15 +++++++++++++++ src/gui/guiConst.cpp | 2 +- 5 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 7ca58611b..6efaddd16 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -98,6 +98,8 @@ const char* DivEngine::getEffectDesc(unsigned char effect, int chan, bool notNul break; case 0xc0: case 0xc1: case 0xc2: case 0xc3: return _("Cxxx: Set tick rate (hz)"); + case 0xdc: + return _("DCxx: Delayed mute"); case 0xe0: return _("E0xx: Set arp speed"); case 0xe1: diff --git a/src/engine/engine.h b/src/engine/engine.h index 288f1af2b..8ef789704 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -133,7 +133,7 @@ struct DivAudioExportOptions { struct DivChannelState { std::vector delayed; int note, oldNote, lastIns, pitch, portaSpeed, portaNote; - int volume, volSpeed, cut, legatoDelay, legatoTarget, rowDelay, volMax; + int volume, volSpeed, cut, volCut, legatoDelay, legatoTarget, rowDelay, volMax; int delayOrder, delayRow, retrigSpeed, retrigTick; int vibratoDepth, vibratoRate, vibratoPos, vibratoPosGiant, vibratoShape, vibratoFine; int tremoloDepth, tremoloRate, tremoloPos; @@ -158,6 +158,7 @@ struct DivChannelState { volume(0x7f00), volSpeed(0), cut(-1), + volCut(-1), legatoDelay(-1), legatoTarget(0), rowDelay(0), diff --git a/src/engine/fileOps/xm.cpp b/src/engine/fileOps/xm.cpp index d4b7c6ca0..0d616968b 100644 --- a/src/engine/fileOps/xm.cpp +++ b/src/engine/fileOps/xm.cpp @@ -1077,8 +1077,24 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) { p->data[j][effectCol[k]++]=0x0c; p->data[j][effectCol[k]++]=(effectVal&15); break; + case 0xa: // vol slide up (fine) + volSlideStatus[k]=((effectVal&15)<<4)|0xf; + volSlideStatusChanged[k]=true; + if (hasNote || hasIns) { + volSlideStatusChanged[k]=true; + } + volSliding[k]=true; + break; + case 0xb: // vol slide down (fine) + volSlideStatus[k]=0xf0|(effectVal&15); + volSlideStatusChanged[k]=true; + if (hasNote || hasIns) { + volSlideStatusChanged[k]=true; + } + volSliding[k]=true; + break; case 0xc: - p->data[j][effectCol[k]++]=0xec; + p->data[j][effectCol[k]++]=0xdc; p->data[j][effectCol[k]++]=MAX(1,effectVal&15); break; case 0xd: diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index efa0959fb..b7b8098b6 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -932,6 +932,12 @@ void DivEngine::processRow(int i, bool afterDelay) { clockDrift=0; subticks=0; break; + case 0xdc: // delayed mute + if (effectVal>0 && (song.delayBehavior==2 || effectVal0) { curSubSong->arpLen=effectVal; @@ -1781,6 +1787,15 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) { } } + // volume cut/mute + if (chan[i].volCut>0) { + if (--chan[i].volCut<1) { + chan[i].volume=0; + dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8)); + dispatchCmd(DivCommand(DIV_CMD_HINT_VOLUME,i,chan[i].volume>>8)); + } + } + // arpeggio if (chan[i].resetArp) { dispatchCmd(DivCommand(DIV_CMD_LEGATO,i,chan[i].note)); diff --git a/src/gui/guiConst.cpp b/src/gui/guiConst.cpp index ca7a26b44..2595827b0 100644 --- a/src/gui/guiConst.cpp +++ b/src/gui/guiConst.cpp @@ -482,7 +482,7 @@ const FurnaceGUIColors fxColors[256]={ GUI_COLOR_PATTERN_EFFECT_INVALID, GUI_COLOR_PATTERN_EFFECT_INVALID, GUI_COLOR_PATTERN_EFFECT_INVALID, - GUI_COLOR_PATTERN_EFFECT_INVALID, + GUI_COLOR_PATTERN_EFFECT_VOLUME, // DC GUI_COLOR_PATTERN_EFFECT_INVALID, GUI_COLOR_PATTERN_EFFECT_INVALID, GUI_COLOR_PATTERN_EFFECT_MISC, // DF