diff --git a/src/gui/fmPreview.cpp b/src/gui/fmPreview.cpp index 503e8de4d..d18f96c4a 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 3edbda1b3..e9ebe8936 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 173060067..86f08232b 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);