GUI: OPLL built-in patch preview!

This commit is contained in:
tildearrow 2022-11-15 17:51:43 -05:00
parent 1f6c25643b
commit 94512e5b20
2 changed files with 1178 additions and 1143 deletions

View file

@ -1072,6 +1072,7 @@ class FurnaceGUI {
int displayInsTypeListMakeInsSample; int displayInsTypeListMakeInsSample;
float mobileMenuPos, autoButtonSize; float mobileMenuPos, autoButtonSize;
const int* curSysSection; const int* curSysSection;
DivInstrumentFM opllPreview;
String pendingRawSample; String pendingRawSample;
int pendingRawSampleDepth, pendingRawSampleChannels; int pendingRawSampleDepth, pendingRawSampleChannels;

View file

@ -28,12 +28,16 @@
#include <imgui.h> #include <imgui.h>
#include "plot_nolerp.h" #include "plot_nolerp.h"
extern "C" {
#include "../../extern/Nuked-OPLL/opll.h"
}
const char* ssgEnvTypes[8]={ const char* ssgEnvTypes[8]={
"Down Down Down", "Down.", "Down Up Down Up", "Down UP", "Up Up Up", "Up.", "Up Down Up Down", "Up DOWN" "Down Down Down", "Down.", "Down Up Down Up", "Down UP", "Up Up Up", "Up.", "Up Down Up Down", "Up DOWN"
}; };
const char* fmParamNames[3][32]={ const char* fmParamNames[3][32]={
{"Algorithm", "Feedback", "LFO > Freq", "LFO > Amp", "Attack", "Decay", "Decay 2", "Release", "Sustain", "Level", "EnvScale", "Multiplier", "Detune", "Detune 2", "SSG-EG", "AM", "AM Depth", "Vibrato Depth", "Sustained", "Sustained", "Level Scaling", "Sustain", "Vibrato", "Waveform", "Key Scale Rate", "OP2 Half Sine", "OP1 Half Sine", "EnvShift", "Reverb", "Fine", "LFO2 > Freq", "LFO2 > Amp"}, {"Algorithm", "Feedback", "LFO > Freq", "LFO > Amp", "Attack", "Decay", "Decay 2", "Release", "Sustain", "Level", "EnvScale", "Multiplier", "Detune", "Detune 2", "SSG-EG", "AM", "AM Depth", "Vibrato Depth", "Sustained", "Sustained", "Level Scaling", "Sustain", "Vibrato", "Waveform", "Scale Rate", "OP2 Half Sine", "OP1 Half Sine", "EnvShift", "Reverb", "Fine", "LFO2 > Freq", "LFO2 > Amp"},
{"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "SR", "RR", "SL", "TL", "KS", "MULT", "DT", "DT2", "SSG-EG", "AM", "AMD", "FMD", "EGT", "EGT", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS/PMS2", "AMS2"}, {"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "SR", "RR", "SL", "TL", "KS", "MULT", "DT", "DT2", "SSG-EG", "AM", "AMD", "FMD", "EGT", "EGT", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS/PMS2", "AMS2"},
{"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "D2R", "RR", "SL", "TL", "RS", "MULT", "DT", "DT2", "SSG-EG", "AM", "DAM", "DVB", "EGT", "EGS", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS/PMS2", "AMS2"} {"ALG", "FB", "FMS/PMS", "AMS", "AR", "DR", "D2R", "RR", "SL", "TL", "RS", "MULT", "DT", "DT2", "SSG-EG", "AM", "DAM", "DVB", "EGT", "EGS", "KSL", "SUS", "VIB", "WS", "KSR", "DC", "DM", "EGS", "REV", "Fine", "FMS/PMS2", "AMS2"}
}; };
@ -2443,8 +2447,38 @@ void FurnaceGUI::drawInsEdit() {
if (ins->fm.opllPreset==16) { if (ins->fm.opllPreset==16) {
ImGui::Text("this volume slider only works in compatibility (non-drums) system."); 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=OPLL_GetPatchROM(opll_type_ym2413);
const opll_patch_t* patch=&patchROM[ins->fm.opllPreset-1];
opllPreview.alg=0;
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];
} }
if (willDisplayOps) { }
}
DivInstrumentFM& fmOrigin=(ins->type==DIV_INS_OPLL && ins->fm.opllPreset>0 && ins->fm.opllPreset<16)?opllPreview:ins->fm;
ImGui::BeginDisabled(!willDisplayOps);
if (settings.fmLayout==0) { if (settings.fmLayout==0) {
int numCols=15; int numCols=15;
if (ins->type==DIV_INS_OPL ||ins->type==DIV_INS_OPL_DRUMS) numCols=13; if (ins->type==DIV_INS_OPL ||ins->type==DIV_INS_OPL_DRUMS) numCols=13;
@ -2594,7 +2628,7 @@ void FurnaceGUI::drawInsEdit() {
float sliderHeight=32.0f*dpiScale; float sliderHeight=32.0f*dpiScale;
for (int i=0; i<opCount; i++) { for (int i=0; i<opCount; i++) {
DivInstrumentFM::Operator& op=ins->fm.op[(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS)?opOrder[i]:i]; DivInstrumentFM::Operator& op=fmOrigin.op[(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS)?opOrder[i]:i];
ImGui::TableNextRow(); ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
@ -2605,12 +2639,12 @@ void FurnaceGUI::drawInsEdit() {
mod=false; mod=false;
} else if (opCount==4) { } else if (opCount==4) {
if (ins->type==DIV_INS_OPL) { if (ins->type==DIV_INS_OPL) {
if (opIsOutputOPL[ins->fm.alg&3][i]) mod=false; if (opIsOutputOPL[fmOrigin.alg&3][i]) mod=false;
} else { } else {
if (opIsOutput[ins->fm.alg&7][i]) mod=false; if (opIsOutput[fmOrigin.alg&7][i]) mod=false;
} }
} else { } else {
if (i==1 || (ins->type==DIV_INS_OPL && (ins->fm.alg&1))) mod=false; if (i==1 || (ins->type==DIV_INS_OPL && (fmOrigin.alg&1))) mod=false;
} }
if (mod) { if (mod) {
pushAccentColors( pushAccentColors(
@ -2635,7 +2669,7 @@ void FurnaceGUI::drawInsEdit() {
String opNameLabel; String opNameLabel;
if (ins->type==DIV_INS_OPL_DRUMS) { if (ins->type==DIV_INS_OPL_DRUMS) {
opNameLabel=fmt::sprintf("%s",oplDrumNames[i]); opNameLabel=fmt::sprintf("%s",oplDrumNames[i]);
} else if (ins->type==DIV_INS_OPL && ins->fm.opllPreset==16) { } else if (ins->type==DIV_INS_OPL && fmOrigin.opllPreset==16) {
if (i==1) { if (i==1) {
opNameLabel="Kick"; opNameLabel="Kick";
} else { } else {
@ -2859,7 +2893,7 @@ void FurnaceGUI::drawInsEdit() {
} }
ImGui::TableNextColumn(); 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)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,ins->fm.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,sliderHeight),ins->type); 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)?((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) { if (settings.separateFMColors) {
popAccentColors(); popAccentColors();
@ -2888,7 +2922,7 @@ void FurnaceGUI::drawInsEdit() {
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding,ImVec2(8.0f*dpiScale,4.0f*dpiScale)); ImGui::PushStyleVar(ImGuiStyleVar_CellPadding,ImVec2(8.0f*dpiScale,4.0f*dpiScale));
if (ImGui::BeginTable("AltFMOperators",columns,ImGuiTableFlags_SizingStretchSame|ImGuiTableFlags_BordersInner)) { if (ImGui::BeginTable("AltFMOperators",columns,ImGuiTableFlags_SizingStretchSame|ImGuiTableFlags_BordersInner)) {
for (int i=0; i<opCount; i++) { for (int i=0; i<opCount; i++) {
DivInstrumentFM::Operator& op=ins->fm.op[(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS)?opOrder[i]:i]; DivInstrumentFM::Operator& op=fmOrigin.op[(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS)?opOrder[i]:i];
if ((settings.fmLayout!=6 && ((i+1)&1)) || i==0 || settings.fmLayout==5) ImGui::TableNextRow(); if ((settings.fmLayout!=6 && ((i+1)&1)) || i==0 || settings.fmLayout==5) ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::PushID(fmt::sprintf("op%d",i).c_str()); ImGui::PushID(fmt::sprintf("op%d",i).c_str());
@ -2900,12 +2934,12 @@ void FurnaceGUI::drawInsEdit() {
mod=false; mod=false;
} else if (opCount==4) { } else if (opCount==4) {
if (ins->type==DIV_INS_OPL) { if (ins->type==DIV_INS_OPL) {
if (opIsOutputOPL[ins->fm.alg&3][i]) mod=false; if (opIsOutputOPL[fmOrigin.alg&3][i]) mod=false;
} else { } else {
if (opIsOutput[ins->fm.alg&7][i]) mod=false; if (opIsOutput[fmOrigin.alg&7][i]) mod=false;
} }
} else { } else {
if (i==1 || (ins->type==DIV_INS_OPL && (ins->fm.alg&1))) mod=false; if (i==1 || (ins->type==DIV_INS_OPL && (fmOrigin.alg&1))) mod=false;
} }
if (mod) { if (mod) {
pushAccentColors( pushAccentColors(
@ -2927,7 +2961,7 @@ void FurnaceGUI::drawInsEdit() {
ImGui::Dummy(ImVec2(dpiScale,dpiScale)); ImGui::Dummy(ImVec2(dpiScale,dpiScale));
if (ins->type==DIV_INS_OPL_DRUMS) { if (ins->type==DIV_INS_OPL_DRUMS) {
snprintf(tempID,1024,"%s",oplDrumNames[i]); snprintf(tempID,1024,"%s",oplDrumNames[i]);
} else if (ins->type==DIV_INS_OPL && ins->fm.opllPreset==16) { } else if (ins->type==DIV_INS_OPL && fmOrigin.opllPreset==16) {
if (i==1) { if (i==1) {
snprintf(tempID,1024,"Envelope 2 (kick only)"); snprintf(tempID,1024,"Envelope 2 (kick only)");
} else { } else {
@ -3134,7 +3168,7 @@ void FurnaceGUI::drawInsEdit() {
} }
case DIV_INS_OPLL: case DIV_INS_OPLL:
// waveform // waveform
drawWaveform(i==0?(ins->fm.ams&1):(ins->fm.fms&1),ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight)); drawWaveform(i==0?(fmOrigin.ams&1):(fmOrigin.fms&1),ins->type==DIV_INS_OPZ,ImVec2(waveWidth,waveHeight));
// params // params
ImGui::Separator(); ImGui::Separator();
@ -3288,7 +3322,7 @@ void FurnaceGUI::drawInsEdit() {
if (ins->type==DIV_INS_OPZ) { if (ins->type==DIV_INS_OPZ) {
envHeight-=ImGui::GetFrameHeightWithSpacing()*2.0f; envHeight-=ImGui::GetFrameHeightWithSpacing()*2.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)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,ins->fm.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,envHeight),ins->type); 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)?((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) { if (ins->type==DIV_INS_OPZ) {
ImGui::Separator(); ImGui::Separator();
@ -3371,7 +3405,7 @@ void FurnaceGUI::drawInsEdit() {
} }
if (ImGui::BeginTable("FMOperators",columns,ImGuiTableFlags_SizingStretchSame)) { if (ImGui::BeginTable("FMOperators",columns,ImGuiTableFlags_SizingStretchSame)) {
for (int i=0; i<opCount; i++) { for (int i=0; i<opCount; i++) {
DivInstrumentFM::Operator& op=ins->fm.op[(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS)?opOrder[i]:i]; DivInstrumentFM::Operator& op=fmOrigin.op[(opCount==4 && ins->type!=DIV_INS_OPL_DRUMS)?opOrder[i]:i];
if ((settings.fmLayout!=3 && ((i+1)&1)) || i==0 || settings.fmLayout==2) ImGui::TableNextRow(); if ((settings.fmLayout!=3 && ((i+1)&1)) || i==0 || settings.fmLayout==2) ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::TableNextColumn();
ImGui::Separator(); ImGui::Separator();
@ -3384,12 +3418,12 @@ void FurnaceGUI::drawInsEdit() {
mod=false; mod=false;
} else if (opCount==4) { } else if (opCount==4) {
if (ins->type==DIV_INS_OPL) { if (ins->type==DIV_INS_OPL) {
if (opIsOutputOPL[ins->fm.alg&3][i]) mod=false; if (opIsOutputOPL[fmOrigin.alg&3][i]) mod=false;
} else { } else {
if (opIsOutput[ins->fm.alg&7][i]) mod=false; if (opIsOutput[fmOrigin.alg&7][i]) mod=false;
} }
} else { } else {
if (i==1 || (ins->type==DIV_INS_OPL && (ins->fm.alg&1))) mod=false; if (i==1 || (ins->type==DIV_INS_OPL && (fmOrigin.alg&1))) mod=false;
} }
if (mod) { if (mod) {
pushAccentColors( pushAccentColors(
@ -3414,7 +3448,7 @@ void FurnaceGUI::drawInsEdit() {
ImGui::SameLine(); ImGui::SameLine();
if (ins->type==DIV_INS_OPL_DRUMS) { if (ins->type==DIV_INS_OPL_DRUMS) {
opNameLabel=fmt::sprintf("%s",oplDrumNames[i]); opNameLabel=fmt::sprintf("%s",oplDrumNames[i]);
} else if (ins->type==DIV_INS_OPL && ins->fm.opllPreset==16) { } else if (ins->type==DIV_INS_OPL && fmOrigin.opllPreset==16) {
if (i==1) { if (i==1) {
opNameLabel="Envelope 2 (kick only)"; opNameLabel="Envelope 2 (kick only)";
} else { } else {
@ -3482,7 +3516,7 @@ void FurnaceGUI::drawInsEdit() {
} }
//52.0 controls vert scaling; default 96 //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)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,op.sus,op.ssgEnv&8,ins->fm.alg,maxTl,maxArDr,15,ImVec2(ImGui::GetContentRegionAvail().x,52.0*dpiScale),ins->type); 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)?((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 //P(CWSliderScalar(FM_NAME(FM_AR),ImGuiDataType_U8,&op.ar,&_ZERO,&_THIRTY_ONE)); rightClickable
if (ImGui::BeginTable("opParams",2,ImGuiTableFlags_SizingStretchProp)) { if (ImGui::BeginTable("opParams",2,ImGuiTableFlags_SizingStretchProp)) {
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); \ ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); \
@ -3702,7 +3736,7 @@ void FurnaceGUI::drawInsEdit() {
ImGui::EndTable(); ImGui::EndTable();
} }
} }
} ImGui::EndDisabled();
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (ImGui::BeginTabItem("FM Macros")) { if (ImGui::BeginTabItem("FM Macros")) {