C64: volIsCutoff compatibility

This commit is contained in:
tildearrow 2023-10-29 02:25:35 -05:00
parent 90032899c7
commit 87b8851900
6 changed files with 94 additions and 27 deletions

View file

@ -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) { 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.triOn=reader.readC();
ins->c64.sawOn=reader.readC(); ins->c64.sawOn=reader.readC();
ins->c64.pulseOn=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.oscSync=reader.readC();
ins->c64.toFilter=reader.readC(); ins->c64.toFilter=reader.readC();
if (ds.version<0x11) { if (ds.version<0x11) {
ins->c64.volIsCutoff=reader.readI(); volIsCutoff=reader.readI();
} else { } else {
ins->c64.volIsCutoff=reader.readC(); volIsCutoff=reader.readC();
} }
ins->c64.initFilter=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(); ins->c64.ch3off=reader.readC();
// weird storage // weird storage
if (ins->c64.volIsCutoff) { if (volIsCutoff) {
for (int j=0; j<ins->std.volMacro.len; j++) { // move to alg (new cutoff)
ins->std.volMacro.val[j]-=18; 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; j<ins->std.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; j<ins->std.dutyMacro.len; j++) { for (int j=0; j<ins->std.dutyMacro.len; j++) {
ins->std.dutyMacro.val[j]-=12; ins->std.dutyMacro.val[j]-=12;
@ -6061,13 +6069,27 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) {
} }
} }
} else { // STD } else { // STD
bool volIsCutoff=false;
if (sys!=DIV_SYSTEM_GB) { if (sys!=DIV_SYSTEM_GB) {
int realVolMacroLen=i->std.volMacro.len; int realVolMacroLen=i->std.volMacro.len;
if (realVolMacroLen>127) realVolMacroLen=127; if (realVolMacroLen>127) realVolMacroLen=127;
w->writeC(realVolMacroLen); w->writeC(realVolMacroLen);
if ((sys==DIV_SYSTEM_C64_6581 || sys==DIV_SYSTEM_C64_8580) && i->c64.volIsCutoff) { if (sys==DIV_SYSTEM_C64_6581 || sys==DIV_SYSTEM_C64_8580) {
for (int j=0; j<realVolMacroLen; j++) { if (i->std.algMacro.len>0) volIsCutoff=true;
w->writeI(i->std.volMacro.val[j]+18); 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; j<realVolMacroLen; j++) {
w->writeI((-i->std.algMacro.val[j])+18);
}
} else {
for (int j=0; j<realVolMacroLen; j++) {
w->writeI(i->std.volMacro.val[j]);
}
} }
} else { } else {
for (int j=0; j<realVolMacroLen; j++) { for (int j=0; j<realVolMacroLen; j++) {
@ -6075,7 +6097,11 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) {
} }
} }
if (realVolMacroLen>0) { if (realVolMacroLen>0) {
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.oscSync);
w->writeC(i->c64.toFilter); w->writeC(i->c64.toFilter);
w->writeC(i->c64.volIsCutoff); w->writeC(volIsCutoff);
w->writeC(i->c64.initFilter); w->writeC(i->c64.initFilter);
w->writeC(i->c64.res); w->writeC(i->c64.res);

View file

@ -349,6 +349,8 @@ void DivEngine::loadDMP(SafeReader& reader, std::vector<DivInstrument*>& ret, St
} }
if (ins->type==DIV_INS_C64) { if (ins->type==DIV_INS_C64) {
bool volIsCutoff=false;
ins->c64.triOn=reader.readC(); ins->c64.triOn=reader.readC();
ins->c64.sawOn=reader.readC(); ins->c64.sawOn=reader.readC();
ins->c64.pulseOn=reader.readC(); ins->c64.pulseOn=reader.readC();
@ -365,9 +367,9 @@ void DivEngine::loadDMP(SafeReader& reader, std::vector<DivInstrument*>& ret, St
ins->c64.oscSync=reader.readC(); ins->c64.oscSync=reader.readC();
ins->c64.toFilter=reader.readC(); ins->c64.toFilter=reader.readC();
if (version<0x07) { // TODO: UNSURE if (version<0x07) { // TODO: UNSURE
ins->c64.volIsCutoff=reader.readI(); volIsCutoff=reader.readI();
} else { } else {
ins->c64.volIsCutoff=reader.readC(); volIsCutoff=reader.readC();
} }
ins->c64.initFilter=reader.readC(); ins->c64.initFilter=reader.readC();
@ -379,10 +381,16 @@ void DivEngine::loadDMP(SafeReader& reader, std::vector<DivInstrument*>& ret, St
ins->c64.ch3off=reader.readC(); ins->c64.ch3off=reader.readC();
// weird storage // weird storage
if (ins->c64.volIsCutoff) { if (volIsCutoff) {
for (int j=0; j<ins->std.volMacro.len; j++) { // move to alg (new cutoff)
ins->std.volMacro.val[j]-=18; 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; j<ins->std.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; j<ins->std.dutyMacro.len; j++) { for (int j=0; j<ins->std.dutyMacro.len; j++) {
ins->std.dutyMacro.val[j]-=12; ins->std.dutyMacro.val[j]-=12;

View file

@ -101,7 +101,6 @@ bool DivInstrumentC64::operator==(const DivInstrumentC64& other) {
_C(ringMod) && _C(ringMod) &&
_C(oscSync) && _C(oscSync) &&
_C(toFilter) && _C(toFilter) &&
_C(volIsCutoff) &&
_C(initFilter) && _C(initFilter) &&
_C(dutyIsAbs) && _C(dutyIsAbs) &&
_C(filterIsAbs) && _C(filterIsAbs) &&
@ -391,7 +390,6 @@ void DivInstrument::writeFeature64(SafeWriter* w) {
w->writeC( w->writeC(
(c64.dutyIsAbs?0x80:0)| (c64.dutyIsAbs?0x80:0)|
(c64.initFilter?0x40:0)| (c64.initFilter?0x40:0)|
(c64.volIsCutoff?0x20:0)|
(c64.toFilter?0x10:0)| (c64.toFilter?0x10:0)|
(c64.noiseOn?8:0)| (c64.noiseOn?8:0)|
(c64.pulseOn?4:0)| (c64.pulseOn?4:0)|
@ -1323,7 +1321,7 @@ void DivInstrument::putInsData(SafeWriter* w) {
w->writeC(c64.oscSync); w->writeC(c64.oscSync);
w->writeC(c64.toFilter); w->writeC(c64.toFilter);
w->writeC(c64.initFilter); w->writeC(c64.initFilter);
w->writeC(c64.volIsCutoff); w->writeC(0); // this was volIsCutoff
w->writeC(c64.res); w->writeC(c64.res);
w->writeC(c64.lp); w->writeC(c64.lp);
w->writeC(c64.bp); w->writeC(c64.bp);
@ -2094,13 +2092,13 @@ void DivInstrument::readFeatureMA(SafeReader& reader, short version) {
READ_FEAT_END; READ_FEAT_END;
} }
void DivInstrument::readFeature64(SafeReader& reader, short version) { void DivInstrument::readFeature64(SafeReader& reader, bool& volIsCutoff, short version) {
READ_FEAT_BEGIN; READ_FEAT_BEGIN;
unsigned char next=reader.readC(); unsigned char next=reader.readC();
c64.dutyIsAbs=next&128; c64.dutyIsAbs=next&128;
c64.initFilter=next&64; c64.initFilter=next&64;
c64.volIsCutoff=next&32; volIsCutoff=next&32;
c64.toFilter=next&16; c64.toFilter=next&16;
c64.noiseOn=next&8; c64.noiseOn=next&8;
c64.pulseOn=next&4; 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) { DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, bool fui, DivSong* song) {
unsigned char featCode[2]; unsigned char featCode[2];
bool volIsCutoff=false;
int dataLen=reader.size()-4; int dataLen=reader.size()-4;
if (!fui) { if (!fui) {
@ -2630,7 +2629,7 @@ DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, b
} else if (memcmp(featCode,"MA",2)==0) { // macros } else if (memcmp(featCode,"MA",2)==0) { // macros
readFeatureMA(reader,version); readFeatureMA(reader,version);
} else if (memcmp(featCode,"64",2)==0) { // C64 } else if (memcmp(featCode,"64",2)==0) { // C64
readFeature64(reader,version); readFeature64(reader,volIsCutoff,version);
} else if (memcmp(featCode,"GB",2)==0) { // Game Boy } else if (memcmp(featCode,"GB",2)==0) { // Game Boy
readFeatureGB(reader,version); readFeatureGB(reader,version);
} else if (memcmp(featCode,"SM",2)==0) { // sample } 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; return DIV_DATA_SUCCESS;
} }
@ -2686,6 +2692,7 @@ DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, b
for (int macroValPos=0; macroValPos<y; macroValPos++) x[macroValPos]=reader.readI(); for (int macroValPos=0; macroValPos<y; macroValPos++) x[macroValPos]=reader.readI();
DivDataErrors DivInstrument::readInsDataOld(SafeReader &reader, short version) { DivDataErrors DivInstrument::readInsDataOld(SafeReader &reader, short version) {
bool volIsCutoff=false;
reader.readI(); // length. ignored. reader.readI(); // length. ignored.
reader.readS(); // format version. ignored. reader.readS(); // format version. ignored.
@ -2768,7 +2775,7 @@ DivDataErrors DivInstrument::readInsDataOld(SafeReader &reader, short version) {
c64.oscSync=reader.readC(); c64.oscSync=reader.readC();
c64.toFilter=reader.readC(); c64.toFilter=reader.readC();
c64.initFilter=reader.readC(); c64.initFilter=reader.readC();
c64.volIsCutoff=reader.readC(); volIsCutoff=reader.readC();
c64.res=reader.readC(); c64.res=reader.readC();
c64.lp=reader.readC(); c64.lp=reader.readC();
c64.bp=reader.readC(); c64.bp=reader.readC();
@ -2826,7 +2833,7 @@ DivDataErrors DivInstrument::readInsDataOld(SafeReader &reader, short version) {
} }
} }
if (type==DIV_INS_C64 && version<87) { if (type==DIV_INS_C64 && version<87) {
if (c64.volIsCutoff && !c64.filterIsAbs) for (int j=0; j<std.volMacro.len; j++) { if (volIsCutoff && !c64.filterIsAbs) for (int j=0; j<std.volMacro.len; j++) {
std.volMacro.val[j]-=18; std.volMacro.val[j]-=18;
} }
if (!c64.dutyIsAbs) for (int j=0; j<std.dutyMacro.len; j++) { if (!c64.dutyIsAbs) for (int j=0; j<std.dutyMacro.len; j++) {
@ -3412,6 +3419,13 @@ DivDataErrors DivInstrument::readInsDataOld(SafeReader &reader, short version) {
} }
} }
// <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; return DIV_DATA_SUCCESS;
} }
@ -3632,7 +3646,7 @@ bool DivInstrument::saveDMP(const char* path) {
w->writeC(c64.ringMod); w->writeC(c64.ringMod);
w->writeC(c64.oscSync); w->writeC(c64.oscSync);
w->writeC(c64.toFilter); w->writeC(c64.toFilter);
w->writeC(c64.volIsCutoff); w->writeC(0); // this was volIsCutoff...
w->writeC(c64.initFilter); w->writeC(c64.initFilter);
w->writeC(c64.res); w->writeC(c64.res);
w->writeC((c64.cut*100)/2047); w->writeC((c64.cut*100)/2047);

View file

@ -412,7 +412,7 @@ struct DivInstrumentC64 {
unsigned char a, d, s, r; unsigned char a, d, s, r;
unsigned short duty; unsigned short duty;
unsigned char ringMod, oscSync; unsigned char ringMod, oscSync;
bool toFilter, volIsCutoff, initFilter, dutyIsAbs, filterIsAbs, noTest; bool toFilter, initFilter, dutyIsAbs, filterIsAbs, noTest;
unsigned char res; unsigned char res;
unsigned short cut; unsigned short cut;
bool hp, lp, bp, ch3off; bool hp, lp, bp, ch3off;
@ -435,7 +435,6 @@ struct DivInstrumentC64 {
ringMod(0), ringMod(0),
oscSync(0), oscSync(0),
toFilter(false), toFilter(false),
volIsCutoff(false),
initFilter(false), initFilter(false),
dutyIsAbs(false), dutyIsAbs(false),
filterIsAbs(false), filterIsAbs(false),
@ -816,7 +815,7 @@ struct DivInstrument {
void readFeatureNA(SafeReader& reader, short version); void readFeatureNA(SafeReader& reader, short version);
void readFeatureFM(SafeReader& reader, short version); void readFeatureFM(SafeReader& reader, short version);
void readFeatureMA(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 readFeatureGB(SafeReader& reader, short version);
void readFeatureSM(SafeReader& reader, short version); void readFeatureSM(SafeReader& reader, short version);
void readFeatureOx(SafeReader& reader, int op, short version); void readFeatureOx(SafeReader& reader, int op, short version);

View file

@ -20,6 +20,7 @@
#include "c64.h" #include "c64.h"
#include "../engine.h" #include "../engine.h"
#include "sound/c64_fp/siddefs-fp.h" #include "sound/c64_fp/siddefs-fp.h"
#include "IconsFontAwesome4.h"
#include <math.h> #include <math.h>
#include "../../ta-log.h" #include "../../ta-log.h"
@ -589,6 +590,24 @@ DivMacroInt* DivPlatformC64::getChanMacroInt(int ch) {
return &chan[ch].std; 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) { DivDispatchOscBuffer* DivPlatformC64::getOscBuffer(int ch) {
return oscBuf[ch]; return oscBuf[ch];
} }

View file

@ -113,6 +113,7 @@ class DivPlatformC64: public DivDispatch {
bool isVolGlobal(); bool isVolGlobal();
float getPostAmp(); float getPostAmp();
DivMacroInt* getChanMacroInt(int ch); DivMacroInt* getChanMacroInt(int ch);
DivChannelModeHints getModeHints(int chan);
void notifyInsDeletion(void* ins); void notifyInsDeletion(void* ins);
void poke(unsigned int addr, unsigned short val); void poke(unsigned int addr, unsigned short val);
void poke(std::vector<DivRegWrite>& wlist); void poke(std::vector<DivRegWrite>& wlist);