mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-01 18:42:40 +00:00
fix crash when changing chip
it was somehow possible to exceed the channel limit...
This commit is contained in:
parent
9dbb1f7371
commit
f0bf58eef2
4 changed files with 99 additions and 12 deletions
|
@ -1003,7 +1003,16 @@ void DivEngine::delUnusedSamples() {
|
|||
BUSY_END;
|
||||
}
|
||||
|
||||
void DivEngine::changeSystem(int index, DivSystem which, bool preserveOrder) {
|
||||
bool DivEngine::changeSystem(int index, DivSystem which, bool preserveOrder) {
|
||||
if (index<0 || index>=song.systemLen) {
|
||||
lastError="invalid index";
|
||||
return false;
|
||||
}
|
||||
if (chans-getChannelCount(song.system[index])+getChannelCount(which)>DIV_MAX_CHANS) {
|
||||
lastError=fmt::sprintf("max number of total channels is %d",DIV_MAX_CHANS);
|
||||
return false;
|
||||
}
|
||||
|
||||
int chanCount=chans;
|
||||
quitDispatch();
|
||||
BUSY_BEGIN;
|
||||
|
@ -1045,6 +1054,8 @@ void DivEngine::changeSystem(int index, DivSystem which, bool preserveOrder) {
|
|||
renderSamples();
|
||||
reset();
|
||||
BUSY_END;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DivEngine::addSystem(DivSystem which) {
|
||||
|
@ -1097,6 +1108,65 @@ bool DivEngine::addSystem(DivSystem which) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DivEngine::duplicateSystem(int index, bool pat, bool end) {
|
||||
if (index<0 || index>=song.systemLen) {
|
||||
lastError="invalid index";
|
||||
return false;
|
||||
}
|
||||
if (song.systemLen>DIV_MAX_CHIPS) {
|
||||
lastError=fmt::sprintf("max number of systems is %d",DIV_MAX_CHIPS);
|
||||
return false;
|
||||
}
|
||||
if (chans+getChannelCount(song.system[index])>DIV_MAX_CHANS) {
|
||||
lastError=fmt::sprintf("max number of total channels is %d",DIV_MAX_CHANS);
|
||||
return false;
|
||||
}
|
||||
quitDispatch();
|
||||
BUSY_BEGIN;
|
||||
saveLock.lock();
|
||||
song.system[song.systemLen]=song.system[index];
|
||||
song.systemVol[song.systemLen]=song.systemVol[index];
|
||||
song.systemPan[song.systemLen]=song.systemPan[index];
|
||||
song.systemPanFR[song.systemLen]=song.systemPanFR[index];
|
||||
song.systemFlags[song.systemLen++]=song.systemFlags[index];
|
||||
recalcChans();
|
||||
saveLock.unlock();
|
||||
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) {
|
||||
song.patchbay.reserve(DIV_MAX_OUTPUTS);
|
||||
for (unsigned int j=0; j<DIV_MAX_OUTPUTS; j++) {
|
||||
song.patchbay.push_back((i<<20)|j);
|
||||
}
|
||||
} else {
|
||||
if (outs>0) song.patchbay.reserve(outs);
|
||||
for (unsigned int j=0; j<outs; j++) {
|
||||
song.patchbay.push_back((i<<20)|(j<<16)|j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// duplicate patterns
|
||||
if (pat) {
|
||||
|
||||
}
|
||||
saveLock.unlock();
|
||||
renderSamples();
|
||||
reset();
|
||||
BUSY_END;
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: maybe issue with subsongs?
|
||||
bool DivEngine::removeSystem(int index, bool preserveOrder) {
|
||||
if (song.systemLen<=1) {
|
||||
|
|
|
@ -1155,11 +1155,14 @@ class DivEngine {
|
|||
void delUnusedSamples();
|
||||
|
||||
// change system
|
||||
void changeSystem(int index, DivSystem which, bool preserveOrder=true);
|
||||
bool changeSystem(int index, DivSystem which, bool preserveOrder=true);
|
||||
|
||||
// add system
|
||||
bool addSystem(DivSystem which);
|
||||
|
||||
// duplicate system
|
||||
bool duplicateSystem(int index, bool pat=true, bool end=false);
|
||||
|
||||
// remove system
|
||||
bool removeSystem(int index, bool preserveOrder=true);
|
||||
|
||||
|
|
|
@ -4284,12 +4284,15 @@ bool FurnaceGUI::loop() {
|
|||
if (ImGui::BeginMenu(fmt::sprintf("%d. %s##_SYSC%d",i+1,getSystemName(e->song.system[i]),i).c_str())) {
|
||||
DivSystem picked=systemPicker();
|
||||
if (picked!=DIV_SYSTEM_NULL) {
|
||||
e->changeSystem(i,picked,preserveChanPos);
|
||||
MARK_MODIFIED;
|
||||
if (e->song.autoSystem) {
|
||||
autoDetectSystem();
|
||||
if (e->changeSystem(i,picked,preserveChanPos)) {
|
||||
MARK_MODIFIED;
|
||||
if (e->song.autoSystem) {
|
||||
autoDetectSystem();
|
||||
}
|
||||
updateWindowTitle();
|
||||
} else {
|
||||
showError("cannot change chip! ("+e->getLastError()+")");
|
||||
}
|
||||
updateWindowTitle();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
|
|
|
@ -83,16 +83,27 @@ void FurnaceGUI::drawSysManager() {
|
|||
ImGui::TreePop();
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("Clone##SysDup")) {
|
||||
if (!e->duplicateSystem(i)) {
|
||||
showError("cannot clone chip! ("+e->getLastError()+")");
|
||||
} else {
|
||||
MARK_MODIFIED;
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Button("Change##SysChange");
|
||||
if (ImGui::BeginPopupContextItem("SysPickerC",ImGuiPopupFlags_MouseButtonLeft)) {
|
||||
DivSystem picked=systemPicker();
|
||||
if (picked!=DIV_SYSTEM_NULL) {
|
||||
e->changeSystem(i,picked,preserveChanPos);
|
||||
MARK_MODIFIED;
|
||||
if (e->song.autoSystem) {
|
||||
autoDetectSystem();
|
||||
if (e->changeSystem(i,picked,preserveChanPos)) {
|
||||
MARK_MODIFIED;
|
||||
if (e->song.autoSystem) {
|
||||
autoDetectSystem();
|
||||
}
|
||||
updateWindowTitle();
|
||||
} else {
|
||||
showError("cannot change chip! ("+e->getLastError()+")");
|
||||
}
|
||||
updateWindowTitle();
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
|
|
Loading…
Reference in a new issue