dev160 - C64: add key priority system

and options to change hard reset envelope

issue #1115
This commit is contained in:
tildearrow 2023-07-04 00:23:28 -05:00
parent 7e6ffd7e12
commit f1b30c01a4
5 changed files with 89 additions and 5 deletions

View file

@ -54,8 +54,8 @@
#define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock(); #define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock();
#define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false; #define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false;
#define DIV_VERSION "dev159" #define DIV_VERSION "dev160"
#define DIV_ENGINE_VERSION 159 #define DIV_ENGINE_VERSION 160
// for imports // for imports
#define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_MOD 0xff01
#define DIV_VERSION_FC 0xff02 #define DIV_VERSION_FC 0xff02

View file

@ -1047,6 +1047,11 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
ds.systemFlags[0].set("dpcmMode",false); 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)); ds.systemName=getSongSystemLegacyName(ds,!getConfInt("noMultiSystem",0));
if (active) quitDispatch(); 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<ds.systemLen; i++) {
if (ds.system[i]==DIV_SYSTEM_C64_8580 || ds.system[i]==DIV_SYSTEM_C64_6581) {
ds.systemFlags[i].set("keyPriority",false);
}
}
}
if (active) quitDispatch(); if (active) quitDispatch();
BUSY_BEGIN_SOFT; BUSY_BEGIN_SOFT;
saveLock.lock(); saveLock.lock();

View file

@ -106,7 +106,9 @@ void DivPlatformC64::updateFilter() {
void DivPlatformC64::tick(bool sysTick) { void DivPlatformC64::tick(bool sysTick) {
bool willUpdateFilter=false; 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(); chan[i].std.next();
if (chan[i].std.vol.had) { if (chan[i].std.vol.had) {
DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_C64); DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_C64);
@ -179,8 +181,8 @@ void DivPlatformC64::tick(bool sysTick) {
if (--chan[i].testWhen<1) { if (--chan[i].testWhen<1) {
if (!chan[i].resetMask && !chan[i].inPorta) { if (!chan[i].resetMask && !chan[i].inPorta) {
DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_C64); DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_C64);
rWrite(i*7+5,0); rWrite(i*7+5,testAD);
rWrite(i*7+6,0); 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)); 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) { int DivPlatformC64::dispatch(DivCommand c) {
if (c.chan>2) return 0;
switch (c.cmd) { switch (c.cmd) {
case DIV_CMD_NOTE_ON: { case DIV_CMD_NOTE_ON: {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_C64); 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) { if (chan[c.chan].insChanged) {
chan[c.chan].insChanged=false; 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); chan[c.chan].macroInit(ins);
break; break;
} }
@ -524,6 +537,10 @@ void DivPlatformC64::reset() {
filtCut=2047; filtCut=2047;
resetTime=1; resetTime=1;
vol=15; vol=15;
chanOrder[0]=0;
chanOrder[1]=1;
chanOrder[2]=2;
} }
void DivPlatformC64::poke(unsigned int addr, unsigned short val) { void DivPlatformC64::poke(unsigned int addr, unsigned short val) {
@ -576,6 +593,9 @@ void DivPlatformC64::setFlags(const DivConfig& flags) {
rate/=4; rate/=4;
sid_fp.setSamplingParameters(chipClock,reSIDfp::DECIMATE,rate,0); 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) { int DivPlatformC64::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) {

View file

@ -67,6 +67,10 @@ class DivPlatformC64: public DivDispatch {
int filtCut, resetTime; int filtCut, resetTime;
bool isFP; bool isFP;
bool keyPriority;
unsigned char chanOrder[3];
unsigned char testAD, testSR;
SID sid; SID sid;
reSIDfp::SID sid_fp; reSIDfp::SID sid_fp;
unsigned char regPool[32]; unsigned char regPool[32];

View file

@ -495,6 +495,13 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
case DIV_SYSTEM_C64_8580: case DIV_SYSTEM_C64_8580:
case DIV_SYSTEM_C64_6581: { case DIV_SYSTEM_C64_6581: {
int clockSel=flags.getInt("clockSel",0); 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)) { if (ImGui::RadioButton("NTSC (1.02MHz)",clockSel==0)) {
clockSel=0; clockSel=0;
@ -509,9 +516,48 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
altered=true; 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) { if (altered) {
e->lockSave([&]() { e->lockSave([&]() {
flags.set("clockSel",clockSel); 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; break;