From 9736b7740127d2fd6bebd4c135d79755d2482ad4 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 17 May 2021 15:06:11 -0500 Subject: [PATCH] better volume slide accuracy volume slide seems to be kind of quirky: - sliding all the way down and then up suddenly sets the vol to max - apparently there is an overflow and the slide stops when it reaches its boundaries (instead of continuing) --- src/engine/dispatch.h | 1 + src/engine/engine.cpp | 5 +++++ src/engine/engine.h | 2 +- src/engine/platform/dummy.cpp | 3 +++ src/engine/platform/genesis.cpp | 3 +++ src/engine/platform/genesisext.cpp | 5 ++++- src/engine/platform/sms.cpp | 3 +++ src/engine/playback.cpp | 22 ++++++++++++++++------ 8 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index fb7ce9ed5..1c35639f7 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -9,6 +9,7 @@ enum DivDispatchCmds { DIV_CMD_INSTRUMENT, DIV_CMD_VOLUME, DIV_CMD_GET_VOLUME, + DIV_CMD_GET_VOLMAX, DIV_CMD_NOTE_PORTA, DIV_CMD_PITCH, DIV_CMD_PANNING, diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index ea48355ad..e165fa165 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -697,6 +697,11 @@ bool DivEngine::init() { blip_set_rates(bb[0],dispatch->rate,got.rate); blip_set_rates(bb[1],dispatch->rate,got.rate); + for (int i=0; idispatch(DivCommand(DIV_CMD_GET_VOLMAX,i))<<8; + chan[i].volume=chan[i].volMax; + } + if (!output->setRun(true)) { logE("error while activating!\n"); return false; diff --git a/src/engine/engine.h b/src/engine/engine.h index 595b26d34..adbfcea13 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -8,7 +8,7 @@ struct DivChannelState { std::vector delayed; int note, pitch, portaSpeed, portaNote; - int volume, volSpeed, cut, rowDelay; + int volume, volSpeed, cut, rowDelay, volMax; int vibratoDepth, vibratoRate, vibratoPos; int tremoloDepth, tremoloRate, tremoloPos; unsigned char arp, arpStage; diff --git a/src/engine/platform/dummy.cpp b/src/engine/platform/dummy.cpp index 932342166..d1e121313 100644 --- a/src/engine/platform/dummy.cpp +++ b/src/engine/platform/dummy.cpp @@ -32,6 +32,9 @@ int DivPlatformDummy::dispatch(DivCommand c) { case DIV_CMD_GET_VOLUME: return chan[c.chan].vol; break; + case DIV_CMD_GET_VOLMAX: + return 15; + break; default: break; } diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 76ad9837b..6abc2c343 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -301,6 +301,9 @@ int DivPlatformGenesis::dispatch(DivCommand c) { break; } + case DIV_CMD_GET_VOLMAX: + return 127; + break; default: printf("WARNING: unimplemented command %d\n",c.cmd); break; diff --git a/src/engine/platform/genesisext.cpp b/src/engine/platform/genesisext.cpp index 88478b35e..bd60dae66 100644 --- a/src/engine/platform/genesisext.cpp +++ b/src/engine/platform/genesisext.cpp @@ -20,6 +20,9 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) { case DIV_CMD_VOLUME: chan[c.chan].vol=c.value; break; + case DIV_CMD_GET_VOLMAX: + return 127; + break; default: break; } @@ -35,4 +38,4 @@ int DivPlatformGenesisExt::init(DivEngine* parent, int channels, int sugRate) { extMode=true; return 13; -} \ No newline at end of file +} diff --git a/src/engine/platform/sms.cpp b/src/engine/platform/sms.cpp index 7e111535d..8dc2d6f0e 100644 --- a/src/engine/platform/sms.cpp +++ b/src/engine/platform/sms.cpp @@ -144,6 +144,9 @@ int DivPlatformSMS::dispatch(DivCommand c) { case DIV_CMD_PRE_PORTA: chan[c.chan].std.init(parent->getIns(chan[c.chan].ins)); break; + case DIV_CMD_GET_VOLMAX: + return 15; + break; default: break; } diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index f1206ead6..320ae5784 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -134,8 +134,10 @@ void DivEngine::processRow(int i, bool afterDelay) { // volume if (pat->data[curRow][3]!=-1) { - chan[i].volume=pat->data[curRow][3]<<8; - dispatch->dispatch(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8)); + if ((chan[i].volume>>8)!=pat->data[curRow][3]) { + chan[i].volume=pat->data[curRow][3]<<8; + dispatch->dispatch(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8)); + } } // effects @@ -342,11 +344,19 @@ void DivEngine::nextTick() { } } if (chan[i].volSpeed!=0) { - chan[i].volume=(chan[i].volume&0xff)|(dispatch->dispatch(DivCommand(DIV_CMD_GET_VOLUME,i))<<8); + //chan[i].volume=(chan[i].volume&0xff)|(dispatch->dispatch(DivCommand(DIV_CMD_GET_VOLUME,i))<<8); chan[i].volume+=chan[i].volSpeed; - if (chan[i].volume>0x7f00) chan[i].volume=0x7f00; - if (chan[i].volume<0) chan[i].volume=0; - dispatch->dispatch(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8)); + if (chan[i].volume>chan[i].volMax) { + chan[i].volume=chan[i].volMax; + chan[i].volSpeed=0; + dispatch->dispatch(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8)); + } else if (chan[i].volume<0) { + chan[i].volSpeed=0; + chan[i].volume=chan[i].volMax; + dispatch->dispatch(DivCommand(DIV_CMD_VOLUME,i,0)); + } else { + dispatch->dispatch(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8)); + } } if (chan[i].vibratoDepth>0) { chan[i].vibratoPos+=chan[i].vibratoRate;