GUI: add a debug window

This commit is contained in:
tildearrow 2022-01-27 00:29:16 -05:00
parent 30b012cc5e
commit 0e633ea69b
44 changed files with 490 additions and 4 deletions

202
src/gui/debug.cpp Normal file
View file

@ -0,0 +1,202 @@
#include "debug.h"
#include "imgui.h"
#include "../engine/platform/genesis.h"
#include "../engine/platform/genesisext.h"
#include "../engine/platform/sms.h"
#include "../engine/platform/gb.h"
#include "../engine/platform/pce.h"
#include "../engine/platform/nes.h"
#include "../engine/platform/c64.h"
#include "../engine/platform/arcade.h"
#include "../engine/platform/ym2610.h"
#include "../engine/platform/ym2610ext.h"
#include "../engine/platform/ay.h"
#include "../engine/platform/ay8930.h"
#include "../engine/platform/tia.h"
#include "../engine/platform/saa.h"
#include "../engine/platform/amiga.h"
#include "../engine/platform/dummy.h"
void putDispatchChan(void* data, int chanNum, int type) {
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: {
DivPlatformGenesis::Channel* ch=(DivPlatformGenesis::Channel*)data;
ImGui::Text("> Genesis");
ImGui::Text("- freqHL: %.2x%.2x",ch->freqH,ch->freqL);
ImGui::Text("* freq: %d",ch->freq);
ImGui::Text(" - base: %d",ch->baseFreq);
ImGui::Text(" - pitch: %d",ch->pitch);
ImGui::Text("- note: %d",ch->note);
ImGui::Text("- ins: %d",ch->ins);
ImGui::Text("- vol: %.2x",ch->vol);
ImGui::Text("- outVol: %.2x",ch->outVol);
ImGui::Text("- pan: %x",ch->pan);
ImGui::TextColored(ch->active?colorOn:colorOff,">> Active");
ImGui::TextColored(ch->insChanged?colorOn:colorOff,">> InsChanged");
ImGui::TextColored(ch->freqChanged?colorOn:colorOff,">> FreqChanged");
ImGui::TextColored(ch->keyOn?colorOn:colorOff,">> KeyOn");
ImGui::TextColored(ch->keyOff?colorOn:colorOff,">> KeyOff");
ImGui::TextColored(ch->portaPause?colorOn:colorOff,">> PortaPause");
ImGui::TextColored(ch->furnaceDac?colorOn:colorOff,">> FurnaceDAC");
ImGui::TextColored(ch->inPorta?colorOn:colorOff,">> InPorta");
break;
}
case DIV_SYSTEM_SMS: {
DivPlatformSMS::Channel* ch=(DivPlatformSMS::Channel*)data;
ImGui::Text("> SMS");
ImGui::Text("* freq: %d",ch->freq);
ImGui::Text(" - base: %d",ch->baseFreq);
ImGui::Text(" - pitch: %d",ch->pitch);
ImGui::Text("- note: %d",ch->note);
ImGui::Text("- ins: %d",ch->ins);
ImGui::Text("- vol: %.2x",ch->vol);
ImGui::Text("- outVol: %.2x",ch->outVol);
ImGui::TextColored(ch->active?colorOn:colorOff,">> Active");
ImGui::TextColored(ch->insChanged?colorOn:colorOff,">> InsChanged");
ImGui::TextColored(ch->freqChanged?colorOn:colorOff,">> FreqChanged");
ImGui::TextColored(ch->keyOn?colorOn:colorOff,">> KeyOn");
ImGui::TextColored(ch->keyOff?colorOn:colorOff,">> KeyOff");
break;
}
case DIV_SYSTEM_GB: {
DivPlatformGB::Channel* ch=(DivPlatformGB::Channel*)data;
ImGui::Text("> GameBoy");
ImGui::Text("* freq: %d",ch->freq);
ImGui::Text(" - base: %d",ch->baseFreq);
ImGui::Text(" - pitch: %d",ch->pitch);
ImGui::Text("- note: %d",ch->note);
ImGui::Text("- ins: %d",ch->ins);
ImGui::Text("- duty: %d",ch->duty);
ImGui::Text("- sweep: %.2x",ch->sweep);
ImGui::Text("- vol: %.2x",ch->vol);
ImGui::Text("- outVol: %.2x",ch->outVol);
ImGui::Text("- wave: %d",ch->wave);
ImGui::TextColored(ch->active?colorOn:colorOff,">> Active");
ImGui::TextColored(ch->insChanged?colorOn:colorOff,">> InsChanged");
ImGui::TextColored(ch->freqChanged?colorOn:colorOff,">> FreqChanged");
ImGui::TextColored(ch->sweepChanged?colorOn:colorOff,">> SweepChanged");
ImGui::TextColored(ch->keyOn?colorOn:colorOff,">> KeyOn");
ImGui::TextColored(ch->keyOff?colorOn:colorOff,">> KeyOff");
ImGui::TextColored(ch->inPorta?colorOn:colorOff,">> InPorta");
break;
}
case DIV_SYSTEM_PCE: {
DivPlatformPCE::Channel* ch=(DivPlatformPCE::Channel*)data;
ImGui::Text("> PCEngine");
ImGui::Text("* freq: %d",ch->freq);
ImGui::Text(" - base: %d",ch->baseFreq);
ImGui::Text(" - pitch: %d",ch->pitch);
ImGui::Text("- note: %d",ch->note);
ImGui::Text("* DAC:");
ImGui::Text(" - period: %d",ch->dacPeriod);
ImGui::Text(" - rate: %d",ch->dacRate);
ImGui::Text(" - pos: %d",ch->dacPos);
ImGui::Text(" - sample: %d",ch->dacSample);
ImGui::Text("- ins: %d",ch->ins);
ImGui::Text("- pan: %.2x",ch->pan);
ImGui::Text("- vol: %.2x",ch->vol);
ImGui::Text("- outVol: %.2x",ch->outVol);
ImGui::Text("- wave: %d",ch->wave);
ImGui::TextColored(ch->active?colorOn:colorOff,">> Active");
ImGui::TextColored(ch->insChanged?colorOn:colorOff,">> InsChanged");
ImGui::TextColored(ch->freqChanged?colorOn:colorOff,">> FreqChanged");
ImGui::TextColored(ch->keyOn?colorOn:colorOff,">> KeyOn");
ImGui::TextColored(ch->keyOff?colorOn:colorOff,">> KeyOff");
ImGui::TextColored(ch->inPorta?colorOn:colorOff,">> InPorta");
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");
ImGui::Text("* freq: %d",ch->freq);
ImGui::Text(" - base: %d",ch->baseFreq);
ImGui::Text(" - pitch: %d",ch->pitch);
ImGui::Text(" - prev: %d",ch->prevFreq);
ImGui::Text("- note: %d",ch->note);
ImGui::Text("- ins: %d",ch->ins);
ImGui::Text("- duty: %d",ch->duty);
ImGui::Text("- sweep: %.2x",ch->sweep);
ImGui::Text("- vol: %.2x",ch->vol);
ImGui::Text("- outVol: %.2x",ch->outVol);
ImGui::Text("- wave: %d",ch->wave);
ImGui::TextColored(ch->active?colorOn:colorOff,">> Active");
ImGui::TextColored(ch->insChanged?colorOn:colorOff,">> InsChanged");
ImGui::TextColored(ch->freqChanged?colorOn:colorOff,">> FreqChanged");
ImGui::TextColored(ch->sweepChanged?colorOn:colorOff,">> SweepChanged");
ImGui::TextColored(ch->keyOn?colorOn:colorOff,">> KeyOn");
ImGui::TextColored(ch->keyOff?colorOn:colorOff,">> KeyOff");
ImGui::TextColored(ch->inPorta?colorOn:colorOff,">> InPorta");
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");
ImGui::Text("* freq: %d",ch->freq);
ImGui::Text(" - base: %d",ch->baseFreq);
ImGui::Text(" - pitch: %d",ch->pitch);
ImGui::Text(" - prev: %d",ch->prevFreq);
ImGui::Text("- testWhen: %d",ch->testWhen);
ImGui::Text("- note: %d",ch->note);
ImGui::Text("- ins: %d",ch->ins);
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);
ImGui::Text("- vol: %.2x",ch->vol);
ImGui::Text("- outVol: %.2x",ch->outVol);
ImGui::TextColored(ch->active?colorOn:colorOff,">> Active");
ImGui::TextColored(ch->insChanged?colorOn:colorOff,">> InsChanged");
ImGui::TextColored(ch->freqChanged?colorOn:colorOff,">> FreqChanged");
ImGui::TextColored(ch->sweepChanged?colorOn:colorOff,">> SweepChanged");
ImGui::TextColored(ch->keyOn?colorOn:colorOff,">> KeyOn");
ImGui::TextColored(ch->keyOff?colorOn:colorOff,">> KeyOff");
ImGui::TextColored(ch->inPorta?colorOn:colorOff,">> InPorta");
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: {
DivPlatformArcade::Channel* ch=(DivPlatformArcade::Channel*)data;
ImGui::Text("> Arcade");
ImGui::Text("- freqHL: %.2x%.2x",ch->freqH,ch->freqL);
ImGui::Text("* freq: %d",ch->freq);
ImGui::Text(" - base: %d",ch->baseFreq);
ImGui::Text(" - pitch: %d",ch->pitch);
//ImGui::Text("- note: %d",ch->note);
ImGui::Text("- ins: %d",ch->ins);
ImGui::Text("- KOnCycles: %d",ch->konCycles);
ImGui::Text("- vol: %.2x",ch->vol);
//ImGui::Text("- outVol: %.2x",ch->outVol);
ImGui::Text("- chVolL: %.2x",ch->chVolL);
ImGui::Text("- chVolR: %.2x",ch->chVolR);
ImGui::Text("* PCM:");
ImGui::Text(" - sample: %d",ch->pcm.sample);
ImGui::Text(" - pos: %d",ch->pcm.pos>>8);
ImGui::Text(" - subPos: %d",ch->pcm.pos&0xff);
ImGui::Text(" - len: %d",ch->pcm.len);
ImGui::Text(" - freq: %.2x",ch->pcm.freq);
ImGui::TextColored(ch->active?colorOn:colorOff,">> Active");
ImGui::TextColored(ch->insChanged?colorOn:colorOff,">> InsChanged");
ImGui::TextColored(ch->freqChanged?colorOn:colorOff,">> FreqChanged");
ImGui::TextColored(ch->keyOn?colorOn:colorOff,">> KeyOn");
ImGui::TextColored(ch->keyOff?colorOn:colorOff,">> KeyOff");
ImGui::TextColored(ch->portaPause?colorOn:colorOff,">> PortaPause");
ImGui::TextColored(ch->furnacePCM?colorOn:colorOff,">> FurnacePCM");
//ImGui::TextColored(ch->inPorta?colorOn:colorOff,">> InPorta");
break;
}
default:
ImGui::Text("Unknown system! Help!");
break;
}
}

6
src/gui/debug.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef _GUI_DEBUG_H
#define _GUI_DEBUG_H
#include "../engine/song.h"
void putDispatchChan(void* data, int chanNum, int type);
#endif

View file

@ -1,5 +1,6 @@
#define _USE_MATH_DEFINES
#include "gui.h"
#include "debug.h"
#include "SDL_clipboard.h"
#include "SDL_events.h"
#include "SDL_keycode.h"
@ -2780,6 +2781,131 @@ void FurnaceGUI::commitSettings() {
ImGui::GetIO().Fonts->Build();
}
void FurnaceGUI::drawDebug() {
static int bpOrder;
static int bpRow;
static int bpTick;
static bool bpOn;
if (!debugOpen) return;
if (ImGui::Begin("Debug",&debugOpen,ImGuiWindowFlags_NoDocking)) {
ImGui::Text("NOTE: use with caution.");
if (ImGui::TreeNode("Debug Controls")) {
ImGui::Button("Pause");
ImGui::SameLine();
ImGui::Button("Frame Advance");
ImGui::SameLine();
ImGui::Button("Row Advance");
ImGui::SameLine();
ImGui::Button("Pattern Advance");
ImGui::Button("Panic");
ImGui::SameLine();
if (ImGui::Button("Abort")) {
abort();
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Breakpoint")) {
ImGui::InputInt("Order",&bpOrder);
ImGui::InputInt("Row",&bpRow);
ImGui::InputInt("Tick",&bpTick);
ImGui::Checkbox("Enable",&bpOn);
ImGui::TreePop();
}
if (ImGui::TreeNode("Dispatch Status")) {
ImGui::Text("for best results set latency to minimum or use the Frame Advance button.");
ImGui::Columns(e->getTotalChannelCount());
for (int i=0; i<e->getTotalChannelCount(); i++) {
void* ch=e->getDispatchChanState(i);
ImGui::TextColored(uiColors[GUI_COLOR_ACCENT_PRIMARY],"Ch. %d: %d, %d",i,e->dispatchOfChan[i],e->dispatchChanOfChan[i]);
if (ch==NULL) {
ImGui::Text("NULL");
} else {
putDispatchChan(ch,e->dispatchChanOfChan[i],e->sysOfChan[i]);
}
ImGui::NextColumn();
}
ImGui::Columns();
ImGui::TreePop();
}
if (ImGui::TreeNode("Playback Status")) {
ImGui::Text("for best results set latency to minimum or use the Frame Advance button.");
ImGui::Columns(e->getTotalChannelCount());
for (int i=0; i<e->getTotalChannelCount(); i++) {
DivChannelState* ch=e->getChanState(i);
ImGui::TextColored(uiColors[GUI_COLOR_ACCENT_PRIMARY],"Channel %d:",i);
if (ch==NULL) {
ImGui::Text("NULL");
} else {
ImGui::Text("* General:");
ImGui::Text("- note = %d",ch->note);
ImGui::Text("- oldNote = %d",ch->oldNote);
ImGui::Text("- pitch = %d",ch->pitch);
ImGui::Text("- portaSpeed = %d",ch->portaSpeed);
ImGui::Text("- portaNote = %d",ch->portaNote);
ImGui::Text("- volume = %.4x",ch->volume);
ImGui::Text("- volSpeed = %d",ch->volSpeed);
ImGui::Text("- cut = %d",ch->cut);
ImGui::Text("- rowDelay = %d",ch->rowDelay);
ImGui::Text("- volMax = %.4x",ch->volMax);
ImGui::Text("- delayOrder = %d",ch->delayOrder);
ImGui::Text("- delayRow = %d",ch->delayRow);
ImGui::Text("- retrigSpeed = %d",ch->retrigSpeed);
ImGui::Text("- retrigTick = %d",ch->retrigTick);
ImGui::PushStyleColor(ImGuiCol_Text,(ch->vibratoDepth>0)?uiColors[GUI_COLOR_MACRO_VOLUME]:uiColors[GUI_COLOR_TEXT]);
ImGui::Text("* Vibrato:");
ImGui::Text("- depth = %d",ch->vibratoDepth);
ImGui::Text("- rate = %d",ch->vibratoRate);
ImGui::Text("- pos = %d",ch->vibratoPos);
ImGui::Text("- dir = %d",ch->vibratoDir);
ImGui::Text("- fine = %d",ch->vibratoFine);
ImGui::PopStyleColor();
ImGui::PushStyleColor(ImGuiCol_Text,(ch->tremoloDepth>0)?uiColors[GUI_COLOR_MACRO_VOLUME]:uiColors[GUI_COLOR_TEXT]);
ImGui::Text("* Tremolo:");
ImGui::Text("- depth = %d",ch->tremoloDepth);
ImGui::Text("- rate = %d",ch->tremoloRate);
ImGui::Text("- pos = %d",ch->tremoloPos);
ImGui::PopStyleColor();
ImGui::PushStyleColor(ImGuiCol_Text,(ch->arp>0)?uiColors[GUI_COLOR_MACRO_VOLUME]:uiColors[GUI_COLOR_TEXT]);
ImGui::Text("* Arpeggio:");
ImGui::Text("- arp = %.2X",ch->arp);
ImGui::Text("- stage = %d",ch->arpStage);
ImGui::Text("- ticks = %d",ch->arpTicks);
ImGui::PopStyleColor();
ImGui::Text("* Miscellaneous:");
ImGui::TextColored(ch->doNote?uiColors[GUI_COLOR_MACRO_VOLUME]:uiColors[GUI_COLOR_HEADER],">> Do Note");
ImGui::TextColored(ch->legato?uiColors[GUI_COLOR_MACRO_VOLUME]:uiColors[GUI_COLOR_HEADER],">> Legato");
ImGui::TextColored(ch->portaStop?uiColors[GUI_COLOR_MACRO_VOLUME]:uiColors[GUI_COLOR_HEADER],">> PortaStop");
ImGui::TextColored(ch->keyOn?uiColors[GUI_COLOR_MACRO_VOLUME]:uiColors[GUI_COLOR_HEADER],">> Key On");
ImGui::TextColored(ch->keyOff?uiColors[GUI_COLOR_MACRO_VOLUME]:uiColors[GUI_COLOR_HEADER],">> Key Off");
ImGui::TextColored(ch->nowYouCanStop?uiColors[GUI_COLOR_MACRO_VOLUME]:uiColors[GUI_COLOR_HEADER],">> NowYouCanStop");
ImGui::TextColored(ch->stopOnOff?uiColors[GUI_COLOR_MACRO_VOLUME]:uiColors[GUI_COLOR_HEADER],">> Stop on Off");
ImGui::TextColored(ch->arpYield?uiColors[GUI_COLOR_MACRO_VOLUME]:uiColors[GUI_COLOR_HEADER],">> Arp Yield");
ImGui::TextColored(ch->delayLocked?uiColors[GUI_COLOR_MACRO_VOLUME]:uiColors[GUI_COLOR_HEADER],">> DelayLocked");
ImGui::TextColored(ch->inPorta?uiColors[GUI_COLOR_MACRO_VOLUME]:uiColors[GUI_COLOR_HEADER],">> InPorta");
ImGui::TextColored(ch->scheduledSlideReset?uiColors[GUI_COLOR_MACRO_VOLUME]:uiColors[GUI_COLOR_HEADER],">> SchedSlide");
}
ImGui::NextColumn();
}
ImGui::Columns();
ImGui::TreePop();
}
if (ImGui::TreeNode("Settings")) {
if (ImGui::Button("Sync")) syncSettings();
ImGui::SameLine();
if (ImGui::Button("Commit")) commitSettings();
ImGui::SameLine();
if (ImGui::Button("Force Load")) e->loadConf();
ImGui::SameLine();
if (ImGui::Button("Force Save")) e->saveConf();
ImGui::TreePop();
}
ImGui::Text("Song format version %d",e->song.version);
ImGui::Text("Furnace version " DIV_VERSION " (%d)",DIV_ENGINE_VERSION);
}
ImGui::End();
}
void FurnaceGUI::startSelection(int xCoarse, int xFine, int y) {
if (xCoarse!=selStart.xCoarse || xFine!=selStart.xFine || y!=selStart.y) {
curNibble=false;
@ -4379,6 +4505,7 @@ bool FurnaceGUI::loop() {
ImGui::EndMenu();
}
if (ImGui::BeginMenu("help")) {
if (ImGui::MenuItem("debug menu")) debugOpen=!debugOpen;
if (ImGui::MenuItem("about...")) {
aboutOpen=true;
aboutScroll=0;
@ -4413,6 +4540,7 @@ bool FurnaceGUI::loop() {
drawMixer();
drawPattern();
drawSettings();
drawDebug();
if (ImGuiFileDialog::Instance()->Display("FileDialog",ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove,ImVec2(600.0f*dpiScale,400.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale))) {
if (ImGuiFileDialog::Instance()->IsOk()) {
@ -4994,6 +5122,9 @@ FurnaceGUI::FurnaceGUI():
soloTimeout(0),
orderEditMode(0),
orderCursor(-1),
loopOrder(-1),
loopRow(-1),
loopEnd(-1),
editControlsOpen(true),
ordersOpen(true),
insListOpen(true),
@ -5007,6 +5138,7 @@ FurnaceGUI::FurnaceGUI():
aboutOpen(false),
settingsOpen(false),
mixerOpen(false),
debugOpen(false),
selecting(false),
curNibble(false),
orderNibble(false),

View file

@ -230,9 +230,10 @@ class FurnaceGUI {
char finalLayoutPath[4096];
int curIns, curWave, curSample, curOctave, oldRow, oldOrder, oldOrder1, editStep, exportLoops, soloChan, soloTimeout, orderEditMode, orderCursor;
int loopOrder, loopRow, loopEnd;
bool editControlsOpen, ordersOpen, insListOpen, songInfoOpen, patternOpen, insEditOpen;
bool waveListOpen, waveEditOpen, sampleListOpen, sampleEditOpen, aboutOpen, settingsOpen;
bool mixerOpen;
bool mixerOpen, debugOpen;
SelectionPoint selStart, selEnd, cursor;
bool selecting, curNibble, orderNibble, extraChannelButtons, followOrders, followPattern, changeAllOrders;
FurnaceGUIWindows curWindow;
@ -313,6 +314,7 @@ class FurnaceGUI {
void drawMixer();
void drawAbout();
void drawSettings();
void drawDebug();
void syncSettings();
void commitSettings();