From f1b30c01a4c37edfd7306a402a5c8ab5eef31e8e Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 4 Jul 2023 00:23:28 -0500 Subject: [PATCH] dev160 - C64: add key priority system and options to change hard reset envelope issue #1115 --- src/engine/engine.h | 4 ++-- src/engine/fileOps.cpp | 14 +++++++++++ src/engine/platform/c64.cpp | 26 ++++++++++++++++++--- src/engine/platform/c64.h | 4 ++++ src/gui/sysConf.cpp | 46 +++++++++++++++++++++++++++++++++++++ 5 files changed, 89 insertions(+), 5 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index 21e15b562..aceee308b 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -54,8 +54,8 @@ #define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock(); #define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false; -#define DIV_VERSION "dev159" -#define DIV_ENGINE_VERSION 159 +#define DIV_VERSION "dev160" +#define DIV_ENGINE_VERSION 160 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index ed0c0ce95..77f3f3dc5 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -1047,6 +1047,11 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { ds.systemFlags[0].set("dpcmMode",false); } + // C64 no key priority + if (ds.system[0]==DIV_SYSTEM_C64_8580 || ds.system[0]==DIV_SYSTEM_C64_6581) { + ds.systemFlags[0].set("keyPriority",false); + } + ds.systemName=getSongSystemLegacyName(ds,!getConfInt("noMultiSystem",0)); if (active) quitDispatch(); @@ -2927,6 +2932,15 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { } } + // C64 key priority compat + if (ds.version<160) { + for (int i=0; igetIns(chan[i].ins,DIV_INS_C64); @@ -179,8 +181,8 @@ void DivPlatformC64::tick(bool sysTick) { if (--chan[i].testWhen<1) { if (!chan[i].resetMask && !chan[i].inPorta) { DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_C64); - rWrite(i*7+5,0); - rWrite(i*7+6,0); + rWrite(i*7+5,testAD); + rWrite(i*7+6,testSR); rWrite(i*7+4,(chan[i].wave<<4)|(ins->c64.noTest?0:8)|(chan[i].test<<3)|(chan[i].ring<<2)|(chan[i].sync<<1)); } } @@ -212,6 +214,7 @@ void DivPlatformC64::tick(bool sysTick) { } int DivPlatformC64::dispatch(DivCommand c) { + if (c.chan>2) return 0; switch (c.cmd) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_C64); @@ -249,6 +252,16 @@ int DivPlatformC64::dispatch(DivCommand c) { if (chan[c.chan].insChanged) { chan[c.chan].insChanged=false; } + if (keyPriority) { + if (chanOrder[1]==c.chan) { + chanOrder[1]=chanOrder[2]; + chanOrder[2]=c.chan; + } else if (chanOrder[0]==c.chan) { + chanOrder[0]=chanOrder[1]; + chanOrder[1]=chanOrder[2]; + chanOrder[2]=c.chan; + } + } chan[c.chan].macroInit(ins); break; } @@ -524,6 +537,10 @@ void DivPlatformC64::reset() { filtCut=2047; resetTime=1; vol=15; + + chanOrder[0]=0; + chanOrder[1]=1; + chanOrder[2]=2; } void DivPlatformC64::poke(unsigned int addr, unsigned short val) { @@ -576,6 +593,9 @@ void DivPlatformC64::setFlags(const DivConfig& flags) { rate/=4; sid_fp.setSamplingParameters(chipClock,reSIDfp::DECIMATE,rate,0); } + keyPriority=flags.getBool("keyPriority",true); + testAD=((flags.getInt("testAttack",0)&15)<<4)|(flags.getInt("testDecay",0)&15); + testSR=((flags.getInt("testSustain",0)&15)<<4)|(flags.getInt("testRelease",0)&15); } int DivPlatformC64::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) { diff --git a/src/engine/platform/c64.h b/src/engine/platform/c64.h index be78c2d01..b9b30b6ec 100644 --- a/src/engine/platform/c64.h +++ b/src/engine/platform/c64.h @@ -67,6 +67,10 @@ class DivPlatformC64: public DivDispatch { int filtCut, resetTime; bool isFP; + bool keyPriority; + unsigned char chanOrder[3]; + unsigned char testAD, testSR; + SID sid; reSIDfp::SID sid_fp; unsigned char regPool[32]; diff --git a/src/gui/sysConf.cpp b/src/gui/sysConf.cpp index 58ee524e1..10bd055a7 100644 --- a/src/gui/sysConf.cpp +++ b/src/gui/sysConf.cpp @@ -495,6 +495,13 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo case DIV_SYSTEM_C64_8580: case DIV_SYSTEM_C64_6581: { int clockSel=flags.getInt("clockSel",0); + bool keyPriority=flags.getBool("keyPriority",true); + int testAttack=flags.getInt("testAttack",0); + int testDecay=flags.getInt("testDecay",0); + int testSustain=flags.getInt("testSustain",0); + int testRelease=flags.getInt("testRelease",0); + + ImGui::Text("Clock rate:"); if (ImGui::RadioButton("NTSC (1.02MHz)",clockSel==0)) { clockSel=0; @@ -509,9 +516,48 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo altered=true; } + ImGui::Text("Global parameter priority:"); + + if (ImGui::RadioButton("Left to right",!keyPriority)) { + keyPriority=false; + altered=true; + } + if (ImGui::RadioButton("Last used channel",keyPriority)) { + keyPriority=true; + altered=true; + } + + ImGui::Text("Hard reset envelope:"); + + if (CWSliderInt("Attack",&testAttack,0,15)) { + if (testAttack<0) testAttack=0; + if (testAttack>15) testAttack=15; + altered=true; + } + if (CWSliderInt("Decay",&testDecay,0,15)) { + if (testDecay<0) testDecay=0; + if (testDecay>15) testDecay=15; + altered=true; + } + if (CWSliderInt("Sustain",&testSustain,0,15)) { + if (testSustain<0) testSustain=0; + if (testSustain>15) testSustain=15; + altered=true; + } + if (CWSliderInt("Release",&testRelease,0,15)) { + if (testRelease<0) testRelease=0; + if (testRelease>15) testRelease=15; + altered=true; + } + if (altered) { e->lockSave([&]() { flags.set("clockSel",clockSel); + flags.set("keyPriority",keyPriority); + flags.set("testAttack",testAttack); + flags.set("testDecay",testDecay); + flags.set("testSustain",testSustain); + flags.set("testRelease",testRelease); }); } break;