diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 5bbcff1eb..ad25b6eea 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -883,6 +883,119 @@ void DivEngine::clearSubSongs() { BUSY_END; } +void DivEngine::delUnusedIns() { + BUSY_BEGIN; + saveLock.lock(); + + bool isUsed[256]; + memset(isUsed,0,256*sizeof(bool)); + + // scan + for (int i=0; ipat[i].data[k]==NULL) continue; + for (int l=0; lpatLen; l++) { + if (song.subsong[j]->pat[i].data[k]->data[l][2]>=0 && song.subsong[j]->pat[i].data[k]->data[l][2]<256) { + isUsed[song.subsong[j]->pat[i].data[k]->data[l][2]]=true; + } + } + } + } + } + + // delete + for (int i=0; itype==DIV_INS_PCE && i->amiga.useSample) || + i->type==DIV_INS_MSM6258 || + i->type==DIV_INS_MSM6295 || + i->type==DIV_INS_ADPCMA || + i->type==DIV_INS_ADPCMB || + i->type==DIV_INS_SEGAPCM || + i->type==DIV_INS_QSOUND || + i->type==DIV_INS_YMZ280B || + i->type==DIV_INS_RF5C68 || + i->type==DIV_INS_AMIGA || + i->type==DIV_INS_MULTIPCM || + (i->type==DIV_INS_MIKEY && i->amiga.useSample) || + (i->type==DIV_INS_X1_010 && i->amiga.useSample) || + (i->type==DIV_INS_SWAN && i->amiga.useSample) || + (i->type==DIV_INS_AY && i->amiga.useSample) || + (i->type==DIV_INS_AY8930 && i->amiga.useSample) || + (i->type==DIV_INS_VRC6 && i->amiga.useSample) || + (i->type==DIV_INS_SU && i->amiga.useSample) || + i->type==DIV_INS_SNES || + i->type==DIV_INS_ES5506 || + i->type==DIV_INS_K007232 || + i->type==DIV_INS_GA20 || + i->type==DIV_INS_K053260 || + i->type==DIV_INS_C140 || + i->type==DIV_INS_C219) { + if (i->amiga.initSample>=0 && i->amiga.initSampleamiga.initSample]=true; + } + if (i->amiga.useNoteMap) { + for (int j=0; j<120; j++) { + if (i->amiga.noteMap[j].map>=0 && i->amiga.noteMap[j].mapamiga.noteMap[j].map]=true; + } + } + } + } + } + + // delete + for (int i=0; i=0 && index<(int)song.ins.size()) { for (int i=0; inotifyInsDeletion(song.ins[index]); @@ -2264,6 +2375,12 @@ void DivEngine::delInstrument(int index) { removeAsset(song.insDir,index); checkAssetDir(song.insDir,song.ins.size()); } +} + +void DivEngine::delInstrument(int index) { + BUSY_BEGIN; + saveLock.lock(); + delInstrumentUnsafe(index); saveLock.unlock(); BUSY_END; } @@ -2444,9 +2561,7 @@ DivWavetable* DivEngine::waveFromFile(const char* path, bool addRaw) { return wave; } -void DivEngine::delWave(int index) { - BUSY_BEGIN; - saveLock.lock(); +void DivEngine::delWaveUnsafe(int index) { if (index>=0 && index<(int)song.wave.size()) { delete song.wave[index]; song.wave.erase(song.wave.begin()+index); @@ -2454,6 +2569,12 @@ void DivEngine::delWave(int index) { removeAsset(song.waveDir,index); checkAssetDir(song.waveDir,song.wave.size()); } +} + +void DivEngine::delWave(int index) { + BUSY_BEGIN; + saveLock.lock(); + delWaveUnsafe(index); saveLock.unlock(); BUSY_END; } @@ -2498,12 +2619,10 @@ int DivEngine::addSamplePtr(DivSample* which) { return sampleCount; } -void DivEngine::delSample(int index) { - BUSY_BEGIN; +void DivEngine::delSampleUnsafe(int index, bool render) { sPreview.sample=-1; sPreview.pos=0; sPreview.dir=false; - saveLock.lock(); if (index>=0 && index<(int)song.sample.size()) { delete song.sample[index]; song.sample.erase(song.sample.begin()+index); @@ -2527,8 +2646,14 @@ void DivEngine::delSample(int index) { } } - renderSamples(); + if (render) renderSamples(); } +} + +void DivEngine::delSample(int index) { + BUSY_BEGIN; + saveLock.lock(); + delSampleUnsafe(index); saveLock.unlock(); BUSY_END; } diff --git a/src/engine/engine.h b/src/engine/engine.h index c1b760bdf..914a207dd 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -889,6 +889,7 @@ class DivEngine { // delete instrument void delInstrument(int index); + void delInstrumentUnsafe(int index); // add wavetable int addWave(); @@ -901,6 +902,7 @@ class DivEngine { // delete wavetable void delWave(int index); + void delWaveUnsafe(int index); // add sample int addSample(); @@ -916,6 +918,7 @@ class DivEngine { // delete sample void delSample(int index); + void delSampleUnsafe(int index, bool render=true); // add order void addOrder(int pos, bool duplicate, bool where); @@ -1095,6 +1098,11 @@ class DivEngine { // clear all subsong data void clearSubSongs(); + // optimize assets + void delUnusedIns(); + void delUnusedWaves(); + void delUnusedSamples(); + // change system void changeSystem(int index, DivSystem which, bool preserveOrder=true); diff --git a/src/gui/doAction.cpp b/src/gui/doAction.cpp index ebb26cac9..6edfa694d 100644 --- a/src/gui/doAction.cpp +++ b/src/gui/doAction.cpp @@ -183,7 +183,7 @@ void FurnaceGUI::doAction(int what) { e->syncReset(); break; case GUI_ACTION_CLEAR: - showWarning("Are you sure you want to clear... (cannot be undone!)",GUI_WARN_CLEAR); + showWarning("Select an option: (cannot be undone!)",GUI_WARN_CLEAR); break; case GUI_ACTION_WINDOW_EDIT_CONTROLS: diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 176e99a02..af2d4458c 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -5521,90 +5521,144 @@ bool FurnaceGUI::loop() { } break; case GUI_WARN_CLEAR: - if (ImGui::Button("All subsongs")) { - stop(); - e->clearSubSongs(); - curOrder=0; - oldOrder=0; - oldOrder1=0; - MARK_MODIFIED; - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::Button("Current subsong")) { - stop(); - e->lockEngine([this]() { - e->curSubSong->clearData(); - }); - e->setOrder(0); - curOrder=0; - oldOrder=0; - oldOrder1=0; - MARK_MODIFIED; - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::Button("Orders")) { - stop(); - e->lockEngine([this]() { - memset(e->curOrders->ord,0,DIV_MAX_CHANS*DIV_MAX_PATTERNS); - e->curSubSong->ordersLen=1; - }); - e->setOrder(0); - curOrder=0; - oldOrder=0; - oldOrder1=0; - MARK_MODIFIED; - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::Button("Pattern")) { - stop(); - e->lockEngine([this]() { - for (int i=0; igetTotalChannelCount(); i++) { - DivPattern* pat=e->curPat[i].getPattern(e->curOrders->ord[i][curOrder],true); - memset(pat->data,-1,DIV_MAX_ROWS*DIV_MAX_COLS*sizeof(short)); - for (int j=0; jdata[j][0]=0; - pat->data[j][1]=0; + if (ImGui::BeginTable("EraseOpt",2,ImGuiTableFlags_BordersInnerV)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.5f); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.5f); + ImGui::TableNextRow(); + + ImGui::TableNextColumn(); + ImGui::PushFont(headFont); + ImGui::AlignTextToFramePadding(); + ImGui::Text("Erasing"); + ImGui::PopFont(); + + if (ImGui::Button("All subsongs")) { + stop(); + e->clearSubSongs(); + curOrder=0; + oldOrder=0; + oldOrder1=0; + MARK_MODIFIED; + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Current subsong")) { + stop(); + e->lockEngine([this]() { + e->curSubSong->clearData(); + }); + e->setOrder(0); + curOrder=0; + oldOrder=0; + oldOrder1=0; + MARK_MODIFIED; + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Orders")) { + stop(); + e->lockEngine([this]() { + memset(e->curOrders->ord,0,DIV_MAX_CHANS*DIV_MAX_PATTERNS); + e->curSubSong->ordersLen=1; + }); + e->setOrder(0); + curOrder=0; + oldOrder=0; + oldOrder1=0; + MARK_MODIFIED; + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Pattern")) { + stop(); + e->lockEngine([this]() { + for (int i=0; igetTotalChannelCount(); i++) { + DivPattern* pat=e->curPat[i].getPattern(e->curOrders->ord[i][curOrder],true); + memset(pat->data,-1,DIV_MAX_ROWS*DIV_MAX_COLS*sizeof(short)); + for (int j=0; jdata[j][0]=0; + pat->data[j][1]=0; + } } - } - }); - MARK_MODIFIED; - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::Button("Instruments")) { - stop(); - e->lockEngine([this]() { - e->song.clearInstruments(); - }); - curIns=-1; - MARK_MODIFIED; - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::Button("Wavetables")) { - stop(); - e->lockEngine([this]() { - e->song.clearWavetables(); - }); - curWave=0; - MARK_MODIFIED; - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - if (ImGui::Button("Samples")) { - stop(); - e->lockEngine([this]() { - e->song.clearSamples(); - }); - curSample=0; - ImGui::CloseCurrentPopup(); + }); + MARK_MODIFIED; + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Instruments")) { + stop(); + e->lockEngine([this]() { + e->song.clearInstruments(); + }); + curIns=-1; + MARK_MODIFIED; + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Wavetables")) { + stop(); + e->lockEngine([this]() { + e->song.clearWavetables(); + }); + curWave=0; + MARK_MODIFIED; + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Samples")) { + stop(); + e->lockEngine([this]() { + e->song.clearSamples(); + }); + curSample=0; + MARK_MODIFIED; + ImGui::CloseCurrentPopup(); + } + + ImGui::TableNextColumn(); + ImGui::PushFont(headFont); + ImGui::AlignTextToFramePadding(); + ImGui::Text("Optimization"); + ImGui::PopFont(); + + if (ImGui::Button("De-duplicate patterns")) { + stop(); + e->lockEngine([this]() { + e->curSubSong->optimizePatterns(); + e->curSubSong->rearrangePatterns(); + }); + MARK_MODIFIED; + ImGui::CloseCurrentPopup(); + } + if (ImGui::Button("Remove unused instruments")) { + stop(); + e->delUnusedIns(); + MARK_MODIFIED; + ImGui::CloseCurrentPopup(); + } + /* + if (ImGui::Button("Remove unused wavetables")) { + stop(); + e->delUnusedWaves(); + MARK_MODIFIED; + ImGui::CloseCurrentPopup(); + }*/ + if (ImGui::Button("Remove unused samples")) { + stop(); + e->delUnusedSamples(); + MARK_MODIFIED; + ImGui::CloseCurrentPopup(); + } + + ImGui::EndTable(); } - if (ImGui::Button("Wait! What am I doing? Cancel!") || ImGui::IsKeyPressed(ImGuiKey_Escape)) { - ImGui::CloseCurrentPopup(); + if (ImGui::BeginTable("EraseOptFooter",3)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.5f); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch,0.5f); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::TableNextColumn(); + if (ImGui::Button("Never mind! Cancel") || ImGui::IsKeyPressed(ImGuiKey_Escape)) { + ImGui::CloseCurrentPopup(); + } + ImGui::TableNextColumn(); + ImGui::EndTable(); } break; case GUI_WARN_SUBSONG_DEL: