From 87b88519003179def404ba5ca4d3c3ba89b81812 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 29 Oct 2023 02:25:35 -0500 Subject: [PATCH] C64: volIsCutoff compatibility --- src/engine/fileOps.cpp | 46 +++++++++++++++++++++++++++++-------- src/engine/fileOpsIns.cpp | 18 +++++++++++---- src/engine/instrument.cpp | 32 ++++++++++++++++++-------- src/engine/instrument.h | 5 ++-- src/engine/platform/c64.cpp | 19 +++++++++++++++ src/engine/platform/c64.h | 1 + 6 files changed, 94 insertions(+), 27 deletions(-) diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index 0175c02e2..d7815ffa9 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -601,6 +601,8 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { } if (ds.system[0]==DIV_SYSTEM_C64_6581 || ds.system[0]==DIV_SYSTEM_C64_8580) { + bool volIsCutoff=false; + ins->c64.triOn=reader.readC(); ins->c64.sawOn=reader.readC(); ins->c64.pulseOn=reader.readC(); @@ -617,9 +619,9 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { ins->c64.oscSync=reader.readC(); ins->c64.toFilter=reader.readC(); if (ds.version<0x11) { - ins->c64.volIsCutoff=reader.readI(); + volIsCutoff=reader.readI(); } else { - ins->c64.volIsCutoff=reader.readC(); + volIsCutoff=reader.readC(); } ins->c64.initFilter=reader.readC(); @@ -631,10 +633,16 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { ins->c64.ch3off=reader.readC(); // weird storage - if (ins->c64.volIsCutoff) { - for (int j=0; jstd.volMacro.len; j++) { - ins->std.volMacro.val[j]-=18; + if (volIsCutoff) { + // move to alg (new cutoff) + ins->std.algMacro.len=ins->std.volMacro.len; + ins->std.algMacro.loop=ins->std.volMacro.loop; + ins->std.algMacro.rel=ins->std.volMacro.rel; + for (int j=0; jstd.algMacro.len; j++) { + ins->std.algMacro.val[j]=-(ins->std.volMacro.val[j]-18); } + ins->std.volMacro.len=0; + memset(ins->std.volMacro.val,0,256*sizeof(int)); } for (int j=0; jstd.dutyMacro.len; j++) { ins->std.dutyMacro.val[j]-=12; @@ -6061,13 +6069,27 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) { } } } else { // STD + bool volIsCutoff=false; + if (sys!=DIV_SYSTEM_GB) { int realVolMacroLen=i->std.volMacro.len; if (realVolMacroLen>127) realVolMacroLen=127; w->writeC(realVolMacroLen); - if ((sys==DIV_SYSTEM_C64_6581 || sys==DIV_SYSTEM_C64_8580) && i->c64.volIsCutoff) { - for (int j=0; jwriteI(i->std.volMacro.val[j]+18); + if (sys==DIV_SYSTEM_C64_6581 || sys==DIV_SYSTEM_C64_8580) { + if (i->std.algMacro.len>0) volIsCutoff=true; + if (volIsCutoff) { + if (i->std.volMacro.len>0) { + addWarning(".dmf only supports volume or cutoff macro in C64, but not both. volume macro will be lost."); + } + realVolMacroLen=i->std.algMacro.len; + if (realVolMacroLen>127) realVolMacroLen=127; + for (int j=0; jwriteI((-i->std.algMacro.val[j])+18); + } + } else { + for (int j=0; jwriteI(i->std.volMacro.val[j]); + } } } else { for (int j=0; j0) { - w->writeC(i->std.volMacro.loop); + if (volIsCutoff) { + w->writeC(i->std.algMacro.loop); + } else { + w->writeC(i->std.volMacro.loop); + } } } @@ -6166,7 +6192,7 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) { w->writeC(i->c64.oscSync); w->writeC(i->c64.toFilter); - w->writeC(i->c64.volIsCutoff); + w->writeC(volIsCutoff); w->writeC(i->c64.initFilter); w->writeC(i->c64.res); diff --git a/src/engine/fileOpsIns.cpp b/src/engine/fileOpsIns.cpp index 0a7682735..8236ebe0f 100644 --- a/src/engine/fileOpsIns.cpp +++ b/src/engine/fileOpsIns.cpp @@ -349,6 +349,8 @@ void DivEngine::loadDMP(SafeReader& reader, std::vector& ret, St } if (ins->type==DIV_INS_C64) { + bool volIsCutoff=false; + ins->c64.triOn=reader.readC(); ins->c64.sawOn=reader.readC(); ins->c64.pulseOn=reader.readC(); @@ -365,9 +367,9 @@ void DivEngine::loadDMP(SafeReader& reader, std::vector& ret, St ins->c64.oscSync=reader.readC(); ins->c64.toFilter=reader.readC(); if (version<0x07) { // TODO: UNSURE - ins->c64.volIsCutoff=reader.readI(); + volIsCutoff=reader.readI(); } else { - ins->c64.volIsCutoff=reader.readC(); + volIsCutoff=reader.readC(); } ins->c64.initFilter=reader.readC(); @@ -379,10 +381,16 @@ void DivEngine::loadDMP(SafeReader& reader, std::vector& ret, St ins->c64.ch3off=reader.readC(); // weird storage - if (ins->c64.volIsCutoff) { - for (int j=0; jstd.volMacro.len; j++) { - ins->std.volMacro.val[j]-=18; + if (volIsCutoff) { + // move to alg (new cutoff) + ins->std.algMacro.len=ins->std.volMacro.len; + ins->std.algMacro.loop=ins->std.volMacro.loop; + ins->std.algMacro.rel=ins->std.volMacro.rel; + for (int j=0; jstd.algMacro.len; j++) { + ins->std.algMacro.val[j]=-(ins->std.volMacro.val[j]-18); } + ins->std.volMacro.len=0; + memset(ins->std.volMacro.val,0,256*sizeof(int)); } for (int j=0; jstd.dutyMacro.len; j++) { ins->std.dutyMacro.val[j]-=12; diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index 43bf02299..46e4b00f7 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -101,7 +101,6 @@ bool DivInstrumentC64::operator==(const DivInstrumentC64& other) { _C(ringMod) && _C(oscSync) && _C(toFilter) && - _C(volIsCutoff) && _C(initFilter) && _C(dutyIsAbs) && _C(filterIsAbs) && @@ -391,7 +390,6 @@ void DivInstrument::writeFeature64(SafeWriter* w) { w->writeC( (c64.dutyIsAbs?0x80:0)| (c64.initFilter?0x40:0)| - (c64.volIsCutoff?0x20:0)| (c64.toFilter?0x10:0)| (c64.noiseOn?8:0)| (c64.pulseOn?4:0)| @@ -1323,7 +1321,7 @@ void DivInstrument::putInsData(SafeWriter* w) { w->writeC(c64.oscSync); w->writeC(c64.toFilter); w->writeC(c64.initFilter); - w->writeC(c64.volIsCutoff); + w->writeC(0); // this was volIsCutoff w->writeC(c64.res); w->writeC(c64.lp); w->writeC(c64.bp); @@ -2094,13 +2092,13 @@ void DivInstrument::readFeatureMA(SafeReader& reader, short version) { READ_FEAT_END; } -void DivInstrument::readFeature64(SafeReader& reader, short version) { +void DivInstrument::readFeature64(SafeReader& reader, bool& volIsCutoff, short version) { READ_FEAT_BEGIN; unsigned char next=reader.readC(); c64.dutyIsAbs=next&128; c64.initFilter=next&64; - c64.volIsCutoff=next&32; + volIsCutoff=next&32; c64.toFilter=next&16; c64.noiseOn=next&8; c64.pulseOn=next&4; @@ -2602,6 +2600,7 @@ void DivInstrument::readFeatureNE(SafeReader& reader, short version) { DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, bool fui, DivSong* song) { unsigned char featCode[2]; + bool volIsCutoff=false; int dataLen=reader.size()-4; if (!fui) { @@ -2630,7 +2629,7 @@ DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, b } else if (memcmp(featCode,"MA",2)==0) { // macros readFeatureMA(reader,version); } else if (memcmp(featCode,"64",2)==0) { // C64 - readFeature64(reader,version); + readFeature64(reader,volIsCutoff,version); } else if (memcmp(featCode,"GB",2)==0) { // Game Boy readFeatureGB(reader,version); } else if (memcmp(featCode,"SM",2)==0) { // sample @@ -2679,6 +2678,13 @@ DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, b } } + // <187 C64 cutoff macro compatibility + if (type==DIV_INS_C64 && volIsCutoff && version<187) { + memcpy(&std.algMacro,&std.volMacro,sizeof(DivInstrumentMacro)); + std.algMacro.macroType=DIV_MACRO_ALG; + std.volMacro=DivInstrumentMacro(DIV_MACRO_VOL,true); + } + return DIV_DATA_SUCCESS; } @@ -2686,6 +2692,7 @@ DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, b for (int macroValPos=0; macroValPoswriteC(c64.ringMod); w->writeC(c64.oscSync); w->writeC(c64.toFilter); - w->writeC(c64.volIsCutoff); + w->writeC(0); // this was volIsCutoff... w->writeC(c64.initFilter); w->writeC(c64.res); w->writeC((c64.cut*100)/2047); diff --git a/src/engine/instrument.h b/src/engine/instrument.h index 6a2a469da..33f140b24 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -412,7 +412,7 @@ struct DivInstrumentC64 { unsigned char a, d, s, r; unsigned short duty; unsigned char ringMod, oscSync; - bool toFilter, volIsCutoff, initFilter, dutyIsAbs, filterIsAbs, noTest; + bool toFilter, initFilter, dutyIsAbs, filterIsAbs, noTest; unsigned char res; unsigned short cut; bool hp, lp, bp, ch3off; @@ -435,7 +435,6 @@ struct DivInstrumentC64 { ringMod(0), oscSync(0), toFilter(false), - volIsCutoff(false), initFilter(false), dutyIsAbs(false), filterIsAbs(false), @@ -816,7 +815,7 @@ struct DivInstrument { void readFeatureNA(SafeReader& reader, short version); void readFeatureFM(SafeReader& reader, short version); void readFeatureMA(SafeReader& reader, short version); - void readFeature64(SafeReader& reader, short version); + void readFeature64(SafeReader& reader, bool& volIsCutoff, short version); void readFeatureGB(SafeReader& reader, short version); void readFeatureSM(SafeReader& reader, short version); void readFeatureOx(SafeReader& reader, int op, short version); diff --git a/src/engine/platform/c64.cpp b/src/engine/platform/c64.cpp index 9d814eec0..1f43d62ab 100644 --- a/src/engine/platform/c64.cpp +++ b/src/engine/platform/c64.cpp @@ -20,6 +20,7 @@ #include "c64.h" #include "../engine.h" #include "sound/c64_fp/siddefs-fp.h" +#include "IconsFontAwesome4.h" #include #include "../../ta-log.h" @@ -589,6 +590,24 @@ DivMacroInt* DivPlatformC64::getChanMacroInt(int ch) { return &chan[ch].std; } +DivChannelModeHints DivPlatformC64::getModeHints(int ch) { + DivChannelModeHints ret; + ret.count=1; + ret.hint[0]=ICON_FA_BELL_SLASH_O; + ret.type[0]=0; + if (ch==2 && (filtControl&8)) { + ret.type[0]=7; + } else if (chan[ch].test && !chan[ch].gate) { + ret.type[0]=5; + } else if (chan[ch].test) { + ret.type[0]=6; + } else if (!chan[ch].gate) { + ret.type[0]=4; + } + + return ret; +} + DivDispatchOscBuffer* DivPlatformC64::getOscBuffer(int ch) { return oscBuf[ch]; } diff --git a/src/engine/platform/c64.h b/src/engine/platform/c64.h index 334479144..dca456998 100644 --- a/src/engine/platform/c64.h +++ b/src/engine/platform/c64.h @@ -113,6 +113,7 @@ class DivPlatformC64: public DivDispatch { bool isVolGlobal(); float getPostAmp(); DivMacroInt* getChanMacroInt(int ch); + DivChannelModeHints getModeHints(int chan); void notifyInsDeletion(void* ins); void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist);