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

View File

@ -170,6 +170,7 @@ src/gui/font_ptMono.cpp
src/gui/font_unifont.cpp
src/gui/font_icon.cpp
src/gui/fonts.cpp
src/gui/debug.cpp
src/gui/gui.cpp)
if (NOT WIN32 AND NOT APPLE)

BIN
demos/bruno_time.fur Normal file

Binary file not shown.

View File

@ -171,6 +171,12 @@ class DivDispatch {
*/
virtual void tick();
/**
* get the state of a channel.
* @return a pointer, or NULL.
*/
virtual void* getChanState(int chan);
/**
* get this dispatch's state.
* @return a pointer to the dispatch's state. must be deallocated manually!

View File

@ -3716,6 +3716,16 @@ void DivEngine::setLoops(int loops) {
remainingLoops=loops;
}
DivChannelState* DivEngine::getChanState(int ch) {
if (ch<0 || ch>=chans) return NULL;
return &chan[ch];
}
void* DivEngine::getDispatchChanState(int ch) {
if (ch<0 || ch>=chans) return NULL;
return disCont[dispatchOfChan[ch]].dispatch->getChanState(dispatchChanOfChan[ch]);
}
void DivEngine::playSub(bool preserveDrift) {
reset();
if (preserveDrift && curOrder==0) return;

View File

@ -150,9 +150,6 @@ class DivEngine {
std::map<String,String> conf;
std::queue<DivNoteEvent> pendingNotes;
bool isMuted[DIV_MAX_CHANS];
DivSystem sysOfChan[DIV_MAX_CHANS];
int dispatchOfChan[DIV_MAX_CHANS];
int dispatchChanOfChan[DIV_MAX_CHANS];
std::mutex isBusy;
String configPath;
String configFile;
@ -206,6 +203,10 @@ class DivEngine {
public:
DivSong song;
DivSystem sysOfChan[DIV_MAX_CHANS];
int dispatchOfChan[DIV_MAX_CHANS];
int dispatchChanOfChan[DIV_MAX_CHANS];
void runExportThread();
void nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size);
DivInstrument* getIns(int index);
@ -448,6 +449,12 @@ class DivEngine {
// set remaining loops. -1 means loop forever.
void setLoops(int loops);
// get channel state
DivChannelState* getChanState(int chan);
// get dispatch channel state
void* getDispatchChanState(int chan);
// set the audio system.
void setAudio(DivAudioEngines which);

View File

@ -1,3 +1,6 @@
#ifndef _ORDERS_H
#define _ORDERS_H
struct DivOrders {
unsigned char ord[DIV_MAX_CHANS][128];
@ -5,3 +8,5 @@ struct DivOrders {
memset(ord,0,DIV_MAX_CHANS*128);
}
};
#endif

View File

@ -6,6 +6,10 @@ void DivDispatch::acquire(short* bufL, short* bufR, size_t start, size_t len) {
void DivDispatch::tick() {
}
void* DivDispatch::getChanState(int chan) {
return NULL;
}
void* DivDispatch::getState() {
return NULL;
}

View File

@ -205,6 +205,10 @@ void DivPlatformAmiga::forceIns() {
}
}
void* DivPlatformAmiga::getChanState(int ch) {
return &chan[ch];
}
void DivPlatformAmiga::reset() {
for (int i=0; i<4; i++) {
chan[i]=DivPlatformAmiga::Channel();

View File

@ -45,9 +45,12 @@ class DivPlatformAmiga: public DivDispatch {
Channel chan[4];
bool isMuted[4];
friend void putDispatchChan(void*,int,int);
public:
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
void reset();
void forceIns();
void tick();

View File

@ -548,6 +548,10 @@ void DivPlatformArcade::notifyInsChange(int ins) {
}
}
void* DivPlatformArcade::getChanState(int ch) {
return &chan[ch];
}
void DivPlatformArcade::reset() {
while (!writes.empty()) writes.pop();
if (useYMFM) {

View File

@ -63,9 +63,12 @@ class DivPlatformArcade: public DivDispatch {
void acquire_nuked(short* bufL, short* bufR, size_t start, size_t len);
void acquire_ymfm(short* bufL, short* bufR, size_t start, size_t len);
friend void putDispatchChan(void*,int,int);
public:
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
void reset();
void forceIns();
void tick();

View File

@ -290,6 +290,10 @@ void DivPlatformAY8910::forceIns() {
immWrite(0x0d,ayEnvMode);
}
void* DivPlatformAY8910::getChanState(int ch) {
return &chan[ch];
}
void DivPlatformAY8910::reset() {
while (!writes.empty()) writes.pop();
ay->device_reset();

View File

@ -49,10 +49,13 @@ class DivPlatformAY8910: public DivDispatch {
short ayEnvSlide;
short* ayBuf[3];
size_t ayBufLen;
friend void putDispatchChan(void*,int,int);
public:
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
void reset();
void forceIns();
void tick();

View File

@ -328,6 +328,10 @@ void DivPlatformAY8930::forceIns() {
}
}
void* DivPlatformAY8930::getChanState(int ch) {
return &chan[ch];
}
void DivPlatformAY8930::reset() {
while (!writes.empty()) writes.pop();
ay->device_reset();

View File

@ -43,10 +43,13 @@ class DivPlatformAY8930: public DivDispatch {
short ayEnvSlide[3];
short* ayBuf[3];
size_t ayBufLen;
friend void putDispatchChan(void*,int,int);
public:
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
void reset();
void forceIns();
void tick();

View File

@ -327,6 +327,10 @@ void DivPlatformC64::notifyInsDeletion(void* ins) {
}
}
void* DivPlatformC64::getChanState(int ch) {
return &chan[ch];
}
void DivPlatformC64::reset() {
for (int i=0; i<3; i++) {
chan[i]=DivPlatformC64::Channel();

View File

@ -52,10 +52,13 @@ class DivPlatformC64: public DivDispatch {
SID sid;
friend void putDispatchChan(void*,int,int);
void updateFilter();
public:
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
void reset();
void forceIns();
void tick();

View File

@ -31,6 +31,10 @@ void DivPlatformDummy::tick() {
}
}
void* DivPlatformDummy::getChanState(int ch) {
return &chan[ch];
}
int DivPlatformDummy::dispatch(DivCommand c) {
switch (c.cmd) {
case DIV_CMD_NOTE_ON:

View File

@ -15,10 +15,12 @@ class DivPlatformDummy: public DivDispatch {
Channel chan[128];
bool isMuted[128];
unsigned char chans;
friend void putDispatchChan(void*,int,int);
public:
void acquire(short* bufL, short* bufR, size_t start, size_t len);
void muteChannel(int ch, bool mute);
int dispatch(DivCommand c);
void* getChanState(int chan);
void reset();
void tick();
int init(DivEngine* parent, int channels, int sugRate, bool pal);

View File

@ -301,6 +301,10 @@ void DivPlatformGB::forceIns() {
updateWave();
}
void* DivPlatformGB::getChanState(int ch) {
return &chan[ch];
}
void DivPlatformGB::reset() {
for (int i=0; i<4; i++) {
chan[i]=DivPlatformGB::Channel();

View File

@ -38,9 +38,11 @@ class DivPlatformGB: public DivDispatch {
GB_gameboy_t* gb;
unsigned char procMute();
void updateWave();
friend void putDispatchChan(void*,int,int);
public:
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
void reset();
void forceIns();
void tick();

View File

@ -567,6 +567,10 @@ void DivPlatformGenesis::toggleRegisterDump(bool enable) {
psg.toggleRegisterDump(enable);
}
void* DivPlatformGenesis::getChanState(int ch) {
return &chan[ch];
}
void DivPlatformGenesis::reset() {
while (!writes.empty()) writes.pop();
OPN2_Reset(&fm);

View File

@ -67,10 +67,13 @@ class DivPlatformGenesis: public DivDispatch {
int octave(int freq);
int toFreq(int freq);
friend void putDispatchChan(void*,int,int);
public:
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
void reset();
void forceIns();
void tick();

View File

@ -296,6 +296,12 @@ void DivPlatformGenesisExt::forceIns() {
}
}
void* DivPlatformGenesisExt::getChanState(int ch) {
if (ch>=6) return &chan[ch-3];
if (ch>=2) return &opChan[ch-2];
return &chan[ch];
}
void DivPlatformGenesisExt::reset() {
DivPlatformGenesis::reset();

View File

@ -16,8 +16,10 @@ class DivPlatformGenesisExt: public DivPlatformGenesis {
};
OpChannel opChan[4];
bool isOpMuted[4];
friend void putDispatchChan(void*,int,int);
public:
int dispatch(DivCommand c);
void* getChanState(int chan);
void reset();
void forceIns();
void tick();

View File

@ -344,6 +344,10 @@ void DivPlatformNES::forceIns() {
}
}
void* DivPlatformNES::getChanState(int ch) {
return &chan[ch];
}
void DivPlatformNES::reset() {
for (int i=0; i<5; i++) {
chan[i]=DivPlatformNES::Channel();

View File

@ -42,10 +42,12 @@ class DivPlatformNES: public DivDispatch {
struct NESAPU* nes;
float freqBase;
friend void putDispatchChan(void*,int,int);
public:
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
void reset();
void forceIns();
void tick();

View File

@ -340,6 +340,10 @@ void DivPlatformPCE::forceIns() {
}
}
void* DivPlatformPCE::getChanState(int ch) {
return &chan[ch];
}
void DivPlatformPCE::reset() {
while (!writes.empty()) writes.pop();
for (int i=0; i<6; i++) {

View File

@ -56,9 +56,11 @@ class DivPlatformPCE: public DivDispatch {
unsigned char sampleBank;
PCE_PSG* pce;
void updateWave(int ch);
friend void putDispatchChan(void*,int,int);
public:
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
void reset();
void forceIns();
void tick();

View File

@ -255,6 +255,10 @@ void DivPlatformSAA1099::forceIns() {
rWrite(0x16,saaNoise[0]|(saaNoise[1]<<4));
}
void* DivPlatformSAA1099::getChanState(int ch) {
return &chan[ch];
}
void DivPlatformSAA1099::reset() {
while (!writes.empty()) writes.pop();
saa=saa1099_device();

View File

@ -47,10 +47,12 @@ class DivPlatformSAA1099: public DivDispatch {
size_t saaBufLen;
unsigned char saaEnv[2];
unsigned char saaNoise[2];
friend void putDispatchChan(void*,int,int);
public:
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
void reset();
void forceIns();
void tick();

View File

@ -187,6 +187,10 @@ void DivPlatformSMS::forceIns() {
}
}
void* DivPlatformSMS::getChanState(int ch) {
return &chan[ch];
}
void DivPlatformSMS::reset() {
for (int i=0; i<4; i++) {
chan[i]=DivPlatformSMS::Channel();

View File

@ -31,10 +31,12 @@ class DivPlatformSMS: public DivDispatch {
unsigned char snNoiseMode;
bool updateSNMode;
sn76496_device* sn;
friend void putDispatchChan(void*,int,int);
public:
int acquireOne();
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
void reset();
void forceIns();
void tick();

View File

@ -228,6 +228,10 @@ void DivPlatformTIA::forceIns() {
}
}
void* DivPlatformTIA::getChanState(int ch) {
return &chan[ch];
}
void DivPlatformTIA::reset() {
tia.reset();
for (int i=0; i<2; i++) {

View File

@ -19,10 +19,12 @@ class DivPlatformTIA: public DivDispatch {
Channel chan[2];
bool isMuted[2];
TIASound tia;
friend void putDispatchChan(void*,int,int);
public:
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
void reset();
void forceIns();
void tick();

View File

@ -570,6 +570,10 @@ void DivPlatformYM2610::forceIns() {
immWrite(0x0d,ayEnvMode);
}
void* DivPlatformYM2610::getChanState(int ch) {
return &chan[ch];
}
void DivPlatformYM2610::reset() {
while (!writes.empty()) writes.pop();
if (dumpWrites) {

View File

@ -63,10 +63,12 @@ class DivPlatformYM2610: public DivDispatch {
int octave(int freq);
int toFreq(int freq);
friend void putDispatchChan(void*,int,int);
public:
void acquire(short* bufL, short* bufR, size_t start, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
void reset();
void forceIns();
void tick();

View File

@ -268,6 +268,13 @@ void DivPlatformYM2610Ext::forceIns() {
}
}
void* DivPlatformYM2610Ext::getChanState(int ch) {
if (ch>=5) return &chan[ch-3];
if (ch>=1) return &opChan[ch-1];
return &chan[ch];
}
void DivPlatformYM2610Ext::reset() {
DivPlatformYM2610::reset();

View File

@ -16,8 +16,10 @@ class DivPlatformYM2610Ext: public DivPlatformYM2610 {
};
OpChannel opChan[4];
bool isOpMuted[4];
friend void putDispatchChan(void*,int,int);
public:
int dispatch(DivCommand c);
void* getChanState(int chan);
void reset();
void forceIns();
void tick();

View File

@ -1,3 +1,5 @@
#ifndef _SONG_H
#define _SONG_H
#include <stdio.h>
#include <vector>
@ -158,3 +160,5 @@ struct DivSong {
system[0]=DIV_SYSTEM_GENESIS;
}
};
#endif

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();