From 3379e8b3804a59029b4319ce07c4587eaee996d5 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 3 Feb 2022 00:34:48 -0500 Subject: [PATCH] prepare for compat flags, piano, comments, etc. --- src/engine/engine.cpp | 29 +++++++++++++--- src/engine/engine.h | 4 +-- src/engine/song.h | 11 ++++-- src/gui/gui.cpp | 81 +++++++++++++++++++++++++++++++++++++++++++ src/gui/gui.h | 7 +++- 5 files changed, 123 insertions(+), 9 deletions(-) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 7781aa237..ae1396f90 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1537,6 +1537,11 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { logI("%s by %s\n",ds.name.c_str(),ds.author.c_str()); } + // compatibility flags + ds.limitSlides=true; + ds.linearPitch=true; + ds.loopModality=0; + logI("reading module data...\n"); if (ds.version>0x0c) { ds.hilightA=reader.readC(); @@ -2057,6 +2062,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { addWarning("this module was created with a more recent version of Furnace!"); } + if (ds.version<37) { // compat flags not stored back then + ds.limitSlides=true; + ds.linearPitch=true; + ds.loopModality=0; + } + reader.readS(); // reserved int infoSeek=reader.readI(); @@ -2122,8 +2133,15 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { reader.readI(); } - // reserved - for (int i=0; i<20; i++) reader.readC(); + // compatibility flags + if (ds.version>=37) { + ds.limitSlides=reader.readC(); + ds.linearPitch=reader.readC(); + ds.loopModality=reader.readC(); + for (int i=0; i<17; i++) reader.readC(); + } else { + for (int i=0; i<20; i++) reader.readC(); + } // pointers reader.read(insPtr,ds.insLen*4); @@ -2469,8 +2487,11 @@ SafeWriter* DivEngine::saveFur() { w->writeF(song.tuning); - // reserved - for (int i=0; i<20; i++) { + // compatibility flags + w->writeC(song.limitSlides); + w->writeC(song.linearPitch); + w->writeC(song.loopModality); + for (int i=0; i<17; i++) { w->writeC(0); } diff --git a/src/engine/engine.h b/src/engine/engine.h index a8fe7d045..b41f759b2 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -11,8 +11,8 @@ #include #include -#define DIV_VERSION "0.5.1" -#define DIV_ENGINE_VERSION 36 +#define DIV_VERSION "0.5.2pre1" +#define DIV_ENGINE_VERSION 37 enum DivStatusView { DIV_STATUS_NOTHING=0, diff --git a/src/engine/song.h b/src/engine/song.h index 7aabb0053..fdd189732 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -201,7 +201,12 @@ struct DivSong { // compatibility flags bool limitSlides; // limit slide range - bool nonLinearSlides; // E5xx behavior control + bool linearPitch; // E5xx behavior control + // loop behavior + // 0: reset on loop + // 1: fake reset on loop + // 2: don't do anything on loop + unsigned char loopModality; DivOrders orders; std::vector ins; @@ -245,7 +250,9 @@ struct DivSong { waveLen(0), sampleLen(0), tuning(440.0f), - limitSlides(false) { + limitSlides(false), + linearPitch(true), + loopModality(0) { for (int i=0; i<32; i++) { system[i]=DIV_SYSTEM_NULL; systemVol[i]=64; diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 70045201d..a1478faee 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -3360,6 +3360,67 @@ void FurnaceGUI::drawDebug() { ImGui::End(); } +void FurnaceGUI::drawStats() { + if (!statsOpen) return; + if (ImGui::Begin("Statistics",&statsOpen)) { + String adpcmUsage=fmt::sprintf("%d/16384KB",e->adpcmMemLen/1024); + String adpcmBUsage=fmt::sprintf("%d/16384KB",e->adpcmBMemLen/1024); + ImGui::Text("ADPCM-A"); + ImGui::SameLine(); + ImGui::ProgressBar(((float)e->adpcmMemLen)/16777216.0f,ImVec2(-FLT_MIN,0),adpcmUsage.c_str()); + ImGui::Text("ADPCM-B"); + ImGui::SameLine(); + ImGui::ProgressBar(((float)e->adpcmBMemLen)/16777216.0f,ImVec2(-FLT_MIN,0),adpcmBUsage.c_str()); + } + ImGui::End(); +} + +void FurnaceGUI::drawCompatFlags() { + if (!compatFlagsOpen) return; + if (ImGui::Begin("Compatibility Flags",&compatFlagsOpen)) { + ImGui::TextWrapped("these flags are stored in the song when saving in .fur format, and are automatically enabled when saving in .dmf format."); + ImGui::Checkbox("Limit slide range",&e->song.limitSlides); + ImGui::Checkbox("Linear pitch control",&e->song.linearPitch); + ImGui::Text("Loop modality:"); + if (ImGui::RadioButton("Reset channels",e->song.loopModality==0)) { + e->song.loopModality=0; + } + if (ImGui::RadioButton("Soft reset channels",e->song.loopModality==1)) { + e->song.loopModality=1; + } + if (ImGui::RadioButton("Do nothing",e->song.loopModality==2)) { + e->song.loopModality=2; + } + } + ImGui::End(); +} + +void FurnaceGUI::drawPiano() { + if (!pianoOpen) return; + if (ImGui::Begin("Piano",&pianoOpen)) { + for (int i=0; igetTotalChannelCount(); i++) { + DivChannelState* cs=e->getChanState(i); + if (cs->keyOn) { + const char* noteName=NULL; + if (cs->note<-60 || cs->note>120) { + noteName="???"; + } else { + noteName=noteNames[cs->note+60]; + } + ImGui::Text("%d: %s",i,noteName); + } + } + } + ImGui::End(); +} + +void FurnaceGUI::drawNotes() { + if (!notesOpen) return; + if (ImGui::Begin("Song Comments",¬esOpen)) { + } + ImGui::End(); +} + void FurnaceGUI::startSelection(int xCoarse, int xFine, int y) { if (xCoarse!=selStart.xCoarse || xFine!=selStart.xFine || y!=selStart.y) { curNibble=false; @@ -5179,6 +5240,10 @@ bool FurnaceGUI::loop() { if (ImGui::MenuItem("mixer")) mixerOpen=!mixerOpen; if (ImGui::MenuItem("oscilloscope")) oscOpen=!oscOpen; if (ImGui::MenuItem("volume meter")) volMeterOpen=!volMeterOpen; + if (ImGui::MenuItem("statistics")) statsOpen=!statsOpen; + if (ImGui::MenuItem("compatibility flags")) compatFlagsOpen=!compatFlagsOpen; + if (ImGui::MenuItem("piano/input pad")) pianoOpen=!pianoOpen; + if (ImGui::MenuItem("song comments")) notesOpen=!notesOpen; ImGui::EndMenu(); } if (ImGui::BeginMenu("help")) { @@ -5221,6 +5286,10 @@ bool FurnaceGUI::loop() { drawPattern(); drawSettings(); drawDebug(); + drawStats(); + drawCompatFlags(); + drawPiano(); + drawNotes(); if (ImGuiFileDialog::Instance()->Display("FileDialog",ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove,ImVec2(600.0f*dpiScale,400.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale))) { //ImGui::GetIO().ConfigFlags&=~ImGuiConfigFlags_NavEnableKeyboard; @@ -5729,6 +5798,10 @@ bool FurnaceGUI::init() { mixerOpen=e->getConfBool("mixerOpen",false); oscOpen=e->getConfBool("oscOpen",true); volMeterOpen=e->getConfBool("volMeterOpen",true); + statsOpen=e->getConfBool("statsOpen",false); + compatFlagsOpen=e->getConfBool("compatFlagsOpen",false); + pianoOpen=e->getConfBool("pianoOpen",false); + notesOpen=e->getConfBool("notesOpen",false); syncSettings(); @@ -5834,6 +5907,10 @@ bool FurnaceGUI::finish() { e->setConf("mixerOpen",mixerOpen); e->setConf("oscOpen",oscOpen); e->setConf("volMeterOpen",volMeterOpen); + e->setConf("statsOpen",statsOpen); + e->setConf("compatFlagsOpen",compatFlagsOpen); + e->setConf("pianoOpen",pianoOpen); + e->setConf("notesOpen",notesOpen); // commit last window size e->setConf("lastWindowWidth",scrW); @@ -5896,6 +5973,10 @@ FurnaceGUI::FurnaceGUI(): debugOpen(false), oscOpen(true), volMeterOpen(true), + statsOpen(false), + compatFlagsOpen(false), + pianoOpen(false), + notesOpen(false), selecting(false), curNibble(false), orderNibble(false), diff --git a/src/gui/gui.h b/src/gui/gui.h index d4783bf61..17ea87b69 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -252,7 +252,8 @@ class FurnaceGUI { int loopOrder, loopRow, loopEnd, isClipping; bool editControlsOpen, ordersOpen, insListOpen, songInfoOpen, patternOpen, insEditOpen; bool waveListOpen, waveEditOpen, sampleListOpen, sampleEditOpen, aboutOpen, settingsOpen; - bool mixerOpen, debugOpen, oscOpen, volMeterOpen; + bool mixerOpen, debugOpen, oscOpen, volMeterOpen, statsOpen, compatFlagsOpen; + bool pianoOpen, notesOpen; SelectionPoint selStart, selEnd, cursor; bool selecting, curNibble, orderNibble, extraChannelButtons, followOrders, followPattern, changeAllOrders; FurnaceGUIWindows curWindow; @@ -337,6 +338,10 @@ class FurnaceGUI { void drawMixer(); void drawOsc(); void drawVolMeter(); + void drawStats(); + void drawCompatFlags(); + void drawPiano(); + void drawNotes(); void drawAbout(); void drawSettings(); void drawDebug();