GUI: improve "clear..." menu

This commit is contained in:
tildearrow 2023-09-08 02:52:15 -05:00
parent ff06ad67bd
commit 5209074c97
4 changed files with 279 additions and 92 deletions

View file

@ -883,6 +883,119 @@ void DivEngine::clearSubSongs() {
BUSY_END; BUSY_END;
} }
void DivEngine::delUnusedIns() {
BUSY_BEGIN;
saveLock.lock();
bool isUsed[256];
memset(isUsed,0,256*sizeof(bool));
// scan
for (int i=0; i<chans; i++) {
for (size_t j=0; j<song.subsong.size(); j++) {
for (int k=0; k<DIV_MAX_PATTERNS; k++) {
if (song.subsong[j]->pat[i].data[k]==NULL) continue;
for (int l=0; l<song.subsong[j]->patLen; 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; i<song.insLen; i++) {
if (!isUsed[i]) {
delInstrumentUnsafe(i);
// rotate
for (int j=i; j<255; j++) {
isUsed[j]=isUsed[j+1];
}
isUsed[255]=true;
i--;
}
}
saveLock.unlock();
BUSY_END;
}
void DivEngine::delUnusedWaves() {
BUSY_BEGIN;
saveLock.lock();
saveLock.unlock();
BUSY_END;
}
void DivEngine::delUnusedSamples() {
BUSY_BEGIN;
saveLock.lock();
bool isUsed[256];
memset(isUsed,0,256*sizeof(bool));
// scan
for (DivInstrument* i: song.ins) {
if ((i->type==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.initSample<song.sampleLen) {
isUsed[i->amiga.initSample]=true;
}
if (i->amiga.useNoteMap) {
for (int j=0; j<120; j++) {
if (i->amiga.noteMap[j].map>=0 && i->amiga.noteMap[j].map<song.sampleLen) {
isUsed[i->amiga.noteMap[j].map]=true;
}
}
}
}
}
// delete
for (int i=0; i<song.sampleLen; i++) {
if (!isUsed[i]) {
delSampleUnsafe(i,false);
// rotate
for (int j=i; j<255; j++) {
isUsed[j]=isUsed[j+1];
}
isUsed[255]=true;
i--;
}
}
// render
renderSamples();
saveLock.unlock();
BUSY_END;
}
void DivEngine::changeSystem(int index, DivSystem which, bool preserveOrder) { void DivEngine::changeSystem(int index, DivSystem which, bool preserveOrder) {
int chanCount=chans; int chanCount=chans;
quitDispatch(); quitDispatch();
@ -2239,9 +2352,7 @@ void DivEngine::loadTempIns(DivInstrument* which) {
BUSY_END; BUSY_END;
} }
void DivEngine::delInstrument(int index) { void DivEngine::delInstrumentUnsafe(int index) {
BUSY_BEGIN;
saveLock.lock();
if (index>=0 && index<(int)song.ins.size()) { if (index>=0 && index<(int)song.ins.size()) {
for (int i=0; i<song.systemLen; i++) { for (int i=0; i<song.systemLen; i++) {
disCont[i].dispatch->notifyInsDeletion(song.ins[index]); disCont[i].dispatch->notifyInsDeletion(song.ins[index]);
@ -2264,6 +2375,12 @@ void DivEngine::delInstrument(int index) {
removeAsset(song.insDir,index); removeAsset(song.insDir,index);
checkAssetDir(song.insDir,song.ins.size()); checkAssetDir(song.insDir,song.ins.size());
} }
}
void DivEngine::delInstrument(int index) {
BUSY_BEGIN;
saveLock.lock();
delInstrumentUnsafe(index);
saveLock.unlock(); saveLock.unlock();
BUSY_END; BUSY_END;
} }
@ -2444,9 +2561,7 @@ DivWavetable* DivEngine::waveFromFile(const char* path, bool addRaw) {
return wave; return wave;
} }
void DivEngine::delWave(int index) { void DivEngine::delWaveUnsafe(int index) {
BUSY_BEGIN;
saveLock.lock();
if (index>=0 && index<(int)song.wave.size()) { if (index>=0 && index<(int)song.wave.size()) {
delete song.wave[index]; delete song.wave[index];
song.wave.erase(song.wave.begin()+index); song.wave.erase(song.wave.begin()+index);
@ -2454,6 +2569,12 @@ void DivEngine::delWave(int index) {
removeAsset(song.waveDir,index); removeAsset(song.waveDir,index);
checkAssetDir(song.waveDir,song.wave.size()); checkAssetDir(song.waveDir,song.wave.size());
} }
}
void DivEngine::delWave(int index) {
BUSY_BEGIN;
saveLock.lock();
delWaveUnsafe(index);
saveLock.unlock(); saveLock.unlock();
BUSY_END; BUSY_END;
} }
@ -2498,12 +2619,10 @@ int DivEngine::addSamplePtr(DivSample* which) {
return sampleCount; return sampleCount;
} }
void DivEngine::delSample(int index) { void DivEngine::delSampleUnsafe(int index, bool render) {
BUSY_BEGIN;
sPreview.sample=-1; sPreview.sample=-1;
sPreview.pos=0; sPreview.pos=0;
sPreview.dir=false; sPreview.dir=false;
saveLock.lock();
if (index>=0 && index<(int)song.sample.size()) { if (index>=0 && index<(int)song.sample.size()) {
delete song.sample[index]; delete song.sample[index];
song.sample.erase(song.sample.begin()+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(); saveLock.unlock();
BUSY_END; BUSY_END;
} }

View file

@ -889,6 +889,7 @@ class DivEngine {
// delete instrument // delete instrument
void delInstrument(int index); void delInstrument(int index);
void delInstrumentUnsafe(int index);
// add wavetable // add wavetable
int addWave(); int addWave();
@ -901,6 +902,7 @@ class DivEngine {
// delete wavetable // delete wavetable
void delWave(int index); void delWave(int index);
void delWaveUnsafe(int index);
// add sample // add sample
int addSample(); int addSample();
@ -916,6 +918,7 @@ class DivEngine {
// delete sample // delete sample
void delSample(int index); void delSample(int index);
void delSampleUnsafe(int index, bool render=true);
// add order // add order
void addOrder(int pos, bool duplicate, bool where); void addOrder(int pos, bool duplicate, bool where);
@ -1095,6 +1098,11 @@ class DivEngine {
// clear all subsong data // clear all subsong data
void clearSubSongs(); void clearSubSongs();
// optimize assets
void delUnusedIns();
void delUnusedWaves();
void delUnusedSamples();
// change system // change system
void changeSystem(int index, DivSystem which, bool preserveOrder=true); void changeSystem(int index, DivSystem which, bool preserveOrder=true);

View file

@ -183,7 +183,7 @@ void FurnaceGUI::doAction(int what) {
e->syncReset(); e->syncReset();
break; break;
case GUI_ACTION_CLEAR: 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; break;
case GUI_ACTION_WINDOW_EDIT_CONTROLS: case GUI_ACTION_WINDOW_EDIT_CONTROLS:

View file

@ -5521,90 +5521,144 @@ bool FurnaceGUI::loop() {
} }
break; break;
case GUI_WARN_CLEAR: case GUI_WARN_CLEAR:
if (ImGui::Button("All subsongs")) { if (ImGui::BeginTable("EraseOpt",2,ImGuiTableFlags_BordersInnerV)) {
stop(); ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch,0.5f);
e->clearSubSongs(); ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch,0.5f);
curOrder=0; ImGui::TableNextRow();
oldOrder=0;
oldOrder1=0; ImGui::TableNextColumn();
MARK_MODIFIED; ImGui::PushFont(headFont);
ImGui::CloseCurrentPopup(); ImGui::AlignTextToFramePadding();
} ImGui::Text("Erasing");
ImGui::SameLine(); ImGui::PopFont();
if (ImGui::Button("Current subsong")) {
stop(); if (ImGui::Button("All subsongs")) {
e->lockEngine([this]() { stop();
e->curSubSong->clearData(); e->clearSubSongs();
}); curOrder=0;
e->setOrder(0); oldOrder=0;
curOrder=0; oldOrder1=0;
oldOrder=0; MARK_MODIFIED;
oldOrder1=0; ImGui::CloseCurrentPopup();
MARK_MODIFIED; }
ImGui::CloseCurrentPopup(); if (ImGui::Button("Current subsong")) {
} stop();
ImGui::SameLine(); e->lockEngine([this]() {
if (ImGui::Button("Orders")) { e->curSubSong->clearData();
stop(); });
e->lockEngine([this]() { e->setOrder(0);
memset(e->curOrders->ord,0,DIV_MAX_CHANS*DIV_MAX_PATTERNS); curOrder=0;
e->curSubSong->ordersLen=1; oldOrder=0;
}); oldOrder1=0;
e->setOrder(0); MARK_MODIFIED;
curOrder=0; ImGui::CloseCurrentPopup();
oldOrder=0; }
oldOrder1=0; if (ImGui::Button("Orders")) {
MARK_MODIFIED; stop();
ImGui::CloseCurrentPopup(); e->lockEngine([this]() {
} memset(e->curOrders->ord,0,DIV_MAX_CHANS*DIV_MAX_PATTERNS);
ImGui::SameLine(); e->curSubSong->ordersLen=1;
if (ImGui::Button("Pattern")) { });
stop(); e->setOrder(0);
e->lockEngine([this]() { curOrder=0;
for (int i=0; i<e->getTotalChannelCount(); i++) { oldOrder=0;
DivPattern* pat=e->curPat[i].getPattern(e->curOrders->ord[i][curOrder],true); oldOrder1=0;
memset(pat->data,-1,DIV_MAX_ROWS*DIV_MAX_COLS*sizeof(short)); MARK_MODIFIED;
for (int j=0; j<DIV_MAX_ROWS; j++) { ImGui::CloseCurrentPopup();
pat->data[j][0]=0; }
pat->data[j][1]=0; if (ImGui::Button("Pattern")) {
stop();
e->lockEngine([this]() {
for (int i=0; i<e->getTotalChannelCount(); 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; j<DIV_MAX_ROWS; j++) {
pat->data[j][0]=0;
pat->data[j][1]=0;
}
} }
} });
}); MARK_MODIFIED;
MARK_MODIFIED; ImGui::CloseCurrentPopup();
ImGui::CloseCurrentPopup(); }
} if (ImGui::Button("Instruments")) {
ImGui::SameLine(); stop();
if (ImGui::Button("Instruments")) { e->lockEngine([this]() {
stop(); e->song.clearInstruments();
e->lockEngine([this]() { });
e->song.clearInstruments(); curIns=-1;
}); MARK_MODIFIED;
curIns=-1; ImGui::CloseCurrentPopup();
MARK_MODIFIED; }
ImGui::CloseCurrentPopup(); if (ImGui::Button("Wavetables")) {
} stop();
ImGui::SameLine(); e->lockEngine([this]() {
if (ImGui::Button("Wavetables")) { e->song.clearWavetables();
stop(); });
e->lockEngine([this]() { curWave=0;
e->song.clearWavetables(); MARK_MODIFIED;
}); ImGui::CloseCurrentPopup();
curWave=0; }
MARK_MODIFIED; if (ImGui::Button("Samples")) {
ImGui::CloseCurrentPopup(); stop();
} e->lockEngine([this]() {
ImGui::SameLine(); e->song.clearSamples();
if (ImGui::Button("Samples")) { });
stop(); curSample=0;
e->lockEngine([this]() { MARK_MODIFIED;
e->song.clearSamples(); ImGui::CloseCurrentPopup();
}); }
curSample=0;
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)) { if (ImGui::BeginTable("EraseOptFooter",3)) {
ImGui::CloseCurrentPopup(); 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; break;
case GUI_WARN_SUBSONG_DEL: case GUI_WARN_SUBSONG_DEL: