From 7912a7982c31fc2752b835dd928c719890620be0 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 16 Sep 2023 18:15:03 -0500 Subject: [PATCH] implement a setting which was missing store/load ins names when saving .fui --- src/engine/engine.h | 2 +- src/engine/fileOpsIns.cpp | 7 ++++++- src/engine/instrument.cpp | 10 +++++----- src/engine/instrument.h | 5 +++-- src/gui/gui.cpp | 8 ++++---- src/gui/gui.h | 4 ++++ src/gui/settings.cpp | 26 ++++++++++++++++++++++++-- 7 files changed, 47 insertions(+), 15 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index 3f755e837..46b96ac57 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -903,7 +903,7 @@ class DivEngine { // get instrument from file // if the returned vector is empty then there was an error. - std::vector instrumentFromFile(const char* path, bool loadAssets=true); + std::vector instrumentFromFile(const char* path, bool loadAssets=true, bool readInsName=true); // load temporary instrument void loadTempIns(DivInstrument* which); diff --git a/src/engine/fileOpsIns.cpp b/src/engine/fileOpsIns.cpp index c23e437d3..0a7682735 100644 --- a/src/engine/fileOpsIns.cpp +++ b/src/engine/fileOpsIns.cpp @@ -1816,7 +1816,7 @@ void DivEngine::loadWOPN(SafeReader& reader, std::vector& ret, S } } -std::vector DivEngine::instrumentFromFile(const char* path, bool loadAssets) { +std::vector DivEngine::instrumentFromFile(const char* path, bool loadAssets, bool readInsName) { std::vector ret; warnings=""; @@ -1921,12 +1921,17 @@ std::vector DivEngine::instrumentFromFile(const char* path, bool reader.seek(dataPtr,SEEK_SET); } + ins->name=stripPath; + if (ins->readInsData(reader,version,loadAssets?(&song):NULL)!=DIV_DATA_SUCCESS) { lastError="invalid instrument header/data!"; delete ins; delete[] buf; return ret; } else { + if (!readInsName) { + ins->name=stripPath; + } ret.push_back(ins); } } catch (EndOfFileException& e) { diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index 28cb99bca..6b871155c 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -719,7 +719,7 @@ void DivInstrument::writeFeatureX1(SafeWriter* w) { FEATURE_END; } -void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song) { +void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bool insName) { size_t blockStartSeek=0; size_t blockEndSeek=0; size_t slSeek=0; @@ -1021,7 +1021,7 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song) { } // check ins name - if (!name.empty()) { + if (!name.empty() && insName) { featureNA=true; } @@ -3380,7 +3380,7 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version, DivS return readInsDataOld(reader,version); } -bool DivInstrument::save(const char* path, bool oldFormat, DivSong* song) { +bool DivInstrument::save(const char* path, bool oldFormat, DivSong* song, bool writeInsName) { SafeWriter* w=new SafeWriter(); w->init(); @@ -3397,14 +3397,14 @@ bool DivInstrument::save(const char* path, bool oldFormat, DivSong* song) { // pointer to data w->writeI(32); - // currently reserved (TODO; wavetable and sample here) + // reserved w->writeS(0); w->writeS(0); w->writeI(0); putInsData(w); } else { - putInsData2(w,true,song); + putInsData2(w,true,song,writeInsName); } FILE* outFile=ps_fopen(path,"wb"); diff --git a/src/engine/instrument.h b/src/engine/instrument.h index a019198f0..20172b7b8 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -720,7 +720,7 @@ struct DivInstrument { * save the instrument to a SafeWriter using new format. * @param w the SafeWriter in question. */ - void putInsData2(SafeWriter* w, bool fui=false, const DivSong* song=NULL); + void putInsData2(SafeWriter* w, bool fui=false, const DivSong* song=NULL, bool insName=true); /** * read instrument data in .fui format. @@ -735,9 +735,10 @@ struct DivInstrument { * @param path file path. * @param oldFormat whether to save in legacy Furnace ins format. * @param song if new format, a DivSong to read wavetables and samples. + * @param writeInsName whether to write the instrument name or not. ignored if old format. * @return whether it was successful. */ - bool save(const char* path, bool oldFormat=false, DivSong* song=NULL); + bool save(const char* path, bool oldFormat=false, DivSong* song=NULL, bool writeInsName=true); /** * save this instrument to a file in .dmp format. diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 9688a28b6..2e05e79de 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -3545,7 +3545,7 @@ bool FurnaceGUI::loop() { case SDL_DROPFILE: if (ev.drop.file!=NULL) { int sampleCountBefore=e->song.sampleLen; - std::vector instruments=e->instrumentFromFile(ev.drop.file); + std::vector instruments=e->instrumentFromFile(ev.drop.file,true,settings.readInsNames); DivWavetable* droppedWave=NULL; DivSample* droppedSample=NULL; if (!instruments.empty()) { @@ -4857,7 +4857,7 @@ bool FurnaceGUI::loop() { break; case GUI_FILE_INS_SAVE: if (curIns>=0 && curIns<(int)e->song.ins.size()) { - if (e->song.ins[curIns]->save(copyOfName.c_str(),false,&e->song)) { + if (e->song.ins[curIns]->save(copyOfName.c_str(),false,&e->song,settings.writeInsNames)) { pushRecentSys(copyOfName.c_str()); } } @@ -4983,7 +4983,7 @@ bool FurnaceGUI::loop() { String warns="there were some warnings/errors while loading instruments:\n"; int sampleCountBefore=e->song.sampleLen; for (String i: fileDialog->getFileName()) { - std::vector insTemp=e->instrumentFromFile(i.c_str()); + std::vector insTemp=e->instrumentFromFile(i.c_str(),true,settings.readInsNames); if (insTemp.empty()) { warn=true; warns+=fmt::sprintf("> %s: cannot load instrument! (%s)\n",i,e->getLastError()); @@ -5029,7 +5029,7 @@ bool FurnaceGUI::loop() { } case GUI_FILE_INS_OPEN_REPLACE: { int sampleCountBefore=e->song.sampleLen; - std::vector instruments=e->instrumentFromFile(copyOfName.c_str()); + std::vector instruments=e->instrumentFromFile(copyOfName.c_str(),true,settings.readInsNames); if (!instruments.empty()) { if (e->song.sampleLen!=sampleCountBefore) { e->renderSamplesP(); diff --git a/src/gui/gui.h b/src/gui/gui.h index 0d3ef9d33..c760354b8 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1591,6 +1591,8 @@ class FurnaceGUI { int chanOscThreads; int renderPoolThreads; int showPool; + int writeInsNames; + int readInsNames; unsigned int maxUndoSteps; String mainFontPath; String headFontPath; @@ -1771,6 +1773,8 @@ class FurnaceGUI { chanOscThreads(0), renderPoolThreads(0), showPool(0), + writeInsNames(1), + readInsNames(1), maxUndoSteps(100), mainFontPath(""), headFontPath(""), diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 37e21c0ae..062b76d0b 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -498,8 +498,24 @@ void FurnaceGUI::drawSettings() { } ImGui::Unindent(); - // SUBSECTION CHIP - CONFIG_SUBSECTION("Chip"); + bool writeInsNamesB=settings.writeInsNames; + if (ImGui::Checkbox("Store instrument name in .fui",&writeInsNamesB)) { + settings.writeInsNames=writeInsNamesB; + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("when enabled,saving an instrument will store its name.\nthis may increase file size."); + } + + bool readInsNamesB=settings.readInsNames; + if (ImGui::Checkbox("Load instrument name from .fui",&readInsNamesB)) { + settings.readInsNames=readInsNamesB; + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip("when enabled, loading an instrument will use the stored name (if present).\notherwise, it will use the file name."); + } + + // SUBSECTION NEW SONG + CONFIG_SUBSECTION("New Song"); ImGui::AlignTextToFramePadding(); ImGui::Text("Initial system:"); ImGui::SameLine(); @@ -3341,6 +3357,8 @@ void FurnaceGUI::syncSettings() { settings.chanOscThreads=e->getConfInt("chanOscThreads",0); settings.renderPoolThreads=e->getConfInt("renderPoolThreads",0); settings.showPool=e->getConfInt("showPool",0); + settings.writeInsNames=e->getConfInt("writeInsNames",1); + settings.readInsNames=e->getConfInt("readInsNames",1); clampSetting(settings.mainFontSize,2,96); clampSetting(settings.headFontSize,2,96); @@ -3494,6 +3512,8 @@ void FurnaceGUI::syncSettings() { clampSetting(settings.chanOscThreads,0,256); clampSetting(settings.renderPoolThreads,0,DIV_MAX_CHIPS); clampSetting(settings.showPool,0,1); + clampSetting(settings.writeInsNames,0,1); + clampSetting(settings.readInsNames,0,1); if (settings.exportLoops<0.0) settings.exportLoops=0.0; if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0; @@ -3755,6 +3775,8 @@ void FurnaceGUI::commitSettings() { e->setConf("chanOscThreads",settings.chanOscThreads); e->setConf("renderPoolThreads",settings.renderPoolThreads); e->setConf("showPool",settings.showPool); + e->setConf("writeInsNames",settings.writeInsNames); + e->setConf("readInsNames",settings.readInsNames); // colors for (int i=0; i