From e702e569013bae84d2e5819e7da27a9faf64b704 Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Wed, 1 Nov 2023 14:56:43 +0700 Subject: [PATCH 01/15] Add X-Y Oscilloscope --- CMakeLists.txt | 1 + src/gui/doAction.cpp | 6 ++ src/gui/gui.cpp | 39 ++++++++ src/gui/gui.h | 18 +++- src/gui/guiConst.cpp | 1 + src/gui/xyOsc.cpp | 231 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 src/gui/xyOsc.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b754d56c..d50f19328 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -809,6 +809,7 @@ src/gui/tutorial.cpp src/gui/util.cpp src/gui/waveEdit.cpp src/gui/volMeter.cpp +src/gui/xyOsc.cpp src/gui/gui.cpp ) diff --git a/src/gui/doAction.cpp b/src/gui/doAction.cpp index 8a1fd8a2e..0d1bcf623 100644 --- a/src/gui/doAction.cpp +++ b/src/gui/doAction.cpp @@ -279,6 +279,9 @@ void FurnaceGUI::doAction(int what) { case GUI_ACTION_WINDOW_GROOVES: nextWindow=GUI_WINDOW_GROOVES; break; + case GUI_ACTION_WINDOW_XY_OSC: + nextWindow=GUI_WINDOW_XY_OSC; + break; case GUI_ACTION_COLLAPSE_WINDOW: collapseWindow=true; @@ -375,6 +378,9 @@ void FurnaceGUI::doAction(int what) { case GUI_WINDOW_GROOVES: groovesOpen=false; break; + case GUI_WINDOW_XY_OSC: + xyOscOpen=false; + break; default: break; } diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 2a4bc8a0a..70fb9508e 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -3430,6 +3430,7 @@ bool FurnaceGUI::loop() { DECLARE_METRIC(readOsc) DECLARE_METRIC(osc) DECLARE_METRIC(chanOsc) + DECLARE_METRIC(xyOsc) DECLARE_METRIC(volMeter) DECLARE_METRIC(settings) DECLARE_METRIC(debug) @@ -4425,6 +4426,7 @@ bool FurnaceGUI::loop() { if (ImGui::MenuItem("piano/input pad",BIND_FOR(GUI_ACTION_WINDOW_PIANO),pianoOpen)) pianoOpen=!pianoOpen; if (ImGui::MenuItem("oscilloscope (master)",BIND_FOR(GUI_ACTION_WINDOW_OSCILLOSCOPE),oscOpen)) oscOpen=!oscOpen; if (ImGui::MenuItem("oscilloscope (per-channel)",BIND_FOR(GUI_ACTION_WINDOW_CHAN_OSC),chanOscOpen)) chanOscOpen=!chanOscOpen; + if (ImGui::MenuItem("oscilloscope (X-Y)",BIND_FOR(GUI_ACTION_WINDOW_XY_OSC),xyOscOpen)) xyOscOpen=!xyOscOpen; if (ImGui::MenuItem("volume meter",BIND_FOR(GUI_ACTION_WINDOW_VOL_METER),volMeterOpen)) volMeterOpen=!volMeterOpen; if (ImGui::MenuItem("clock",BIND_FOR(GUI_ACTION_WINDOW_CLOCK),clockOpen)) clockOpen=!clockOpen; if (ImGui::MenuItem("register view",BIND_FOR(GUI_ACTION_WINDOW_REGISTER_VIEW),regViewOpen)) regViewOpen=!regViewOpen; @@ -4645,6 +4647,7 @@ bool FurnaceGUI::loop() { MEASURE(readOsc,readOsc()); MEASURE(osc,drawOsc()); MEASURE(chanOsc,drawChanOsc()); + MEASURE(xyOsc,drawXYOsc()); MEASURE(grooves,drawGrooves()); MEASURE(regView,drawRegView()); } else { @@ -4674,6 +4677,7 @@ bool FurnaceGUI::loop() { MEASURE(osc,drawOsc()); MEASURE(chanOsc,drawChanOsc()); + MEASURE(xyOsc,drawXYOsc()); MEASURE(volMeter,drawVolMeter()); MEASURE(settings,drawSettings()); MEASURE(debug,drawDebug()); @@ -6413,6 +6417,7 @@ bool FurnaceGUI::init() { mixerOpen=e->getConfBool("mixerOpen",false); oscOpen=e->getConfBool("oscOpen",true); chanOscOpen=e->getConfBool("chanOscOpen",false); + xyOscOpen=e->getConfBool("xyOscOpen",false); volMeterOpen=e->getConfBool("volMeterOpen",true); statsOpen=e->getConfBool("statsOpen",false); compatFlagsOpen=e->getConfBool("compatFlagsOpen",false); @@ -6521,6 +6526,16 @@ bool FurnaceGUI::init() { chanOscGrad.fromString(e->getConfString("chanOscGrad","")); chanOscGrad.render(); + xyOscXChannel=e->getConfInt("xyOscXChannel",0); + xyOscXInvert=e->getConfBool("xyOscXInvert",false); + xyOscYChannel=e->getConfInt("xyOscYChannel",1); + xyOscYInvert=e->getConfBool("xyOscYInvert",false); + xyOscZoom=e->getConfFloat("xyOscZoom",1.0f); + xyOscSamples=e->getConfInt("xyOscSamples",32768); + xyOscDecayTime=e->getConfFloat("xyOscDecayTime",10.0f); + xyOscIntensity=e->getConfFloat("xyOscIntensity",2.0f); + xyOscThickness=e->getConfFloat("xyOscThickness",2.0f); + syncSettings(); syncTutorial(); @@ -6968,6 +6983,7 @@ void FurnaceGUI::commitState() { e->setConf("mixerOpen",mixerOpen); e->setConf("oscOpen",oscOpen); e->setConf("chanOscOpen",chanOscOpen); + e->setConf("xyOscOpen",xyOscOpen); e->setConf("volMeterOpen",volMeterOpen); e->setConf("statsOpen",statsOpen); e->setConf("compatFlagsOpen",compatFlagsOpen); @@ -7062,6 +7078,17 @@ void FurnaceGUI::commitState() { e->setConf("chanOscUseGrad",chanOscUseGrad); e->setConf("chanOscGrad",chanOscGrad.toString()); + // commit x-y osc state + e->setConf("xyOscXChannel",xyOscXChannel); + e->setConf("xyOscXInvert",xyOscXInvert); + e->setConf("xyOscYChannel",xyOscYChannel); + e->setConf("xyOscYInvert",xyOscYInvert); + e->setConf("xyOscZoom",xyOscZoom); + e->setConf("xyOscSamples",xyOscSamples); + e->setConf("xyOscDecayTime",xyOscDecayTime); + e->setConf("xyOscIntensity",xyOscIntensity); + e->setConf("xyOscThickness",xyOscThickness); + // commit recent files for (int i=0; i<30; i++) { String key=fmt::sprintf("recentFile%d",i); @@ -7301,6 +7328,7 @@ FurnaceGUI::FurnaceGUI(): clockOpen(false), speedOpen(true), groovesOpen(false), + xyOscOpen(false), basicMode(true), shortIntro(false), insListDir(false), @@ -7541,6 +7569,17 @@ FurnaceGUI::FurnaceGUI(): chanOscGrad(64,64), chanOscGradTex(NULL), chanOscWorkPool(NULL), + xyOscPointTex(NULL), + xyOscOptions(false), + xyOscXChannel(0), + xyOscXInvert(false), + xyOscYChannel(1), + xyOscYInvert(false), + xyOscZoom(1.0f), + xyOscSamples(32768), + xyOscDecayTime(10.0f), + xyOscIntensity(2.0f), + xyOscThickness(2.0f), followLog(true), #ifdef IS_MOBILE pianoOctaves(7), diff --git a/src/gui/gui.h b/src/gui/gui.h index 5d98548f7..39a412e9b 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -419,6 +419,7 @@ enum FurnaceGUIWindows { GUI_WINDOW_FIND, GUI_WINDOW_CLOCK, GUI_WINDOW_GROOVES, + GUI_WINDOW_XY_OSC, GUI_WINDOW_INTRO_MON, GUI_WINDOW_SPOILER }; @@ -572,6 +573,7 @@ enum FurnaceGUIActions { GUI_ACTION_WINDOW_FIND, GUI_ACTION_WINDOW_CLOCK, GUI_ACTION_WINDOW_GROOVES, + GUI_ACTION_WINDOW_XY_OSC, GUI_ACTION_COLLAPSE_WINDOW, GUI_ACTION_CLOSE_WINDOW, @@ -1873,7 +1875,7 @@ class FurnaceGUI { bool mixerOpen, debugOpen, inspectorOpen, oscOpen, volMeterOpen, statsOpen, compatFlagsOpen; bool pianoOpen, notesOpen, channelsOpen, regViewOpen, logOpen, effectListOpen, chanOscOpen; bool subSongsOpen, findOpen, spoilerOpen, patManagerOpen, sysManagerOpen, clockOpen, speedOpen; - bool groovesOpen; + bool groovesOpen, xyOscOpen; bool basicMode, shortIntro; bool insListDir, waveListDir, sampleListDir; @@ -2167,6 +2169,19 @@ class FurnaceGUI { planI(NULL) {} } chanOscChan[DIV_MAX_CHANS]; + // x-y oscilloscope + FurnaceGUITexture* xyOscPointTex; + bool xyOscOptions; + int xyOscXChannel; + bool xyOscXInvert; + int xyOscYChannel; + bool xyOscYInvert; + float xyOscZoom; + int xyOscSamples; + float xyOscDecayTime; + float xyOscIntensity; + float xyOscThickness; + // visualizer float keyHit[DIV_MAX_CHANS]; float keyHit1[DIV_MAX_CHANS]; @@ -2357,6 +2372,7 @@ class FurnaceGUI { void drawSpoiler(); void drawClock(); void drawTutorial(); + void drawXYOsc(); void parseKeybinds(); void promptKey(int which); diff --git a/src/gui/guiConst.cpp b/src/gui/guiConst.cpp index a31273004..0411d8a3c 100644 --- a/src/gui/guiConst.cpp +++ b/src/gui/guiConst.cpp @@ -594,6 +594,7 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={ D("WINDOW_FIND", "Find/Replace", FURKMOD_CMD|SDLK_f), D("WINDOW_CLOCK", "Clock", 0), D("WINDOW_GROOVES", "Grooves", 0), + D("WINDOW_XY_OSC", "Oscilloscope (X-Y)", 0), D("COLLAPSE_WINDOW", "Collapse/expand current window", 0), D("CLOSE_WINDOW", "Close current window", FURKMOD_SHIFT|SDLK_ESCAPE), diff --git a/src/gui/xyOsc.cpp b/src/gui/xyOsc.cpp new file mode 100644 index 000000000..d31ff5edc --- /dev/null +++ b/src/gui/xyOsc.cpp @@ -0,0 +1,231 @@ +/** + * Furnace Tracker - multi-system chiptune tracker + * Copyright (C) 2021-2023 tildearrow and contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "gui.h" +#include "imgui_internal.h" +#include +#include "../ta-log.h" +#include "../engine/filter.h" + +void FurnaceGUI::drawXYOsc() { + if (nextWindow==GUI_WINDOW_XY_OSC) { + xyOscOpen=true; + ImGui::SetNextWindowFocus(); + nextWindow=GUI_WINDOW_NOTHING; + } + if (!xyOscOpen) return; + ImGui::SetNextWindowSizeConstraints(ImVec2(64.0f*dpiScale,32.0f*dpiScale),ImVec2(canvasW,canvasH)); + if (settings.oscTakesEntireWindow && !xyOscOptions) { + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding,ImVec2(0,0)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,ImVec2(0,0)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing,ImVec2(0,0)); + } + if (ImGui::Begin("Oscilloscope (X-Y)",&xyOscOpen,globalWinFlags)) { + if (xyOscOptions) { + int xyOscXChannelP1 = xyOscXChannel+1; + int xyOscYChannelP1 = xyOscYChannel+1; + + ImGui::Text("X Channel"); + ImGui::SameLine(); + if (ImGui::DragInt("##XChannel",&xyOscXChannelP1,1.0f,1,DIV_MAX_OUTPUTS)) { + xyOscXChannel=MIN(MAX(xyOscXChannelP1,1),DIV_MAX_OUTPUTS)-1; + } rightClickable + ImGui::SameLine(); + ImGui::Checkbox("Invert##X",&xyOscXInvert); + ImGui::Text("Y Channel"); + ImGui::SameLine(); + if (ImGui::DragInt("##YChannel",&xyOscYChannelP1,1.0f,1,DIV_MAX_OUTPUTS)) { + xyOscXChannel=MIN(MAX(xyOscYChannelP1,1),DIV_MAX_OUTPUTS)-1; + } rightClickable + ImGui::SameLine(); + ImGui::Checkbox("Invert##Y",&xyOscYInvert); + if (ImGui::SliderFloat("Zoom",&xyOscZoom,0.5f,4.0f,"%.2fx")) { + xyOscZoom=MAX(xyOscZoom,0.0f); + } rightClickable + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("%.1fdB",20.0f*log10f(xyOscZoom)); + } + if (ImGui::IsItemClicked(ImGuiMouseButton_Middle)) { + xyOscZoom=1.0f; + } + if (ImGui::SliderInt("Samples",&xyOscSamples,2,32768)) { + xyOscSamples=MIN(MAX(xyOscSamples,2),32768); + } rightClickable + if (ImGui::SliderFloat("Decay Time (ms)",&xyOscDecayTime,1.0f,1000.0f,"%.1f",ImGuiSliderFlags_Logarithmic)) { + xyOscDecayTime=MAX(xyOscDecayTime,0.0f); + } rightClickable + if (ImGui::SliderFloat("Intensity",&xyOscIntensity,0.0f,2.0f,"%.2f")) { + xyOscIntensity=MAX(xyOscIntensity,0.0f); + } rightClickable + if (ImGui::SliderFloat("Line Thickness",&xyOscThickness,0.0f,10.0f,"%.2f")) { + xyOscThickness=MAX(xyOscThickness,0.0f); + } rightClickable + if (ImGui::Button("OK")) { + xyOscOptions=false; + } + } else { + ImDrawList* dl=ImGui::GetWindowDrawList(); + ImGuiWindow* window=ImGui::GetCurrentWindow(); + ImVec2 size=ImGui::GetContentRegionAvail(); + + ImVec2 minArea=window->DC.CursorPos; + ImVec2 maxArea=ImVec2( + minArea.x+size.x, + minArea.y+size.y + ); + ImRect rect=ImRect(minArea,maxArea); + ImRect inRect=rect; + inRect.Min.x+=dpiScale; + inRect.Min.y+=dpiScale; + inRect.Max.x-=dpiScale; + inRect.Max.y-=dpiScale; + ImVec2 inSqrCenter=rect.GetCenter(); + float inSqrLength; + ImRect inSqr=inRect; + if (rect.GetWidth() > rect.GetHeight()) { + inSqrLength=inSqr.GetHeight()/2; + inSqr.Min.x=inSqrCenter.x-inSqrLength; + inSqr.Max.x=inSqrCenter.x+inSqrLength; + } else { + inSqrLength=inSqr.GetWidth()/2; + inSqr.Min.y=inSqrCenter.y-inSqrLength; + inSqr.Max.y=inSqrCenter.y+inSqrLength; + } + float scaleX=xyOscZoom*inSqrLength*(xyOscXInvert?-1:1); + float scaleY=xyOscZoom*inSqrLength*(xyOscYInvert?1:-1); + const ImGuiStyle& style=ImGui::GetStyle(); + ImU32 color=ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_WAVE]); + color&=~IM_COL32_A_MASK; + ImU32 borderColor=ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_BORDER]); + ImU32 refColor=ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_REF]); + ImU32 guideColor=ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_GUIDE]); + ImGui::ItemSize(size,style.FramePadding.y); + if (ImGui::ItemAdd(rect,ImGui::GetID("wsDisplay"))) { + // background + dl->AddRectFilledMultiColor( + inRect.Min, + inRect.Max, + ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_BG1]), + ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_BG2]), + ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_BG4]), + ImGui::GetColorU32(uiColors[GUI_COLOR_OSC_BG3]), + settings.oscRoundedCorners?(8.0f*dpiScale):0.0f + ); + + // axis guides + dl->AddLine( + ImLerp(rect.Min,rect.Max,ImVec2(0.0f,0.5f)), + ImLerp(rect.Min,rect.Max,ImVec2(1.0f,0.5f)), + refColor, + dpiScale + ); + + dl->AddLine( + ImLerp(rect.Min,rect.Max,ImVec2(0.5f,0.0f)), + ImLerp(rect.Min,rect.Max,ImVec2(0.5f,1.0f)), + refColor, + dpiScale + ); + + bool reflect=xyOscXInvert!=xyOscYInvert; + dl->AddLine( + ImLerp(inSqr.Min,inSqr.Max,ImVec2(0.0f,reflect?0.0f:1.0f)), + ImLerp(inSqr.Min,inSqr.Max,ImVec2(1.0f,reflect?1.0f:0.0f)), + refColor, + dpiScale + ); + + for (int i=1; i<5; i++) { + float ip = (float)i/8.f; + dl->AddRect( + ImLerp(inSqr.Min,inSqr.Max,ImVec2(0.5f-ip,0.5f-ip)), + ImLerp(inSqr.Min,inSqr.Max,ImVec2(0.5f+ip,0.5f+ip)), + guideColor, + 0.0f,0,dpiScale + ); + } + + // line + const float* oscBufX=e->oscBuf[xyOscXChannel]; + const float* oscBufY=e->oscBuf[xyOscYChannel]; + if (oscBufX!=NULL && oscBufY!=NULL) { + int pos=e->oscWritePos; + float lx=inSqrCenter.x; + float ly=inSqrCenter.y; + float maxA=xyOscIntensity*256.f; + float decay=exp2f(-1e3f/e->getAudioDescGot().rate/xyOscDecayTime); + ImDrawListFlags prevFlags=dl->Flags; + dl->Flags|=ImDrawFlags_RoundCornersNone; + if (!settings.oscAntiAlias || safeMode) { + dl->Flags&=~(ImDrawListFlags_AntiAliasedLines|ImDrawListFlags_AntiAliasedLinesUseTex); + } + if (settings.oscEscapesBoundary) { + dl->PushClipRectFullScreen(); + } + for (int i=0; i=1) { + a=MIN(a,255); + dl->AddLine(ImVec2(lx,ly),ImVec2(x,y),(color|((ImU32)a<PopClipRect(); + } + dl->Flags=prevFlags; + } + if (settings.oscBorder) { + dl->AddRect(inRect.Min,inRect.Max,borderColor,settings.oscRoundedCorners?(8.0f*dpiScale):0.0f,0,1.5f*dpiScale); + } + } + if (ImGui::IsItemHovered()) { + float valX=20.0f*log10f(fabsf((ImGui::GetMousePos().x-inSqrCenter.x)/scaleX)); + float valY=20.0f*log10f(fabsf((ImGui::GetMousePos().y-inSqrCenter.y)/scaleY)); + if (valX<=-INFINITY && valY<=-INFINITY) { + ImGui::SetTooltip("(-Infinity)dB,(-Infinity)dB"); + } else if (valX<=-INFINITY) { + ImGui::SetTooltip("(-Infinity)dB,%.1fdB",valY); + } else if (valY<=-INFINITY) { + ImGui::SetTooltip("%.1fdB,(-Infinity)dB",valY); + } else { + ImGui::SetTooltip("%.1fdB,%.1fdB",valX,valY); + } + } + if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) { + xyOscOptions=true; + } + if (settings.oscTakesEntireWindow) { + ImGui::PopStyleVar(3); + } + } + } + if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_XY_OSC; + ImGui::End(); +} From 811ce6da6b44de2ffcb417c13db25e33339d3561 Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Wed, 1 Nov 2023 18:13:09 +0700 Subject: [PATCH 02/15] Extend intensity range --- src/gui/xyOsc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/xyOsc.cpp b/src/gui/xyOsc.cpp index d31ff5edc..b1094007f 100644 --- a/src/gui/xyOsc.cpp +++ b/src/gui/xyOsc.cpp @@ -70,7 +70,7 @@ void FurnaceGUI::drawXYOsc() { if (ImGui::SliderFloat("Decay Time (ms)",&xyOscDecayTime,1.0f,1000.0f,"%.1f",ImGuiSliderFlags_Logarithmic)) { xyOscDecayTime=MAX(xyOscDecayTime,0.0f); } rightClickable - if (ImGui::SliderFloat("Intensity",&xyOscIntensity,0.0f,2.0f,"%.2f")) { + if (ImGui::SliderFloat("Intensity",&xyOscIntensity,0.0f,5.0f,"%.2f")) { xyOscIntensity=MAX(xyOscIntensity,0.0f); } rightClickable if (ImGui::SliderFloat("Line Thickness",&xyOscThickness,0.0f,10.0f,"%.2f")) { From b812a90637f72c4bc52d3093dae31d49caebb767 Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Wed, 1 Nov 2023 22:34:35 +0700 Subject: [PATCH 03/15] Fix StyleVar stack mismatch --- src/gui/xyOsc.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/xyOsc.cpp b/src/gui/xyOsc.cpp index b1094007f..328b86087 100644 --- a/src/gui/xyOsc.cpp +++ b/src/gui/xyOsc.cpp @@ -221,11 +221,11 @@ void FurnaceGUI::drawXYOsc() { if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) { xyOscOptions=true; } - if (settings.oscTakesEntireWindow) { - ImGui::PopStyleVar(3); - } } } + if (settings.oscTakesEntireWindow && !xyOscOptions) { + ImGui::PopStyleVar(3); + } if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_XY_OSC; ImGui::End(); } From 5de2c2dc4bccb26833be7c789f0a9aed1b45e051 Mon Sep 17 00:00:00 2001 From: LTVA1 <87536432+LTVA1@users.noreply.github.com> Date: Wed, 1 Nov 2023 21:15:10 +0300 Subject: [PATCH 04/15] Update c64.md Update C64 instrument info --- doc/4-instrument/c64.md | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/doc/4-instrument/c64.md b/doc/4-instrument/c64.md index bd864b031..3f2b7e880 100644 --- a/doc/4-instrument/c64.md +++ b/doc/4-instrument/c64.md @@ -5,15 +5,13 @@ the C64 instrument editor consists of two tabs: "C64" to control various paramet ## C64 - **Waveform**: allows selecting a waveform. - - more than one waveform can be selected at once. in that case logical AND mix of waves will occur. + - more than one waveform can be selected at once. in that case logical AND mix of waves should occur, bit actually a weird bit mixing occurs (due to the hardware flaws; 6581 and 8580 models handle those "combined waves" differently). - noise is an exception. it cannot be used with any of the other waveforms. - **Attack**: determines the rising time for the sound. the bigger the value, the slower the attack. (0 to 15). - **Decay**: determines the diminishing time for the sound. the higher the value, the longer the decay (0 to 15). - **Sustain**: sets the volume level at which the sound stops decaying and holds steady (0 to 15). - **Release**: determines the rate at which the sound fades out after note off. the higher the value, the longer the release (0 to 15). - - **Duty**: specifies the width of a pulse wave (0 to 4095). - - **Ring Modulation**: when enabled, the channel's output will be multiplied with the previous channel's. - **Oscillator Sync**: enables oscillator hard sync. as the previous channel's oscillator finishes a cycle, it resets the period of the channel's oscillator, forcing the latter to have the same base frequency. this can produce a harmonically rich sound, the timbre of which can be altered by varying the synchronized oscillator's frequency. @@ -26,9 +24,8 @@ the C64 instrument editor consists of two tabs: "C64" to control various paramet - **high**: a high-pass filter. higher cutoff values result in a less "bassy" sound. - **band**: a band-pass filter. cutoff determines which part of the sound is heard (from bass to treble). - **ch3off**: mutes channel 3 when enabled. not sure why is this part of the chip's design, but it is. + - Different filter modes can be selected simultaneously, e.g. low+high. The resulting sound would be as if input was passed through lowpass filter and then highpass filter (or vice versa, you get the idea). -- **Volume Macro is Cutoff Macro**: turns the volume macro in the Macros tab into a filter cutoff macro. - - volume control is global (affects entire chip output), hence the option. - **Absolute Cutoff Macro**: when enabled, the cutoff macro will go from 0 to 2047, and it will be absolute (in other words, control the cutoff directly rather than being relative). - **Absolute Duty Macro**: when enabled, the duty macro will go from 0 to 4095. - **Don't test before new note**: this option disables the one-tick hard reset and test bit before a new note. @@ -37,12 +34,21 @@ the C64 instrument editor consists of two tabs: "C64" to control various paramet - **Volume**: volume sequence. - warning: volume sequence is global! this means it controls the chip's volume and therefore affects all channels. - - this macro becomes **Cutoff** when the **Volume Macro is Cutoff Macro** option is enabled in the C64 tab. - **Arpeggio**: pitch sequence. - **Duty**: pulse width sequence. - **Waveform**: select the waveform used by instrument. - **Pitch**: fine pitch. +- **Cutoff**: filter cutoff. - **Filter mode**: select the filter mode. - **Resonance**: filter resonance sequence. -- **Special**: ring and oscillator sync selector. -- **Test/Gate**: when on, the test bit is set, which mutes the channel. +- **Special**: ring and oscillator sync selector, as well as: + - **gate bit**: + - set (1) = key on, if previous state was 0 it triggers envelope start/restart, if previous state was 1 does nothing + - reset (0) = key off, if previous state was 1 it triggers envelope release, if previous state was 0 does nothing + - **test bit**: + - set (1) = channel immediately muted (if the channel is a source of ring mod and/or hard sync those stop working until you reset the bit) + - reset (0) = unmute channel, restore ring mod/hard sync functionality described above +- **Attack**: sets envelope attack speed. If you modify attack speed when envelope is in attack phase it immediately changes. +- **Decay**: sets envelope decay speed. If you modify decay speed when envelope is in decay phase it immediately changes. +- **Sustain**: sets envelope sustain level. If you modify sustain level when envelope is in sustain phase it immediately changes, although you can only go down (e.g. 9->8 and 8->8 works, but if you go 8->9 channel immediately mutes itself). +- **Release**: sets envelope release speed. If you modify release speed when envelope is in release phase it immediately changes. From d04f4da359131debd9e4d01a2945f0bd8a07b806 Mon Sep 17 00:00:00 2001 From: LTVA1 <87536432+LTVA1@users.noreply.github.com> Date: Wed, 1 Nov 2023 21:19:46 +0300 Subject: [PATCH 05/15] Update effects.md Change macro attribution table for C64 insturment --- doc/3-pattern/effects.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/3-pattern/effects.md b/doc/3-pattern/effects.md index b2622426c..c76826c02 100644 --- a/doc/3-pattern/effects.md +++ b/doc/3-pattern/effects.md @@ -154,16 +154,16 @@ ex | FM | OPM | OPZ | OPLL | AY-3-8910 | AY8930 | Lynx W | | LFO Shape | LFO Shape | Patch | Waveform | Waveform | | Waveform | 1 | | AMD | AMD | | | Duty | | FilterMode | 2 | | PMD | PMD | | Envelope | Envelope | | Resonance | - 3 | LFOSpd | LFO Speed | LFO Speed | | AutoEnvNum | AutoEnvNum | | Special | - A | ALG | ALG | ALG | | AutoEnvDen | AutoEnvDen | | | + 3 | LFOSpd | LFO Speed | LFO Speed | | AutoEnvNum | AutoEnvNum | | | + A | ALG | ALG | ALG | | AutoEnvDen | AutoEnvDen | | Cutoff | B | FB | FB | FB | | | Noise AND | | | C | FMS | FMS | FMS | | | Noise OR | | | D | AMS | AMS | AMS | | | | | | - 4 | OpMask | OpMask | | | | | | Test/Gate | - 5 | | | AMD2 | | | | | | - 6 | | | PMD2 | | | | | | - 7 | | | LFO2Speed | | | | | | - 8 | | | LFO2Shape | | | | | | + 4 | OpMask | OpMask | | | | | | Special | + 5 | | | AMD2 | | | | | Attack | + 6 | | | PMD2 | | | | | Decay | + 7 | | | LFO2Speed | | | | | Sustain | + 8 | | | LFO2Shape | | | | | Release | ex | SAA1099 | X1-010 | Namco 163 | FDS | Sound Unit | ES5506 | MSM6258 | ---|----------|------------|------------|-----------|------------|-----------|----------| From 2e9cfd059a660a419222588284f40c9d34a30ed9 Mon Sep 17 00:00:00 2001 From: Natt Akuma Date: Thu, 2 Nov 2023 01:34:01 +0700 Subject: [PATCH 06/15] Fix StyleVar stack mismatch 2 --- src/gui/xyOsc.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/xyOsc.cpp b/src/gui/xyOsc.cpp index 328b86087..3a00b811d 100644 --- a/src/gui/xyOsc.cpp +++ b/src/gui/xyOsc.cpp @@ -31,7 +31,8 @@ void FurnaceGUI::drawXYOsc() { } if (!xyOscOpen) return; ImGui::SetNextWindowSizeConstraints(ImVec2(64.0f*dpiScale,32.0f*dpiScale),ImVec2(canvasW,canvasH)); - if (settings.oscTakesEntireWindow && !xyOscOptions) { + bool noPadding=settings.oscTakesEntireWindow && !xyOscOptions; + if (noPadding) { ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding,ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing,ImVec2(0,0)); @@ -223,7 +224,7 @@ void FurnaceGUI::drawXYOsc() { } } } - if (settings.oscTakesEntireWindow && !xyOscOptions) { + if (noPadding) { ImGui::PopStyleVar(3); } if (ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows)) curWindow=GUI_WINDOW_XY_OSC; From f0738c19a02a38963adbe4c8890a3fb8bb307911 Mon Sep 17 00:00:00 2001 From: Electric Keet Date: Thu, 2 Nov 2023 22:47:51 -0700 Subject: [PATCH 07/15] Editing the C64 instrument doc. Edits for style consistency and clarity (I hope). --- doc/4-instrument/c64.md | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/doc/4-instrument/c64.md b/doc/4-instrument/c64.md index 3f2b7e880..239f07782 100644 --- a/doc/4-instrument/c64.md +++ b/doc/4-instrument/c64.md @@ -5,7 +5,8 @@ the C64 instrument editor consists of two tabs: "C64" to control various paramet ## C64 - **Waveform**: allows selecting a waveform. - - more than one waveform can be selected at once. in that case logical AND mix of waves should occur, bit actually a weird bit mixing occurs (due to the hardware flaws; 6581 and 8580 models handle those "combined waves" differently). + - more than one waveform can be selected at once. in that case a logical AND mix of waves will occur... + - due to hardware flaws, the mixing is a bit weird and sounds different between the 6581 and the 8580. - noise is an exception. it cannot be used with any of the other waveforms. - **Attack**: determines the rising time for the sound. the bigger the value, the slower the attack. (0 to 15). - **Decay**: determines the diminishing time for the sound. the higher the value, the longer the decay (0 to 15). @@ -24,7 +25,7 @@ the C64 instrument editor consists of two tabs: "C64" to control various paramet - **high**: a high-pass filter. higher cutoff values result in a less "bassy" sound. - **band**: a band-pass filter. cutoff determines which part of the sound is heard (from bass to treble). - **ch3off**: mutes channel 3 when enabled. not sure why is this part of the chip's design, but it is. - - Different filter modes can be selected simultaneously, e.g. low+high. The resulting sound would be as if input was passed through lowpass filter and then highpass filter (or vice versa, you get the idea). + - multiple filter modes can be selected simultaneously. for example, selecting both "low" and "high" would combine the effects of both, resulting in a bandpass filter. - **Absolute Cutoff Macro**: when enabled, the cutoff macro will go from 0 to 2047, and it will be absolute (in other words, control the cutoff directly rather than being relative). - **Absolute Duty Macro**: when enabled, the duty macro will go from 0 to 4095. @@ -43,12 +44,17 @@ the C64 instrument editor consists of two tabs: "C64" to control various paramet - **Resonance**: filter resonance sequence. - **Special**: ring and oscillator sync selector, as well as: - **gate bit**: - - set (1) = key on, if previous state was 0 it triggers envelope start/restart, if previous state was 1 does nothing - - reset (0) = key off, if previous state was 1 it triggers envelope release, if previous state was 0 does nothing + - set (1): key on. if previous state was 0 it triggers envelope start/restart; if previous state was 1, it does nothing. + - reset (0): key off. if previous state was 1 it triggers envelope release; if previous state was 0, it does nothing. - **test bit**: - - set (1) = channel immediately muted (if the channel is a source of ring mod and/or hard sync those stop working until you reset the bit) - - reset (0) = unmute channel, restore ring mod/hard sync functionality described above -- **Attack**: sets envelope attack speed. If you modify attack speed when envelope is in attack phase it immediately changes. -- **Decay**: sets envelope decay speed. If you modify decay speed when envelope is in decay phase it immediately changes. -- **Sustain**: sets envelope sustain level. If you modify sustain level when envelope is in sustain phase it immediately changes, although you can only go down (e.g. 9->8 and 8->8 works, but if you go 8->9 channel immediately mutes itself). -- **Release**: sets envelope release speed. If you modify release speed when envelope is in release phase it immediately changes. + - set (1): immediately mute channel + - if the channel is a source of ring mod and/or hard sync, those stop working until the bit is reset. + - reset (0): unmute channel and restore ring mod/hard sync. +- **Attack**: sets envelope attack speed. + - if you modify attack speed when the envelope is in attack phase it immediately changes. +- **Decay**: sets envelope decay speed. + - if you modify decay speed when envelope is in decay phase it immediately changes. +- **Sustain**: sets envelope sustain level. + - if you modify sustain level when envelope is in sustain phase it immediately changes, although you can only go down. for example, 9-to-8 and 8-to-8 both work, but 8-to-9 immediately mutes the channel. +- **Release**: sets envelope release speed. + - if you modify release speed when envelope is in release phase it immediately changes. \ No newline at end of file From 5909c2e1ed50c9b3599c90101fbde15030a1572d Mon Sep 17 00:00:00 2001 From: Electric Keet Date: Thu, 2 Nov 2023 23:11:11 -0700 Subject: [PATCH 08/15] Small correction. --- doc/4-instrument/c64.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/4-instrument/c64.md b/doc/4-instrument/c64.md index 239f07782..a9bb080b6 100644 --- a/doc/4-instrument/c64.md +++ b/doc/4-instrument/c64.md @@ -25,7 +25,7 @@ the C64 instrument editor consists of two tabs: "C64" to control various paramet - **high**: a high-pass filter. higher cutoff values result in a less "bassy" sound. - **band**: a band-pass filter. cutoff determines which part of the sound is heard (from bass to treble). - **ch3off**: mutes channel 3 when enabled. not sure why is this part of the chip's design, but it is. - - multiple filter modes can be selected simultaneously. for example, selecting both "low" and "high" would combine the effects of both, resulting in a bandpass filter. + - multiple filter modes can be selected simultaneously. for example, selecting both "low" and "high" results in a bandstop (notch) filter. - **Absolute Cutoff Macro**: when enabled, the cutoff macro will go from 0 to 2047, and it will be absolute (in other words, control the cutoff directly rather than being relative). - **Absolute Duty Macro**: when enabled, the duty macro will go from 0 to 4095. From 28065f7eb2c24fb56ff1fea29eb12a9d2be4e076 Mon Sep 17 00:00:00 2001 From: LTVA1 <87536432+LTVA1@users.noreply.github.com> Date: Fri, 3 Nov 2023 09:19:39 +0300 Subject: [PATCH 09/15] Clearer ch3off bit explanation --- doc/4-instrument/c64.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/4-instrument/c64.md b/doc/4-instrument/c64.md index a9bb080b6..0beb20d94 100644 --- a/doc/4-instrument/c64.md +++ b/doc/4-instrument/c64.md @@ -24,7 +24,7 @@ the C64 instrument editor consists of two tabs: "C64" to control various paramet - **low**: a low-pass filter. the lower the cutoff, the darker the sound. - **high**: a high-pass filter. higher cutoff values result in a less "bassy" sound. - **band**: a band-pass filter. cutoff determines which part of the sound is heard (from bass to treble). - - **ch3off**: mutes channel 3 when enabled. not sure why is this part of the chip's design, but it is. + - **ch3off**: mutes channel 3 when enabled. It was originally planned for usage with two registers where program could read current oscillator and envelope outputs, thus making vibrato and SFX generation easier. But who wanted to sacrifice one channel out of three! So aforementioned was just done in software, and the feature was never used. - multiple filter modes can be selected simultaneously. for example, selecting both "low" and "high" results in a bandstop (notch) filter. - **Absolute Cutoff Macro**: when enabled, the cutoff macro will go from 0 to 2047, and it will be absolute (in other words, control the cutoff directly rather than being relative). @@ -57,4 +57,4 @@ the C64 instrument editor consists of two tabs: "C64" to control various paramet - **Sustain**: sets envelope sustain level. - if you modify sustain level when envelope is in sustain phase it immediately changes, although you can only go down. for example, 9-to-8 and 8-to-8 both work, but 8-to-9 immediately mutes the channel. - **Release**: sets envelope release speed. - - if you modify release speed when envelope is in release phase it immediately changes. \ No newline at end of file + - if you modify release speed when envelope is in release phase it immediately changes. From d3e46921ddc4f3a5c6cf14b39fa1863f764da79c Mon Sep 17 00:00:00 2001 From: LTVA1 <87536432+LTVA1@users.noreply.github.com> Date: Fri, 3 Nov 2023 09:33:12 +0300 Subject: [PATCH 10/15] Update c64.md --- doc/4-instrument/c64.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/4-instrument/c64.md b/doc/4-instrument/c64.md index 0beb20d94..7f2acb996 100644 --- a/doc/4-instrument/c64.md +++ b/doc/4-instrument/c64.md @@ -24,7 +24,7 @@ the C64 instrument editor consists of two tabs: "C64" to control various paramet - **low**: a low-pass filter. the lower the cutoff, the darker the sound. - **high**: a high-pass filter. higher cutoff values result in a less "bassy" sound. - **band**: a band-pass filter. cutoff determines which part of the sound is heard (from bass to treble). - - **ch3off**: mutes channel 3 when enabled. It was originally planned for usage with two registers where program could read current oscillator and envelope outputs, thus making vibrato and SFX generation easier. But who wanted to sacrifice one channel out of three! So aforementioned was just done in software, and the feature was never used. + - **ch3off**: mutes channel 3 when enabled. It was originally planned for usage with two registers where program could read current oscillator and envelope outputs, thus making vibrato and SFX generation easier. but who wanted to sacrifice one channel out of three! so aforementioned was just done in software, and the feature was never used. - multiple filter modes can be selected simultaneously. for example, selecting both "low" and "high" results in a bandstop (notch) filter. - **Absolute Cutoff Macro**: when enabled, the cutoff macro will go from 0 to 2047, and it will be absolute (in other words, control the cutoff directly rather than being relative). From c5ed20a2b24c88f5f6e31c6276928798b413b488 Mon Sep 17 00:00:00 2001 From: LTVA1 <87536432+LTVA1@users.noreply.github.com> Date: Fri, 3 Nov 2023 09:45:34 +0300 Subject: [PATCH 11/15] Update c64.md --- doc/4-instrument/c64.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/4-instrument/c64.md b/doc/4-instrument/c64.md index 7f2acb996..8442560bf 100644 --- a/doc/4-instrument/c64.md +++ b/doc/4-instrument/c64.md @@ -24,7 +24,7 @@ the C64 instrument editor consists of two tabs: "C64" to control various paramet - **low**: a low-pass filter. the lower the cutoff, the darker the sound. - **high**: a high-pass filter. higher cutoff values result in a less "bassy" sound. - **band**: a band-pass filter. cutoff determines which part of the sound is heard (from bass to treble). - - **ch3off**: mutes channel 3 when enabled. It was originally planned for usage with two registers where program could read current oscillator and envelope outputs, thus making vibrato and SFX generation easier. but who wanted to sacrifice one channel out of three! so aforementioned was just done in software, and the feature was never used. + - **ch3off**: mutes channel 3 when enabled. it was originally planned for usage with two registers where program could read current oscillator and envelope outputs, thus making vibrato and SFX generation easier. but who wanted to sacrifice one channel out of three! so aforementioned was just done in software, and the feature was never used. - multiple filter modes can be selected simultaneously. for example, selecting both "low" and "high" results in a bandstop (notch) filter. - **Absolute Cutoff Macro**: when enabled, the cutoff macro will go from 0 to 2047, and it will be absolute (in other words, control the cutoff directly rather than being relative). From 4e48e873130c3388cd3bfbac67de67230501a05f Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 3 Nov 2023 12:54:37 -0500 Subject: [PATCH 12/15] GUI; add button --- src/gui/editControls.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gui/editControls.cpp b/src/gui/editControls.cpp index b7b39c589..8a199997e 100644 --- a/src/gui/editControls.cpp +++ b/src/gui/editControls.cpp @@ -591,6 +591,10 @@ void FurnaceGUI::drawMobileControls() { if (ImGui::Button("Compat Flags")) { compatFlagsOpen=!compatFlagsOpen; } + ImGui::SameLine(); + if (ImGui::Button("XYOsc")) { + xyOscOpen=!xyOscOpen; + } ImGui::Separator(); From e1cb84a0762f8d9bfe40ac023f20b71755f36bb3 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 3 Nov 2023 14:46:23 -0500 Subject: [PATCH 13/15] volume handling refactor, part 1 - BEWARE do not use these versions for production. your modules will break until this is finished! only Amiga is done for now --- src/engine/chipUtils.h | 19 +++++++++++++++++-- src/engine/macroInt.cpp | 12 +++++++----- src/engine/macroInt.h | 10 +++++++--- src/engine/platform/amiga.cpp | 35 ++++++++--------------------------- src/engine/platform/amiga.h | 3 +-- 5 files changed, 40 insertions(+), 39 deletions(-) diff --git a/src/engine/chipUtils.h b/src/engine/chipUtils.h index 7607193bb..eccf9621f 100644 --- a/src/engine/chipUtils.h +++ b/src/engine/chipUtils.h @@ -31,7 +31,7 @@ template struct SharedChannel { int freq, baseFreq, baseNoteOverride, pitch, pitch2, arpOff; int ins, note; bool active, insChanged, freqChanged, fixedArp, keyOn, keyOff, portaPause, inPorta, volChanged; - T vol, outVol; + T vol, macroVol, outVol, maxVol; DivMacroInt std; void handleArp(int offset=0) { if (std.arp.had) { @@ -61,6 +61,19 @@ template struct SharedChannel { arpOff=0; baseNoteOverride=0; fixedArp=false; + if (active && !std.brokenOutVol()) { + if (which==NULL) { + if (macroVol!=maxVol) { + macroVol=maxVol; + volChanged=true; + } + } else if (which->std.volMacro.len==0) { + if (macroVol!=maxVol) { + macroVol=maxVol; + volChanged=true; + } + } + } } SharedChannel(T initVol): freq(0), @@ -79,9 +92,11 @@ template struct SharedChannel { keyOff(false), portaPause(false), inPorta(false), - volChanged(false), + volChanged(true), vol(initVol), + macroVol(initVol), outVol(initVol), + maxVol(initVol), std() {} }; diff --git a/src/engine/macroInt.cpp b/src/engine/macroInt.cpp index 557777cc8..1efbbe87f 100644 --- a/src/engine/macroInt.cpp +++ b/src/engine/macroInt.cpp @@ -43,7 +43,6 @@ void DivMacroStruct::prepare(DivInstrumentMacro& source, DivEngine* e) { mode=source.mode; type=(source.open>>1)&3; activeRelease=source.open&8; - linger=(source.macroType==DIV_MACRO_VOL && e->song.volMacroLinger); lfoPos=LFO_PHASE; } @@ -64,7 +63,7 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic } if (delay>0) { delay--; - if (!linger) had=false; + had=false; return; } if (began && source.delay>0) { @@ -98,8 +97,6 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic if (pos>=source.len) { if (source.loop=source.rel || source.rel>=source.len)) { pos=source.loop; - } else if (linger) { - pos--; } else { has=false; } @@ -140,7 +137,7 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic break; case 4: // end pos=0; - if (!linger) has=false; + has=false; break; } val=ADSR_LOW+((pos+(ADSR_HIGH-ADSR_LOW)*pos)>>8); @@ -253,6 +250,11 @@ void DivMacroInt::setEngine(DivEngine* eng) { e=eng; } +bool DivMacroInt::brokenOutVol() { + if (e==NULL) return false; + return e->song.brokenOutVol; +} + #define ADD_MACRO(m,s) \ if (!m.masked) { \ macroList[macroListLen]=&m; \ diff --git a/src/engine/macroInt.h b/src/engine/macroInt.h index 28e605029..f68df9ec1 100644 --- a/src/engine/macroInt.h +++ b/src/engine/macroInt.h @@ -27,14 +27,13 @@ class DivEngine; struct DivMacroStruct { int pos, lastPos, lfoPos, delay; int val; - bool has, had, actualHad, finished, will, linger, began, masked, activeRelease; + bool has, had, actualHad, finished, will, began, masked, activeRelease; unsigned int mode, type; unsigned char macroType; void doMacro(DivInstrumentMacro& source, bool released, bool tick); void init() { pos=lastPos=lfoPos=mode=type=delay=0; has=had=actualHad=will=false; - linger=false; began=true; // TODO: test whether this breaks anything? val=0; @@ -51,7 +50,6 @@ struct DivMacroStruct { actualHad(false), finished(false), will(false), - linger(false), began(true), masked(false), activeRelease(false), @@ -109,6 +107,12 @@ class DivMacroInt { // state bool hasRelease; + /** + * get whether brokenOutVol is enabled. + * @return the value of brokenOutVol, or false if not bound to an engine. + */ + bool brokenOutVol(); + /** * set mask on macro. */ diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index a4e279dad..c4d1ed067 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -68,17 +68,6 @@ const char** DivPlatformAmiga::getRegisterSheet() { return regCheatSheetAmiga; } -#define writeAudDat(x) \ - chan[i].audDat=x; \ - if (i<3 && chan[i].useV) { \ - chan[i+1].outVol=(unsigned char)chan[i].audDat^0x80; \ - if (chan[i+1].outVol>64) chan[i+1].outVol=64; \ - } \ - if (i<3 && chan[i].useP) { \ - chan[i+1].freq=(unsigned char)chan[i].audDat^0x80; \ - if (chan[i+1].freq>6; - chan[i].writeVol=true; + chan[i].macroVol=chan[i].std.vol.val; + chan[i].volChanged=true; } double off=1.0; if (!chan[i].useWave && chan[i].sample>=0 && chan[i].samplesong.sampleLen) { @@ -516,8 +505,9 @@ void DivPlatformAmiga::tick(bool sysTick) { } for (int i=0; i<4; i++) { - if (chan[i].writeVol) { - chan[i].writeVol=false; + if (chan[i].volChanged) { + chan[i].outVol=((chan[i].vol%65)*MIN(64,chan[i].macroVol))>>6; + chan[i].volChanged=false; chWrite(i,8,chan[i].outVol); } if (chan[i].updateWave) { @@ -585,10 +575,6 @@ int DivPlatformAmiga::dispatch(DivCommand c) { chan[c.chan].active=true; chan[c.chan].keyOn=true; chan[c.chan].macroInit(ins); - if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) { - chan[c.chan].outVol=chan[c.chan].vol; - chan[c.chan].writeVol=true; - } if (chan[c.chan].useWave) { chan[c.chan].ws.init(ins,chan[c.chan].audLen<<1,255,chan[c.chan].insChanged); chan[c.chan].updateWave=true; @@ -615,17 +601,12 @@ int DivPlatformAmiga::dispatch(DivCommand c) { case DIV_CMD_VOLUME: if (chan[c.chan].vol!=c.value) { chan[c.chan].vol=c.value; - if (!chan[c.chan].std.vol.has) { - chan[c.chan].outVol=c.value; - chan[c.chan].writeVol=true; - } + if (!parent->song.volMacroLinger) chan[c.chan].macroVol=chan[c.chan].maxVol; + chan[c.chan].volChanged=true; } break; case DIV_CMD_GET_VOLUME: - if (chan[c.chan].std.vol.has) { - return chan[c.chan].vol; - } - return chan[c.chan].outVol; + return chan[c.chan].vol; break; case DIV_CMD_PITCH: chan[c.chan].pitch=c.value; diff --git a/src/engine/platform/amiga.h b/src/engine/platform/amiga.h index a05a5994d..97accae1f 100644 --- a/src/engine/platform/amiga.h +++ b/src/engine/platform/amiga.h @@ -30,7 +30,7 @@ class DivPlatformAmiga: public DivDispatch { int audSub; unsigned char volPos; int sample, wave; - bool useWave, setPos, useV, useP, dmaOn, audDatClock, writeVol, updateWave; + bool useWave, setPos, useV, useP, dmaOn, audDatClock, updateWave; DivWaveSynth ws; Channel(): SharedChannel(64), @@ -49,7 +49,6 @@ class DivPlatformAmiga: public DivDispatch { useP(false), dmaOn(false), audDatClock(false), - writeVol(true), updateWave(true) {} }; Channel chan[4]; From 54187d043d9c1b0871263205320234a6a7ac95d8 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 4 Nov 2023 04:13:20 -0500 Subject: [PATCH 14/15] Revert "volume handling refactor, part 1 - BEWARE" This reverts commit e1cb84a0762f8d9bfe40ac023f20b71755f36bb3. --- src/engine/chipUtils.h | 19 ++----------------- src/engine/macroInt.cpp | 12 +++++------- src/engine/macroInt.h | 10 +++------- src/engine/platform/amiga.cpp | 35 +++++++++++++++++++++++++++-------- src/engine/platform/amiga.h | 3 ++- 5 files changed, 39 insertions(+), 40 deletions(-) diff --git a/src/engine/chipUtils.h b/src/engine/chipUtils.h index eccf9621f..7607193bb 100644 --- a/src/engine/chipUtils.h +++ b/src/engine/chipUtils.h @@ -31,7 +31,7 @@ template struct SharedChannel { int freq, baseFreq, baseNoteOverride, pitch, pitch2, arpOff; int ins, note; bool active, insChanged, freqChanged, fixedArp, keyOn, keyOff, portaPause, inPorta, volChanged; - T vol, macroVol, outVol, maxVol; + T vol, outVol; DivMacroInt std; void handleArp(int offset=0) { if (std.arp.had) { @@ -61,19 +61,6 @@ template struct SharedChannel { arpOff=0; baseNoteOverride=0; fixedArp=false; - if (active && !std.brokenOutVol()) { - if (which==NULL) { - if (macroVol!=maxVol) { - macroVol=maxVol; - volChanged=true; - } - } else if (which->std.volMacro.len==0) { - if (macroVol!=maxVol) { - macroVol=maxVol; - volChanged=true; - } - } - } } SharedChannel(T initVol): freq(0), @@ -92,11 +79,9 @@ template struct SharedChannel { keyOff(false), portaPause(false), inPorta(false), - volChanged(true), + volChanged(false), vol(initVol), - macroVol(initVol), outVol(initVol), - maxVol(initVol), std() {} }; diff --git a/src/engine/macroInt.cpp b/src/engine/macroInt.cpp index 1efbbe87f..557777cc8 100644 --- a/src/engine/macroInt.cpp +++ b/src/engine/macroInt.cpp @@ -43,6 +43,7 @@ void DivMacroStruct::prepare(DivInstrumentMacro& source, DivEngine* e) { mode=source.mode; type=(source.open>>1)&3; activeRelease=source.open&8; + linger=(source.macroType==DIV_MACRO_VOL && e->song.volMacroLinger); lfoPos=LFO_PHASE; } @@ -63,7 +64,7 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic } if (delay>0) { delay--; - had=false; + if (!linger) had=false; return; } if (began && source.delay>0) { @@ -97,6 +98,8 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic if (pos>=source.len) { if (source.loop=source.rel || source.rel>=source.len)) { pos=source.loop; + } else if (linger) { + pos--; } else { has=false; } @@ -137,7 +140,7 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic break; case 4: // end pos=0; - has=false; + if (!linger) has=false; break; } val=ADSR_LOW+((pos+(ADSR_HIGH-ADSR_LOW)*pos)>>8); @@ -250,11 +253,6 @@ void DivMacroInt::setEngine(DivEngine* eng) { e=eng; } -bool DivMacroInt::brokenOutVol() { - if (e==NULL) return false; - return e->song.brokenOutVol; -} - #define ADD_MACRO(m,s) \ if (!m.masked) { \ macroList[macroListLen]=&m; \ diff --git a/src/engine/macroInt.h b/src/engine/macroInt.h index f68df9ec1..28e605029 100644 --- a/src/engine/macroInt.h +++ b/src/engine/macroInt.h @@ -27,13 +27,14 @@ class DivEngine; struct DivMacroStruct { int pos, lastPos, lfoPos, delay; int val; - bool has, had, actualHad, finished, will, began, masked, activeRelease; + bool has, had, actualHad, finished, will, linger, began, masked, activeRelease; unsigned int mode, type; unsigned char macroType; void doMacro(DivInstrumentMacro& source, bool released, bool tick); void init() { pos=lastPos=lfoPos=mode=type=delay=0; has=had=actualHad=will=false; + linger=false; began=true; // TODO: test whether this breaks anything? val=0; @@ -50,6 +51,7 @@ struct DivMacroStruct { actualHad(false), finished(false), will(false), + linger(false), began(true), masked(false), activeRelease(false), @@ -107,12 +109,6 @@ class DivMacroInt { // state bool hasRelease; - /** - * get whether brokenOutVol is enabled. - * @return the value of brokenOutVol, or false if not bound to an engine. - */ - bool brokenOutVol(); - /** * set mask on macro. */ diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index c4d1ed067..a4e279dad 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -68,6 +68,17 @@ const char** DivPlatformAmiga::getRegisterSheet() { return regCheatSheetAmiga; } +#define writeAudDat(x) \ + chan[i].audDat=x; \ + if (i<3 && chan[i].useV) { \ + chan[i+1].outVol=(unsigned char)chan[i].audDat^0x80; \ + if (chan[i+1].outVol>64) chan[i+1].outVol=64; \ + } \ + if (i<3 && chan[i].useP) { \ + chan[i+1].freq=(unsigned char)chan[i].audDat^0x80; \ + if (chan[i+1].freq>6; + chan[i].writeVol=true; } double off=1.0; if (!chan[i].useWave && chan[i].sample>=0 && chan[i].samplesong.sampleLen) { @@ -505,9 +516,8 @@ void DivPlatformAmiga::tick(bool sysTick) { } for (int i=0; i<4; i++) { - if (chan[i].volChanged) { - chan[i].outVol=((chan[i].vol%65)*MIN(64,chan[i].macroVol))>>6; - chan[i].volChanged=false; + if (chan[i].writeVol) { + chan[i].writeVol=false; chWrite(i,8,chan[i].outVol); } if (chan[i].updateWave) { @@ -575,6 +585,10 @@ int DivPlatformAmiga::dispatch(DivCommand c) { chan[c.chan].active=true; chan[c.chan].keyOn=true; chan[c.chan].macroInit(ins); + if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) { + chan[c.chan].outVol=chan[c.chan].vol; + chan[c.chan].writeVol=true; + } if (chan[c.chan].useWave) { chan[c.chan].ws.init(ins,chan[c.chan].audLen<<1,255,chan[c.chan].insChanged); chan[c.chan].updateWave=true; @@ -601,12 +615,17 @@ int DivPlatformAmiga::dispatch(DivCommand c) { case DIV_CMD_VOLUME: if (chan[c.chan].vol!=c.value) { chan[c.chan].vol=c.value; - if (!parent->song.volMacroLinger) chan[c.chan].macroVol=chan[c.chan].maxVol; - chan[c.chan].volChanged=true; + if (!chan[c.chan].std.vol.has) { + chan[c.chan].outVol=c.value; + chan[c.chan].writeVol=true; + } } break; case DIV_CMD_GET_VOLUME: - return chan[c.chan].vol; + if (chan[c.chan].std.vol.has) { + return chan[c.chan].vol; + } + return chan[c.chan].outVol; break; case DIV_CMD_PITCH: chan[c.chan].pitch=c.value; diff --git a/src/engine/platform/amiga.h b/src/engine/platform/amiga.h index 97accae1f..a05a5994d 100644 --- a/src/engine/platform/amiga.h +++ b/src/engine/platform/amiga.h @@ -30,7 +30,7 @@ class DivPlatformAmiga: public DivDispatch { int audSub; unsigned char volPos; int sample, wave; - bool useWave, setPos, useV, useP, dmaOn, audDatClock, updateWave; + bool useWave, setPos, useV, useP, dmaOn, audDatClock, writeVol, updateWave; DivWaveSynth ws; Channel(): SharedChannel(64), @@ -49,6 +49,7 @@ class DivPlatformAmiga: public DivDispatch { useP(false), dmaOn(false), audDatClock(false), + writeVol(true), updateWave(true) {} }; Channel chan[4]; From 6df06a7f89b26bc1710f9c13ca3451dc7f262295 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 4 Nov 2023 04:13:30 -0500 Subject: [PATCH 15/15] Revert "prepare for volume handling refactor" sorry......... this refactor is canceled as it seems harder than I thought... --- src/engine/chipUtils.h | 3 +- src/engine/platform/es5506.cpp | 38 +- src/engine/platform/es5506.h | 4 +- src/gui/debug.cpp | 859 ++++++++++++++++++++++++++++++++- 4 files changed, 879 insertions(+), 25 deletions(-) diff --git a/src/engine/chipUtils.h b/src/engine/chipUtils.h index 7607193bb..4ddc0738d 100644 --- a/src/engine/chipUtils.h +++ b/src/engine/chipUtils.h @@ -30,7 +30,7 @@ template struct SharedChannel { int freq, baseFreq, baseNoteOverride, pitch, pitch2, arpOff; int ins, note; - bool active, insChanged, freqChanged, fixedArp, keyOn, keyOff, portaPause, inPorta, volChanged; + bool active, insChanged, freqChanged, fixedArp, keyOn, keyOff, portaPause, inPorta; T vol, outVol; DivMacroInt std; void handleArp(int offset=0) { @@ -79,7 +79,6 @@ template struct SharedChannel { keyOff(false), portaPause(false), inPorta(false), - volChanged(false), vol(initVol), outVol(initVol), std() {} diff --git a/src/engine/platform/es5506.cpp b/src/engine/platform/es5506.cpp index 2881bbc42..64aca0be5 100644 --- a/src/engine/platform/es5506.cpp +++ b/src/engine/platform/es5506.cpp @@ -191,22 +191,22 @@ void DivPlatformES5506::tick(bool sysTick) { const int nextVol=VOL_SCALE_LOG((0xfff*chan[i].vol)/0xff,(0xfff*chan[i].std.vol.val)/chan[i].volMacroMax,0xfff); if (chan[i].outVol!=nextVol) { chan[i].outVol=nextVol; - chan[i].volChangedES.lVol=1; - chan[i].volChangedES.rVol=1; + chan[i].volChanged.lVol=1; + chan[i].volChanged.rVol=1; } } if (chan[i].std.panL.had) { const int nextLVol=VOL_SCALE_LOG((0xfff*chan[i].lVol)/0xff,(0xfff*chan[i].std.panL.val)/chan[i].panMacroMax,0xfff); if (chan[i].outLVol!=nextLVol) { chan[i].outLVol=nextLVol; - chan[i].volChangedES.lVol=1; + chan[i].volChanged.lVol=1; } } if (chan[i].std.panR.had) { const int nextRVol=VOL_SCALE_LOG((0xfff*chan[i].rVol)/0xff,(0xfff*chan[i].std.panR.val)/chan[i].panMacroMax,0xfff); if (chan[i].outRVol!=nextRVol) { chan[i].outRVol=nextRVol; - chan[i].volChangedES.rVol=1; + chan[i].volChanged.rVol=1; } } // arpeggio/pitch macros, frequency related @@ -340,7 +340,7 @@ void DivPlatformES5506::tick(bool sysTick) { if (chan[i].ca!=ca) { chan[i].ca=ca; if (!chan[i].keyOn) { - chan[i].volChangedES.ca=1; + chan[i].volChanged.ca=1; } } } @@ -360,9 +360,9 @@ void DivPlatformES5506::tick(bool sysTick) { } } // update registers - if (chan[i].volChangedES.changed) { + if (chan[i].volChanged.changed) { // calculate volume (16 bit) - if (chan[i].volChangedES.lVol) { + if (chan[i].volChanged.lVol) { chan[i].resLVol=VOL_SCALE_LOG(chan[i].outVol,chan[i].outLVol,0xfff); chan[i].resLVol-=volScale; if (chan[i].resLVol<0) chan[i].resLVol=0; @@ -371,7 +371,7 @@ void DivPlatformES5506::tick(bool sysTick) { pageWrite(0x00|i,0x02,chan[i].resLVol); } } - if (chan[i].volChangedES.rVol) { + if (chan[i].volChanged.rVol) { chan[i].resRVol=VOL_SCALE_LOG(chan[i].outVol,chan[i].outRVol,0xfff); chan[i].resRVol-=volScale; if (chan[i].resRVol<0) chan[i].resRVol=0; @@ -380,10 +380,10 @@ void DivPlatformES5506::tick(bool sysTick) { pageWrite(0x00|i,0x04,chan[i].resRVol); } } - if (chan[i].volChangedES.ca) { + if (chan[i].volChanged.ca) { pageWriteMask(0x00|i,0x5f,0x00,(chan[i].ca<<10),0x1c00); } - chan[i].volChangedES.changed=0; + chan[i].volChanged.changed=0; } if (chan[i].pcmChanged.changed) { if (chan[i].pcmChanged.index) { @@ -750,7 +750,7 @@ int DivPlatformES5506::dispatch(DivCommand c) { chan[c.chan].freqChanged=true; chan[c.chan].pcmChanged.changed=0xff; chan[c.chan].noteChanged.changed=0xff; - chan[c.chan].volChangedES.changed=0xff; + chan[c.chan].volChanged.changed=0xff; } if (!chan[c.chan].std.vol.will) { chan[c.chan].outVol=(0xfff*chan[c.chan].vol)/0xff; @@ -787,7 +787,7 @@ int DivPlatformES5506::dispatch(DivCommand c) { chan[c.chan].vol=c.value; if (!chan[c.chan].std.vol.has) { chan[c.chan].outVol=(0xfff*c.value)/0xff; - chan[c.chan].volChangedES.changed=0xff; + chan[c.chan].volChanged.changed=0xff; } } break; @@ -797,14 +797,14 @@ int DivPlatformES5506::dispatch(DivCommand c) { case DIV_CMD_PANNING: { if (chan[c.chan].ca!=0) { chan[c.chan].ca=0; - chan[c.chan].volChangedES.ca=1; + chan[c.chan].volChanged.ca=1; } // Left volume if (chan[c.chan].lVol!=c.value) { chan[c.chan].lVol=c.value; if (!chan[c.chan].std.panL.has) { chan[c.chan].outLVol=(0xfff*c.value)/0xff; - chan[c.chan].volChangedES.lVol=1; + chan[c.chan].volChanged.lVol=1; } } // Right volume @@ -812,7 +812,7 @@ int DivPlatformES5506::dispatch(DivCommand c) { chan[c.chan].rVol=c.value2; if (!chan[c.chan].std.panR.has) { chan[c.chan].outRVol=(0xfff*c.value2)/0xff; - chan[c.chan].volChangedES.rVol=1; + chan[c.chan].volChanged.rVol=1; } } break; @@ -821,7 +821,7 @@ int DivPlatformES5506::dispatch(DivCommand c) { unsigned char ca=CLAMP(c.value>>1,0,5); if (chan[c.chan].ca!=ca) { chan[c.chan].ca=ca; - chan[c.chan].volChangedES.ca=1; + chan[c.chan].volChanged.ca=1; } if ((c.value&1)==0) { // Left volume @@ -829,7 +829,7 @@ int DivPlatformES5506::dispatch(DivCommand c) { chan[c.chan].lVol=c.value2; if (!chan[c.chan].std.panL.has) { chan[c.chan].outLVol=(0xfff*c.value2)/0xff; - chan[c.chan].volChangedES.lVol=1; + chan[c.chan].volChanged.lVol=1; } } } @@ -839,7 +839,7 @@ int DivPlatformES5506::dispatch(DivCommand c) { chan[c.chan].rVol=c.value2; if (!chan[c.chan].std.panR.has) { chan[c.chan].outRVol=(0xfff*c.value2)/0xff; - chan[c.chan].volChangedES.rVol=1; + chan[c.chan].volChanged.rVol=1; } } } @@ -1041,7 +1041,7 @@ void DivPlatformES5506::forceIns() { chan[i].insChanged=true; chan[i].freqChanged=true; chan[i].noteChanged.changed=0xff; - chan[i].volChangedES.changed=0xff; + chan[i].volChanged.changed=0xff; chan[i].filterChanged.changed=0xff; chan[i].envChanged.changed=0xff; chan[i].pcmChanged.changed=0xff; diff --git a/src/engine/platform/es5506.h b/src/engine/platform/es5506.h index e02dd4116..6bac20c37 100644 --- a/src/engine/platform/es5506.h +++ b/src/engine/platform/es5506.h @@ -97,7 +97,7 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf { VolChanged() : changed(0) {} - } volChangedES; + } volChanged; struct FilterChanged { // Filter changed flags union { // pack flag bits in single byte @@ -198,7 +198,7 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf { isReverseLoop(false), cr(0), noteChanged(NoteChanged()), - volChangedES(VolChanged()), + volChanged(VolChanged()), filterChanged(FilterChanged()), envChanged(EnvChanged()), pcmChanged(PCMChanged()), diff --git a/src/gui/debug.cpp b/src/gui/debug.cpp index a799fd105..df634f1e8 100644 --- a/src/gui/debug.cpp +++ b/src/gui/debug.cpp @@ -237,8 +237,863 @@ ImGui::TextColored(ch->mask?colorOn:colorOff,">> Mask"); void putDispatchChip(void* data, int type) { - ImGui::Text("I will finish later..."); + ImVec4 colorOn=ImVec4(1.0f,1.0f,0.0f,1.0f); + ImVec4 colorOff=ImVec4(0.3f,0.3f,0.3f,1.0f); + switch (type) { + case DIV_SYSTEM_YM2612: + case DIV_SYSTEM_YM2612_EXT: + case DIV_SYSTEM_YM2612_DUALPCM: + case DIV_SYSTEM_YM2612_DUALPCM_EXT: { + GENESIS_CHIP_DEBUG; + break; + } + case DIV_SYSTEM_GENESIS: + case DIV_SYSTEM_GENESIS_EXT: { + GENESIS_CHIP_DEBUG; + SMS_CHIP_DEBUG; + break; + } + case DIV_SYSTEM_SMS: { + SMS_CHIP_DEBUG; + break; + } + case DIV_SYSTEM_YM2203: + case DIV_SYSTEM_YM2203_EXT: { + DivPlatformYM2203* ch=(DivPlatformYM2203*)data; + ImGui::Text("> YM2203"); + FM_OPN_CHIP_DEBUG; + ImGui::Text("- sampleBank: %d",ch->sampleBank); + ImGui::Text("- prescale: %d",ch->prescale); + FM_OPN_CHIP_DEBUG_BOOL; + ImGui::TextColored(ch->extMode?colorOn:colorOff,">> ExtMode"); + break; + } + case DIV_SYSTEM_YM2608: + case DIV_SYSTEM_YM2608_EXT: { + DivPlatformYM2608* ch=(DivPlatformYM2608*)data; + ImGui::Text("> YM2608"); + FM_OPN_CHIP_DEBUG; + ImGui::Text("- sampleBank: %d",ch->sampleBank); + ImGui::Text("- writeRSSOff: %d",ch->writeRSSOff); + ImGui::Text("- writeRSSOn: %d",ch->writeRSSOn); + ImGui::Text("- globalRSSVolume: %d",ch->globalRSSVolume); + ImGui::Text("- prescale: %d",ch->prescale); + FM_OPN_CHIP_DEBUG_BOOL; + ImGui::TextColored(ch->extMode?colorOn:colorOff,">> ExtMode"); + break; + } + case DIV_SYSTEM_YM2610: + case DIV_SYSTEM_YM2610_EXT: + case DIV_SYSTEM_YM2610_FULL: + case DIV_SYSTEM_YM2610_FULL_EXT: { + DivPlatformYM2610* ch=(DivPlatformYM2610*)data; + ImGui::Text("> YM2610"); + OPNB_CHIP_DEBUG; + break; + } + case DIV_SYSTEM_YM2610B: + case DIV_SYSTEM_YM2610B_EXT: { + DivPlatformYM2610B* ch=(DivPlatformYM2610B*)data; + ImGui::Text("> YM2610B"); + OPNB_CHIP_DEBUG; + break; + } + case DIV_SYSTEM_GB: { + DivPlatformGB* ch=(DivPlatformGB*)data; + ImGui::Text("> GameBoy"); + COMMON_CHIP_DEBUG; + ImGui::Text("- lastPan: %d",ch->lastPan); + ImGui::Text("- antiClickPeriodCount: %d",ch->antiClickPeriodCount); + ImGui::Text("- antiClickWavePos: %d",ch->antiClickWavePos); + COMMON_CHIP_DEBUG_BOOL; + ImGui::TextColored(ch->antiClickEnabled?colorOn:colorOff,">> AntiClickEnabled"); + break; + } + case DIV_SYSTEM_PCE: { + DivPlatformPCE* ch=(DivPlatformPCE*)data; + ImGui::Text("> PCEngine"); + COMMON_CHIP_DEBUG; + ImGui::Text("- lastPan: %d",ch->lastPan); + ImGui::Text("- cycles: %d",ch->cycles); + ImGui::Text("- curChan: %d",ch->curChan); + ImGui::Text("- delay: %d",ch->delay); + ImGui::Text("- sampleBank: %d",ch->sampleBank); + ImGui::Text("- lfoMode: %d",ch->lfoMode); + ImGui::Text("- lfoSpeed: %d",ch->lfoSpeed); + COMMON_CHIP_DEBUG_BOOL; + ImGui::TextColored(ch->antiClickEnabled?colorOn:colorOff,">> AntiClickEnabled"); + break; + } + case DIV_SYSTEM_NES: { + DivPlatformNES* ch=(DivPlatformNES*)data; + ImGui::Text("> NES"); + COMMON_CHIP_DEBUG; + ImGui::Text("* DAC:"); + ImGui::Text(" - Period: %d",ch->dacPeriod); + ImGui::Text(" - Rate: %d",ch->dacRate); + ImGui::Text(" - Pos: %d",ch->dacPos); + ImGui::Text(" - AntiClick: %d",ch->dacAntiClick); + ImGui::Text(" - Sample: %d",ch->dacSample); + ImGui::Text("- dpcmBank: %d",ch->dpcmBank); + ImGui::Text("- sampleBank: %d",ch->sampleBank); + ImGui::Text("- writeOscBuf: %d",ch->writeOscBuf); + ImGui::Text("- apuType: %d",ch->apuType); + COMMON_CHIP_DEBUG_BOOL; + ImGui::TextColored(ch->dpcmMode?colorOn:colorOff,">> DPCMMode"); + ImGui::TextColored(ch->dacAntiClickOn?colorOn:colorOff,">> DACAntiClickOn"); + ImGui::TextColored(ch->useNP?colorOn:colorOff,">> UseNP"); + ImGui::TextColored(ch->goingToLoop?colorOn:colorOff,">> GoingToLoop"); + break; + } + case DIV_SYSTEM_C64_6581: case DIV_SYSTEM_C64_8580: { + DivPlatformC64* ch=(DivPlatformC64*)data; + ImGui::Text("> C64"); + COMMON_CHIP_DEBUG; + ImGui::Text("- filtControl: %d",ch->filtControl); + ImGui::Text("- filtRes: %d",ch->filtRes); + ImGui::Text("- vol: %d",ch->vol); + ImGui::Text("- writeOscBuf: %d",ch->writeOscBuf); + ImGui::Text("- filtCut: %d",ch->filtCut); + ImGui::Text("- resetTime: %d",ch->resetTime); + COMMON_CHIP_DEBUG_BOOL; + break; + } + case DIV_SYSTEM_ARCADE: + case DIV_SYSTEM_YM2151: { + DivPlatformArcade* ch=(DivPlatformArcade*)data; + ImGui::Text("> YM2151"); + FM_CHIP_DEBUG; + ImGui::Text("- baseFreqOff: %d",ch->baseFreqOff); + ImGui::Text("- amDepth: %d",ch->amDepth); + ImGui::Text("- pmDepth: %d",ch->pmDepth); + FM_CHIP_DEBUG_BOOL; + ImGui::TextColored(ch->useYMFM?colorOn:colorOff,">> UseYMFM"); + break; + } + case DIV_SYSTEM_SEGAPCM: + case DIV_SYSTEM_SEGAPCM_COMPAT: { + DivPlatformSegaPCM* ch=(DivPlatformSegaPCM*)data; + ImGui::Text("> SegaPCM"); + COMMON_CHIP_DEBUG; + ImGui::Text("- delay: %d",ch->delay); + ImGui::Text("- pcmL: %d",ch->pcmL); + ImGui::Text("- pcmR: %d",ch->pcmR); + ImGui::Text("- pcmCycles: %d",ch->pcmCycles); + ImGui::Text("- sampleBank: %d",ch->sampleBank); + COMMON_CHIP_DEBUG_BOOL; + break; + } + case DIV_SYSTEM_AY8910: { + DivPlatformAY8910* ch=(DivPlatformAY8910*)data; + ImGui::Text("> AY-3-8910"); + COMMON_CHIP_DEBUG; + ImGui::Text("- sampleBank: %d",ch->sampleBank); + ImGui::Text("- stereoSep: %d",ch->stereoSep); + ImGui::Text("- delay: %d",ch->delay); + ImGui::Text("- extClock: %d",ch->extClock); + ImGui::Text("- extDiv: %d",ch->extDiv); + ImGui::Text("- portAVal: %d",ch->portAVal); + ImGui::Text("- portBVal: %d",ch->portBVal); + ImGui::Text("* envelope:"); + ImGui::Text(" - mode: %d",ch->ayEnvMode); + ImGui::Text(" - period: %d",ch->ayEnvPeriod); + ImGui::Text(" * slide: %d",ch->ayEnvSlide); + ImGui::Text(" - slideLow: %d",ch->ayEnvSlideLow); + COMMON_CHIP_DEBUG_BOOL; + ImGui::TextColored(ch->extMode?colorOn:colorOff,">> ExtMode"); + ImGui::TextColored(ch->stereo?colorOn:colorOff,">> Stereo"); + ImGui::TextColored(ch->sunsoft?colorOn:colorOff,">> Sunsoft"); + ImGui::TextColored(ch->intellivision?colorOn:colorOff,">> Intellivision"); + ImGui::TextColored(ch->clockSel?colorOn:colorOff,">> ClockSel"); + ImGui::TextColored(ch->ioPortA?colorOn:colorOff,">> IoPortA"); + ImGui::TextColored(ch->ioPortB?colorOn:colorOff,">> IoPortB"); + break; + } + case DIV_SYSTEM_AY8930: { + DivPlatformAY8930* ch=(DivPlatformAY8930*)data; + ImGui::Text("> AY8930"); + COMMON_CHIP_DEBUG; + ImGui::Text("* noise:"); + ImGui::Text(" - and: %d",ch->ayNoiseAnd); + ImGui::Text(" - or: %d",ch->ayNoiseOr); + ImGui::Text("- sampleBank: %d",ch->sampleBank); + ImGui::Text("- stereoSep: %d",ch->stereoSep); + ImGui::Text("- delay: %d",ch->delay); + ImGui::Text("- portAVal: %d",ch->portAVal); + ImGui::Text("- portBVal: %d",ch->portBVal); + COMMON_CHIP_DEBUG_BOOL; + ImGui::TextColored(ch->bank?colorOn:colorOff,">> Bank"); + ImGui::TextColored(ch->extMode?colorOn:colorOff,">> ExtMode"); + ImGui::TextColored(ch->stereo?colorOn:colorOff,">> Stereo"); + ImGui::TextColored(ch->clockSel?colorOn:colorOff,">> ClockSel"); + ImGui::TextColored(ch->ioPortA?colorOn:colorOff,">> IoPortA"); + ImGui::TextColored(ch->ioPortB?colorOn:colorOff,">> IoPortB"); + break; + } + case DIV_SYSTEM_QSOUND: { + DivPlatformQSound* ch=(DivPlatformQSound*)data; + ImGui::Text("> QSound"); + COMMON_CHIP_DEBUG; + ImGui::Text("* echo:"); + ImGui::Text(" - delay: %d",ch->echoDelay); + ImGui::Text(" - feedback: %d",ch->echoFeedback); + COMMON_CHIP_DEBUG_BOOL; + break; + } + case DIV_SYSTEM_X1_010: { + DivPlatformX1_010* ch=(DivPlatformX1_010*)data; + ImGui::Text("> X1-010"); + COMMON_CHIP_DEBUG; + ImGui::Text("- sampleBank: %d",ch->sampleBank); + ImGui::Text("- bankSlot: [%d,%d,%d,%d,%d,%d,%d,%d]",ch->bankSlot[0],ch->bankSlot[1],ch->bankSlot[2],ch->bankSlot[3],ch->bankSlot[4],ch->bankSlot[5],ch->bankSlot[6],ch->bankSlot[7]); + COMMON_CHIP_DEBUG_BOOL; + ImGui::TextColored(ch->stereo?colorOn:colorOff,">> Stereo"); + ImGui::TextColored(ch->isBanked?colorOn:colorOff,">> IsBanked"); + break; + } + case DIV_SYSTEM_N163: { + DivPlatformN163* ch=(DivPlatformN163*)data; + ImGui::Text("> N163"); + COMMON_CHIP_DEBUG; + ImGui::Text("- initChanMax: %d",ch->initChanMax); + ImGui::Text("- chanMax: %d",ch->chanMax); + ImGui::Text("- loadWave: %d",ch->loadWave); + ImGui::Text("- loadPos: %d",ch->loadPos); + COMMON_CHIP_DEBUG_BOOL; + ImGui::TextColored(ch->multiplex?colorOn:colorOff,">> Multiplex"); + break; + } + case DIV_SYSTEM_VRC6: { + DivPlatformVRC6* ch=(DivPlatformVRC6*)data; + ImGui::Text("> VRC6"); + COMMON_CHIP_DEBUG; + ImGui::Text("- sampleBank: %.2x",ch->sampleBank); + ImGui::Text("- writeOscBuf: %.2x",ch->writeOscBuf); + COMMON_CHIP_DEBUG_BOOL; + break; + } + case DIV_SYSTEM_LYNX: { + DivPlatformLynx* ch=(DivPlatformLynx*)data; + ImGui::Text("> Lynx"); + COMMON_CHIP_DEBUG; + COMMON_CHIP_DEBUG_BOOL; + break; + } + case DIV_SYSTEM_PCM_DAC: { + DivPlatformPCMDAC* ch=(DivPlatformPCMDAC*)data; + ImGui::Text("> PCM DAC"); + COMMON_CHIP_DEBUG; + ImGui::Text("- outDepth: %d",ch->outDepth); + COMMON_CHIP_DEBUG_BOOL; + ImGui::TextColored(ch->outStereo?colorOn:colorOff,">> OutStereo"); + break; + } + case DIV_SYSTEM_ES5506: { + DivPlatformES5506* ch=(DivPlatformES5506*)data; + ImGui::Text("> ES5506"); + COMMON_CHIP_DEBUG; + ImGui::Text("- cycle: %d",ch->cycle); + ImGui::Text("- curPage: %d",ch->curPage); + ImGui::Text("- volScale: %d",ch->volScale); + ImGui::Text("- maskedVal: %.2x",ch->maskedVal); + ImGui::Text("- irqv: %.2x",ch->irqv); + ImGui::Text("- curCR: %.8x",ch->curCR); + ImGui::Text("- initChanMax: %d",ch->initChanMax); + ImGui::Text("- chanMax: %d",ch->chanMax); + COMMON_CHIP_DEBUG_BOOL; + ImGui::TextColored(ch->isMasked?colorOn:colorOff,">> IsMasked"); + ImGui::TextColored(ch->isReaded?colorOn:colorOff,">> isReaded"); + ImGui::TextColored(ch->irqTrigger?colorOn:colorOff,">> IrqTrigger"); + break; + } + case DIV_SYSTEM_K007232: { + DivPlatformK007232* ch=(DivPlatformK007232*)data; + ImGui::Text("> K007232"); + COMMON_CHIP_DEBUG; + ImGui::Text("- delay: %.2x",ch->delay); + ImGui::Text("- lastLoop: %.2x",ch->lastLoop); + ImGui::Text("- lastVolume: %.2x",ch->lastVolume); + COMMON_CHIP_DEBUG_BOOL; + ImGui::TextColored(ch->stereo?colorOn:colorOff,">> Stereo"); + break; + } + case DIV_SYSTEM_GA20: { + DivPlatformGA20* ch=(DivPlatformGA20*)data; + ImGui::Text("> GA20"); + COMMON_CHIP_DEBUG; + ImGui::Text("- delay: %.2x",ch->delay); + COMMON_CHIP_DEBUG_BOOL; + break; + } + case DIV_SYSTEM_SM8521: { + DivPlatformSM8521* ch=(DivPlatformSM8521*)data; + ImGui::Text("> SM8521"); + COMMON_CHIP_DEBUG; + COMMON_CHIP_DEBUG_BOOL; + ImGui::TextColored(ch->antiClickEnabled?colorOn:colorOff,">> AntiClickEnabled"); + break; + } + case DIV_SYSTEM_PV1000: { + DivPlatformPV1000* ch=(DivPlatformPV1000*)data; + ImGui::Text("> PV1000"); + COMMON_CHIP_DEBUG; + COMMON_CHIP_DEBUG_BOOL; + break; + } + case DIV_SYSTEM_K053260: { + DivPlatformK053260* ch=(DivPlatformK053260*)data; + ImGui::Text("> K053260"); + COMMON_CHIP_DEBUG; + COMMON_CHIP_DEBUG_BOOL; + break; + } + case DIV_SYSTEM_C140: { + DivPlatformC140* ch=(DivPlatformC140*)data; + ImGui::Text("> C140"); + COMMON_CHIP_DEBUG; + COMMON_CHIP_DEBUG_BOOL; + break; + } + default: + ImGui::Text("Unimplemented chip! Help!"); + break; + } } void putDispatchChan(void* data, int chanNum, int type) { - ImGui::Text("I will finish later..."); + ImVec4 colorOn=ImVec4(1.0f,1.0f,0.0f,1.0f); + ImVec4 colorOff=ImVec4(0.3f,0.3f,0.3f,1.0f); + switch (type) { + case DIV_SYSTEM_GENESIS: { + if (chanNum>5) { + SMS_CHAN_DEBUG; + } else { + GENESIS_CHAN_DEBUG; + } + break; + } + case DIV_SYSTEM_GENESIS_EXT: { + if (chanNum>8) { + SMS_CHAN_DEBUG; + } else if (chanNum>=2 && chanNum<=5) { + DivPlatformOPN::OPNOpChannelStereo* ch=(DivPlatformOPN::OPNOpChannelStereo*)data; + ImGui::Text("> YM2612 (per operator)"); + OPNB_OPCHAN_DEBUG; + } else { + GENESIS_CHAN_DEBUG; + } + break; + } + case DIV_SYSTEM_YM2612: + case DIV_SYSTEM_YM2612_DUALPCM: { + GENESIS_CHAN_DEBUG; + break; + } + case DIV_SYSTEM_YM2612_EXT: + case DIV_SYSTEM_YM2612_DUALPCM_EXT: { + if (chanNum>=2 && chanNum<=5) { + DivPlatformOPN::OPNOpChannelStereo* ch=(DivPlatformOPN::OPNOpChannelStereo*)data; + ImGui::Text("> YM2612 (per operator)"); + OPNB_OPCHAN_DEBUG; + } else { + GENESIS_CHAN_DEBUG; + } + break; + } + case DIV_SYSTEM_SMS: { + SMS_CHAN_DEBUG; + break; + } + case DIV_SYSTEM_YM2203: { + OPN_CHAN_DEBUG; + break; + } + case DIV_SYSTEM_YM2203_EXT: { + if (chanNum>=2 && chanNum<=5) { + OPN_OPCHAN_DEBUG; + } else { + OPN_CHAN_DEBUG; + } + break; + } + case DIV_SYSTEM_YM2608: { + DivPlatformOPN::OPNChannelStereo* ch=(DivPlatformOPN::OPNChannelStereo*)data; + ImGui::Text("> YM2608"); + OPNB_CHAN_DEBUG; + break; + } + case DIV_SYSTEM_YM2608_EXT: { + if (chanNum>=2 && chanNum<=5) { + DivPlatformOPN::OPNOpChannelStereo* ch=(DivPlatformOPN::OPNOpChannelStereo*)data; + ImGui::Text("> YM2608 (per operator)"); + OPNB_OPCHAN_DEBUG; + } else { + DivPlatformOPN::OPNChannelStereo* ch=(DivPlatformOPN::OPNChannelStereo*)data; + ImGui::Text("> YM2608"); + OPNB_CHAN_DEBUG; + } + break; + } + case DIV_SYSTEM_YM2610: + case DIV_SYSTEM_YM2610_FULL: { + DivPlatformOPN::OPNChannelStereo* ch=(DivPlatformOPN::OPNChannelStereo*)data; + ImGui::Text("> YM2610"); + OPNB_CHAN_DEBUG; + break; + } + case DIV_SYSTEM_YM2610B: { + DivPlatformOPN::OPNChannelStereo* ch=(DivPlatformOPN::OPNChannelStereo*)data; + ImGui::Text("> YM2610B"); + OPNB_CHAN_DEBUG; + break; + } + case DIV_SYSTEM_YM2610_EXT: + case DIV_SYSTEM_YM2610_FULL_EXT: { + if (chanNum>=1 && chanNum<=4) { + DivPlatformOPN::OPNOpChannelStereo* ch=(DivPlatformOPN::OPNOpChannelStereo*)data; + ImGui::Text("> YM2610 (per operator)"); + OPNB_OPCHAN_DEBUG; + } else { + DivPlatformOPN::OPNChannelStereo* ch=(DivPlatformOPN::OPNChannelStereo*)data; + ImGui::Text("> YM2610"); + OPNB_CHAN_DEBUG; + } + break; + } + case DIV_SYSTEM_YM2610B_EXT: { + if (chanNum>=2 && chanNum<=5) { + DivPlatformOPN::OPNOpChannelStereo* ch=(DivPlatformOPN::OPNOpChannelStereo*)data; + ImGui::Text("> YM2610B (per operator)"); + OPNB_OPCHAN_DEBUG; + } else { + DivPlatformOPN::OPNChannelStereo* ch=(DivPlatformOPN::OPNChannelStereo*)data; + ImGui::Text("> YM2610B"); + OPNB_CHAN_DEBUG; + } + break; + } + case DIV_SYSTEM_GB: { + DivPlatformGB::Channel* ch=(DivPlatformGB::Channel*)data; + ImGui::Text("> GameBoy"); + COMMON_CHAN_DEBUG; + ImGui::Text("- duty: %d",ch->duty); + ImGui::Text("- sweep: %.2x",ch->sweep); + ImGui::Text("- wave: %d",ch->wave); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->sweepChanged?colorOn:colorOff,">> SweepChanged"); + break; + } + case DIV_SYSTEM_PCE: { + DivPlatformPCE::Channel* ch=(DivPlatformPCE::Channel*)data; + ImGui::Text("> PCEngine"); + COMMON_CHAN_DEBUG; + ImGui::Text("* DAC:"); + ImGui::Text(" - period: %d",ch->dacPeriod); + ImGui::Text(" - rate: %d",ch->dacRate); + ImGui::Text(" - pos: %d",ch->dacPos); + ImGui::Text(" - out: %d",ch->dacOut); + ImGui::Text(" - sample: %d",ch->dacSample); + ImGui::Text("- pan: %.2x",ch->pan); + ImGui::Text("- wave: %d",ch->wave); + ImGui::Text("- macroVolMul: %d",ch->macroVolMul); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->noise?colorOn:colorOff,">> Noise"); + ImGui::TextColored(ch->pcm?colorOn:colorOff,">> DAC"); + ImGui::TextColored(ch->furnaceDac?colorOn:colorOff,">> FurnaceDAC"); + break; + } + case DIV_SYSTEM_NES: { + DivPlatformNES::Channel* ch=(DivPlatformNES::Channel*)data; + ImGui::Text("> NES"); + COMMON_CHAN_DEBUG; + ImGui::Text(" - prev: %d",ch->prevFreq); + ImGui::Text("- duty: %d",ch->duty); + ImGui::Text("- sweep: %.2x",ch->sweep); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->sweepChanged?colorOn:colorOff,">> SweepChanged"); + ImGui::TextColored(ch->furnaceDac?colorOn:colorOff,">> FurnaceDAC"); + break; + } + case DIV_SYSTEM_C64_6581: case DIV_SYSTEM_C64_8580: { + DivPlatformC64::Channel* ch=(DivPlatformC64::Channel*)data; + ImGui::Text("> C64"); + COMMON_CHAN_DEBUG; + ImGui::Text("- prevFreq: %d",ch->prevFreq); + ImGui::Text("- testWhen: %d",ch->testWhen); + ImGui::Text("- duty: %d",ch->duty); + ImGui::Text("- sweep: %.2x",ch->sweep); + ImGui::Text("- wave: %.1x",ch->wave); + ImGui::Text("- ADSR: %.1x %.1x %.1x %.1x",ch->attack,ch->decay,ch->sustain,ch->release); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->sweepChanged?colorOn:colorOff,">> SweepChanged"); + ImGui::TextColored(ch->filter?colorOn:colorOff,">> Filter"); + ImGui::TextColored(ch->resetMask?colorOn:colorOff,">> ResetMask"); + ImGui::TextColored(ch->resetFilter?colorOn:colorOff,">> ResetFilter"); + ImGui::TextColored(ch->resetDuty?colorOn:colorOff,">> ResetDuty"); + ImGui::TextColored(ch->ring?colorOn:colorOff,">> Ring"); + ImGui::TextColored(ch->sync?colorOn:colorOff,">> Sync"); + break; + } + case DIV_SYSTEM_ARCADE: + case DIV_SYSTEM_YM2151: { + DivPlatformArcade::Channel* ch=(DivPlatformArcade::Channel*)data; + ImGui::Text("> YM2151"); + ImGui::Text("- freqHL: %.2x%.2x",ch->freqH,ch->freqL); + COMMON_CHAN_DEBUG; + ImGui::Text("- KOnCycles: %d",ch->konCycles); + ImGui::Text("- chVolL: %.2x",ch->chVolL); + ImGui::Text("- chVolR: %.2x",ch->chVolR); + COMMON_CHAN_DEBUG_BOOL; + break; + } + case DIV_SYSTEM_SEGAPCM: + case DIV_SYSTEM_SEGAPCM_COMPAT: { + DivPlatformSegaPCM::Channel* ch=(DivPlatformSegaPCM::Channel*)data; + ImGui::Text("> SegaPCM"); + COMMON_CHAN_DEBUG; + ImGui::Text("* PCM:"); + ImGui::Text(" - sample: %d",ch->pcm.sample); + ImGui::Text(" - pos: %d",ch->pcm.pos); + ImGui::Text(" - len: %d",ch->pcm.len); + ImGui::Text(" - freq: %d",ch->pcm.freq); + ImGui::Text("- chVolL: %.2x",ch->chVolL); + ImGui::Text("- chVolR: %.2x",ch->chVolR); + ImGui::Text("- chPanL: %.2x",ch->chPanL); + ImGui::Text("- chPanR: %.2x",ch->chPanR); + ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->furnacePCM?colorOn:colorOff,">> FurnacePCM"); + ImGui::TextColored(ch->isNewSegaPCM?colorOn:colorOff,">> IsNewSegaPCM"); + break; + } + case DIV_SYSTEM_AY8910: { + DivPlatformAY8910::Channel* ch=(DivPlatformAY8910::Channel*)data; + ImGui::Text("> AY-3-8910"); + COMMON_CHAN_DEBUG; + ImGui::Text("* DAC:"); + ImGui::Text(" - sample: %d",ch->dac.sample); + ImGui::Text(" - rate: %d",ch->dac.rate); + ImGui::Text(" - period: %d",ch->dac.period); + ImGui::Text(" - pos: %d",ch->dac.pos); + ImGui::Text(" - out: %d",ch->dac.out); + ImGui::Text("- autoEnvNum: %.2x",ch->autoEnvNum); + ImGui::Text("- autoEnvDen: %.2x",ch->autoEnvDen); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->dac.furnaceDAC?colorOn:colorOff,">> furnaceDAC"); + break; + } + case DIV_SYSTEM_AY8930: { + DivPlatformAY8930::Channel* ch=(DivPlatformAY8930::Channel*)data; + ImGui::Text("> AY8930"); + COMMON_CHAN_DEBUG; + ImGui::Text("- duty: %d",ch->duty); + ImGui::Text("* DAC:"); + ImGui::Text(" - sample: %d",ch->dac.sample); + ImGui::Text(" - rate: %d",ch->dac.rate); + ImGui::Text(" - period: %d",ch->dac.period); + ImGui::Text(" - pos: %d",ch->dac.pos); + ImGui::Text(" - out: %d",ch->dac.out); + ImGui::Text("- autoEnvNum: %.2x",ch->autoEnvNum); + ImGui::Text("- autoEnvDen: %.2x",ch->autoEnvDen); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->dac.furnaceDAC?colorOn:colorOff,">> furnaceDAC"); + break; + } + case DIV_SYSTEM_QSOUND: { + DivPlatformQSound::Channel* ch=(DivPlatformQSound::Channel*)data; + ImGui::Text("> QSound"); + COMMON_CHAN_DEBUG; + ImGui::Text("- sample: %d",ch->sample); + ImGui::Text("- echo: %d",ch->echo); + ImGui::Text("- panning: %d",ch->panning); + ImGui::Text("- resVol: %.2x",ch->resVol); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->useWave?colorOn:colorOff,">> UseWave"); + ImGui::TextColored(ch->surround?colorOn:colorOff,">> Surround"); + ImGui::TextColored(ch->isNewQSound?colorOn:colorOff,">> IsNewQSound"); + break; + } + case DIV_SYSTEM_X1_010: { + DivPlatformX1_010::Channel* ch=(DivPlatformX1_010::Channel*)data; + ImGui::Text("> X1-010"); + COMMON_CHAN_DEBUG; + ImGui::Text("- wave: %d",ch->wave); + ImGui::Text("- sample: %d",ch->sample); + ImGui::Text("- pan: %d",ch->pan); + ImGui::Text("* envelope:"); + ImGui::Text(" - shape: %d",ch->env.shape); + ImGui::Text(" - period: %.2x",ch->env.period); + ImGui::Text(" - slide: %.2x",ch->env.slide); + ImGui::Text(" - slidefrac: %.2x",ch->env.slidefrac); + ImGui::Text(" - autoEnvNum: %.2x",ch->autoEnvNum); + ImGui::Text(" - autoEnvDen: %.2x",ch->autoEnvDen); + ImGui::Text("- WaveBank: %d",ch->waveBank); + ImGui::Text("- bankSlot: %d",ch->bankSlot); + ImGui::Text("- Lvol: %.2x",ch->lvol); + ImGui::Text("- Rvol: %.2x",ch->rvol); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->envChanged?colorOn:colorOff,">> EnvChanged"); + ImGui::TextColored(ch->furnacePCM?colorOn:colorOff,">> FurnacePCM"); + ImGui::TextColored(ch->pcm?colorOn:colorOff,">> PCM"); + ImGui::TextColored(ch->env.flag.envEnable?colorOn:colorOff,">> EnvEnable"); + ImGui::TextColored(ch->env.flag.envOneshot?colorOn:colorOff,">> EnvOneshot"); + ImGui::TextColored(ch->env.flag.envSplit?colorOn:colorOff,">> EnvSplit"); + ImGui::TextColored(ch->env.flag.envHinvR?colorOn:colorOff,">> EnvHinvR"); + ImGui::TextColored(ch->env.flag.envVinvR?colorOn:colorOff,">> EnvVinvR"); + ImGui::TextColored(ch->env.flag.envHinvL?colorOn:colorOff,">> EnvHinvL"); + ImGui::TextColored(ch->env.flag.envVinvL?colorOn:colorOff,">> EnvVinvL"); + break; + } + case DIV_SYSTEM_N163: { + DivPlatformN163::Channel* ch=(DivPlatformN163::Channel*)data; + ImGui::Text("> N163"); + COMMON_CHAN_DEBUG; + ImGui::Text("- wave: %d",ch->wave); + ImGui::Text("- wavepos: %d",ch->wavePos); + ImGui::Text("- wavelen: %d",ch->waveLen); + ImGui::Text("- wavemode: %d",ch->waveMode); + ImGui::Text("- resVol: %.2x",ch->resVol); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->volumeChanged?colorOn:colorOff,">> VolumeChanged"); + ImGui::TextColored(ch->waveChanged?colorOn:colorOff,">> WaveChanged"); + ImGui::TextColored(ch->waveUpdated?colorOn:colorOff,">> WaveUpdated"); + break; + } + case DIV_SYSTEM_VRC6: { + DivPlatformVRC6::Channel* ch=(DivPlatformVRC6::Channel*)data; + ImGui::Text("> VRC6"); + COMMON_CHAN_DEBUG; + ImGui::Text("* DAC:"); + ImGui::Text(" - period: %d",ch->dacPeriod); + ImGui::Text(" - rate: %d",ch->dacRate); + ImGui::Text(" - out: %d",ch->dacOut); + ImGui::Text(" - pos: %d",ch->dacPos); + ImGui::Text(" - sample: %d",ch->dacSample); + ImGui::Text("- duty: %d",ch->duty); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->pcm?colorOn:colorOff,">> DAC"); + ImGui::TextColored(ch->furnaceDac?colorOn:colorOff,">> FurnaceDAC"); + break; + } + case DIV_SYSTEM_ES5506: { + DivPlatformES5506::Channel* ch=(DivPlatformES5506::Channel*)data; + ImGui::Text("> ES5506"); + COMMON_CHAN_DEBUG; + ImGui::Text("- nextFreq: %d",ch->nextFreq); + ImGui::Text("- nextNote: %d",ch->nextNote); + ImGui::Text("- currNote: %d",ch->currNote); + ImGui::Text("- wave: %d",ch->wave); + ImGui::Text("- VolMacroMax: %d",ch->volMacroMax); + ImGui::Text("- PanMacroMax: %d",ch->panMacroMax); + ImGui::Text("* PCM:"); + ImGui::Text(" * index: %d",ch->pcm.index); + ImGui::Text(" - next: %d",ch->pcm.next); + ImGui::Text(" - note: %d",ch->pcm.note); + ImGui::Text(" * freqOffs: %.6f",ch->pcm.freqOffs); + ImGui::Text(" - next: %.6f",ch->pcm.nextFreqOffs); + ImGui::Text(" - bank: %.2x",ch->pcm.bank); + ImGui::Text(" - start: %.8x",ch->pcm.start); + ImGui::Text(" - end: %.8x",ch->pcm.end); + ImGui::Text(" - length: %.8x",ch->pcm.length); + ImGui::Text(" - loopStart: %.8x",ch->pcm.loopStart); + ImGui::Text(" - loopEnd: %.8x",ch->pcm.loopEnd); + ImGui::Text(" - loopMode: %d",ch->pcm.loopMode); + ImGui::Text(" - nextPos: %d",ch->pcm.nextPos); + ImGui::Text("* Filter:"); + ImGui::Text(" - Mode: %d",ch->filter.mode); + ImGui::Text(" - K1: %.4x",ch->filter.k1); + ImGui::Text(" - K2: %.4x",ch->filter.k2); + ImGui::Text("* Envelope:"); + ImGui::Text(" - EnvCount: %.3x",ch->envelope.ecount); + ImGui::Text(" - LVRamp: %d",ch->envelope.lVRamp); + ImGui::Text(" - RVRamp: %d",ch->envelope.rVRamp); + ImGui::Text(" - K1Ramp: %d",ch->envelope.k1Ramp); + ImGui::Text(" - K2Ramp: %d",ch->envelope.k2Ramp); + ImGui::Text(" - K1Offs: %d",ch->k1Offs); + ImGui::Text(" - K2Offs: %d",ch->k2Offs); + ImGui::Text(" - K1Slide: %d",ch->k1Slide); + ImGui::Text(" - K2Slide: %d",ch->k2Slide); + ImGui::Text(" - K1Prev: %.4x",ch->k1Prev); + ImGui::Text(" - K2Prev: %.4x",ch->k2Prev); + ImGui::Text("* Overwrite:"); + ImGui::Text(" * Filter:"); + ImGui::Text(" - Mode: %d",ch->overwrite.filter.mode); + ImGui::Text(" - K1: %.4x",ch->overwrite.filter.k1); + ImGui::Text(" - K2: %.4x",ch->overwrite.filter.k2); + ImGui::Text(" * Envelope:"); + ImGui::Text(" - EnvCount: %.3x",ch->overwrite.envelope.ecount); + ImGui::Text(" - LVRamp: %d",ch->overwrite.envelope.lVRamp); + ImGui::Text(" - RVRamp: %d",ch->overwrite.envelope.rVRamp); + ImGui::Text(" - K1Ramp: %d",ch->overwrite.envelope.k1Ramp); + ImGui::Text(" - K2Ramp: %d",ch->overwrite.envelope.k2Ramp); + ImGui::Text("- CA: %.2x",ch->ca); + ImGui::Text("- LVol: %.2x",ch->lVol); + ImGui::Text("- RVol: %.2x",ch->rVol); + ImGui::Text("- outLVol: %.2x",ch->outLVol); + ImGui::Text("- outRVol: %.2x",ch->outRVol); + ImGui::Text("- ResLVol: %.2x",ch->resLVol); + ImGui::Text("- ResRVol: %.2x",ch->resRVol); + ImGui::Text("- oscOut: %d",ch->oscOut); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->volChanged.lVol?colorOn:colorOff,">> LVolChanged"); + ImGui::TextColored(ch->volChanged.rVol?colorOn:colorOff,">> RVolChanged"); + ImGui::TextColored(ch->filterChanged.mode?colorOn:colorOff,">> FilterModeChanged"); + ImGui::TextColored(ch->filterChanged.k1?colorOn:colorOff,">> FilterK1Changed"); + ImGui::TextColored(ch->filterChanged.k2?colorOn:colorOff,">> FilterK2Changed"); + ImGui::TextColored(ch->envChanged.ecount?colorOn:colorOff,">> EnvECountChanged"); + ImGui::TextColored(ch->envChanged.lVRamp?colorOn:colorOff,">> EnvLVRampChanged"); + ImGui::TextColored(ch->envChanged.rVRamp?colorOn:colorOff,">> EnvRVRampChanged"); + ImGui::TextColored(ch->envChanged.k1Ramp?colorOn:colorOff,">> EnvK1RampChanged"); + ImGui::TextColored(ch->envChanged.k2Ramp?colorOn:colorOff,">> EnvK2RampChanged"); + ImGui::TextColored(ch->pcmChanged.index?colorOn:colorOff,">> PCMIndexChanged"); + ImGui::TextColored(ch->pcmChanged.slice?colorOn:colorOff,">> PCMSliceChanged"); + ImGui::TextColored(ch->pcmChanged.position?colorOn:colorOff,">> PCMPositionChanged"); + ImGui::TextColored(ch->pcmChanged.loopBank?colorOn:colorOff,">> PCMLoopBankChanged"); + ImGui::TextColored(ch->isReverseLoop?colorOn:colorOff,">> IsReverseLoop"); + ImGui::TextColored(ch->pcm.isNoteMap?colorOn:colorOff,">> PCMIsNoteMap"); + ImGui::TextColored(ch->pcm.pause?colorOn:colorOff,">> PCMPause"); + ImGui::TextColored(ch->pcm.direction?colorOn:colorOff,">> PCMDirection"); + ImGui::TextColored(ch->pcm.setPos?colorOn:colorOff,">> PCMSetPos"); + ImGui::TextColored(ch->envelope.k1Slow?colorOn:colorOff,">> EnvK1Slow"); + ImGui::TextColored(ch->envelope.k2Slow?colorOn:colorOff,">> EnvK2Slow"); + ImGui::TextColored(ch->overwrite.envelope.k1Slow?colorOn:colorOff,">> EnvK1SlowOverwrite"); + ImGui::TextColored(ch->overwrite.envelope.k2Slow?colorOn:colorOff,">> EnvK2SlowOverwrite"); + ImGui::TextColored(ch->overwrite.state.mode?colorOn:colorOff,">> FilterModeOverwrited"); + ImGui::TextColored(ch->overwrite.state.k1?colorOn:colorOff,">> FilterK1Overwrited"); + ImGui::TextColored(ch->overwrite.state.k2?colorOn:colorOff,">> FilterK2Overwrited"); + ImGui::TextColored(ch->overwrite.state.ecount?colorOn:colorOff,">> EnvECountOverwrited"); + ImGui::TextColored(ch->overwrite.state.lVRamp?colorOn:colorOff,">> EnvLVRampOverwrited"); + ImGui::TextColored(ch->overwrite.state.rVRamp?colorOn:colorOff,">> EnvRVRampOverwrited"); + ImGui::TextColored(ch->overwrite.state.k1Ramp?colorOn:colorOff,">> EnvK1RampOverwrited"); + ImGui::TextColored(ch->overwrite.state.k2Ramp?colorOn:colorOff,">> EnvK2RampOverwrited"); + break; + } + case DIV_SYSTEM_LYNX: { + DivPlatformLynx::Channel* ch=(DivPlatformLynx::Channel*)data; + ImGui::Text("> Lynx"); + COMMON_CHAN_DEBUG; + ImGui::Text("* FreqDiv:"); + ImGui::Text(" - clockDivider: %d",ch->fd.clockDivider); + ImGui::Text(" - backup: %d",ch->fd.backup); + ImGui::Text("- actualNote: %d",ch->actualNote); + ImGui::Text("* Sample:"); + ImGui::Text(" - sample: %d",ch->sample); + ImGui::Text(" - pos: %d",ch->samplePos); + ImGui::Text(" - accum: %d",ch->sampleAccum); + ImGui::Text(" * freq: %d",ch->sampleFreq); + ImGui::Text(" - base: %d",ch->sampleBaseFreq); + ImGui::Text("* duty:"); + ImGui::Text(" - int_feedback7: %d",ch->duty.int_feedback7); + ImGui::Text(" - feedback: %d",ch->duty.feedback); + ImGui::Text("- pan: %.2x",ch->pan); + ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->pcm?colorOn:colorOff,">> DAC"); + break; + } + case DIV_SYSTEM_PCM_DAC: { + DivPlatformPCMDAC::Channel* ch=(DivPlatformPCMDAC::Channel*)data; + ImGui::Text("> PCM DAC"); + COMMON_CHAN_DEBUG; + ImGui::Text("* Sample: %d",ch->sample); + ImGui::Text(" - dir: %d",ch->audDir); + ImGui::Text(" - loc: %d",ch->audLoc); + ImGui::Text(" - len: %d",ch->audLen); + ImGui::Text(" * pos: %d",ch->audPos); + ImGui::Text(" - sub: %d",ch->audSub); + ImGui::Text("- wave: %d",ch->wave); + ImGui::Text("- panL: %.2x",ch->panL); + ImGui::Text("- panR: %.2x",ch->panR); + ImGui::Text("- envVol: %.2x",ch->envVol); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->useWave?colorOn:colorOff,">> UseWave"); + ImGui::TextColored(ch->setPos?colorOn:colorOff,">> SetPos"); + break; + } + case DIV_SYSTEM_K007232: { + DivPlatformK007232::Channel* ch=(DivPlatformK007232::Channel*)data; + ImGui::Text("> K007232"); + COMMON_CHAN_DEBUG; + ImGui::Text("- prevFreq: %d",ch->prevFreq); + ImGui::Text("* Sample: %d",ch->sample); + ImGui::Text(" - pos: %d",ch->audPos); + ImGui::Text(" - prevBank: %d",ch->prevBank); + ImGui::Text("* panning: %d",ch->panning); + ImGui::Text(" - prev: %d",ch->prevPan); + ImGui::Text("- resVol: %.2x",ch->resVol); + ImGui::Text("- lvol: %.2x",ch->lvol); + ImGui::Text("- rvol: %.2x",ch->rvol); + ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->volumeChanged?colorOn:colorOff,">> VolumeChanged"); + ImGui::TextColored(ch->setPos?colorOn:colorOff,">> SetPos"); + break; + } + case DIV_SYSTEM_GA20: { + DivPlatformGA20::Channel* ch=(DivPlatformGA20::Channel*)data; + ImGui::Text("> GA20"); + COMMON_CHAN_DEBUG; + ImGui::Text("- prevFreq: %d",ch->prevFreq); + ImGui::Text("* Sample: %d",ch->sample); + ImGui::Text(" - pos: %d",ch->audPos); + ImGui::Text("- resVol: %.2x",ch->resVol); + ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->volumeChanged?colorOn:colorOff,">> VolumeChanged"); + ImGui::TextColored(ch->setPos?colorOn:colorOff,">> SetPos"); + break; + } + case DIV_SYSTEM_SM8521: { + DivPlatformSM8521::Channel* ch=(DivPlatformSM8521::Channel*)data; + ImGui::Text("> SM8521"); + COMMON_CHAN_DEBUG; + ImGui::Text("* AntiClick:"); + ImGui::Text(" - periodCount: %d",ch->antiClickPeriodCount); + ImGui::Text(" - wavePos: %d",ch->antiClickWavePos); + ImGui::Text("- wave: %d",ch->wave); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->volumeChanged?colorOn:colorOff,">> VolumeChanged"); + break; + } + case DIV_SYSTEM_PV1000: { + DivPlatformPV1000::Channel* ch=(DivPlatformPV1000::Channel*)data; + ImGui::Text("> PV1000"); + COMMON_CHAN_DEBUG; + COMMON_CHAN_DEBUG_BOOL; + break; + } + case DIV_SYSTEM_K053260: { + DivPlatformK053260::Channel* ch=(DivPlatformK053260::Channel*)data; + ImGui::Text("> K053260"); + COMMON_CHAN_DEBUG; + ImGui::Text("* Sample: %d",ch->sample); + ImGui::Text(" - pos: %d",ch->audPos); + ImGui::Text("- panning: %d",ch->panning); + ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->setPos?colorOn:colorOff,">> SetPos"); + ImGui::TextColored(ch->reverse?colorOn:colorOff,">> Reverse"); + break; + } + case DIV_SYSTEM_C140: { + DivPlatformC140::Channel* ch=(DivPlatformC140::Channel*)data; + ImGui::Text("> C140"); + COMMON_CHAN_DEBUG; + ImGui::Text("* Sample: %d",ch->sample); + ImGui::Text(" - pos: %d",ch->audPos); + ImGui::Text("- chPanL: %.2x",ch->chPanL); + ImGui::Text("- chPanR: %.2x",ch->chPanR); + ImGui::Text("- chVolL: %.2x",ch->chVolL); + ImGui::Text("- chVolR: %.2x",ch->chVolR); + ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul); + ImGui::Text("- macroPanMul: %.2x",ch->macroPanMul); + COMMON_CHAN_DEBUG_BOOL; + ImGui::TextColored(ch->volChangedL?colorOn:colorOff,">> VolChangedL"); + ImGui::TextColored(ch->volChangedR?colorOn:colorOff,">> VolChangedR"); + ImGui::TextColored(ch->setPos?colorOn:colorOff,">> SetPos"); + break; + } + default: + ImGui::Text("Unimplemented chip! Help!"); + break; + } }