OPZ: add FMS2/AMS2 macros

This commit is contained in:
tildearrow 2025-03-23 04:22:43 -05:00
parent beb7411ba7
commit 2e9621073e
8 changed files with 53 additions and 4 deletions

View file

@ -130,6 +130,9 @@ the following instrument types are available:
- 61: GBA MinMod - 61: GBA MinMod
- 62: Bifurcator - 62: Bifurcator
- 63: SID2 - 63: SID2
- 64: Supervision
- 65: µPD1771C
- 66: SID3
the following feature codes are recognized: the following feature codes are recognized:
@ -255,6 +258,8 @@ size | description
| - 17: ex6 | - 17: ex6
| - 18: ex7 | - 18: ex7
| - 19: ex8 | - 19: ex8
| - 20: ex9
| - 21: ex10
| - 255: stop reading and move on | - 255: stop reading and move on
1 | macro length 1 | macro length
1 | macro loop 1 | macro loop

View file

@ -221,6 +221,8 @@ SafeWriter* DivEngine::saveText(bool separatePatterns) {
writeTextMacro(w,ins->std.ex6Macro,"ex6",header); writeTextMacro(w,ins->std.ex6Macro,"ex6",header);
writeTextMacro(w,ins->std.ex7Macro,"ex7",header); writeTextMacro(w,ins->std.ex7Macro,"ex7",header);
writeTextMacro(w,ins->std.ex8Macro,"ex8",header); writeTextMacro(w,ins->std.ex8Macro,"ex8",header);
writeTextMacro(w,ins->std.ex9Macro,"ex9",header);
writeTextMacro(w,ins->std.ex10Macro,"ex10",header);
writeTextMacro(w,ins->std.algMacro,"alg",header); writeTextMacro(w,ins->std.algMacro,"alg",header);
writeTextMacro(w,ins->std.fbMacro,"fb",header); writeTextMacro(w,ins->std.fbMacro,"fb",header);
writeTextMacro(w,ins->std.fmsMacro,"fms",header); writeTextMacro(w,ins->std.fmsMacro,"fms",header);

View file

@ -360,6 +360,8 @@ DivInstrumentMacro* DivInstrumentSTD::macroByType(DivMacroType type) {
CONSIDER(ex6Macro,DIV_MACRO_EX6) CONSIDER(ex6Macro,DIV_MACRO_EX6)
CONSIDER(ex7Macro,DIV_MACRO_EX7) CONSIDER(ex7Macro,DIV_MACRO_EX7)
CONSIDER(ex8Macro,DIV_MACRO_EX8) CONSIDER(ex8Macro,DIV_MACRO_EX8)
CONSIDER(ex9Macro,DIV_MACRO_EX9)
CONSIDER(ex10Macro,DIV_MACRO_EX10)
} }
return NULL; return NULL;
@ -648,6 +650,8 @@ void DivInstrument::writeFeatureMA(SafeWriter* w) {
writeMacro(w,std.ex6Macro); writeMacro(w,std.ex6Macro);
writeMacro(w,std.ex7Macro); writeMacro(w,std.ex7Macro);
writeMacro(w,std.ex8Macro); writeMacro(w,std.ex8Macro);
writeMacro(w,std.ex9Macro);
writeMacro(w,std.ex10Macro);
// "stop reading" code // "stop reading" code
w->writeC(-1); w->writeC(-1);
@ -1520,7 +1524,9 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo
std.ex5Macro.len || std.ex5Macro.len ||
std.ex6Macro.len || std.ex6Macro.len ||
std.ex7Macro.len || std.ex7Macro.len ||
std.ex8Macro.len) { std.ex8Macro.len ||
std.ex9Macro.len ||
std.ex10Macro.len) {
featureMA=true; featureMA=true;
} }
@ -1874,6 +1880,12 @@ void DivInstrument::readFeatureMA(SafeReader& reader, short version) {
case 19: case 19:
target=&std.ex8Macro; target=&std.ex8Macro;
break; break;
case 20:
target=&std.ex9Macro;
break;
case 21:
target=&std.ex10Macro;
break;
default: default:
logW("invalid macro code %d!"); logW("invalid macro code %d!");
break; break;

View file

@ -123,7 +123,9 @@ enum DivMacroType: unsigned char {
DIV_MACRO_EX5, DIV_MACRO_EX5,
DIV_MACRO_EX6, DIV_MACRO_EX6,
DIV_MACRO_EX7, DIV_MACRO_EX7,
DIV_MACRO_EX8 DIV_MACRO_EX8,
DIV_MACRO_EX9,
DIV_MACRO_EX10
}; };
enum DivMacroTypeOp: unsigned char { enum DivMacroTypeOp: unsigned char {
@ -301,6 +303,8 @@ struct DivInstrumentSTD {
DivInstrumentMacro ex6Macro; DivInstrumentMacro ex6Macro;
DivInstrumentMacro ex7Macro; DivInstrumentMacro ex7Macro;
DivInstrumentMacro ex8Macro; DivInstrumentMacro ex8Macro;
DivInstrumentMacro ex9Macro;
DivInstrumentMacro ex10Macro;
struct OpMacro { struct OpMacro {
// ar, dr, mult, rr, sl, tl, dt2, rs, dt, d2r, ssgEnv; // ar, dr, mult, rr, sl, tl, dt2, rs, dt, d2r, ssgEnv;
@ -354,7 +358,9 @@ struct DivInstrumentSTD {
ex5Macro(DIV_MACRO_EX5), ex5Macro(DIV_MACRO_EX5),
ex6Macro(DIV_MACRO_EX6), ex6Macro(DIV_MACRO_EX6),
ex7Macro(DIV_MACRO_EX7), ex7Macro(DIV_MACRO_EX7),
ex8Macro(DIV_MACRO_EX8) { ex8Macro(DIV_MACRO_EX8),
ex9Macro(DIV_MACRO_EX9),
ex10Macro(DIV_MACRO_EX10) {
for (int i=0; i<4; i++) { for (int i=0; i<4; i++) {
opMacros[i].amMacro.macroType=DIV_MACRO_OP_AM+(i<<5); opMacros[i].amMacro.macroType=DIV_MACRO_OP_AM+(i<<5);
opMacros[i].arMacro.macroType=DIV_MACRO_OP_AR+(i<<5); opMacros[i].arMacro.macroType=DIV_MACRO_OP_AR+(i<<5);

View file

@ -242,6 +242,8 @@ void DivMacroInt::mask(unsigned char id, bool enabled) {
CONSIDER(ex6,17) CONSIDER(ex6,17)
CONSIDER(ex7,18) CONSIDER(ex7,18)
CONSIDER(ex8,19) CONSIDER(ex8,19)
CONSIDER(ex9,20)
CONSIDER(ex10,21)
CONSIDER_OP(0,0x20) CONSIDER_OP(0,0x20)
CONSIDER_OP(2,0x40) CONSIDER_OP(2,0x40)
@ -309,6 +311,8 @@ void DivMacroInt::restart(unsigned char id) {
CONSIDER(ex6,ex6Macro,17) CONSIDER(ex6,ex6Macro,17)
CONSIDER(ex7,ex7Macro,18) CONSIDER(ex7,ex7Macro,18)
CONSIDER(ex8,ex8Macro,19) CONSIDER(ex8,ex8Macro,19)
CONSIDER(ex9,ex9Macro,20)
CONSIDER(ex10,ex10Macro,21)
CONSIDER_OP(0,0x20) CONSIDER_OP(0,0x20)
CONSIDER_OP(2,0x40) CONSIDER_OP(2,0x40)
@ -418,6 +422,12 @@ void DivMacroInt::init(DivInstrument* which) {
if (ins->std.ex8Macro.len>0) { if (ins->std.ex8Macro.len>0) {
ADD_MACRO(ex8,ins->std.ex8Macro); ADD_MACRO(ex8,ins->std.ex8Macro);
} }
if (ins->std.ex9Macro.len>0) {
ADD_MACRO(ex9,ins->std.ex9Macro);
}
if (ins->std.ex10Macro.len>0) {
ADD_MACRO(ex10,ins->std.ex10Macro);
}
// prepare FM operator macros // prepare FM operator macros
for (int i=0; i<4; i++) { for (int i=0; i<4; i++) {
@ -559,6 +569,8 @@ DivMacroStruct* DivMacroInt::structByType(unsigned char type) {
CONSIDER(ex6,DIV_MACRO_EX6) CONSIDER(ex6,DIV_MACRO_EX6)
CONSIDER(ex7,DIV_MACRO_EX7) CONSIDER(ex7,DIV_MACRO_EX7)
CONSIDER(ex8,DIV_MACRO_EX8) CONSIDER(ex8,DIV_MACRO_EX8)
CONSIDER(ex9,DIV_MACRO_EX9)
CONSIDER(ex10,DIV_MACRO_EX10)
} }
return NULL; return NULL;

View file

@ -75,6 +75,7 @@ class DivMacroInt {
DivMacroStruct duty, wave, pitch, ex1, ex2, ex3; DivMacroStruct duty, wave, pitch, ex1, ex2, ex3;
DivMacroStruct alg, fb, fms, ams; DivMacroStruct alg, fb, fms, ams;
DivMacroStruct panL, panR, phaseReset, ex4, ex5, ex6, ex7, ex8; DivMacroStruct panL, panR, phaseReset, ex4, ex5, ex6, ex7, ex8;
DivMacroStruct ex9, ex10;
// FM operator macro // FM operator macro
struct IntOp { struct IntOp {
@ -180,6 +181,8 @@ class DivMacroInt {
ex6(DIV_MACRO_EX6), ex6(DIV_MACRO_EX6),
ex7(DIV_MACRO_EX7), ex7(DIV_MACRO_EX7),
ex8(DIV_MACRO_EX8), ex8(DIV_MACRO_EX8),
ex9(DIV_MACRO_EX9),
ex10(DIV_MACRO_EX10),
hasRelease(false) { hasRelease(false) {
memset(macroList,0,128*sizeof(void*)); memset(macroList,0,128*sizeof(void*));
memset(macroSource,0,128*sizeof(void*)); memset(macroSource,0,128*sizeof(void*));

View file

@ -255,6 +255,14 @@ void DivPlatformTX81Z::tick(bool sysTick) {
chan[i].state.ams=chan[i].std.ams.val; chan[i].state.ams=chan[i].std.ams.val;
rWrite(chanOffs[i]+ADDR_FMS_AMS,((chan[i].state.fms&7)<<4)|(chan[i].state.ams&3)); rWrite(chanOffs[i]+ADDR_FMS_AMS,((chan[i].state.fms&7)<<4)|(chan[i].state.ams&3));
} }
if (chan[i].std.ex9.had) {
chan[i].state.fms2=chan[i].std.ex9.val;
rWrite(chanOffs[i]+ADDR_FMS2_AMS2,((chan[i].state.fms2&7)<<4)|(chan[i].state.ams2&3));
}
if (chan[i].std.ex10.had) {
chan[i].state.ams2=chan[i].std.ex10.val;
rWrite(chanOffs[i]+ADDR_FMS2_AMS2,((chan[i].state.fms2&7)<<4)|(chan[i].state.ams2&3));
}
for (int j=0; j<4; j++) { for (int j=0; j<4; j++) {
unsigned short baseAddr=chanOffs[i]|opOffs[j]; unsigned short baseAddr=chanOffs[i]|opOffs[j];
DivInstrumentFM::Operator& op=chan[i].state.op[j]; DivInstrumentFM::Operator& op=chan[i].state.op[j];

View file

@ -6649,9 +6649,10 @@ void FurnaceGUI::drawInsEdit() {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FB),&ins->std.fbMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER])); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FB),&ins->std.fbMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER]));
if (ins->type!=DIV_INS_OPL && ins->type!=DIV_INS_OPL_DRUMS) { if (ins->type!=DIV_INS_OPL && ins->type!=DIV_INS_OPL_DRUMS) {
if (ins->type==DIV_INS_OPZ) { if (ins->type==DIV_INS_OPZ) {
// TODO: FMS2/AMS2 macros
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FMS),&ins->std.fmsMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER])); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FMS),&ins->std.fmsMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AMS),&ins->std.amsMacro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER])); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AMS),&ins->std.amsMacro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FMS2),&ins->std.ex9Macro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AMS2),&ins->std.ex10Macro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER]));
} else { } else {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FMS),&ins->std.fmsMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER])); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_FMS),&ins->std.fmsMacro,0,7,96,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AMS),&ins->std.amsMacro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER])); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AMS),&ins->std.amsMacro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER]));