From ecd3875a64e03e00ecc09e06412b757077d0aeef Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 22 Feb 2024 12:48:16 -0500 Subject: [PATCH] ... --- src/engine/engine.cpp | 59 +++++++++++++++++++++++++++++------------- src/engine/engine.h | 2 ++ src/gui/gui.cpp | 1 + src/gui/gui.h | 2 +- src/gui/sysManager.cpp | 4 ++- 5 files changed, 48 insertions(+), 20 deletions(-) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index d859c7961..fec69a3f6 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1190,6 +1190,25 @@ bool DivEngine::duplicateSystem(int index, bool pat, bool end) { renderSamples(); reset(); BUSY_END; + + if (!end) { + quitDispatch(); + BUSY_BEGIN; + saveLock.lock(); + + for (int i=song.systemLen-1; i>index; i--) { + swapSystemUnsafe(i,i-1,false); + } + + recalcChans(); + saveLock.unlock(); + BUSY_END; + initDispatch(); + BUSY_BEGIN; + renderSamples(); + reset(); + BUSY_END; + } return true; } @@ -1247,24 +1266,7 @@ bool DivEngine::removeSystem(int index, bool preserveOrder) { return true; } -bool DivEngine::swapSystem(int src, int dest, bool preserveOrder) { - if (src==dest) { - lastError="source and destination are equal"; - return false; - } - if (src<0 || src>=song.systemLen) { - lastError="invalid source index"; - return false; - } - if (dest<0 || dest>=song.systemLen) { - lastError="invalid destination index"; - return false; - } - //int chanCount=chans; - quitDispatch(); - BUSY_BEGIN; - saveLock.lock(); - +void DivEngine::swapSystemUnsafe(int src, int dest, bool preserveOrder) { if (!preserveOrder) { // move channels unsigned char unswappedChannels[DIV_MAX_CHANS]; @@ -1380,6 +1382,27 @@ bool DivEngine::swapSystem(int src, int dest, bool preserveOrder) { i=(i&(~0xfff00000))|((unsigned int)src<<20); } } +} + +bool DivEngine::swapSystem(int src, int dest, bool preserveOrder) { + if (src==dest) { + lastError="source and destination are equal"; + return false; + } + if (src<0 || src>=song.systemLen) { + lastError="invalid source index"; + return false; + } + if (dest<0 || dest>=song.systemLen) { + lastError="invalid destination index"; + return false; + } + //int chanCount=chans; + quitDispatch(); + BUSY_BEGIN; + saveLock.lock(); + + swapSystemUnsafe(src,dest,preserveOrder); recalcChans(); saveLock.unlock(); diff --git a/src/engine/engine.h b/src/engine/engine.h index be98e8cd0..8e3bacdf2 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -584,6 +584,8 @@ class DivEngine { // change song (UNSAFE) void changeSong(size_t songIndex); + void swapSystemUnsafe(int src, int dest, bool preserveOrder=true); + // move an asset void moveAsset(std::vector& dir, int before, int after); diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 3a4717c19..5c2978f90 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -7319,6 +7319,7 @@ FurnaceGUI::FurnaceGUI(): fullScreen(false), preserveChanPos(false), sysDupCloneChannels(true), + sysDupEnd(false), wantScrollList(false), noteInputPoly(true), notifyWaveChange(false), diff --git a/src/gui/gui.h b/src/gui/gui.h index fbc9e5daf..1be02a95b 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1503,7 +1503,7 @@ class FurnaceGUI { bool vgmExportDirectStream, displayInsTypeList, displayWaveSizeList; bool portrait, injectBackUp, mobileMenuOpen, warnColorPushed; bool wantCaptureKeyboard, oldWantCaptureKeyboard, displayMacroMenu; - bool displayNew, displayExport, displayPalette, fullScreen, preserveChanPos, sysDupCloneChannels, wantScrollList, noteInputPoly, notifyWaveChange; + bool displayNew, displayExport, displayPalette, fullScreen, preserveChanPos, sysDupCloneChannels, sysDupEnd, wantScrollList, noteInputPoly, notifyWaveChange; bool displayPendingIns, pendingInsSingle, displayPendingRawSample, snesFilterHex, modTableHex, displayEditString; bool mobileEdit; bool killGraphics; diff --git a/src/gui/sysManager.cpp b/src/gui/sysManager.cpp index faff75a1f..68b3cbda9 100644 --- a/src/gui/sysManager.cpp +++ b/src/gui/sysManager.cpp @@ -42,6 +42,8 @@ void FurnaceGUI::drawSysManager() { ImGui::Checkbox("Preserve channel order",&preserveChanPos); ImGui::SameLine(); ImGui::Checkbox("Clone channel data",&sysDupCloneChannels); + ImGui::SameLine(); + ImGui::Checkbox("Clone at end",&sysDupEnd); if (ImGui::BeginTable("SystemList",3)) { ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch); @@ -86,7 +88,7 @@ void FurnaceGUI::drawSysManager() { } ImGui::TableNextColumn(); if (ImGui::Button("Clone##SysDup")) { - if (!e->duplicateSystem(i,sysDupCloneChannels)) { + if (!e->duplicateSystem(i,sysDupCloneChannels,sysDupEnd)) { showError("cannot clone chip! ("+e->getLastError()+")"); } else { MARK_MODIFIED;