From 70f774312bd898ea2e38f472a75eb9fe6e1f8511 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 21 Aug 2023 19:56:22 -0500 Subject: [PATCH] GUI: OPLL preview --- src/gui/fmPreview.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++ src/gui/gui.h | 2 +- src/gui/insEdit.cpp | 11 +++++--- 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/gui/fmPreview.cpp b/src/gui/fmPreview.cpp index 503e8de4..d18f96c4 100644 --- a/src/gui/fmPreview.cpp +++ b/src/gui/fmPreview.cpp @@ -22,7 +22,9 @@ #include "../../extern/opn/ym3438.h" #include "../../extern/opm/opm.h" #include "../../extern/opl/opl3.h" +extern "C" { #include "../../extern/Nuked-OPLL/opll.h" +} #include "../engine/platform/sound/ymfm/ymfm_opz.h" #define OPN_WRITE(addr,val) \ @@ -151,7 +153,63 @@ void FurnaceGUI::renderFMPreviewOPM(const DivInstrumentFM& params, int pos) { } } +#define OPLL_WRITE(addr,val) \ + OPLL_Write((opll_t*)fmPreviewOPLL,0,(addr)); \ + for (int _i=0; _i<3; _i++) { \ + OPLL_Clock((opll_t*)fmPreviewOPLL,out); \ + } \ + OPLL_Write((opll_t*)fmPreviewOPLL,1,(val)); \ + for (int _i=0; _i<21; _i++) { \ + OPLL_Clock((opll_t*)fmPreviewOPLL,out); \ + } + void FurnaceGUI::renderFMPreviewOPLL(const DivInstrumentFM& params, int pos) { + if (fmPreviewOPLL==NULL) { + fmPreviewOPLL=new opm_t; + pos=0; + } + int out[2]; + int aOut=0; + bool mult0=false; + + if (pos==0) { + OPLL_Reset((opll_t*)fmPreviewOPLL,opll_type_ym2413); + + // set params + const DivInstrumentFM::Operator& mod=params.op[0]; + const DivInstrumentFM::Operator& car=params.op[1]; + if (params.opllPreset==0) { + for (int i=0; i<2; i++) { + if ((params.op[i].mult&15)==0) { + mult0=true; + break; + } + } + OPLL_WRITE(0x00,(mod.am<<7)|(mod.vib<<6)|((mod.ssgEnv&8)<<2)|(mod.ksr<<4)|(mod.mult)); + OPLL_WRITE(0x01,(car.am<<7)|(car.vib<<6)|((car.ssgEnv&8)<<2)|(car.ksr<<4)|(car.mult)); + OPLL_WRITE(0x02,(mod.ksl<<6)|(mod.tl&63)); + OPLL_WRITE(0x03,(car.ksl<<6)|((params.fms&1)<<4)|((params.ams&1)<<3)|(params.fb&7)); + OPLL_WRITE(0x04,(mod.ar<<4)|(mod.dr)); + OPLL_WRITE(0x05,(car.ar<<4)|(car.dr)); + OPLL_WRITE(0x06,(mod.sl<<4)|(mod.rr)); + OPLL_WRITE(0x07,(car.sl<<4)|(car.rr)); + } + OPLL_WRITE(0x10,0); + OPLL_WRITE(0x30,(params.opllPreset<<4)|(car.tl&15)); + OPLL_WRITE(0x20,(params.alg?0x20:0)|(mult0?0x15:0x13)); + } + + // render + for (int i=0; i32767) aOut=32767; + fmPreview[i]=aOut; + } } void FurnaceGUI::renderFMPreviewOPL(const DivInstrumentFM& params, int pos) { diff --git a/src/gui/gui.h b/src/gui/gui.h index 3edbda1b..e9ebe893 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -2139,7 +2139,7 @@ class FurnaceGUI { void drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr, unsigned char d2r, unsigned char rr, unsigned char sl, unsigned char sus, unsigned char egt, unsigned char algOrGlobalSus, float maxTl, float maxArDr, float maxRr, const ImVec2& size, unsigned short instType); void drawGBEnv(unsigned char vol, unsigned char len, unsigned char sLen, bool dir, const ImVec2& size); bool drawSysConf(int chan, DivSystem type, DivConfig& flags, bool modifyOnChange, bool fromMenu=false); - void kvsConfig(DivInstrument* ins); + void kvsConfig(DivInstrument* ins, bool supportsKVS=true); void drawFMPreview(const ImVec2& size); void renderFMPreview(const DivInstrument* ins, int pos=0); void renderFMPreviewOPN(const DivInstrumentFM& params, int pos=0); diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 17306006..86f08232 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -1284,7 +1284,7 @@ inline bool enBit30(const int val) { } -void FurnaceGUI::kvsConfig(DivInstrument* ins) { +void FurnaceGUI::kvsConfig(DivInstrument* ins, bool supportsKVS) { if (fmPreviewOn) { if (ImGui::IsItemHovered()) { ImGui::SetTooltip("left click to restart\nmiddle click to pause\nright click to see algorithm"); @@ -1295,10 +1295,14 @@ void FurnaceGUI::kvsConfig(DivInstrument* ins) { if (ImGui::IsItemClicked(ImGuiMouseButton_Middle)) { fmPreviewPaused=!fmPreviewPaused; } - } else { + } else if (supportsKVS) { if (ImGui::IsItemHovered()) { ImGui::SetTooltip("left click to configure TL scaling\nright click to see FM preview"); } + } else { + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("right click to see FM preview"); + } } if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) { fmPreviewOn=!fmPreviewOn; @@ -1307,7 +1311,7 @@ void FurnaceGUI::kvsConfig(DivInstrument* ins) { NOTIFY_LONG_HOLD; fmPreviewOn=!fmPreviewOn; } - if (!fmPreviewOn) { + if (!fmPreviewOn && supportsKVS) { int opCount=4; if (ins->type==DIV_INS_OPLL) opCount=2; if (ins->type==DIV_INS_OPL) opCount=(ins->fm.ops==4)?4:2; @@ -2587,6 +2591,7 @@ void FurnaceGUI::drawInsEdit() { } else { drawAlgorithm(0,FM_ALGS_2OP_OPL,ImVec2(ImGui::GetContentRegionAvail().x,24.0*dpiScale)); } + kvsConfig(ins,false); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);