@@ -2,13 +2,11 @@ | |||
/Rack.exe | |||
/Rack.res | |||
/libRack.a | |||
/autosave.json | |||
/settings.json | |||
/dep | |||
/plugins | |||
/build | |||
/dep | |||
*.vcv | |||
/dist | |||
/patches | |||
/design | |||
.DS_Store | |||
/dist | |||
/autosave.vcv | |||
/settings.json |
@@ -13,13 +13,14 @@ struct PatchManager { | |||
int legacy; | |||
std::string warningLog; | |||
void init(std::string path); | |||
void reset(); | |||
void resetDialog(); | |||
void save(std::string path); | |||
void saveDialog(); | |||
void saveAsDialog(); | |||
void saveTemplateDialog(); | |||
void load(std::string path); | |||
bool load(std::string path); | |||
void loadDialog(); | |||
/** If `lastPath` is defined, ask the user to reload it */ | |||
void revertDialog(); | |||
@@ -37,7 +37,7 @@ int main(int argc, char *argv[]) { | |||
#endif | |||
bool devMode = false; | |||
std::string patchFile; | |||
std::string patchPath; | |||
// Parse command line arguments | |||
int c; | |||
@@ -57,7 +57,7 @@ int main(int argc, char *argv[]) { | |||
} | |||
} | |||
if (optind < argc) { | |||
patchFile = argv[optind]; | |||
patchPath = argv[optind]; | |||
} | |||
// Initialize environment | |||
@@ -86,28 +86,8 @@ int main(int argc, char *argv[]) { | |||
appInit(); | |||
app()->scene->devMode = devMode; | |||
settings::load(asset::user("settings.json")); | |||
app()->patch->init(patchPath); | |||
if (patchFile.empty()) { | |||
// To prevent launch crashes, if Rack crashes between now and 15 seconds from now, the "skipAutosaveOnLaunch" property will remain in settings.json, so that in the next launch, the broken autosave will not be loaded. | |||
bool oldSkipLoadOnLaunch = settings::skipLoadOnLaunch; | |||
settings::skipLoadOnLaunch = true; | |||
settings::save(asset::user("settings.json")); | |||
settings::skipLoadOnLaunch = false; | |||
if (oldSkipLoadOnLaunch && osdialog_message(OSDIALOG_INFO, OSDIALOG_YES_NO, "Rack has recovered from a crash, possibly caused by a faulty module in your patch. Clear your patch and start over?")) { | |||
app()->patch->path = ""; | |||
} | |||
else { | |||
// Load autosave | |||
std::string oldLastPath = app()->patch->path; | |||
app()->patch->load(asset::user("autosave.vcv")); | |||
app()->patch->path = oldLastPath; | |||
} | |||
} | |||
else { | |||
// Load patch | |||
app()->patch->load(patchFile); | |||
app()->patch->path = patchFile; | |||
} | |||
INFO("Initialized app"); | |||
app()->engine->start(); | |||
@@ -5,6 +5,8 @@ | |||
#include "app/Scene.hpp" | |||
#include "app/RackWidget.hpp" | |||
#include "history.hpp" | |||
#include "settings.hpp" | |||
#include "osdialog.h" | |||
@@ -14,6 +16,39 @@ namespace rack { | |||
static const char PATCH_FILTERS[] = "VCV Rack patch (.vcv):vcv"; | |||
void PatchManager::init(std::string path) { | |||
if (!path.empty()) { | |||
// Load patch | |||
load(path); | |||
this->path = path; | |||
return; | |||
} | |||
// To prevent launch crashes, if Rack crashes between now and 15 seconds from now, the "skipAutosaveOnLaunch" property will remain in settings.json, so that in the next launch, the broken autosave will not be loaded. | |||
bool oldSkipLoadOnLaunch = settings::skipLoadOnLaunch; | |||
settings::skipLoadOnLaunch = true; | |||
settings::save(asset::user("settings.json")); | |||
settings::skipLoadOnLaunch = false; | |||
if (oldSkipLoadOnLaunch && osdialog_message(OSDIALOG_INFO, OSDIALOG_YES_NO, "Rack has recovered from a crash, possibly caused by a faulty module in your patch. Clear your patch and start over?")) { | |||
this->path = ""; | |||
return; | |||
} | |||
// Load autosave | |||
if (load(asset::user("autosave.vcv"))) { | |||
return; | |||
} | |||
this->path = ""; | |||
if (load(asset::user("template.vcv"))) { | |||
return; | |||
} | |||
if (load(asset::system("template.vcv"))) { | |||
return; | |||
} | |||
} | |||
void PatchManager::reset() { | |||
app()->history->clear(); | |||
app()->scene->rackWidget->clear(); | |||
@@ -102,12 +137,12 @@ void PatchManager::saveTemplateDialog() { | |||
} | |||
} | |||
void PatchManager::load(std::string path) { | |||
bool PatchManager::load(std::string path) { | |||
INFO("Loading patch %s", path.c_str()); | |||
FILE *file = std::fopen(path.c_str(), "r"); | |||
if (!file) { | |||
// Exit silently | |||
return; | |||
return false; | |||
} | |||
DEFER({ | |||
std::fclose(file); | |||
@@ -118,7 +153,7 @@ void PatchManager::load(std::string path) { | |||
if (!rootJ) { | |||
std::string message = string::f("JSON parsing error at %s %d:%d %s", error.source, error.line, error.column, error.text); | |||
osdialog_message(OSDIALOG_WARNING, OSDIALOG_OK, message.c_str()); | |||
return; | |||
return false; | |||
} | |||
DEFER({ | |||
json_decref(rootJ); | |||
@@ -128,6 +163,7 @@ void PatchManager::load(std::string path) { | |||
app()->scene->rackWidget->clear(); | |||
app()->scene->scrollWidget->offset = math::Vec(0, 0); | |||
fromJson(rootJ); | |||
return true; | |||
} | |||
void PatchManager::loadDialog() { | |||
@@ -0,0 +1,238 @@ | |||
{ | |||
"version": "1.dev", | |||
"modules": [ | |||
{ | |||
"plugin": "Core", | |||
"version": "1.dev", | |||
"model": "AudioInterface", | |||
"params": [], | |||
"data": { | |||
}, | |||
"id": 1, | |||
"pos": [ | |||
47, | |||
0 | |||
] | |||
}, | |||
{ | |||
"plugin": "Fundamental", | |||
"version": "1.0.0", | |||
"model": "VCMixer", | |||
"params": [ | |||
{ | |||
"value": 1.0 | |||
}, | |||
{ | |||
"value": 1.0 | |||
}, | |||
{ | |||
"value": 1.0 | |||
}, | |||
{ | |||
"value": 1.0 | |||
}, | |||
{ | |||
"value": 1.0 | |||
} | |||
], | |||
"id": 2, | |||
"pos": [ | |||
37, | |||
0 | |||
] | |||
}, | |||
{ | |||
"plugin": "Fundamental", | |||
"version": "1.0.0", | |||
"model": "VCO", | |||
"params": [ | |||
{ | |||
"value": 1.0 | |||
}, | |||
{ | |||
"value": 1.0 | |||
}, | |||
{ | |||
"value": 0.0 | |||
}, | |||
{ | |||
"value": 0.0 | |||
}, | |||
{ | |||
"value": 0.0 | |||
}, | |||
{ | |||
"value": 0.5 | |||
}, | |||
{ | |||
"value": 0.0 | |||
} | |||
], | |||
"id": 3, | |||
"pos": [ | |||
8, | |||
0 | |||
] | |||
}, | |||
{ | |||
"plugin": "Fundamental", | |||
"version": "1.0.0", | |||
"model": "VCF", | |||
"params": [ | |||
{ | |||
"value": 0.262999862 | |||
}, | |||
{ | |||
"value": 0.5 | |||
}, | |||
{ | |||
"value": 0.236999944 | |||
}, | |||
{ | |||
"value": 0.869999945 | |||
}, | |||
{ | |||
"value": 0.0 | |||
} | |||
], | |||
"id": 4, | |||
"pos": [ | |||
18, | |||
0 | |||
] | |||
}, | |||
{ | |||
"plugin": "Core", | |||
"version": "1.dev", | |||
"model": "MIDIToCVInterface", | |||
"params": [], | |||
"data": { | |||
"divisions": [ | |||
24, | |||
6 | |||
] | |||
}, | |||
"id": 5, | |||
"pos": [ | |||
0, | |||
0 | |||
] | |||
}, | |||
{ | |||
"plugin": "Fundamental", | |||
"version": "1.0.0", | |||
"model": "VCA-1", | |||
"params": [ | |||
{ | |||
"value": 1.0 | |||
}, | |||
{ | |||
"value": 1.0 | |||
} | |||
], | |||
"id": 6, | |||
"pos": [ | |||
26, | |||
0 | |||
] | |||
}, | |||
{ | |||
"plugin": "Fundamental", | |||
"version": "1.0.0", | |||
"model": "ADSR", | |||
"params": [ | |||
{ | |||
"value": 0.356000006 | |||
}, | |||
{ | |||
"value": 0.671000004 | |||
}, | |||
{ | |||
"value": 0.358999938 | |||
}, | |||
{ | |||
"value": 0.5 | |||
} | |||
], | |||
"id": 7, | |||
"pos": [ | |||
29, | |||
0 | |||
] | |||
} | |||
], | |||
"cables": [ | |||
{ | |||
"id": 1, | |||
"outputModuleId": 5, | |||
"outputId": 0, | |||
"inputModuleId": 3, | |||
"inputId": 0, | |||
"color": "#c91847" | |||
}, | |||
{ | |||
"id": 2, | |||
"outputModuleId": 3, | |||
"outputId": 2, | |||
"inputModuleId": 4, | |||
"inputId": 3, | |||
"color": "#0c8e15" | |||
}, | |||
{ | |||
"id": 3, | |||
"outputModuleId": 4, | |||
"outputId": 0, | |||
"inputModuleId": 6, | |||
"inputId": 1, | |||
"color": "#0986ad" | |||
}, | |||
{ | |||
"id": 4, | |||
"outputModuleId": 6, | |||
"outputId": 0, | |||
"inputModuleId": 2, | |||
"inputId": 1, | |||
"color": "#c9b70e" | |||
}, | |||
{ | |||
"id": 5, | |||
"outputModuleId": 2, | |||
"outputId": 0, | |||
"inputModuleId": 1, | |||
"inputId": 0, | |||
"color": "#0986ad" | |||
}, | |||
{ | |||
"id": 6, | |||
"outputModuleId": 2, | |||
"outputId": 0, | |||
"inputModuleId": 1, | |||
"inputId": 1, | |||
"color": "#c9b70e" | |||
}, | |||
{ | |||
"id": 7, | |||
"outputModuleId": 7, | |||
"outputId": 0, | |||
"inputModuleId": 4, | |||
"inputId": 0, | |||
"color": "#c91847" | |||
}, | |||
{ | |||
"id": 8, | |||
"outputModuleId": 7, | |||
"outputId": 0, | |||
"inputModuleId": 6, | |||
"inputId": 0, | |||
"color": "#0c8e15" | |||
}, | |||
{ | |||
"id": 9, | |||
"outputModuleId": 5, | |||
"outputId": 1, | |||
"inputModuleId": 7, | |||
"inputId": 4, | |||
"color": "#c9b70e" | |||
} | |||
] | |||
} |