Implement ESFM macros

This commit is contained in:
Kagamiin~ 2023-10-17 19:24:57 -03:00
parent 8ae86f79a8
commit a01ddd381e
3 changed files with 163 additions and 48 deletions

View file

@ -802,7 +802,6 @@ struct DivInstrumentESFM {
op[3].modIn=7; op[3].modIn=7;
op[3].outLvl=7; op[3].outLvl=7;
} }
}; };
struct DivInstrument { struct DivInstrument {

View file

@ -93,12 +93,15 @@ void DivPlatformESFM::tick(bool sysTick) {
chan[i].freqChanged=true; chan[i].freqChanged=true;
} }
// TODO: check why I disabled globalPan here?
#if 0
if (chan[i].std.panL.had) { if (chan[i].std.panL.had) {
chan[i].globalPan=((chan[i].std.panL.val&1)<<1)|((chan[i].std.panL.val&2)>>1); chan[i].globalPan=((chan[i].std.panL.val&1)<<1)|((chan[i].std.panL.val&2)>>1);
for (int o=0; o<4; o++) {
unsigned short baseAddr=i*32 + o*8;
DivInstrumentFM::Operator& op=chan[i].state.fm.op[o];
DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o];
rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7));
}
} }
#endif
if (chan[i].std.pitch.had) { if (chan[i].std.pitch.had) {
if (chan[i].std.pitch.mode) { if (chan[i].std.pitch.mode) {
@ -116,9 +119,25 @@ void DivPlatformESFM::tick(bool sysTick) {
} }
} }
if (chan[i].std.duty.had) {
int o=3;
unsigned short baseAddr=i*32 + o*8;
DivInstrumentESFM& ins=chan[i].state.esfm;
DivInstrumentFM::Operator& op=chan[i].state.fm.op[o];
DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o];
ins.noise=chan[i].std.duty.val;
if (isMuted[i]) {
rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?ins.noise&3:0)<<3)|0);
} else {
rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?ins.noise&3:0)<<3)|((opE.outLvl&7)<<5));
}
}
for (int o=0; o<4; o++) { for (int o=0; o<4; o++) {
unsigned short baseAddr=i*32 + o*8; unsigned short baseAddr=i*32 + o*8;
DivInstrumentFM::Operator& op=chan[i].state.fm.op[o]; DivInstrumentFM::Operator& op=chan[i].state.fm.op[o];
DivInstrumentESFM::Operator& opE=chan[i].state.esfm.op[o];
DivMacroInt::IntOp& m=chan[i].std.op[o]; DivMacroInt::IntOp& m=chan[i].std.op[o];
if (m.am.had) { if (m.am.had) {
@ -173,6 +192,68 @@ void DivPlatformESFM::tick(bool sysTick) {
rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6)); rWrite(baseAddr+OFFSET_KSL_TL,(op.tl&0x3f)|(op.ksl<<6));
} }
} }
if (m.dam.had) {
op.dam=m.dam.val;
rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7));
}
if (m.dvb.had) {
op.dvb=m.dvb.val;
rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7));
}
if (m.rs.had) {
// operator panning
opE.left=(m.rs.val&2)!=0;
opE.right=(m.rs.val&1)!=0;
rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7));
}
if (m.d2r.had) {
// modIn
opE.modIn=m.d2r.val;
rWrite(baseAddr+OFFSET_DAM_DVB_LEFT_RIGHT_MODIN,((opE.modIn&7)<<1)|(((opE.left&chan[i].globalPan)&1)<<4)|(((opE.right&(chan[i].globalPan>>1))&1)<<5)|((op.dvb&1)<<6)|(op.dam<<7));
}
if (m.egt.had | m.ws.had) {
unsigned char noise=chan[i].state.esfm.noise&3;
if (m.egt.had) {
// outLvl
opE.outLvl=m.egt.val;
}
if (m.ws.had) {
op.ws=m.ws.val;
}
if (isMuted[i]) {
rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|0);
} else {
rWrite(baseAddr+OFFSET_OUTLVL_NOISE_WS,(op.ws&7)|((o==3?noise:0)<<3)|((opE.outLvl&7)<<5));
}
}
if (opE.fixed) {
if (m.ssg.had) {
opE.ct=(opE.ct&(~(7<<2)))|((m.ssg.val&7)<<2);
chan[i].freqChanged=true;
}
if (m.dt.had) {
opE.dt=m.dt.val&0xff;
opE.ct=(opE.ct&(~3))|((m.dt.val>>8)&3);
chan[i].freqChanged=true;
}
} else {
if (m.ssg.had) {
opE.ct=(signed char)m.ssg.val;
chan[i].freqChanged=true;
}
if (m.dt.had) {
opE.dt=(signed char)m.dt.val;
chan[i].freqChanged=true;
}
}
if (m.dt2.had) {
opE.delay=m.dt2.val;
rWrite(baseAddr+OFFSET_FREQH_BLOCK_DELAY,chan[i].freqH[o]|(opE.delay<<5));
}
} }
} }

View file

@ -5216,6 +5216,7 @@ void FurnaceGUI::drawInsEdit() {
ImGui::EndDisabled(); ImGui::EndDisabled();
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (ins->type!=DIV_INS_ESFM) {
if (ImGui::BeginTabItem("FM Macros")) { if (ImGui::BeginTabItem("FM Macros")) {
if (ins->type==DIV_INS_OPLL) { if (ins->type==DIV_INS_OPLL) {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SUS),&ins->std.algMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SUS),&ins->std.algMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
@ -5257,6 +5258,7 @@ void FurnaceGUI::drawInsEdit() {
drawMacros(macroList,macroEditStateFM); drawMacros(macroList,macroEditStateFM);
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
}
for (int i=0; i<opCount; i++) { for (int i=0; i<opCount; i++) {
if (ins->type==DIV_INS_OPL_DRUMS) { if (ins->type==DIV_INS_OPL_DRUMS) {
if (i>0) break; if (i>0) break;
@ -5275,7 +5277,7 @@ void FurnaceGUI::drawInsEdit() {
maxTl=63; maxTl=63;
} }
} }
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) { if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) {
maxTl=63; maxTl=63;
} }
int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM)?31:15; int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM)?31:15;
@ -5307,6 +5309,33 @@ void FurnaceGUI::drawInsEdit() {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_VIB),&ins->std.opMacros[ordi].vibMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_VIB),&ins->std.opMacros[ordi].vibMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_KSR),&ins->std.opMacros[ordi].ksrMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_KSR),&ins->std.opMacros[ordi].ksrMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_EGS),&ins->std.opMacros[ordi].egtMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_EGS),&ins->std.opMacros[ordi].egtMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
} else if (ins->type==DIV_INS_ESFM) {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_TL),&ins->std.opMacros[ordi].tlMacro,0,maxTl,128,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(ESFM_NAME(ESFM_DELAY),&ins->std.opMacros[ordi].dt2Macro,0,7,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AR),&ins->std.opMacros[ordi].arMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DR),&ins->std.opMacros[ordi].drMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SL),&ins->std.opMacros[ordi].slMacro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_RR),&ins->std.opMacros[ordi].rrMacro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_KSL),&ins->std.opMacros[ordi].kslMacro,0,3,32,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_MULT),&ins->std.opMacros[ordi].multMacro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_WS),&ins->std.opMacros[ordi].wsMacro,0,7,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(ESFM_NAME(ESFM_OUTLVL),&ins->std.opMacros[ordi].egtMacro,0,7,64,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(ESFM_NAME(ESFM_MODIN),&ins->std.opMacros[ordi].d2rMacro,0,7,64,uiColors[GUI_COLOR_MACRO_OTHER]));
if (ins->esfm.op[ordi].fixed) {
macroList.push_back(FurnaceGUIMacroDesc("Block",&ins->std.opMacros[ordi].ssgMacro,0,7,64,uiColors[GUI_COLOR_MACRO_OTHER],true));
macroList.push_back(FurnaceGUIMacroDesc("FreqNum",&ins->std.opMacros[ordi].dtMacro,0,1023,160,uiColors[GUI_COLOR_MACRO_OTHER]));
} else {
macroList.push_back(FurnaceGUIMacroDesc(ESFM_NAME(ESFM_CT),&ins->std.opMacros[ordi].ssgMacro,-24,24,128,uiColors[GUI_COLOR_MACRO_OTHER],true));
macroList.push_back(FurnaceGUIMacroDesc(ESFM_NAME(ESFM_DT),&ins->std.opMacros[ordi].dtMacro,-128,127,160,uiColors[GUI_COLOR_MACRO_OTHER]));
}
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AM),&ins->std.opMacros[ordi].amMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_VIB),&ins->std.opMacros[ordi].vibMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DAM),&ins->std.opMacros[ordi].damMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_DVB),&ins->std.opMacros[ordi].dvbMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_KSR),&ins->std.opMacros[ordi].ksrMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_SUS),&ins->std.opMacros[ordi].susMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
macroList.push_back(FurnaceGUIMacroDesc("Op. Panning",&ins->std.opMacros[ordi].rsMacro,0,2,40,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits));
} else { } else {
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_TL),&ins->std.opMacros[ordi].tlMacro,0,maxTl,128,uiColors[GUI_COLOR_MACRO_OTHER])); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_TL),&ins->std.opMacros[ordi].tlMacro,0,maxTl,128,uiColors[GUI_COLOR_MACRO_OTHER]));
macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AR),&ins->std.opMacros[ordi].arMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_OTHER])); macroList.push_back(FurnaceGUIMacroDesc(FM_NAME(FM_AR),&ins->std.opMacros[ordi].arMacro,0,maxArDr,64,uiColors[GUI_COLOR_MACRO_OTHER]));
@ -6448,7 +6477,7 @@ void FurnaceGUI::drawInsEdit() {
if (ins->type==DIV_INS_PCE || ins->type==DIV_INS_AY8930 || ins->type==DIV_INS_SM8521) { if (ins->type==DIV_INS_PCE || ins->type==DIV_INS_AY8930 || ins->type==DIV_INS_SM8521) {
volMax=31; volMax=31;
} }
if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_VERA || ins->type==DIV_INS_VRC6_SAW) { if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_VERA || ins->type==DIV_INS_VRC6_SAW || ins->type==DIV_INS_ESFM) {
volMax=63; volMax=63;
} }
if (ins->type==DIV_INS_AMIGA) { if (ins->type==DIV_INS_AMIGA) {
@ -6628,6 +6657,10 @@ void FurnaceGUI::drawInsEdit() {
dutyLabel="Echo Level"; dutyLabel="Echo Level";
dutyMax=32767; dutyMax=32767;
} }
if (ins->type==DIV_INS_ESFM) {
dutyLabel="OP4 Noise Mode";
dutyMax=3;
}
const char* waveLabel="Waveform"; const char* waveLabel="Waveform";
int waveMax=(ins->type==DIV_INS_VERA)?3:(MAX(1,e->song.waveLen-1)); int waveMax=(ins->type==DIV_INS_VERA)?3:(MAX(1,e->song.waveLen-1));
@ -6641,7 +6674,7 @@ void FurnaceGUI::drawInsEdit() {
if (ins->type==DIV_INS_TIA || ins->type==DIV_INS_VIC || ins->type==DIV_INS_OPLL) waveMax=15; if (ins->type==DIV_INS_TIA || ins->type==DIV_INS_VIC || ins->type==DIV_INS_OPLL) waveMax=15;
if (ins->type==DIV_INS_C64) waveMax=4; if (ins->type==DIV_INS_C64) waveMax=4;
if (ins->type==DIV_INS_SAA1099) waveMax=2; if (ins->type==DIV_INS_SAA1099) waveMax=2;
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) waveMax=0; if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM || ins->type==DIV_INS_ESFM) waveMax=0;
if (ins->type==DIV_INS_MIKEY) waveMax=0; if (ins->type==DIV_INS_MIKEY) waveMax=0;
if (ins->type==DIV_INS_MULTIPCM) waveMax=0; if (ins->type==DIV_INS_MULTIPCM) waveMax=0;
if (ins->type==DIV_INS_ADPCMA) waveMax=0; if (ins->type==DIV_INS_ADPCMA) waveMax=0;
@ -6742,7 +6775,8 @@ void FurnaceGUI::drawInsEdit() {
ins->type==DIV_INS_MSM6258 || ins->type==DIV_INS_MSM6258 ||
ins->type==DIV_INS_VERA || ins->type==DIV_INS_VERA ||
ins->type==DIV_INS_ADPCMA || ins->type==DIV_INS_ADPCMA ||
ins->type==DIV_INS_ADPCMB) { ins->type==DIV_INS_ADPCMB ||
ins->type==DIV_INS_ESFM) {
panMax=2; panMax=2;
panSingle=true; panSingle=true;
} }
@ -6885,7 +6919,8 @@ void FurnaceGUI::drawInsEdit() {
ins->type==DIV_INS_K053260 || ins->type==DIV_INS_K053260 ||
ins->type==DIV_INS_C140 || ins->type==DIV_INS_C140 ||
ins->type==DIV_INS_C219 || ins->type==DIV_INS_C219 ||
ins->type==DIV_INS_TED) { ins->type==DIV_INS_TED ||
ins->type==DIV_INS_ESFM) {
macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
} }
if (ex1Max>0) { if (ex1Max>0) {