Signed-off-by: falkTX <falktx@falktx.com>tags/24.04
| @@ -153,10 +153,10 @@ ifeq ($(HEADLESS),true) | |||
| BASE_FLAGS += -DHEADLESS | |||
| endif | |||
| ifeq ($(USE_GLES2),true) | |||
| BASE_FLAGS += -DNANOVG_GLES2_FORCED | |||
| else ifeq ($(USE_GLES3),true) | |||
| ifeq ($(USE_GLES3),true) | |||
| BASE_FLAGS += -DNANOVG_GLES3_FORCED | |||
| else ifeq ($(USE_GLES2),true) | |||
| BASE_FLAGS += -DNANOVG_GLES2_FORCED | |||
| endif | |||
| # needed for enabling SSE in pffft | |||
| @@ -175,7 +175,7 @@ BASE_FLAGS += -msse -msse2 -msse3 -msimd128 | |||
| else ifeq ($(CPU_ARM32),true) | |||
| BASE_FLAGS += -mfpu=neon-vfpv4 -mfloat-abi=hard | |||
| else ifeq ($(CPU_I386_OR_X86_64),true) | |||
| BASE_FLAGS += -msse -msse2 -mfpmath=sse | |||
| BASE_FLAGS += -msse -msse2 -msse3 -mfpmath=sse | |||
| endif | |||
| endif | |||
| @@ -36,12 +36,6 @@ | |||
| namespace rack { | |||
| #ifndef HEADLESS | |||
| namespace asset { | |||
| void updateForcingBlackSilverScrewMode(std::string slug); | |||
| } | |||
| #endif | |||
| struct CardinalPluginModelHelper : plugin::Model { | |||
| virtual app::ModuleWidget* createModuleWidgetFromEngineLoad(engine::Module* m) = 0; | |||
| virtual void removeCachedModuleWidget(engine::Module* m) = 0; | |||
| @@ -78,9 +72,6 @@ struct CardinalPluginModel : CardinalPluginModelHelper | |||
| } | |||
| tm = dynamic_cast<TModule*>(m); | |||
| } | |||
| #ifndef HEADLESS | |||
| asset::updateForcingBlackSilverScrewMode(slug); | |||
| #endif | |||
| app::ModuleWidget* const tmw = new TModuleWidget(tm); | |||
| DISTRHO_CUSTOM_SAFE_ASSERT_RETURN(m != nullptr ? m->model->name.c_str() : "null", tmw->module == m, nullptr); | |||
| tmw->setModel(this); | |||
| @@ -95,9 +86,6 @@ struct CardinalPluginModel : CardinalPluginModelHelper | |||
| TModule* const tm = dynamic_cast<TModule*>(m); | |||
| DISTRHO_SAFE_ASSERT_RETURN(tm != nullptr, nullptr); | |||
| #ifndef HEADLESS | |||
| asset::updateForcingBlackSilverScrewMode(slug); | |||
| #endif | |||
| TModuleWidget* const tmw = new TModuleWidget(tm); | |||
| DISTRHO_SAFE_ASSERT_RETURN(tmw->module == m, nullptr); | |||
| tmw->setModel(this); | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Cardinal Plugin | |||
| * Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -22,7 +22,6 @@ | |||
| namespace rack { | |||
| namespace settings { | |||
| extern bool darkMode; | |||
| extern int rateLimit; | |||
| } // namespace settings | |||
| @@ -17,41 +17,21 @@ | |||
| #pragma once | |||
| #if (defined(__i386__) || defined(__x86_64__)) && !defined(CARDINAL_NOSIMD) | |||
| #if (defined(__i386__) || defined(__x86_64__) || defined(__EMSCRIPTEN__)) && !defined(CARDINAL_NOSIMD) | |||
| # include_next <pmmintrin.h> | |||
| // bring in extra SSE3 support via simde | |||
| # define SIMDE_X86_SSE2_NATIVE | |||
| # define SIMDE_X86_SSE3_ENABLE_NATIVE_ALIASES | |||
| // make sure to not include windows.h here | |||
| # ifdef _WIN32 | |||
| # define _WIN32_WAS_DEFINED | |||
| # undef _WIN32 | |||
| # endif | |||
| // assume SSE3 only on macOS | |||
| # ifndef ARCH_MAC | |||
| # include "simde/x86/sse3.h" | |||
| # endif | |||
| # ifdef _WIN32_WAS_DEFINED | |||
| # define _WIN32 | |||
| # undef _WIN32_WAS_DEFINED | |||
| # endif | |||
| # undef SIMDE_X86_SSE2_NATIVE | |||
| # undef SIMDE_X86_SSE3_ENABLE_NATIVE_ALIASES | |||
| #elif defined(__EMSCRIPTEN__) && !defined(CARDINAL_NOSIMD) | |||
| # include_next <pmmintrin.h> | |||
| # if defined(__EMSCRIPTEN__) && !defined(CARDINAL_NOSIMD) | |||
| static __inline__ __m64 __attribute__((__always_inline__, __nodebug__)) | |||
| _mm_set1_pi16(short w) | |||
| { | |||
| return __extension__ (__m64){ static_cast<float>(w), static_cast<float>(w) }; | |||
| } | |||
| # endif | |||
| #else | |||
| # define SIMDE_ENABLE_NATIVE_ALIASES | |||
| # include "simde/x86/sse.h" | |||
| # include "simde/x86/sse2.h" | |||
| # include "simde/x86/sse3.h" | |||
| # undef SIMDE_ENABLE_NATIVE_ALIASES | |||
| /* | |||
| #elif defined(__ARM_NEON) | |||
| # include "../sse2neon/sse2neon.h" | |||
| @@ -68,11 +48,4 @@ __m64 _mm_set1_pi16(short w) | |||
| return vreinterpret_s64_s16(vdup_n_s16(w)); | |||
| } | |||
| */ | |||
| #else | |||
| # define SIMDE_ENABLE_NATIVE_ALIASES | |||
| # include "simde/x86/sse.h" | |||
| # include "simde/x86/sse2.h" | |||
| # include "simde/x86/sse3.h" | |||
| # undef SIMDE_ENABLE_NATIVE_ALIASES | |||
| #endif | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * DISTRHO Cardinal Plugin | |||
| * Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2021-2023 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -17,7 +17,7 @@ | |||
| /** | |||
| * This file is an edited version of VCVRack's simd/Vector.hpp | |||
| * Copyright (C) 2016-2021 VCV. | |||
| * Copyright (C) 2016-2023 VCV. | |||
| * | |||
| * This program is free software: you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -0,0 +1,8 @@ | |||
| #pragma once | |||
| #ifdef __SSE4_2__ | |||
| #include <nmmintrin.h> | |||
| #else | |||
| #define SIMDE_ENABLE_NATIVE_ALIASES | |||
| #include <simde/x86/sse4.2.h> | |||
| #endif | |||
| @@ -214,10 +214,10 @@ struct HostTimeWidget : ModuleWidgetWith8HP { | |||
| const float y = startY_cv + offset * padding; | |||
| nvgBeginPath(vg); | |||
| nvgRoundedRect(vg, startX - 1.0f, y - 2.f, box.size.x - startX * 2 + 2.f, 28.f, 4); | |||
| nvgFillColor(vg, rack::settings::darkMode ? nvgRGB(0xd0, 0xd0, 0xd0) : nvgRGB(0x2f, 0x2f, 0x2f)); | |||
| nvgFillColor(vg, rack::settings::preferDarkPanels ? nvgRGB(0xd0, 0xd0, 0xd0) : nvgRGB(0x2f, 0x2f, 0x2f)); | |||
| nvgFill(vg); | |||
| nvgBeginPath(vg); | |||
| nvgFillColor(vg, rack::settings::darkMode ? color::BLACK : color::WHITE); | |||
| nvgFillColor(vg, rack::settings::preferDarkPanels ? color::BLACK : color::WHITE); | |||
| nvgText(vg, startX + 36, y + 16, text, nullptr); | |||
| } | |||
| @@ -234,11 +234,11 @@ void ImGuiTextEditor::onHoverScroll(const HoverScrollEvent& e) | |||
| void ImGuiTextEditor::step() | |||
| { | |||
| if (pData->darkMode != settings::darkMode) | |||
| if (pData->darkMode != settings::preferDarkPanels) | |||
| { | |||
| pData->darkMode = settings::darkMode; | |||
| pData->editor.SetPalette(settings::darkMode ? TextEditor::GetDarkPalette() | |||
| : TextEditor::GetLightPalette()); | |||
| pData->darkMode = settings::preferDarkPanels; | |||
| pData->editor.SetPalette(settings::preferDarkPanels ? TextEditor::GetDarkPalette() | |||
| : TextEditor::GetLightPalette()); | |||
| } | |||
| ImGuiWidget::step(); | |||
| @@ -229,7 +229,7 @@ struct ImGuiWidget::PrivateData { | |||
| colors[ImGuiCol_HeaderHovered] = color_DimCardinal; | |||
| colors[ImGuiCol_HeaderActive] = color_Cardinal; | |||
| if (!settings::darkMode) | |||
| if (!settings::preferDarkPanels) | |||
| { | |||
| for (int c = 0; c < ImGuiCol_COUNT; ++c) | |||
| { | |||
| @@ -432,9 +432,9 @@ void ImGuiWidget::onSelectText(const SelectTextEvent& e) | |||
| void ImGuiWidget::step() | |||
| { | |||
| if (imData->darkMode != settings::darkMode) | |||
| if (imData->darkMode != settings::preferDarkPanels) | |||
| { | |||
| imData->darkMode = settings::darkMode; | |||
| imData->darkMode = settings::preferDarkPanels; | |||
| imData->resetEverything(true); | |||
| } | |||
| @@ -70,7 +70,7 @@ struct ModuleWidgetWithSideScrews : ModuleWidget { | |||
| void drawBackground(NVGcontext* const vg) { | |||
| nvgBeginPath(vg); | |||
| nvgRect(vg, 0, 0, box.size.x, box.size.y); | |||
| if (rack::settings::darkMode) | |||
| if (rack::settings::preferDarkPanels) | |||
| nvgFillPaint(vg, nvgLinearGradient(vg, 0, 0, 0, box.size.y, | |||
| nvgRGB(0x18, 0x19, 0x19), nvgRGB(0x21, 0x22, 0x22))); | |||
| else | |||
| @@ -82,14 +82,14 @@ struct ModuleWidgetWithSideScrews : ModuleWidget { | |||
| void drawOutputJacksArea(NVGcontext* const vg, const int numOutputs) { | |||
| nvgBeginPath(vg); | |||
| nvgRoundedRect(vg, startX_Out - 2.5f, startY - 2.0f, padding, padding * numOutputs, 4); | |||
| nvgFillColor(vg, rack::settings::darkMode ? nvgRGB(0xd0, 0xd0, 0xd0) : nvgRGB(0x2f, 0x2f, 0x2f)); | |||
| nvgFillColor(vg, rack::settings::preferDarkPanels ? nvgRGB(0xd0, 0xd0, 0xd0) : nvgRGB(0x2f, 0x2f, 0x2f)); | |||
| nvgFill(vg); | |||
| } | |||
| void drawTextLine(NVGcontext* const vg, const uint posY, const char* const text) { | |||
| const float y = startY + posY * padding; | |||
| nvgBeginPath(vg); | |||
| nvgFillColor(vg, rack::settings::darkMode ? color::WHITE : color::BLACK); | |||
| nvgFillColor(vg, rack::settings::preferDarkPanels ? color::WHITE : color::BLACK); | |||
| nvgText(vg, box.size.x * 0.5f, y + 16, text, nullptr); | |||
| } | |||
| @@ -285,7 +285,7 @@ struct SassyScopeWidget : ImGuiWidget { | |||
| ImGui::SetNextWindowSize(ImVec2(box.size.x * scaleFactor, box.size.y * scaleFactor)); | |||
| ScopeData* const scope = module != nullptr ? &module->scope : getFakeScopeInstance(); | |||
| scope->darkMode = settings::darkMode; | |||
| scope->darkMode = settings::preferDarkPanels; | |||
| do_show_scope_window(scope, scaleFactor); | |||
| } | |||
| @@ -384,8 +384,8 @@ struct TextEditorModuleWidget : ModuleWidget { | |||
| { | |||
| nvgBeginPath(args.vg); | |||
| nvgRect(args.vg, 0.0, 0.0, box.size.x, box.size.y); | |||
| nvgFillColor(args.vg, settings::darkMode ? nvgRGB(0x20, 0x20, 0x20) | |||
| : nvgRGB(0xe6, 0xe6, 0xe6)); | |||
| nvgFillColor(args.vg, settings::preferDarkPanels ? nvgRGB(0x20, 0x20, 0x20) | |||
| : nvgRGB(0xe6, 0xe6, 0xe6)); | |||
| nvgFill(args.vg); | |||
| ModuleWidget::draw(args); | |||
| } | |||
| @@ -231,7 +231,7 @@ struct NanoKnob : Knob { | |||
| // bottom label (name) | |||
| bndIconLabelValue(args.vg, -w, knobStartY + knobSize + BND_WIDGET_HEIGHT * 0.75f, | |||
| w*3, BND_WIDGET_HEIGHT, -1, | |||
| settings::darkMode ? SCHEME_WHITE : SCHEME_BLACK, BND_CENTER, | |||
| settings::preferDarkPanels ? SCHEME_WHITE : SCHEME_BLACK, BND_CENTER, | |||
| BND_LABEL_FONT_SIZE, displayLabel.c_str(), nullptr); | |||
| } | |||
| @@ -783,8 +783,8 @@ std::vector<Model*> hostTerminalModels; | |||
| #ifndef NOPLUGINS | |||
| // stuff that reads config files, we don't want that | |||
| int loadConsoleType() { return 0; } | |||
| bool loadDarkAsDefault() { return settings::darkMode; } | |||
| ModuleTheme loadDefaultTheme() { return settings::darkMode ? DARK_THEME : LIGHT_THEME; } | |||
| bool loadDarkAsDefault() { return settings::preferDarkPanels; } | |||
| ModuleTheme loadDefaultTheme() { return settings::preferDarkPanels ? DARK_THEME : LIGHT_THEME; } | |||
| int loadDirectOutMode() { return 0; } | |||
| void readDefaultTheme() { defaultPanelTheme = loadDefaultTheme(); } | |||
| void saveConsoleType(int) {} | |||
| @@ -1558,7 +1558,7 @@ static void initStatic__BogaudioModules() | |||
| { | |||
| // Make sure to use dark theme as default | |||
| Skins& skins(Skins::skins()); | |||
| skins._default = settings::darkMode ? "dark" : "light"; | |||
| skins._default = settings::preferDarkPanels ? "dark" : "light"; | |||
| #define modelADSR modelBogaudioADSR | |||
| #define modelLFO modelBogaudioLFO | |||
| #define modelNoise modelBogaudioNoise | |||
| @@ -3173,7 +3173,7 @@ void destroyStaticPlugins() | |||
| void updateStaticPluginsDarkMode() | |||
| { | |||
| #ifndef NOPLUGINS | |||
| const bool darkMode = settings::darkMode; | |||
| const bool darkMode = settings::preferDarkPanels; | |||
| // bogaudio | |||
| { | |||
| Skins& skins(Skins::skins()); | |||
| @@ -23,49 +23,10 @@ | |||
| #include <string> | |||
| namespace rack { | |||
| #ifndef HEADLESS | |||
| namespace asset { | |||
| bool forceBlackScrew = false; | |||
| bool forceSilverScrew = false; | |||
| void updateForcingBlackSilverScrewMode(std::string slug) { | |||
| forceBlackScrew = ( | |||
| // arable instruments | |||
| slug == "Joni" | |||
| // axioma | |||
| || slug == "TheBifurcator" | |||
| || slug == "Tesseract" | |||
| || slug == "Ikeda" | |||
| || slug == "Rhodonea" | |||
| // parable instruments | |||
| || slug == "Neil" | |||
| // rackwindows | |||
| || slug == "bitshiftgain" | |||
| || slug == "capacitor" | |||
| || slug == "capacitor_stereo" | |||
| || slug == "chorus" | |||
| || slug == "console" | |||
| || slug == "console_mm" | |||
| || slug == "distance" | |||
| || slug == "golem" | |||
| || slug == "holt" | |||
| || slug == "hombre" | |||
| || slug == "interstage" | |||
| || slug == "monitoring" | |||
| || slug == "mv" | |||
| || slug == "rasp" | |||
| || slug == "reseq" | |||
| || slug == "tape" | |||
| || slug == "tremolo" | |||
| || slug == "vibrato" | |||
| ); | |||
| } | |||
| } | |||
| #endif | |||
| namespace plugin { | |||
| void updateStaticPluginsDarkMode(); | |||
| } | |||
| namespace settings { | |||
| bool darkMode = true; | |||
| int rateLimit = 0; | |||
| extern std::string uiTheme; | |||
| } | |||
| @@ -90,7 +51,7 @@ float FollowerBase::efGainMaxDecibelsDebug = 12.0f; | |||
| extern "C" { | |||
| NVGcolor nvgRGBblank(const unsigned char r, const unsigned char g, const unsigned char b) | |||
| { | |||
| return rack::settings::darkMode ? nvgRGB(0x20, 0x20, 0x20) : nvgRGB(r, g, b); | |||
| return rack::settings::preferDarkPanels ? nvgRGB(0x20, 0x20, 0x20) : nvgRGB(r, g, b); | |||
| } | |||
| } | |||
| @@ -1510,10 +1471,9 @@ namespace rack { | |||
| void switchDarkMode(const bool darkMode) | |||
| { | |||
| #ifndef HEADLESS | |||
| if (settings::darkMode == darkMode) | |||
| return; | |||
| // TODO sort this out after build with Rack2.4 succeeds | |||
| return; | |||
| settings::darkMode = darkMode; | |||
| settings::uiTheme = darkMode ? "dark" : "light"; | |||
| ui::refreshTheme(); | |||
| plugin::updateStaticPluginsDarkMode(); | |||
| @@ -1,4 +1,4 @@ | |||
| --- ../Rack/src/engine/Engine.cpp 2023-09-10 12:59:02.631898592 +0200 | |||
| --- ../Rack/src/engine/Engine.cpp 2023-12-17 12:57:01.138429358 +0100 | |||
| +++ Engine.cpp 2023-05-22 04:26:39.902464764 +0200 | |||
| @@ -1,3 +1,30 @@ | |||
| +/* | |||
| @@ -252,7 +252,7 @@ | |||
| // Meter | |||
| int meterCount = 0; | |||
| double meterTotal = 0.0; | |||
| @@ -214,33 +98,32 @@ | |||
| @@ -214,37 +98,36 @@ | |||
| double meterLastTime = -INFINITY; | |||
| double meterLastAverage = 0.0; | |||
| double meterLastMax = 0.0; | |||
| @@ -300,6 +300,11 @@ | |||
| }; | |||
| -static void Engine_updateExpander_NoLock(Engine* that, Module* module, uint8_t side) { | |||
| +static void Engine_updateExpander_NoLock(Engine* that, Module* module, bool side) { | |||
| Module::Expander& expander = side ? module->rightExpander : module->leftExpander; | |||
| Module* oldExpanderModule = expander.module; | |||
| @@ -268,89 +151,134 @@ | |||
| } | |||
| @@ -1,4 +1,4 @@ | |||
| --- ../Rack/src/app/MenuBar.cpp 2023-09-10 12:59:02.630898560 +0200 | |||
| --- ../Rack/src/app/MenuBar.cpp 2023-12-17 12:57:01.136429153 +0100 | |||
| +++ MenuBar.cpp 2023-08-15 17:56:23.782915145 +0200 | |||
| @@ -1,8 +1,33 @@ | |||
| +/* | |||
| @@ -248,26 +248,26 @@ | |||
| + wasmSaveAs(); | |||
| + else | |||
| + patchUtils::saveDialog(APP->patch->path); | |||
| })); | |||
| - menu->addChild(createMenuItem("Save as", RACK_MOD_CTRL_NAME "+Shift+S", []() { | |||
| - APP->patch->saveAsDialog(); | |||
| + })); | |||
| + | |||
| + menu->addChild(createMenuItem("Save as...", "", []() { | |||
| + wasmSaveAs(); | |||
| })); | |||
| - menu->addChild(createMenuItem("Save a copy", "", []() { | |||
| - APP->patch->saveAsDialog(false); | |||
| - menu->addChild(createMenuItem("Save as", RACK_MOD_CTRL_NAME "+Shift+S", []() { | |||
| - APP->patch->saveAsDialog(); | |||
| + menu->addChild(createMenuItem("Save and download compressed", "", []() { | |||
| + patchUtils::saveAsDialog(); | |||
| })); | |||
| - menu->addChild(createMenuItem("Save a copy", "", []() { | |||
| - APP->patch->saveAsDialog(false); | |||
| + menu->addChild(createMenuItem("Save and download uncompressed", "", []() { | |||
| + patchUtils::saveAsDialogUncompressed(); | |||
| + })); | |||
| })); | |||
| +#endif | |||
| +#endif | |||
| + | |||
| menu->addChild(createMenuItem("Revert", RACK_MOD_CTRL_NAME "+" RACK_MOD_SHIFT_NAME "+O", []() { | |||
| - APP->patch->revertDialog(); | |||
| - }, APP->patch->path == "")); | |||
| @@ -462,11 +462,11 @@ | |||
| static const std::vector<std::string> knobModeLabels = { | |||
| "Linear", | |||
| @@ -487,11 +692,34 @@ | |||
| @@ -487,13 +692,34 @@ | |||
| menu->addChild(knobScrollSensitivitySlider); | |||
| menu->addChild(new ui::MenuSeparator); | |||
| - menu->addChild(createMenuLabel("Module")); | |||
| - menu->addChild(createMenuLabel("Modules")); | |||
| + menu->addChild(createMenuLabel("Window")); | |||
| - menu->addChild(createBoolPtrMenuItem("Lock positions", "", &settings::lockModules)); | |||
| @@ -480,9 +480,10 @@ | |||
| + })); | |||
| +#endif | |||
| - menu->addChild(createBoolPtrMenuItem("Auto-squeeze algorithm (experimental)", "", &settings::squeezeModules)); | |||
| - menu->addChild(createBoolPtrMenuItem("Smart rearrangement", "", &settings::squeezeModules)); | |||
| + menu->addChild(createBoolPtrMenuItem("Invert zoom", "", &settings::invertZoom)); | |||
| + | |||
| - menu->addChild(createBoolPtrMenuItem("Use dark panels if available (experimental)", "", &settings::preferDarkPanels)); | |||
| + static const std::vector<std::string> rateLimitLabels = { | |||
| + "None", | |||
| + "2x", | |||
| @@ -500,7 +501,7 @@ | |||
| } | |||
| }; | |||
| @@ -501,48 +729,11 @@ | |||
| @@ -503,48 +729,11 @@ | |||
| //////////////////// | |||
| @@ -553,7 +554,7 @@ | |||
| void onAction(const ActionEvent& e) override { | |||
| ui::Menu* menu = createMenu(); | |||
| menu->cornerFlags = BND_CORNER_TOP; | |||
| @@ -555,269 +746,87 @@ | |||
| @@ -557,292 +746,87 @@ | |||
| settings::cpuMeter ^= true; | |||
| })); | |||
| @@ -664,26 +665,42 @@ | |||
| - return NULL; | |||
| - library::UpdateInfo update = it->second; | |||
| - | |||
| - if (update.changelogUrl == "") | |||
| - return NULL; | |||
| - | |||
| - ui::Menu* menu = new ui::Menu; | |||
| - | |||
| - std::string changelogUrl = update.changelogUrl; | |||
| - menu->addChild(createMenuItem("Changelog", "", [=]() { | |||
| - system::openBrowser(changelogUrl); | |||
| - })); | |||
| - if (update.minRackVersion != "") { | |||
| - menu->addChild(createMenuLabel(string::f("Requires Rack %s+", update.minRackVersion.c_str()))); | |||
| - } | |||
| - | |||
| - if (update.changelogUrl != "") { | |||
| - std::string changelogUrl = update.changelogUrl; | |||
| - menu->addChild(createMenuItem("Changelog", "", [=]() { | |||
| - system::openBrowser(changelogUrl); | |||
| - })); | |||
| - } | |||
| - | |||
| - if (menu->children.empty()) { | |||
| - delete menu; | |||
| - return NULL; | |||
| - } | |||
| - return menu; | |||
| - } | |||
| - | |||
| - void step() override { | |||
| - disabled = library::isSyncing; | |||
| - disabled = false; | |||
| - | |||
| - if (library::isSyncing) | |||
| - disabled = true; | |||
| - | |||
| - auto it = library::updateInfos.find(slug); | |||
| - if (it != library::updateInfos.end()) { | |||
| - if (it == library::updateInfos.end()) { | |||
| - disabled = true; | |||
| - } | |||
| - else { | |||
| - library::UpdateInfo update = it->second; | |||
| - | |||
| - if (update.minRackVersion != "") | |||
| - disabled = true; | |||
| - | |||
| - if (update.downloaded) { | |||
| - rightText = CHECKMARK_STRING; | |||
| - disabled = true; | |||
| @@ -713,7 +730,7 @@ | |||
| - rightText += update.version; | |||
| - } | |||
| - } | |||
| - | |||
| - MenuItem::step(); | |||
| - } | |||
| - | |||
| @@ -725,18 +742,13 @@ | |||
| - e.unconsume(); | |||
| - } | |||
| -}; | |||
| + async_dialog_text_input("OSC network port", CARDINAL_DEFAULT_REMOTE_PORT, [=](char* const port) { | |||
| + if (port == nullptr) | |||
| + return; | |||
| + if (plugin->startRemoteServer(port)) | |||
| + remoteServerStarted = true; | |||
| - | |||
| - | |||
| -struct LibraryMenu : ui::Menu { | |||
| - LibraryMenu() { | |||
| - refresh(); | |||
| - } | |||
| - | |||
| - void step() override { | |||
| - // Refresh menu when appropriate | |||
| - if (library::refreshRequested) { | |||
| @@ -745,11 +757,16 @@ | |||
| - } | |||
| - Menu::step(); | |||
| - } | |||
| - | |||
| + async_dialog_text_input("OSC network port", CARDINAL_DEFAULT_REMOTE_PORT, [=](char* const port) { | |||
| + if (port == nullptr) | |||
| + return; | |||
| - void refresh() { | |||
| - setChildMenu(NULL); | |||
| - clearChildren(); | |||
| - | |||
| + if (plugin->startRemoteServer(port)) | |||
| + remoteServerStarted = true; | |||
| - if (settings::devMode) { | |||
| - addChild(createMenuLabel("Disabled in development mode")); | |||
| - } | |||
| @@ -759,9 +776,7 @@ | |||
| + std::free(port); | |||
| + }); | |||
| })); | |||
| + } | |||
| +#endif | |||
| - | |||
| - ui::TextField* emailField = new ui::TextField; | |||
| - emailField->placeholder = "Email"; | |||
| - emailField->box.size.x = 240.0; | |||
| @@ -779,11 +794,34 @@ | |||
| - logInItem->passwordField = passwordField; | |||
| - passwordField->logInItem = logInItem; | |||
| - addChild(logInItem); | |||
| - } | |||
| } | |||
| - else { | |||
| - addChild(createMenuItem("Log out", "", [=]() { | |||
| - library::logOut(); | |||
| - })); | |||
| +#endif | |||
| - addChild(createMenuItem("Account settings", "", [=]() { | |||
| - system::openBrowser("https://vcvrack.com/account"); | |||
| - })); | |||
| - | |||
| - addChild(createMenuItem("Browse VCV Library", "", [=]() { | |||
| - system::openBrowser("https://library.vcvrack.com/"); | |||
| - })); | |||
| - | |||
| - SyncUpdatesItem* syncItem = new SyncUpdatesItem; | |||
| - syncItem->text = "Update all"; | |||
| - addChild(syncItem); | |||
| - | |||
| - if (!library::updateInfos.empty()) { | |||
| - addChild(new ui::MenuSeparator); | |||
| - addChild(createMenuLabel("Updates")); | |||
| - | |||
| - for (auto& pair : library::updateInfos) { | |||
| - SyncUpdateItem* updateItem = new SyncUpdateItem; | |||
| - updateItem->setUpdate(pair.first); | |||
| - addChild(updateItem); | |||
| - } | |||
| + if (isUsingNativeAudio()) { | |||
| + if (supportsAudioInput()) { | |||
| + const bool enabled = isAudioInputEnabled(); | |||
| @@ -794,11 +832,11 @@ | |||
| + if (!enabled) | |||
| + requestAudioInput(); | |||
| + })); | |||
| + } | |||
| } | |||
| - } | |||
| - } | |||
| -}; | |||
| - addChild(createMenuItem("Browse VCV Library", "", [=]() { | |||
| - system::openBrowser("https://library.vcvrack.com/"); | |||
| - })); | |||
| + if (supportsMIDI()) { | |||
| + std::string rightText; | |||
| + if (isMIDIEnabled()) | |||
| @@ -808,19 +846,26 @@ | |||
| + })); | |||
| + } | |||
| - SyncUpdatesItem* syncItem = new SyncUpdatesItem; | |||
| - syncItem->text = "Update all"; | |||
| - addChild(syncItem); | |||
| -struct LibraryButton : MenuButton { | |||
| - NotificationIcon* notification; | |||
| - | |||
| - if (!library::updateInfos.empty()) { | |||
| - addChild(new ui::MenuSeparator); | |||
| - addChild(createMenuLabel("Updates")); | |||
| - LibraryButton() { | |||
| - notification = new NotificationIcon; | |||
| - addChild(notification); | |||
| - } | |||
| - | |||
| - for (auto& pair : library::updateInfos) { | |||
| - SyncUpdateItem* updateItem = new SyncUpdateItem; | |||
| - updateItem->setUpdate(pair.first); | |||
| - addChild(updateItem); | |||
| - } | |||
| - void onAction(const ActionEvent& e) override { | |||
| - ui::Menu* menu = createMenu<LibraryMenu>(); | |||
| - menu->cornerFlags = BND_CORNER_TOP; | |||
| - menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y)); | |||
| - | |||
| - // Check for updates when menu is opened | |||
| - if (!settings::devMode) { | |||
| - std::thread t([&]() { | |||
| - system::setThreadName("Library"); | |||
| - library::checkUpdates(); | |||
| - }); | |||
| - t.detach(); | |||
| + if (supportsBufferSizeChanges()) { | |||
| + static const std::vector<uint32_t> bufferSizes = { | |||
| + #ifdef DISTRHO_OS_WASM | |||
| @@ -838,31 +883,9 @@ | |||
| + )); | |||
| + } | |||
| + })); | |||
| } | |||
| + } | |||
| } | |||
| } | |||
| -}; | |||
| - | |||
| - | |||
| -struct LibraryButton : MenuButton { | |||
| - NotificationIcon* notification; | |||
| - | |||
| - LibraryButton() { | |||
| - notification = new NotificationIcon; | |||
| - addChild(notification); | |||
| - } | |||
| - | |||
| - void onAction(const ActionEvent& e) override { | |||
| - ui::Menu* menu = createMenu<LibraryMenu>(); | |||
| - menu->cornerFlags = BND_CORNER_TOP; | |||
| - menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y)); | |||
| - // Check for updates when menu is opened | |||
| - std::thread t([&]() { | |||
| - system::setThreadName("Library"); | |||
| - library::checkUpdates(); | |||
| - }); | |||
| - t.detach(); | |||
| - } | |||
| +#ifdef HAVE_LIBLO | |||
| void step() override { | |||
| @@ -888,7 +911,7 @@ | |||
| }; | |||
| @@ -827,63 +836,30 @@ | |||
| @@ -852,63 +836,30 @@ | |||
| struct HelpButton : MenuButton { | |||
| @@ -906,14 +929,14 @@ | |||
| - menu->addChild(createMenuItem("Tips", "", [=]() { | |||
| - APP->scene->addChild(tipWindowCreate()); | |||
| - })); | |||
| - | |||
| - menu->addChild(createMenuItem("User manual", "F1", [=]() { | |||
| - system::openBrowser("https://vcvrack.com/manual"); | |||
| + menu->addChild(createMenuItem("Rack User manual", "F1", [=]() { | |||
| + patchUtils::openBrowser("https://vcvrack.com/manual"); | |||
| })); | |||
| - menu->addChild(createMenuItem("User manual", "F1", [=]() { | |||
| - system::openBrowser("https://vcvrack.com/manual"); | |||
| - })); | |||
| - | |||
| - menu->addChild(createMenuItem("Support", "", [=]() { | |||
| - system::openBrowser("https://vcvrack.com/support"); | |||
| - })); | |||
| @@ -960,7 +983,7 @@ | |||
| } | |||
| }; | |||
| @@ -926,15 +902,19 @@ | |||
| @@ -951,15 +902,19 @@ | |||
| text = ""; | |||
| @@ -983,7 +1006,7 @@ | |||
| Label::step(); | |||
| } | |||
| @@ -944,7 +924,9 @@ | |||
| @@ -969,7 +924,9 @@ | |||
| struct MenuBar : widget::OpaqueWidget { | |||
| InfoLabel* infoLabel; | |||
| @@ -994,7 +1017,7 @@ | |||
| const float margin = 5; | |||
| box.size.y = BND_WIDGET_HEIGHT + 2 * margin; | |||
| @@ -953,7 +935,7 @@ | |||
| @@ -978,7 +935,7 @@ | |||
| layout->spacing = math::Vec(0, 0); | |||
| addChild(layout); | |||
| @@ -1003,7 +1026,7 @@ | |||
| fileButton->text = "File"; | |||
| layout->addChild(fileButton); | |||
| @@ -965,13 +947,11 @@ | |||
| @@ -990,13 +947,11 @@ | |||
| viewButton->text = "View"; | |||
| layout->addChild(viewButton); | |||
| @@ -1019,7 +1042,7 @@ | |||
| HelpButton* helpButton = new HelpButton; | |||
| helpButton->text = "Help"; | |||
| @@ -1003,7 +983,7 @@ | |||
| @@ -1028,7 +983,7 @@ | |||
| widget::Widget* createMenuBar() { | |||
| @@ -1,4 +1,4 @@ | |||
| --- ../Rack/src/app/ModuleWidget.cpp 2023-09-10 12:59:02.630898560 +0200 | |||
| --- ../Rack/src/app/ModuleWidget.cpp 2023-12-17 12:57:01.136429153 +0100 | |||
| +++ ModuleWidget.cpp 2023-05-20 18:40:08.948302802 +0200 | |||
| @@ -1,8 +1,35 @@ | |||
| +/* | |||
| @@ -167,7 +167,20 @@ | |||
| } | |||
| })); | |||
| } | |||
| @@ -1129,4 +1165,4 @@ | |||
| @@ -990,12 +1026,6 @@ | |||
| // Info | |||
| menu->addChild(createSubmenuItem("Info", "", [=](ui::Menu* menu) { | |||
| model->appendContextMenu(menu); | |||
| - | |||
| - if (!weakThis) | |||
| - return; | |||
| - menu->addChild(new ui::MenuSeparator); | |||
| - menu->addChild(createMenuLabel("Module instance ID:")); | |||
| - menu->addChild(createMenuLabel(string::f("%lld", (long long) weakThis->module->getId()))); | |||
| })); | |||
| // Preset | |||
| @@ -1135,4 +1165,4 @@ | |||
| } // namespace app | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/app/Scene.cpp 2022-09-21 20:49:12.199540706 +0200 | |||
| +++ Scene.cpp 2023-07-03 09:30:14.548718644 +0200 | |||
| +++ Scene.cpp 2023-10-21 13:42:59.503556170 +0200 | |||
| @@ -1,12 +1,36 @@ | |||
| -#include <thread> | |||
| - | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/window/Window.cpp 2023-09-10 12:59:02.631898592 +0200 | |||
| +++ Window.cpp 2023-08-28 09:55:57.292032175 +0200 | |||
| --- ../Rack/src/window/Window.cpp 2023-12-17 12:57:01.139429461 +0100 | |||
| +++ Window.cpp 2023-10-22 13:33:43.777041594 +0200 | |||
| @@ -1,33 +1,94 @@ | |||
| +/* | |||
| + * DISTRHO Cardinal Plugin | |||
| @@ -119,7 +119,7 @@ | |||
| throw Exception("Failed to load font %s", filename.c_str()); | |||
| } | |||
| INFO("Loaded font %s", filename.c_str()); | |||
| @@ -79,338 +139,478 @@ | |||
| @@ -79,340 +139,478 @@ | |||
| } | |||
| @@ -194,7 +194,7 @@ | |||
| + Internal() | |||
| +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | |||
| + : hiddenApp(false), | |||
| + hiddenWindow(hiddenApp) | |||
| + hiddenWindow(hiddenApp, 0, DISTRHO_UI_DEFAULT_WIDTH, DISTRHO_UI_DEFAULT_HEIGHT, 0.0, true) | |||
| + { | |||
| + hiddenWindow.setIgnoringKeyRepeat(true); | |||
| + hiddenApp.idle(); | |||
| @@ -269,7 +269,7 @@ | |||
| - int cursorMode = glfwGetInputMode(win, GLFW_CURSOR); | |||
| - (void) cursorMode; | |||
| +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | |||
| + DGL_NAMESPACE::Window::ScopedGraphicsContext sgc(internal->hiddenWindow); | |||
| + const DGL_NAMESPACE::Window::ScopedGraphicsContext sgc(internal->hiddenWindow); | |||
| + vg = nvgCreateGL(nvgFlags); | |||
| +#else | |||
| + vg = static_cast<CardinalPluginContext*>(APP)->tlw->getContext(); | |||
| @@ -684,6 +684,7 @@ | |||
| - if (APP->scene) { | |||
| - widget::Widget::ContextCreateEvent e; | |||
| - e.vg = vg; | |||
| - APP->scene->onContextCreate(e); | |||
| +#if defined NANOVG_GLES2 | |||
| + nvgDeleteGLES2(window->internal->r_fbVg); | |||
| @@ -706,6 +707,7 @@ | |||
| Window::~Window() { | |||
| - if (APP->scene) { | |||
| - widget::Widget::ContextDestroyEvent e; | |||
| - e.vg = vg; | |||
| - APP->scene->onContextDestroy(e); | |||
| - } | |||
| + { | |||
| @@ -852,7 +854,7 @@ | |||
| double frameTime = system::getTime(); | |||
| if (std::isfinite(internal->frameTime)) { | |||
| internal->lastFrameDuration = frameTime - internal->frameTime; | |||
| @@ -422,57 +622,52 @@ | |||
| @@ -424,57 +622,52 @@ | |||
| // Make event handlers and step() have a clean NanoVG context | |||
| nvgReset(vg); | |||
| @@ -945,7 +947,7 @@ | |||
| windowRatio = (float)fbWidth / winWidth; | |||
| // t1 = system::getTime(); | |||
| @@ -486,10 +681,8 @@ | |||
| @@ -488,10 +681,8 @@ | |||
| // t2 = system::getTime(); | |||
| // Render scene | |||
| @@ -957,7 +959,7 @@ | |||
| nvgScale(vg, pixelRatio, pixelRatio); | |||
| // Draw scene | |||
| @@ -500,23 +693,16 @@ | |||
| @@ -502,23 +693,16 @@ | |||
| // t3 = system::getTime(); | |||
| glViewport(0, 0, fbWidth, fbHeight); | |||
| @@ -985,7 +987,7 @@ | |||
| // t5 = system::getTime(); | |||
| // DEBUG("pre-step %6.1f step %6.1f draw %6.1f nvgEndFrame %6.1f glfwSwapBuffers %6.1f total %6.1f", | |||
| // (t1 - frameTime) * 1e3f, | |||
| @@ -526,163 +712,132 @@ | |||
| @@ -528,168 +712,132 @@ | |||
| // (t5 - t4) * 1e3f, | |||
| // (t5 - frameTime) * 1e3f | |||
| // ); | |||
| @@ -1068,6 +1070,11 @@ | |||
| void Window::screenshotModules(const std::string& screenshotsDir, float zoom) { | |||
| - // Disable preferDarkPanels | |||
| - bool preferDarkPanels = settings::preferDarkPanels; | |||
| - settings::preferDarkPanels = false; | |||
| - DEFER({settings::preferDarkPanels = preferDarkPanels;}); | |||
| - | |||
| - // Iterate plugins and create directories | |||
| - system::createDirectories(screenshotsDir); | |||
| - for (plugin::Plugin* p : plugin::plugins) { | |||
| @@ -1227,7 +1234,7 @@ | |||
| } | |||
| @@ -702,7 +857,7 @@ | |||
| @@ -709,7 +857,7 @@ | |||
| double Window::getFrameDurationRemaining() { | |||
| @@ -1236,7 +1243,7 @@ | |||
| return frameDuration - (system::getTime() - internal->frameTime); | |||
| } | |||
| @@ -713,14 +868,15 @@ | |||
| @@ -720,14 +868,15 @@ | |||
| return pair->second; | |||
| // Load font | |||
| @@ -1255,7 +1262,7 @@ | |||
| } | |||
| internal->fontCache[filename] = font; | |||
| return font; | |||
| @@ -733,14 +889,15 @@ | |||
| @@ -740,14 +889,15 @@ | |||
| return pair->second; | |||
| // Load image | |||
| @@ -1274,7 +1281,7 @@ | |||
| } | |||
| internal->imageCache[filename] = image; | |||
| return image; | |||
| @@ -757,28 +914,156 @@ | |||
| @@ -764,28 +914,156 @@ | |||
| } | |||
| @@ -1,4 +1,4 @@ | |||
| --- ../Rack/src/context.cpp 2023-09-10 12:59:02.630898560 +0200 | |||
| --- ../Rack/src/context.cpp 2023-12-17 12:57:01.137429255 +0100 | |||
| +++ context.cpp 2023-05-20 18:08:56.497736615 +0200 | |||
| @@ -1,14 +1,44 @@ | |||
| +/* | |||
| @@ -47,7 +47,7 @@ | |||
| Context::~Context() { | |||
| // Deleting NULL is safe in C++. | |||
| @@ -38,17 +68,13 @@ | |||
| @@ -38,16 +68,13 @@ | |||
| INFO("Deleting engine"); | |||
| delete engine; | |||
| engine = NULL; | |||
| @@ -61,7 +61,6 @@ | |||
| static thread_local Context* threadContext = NULL; | |||
| Context* contextGet() { | |||
| - assert(threadContext); | |||
| + DISTRHO_SAFE_ASSERT(threadContext != nullptr); | |||
| return threadContext; | |||
| } | |||
| @@ -1,4 +1,4 @@ | |||
| --- ../Rack/include/engine/Port.hpp 2023-09-10 12:59:02.629898529 +0200 | |||
| --- ../Rack/include/engine/Port.hpp 2023-12-17 12:57:01.129428435 +0100 | |||
| +++ ../../include/engine/Port.hpp 2023-07-07 18:20:12.030329564 +0200 | |||
| @@ -1,19 +1,57 @@ | |||
| +/* | |||
| @@ -60,11 +60,11 @@ | |||
| /** Unstable API. Use getVoltage() and setVoltage() instead. */ | |||
| float voltages[PORT_MAX_CHANNELS] = {}; | |||
| /** DEPRECATED. Unstable API. Use getVoltage() and setVoltage() instead. */ | |||
| @@ -40,40 +78,40 @@ | |||
| @@ -40,41 +78,41 @@ | |||
| }; | |||
| /** Sets the voltage of the given channel. */ | |||
| - void setVoltage(float voltage, int channel = 0) { | |||
| - void setVoltage(float voltage, uint8_t channel = 0) { | |||
| + void setVoltage(float voltage, int channel = 0) noexcept { | |||
| voltages[channel] = voltage; | |||
| } | |||
| @@ -72,24 +72,24 @@ | |||
| /** Returns the voltage of the given channel. | |||
| Because of proper bookkeeping, all channels higher than the input port's number of channels should be 0V. | |||
| */ | |||
| - float getVoltage(int channel = 0) { | |||
| - float getVoltage(uint8_t channel = 0) { | |||
| + float getVoltage(int channel = 0) const noexcept { | |||
| return voltages[channel]; | |||
| } | |||
| /** Returns the given channel's voltage if the port is polyphonic, otherwise returns the first voltage (channel 0). */ | |||
| - float getPolyVoltage(int channel) { | |||
| - float getPolyVoltage(uint8_t channel) { | |||
| + float getPolyVoltage(int channel) const noexcept { | |||
| return isMonophonic() ? getVoltage(0) : getVoltage(channel); | |||
| } | |||
| /** Returns the voltage if a cable is connected, otherwise returns the given normal voltage. */ | |||
| - float getNormalVoltage(float normalVoltage, int channel = 0) { | |||
| - float getNormalVoltage(float normalVoltage, uint8_t channel = 0) { | |||
| + float getNormalVoltage(float normalVoltage, int channel = 0) const noexcept { | |||
| return isConnected() ? getVoltage(channel) : normalVoltage; | |||
| } | |||
| - float getNormalPolyVoltage(float normalVoltage, int channel) { | |||
| - float getNormalPolyVoltage(float normalVoltage, uint8_t channel) { | |||
| + float getNormalPolyVoltage(float normalVoltage, int channel) const noexcept { | |||
| return isConnected() ? getPolyVoltage(channel) : normalVoltage; | |||
| } | |||
| @@ -97,24 +97,34 @@ | |||
| /** Returns a pointer to the array of voltages beginning with firstChannel. | |||
| The pointer can be used for reading and writing. | |||
| */ | |||
| - float* getVoltages(int firstChannel = 0) { | |||
| - float* getVoltages(uint8_t firstChannel = 0) { | |||
| + float* getVoltages(int firstChannel = 0) noexcept { | |||
| return &voltages[firstChannel]; | |||
| } | |||
| /** Copies the port's voltages to an array of size at least `channels`. */ | |||
| - void readVoltages(float* v) { | |||
| - for (uint8_t c = 0; c < channels; c++) { | |||
| + void readVoltages(float* v) const noexcept { | |||
| for (int c = 0; c < channels; c++) { | |||
| + for (int c = 0; c < channels; c++) { | |||
| v[c] = voltages[c]; | |||
| } | |||
| @@ -89,14 +127,14 @@ | |||
| } | |||
| @@ -83,22 +121,22 @@ | |||
| Remember to set the number of channels *before* calling this method. | |||
| */ | |||
| void writeVoltages(const float* v) { | |||
| - for (uint8_t c = 0; c < channels; c++) { | |||
| + for (int c = 0; c < channels; c++) { | |||
| voltages[c] = v[c]; | |||
| } | |||
| } | |||
| /** Sets all voltages to 0. */ | |||
| - void clearVoltages() { | |||
| - for (uint8_t c = 0; c < channels; c++) { | |||
| + void clearVoltages() noexcept { | |||
| for (int c = 0; c < channels; c++) { | |||
| + for (int c = 0; c < channels; c++) { | |||
| voltages[c] = 0.f; | |||
| } | |||
| } | |||
| @@ -123,8 +133,11 @@ | |||
| - float getVoltageSum() { | |||
| + float getVoltageSum() const noexcept { | |||
| float sum = 0.f; | |||
| for (int c = 0; c < channels; c++) { | |||
| - for (uint8_t c = 0; c < channels; c++) { | |||
| + for (int c = 0; c < channels; c++) { | |||
| sum += voltages[c]; | |||
| } | |||
| return sum; | |||
| @@ -107,7 +145,7 @@ | |||
| /** Returns the root-mean-square of all voltages. | |||
| Uses sqrt() which is slow, so use a custom approximation if calling frequently. | |||
| @@ -134,45 +147,61 @@ | |||
| if (channels == 0) { | |||
| return 0.f; | |||
| } | |||
| @@ -124,22 +162,22 @@ | |||
| @@ -116,7 +154,7 @@ | |||
| } | |||
| else { | |||
| float sum = 0.f; | |||
| - for (uint8_t c = 0; c < channels; c++) { | |||
| + for (int c = 0; c < channels; c++) { | |||
| sum += std::pow(voltages[c], 2); | |||
| } | |||
| return std::sqrt(sum); | |||
| @@ -124,27 +162,27 @@ | |||
| } | |||
| template <typename T> | |||
| - T getVoltageSimd(int firstChannel) { | |||
| - T getVoltageSimd(uint8_t firstChannel) { | |||
| + T getVoltageSimd(int firstChannel) const noexcept { | |||
| return T::load(&voltages[firstChannel]); | |||
| } | |||
| template <typename T> | |||
| - T getPolyVoltageSimd(int firstChannel) { | |||
| - T getPolyVoltageSimd(uint8_t firstChannel) { | |||
| + T getPolyVoltageSimd(int firstChannel) const noexcept { | |||
| return isMonophonic() ? getVoltage(0) : getVoltageSimd<T>(firstChannel); | |||
| } | |||
| template <typename T> | |||
| - T getNormalVoltageSimd(T normalVoltage, int firstChannel) { | |||
| - T getNormalVoltageSimd(T normalVoltage, uint8_t firstChannel) { | |||
| + T getNormalVoltageSimd(T normalVoltage, int firstChannel) const noexcept { | |||
| return isConnected() ? getVoltageSimd<T>(firstChannel) : normalVoltage; | |||
| } | |||
| template <typename T> | |||
| - T getNormalPolyVoltageSimd(T normalVoltage, int firstChannel) { | |||
| - T getNormalPolyVoltageSimd(T normalVoltage, uint8_t firstChannel) { | |||
| + T getNormalPolyVoltageSimd(T normalVoltage, int firstChannel) const noexcept { | |||
| return isConnected() ? getPolyVoltageSimd<T>(firstChannel) : normalVoltage; | |||
| } | |||
| template <typename T> | |||
| - void setVoltageSimd(T voltage, uint8_t firstChannel) { | |||
| + void setVoltageSimd(T voltage, int firstChannel) { | |||
| voltage.store(&voltages[firstChannel]); | |||
| } | |||
| @@ -153,13 +191,15 @@ | |||
| If disconnected, this does nothing (`channels` remains 0). | |||
| If 0 is given, `channels` is set to 1 but all voltages are cleared. | |||
| */ | |||
| - void setChannels(int channels) { | |||
| - void setChannels(uint8_t channels) { | |||
| + void setChannels(int channels) noexcept { | |||
| // If disconnected, keep the number of channels at 0. | |||
| if (this->channels == 0) { | |||
| return; | |||
| } | |||
| // Set higher channel voltages to 0 | |||
| for (int c = channels; c < this->channels; c++) { | |||
| - for (uint8_t c = channels; c < this->channels; c++) { | |||
| + for (int c = channels; c < this->channels; c++) { | |||
| + if (c >= PORT_MAX_CHANNELS) | |||
| + __builtin_unreachable(); | |||
| voltages[c] = 0.f; | |||
| @@ -1,6 +1,6 @@ | |||
| --- ../Rack/src/plugin.cpp 2023-09-10 12:59:02.631898592 +0200 | |||
| --- ../Rack/src/plugin.cpp 2023-12-17 12:57:01.138429358 +0100 | |||
| +++ plugin.cpp 2023-05-20 18:43:27.496323540 +0200 | |||
| @@ -1,356 +1,46 @@ | |||
| @@ -1,363 +1,46 @@ | |||
| -#include <thread> | |||
| -#include <map> | |||
| -#include <stdexcept> | |||
| @@ -134,14 +134,7 @@ | |||
| - libraryExt = "dylib"; | |||
| -#endif | |||
| - | |||
| -#if defined ARCH_X64 | |||
| - // Use `plugin.EXT` on x64 for backward compatibility. | |||
| - // Change to `plugin-OS-CPU.EXT` in Rack 3. | |||
| - std::string libraryFilename = "plugin." + libraryExt; | |||
| -#else | |||
| - // Use `plugin-CPU.EXT` on other CPUs like ARM64 | |||
| - std::string libraryFilename = "plugin-" + APP_CPU + "." + libraryExt; | |||
| -#endif | |||
| - std::string libraryPath = system::join(plugin->path, libraryFilename); | |||
| - | |||
| - // Check file existence | |||
| @@ -291,9 +284,23 @@ | |||
| - // Load Core | |||
| - loadPlugin(""); | |||
| - | |||
| - pluginsPath = asset::user("plugins"); | |||
| - | |||
| - // Get user plugins directory | |||
| - if (settings::devMode) { | |||
| - pluginsPath = asset::user("plugins"); | |||
| - } | |||
| - else { | |||
| - pluginsPath = asset::user("plugins-" + APP_OS + "-" + APP_CPU); | |||
| - } | |||
| - | |||
| - // In Rack <2.4.0, plugins dir was "plugins" regardless of arch. | |||
| - // Rename old dir if running x64. | |||
| -#if defined ARCH_X64 | |||
| - std::string oldPluginsPath = asset::user("plugins"); | |||
| - if (system::isDirectory(oldPluginsPath)) { | |||
| - system::rename(oldPluginsPath, pluginsPath); | |||
| - } | |||
| -#endif | |||
| - | |||
| - system::createDirectory(pluginsPath); | |||
| - | |||
| - // Don't load plugins if safe mode is enabled | |||
| @@ -387,7 +394,15 @@ | |||
| */ | |||
| static const std::map<std::string, std::string> pluginSlugFallbacks = { | |||
| {"VultModulesFree", "VultModules"}, | |||
| @@ -399,8 +89,19 @@ | |||
| @@ -365,7 +48,6 @@ | |||
| {"AudibleInstrumentsPreview", "AudibleInstruments"}, | |||
| {"SequelSequencers", "DanielDavies"}, | |||
| {"DelexanderVol1", "DelexandraVol1"}, | |||
| - {"VCV-Pro", "Fundamental"}, | |||
| // {"", ""}, | |||
| }; | |||
| @@ -407,8 +89,19 @@ | |||
| */ | |||
| using PluginModuleSlug = std::tuple<std::string, std::string>; | |||
| static const std::map<PluginModuleSlug, PluginModuleSlug> moduleSlugFallbacks = { | |||
| @@ -408,7 +423,7 @@ | |||
| // {{"", ""}, {"", ""}}, | |||
| }; | |||
| @@ -488,7 +189,6 @@ | |||
| @@ -496,7 +189,6 @@ | |||
| } | |||