Signed-off-by: falkTX <falktx@falktx.com>tags/23.07
| @@ -1 +1 @@ | |||
| Subproject commit b4460beb094502c868dda5991e356623b13ce658 | |||
| Subproject commit 802e4460844b75b4c2a96c5a9f9baa791209f74e | |||
| @@ -892,8 +892,8 @@ struct AidaWidget : ModuleWidgetWithSideScrews<23> { | |||
| heightPedal, | |||
| cornerRadius, | |||
| cornerRadius, | |||
| nvgRGBA(0,0,0,1.f), | |||
| nvgRGBA(0,0,0,0.f))); | |||
| nvgRGBAf(0,0,0,1.f), | |||
| nvgRGBAf(0,0,0,0.f))); | |||
| nvgFill(args.vg); | |||
| // .rt-neural .grid | |||
| @@ -916,7 +916,7 @@ struct AidaWidget : ModuleWidgetWithSideScrews<23> { | |||
| nvgFill(args.vg); | |||
| // extra | |||
| nvgStrokeColor(args.vg, nvgRGBA(150, 150, 150, 0.25f)); | |||
| nvgStrokeColor(args.vg, nvgRGBA(150, 150, 150, 60)); | |||
| nvgStroke(args.vg); | |||
| drawOutputJacksArea(args.vg); | |||
| @@ -471,10 +471,10 @@ struct AudioFileListWidget : ImGuiWidget { | |||
| selectedFile = (size_t)-1; | |||
| static constexpr const char* const supportedExtensions[] = { | |||
| #ifdef HAVE_SNDFILE | |||
| #ifdef HAVE_SNDFILE | |||
| ".aif",".aifc",".aiff",".au",".bwf",".flac",".htk",".iff",".mat4",".mat5",".oga",".ogg",".opus", | |||
| ".paf",".pvf",".pvf5",".sd2",".sf",".snd",".svx",".vcc",".w64",".wav",".xi", | |||
| #endif | |||
| #endif | |||
| ".mp3" | |||
| }; | |||
| @@ -89,9 +89,9 @@ | |||
| #ifdef DISTRHO_OS_WASM | |||
| # if CARDINAL_VARIANT_MINI | |||
| # define CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME "welcome-wasm-mini.vcv" | |||
| # define CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME "welcome-wasm-mini" | |||
| # else | |||
| # define CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME "welcome-wasm.vcv" | |||
| # define CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME "welcome-wasm" | |||
| # endif | |||
| #endif | |||
| @@ -374,6 +374,17 @@ static int osc_screenshot_handler(const char*, const char* types, lo_arg** argv, | |||
| } | |||
| #endif | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| #ifdef DISTRHO_OS_WASM | |||
| static void WebBrowserDataLoaded(void* const data) | |||
| { | |||
| static_cast<Initializer*>(data)->loadSettings(true); | |||
| } | |||
| #endif | |||
| // ----------------------------------------------------------------------------------------------------------- | |||
| Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalBaseUI* const ui) | |||
| { | |||
| using namespace rack; | |||
| @@ -490,7 +501,17 @@ Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalB | |||
| #endif | |||
| if (isRealInstance) | |||
| { | |||
| #ifdef DISTRHO_OS_WASM | |||
| EM_ASM({ | |||
| Module.FS.mkdir('/userfiles'); | |||
| Module.FS.mount(Module.IDBFS, {}, '/userfiles'); | |||
| Module.FS.syncfs(true, function(err) { if (!err) { dynCall('vi', $0, [$1]) } }); | |||
| }, WebBrowserDataLoaded, this); | |||
| #else | |||
| system::createDirectory(asset::userDir); | |||
| #endif | |||
| } | |||
| } | |||
| #ifndef CARDINAL_COMMON_DSP_ONLY | |||
| @@ -513,13 +534,11 @@ Initializer::Initializer(const CardinalBasePlugin* const plugin, const CardinalB | |||
| if (settings::settingsPath.empty()) | |||
| settings::settingsPath = asset::config(CARDINAL_VARIANT_NAME ".json"); | |||
| const std::string patchesPath = asset::patchesPath(); | |||
| templatePath = asset::user("templates/" CARDINAL_VARIANT_NAME ".vcv"); | |||
| #ifdef DISTRHO_OS_WASM | |||
| templatePath = system::join(patchesPath, CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME ".vcv"); | |||
| factoryTemplatePath = system::join(patchesPath, "templates/" CARDINAL_VARIANT_NAME ".vcv"); | |||
| factoryTemplatePath = system::join(asset::patchesPath(), CARDINAL_WASM_WELCOME_TEMPLATE_FILENAME ".vcv"); | |||
| #else | |||
| templatePath = asset::user("templates/" CARDINAL_VARIANT_NAME ".vcv"); | |||
| factoryTemplatePath = system::join(patchesPath, "templates/" CARDINAL_VARIANT_NAME ".vcv"); | |||
| factoryTemplatePath = system::join(asset::patchesPath(), "templates/" CARDINAL_VARIANT_NAME ".vcv"); | |||
| #endif | |||
| // Log environment | |||
| @@ -672,7 +691,8 @@ bool isMini() | |||
| bool isStandalone() | |||
| { | |||
| return std::strstr(getPluginFormatName(), "Standalone") != nullptr; | |||
| static const bool standalone = std::strstr(getPluginFormatName(), "Standalone") != nullptr; | |||
| return standalone; | |||
| } | |||
| #ifdef ARCH_WIN | |||
| @@ -712,6 +732,15 @@ std::string getSpecialPath(const SpecialPath type) | |||
| char* patchFromURL = nullptr; | |||
| char* patchRemoteURL = nullptr; | |||
| char* patchStorageSlug = nullptr; | |||
| void syncfs() | |||
| { | |||
| settings::save(); | |||
| EM_ASM({ | |||
| Module.FS.syncfs(false, function(){} ); | |||
| }); | |||
| } | |||
| #endif | |||
| std::string homeDir() | |||
| @@ -783,6 +812,10 @@ void loadPathDialog(const std::string& path, const bool asTemplate) | |||
| APP->history->setSaved(); | |||
| } | |||
| #ifdef DISTRHO_OS_WASM | |||
| syncfs(); | |||
| #endif | |||
| if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote()) | |||
| if (remoteDetails->autoDeploy) | |||
| remoteUtils::sendFullPatchToRemote(remoteDetails); | |||
| @@ -812,6 +845,10 @@ void loadSelectionDialog() | |||
| std::free(pathC); | |||
| #ifdef DISTRHO_OS_WASM | |||
| syncfs(); | |||
| #endif | |||
| if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote()) | |||
| if (remoteDetails->autoDeploy) | |||
| remoteUtils::sendFullPatchToRemote(remoteDetails); | |||
| @@ -839,6 +876,10 @@ void loadTemplate(const bool factory) | |||
| APP->patch->path.clear(); | |||
| APP->history->setSaved(); | |||
| #ifdef DISTRHO_OS_WASM | |||
| syncfs(); | |||
| #endif | |||
| if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote()) | |||
| if (remoteDetails->autoDeploy) | |||
| remoteUtils::sendFullPatchToRemote(remoteDetails); | |||
| @@ -862,6 +903,10 @@ void revertDialog() | |||
| promptClear("Revert patch to the last saved state?", []{ | |||
| APP->patch->loadAction(APP->patch->path); | |||
| #ifdef DISTRHO_OS_WASM | |||
| syncfs(); | |||
| #endif | |||
| if (remoteUtils::RemoteDetails* const remoteDetails = remoteUtils::getRemote()) | |||
| if (remoteDetails->autoDeploy) | |||
| remoteUtils::sendFullPatchToRemote(remoteDetails); | |||
| @@ -886,6 +931,14 @@ void saveDialog(const std::string& path) | |||
| asyncDialog::create(string::f("Could not save patch: %s", e.what()).c_str()); | |||
| return; | |||
| } | |||
| APP->patch->pushRecentPath(path); | |||
| #ifdef DISTRHO_OS_WASM | |||
| syncfs(); | |||
| #else | |||
| rack::settings::save(); | |||
| #endif | |||
| #endif | |||
| } | |||
| @@ -944,7 +997,11 @@ void saveTemplateDialog() | |||
| catch (Exception& e) { | |||
| asyncDialog::create(string::f("Could not save template patch: %s", e.what()).c_str()); | |||
| return; | |||
| } | |||
| } | |||
| #ifdef DISTRHO_OS_WASM | |||
| syncfs(); | |||
| #endif | |||
| }); | |||
| } | |||
| @@ -53,6 +53,7 @@ std::string getSpecialPath(SpecialPath type); | |||
| extern char* patchFromURL; | |||
| extern char* patchRemoteURL; | |||
| extern char* patchStorageSlug; | |||
| void syncfs(); | |||
| #endif | |||
| std::string homeDir(); | |||
| @@ -66,6 +66,11 @@ namespace app { | |||
| rack::widget::Widget* createMenuBar() { return new rack::widget::Widget; } | |||
| } | |||
| #endif | |||
| #ifdef DISTRHO_OS_WASM | |||
| namespace asset { | |||
| std::string patchesPath(); | |||
| } | |||
| #endif | |||
| namespace engine { | |||
| void Engine_setAboutToClose(Engine*); | |||
| } | |||
| @@ -312,6 +317,15 @@ public: | |||
| context->scene->rackScroll->reset(); | |||
| } | |||
| #ifdef DISTRHO_OS_WASM | |||
| // switch factory template to regular one after first load | |||
| #if CARDINAL_VARIANT_MINI | |||
| context->patch->factoryTemplatePath = rack::system::join(rack::asset::patchesPath(), "templates/mini.vcv"); | |||
| #else | |||
| context->patch->factoryTemplatePath = rack::system::join(rack::asset::patchesPath(), "templates/main.vcv"); | |||
| #endif | |||
| #endif | |||
| #ifdef CARDINAL_INIT_OSC_THREAD | |||
| fInitializer->remotePluginInstance = this; | |||
| #endif | |||
| @@ -62,6 +62,11 @@ | |||
| #endif | |||
| namespace rack { | |||
| #ifdef DISTRHO_OS_WASM | |||
| namespace asset { | |||
| std::string patchesPath(); | |||
| } | |||
| #endif | |||
| namespace engine { | |||
| void Engine_setAboutToClose(Engine*); | |||
| void Engine_setRemoteDetails(Engine*, remoteUtils::RemoteDetails*); | |||
| @@ -246,7 +251,7 @@ static void downloadRemotePatchFailed(const char* const filename) | |||
| } | |||
| using namespace rack; | |||
| context->patch->templatePath = system::join(asset::systemDir, "init/wasm.vcv"); // FIXME | |||
| context->patch->templatePath = rack::system::join(asset::patchesPath(), "templates/main.vcv"); | |||
| context->patch->loadTemplate(); | |||
| context->scene->rackScroll->reset(); | |||
| } | |||
| @@ -1228,7 +1233,11 @@ protected: | |||
| context->patch->pushRecentPath(sfilename); | |||
| context->history->setSaved(); | |||
| #ifdef DISTRHO_OS_WASM | |||
| rack::syncfs(); | |||
| #else | |||
| rack::settings::save(); | |||
| #endif | |||
| } | |||
| #if 0 | |||
| @@ -283,6 +283,7 @@ LINK_FLAGS += -O3 | |||
| LINK_FLAGS += -sALLOW_MEMORY_GROWTH | |||
| LINK_FLAGS += -sINITIAL_MEMORY=64Mb | |||
| LINK_FLAGS += -sLZ4=1 | |||
| LINK_FLAGS += -lidbfs.js | |||
| ifeq ($(CARDINAL_VARIANT),mini) | |||
| LINK_FLAGS += --preload-file=../../bin/CardinalMini.lv2/resources@/resources | |||
| @@ -56,6 +56,11 @@ | |||
| #include "DistrhoPlugin.hpp" | |||
| #include "DistrhoStandaloneUtils.hpp" | |||
| #ifdef DISTRHO_OS_WASM | |||
| # include <emscripten/emscripten.h> | |||
| # undef HAVE_LIBLO | |||
| #endif | |||
| #ifdef HAVE_LIBLO | |||
| # include <lo/lo.h> | |||
| #endif | |||
| @@ -98,6 +103,28 @@ struct FileButton : MenuButton { | |||
| const bool isStandalone; | |||
| std::vector<std::string> demoPatches; | |||
| #ifdef DISTRHO_OS_WASM | |||
| static void WebBrowserDataSaved(const int err) | |||
| { | |||
| err ? async_dialog_message("Error, could not save web browser data!") | |||
| : async_dialog_message("Web browser data saved!"); | |||
| } | |||
| static void wasmSaveAs() | |||
| { | |||
| async_dialog_text_input("Filename", nullptr, [](char* const filename) { | |||
| if (filename == nullptr) | |||
| return; | |||
| APP->patch->path = "/userfiles/"; | |||
| APP->patch->path += filename; | |||
| if (rack::system::getExtension(filename) != ".vcv") | |||
| APP->patch->path += ".vcv"; | |||
| patchUtils::saveDialog(APP->patch->path); | |||
| std::free(filename); | |||
| }); | |||
| } | |||
| #endif | |||
| FileButton(const bool standalone) | |||
| : MenuButton(), isStandalone(standalone) | |||
| { | |||
| @@ -131,7 +158,6 @@ struct FileButton : MenuButton { | |||
| })); | |||
| #if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | |||
| #ifndef DISTRHO_OS_WASM | |||
| menu->addChild(createMenuItem("New (factory template)", "", []() { | |||
| patchUtils::loadTemplateDialog(true); | |||
| })); | |||
| @@ -149,6 +175,11 @@ struct FileButton : MenuButton { | |||
| } | |||
| }, settings::recentPatchPaths.empty())); | |||
| menu->addChild(createMenuItem("Import selection...", "", [=]() { | |||
| patchUtils::loadSelectionDialog(); | |||
| }, false, true)); | |||
| #ifndef DISTRHO_OS_WASM | |||
| menu->addChild(createMenuItem("Save", RACK_MOD_CTRL_NAME "+S", []() { | |||
| // NOTE: will do nothing if path is empty, intentionally | |||
| patchUtils::saveDialog(APP->patch->path); | |||
| @@ -158,13 +189,16 @@ struct FileButton : MenuButton { | |||
| patchUtils::saveAsDialog(); | |||
| })); | |||
| #else | |||
| menu->addChild(createMenuItem("Import patch...", RACK_MOD_CTRL_NAME "+O", []() { | |||
| patchUtils::loadDialog(); | |||
| menu->addChild(createMenuItem("Save", "", []() { | |||
| if (APP->patch->path.empty()) | |||
| wasmSaveAs(); | |||
| else | |||
| patchUtils::saveDialog(APP->patch->path); | |||
| })); | |||
| menu->addChild(createMenuItem("Import selection...", "", [=]() { | |||
| patchUtils::loadSelectionDialog(); | |||
| }, false, true)); | |||
| menu->addChild(createMenuItem("Save as", "", []() { | |||
| wasmSaveAs(); | |||
| })); | |||
| menu->addChild(createMenuItem("Save and download compressed", RACK_MOD_CTRL_NAME "+Shift+S", []() { | |||
| patchUtils::saveAsDialog(); | |||
| @@ -184,6 +218,17 @@ struct FileButton : MenuButton { | |||
| patchUtils::saveTemplateDialog(); | |||
| })); | |||
| #ifdef DISTRHO_OS_WASM | |||
| menu->addChild(new ui::MenuSeparator); | |||
| menu->addChild(createMenuItem("Save persistent browser data", "", []() { | |||
| settings::save(); | |||
| EM_ASM({ | |||
| Module.FS.syncfs(false, function(err){ dynCall('vi', $0, [!!err]) }); | |||
| }, WebBrowserDataSaved); | |||
| })); | |||
| #endif | |||
| #if defined(HAVE_LIBLO) || ! DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | |||
| #ifdef __MOD_DEVICES__ | |||
| #define REMOTE_NAME "MOD" | |||
| @@ -213,21 +258,6 @@ struct FileButton : MenuButton { | |||
| } | |||
| #endif | |||
| #if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | |||
| #ifndef DISTRHO_OS_WASM | |||
| menu->addChild(new ui::MenuSeparator); | |||
| // Load selection | |||
| menu->addChild(createMenuItem("Import selection...", "", [=]() { | |||
| patchUtils::loadSelectionDialog(); | |||
| }, false, true)); | |||
| menu->addChild(createMenuItem("Export uncompressed json...", "", []() { | |||
| patchUtils::saveAsDialogUncompressed(); | |||
| })); | |||
| #endif | |||
| #endif | |||
| if (!demoPatches.empty()) | |||
| { | |||
| menu->addChild(new ui::MenuSeparator); | |||
| @@ -276,13 +276,11 @@ void Scene::onHoverKey(const HoverKeyEvent& e) { | |||
| patchUtils::revertDialog(); | |||
| e.consume(this); | |||
| } | |||
| #ifndef DISTRHO_OS_WASM | |||
| if (e.keyName == "s" && (e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL) { | |||
| // NOTE: will do nothing if path is empty, intentionally | |||
| patchUtils::saveDialog(APP->patch->path); | |||
| e.consume(this); | |||
| } | |||
| #endif | |||
| if (e.keyName == "s" && (e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) { | |||
| patchUtils::saveAsDialog(); | |||
| e.consume(this); | |||