From d2076c6bc3657ff2ac5b2c18334c0b640fd2a9f4 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 3 May 2024 18:34:16 -0500 Subject: [PATCH 01/22] GUI: add missing sample offset compat flag --- src/gui/compatFlags.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/compatFlags.cpp b/src/gui/compatFlags.cpp index 81e96a1cb..0c2d92a9b 100644 --- a/src/gui/compatFlags.cpp +++ b/src/gui/compatFlags.cpp @@ -196,6 +196,10 @@ void FurnaceGUI::drawCompatFlags() { if (ImGui::IsItemHovered()) { ImGui::SetTooltip("behavior changed in 0.6.1\nthis flag will be removed if I find out that none of the songs break after disabling it."); } + ImGui::Checkbox("Old sample offset effect",&e->song.oldSampleOffset); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("behavior changed in 0.6.3"); + } ImGui::EndTabItem(); } if (ImGui::BeginTabItem(".mod import")) { From be48cb5ccb7b6c5170c49f4363b274b6cd9aaa94 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 3 May 2024 18:34:30 -0500 Subject: [PATCH 02/22] GUI: insEdit refactor, part 1 do not complain yet --- src/gui/insEdit.cpp | 478 +++++++++++++++++++++++++++++--------------- 1 file changed, 321 insertions(+), 157 deletions(-) diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index c66007b5c..eef6cda95 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -6760,217 +6760,411 @@ void FurnaceGUI::drawInsEdit() { } } if (ins->typetype==DIV_INS_PCE || ins->type==DIV_INS_AY8930 || ins->type==DIV_INS_SM8521) { - 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 || ins->type==DIV_INS_ESFM || ins->type==DIV_INS_DAVE) { - volMax=63; - } - if (ins->type==DIV_INS_AMIGA) { - volMax=64; - } - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_SEGAPCM || ins->type==DIV_INS_MIKEY || - ins->type==DIV_INS_MULTIPCM || ins->type==DIV_INS_SU || ins->type==DIV_INS_OPZ || - ins->type==DIV_INS_OPM || ins->type==DIV_INS_SNES || ins->type==DIV_INS_MSM5232 || - ins->type==DIV_INS_K053260 || ins->type==DIV_INS_NDS) { - volMax=127; - } - if (ins->type==DIV_INS_GB) { - if (ins->gb.softEnv) { - volMax=15; - } else { - volMax=0; - } - } - if (ins->type==DIV_INS_PET || ins->type==DIV_INS_BEEPER || ins->type==DIV_INS_PV1000) { - volMax=1; - } - if (ins->type==DIV_INS_FDS) { - volMax=32; - } - if (ins->type==DIV_INS_ES5506) { - volMax=4095; - } - if (ins->type==DIV_INS_MSM6258) { - volMax=0; - } - if (ins->type==DIV_INS_MSM6295 || ins->type==DIV_INS_TED) { - volMax=8; - } - if (ins->type==DIV_INS_ADPCMA) { - volMax=31; - } - if (ins->type==DIV_INS_ADPCMB || ins->type==DIV_INS_YMZ280B || ins->type==DIV_INS_RF5C68 || - ins->type==DIV_INS_GA20 || ins->type==DIV_INS_C140 || ins->type==DIV_INS_C219 || ins->type==DIV_INS_GBA_MINMOD || - ins->type==DIV_INS_BIFURCATOR) { - volMax=255; - } - if (ins->type==DIV_INS_QSOUND) { - volMax=16383; - } - if (ins->type==DIV_INS_POKEMINI || ins->type==DIV_INS_GBA_DMA) { - volMax=2; - } - - const char* dutyLabel="Duty/Noise"; - int dutyMin=0; + // OLD CODE int dutyMax=3; if (ins->type==DIV_INS_C64 || ins->type==DIV_INS_SID2) { - dutyLabel="Duty"; - if (ins->c64.dutyIsAbs) { - dutyMax=4095; - } else { - dutyMin=-4095; - dutyMax=4095; - } - } - if (ins->type==DIV_INS_STD) { - dutyLabel="Duty"; + dutyMax=4095; } if (ins->type==DIV_INS_OPM || ins->type==DIV_INS_OPZ) { dutyMax=32; } if (ins->type==DIV_INS_AY) { - dutyMax=ins->amiga.useSample?0:31; - } - if (ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930 || ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM) { - dutyLabel="Noise Freq"; + dutyMax=31; } if (ins->type==DIV_INS_POKEY) { - dutyLabel="AUDCTL"; dutyMax=8; } if (ins->type==DIV_INS_MIKEY) { - dutyLabel="Duty/Int"; - dutyMax=ins->amiga.useSample?0:10; + dutyMax=10; } if (ins->type==DIV_INS_MSM5232) { - dutyLabel="Group Ctrl"; dutyMax=5; } if (ins->type==DIV_INS_C219) { - dutyLabel="Control"; dutyMax=3; } if (ins->type==DIV_INS_BEEPER || ins->type==DIV_INS_POKEMINI) { - dutyLabel="Pulse Width"; dutyMax=255; } if (ins->type==DIV_INS_T6W28) { - dutyLabel="Noise Type"; dutyMax=1; } if (ins->type==DIV_INS_AY8930) { - dutyMax=ins->amiga.useSample?0:255; - } - if (ins->type==DIV_INS_TIA || ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_SCC || - ins->type==DIV_INS_PET || ins->type==DIV_INS_SEGAPCM || - ins->type==DIV_INS_FM || ins->type==DIV_INS_K007232 || ins->type==DIV_INS_GA20 || - ins->type==DIV_INS_SM8521 || ins->type==DIV_INS_PV1000 || ins->type==DIV_INS_K053260 || - ins->type==DIV_INS_C140 || ins->type==DIV_INS_GBA_DMA || ins->type==DIV_INS_GBA_MINMOD) { - dutyMax=0; + dutyMax=255; } if (ins->type==DIV_INS_VBOY) { - dutyLabel="Noise Length"; dutyMax=7; } if (ins->type==DIV_INS_PCE) { - dutyLabel="Noise"; - dutyMax=(!ins->amiga.useSample)?1:0; + dutyMax=1; } if (ins->type==DIV_INS_NAMCO) { - dutyLabel="Noise"; dutyMax=1; } if (ins->type==DIV_INS_VIC) { - dutyLabel="On/Off"; dutyMax=1; } if (ins->type==DIV_INS_TED) { - dutyLabel="Square/Noise"; dutyMax=2; } if (ins->type==DIV_INS_SWAN) { - dutyLabel="Noise"; - dutyMax=ins->amiga.useSample?0:8; + dutyMax=8; } if (ins->type==DIV_INS_SNES) { - dutyLabel="Noise Freq"; dutyMax=31; } - if (ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || - ins->type==DIV_INS_VRC6_SAW || ins->type==DIV_INS_FDS || ins->type==DIV_INS_MULTIPCM) { - dutyMax=0; - } if (ins->type==DIV_INS_VERA) { - dutyLabel="Duty"; dutyMax=63; } if (ins->type==DIV_INS_N163) { - dutyLabel="Wave Pos"; dutyMax=255; } if (ins->type==DIV_INS_VRC6) { - dutyLabel="Duty"; - dutyMax=ins->amiga.useSample?0:7; + dutyMax=7; } if (ins->type==DIV_INS_ES5506) { - dutyLabel="Filter Mode"; dutyMax=3; } if (ins->type==DIV_INS_SU) { dutyMax=127; } - if (ins->type==DIV_INS_ES5506) { - dutyLabel="Filter Mode"; - dutyMax=3; - } if (ins->type==DIV_INS_MSM6258) { - dutyLabel="Frequency Divider"; dutyMax=2; } if (ins->type==DIV_INS_MSM6295) { - dutyLabel="Frequency Divider"; dutyMax=1; } if (ins->type==DIV_INS_ADPCMA) { - dutyLabel="Global Volume"; dutyMax=63; } - if (ins->type==DIV_INS_ADPCMB || ins->type==DIV_INS_YMZ280B || ins->type==DIV_INS_RF5C68) { - dutyMax=0; - } if (ins->type==DIV_INS_QSOUND) { - dutyLabel="Echo Level"; dutyMax=32767; } if (ins->type==DIV_INS_ESFM) { - dutyLabel="OP4 Noise Mode"; dutyMax=3; } - if (ins->type==DIV_INS_POWERNOISE) { - dutyMax=0; - } - if (ins->type==DIV_INS_POWERNOISE_SLOPE) { - dutyMax=0; - } if (ins->type==DIV_INS_DAVE) { - dutyLabel="Noise Freq"; dutyMax=3; } if (ins->type==DIV_INS_NDS) { - dutyLabel="Duty"; - dutyMax=ins->amiga.useSample?0:7; + dutyMax=7; } if (ins->type==DIV_INS_BIFURCATOR) { - dutyLabel="Parameter"; dutyMax=65535; } + // NEW CODE + // this is only the first part of an insEdit refactor. + // don't complain yet! + switch (ins->type) { + case DIV_INS_STD: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_FM: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_GB: + if (ins->gb.softEnv) { + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + } + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Duty/Noise",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_C64: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,ins->c64.dutyIsAbs?0:-4095,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_AMIGA: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,64,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_PCE: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,31,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + if (!ins->amiga.useSample) { + macroList.push_back(FurnaceGUIMacroDesc("Noise",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + } + break; + case DIV_INS_AY: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + if (!ins->amiga.useSample) { + macroList.push_back(FurnaceGUIMacroDesc("Noise Freq",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + } + break; + case DIV_INS_AY8930: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,31,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + if (!ins->amiga.useSample) { + macroList.push_back(FurnaceGUIMacroDesc("Noise Freq",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + } + break; + case DIV_INS_TIA: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_SAA1099: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Duty/Noise",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_VIC: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("On/Off",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_PET: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,1,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_VRC6: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + if (!ins->amiga.useSample) { + macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + } + break; + case DIV_INS_OPLL: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_OPL: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_FDS: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,32,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_VBOY: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Noise Length",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_N163: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Wave Pos",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_SCC: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_OPZ: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Duty/Noise",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_POKEY: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("AUDCTL",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,pokeyCtlBits)); + break; + case DIV_INS_BEEPER: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,1,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Pulse Width",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_SWAN: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + if (!ins->amiga.useSample) { + macroList.push_back(FurnaceGUIMacroDesc("Noise",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + } + break; + case DIV_INS_MIKEY: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + if (!ins->amiga.useSample) { + macroList.push_back(FurnaceGUIMacroDesc("Duty/Int",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,mikeyFeedbackBits)); + } + break; + case DIV_INS_VERA: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_X1_010: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_VRC6_SAW: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_ES5506: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,4095,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Filter Mode",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,¯oHoverES5506FilterMode)); + break; + case DIV_INS_MULTIPCM: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_SNES: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Noise Freq",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_SU: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Duty/Noise",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_NAMCO: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Noise",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_OPL_DRUMS: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_OPM: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Noise Freq",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_NES: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Duty/Noise",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_MSM6258: + macroList.push_back(FurnaceGUIMacroDesc("Freq Divider",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_MSM6295: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,8,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Freq Divider",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_ADPCMA: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,31,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Global Volume",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_ADPCMB: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_SEGAPCM: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_QSOUND: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,16383,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Echo Level",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_YMZ280B: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_RF5C68: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_MSM5232: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Group Ctrl",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,msm5232ControlBits)); + break; + case DIV_INS_T6W28: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Noise Type",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_K007232: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_GA20: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_POKEMINI: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,2,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Pulse Width",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_SM8521: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,31,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_PV1000: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,1,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_K053260: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_TED: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,8,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Square/Noise",&ins->std.dutyMacro,0,dutyMax,80,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,tedControlBits)); + break; + case DIV_INS_C140: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_C219: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.dutyMacro,0,dutyMax,120,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,c219ControlBits)); + break; + case DIV_INS_ESFM: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("OP4 Noise Mode",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_POWERNOISE: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_POWERNOISE_SLOPE: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_DAVE: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Noise Freq",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_NDS: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + if (!ins->amiga.useSample) { + macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + } + break; + case DIV_INS_GBA_DMA: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,2,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_GBA_MINMOD: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + break; + case DIV_INS_BIFURCATOR: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Parameter",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + case DIV_INS_SID2: + macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); + macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,ins->c64.dutyIsAbs?0:-4095,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + break; + + case DIV_INS_MAX: + case DIV_INS_NULL: + break; + } + + // OLD CODE const char* waveLabel="Waveform"; int waveMax=(ins->type==DIV_INS_VERA)?3:(MAX(1,e->song.waveLen-1)); bool waveBitMode=false; @@ -7044,7 +7238,6 @@ void FurnaceGUI::drawInsEdit() { ex2Max=255; } if (ins->type==DIV_INS_X1_010) { - dutyMax=0; ex1Max=ins->amiga.useSample?0:7; ex2Max=ins->amiga.useSample?0:255; ex2Bit=false; @@ -7180,29 +7373,6 @@ void FurnaceGUI::drawInsEdit() { panSingleNoBit=true; } - if (volMax>0) { - macroList.push_back(FurnaceGUIMacroDesc(volumeLabel,&ins->std.volMacro,volMin,volMax,160,uiColors[GUI_COLOR_MACRO_VOLUME])); - } - if (ins->type!=DIV_INS_MSM6258 && ins->type!=DIV_INS_MSM6295 && ins->type!=DIV_INS_ADPCMA) { - macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - } - if (dutyMax>0) { - if (ins->type==DIV_INS_MIKEY) { - macroList.push_back(FurnaceGUIMacroDesc(dutyLabel,&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,mikeyFeedbackBits)); - } else if (ins->type==DIV_INS_POKEY) { - macroList.push_back(FurnaceGUIMacroDesc(dutyLabel,&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,pokeyCtlBits)); - } else if (ins->type==DIV_INS_TED) { - macroList.push_back(FurnaceGUIMacroDesc(dutyLabel,&ins->std.dutyMacro,0,dutyMax,80,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,tedControlBits)); - } else if (ins->type==DIV_INS_MSM5232) { - macroList.push_back(FurnaceGUIMacroDesc(dutyLabel,&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,msm5232ControlBits)); - } else if (ins->type==DIV_INS_ES5506) { - macroList.push_back(FurnaceGUIMacroDesc(dutyLabel,&ins->std.dutyMacro,dutyMin,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,¯oHoverES5506FilterMode)); - } else if (ins->type==DIV_INS_C219) { - macroList.push_back(FurnaceGUIMacroDesc(dutyLabel,&ins->std.dutyMacro,0,dutyMax,120,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,c219ControlBits)); - } else { - macroList.push_back(FurnaceGUIMacroDesc(dutyLabel,&ins->std.dutyMacro,dutyMin,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); - } - } if (waveMax>0) { macroList.push_back(FurnaceGUIMacroDesc(waveLabel,&ins->std.waveMacro,0,waveMax,(waveBitMode && ins->type!=DIV_INS_PET)?64:160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,waveBitMode,waveNames)); } @@ -7385,12 +7555,6 @@ void FurnaceGUI::drawInsEdit() { macroList.push_back(FurnaceGUIMacroDesc("Phase Reset Timer",&ins->std.ex4Macro,0,65535,160,uiColors[GUI_COLOR_MACRO_OTHER])); // again reuse code from resonance macro but use ex4 instead } if (ins->type==DIV_INS_ES5506) { - /*macroList.push_back(FurnaceGUIMacroDesc("Envelope counter",&ins->std.ex3Macro,0,511,160,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Envelope left volume ramp",&ins->std.ex4Macro,-128,127,160,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Envelope right volume ramp",&ins->std.ex5Macro,-128,127,160,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Envelope K1 ramp",&ins->std.ex6Macro,-128,127,160,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Envelope K2 ramp",&ins->std.ex7Macro,-128,127,160,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Envelope mode",&ins->std.ex8Macro,0,2,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,es5506EnvelopeModes));*/ macroList.push_back(FurnaceGUIMacroDesc("Outputs",&ins->std.fbMacro,0,5,64,uiColors[GUI_COLOR_MACRO_OTHER])); macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.algMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,es5506ControlModes)); } From fb16897e763fddccae6e022916ca53b1809001eb Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 4 May 2024 13:34:29 -0500 Subject: [PATCH 03/22] GUI: insEdit refactor, part 2 all general macros are now part of a switch block now it is cleaner than the previous mess --- src/gui/insEdit.cpp | 848 ++++++++++++++++---------------------------- 1 file changed, 307 insertions(+), 541 deletions(-) diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index eef6cda95..ca960ff9e 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -6760,403 +6760,580 @@ void FurnaceGUI::drawInsEdit() { } } if (ins->typetype==DIV_INS_C64 || ins->type==DIV_INS_SID2) { - dutyMax=4095; - } - if (ins->type==DIV_INS_OPM || ins->type==DIV_INS_OPZ) { - dutyMax=32; - } - if (ins->type==DIV_INS_AY) { - dutyMax=31; - } - if (ins->type==DIV_INS_POKEY) { - dutyMax=8; - } - if (ins->type==DIV_INS_MIKEY) { - dutyMax=10; - } - if (ins->type==DIV_INS_MSM5232) { - dutyMax=5; - } - if (ins->type==DIV_INS_C219) { - dutyMax=3; - } - if (ins->type==DIV_INS_BEEPER || ins->type==DIV_INS_POKEMINI) { - dutyMax=255; - } - if (ins->type==DIV_INS_T6W28) { - dutyMax=1; - } - if (ins->type==DIV_INS_AY8930) { - dutyMax=255; - } - if (ins->type==DIV_INS_VBOY) { - dutyMax=7; - } - if (ins->type==DIV_INS_PCE) { - dutyMax=1; - } - if (ins->type==DIV_INS_NAMCO) { - dutyMax=1; - } - if (ins->type==DIV_INS_VIC) { - dutyMax=1; - } - if (ins->type==DIV_INS_TED) { - dutyMax=2; - } - if (ins->type==DIV_INS_SWAN) { - dutyMax=8; - } - if (ins->type==DIV_INS_SNES) { - dutyMax=31; - } - if (ins->type==DIV_INS_VERA) { - dutyMax=63; - } - if (ins->type==DIV_INS_N163) { - dutyMax=255; - } - if (ins->type==DIV_INS_VRC6) { - dutyMax=7; - } - if (ins->type==DIV_INS_ES5506) { - dutyMax=3; - } - if (ins->type==DIV_INS_SU) { - dutyMax=127; - } - if (ins->type==DIV_INS_MSM6258) { - dutyMax=2; - } - if (ins->type==DIV_INS_MSM6295) { - dutyMax=1; - } - if (ins->type==DIV_INS_ADPCMA) { - dutyMax=63; - } - if (ins->type==DIV_INS_QSOUND) { - dutyMax=32767; - } - if (ins->type==DIV_INS_ESFM) { - dutyMax=3; - } - if (ins->type==DIV_INS_DAVE) { - dutyMax=3; - } - if (ins->type==DIV_INS_NDS) { - dutyMax=7; - } - if (ins->type==DIV_INS_BIFURCATOR) { - dutyMax=65535; - } - // NEW CODE // this is only the first part of an insEdit refactor. // don't complain yet! + int waveCount=MAX(1,e->song.waveLen-1); + switch (ins->type) { case DIV_INS_STD: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,0,3,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_FM: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_GB: if (ins->gb.softEnv) { macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); } macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Duty/Noise",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Duty/Noise",&ins->std.dutyMacro,0,3,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_C64: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,ins->c64.dutyIsAbs?0:-4095,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,ins->c64.dutyIsAbs?0:-4095,4095,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,4,64,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,true,c64ShapeBits)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Cutoff",&ins->std.algMacro,ins->c64.filterIsAbs?0:-2047,2047,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Filter Mode",&ins->std.ex1Macro,0,4,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,filtModeBits)); + macroList.push_back(FurnaceGUIMacroDesc("Resonance",&ins->std.ex2Macro,0,15,64,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Special",&ins->std.ex4Macro,0,4,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,c64TestGateBits)); + macroList.push_back(FurnaceGUIMacroDesc("Attack",&ins->std.ex5Macro,0,15,128,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Decay",&ins->std.ex6Macro,0,15,128,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Sustain",&ins->std.ex7Macro,0,15,128,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Release",&ins->std.ex8Macro,0,15,128,uiColors[GUI_COLOR_MACRO_OTHER])); break; case DIV_INS_AMIGA: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,64,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + if (ins->std.panLMacro.mode) { + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,-16,16,63,uiColors[GUI_COLOR_MACRO_OTHER],false,macroQSoundMode)); + macroList.push_back(FurnaceGUIMacroDesc("Surround",&ins->std.panRMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); + } else { + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,127,158,uiColors[GUI_COLOR_MACRO_OTHER],false,macroQSoundMode)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,127,158,uiColors[GUI_COLOR_MACRO_OTHER])); + } + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_PCE: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,31,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); if (!ins->amiga.useSample) { - macroList.push_back(FurnaceGUIMacroDesc("Noise",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Noise",&ins->std.dutyMacro,0,1,160,uiColors[GUI_COLOR_MACRO_OTHER])); } + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_AY: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); if (!ins->amiga.useSample) { - macroList.push_back(FurnaceGUIMacroDesc("Noise Freq",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Noise Freq",&ins->std.dutyMacro,0,31,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,3,64,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,true,ayShapeBits)); } + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + 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("Envelope",&ins->std.ex2Macro,0,4,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,ayEnvBits)); + macroList.push_back(FurnaceGUIMacroDesc("AutoEnv Num",&ins->std.ex3Macro,0,15,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("AutoEnv Den",&ins->std.algMacro,0,15,160,uiColors[GUI_COLOR_MACRO_OTHER])); break; case DIV_INS_AY8930: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,31,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); if (!ins->amiga.useSample) { - macroList.push_back(FurnaceGUIMacroDesc("Noise Freq",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Noise Freq",&ins->std.dutyMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,3,64,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,true,ayShapeBits)); } + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + 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("Duty",&ins->std.ex1Macro,0,8,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Envelope",&ins->std.ex2Macro,0,4,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,ayEnvBits)); + macroList.push_back(FurnaceGUIMacroDesc("AutoEnv Num",&ins->std.ex3Macro,0,15,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("AutoEnv Den",&ins->std.algMacro,0,15,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Noise AND Mask",&ins->std.fbMacro,0,8,96,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); + macroList.push_back(FurnaceGUIMacroDesc("Noise OR Mask",&ins->std.fmsMacro,0,8,96,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_TIA: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,15,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); break; case DIV_INS_SAA1099: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Duty/Noise",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Duty/Noise",&ins->std.dutyMacro,0,3,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,2,64,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,true,ayShapeBits)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Envelope",&ins->std.ex1Macro,0,8,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,saaEnvBits)); break; case DIV_INS_VIC: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("On/Off",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("On/Off",&ins->std.dutyMacro,0,1,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,15,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); break; case DIV_INS_PET: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,1,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,8,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,true,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); break; case DIV_INS_VRC6: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); if (!ins->amiga.useSample) { - macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,0,7,160,uiColors[GUI_COLOR_MACRO_OTHER])); + } else { + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + } + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + if (ins->amiga.useSample) { + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); } break; case DIV_INS_OPLL: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Patch",&ins->std.waveMacro,0,15,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_OPL: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,0,4,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_FDS: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,32,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Mod Depth",&ins->std.ex1Macro,0,63,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Mod Speed",&ins->std.ex2Macro,0,4095,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Mod Position",&ins->std.ex3Macro,0,127,160,uiColors[GUI_COLOR_MACRO_OTHER])); break; case DIV_INS_VBOY: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Noise Length",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Noise Length",&ins->std.dutyMacro,0,7,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_N163: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Wave Pos",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Wave Pos",&ins->std.dutyMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Wave Length",&ins->std.ex1Macro,0,252,160,uiColors[GUI_COLOR_MACRO_OTHER])); break; case DIV_INS_SCC: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); break; case DIV_INS_OPZ: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Duty/Noise",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Noise Freq",&ins->std.dutyMacro,0,32,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_POKEY: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("AUDCTL",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,pokeyCtlBits)); + macroList.push_back(FurnaceGUIMacroDesc("AUDCTL",&ins->std.dutyMacro,0,8,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,pokeyCtlBits)); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,7,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); break; case DIV_INS_BEEPER: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,1,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Pulse Width",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pulse Width",&ins->std.dutyMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); break; case DIV_INS_SWAN: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); if (!ins->amiga.useSample) { - macroList.push_back(FurnaceGUIMacroDesc("Noise",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Noise",&ins->std.dutyMacro,0,8,160,uiColors[GUI_COLOR_MACRO_OTHER])); } + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_MIKEY: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); if (!ins->amiga.useSample) { - macroList.push_back(FurnaceGUIMacroDesc("Duty/Int",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,mikeyFeedbackBits)); + macroList.push_back(FurnaceGUIMacroDesc("Duty/Int",&ins->std.dutyMacro,0,10,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,mikeyFeedbackBits)); } + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + 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("Load LFSR",&ins->std.ex1Macro,0,12,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_VERA: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,0,63,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,3,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); break; case DIV_INS_X1_010: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + if (ins->amiga.useSample) { + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); + } else { + macroList.push_back(FurnaceGUIMacroDesc("Envelope Mode",&ins->std.ex1Macro,0,7,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,x1_010EnvBits)); + macroList.push_back(FurnaceGUIMacroDesc("Envelope",&ins->std.ex2Macro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,false,ayEnvBits)); + macroList.push_back(FurnaceGUIMacroDesc("AutoEnv Num",&ins->std.ex3Macro,0,15,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("AutoEnv Den",&ins->std.algMacro,0,15,160,uiColors[GUI_COLOR_MACRO_OTHER])); + } break; case DIV_INS_VRC6_SAW: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); break; case DIV_INS_ES5506: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,4095,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Filter Mode",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,¯oHoverES5506FilterMode)); + macroList.push_back(FurnaceGUIMacroDesc("Filter Mode",&ins->std.dutyMacro,0,3,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,¯oHoverES5506FilterMode)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,4095,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,4095,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + 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("Filter K1",&ins->std.ex1Macro,((ins->std.ex1Macro.mode==1)?(-65535):0),65535,160,uiColors[GUI_COLOR_MACRO_OTHER],false,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Filter K2",&ins->std.ex2Macro,((ins->std.ex2Macro.mode==1)?(-65535):0),65535,160,uiColors[GUI_COLOR_MACRO_OTHER],false,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Outputs",&ins->std.fbMacro,0,5,64,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.algMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,es5506ControlModes)); break; case DIV_INS_MULTIPCM: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,-7,7,45,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_SNES: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Noise Freq",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Noise Freq",&ins->std.dutyMacro,0,31,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,127,158,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,127,158,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Special",&ins->std.ex1Macro,0,5,96,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,snesModeBits)); + macroList.push_back(FurnaceGUIMacroDesc("Gain",&ins->std.ex2Macro,0,255,256,uiColors[GUI_COLOR_MACRO_VOLUME],false,NULL,macroHoverGain,false)); break; case DIV_INS_SU: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Duty/Noise",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Duty/Noise",&ins->std.dutyMacro,0,127,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,7,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,-127,127,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + 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("Cutoff",&ins->std.ex1Macro,0,16383,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Resonance",&ins->std.ex2Macro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.ex3Macro,0,4,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,suControlBits)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset Timer",&ins->std.ex4Macro,0,65535,160,uiColors[GUI_COLOR_MACRO_OTHER])); // again reuse code from resonance macro but use ex4 instead break; case DIV_INS_NAMCO: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Noise",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Noise",&ins->std.dutyMacro,0,1,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); break; case DIV_INS_OPL_DRUMS: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,0,4,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_OPM: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Noise Freq",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Noise Freq",&ins->std.dutyMacro,0,32,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_NES: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Duty/Noise",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Duty/Noise",&ins->std.dutyMacro,0,3,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_MSM6258: - macroList.push_back(FurnaceGUIMacroDesc("Freq Divider",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Freq Divider",&ins->std.dutyMacro,0,2,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits)); + 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("Clock Divider",&ins->std.ex1Macro,0,1,160,uiColors[GUI_COLOR_MACRO_OTHER])); break; case DIV_INS_MSM6295: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,8,160,uiColors[GUI_COLOR_MACRO_VOLUME])); - macroList.push_back(FurnaceGUIMacroDesc("Freq Divider",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Freq Divider",&ins->std.dutyMacro,0,1,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_ADPCMA: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,31,160,uiColors[GUI_COLOR_MACRO_VOLUME])); - macroList.push_back(FurnaceGUIMacroDesc("Global Volume",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Global Volume",&ins->std.dutyMacro,0,63,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_ADPCMB: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_SEGAPCM: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,127,158,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,127,158,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_QSOUND: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,16383,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Echo Level",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Echo Level",&ins->std.dutyMacro,0,32767,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,-16,16,63,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Surround",&ins->std.panRMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + 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("Echo Feedback",&ins->std.ex1Macro,0,16383,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Echo Length",&ins->std.ex2Macro,0,2725,160,uiColors[GUI_COLOR_MACRO_OTHER])); break; case DIV_INS_YMZ280B: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,-7,7,45,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_RF5C68: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_MSM5232: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Group Ctrl",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,msm5232ControlBits)); + macroList.push_back(FurnaceGUIMacroDesc("Group Ctrl",&ins->std.dutyMacro,0,5,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,msm5232ControlBits)); + macroList.push_back(FurnaceGUIMacroDesc("Group Attack",&ins->std.ex1Macro,0,5,96,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Group Decay",&ins->std.ex2Macro,0,11,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Noise",&ins->std.ex3Macro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_T6W28: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Noise Type",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Noise Type",&ins->std.dutyMacro,0,1,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_K007232: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_GA20: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_POKEMINI: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,2,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Pulse Width",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pulse Width",&ins->std.dutyMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); break; case DIV_INS_SM8521: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,31,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); break; case DIV_INS_PV1000: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,1,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); break; case DIV_INS_K053260: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,-3,3,37,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_TED: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,8,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Square/Noise",&ins->std.dutyMacro,0,dutyMax,80,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,tedControlBits)); + macroList.push_back(FurnaceGUIMacroDesc("Square/Noise",&ins->std.dutyMacro,0,2,80,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,tedControlBits)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_C140: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_C219: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.dutyMacro,0,dutyMax,120,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,c219ControlBits)); + macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.dutyMacro,0,3,120,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,c219ControlBits)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_ESFM: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("OP4 Noise Mode",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("OP4 Noise Mode",&ins->std.dutyMacro,0,3,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_POWERNOISE: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + 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("Control",&ins->std.ex1Macro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,powerNoiseControlBits)); + macroList.push_back(FurnaceGUIMacroDesc("Tap A Location",&ins->std.ex4Macro,0,15,96,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Tap B Location",&ins->std.ex5Macro,0,15,96,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Load LFSR",&ins->std.ex8Macro,0,16,256,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_POWERNOISE_SLOPE: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,15,46,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + 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("Control",&ins->std.ex1Macro,0,6,96,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,powerNoiseSlopeControlBits)); + macroList.push_back(FurnaceGUIMacroDesc("Portion A Length",&ins->std.ex2Macro,0,255,128,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Portion B Length",&ins->std.ex3Macro,0,255,128,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Portion A Offset",&ins->std.ex6Macro,0,15,96,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Portion B Offset",&ins->std.ex7Macro,0,15,96,uiColors[GUI_COLOR_MACRO_OTHER])); break; case DIV_INS_DAVE: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,63,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Noise Freq",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Noise Freq",&ins->std.dutyMacro,0,3,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,4,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,63,94,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,63,94,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + 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("Control",&ins->std.ex1Macro,0,4,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,daveControlBits)); break; case DIV_INS_NDS: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,127,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); if (!ins->amiga.useSample) { - macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,0,7,160,uiColors[GUI_COLOR_MACRO_OTHER])); } + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,-64,63,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_GBA_DMA: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,2,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); break; case DIV_INS_GBA_MINMOD: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,waveCount,160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + 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("Special",&ins->std.ex1Macro,0,2,96,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,minModModeBits)); break; case DIV_INS_BIFURCATOR: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,255,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Parameter",&ins->std.dutyMacro,0,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Parameter",&ins->std.dutyMacro,0,65535,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL)); + macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + macroList.push_back(FurnaceGUIMacroDesc("Load Value",&ins->std.ex1Macro,0,65535,160,uiColors[GUI_COLOR_MACRO_OTHER])); break; case DIV_INS_SID2: macroList.push_back(FurnaceGUIMacroDesc("Volume",&ins->std.volMacro,0,15,160,uiColors[GUI_COLOR_MACRO_VOLUME])); macroList.push_back(FurnaceGUIMacroDesc("Arpeggio",&ins->std.arpMacro,-120,120,160,uiColors[GUI_COLOR_MACRO_PITCH],true,NULL,macroHoverNote,false,NULL,true,ins->std.arpMacro.val)); - macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,ins->c64.dutyIsAbs?0:-4095,dutyMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.dutyMacro,ins->c64.dutyIsAbs?0:-4095,4095,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Waveform",&ins->std.waveMacro,0,4,64,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,true,c64ShapeBits)); + macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); + 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("Cutoff",&ins->std.algMacro,ins->c64.filterIsAbs?0:-4095,4095,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Filter Mode",&ins->std.ex1Macro,0,3,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,filtModeBits)); + macroList.push_back(FurnaceGUIMacroDesc("Resonance",&ins->std.ex2Macro,0,255,160,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Filter Toggle",&ins->std.ex3Macro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); + macroList.push_back(FurnaceGUIMacroDesc("Special",&ins->std.ex4Macro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,sid2ControlBits)); + macroList.push_back(FurnaceGUIMacroDesc("Attack",&ins->std.ex5Macro,0,15,128,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Decay",&ins->std.ex6Macro,0,15,128,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Sustain",&ins->std.ex7Macro,0,15,128,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Release",&ins->std.ex8Macro,0,15,128,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Noise Mode",&ins->std.fmsMacro,0,3,64,uiColors[GUI_COLOR_MACRO_OTHER])); + macroList.push_back(FurnaceGUIMacroDesc("Wave Mix",&ins->std.amsMacro,0,3,64,uiColors[GUI_COLOR_MACRO_OTHER])); break; case DIV_INS_MAX: @@ -7164,417 +7341,6 @@ void FurnaceGUI::drawInsEdit() { break; } - // OLD CODE - const char* waveLabel="Waveform"; - int waveMax=(ins->type==DIV_INS_VERA)?3:(MAX(1,e->song.waveLen-1)); - bool waveBitMode=false; - if (ins->type==DIV_INS_C64 || ins->type==DIV_INS_SAA1099 || ins->type==DIV_INS_SID2) { - waveBitMode=true; - } - if (ins->type==DIV_INS_STD || ins->type==DIV_INS_VRC6_SAW || ins->type==DIV_INS_NES || - ins->type==DIV_INS_T6W28 || ins->type==DIV_INS_PV1000) - waveMax=0; - if (ins->type==DIV_INS_TIA || ins->type==DIV_INS_VIC || ins->type==DIV_INS_OPLL) waveMax=15; - if (ins->type==DIV_INS_C64 || ins->type==DIV_INS_SID2) waveMax=4; - 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 || ins->type==DIV_INS_ESFM) waveMax=0; - if (ins->type==DIV_INS_MIKEY) waveMax=0; - if (ins->type==DIV_INS_MULTIPCM) waveMax=0; - if (ins->type==DIV_INS_ADPCMA) waveMax=0; - if (ins->type==DIV_INS_ADPCMB) waveMax=0; - if (ins->type==DIV_INS_QSOUND) waveMax=0; - if (ins->type==DIV_INS_YMZ280B) waveMax=0; - if (ins->type==DIV_INS_RF5C68) waveMax=0; - if (ins->type==DIV_INS_MSM5232) waveMax=0; - if (ins->type==DIV_INS_MSM6258) waveMax=0; - if (ins->type==DIV_INS_MSM6295) waveMax=0; - if (ins->type==DIV_INS_SEGAPCM) waveMax=0; - if (ins->type==DIV_INS_K007232) waveMax=0; - if (ins->type==DIV_INS_ES5506) waveMax=0; - if (ins->type==DIV_INS_GA20) waveMax=0; - if (ins->type==DIV_INS_K053260) waveMax=0; - if (ins->type==DIV_INS_BEEPER) waveMax=0; - if (ins->type==DIV_INS_POKEMINI) waveMax=0; - if (ins->type==DIV_INS_TED) waveMax=0; - if (ins->type==DIV_INS_C140) waveMax=0; - if (ins->type==DIV_INS_C219) waveMax=0; - if (ins->type==DIV_INS_POWERNOISE) waveMax=0; - if (ins->type==DIV_INS_POWERNOISE_SLOPE) waveMax=0; - if (ins->type==DIV_INS_SU || ins->type==DIV_INS_POKEY) waveMax=7; - if (ins->type==DIV_INS_DAVE) waveMax=4; - if (ins->type==DIV_INS_NDS) waveMax=0; - if (ins->type==DIV_INS_BIFURCATOR) waveMax=0; - if (ins->type==DIV_INS_PET) { - waveMax=8; - waveBitMode=true; - } - if (ins->type==DIV_INS_VRC6) { - waveMax=ins->amiga.useSample?(MAX(1,e->song.waveLen-1)):0; - } - - if (ins->type==DIV_INS_OPLL) { - waveLabel="Patch"; - } - - if (ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930) { - waveMax=ins->amiga.useSample?0:3; - waveBitMode=ins->amiga.useSample?false:true; - } - - const char** waveNames=NULL; - if (ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930 || ins->type==DIV_INS_SAA1099) waveNames=ayShapeBits; - if (ins->type==DIV_INS_C64 || ins->type==DIV_INS_SID2) waveNames=c64ShapeBits; - - int ex1Max=(ins->type==DIV_INS_AY8930)?8:0; - int ex2Max=(ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930)?4:0; - bool ex2Bit=true; - - if (ins->type==DIV_INS_C64) { - ex1Max=4; - ex2Max=15; - } - if (ins->type==DIV_INS_SID2) { - ex1Max=3; - ex2Max=255; - } - if (ins->type==DIV_INS_X1_010) { - ex1Max=ins->amiga.useSample?0:7; - ex2Max=ins->amiga.useSample?0:255; - ex2Bit=false; - } - if (ins->type==DIV_INS_N163) { - ex1Max=252; - } - if (ins->type==DIV_INS_FDS) { - ex1Max=63; - ex2Max=4095; - } - if (ins->type==DIV_INS_SU) { - ex1Max=16383; - ex2Max=255; - } - if (ins->type==DIV_INS_MSM6258) { - ex1Max=1; - } - if (ins->type==DIV_INS_QSOUND) { - ex1Max=16383; - ex2Max=2725; - } - if (ins->type==DIV_INS_SAA1099) ex1Max=8; - if (ins->type==DIV_INS_ES5506) { - ex1Max=65535; - ex2Max=65535; - } - if (ins->type==DIV_INS_SNES) { - ex1Max=5; - ex2Max=255; - } - if (ins->type==DIV_INS_MSM5232) { - ex1Max=5; - ex2Max=11; - } - if (ins->type==DIV_INS_DAVE) { - ex1Max=4; - } - if (ins->type==DIV_INS_MIKEY) { - ex1Max=12; - } - if (ins->type==DIV_INS_GBA_MINMOD) { - ex1Max=2; - } - if (ins->type==DIV_INS_BIFURCATOR) { - ex1Max=65535; - } - - int panMin=0; - int panMax=0; - bool panSingle=false; - bool panSingleNoBit=false; - if (ins->type==DIV_INS_STD || // Game Gear - ins->type==DIV_INS_FM || - ins->type==DIV_INS_OPM || - ins->type==DIV_INS_GB || - ins->type==DIV_INS_OPZ || - ins->type==DIV_INS_MSM6258 || - ins->type==DIV_INS_VERA || - ins->type==DIV_INS_ADPCMA || - ins->type==DIV_INS_ADPCMB || - ins->type==DIV_INS_ESFM || - ins->type==DIV_INS_GBA_DMA) { - panMax=2; - panSingle=true; - } - if (ins->type==DIV_INS_OPL || - ins->type==DIV_INS_OPL_DRUMS) { - panMax=4; - panSingle=true; - } - if (ins->type==DIV_INS_X1_010 || ins->type==DIV_INS_PCE || ins->type==DIV_INS_MIKEY || - ins->type==DIV_INS_SAA1099 || ins->type==DIV_INS_NAMCO || ins->type==DIV_INS_RF5C68 || - ins->type==DIV_INS_VBOY || ins->type==DIV_INS_T6W28 || ins->type==DIV_INS_K007232) { - panMax=15; - } - if (ins->type==DIV_INS_SEGAPCM) { - panMax=127; - } - if (ins->type==DIV_INS_AMIGA) { - if (ins->std.panLMacro.mode) { - panMin=-16; - panMax=16; - } else { - panMin=0; - panMax=127; - } - } - if (ins->type==DIV_INS_QSOUND) { - panMin=-16; - panMax=16; - panSingleNoBit=true; - } - if (ins->type==DIV_INS_MULTIPCM || ins->type==DIV_INS_YMZ280B) { - panMin=-7; - panMax=7; - panSingleNoBit=true; - } - if (ins->type==DIV_INS_K053260) { - panMin=-3; - panMax=3; - panSingleNoBit=true; - } - if (ins->type==DIV_INS_SU) { - panMin=-127; - panMax=127; - panSingleNoBit=true; - } - if (ins->type==DIV_INS_SNES) { - panMin=0; - panMax=127; - } - if (ins->type==DIV_INS_C140 || ins->type==DIV_INS_C219 || ins->type==DIV_INS_GBA_MINMOD || - ins->type==DIV_INS_BIFURCATOR) { - panMin=0; - panMax=255; - } - if (ins->type==DIV_INS_ES5506) { - panMax=4095; - } - if (ins->type==DIV_INS_POWERNOISE) { - panMax=15; - } - if (ins->type==DIV_INS_POWERNOISE_SLOPE) { - panMax=15; - } - if (ins->type==DIV_INS_DAVE) { - panMax=63; - } - if (ins->type==DIV_INS_NDS) { - panMin=-64; - panMax=63; - panSingleNoBit=true; - } - - if (waveMax>0) { - macroList.push_back(FurnaceGUIMacroDesc(waveLabel,&ins->std.waveMacro,0,waveMax,(waveBitMode && ins->type!=DIV_INS_PET)?64:160,uiColors[GUI_COLOR_MACRO_WAVE],false,NULL,NULL,waveBitMode,waveNames)); - } - if (panMax>0) { - if (panSingle) { - macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,0,panMax,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,panBits)); - } else if (ins->type==DIV_INS_QSOUND) { - macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,panMin,panMax,CLAMP(31+panMax-panMin,32,160),uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Surround",&ins->std.panRMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); - } else { - if (panSingleNoBit || (ins->type==DIV_INS_AMIGA && ins->std.panLMacro.mode)) { - macroList.push_back(FurnaceGUIMacroDesc("Panning",&ins->std.panLMacro,panMin,panMax,CLAMP(31+panMax-panMin,32,160),uiColors[GUI_COLOR_MACRO_OTHER],false,(ins->type==DIV_INS_AMIGA)?macroQSoundMode:NULL)); - } else { - macroList.push_back(FurnaceGUIMacroDesc("Panning (left)",&ins->std.panLMacro,panMin,panMax,CLAMP(31+panMax-panMin,32,160),uiColors[GUI_COLOR_MACRO_OTHER],false,(ins->type==DIV_INS_AMIGA)?macroQSoundMode:NULL)); - } - if (!panSingleNoBit) { - if (ins->type==DIV_INS_AMIGA && ins->std.panLMacro.mode) { - macroList.push_back(FurnaceGUIMacroDesc("Surround",&ins->std.panRMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); - } else { - macroList.push_back(FurnaceGUIMacroDesc("Panning (right)",&ins->std.panRMacro,panMin,panMax,CLAMP(31+panMax-panMin,32,160),uiColors[GUI_COLOR_MACRO_OTHER])); - } - } - } - } - if (ins->type!=DIV_INS_MSM5232 && ins->type!=DIV_INS_MSM6258 && ins->type!=DIV_INS_MSM6295 && ins->type!=DIV_INS_ADPCMA) { - macroList.push_back(FurnaceGUIMacroDesc("Pitch",&ins->std.pitchMacro,-2048,2047,160,uiColors[GUI_COLOR_MACRO_PITCH],true,macroRelativeMode)); - } - if (ins->type==DIV_INS_FM || - ins->type==DIV_INS_OPM || - ins->type==DIV_INS_STD || - ins->type==DIV_INS_NES || - ins->type==DIV_INS_OPL || - ins->type==DIV_INS_OPL_DRUMS || - ins->type==DIV_INS_OPZ || - ins->type==DIV_INS_PCE || - ins->type==DIV_INS_GB || - ins->type==DIV_INS_MSM6258 || - ins->type==DIV_INS_MSM6295 || - ins->type==DIV_INS_ADPCMA || - ins->type==DIV_INS_ADPCMB || - ins->type==DIV_INS_SEGAPCM || - ins->type==DIV_INS_QSOUND || - ins->type==DIV_INS_YMZ280B || - ins->type==DIV_INS_RF5C68 || - ins->type==DIV_INS_AMIGA || - ins->type==DIV_INS_OPLL || - ins->type==DIV_INS_AY || - ins->type==DIV_INS_AY8930 || - ins->type==DIV_INS_SWAN || - ins->type==DIV_INS_MULTIPCM || - (ins->type==DIV_INS_VRC6 && ins->amiga.useSample) || - ins->type==DIV_INS_SU || - ins->type==DIV_INS_MIKEY || - ins->type==DIV_INS_ES5506 || - ins->type==DIV_INS_T6W28 || - ins->type==DIV_INS_VBOY || - (ins->type==DIV_INS_X1_010 && ins->amiga.useSample) || - ins->type==DIV_INS_K007232 || - ins->type==DIV_INS_GA20 || - ins->type==DIV_INS_K053260 || - ins->type==DIV_INS_C140 || - ins->type==DIV_INS_C219 || - ins->type==DIV_INS_TED || - ins->type==DIV_INS_ESFM || - ins->type==DIV_INS_POWERNOISE || - ins->type==DIV_INS_POWERNOISE_SLOPE || - ins->type==DIV_INS_DAVE || - ins->type==DIV_INS_NDS || - ins->type==DIV_INS_GBA_DMA || - ins->type==DIV_INS_GBA_MINMOD || - ins->type==DIV_INS_SID2) { - 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 (ins->type==DIV_INS_C64 || ins->type==DIV_INS_SID2) { - int cutoffMin=-2047; - int cutoffMax=2047; - - if (ins->c64.filterIsAbs) { - cutoffMin=0; - cutoffMax=2047; - } - - if (ins->type==DIV_INS_SID2) { - if (ins->c64.filterIsAbs) { - cutoffMin=0; - cutoffMax=4095; - } else { - cutoffMin=-4095; - cutoffMax=4095; - } - } - - macroList.push_back(FurnaceGUIMacroDesc("Cutoff",&ins->std.algMacro,cutoffMin,cutoffMax,160,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Filter Mode",&ins->std.ex1Macro,0,ex1Max,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,filtModeBits)); - } else if (ins->type==DIV_INS_SAA1099) { - macroList.push_back(FurnaceGUIMacroDesc("Envelope",&ins->std.ex1Macro,0,ex1Max,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,saaEnvBits)); - } else if (ins->type==DIV_INS_X1_010 && !ins->amiga.useSample) { - macroList.push_back(FurnaceGUIMacroDesc("Envelope Mode",&ins->std.ex1Macro,0,ex1Max,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,x1_010EnvBits)); - } else if (ins->type==DIV_INS_N163) { - macroList.push_back(FurnaceGUIMacroDesc("Wave Length",&ins->std.ex1Macro,0,ex1Max,160,uiColors[GUI_COLOR_MACRO_OTHER])); - } else if (ins->type==DIV_INS_FDS) { - macroList.push_back(FurnaceGUIMacroDesc("Mod Depth",&ins->std.ex1Macro,0,ex1Max,160,uiColors[GUI_COLOR_MACRO_OTHER])); - } else if (ins->type==DIV_INS_SU) { - macroList.push_back(FurnaceGUIMacroDesc("Cutoff",&ins->std.ex1Macro,0,ex1Max,160,uiColors[GUI_COLOR_MACRO_OTHER])); - } else if (ins->type==DIV_INS_ES5506) { - macroList.push_back(FurnaceGUIMacroDesc("Filter K1",&ins->std.ex1Macro,((ins->std.ex1Macro.mode==1)?(-ex1Max):0),ex1Max,160,uiColors[GUI_COLOR_MACRO_OTHER],false,macroRelativeMode)); - } else if (ins->type==DIV_INS_MSM6258) { - macroList.push_back(FurnaceGUIMacroDesc("Clock Divider",&ins->std.ex1Macro,0,ex1Max,160,uiColors[GUI_COLOR_MACRO_OTHER])); - } else if (ins->type==DIV_INS_QSOUND) { - macroList.push_back(FurnaceGUIMacroDesc("Echo Feedback",&ins->std.ex1Macro,0,ex1Max,160,uiColors[GUI_COLOR_MACRO_OTHER])); - } else if (ins->type==DIV_INS_SNES) { - macroList.push_back(FurnaceGUIMacroDesc("Special",&ins->std.ex1Macro,0,ex1Max,96,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,snesModeBits)); - } else if (ins->type==DIV_INS_MSM5232) { - macroList.push_back(FurnaceGUIMacroDesc("Group Attack",&ins->std.ex1Macro,0,ex1Max,96,uiColors[GUI_COLOR_MACRO_OTHER])); - } else if (ins->type==DIV_INS_DAVE) { - macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.ex1Macro,0,ex1Max,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,daveControlBits)); - } else if (ins->type==DIV_INS_MIKEY) { - macroList.push_back(FurnaceGUIMacroDesc("Load LFSR",&ins->std.ex1Macro,0,12,160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); - } else if (ins->type==DIV_INS_GBA_MINMOD) { - macroList.push_back(FurnaceGUIMacroDesc("Special",&ins->std.ex1Macro,0,ex1Max,96,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,minModModeBits)); - } else if (ins->type==DIV_INS_BIFURCATOR) { - macroList.push_back(FurnaceGUIMacroDesc("Load Value",&ins->std.ex1Macro,0,ex1Max,160,uiColors[GUI_COLOR_MACRO_OTHER])); - } else { - macroList.push_back(FurnaceGUIMacroDesc("Duty",&ins->std.ex1Macro,0,ex1Max,160,uiColors[GUI_COLOR_MACRO_OTHER])); - } - } - if (ex2Max>0) { - if (ins->type==DIV_INS_C64) { - macroList.push_back(FurnaceGUIMacroDesc("Resonance",&ins->std.ex2Macro,0,ex2Max,64,uiColors[GUI_COLOR_MACRO_OTHER])); - } else if (ins->type==DIV_INS_SID2) { - macroList.push_back(FurnaceGUIMacroDesc("Resonance",&ins->std.ex2Macro,0,ex2Max,160,uiColors[GUI_COLOR_MACRO_OTHER])); - } else if (ins->type==DIV_INS_FDS) { - macroList.push_back(FurnaceGUIMacroDesc("Mod Speed",&ins->std.ex2Macro,0,ex2Max,160,uiColors[GUI_COLOR_MACRO_OTHER])); - } else if (ins->type==DIV_INS_SU) { - macroList.push_back(FurnaceGUIMacroDesc("Resonance",&ins->std.ex2Macro,0,ex2Max,160,uiColors[GUI_COLOR_MACRO_OTHER])); - } else if (ins->type==DIV_INS_ES5506) { - macroList.push_back(FurnaceGUIMacroDesc("Filter K2",&ins->std.ex2Macro,((ins->std.ex2Macro.mode==1)?(-ex2Max):0),ex2Max,160,uiColors[GUI_COLOR_MACRO_OTHER],false,macroRelativeMode)); - } else if (ins->type==DIV_INS_QSOUND) { - macroList.push_back(FurnaceGUIMacroDesc("Echo Length",&ins->std.ex2Macro,0,ex2Max,160,uiColors[GUI_COLOR_MACRO_OTHER])); - } else if (ins->type==DIV_INS_SNES) { - macroList.push_back(FurnaceGUIMacroDesc("Gain",&ins->std.ex2Macro,0,ex2Max,256,uiColors[GUI_COLOR_MACRO_VOLUME],false,NULL,macroHoverGain,false)); - } else if (ins->type==DIV_INS_MSM5232) { - macroList.push_back(FurnaceGUIMacroDesc("Group Decay",&ins->std.ex2Macro,0,ex2Max,160,uiColors[GUI_COLOR_MACRO_OTHER])); - } else { - macroList.push_back(FurnaceGUIMacroDesc("Envelope",&ins->std.ex2Macro,0,ex2Max,ex2Bit?64:160,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,ex2Bit,ayEnvBits)); - } - } - if (ins->type==DIV_INS_C64) { - macroList.push_back(FurnaceGUIMacroDesc("Special",&ins->std.ex4Macro,0,4,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,c64TestGateBits)); - macroList.push_back(FurnaceGUIMacroDesc("Attack",&ins->std.ex5Macro,0,15,128,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Decay",&ins->std.ex6Macro,0,15,128,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Sustain",&ins->std.ex7Macro,0,15,128,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Release",&ins->std.ex8Macro,0,15,128,uiColors[GUI_COLOR_MACRO_OTHER])); - } - if (ins->type==DIV_INS_SID2) { - macroList.push_back(FurnaceGUIMacroDesc("Filter Toggle",&ins->std.ex3Macro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); - macroList.push_back(FurnaceGUIMacroDesc("Special",&ins->std.ex4Macro,0,3,48,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,sid2ControlBits)); - macroList.push_back(FurnaceGUIMacroDesc("Attack",&ins->std.ex5Macro,0,15,128,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Decay",&ins->std.ex6Macro,0,15,128,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Sustain",&ins->std.ex7Macro,0,15,128,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Release",&ins->std.ex8Macro,0,15,128,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Noise Mode",&ins->std.fmsMacro,0,3,64,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Wave Mix",&ins->std.amsMacro,0,3,64,uiColors[GUI_COLOR_MACRO_OTHER])); - } - if (ins->type==DIV_INS_AY || ins->type==DIV_INS_AY8930 || (ins->type==DIV_INS_X1_010 && !ins->amiga.useSample)) { - macroList.push_back(FurnaceGUIMacroDesc("AutoEnv Num",&ins->std.ex3Macro,0,15,160,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("AutoEnv Den",&ins->std.algMacro,0,15,160,uiColors[GUI_COLOR_MACRO_OTHER])); - } - if (ins->type==DIV_INS_AY8930) { - // oh my i am running out of macros - macroList.push_back(FurnaceGUIMacroDesc("Noise AND Mask",&ins->std.fbMacro,0,8,96,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); - macroList.push_back(FurnaceGUIMacroDesc("Noise OR Mask",&ins->std.fmsMacro,0,8,96,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); - } - if (ins->type==DIV_INS_FDS) { - macroList.push_back(FurnaceGUIMacroDesc("Mod Position",&ins->std.ex3Macro,0,127,160,uiColors[GUI_COLOR_MACRO_OTHER])); - } - if (ins->type==DIV_INS_SU) { - macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.ex3Macro,0,4,64,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,suControlBits)); - macroList.push_back(FurnaceGUIMacroDesc("Phase Reset Timer",&ins->std.ex4Macro,0,65535,160,uiColors[GUI_COLOR_MACRO_OTHER])); // again reuse code from resonance macro but use ex4 instead - } - if (ins->type==DIV_INS_ES5506) { - macroList.push_back(FurnaceGUIMacroDesc("Outputs",&ins->std.fbMacro,0,5,64,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.algMacro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,es5506ControlModes)); - } - if (ins->type==DIV_INS_MSM5232) { - macroList.push_back(FurnaceGUIMacroDesc("Noise",&ins->std.ex3Macro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); - } - if (ins->type==DIV_INS_POWERNOISE) { - macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.ex1Macro,0,2,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,powerNoiseControlBits)); - macroList.push_back(FurnaceGUIMacroDesc("Tap A Location",&ins->std.ex4Macro,0,15,96,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Tap B Location",&ins->std.ex5Macro,0,15,96,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Load LFSR",&ins->std.ex8Macro,0,16,256,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); - } - if (ins->type==DIV_INS_POWERNOISE_SLOPE) { - macroList.push_back(FurnaceGUIMacroDesc("Control",&ins->std.ex1Macro,0,6,96,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true,powerNoiseSlopeControlBits)); - macroList.push_back(FurnaceGUIMacroDesc("Portion A Length",&ins->std.ex2Macro,0,255,128,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Portion B Length",&ins->std.ex3Macro,0,255,128,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Portion A Offset",&ins->std.ex6Macro,0,15,96,uiColors[GUI_COLOR_MACRO_OTHER])); - macroList.push_back(FurnaceGUIMacroDesc("Portion B Offset",&ins->std.ex7Macro,0,15,96,uiColors[GUI_COLOR_MACRO_OTHER])); - } - drawMacros(macroList,macroEditStateMacros); ImGui::EndTabItem(); } From 9c42d3a7b3c7e4632f3df58aa1b6bb9022f4e257 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 4 May 2024 13:40:29 -0500 Subject: [PATCH 04/22] fix crash when adding/cloning more than 32 chips --- src/engine/engine.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 04bcaa938..d71ac189c 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1095,7 +1095,7 @@ bool DivEngine::changeSystem(int index, DivSystem which, bool preserveOrder) { } bool DivEngine::addSystem(DivSystem which) { - if (song.systemLen>DIV_MAX_CHIPS) { + if (song.systemLen>=DIV_MAX_CHIPS) { lastError=fmt::sprintf("max number of systems is %d",DIV_MAX_CHIPS); return false; } @@ -1149,7 +1149,7 @@ bool DivEngine::duplicateSystem(int index, bool pat, bool end) { lastError="invalid index"; return false; } - if (song.systemLen>DIV_MAX_CHIPS) { + if (song.systemLen>=DIV_MAX_CHIPS) { lastError=fmt::sprintf("max number of systems is %d",DIV_MAX_CHIPS); return false; } From 83007601f77d8f1056ff579c0bf152b3a72fc2c7 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 4 May 2024 16:46:41 -0500 Subject: [PATCH 05/22] add option to build with console subsystem on Wind --- CMakeLists.txt | 7 ++++++- src/gui/gui.h | 1 + src/main.cpp | 3 ++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index df850c42b..41188fd9e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,6 +122,7 @@ option(WITH_DEMOS "Install demo songs" ON) option(WITH_INSTRUMENTS "Install instruments" ON) option(WITH_WAVETABLES "Install wavetables" ON) option(SHOW_OPEN_ASSETS_MENU_ENTRY "Show option to open built-in assets directory (on supported platforms)" OFF) +option(CONSOLE_SUBSYSTEM "Build Furnace with Console subsystem on Windows" OFF) if (APPLE) option(FORCE_APPLE_BIN "Force enable binary installation to /bin" OFF) else() @@ -1128,9 +1129,13 @@ if (NOT ANDROID OR TERMUX) endif() endif() +if (WIN32 AND CONSOLE_SUBSYSTEM) + list(APPEND DEPENDENCIES_DEFINES "TA_SUBSYSTEM_CONSOLE") +endif() + if(ANDROID AND NOT TERMUX) add_library(furnace SHARED ${USED_SOURCES}) -elseif(WIN32) +elseif(WIN32 AND NOT CONSOLE_SUBSYSTEM) add_executable(furnace WIN32 ${USED_SOURCES}) else() add_executable(furnace ${USED_SOURCES}) diff --git a/src/gui/gui.h b/src/gui/gui.h index 07938ba54..3b050e066 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -2665,6 +2665,7 @@ class FurnaceGUI { void drawMacros(std::vector& macros, FurnaceGUIMacroEditState& state); void alterSampleMap(int column, int val); + void insTabFM(DivInstrument* ins); void insTabSample(DivInstrument* ins); void drawOrderButtons(); diff --git a/src/main.cpp b/src/main.cpp index 06183444e..f635955ed 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -451,12 +451,13 @@ int main(int argc, char** argv) { // Windows console thing - thanks dj.tuBIG/MaliceX #ifdef _WIN32 - +#ifndef TA_SUBSYSTEM_CONSOLE if (AttachConsole(ATTACH_PARENT_PROCESS)) { freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr); freopen("CONIN$", "r", stdin); } +#endif #endif srand(time(NULL)); From fb95d7d44cee2ce57a7f71d701f973985474c274 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 4 May 2024 16:48:45 -0500 Subject: [PATCH 06/22] document it --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a522ed88e..2eca5e5b0 100644 --- a/README.md +++ b/README.md @@ -280,6 +280,7 @@ Available options: | `WITH_INSTRUMENTS` | `ON` | Install demo instruments on `make install` | | `WITH_WAVETABLES` | `ON` | Install wavetables on `make install` | | `SHOW_OPEN_ASSETS_MENU_ENTRY` | `OFF` | Show option to open built-in assets directory (on supported platforms) | +| `CONSOLE_SUBSYSTEM` | `OFF` | Build with subsystem set to Console on Windows | | `FORCE_APPLE_BIN` | `OFF` | Enable installation of binaries (when doing `make install`) to PREFIX/bin on Apple platforms | (\*) `ON` if system-installed JACK detected, otherwise `OFF` From f994c7c5e3e2103a37ff46a8961fdf8d8ed06228 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 4 May 2024 22:10:31 -0500 Subject: [PATCH 07/22] GUI: insEdit refactor, part 3 prepare to split --- src/gui/insEdit.cpp | 4235 ++++++++++++++++++++++--------------------- 1 file changed, 2122 insertions(+), 2113 deletions(-) diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index ca960ff9e..e36f66f39 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -2925,6 +2925,2127 @@ void FurnaceGUI::insTabSample(DivInstrument* ins) { } } +void FurnaceGUI::insTabFM(DivInstrument* ins) { + int opCount=4; + if (ins->type==DIV_INS_OPLL) opCount=2; + if (ins->type==DIV_INS_OPL) opCount=(ins->fm.ops==4)?4:2; + bool opsAreMutable=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM); + + if (ImGui::BeginTabItem("FM")) { + DivInstrumentFM& fmOrigin=(ins->type==DIV_INS_OPLL && ins->fm.opllPreset>0 && ins->fm.opllPreset<16)?opllPreview:ins->fm; + + bool isPresent[4]; + int isPresentCount=0; + memset(isPresent,0,4*sizeof(bool)); + for (int i=0; isong.systemLen; i++) { + if (e->song.system[i]==DIV_SYSTEM_VRC7) { + isPresent[3]=true; + } else if (e->song.system[i]==DIV_SYSTEM_OPLL || e->song.system[i]==DIV_SYSTEM_OPLL_DRUMS) { + isPresent[(e->song.systemFlags[i].getInt("patchSet",0))&3]=true; + } + } + if (!isPresent[0] && !isPresent[1] && !isPresent[2] && !isPresent[3]) { + isPresent[0]=true; + } + for (int i=0; i<4; i++) { + if (isPresent[i]) isPresentCount++; + } + int presentWhich=0; + for (int i=0; i<4; i++) { + if (isPresent[i]) { + presentWhich=i; + break; + } + } + + if (ImGui::BeginTable("fmDetails",3,(ins->type==DIV_INS_ESFM)?ImGuiTableFlags_SizingStretchProp:ImGuiTableFlags_SizingStretchSame)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.50f:0.0f)); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.15f:0.0f)); + ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.35f:0.0f)); + + ImGui::TableNextRow(); + switch (ins->type) { + case DIV_INS_FM: + case DIV_INS_OPM: + ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable + P(CWSliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); rightClickable + ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable + P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable + ImGui::TableNextColumn(); + if (fmPreviewOn) { + drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + if (!fmPreviewPaused) { + renderFMPreview(ins,1); + WAKE_UP; + } + } else { + drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + } + kvsConfig(ins); + break; + case DIV_INS_OPZ: + ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable + P(CWSliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); rightClickable + P(CWSliderScalar(FM_NAME(FM_FMS2),ImGuiDataType_U8,&ins->fm.fms2,&_ZERO,&_SEVEN)); rightClickable + ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable + P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable + P(CWSliderScalar(FM_NAME(FM_AMS2),ImGuiDataType_U8,&ins->fm.ams2,&_ZERO,&_THREE)); rightClickable + ImGui::TableNextColumn(); + if (fmPreviewOn) { + drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + if (!fmPreviewPaused) { + renderFMPreview(ins,1); + WAKE_UP; + } + } else { + drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + } + kvsConfig(ins); + + if (ImGui::Button("Request from TX81Z")) { + doAction(GUI_ACTION_TX81Z_REQUEST); + } + /* + ImGui::SameLine(); + if (ImGui::Button("Send to TX81Z")) { + showError("Coming soon!"); + } + */ + break; + case DIV_INS_OPL: + case DIV_INS_OPL_DRUMS: { + bool fourOp=(ins->fm.ops==4 || ins->type==DIV_INS_OPL_DRUMS); + bool drums=ins->fm.opllPreset==16; + int algMax=fourOp?3:1; + ImGui::TableNextColumn(); + ins->fm.alg&=algMax; + P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable + if (ins->type==DIV_INS_OPL) { + ImGui::BeginDisabled(ins->fm.opllPreset==16); + if (ImGui::Checkbox("4-op",&fourOp)) { PARAMETER + ins->fm.ops=fourOp?4:2; + } + ImGui::EndDisabled(); + } + ImGui::TableNextColumn(); + P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&algMax)); rightClickable + if (ins->type==DIV_INS_OPL) { + if (ImGui::Checkbox("Drums",&drums)) { PARAMETER + ins->fm.opllPreset=drums?16:0; + } + } + ImGui::TableNextColumn(); + if (fmPreviewOn) { + drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + if (!fmPreviewPaused) { + renderFMPreview(ins,1); + WAKE_UP; + } + } else { + drawAlgorithm(ins->fm.alg&algMax,fourOp?FM_ALGS_4OP_OPL:FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + } + kvsConfig(ins); + break; + } + case DIV_INS_OPLL: { + bool dc=fmOrigin.fms; + bool dm=fmOrigin.ams; + bool sus=ins->fm.alg; + ImGui::TableNextColumn(); + ImGui::BeginDisabled(ins->fm.opllPreset!=0); + P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&fmOrigin.fb,&_ZERO,&_SEVEN)); rightClickable + if (ImGui::Checkbox(FM_NAME(FM_DC),&dc)) { PARAMETER + fmOrigin.fms=dc; + } + ImGui::EndDisabled(); + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_NAME(FM_SUS),&sus)) { PARAMETER + ins->fm.alg=sus; + } + ImGui::BeginDisabled(ins->fm.opllPreset!=0); + if (ImGui::Checkbox(FM_NAME(FM_DM),&dm)) { PARAMETER + fmOrigin.ams=dm; + } + ImGui::EndDisabled(); + ImGui::TableNextColumn(); + if (fmPreviewOn) { + drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale)); + if (!fmPreviewPaused) { + renderFMPreview(ins,1); + WAKE_UP; + } + } else { + drawAlgorithm(0,FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale)); + } + kvsConfig(ins,false); + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + + if (ImGui::BeginCombo("##LLPreset",opllInsNames[presentWhich][ins->fm.opllPreset])) { + if (isPresentCount>1) { + if (ImGui::BeginTable("LLPresetList",isPresentCount)) { + ImGui::TableNextRow(ImGuiTableRowFlags_Headers); + for (int i=0; i<4; i++) { + if (!isPresent[i]) continue; + ImGui::TableNextColumn(); + ImGui::Text("%s name",opllVariants[i]); + } + for (int i=0; i<17; i++) { + ImGui::TableNextRow(); + for (int j=0; j<4; j++) { + if (!isPresent[j]) continue; + ImGui::TableNextColumn(); + ImGui::PushID(j*17+i); + if (ImGui::Selectable(opllInsNames[j][i])) { + ins->fm.opllPreset=i; + } + ImGui::PopID(); + } + } + ImGui::EndTable(); + } + } else { + for (int i=0; i<17; i++) { + if (ImGui::Selectable(opllInsNames[presentWhich][i])) { + ins->fm.opllPreset=i; + } + } + } + ImGui::EndCombo(); + } + break; + } + case DIV_INS_ESFM: { + ImGui::TableNextColumn(); + P(CWSliderScalar(ESFM_LONG_NAME(ESFM_NOISE),ImGuiDataType_U8,&ins->esfm.noise,&_ZERO,&_THREE,esfmNoiseModeNames[ins->esfm.noise&3])); rightClickable + ImGui::TextUnformatted(esfmNoiseModeDescriptions[ins->esfm.noise&3]); + ImGui::TableNextColumn(); + ImGui::TableNextColumn(); + if (fmPreviewOn) { + drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + if (!fmPreviewPaused) { + renderFMPreview(ins,1); + WAKE_UP; + } + } else { + drawESFMAlgorithm(ins->esfm, ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); + } + kvsConfig(ins); + } + default: + break; + } + ImGui::EndTable(); + } + + if (((ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL) && ins->fm.opllPreset==16) || ins->type==DIV_INS_OPL_DRUMS) { + ins->fm.ops=2; + P(ImGui::Checkbox("Fixed frequency mode",&ins->fm.fixedDrums)); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("when enabled, drums will be set to the specified frequencies, ignoring the note."); + } + if (ins->fm.fixedDrums) { + int block=0; + int fNum=0; + if (ImGui::BeginTable("fixedDrumSettings",3)) { + ImGui::TableNextRow(ImGuiTableRowFlags_Headers); + ImGui::TableNextColumn(); + ImGui::Text("Drum"); + ImGui::TableNextColumn(); + ImGui::Text("Block"); + ImGui::TableNextColumn(); + ImGui::Text("FreqNum"); + + DRUM_FREQ("Kick","##DBlock0","##DFreq0",ins->fm.kickFreq); + DRUM_FREQ("Snare/Hi-hat","##DBlock1","##DFreq1",ins->fm.snareHatFreq); + DRUM_FREQ("Tom/Top","##DBlock2","##DFreq2",ins->fm.tomTopFreq); + ImGui::EndTable(); + } + } + } + + bool willDisplayOps=true; + if (ins->type==DIV_INS_OPLL && ins->fm.opllPreset!=0) willDisplayOps=false; + if (!willDisplayOps && ins->type==DIV_INS_OPLL) { + ins->fm.op[1].tl&=15; + P(CWSliderScalar("Volume##TL",ImGuiDataType_U8,&ins->fm.op[1].tl,&_FIFTEEN,&_ZERO)); rightClickable + if (ins->fm.opllPreset==16) { + ImGui::Text("this volume slider only works in compatibility (non-drums) system."); + } + + // update OPLL preset preview + if (ins->fm.opllPreset>0 && ins->fm.opllPreset<16) { + const opll_patch_t* patchROM=NULL; + + switch (presentWhich) { + case 1: + patchROM=OPLL_GetPatchROM(opll_type_ymf281); + break; + case 2: + patchROM=OPLL_GetPatchROM(opll_type_ym2423); + break; + case 3: + patchROM=OPLL_GetPatchROM(opll_type_ds1001); + break; + default: + patchROM=OPLL_GetPatchROM(opll_type_ym2413); + break; + } + + const opll_patch_t* patch=&patchROM[ins->fm.opllPreset-1]; + + opllPreview.alg=ins->fm.alg; + opllPreview.fb=patch->fb; + opllPreview.fms=patch->dm; + opllPreview.ams=patch->dc; + + opllPreview.op[0].tl=patch->tl; + opllPreview.op[1].tl=ins->fm.op[1].tl; + + for (int i=0; i<2; i++) { + opllPreview.op[i].am=patch->am[i]; + opllPreview.op[i].vib=patch->vib[i]; + opllPreview.op[i].ssgEnv=patch->et[i]?8:0; + opllPreview.op[i].ksr=patch->ksr[i]; + opllPreview.op[i].mult=patch->multi[i]; + opllPreview.op[i].ar=patch->ar[i]; + opllPreview.op[i].dr=patch->dr[i]; + opllPreview.op[i].sl=patch->sl[i]; + opllPreview.op[i].rr=patch->rr[i]; + } + } + } + + ImGui::BeginDisabled(!willDisplayOps); + if (settings.fmLayout==0) { + int numCols=15; + if (ins->type==DIV_INS_OPL ||ins->type==DIV_INS_OPL_DRUMS) numCols=13; + if (ins->type==DIV_INS_OPLL) numCols=12; + if (ins->type==DIV_INS_OPZ) numCols=19; + if (ins->type==DIV_INS_ESFM) numCols=19; + if (ImGui::BeginTable("FMOperators",numCols,ImGuiTableFlags_SizingStretchProp|ImGuiTableFlags_BordersH|ImGuiTableFlags_BordersOuterV)) { + // configure columns + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed); // op name + if (ins->type==DIV_INS_ESFM) { + ImGui::TableSetupColumn("c0e0",ImGuiTableColumnFlags_WidthStretch,0.05f); // outLvl + ImGui::TableSetupColumn("c0e1",ImGuiTableColumnFlags_WidthFixed); // -separator- + ImGui::TableSetupColumn("c0e2",ImGuiTableColumnFlags_WidthStretch,0.05f); // delay + } + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.05f); // ar + ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.05f); // dr + ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthStretch,0.05f); // sl + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { + ImGui::TableSetupColumn("c4",ImGuiTableColumnFlags_WidthStretch,0.05f); // d2r + } + ImGui::TableSetupColumn("c5",ImGuiTableColumnFlags_WidthStretch,0.05f); // rr + ImGui::TableSetupColumn("c6",ImGuiTableColumnFlags_WidthFixed); // -separator- + ImGui::TableSetupColumn("c7",ImGuiTableColumnFlags_WidthStretch,0.05f); // tl + ImGui::TableSetupColumn("c8",ImGuiTableColumnFlags_WidthStretch,0.05f); // rs/ksl + if (ins->type==DIV_INS_OPZ) { + ImGui::TableSetupColumn("c8z0",ImGuiTableColumnFlags_WidthStretch,0.05f); // egs + ImGui::TableSetupColumn("c8z1",ImGuiTableColumnFlags_WidthStretch,0.05f); // rev + } + if (ins->type==DIV_INS_ESFM) { + ImGui::TableSetupColumn("c8e0",ImGuiTableColumnFlags_WidthStretch,0.05f); // outLvl + } + ImGui::TableSetupColumn("c9",ImGuiTableColumnFlags_WidthStretch,0.05f); // mult + + if (ins->type==DIV_INS_OPZ) { + ImGui::TableSetupColumn("c9z",ImGuiTableColumnFlags_WidthStretch,0.05f); // fine + } + + if (ins->type==DIV_INS_ESFM) { + ImGui::TableSetupColumn("c9e",ImGuiTableColumnFlags_WidthStretch,0.05f); // ct + } + + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM || ins->type==DIV_INS_ESFM) { + ImGui::TableSetupColumn("c10",ImGuiTableColumnFlags_WidthStretch,0.05f); // dt + } + if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { + ImGui::TableSetupColumn("c11",ImGuiTableColumnFlags_WidthStretch,0.05f); // dt2 + } + ImGui::TableSetupColumn("c15",ImGuiTableColumnFlags_WidthFixed); // am + + ImGui::TableSetupColumn("c12",ImGuiTableColumnFlags_WidthFixed); // -separator- + if (ins->type!=DIV_INS_OPLL && ins->type!=DIV_INS_OPM) { + ImGui::TableSetupColumn("c13",ImGuiTableColumnFlags_WidthStretch,0.2f); // ssg/waveform + } + ImGui::TableSetupColumn("c14",ImGuiTableColumnFlags_WidthStretch,0.3f); // env + + // header + ImGui::TableNextRow(ImGuiTableRowFlags_Headers); + ImGui::TableNextColumn(); + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextColumn(); + CENTER_TEXT(ESFM_SHORT_NAME(ESFM_MODIN)); + ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_MODIN)); + TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_MODIN)); + ImGui::TableNextColumn(); + ImGui::TableNextColumn(); + CENTER_TEXT(ESFM_SHORT_NAME(ESFM_DELAY)); + ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DELAY)); + TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_DELAY)); + } + ImGui::TableNextColumn(); + CENTER_TEXT(FM_SHORT_NAME(FM_AR)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR)); + TOOLTIP_TEXT(FM_NAME(FM_AR)); + ImGui::TableNextColumn(); + CENTER_TEXT(FM_SHORT_NAME(FM_DR)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_DR)); + TOOLTIP_TEXT(FM_NAME(FM_DR)); + if (settings.susPosition==0) { + ImGui::TableNextColumn(); + CENTER_TEXT(FM_SHORT_NAME(FM_SL)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL)); + TOOLTIP_TEXT(FM_NAME(FM_SL)); + } + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { + ImGui::TableNextColumn(); + CENTER_TEXT(FM_SHORT_NAME(FM_D2R)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_D2R)); + TOOLTIP_TEXT(FM_NAME(FM_D2R)); + } + ImGui::TableNextColumn(); + CENTER_TEXT(FM_SHORT_NAME(FM_RR)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_RR)); + TOOLTIP_TEXT(FM_NAME(FM_RR)); + if (settings.susPosition==1) { + ImGui::TableNextColumn(); + CENTER_TEXT(FM_SHORT_NAME(FM_SL)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL)); + TOOLTIP_TEXT(FM_NAME(FM_SL)); + } + ImGui::TableNextColumn(); + ImGui::TableNextColumn(); + CENTER_TEXT(FM_SHORT_NAME(FM_TL)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_TL)); + TOOLTIP_TEXT(FM_NAME(FM_TL)); + ImGui::TableNextColumn(); + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { + CENTER_TEXT(FM_SHORT_NAME(FM_RS)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_RS)); + TOOLTIP_TEXT(FM_NAME(FM_RS)); + } else { + CENTER_TEXT(FM_SHORT_NAME(FM_KSL)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_KSL)); + TOOLTIP_TEXT(FM_NAME(FM_KSL)); + } + if (ins->type==DIV_INS_OPZ) { + ImGui::TableNextColumn(); + CENTER_TEXT(FM_SHORT_NAME(FM_EGSHIFT)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_EGSHIFT)); + TOOLTIP_TEXT(FM_NAME(FM_EGSHIFT)); + ImGui::TableNextColumn(); + CENTER_TEXT(FM_SHORT_NAME(FM_REV)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_REV)); + TOOLTIP_TEXT(FM_NAME(FM_REV)); + } + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextColumn(); + CENTER_TEXT(ESFM_SHORT_NAME(ESFM_OUTLVL)); + ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_OUTLVL)); + TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_OUTLVL)); + } + ImGui::TableNextColumn(); + CENTER_TEXT(FM_SHORT_NAME(FM_MULT)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_MULT)); + TOOLTIP_TEXT(FM_NAME(FM_MULT)); + if (ins->type==DIV_INS_OPZ) { + ImGui::TableNextColumn(); + CENTER_TEXT(FM_SHORT_NAME(FM_FINE)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_FINE)); + TOOLTIP_TEXT(FM_NAME(FM_FINE)); + } + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextColumn(); + CENTER_TEXT(ESFM_SHORT_NAME(ESFM_CT)); + ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_CT)); + TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_CT)); + } + ImGui::TableNextColumn(); + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { + CENTER_TEXT(FM_SHORT_NAME(FM_DT)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_DT)); + TOOLTIP_TEXT(FM_NAME(FM_DT)); + ImGui::TableNextColumn(); + } + if (ins->type==DIV_INS_ESFM) { + CENTER_TEXT(ESFM_SHORT_NAME(ESFM_DT)); + ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DT)); + TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_DT)); + ImGui::TableNextColumn(); + } + if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { + CENTER_TEXT(FM_SHORT_NAME(FM_DT2)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_DT2)); + TOOLTIP_TEXT(FM_NAME(FM_DT2)); + ImGui::TableNextColumn(); + } + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM) { + CENTER_TEXT(FM_SHORT_NAME(FM_AM)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_AM)); + TOOLTIP_TEXT(FM_NAME(FM_AM)); + } else { + CENTER_TEXT("Other"); + ImGui::TextUnformatted("Other"); + } + ImGui::TableNextColumn(); + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) { + ImGui::TableNextColumn(); + CENTER_TEXT(FM_NAME(FM_WS)); + ImGui::TextUnformatted(FM_NAME(FM_WS)); + } else if (ins->type!=DIV_INS_OPLL && ins->type!=DIV_INS_OPM) { + ImGui::TableNextColumn(); + CENTER_TEXT(FM_NAME(FM_SSG)); + ImGui::TextUnformatted(FM_NAME(FM_SSG)); + } + ImGui::TableNextColumn(); + CENTER_TEXT("Envelope"); + ImGui::TextUnformatted("Envelope"); + + float sliderHeight=32.0f*dpiScale; + + for (int i=0; itype!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[i]:i]; + DivInstrumentESFM::Operator& opE=ins->esfm.op[i]; + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + + // push colors + if (settings.separateFMColors) { + bool mod=true; + if (ins->type==DIV_INS_OPL_DRUMS) { + mod=false; + } else if (ins->type==DIV_INS_ESFM) { + // this is the same as the KVS heuristic in platform/esfm.h + if (opE.outLvl==7) { + mod=false; + } else if (opE.outLvl>0) { + if (i==3) { + mod=false; + } else { + DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1]; + if (opENext.modIn==0) { + mod=false; + } else if ((opE.outLvl-opENext.modIn)>=2) { + mod=false; + } + } + } + } else if (opCount==4) { + if (ins->type==DIV_INS_OPL) { + if (opIsOutputOPL[fmOrigin.alg&3][i]) mod=false; + } else { + if (opIsOutput[fmOrigin.alg&7][i]) mod=false; + } + } else { + if (i==1 || (ins->type==DIV_INS_OPL && (fmOrigin.alg&1))) mod=false; + } + if (mod) { + pushAccentColors( + uiColors[GUI_COLOR_FM_PRIMARY_MOD], + uiColors[GUI_COLOR_FM_SECONDARY_MOD], + uiColors[GUI_COLOR_FM_BORDER_MOD], + uiColors[GUI_COLOR_FM_BORDER_SHADOW_MOD] + ); + } else { + pushAccentColors( + uiColors[GUI_COLOR_FM_PRIMARY_CAR], + uiColors[GUI_COLOR_FM_SECONDARY_CAR], + uiColors[GUI_COLOR_FM_BORDER_CAR], + uiColors[GUI_COLOR_FM_BORDER_SHADOW_CAR] + ); + } + } + + if (i==0) { + sliderHeight=(ImGui::GetContentRegionAvail().y/opCount)-ImGui::GetStyle().ItemSpacing.y; + float sliderMinHeightOPL=ImGui::GetFrameHeight()*4.0+ImGui::GetStyle().ItemSpacing.y*3.0; + float sliderMinHeightESFM=ImGui::GetFrameHeight()*5.0+ImGui::GetStyle().ItemSpacing.y*4.0; + if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL) && sliderHeighttype==DIV_INS_ESFM && sliderHeighttype==DIV_INS_OPL_DRUMS) { + opNameLabel=fmt::sprintf("%s",oplDrumNames[i]); + } else if (ins->type==DIV_INS_OPL && fmOrigin.opllPreset==16) { + if (i==1) { + opNameLabel="Kick"; + } else { + opNameLabel="Env"; + } + } else { + opNameLabel=fmt::sprintf("OP%d",i+1); + } + if (opsAreMutable) { + pushToggleColors(op.enable); + if (ImGui::Button(opNameLabel.c_str())) { + op.enable=!op.enable; + PARAMETER; + } + popToggleColors(); + } else { + ImGui::TextUnformatted(opNameLabel.c_str()); + } + + // drag point + OP_DRAG_POINT; + + int maxTl=127; + if (ins->type==DIV_INS_OPLL) { + if (i==1) { + maxTl=15; + } else { + maxTl=63; + } + } + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) { + maxTl=63; + } + int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM)?31:15; + bool ssgOn=op.ssgEnv&8; + bool ksrOn=op.ksr; + bool vibOn=op.vib; + bool susOn=op.sus; + bool fixedOn=opE.fixed; + unsigned char ssgEnv=op.ssgEnv&7; + + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextColumn(); + CENTER_VSLIDER; + P(CWVSliderScalar("##MODIN",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&opE.modIn,&_ZERO,&_SEVEN)); rightClickable + ImGui::TableNextColumn(); + ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale)); + ImGui::TableNextColumn(); + opE.delay&=7; + CENTER_VSLIDER; + P(CWVSliderScalar("##DELAY",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&opE.delay,&_ZERO,&_SEVEN)); rightClickable + } + + ImGui::TableNextColumn(); + op.ar&=maxArDr; + CENTER_VSLIDER; + P(CWVSliderScalar("##AR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.ar,&maxArDr,&_ZERO)); rightClickable + + ImGui::TableNextColumn(); + op.dr&=maxArDr; + CENTER_VSLIDER; + P(CWVSliderScalar("##DR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dr,&maxArDr,&_ZERO)); rightClickable + + if (settings.susPosition==0) { + ImGui::TableNextColumn(); + op.sl&=15; + CENTER_VSLIDER; + P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable + } + + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { + ImGui::TableNextColumn(); + op.d2r&=31; + CENTER_VSLIDER; + P(CWVSliderScalar("##D2R",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.d2r,&_THIRTY_ONE,&_ZERO)); rightClickable + } + + ImGui::TableNextColumn(); + op.rr&=15; + CENTER_VSLIDER; + P(CWVSliderScalar("##RR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.rr,&_FIFTEEN,&_ZERO)); rightClickable + + if (settings.susPosition==1) { + ImGui::TableNextColumn(); + op.sl&=15; + CENTER_VSLIDER; + P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable + } + + ImGui::TableNextColumn(); + ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale)); + + ImGui::TableNextColumn(); + op.tl&=maxTl; + CENTER_VSLIDER; + P(CWVSliderScalar("##TL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); rightClickable + + ImGui::TableNextColumn(); + CENTER_VSLIDER; + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { + P(CWVSliderScalar("##RS",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE)); rightClickable + } else { + int ksl=ins->type==DIV_INS_OPLL?op.ksl:kslMap[op.ksl&3]; + if (CWVSliderInt("##KSL",ImVec2(20.0f*dpiScale,sliderHeight),&ksl,0,3)) { + op.ksl=(ins->type==DIV_INS_OPLL?ksl:kslMap[ksl&3]); + PARAMETER; + } rightClickable + } + + if (ins->type==DIV_INS_OPZ) { + ImGui::TableNextColumn(); + CENTER_VSLIDER; + P(CWVSliderScalar("##EGS",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE)); rightClickable + + ImGui::TableNextColumn(); + CENTER_VSLIDER; + P(CWVSliderScalar("##REV",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dam,&_ZERO,&_SEVEN)); rightClickable + } + + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextColumn(); + CENTER_VSLIDER; + P(CWVSliderScalar("##OUTLVL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&opE.outLvl,&_ZERO,&_SEVEN)); rightClickable + } + + ImGui::TableNextColumn(); + CENTER_VSLIDER; + P(CWVSliderScalar("##MULT",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN)); rightClickable + + if (ins->type==DIV_INS_OPZ) { + ImGui::TableNextColumn(); + CENTER_VSLIDER; + P(CWVSliderScalar("##FINE",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dvb,&_ZERO,&_FIFTEEN)); rightClickable + } + + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextColumn(); + CENTER_VSLIDER; + P(CWVSliderScalar("##CT",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_S8,&opE.ct,&_MINUS_TWENTY_FOUR,&_TWENTY_FOUR)); rightClickable + } + + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { + int detune=detuneMap[settings.unsignedDetune?1:0][op.dt&7]; + ImGui::TableNextColumn(); + CENTER_VSLIDER; + if (CWVSliderInt("##DT",ImVec2(20.0f*dpiScale,sliderHeight),&detune,settings.unsignedDetune?0:-3,settings.unsignedDetune?7:4)) { PARAMETER + if (detune<-3) detune=-3; + if (detune>7) detune=7; + op.dt=detuneUnmap[settings.unsignedDetune?1:0][detune+3]; + } rightClickable + + if (ins->type!=DIV_INS_FM) { + ImGui::TableNextColumn(); + CENTER_VSLIDER; + P(CWVSliderScalar("##DT2",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE)); rightClickable + } + + ImGui::TableNextColumn(); + bool amOn=op.am; + if (ins->type==DIV_INS_OPZ) { + bool egtOn=op.egt; + if (egtOn) { + ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight()*4.0-ImGui::GetStyle().ItemSpacing.y*3.0)); + } else { + ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight()*2.0-ImGui::GetStyle().ItemSpacing.y*1.0)); + } + if (ImGui::Checkbox("AM",&amOn)) { PARAMETER + op.am=amOn; + } + if (ImGui::Checkbox("Fixed",&egtOn)) { PARAMETER + op.egt=egtOn; + } + if (egtOn) { + int block=op.dt; + int freqNum=(op.mult<<4)|(op.dvb&15); + if (ImGui::InputInt("Block",&block,1,1)) { + if (block<0) block=0; + if (block>7) block=7; + op.dt=block; + } + if (ImGui::InputInt("FreqNum",&freqNum,1,16)) { + if (freqNum<0) freqNum=0; + if (freqNum>255) freqNum=255; + op.mult=freqNum>>4; + op.dvb=freqNum&15; + } + } + } else { + ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight())); + if (ImGui::Checkbox("##AM",&amOn)) { PARAMETER + op.am=amOn; + } + } + + if (ins->type!=DIV_INS_OPL && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_OPZ && ins->type!=DIV_INS_OPM) { + ImGui::TableNextColumn(); + ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale)); + ImGui::TableNextColumn(); + ImGui::BeginDisabled(!ssgOn); + drawSSGEnv(op.ssgEnv&7,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight-ImGui::GetFrameHeightWithSpacing())); + ImGui::EndDisabled(); + if (ImGui::Checkbox("##SSGOn",&ssgOn)) { PARAMETER + op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3); + } + + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (CWSliderScalar("##SSG",ImGuiDataType_U8,&ssgEnv,&_ZERO,&_SEVEN,ssgEnvTypes[ssgEnv])) { PARAMETER + op.ssgEnv=(op.ssgEnv&8)|(ssgEnv&7); + } + } + } else if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextColumn(); + CENTER_VSLIDER; + P(CWVSliderScalar("##DT",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_S8,&opE.dt,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN)); rightClickable + + ImGui::TableNextColumn(); + bool amOn=op.am; + bool leftOn=opE.left; + bool rightOn=opE.right; + + ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight()*5.0-ImGui::GetStyle().ItemSpacing.y*4.0)); + ImVec2 curPosBeforeDummy = ImGui::GetCursorPos(); + ImGui::Dummy(ImVec2(ImGui::GetFrameHeightWithSpacing()*2.0f+ImGui::CalcTextSize(FM_SHORT_NAME(FM_DAM)).x*2.0f,1.0f)); + ImGui::SetCursorPos(curPosBeforeDummy); + + if (ImGui::BeginTable("panCheckboxes",(fixedOn)?3:2,ImGuiTableFlags_SizingStretchProp)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,1.0); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,1.0); + if (fixedOn) { + ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,1.2); + } + + float yCoordBeforeTablePadding=ImGui::GetCursorPosY(); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yCoordBeforeTablePadding); + if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_LEFT),&leftOn)) { PARAMETER + opE.left=leftOn; + } + ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yCoordBeforeTablePadding); + if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_RIGHT),&rightOn)) { PARAMETER + opE.right=rightOn; + } + if (fixedOn) { + ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yCoordBeforeTablePadding); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_AM),&amOn)) { PARAMETER + op.am=amOn; + } + } + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_KSR),&ksrOn)) { PARAMETER + op.ksr=ksrOn; + } + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_SUS),&susOn)) { PARAMETER + op.sus=susOn; + } + if (fixedOn) { + bool damOn=op.dam; + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_DAM),&damOn)) { PARAMETER + op.dam=damOn; + } + } + ImGui::EndTable(); + } + ImGui::SetCursorPosY(ImGui::GetCursorPosY()-0.5*ImGui::GetStyle().ItemSpacing.y); + if (ImGui::Checkbox(ESFM_NAME(ESFM_FIXED),&fixedOn)) { PARAMETER + opE.fixed=fixedOn; + // HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly + ins->std.opMacros[i].ssgMacro.vZoom=-1; + ins->std.opMacros[i].dtMacro.vZoom=-1; + } + if (ins->type==DIV_INS_ESFM) { + if (fixedOn) { + int block=(opE.ct>>2)&7; + int freqNum=((opE.ct&3)<<8)|((unsigned char)opE.dt); + if (ImGui::InputInt("Block",&block,1,1)) { + if (block<0) block=0; + if (block>7) block=7; + opE.ct=(opE.ct&(~(7<<2)))|(block<<2); + } + if (ImGui::InputInt("FreqNum",&freqNum,1,16)) { + if (freqNum<0) freqNum=0; + if (freqNum>1023) freqNum=1023; + opE.dt=freqNum&0xff; + opE.ct=(opE.ct&(~3))|(freqNum>>8); + } + } else { + if (ImGui::BeginTable("amVibCheckboxes",2,ImGuiTableFlags_SizingStretchSame)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0); + + float yCoordBeforeTablePadding=ImGui::GetCursorPosY(); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yCoordBeforeTablePadding); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_AM),&amOn)) { PARAMETER + op.am=amOn; + } + ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yCoordBeforeTablePadding); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_VIB),&vibOn)) { PARAMETER + op.vib=vibOn; + } + bool damOn=op.dam; + bool dvbOn=op.dvb; + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_DAM),&damOn)) { PARAMETER + op.dam=damOn; + } + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_DVB),&dvbOn)) { PARAMETER + op.dvb=dvbOn; + } + ImGui::EndTable(); + } + } + } + } else if (ins->type!=DIV_INS_OPM) { + ImGui::TableNextColumn(); + bool amOn=op.am; + ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight()*4.0-ImGui::GetStyle().ItemSpacing.y*3.0)); + if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER + op.am=amOn; + } + if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER + op.vib=vibOn; + } + if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER + op.ksr=ksrOn; + } + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) { + if (ImGui::Checkbox(FM_NAME(FM_SUS),&susOn)) { PARAMETER + op.sus=susOn; + } + } else if (ins->type==DIV_INS_OPLL) { + if (ImGui::Checkbox(FM_NAME(FM_EGS),&ssgOn)) { PARAMETER + op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3); + } + } + } + + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) { + ImGui::TableNextColumn(); + ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale)); + ImGui::TableNextColumn(); + + drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight-ImGui::GetFrameHeightWithSpacing()*((ins->type==DIV_INS_ESFM && fixedOn)?3.0f:1.0f))); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable + if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) { + ImGui::SetTooltip("OPL2/3 only (last 4 waveforms are OPL3 only)"); + } + if (ins->type==DIV_INS_ESFM && fixedOn) { + if (ImGui::Checkbox(FM_SHORT_NAME(FM_VIB),&vibOn)) { PARAMETER + op.vib=vibOn; + } + bool dvbOn=op.dvb; + if (ImGui::Checkbox(FM_SHORT_NAME(FM_DVB),&dvbOn)) { PARAMETER + op.dvb=dvbOn; + } + } + } else if (ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPM) { + ImGui::TableNextColumn(); + ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale)); + } + + ImGui::TableNextColumn(); + drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_ESFM)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight),ins->type); + + if (settings.separateFMColors) { + popAccentColors(); + } + + ImGui::PopID(); + } + + ImGui::EndTable(); + } + } else if (settings.fmLayout>=4 && settings.fmLayout<=6) { // alternate + int columns=2; + switch (settings.fmLayout) { + case 4: // 2x2 + columns=2; + break; + case 5: // 1x4 + columns=1; + break; + case 6: // 4x1 + columns=opCount; + break; + } + char tempID[1024]; + ImVec2 oldPadding=ImGui::GetStyle().CellPadding; + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding,ImVec2(8.0f*dpiScale,4.0f*dpiScale)); + if (ImGui::BeginTable("AltFMOperators",columns,ImGuiTableFlags_SizingStretchSame|ImGuiTableFlags_BordersInner)) { + for (int i=0; itype!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[i]:i]; + DivInstrumentESFM::Operator& opE=ins->esfm.op[i]; + if ((settings.fmLayout!=6 && ((i+1)&1)) || i==0 || settings.fmLayout==5) ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::PushID(fmt::sprintf("op%d",i).c_str()); + + // push colors + if (settings.separateFMColors) { + bool mod=true; + if (ins->type==DIV_INS_OPL_DRUMS) { + mod=false; + } else if (ins->type==DIV_INS_ESFM) { + // this is the same as the KVS heuristic in platform/esfm.h + if (opE.outLvl==7) mod=false; + else if (opE.outLvl>0) { + if (i==3) mod=false; + else { + DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1]; + if (opENext.modIn==0) mod=false; + else if ((opE.outLvl-opENext.modIn)>=2) mod=false; + } + } + } else if (opCount==4) { + if (ins->type==DIV_INS_OPL) { + if (opIsOutputOPL[fmOrigin.alg&3][i]) mod=false; + } else { + if (opIsOutput[fmOrigin.alg&7][i]) mod=false; + } + } else { + if (i==1 || (ins->type==DIV_INS_OPL && (fmOrigin.alg&1))) mod=false; + } + if (mod) { + pushAccentColors( + uiColors[GUI_COLOR_FM_PRIMARY_MOD], + uiColors[GUI_COLOR_FM_SECONDARY_MOD], + uiColors[GUI_COLOR_FM_BORDER_MOD], + uiColors[GUI_COLOR_FM_BORDER_SHADOW_MOD] + ); + } else { + pushAccentColors( + uiColors[GUI_COLOR_FM_PRIMARY_CAR], + uiColors[GUI_COLOR_FM_SECONDARY_CAR], + uiColors[GUI_COLOR_FM_BORDER_CAR], + uiColors[GUI_COLOR_FM_BORDER_SHADOW_CAR] + ); + } + } + + ImGui::Dummy(ImVec2(dpiScale,dpiScale)); + if (ins->type==DIV_INS_OPL_DRUMS) { + snprintf(tempID,1024,"%s",oplDrumNames[i]); + } else if (ins->type==DIV_INS_OPL && fmOrigin.opllPreset==16) { + if (i==1) { + snprintf(tempID,1024,"Envelope 2 (kick only)"); + } else { + snprintf(tempID,1024,"Envelope"); + } + } else { + snprintf(tempID,1024,"Operator %d",i+1); + } + float nextCursorPosX=ImGui::GetCursorPosX()+0.5*(ImGui::GetContentRegionAvail().x-ImGui::CalcTextSize(tempID).x-(opsAreMutable?(ImGui::GetStyle().FramePadding.x*2.0f):0.0f)); + OP_DRAG_POINT; + ImGui::SameLine(); + ImGui::SetCursorPosX(nextCursorPosX); + if (opsAreMutable) { + pushToggleColors(op.enable); + if (ImGui::Button(tempID)) { + op.enable=!op.enable; + PARAMETER; + } + popToggleColors(); + } else { + ImGui::TextUnformatted(tempID); + } + + float sliderHeight=200.0f*dpiScale; + float waveWidth=140.0*dpiScale*((ins->type==DIV_INS_ESFM)?0.85f:1.0f); + float waveHeight=sliderHeight-ImGui::GetFrameHeightWithSpacing()*((ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPL || ins->type==DIV_INS_ESFM)?5.0f:4.5f); + + int maxTl=127; + if (ins->type==DIV_INS_OPLL) { + if (i==1) { + maxTl=15; + } else { + maxTl=63; + } + } + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) { + maxTl=63; + } + int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM)?31:15; + + bool ssgOn=op.ssgEnv&8; + bool ksrOn=op.ksr; + bool vibOn=op.vib; + bool egtOn=op.egt; + bool susOn=op.sus; // yawn + unsigned char ssgEnv=op.ssgEnv&7; + + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding,oldPadding); + if (ImGui::BeginTable("opParams",4,ImGuiTableFlags_BordersInnerV)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,waveWidth); + ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthFixed); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + float textY=ImGui::GetCursorPosY(); + if (ins->type==DIV_INS_ESFM) { + CENTER_TEXT_20(ESFM_SHORT_NAME(ESFM_DELAY)); + ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DELAY)); + TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_DELAY)); + } else { + CENTER_TEXT_20(FM_SHORT_NAME(FM_AR)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR)); + TOOLTIP_TEXT(FM_NAME(FM_AR)); + } + ImGui::TableNextColumn(); + if (ins->type==DIV_INS_FM) { + ImGui::Text("SSG-EG"); + } else { + ImGui::Text("Waveform"); + } + ImGui::TableNextColumn(); + ImGui::Text("Envelope"); + ImGui::TableNextColumn(); + + // A/D/S/R + ImGui::TableNextColumn(); + + if (ins->type==DIV_INS_ESFM) { + opE.delay&=7; + P(CWVSliderScalar("##DELAY",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&opE.delay,&_ZERO,&_SEVEN)); rightClickable + ImGui::SameLine(); + } + + op.ar&=maxArDr; + float textX_AR=ImGui::GetCursorPosX(); + P(CWVSliderScalar("##AR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.ar,&maxArDr,&_ZERO)); rightClickable + + ImGui::SameLine(); + op.dr&=maxArDr; + float textX_DR=ImGui::GetCursorPosX(); + P(CWVSliderScalar("##DR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dr,&maxArDr,&_ZERO)); rightClickable + + float textX_SL=0.0f; + if (settings.susPosition==0) { + ImGui::SameLine(); + op.sl&=15; + textX_SL=ImGui::GetCursorPosX(); + P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable + } + + float textX_D2R=0.0f; + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { + ImGui::SameLine(); + op.d2r&=31; + textX_D2R=ImGui::GetCursorPosX(); + P(CWVSliderScalar("##D2R",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.d2r,&_THIRTY_ONE,&_ZERO)); rightClickable + } + + ImGui::SameLine(); + op.rr&=15; + float textX_RR=ImGui::GetCursorPosX(); + P(CWVSliderScalar("##RR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.rr,&_FIFTEEN,&_ZERO)); rightClickable + + if (settings.susPosition==1) { + ImGui::SameLine(); + op.sl&=15; + textX_SL=ImGui::GetCursorPosX(); + P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable + } + + ImVec2 prevCurPos=ImGui::GetCursorPos(); + + // labels + if (ins->type==DIV_INS_ESFM) { + ImGui::SetCursorPos(ImVec2(textX_AR,textY)); + CENTER_TEXT_20(FM_SHORT_NAME(FM_AR)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR)); + TOOLTIP_TEXT(FM_NAME(FM_AR)); + } + + ImGui::SetCursorPos(ImVec2(textX_DR,textY)); + CENTER_TEXT_20(FM_SHORT_NAME(FM_DR)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_DR)); + TOOLTIP_TEXT(FM_NAME(FM_DR)); + + ImGui::SetCursorPos(ImVec2(textX_SL,textY)); + CENTER_TEXT_20(FM_SHORT_NAME(FM_SL)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL)); + TOOLTIP_TEXT(FM_NAME(FM_SL)); + + ImGui::SetCursorPos(ImVec2(textX_RR,textY)); + CENTER_TEXT_20(FM_SHORT_NAME(FM_RR)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_RR)); + TOOLTIP_TEXT(FM_NAME(FM_RR)); + + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { + ImGui::SetCursorPos(ImVec2(textX_D2R,textY)); + CENTER_TEXT_20(FM_SHORT_NAME(FM_D2R)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_D2R)); + TOOLTIP_TEXT(FM_NAME(FM_D2R)); + } + + ImGui::SetCursorPos(prevCurPos); + + ImGui::TableNextColumn(); + switch (ins->type) { + case DIV_INS_FM: { + // SSG + ImGui::BeginDisabled(!ssgOn); + drawSSGEnv(op.ssgEnv&7,ImVec2(waveWidth,waveHeight)); + ImGui::EndDisabled(); + if (ImGui::Checkbox("##SSGOn",&ssgOn)) { PARAMETER + op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3); + } + + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (CWSliderScalar("##SSG",ImGuiDataType_U8,&ssgEnv,&_ZERO,&_SEVEN,ssgEnvTypes[ssgEnv])) { PARAMETER + op.ssgEnv=(op.ssgEnv&8)|(ssgEnv&7); + } + + // params + ImGui::Separator(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT)); + P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable + + int detune=detuneMap[settings.unsignedDetune?1:0][op.dt&7]; + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT)); + if (CWSliderInt("##DT",&detune,settings.unsignedDetune?0:-3,settings.unsignedDetune?7:4,tempID)) { PARAMETER + if (detune<-3) detune=-3; + if (detune>7) detune=7; + op.dt=detuneUnmap[settings.unsignedDetune?1:0][detune+3]; + } rightClickable + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_RS)); + P(CWSliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE,tempID)); rightClickable + + break; + } + case DIV_INS_OPM: { + drawWaveform(0,true,ImVec2(waveWidth,waveHeight)); + + // params + ImGui::Separator(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT)); + P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable + + int detune=detuneMap[settings.unsignedDetune?1:0][op.dt&7]; + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT)); + if (CWSliderInt("##DT",&detune,settings.unsignedDetune?0:-3,settings.unsignedDetune?7:4,tempID)) { PARAMETER + if (detune<-3) detune=-3; + if (detune>7) detune=7; + op.dt=detuneUnmap[settings.unsignedDetune?1:0][detune+3]; + } rightClickable + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT2)); + P(CWSliderScalar("##DT2",ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE,tempID)); rightClickable + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_RS)); + P(CWSliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE,tempID)); rightClickable + break; + } + case DIV_INS_OPLL: + // waveform + drawWaveform(i==0?(fmOrigin.ams&1):(fmOrigin.fms&1),ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight)); + + // params + ImGui::Separator(); + if (ImGui::BeginTable("FMParamsInner",2)) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + bool amOn=op.am; + if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER + op.am=amOn; + } + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER + op.ksr=ksrOn; + } + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER + op.vib=vibOn; + } + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_NAME(FM_EGS),&ssgOn)) { PARAMETER + op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3); + } + + ImGui::EndTable(); + } + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT)); + P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_KSL)); + P(CWSliderScalar("##KSL",ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE,tempID)); rightClickable + + break; + case DIV_INS_OPL: + case DIV_INS_OPL_DRUMS: { + // waveform + drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight)); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable + if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) { + ImGui::SetTooltip("OPL2/3 only (last 4 waveforms are OPL3 only)"); + } + + // params + ImGui::Separator(); + if (ImGui::BeginTable("FMParamsInner",2)) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + bool amOn=op.am; + if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER + op.am=amOn; + } + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER + op.ksr=ksrOn; + } + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER + op.vib=vibOn; + } + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_NAME(FM_SUS),&susOn)) { PARAMETER + op.sus=susOn; + } + + ImGui::EndTable(); + } + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT)); + P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_KSL)); + int ksl=kslMap[op.ksl&3]; + if (CWSliderInt("##KSL",&ksl,0,3,tempID)) { + op.ksl=kslMap[ksl&3]; + PARAMETER; + } rightClickable + + break; + } + case DIV_INS_OPZ: { + // waveform + drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight)); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable + if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) { + ImGui::SetTooltip("OPL2/3 only (last 4 waveforms are OPL3 only)"); + } + + // params + ImGui::Separator(); + if (egtOn) { + int block=op.dt; + int freqNum=(op.mult<<4)|(op.dvb&15); + ImGui::Text("Block"); + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + ImVec2 cursorAlign=ImGui::GetCursorPos(); + if (ImGui::InputInt("##Block",&block,1,1)) { + if (block<0) block=0; + if (block>7) block=7; + op.dt=block; + } + + ImGui::Text("Freq"); + ImGui::SameLine(); + ImGui::SetCursorPos(ImVec2(cursorAlign.x,ImGui::GetCursorPosY())); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (ImGui::InputInt("##FreqNum",&freqNum,1,16)) { + if (freqNum<0) freqNum=0; + if (freqNum>255) freqNum=255; + op.mult=freqNum>>4; + op.dvb=freqNum&15; + } + } else { + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT)); + P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable + + int detune=detuneMap[settings.unsignedDetune?1:0][op.dt&7]; + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT)); + if (CWSliderInt("##DT",&detune,settings.unsignedDetune?0:-3,settings.unsignedDetune?7:4,tempID)) { PARAMETER + if (detune<-3) detune=-3; + if (detune>7) detune=7; + op.dt=detuneUnmap[settings.unsignedDetune?1:0][detune+3]; + } rightClickable + } + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT2)); + P(CWSliderScalar("##DT2",ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE,tempID)); rightClickable + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Only on YM2151 (OPM)"); + } + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_RS)); + P(CWSliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE,tempID)); rightClickable + break; + } + case DIV_INS_ESFM: + // waveform + drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight)); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable + + // params + ImGui::Separator(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT)); + P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable + + if (opE.fixed) { + int block=(opE.ct>>2)&7; + int freqNum=((opE.ct&3)<<8)|((unsigned char)opE.dt); + ImGui::Text("Blk"); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Block"); + } + ImGui::SameLine(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + //ImVec2 cursorAlign=ImGui::GetCursorPos(); + if (ImGui::InputInt("##Block",&block,1,1)) { + if (block<0) block=0; + if (block>7) block=7; + opE.ct=(opE.ct&(~(7<<2)))|(block<<2); + } + + ImGui::Text("F"); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("Frequency (F-Num)"); + } + ImGui::SameLine(); + //ImGui::SetCursorPos(ImVec2(cursorAlign.x,ImGui::GetCursorPosY())); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (ImGui::InputInt("##FreqNum",&freqNum,1,16)) { + if (freqNum<0) freqNum=0; + if (freqNum>1023) freqNum=1023; + opE.dt=freqNum&0xff; + opE.ct=(opE.ct&(~3))|(freqNum>>8); + } + } else { + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",ESFM_NAME(ESFM_CT)); + P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWENTY_FOUR,&_TWENTY_FOUR,tempID)); rightClickable + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",ESFM_NAME(ESFM_DT)); + P(CWSliderScalar("##DT",ImGuiDataType_S8,&opE.dt,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN,tempID)); rightClickable + } + + if (ImGui::BeginTable("panCheckboxes",2,ImGuiTableFlags_SizingStretchSame)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0f); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0f); + + float yPosOutsideTablePadding=ImGui::GetCursorPosY(); + bool leftOn=opE.left; + bool rightOn=opE.right; + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yPosOutsideTablePadding); + if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_LEFT),&leftOn)) { PARAMETER + opE.left=leftOn; + } + ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yPosOutsideTablePadding); + if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_RIGHT),&rightOn)) { PARAMETER + opE.right=rightOn; + } + ImGui::EndTable(); + } + break; + default: + break; + } + + ImGui::TableNextColumn(); + float envHeight=sliderHeight;//-ImGui::GetStyle().ItemSpacing.y*2.0f; + if (ins->type==DIV_INS_OPZ) { + envHeight-=ImGui::GetFrameHeightWithSpacing()*2.0f; + } + if (ins->type==DIV_INS_ESFM) { + envHeight-=ImGui::GetFrameHeightWithSpacing()*3.0f; + } + drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_ESFM)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,envHeight),ins->type); + + if (ins->type==DIV_INS_OPZ) { + ImGui::Separator(); + if (ImGui::BeginTable("FMParamsInnerOPZ",2)) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + if (!egtOn) { + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_FINE)); + P(CWSliderScalar("##FINE",ImGuiDataType_U8,&op.dvb,&_ZERO,&_FIFTEEN,tempID)); rightClickable + } + + ImGui::TableNextColumn(); + bool amOn=op.am; + if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER + op.am=amOn; + } + ImGui::SameLine(); + if (ImGui::Checkbox("Fixed",&egtOn)) { PARAMETER + op.egt=egtOn; + } + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_EGSHIFT)); + P(CWSliderScalar("##EGShift",ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE,tempID)); rightClickable + + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_REV)); + P(CWSliderScalar("##REV",ImGuiDataType_U8,&op.dam,&_ZERO,&_SEVEN,tempID)); rightClickable + + ImGui::TableNextColumn(); + + + ImGui::EndTable(); + } + } + + if (ins->type==DIV_INS_ESFM) { + ImGui::Separator(); + if (ImGui::BeginTable("FMParamsInnerESFM",2)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.64f); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.36f); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_KSL)); + int ksl=kslMap[op.ksl&3]; + if (CWSliderInt("##KSL",&ksl,0,3,tempID)) { + op.ksl=kslMap[ksl&3]; + PARAMETER; + } rightClickable + + bool amOn=op.am; + bool fixedOn=opE.fixed; + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_KSR),&ksrOn)) { PARAMETER + op.ksr=ksrOn; + } + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + if (ImGui::BeginTable("vibAmCheckboxes",2)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0f); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0f); + + float yPosOutsideTablePadding=ImGui::GetCursorPosY(); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yPosOutsideTablePadding); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_VIB),&vibOn)) { PARAMETER + op.vib=vibOn; + } + ImGui::TableNextColumn(); + ImGui::SetCursorPosY(yPosOutsideTablePadding); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_AM),&amOn)) { PARAMETER + op.am=amOn; + } + + bool damOn=op.dam; + bool dvbOn=op.dvb; + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_DVB),&dvbOn)) { PARAMETER + op.dvb=dvbOn; + } + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_DAM),&damOn)) { PARAMETER + op.dam=damOn; + } + ImGui::EndTable(); + } + ImGui::TableNextColumn(); + if (ImGui::Checkbox(FM_SHORT_NAME(FM_SUS),&susOn)) { PARAMETER + op.sus=susOn; + } + if (ImGui::Checkbox(ESFM_NAME(ESFM_FIXED),&fixedOn)) { PARAMETER + opE.fixed=fixedOn; + // HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly + ins->std.opMacros[i].ssgMacro.vZoom=-1; + ins->std.opMacros[i].dtMacro.vZoom=-1; + } + + ImGui::EndTable(); + } + } + + ImGui::TableNextColumn(); + op.tl&=maxTl; + float tlSliderWidth=(ins->type==DIV_INS_ESFM)?20.0f*dpiScale:ImGui::GetFrameHeight(); + float tlSliderHeight=sliderHeight-((ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM)?(ImGui::GetFrameHeightWithSpacing()+ImGui::CalcTextSize(FM_SHORT_NAME(FM_AM)).y+ImGui::GetStyle().ItemSpacing.y):0.0f); + float textX_tl=ImGui::GetCursorPosX(); + P(CWVSliderScalar("##TL",ImVec2(tlSliderWidth,tlSliderHeight),ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); rightClickable + + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM) { + CENTER_TEXT(FM_SHORT_NAME(FM_AM)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_AM)); + TOOLTIP_TEXT(FM_NAME(FM_AM)); + bool amOn=op.am; + if (ImGui::Checkbox("##AM",&amOn)) { PARAMETER + op.am=amOn; + } + } + + if (ins->type==DIV_INS_ESFM) { + ImGui::SameLine(); + float textX_outLvl=ImGui::GetCursorPosX(); + P(CWVSliderScalar("##OUTLVL",ImVec2(tlSliderWidth,tlSliderHeight),ImGuiDataType_U8,&opE.outLvl,&_ZERO,&_SEVEN)); rightClickable + + ImGui::SameLine(); + float textX_modIn=ImGui::GetCursorPosX(); + P(CWVSliderScalar("##MODIN",ImVec2(tlSliderWidth,tlSliderHeight),ImGuiDataType_U8,&opE.modIn,&_ZERO,&_SEVEN)); rightClickable + + prevCurPos=ImGui::GetCursorPos(); + ImGui::SetCursorPos(ImVec2(textX_tl,textY)); + CENTER_TEXT_20(FM_SHORT_NAME(FM_TL)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_TL)); + TOOLTIP_TEXT(FM_NAME(FM_TL)); + + ImGui::SetCursorPos(ImVec2(textX_outLvl,textY)); + CENTER_TEXT_20(ESFM_SHORT_NAME(ESFM_OUTLVL)); + ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_OUTLVL)); + TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_OUTLVL)); + + ImGui::SetCursorPos(ImVec2(textX_modIn,textY)); + CENTER_TEXT_20(ESFM_SHORT_NAME(ESFM_MODIN)); + ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_MODIN)); + TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_MODIN)); + + ImGui::SetCursorPos(prevCurPos); + } else { + prevCurPos=ImGui::GetCursorPos(); + ImGui::SetCursorPos(ImVec2(textX_tl,textY)); + CENTER_TEXT(FM_SHORT_NAME(FM_TL)); + ImGui::TextUnformatted(FM_SHORT_NAME(FM_TL)); + TOOLTIP_TEXT(FM_NAME(FM_TL)); + + ImGui::SetCursorPos(prevCurPos); + } + + ImGui::EndTable(); + } + ImGui::PopStyleVar(); + + if (settings.separateFMColors) { + popAccentColors(); + } + + ImGui::PopID(); + } + ImGui::EndTable(); + } + ImGui::PopStyleVar(); + } else { // classic + int columns=2; + switch (settings.fmLayout) { + case 1: // 2x2 + columns=2; + break; + case 2: // 1x4 + columns=1; + break; + case 3: // 4x1 + columns=opCount; + break; + } + if (ImGui::BeginTable("FMOperators",columns,ImGuiTableFlags_SizingStretchSame)) { + for (int i=0; itype!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[i]:i]; + DivInstrumentESFM::Operator& opE=ins->esfm.op[i]; + if ((settings.fmLayout!=3 && ((i+1)&1)) || i==0 || settings.fmLayout==2) ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Separator(); + ImGui::PushID(fmt::sprintf("op%d",i).c_str()); + + // push colors + if (settings.separateFMColors) { + bool mod=true; + if (ins->type==DIV_INS_OPL_DRUMS) { + mod=false; + } else if (ins->type==DIV_INS_ESFM) { + // this is the same as the KVS heuristic in platform/esfm.h + if (opE.outLvl==7) { + mod=false; + } else if (opE.outLvl>0) { + if (i==3) { + mod=false; + } else { + DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1]; + if (opENext.modIn==0) { + mod=false; + } else if ((opE.outLvl-opENext.modIn)>=2) { + mod=false; + } + } + } + } else if (opCount==4) { + if (ins->type==DIV_INS_OPL) { + if (opIsOutputOPL[fmOrigin.alg&3][i]) mod=false; + } else { + if (opIsOutput[fmOrigin.alg&7][i]) mod=false; + } + } else { + if (i==1 || (ins->type==DIV_INS_OPL && (fmOrigin.alg&1))) mod=false; + } + if (mod) { + pushAccentColors( + uiColors[GUI_COLOR_FM_PRIMARY_MOD], + uiColors[GUI_COLOR_FM_SECONDARY_MOD], + uiColors[GUI_COLOR_FM_BORDER_MOD], + uiColors[GUI_COLOR_FM_BORDER_SHADOW_MOD] + ); + } else { + pushAccentColors( + uiColors[GUI_COLOR_FM_PRIMARY_CAR], + uiColors[GUI_COLOR_FM_SECONDARY_CAR], + uiColors[GUI_COLOR_FM_BORDER_CAR], + uiColors[GUI_COLOR_FM_BORDER_SHADOW_CAR] + ); + } + } + + ImGui::Dummy(ImVec2(dpiScale,dpiScale)); + String opNameLabel; + OP_DRAG_POINT; + ImGui::SameLine(); + if (ins->type==DIV_INS_OPL_DRUMS) { + opNameLabel=fmt::sprintf("%s",oplDrumNames[i]); + } else if (ins->type==DIV_INS_OPL && fmOrigin.opllPreset==16) { + if (i==1) { + opNameLabel="Envelope 2 (kick only)"; + } else { + opNameLabel="Envelope"; + } + } else { + opNameLabel=fmt::sprintf("OP%d",i+1); + } + if (opsAreMutable) { + pushToggleColors(op.enable); + if (ImGui::Button(opNameLabel.c_str())) { + op.enable=!op.enable; + PARAMETER; + } + popToggleColors(); + } else { + ImGui::TextUnformatted(opNameLabel.c_str()); + } + + ImGui::SameLine(); + + bool amOn=op.am; + if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER + op.am=amOn; + } + + int maxTl=127; + if (ins->type==DIV_INS_OPLL) { + if (i==1) { + maxTl=15; + } else { + maxTl=63; + } + } + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) { + maxTl=63; + } + int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM)?31:15; + + bool ssgOn=op.ssgEnv&8; + bool ksrOn=op.ksr; + bool vibOn=op.vib; + bool susOn=op.sus; // don't you make fun of this one + unsigned char ssgEnv=op.ssgEnv&7; + if (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) { + ImGui::SameLine(); + if (ImGui::Checkbox((ins->type==DIV_INS_OPLL)?FM_NAME(FM_EGS):"SSG On",&ssgOn)) { PARAMETER + op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3); + } + } + + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) { + ImGui::SameLine(); + if (ImGui::Checkbox(FM_NAME(FM_SUS),&susOn)) { PARAMETER + op.sus=susOn; + } + } + + if (ins->type==DIV_INS_OPZ) { + ImGui::SameLine(); + bool fixedOn=op.egt; + if (ImGui::Checkbox("Fixed",&fixedOn)) { PARAMETER + op.egt=fixedOn; + } + } + + //52.0 controls vert scaling; default 96 + drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_ESFM)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,52.0*dpiScale),ins->type); + //P(CWSliderScalar(FM_NAME(FM_AR),ImGuiDataType_U8,&op.ar,&_ZERO,&_THIRTY_ONE)); rightClickable + if (ImGui::BeginTable("opParams",2,ImGuiTableFlags_SizingStretchProp)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); \ + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,0.0); \ + + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + opE.delay&=7; + P(CWSliderScalar("##DELAY",ImGuiDataType_U8,&opE.delay,&_ZERO,&_SEVEN)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",ESFM_NAME(ESFM_DELAY)); + } + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + op.ar&=maxArDr; + P(CWSliderScalar("##AR",ImGuiDataType_U8,&op.ar,&maxArDr,&_ZERO)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_AR)); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + op.dr&=maxArDr; + P(CWSliderScalar("##DR",ImGuiDataType_U8,&op.dr,&maxArDr,&_ZERO)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_DR)); + + if (settings.susPosition==0) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##SL",ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_SL)); + } + + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##D2R",ImGuiDataType_U8,&op.d2r,&_THIRTY_ONE,&_ZERO)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_D2R)); + } + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##RR",ImGuiDataType_U8,&op.rr,&_FIFTEEN,&_ZERO)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_RR)); + + if (settings.susPosition==1) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##SL",ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_SL)); + } + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + op.tl&=maxTl; + P(CWSliderScalar("##TL",ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_TL)); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Separator(); + ImGui::TableNextColumn(); + ImGui::Separator(); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { + P(CWSliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_RS)); + } else { + int ksl=ins->type==DIV_INS_OPLL?op.ksl:kslMap[op.ksl&3]; + if (CWSliderInt("##KSL",&ksl,0,3)) { + op.ksl=(ins->type==DIV_INS_OPLL?ksl:kslMap[ksl&3]); + PARAMETER; + } rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_KSL)); + } + + if (ins->type==DIV_INS_OPZ) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar(FM_NAME(FM_EGSHIFT),ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_EGSHIFT)); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar(FM_NAME(FM_REV),ImGuiDataType_U8,&op.dam,&_ZERO,&_SEVEN)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_REV)); + } + + if (ins->type==DIV_INS_OPZ) { + if (op.egt) { + int block=op.dt; + int freqNum=(op.mult<<4)|(op.dvb&15); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (CWSliderInt(FM_NAME(FM_MULT),&block,0,7)) { PARAMETER + if (block<0) block=0; + if (block>7) block=7; + op.dt=block; + } rightClickable + ImGui::TableNextColumn(); + ImGui::Text("Block"); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (CWSliderInt(FM_NAME(FM_FINE),&freqNum,0,255)) { PARAMETER + if (freqNum<0) freqNum=0; + if (freqNum>255) freqNum=255; + op.mult=freqNum>>4; + op.dvb=freqNum&15; + } rightClickable + ImGui::TableNextColumn(); + ImGui::Text("FreqNum"); + } else { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar(FM_NAME(FM_MULT),ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_MULT)); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar(FM_NAME(FM_FINE),ImGuiDataType_U8,&op.dvb,&_ZERO,&_FIFTEEN)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_FINE)); + } + } else { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar(FM_NAME(FM_MULT),ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_MULT)); + } + + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { + if (!(ins->type==DIV_INS_OPZ && op.egt)) { + int detune=detuneMap[settings.unsignedDetune?1:0][op.dt&7]; + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (CWSliderInt("##DT",&detune,settings.unsignedDetune?0:-3,settings.unsignedDetune?7:4)) { PARAMETER + if (detune<-3) detune=-3; + if (detune>7) detune=7; + op.dt=detuneUnmap[settings.unsignedDetune?1:0][detune+3]; + } rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_DT)); + } + + if (ins->type!=DIV_INS_FM) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##DT2",ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_DT2)); + } + + if (ins->type==DIV_INS_FM) { // OPN only + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (CWSliderScalar("##SSG",ImGuiDataType_U8,&ssgEnv,&_ZERO,&_SEVEN,ssgEnvTypes[ssgEnv])) { PARAMETER + op.ssgEnv=(op.ssgEnv&8)|(ssgEnv&7); + } rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_SSG)); + } + } + + if (ins->type==DIV_INS_ESFM) { + bool fixedOn=opE.fixed; + if (fixedOn) { + int block=(opE.ct>>2)&7; + int freqNum=((opE.ct&3)<<8)|((unsigned char)opE.dt); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (ImGui::InputInt("##Block",&block,1,1)) { + if (block<0) block=0; + if (block>7) block=7; + opE.ct=(opE.ct&(~(7<<2)))|(block<<2); + } + ImGui::TableNextColumn(); + ImGui::Text("Block"); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (ImGui::InputInt("##FreqNum",&freqNum,1,16)) { + if (freqNum<0) freqNum=0; + if (freqNum>1023) freqNum=1023; + opE.dt=freqNum&0xff; + opE.ct=(opE.ct&(~3))|(freqNum>>8); + } + ImGui::TableNextColumn(); + ImGui::Text("FreqNum"); + } else { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWENTY_FOUR,&_TWENTY_FOUR)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",ESFM_NAME(ESFM_CT)); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##DT",ImGuiDataType_S8,&opE.dt,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",ESFM_NAME(ESFM_DT)); + } + + } + + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable + if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) { + ImGui::SetTooltip("OPL2/3 only (last 4 waveforms are OPL3 only)"); + } + ImGui::TableNextColumn(); + ImGui::Text("%s",FM_NAME(FM_WS)); + } + + if (ins->type==DIV_INS_ESFM) { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Separator(); + ImGui::TableNextColumn(); + ImGui::Separator(); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##OUTLVL",ImGuiDataType_U8,&opE.outLvl,&_ZERO,&_SEVEN)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",ESFM_NAME(ESFM_OUTLVL)); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + P(CWSliderScalar("##MODIN",ImGuiDataType_U8,&opE.modIn,&_ZERO,&_SEVEN)); rightClickable + ImGui::TableNextColumn(); + ImGui::Text("%s",ESFM_NAME(ESFM_MODIN)); + } + + ImGui::EndTable(); + } + + if (ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) { + if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER + op.vib=vibOn; + } + ImGui::SameLine(); + if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER + op.ksr=ksrOn; + } + } + + if (ins->type==DIV_INS_ESFM) { + bool dvbOn=op.dvb; + bool damOn=op.dam; + bool leftOn=opE.left; + bool rightOn=opE.right; + bool fixedOn=opE.fixed; + if (ImGui::Checkbox(FM_NAME(FM_DVB),&dvbOn)) { PARAMETER + op.dvb=dvbOn; + } + ImGui::SameLine(); + if (ImGui::Checkbox(FM_NAME(FM_DAM),&damOn)) { PARAMETER + op.dam=damOn; + } + if (ImGui::Checkbox(ESFM_NAME(ESFM_LEFT),&leftOn)) { PARAMETER + opE.left=leftOn; + } + ImGui::SameLine(); + if (ImGui::Checkbox(ESFM_NAME(ESFM_RIGHT),&rightOn)) { PARAMETER + opE.right=rightOn; + } + ImGui::SameLine(); + if (ImGui::Checkbox(ESFM_NAME(ESFM_FIXED),&fixedOn)) { PARAMETER + opE.fixed=fixedOn; + // HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly + ins->std.opMacros[i].ssgMacro.vZoom=-1; + ins->std.opMacros[i].dtMacro.vZoom=-1; + } + } + + if (settings.separateFMColors) { + popAccentColors(); + } + + ImGui::PopID(); + } + ImGui::EndTable(); + } + } + ImGui::EndDisabled(); + ImGui::EndTabItem(); + } +} + void FurnaceGUI::drawInsEdit() { if (nextWindow==GUI_WINDOW_INS_EDIT) { insEditOpen=true; @@ -3146,2121 +5267,9 @@ void FurnaceGUI::drawInsEdit() { int opCount=4; if (ins->type==DIV_INS_OPLL) opCount=2; if (ins->type==DIV_INS_OPL) opCount=(ins->fm.ops==4)?4:2; - bool opsAreMutable=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM); - if (ImGui::BeginTabItem("FM")) { - DivInstrumentFM& fmOrigin=(ins->type==DIV_INS_OPLL && ins->fm.opllPreset>0 && ins->fm.opllPreset<16)?opllPreview:ins->fm; + insTabFM(ins); - bool isPresent[4]; - int isPresentCount=0; - memset(isPresent,0,4*sizeof(bool)); - for (int i=0; isong.systemLen; i++) { - if (e->song.system[i]==DIV_SYSTEM_VRC7) { - isPresent[3]=true; - } else if (e->song.system[i]==DIV_SYSTEM_OPLL || e->song.system[i]==DIV_SYSTEM_OPLL_DRUMS) { - isPresent[(e->song.systemFlags[i].getInt("patchSet",0))&3]=true; - } - } - if (!isPresent[0] && !isPresent[1] && !isPresent[2] && !isPresent[3]) { - isPresent[0]=true; - } - for (int i=0; i<4; i++) { - if (isPresent[i]) isPresentCount++; - } - int presentWhich=0; - for (int i=0; i<4; i++) { - if (isPresent[i]) { - presentWhich=i; - break; - } - } - - if (ImGui::BeginTable("fmDetails",3,(ins->type==DIV_INS_ESFM)?ImGuiTableFlags_SizingStretchProp:ImGuiTableFlags_SizingStretchSame)) { - ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.50f:0.0f)); - ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.15f:0.0f)); - ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,((ins->type==DIV_INS_ESFM)?0.35f:0.0f)); - - ImGui::TableNextRow(); - switch (ins->type) { - case DIV_INS_FM: - case DIV_INS_OPM: - ImGui::TableNextColumn(); - P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable - P(CWSliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); rightClickable - ImGui::TableNextColumn(); - P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable - P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable - ImGui::TableNextColumn(); - if (fmPreviewOn) { - drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - if (!fmPreviewPaused) { - renderFMPreview(ins,1); - WAKE_UP; - } - } else { - drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - } - kvsConfig(ins); - break; - case DIV_INS_OPZ: - ImGui::TableNextColumn(); - P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable - P(CWSliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); rightClickable - P(CWSliderScalar(FM_NAME(FM_FMS2),ImGuiDataType_U8,&ins->fm.fms2,&_ZERO,&_SEVEN)); rightClickable - ImGui::TableNextColumn(); - P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable - P(CWSliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable - P(CWSliderScalar(FM_NAME(FM_AMS2),ImGuiDataType_U8,&ins->fm.ams2,&_ZERO,&_THREE)); rightClickable - ImGui::TableNextColumn(); - if (fmPreviewOn) { - drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - if (!fmPreviewPaused) { - renderFMPreview(ins,1); - WAKE_UP; - } - } else { - drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - } - kvsConfig(ins); - - if (ImGui::Button("Request from TX81Z")) { - doAction(GUI_ACTION_TX81Z_REQUEST); - } - /* - ImGui::SameLine(); - if (ImGui::Button("Send to TX81Z")) { - showError("Coming soon!"); - } - */ - break; - case DIV_INS_OPL: - case DIV_INS_OPL_DRUMS: { - bool fourOp=(ins->fm.ops==4 || ins->type==DIV_INS_OPL_DRUMS); - bool drums=ins->fm.opllPreset==16; - int algMax=fourOp?3:1; - ImGui::TableNextColumn(); - ins->fm.alg&=algMax; - P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable - if (ins->type==DIV_INS_OPL) { - ImGui::BeginDisabled(ins->fm.opllPreset==16); - if (ImGui::Checkbox("4-op",&fourOp)) { PARAMETER - ins->fm.ops=fourOp?4:2; - } - ImGui::EndDisabled(); - } - ImGui::TableNextColumn(); - P(CWSliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&algMax)); rightClickable - if (ins->type==DIV_INS_OPL) { - if (ImGui::Checkbox("Drums",&drums)) { PARAMETER - ins->fm.opllPreset=drums?16:0; - } - } - ImGui::TableNextColumn(); - if (fmPreviewOn) { - drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - if (!fmPreviewPaused) { - renderFMPreview(ins,1); - WAKE_UP; - } - } else { - drawAlgorithm(ins->fm.alg&algMax,fourOp?FM_ALGS_4OP_OPL:FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - } - kvsConfig(ins); - break; - } - case DIV_INS_OPLL: { - bool dc=fmOrigin.fms; - bool dm=fmOrigin.ams; - bool sus=ins->fm.alg; - ImGui::TableNextColumn(); - ImGui::BeginDisabled(ins->fm.opllPreset!=0); - P(CWSliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&fmOrigin.fb,&_ZERO,&_SEVEN)); rightClickable - if (ImGui::Checkbox(FM_NAME(FM_DC),&dc)) { PARAMETER - fmOrigin.fms=dc; - } - ImGui::EndDisabled(); - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_NAME(FM_SUS),&sus)) { PARAMETER - ins->fm.alg=sus; - } - ImGui::BeginDisabled(ins->fm.opllPreset!=0); - if (ImGui::Checkbox(FM_NAME(FM_DM),&dm)) { PARAMETER - fmOrigin.ams=dm; - } - ImGui::EndDisabled(); - ImGui::TableNextColumn(); - if (fmPreviewOn) { - drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale)); - if (!fmPreviewPaused) { - renderFMPreview(ins,1); - WAKE_UP; - } - } else { - drawAlgorithm(0,FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale)); - } - kvsConfig(ins,false); - - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - - if (ImGui::BeginCombo("##LLPreset",opllInsNames[presentWhich][ins->fm.opllPreset])) { - if (isPresentCount>1) { - if (ImGui::BeginTable("LLPresetList",isPresentCount)) { - ImGui::TableNextRow(ImGuiTableRowFlags_Headers); - for (int i=0; i<4; i++) { - if (!isPresent[i]) continue; - ImGui::TableNextColumn(); - ImGui::Text("%s name",opllVariants[i]); - } - for (int i=0; i<17; i++) { - ImGui::TableNextRow(); - for (int j=0; j<4; j++) { - if (!isPresent[j]) continue; - ImGui::TableNextColumn(); - ImGui::PushID(j*17+i); - if (ImGui::Selectable(opllInsNames[j][i])) { - ins->fm.opllPreset=i; - } - ImGui::PopID(); - } - } - ImGui::EndTable(); - } - } else { - for (int i=0; i<17; i++) { - if (ImGui::Selectable(opllInsNames[presentWhich][i])) { - ins->fm.opllPreset=i; - } - } - } - ImGui::EndCombo(); - } - break; - } - case DIV_INS_ESFM: { - ImGui::TableNextColumn(); - P(CWSliderScalar(ESFM_LONG_NAME(ESFM_NOISE),ImGuiDataType_U8,&ins->esfm.noise,&_ZERO,&_THREE,esfmNoiseModeNames[ins->esfm.noise&3])); rightClickable - ImGui::TextUnformatted(esfmNoiseModeDescriptions[ins->esfm.noise&3]); - ImGui::TableNextColumn(); - ImGui::TableNextColumn(); - if (fmPreviewOn) { - drawFMPreview(ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - if (!fmPreviewPaused) { - renderFMPreview(ins,1); - WAKE_UP; - } - } else { - drawESFMAlgorithm(ins->esfm, ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); - } - kvsConfig(ins); - } - default: - break; - } - ImGui::EndTable(); - } - - if (((ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL) && ins->fm.opllPreset==16) || ins->type==DIV_INS_OPL_DRUMS) { - ins->fm.ops=2; - P(ImGui::Checkbox("Fixed frequency mode",&ins->fm.fixedDrums)); - if (ImGui::IsItemHovered()) { - ImGui::SetTooltip("when enabled, drums will be set to the specified frequencies, ignoring the note."); - } - if (ins->fm.fixedDrums) { - int block=0; - int fNum=0; - if (ImGui::BeginTable("fixedDrumSettings",3)) { - ImGui::TableNextRow(ImGuiTableRowFlags_Headers); - ImGui::TableNextColumn(); - ImGui::Text("Drum"); - ImGui::TableNextColumn(); - ImGui::Text("Block"); - ImGui::TableNextColumn(); - ImGui::Text("FreqNum"); - - DRUM_FREQ("Kick","##DBlock0","##DFreq0",ins->fm.kickFreq); - DRUM_FREQ("Snare/Hi-hat","##DBlock1","##DFreq1",ins->fm.snareHatFreq); - DRUM_FREQ("Tom/Top","##DBlock2","##DFreq2",ins->fm.tomTopFreq); - ImGui::EndTable(); - } - } - } - - bool willDisplayOps=true; - if (ins->type==DIV_INS_OPLL && ins->fm.opllPreset!=0) willDisplayOps=false; - if (!willDisplayOps && ins->type==DIV_INS_OPLL) { - ins->fm.op[1].tl&=15; - P(CWSliderScalar("Volume##TL",ImGuiDataType_U8,&ins->fm.op[1].tl,&_FIFTEEN,&_ZERO)); rightClickable - if (ins->fm.opllPreset==16) { - ImGui::Text("this volume slider only works in compatibility (non-drums) system."); - } - - // update OPLL preset preview - if (ins->fm.opllPreset>0 && ins->fm.opllPreset<16) { - const opll_patch_t* patchROM=NULL; - - switch (presentWhich) { - case 1: - patchROM=OPLL_GetPatchROM(opll_type_ymf281); - break; - case 2: - patchROM=OPLL_GetPatchROM(opll_type_ym2423); - break; - case 3: - patchROM=OPLL_GetPatchROM(opll_type_ds1001); - break; - default: - patchROM=OPLL_GetPatchROM(opll_type_ym2413); - break; - } - - const opll_patch_t* patch=&patchROM[ins->fm.opllPreset-1]; - - opllPreview.alg=ins->fm.alg; - opllPreview.fb=patch->fb; - opllPreview.fms=patch->dm; - opllPreview.ams=patch->dc; - - opllPreview.op[0].tl=patch->tl; - opllPreview.op[1].tl=ins->fm.op[1].tl; - - for (int i=0; i<2; i++) { - opllPreview.op[i].am=patch->am[i]; - opllPreview.op[i].vib=patch->vib[i]; - opllPreview.op[i].ssgEnv=patch->et[i]?8:0; - opllPreview.op[i].ksr=patch->ksr[i]; - opllPreview.op[i].mult=patch->multi[i]; - opllPreview.op[i].ar=patch->ar[i]; - opllPreview.op[i].dr=patch->dr[i]; - opllPreview.op[i].sl=patch->sl[i]; - opllPreview.op[i].rr=patch->rr[i]; - } - } - } - - ImGui::BeginDisabled(!willDisplayOps); - if (settings.fmLayout==0) { - int numCols=15; - if (ins->type==DIV_INS_OPL ||ins->type==DIV_INS_OPL_DRUMS) numCols=13; - if (ins->type==DIV_INS_OPLL) numCols=12; - if (ins->type==DIV_INS_OPZ) numCols=19; - if (ins->type==DIV_INS_ESFM) numCols=19; - if (ImGui::BeginTable("FMOperators",numCols,ImGuiTableFlags_SizingStretchProp|ImGuiTableFlags_BordersH|ImGuiTableFlags_BordersOuterV)) { - // configure columns - ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed); // op name - if (ins->type==DIV_INS_ESFM) { - ImGui::TableSetupColumn("c0e0",ImGuiTableColumnFlags_WidthStretch,0.05f); // outLvl - ImGui::TableSetupColumn("c0e1",ImGuiTableColumnFlags_WidthFixed); // -separator- - ImGui::TableSetupColumn("c0e2",ImGuiTableColumnFlags_WidthStretch,0.05f); // delay - } - ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.05f); // ar - ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.05f); // dr - ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthStretch,0.05f); // sl - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { - ImGui::TableSetupColumn("c4",ImGuiTableColumnFlags_WidthStretch,0.05f); // d2r - } - ImGui::TableSetupColumn("c5",ImGuiTableColumnFlags_WidthStretch,0.05f); // rr - ImGui::TableSetupColumn("c6",ImGuiTableColumnFlags_WidthFixed); // -separator- - ImGui::TableSetupColumn("c7",ImGuiTableColumnFlags_WidthStretch,0.05f); // tl - ImGui::TableSetupColumn("c8",ImGuiTableColumnFlags_WidthStretch,0.05f); // rs/ksl - if (ins->type==DIV_INS_OPZ) { - ImGui::TableSetupColumn("c8z0",ImGuiTableColumnFlags_WidthStretch,0.05f); // egs - ImGui::TableSetupColumn("c8z1",ImGuiTableColumnFlags_WidthStretch,0.05f); // rev - } - if (ins->type==DIV_INS_ESFM) { - ImGui::TableSetupColumn("c8e0",ImGuiTableColumnFlags_WidthStretch,0.05f); // outLvl - } - ImGui::TableSetupColumn("c9",ImGuiTableColumnFlags_WidthStretch,0.05f); // mult - - if (ins->type==DIV_INS_OPZ) { - ImGui::TableSetupColumn("c9z",ImGuiTableColumnFlags_WidthStretch,0.05f); // fine - } - - if (ins->type==DIV_INS_ESFM) { - ImGui::TableSetupColumn("c9e",ImGuiTableColumnFlags_WidthStretch,0.05f); // ct - } - - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM || ins->type==DIV_INS_ESFM) { - ImGui::TableSetupColumn("c10",ImGuiTableColumnFlags_WidthStretch,0.05f); // dt - } - if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { - ImGui::TableSetupColumn("c11",ImGuiTableColumnFlags_WidthStretch,0.05f); // dt2 - } - ImGui::TableSetupColumn("c15",ImGuiTableColumnFlags_WidthFixed); // am - - ImGui::TableSetupColumn("c12",ImGuiTableColumnFlags_WidthFixed); // -separator- - if (ins->type!=DIV_INS_OPLL && ins->type!=DIV_INS_OPM) { - ImGui::TableSetupColumn("c13",ImGuiTableColumnFlags_WidthStretch,0.2f); // ssg/waveform - } - ImGui::TableSetupColumn("c14",ImGuiTableColumnFlags_WidthStretch,0.3f); // env - - // header - ImGui::TableNextRow(ImGuiTableRowFlags_Headers); - ImGui::TableNextColumn(); - if (ins->type==DIV_INS_ESFM) { - ImGui::TableNextColumn(); - CENTER_TEXT(ESFM_SHORT_NAME(ESFM_MODIN)); - ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_MODIN)); - TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_MODIN)); - ImGui::TableNextColumn(); - ImGui::TableNextColumn(); - CENTER_TEXT(ESFM_SHORT_NAME(ESFM_DELAY)); - ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DELAY)); - TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_DELAY)); - } - ImGui::TableNextColumn(); - CENTER_TEXT(FM_SHORT_NAME(FM_AR)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR)); - TOOLTIP_TEXT(FM_NAME(FM_AR)); - ImGui::TableNextColumn(); - CENTER_TEXT(FM_SHORT_NAME(FM_DR)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_DR)); - TOOLTIP_TEXT(FM_NAME(FM_DR)); - if (settings.susPosition==0) { - ImGui::TableNextColumn(); - CENTER_TEXT(FM_SHORT_NAME(FM_SL)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL)); - TOOLTIP_TEXT(FM_NAME(FM_SL)); - } - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { - ImGui::TableNextColumn(); - CENTER_TEXT(FM_SHORT_NAME(FM_D2R)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_D2R)); - TOOLTIP_TEXT(FM_NAME(FM_D2R)); - } - ImGui::TableNextColumn(); - CENTER_TEXT(FM_SHORT_NAME(FM_RR)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_RR)); - TOOLTIP_TEXT(FM_NAME(FM_RR)); - if (settings.susPosition==1) { - ImGui::TableNextColumn(); - CENTER_TEXT(FM_SHORT_NAME(FM_SL)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL)); - TOOLTIP_TEXT(FM_NAME(FM_SL)); - } - ImGui::TableNextColumn(); - ImGui::TableNextColumn(); - CENTER_TEXT(FM_SHORT_NAME(FM_TL)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_TL)); - TOOLTIP_TEXT(FM_NAME(FM_TL)); - ImGui::TableNextColumn(); - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { - CENTER_TEXT(FM_SHORT_NAME(FM_RS)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_RS)); - TOOLTIP_TEXT(FM_NAME(FM_RS)); - } else { - CENTER_TEXT(FM_SHORT_NAME(FM_KSL)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_KSL)); - TOOLTIP_TEXT(FM_NAME(FM_KSL)); - } - if (ins->type==DIV_INS_OPZ) { - ImGui::TableNextColumn(); - CENTER_TEXT(FM_SHORT_NAME(FM_EGSHIFT)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_EGSHIFT)); - TOOLTIP_TEXT(FM_NAME(FM_EGSHIFT)); - ImGui::TableNextColumn(); - CENTER_TEXT(FM_SHORT_NAME(FM_REV)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_REV)); - TOOLTIP_TEXT(FM_NAME(FM_REV)); - } - if (ins->type==DIV_INS_ESFM) { - ImGui::TableNextColumn(); - CENTER_TEXT(ESFM_SHORT_NAME(ESFM_OUTLVL)); - ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_OUTLVL)); - TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_OUTLVL)); - } - ImGui::TableNextColumn(); - CENTER_TEXT(FM_SHORT_NAME(FM_MULT)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_MULT)); - TOOLTIP_TEXT(FM_NAME(FM_MULT)); - if (ins->type==DIV_INS_OPZ) { - ImGui::TableNextColumn(); - CENTER_TEXT(FM_SHORT_NAME(FM_FINE)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_FINE)); - TOOLTIP_TEXT(FM_NAME(FM_FINE)); - } - if (ins->type==DIV_INS_ESFM) { - ImGui::TableNextColumn(); - CENTER_TEXT(ESFM_SHORT_NAME(ESFM_CT)); - ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_CT)); - TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_CT)); - } - ImGui::TableNextColumn(); - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { - CENTER_TEXT(FM_SHORT_NAME(FM_DT)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_DT)); - TOOLTIP_TEXT(FM_NAME(FM_DT)); - ImGui::TableNextColumn(); - } - if (ins->type==DIV_INS_ESFM) { - CENTER_TEXT(ESFM_SHORT_NAME(ESFM_DT)); - ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DT)); - TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_DT)); - ImGui::TableNextColumn(); - } - if (ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { - CENTER_TEXT(FM_SHORT_NAME(FM_DT2)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_DT2)); - TOOLTIP_TEXT(FM_NAME(FM_DT2)); - ImGui::TableNextColumn(); - } - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM) { - CENTER_TEXT(FM_SHORT_NAME(FM_AM)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_AM)); - TOOLTIP_TEXT(FM_NAME(FM_AM)); - } else { - CENTER_TEXT("Other"); - ImGui::TextUnformatted("Other"); - } - ImGui::TableNextColumn(); - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) { - ImGui::TableNextColumn(); - CENTER_TEXT(FM_NAME(FM_WS)); - ImGui::TextUnformatted(FM_NAME(FM_WS)); - } else if (ins->type!=DIV_INS_OPLL && ins->type!=DIV_INS_OPM) { - ImGui::TableNextColumn(); - CENTER_TEXT(FM_NAME(FM_SSG)); - ImGui::TextUnformatted(FM_NAME(FM_SSG)); - } - ImGui::TableNextColumn(); - CENTER_TEXT("Envelope"); - ImGui::TextUnformatted("Envelope"); - - float sliderHeight=32.0f*dpiScale; - - for (int i=0; itype!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[i]:i]; - DivInstrumentESFM::Operator& opE=ins->esfm.op[i]; - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - - // push colors - if (settings.separateFMColors) { - bool mod=true; - if (ins->type==DIV_INS_OPL_DRUMS) { - mod=false; - } else if (ins->type==DIV_INS_ESFM) { - // this is the same as the KVS heuristic in platform/esfm.h - if (opE.outLvl==7) { - mod=false; - } else if (opE.outLvl>0) { - if (i==3) { - mod=false; - } else { - DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1]; - if (opENext.modIn==0) { - mod=false; - } else if ((opE.outLvl-opENext.modIn)>=2) { - mod=false; - } - } - } - } else if (opCount==4) { - if (ins->type==DIV_INS_OPL) { - if (opIsOutputOPL[fmOrigin.alg&3][i]) mod=false; - } else { - if (opIsOutput[fmOrigin.alg&7][i]) mod=false; - } - } else { - if (i==1 || (ins->type==DIV_INS_OPL && (fmOrigin.alg&1))) mod=false; - } - if (mod) { - pushAccentColors( - uiColors[GUI_COLOR_FM_PRIMARY_MOD], - uiColors[GUI_COLOR_FM_SECONDARY_MOD], - uiColors[GUI_COLOR_FM_BORDER_MOD], - uiColors[GUI_COLOR_FM_BORDER_SHADOW_MOD] - ); - } else { - pushAccentColors( - uiColors[GUI_COLOR_FM_PRIMARY_CAR], - uiColors[GUI_COLOR_FM_SECONDARY_CAR], - uiColors[GUI_COLOR_FM_BORDER_CAR], - uiColors[GUI_COLOR_FM_BORDER_SHADOW_CAR] - ); - } - } - - if (i==0) { - sliderHeight=(ImGui::GetContentRegionAvail().y/opCount)-ImGui::GetStyle().ItemSpacing.y; - float sliderMinHeightOPL=ImGui::GetFrameHeight()*4.0+ImGui::GetStyle().ItemSpacing.y*3.0; - float sliderMinHeightESFM=ImGui::GetFrameHeight()*5.0+ImGui::GetStyle().ItemSpacing.y*4.0; - if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL) && sliderHeighttype==DIV_INS_ESFM && sliderHeighttype==DIV_INS_OPL_DRUMS) { - opNameLabel=fmt::sprintf("%s",oplDrumNames[i]); - } else if (ins->type==DIV_INS_OPL && fmOrigin.opllPreset==16) { - if (i==1) { - opNameLabel="Kick"; - } else { - opNameLabel="Env"; - } - } else { - opNameLabel=fmt::sprintf("OP%d",i+1); - } - if (opsAreMutable) { - pushToggleColors(op.enable); - if (ImGui::Button(opNameLabel.c_str())) { - op.enable=!op.enable; - PARAMETER; - } - popToggleColors(); - } else { - ImGui::TextUnformatted(opNameLabel.c_str()); - } - - // drag point - OP_DRAG_POINT; - - int maxTl=127; - if (ins->type==DIV_INS_OPLL) { - if (i==1) { - maxTl=15; - } else { - maxTl=63; - } - } - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) { - maxTl=63; - } - int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM)?31:15; - bool ssgOn=op.ssgEnv&8; - bool ksrOn=op.ksr; - bool vibOn=op.vib; - bool susOn=op.sus; - bool fixedOn=opE.fixed; - unsigned char ssgEnv=op.ssgEnv&7; - - if (ins->type==DIV_INS_ESFM) { - ImGui::TableNextColumn(); - CENTER_VSLIDER; - P(CWVSliderScalar("##MODIN",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&opE.modIn,&_ZERO,&_SEVEN)); rightClickable - ImGui::TableNextColumn(); - ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale)); - ImGui::TableNextColumn(); - opE.delay&=7; - CENTER_VSLIDER; - P(CWVSliderScalar("##DELAY",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&opE.delay,&_ZERO,&_SEVEN)); rightClickable - } - - ImGui::TableNextColumn(); - op.ar&=maxArDr; - CENTER_VSLIDER; - P(CWVSliderScalar("##AR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.ar,&maxArDr,&_ZERO)); rightClickable - - ImGui::TableNextColumn(); - op.dr&=maxArDr; - CENTER_VSLIDER; - P(CWVSliderScalar("##DR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dr,&maxArDr,&_ZERO)); rightClickable - - if (settings.susPosition==0) { - ImGui::TableNextColumn(); - op.sl&=15; - CENTER_VSLIDER; - P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable - } - - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { - ImGui::TableNextColumn(); - op.d2r&=31; - CENTER_VSLIDER; - P(CWVSliderScalar("##D2R",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.d2r,&_THIRTY_ONE,&_ZERO)); rightClickable - } - - ImGui::TableNextColumn(); - op.rr&=15; - CENTER_VSLIDER; - P(CWVSliderScalar("##RR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.rr,&_FIFTEEN,&_ZERO)); rightClickable - - if (settings.susPosition==1) { - ImGui::TableNextColumn(); - op.sl&=15; - CENTER_VSLIDER; - P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable - } - - ImGui::TableNextColumn(); - ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale)); - - ImGui::TableNextColumn(); - op.tl&=maxTl; - CENTER_VSLIDER; - P(CWVSliderScalar("##TL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); rightClickable - - ImGui::TableNextColumn(); - CENTER_VSLIDER; - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { - P(CWVSliderScalar("##RS",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE)); rightClickable - } else { - int ksl=ins->type==DIV_INS_OPLL?op.ksl:kslMap[op.ksl&3]; - if (CWVSliderInt("##KSL",ImVec2(20.0f*dpiScale,sliderHeight),&ksl,0,3)) { - op.ksl=(ins->type==DIV_INS_OPLL?ksl:kslMap[ksl&3]); - PARAMETER; - } rightClickable - } - - if (ins->type==DIV_INS_OPZ) { - ImGui::TableNextColumn(); - CENTER_VSLIDER; - P(CWVSliderScalar("##EGS",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE)); rightClickable - - ImGui::TableNextColumn(); - CENTER_VSLIDER; - P(CWVSliderScalar("##REV",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dam,&_ZERO,&_SEVEN)); rightClickable - } - - if (ins->type==DIV_INS_ESFM) { - ImGui::TableNextColumn(); - CENTER_VSLIDER; - P(CWVSliderScalar("##OUTLVL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&opE.outLvl,&_ZERO,&_SEVEN)); rightClickable - } - - ImGui::TableNextColumn(); - CENTER_VSLIDER; - P(CWVSliderScalar("##MULT",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN)); rightClickable - - if (ins->type==DIV_INS_OPZ) { - ImGui::TableNextColumn(); - CENTER_VSLIDER; - P(CWVSliderScalar("##FINE",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dvb,&_ZERO,&_FIFTEEN)); rightClickable - } - - if (ins->type==DIV_INS_ESFM) { - ImGui::TableNextColumn(); - CENTER_VSLIDER; - P(CWVSliderScalar("##CT",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_S8,&opE.ct,&_MINUS_TWENTY_FOUR,&_TWENTY_FOUR)); rightClickable - } - - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { - int detune=detuneMap[settings.unsignedDetune?1:0][op.dt&7]; - ImGui::TableNextColumn(); - CENTER_VSLIDER; - if (CWVSliderInt("##DT",ImVec2(20.0f*dpiScale,sliderHeight),&detune,settings.unsignedDetune?0:-3,settings.unsignedDetune?7:4)) { PARAMETER - if (detune<-3) detune=-3; - if (detune>7) detune=7; - op.dt=detuneUnmap[settings.unsignedDetune?1:0][detune+3]; - } rightClickable - - if (ins->type!=DIV_INS_FM) { - ImGui::TableNextColumn(); - CENTER_VSLIDER; - P(CWVSliderScalar("##DT2",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE)); rightClickable - } - - ImGui::TableNextColumn(); - bool amOn=op.am; - if (ins->type==DIV_INS_OPZ) { - bool egtOn=op.egt; - if (egtOn) { - ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight()*4.0-ImGui::GetStyle().ItemSpacing.y*3.0)); - } else { - ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight()*2.0-ImGui::GetStyle().ItemSpacing.y*1.0)); - } - if (ImGui::Checkbox("AM",&amOn)) { PARAMETER - op.am=amOn; - } - if (ImGui::Checkbox("Fixed",&egtOn)) { PARAMETER - op.egt=egtOn; - } - if (egtOn) { - int block=op.dt; - int freqNum=(op.mult<<4)|(op.dvb&15); - if (ImGui::InputInt("Block",&block,1,1)) { - if (block<0) block=0; - if (block>7) block=7; - op.dt=block; - } - if (ImGui::InputInt("FreqNum",&freqNum,1,16)) { - if (freqNum<0) freqNum=0; - if (freqNum>255) freqNum=255; - op.mult=freqNum>>4; - op.dvb=freqNum&15; - } - } - } else { - ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight())); - if (ImGui::Checkbox("##AM",&amOn)) { PARAMETER - op.am=amOn; - } - } - - if (ins->type!=DIV_INS_OPL && ins->type!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_OPZ && ins->type!=DIV_INS_OPM) { - ImGui::TableNextColumn(); - ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale)); - ImGui::TableNextColumn(); - ImGui::BeginDisabled(!ssgOn); - drawSSGEnv(op.ssgEnv&7,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight-ImGui::GetFrameHeightWithSpacing())); - ImGui::EndDisabled(); - if (ImGui::Checkbox("##SSGOn",&ssgOn)) { PARAMETER - op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3); - } - - ImGui::SameLine(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - if (CWSliderScalar("##SSG",ImGuiDataType_U8,&ssgEnv,&_ZERO,&_SEVEN,ssgEnvTypes[ssgEnv])) { PARAMETER - op.ssgEnv=(op.ssgEnv&8)|(ssgEnv&7); - } - } - } else if (ins->type==DIV_INS_ESFM) { - ImGui::TableNextColumn(); - CENTER_VSLIDER; - P(CWVSliderScalar("##DT",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_S8,&opE.dt,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN)); rightClickable - - ImGui::TableNextColumn(); - bool amOn=op.am; - bool leftOn=opE.left; - bool rightOn=opE.right; - - ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight()*5.0-ImGui::GetStyle().ItemSpacing.y*4.0)); - ImVec2 curPosBeforeDummy = ImGui::GetCursorPos(); - ImGui::Dummy(ImVec2(ImGui::GetFrameHeightWithSpacing()*2.0f+ImGui::CalcTextSize(FM_SHORT_NAME(FM_DAM)).x*2.0f,1.0f)); - ImGui::SetCursorPos(curPosBeforeDummy); - - if (ImGui::BeginTable("panCheckboxes",(fixedOn)?3:2,ImGuiTableFlags_SizingStretchProp)) { - ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,1.0); - ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,1.0); - if (fixedOn) { - ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,1.2); - } - - float yCoordBeforeTablePadding=ImGui::GetCursorPosY(); - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetCursorPosY(yCoordBeforeTablePadding); - if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_LEFT),&leftOn)) { PARAMETER - opE.left=leftOn; - } - ImGui::TableNextColumn(); - ImGui::SetCursorPosY(yCoordBeforeTablePadding); - if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_RIGHT),&rightOn)) { PARAMETER - opE.right=rightOn; - } - if (fixedOn) { - ImGui::TableNextColumn(); - ImGui::SetCursorPosY(yCoordBeforeTablePadding); - if (ImGui::Checkbox(FM_SHORT_NAME(FM_AM),&amOn)) { PARAMETER - op.am=amOn; - } - } - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_SHORT_NAME(FM_KSR),&ksrOn)) { PARAMETER - op.ksr=ksrOn; - } - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_SHORT_NAME(FM_SUS),&susOn)) { PARAMETER - op.sus=susOn; - } - if (fixedOn) { - bool damOn=op.dam; - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_SHORT_NAME(FM_DAM),&damOn)) { PARAMETER - op.dam=damOn; - } - } - ImGui::EndTable(); - } - ImGui::SetCursorPosY(ImGui::GetCursorPosY()-0.5*ImGui::GetStyle().ItemSpacing.y); - if (ImGui::Checkbox(ESFM_NAME(ESFM_FIXED),&fixedOn)) { PARAMETER - opE.fixed=fixedOn; - // HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly - ins->std.opMacros[i].ssgMacro.vZoom=-1; - ins->std.opMacros[i].dtMacro.vZoom=-1; - } - if (ins->type==DIV_INS_ESFM) { - if (fixedOn) { - int block=(opE.ct>>2)&7; - int freqNum=((opE.ct&3)<<8)|((unsigned char)opE.dt); - if (ImGui::InputInt("Block",&block,1,1)) { - if (block<0) block=0; - if (block>7) block=7; - opE.ct=(opE.ct&(~(7<<2)))|(block<<2); - } - if (ImGui::InputInt("FreqNum",&freqNum,1,16)) { - if (freqNum<0) freqNum=0; - if (freqNum>1023) freqNum=1023; - opE.dt=freqNum&0xff; - opE.ct=(opE.ct&(~3))|(freqNum>>8); - } - } else { - if (ImGui::BeginTable("amVibCheckboxes",2,ImGuiTableFlags_SizingStretchSame)) { - ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); - ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0); - - float yCoordBeforeTablePadding=ImGui::GetCursorPosY(); - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetCursorPosY(yCoordBeforeTablePadding); - if (ImGui::Checkbox(FM_SHORT_NAME(FM_AM),&amOn)) { PARAMETER - op.am=amOn; - } - ImGui::TableNextColumn(); - ImGui::SetCursorPosY(yCoordBeforeTablePadding); - if (ImGui::Checkbox(FM_SHORT_NAME(FM_VIB),&vibOn)) { PARAMETER - op.vib=vibOn; - } - bool damOn=op.dam; - bool dvbOn=op.dvb; - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_SHORT_NAME(FM_DAM),&damOn)) { PARAMETER - op.dam=damOn; - } - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_SHORT_NAME(FM_DVB),&dvbOn)) { PARAMETER - op.dvb=dvbOn; - } - ImGui::EndTable(); - } - } - } - } else if (ins->type!=DIV_INS_OPM) { - ImGui::TableNextColumn(); - bool amOn=op.am; - ImGui::SetCursorPosY(ImGui::GetCursorPosY()+0.5*(sliderHeight-ImGui::GetFrameHeight()*4.0-ImGui::GetStyle().ItemSpacing.y*3.0)); - if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER - op.am=amOn; - } - if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER - op.vib=vibOn; - } - if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER - op.ksr=ksrOn; - } - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) { - if (ImGui::Checkbox(FM_NAME(FM_SUS),&susOn)) { PARAMETER - op.sus=susOn; - } - } else if (ins->type==DIV_INS_OPLL) { - if (ImGui::Checkbox(FM_NAME(FM_EGS),&ssgOn)) { PARAMETER - op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3); - } - } - } - - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) { - ImGui::TableNextColumn(); - ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale)); - ImGui::TableNextColumn(); - - drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight-ImGui::GetFrameHeightWithSpacing()*((ins->type==DIV_INS_ESFM && fixedOn)?3.0f:1.0f))); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable - if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) { - ImGui::SetTooltip("OPL2/3 only (last 4 waveforms are OPL3 only)"); - } - if (ins->type==DIV_INS_ESFM && fixedOn) { - if (ImGui::Checkbox(FM_SHORT_NAME(FM_VIB),&vibOn)) { PARAMETER - op.vib=vibOn; - } - bool dvbOn=op.dvb; - if (ImGui::Checkbox(FM_SHORT_NAME(FM_DVB),&dvbOn)) { PARAMETER - op.dvb=dvbOn; - } - } - } else if (ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPM) { - ImGui::TableNextColumn(); - ImGui::Dummy(ImVec2(4.0f*dpiScale,2.0f*dpiScale)); - } - - ImGui::TableNextColumn(); - drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_ESFM)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight),ins->type); - - if (settings.separateFMColors) { - popAccentColors(); - } - - ImGui::PopID(); - } - - ImGui::EndTable(); - } - } else if (settings.fmLayout>=4 && settings.fmLayout<=6) { // alternate - int columns=2; - switch (settings.fmLayout) { - case 4: // 2x2 - columns=2; - break; - case 5: // 1x4 - columns=1; - break; - case 6: // 4x1 - columns=opCount; - break; - } - char tempID[1024]; - ImVec2 oldPadding=ImGui::GetStyle().CellPadding; - ImGui::PushStyleVar(ImGuiStyleVar_CellPadding,ImVec2(8.0f*dpiScale,4.0f*dpiScale)); - if (ImGui::BeginTable("AltFMOperators",columns,ImGuiTableFlags_SizingStretchSame|ImGuiTableFlags_BordersInner)) { - for (int i=0; itype!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[i]:i]; - DivInstrumentESFM::Operator& opE=ins->esfm.op[i]; - if ((settings.fmLayout!=6 && ((i+1)&1)) || i==0 || settings.fmLayout==5) ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::PushID(fmt::sprintf("op%d",i).c_str()); - - // push colors - if (settings.separateFMColors) { - bool mod=true; - if (ins->type==DIV_INS_OPL_DRUMS) { - mod=false; - } else if (ins->type==DIV_INS_ESFM) { - // this is the same as the KVS heuristic in platform/esfm.h - if (opE.outLvl==7) mod=false; - else if (opE.outLvl>0) { - if (i==3) mod=false; - else { - DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1]; - if (opENext.modIn==0) mod=false; - else if ((opE.outLvl-opENext.modIn)>=2) mod=false; - } - } - } else if (opCount==4) { - if (ins->type==DIV_INS_OPL) { - if (opIsOutputOPL[fmOrigin.alg&3][i]) mod=false; - } else { - if (opIsOutput[fmOrigin.alg&7][i]) mod=false; - } - } else { - if (i==1 || (ins->type==DIV_INS_OPL && (fmOrigin.alg&1))) mod=false; - } - if (mod) { - pushAccentColors( - uiColors[GUI_COLOR_FM_PRIMARY_MOD], - uiColors[GUI_COLOR_FM_SECONDARY_MOD], - uiColors[GUI_COLOR_FM_BORDER_MOD], - uiColors[GUI_COLOR_FM_BORDER_SHADOW_MOD] - ); - } else { - pushAccentColors( - uiColors[GUI_COLOR_FM_PRIMARY_CAR], - uiColors[GUI_COLOR_FM_SECONDARY_CAR], - uiColors[GUI_COLOR_FM_BORDER_CAR], - uiColors[GUI_COLOR_FM_BORDER_SHADOW_CAR] - ); - } - } - - ImGui::Dummy(ImVec2(dpiScale,dpiScale)); - if (ins->type==DIV_INS_OPL_DRUMS) { - snprintf(tempID,1024,"%s",oplDrumNames[i]); - } else if (ins->type==DIV_INS_OPL && fmOrigin.opllPreset==16) { - if (i==1) { - snprintf(tempID,1024,"Envelope 2 (kick only)"); - } else { - snprintf(tempID,1024,"Envelope"); - } - } else { - snprintf(tempID,1024,"Operator %d",i+1); - } - float nextCursorPosX=ImGui::GetCursorPosX()+0.5*(ImGui::GetContentRegionAvail().x-ImGui::CalcTextSize(tempID).x-(opsAreMutable?(ImGui::GetStyle().FramePadding.x*2.0f):0.0f)); - OP_DRAG_POINT; - ImGui::SameLine(); - ImGui::SetCursorPosX(nextCursorPosX); - if (opsAreMutable) { - pushToggleColors(op.enable); - if (ImGui::Button(tempID)) { - op.enable=!op.enable; - PARAMETER; - } - popToggleColors(); - } else { - ImGui::TextUnformatted(tempID); - } - - float sliderHeight=200.0f*dpiScale; - float waveWidth=140.0*dpiScale*((ins->type==DIV_INS_ESFM)?0.85f:1.0f); - float waveHeight=sliderHeight-ImGui::GetFrameHeightWithSpacing()*((ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPL || ins->type==DIV_INS_ESFM)?5.0f:4.5f); - - int maxTl=127; - if (ins->type==DIV_INS_OPLL) { - if (i==1) { - maxTl=15; - } else { - maxTl=63; - } - } - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) { - maxTl=63; - } - int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM)?31:15; - - bool ssgOn=op.ssgEnv&8; - bool ksrOn=op.ksr; - bool vibOn=op.vib; - bool egtOn=op.egt; - bool susOn=op.sus; // yawn - unsigned char ssgEnv=op.ssgEnv&7; - - ImGui::PushStyleVar(ImGuiStyleVar_CellPadding,oldPadding); - if (ImGui::BeginTable("opParams",4,ImGuiTableFlags_BordersInnerV)) { - ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed); - ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,waveWidth); - ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch); - ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthFixed); - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - float textY=ImGui::GetCursorPosY(); - if (ins->type==DIV_INS_ESFM) { - CENTER_TEXT_20(ESFM_SHORT_NAME(ESFM_DELAY)); - ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_DELAY)); - TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_DELAY)); - } else { - CENTER_TEXT_20(FM_SHORT_NAME(FM_AR)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR)); - TOOLTIP_TEXT(FM_NAME(FM_AR)); - } - ImGui::TableNextColumn(); - if (ins->type==DIV_INS_FM) { - ImGui::Text("SSG-EG"); - } else { - ImGui::Text("Waveform"); - } - ImGui::TableNextColumn(); - ImGui::Text("Envelope"); - ImGui::TableNextColumn(); - - // A/D/S/R - ImGui::TableNextColumn(); - - if (ins->type==DIV_INS_ESFM) { - opE.delay&=7; - P(CWVSliderScalar("##DELAY",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&opE.delay,&_ZERO,&_SEVEN)); rightClickable - ImGui::SameLine(); - } - - op.ar&=maxArDr; - float textX_AR=ImGui::GetCursorPosX(); - P(CWVSliderScalar("##AR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.ar,&maxArDr,&_ZERO)); rightClickable - - ImGui::SameLine(); - op.dr&=maxArDr; - float textX_DR=ImGui::GetCursorPosX(); - P(CWVSliderScalar("##DR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.dr,&maxArDr,&_ZERO)); rightClickable - - float textX_SL=0.0f; - if (settings.susPosition==0) { - ImGui::SameLine(); - op.sl&=15; - textX_SL=ImGui::GetCursorPosX(); - P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable - } - - float textX_D2R=0.0f; - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { - ImGui::SameLine(); - op.d2r&=31; - textX_D2R=ImGui::GetCursorPosX(); - P(CWVSliderScalar("##D2R",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.d2r,&_THIRTY_ONE,&_ZERO)); rightClickable - } - - ImGui::SameLine(); - op.rr&=15; - float textX_RR=ImGui::GetCursorPosX(); - P(CWVSliderScalar("##RR",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.rr,&_FIFTEEN,&_ZERO)); rightClickable - - if (settings.susPosition==1) { - ImGui::SameLine(); - op.sl&=15; - textX_SL=ImGui::GetCursorPosX(); - P(CWVSliderScalar("##SL",ImVec2(20.0f*dpiScale,sliderHeight),ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable - } - - ImVec2 prevCurPos=ImGui::GetCursorPos(); - - // labels - if (ins->type==DIV_INS_ESFM) { - ImGui::SetCursorPos(ImVec2(textX_AR,textY)); - CENTER_TEXT_20(FM_SHORT_NAME(FM_AR)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_AR)); - TOOLTIP_TEXT(FM_NAME(FM_AR)); - } - - ImGui::SetCursorPos(ImVec2(textX_DR,textY)); - CENTER_TEXT_20(FM_SHORT_NAME(FM_DR)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_DR)); - TOOLTIP_TEXT(FM_NAME(FM_DR)); - - ImGui::SetCursorPos(ImVec2(textX_SL,textY)); - CENTER_TEXT_20(FM_SHORT_NAME(FM_SL)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_SL)); - TOOLTIP_TEXT(FM_NAME(FM_SL)); - - ImGui::SetCursorPos(ImVec2(textX_RR,textY)); - CENTER_TEXT_20(FM_SHORT_NAME(FM_RR)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_RR)); - TOOLTIP_TEXT(FM_NAME(FM_RR)); - - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { - ImGui::SetCursorPos(ImVec2(textX_D2R,textY)); - CENTER_TEXT_20(FM_SHORT_NAME(FM_D2R)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_D2R)); - TOOLTIP_TEXT(FM_NAME(FM_D2R)); - } - - ImGui::SetCursorPos(prevCurPos); - - ImGui::TableNextColumn(); - switch (ins->type) { - case DIV_INS_FM: { - // SSG - ImGui::BeginDisabled(!ssgOn); - drawSSGEnv(op.ssgEnv&7,ImVec2(waveWidth,waveHeight)); - ImGui::EndDisabled(); - if (ImGui::Checkbox("##SSGOn",&ssgOn)) { PARAMETER - op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3); - } - - ImGui::SameLine(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - if (CWSliderScalar("##SSG",ImGuiDataType_U8,&ssgEnv,&_ZERO,&_SEVEN,ssgEnvTypes[ssgEnv])) { PARAMETER - op.ssgEnv=(op.ssgEnv&8)|(ssgEnv&7); - } - - // params - ImGui::Separator(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT)); - P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable - - int detune=detuneMap[settings.unsignedDetune?1:0][op.dt&7]; - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT)); - if (CWSliderInt("##DT",&detune,settings.unsignedDetune?0:-3,settings.unsignedDetune?7:4,tempID)) { PARAMETER - if (detune<-3) detune=-3; - if (detune>7) detune=7; - op.dt=detuneUnmap[settings.unsignedDetune?1:0][detune+3]; - } rightClickable - - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_RS)); - P(CWSliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE,tempID)); rightClickable - - break; - } - case DIV_INS_OPM: { - drawWaveform(0,true,ImVec2(waveWidth,waveHeight)); - - // params - ImGui::Separator(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT)); - P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable - - int detune=detuneMap[settings.unsignedDetune?1:0][op.dt&7]; - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT)); - if (CWSliderInt("##DT",&detune,settings.unsignedDetune?0:-3,settings.unsignedDetune?7:4,tempID)) { PARAMETER - if (detune<-3) detune=-3; - if (detune>7) detune=7; - op.dt=detuneUnmap[settings.unsignedDetune?1:0][detune+3]; - } rightClickable - - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT2)); - P(CWSliderScalar("##DT2",ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE,tempID)); rightClickable - - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_RS)); - P(CWSliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE,tempID)); rightClickable - break; - } - case DIV_INS_OPLL: - // waveform - drawWaveform(i==0?(fmOrigin.ams&1):(fmOrigin.fms&1),ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight)); - - // params - ImGui::Separator(); - if (ImGui::BeginTable("FMParamsInner",2)) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - bool amOn=op.am; - if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER - op.am=amOn; - } - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER - op.ksr=ksrOn; - } - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER - op.vib=vibOn; - } - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_NAME(FM_EGS),&ssgOn)) { PARAMETER - op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3); - } - - ImGui::EndTable(); - } - - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT)); - P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable - - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_KSL)); - P(CWSliderScalar("##KSL",ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE,tempID)); rightClickable - - break; - case DIV_INS_OPL: - case DIV_INS_OPL_DRUMS: { - // waveform - drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight)); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable - if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) { - ImGui::SetTooltip("OPL2/3 only (last 4 waveforms are OPL3 only)"); - } - - // params - ImGui::Separator(); - if (ImGui::BeginTable("FMParamsInner",2)) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - bool amOn=op.am; - if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER - op.am=amOn; - } - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER - op.ksr=ksrOn; - } - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER - op.vib=vibOn; - } - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_NAME(FM_SUS),&susOn)) { PARAMETER - op.sus=susOn; - } - - ImGui::EndTable(); - } - - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT)); - P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable - - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_KSL)); - int ksl=kslMap[op.ksl&3]; - if (CWSliderInt("##KSL",&ksl,0,3,tempID)) { - op.ksl=kslMap[ksl&3]; - PARAMETER; - } rightClickable - - break; - } - case DIV_INS_OPZ: { - // waveform - drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight)); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable - if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) { - ImGui::SetTooltip("OPL2/3 only (last 4 waveforms are OPL3 only)"); - } - - // params - ImGui::Separator(); - if (egtOn) { - int block=op.dt; - int freqNum=(op.mult<<4)|(op.dvb&15); - ImGui::Text("Block"); - ImGui::SameLine(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - ImVec2 cursorAlign=ImGui::GetCursorPos(); - if (ImGui::InputInt("##Block",&block,1,1)) { - if (block<0) block=0; - if (block>7) block=7; - op.dt=block; - } - - ImGui::Text("Freq"); - ImGui::SameLine(); - ImGui::SetCursorPos(ImVec2(cursorAlign.x,ImGui::GetCursorPosY())); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - if (ImGui::InputInt("##FreqNum",&freqNum,1,16)) { - if (freqNum<0) freqNum=0; - if (freqNum>255) freqNum=255; - op.mult=freqNum>>4; - op.dvb=freqNum&15; - } - } else { - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT)); - P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable - - int detune=detuneMap[settings.unsignedDetune?1:0][op.dt&7]; - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT)); - if (CWSliderInt("##DT",&detune,settings.unsignedDetune?0:-3,settings.unsignedDetune?7:4,tempID)) { PARAMETER - if (detune<-3) detune=-3; - if (detune>7) detune=7; - op.dt=detuneUnmap[settings.unsignedDetune?1:0][detune+3]; - } rightClickable - } - - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_DT2)); - P(CWSliderScalar("##DT2",ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE,tempID)); rightClickable - if (ImGui::IsItemHovered()) { - ImGui::SetTooltip("Only on YM2151 (OPM)"); - } - - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_RS)); - P(CWSliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE,tempID)); rightClickable - break; - } - case DIV_INS_ESFM: - // waveform - drawWaveform(op.ws&7,ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight)); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable - - // params - ImGui::Separator(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_MULT)); - P(CWSliderScalar("##MULT",ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN,tempID)); rightClickable - - if (opE.fixed) { - int block=(opE.ct>>2)&7; - int freqNum=((opE.ct&3)<<8)|((unsigned char)opE.dt); - ImGui::Text("Blk"); - if (ImGui::IsItemHovered()) { - ImGui::SetTooltip("Block"); - } - ImGui::SameLine(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - //ImVec2 cursorAlign=ImGui::GetCursorPos(); - if (ImGui::InputInt("##Block",&block,1,1)) { - if (block<0) block=0; - if (block>7) block=7; - opE.ct=(opE.ct&(~(7<<2)))|(block<<2); - } - - ImGui::Text("F"); - if (ImGui::IsItemHovered()) { - ImGui::SetTooltip("Frequency (F-Num)"); - } - ImGui::SameLine(); - //ImGui::SetCursorPos(ImVec2(cursorAlign.x,ImGui::GetCursorPosY())); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - if (ImGui::InputInt("##FreqNum",&freqNum,1,16)) { - if (freqNum<0) freqNum=0; - if (freqNum>1023) freqNum=1023; - opE.dt=freqNum&0xff; - opE.ct=(opE.ct&(~3))|(freqNum>>8); - } - } else { - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",ESFM_NAME(ESFM_CT)); - P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWENTY_FOUR,&_TWENTY_FOUR,tempID)); rightClickable - - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",ESFM_NAME(ESFM_DT)); - P(CWSliderScalar("##DT",ImGuiDataType_S8,&opE.dt,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN,tempID)); rightClickable - } - - if (ImGui::BeginTable("panCheckboxes",2,ImGuiTableFlags_SizingStretchSame)) { - ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0f); - ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0f); - - float yPosOutsideTablePadding=ImGui::GetCursorPosY(); - bool leftOn=opE.left; - bool rightOn=opE.right; - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetCursorPosY(yPosOutsideTablePadding); - if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_LEFT),&leftOn)) { PARAMETER - opE.left=leftOn; - } - ImGui::TableNextColumn(); - ImGui::SetCursorPosY(yPosOutsideTablePadding); - if (ImGui::Checkbox(ESFM_SHORT_NAME(ESFM_RIGHT),&rightOn)) { PARAMETER - opE.right=rightOn; - } - ImGui::EndTable(); - } - break; - default: - break; - } - - ImGui::TableNextColumn(); - float envHeight=sliderHeight;//-ImGui::GetStyle().ItemSpacing.y*2.0f; - if (ins->type==DIV_INS_OPZ) { - envHeight-=ImGui::GetFrameHeightWithSpacing()*2.0f; - } - if (ins->type==DIV_INS_ESFM) { - envHeight-=ImGui::GetFrameHeightWithSpacing()*3.0f; - } - drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_ESFM)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,envHeight),ins->type); - - if (ins->type==DIV_INS_OPZ) { - ImGui::Separator(); - if (ImGui::BeginTable("FMParamsInnerOPZ",2)) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - if (!egtOn) { - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_FINE)); - P(CWSliderScalar("##FINE",ImGuiDataType_U8,&op.dvb,&_ZERO,&_FIFTEEN,tempID)); rightClickable - } - - ImGui::TableNextColumn(); - bool amOn=op.am; - if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER - op.am=amOn; - } - ImGui::SameLine(); - if (ImGui::Checkbox("Fixed",&egtOn)) { PARAMETER - op.egt=egtOn; - } - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_EGSHIFT)); - P(CWSliderScalar("##EGShift",ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE,tempID)); rightClickable - - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_REV)); - P(CWSliderScalar("##REV",ImGuiDataType_U8,&op.dam,&_ZERO,&_SEVEN,tempID)); rightClickable - - ImGui::TableNextColumn(); - - - ImGui::EndTable(); - } - } - - if (ins->type==DIV_INS_ESFM) { - ImGui::Separator(); - if (ImGui::BeginTable("FMParamsInnerESFM",2)) { - ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.64f); - ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.36f); - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - snprintf(tempID,1024,"%s: %%d",FM_NAME(FM_KSL)); - int ksl=kslMap[op.ksl&3]; - if (CWSliderInt("##KSL",&ksl,0,3,tempID)) { - op.ksl=kslMap[ksl&3]; - PARAMETER; - } rightClickable - - bool amOn=op.am; - bool fixedOn=opE.fixed; - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_SHORT_NAME(FM_KSR),&ksrOn)) { PARAMETER - op.ksr=ksrOn; - } - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - if (ImGui::BeginTable("vibAmCheckboxes",2)) { - ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0f); - ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.0f); - - float yPosOutsideTablePadding=ImGui::GetCursorPosY(); - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetCursorPosY(yPosOutsideTablePadding); - if (ImGui::Checkbox(FM_SHORT_NAME(FM_VIB),&vibOn)) { PARAMETER - op.vib=vibOn; - } - ImGui::TableNextColumn(); - ImGui::SetCursorPosY(yPosOutsideTablePadding); - if (ImGui::Checkbox(FM_SHORT_NAME(FM_AM),&amOn)) { PARAMETER - op.am=amOn; - } - - bool damOn=op.dam; - bool dvbOn=op.dvb; - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_SHORT_NAME(FM_DVB),&dvbOn)) { PARAMETER - op.dvb=dvbOn; - } - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_SHORT_NAME(FM_DAM),&damOn)) { PARAMETER - op.dam=damOn; - } - ImGui::EndTable(); - } - ImGui::TableNextColumn(); - if (ImGui::Checkbox(FM_SHORT_NAME(FM_SUS),&susOn)) { PARAMETER - op.sus=susOn; - } - if (ImGui::Checkbox(ESFM_NAME(ESFM_FIXED),&fixedOn)) { PARAMETER - opE.fixed=fixedOn; - // HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly - ins->std.opMacros[i].ssgMacro.vZoom=-1; - ins->std.opMacros[i].dtMacro.vZoom=-1; - } - - ImGui::EndTable(); - } - } - - ImGui::TableNextColumn(); - op.tl&=maxTl; - float tlSliderWidth=(ins->type==DIV_INS_ESFM)?20.0f*dpiScale:ImGui::GetFrameHeight(); - float tlSliderHeight=sliderHeight-((ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM)?(ImGui::GetFrameHeightWithSpacing()+ImGui::CalcTextSize(FM_SHORT_NAME(FM_AM)).y+ImGui::GetStyle().ItemSpacing.y):0.0f); - float textX_tl=ImGui::GetCursorPosX(); - P(CWVSliderScalar("##TL",ImVec2(tlSliderWidth,tlSliderHeight),ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); rightClickable - - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPM) { - CENTER_TEXT(FM_SHORT_NAME(FM_AM)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_AM)); - TOOLTIP_TEXT(FM_NAME(FM_AM)); - bool amOn=op.am; - if (ImGui::Checkbox("##AM",&amOn)) { PARAMETER - op.am=amOn; - } - } - - if (ins->type==DIV_INS_ESFM) { - ImGui::SameLine(); - float textX_outLvl=ImGui::GetCursorPosX(); - P(CWVSliderScalar("##OUTLVL",ImVec2(tlSliderWidth,tlSliderHeight),ImGuiDataType_U8,&opE.outLvl,&_ZERO,&_SEVEN)); rightClickable - - ImGui::SameLine(); - float textX_modIn=ImGui::GetCursorPosX(); - P(CWVSliderScalar("##MODIN",ImVec2(tlSliderWidth,tlSliderHeight),ImGuiDataType_U8,&opE.modIn,&_ZERO,&_SEVEN)); rightClickable - - prevCurPos=ImGui::GetCursorPos(); - ImGui::SetCursorPos(ImVec2(textX_tl,textY)); - CENTER_TEXT_20(FM_SHORT_NAME(FM_TL)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_TL)); - TOOLTIP_TEXT(FM_NAME(FM_TL)); - - ImGui::SetCursorPos(ImVec2(textX_outLvl,textY)); - CENTER_TEXT_20(ESFM_SHORT_NAME(ESFM_OUTLVL)); - ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_OUTLVL)); - TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_OUTLVL)); - - ImGui::SetCursorPos(ImVec2(textX_modIn,textY)); - CENTER_TEXT_20(ESFM_SHORT_NAME(ESFM_MODIN)); - ImGui::TextUnformatted(ESFM_SHORT_NAME(ESFM_MODIN)); - TOOLTIP_TEXT(ESFM_LONG_NAME(ESFM_MODIN)); - - ImGui::SetCursorPos(prevCurPos); - } else { - prevCurPos=ImGui::GetCursorPos(); - ImGui::SetCursorPos(ImVec2(textX_tl,textY)); - CENTER_TEXT(FM_SHORT_NAME(FM_TL)); - ImGui::TextUnformatted(FM_SHORT_NAME(FM_TL)); - TOOLTIP_TEXT(FM_NAME(FM_TL)); - - ImGui::SetCursorPos(prevCurPos); - } - - ImGui::EndTable(); - } - ImGui::PopStyleVar(); - - if (settings.separateFMColors) { - popAccentColors(); - } - - ImGui::PopID(); - } - ImGui::EndTable(); - } - ImGui::PopStyleVar(); - } else { // classic - int columns=2; - switch (settings.fmLayout) { - case 1: // 2x2 - columns=2; - break; - case 2: // 1x4 - columns=1; - break; - case 3: // 4x1 - columns=opCount; - break; - } - if (ImGui::BeginTable("FMOperators",columns,ImGuiTableFlags_SizingStretchSame)) { - for (int i=0; itype!=DIV_INS_OPL_DRUMS && ins->type!=DIV_INS_ESFM)?opOrder[i]:i]; - DivInstrumentESFM::Operator& opE=ins->esfm.op[i]; - if ((settings.fmLayout!=3 && ((i+1)&1)) || i==0 || settings.fmLayout==2) ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::Separator(); - ImGui::PushID(fmt::sprintf("op%d",i).c_str()); - - // push colors - if (settings.separateFMColors) { - bool mod=true; - if (ins->type==DIV_INS_OPL_DRUMS) { - mod=false; - } else if (ins->type==DIV_INS_ESFM) { - // this is the same as the KVS heuristic in platform/esfm.h - if (opE.outLvl==7) { - mod=false; - } else if (opE.outLvl>0) { - if (i==3) { - mod=false; - } else { - DivInstrumentESFM::Operator& opENext=ins->esfm.op[i+1]; - if (opENext.modIn==0) { - mod=false; - } else if ((opE.outLvl-opENext.modIn)>=2) { - mod=false; - } - } - } - } else if (opCount==4) { - if (ins->type==DIV_INS_OPL) { - if (opIsOutputOPL[fmOrigin.alg&3][i]) mod=false; - } else { - if (opIsOutput[fmOrigin.alg&7][i]) mod=false; - } - } else { - if (i==1 || (ins->type==DIV_INS_OPL && (fmOrigin.alg&1))) mod=false; - } - if (mod) { - pushAccentColors( - uiColors[GUI_COLOR_FM_PRIMARY_MOD], - uiColors[GUI_COLOR_FM_SECONDARY_MOD], - uiColors[GUI_COLOR_FM_BORDER_MOD], - uiColors[GUI_COLOR_FM_BORDER_SHADOW_MOD] - ); - } else { - pushAccentColors( - uiColors[GUI_COLOR_FM_PRIMARY_CAR], - uiColors[GUI_COLOR_FM_SECONDARY_CAR], - uiColors[GUI_COLOR_FM_BORDER_CAR], - uiColors[GUI_COLOR_FM_BORDER_SHADOW_CAR] - ); - } - } - - ImGui::Dummy(ImVec2(dpiScale,dpiScale)); - String opNameLabel; - OP_DRAG_POINT; - ImGui::SameLine(); - if (ins->type==DIV_INS_OPL_DRUMS) { - opNameLabel=fmt::sprintf("%s",oplDrumNames[i]); - } else if (ins->type==DIV_INS_OPL && fmOrigin.opllPreset==16) { - if (i==1) { - opNameLabel="Envelope 2 (kick only)"; - } else { - opNameLabel="Envelope"; - } - } else { - opNameLabel=fmt::sprintf("OP%d",i+1); - } - if (opsAreMutable) { - pushToggleColors(op.enable); - if (ImGui::Button(opNameLabel.c_str())) { - op.enable=!op.enable; - PARAMETER; - } - popToggleColors(); - } else { - ImGui::TextUnformatted(opNameLabel.c_str()); - } - - ImGui::SameLine(); - - bool amOn=op.am; - if (ImGui::Checkbox(FM_NAME(FM_AM),&amOn)) { PARAMETER - op.am=amOn; - } - - int maxTl=127; - if (ins->type==DIV_INS_OPLL) { - if (i==1) { - maxTl=15; - } else { - maxTl=63; - } - } - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) { - maxTl=63; - } - int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM)?31:15; - - bool ssgOn=op.ssgEnv&8; - bool ksrOn=op.ksr; - bool vibOn=op.vib; - bool susOn=op.sus; // don't you make fun of this one - unsigned char ssgEnv=op.ssgEnv&7; - if (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) { - ImGui::SameLine(); - if (ImGui::Checkbox((ins->type==DIV_INS_OPLL)?FM_NAME(FM_EGS):"SSG On",&ssgOn)) { PARAMETER - op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3); - } - } - - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) { - ImGui::SameLine(); - if (ImGui::Checkbox(FM_NAME(FM_SUS),&susOn)) { PARAMETER - op.sus=susOn; - } - } - - if (ins->type==DIV_INS_OPZ) { - ImGui::SameLine(); - bool fixedOn=op.egt; - if (ImGui::Checkbox("Fixed",&fixedOn)) { PARAMETER - op.egt=fixedOn; - } - } - - //52.0 controls vert scaling; default 96 - drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_ESFM)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,fmOrigin.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,52.0*dpiScale),ins->type); - //P(CWSliderScalar(FM_NAME(FM_AR),ImGuiDataType_U8,&op.ar,&_ZERO,&_THIRTY_ONE)); rightClickable - if (ImGui::BeginTable("opParams",2,ImGuiTableFlags_SizingStretchProp)) { - ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); \ - ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,0.0); \ - - if (ins->type==DIV_INS_ESFM) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - opE.delay&=7; - P(CWSliderScalar("##DELAY",ImGuiDataType_U8,&opE.delay,&_ZERO,&_SEVEN)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",ESFM_NAME(ESFM_DELAY)); - } - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - op.ar&=maxArDr; - P(CWSliderScalar("##AR",ImGuiDataType_U8,&op.ar,&maxArDr,&_ZERO)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_AR)); - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - op.dr&=maxArDr; - P(CWSliderScalar("##DR",ImGuiDataType_U8,&op.dr,&maxArDr,&_ZERO)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_DR)); - - if (settings.susPosition==0) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##SL",ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_SL)); - } - - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##D2R",ImGuiDataType_U8,&op.d2r,&_THIRTY_ONE,&_ZERO)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_D2R)); - } - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##RR",ImGuiDataType_U8,&op.rr,&_FIFTEEN,&_ZERO)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_RR)); - - if (settings.susPosition==1) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##SL",ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_SL)); - } - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - op.tl&=maxTl; - P(CWSliderScalar("##TL",ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_TL)); - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::Separator(); - ImGui::TableNextColumn(); - ImGui::Separator(); - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { - P(CWSliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_RS)); - } else { - int ksl=ins->type==DIV_INS_OPLL?op.ksl:kslMap[op.ksl&3]; - if (CWSliderInt("##KSL",&ksl,0,3)) { - op.ksl=(ins->type==DIV_INS_OPLL?ksl:kslMap[ksl&3]); - PARAMETER; - } rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_KSL)); - } - - if (ins->type==DIV_INS_OPZ) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar(FM_NAME(FM_EGSHIFT),ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_EGSHIFT)); - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar(FM_NAME(FM_REV),ImGuiDataType_U8,&op.dam,&_ZERO,&_SEVEN)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_REV)); - } - - if (ins->type==DIV_INS_OPZ) { - if (op.egt) { - int block=op.dt; - int freqNum=(op.mult<<4)|(op.dvb&15); - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - if (CWSliderInt(FM_NAME(FM_MULT),&block,0,7)) { PARAMETER - if (block<0) block=0; - if (block>7) block=7; - op.dt=block; - } rightClickable - ImGui::TableNextColumn(); - ImGui::Text("Block"); - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - if (CWSliderInt(FM_NAME(FM_FINE),&freqNum,0,255)) { PARAMETER - if (freqNum<0) freqNum=0; - if (freqNum>255) freqNum=255; - op.mult=freqNum>>4; - op.dvb=freqNum&15; - } rightClickable - ImGui::TableNextColumn(); - ImGui::Text("FreqNum"); - } else { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar(FM_NAME(FM_MULT),ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_MULT)); - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar(FM_NAME(FM_FINE),ImGuiDataType_U8,&op.dvb,&_ZERO,&_FIFTEEN)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_FINE)); - } - } else { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar(FM_NAME(FM_MULT),ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_MULT)); - } - - if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPM) { - if (!(ins->type==DIV_INS_OPZ && op.egt)) { - int detune=detuneMap[settings.unsignedDetune?1:0][op.dt&7]; - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - if (CWSliderInt("##DT",&detune,settings.unsignedDetune?0:-3,settings.unsignedDetune?7:4)) { PARAMETER - if (detune<-3) detune=-3; - if (detune>7) detune=7; - op.dt=detuneUnmap[settings.unsignedDetune?1:0][detune+3]; - } rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_DT)); - } - - if (ins->type!=DIV_INS_FM) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##DT2",ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_DT2)); - } - - if (ins->type==DIV_INS_FM) { // OPN only - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - if (CWSliderScalar("##SSG",ImGuiDataType_U8,&ssgEnv,&_ZERO,&_SEVEN,ssgEnvTypes[ssgEnv])) { PARAMETER - op.ssgEnv=(op.ssgEnv&8)|(ssgEnv&7); - } rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_SSG)); - } - } - - if (ins->type==DIV_INS_ESFM) { - bool fixedOn=opE.fixed; - if (fixedOn) { - int block=(opE.ct>>2)&7; - int freqNum=((opE.ct&3)<<8)|((unsigned char)opE.dt); - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - if (ImGui::InputInt("##Block",&block,1,1)) { - if (block<0) block=0; - if (block>7) block=7; - opE.ct=(opE.ct&(~(7<<2)))|(block<<2); - } - ImGui::TableNextColumn(); - ImGui::Text("Block"); - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - if (ImGui::InputInt("##FreqNum",&freqNum,1,16)) { - if (freqNum<0) freqNum=0; - if (freqNum>1023) freqNum=1023; - opE.dt=freqNum&0xff; - opE.ct=(opE.ct&(~3))|(freqNum>>8); - } - ImGui::TableNextColumn(); - ImGui::Text("FreqNum"); - } else { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##CT",ImGuiDataType_S8,&opE.ct,&_MINUS_TWENTY_FOUR,&_TWENTY_FOUR)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",ESFM_NAME(ESFM_CT)); - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##DT",ImGuiDataType_S8,&opE.dt,&_MINUS_ONE_HUNDRED_TWENTY_EIGHT,&_ONE_HUNDRED_TWENTY_SEVEN)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",ESFM_NAME(ESFM_DT)); - } - - } - - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_ESFM) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##WS",ImGuiDataType_U8,&op.ws,&_ZERO,&_SEVEN,(ins->type==DIV_INS_OPZ)?opzWaveforms[op.ws&7]:(settings.oplStandardWaveNames?oplWaveformsStandard[op.ws&7]:oplWaveforms[op.ws&7]))); rightClickable - if ((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS) && ImGui::IsItemHovered()) { - ImGui::SetTooltip("OPL2/3 only (last 4 waveforms are OPL3 only)"); - } - ImGui::TableNextColumn(); - ImGui::Text("%s",FM_NAME(FM_WS)); - } - - if (ins->type==DIV_INS_ESFM) { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::Separator(); - ImGui::TableNextColumn(); - ImGui::Separator(); - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##OUTLVL",ImGuiDataType_U8,&opE.outLvl,&_ZERO,&_SEVEN)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",ESFM_NAME(ESFM_OUTLVL)); - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(CWSliderScalar("##MODIN",ImGuiDataType_U8,&opE.modIn,&_ZERO,&_SEVEN)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("%s",ESFM_NAME(ESFM_MODIN)); - } - - ImGui::EndTable(); - } - - if (ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_ESFM) { - if (ImGui::Checkbox(FM_NAME(FM_VIB),&vibOn)) { PARAMETER - op.vib=vibOn; - } - ImGui::SameLine(); - if (ImGui::Checkbox(FM_NAME(FM_KSR),&ksrOn)) { PARAMETER - op.ksr=ksrOn; - } - } - - if (ins->type==DIV_INS_ESFM) { - bool dvbOn=op.dvb; - bool damOn=op.dam; - bool leftOn=opE.left; - bool rightOn=opE.right; - bool fixedOn=opE.fixed; - if (ImGui::Checkbox(FM_NAME(FM_DVB),&dvbOn)) { PARAMETER - op.dvb=dvbOn; - } - ImGui::SameLine(); - if (ImGui::Checkbox(FM_NAME(FM_DAM),&damOn)) { PARAMETER - op.dam=damOn; - } - if (ImGui::Checkbox(ESFM_NAME(ESFM_LEFT),&leftOn)) { PARAMETER - opE.left=leftOn; - } - ImGui::SameLine(); - if (ImGui::Checkbox(ESFM_NAME(ESFM_RIGHT),&rightOn)) { PARAMETER - opE.right=rightOn; - } - ImGui::SameLine(); - if (ImGui::Checkbox(ESFM_NAME(ESFM_FIXED),&fixedOn)) { PARAMETER - opE.fixed=fixedOn; - // HACK: reset zoom and scroll in fixed pitch macros so that they draw correctly - ins->std.opMacros[i].ssgMacro.vZoom=-1; - ins->std.opMacros[i].dtMacro.vZoom=-1; - } - } - - if (settings.separateFMColors) { - popAccentColors(); - } - - ImGui::PopID(); - } - ImGui::EndTable(); - } - } - ImGui::EndDisabled(); - ImGui::EndTabItem(); - } if (ins->type!=DIV_INS_ESFM) { if (ImGui::BeginTabItem("FM Macros")) { if (ins->type==DIV_INS_OPLL) { From 74df8a5d5e418de2fb5ebe95328f3913be0cb226 Mon Sep 17 00:00:00 2001 From: Brad Smith Date: Sun, 5 May 2024 08:06:31 -0400 Subject: [PATCH 08/22] Replace hardcoded use of libdl with CMAKE_DL_LIBS Replace the hardcoded use of libdl. *BSD's do not have libdl and other OS's might not as well. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41188fd9e..edd581b6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1082,7 +1082,7 @@ elseif (APPLE) find_library(COCOA Cocoa REQUIRED) list(APPEND DEPENDENCIES_LIBRARIES ${COCOA}) else() - list(APPEND DEPENDENCIES_LIBRARIES dl) + list(APPEND DEPENDENCIES_LIBRARIES ${CMAKE_DL_LIBS}) endif() if (NOT MSVC) From b4059d69da08a7dc303cda80b0e819128b441e4d Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 5 May 2024 16:49:05 -0500 Subject: [PATCH 09/22] script to make console release --- .gitignore | 1 + scripts/release-winconsole.sh | 42 +++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100755 scripts/release-winconsole.sh diff --git a/.gitignore b/.gitignore index c57b41113..f31a9c094 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ nosdl/ release/ t/ winbuild/ +winCbuild/ win32build/ xpbuild/ macbuild/ diff --git a/scripts/release-winconsole.sh b/scripts/release-winconsole.sh new file mode 100755 index 000000000..72a4c1453 --- /dev/null +++ b/scripts/release-winconsole.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# make Windows release +# this script shall be run from Arch Linux with MinGW installed! + +if [ ! -e /tmp/furnace ]; then + ln -s "$PWD" /tmp/furnace || exit 1 +fi + +cd /tmp/furnace + +if [ ! -e winCbuild ]; then + mkdir winCbuild || exit 1 +fi + +cd winCbuild + +# TODO: potential Arch-ism? +x86_64-w64-mingw32-cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS="-O2" -DCMAKE_CXX_FLAGS="-O2 -Wall -Wextra -Wno-unused-parameter -Wno-cast-function-type -Wno-deprecated-declarations -Werror" -DUSE_BACKWARD=ON -DCONSOLE_SUBSYSTEM=ON .. || exit 1 +make -j8 || exit 1 + +cd .. + +mkdir -p release/winconsole || exit 1 +cd release/winconsole + +cp ../../LICENSE LICENSE.txt || exit 1 +cp ../../winCbuild/furnace.exe . || exit 1 +cp ../../res/releaseReadme/stable-win.txt README.txt || exit 1 +cp -r ../../papers papers || exit 1 +cp -r ../../demos demos || exit 1 +cp -r ../../instruments instruments || exit 1 +cp -r ../../wavetables wavetables || exit 1 + +cp ../../res/docpdf/manual.pdf . || exit 1 + +x86_64-w64-mingw32-strip -s furnace.exe || exit 1 + +zip -r furnace.zip LICENSE.txt furnace.exe README.txt manual.pdf papers demos instruments wavetables + +furName=$(git describe --tags | sed "s/v0/0/") + +mv furnace.zip furnace-"$furName"-win64-console.zip From b5b85098402a57a8048d989d727a8f9df5119388 Mon Sep 17 00:00:00 2001 From: Brad Smith Date: Sun, 5 May 2024 18:22:22 -0400 Subject: [PATCH 10/22] Fix build on OpenBSD IGFD appears to be a fork but I pushed this upstream as well. https://github.com/aiekick/ImGuiFileDialog/commit/30a00cf727b62c90fb667eefad06080786ca4616 --- extern/igfd/ImGuiFileDialog.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/igfd/ImGuiFileDialog.cpp b/extern/igfd/ImGuiFileDialog.cpp index b53cdf7d6..5628f0401 100644 --- a/extern/igfd/ImGuiFileDialog.cpp +++ b/extern/igfd/ImGuiFileDialog.cpp @@ -54,7 +54,7 @@ SOFTWARE. #ifndef PATH_MAX #define PATH_MAX 260 #endif // PATH_MAX -#elif defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) || defined (__EMSCRIPTEN__) || defined(__HAIKU__) +#elif defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined (__EMSCRIPTEN__) || defined(__HAIKU__) #define UNIX #define stricmp strcasecmp #include From d16e940c4dd87ab0b48ac290839ea9859ec4dbd9 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 6 May 2024 16:40:19 -0500 Subject: [PATCH 11/22] fall back to software if no matching GL pixel form at available --- src/gui/gui.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 168bf614d..6fd70bd23 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -6987,7 +6987,14 @@ bool FurnaceGUI::init() { logD("creating window..."); sdlWin=SDL_CreateWindow("Furnace",scrX,scrY,scrW,scrH,SDL_WINDOW_RESIZABLE|SDL_WINDOW_ALLOW_HIGHDPI|(scrMax?SDL_WINDOW_MAXIMIZED:0)|(fullScreen?SDL_WINDOW_FULLSCREEN_DESKTOP:0)|rend->getWindowFlags()); if (sdlWin==NULL) { - lastError=fmt::sprintf("could not open window! %s",SDL_GetError()); + const char* sdlErr=SDL_GetError(); + lastError=fmt::sprintf("could not open window! %s",sdlErr); + if (settings.renderBackend!="Software" && strcmp(sdlErr,"No matching GL pixel format available")==0) { + settings.renderBackend="Software"; + e->setConf("renderBackend","Software"); + e->saveConf(); + lastError+="\r\nfalling back to software renderer. please restart Furnace."; + } return false; } From 542206bbb7f2d0dd73a2551b8bbbe53c153728db Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 6 May 2024 23:24:57 -0500 Subject: [PATCH 12/22] GUI: add action to move selected content in pattern editor TODO: CHECK FOR CVE --- src/gui/doAction.cpp | 12 ++++++++++++ src/gui/editing.cpp | 19 +++++++++++++++++++ src/gui/gui.h | 5 +++++ src/gui/guiConst.cpp | 4 ++++ src/gui/settings.cpp | 4 ++++ 5 files changed, 44 insertions(+) diff --git a/src/gui/doAction.cpp b/src/gui/doAction.cpp index 975be07b8..7dd184691 100644 --- a/src/gui/doAction.cpp +++ b/src/gui/doAction.cpp @@ -555,6 +555,18 @@ void FurnaceGUI::doAction(int what) { case GUI_ACTION_PAT_SELECTION_DOWN_COARSE: moveCursor(0,editStepCoarse,true); break; + case GUI_ACTION_PAT_MOVE_UP: + moveSelected(0,-1); + break; + case GUI_ACTION_PAT_MOVE_DOWN: + moveSelected(0,1); + break; + case GUI_ACTION_PAT_MOVE_LEFT_CHANNEL: + moveSelected(-1,0); + break; + case GUI_ACTION_PAT_MOVE_RIGHT_CHANNEL: + moveSelected(1,0); + break; case GUI_ACTION_PAT_DELETE: doDelete(); if (settings.stepOnDelete) { diff --git a/src/gui/editing.cpp b/src/gui/editing.cpp index fcd033913..dad5f3efb 100644 --- a/src/gui/editing.cpp +++ b/src/gui/editing.cpp @@ -1842,6 +1842,25 @@ void FurnaceGUI::doDrag() { makeUndo(GUI_UNDO_PATTERN_DRAG); } +void FurnaceGUI::moveSelected(int x, int y) { + prepareUndo(GUI_UNDO_PATTERN_DRAG); + + // copy and clear + String c=doCopy(true,false,selStart,selEnd); + + logV("copy: %s",c); + + // replace + selStart.xCoarse+=x; + selEnd.xCoarse+=x; + selStart.y+=y; + selEnd.y+=y; + cursor=selStart; + doPaste(GUI_PASTE_MODE_NORMAL,0,false,c); + + makeUndo(GUI_UNDO_PATTERN_DRAG); +} + void FurnaceGUI::doUndo() { if (undoHist.empty()) return; UndoStep& us=undoHist.back(); diff --git a/src/gui/gui.h b/src/gui/gui.h index 3b050e066..0f1839130 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -778,6 +778,10 @@ enum FurnaceGUIActions { GUI_ACTION_PAT_SELECTION_END, GUI_ACTION_PAT_SELECTION_UP_COARSE, GUI_ACTION_PAT_SELECTION_DOWN_COARSE, + GUI_ACTION_PAT_MOVE_UP, + GUI_ACTION_PAT_MOVE_DOWN, + GUI_ACTION_PAT_MOVE_LEFT_CHANNEL, + GUI_ACTION_PAT_MOVE_RIGHT_CHANNEL, GUI_ACTION_PAT_DELETE, GUI_ACTION_PAT_PULL_DELETE, GUI_ACTION_PAT_INSERT, @@ -2783,6 +2787,7 @@ class FurnaceGUI { void doDelete(); void doPullDelete(); void doInsert(); + void moveSelected(int x, int y); void doTranspose(int amount, OperationMask& mask); String doCopy(bool cut, bool writeClipboard, const SelectionPoint& sStart, const SelectionPoint& sEnd); void doPasteFurnace(PasteMode mode, int arg, bool readClipboard, String clipb, std::vector data, int startOff, bool invalidData, UndoRegion ur); diff --git a/src/gui/guiConst.cpp b/src/gui/guiConst.cpp index f3ea831df..fccc5b86c 100644 --- a/src/gui/guiConst.cpp +++ b/src/gui/guiConst.cpp @@ -659,6 +659,10 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={ D("PAT_SELECTION_END", "Expand selection to end of pattern", 0), D("PAT_SELECTION_UP_COARSE", "Expand selection upwards (coarse)", FURKMOD_SHIFT|SDLK_PAGEUP), D("PAT_SELECTION_DOWN_COARSE", "Expand selection downwards (coarse)", FURKMOD_SHIFT|SDLK_PAGEDOWN), + D("PAT_MOVE_UP", "Move selection up", FURKMOD_ALT|SDLK_UP), + D("PAT_MOVE_DOWN", "Move selection down", FURKMOD_ALT|SDLK_DOWN), + D("PAT_MOVE_LEFT_CHANNEL", "Move selection to previous channel", FURKMOD_ALT|SDLK_LEFT), + D("PAT_MOVE_RIGHT_CHANNEL", "Move selection to next channel", FURKMOD_ALT|SDLK_RIGHT), D("PAT_DELETE", "Delete", SDLK_DELETE), D("PAT_PULL_DELETE", "Pull delete", SDLK_BACKSPACE), D("PAT_INSERT", "Insert", SDLK_INSERT), diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 83ce9ede0..a3281d4a9 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -2106,6 +2106,10 @@ void FurnaceGUI::drawSettings() { UI_KEYBIND_CONFIG(GUI_ACTION_PAT_SELECTION_END); UI_KEYBIND_CONFIG(GUI_ACTION_PAT_SELECTION_UP_COARSE); UI_KEYBIND_CONFIG(GUI_ACTION_PAT_SELECTION_DOWN_COARSE); + UI_KEYBIND_CONFIG(GUI_ACTION_PAT_MOVE_UP); + UI_KEYBIND_CONFIG(GUI_ACTION_PAT_MOVE_DOWN); + UI_KEYBIND_CONFIG(GUI_ACTION_PAT_MOVE_LEFT_CHANNEL); + UI_KEYBIND_CONFIG(GUI_ACTION_PAT_MOVE_RIGHT_CHANNEL); UI_KEYBIND_CONFIG(GUI_ACTION_PAT_DELETE); UI_KEYBIND_CONFIG(GUI_ACTION_PAT_PULL_DELETE); UI_KEYBIND_CONFIG(GUI_ACTION_PAT_INSERT); From c2565b1300eb3050c5bcc3c6de725a0e707198bc Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 7 May 2024 02:09:44 -0500 Subject: [PATCH 13/22] AY8930: fix typo in noise freq effect --- src/engine/sysDef.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index 0a537f4a6..dd05313ba 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -437,14 +437,23 @@ void DivEngine::registerSystems() { {0x2f, {DIV_CMD_AY_IO_WRITE, "2Fxx: Write to I/O port B", constVal<1>, effectVal}}, }; - EffectHandlerMap ay8930PostEffectHandlerMap(ayPostEffectHandlerMap); - ay8930PostEffectHandlerMap.insert({ + EffectHandlerMap ay8930PostEffectHandlerMap={ + {0x20, {DIV_CMD_STD_NOISE_MODE, "20xx: Set channel mode (bit 0: square; bit 1: noise; bit 2: envelope)"}}, + {0x21, {DIV_CMD_STD_NOISE_FREQ, "21xx: Set noise frequency (0 to FF)"}}, + {0x22, {DIV_CMD_AY_ENVELOPE_SET, "22xy: Set envelope mode (x: shape, y: enable for this channel)"}}, + {0x23, {DIV_CMD_AY_ENVELOPE_LOW, "23xx: Set envelope period low byte"}}, + {0x24, {DIV_CMD_AY_ENVELOPE_HIGH, "24xx: Set envelope period high byte"}}, + {0x25, {DIV_CMD_AY_ENVELOPE_SLIDE, "25xx: Envelope slide up", negEffectVal}}, + {0x26, {DIV_CMD_AY_ENVELOPE_SLIDE, "26xx: Envelope slide down"}}, + {0x29, {DIV_CMD_AY_AUTO_ENVELOPE, "29xy: Set auto-envelope (x: numerator; y: denominator)"}}, + {0x2e, {DIV_CMD_AY_IO_WRITE, "2Exx: Write to I/O port A", constVal<0>, effectVal}}, + {0x2f, {DIV_CMD_AY_IO_WRITE, "2Fxx: Write to I/O port B", constVal<1>, effectVal}}, {0x12, {DIV_CMD_STD_NOISE_MODE, "12xx: Set duty cycle (0 to 8)", [](unsigned char, unsigned char val) -> int { return 0x10+(val&15); }}}, {0x27, {DIV_CMD_AY_NOISE_MASK_AND, "27xx: Set noise AND mask"}}, {0x28, {DIV_CMD_AY_NOISE_MASK_OR, "28xx: Set noise OR mask"}}, {0x2d, {DIV_CMD_AY_IO_WRITE, "2Dxx: NOT TO BE EMPLOYED BY THE COMPOSER", constVal<255>, effectVal}}, - }); + }; EffectHandlerMap fmEffectHandlerMap={ {0x30, {DIV_CMD_FM_HARD_RESET, "30xx: Toggle hard envelope reset on new notes"}}, From f64adfa8ddff549a6fc3d447c5d5a66a62ef77ad Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 7 May 2024 02:31:22 -0500 Subject: [PATCH 14/22] AY8930: finally implement auto noise freq --- src/engine/platform/ay8930.cpp | 29 +++++++++++++++++++++++++++++ src/engine/platform/ay8930.h | 8 +++++--- src/engine/sysDef.cpp | 1 + 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/engine/platform/ay8930.cpp b/src/engine/platform/ay8930.cpp index 12171b162..68e25740a 100644 --- a/src/engine/platform/ay8930.cpp +++ b/src/engine/platform/ay8930.cpp @@ -362,6 +362,29 @@ void DivPlatformAY8930::tick(bool sysTick) { immWrite(regPeriodL[i],chan[i].envelope.period); immWrite(regPeriodH[i],chan[i].envelope.period>>8); } + if (chan[i].freqChanged && chan[i].autoNoiseMode) { + int noiseFreq=chan[i].freq; + switch (chan[i].autoNoiseMode) { + case 1: // noise + noiseFreq+=chan[i].autoNoiseOff; + if (noiseFreq<0) noiseFreq=0; + if (noiseFreq>255) noiseFreq=255; + rWrite(0x06,noiseFreq); + break; + case 2: { // noise + OR mask + if (noiseFreq<0) noiseFreq=0; + int noiseDiv=(noiseFreq>>8)+1; + noiseFreq/=noiseDiv; + ayNoiseOr=noiseDiv; + immWrite(0x1a,ayNoiseOr); + noiseFreq+=chan[i].autoNoiseOff; + if (noiseFreq<0) noiseFreq=0; + if (noiseFreq>255) noiseFreq=255; + rWrite(0x06,noiseFreq); + break; + } + } + } chan[i].freqChanged=false; } @@ -632,6 +655,12 @@ int DivPlatformAY8930::dispatch(DivCommand c) { chan[c.chan].autoEnvDen=c.value&15; chan[c.chan].freqChanged=true; break; + case DIV_CMD_AY_AUTO_PWM: + chan[c.chan].autoNoiseMode=c.value>>4; + chan[c.chan].autoNoiseOff=c.value&15; + if (chan[c.chan].autoNoiseOff>=8) chan[c.chan].autoNoiseOff-=16; + chan[c.chan].freqChanged=true; + break; case DIV_CMD_AY_IO_WRITE: if (c.value==255) { immWrite(0x1f,c.value2); diff --git a/src/engine/platform/ay8930.h b/src/engine/platform/ay8930.h index 457601848..e9f3cf21e 100644 --- a/src/engine/platform/ay8930.h +++ b/src/engine/platform/ay8930.h @@ -77,8 +77,8 @@ class DivPlatformAY8930: public DivDispatch { setPos(false) {} } dac; - unsigned char autoEnvNum, autoEnvDen, duty; - signed char konCycles; + unsigned char autoEnvNum, autoEnvDen, duty, autoNoiseMode; + signed char konCycles, autoNoiseOff; Channel(): SharedChannel(31), envelope(Envelope()), @@ -88,7 +88,9 @@ class DivPlatformAY8930: public DivDispatch { autoEnvNum(0), autoEnvDen(0), duty(4), - konCycles(0) {} + autoNoiseMode(0), + konCycles(0), + autoNoiseOff(0) {} }; Channel chan[3]; bool isMuted[3]; diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index dd05313ba..45e0bb52a 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -452,6 +452,7 @@ void DivEngine::registerSystems() { [](unsigned char, unsigned char val) -> int { return 0x10+(val&15); }}}, {0x27, {DIV_CMD_AY_NOISE_MASK_AND, "27xx: Set noise AND mask"}}, {0x28, {DIV_CMD_AY_NOISE_MASK_OR, "28xx: Set noise OR mask"}}, + {0x2c, {DIV_CMD_AY_AUTO_PWM, "2Cxy: Automatic noise frequency (x: mode (0: disable, 1: freq, 2: freq + OR mask); y: offset"}}, {0x2d, {DIV_CMD_AY_IO_WRITE, "2Dxx: NOT TO BE EMPLOYED BY THE COMPOSER", constVal<255>, effectVal}}, }; From 44f45c24fd82d2d871dc99f93d392a02ea93ee6a Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 7 May 2024 03:37:43 -0500 Subject: [PATCH 15/22] update to-do list --- TODO.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/TODO.md b/TODO.md index d76bef7a5..b08c462b3 100644 --- a/TODO.md +++ b/TODO.md @@ -1,3 +1,8 @@ +# to-do for 0.6.4 + +- fix possible issues when moving selection +- fix Metal intro crash + # to-do long term - finish auto-clone From 5f89cb1dea4fb70ad26f2df4fc7e15b771171145 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 7 May 2024 11:51:54 -0500 Subject: [PATCH 16/22] make a macOS debug build --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 44f446483..25d974271 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,7 @@ defaults: shell: bash env: - BUILD_TYPE: RelWithDebInfo + BUILD_TYPE: Debug jobs: build: From ae386f6269f97107a0774eac3d42daaddd723cc6 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 7 May 2024 13:44:16 -0500 Subject: [PATCH 17/22] GUI: add render preInit settings --- src/gui/gui.cpp | 2 +- src/gui/gui.h | 14 +++++- src/gui/render/abstract.cpp | 2 +- src/gui/render/renderDX11.cpp | 2 +- src/gui/render/renderDX11.h | 2 +- src/gui/render/renderGL.cpp | 14 +++--- src/gui/render/renderGL.h | 2 +- src/gui/render/renderGL1.cpp | 16 +++--- src/gui/render/renderGL1.h | 2 +- src/gui/render/renderMetal.h | 2 +- src/gui/render/renderMetal.mm | 2 +- src/gui/render/renderSDL.cpp | 2 +- src/gui/render/renderSDL.h | 2 +- src/gui/render/renderSoftware.cpp | 2 +- src/gui/render/renderSoftware.h | 2 +- src/gui/settings.cpp | 84 ++++++++++++++++++++++++++----- 16 files changed, 111 insertions(+), 41 deletions(-) diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 6fd70bd23..5a5c36467 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -6982,7 +6982,7 @@ bool FurnaceGUI::init() { return false; } - rend->preInit(); + rend->preInit(e->getConfObject()); logD("creating window..."); sdlWin=SDL_CreateWindow("Furnace",scrX,scrY,scrW,scrH,SDL_WINDOW_RESIZABLE|SDL_WINDOW_ALLOW_HIGHDPI|(scrMax?SDL_WINDOW_MAXIMIZED:0)|(fullScreen?SDL_WINDOW_FULLSCREEN_DESKTOP:0)|rend->getWindowFlags()); diff --git a/src/gui/gui.h b/src/gui/gui.h index 0f1839130..90e181259 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1509,7 +1509,7 @@ class FurnaceGUIRender { virtual const char* getDeviceName(); virtual const char* getAPIVersion(); virtual void setSwapInterval(int swapInterval); - virtual void preInit(); + virtual void preInit(const DivConfig& conf); virtual bool init(SDL_Window* win, int swapInterval); virtual void initGUI(SDL_Window* win); virtual void quitGUI(); @@ -1896,6 +1896,12 @@ class FurnaceGUI { int frameRateLimit; int displayRenderTime; int inputRepeat; + int glRedSize; + int glGreenSize; + int glBlueSize; + int glAlphaSize; + int glDepthSize; + int glDoubleBuffer; unsigned int maxUndoSteps; float vibrationStrength; int vibrationLength; @@ -2139,6 +2145,12 @@ class FurnaceGUI { frameRateLimit(60), displayRenderTime(0), inputRepeat(0), + glRedSize(8), + glGreenSize(8), + glBlueSize(8), + glAlphaSize(0), + glDepthSize(24), + glDoubleBuffer(1), maxUndoSteps(100), vibrationStrength(0.5f), vibrationLength(20), diff --git a/src/gui/render/abstract.cpp b/src/gui/render/abstract.cpp index c8d9be046..48710cb2f 100644 --- a/src/gui/render/abstract.cpp +++ b/src/gui/render/abstract.cpp @@ -128,7 +128,7 @@ const char* FurnaceGUIRender::getAPIVersion() { void FurnaceGUIRender::setSwapInterval(int swapInterval) { } -void FurnaceGUIRender::preInit() { +void FurnaceGUIRender::preInit(const DivConfig& conf) { } bool FurnaceGUIRender::init(SDL_Window* win, int swapInterval) { diff --git a/src/gui/render/renderDX11.cpp b/src/gui/render/renderDX11.cpp index 83ef53520..75ff58fc9 100644 --- a/src/gui/render/renderDX11.cpp +++ b/src/gui/render/renderDX11.cpp @@ -397,7 +397,7 @@ void FurnaceGUIRenderDX11::setSwapInterval(int swapInt) { swapInterval=swapInt; } -void FurnaceGUIRenderDX11::preInit() { +void FurnaceGUIRenderDX11::preInit(const DivConfig& conf) { } const float wipeVertices[4][4]={ diff --git a/src/gui/render/renderDX11.h b/src/gui/render/renderDX11.h index eba32218c..1fd015122 100644 --- a/src/gui/render/renderDX11.h +++ b/src/gui/render/renderDX11.h @@ -89,7 +89,7 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender { const char* getDeviceName(); const char* getAPIVersion(); void setSwapInterval(int swapInterval); - void preInit(); + void preInit(const DivConfig& conf); bool init(SDL_Window* win, int swapInterval); void initGUI(SDL_Window* win); void quitGUI(); diff --git a/src/gui/render/renderGL.cpp b/src/gui/render/renderGL.cpp index f8ba1a0d4..dffd16d20 100644 --- a/src/gui/render/renderGL.cpp +++ b/src/gui/render/renderGL.cpp @@ -580,7 +580,7 @@ void FurnaceGUIRenderGL::setSwapInterval(int swapInterval) { } } -void FurnaceGUIRenderGL::preInit() { +void FurnaceGUIRenderGL::preInit(const DivConfig& conf) { #if defined(USE_GLES) SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS,0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,SDL_GL_CONTEXT_PROFILE_ES); @@ -603,12 +603,12 @@ void FurnaceGUIRenderGL::preInit() { SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,0); #endif - SDL_GL_SetAttribute(SDL_GL_RED_SIZE,8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,0); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,24); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE,conf.getInt("glRedSize",8)); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,conf.getInt("glGreenSize",8)); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,conf.getInt("glBlueSize",8)); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,conf.getInt("glAlphaSize",0)); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,conf.getInt("glDoubleBuffer",1)); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,conf.getInt("glDepthSize",24)); } #define LOAD_PROC_MANDATORY(_v,_t,_s) \ diff --git a/src/gui/render/renderGL.h b/src/gui/render/renderGL.h index eb452eb9a..4664bec34 100644 --- a/src/gui/render/renderGL.h +++ b/src/gui/render/renderGL.h @@ -82,7 +82,7 @@ class FurnaceGUIRenderGL: public FurnaceGUIRender { const char* getDeviceName(); const char* getAPIVersion(); void setSwapInterval(int swapInterval); - void preInit(); + void preInit(const DivConfig& conf); bool init(SDL_Window* win, int swapInterval); void initGUI(SDL_Window* win); void quitGUI(); diff --git a/src/gui/render/renderGL1.cpp b/src/gui/render/renderGL1.cpp index 1ce8e054f..9fb4485b5 100644 --- a/src/gui/render/renderGL1.cpp +++ b/src/gui/render/renderGL1.cpp @@ -245,18 +245,18 @@ void FurnaceGUIRenderGL1::setSwapInterval(int swapInterval) { } } -void FurnaceGUIRenderGL1::preInit() { +void FurnaceGUIRenderGL1::preInit(const DivConfig& conf) { SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS,0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION,1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION,1); - SDL_GL_SetAttribute(SDL_GL_RED_SIZE,8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,0); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,24); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE,conf.getInt("glRedSize",8)); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,conf.getInt("glGreenSize",8)); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,conf.getInt("glBlueSize",8)); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,conf.getInt("glAlphaSize",0)); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,conf.getInt("glDoubleBuffer",1)); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,conf.getInt("glDepthSize",24)); } #define LOAD_PROC_MANDATORY(_v,_t,_s) \ @@ -334,4 +334,4 @@ void FurnaceGUIRenderGL1::quitGUI() { // sadly, OpenGL 1.1 doesn't have the ability to recover from death... bool FurnaceGUIRenderGL1::isDead() { return false; -} \ No newline at end of file +} diff --git a/src/gui/render/renderGL1.h b/src/gui/render/renderGL1.h index d80ca073b..f6081be6a 100644 --- a/src/gui/render/renderGL1.h +++ b/src/gui/render/renderGL1.h @@ -56,7 +56,7 @@ class FurnaceGUIRenderGL1: public FurnaceGUIRender { const char* getDeviceName(); const char* getAPIVersion(); void setSwapInterval(int swapInterval); - void preInit(); + void preInit(const DivConfig& conf); bool init(SDL_Window* win, int swapInterval); void initGUI(SDL_Window* win); void quitGUI(); diff --git a/src/gui/render/renderMetal.h b/src/gui/render/renderMetal.h index db927e594..8aaa88d89 100644 --- a/src/gui/render/renderMetal.h +++ b/src/gui/render/renderMetal.h @@ -52,7 +52,7 @@ class FurnaceGUIRenderMetal: public FurnaceGUIRender { const char* getDeviceName(); const char* getAPIVersion(); void setSwapInterval(int swapInterval); - void preInit(); + void preInit(const DivConfig& conf); bool init(SDL_Window* win, int swapInterval); void initGUI(SDL_Window* win); void quitGUI(); diff --git a/src/gui/render/renderMetal.mm b/src/gui/render/renderMetal.mm index 45ed95562..8649b66a0 100644 --- a/src/gui/render/renderMetal.mm +++ b/src/gui/render/renderMetal.mm @@ -218,7 +218,7 @@ void FurnaceGUIRenderMetal::setSwapInterval(int swapInterval) { } } -void FurnaceGUIRenderMetal::preInit() { +void FurnaceGUIRenderMetal::preInit(const DivConfig& conf) { SDL_SetHint(SDL_HINT_RENDER_DRIVER,"metal"); priv=new FurnaceGUIRenderMetalPrivate; } diff --git a/src/gui/render/renderSDL.cpp b/src/gui/render/renderSDL.cpp index 7adfe62e5..a5f95ead9 100644 --- a/src/gui/render/renderSDL.cpp +++ b/src/gui/render/renderSDL.cpp @@ -182,7 +182,7 @@ void FurnaceGUIRenderSDL::setSwapInterval(int swapInterval) { } } -void FurnaceGUIRenderSDL::preInit() { +void FurnaceGUIRenderSDL::preInit(const DivConfig& conf) { } bool FurnaceGUIRenderSDL::init(SDL_Window* win, int swapInterval) { diff --git a/src/gui/render/renderSDL.h b/src/gui/render/renderSDL.h index 370b11289..46a47559a 100644 --- a/src/gui/render/renderSDL.h +++ b/src/gui/render/renderSDL.h @@ -50,7 +50,7 @@ class FurnaceGUIRenderSDL: public FurnaceGUIRender { const char* getDeviceName(); const char* getAPIVersion(); void setSwapInterval(int swapInterval); - void preInit(); + void preInit(const DivConfig& conf); bool init(SDL_Window* win, int swapInterval); void initGUI(SDL_Window* win); void quitGUI(); diff --git a/src/gui/render/renderSoftware.cpp b/src/gui/render/renderSoftware.cpp index 0b54c37bb..8ca812661 100644 --- a/src/gui/render/renderSoftware.cpp +++ b/src/gui/render/renderSoftware.cpp @@ -160,7 +160,7 @@ const char* FurnaceGUIRenderSoftware::getAPIVersion() { void FurnaceGUIRenderSoftware::setSwapInterval(int swapInterval) { } -void FurnaceGUIRenderSoftware::preInit() { +void FurnaceGUIRenderSoftware::preInit(const DivConfig& conf) { } bool FurnaceGUIRenderSoftware::init(SDL_Window* win, int swapInterval) { diff --git a/src/gui/render/renderSoftware.h b/src/gui/render/renderSoftware.h index 498dec69a..05315dab8 100644 --- a/src/gui/render/renderSoftware.h +++ b/src/gui/render/renderSoftware.h @@ -47,7 +47,7 @@ class FurnaceGUIRenderSoftware: public FurnaceGUIRender { const char* getDeviceName(); const char* getAPIVersion(); void setSwapInterval(int swapInterval); - void preInit(); + void preInit(const DivConfig& conf); bool init(SDL_Window* win, int swapInterval); void initGUI(SDL_Window* win); void quitGUI(); diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index a3281d4a9..d316d0094 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -449,22 +449,60 @@ void FurnaceGUI::drawSettings() { if (ImGui::IsItemHovered()) { ImGui::SetTooltip("you may need to restart Furnace for this setting to take effect."); } - if (curRenderBackend=="SDL") { - if (ImGui::BeginCombo("Render driver",settings.renderDriver.empty()?"Automatic":settings.renderDriver.c_str())) { - if (ImGui::Selectable("Automatic",settings.renderDriver.empty())) { - settings.renderDriver=""; - settingsChanged=true; - } - for (String& i: availRenderDrivers) { - if (ImGui::Selectable(i.c_str(),i==settings.renderDriver)) { - settings.renderDriver=i; + + if (ImGui::TreeNode("Advanced render backend settings")) { + if (curRenderBackend=="SDL") { + if (ImGui::BeginCombo("Render driver",settings.renderDriver.empty()?"Automatic":settings.renderDriver.c_str())) { + if (ImGui::Selectable("Automatic",settings.renderDriver.empty())) { + settings.renderDriver=""; settingsChanged=true; } + for (String& i: availRenderDrivers) { + if (ImGui::Selectable(i.c_str(),i==settings.renderDriver)) { + settings.renderDriver=i; + settingsChanged=true; + } + } + ImGui::EndCombo(); } - ImGui::EndCombo(); - } - if (ImGui::IsItemHovered()) { - ImGui::SetTooltip("you may need to restart Furnace for this setting to take effect."); + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("you may need to restart Furnace for this setting to take effect."); + } + } else if (curRenderBackend.find("OpenGL")==0) { + ImGui::TextWrapped("beware: changing these settings may render Furnace unusable! do so at your own risk.\nstart Furnace with -safemode if you mess something up."); + if (ImGui::InputInt("Red bits",&settings.glRedSize)) { + if (settings.glRedSize<0) settings.glRedSize=0; + if (settings.glRedSize>32) settings.glRedSize=32; + settingsChanged=true; + } + if (ImGui::InputInt("Green bits",&settings.glGreenSize)) { + if (settings.glGreenSize<0) settings.glGreenSize=0; + if (settings.glGreenSize>32) settings.glGreenSize=32; + settingsChanged=true; + } + if (ImGui::InputInt("Blue bits",&settings.glBlueSize)) { + if (settings.glBlueSize<0) settings.glBlueSize=0; + if (settings.glBlueSize>32) settings.glBlueSize=32; + settingsChanged=true; + } + if (ImGui::InputInt("Alpha bits",&settings.glAlphaSize)) { + if (settings.glAlphaSize<0) settings.glAlphaSize=0; + if (settings.glAlphaSize>32) settings.glAlphaSize=32; + settingsChanged=true; + } + if (ImGui::InputInt("Color depth",&settings.glDepthSize)) { + if (settings.glDepthSize<0) settings.glDepthSize=0; + if (settings.glDepthSize>128) settings.glDepthSize=128; + settingsChanged=true; + } + bool glDoubleBufferB=settings.glDoubleBuffer; + if (ImGui::Checkbox("Double buffer",&glDoubleBufferB)) { + settings.glDoubleBuffer=glDoubleBufferB; + settingsChanged=true; + } + + ImGui::TextWrapped("the following values are common (in red, green, blue, alpha order):\n- 24 bits: 8, 8, 8, 0\n- 16 bits: 5, 6, 5, 0\n- 32 bits (with alpha): 8, 8, 8, 8\n- 30 bits (deep): 10, 10, 10, 0"); + } } @@ -4123,6 +4161,13 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) { settings.renderBackend=conf.getString("renderBackend",GUI_BACKEND_DEFAULT_NAME); settings.renderClearPos=conf.getInt("renderClearPos",0); + settings.glRedSize=conf.getInt("glRedSize",8); + settings.glGreenSize=conf.getInt("glGreenSize",8); + settings.glBlueSize=conf.getInt("glBlueSize",8); + settings.glAlphaSize=conf.getInt("glAlphaSize",0); + settings.glDepthSize=conf.getInt("glDepthSize",24); + settings.glDoubleBuffer=conf.getInt("glDoubleBuffer",1); + settings.vsync=conf.getInt("vsync",1); settings.frameRateLimit=conf.getInt("frameRateLimit",100); settings.displayRenderTime=conf.getInt("displayRenderTime",0); @@ -4657,6 +4702,12 @@ void FurnaceGUI::readConfig(DivConfig& conf, FurnaceGUISettingGroups groups) { clampSetting(settings.vibrationStrength,0.0f,1.0f); clampSetting(settings.vibrationLength,10,500); clampSetting(settings.inputRepeat,0,1); + clampSetting(settings.glRedSize,0,32); + clampSetting(settings.glGreenSize,0,32); + clampSetting(settings.glBlueSize,0,32); + clampSetting(settings.glAlphaSize,0,32); + clampSetting(settings.glDepthSize,0,128); + clampSetting(settings.glDoubleBuffer,0,1); if (settings.exportLoops<0.0) settings.exportLoops=0.0; if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0; @@ -4680,6 +4731,13 @@ void FurnaceGUI::writeConfig(DivConfig& conf, FurnaceGUISettingGroups groups) { conf.set("renderBackend",settings.renderBackend); conf.set("renderClearPos",settings.renderClearPos); + conf.set("glRedSize",settings.glRedSize); + conf.set("glGreenSize",settings.glGreenSize); + conf.set("glBlueSize",settings.glBlueSize); + conf.set("glAlphaSize",settings.glAlphaSize); + conf.set("glDepthSize",settings.glDepthSize); + conf.set("glDoubleBuffer",settings.glDoubleBuffer); + conf.set("vsync",settings.vsync); conf.set("frameRateLimit",settings.frameRateLimit); conf.set("displayRenderTime",settings.displayRenderTime); From e5026e43aadb5403c172ec270f34ec9f1baed3a3 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 7 May 2024 13:46:31 -0500 Subject: [PATCH 18/22] POP THE TREE --- src/gui/settings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index d316d0094..0e4684bee 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -502,8 +502,8 @@ void FurnaceGUI::drawSettings() { } ImGui::TextWrapped("the following values are common (in red, green, blue, alpha order):\n- 24 bits: 8, 8, 8, 0\n- 16 bits: 5, 6, 5, 0\n- 32 bits (with alpha): 8, 8, 8, 8\n- 30 bits (deep): 10, 10, 10, 0"); - } + ImGui::TreePop(); } ImGui::TextWrapped("current backend: %s\n%s\n%s\n%s",rend->getBackendName(),rend->getVendorName(),rend->getDeviceName(),rend->getAPIVersion()); From 008fe4b6b8be6bbd6aa885610712cd537e803c24 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 10 May 2024 20:01:12 -0500 Subject: [PATCH 19/22] improve audio export options - UNTESTED/UNFINISHED --- TODO.md | 3 +++ src/engine/engine.h | 26 ++++++++++++++++++++- src/engine/wavOps.cpp | 48 +++++++++++++++++++++++---------------- src/gui/exportOptions.cpp | 43 ++++++++++++++++++++++++++--------- src/gui/gui.cpp | 21 ++++++++--------- src/gui/gui.h | 6 ++--- src/gui/settings.cpp | 8 +++---- src/main.cpp | 17 +++++++------- 8 files changed, 112 insertions(+), 60 deletions(-) diff --git a/TODO.md b/TODO.md index b08c462b3..3fa7f4b99 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,6 @@ # to-do for 0.6.4 +- revamp audio export dialog - fix possible issues when moving selection - fix Metal intro crash @@ -7,3 +8,5 @@ - finish auto-clone - new pattern renderer - performance improvements +- new info header +- unlimited channels and chips diff --git a/src/engine/engine.h b/src/engine/engine.h index fa01495d1..00789b916 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -98,6 +98,28 @@ enum DivMIDIModes { DIV_MIDI_MODE_LIGHT_SHOW }; +struct DivAudioExportOptions { + DivAudioExportModes mode; + int sampleRate; + int chans; + int loops; + double fadeOut; + int orderBegin, orderEnd; + bool channelMask[DIV_MAX_CHANS]; + DivAudioExportOptions(): + mode(DIV_EXPORT_MODE_ONE), + sampleRate(44100), + chans(2), + loops(0), + fadeOut(0.0), + orderBegin(-1), + orderEnd(-1) { + for (int i=0; i delayed; int note, oldNote, lastIns, pitch, portaSpeed, portaNote; @@ -457,6 +479,7 @@ class DivEngine { DivAudioEngines audioEngine; DivAudioExportModes exportMode; double exportFadeOut; + int exportOutputs; DivConfig conf; FixedQueue pendingNotes; // bitfield @@ -670,7 +693,7 @@ class DivEngine { // export to text SafeWriter* saveText(bool separatePatterns=true); // export to an audio file - bool saveAudio(const char* path, int loops, DivAudioExportModes mode, double fadeOutTime=0.0); + bool saveAudio(const char* path, DivAudioExportOptions options); // wait for audio export to finish void waitAudioFile(); // stop audio file export @@ -1360,6 +1383,7 @@ class DivEngine { audioEngine(DIV_AUDIO_NULL), exportMode(DIV_EXPORT_MODE_ONE), exportFadeOut(0.0), + exportOutputs(2), cmdStreamInt(NULL), midiBaseChan(0), midiPoly(true), diff --git a/src/engine/wavOps.cpp b/src/engine/wavOps.cpp index edf4a8885..dba9e4b3c 100644 --- a/src/engine/wavOps.cpp +++ b/src/engine/wavOps.cpp @@ -45,7 +45,7 @@ void DivEngine::runExportThread() { SF_INFO si; SFWrapper sfWrap; si.samplerate=got.rate; - si.channels=2; + si.channels=exportOutputs; si.format=SF_FORMAT_WAV|SF_FORMAT_PCM_16; sf=sfWrap.doOpen(exportPath.c_str(),SFM_WRITE,&si); @@ -55,10 +55,12 @@ void DivEngine::runExportThread() { return; } - float* outBuf[3]; - outBuf[0]=new float[EXPORT_BUFSIZE]; - outBuf[1]=new float[EXPORT_BUFSIZE]; - outBuf[2]=new float[EXPORT_BUFSIZE*2]; + float* outBuf[DIV_MAX_OUTPUTS]; + float* outBufFinal; + for (int i=0; iEXPORT_BUFSIZE) { logE("error: total processed is bigger than export bufsize! %d>%d",totalProcessed,EXPORT_BUFSIZE); totalProcessed=EXPORT_BUFSIZE; } + int fi=0; for (int i=0; i<(int)totalProcessed; i++) { total++; if (isFadingOut) { double mul=(1.0-((double)curFadeOutSample/(double)fadeOutSamples)); - outBuf[2][i<<1]=MAX(-1.0f,MIN(1.0f,outBuf[0][i]))*mul; - outBuf[2][1+(i<<1)]=MAX(-1.0f,MIN(1.0f,outBuf[1][i]))*mul; + for (int j=0; j=fadeOutSamples) { playing=false; break; } } else { - outBuf[2][i<<1]=MAX(-1.0f,MIN(1.0f,outBuf[0][i])); - outBuf[2][1+(i<<1)]=MAX(-1.0f,MIN(1.0f,outBuf[1][i])); + for (int j=0; j-1 && i>=lastLoopPos && totalLoops>=exportLoopCount) { logD("start fading out..."); isFadingOut=true; @@ -94,15 +99,16 @@ void DivEngine::runExportThread() { } } - if (sf_writef_float(sf,outBuf[2],total)!=(int)total) { + if (sf_writef_float(sf,outBufFinal,total)!=(int)total) { logE("error: failed to write entire buffer!"); break; } } - delete[] outBuf[0]; - delete[] outBuf[1]; - delete[] outBuf[2]; + delete[] outBufFinal; + for (int i=0; iDIV_MAX_OUTPUTS) exportOutputs=DIV_MAX_OUTPUTS; + + exportLoopCount=options.loops+1; exportThread=new std::thread(_runExportThread,this); return true; #endif diff --git a/src/gui/exportOptions.cpp b/src/gui/exportOptions.cpp index 5bbf84a78..5274115c6 100644 --- a/src/gui/exportOptions.cpp +++ b/src/gui/exportOptions.cpp @@ -26,14 +26,35 @@ void FurnaceGUI::drawExportAudio(bool onWindow) { exitDisabledTimer=1; - ImGui::RadioButton("one file",&audioExportType,0); - ImGui::RadioButton("multiple files (one per chip)",&audioExportType,1); - ImGui::RadioButton("multiple files (one per channel)",&audioExportType,2); - if (ImGui::InputInt("Loops",&exportLoops,1,2)) { - if (exportLoops<0) exportLoops=0; + ImGui::Text("Export type:"); + + ImGui::Indent(); + if (ImGui::RadioButton("one file",audioExportOptions.mode==DIV_EXPORT_MODE_ONE)) { + audioExportOptions.mode=DIV_EXPORT_MODE_ONE; } - if (ImGui::InputDouble("Fade out (seconds)",&exportFadeOut,1.0,2.0,"%.1f")) { - if (exportFadeOut<0.0) exportFadeOut=0.0; + if (ImGui::RadioButton("multiple files (one per chip)",audioExportOptions.mode==DIV_EXPORT_MODE_MANY_SYS)) { + audioExportOptions.mode=DIV_EXPORT_MODE_MANY_SYS; + } + if (ImGui::RadioButton("multiple files (one per channel)",audioExportOptions.mode==DIV_EXPORT_MODE_MANY_CHAN)) { + audioExportOptions.mode=DIV_EXPORT_MODE_MANY_CHAN; + } + ImGui::Unindent(); + + if (ImGui::InputInt("Sample rate",&audioExportOptions.sampleRate,100,10000)) { + if (audioExportOptions.sampleRate<8000) audioExportOptions.sampleRate=8000; + if (audioExportOptions.sampleRate>384000) audioExportOptions.sampleRate=384000; + } + + if (ImGui::InputInt("Channels in file",&audioExportOptions.chans,1,1)) { + if (audioExportOptions.chans<1) audioExportOptions.chans=1; + if (audioExportOptions.chans>16) audioExportOptions.chans=16; + } + + if (ImGui::InputInt("Loops",&audioExportOptions.loops,1,2)) { + if (audioExportOptions.loops<0) audioExportOptions.loops=0; + } + if (ImGui::InputDouble("Fade out (seconds)",&audioExportOptions.fadeOut,1.0,2.0,"%.1f")) { + if (audioExportOptions.fadeOut<0.0) audioExportOptions.fadeOut=0.0; } if (onWindow) { @@ -43,14 +64,14 @@ void FurnaceGUI::drawExportAudio(bool onWindow) { } if (ImGui::Button("Export",ImVec2(200.0f*dpiScale,0))) { - switch (audioExportType) { - case 0: + switch (audioExportOptions.mode) { + case DIV_EXPORT_MODE_ONE: openFileDialog(GUI_FILE_EXPORT_AUDIO_ONE); break; - case 1: + case DIV_EXPORT_MODE_MANY_SYS: openFileDialog(GUI_FILE_EXPORT_AUDIO_PER_SYS); break; - case 2: + case DIV_EXPORT_MODE_MANY_CHAN: openFileDialog(GUI_FILE_EXPORT_AUDIO_PER_CHANNEL); break; } diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 5a5c36467..4cfc563ce 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -2436,7 +2436,7 @@ int FurnaceGUI::loadStream(String path) { void FurnaceGUI::exportAudio(String path, DivAudioExportModes mode) { - e->saveAudio(path.c_str(),exportLoops+1,mode,exportFadeOut); + e->saveAudio(path.c_str(),audioExportOptions); displayExporting=true; } @@ -6761,10 +6761,10 @@ bool FurnaceGUI::init() { followOrders=e->getConfBool("followOrders",true); followPattern=e->getConfBool("followPattern",true); noteInputPoly=e->getConfBool("noteInputPoly",true); - exportLoops=e->getConfInt("exportLoops",0); - if (exportLoops<0) exportLoops=0; - exportFadeOut=e->getConfDouble("exportFadeOut",0.0); - if (exportFadeOut<0.0) exportFadeOut=0.0; + audioExportOptions.loops=e->getConfInt("exportLoops",0); + if (audioExportOptions.loops<0) audioExportOptions.loops=0; + audioExportOptions.fadeOut=e->getConfDouble("exportFadeOut",0.0); + if (audioExportOptions.fadeOut<0.0) audioExportOptions.fadeOut=0.0; orderEditMode=e->getConfInt("orderEditMode",0); if (orderEditMode<0) orderEditMode=0; if (orderEditMode>3) orderEditMode=3; @@ -6826,8 +6826,8 @@ bool FurnaceGUI::init() { syncTutorial(); if (!settings.persistFadeOut) { - exportLoops=settings.exportLoops; - exportFadeOut=settings.exportFadeOut; + audioExportOptions.loops=settings.exportLoops; + audioExportOptions.fadeOut=settings.exportFadeOut; } for (int i=0; isetConf("orderEditMode",orderEditMode); e->setConf("noteInputPoly",noteInputPoly); if (settings.persistFadeOut) { - e->setConf("exportLoops",exportLoops); - e->setConf("exportFadeOut",exportFadeOut); + e->setConf("exportLoops",audioExportOptions.loops); + e->setConf("exportFadeOut",audioExportOptions.fadeOut); } // commit oscilloscope state @@ -7581,7 +7581,6 @@ FurnaceGUI::FurnaceGUI(): oldRow(0), editStep(1), editStepCoarse(16), - exportLoops(0), soloChan(-1), orderEditMode(0), orderCursor(-1), @@ -7604,7 +7603,6 @@ FurnaceGUI::FurnaceGUI(): curPaletteChoice(0), curPaletteType(0), soloTimeout(0.0f), - exportFadeOut(5.0), patExtraButtons(false), patChannelNames(false), patChannelPairs(true), @@ -7955,7 +7953,6 @@ FurnaceGUI::FurnaceGUI(): introStopped(false), curTutorial(-1), curTutorialStep(0), - audioExportType(0), dmfExportVersion(0), curExportType(GUI_EXPORT_NONE) { // value keys diff --git a/src/gui/gui.h b/src/gui/gui.h index 90e181259..e29c7e3b6 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -2194,15 +2194,13 @@ class FurnaceGUI { int pendingLayoutImportStep; FixedQueue pendingLayoutImportReopen; - int curIns, curWave, curSample, curOctave, curOrder, playOrder, prevIns, oldRow, editStep, editStepCoarse, exportLoops, soloChan, orderEditMode, orderCursor; + int curIns, curWave, curSample, curOctave, curOrder, playOrder, prevIns, oldRow, editStep, editStepCoarse, soloChan, orderEditMode, orderCursor; int loopOrder, loopRow, loopEnd, isClipping, newSongCategory, latchTarget; int wheelX, wheelY, dragSourceX, dragSourceXFine, dragSourceY, dragDestinationX, dragDestinationXFine, dragDestinationY, oldBeat, oldBar; int curGroove, exitDisabledTimer; int curPaletteChoice, curPaletteType; float soloTimeout; - double exportFadeOut; - bool patExtraButtons, patChannelNames, patChannelPairs; unsigned char patChannelHints; @@ -2603,7 +2601,7 @@ class FurnaceGUI { ImGuiListClipper csClipper; // export options - int audioExportType; + DivAudioExportOptions audioExportOptions; int dmfExportVersion; FurnaceGUIExportTypes curExportType; diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 0e4684bee..d3a64033e 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -705,13 +705,13 @@ void FurnaceGUI::drawSettings() { ImGui::BeginDisabled(settings.persistFadeOut); ImGui::Indent(); if (ImGui::InputInt("Loops",&settings.exportLoops,1,2)) { - if (exportLoops<0) exportLoops=0; - exportLoops=settings.exportLoops; + if (settings.exportLoops<0) settings.exportLoops=0; + audioExportOptions.loops=settings.exportLoops; settingsChanged=true; } if (ImGui::InputDouble("Fade out (seconds)",&settings.exportFadeOut,1.0,2.0,"%.1f")) { - if (exportFadeOut<0.0) exportFadeOut=0.0; - exportFadeOut=settings.exportFadeOut; + if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0; + audioExportOptions.fadeOut=settings.exportFadeOut; settingsChanged=true; } ImGui::Unindent(); diff --git a/src/main.cpp b/src/main.cpp index f635955ed..7254ddcc4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -66,10 +66,9 @@ String outName; String vgmOutName; String zsmOutName; String cmdOutName; -int loops=1; int benchMode=0; int subsong=-1; -DivAudioExportModes outMode=DIV_EXPORT_MODE_ONE; +DivAudioExportOptions exportOptions; #ifdef HAVE_GUI bool consoleMode=false; @@ -299,9 +298,9 @@ TAParamResult pLoops(String val) { try { int count=std::stoi(val); if (count<0) { - loops=0; + exportOptions.loops=0; } else { - loops=count+1; + exportOptions.loops=count; } } catch (std::exception& e) { logE("loop count shall be a number."); @@ -327,11 +326,11 @@ TAParamResult pSubSong(String val) { TAParamResult pOutMode(String val) { if (val=="one") { - outMode=DIV_EXPORT_MODE_ONE; + exportOptions.mode=DIV_EXPORT_MODE_ONE; } else if (val=="persys") { - outMode=DIV_EXPORT_MODE_MANY_SYS; + exportOptions.mode=DIV_EXPORT_MODE_MANY_SYS; } else if (val=="perchan") { - outMode=DIV_EXPORT_MODE_MANY_CHAN; + exportOptions.mode=DIV_EXPORT_MODE_MANY_CHAN; } else { logE("invalid value for outmode! valid values are: one, persys and perchan."); return TA_PARAM_ERROR; @@ -401,7 +400,7 @@ void initParams() { params.push_back(TAParam("n","nostatus",false,pNoStatus,"","disable playback status in console mode")); params.push_back(TAParam("N","nocontrols",false,pNoControls,"","disable standard input controls in console mode")); - params.push_back(TAParam("l","loops",true,pLoops,"","set number of loops (-1 means loop forever)")); + params.push_back(TAParam("l","loops",true,pLoops,"","set number of loops")); params.push_back(TAParam("s","subsong",true,pSubSong,"","set sub-song")); params.push_back(TAParam("o","outmode",true,pOutMode,"one|persys|perchan","set file output mode")); params.push_back(TAParam("S","safemode",false,pSafeMode,"","enable safe mode (software rendering and no audio)")); @@ -716,7 +715,7 @@ int main(int argc, char** argv) { } if (outName!="") { e.setConsoleMode(true); - e.saveAudio(outName.c_str(),loops,outMode); + e.saveAudio(outName.c_str(),exportOptions); e.waitAudioFile(); } finishLogFile(); From fc66fe1b152748779ea377daedc041bbfc08f326 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 11 May 2024 02:05:20 -0500 Subject: [PATCH 20/22] audio export: fix sample rate change --- src/engine/wavOps.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/wavOps.cpp b/src/engine/wavOps.cpp index dba9e4b3c..072f0b9d6 100644 --- a/src/engine/wavOps.cpp +++ b/src/engine/wavOps.cpp @@ -403,6 +403,7 @@ bool DivEngine::saveAudio(const char* path, DivAudioExportOptions options) { repeatPattern=false; setOrder(0); remainingLoops=-1; + got.rate=options.sampleRate; if (shallSwitchCores()) { bool isMutedBefore[DIV_MAX_CHANS]; @@ -417,7 +418,6 @@ bool DivEngine::saveAudio(const char* path, DivAudioExportOptions options) { } } - got.rate=options.sampleRate; exportOutputs=options.chans; if (exportOutputs<1) exportOutputs=1; if (exportOutputs>DIV_MAX_OUTPUTS) exportOutputs=DIV_MAX_OUTPUTS; From 68383869d3777e47eea7eb5b2313dcd6eb54fba6 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 11 May 2024 02:32:35 -0500 Subject: [PATCH 21/22] audio export: fix channel count in per-chan export --- src/engine/wavOps.cpp | 34 ++++++++++++++++++++-------------- src/gui/exportOptions.cpp | 8 +++++--- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/engine/wavOps.cpp b/src/engine/wavOps.cpp index 072f0b9d6..f904994ac 100644 --- a/src/engine/wavOps.cpp +++ b/src/engine/wavOps.cpp @@ -243,10 +243,12 @@ void DivEngine::runExportThread() { // take control of audio output deinitAudioBackend(); - float* outBuf[3]; - outBuf[0]=new float[EXPORT_BUFSIZE]; - outBuf[1]=new float[EXPORT_BUFSIZE]; - outBuf[2]=new float[EXPORT_BUFSIZE*2]; + float* outBuf[DIV_MAX_OUTPUTS]; + float* outBufFinal; + for (int i=0; iEXPORT_BUFSIZE) { logE("error: total processed is bigger than export bufsize! %d>%d",totalProcessed,EXPORT_BUFSIZE); totalProcessed=EXPORT_BUFSIZE; } + int fi=0; for (int j=0; j<(int)totalProcessed; j++) { total++; if (isFadingOut) { double mul=(1.0-((double)curFadeOutSample/(double)fadeOutSamples)); - outBuf[2][j<<1]=MAX(-1.0f,MIN(1.0f,outBuf[0][j]))*mul; - outBuf[2][1+(j<<1)]=MAX(-1.0f,MIN(1.0f,outBuf[1][j]))*mul; + for (int k=0; k=fadeOutSamples) { playing=false; break; } } else { - outBuf[2][j<<1]=MAX(-1.0f,MIN(1.0f,outBuf[0][j])); - outBuf[2][1+(j<<1)]=MAX(-1.0f,MIN(1.0f,outBuf[1][j])); + for (int k=0; k-1 && j>=lastLoopPos && totalLoops>=exportLoopCount) { logD("start fading out..."); isFadingOut=true; @@ -318,7 +323,7 @@ void DivEngine::runExportThread() { } } } - if (sf_writef_float(sf,outBuf[2],total)!=(int)total) { + if (sf_writef_float(sf,outBufFinal,total)!=(int)total) { logE("error: failed to write entire buffer!"); break; } @@ -341,9 +346,10 @@ void DivEngine::runExportThread() { if (stopExport) break; } - delete[] outBuf[0]; - delete[] outBuf[1]; - delete[] outBuf[2]; + delete[] outBufFinal; + for (int i=0; i384000) audioExportOptions.sampleRate=384000; } - if (ImGui::InputInt("Channels in file",&audioExportOptions.chans,1,1)) { - if (audioExportOptions.chans<1) audioExportOptions.chans=1; - if (audioExportOptions.chans>16) audioExportOptions.chans=16; + if (audioExportOptions.mode!=DIV_EXPORT_MODE_MANY_SYS) { + if (ImGui::InputInt("Channels in file",&audioExportOptions.chans,1,1)) { + if (audioExportOptions.chans<1) audioExportOptions.chans=1; + if (audioExportOptions.chans>16) audioExportOptions.chans=16; + } } if (ImGui::InputInt("Loops",&audioExportOptions.loops,1,2)) { From 56a3cfe13d830c952ca9894bcbe98066789c23e4 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 11 May 2024 14:25:53 -0500 Subject: [PATCH 22/22] audio export: more stuff --- src/engine/engine.h | 11 ++++++ src/engine/wavOps.cpp | 15 ++++++-- src/gui/exportOptions.cpp | 76 ++++++++++++++++++++++++++++++++------- 3 files changed, 87 insertions(+), 15 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index 00789b916..ace57ec76 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -98,8 +98,14 @@ enum DivMIDIModes { DIV_MIDI_MODE_LIGHT_SHOW }; +enum DivAudioExportFormats { + DIV_EXPORT_FORMAT_S16=0, + DIV_EXPORT_FORMAT_F32 +}; + struct DivAudioExportOptions { DivAudioExportModes mode; + DivAudioExportFormats format; int sampleRate; int chans; int loops; @@ -108,6 +114,7 @@ struct DivAudioExportOptions { bool channelMask[DIV_MAX_CHANS]; DivAudioExportOptions(): mode(DIV_EXPORT_MODE_ONE), + format(DIV_EXPORT_FORMAT_S16), sampleRate(44100), chans(2), loops(0), @@ -478,8 +485,10 @@ class DivEngine { DivChannelState chan[DIV_MAX_CHANS]; DivAudioEngines audioEngine; DivAudioExportModes exportMode; + DivAudioExportFormats exportFormat; double exportFadeOut; int exportOutputs; + bool exportChannelMask[DIV_MAX_CHANS]; DivConfig conf; FixedQueue pendingNotes; // bitfield @@ -1382,6 +1391,7 @@ class DivEngine { haltOn(DIV_HALT_NONE), audioEngine(DIV_AUDIO_NULL), exportMode(DIV_EXPORT_MODE_ONE), + exportFormat(DIV_EXPORT_FORMAT_S16), exportFadeOut(0.0), exportOutputs(2), cmdStreamInt(NULL), @@ -1435,6 +1445,7 @@ class DivEngine { memset(sysDefs,0,DIV_MAX_CHIP_DEFS*sizeof(void*)); memset(walked,0,8192); memset(oscBuf,0,DIV_MAX_OUTPUTS*(sizeof(float*))); + memset(exportChannelMask,1,DIV_MAX_CHANS*sizeof(bool)); for (int i=0; i384000) audioExportOptions.sampleRate=384000; @@ -59,25 +71,63 @@ void FurnaceGUI::drawExportAudio(bool onWindow) { if (audioExportOptions.fadeOut<0.0) audioExportOptions.fadeOut=0.0; } + bool isOneOn=false; + if (audioExportOptions.mode==DIV_EXPORT_MODE_MANY_CHAN) { + ImGui::Text("Channels to export:"); + ImGui::SameLine(); + if (ImGui::SmallButton("All")) { + for (int i=0; igetTotalChannelCount(); i++) { + String name=fmt::sprintf("%d. %s##_CE%d",i+1,e->getChannelName(i),i); + ImGui::Checkbox(name.c_str(),&audioExportOptions.channelMask[i]); + if (audioExportOptions.channelMask[i]) isOneOn=true; + } + } + ImGui::EndChild(); + } else { + isOneOn=true; + } + if (onWindow) { ImGui::Separator(); if (ImGui::Button("Cancel",ImVec2(200.0f*dpiScale,0))) ImGui::CloseCurrentPopup(); ImGui::SameLine(); } - if (ImGui::Button("Export",ImVec2(200.0f*dpiScale,0))) { - switch (audioExportOptions.mode) { - case DIV_EXPORT_MODE_ONE: - openFileDialog(GUI_FILE_EXPORT_AUDIO_ONE); - break; - case DIV_EXPORT_MODE_MANY_SYS: - openFileDialog(GUI_FILE_EXPORT_AUDIO_PER_SYS); - break; - case DIV_EXPORT_MODE_MANY_CHAN: - openFileDialog(GUI_FILE_EXPORT_AUDIO_PER_CHANNEL); - break; + if (isOneOn) { + if (ImGui::Button("Export",ImVec2(200.0f*dpiScale,0))) { + switch (audioExportOptions.mode) { + case DIV_EXPORT_MODE_ONE: + openFileDialog(GUI_FILE_EXPORT_AUDIO_ONE); + break; + case DIV_EXPORT_MODE_MANY_SYS: + openFileDialog(GUI_FILE_EXPORT_AUDIO_PER_SYS); + break; + case DIV_EXPORT_MODE_MANY_CHAN: + openFileDialog(GUI_FILE_EXPORT_AUDIO_PER_CHANNEL); + break; + } + ImGui::CloseCurrentPopup(); } - ImGui::CloseCurrentPopup(); + } else { + ImGui::Text("select at least one channel"); } }