From 4a9855f090d4aa81f15d0271d2464ddde23df48f Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 27 Apr 2022 23:54:45 -0500 Subject: [PATCH] dev89 - C64: add test/gate macro and "don't test/gate before new note" setting --- src/engine/engine.h | 4 ++-- src/engine/instrument.cpp | 8 ++++++++ src/engine/instrument.h | 3 ++- src/engine/platform/c64.cpp | 21 ++++++++++++++------- src/engine/platform/c64.h | 3 ++- src/gui/insEdit.cpp | 2 ++ 6 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index b36ee1403..bab5dcd03 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -44,8 +44,8 @@ #define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock(); #define BUSY_END isBusy.unlock(); softLocked=false; -#define DIV_VERSION "dev88" -#define DIV_ENGINE_VERSION 88 +#define DIV_VERSION "dev89" +#define DIV_ENGINE_VERSION 89 // for imports #define DIV_VERSION_MOD 0xff01 diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index d5061e0b7..f9a39724a 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -503,6 +503,9 @@ void DivInstrument::putInsData(SafeWriter* w) { w->writeC(std.ex6Macro.mode); w->writeC(std.ex7Macro.mode); w->writeC(std.ex8Macro.mode); + + // C64 no test + w->writeC(c64.noTest); } DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) { @@ -1006,6 +1009,11 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) { std.ex8Macro.mode=reader.readC(); } + // C64 no test + if (version>=89) { + c64.noTest=reader.readC(); + } + return DIV_DATA_SUCCESS; } diff --git a/src/engine/instrument.h b/src/engine/instrument.h index 0ca780043..d660c5796 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -265,7 +265,7 @@ struct DivInstrumentC64 { unsigned char a, d, s, r; unsigned short duty; unsigned char ringMod, oscSync; - bool toFilter, volIsCutoff, initFilter, dutyIsAbs, filterIsAbs; + bool toFilter, volIsCutoff, initFilter, dutyIsAbs, filterIsAbs, noTest; unsigned char res; unsigned short cut; bool hp, lp, bp, ch3off; @@ -287,6 +287,7 @@ struct DivInstrumentC64 { initFilter(false), dutyIsAbs(false), filterIsAbs(false), + noTest(false), res(0), cut(0), hp(false), diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 79cfb42ba..d893283fc 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -170,16 +170,17 @@ void DivPlatformC64::tick(bool sysTick) { if (chan[i].testWhen>0) { 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+4,(chan[i].wave<<4)|8|(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)); } } } } if (chan[i].std.wave.had) { chan[i].wave=chan[i].std.wave.val; - rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].ring<<2)|(chan[i].sync<<1)|(int)(chan[i].active)); + rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].test<<3)|(chan[i].ring<<2)|(chan[i].sync<<1)|(int)(chan[i].active)); } if (chan[i].std.pitch.had) { chan[i].freqChanged=true; @@ -196,6 +197,11 @@ void DivPlatformC64::tick(bool sysTick) { chan[i].sync=chan[i].std.ex3.val&1; chan[i].ring=chan[i].std.ex3.val&2; chan[i].freqChanged=true; + rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].test<<3)|(chan[i].ring<<2)|(chan[i].sync<<1)|(int)(chan[i].active)); + } + if (chan[i].std.ex4.had) { + chan[i].test=chan[i].std.ex4.val&1; + rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].test<<3)|(chan[i].ring<<2)|(chan[i].sync<<1)|(int)(chan[i].active)); } if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { @@ -204,12 +210,12 @@ void DivPlatformC64::tick(bool sysTick) { if (chan[i].keyOn) { rWrite(i*7+5,(chan[i].attack<<4)|(chan[i].decay)); rWrite(i*7+6,(chan[i].sustain<<4)|(chan[i].release)); - rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].ring<<2)|(chan[i].sync<<1)|1); + rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].test<<3)|(chan[i].ring<<2)|(chan[i].sync<<1)|1); } if (chan[i].keyOff) { rWrite(i*7+5,(chan[i].attack<<4)|(chan[i].decay)); rWrite(i*7+6,(chan[i].sustain<<4)|(chan[i].release)); - rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].ring<<2)|(chan[i].sync<<1)|0); + rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].test<<3)|(chan[i].ring<<2)|(chan[i].sync<<1)|0); } rWrite(i*7,chan[i].freq&0xff); rWrite(i*7+1,chan[i].freq>>8); @@ -231,6 +237,7 @@ int DivPlatformC64::dispatch(DivCommand c) { } chan[c.chan].active=true; chan[c.chan].keyOn=true; + chan[c.chan].test=false; if (chan[c.chan].insChanged || chan[c.chan].resetDuty || ins->std.waveMacro.len>0) { chan[c.chan].duty=ins->c64.duty; rWrite(c.chan*7+2,chan[c.chan].duty&0xff); @@ -335,7 +342,7 @@ int DivPlatformC64::dispatch(DivCommand c) { break; case DIV_CMD_WAVE: chan[c.chan].wave=c.value; - rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|(int)(chan[c.chan].active)); + rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].test<<3)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|(int)(chan[c.chan].active)); break; case DIV_CMD_LEGATO: chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value+((chan[c.chan].std.arp.will && !chan[c.chan].std.arp.mode)?(chan[c.chan].std.arp.val):(0))); @@ -416,11 +423,11 @@ int DivPlatformC64::dispatch(DivCommand c) { break; case 4: chan[c.chan].ring=c.value; - rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|(int)(chan[c.chan].active)); + rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].test<<3)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|(int)(chan[c.chan].active)); break; case 5: chan[c.chan].sync=c.value; - rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|(int)(chan[c.chan].active)); + rWrite(c.chan*7+4,(chan[c.chan].wave<<4)|(chan[c.chan].test<<3)|(chan[c.chan].ring<<2)|(chan[c.chan].sync<<1)|(int)(chan[c.chan].active)); break; case 6: filtControl&=7; diff --git a/src/engine/platform/c64.h b/src/engine/platform/c64.h index 8df82051c..bc3cbf98f 100644 --- a/src/engine/platform/c64.h +++ b/src/engine/platform/c64.h @@ -30,7 +30,7 @@ class DivPlatformC64: public DivDispatch { unsigned char sweep, wave, attack, decay, sustain, release; short duty; bool active, insChanged, freqChanged, sweepChanged, keyOn, keyOff, inPorta, filter; - bool resetMask, resetFilter, resetDuty, ring, sync; + bool resetMask, resetFilter, resetDuty, ring, sync, test; signed char vol, outVol; DivMacroInt std; Channel(): @@ -61,6 +61,7 @@ class DivPlatformC64: public DivDispatch { resetDuty(false), ring(false), sync(false), + test(false), vol(15) {} }; Channel chan[3]; diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 8631e74f8..105921881 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -2433,6 +2433,7 @@ void FurnaceGUI::drawInsEdit() { P(ImGui::Checkbox("Volume Macro is Cutoff Macro",&ins->c64.volIsCutoff)); P(ImGui::Checkbox("Absolute Cutoff Macro",&ins->c64.filterIsAbs)); P(ImGui::Checkbox("Absolute Duty Macro",&ins->c64.dutyIsAbs)); + P(ImGui::Checkbox("Don't test/gate before new note",&ins->c64.noTest)); ImGui::EndTabItem(); } if (ins->type==DIV_INS_AMIGA) if (ImGui::BeginTabItem("Sample")) { @@ -2926,6 +2927,7 @@ void FurnaceGUI::drawInsEdit() { } if (ins->type==DIV_INS_C64) { NORMAL_MACRO(ins->std.ex3Macro,0,2,"ex3","Special",32,ins->std.ex3Macro.open,true,c64SpecialBits,false,NULL,0,0,0,0,false,0,macroDummyMode,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[6],0,2,NULL,false); + NORMAL_MACRO(ins->std.ex4Macro,0,1,"ex4","Test/Gate",32,ins->std.ex4Macro.open,true,NULL,false,NULL,0,0,0,0,false,0,macroDummyMode,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[7],0,1,NULL,false); } if (ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930 || ins->type==DIV_INS_X1_010) { NORMAL_MACRO(ins->std.ex3Macro,0,15,"ex3","AutoEnv Num",96,ins->std.ex3Macro.open,false,NULL,false,NULL,0,0,0,0,false,0,macroDummyMode,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[6],0,15,NULL,false);