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; i +#include "../../ta-log.h" #define rWrite(a,v) if (!skipRegisterWrites) {writes.emplace(a,v); if (dumpWrites) {addWrite(a,v);} } @@ -106,7 +107,9 @@ void DivPlatformC64::updateFilter() { void DivPlatformC64::tick(bool sysTick) { bool willUpdateFilter=false; - for (int i=0; i<3; i++) { + for (int _i=0; _i<3; _i++) { + int i=chanOrder[_i]; + chan[i].std.next(); if (chan[i].std.vol.had) { DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_C64); @@ -179,8 +182,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 +215,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 +253,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; } @@ -512,6 +526,7 @@ void DivPlatformC64::reset() { if (isFP) { sid_fp.reset(); + sid_fp.clockSilent(16000); } else { sid.reset(); } @@ -524,6 +539,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 +595,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/engine/platform/sound/c64_fp/EnvelopeGenerator.cpp b/src/engine/platform/sound/c64_fp/EnvelopeGenerator.cpp index af636ac7f..d92f68d60 100644 --- a/src/engine/platform/sound/c64_fp/EnvelopeGenerator.cpp +++ b/src/engine/platform/sound/c64_fp/EnvelopeGenerator.cpp @@ -61,7 +61,6 @@ const unsigned int EnvelopeGenerator::adsrtable[16] = void EnvelopeGenerator::reset() { - // counter is not changed on reset envelope_pipeline = 0; state_pipeline = 0; @@ -73,7 +72,7 @@ void EnvelopeGenerator::reset() gate = false; - resetLfsr = true; + resetLfsr = false; exponential_counter = 0; exponential_counter_period = 1; @@ -81,7 +80,11 @@ void EnvelopeGenerator::reset() state = RELEASE; counter_enabled = true; - rate = adsrtable[release]; + rate = 0; + + envelope_counter = 0; + env3 = 0; + lfsr = 0x7fff; } void EnvelopeGenerator::writeCONTROL_REG(unsigned char control) diff --git a/src/engine/platform/sound/c64_fp/EnvelopeGenerator.h b/src/engine/platform/sound/c64_fp/EnvelopeGenerator.h index f2aab3874..1014cf82c 100644 --- a/src/engine/platform/sound/c64_fp/EnvelopeGenerator.h +++ b/src/engine/platform/sound/c64_fp/EnvelopeGenerator.h @@ -146,7 +146,7 @@ public: counter_enabled(true), gate(false), resetLfsr(false), - envelope_counter(0xaa), + envelope_counter(0), attack(0), decay(0), sustain(0), 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;