diff --git a/papers/format.md b/papers/format.md index 076729ec6..d8ec4bbf0 100644 --- a/papers/format.md +++ b/papers/format.md @@ -32,6 +32,7 @@ these fields are 0 in format versions prior to 100 (0.6pre1). the format versions are: +- 136: Furnace dev136 - 135: Furnace dev135 - 134: Furnace dev134 - 133: Furnace 0.6pre3 @@ -396,6 +397,7 @@ size | description 4 | patchbay connection count 4?? | patchbay | - see next section for more details. + 1 | automatic patchbay (>=136) ``` # patchbay diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 14fa8eecd..8b8849aa8 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -1693,6 +1693,27 @@ bool DivEngine::addSystem(DivSystem which) { BUSY_END; initDispatch(); BUSY_BEGIN; + saveLock.lock(); + if (song.patchbayAuto) { + autoPatchbay(); + } else { + int i=song.systemLen-1; + if (disCont[i].dispatch!=NULL) { + unsigned int outs=disCont[i].dispatch->getOutputCount(); + if (outs>16) outs=16; + if (outs<2) { + for (unsigned int j=0; j>20)&0xfff)==index) { + song.patchbay.erase(song.patchbay.begin()+i); + i--; + } + } + song.system[index]=DIV_SYSTEM_NULL; song.systemLen--; for (int i=index; i>20)&0xfff)==src) { + i=(i&(~0xfff00000))|((unsigned int)dest<<20); + } else if (((i>>20)&0xfff)==dest) { + i=(i&(~0xfff00000))|((unsigned int)src<<20); + } + } + recalcChans(); saveLock.unlock(); BUSY_END; @@ -3794,6 +3832,14 @@ void DivEngine::autoPatchbay() { } } +void DivEngine::autoPatchbayP() { + BUSY_BEGIN; + saveLock.lock(); + autoPatchbay(); + saveLock.unlock(); + BUSY_END; +} + bool DivEngine::patchConnect(unsigned int src, unsigned int dest) { unsigned int armed=(src<<16)|(dest&0xffff); for (unsigned int i: song.patchbay) { @@ -3802,6 +3848,7 @@ bool DivEngine::patchConnect(unsigned int src, unsigned int dest) { BUSY_BEGIN; saveLock.lock(); song.patchbay.push_back(armed); + song.patchbayAuto=false; saveLock.unlock(); BUSY_END; return true; @@ -3814,6 +3861,7 @@ bool DivEngine::patchDisconnect(unsigned int src, unsigned int dest) { BUSY_BEGIN; saveLock.lock(); song.patchbay.erase(i); + song.patchbayAuto=false; saveLock.unlock(); BUSY_END; return true; @@ -3961,6 +4009,14 @@ void DivEngine::updateSysFlags(int system, bool restart) { BUSY_BEGIN_SOFT; disCont[system].dispatch->setFlags(song.systemFlags[system]); disCont[system].setRates(got.rate); + + // patchbay + if (song.patchbayAuto) { + saveLock.lock(); + autoPatchbay(); + saveLock.unlock(); + } + if (restart && isPlaying()) { playSub(false); } diff --git a/src/engine/engine.h b/src/engine/engine.h index 88029651c..bffff7816 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -47,8 +47,8 @@ #define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock(); #define BUSY_END isBusy.unlock(); softLocked=false; -#define DIV_VERSION "dev135" -#define DIV_ENGINE_VERSION 135 +#define DIV_VERSION "dev136" +#define DIV_ENGINE_VERSION 136 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 @@ -837,6 +837,7 @@ class DivEngine { // automatic patchbay void autoPatchbay(); + void autoPatchbayP(); // connect in patchbay // returns false if connection already made diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index 0503d03fb..349e83794 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -2220,6 +2220,8 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { } } + if (ds.version>=136) song.patchbayAuto=reader.readC(); + // read system flags if (ds.version>=119) { logD("reading chip flags..."); @@ -4489,6 +4491,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) { for (unsigned int i: song.patchbay) { w->writeI(i); } + w->writeC(song.patchbayAuto); blockEndSeek=w->tell(); w->seek(blockStartSeek,SEEK_SET); diff --git a/src/engine/song.h b/src/engine/song.h index 3fbe5e27f..dfe579bbb 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -329,6 +329,7 @@ struct DivSong { bool disableSampleMacro; bool autoSystem; bool oldArpStrategy; + bool patchbayAuto; std::vector ins; std::vector wave; @@ -437,7 +438,8 @@ struct DivSong { snNoLowPeriods(false), disableSampleMacro(false), autoSystem(true), - oldArpStrategy(false) { + oldArpStrategy(false), + patchbayAuto(true) { for (int i=0; isong.patchbayAuto)) { + if (e->song.patchbayAuto) e->autoPatchbayP(); + MARK_MODIFIED; + } + ImGui::Checkbox("Display hidden ports",&displayHiddenPorts); + ImGui::Dummy(ImVec2(1.0f,ImGui::GetFrameHeightWithSpacing()*2.0f)); } hoveredPortSet=0x1fff; @@ -260,6 +265,8 @@ void FurnaceGUI::drawMixer() { ImVec2 topPos=ImGui::GetCursorPos(); topPos.x+=ImGui::GetContentRegionAvail().x-60.0*dpiScale; + if (ImGui::IsWindowHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) selectedPortSet=0x1fff; + if (portDragActive) { dl->AddLine(subPortPos,ImGui::GetMousePos(),ImGui::GetColorU32(uiColors[GUI_COLOR_PATCHBAY_CONNECTION]),2.0f*dpiScale); } @@ -281,7 +288,7 @@ void FurnaceGUI::drawMixer() { } } ImGui::SetCursorPos(topPos); - if (portSet("System",0x1000,e->getAudioDescGot().outChans,0,e->getAudioDescGot().outChans,0,selectedSubPort,portPos)) { + if (portSet("System",0x1000,displayHiddenPorts?DIV_MAX_OUTPUTS:e->getAudioDescGot().outChans,0,e->getAudioDescGot().outChans,0,selectedSubPort,portPos)) { selectedPortSet=0x1000; if (selectedSubPort>=0) { portDragActive=true;