diff --git a/extern/imgui_patched/imgui_impl_sdlrenderer.cpp b/extern/imgui_patched/imgui_impl_sdlrenderer.cpp index ae034179c..89c87f62b 100644 --- a/extern/imgui_patched/imgui_impl_sdlrenderer.cpp +++ b/extern/imgui_patched/imgui_impl_sdlrenderer.cpp @@ -26,6 +26,7 @@ #include "imgui.h" #include "imgui_impl_sdlrenderer.h" +#include #if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier #include // intptr_t #else @@ -184,6 +185,7 @@ void ImGui_ImplSDLRenderer_RenderDrawData(ImDrawData* draw_data) // Bind texture, Draw SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID(); + SDL_SetTextureScaleMode(tex, SDL_ScaleModeBest); // ??? SDL_RenderGeometryRaw(bd->SDLRenderer, tex, xy, (int)sizeof(ImDrawVert), color, (int)sizeof(ImDrawVert), diff --git a/papers/doc/2-interface/components.md b/papers/doc/2-interface/components.md index 8ff73e3fe..0243662b8 100644 --- a/papers/doc/2-interface/components.md +++ b/papers/doc/2-interface/components.md @@ -80,4 +80,4 @@ TODO: image sliders are used for controlling values in a quick manner by being dragged. -alternatively, Ctrl-clicking a slider (Command-click on macOS) will turn it into a number input field for a short period of time, allowing you to input fine values. +alternatively, right-clicking or Ctrl-clicking or a slider (Command-click on macOS) will turn it into a number input field for a short period of time, allowing you to input fine values. diff --git a/papers/doc/3-pattern/effects.md b/papers/doc/3-pattern/effects.md index e940a4aa7..ce47e4849 100644 --- a/papers/doc/3-pattern/effects.md +++ b/papers/doc/3-pattern/effects.md @@ -48,4 +48,4 @@ however, effects are continuous, which means you only need to type it once and t - `80` is center. - `FFxx`: end of song/stop playback. -additionally each system has its own effects. more details in another section of the manual. +additionally each system has its own effects. [click here for more details](../7-systems/README.md). diff --git a/papers/format.md b/papers/format.md index 21beaf0aa..8a13d8c3a 100644 --- a/papers/format.md +++ b/papers/format.md @@ -199,9 +199,9 @@ size | description 4?? | pointers to samples 4?? | pointers to patterns ??? | orders - | - a table of shorts + | - a table of bytes | - size=channels*ordLen - | - read orders than channels + | - read orders then channels ??? | effect columns | - size=channels 1?? | channel hide status @@ -427,6 +427,48 @@ size | description 4 | DT macro release 4 | D2R macro release 4 | SSG-EG macro release + --- | **extended op macro headers** × 4 (>=61) + 4 | DAM macro length + 4 | DVB macro length + 4 | EGT macro length + 4 | KSL macro length + 4 | SUS macro length + 4 | VIB macro length + 4 | WS macro length + 4 | KSR macro length + 4 | DAM macro loop + 4 | DVB macro loop + 4 | EGT macro loop + 4 | KSL macro loop + 4 | SUS macro loop + 4 | VIB macro loop + 4 | WS macro loop + 4 | KSR macro loop + 4 | DAM macro release + 4 | DVB macro release + 4 | EGT macro release + 4 | KSL macro release + 4 | SUS macro release + 4 | VIB macro release + 4 | WS macro release + 4 | KSR macro release + 1 | DAM macro open + 1 | DVB macro open + 1 | EGT macro open + 1 | KSL macro open + 1 | SUS macro open + 1 | VIB macro open + 1 | WS macro open + 1 | KSR macro open + --- | **extended op macros** × 4 (>=61) + 1?? | DAM macro + 1?? | DVB macro + 1?? | EGT macro + 1?? | KSL macro + 1?? | SUS macro + 1?? | VIB macro + 1?? | WS macro + 1?? | KSR macro ``` # wavetable diff --git a/src/engine/dispatchContainer.cpp b/src/engine/dispatchContainer.cpp index a5d79befc..8398ca3d0 100644 --- a/src/engine/dispatchContainer.cpp +++ b/src/engine/dispatchContainer.cpp @@ -206,6 +206,8 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do case DIV_SYSTEM_OPLL_DRUMS: case DIV_SYSTEM_VRC7: dispatch=new DivPlatformOPLL; + ((DivPlatformOPLL*)dispatch)->setVRC7(sys==DIV_SYSTEM_VRC7); + ((DivPlatformOPLL*)dispatch)->setProperDrums(sys==DIV_SYSTEM_OPLL_DRUMS); break; case DIV_SYSTEM_SAA1099: { int saaCore=eng->getConfInt("saaCore",0); diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index a9fd637ef..cd4bb4222 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -501,6 +501,7 @@ void DivEngine::renderSamples() { // step 4: allocate qsound pcm samples if (qsoundMem==NULL) qsoundMem=new unsigned char[16777216]; + memset(qsoundMem,0,16777216); memPos=0; for (int i=0; iwriteI(op.d2rMacroRel); w->writeI(op.ssgMacroRel); } + + // extended op macros + for (int i=0; i<4; i++) { + DivInstrumentSTD::OpMacro& op=std.opMacros[i]; + + w->writeI(op.damMacroLen); + w->writeI(op.dvbMacroLen); + w->writeI(op.egtMacroLen); + w->writeI(op.kslMacroLen); + w->writeI(op.susMacroLen); + w->writeI(op.vibMacroLen); + w->writeI(op.wsMacroLen); + w->writeI(op.ksrMacroLen); + + w->writeI(op.damMacroLoop); + w->writeI(op.dvbMacroLoop); + w->writeI(op.egtMacroLoop); + w->writeI(op.kslMacroLoop); + w->writeI(op.susMacroLoop); + w->writeI(op.vibMacroLoop); + w->writeI(op.wsMacroLoop); + w->writeI(op.ksrMacroLoop); + + w->writeI(op.damMacroRel); + w->writeI(op.dvbMacroRel); + w->writeI(op.egtMacroRel); + w->writeI(op.kslMacroRel); + w->writeI(op.susMacroRel); + w->writeI(op.vibMacroRel); + w->writeI(op.wsMacroRel); + w->writeI(op.ksrMacroRel); + + w->writeC(op.damMacroOpen); + w->writeC(op.dvbMacroOpen); + w->writeC(op.egtMacroOpen); + w->writeC(op.kslMacroOpen); + w->writeC(op.susMacroOpen); + w->writeC(op.vibMacroOpen); + w->writeC(op.wsMacroOpen); + w->writeC(op.ksrMacroOpen); + } + + for (int i=0; i<4; i++) { + DivInstrumentSTD::OpMacro& op=std.opMacros[i]; + for (int j=0; jwriteC(op.damMacro[j]); + } + for (int j=0; jwriteC(op.dvbMacro[j]); + } + for (int j=0; jwriteC(op.egtMacro[j]); + } + for (int j=0; jwriteC(op.kslMacro[j]); + } + for (int j=0; jwriteC(op.susMacro[j]); + } + for (int j=0; jwriteC(op.vibMacro[j]); + } + for (int j=0; jwriteC(op.wsMacro[j]); + } + for (int j=0; jwriteC(op.ksrMacro[j]); + } + } } DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) { @@ -570,6 +639,61 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) { } } + // extended op macros + if (version>=61) { + for (int i=0; i<4; i++) { + DivInstrumentSTD::OpMacro& op=std.opMacros[i]; + + op.damMacroLen=reader.readI(); + op.dvbMacroLen=reader.readI(); + op.egtMacroLen=reader.readI(); + op.kslMacroLen=reader.readI(); + op.susMacroLen=reader.readI(); + op.vibMacroLen=reader.readI(); + op.wsMacroLen=reader.readI(); + op.ksrMacroLen=reader.readI(); + + op.damMacroLoop=reader.readI(); + op.dvbMacroLoop=reader.readI(); + op.egtMacroLoop=reader.readI(); + op.kslMacroLoop=reader.readI(); + op.susMacroLoop=reader.readI(); + op.vibMacroLoop=reader.readI(); + op.wsMacroLoop=reader.readI(); + op.ksrMacroLoop=reader.readI(); + + op.damMacroRel=reader.readI(); + op.dvbMacroRel=reader.readI(); + op.egtMacroRel=reader.readI(); + op.kslMacroRel=reader.readI(); + op.susMacroRel=reader.readI(); + op.vibMacroRel=reader.readI(); + op.wsMacroRel=reader.readI(); + op.ksrMacroRel=reader.readI(); + + op.damMacroOpen=reader.readC(); + op.dvbMacroOpen=reader.readC(); + op.egtMacroOpen=reader.readC(); + op.kslMacroOpen=reader.readC(); + op.susMacroOpen=reader.readC(); + op.vibMacroOpen=reader.readC(); + op.wsMacroOpen=reader.readC(); + op.ksrMacroOpen=reader.readC(); + } + + for (int i=0; i<4; i++) { + DivInstrumentSTD::OpMacro& op=std.opMacros[i]; + reader.read(op.damMacro,op.damMacroLen); + reader.read(op.dvbMacro,op.dvbMacroLen); + reader.read(op.egtMacro,op.egtMacroLen); + reader.read(op.kslMacro,op.kslMacroLen); + reader.read(op.susMacro,op.susMacroLen); + reader.read(op.vibMacro,op.vibMacroLen); + reader.read(op.wsMacro,op.wsMacroLen); + reader.read(op.ksrMacro,op.ksrMacroLen); + } + } + return DIV_DATA_SUCCESS; } diff --git a/src/engine/instrument.h b/src/engine/instrument.h index 366bd87d6..aef84f202 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -50,11 +50,26 @@ enum DivInstrumentType { DIV_INS_MIKEY=23, }; +// FM operator structure: +// - OPN: +// - AM, AR, DR, MULT, RR, SL, TL, RS, DT, D2R, SSG-EG +// - OPM: +// - AM, AR, DR, MULT, RR, SL, TL, DT2, RS, DT, D2R +// - OPLL: +// - AM, AR, DR, MULT, RR, SL, TL, SSG-EG&8 = EG-S +// - KSL, VIB, KSR +// - OPL: +// - AM, AR, DR, MULT, RR, SL, TL, SSG-EG&8 = EG-S +// - KSL, VIB, WS (OPL2/3), KSR +// - OPZ: NOT FINAL! +// - AM, AR, DR, MULT (CRS), RR, SL, TL, DT2, RS, DT, D2R +// - KSL = LS, WS, DVB = MULT (FINE), DAM = REV, EGT = EGShift + struct DivInstrumentFM { unsigned char alg, fb, fms, ams, ops, opllPreset; struct Operator { unsigned char am, ar, dr, mult, rr, sl, tl, dt2, rs, dt, d2r, ssgEnv; - unsigned char dam, dvb, egt, ksl, sus, vib, ws, ksr; // YMU759/OPL + unsigned char dam, dvb, egt, ksl, sus, vib, ws, ksr; // YMU759/OPL/OPZ Operator(): am(0), ar(0), @@ -161,31 +176,55 @@ struct DivInstrumentSTD { unsigned char dtMacro[256]; unsigned char d2rMacro[256]; unsigned char ssgMacro[256]; + unsigned char damMacro[256]; + unsigned char dvbMacro[256]; + unsigned char egtMacro[256]; + unsigned char kslMacro[256]; + unsigned char susMacro[256]; + unsigned char vibMacro[256]; + unsigned char wsMacro[256]; + unsigned char ksrMacro[256]; bool amMacroOpen, arMacroOpen, drMacroOpen, multMacroOpen; bool rrMacroOpen, slMacroOpen, tlMacroOpen, dt2MacroOpen; bool rsMacroOpen, dtMacroOpen, d2rMacroOpen, ssgMacroOpen; + bool damMacroOpen, dvbMacroOpen, egtMacroOpen, kslMacroOpen; + bool susMacroOpen, vibMacroOpen, wsMacroOpen, ksrMacroOpen; unsigned char amMacroLen, arMacroLen, drMacroLen, multMacroLen; unsigned char rrMacroLen, slMacroLen, tlMacroLen, dt2MacroLen; unsigned char rsMacroLen, dtMacroLen, d2rMacroLen, ssgMacroLen; + unsigned char damMacroLen, dvbMacroLen, egtMacroLen, kslMacroLen; + unsigned char susMacroLen, vibMacroLen, wsMacroLen, ksrMacroLen; signed char amMacroLoop, arMacroLoop, drMacroLoop, multMacroLoop; signed char rrMacroLoop, slMacroLoop, tlMacroLoop, dt2MacroLoop; signed char rsMacroLoop, dtMacroLoop, d2rMacroLoop, ssgMacroLoop; + signed char damMacroLoop, dvbMacroLoop, egtMacroLoop, kslMacroLoop; + signed char susMacroLoop, vibMacroLoop, wsMacroLoop, ksrMacroLoop; signed char amMacroRel, arMacroRel, drMacroRel, multMacroRel; signed char rrMacroRel, slMacroRel, tlMacroRel, dt2MacroRel; signed char rsMacroRel, dtMacroRel, d2rMacroRel, ssgMacroRel; + signed char damMacroRel, dvbMacroRel, egtMacroRel, kslMacroRel; + signed char susMacroRel, vibMacroRel, wsMacroRel, ksrMacroRel; OpMacro(): amMacroOpen(false), arMacroOpen(false), drMacroOpen(false), multMacroOpen(false), rrMacroOpen(false), slMacroOpen(false), tlMacroOpen(true), dt2MacroOpen(false), rsMacroOpen(false), dtMacroOpen(false), d2rMacroOpen(false), ssgMacroOpen(false), + damMacroOpen(false), dvbMacroOpen(false), egtMacroOpen(false), kslMacroOpen(false), + susMacroOpen(false), vibMacroOpen(false), wsMacroOpen(false), ksrMacroOpen(false), amMacroLen(0), arMacroLen(0), drMacroLen(0), multMacroLen(0), rrMacroLen(0), slMacroLen(0), tlMacroLen(0), dt2MacroLen(0), rsMacroLen(0), dtMacroLen(0), d2rMacroLen(0), ssgMacroLen(0), + damMacroLen(0), dvbMacroLen(0), egtMacroLen(0), kslMacroLen(0), + susMacroLen(0), vibMacroLen(0), wsMacroLen(0), ksrMacroLen(0), amMacroLoop(-1), arMacroLoop(-1), drMacroLoop(-1), multMacroLoop(-1), rrMacroLoop(-1), slMacroLoop(-1), tlMacroLoop(-1), dt2MacroLoop(-1), rsMacroLoop(-1), dtMacroLoop(-1), d2rMacroLoop(-1), ssgMacroLoop(-1), + damMacroLoop(-1), dvbMacroLoop(-1), egtMacroLoop(-1), kslMacroLoop(-1), + susMacroLoop(-1), vibMacroLoop(-1), wsMacroLoop(-1), ksrMacroLoop(-1), amMacroRel(-1), arMacroRel(-1), drMacroRel(-1), multMacroRel(-1), rrMacroRel(-1), slMacroRel(-1), tlMacroRel(-1), dt2MacroRel(-1), - rsMacroRel(-1), dtMacroRel(-1), d2rMacroRel(-1), ssgMacroRel(-1) { + rsMacroRel(-1), dtMacroRel(-1), d2rMacroRel(-1), ssgMacroRel(-1), + damMacroRel(-1), dvbMacroRel(-1), egtMacroRel(-1), kslMacroRel(-1), + susMacroRel(-1), vibMacroRel(-1), wsMacroRel(-1), ksrMacroRel(-1) { memset(amMacro,0,256); memset(arMacro,0,256); memset(drMacro,0,256); @@ -198,6 +237,14 @@ struct DivInstrumentSTD { memset(dtMacro,0,256); memset(d2rMacro,0,256); memset(ssgMacro,0,256); + memset(damMacro,0,256); + memset(dvbMacro,0,256); + memset(egtMacro,0,256); + memset(kslMacro,0,256); + memset(susMacro,0,256); + memset(vibMacro,0,256); + memset(wsMacro,0,256); + memset(ksrMacro,0,256); } } opMacros[4]; DivInstrumentSTD(): diff --git a/src/engine/macroInt.cpp b/src/engine/macroInt.cpp index 8ae31411b..adcb33139 100644 --- a/src/engine/macroInt.cpp +++ b/src/engine/macroInt.cpp @@ -44,6 +44,7 @@ } \ } +// CPU hell void DivMacroInt::next() { if (ins==NULL) return; @@ -79,6 +80,16 @@ void DivMacroInt::next() { doMacro(o.finishedDt,o.hadDt,o.hasDt,o.dt,o.dtPos,m.dtMacro,m.dtMacroLen,m.dtMacroLoop,m.dtMacroRel); doMacro(o.finishedD2r,o.hadD2r,o.hasD2r,o.d2r,o.d2rPos,m.d2rMacro,m.d2rMacroLen,m.d2rMacroLoop,m.d2rMacroRel); doMacro(o.finishedSsg,o.hadSsg,o.hasSsg,o.ssg,o.ssgPos,m.ssgMacro,m.ssgMacroLen,m.ssgMacroLoop,m.ssgMacroRel); + + doMacro(o.finishedDam,o.hadDam,o.hasDam,o.dam,o.damPos,m.damMacro,m.damMacroLen,m.damMacroLoop,m.damMacroRel); + doMacro(o.finishedDvb,o.hadDvb,o.hasDvb,o.dvb,o.dvbPos,m.dvbMacro,m.dvbMacroLen,m.dvbMacroLoop,m.dvbMacroRel); + doMacro(o.finishedEgt,o.hadEgt,o.hasEgt,o.egt,o.egtPos,m.egtMacro,m.egtMacroLen,m.egtMacroLoop,m.egtMacroRel); + doMacro(o.finishedKsl,o.hadKsl,o.hasKsl,o.ksl,o.kslPos,m.kslMacro,m.kslMacroLen,m.kslMacroLoop,m.kslMacroRel); + + doMacro(o.finishedSus,o.hadSus,o.hasSus,o.sus,o.susPos,m.susMacro,m.susMacroLen,m.susMacroLoop,m.susMacroRel); + doMacro(o.finishedVib,o.hadVib,o.hasVib,o.vib,o.vibPos,m.vibMacro,m.vibMacroLen,m.vibMacroLoop,m.vibMacroRel); + doMacro(o.finishedWs,o.hadWs,o.hasWs,o.ws,o.wsPos,m.wsMacro,m.wsMacroLen,m.wsMacroLoop,m.wsMacroRel); + doMacro(o.finishedKsr,o.hadKsr,o.hasKsr,o.ksr,o.ksrPos,m.ksrMacro,m.ksrMacroLen,m.ksrMacroLoop,m.ksrMacroRel); } } @@ -280,6 +291,47 @@ void DivMacroInt::init(DivInstrument* which) { o.hasSsg=true; o.willSsg=true; } + + if (m.damMacroLen>0) { + o.hadDam=true; + o.hasDam=true; + o.willDam=true; + } + if (m.dvbMacroLen>0) { + o.hadDvb=true; + o.hasDvb=true; + o.willDvb=true; + } + if (m.egtMacroLen>0) { + o.hadEgt=true; + o.hasEgt=true; + o.willEgt=true; + } + if (m.kslMacroLen>0) { + o.hadKsl=true; + o.hasKsl=true; + o.willKsl=true; + } + if (m.susMacroLen>0) { + o.hadSus=true; + o.hasSus=true; + o.willSus=true; + } + if (m.vibMacroLen>0) { + o.hadVib=true; + o.hasVib=true; + o.willVib=true; + } + if (m.wsMacroLen>0) { + o.hadWs=true; + o.hasWs=true; + o.willWs=true; + } + if (m.ksrMacroLen>0) { + o.hadKsr=true; + o.hasKsr=true; + o.willKsr=true; + } } } diff --git a/src/engine/macroInt.h b/src/engine/macroInt.h index 60221d063..b107a4732 100644 --- a/src/engine/macroInt.h +++ b/src/engine/macroInt.h @@ -42,26 +42,38 @@ class DivMacroInt { int amPos, arPos, drPos, multPos; int rrPos, slPos, tlPos, dt2Pos; int rsPos, dtPos, d2rPos, ssgPos; + int damPos, dvbPos, egtPos, kslPos; + int susPos, vibPos, wsPos, ksrPos; int am, ar, dr, mult; int rr, sl, tl, dt2; int rs, dt, d2r, ssg; + int dam, dvb, egt, ksl; + int sus, vib, ws, ksr; bool hasAm, hasAr, hasDr, hasMult; bool hasRr, hasSl, hasTl, hasDt2; bool hasRs, hasDt, hasD2r, hasSsg; + bool hasDam, hasDvb, hasEgt, hasKsl; + bool hasSus, hasVib, hasWs, hasKsr; bool hadAm, hadAr, hadDr, hadMult; bool hadRr, hadSl, hadTl, hadDt2; bool hadRs, hadDt, hadD2r, hadSsg; + bool hadDam, hadDvb, hadEgt, hadKsl; + bool hadSus, hadVib, hadWs, hadKsr; bool finishedAm, finishedAr, finishedDr, finishedMult; bool finishedRr, finishedSl, finishedTl, finishedDt2; bool finishedRs, finishedDt, finishedD2r, finishedSsg; + bool finishedDam, finishedDvb, finishedEgt, finishedKsl; + bool finishedSus, finishedVib, finishedWs, finishedKsr; bool willAm, willAr, willDr, willMult; bool willRr, willSl, willTl, willDt2; bool willRs, willDt, willD2r, willSsg; + bool willDam, willDvb, willEgt, willKsl; + bool willSus, willVib, willWs, willKsr; IntOp(): amPos(0), arPos(0), @@ -75,6 +87,14 @@ class DivMacroInt { dtPos(0), d2rPos(0), ssgPos(0), + damPos(0), + dvbPos(0), + egtPos(0), + kslPos(0), + susPos(0), + vibPos(0), + wsPos(0), + ksrPos(0), am(0), ar(0), dr(0), @@ -87,18 +107,34 @@ class DivMacroInt { dt(0), d2r(0), ssg(0), + dam(0), + dvb(0), + egt(0), + ksl(0), + sus(0), + vib(0), + ws(0), + ksr(0), hasAm(false), hasAr(false), hasDr(false), hasMult(false), hasRr(false), hasSl(false), hasTl(false), hasDt2(false), hasRs(false), hasDt(false), hasD2r(false), hasSsg(false), + hasDam(false), hasDvb(false), hasEgt(false), hasKsl(false), + hasSus(false), hasVib(false), hasWs(false), hasKsr(false), hadAm(false), hadAr(false), hadDr(false), hadMult(false), hadRr(false), hadSl(false), hadTl(false), hadDt2(false), hadRs(false), hadDt(false), hadD2r(false), hadSsg(false), + hadDam(false), hadDvb(false), hadEgt(false), hadKsl(false), + hadSus(false), hadVib(false), hadWs(false), hadKsr(false), finishedAm(false), finishedAr(false), finishedDr(false), finishedMult(false), finishedRr(false), finishedSl(false), finishedTl(false), finishedDt2(false), finishedRs(false), finishedDt(false), finishedD2r(false), finishedSsg(false), + finishedDam(false), finishedDvb(false), finishedEgt(false), finishedKsl(false), + finishedSus(false), finishedVib(false), finishedWs(false), finishedKsr(false), willAm(false), willAr(false), willDr(false), willMult(false), willRr(false), willSl(false), willTl(false), willDt2(false), - willRs(false), willDt(false), willD2r(false), willSsg(false) {} + willRs(false), willDt(false), willD2r(false), willSsg(false), + willDam(false), willDvb(false), willEgt(false), willKsl(false), + willSus(false), willVib(false), willWs(false), willKsr(false) {} } op[4]; void release(); void next(); diff --git a/src/engine/platform/lynx.cpp b/src/engine/platform/lynx.cpp index 856950f95..2783ba5d5 100644 --- a/src/engine/platform/lynx.cpp +++ b/src/engine/platform/lynx.cpp @@ -273,6 +273,7 @@ void DivPlatformLynx::forceIns() { chan[i].insChanged=true; chan[i].freqChanged=true; } + WRITE_ATTEN(i,chan[i].pan); } } diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index 28285931a..03db96c23 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -75,6 +75,10 @@ const char* DivPlatformOPLL::getEffectName(unsigned char effect) { return NULL; } +const unsigned char cycleMapOPLL[18]={ + 8, 7, 6, 7, 8, 7, 8, 6, 0, 1, 2, 7, 8, 9, 3, 4, 5, 9 +}; + void DivPlatformOPLL::acquire_nuked(short* bufL, short* bufR, size_t start, size_t len) { static int o[2]; static int os; @@ -100,7 +104,10 @@ void DivPlatformOPLL::acquire_nuked(short* bufL, short* bufR, size_t start, size } OPLL_Clock(&fm,o); - os+=(o[0]+o[1]); + unsigned char nextOut=cycleMapOPLL[fm.cycles]; + if (!isMuted[nextOut]) { + os+=(o[0]+o[1]); + } } os*=50; if (os<-32768) os=-32768; @@ -120,21 +127,9 @@ void DivPlatformOPLL::tick() { for (int i=0; i<9; i++) { chan[i].std.next(); - /*if (chan[i].std.hadVol) { - chan[i].outVol=(chan[i].vol*MIN(127,chan[i].std.vol))/127; - for (int j=0; j<4; j++) { - unsigned short baseAddr=chanOffs[i]|opOffs[j]; - DivInstrumentFM::Operator& op=chan[i].state.op[j]; - if (isMuted[i]) { - rWrite(baseAddr+ADDR_TL,127); - } else { - if (isOutput[chan[i].state.alg][j]) { - rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[i].outVol&0x7f))/127)); - } else { - rWrite(baseAddr+ADDR_TL,op.tl); - } - } - } + if (chan[i].std.hadVol) { + chan[i].outVol=(chan[i].vol*MIN(15,chan[i].std.vol))/15; + rWrite(0x30+i,(15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)|(chan[i].state.opllPreset<<4)); } if (chan[i].std.hadArp) { @@ -153,95 +148,86 @@ void DivPlatformOPLL::tick() { } } - if (chan[i].std.hadAlg) { - chan[i].state.alg=chan[i].std.alg; - rWrite(chanOffs[i]+ADDR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3)); - if (!parent->song.algMacroBehavior) for (int j=0; j<4; j++) { - unsigned short baseAddr=chanOffs[i]|opOffs[j]; + if (chan[i].state.opllPreset==0) { + if (chan[i].std.hadAlg) { // SUS + chan[i].state.alg=chan[i].std.alg; + chan[i].freqChanged=true; + } + if (chan[i].std.hadFb) { + chan[i].state.fb=chan[i].std.fb; + rWrite(0x03,(chan[i].state.op[0].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb); + } + if (chan[i].std.hadFms) { + chan[i].state.fms=chan[i].std.fms; + rWrite(0x03,(chan[i].state.op[0].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb); + } + if (chan[i].std.hadAms) { + chan[i].state.ams=chan[i].std.ams; + rWrite(0x03,(chan[i].state.op[0].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb); + } + + for (int j=0; j<2; j++) { DivInstrumentFM::Operator& op=chan[i].state.op[j]; - if (isMuted[i]) { - rWrite(baseAddr+ADDR_TL,127); - } else { - if (isOutput[chan[i].state.alg][j]) { - rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[i].outVol&0x7f))/127)); + DivMacroInt::IntOp& m=chan[i].std.op[j]; + + if (m.hadAm) { + op.am=m.am; + rWrite(0x00+j,(op.am<<7)|(op.vib<<6)|((op.ssgEnv&8)<<2)|(op.ksr<<4)|(op.mult)); + } + if (m.hadAr) { + op.ar=m.ar; + rWrite(0x04+j,(op.ar<<4)|(op.dr)); + } + if (m.hadDr) { + op.dr=m.dr; + rWrite(0x04+j,(op.ar<<4)|(op.dr)); + } + if (m.hadMult) { + op.mult=m.mult; + rWrite(0x00+j,(op.am<<7)|(op.vib<<6)|((op.ssgEnv&8)<<2)|(op.ksr<<4)|(op.mult)); + } + if (m.hadRr) { + op.rr=m.rr; + rWrite(0x06+j,(op.sl<<4)|(op.rr)); + } + if (m.hadSl) { + op.sl=m.sl; + rWrite(0x06+j,(op.sl<<4)|(op.rr)); + } + if (m.hadTl) { + op.tl=((j==1)?15:63)-m.tl; + if (j==1) { + rWrite(0x30+i,(15-(chan[i].outVol*(15-chan[i].state.op[1].tl))/15)|(chan[i].state.opllPreset<<4)); } else { - rWrite(baseAddr+ADDR_TL,op.tl); + rWrite(0x02,(chan[i].state.op[1].ksl<<6)|(op.tl&63)); } } + + if (m.hadEgt) { + op.ssgEnv=(m.egt&1)?8:0; + rWrite(0x00+j,(op.am<<7)|(op.vib<<6)|((op.ssgEnv&8)<<2)|(op.ksr<<4)|(op.mult)); + } + if (m.hadKsl) { + op.ksl=m.ksl; + if (j==1) { + rWrite(0x02,(op.ksl<<6)|(chan[i].state.op[0].tl&63)); + } else { + rWrite(0x03,(chan[i].state.op[0].ksl<<6)|((chan[i].state.fms&1)<<4)|((chan[i].state.ams&1)<<3)|chan[i].state.fb); + } + } + if (m.hadKsr) { + op.ksr=m.ksr; + rWrite(0x00+j,(op.am<<7)|(op.vib<<6)|((op.ssgEnv&8)<<2)|(op.ksr<<4)|(op.mult)); + } + if (m.hadVib) { + op.vib=m.vib; + rWrite(0x00+j,(op.am<<7)|(op.vib<<6)|((op.ssgEnv&8)<<2)|(op.ksr<<4)|(op.mult)); + } } } - if (chan[i].std.hadFb) { - chan[i].state.fb=chan[i].std.fb; - rWrite(chanOffs[i]+ADDR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3)); - } - if (chan[i].std.hadFms) { - chan[i].state.fms=chan[i].std.fms; - rWrite(chanOffs[i]+ADDR_LRAF,(isMuted[i]?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4)); - } - if (chan[i].std.hadAms) { - chan[i].state.ams=chan[i].std.ams; - rWrite(chanOffs[i]+ADDR_LRAF,(isMuted[i]?0:(chan[i].pan<<6))|(chan[i].state.fms&7)|((chan[i].state.ams&3)<<4)); - } - for (int j=0; j<2; j++) { - unsigned short baseAddr=chanOffs[i]|opOffs[j]; - DivInstrumentFM::Operator& op=chan[i].state.op[j]; - DivMacroInt::IntOp& m=chan[i].std.op[j]; - if (m.hadAm) { - op.am=m.am; - rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7)); - } - if (m.hadAr) { - op.ar=m.ar; - rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6)); - } - if (m.hadDr) { - op.dr=m.dr; - rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7)); - } - if (m.hadMult) { - op.mult=m.mult; - rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4)); - } - if (m.hadRr) { - op.rr=m.rr; - rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4)); - } - if (m.hadSl) { - op.sl=m.sl; - rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4)); - } - if (m.hadTl) { - op.tl=127-m.tl; - if (isMuted[i]) { - rWrite(baseAddr+ADDR_TL,127); - } else { - if (isOutput[chan[i].state.alg][j]) { - rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[i].outVol&0x7f))/127)); - } else { - rWrite(baseAddr+ADDR_TL,op.tl); - } - } - } - if (m.hadRs) { - op.rs=m.rs; - rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6)); - } - if (m.hadDt) { - op.dt=m.dt; - rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4)); - } - if (m.hadD2r) { - op.d2r=m.d2r; - rWrite(baseAddr+ADDR_DT2_D2R,op.d2r&31); - } - if (m.hadSsg) { - op.ssgEnv=m.ssg; - rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15); - } - }*/ if (chan[i].keyOn || chan[i].keyOff) { - if (chan[i].drums) { + if (i>=6 && drums) { drumState&=~(0x10>>(chan[i].note%12)); immWrite(0x0e,0x20|drumState); } else { @@ -266,11 +252,11 @@ void DivPlatformOPLL::tick() { int freqt=toFreq(chan[i].freq); chan[i].freqH=freqt>>8; chan[i].freqL=freqt&0xff; - if (!chan[i].drums) { + if (i<6 || !drums) { immWrite(0x10+i,freqt&0xff); } } - if (chan[i].keyOn && chan[i].drums) { + if (chan[i].keyOn && i>=6 && drums) { //printf("%d\n",chan[i].note%12); drumState|=(0x10>>(chan[i].note%12)); immWrite(0x0e,0x20|drumState); @@ -372,21 +358,27 @@ int DivPlatformOPLL::dispatch(DivCommand c) { rWrite(0x05,(car.ar<<4)|(car.dr)); rWrite(0x06,(mod.sl<<4)|(mod.rr)); rWrite(0x07,(car.sl<<4)|(car.rr)); + lastCustomMemory=c.chan; } if (chan[c.chan].state.opllPreset==16) { // compatible drums mode - chan[c.chan].drums=true; - immWrite(0x16,0x20); - immWrite(0x26,0x05); - immWrite(0x16,0x20); - immWrite(0x26,0x05); - immWrite(0x17,0x50); - immWrite(0x27,0x05); - immWrite(0x17,0x50); - immWrite(0x27,0x05); - immWrite(0x18,0xC0); - immWrite(0x28,0x01); + if (c.chan>=6) { + drums=true; + immWrite(0x16,0x20); + immWrite(0x26,0x05); + immWrite(0x16,0x20); + immWrite(0x26,0x05); + immWrite(0x17,0x50); + immWrite(0x27,0x05); + immWrite(0x17,0x50); + immWrite(0x27,0x05); + immWrite(0x18,0xC0); + immWrite(0x28,0x01); + } } else { - chan[c.chan].drums=false; + if (c.chan>=6) { + drums=false; + immWrite(0x0e,0); + } rWrite(0x30+c.chan,(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)|(chan[c.chan].state.opllPreset<<4)); } } @@ -397,7 +389,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) { chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value); chan[c.chan].note=c.value; - if (chan[c.chan].drums) { + if (c.chan>=6 && drums) { switch (chan[c.chan].note%12) { case 0: // kick drumVol[0]=(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15); @@ -444,7 +436,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) { if (!chan[c.chan].std.hasVol) { chan[c.chan].outVol=c.value; } - if (!chan[c.chan].drums) { + if (c.chan<6 || !drums) { rWrite(0x30+c.chan,(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)|(chan[c.chan].state.opllPreset<<4)); } break; @@ -502,52 +494,56 @@ int DivPlatformOPLL::dispatch(DivCommand c) { chan[c.chan].freqChanged=true; break; } - /* case DIV_CMD_FM_FB: { + DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0]; + //DivInstrumentFM::Operator& car=chan[c.chan].state.op[1]; chan[c.chan].state.fb=c.value&7; - rWrite(chanOffs[c.chan]+ADDR_FB_ALG,(chan[c.chan].state.alg&7)|(chan[c.chan].state.fb<<3)); + rWrite(0x03,(mod.ksl<<6)|((chan[c.chan].state.fms&1)<<4)|((chan[c.chan].state.ams&1)<<3)|chan[c.chan].state.fb); break; } + case DIV_CMD_FM_MULT: { - unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]]; - DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]]; - op.mult=c.value2&15; - rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4)); + if (c.value==0) { + DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0]; + mod.mult=c.value2&15; + rWrite(0x00,(mod.am<<7)|(mod.vib<<6)|((mod.ssgEnv&8)<<2)|(mod.ksr<<4)|(mod.mult)); + } else { + DivInstrumentFM::Operator& car=chan[c.chan].state.op[1]; + car.mult=c.value2&15; + rWrite(0x30+c.chan,(15-(chan[c.chan].outVol*(15-chan[c.chan].state.op[1].tl))/15)|(chan[c.chan].state.opllPreset<<4)); + } break; } case DIV_CMD_FM_TL: { - unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]]; - DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]]; - op.tl=c.value2; - if (isMuted[c.chan]) { - rWrite(baseAddr+ADDR_TL,127); + if (c.value==0) { + DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0]; + DivInstrumentFM::Operator& car=chan[c.chan].state.op[1]; + mod.tl=c.value2&63; + rWrite(0x02,(car.ksl<<6)|(mod.tl&63)); } else { - if (isOutput[chan[c.chan].state.alg][c.value]) { - rWrite(baseAddr+ADDR_TL,127-(((127-op.tl)*(chan[c.chan].outVol&0x7f))/127)); - } else { - rWrite(baseAddr+ADDR_TL,op.tl); - } + DivInstrumentFM::Operator& car=chan[c.chan].state.op[1]; + car.tl=c.value2&15; + rWrite(0x01,(car.am<<7)|(car.vib<<6)|((car.ssgEnv&8)<<2)|(car.ksr<<4)|(car.mult)); } break; } case DIV_CMD_FM_AR: { + DivInstrumentFM::Operator& mod=chan[c.chan].state.op[0]; + DivInstrumentFM::Operator& car=chan[c.chan].state.op[1]; if (c.value<0) { - for (int i=0; i<4; i++) { - DivInstrumentFM::Operator& op=chan[c.chan].state.op[i]; - op.ar=c.value2&31; - unsigned short baseAddr=chanOffs[c.chan]|opOffs[i]; - rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6)); - } + mod.ar=c.value2&15; + car.ar=c.value2&15; } else { - DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]]; - op.ar=c.value2&31; - unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]]; - rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6)); + if (c.value==0) { + mod.ar=c.value2&15; + } else { + car.ar=c.value2&15; + } } - + rWrite(0x04,(mod.ar<<4)|(mod.dr)); + rWrite(0x05,(car.ar<<4)|(car.dr)); break; } - */ case DIV_ALWAYS_SET_VOLUME: return 0; break; @@ -569,7 +565,7 @@ int DivPlatformOPLL::dispatch(DivCommand c) { void DivPlatformOPLL::forceIns() { for (int i=0; i<9; i++) { // update custom preset - if (chan[i].state.opllPreset==0) { + if (chan[i].state.opllPreset==0 && i==lastCustomMemory) { DivInstrumentFM::Operator& mod=chan[i].state.op[0]; DivInstrumentFM::Operator& car=chan[i].state.op[1]; rWrite(0x00,(mod.am<<7)|(mod.vib<<6)|((mod.ssgEnv&8)<<2)|(mod.ksr<<4)|(mod.mult)); @@ -587,12 +583,33 @@ void DivPlatformOPLL::forceIns() { chan[i].freqChanged=true; } } + if (drums) { + immWrite(0x16,0x20); + immWrite(0x26,0x05); + immWrite(0x16,0x20); + immWrite(0x26,0x05); + immWrite(0x17,0x50); + immWrite(0x27,0x05); + immWrite(0x17,0x50); + immWrite(0x27,0x05); + immWrite(0x18,0xC0); + immWrite(0x28,0x01); + } } void DivPlatformOPLL::toggleRegisterDump(bool enable) { DivDispatch::toggleRegisterDump(enable); } +void DivPlatformOPLL::setVRC7(bool vrc) { + vrc7=vrc; +} + +void DivPlatformOPLL::setProperDrums(bool pd) { + properDrums=pd; +} + + void* DivPlatformOPLL::getChanState(int ch) { return &chan[ch]; } @@ -608,7 +625,11 @@ int DivPlatformOPLL::getRegisterPoolSize() { void DivPlatformOPLL::reset() { while (!writes.empty()) writes.pop(); memset(regPool,0,256); - OPLL_Reset(&fm,opll_type_ym2413); + if (vrc7) { + OPLL_Reset(&fm,opll_type_ds1001); + } else { + OPLL_Reset(&fm,opll_type_ym2413); + } if (dumpWrites) { addWrite(0xffffffff,0); } @@ -625,6 +646,7 @@ void DivPlatformOPLL::reset() { lastBusy=60; drumState=0; + lastCustomMemory=-1; drumVol[0]=0; drumVol[1]=0; diff --git a/src/engine/platform/opll.h b/src/engine/platform/opll.h index 5db8e26a8..0bada9036 100644 --- a/src/engine/platform/opll.h +++ b/src/engine/platform/opll.h @@ -35,7 +35,7 @@ class DivPlatformOPLL: public DivDispatch { unsigned char freqH, freqL; int freq, baseFreq, pitch, note; unsigned char ins; - bool active, insChanged, freqChanged, keyOn, keyOff, drums, portaPause, furnaceDac, inPorta; + bool active, insChanged, freqChanged, keyOn, keyOff, portaPause, furnaceDac, inPorta; int vol, outVol; unsigned char pan; Channel(): @@ -51,15 +51,14 @@ class DivPlatformOPLL: public DivDispatch { freqChanged(false), keyOn(false), keyOff(false), - drums(false), portaPause(false), furnaceDac(false), inPorta(false), vol(0), pan(3) {} }; - Channel chan[9]; - bool isMuted[9]; + Channel chan[11]; + bool isMuted[11]; struct QueuedWrite { unsigned short addr; unsigned char val; @@ -68,7 +67,7 @@ class DivPlatformOPLL: public DivDispatch { }; std::queue writes; opll_t fm; - int delay; + int delay, lastCustomMemory; unsigned char lastBusy; unsigned char drumState; unsigned char drumVol[5]; @@ -76,6 +75,9 @@ class DivPlatformOPLL: public DivDispatch { unsigned char regPool[256]; bool useYMFM; + bool drums; + bool properDrums; + bool vrc7; short oldWrites[256]; short pendingWrites[256]; @@ -102,6 +104,8 @@ class DivPlatformOPLL: public DivDispatch { bool keyOffAffectsArp(int ch); bool keyOffAffectsPorta(int ch); void toggleRegisterDump(bool enable); + void setVRC7(bool vrc); + void setProperDrums(bool pd); void setFlags(unsigned int flags); void notifyInsChange(int ins); void notifyInsDeletion(void* ins); diff --git a/src/engine/platform/sound/nes/apu.c b/src/engine/platform/sound/nes/apu.c index a278cbf74..70eddc8e7 100644 --- a/src/engine/platform/sound/nes/apu.c +++ b/src/engine/platform/sound/nes/apu.c @@ -226,4 +226,6 @@ void apu_turn_on(struct NESAPU* a, BYTE apu_type) { a->DMC.length = 1; a->DMC.address_start = 0xC000; a->apu.odd_cycle = 0; + // come non viene inizializzato? Vorrei qualche spiegazione... + a->r4011.frames = 0; } diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index f42eaf1f3..567a2b6e6 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -373,6 +373,39 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char return false; } break; + case DIV_SYSTEM_OPLL: + case DIV_SYSTEM_OPLL_DRUMS: + case DIV_SYSTEM_VRC7: + switch (effect) { + case 0x11: // FB + dispatchCmd(DivCommand(DIV_CMD_FM_FB,ch,effectVal&7)); + break; + case 0x12: // TL op1 + dispatchCmd(DivCommand(DIV_CMD_FM_TL,ch,0,effectVal&0x3f)); + break; + case 0x13: // TL op2 + dispatchCmd(DivCommand(DIV_CMD_FM_TL,ch,1,effectVal&0x0f)); + break; + case 0x16: // MULT + if ((effectVal>>4)>0 && (effectVal>>4)<3) { + dispatchCmd(DivCommand(DIV_CMD_FM_MULT,ch,(effectVal>>4)-1,effectVal&15)); + } + break; + case 0x18: // drum mode toggle + break; + case 0x19: // AR global + dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,-1,effectVal&31)); + break; + case 0x1a: // AR op1 + dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,0,effectVal&31)); + break; + case 0x1b: // AR op2 + dispatchCmd(DivCommand(DIV_CMD_FM_AR,ch,1,effectVal&31)); + break; + default: + return false; + } + break; case DIV_SYSTEM_C64_6581: case DIV_SYSTEM_C64_8580: switch (effect) { case 0x10: // select waveform diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index c74ebcf8d..a0d211c68 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -680,9 +680,9 @@ const char* DivEngine::getSystemChips(DivSystem sys) { case DIV_SYSTEM_AMIGA: return "MOS 8364 Paula"; case DIV_SYSTEM_YM2151: - return "Yamaha YM2151 standalone"; + return "Yamaha YM2151"; case DIV_SYSTEM_YM2612: - return "Yamaha YM2612 standalone"; + return "Yamaha YM2612"; case DIV_SYSTEM_TIA: return "Atari TIA"; case DIV_SYSTEM_VIC20: diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index ec566676b..b9321e3e5 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -1355,7 +1355,7 @@ void FurnaceGUI::drawMixer() { if (ImGui::SliderFloat("Master Volume",&e->song.masterVol,0,3,"%.2fx")) { if (e->song.masterVol<0) e->song.masterVol=0; if (e->song.masterVol>3) e->song.masterVol=3; - } + } rightClickable for (int i=0; isong.systemLen; i++) { snprintf(id,31,"MixS%d",i); bool doInvert=e->song.systemVol[i]&128; @@ -1369,9 +1369,9 @@ void FurnaceGUI::drawMixer() { ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-(50.0f*dpiScale)); if (ImGui::SliderScalar("Volume",ImGuiDataType_S8,&vol,&_ZERO,&_ONE_HUNDRED_TWENTY_SEVEN)) { e->song.systemVol[i]=(e->song.systemVol[i]&128)|vol; - } + } rightClickable ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x-(50.0f*dpiScale)); - ImGui::SliderScalar("Panning",ImGuiDataType_S8,&e->song.systemPan[i],&_MINUS_ONE_HUNDRED_TWENTY_SEVEN,&_ONE_HUNDRED_TWENTY_SEVEN); + ImGui::SliderScalar("Panning",ImGuiDataType_S8,&e->song.systemPan[i],&_MINUS_ONE_HUNDRED_TWENTY_SEVEN,&_ONE_HUNDRED_TWENTY_SEVEN); rightClickable ImGui::PopID(); } @@ -4505,6 +4505,7 @@ bool FurnaceGUI::loop() { sysAddOption(DIV_SYSTEM_AY8910); sysAddOption(DIV_SYSTEM_AMIGA); sysAddOption(DIV_SYSTEM_OPLL); + sysAddOption(DIV_SYSTEM_OPLL_DRUMS); sysAddOption(DIV_SYSTEM_VRC7); sysAddOption(DIV_SYSTEM_TIA); sysAddOption(DIV_SYSTEM_SAA1099); @@ -4700,7 +4701,7 @@ bool FurnaceGUI::loop() { if (stereoSep>127) stereoSep=127; e->setSysFlags(i,(flags&1)|((stereoSep&127)<<8),restart); updateWindowTitle(); - } + } rightClickable /* TODO LATER: I want 0.5 out already if (ImGui::RadioButton("Amiga 500 (OCS)",(flags&2)==0)) { e->setSysFlags(i,flags&1); @@ -4723,7 +4724,7 @@ bool FurnaceGUI::loop() { if (echoBufSize>2725) echoBufSize=2725; e->setSysFlags(i,(flags & ~4095) | ((2725 - echoBufSize) & 4095),restart); updateWindowTitle(); - } + } rightClickable ImGui::Text("Echo feedback:"); int echoFeedback=(flags>>12)&255; if (ImGui::SliderInt("##EchoFeedback",&echoFeedback,0,255)) { @@ -4731,7 +4732,7 @@ bool FurnaceGUI::loop() { if (echoFeedback>255) echoFeedback=255; e->setSysFlags(i,(flags & ~(255 << 12)) | ((echoFeedback & 255) << 12),restart); updateWindowTitle(); - } + } rightClickable break; } case DIV_SYSTEM_GB: @@ -4779,6 +4780,7 @@ bool FurnaceGUI::loop() { sysChangeOption(i,DIV_SYSTEM_AY8910); sysChangeOption(i,DIV_SYSTEM_AMIGA); sysChangeOption(i,DIV_SYSTEM_OPLL); + sysChangeOption(i,DIV_SYSTEM_OPLL_DRUMS); sysChangeOption(i,DIV_SYSTEM_VRC7); sysChangeOption(i,DIV_SYSTEM_TIA); sysChangeOption(i,DIV_SYSTEM_SAA1099); diff --git a/src/gui/gui.h b/src/gui/gui.h index 6eb591754..291db6d8d 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -26,6 +26,8 @@ #include #include +#define rightClickable if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) ImGui::SetKeyboardFocusHere(-1); + enum FurnaceGUIColors { GUI_COLOR_BACKGROUND=0, GUI_COLOR_FRAME_BACKGROUND, @@ -626,7 +628,7 @@ class FurnaceGUI { int lastIns[DIV_MAX_CHANS]; void drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, const ImVec2& size); - void drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr, unsigned char d2r, unsigned char rr, unsigned char sl, const ImVec2& size); + void drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr, unsigned char d2r, unsigned char rr, unsigned char sl, float maxTl, float maxArDr, const ImVec2& size); void updateWindowTitle(); void prepareLayout(); diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 6ead6353a..408c3c150 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -148,6 +148,10 @@ const char* mikeyFeedbackBits[11] = { "0", "1", "2", "3", "4", "5", "7", "10", "11", "int", NULL }; +const char* oneBit[2]={ + "on", NULL +}; + const int orderedOps[4]={ 0, 2, 1, 3 }; @@ -183,6 +187,13 @@ String macroLFOWaves(int id, float val) { return "???"; } +void addAALine(ImDrawList* dl, const ImVec2& p1, const ImVec2& p2, const ImU32 color, float thickness=1.0f) { + ImVec2 pt[2]; + pt[0]=p1; + pt[1]=p2; + dl->AddPolyline(pt,2,color,ImDrawFlags_None,thickness); +} + void FurnaceGUI::drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, const ImVec2& size) { ImDrawList* dl=ImGui::GetWindowDrawList(); ImGuiWindow* window=ImGui::GetCurrentWindow(); @@ -199,7 +210,6 @@ void FurnaceGUI::drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, cons ImGui::ItemSize(size,style.FramePadding.y); if (ImGui::ItemAdd(rect,ImGui::GetID("alg"))) { ImGui::RenderFrame(rect.Min,rect.Max,ImGui::GetColorU32(ImGuiCol_FrameBg),true,style.FrameRounding); - //ImReallyTiredOfThisGarbage(); const float circleRadius=6.0f*dpiScale+1.0f; switch (algType) { case FM_ALGS_4OP: @@ -211,11 +221,11 @@ void FurnaceGUI::drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, cons ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(0.8,0.5)); dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,color); dl->AddCircle(pos1,6.0f*dpiScale+1.0f,color); - dl->AddLine(pos1,pos2,colorL); + addAALine(dl,pos1,pos2,colorL); dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,color); - dl->AddLine(pos2,pos3,colorL); + addAALine(dl,pos2,pos3,colorL); dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,color); - dl->AddLine(pos3,pos4,colorL); + addAALine(dl,pos3,pos4,colorL); dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,color); pos1.x-=ImGui::CalcTextSize("1").x*0.5; @@ -239,11 +249,11 @@ void FurnaceGUI::drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, cons ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.5)); dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,color); dl->AddCircle(pos1,6.0f*dpiScale+1.0f,color); - dl->AddLine(pos1,pos3,colorL); + addAALine(dl,pos1,pos3,colorL); dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,color); - dl->AddLine(pos2,pos3,colorL); + addAALine(dl,pos2,pos3,colorL); dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,color); - dl->AddLine(pos3,pos4,colorL); + addAALine(dl,pos3,pos4,colorL); dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,color); pos2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale; @@ -267,11 +277,11 @@ void FurnaceGUI::drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, cons ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.5)); dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,color); dl->AddCircle(pos1,6.0f*dpiScale+1.0f,color); - dl->AddLine(pos1,pos4,colorL); + addAALine(dl,pos1,pos4,colorL); dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,color); - dl->AddLine(pos2,pos3,colorL); + addAALine(dl,pos2,pos3,colorL); dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,color); - dl->AddLine(pos3,pos4,colorL); + addAALine(dl,pos3,pos4,colorL); dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,color); pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale; @@ -295,11 +305,11 @@ void FurnaceGUI::drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, cons ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.5)); dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,color); dl->AddCircle(pos1,6.0f*dpiScale+1.0f,color); - dl->AddLine(pos1,pos2,colorL); + addAALine(dl,pos1,pos2,colorL); dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,color); - dl->AddLine(pos2,pos4,colorL); + addAALine(dl,pos2,pos4,colorL); dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,color); - dl->AddLine(pos3,pos4,colorL); + addAALine(dl,pos3,pos4,colorL); dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,color); pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale; @@ -324,13 +334,13 @@ void FurnaceGUI::drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, cons ImVec2 pos5=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.5)); dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,color); dl->AddCircle(pos1,6.0f*dpiScale+1.0f,color); - dl->AddLine(pos1,pos2,colorL); + addAALine(dl,pos1,pos2,colorL); dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,color); dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,color); - dl->AddLine(pos3,pos4,colorL); + addAALine(dl,pos3,pos4,colorL); dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,color); - dl->AddLine(pos2,pos5,colorL); - dl->AddLine(pos4,pos5,colorL); + addAALine(dl,pos2,pos5,colorL); + addAALine(dl,pos4,pos5,colorL); pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale; pos2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale; @@ -354,15 +364,15 @@ void FurnaceGUI::drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, cons ImVec2 pos5=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.5)); dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,color); dl->AddCircle(pos1,6.0f*dpiScale+1.0f,color); - dl->AddLine(pos1,pos2,colorL); - dl->AddLine(pos1,pos3,colorL); - dl->AddLine(pos1,pos4,colorL); + addAALine(dl,pos1,pos2,colorL); + addAALine(dl,pos1,pos3,colorL); + addAALine(dl,pos1,pos4,colorL); dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,color); dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,color); dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,color); - dl->AddLine(pos2,pos5,colorL); - dl->AddLine(pos3,pos5,colorL); - dl->AddLine(pos4,pos5,colorL); + addAALine(dl,pos2,pos5,colorL); + addAALine(dl,pos3,pos5,colorL); + addAALine(dl,pos4,pos5,colorL); pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale; pos2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale; @@ -386,13 +396,13 @@ void FurnaceGUI::drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, cons ImVec2 pos5=ImLerp(rect.Min,rect.Max,ImVec2(0.75,0.5)); dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,color); dl->AddCircle(pos1,6.0f*dpiScale+1.0f,color); - dl->AddLine(pos1,pos2,colorL); + addAALine(dl,pos1,pos2,colorL); dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,color); dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,color); dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,color); - dl->AddLine(pos2,pos5,colorL); - dl->AddLine(pos3,pos5,colorL); - dl->AddLine(pos4,pos5,colorL); + addAALine(dl,pos2,pos5,colorL); + addAALine(dl,pos3,pos5,colorL); + addAALine(dl,pos4,pos5,colorL); pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale; pos2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale; @@ -419,10 +429,10 @@ void FurnaceGUI::drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, cons dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,color); dl->AddCircleFilled(pos3,4.0f*dpiScale+1.0f,color); dl->AddCircleFilled(pos4,4.0f*dpiScale+1.0f,color); - dl->AddLine(pos1,pos5,colorL); - dl->AddLine(pos2,pos5,colorL); - dl->AddLine(pos3,pos5,colorL); - dl->AddLine(pos4,pos5,colorL); + addAALine(dl,pos1,pos5,colorL); + addAALine(dl,pos2,pos5,colorL); + addAALine(dl,pos3,pos5,colorL); + addAALine(dl,pos4,pos5,colorL); pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale; pos2.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale; @@ -447,7 +457,7 @@ void FurnaceGUI::drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, cons ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(0.67,0.5)); dl->AddCircleFilled(pos1,4.0f*dpiScale+1.0f,color); dl->AddCircle(pos1,6.0f*dpiScale+1.0f,color); - dl->AddLine(pos1,pos2,colorL); + addAALine(dl,pos1,pos2,colorL); dl->AddCircleFilled(pos2,4.0f*dpiScale+1.0f,color); pos1.x-=ImGui::CalcTextSize("2").x+circleRadius+3.0*dpiScale; @@ -481,7 +491,7 @@ void FurnaceGUI::drawAlgorithm(unsigned char alg, FurnaceGUIFMAlgs algType, cons } } -void FurnaceGUI::drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr, unsigned char d2r, unsigned char rr, unsigned char sl, const ImVec2& size) { +void FurnaceGUI::drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr, unsigned char d2r, unsigned char rr, unsigned char sl, float maxTl, float maxArDr, const ImVec2& size) { ImDrawList* dl=ImGui::GetWindowDrawList(); ImGuiWindow* window=ImGui::GetCurrentWindow(); @@ -499,8 +509,8 @@ void FurnaceGUI::drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr, ImGui::RenderFrame(rect.Min,rect.Max,ImGui::GetColorU32(ImGuiCol_FrameBg),true,style.FrameRounding); //calculate x positions - float arPos=float(31-ar)/31.0; //peak of AR, start of DR - float drPos=arPos+((sl/15.0)*(float(31-dr)/31.0)); //end of DR, start of D2R + float arPos=float(maxArDr-ar)/maxArDr; //peak of AR, start of DR + float drPos=arPos+((sl/15.0)*(float(maxArDr-dr)/maxArDr)); //end of DR, start of D2R float d2rPos=drPos+(((15.0-sl)/15.0)*(float(31.0-d2r)/31.0)); //End of D2R float rrPos=(float(15-rr)/15.0); //end of RR @@ -511,43 +521,42 @@ void FurnaceGUI::drawFMEnv(unsigned char tl, unsigned char ar, unsigned char dr, rrPos/=1.0; ImVec2 pos1=ImLerp(rect.Min,rect.Max,ImVec2(0.0,1.0)); //the bottom corner - ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(arPos,(tl/127.0))); //peak of AR, start of DR - ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(drPos,(float)((tl/127.0)+(sl/15.0)-((tl/127.0)*(sl/15.0))))); //end of DR, start of D2R + ImVec2 pos2=ImLerp(rect.Min,rect.Max,ImVec2(arPos,(tl/maxTl))); //peak of AR, start of DR + ImVec2 pos3=ImLerp(rect.Min,rect.Max,ImVec2(drPos,(float)((tl/maxTl)+(sl/15.0)-((tl/maxTl)*(sl/15.0))))); //end of DR, start of D2R ImVec2 pos4=ImLerp(rect.Min,rect.Max,ImVec2(d2rPos,1.0)); //end of D2R - ImVec2 posRStart=ImLerp(rect.Min,rect.Max,ImVec2(0.0,(tl/127.0))); //release start + ImVec2 posRStart=ImLerp(rect.Min,rect.Max,ImVec2(0.0,(tl/maxTl))); //release start ImVec2 posREnd=ImLerp(rect.Min,rect.Max,ImVec2(rrPos,1.0));//release end - ImVec2 posSLineHEnd=ImLerp(rect.Min,rect.Max,ImVec2(1.0,(float)((tl/127.0)+(sl/15.0)-((tl/127.0)*(sl/15.0))))); //sustain horizontal line end + ImVec2 posSLineHEnd=ImLerp(rect.Min,rect.Max,ImVec2(1.0,(float)((tl/maxTl)+(sl/15.0)-((tl/maxTl)*(sl/15.0))))); //sustain horizontal line end ImVec2 posSLineVEnd=ImLerp(rect.Min,rect.Max,ImVec2(drPos,1.0)); //sustain vertical line end - ImVec2 posDecayRate0Pt=ImLerp(rect.Min,rect.Max,ImVec2(1.0,(tl/127.0))); //Heght of the peak of AR, forever - ImVec2 posDecay2Rate0Pt=ImLerp(rect.Min,rect.Max,ImVec2(1.0,(float)((tl/127.0)+(sl/15.0)-((tl/127.0)*(sl/15.0))))); //Heght of the peak of SR, forever + ImVec2 posDecayRate0Pt=ImLerp(rect.Min,rect.Max,ImVec2(1.0,(tl/maxTl))); //Heght of the peak of AR, forever + ImVec2 posDecay2Rate0Pt=ImLerp(rect.Min,rect.Max,ImVec2(1.0,(float)((tl/maxTl)+(sl/15.0)-((tl/maxTl)*(sl/15.0))))); //Heght of the peak of SR, forever + //dl->Flags=ImDrawListFlags_AntiAliasedLines|ImDrawListFlags_AntiAliasedLinesUseTex; if (ar==0.0) { //if AR = 0, the envelope never starts dl->AddTriangleFilled(posRStart,posREnd,pos1,colorS); //draw release as shaded triangle behind everything - dl->AddLine(pos1,pos4,color); //draw line on ground - } - else if (dr==0.0 && sl!=0.0) { //if DR = 0 and SL is not 0, then the envelope stays at max volume forever + addAALine(dl,pos1,pos4,color); //draw line on ground + } else if (dr==0.0 && sl!=0.0) { //if DR = 0 and SL is not 0, then the envelope stays at max volume forever dl->AddTriangleFilled(posRStart,posREnd,pos1,colorS); //draw release as shaded triangle behind everything - //dl->AddLine(pos3,posSLineHEnd,colorS); //draw horiz line through sustain level - //dl->AddLine(pos3,posSLineVEnd,colorS); //draw vert. line through sustain level - dl->AddLine(pos1,pos2,color); //A - dl->AddLine(pos2,posDecayRate0Pt,color); //Line from A to end of graph - } - else if(d2r==0.0) { //if D2R = 0, the envelope stays at the sustain level forever + //addAALine(dl,pos3,posSLineHEnd,colorS); //draw horiz line through sustain level + //addAALine(dl,pos3,posSLineVEnd,colorS); //draw vert. line through sustain level + addAALine(dl,pos1,pos2,color); //A + addAALine(dl,pos2,posDecayRate0Pt,color); //Line from A to end of graph + } else if (d2r==0.0) { //if D2R = 0, the envelope stays at the sustain level forever dl->AddTriangleFilled(posRStart,posREnd,pos1,colorS); //draw release as shaded triangle behind everything - dl->AddLine(pos3,posSLineHEnd,colorS); //draw horiz line through sustain level - dl->AddLine(pos3,posSLineVEnd,colorS); //draw vert. line through sustain level - dl->AddLine(pos1,pos2,color); //A - dl->AddLine(pos2,pos3,color); //D - dl->AddLine(pos3,posDecay2Rate0Pt,color); //Line from D to end of graph - } - else { //draw graph normally + addAALine(dl,pos3,posSLineHEnd,colorS); //draw horiz line through sustain level + addAALine(dl,pos3,posSLineVEnd,colorS); //draw vert. line through sustain level + addAALine(dl,pos1,pos2,color); //A + addAALine(dl,pos2,pos3,color); //D + addAALine(dl,pos3,posDecay2Rate0Pt,color); //Line from D to end of graph + } else { //draw graph normally dl->AddTriangleFilled(posRStart,posREnd,pos1,colorS); //draw release as shaded triangle behind everything - dl->AddLine(pos3,posSLineHEnd,colorS); //draw horiz line through sustain level - dl->AddLine(pos3,posSLineVEnd,colorS); //draw vert. line through sustain level - dl->AddLine(pos1,pos2,color); //A - dl->AddLine(pos2,pos3,color); //D - dl->AddLine(pos3,pos4,color); //D2 + addAALine(dl,pos3,posSLineHEnd,colorS); //draw horiz line through sustain level + addAALine(dl,pos3,posSLineVEnd,colorS); //draw vert. line through sustain level + addAALine(dl,pos1,pos2,color); //A + addAALine(dl,pos2,pos3,color); //D + addAALine(dl,pos3,pos4,color); //D2 } + //dl->Flags^=ImDrawListFlags_AntiAliasedLines|ImDrawListFlags_AntiAliasedLinesUseTex; } } @@ -786,6 +795,9 @@ void FurnaceGUI::drawInsEdit() { float asFloat[256]; int asInt[256]; float loopIndicator[256]; + int opCount=4; + if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL) opCount=2; + if (ImGui::BeginTabItem("FM")) { if (ImGui::BeginTable("fmDetails",3,ImGuiTableFlags_SizingStretchSame)) { ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.0); @@ -796,11 +808,11 @@ void FurnaceGUI::drawInsEdit() { case DIV_INS_FM: case DIV_INS_OPZ: ImGui::TableNextColumn(); - P(ImGui::SliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); - P(ImGui::SliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); + P(ImGui::SliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable + P(ImGui::SliderScalar(FM_NAME(FM_FMS),ImGuiDataType_U8,&ins->fm.fms,&_ZERO,&_SEVEN)); rightClickable ImGui::TableNextColumn(); - P(ImGui::SliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); - P(ImGui::SliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); + P(ImGui::SliderScalar(FM_NAME(FM_ALG),ImGuiDataType_U8,&ins->fm.alg,&_ZERO,&_SEVEN)); rightClickable + P(ImGui::SliderScalar(FM_NAME(FM_AMS),ImGuiDataType_U8,&ins->fm.ams,&_ZERO,&_THREE)); rightClickable ImGui::TableNextColumn(); drawAlgorithm(ins->fm.alg,FM_ALGS_4OP,ImVec2(ImGui::GetContentRegionAvail().x,48.0*dpiScale)); break; @@ -811,7 +823,7 @@ void FurnaceGUI::drawInsEdit() { bool sus=ins->fm.alg; ImGui::TableNextColumn(); ImGui::BeginDisabled(ins->fm.opllPreset!=0); - P(ImGui::SliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); + P(ImGui::SliderScalar(FM_NAME(FM_FB),ImGuiDataType_U8,&ins->fm.fb,&_ZERO,&_SEVEN)); rightClickable if (ImGui::Checkbox(FM_NAME(FM_DC),&dc)) { PARAMETER ins->fm.fms=dc; } @@ -849,11 +861,9 @@ void FurnaceGUI::drawInsEdit() { } bool willDisplayOps=true; - int opCount=4; if (ins->type==DIV_INS_OPLL && ins->fm.opllPreset!=0) willDisplayOps=false; - if (ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL) opCount=2; if (!willDisplayOps && ins->type==DIV_INS_OPLL) { - P(ImGui::SliderScalar("Volume##TL",ImGuiDataType_U8,&ins->fm.op[1].tl,&_FIFTEEN,&_ZERO)); + P(ImGui::SliderScalar("Volume##TL",ImGuiDataType_U8,&ins->fm.op[1].tl,&_FIFTEEN,&_ZERO)); rightClickable } if (willDisplayOps) if (ImGui::BeginTable("FMOperators",2,ImGuiTableFlags_SizingStretchSame)) { for (int i=0; itype==DIV_INS_FM || ins->type==DIV_INS_OPZ)?31:15; bool ssgOn=op.ssgEnv&8; bool ksrOn=op.ksr; bool vibOn=op.vib; unsigned char ssgEnv=op.ssgEnv&7; - int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ)?31:15; if (ImGui::Checkbox((ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL)?FM_NAME(FM_EGS):"SSG On",&ssgOn)) { PARAMETER op.ssgEnv=(op.ssgEnv&7)|(ssgOn<<3); } @@ -898,8 +908,8 @@ void FurnaceGUI::drawInsEdit() { } //52.0 controls vert scaling; default 96 - drawFMEnv(op.tl,op.ar,op.dr,op.d2r,op.rr,op.sl,ImVec2(ImGui::GetContentRegionAvail().x,52.0*dpiScale)); - //P(ImGui::SliderScalar(FM_NAME(FM_AR),ImGuiDataType_U8,&op.ar,&_ZERO,&_THIRTY_ONE)); + drawFMEnv(op.tl&maxTl,op.ar&maxArDr,op.dr&maxArDr,(ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL)?((op.rr&15)*2):op.d2r&31,op.rr&15,op.sl&15,maxTl,maxArDr,ImVec2(ImGui::GetContentRegionAvail().x,52.0*dpiScale)); + //P(ImGui::SliderScalar(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); \ @@ -907,21 +917,21 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(ImGui::SliderScalar("##AR",ImGuiDataType_U8,&op.ar,&maxArDr,&_ZERO)); + P(ImGui::SliderScalar("##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); - P(ImGui::SliderScalar("##DR",ImGuiDataType_U8,&op.dr,&maxArDr,&_ZERO)); + P(ImGui::SliderScalar("##DR",ImGuiDataType_U8,&op.dr,&maxArDr,&_ZERO)); rightClickable ImGui::TableNextColumn(); ImGui::Text("%s",FM_NAME(FM_DR)); ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(ImGui::SliderScalar("##SL",ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); + P(ImGui::SliderScalar("##SL",ImGuiDataType_U8,&op.sl,&_FIFTEEN,&_ZERO)); rightClickable ImGui::TableNextColumn(); ImGui::Text("%s",FM_NAME(FM_SL)); @@ -929,7 +939,7 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(ImGui::SliderScalar("##D2R",ImGuiDataType_U8,&op.d2r,&_THIRTY_ONE,&_ZERO)); + P(ImGui::SliderScalar("##D2R",ImGuiDataType_U8,&op.d2r,&_THIRTY_ONE,&_ZERO)); rightClickable ImGui::TableNextColumn(); ImGui::Text("%s",FM_NAME(FM_D2R)); } @@ -937,14 +947,14 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(ImGui::SliderScalar("##RR",ImGuiDataType_U8,&op.rr,&_FIFTEEN,&_ZERO)); + P(ImGui::SliderScalar("##RR",ImGuiDataType_U8,&op.rr,&_FIFTEEN,&_ZERO)); rightClickable ImGui::TableNextColumn(); ImGui::Text("%s",FM_NAME(FM_RR)); ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(ImGui::SliderScalar("##TL",ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); + P(ImGui::SliderScalar("##TL",ImGuiDataType_U8,&op.tl,&maxTl,&_ZERO)); rightClickable ImGui::TableNextColumn(); ImGui::Text("%s",FM_NAME(FM_TL)); @@ -958,11 +968,11 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextColumn(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ) { - P(ImGui::SliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE)); + P(ImGui::SliderScalar("##RS",ImGuiDataType_U8,&op.rs,&_ZERO,&_THREE)); rightClickable ImGui::TableNextColumn(); ImGui::Text("%s",FM_NAME(FM_RS)); } else { - P(ImGui::SliderScalar("##KSL",ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE)); + P(ImGui::SliderScalar("##KSL",ImGuiDataType_U8,&op.ksl,&_ZERO,&_THREE)); rightClickable ImGui::TableNextColumn(); ImGui::Text("%s",FM_NAME(FM_KSL)); } @@ -970,7 +980,7 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(ImGui::SliderScalar(FM_NAME(FM_MULT),ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN)); + P(ImGui::SliderScalar(FM_NAME(FM_MULT),ImGuiDataType_U8,&op.mult,&_ZERO,&_FIFTEEN)); rightClickable ImGui::TableNextColumn(); ImGui::Text("%s",FM_NAME(FM_MULT)); @@ -981,14 +991,14 @@ void FurnaceGUI::drawInsEdit() { ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); if (ImGui::SliderInt("##DT",&detune,-3,3)) { PARAMETER op.dt=detune+3; - } + } rightClickable ImGui::TableNextColumn(); ImGui::Text("%s",FM_NAME(FM_DT)); ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - P(ImGui::SliderScalar("##DT2",ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE)); + P(ImGui::SliderScalar("##DT2",ImGuiDataType_U8,&op.dt2,&_ZERO,&_THREE)); rightClickable if (ImGui::IsItemHovered()) { ImGui::SetTooltip("Only for Arcade system"); } @@ -1000,7 +1010,7 @@ void FurnaceGUI::drawInsEdit() { ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); if (ImGui::SliderScalar("##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)); } @@ -1026,36 +1036,70 @@ void FurnaceGUI::drawInsEdit() { } if (ImGui::BeginTabItem("FM Macros")) { MACRO_BEGIN(0); - NORMAL_MACRO(ins->std.algMacro,ins->std.algMacroLen,ins->std.algMacroLoop,ins->std.algMacroRel,0,7,"alg",FM_NAME(FM_ALG),96,ins->std.algMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[0],0,7,NULL,false); - NORMAL_MACRO(ins->std.fbMacro,ins->std.fbMacroLen,ins->std.fbMacroLoop,ins->std.fbMacroRel,0,7,"fb",FM_NAME(FM_FB),96,ins->std.fbMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[1],0,7,NULL,false); - NORMAL_MACRO(ins->std.fmsMacro,ins->std.fmsMacroLen,ins->std.fmsMacroLoop,ins->std.fmsMacroRel,0,7,"fms",FM_NAME(FM_FMS),96,ins->std.fmsMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[2],0,7,NULL,false); - NORMAL_MACRO(ins->std.amsMacro,ins->std.amsMacroLen,ins->std.amsMacroLoop,ins->std.amsMacroRel,0,3,"ams",FM_NAME(FM_AMS),48,ins->std.amsMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[3],0,3,NULL,false); + if (ins->type==DIV_INS_OPLL) { + NORMAL_MACRO(ins->std.algMacro,ins->std.algMacroLen,ins->std.algMacroLoop,ins->std.algMacroRel,0,1,"alg",FM_NAME(FM_SUS),32,ins->std.algMacroOpen,true,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[0],0,1,NULL,false); + NORMAL_MACRO(ins->std.fbMacro,ins->std.fbMacroLen,ins->std.fbMacroLoop,ins->std.fbMacroRel,0,7,"fb",FM_NAME(FM_FB),96,ins->std.fbMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[1],0,7,NULL,false); + NORMAL_MACRO(ins->std.fmsMacro,ins->std.fmsMacroLen,ins->std.fmsMacroLoop,ins->std.fmsMacroRel,0,1,"fms",FM_NAME(FM_DC),32,ins->std.fmsMacroOpen,true,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[2],0,1,NULL,false); + NORMAL_MACRO(ins->std.amsMacro,ins->std.amsMacroLen,ins->std.amsMacroLoop,ins->std.amsMacroRel,0,1,"ams",FM_NAME(FM_DM),32,ins->std.amsMacroOpen,true,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[3],0,1,NULL,false); + } else { + NORMAL_MACRO(ins->std.algMacro,ins->std.algMacroLen,ins->std.algMacroLoop,ins->std.algMacroRel,0,7,"alg",FM_NAME(FM_ALG),96,ins->std.algMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[0],0,7,NULL,false); + NORMAL_MACRO(ins->std.fbMacro,ins->std.fbMacroLen,ins->std.fbMacroLoop,ins->std.fbMacroRel,0,7,"fb",FM_NAME(FM_FB),96,ins->std.fbMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[1],0,7,NULL,false); + NORMAL_MACRO(ins->std.fmsMacro,ins->std.fmsMacroLen,ins->std.fmsMacroLoop,ins->std.fmsMacroRel,0,7,"fms",FM_NAME(FM_FMS),96,ins->std.fmsMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[2],0,7,NULL,false); + NORMAL_MACRO(ins->std.amsMacro,ins->std.amsMacroLen,ins->std.amsMacroLoop,ins->std.amsMacroRel,0,3,"ams",FM_NAME(FM_AMS),48,ins->std.amsMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[3],0,3,NULL,false); + } - NORMAL_MACRO(ins->std.ex1Macro,ins->std.ex1MacroLen,ins->std.ex1MacroLoop,ins->std.ex1MacroRel,0,127,"ex1","AM Depth",128,ins->std.ex1MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[4],0,127,NULL,false); - NORMAL_MACRO(ins->std.ex2Macro,ins->std.ex2MacroLen,ins->std.ex2MacroLoop,ins->std.ex2MacroRel,0,127,"ex2","PM Depth",128,ins->std.ex2MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[5],0,127,NULL,false); - NORMAL_MACRO(ins->std.ex3Macro,ins->std.ex3MacroLen,ins->std.ex3MacroLoop,ins->std.ex3MacroRel,0,255,"ex3","LFO Speed",128,ins->std.ex3MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[6],0,255,NULL,false); - NORMAL_MACRO(ins->std.waveMacro,ins->std.waveMacroLen,ins->std.waveMacroLoop,ins->std.waveMacroRel,0,3,"wave","LFO Shape",48,ins->std.waveMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_WAVE],mmlString[7],0,3,¯oLFOWaves,false); + if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ) { + NORMAL_MACRO(ins->std.ex1Macro,ins->std.ex1MacroLen,ins->std.ex1MacroLoop,ins->std.ex1MacroRel,0,127,"ex1","AM Depth",128,ins->std.ex1MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[4],0,127,NULL,false); + NORMAL_MACRO(ins->std.ex2Macro,ins->std.ex2MacroLen,ins->std.ex2MacroLoop,ins->std.ex2MacroRel,0,127,"ex2","PM Depth",128,ins->std.ex2MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[5],0,127,NULL,false); + NORMAL_MACRO(ins->std.ex3Macro,ins->std.ex3MacroLen,ins->std.ex3MacroLoop,ins->std.ex3MacroRel,0,255,"ex3","LFO Speed",128,ins->std.ex3MacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_OTHER],mmlString[6],0,255,NULL,false); + NORMAL_MACRO(ins->std.waveMacro,ins->std.waveMacroLen,ins->std.waveMacroLoop,ins->std.waveMacroRel,0,3,"wave","LFO Shape",48,ins->std.waveMacroOpen,false,NULL,false,NULL,0,0,0,NULL,uiColors[GUI_COLOR_MACRO_WAVE],mmlString[7],0,3,¯oLFOWaves,false); + } MACRO_END; ImGui::EndTabItem(); } - for (int i=0; i<4; i++) { + for (int i=0; istd.opMacros[ordi].tlMacro,ins->std.opMacros[ordi].tlMacroLen,ins->std.opMacros[ordi].tlMacroLoop,ins->std.opMacros[ordi].tlMacroRel,127,ordi,"tl",FM_NAME(FM_TL),128,ins->std.opMacros[ordi].tlMacroOpen,false,NULL,mmlString[0]); - OP_MACRO(ins->std.opMacros[ordi].arMacro,ins->std.opMacros[ordi].arMacroLen,ins->std.opMacros[ordi].arMacroLoop,ins->std.opMacros[ordi].arMacroRel,31,ordi,"ar",FM_NAME(FM_AR),64,ins->std.opMacros[ordi].arMacroOpen,false,NULL,mmlString[1]); - OP_MACRO(ins->std.opMacros[ordi].drMacro,ins->std.opMacros[ordi].drMacroLen,ins->std.opMacros[ordi].drMacroLoop,ins->std.opMacros[ordi].drMacroRel,31,ordi,"dr",FM_NAME(FM_DR),64,ins->std.opMacros[ordi].drMacroOpen,false,NULL,mmlString[2]); - OP_MACRO(ins->std.opMacros[ordi].d2rMacro,ins->std.opMacros[ordi].d2rMacroLen,ins->std.opMacros[ordi].d2rMacroLoop,ins->std.opMacros[ordi].d2rMacroRel,31,ordi,"d2r",FM_NAME(FM_D2R),64,ins->std.opMacros[ordi].d2rMacroOpen,false,NULL,mmlString[3]); - OP_MACRO(ins->std.opMacros[ordi].rrMacro,ins->std.opMacros[ordi].rrMacroLen,ins->std.opMacros[ordi].rrMacroLoop,ins->std.opMacros[ordi].rrMacroRel,15,ordi,"rr",FM_NAME(FM_RR),64,ins->std.opMacros[ordi].rrMacroOpen,false,NULL,mmlString[4]); - OP_MACRO(ins->std.opMacros[ordi].slMacro,ins->std.opMacros[ordi].slMacroLen,ins->std.opMacros[ordi].slMacroLoop,ins->std.opMacros[ordi].slMacroRel,15,ordi,"sl",FM_NAME(FM_SL),64,ins->std.opMacros[ordi].slMacroOpen,false,NULL,mmlString[5]); - OP_MACRO(ins->std.opMacros[ordi].rsMacro,ins->std.opMacros[ordi].rsMacroLen,ins->std.opMacros[ordi].rsMacroLoop,ins->std.opMacros[ordi].rsMacroRel,3,ordi,"rs",FM_NAME(FM_RS),32,ins->std.opMacros[ordi].rsMacroOpen,false,NULL,mmlString[6]); - OP_MACRO(ins->std.opMacros[ordi].multMacro,ins->std.opMacros[ordi].multMacroLen,ins->std.opMacros[ordi].multMacroLoop,ins->std.opMacros[ordi].multMacroRel,15,ordi,"mult",FM_NAME(FM_MULT),64,ins->std.opMacros[ordi].multMacroOpen,false,NULL,mmlString[7]); - OP_MACRO(ins->std.opMacros[ordi].dtMacro,ins->std.opMacros[ordi].dtMacroLen,ins->std.opMacros[ordi].dtMacroLoop,ins->std.opMacros[ordi].dtMacroRel,7,ordi,"dt",FM_NAME(FM_DT),64,ins->std.opMacros[ordi].dtMacroOpen,false,NULL,mmlString[8]); - OP_MACRO(ins->std.opMacros[ordi].dt2Macro,ins->std.opMacros[ordi].dt2MacroLen,ins->std.opMacros[ordi].dt2MacroLoop,ins->std.opMacros[ordi].dt2MacroRel,3,ordi,"dt2",FM_NAME(FM_DT2),32,ins->std.opMacros[ordi].dt2MacroOpen,false,NULL,mmlString[9]); - OP_MACRO(ins->std.opMacros[ordi].amMacro,ins->std.opMacros[ordi].amMacroLen,ins->std.opMacros[ordi].amMacroLoop,ins->std.opMacros[ordi].amMacroRel,1,ordi,"am",FM_NAME(FM_AM),32,ins->std.opMacros[ordi].amMacroOpen,true,NULL,mmlString[10]); - OP_MACRO(ins->std.opMacros[ordi].ssgMacro,ins->std.opMacros[ordi].ssgMacroLen,ins->std.opMacros[ordi].ssgMacroLoop,ins->std.opMacros[ordi].ssgMacroRel,4,ordi,"ssg",FM_NAME(FM_SSG),64,ins->std.opMacros[ordi].ssgMacroOpen,true,ssgEnvBits,mmlString[11]); + int ordi=(opCount==4)?orderedOps[i]:i; + int maxTl=127; + if (ins->type==DIV_INS_OPLL) { + if (i==1) { + maxTl=15; + } else { + maxTl=63; + } + } + int maxArDr=(ins->type==DIV_INS_FM || ins->type==DIV_INS_OPZ)?31:15; + + if (ins->type==DIV_INS_OPLL) { + OP_MACRO(ins->std.opMacros[ordi].tlMacro,ins->std.opMacros[ordi].tlMacroLen,ins->std.opMacros[ordi].tlMacroLoop,ins->std.opMacros[ordi].tlMacroRel,maxTl,ordi,"tl",FM_NAME(FM_TL),128,ins->std.opMacros[ordi].tlMacroOpen,false,NULL,mmlString[0]); + OP_MACRO(ins->std.opMacros[ordi].arMacro,ins->std.opMacros[ordi].arMacroLen,ins->std.opMacros[ordi].arMacroLoop,ins->std.opMacros[ordi].arMacroRel,maxArDr,ordi,"ar",FM_NAME(FM_AR),64,ins->std.opMacros[ordi].arMacroOpen,false,NULL,mmlString[1]); + OP_MACRO(ins->std.opMacros[ordi].drMacro,ins->std.opMacros[ordi].drMacroLen,ins->std.opMacros[ordi].drMacroLoop,ins->std.opMacros[ordi].drMacroRel,maxArDr,ordi,"dr",FM_NAME(FM_DR),64,ins->std.opMacros[ordi].drMacroOpen,false,NULL,mmlString[2]); + OP_MACRO(ins->std.opMacros[ordi].slMacro,ins->std.opMacros[ordi].slMacroLen,ins->std.opMacros[ordi].slMacroLoop,ins->std.opMacros[ordi].slMacroRel,15,ordi,"sl",FM_NAME(FM_SL),64,ins->std.opMacros[ordi].slMacroOpen,false,NULL,mmlString[5]); + OP_MACRO(ins->std.opMacros[ordi].rrMacro,ins->std.opMacros[ordi].rrMacroLen,ins->std.opMacros[ordi].rrMacroLoop,ins->std.opMacros[ordi].rrMacroRel,15,ordi,"rr",FM_NAME(FM_RR),64,ins->std.opMacros[ordi].rrMacroOpen,false,NULL,mmlString[4]); + OP_MACRO(ins->std.opMacros[ordi].kslMacro,ins->std.opMacros[ordi].kslMacroLen,ins->std.opMacros[ordi].kslMacroLoop,ins->std.opMacros[ordi].kslMacroRel,3,ordi,"ksl",FM_NAME(FM_KSL),32,ins->std.opMacros[ordi].kslMacroOpen,false,NULL,mmlString[6]); + OP_MACRO(ins->std.opMacros[ordi].multMacro,ins->std.opMacros[ordi].multMacroLen,ins->std.opMacros[ordi].multMacroLoop,ins->std.opMacros[ordi].multMacroRel,15,ordi,"mult",FM_NAME(FM_MULT),64,ins->std.opMacros[ordi].multMacroOpen,false,NULL,mmlString[7]); + + OP_MACRO(ins->std.opMacros[ordi].amMacro,ins->std.opMacros[ordi].amMacroLen,ins->std.opMacros[ordi].amMacroLoop,ins->std.opMacros[ordi].amMacroRel,1,ordi,"am",FM_NAME(FM_AM),32,ins->std.opMacros[ordi].amMacroOpen,true,NULL,mmlString[8]); + OP_MACRO(ins->std.opMacros[ordi].vibMacro,ins->std.opMacros[ordi].vibMacroLen,ins->std.opMacros[ordi].vibMacroLoop,ins->std.opMacros[ordi].vibMacroRel,1,ordi,"vib",FM_NAME(FM_VIB),32,ins->std.opMacros[ordi].vibMacroOpen,true,NULL,mmlString[9]); + OP_MACRO(ins->std.opMacros[ordi].ksrMacro,ins->std.opMacros[ordi].ksrMacroLen,ins->std.opMacros[ordi].ksrMacroLoop,ins->std.opMacros[ordi].ksrMacroRel,1,ordi,"ksr",FM_NAME(FM_KSR),32,ins->std.opMacros[ordi].ksrMacroOpen,true,NULL,mmlString[10]); + OP_MACRO(ins->std.opMacros[ordi].egtMacro,ins->std.opMacros[ordi].egtMacroLen,ins->std.opMacros[ordi].egtMacroLoop,ins->std.opMacros[ordi].egtMacroRel,1,ordi,"egt",FM_NAME(FM_EGS),32,ins->std.opMacros[ordi].egtMacroOpen,true,NULL,mmlString[11]); + } else { + OP_MACRO(ins->std.opMacros[ordi].tlMacro,ins->std.opMacros[ordi].tlMacroLen,ins->std.opMacros[ordi].tlMacroLoop,ins->std.opMacros[ordi].tlMacroRel,maxTl,ordi,"tl",FM_NAME(FM_TL),128,ins->std.opMacros[ordi].tlMacroOpen,false,NULL,mmlString[0]); + OP_MACRO(ins->std.opMacros[ordi].arMacro,ins->std.opMacros[ordi].arMacroLen,ins->std.opMacros[ordi].arMacroLoop,ins->std.opMacros[ordi].arMacroRel,maxArDr,ordi,"ar",FM_NAME(FM_AR),64,ins->std.opMacros[ordi].arMacroOpen,false,NULL,mmlString[1]); + OP_MACRO(ins->std.opMacros[ordi].drMacro,ins->std.opMacros[ordi].drMacroLen,ins->std.opMacros[ordi].drMacroLoop,ins->std.opMacros[ordi].drMacroRel,maxArDr,ordi,"dr",FM_NAME(FM_DR),64,ins->std.opMacros[ordi].drMacroOpen,false,NULL,mmlString[2]); + OP_MACRO(ins->std.opMacros[ordi].d2rMacro,ins->std.opMacros[ordi].d2rMacroLen,ins->std.opMacros[ordi].d2rMacroLoop,ins->std.opMacros[ordi].d2rMacroRel,31,ordi,"d2r",FM_NAME(FM_D2R),64,ins->std.opMacros[ordi].d2rMacroOpen,false,NULL,mmlString[3]); + OP_MACRO(ins->std.opMacros[ordi].rrMacro,ins->std.opMacros[ordi].rrMacroLen,ins->std.opMacros[ordi].rrMacroLoop,ins->std.opMacros[ordi].rrMacroRel,15,ordi,"rr",FM_NAME(FM_RR),64,ins->std.opMacros[ordi].rrMacroOpen,false,NULL,mmlString[4]); + OP_MACRO(ins->std.opMacros[ordi].slMacro,ins->std.opMacros[ordi].slMacroLen,ins->std.opMacros[ordi].slMacroLoop,ins->std.opMacros[ordi].slMacroRel,15,ordi,"sl",FM_NAME(FM_SL),64,ins->std.opMacros[ordi].slMacroOpen,false,NULL,mmlString[5]); + OP_MACRO(ins->std.opMacros[ordi].rsMacro,ins->std.opMacros[ordi].rsMacroLen,ins->std.opMacros[ordi].rsMacroLoop,ins->std.opMacros[ordi].rsMacroRel,3,ordi,"rs",FM_NAME(FM_RS),32,ins->std.opMacros[ordi].rsMacroOpen,false,NULL,mmlString[6]); + OP_MACRO(ins->std.opMacros[ordi].multMacro,ins->std.opMacros[ordi].multMacroLen,ins->std.opMacros[ordi].multMacroLoop,ins->std.opMacros[ordi].multMacroRel,15,ordi,"mult",FM_NAME(FM_MULT),64,ins->std.opMacros[ordi].multMacroOpen,false,NULL,mmlString[7]); + OP_MACRO(ins->std.opMacros[ordi].dtMacro,ins->std.opMacros[ordi].dtMacroLen,ins->std.opMacros[ordi].dtMacroLoop,ins->std.opMacros[ordi].dtMacroRel,7,ordi,"dt",FM_NAME(FM_DT),64,ins->std.opMacros[ordi].dtMacroOpen,false,NULL,mmlString[8]); + OP_MACRO(ins->std.opMacros[ordi].dt2Macro,ins->std.opMacros[ordi].dt2MacroLen,ins->std.opMacros[ordi].dt2MacroLoop,ins->std.opMacros[ordi].dt2MacroRel,3,ordi,"dt2",FM_NAME(FM_DT2),32,ins->std.opMacros[ordi].dt2MacroOpen,false,NULL,mmlString[9]); + OP_MACRO(ins->std.opMacros[ordi].amMacro,ins->std.opMacros[ordi].amMacroLen,ins->std.opMacros[ordi].amMacroLoop,ins->std.opMacros[ordi].amMacroRel,1,ordi,"am",FM_NAME(FM_AM),32,ins->std.opMacros[ordi].amMacroOpen,true,NULL,mmlString[10]); + OP_MACRO(ins->std.opMacros[ordi].ssgMacro,ins->std.opMacros[ordi].ssgMacroLen,ins->std.opMacros[ordi].ssgMacroLoop,ins->std.opMacros[ordi].ssgMacroRel,4,ordi,"ssg",FM_NAME(FM_SSG),64,ins->std.opMacros[ordi].ssgMacroOpen,true,ssgEnvBits,mmlString[11]); + } MACRO_END; ImGui::PopID(); ImGui::EndTabItem(); @@ -1063,9 +1107,9 @@ void FurnaceGUI::drawInsEdit() { } } if (ins->type==DIV_INS_GB) if (ImGui::BeginTabItem("Game Boy")) { - P(ImGui::SliderScalar("Volume",ImGuiDataType_U8,&ins->gb.envVol,&_ZERO,&_FIFTEEN)); - P(ImGui::SliderScalar("Envelope Length",ImGuiDataType_U8,&ins->gb.envLen,&_ZERO,&_SEVEN)); - P(ImGui::SliderScalar("Sound Length",ImGuiDataType_U8,&ins->gb.soundLen,&_ZERO,&_SIXTY_FOUR,ins->gb.soundLen>63?"Infinity":"%d")); + P(ImGui::SliderScalar("Volume",ImGuiDataType_U8,&ins->gb.envVol,&_ZERO,&_FIFTEEN)); rightClickable + P(ImGui::SliderScalar("Envelope Length",ImGuiDataType_U8,&ins->gb.envLen,&_ZERO,&_SEVEN)); rightClickable + P(ImGui::SliderScalar("Sound Length",ImGuiDataType_U8,&ins->gb.soundLen,&_ZERO,&_SIXTY_FOUR,ins->gb.soundLen>63?"Infinity":"%d")); rightClickable ImGui::Text("Envelope Direction:"); bool goesUp=ins->gb.envDir; @@ -1108,11 +1152,11 @@ void FurnaceGUI::drawInsEdit() { } ImGui::PopStyleColor(); - P(ImGui::SliderScalar("Attack",ImGuiDataType_U8,&ins->c64.a,&_ZERO,&_FIFTEEN)); - P(ImGui::SliderScalar("Decay",ImGuiDataType_U8,&ins->c64.d,&_ZERO,&_FIFTEEN)); - P(ImGui::SliderScalar("Sustain",ImGuiDataType_U8,&ins->c64.s,&_ZERO,&_FIFTEEN)); - P(ImGui::SliderScalar("Release",ImGuiDataType_U8,&ins->c64.r,&_ZERO,&_FIFTEEN)); - P(ImGui::SliderScalar("Duty",ImGuiDataType_U16,&ins->c64.duty,&_ZERO,&_FOUR_THOUSAND_NINETY_FIVE)); + P(ImGui::SliderScalar("Attack",ImGuiDataType_U8,&ins->c64.a,&_ZERO,&_FIFTEEN)); rightClickable + P(ImGui::SliderScalar("Decay",ImGuiDataType_U8,&ins->c64.d,&_ZERO,&_FIFTEEN)); rightClickable + P(ImGui::SliderScalar("Sustain",ImGuiDataType_U8,&ins->c64.s,&_ZERO,&_FIFTEEN)); rightClickable + P(ImGui::SliderScalar("Release",ImGuiDataType_U8,&ins->c64.r,&_ZERO,&_FIFTEEN)); rightClickable + P(ImGui::SliderScalar("Duty",ImGuiDataType_U16,&ins->c64.duty,&_ZERO,&_FOUR_THOUSAND_NINETY_FIVE)); rightClickable bool ringMod=ins->c64.ringMod; if (ImGui::Checkbox("Ring Modulation",&ringMod)) { PARAMETER @@ -1126,8 +1170,8 @@ void FurnaceGUI::drawInsEdit() { P(ImGui::Checkbox("Enable filter",&ins->c64.toFilter)); P(ImGui::Checkbox("Initialize filter",&ins->c64.initFilter)); - P(ImGui::SliderScalar("Cutoff",ImGuiDataType_U16,&ins->c64.cut,&_ZERO,&_TWO_THOUSAND_FORTY_SEVEN)); - P(ImGui::SliderScalar("Resonance",ImGuiDataType_U8,&ins->c64.res,&_ZERO,&_FIFTEEN)); + P(ImGui::SliderScalar("Cutoff",ImGuiDataType_U16,&ins->c64.cut,&_ZERO,&_TWO_THOUSAND_FORTY_SEVEN)); rightClickable + P(ImGui::SliderScalar("Resonance",ImGuiDataType_U8,&ins->c64.res,&_ZERO,&_FIFTEEN)); rightClickable ImGui::Text("Filter Mode"); ImGui::SameLine(); diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 52faa7b95..136e95122 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -292,7 +292,7 @@ void FurnaceGUI::drawSettings() { if (ImGui::SliderFloat("UI scaling factor",&settings.dpiScale,1.0f,3.0f,"%.2fx")) { if (settings.dpiScale<0.5f) settings.dpiScale=0.5f; if (settings.dpiScale>3.0f) settings.dpiScale=3.0f; - } + } rightClickable } ImGui::Text("Main font"); ImGui::SameLine();