Browse Source

Fixup code style, regen Rack diffs

Signed-off-by: falkTX <falktx@falktx.com>
tags/22.11
falkTX 2 years ago
parent
commit
eb730b6c33
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
14 changed files with 519 additions and 299 deletions
  1. +1
    -1
      .github/workflows/irc.yml
  2. +1
    -0
      src/override/.generate-diffs.sh
  3. +6
    -6
      src/override/Engine.cpp
  4. +144
    -57
      src/override/diffs/Engine.cpp.diff
  5. +128
    -77
      src/override/diffs/MenuBar.cpp.diff
  6. +2
    -2
      src/override/diffs/Model.cpp.diff
  7. +2
    -2
      src/override/diffs/OpenGlWidget.cpp.diff
  8. +2
    -2
      src/override/diffs/Scene.cpp.diff
  9. +163
    -144
      src/override/diffs/Window.cpp.diff
  10. +2
    -2
      src/override/diffs/blendish.c.diff
  11. +2
    -2
      src/override/diffs/common.cpp.diff
  12. +2
    -2
      src/override/diffs/context.cpp.diff
  13. +62
    -0
      src/override/diffs/minblep.cpp.diff
  14. +2
    -2
      src/override/diffs/plugin.cpp.diff

+ 1
- 1
.github/workflows/irc.yml View File

@@ -9,7 +9,7 @@ jobs:
steps:
- name: Format message
run: |
echo commitmessage=$(echo "${{ github.event.commits[0].message }}" | head -n 1) >> $GITHUB_ENV
echo commitmessage=$(echo "${{ github.event.commits[0].message }}" | head -n 1) >> $GITHUB_ENV
- name: Format message
run: |
echo message="${{ github.actor }} pushed ${{ env.commitmessage }} ${{ github.event.commits[0].url }}" >> $GITHUB_ENV


+ 1
- 0
src/override/.generate-diffs.sh View File

@@ -9,6 +9,7 @@ diff -U3 ../Rack/src/plugin.cpp plugin.cpp > diffs/plugin.cpp.diff
diff -U3 ../Rack/src/app/MenuBar.cpp MenuBar.cpp > diffs/MenuBar.cpp.diff
diff -U3 ../Rack/src/app/Scene.cpp Scene.cpp > diffs/Scene.cpp.diff
diff -U3 ../Rack/src/engine/Engine.cpp Engine.cpp > diffs/Engine.cpp.diff
diff -U3 ../Rack/src/dsp/minblep.cpp minblep.cpp > diffs/minblep.cpp.diff
diff -U3 ../Rack/src/plugin/Model.cpp Model.cpp > diffs/Model.cpp.diff
diff -U3 ../Rack/src/widget/OpenGlWidget.cpp OpenGlWidget.cpp > diffs/OpenGlWidget.cpp.diff
diff -U3 ../Rack/src/window/Window.cpp Window.cpp > diffs/Window.cpp.diff

+ 6
- 6
src/override/Engine.cpp View File

@@ -283,21 +283,21 @@ template<typename T>
using IdentityDictionary = std::unordered_map<T, T>;

template<typename T>
inline bool dictContains(IdentityDictionary<T> &dict, T key) {
inline bool dictContains(IdentityDictionary<T>& dict, T key) {
return dict.find(key) != dict.end();
}

template<typename T>
inline void dictAdd(IdentityDictionary<T> &dict, T key) {
inline void dictAdd(IdentityDictionary<T>& dict, T key) {
dict[key] = key;
}

static void Engine_storeTerminalModulesIDs(std::vector<TerminalModule*> terminalModules, IdentityDictionary<int64_t> &terminalModulesIDs) {
static void Engine_storeTerminalModulesIDs(std::vector<TerminalModule*> terminalModules, IdentityDictionary<int64_t>& terminalModulesIDs) {
for (TerminalModule* terminalModule : terminalModules)
dictAdd(terminalModulesIDs, terminalModule->id);
}

static void Engine_orderModule(Module* module, IdentityDictionary<Module*> &touchedModules, std::vector<Module*> &orderedModules, IdentityDictionary<int64_t> &terminalModulesIDs) {
static void Engine_orderModule(Module* module, IdentityDictionary<Module*>& touchedModules, std::vector<Module*>& orderedModules, IdentityDictionary<int64_t>& terminalModulesIDs) {
if (!dictContains(touchedModules, module) && !dictContains(terminalModulesIDs, module->id)) { // Ignore feedback loops and terminal modules
dictAdd(touchedModules, module);
for (Output& output : module->outputs) {
@@ -310,7 +310,7 @@ static void Engine_orderModule(Module* module, IdentityDictionary<Module*> &touc
}
}

static void Engine_assignOrderedModules(std::vector<Module*> &modules, std::vector<Module*> &orderedModules) {
static void Engine_assignOrderedModules(std::vector<Module*>& modules, std::vector<Module*>& orderedModules) {
std::reverse(orderedModules.begin(), orderedModules.end()); // These are stored bottom up
if (orderedModules.size() == modules.size()) {
for (unsigned int i = 0; i < orderedModules.size(); i++)
@@ -319,7 +319,7 @@ static void Engine_assignOrderedModules(std::vector<Module*> &modules, std::vect
}

#if DEBUG_ORDERED_MODULES
static void Engine_debugOrderedModules(std::vector<Module*> &modules) {
static void Engine_debugOrderedModules(std::vector<Module*>& modules) {
printf("\n--- Ordered modules ---\n");
for (unsigned int i = 0; i < modules.size(); i++)
printf("%d) %s - %ld\n", i, modules[i]->model->getFullName().c_str(), modules[i]->id);


+ 144
- 57
src/override/diffs/Engine.cpp.diff View File

@@ -1,5 +1,5 @@
--- ../Rack/src/engine/Engine.cpp 2022-04-11 20:05:02.011283836 +0100
+++ Engine.cpp 2022-06-29 01:30:02.024102120 +0100
--- ../Rack/src/engine/Engine.cpp 2022-09-21 19:49:12.200540736 +0100
+++ Engine.cpp 2022-11-25 17:57:38.799958734 +0000
@@ -1,3 +1,30 @@
+/*
+ * DISTRHO Cardinal Plugin
@@ -31,8 +31,11 @@
#include <algorithm>
#include <set>
#include <thread>
@@ -8,181 +35,35 @@
@@ -6,183 +33,38 @@
#include <atomic>
#include <tuple>
#include <pmmintrin.h>
+#include <unordered_map>
#include <engine/Engine.hpp>
+#include <engine/TerminalModule.hpp>
@@ -95,21 +98,23 @@
- });
- }
-};
-
-
+#include "DistrhoUtils.hpp"
-/** 2-phase barrier based on spin-locking.
-*/
-struct SpinBarrier {
- std::atomic<int> count{0};
- std::atomic<uint8_t> step{0};
- int threads = 0;
-
+// known terminal modules
+extern std::vector<rack::plugin::Model*> hostTerminalModels;
- /** Must be called when no threads are calling wait().
- */
- void setThreads(int threads) {
- this->threads = threads;
- }
+#include "DistrhoUtils.hpp"
- void wait() {
- uint8_t s = step;
@@ -129,10 +134,8 @@
- }
- }
-};
+// known terminal modules
+extern std::vector<rack::plugin::Model*> hostTerminalModels;
-
-
-/** Barrier that spin-locks until yield() is called, and then all threads switch to a mutex.
-yield() should be called if it is likely that all threads will block for a while and continuing to spin-lock is unnecessary.
-Saves CPU power after yield is called.
@@ -169,7 +172,7 @@
- }
- return;
- }
-
- // Spin until the last thread begins waiting
- while (!yielded.load(std::memory_order_relaxed)) {
- if (step.load(std::memory_order_relaxed) != s)
@@ -224,7 +227,7 @@
// moduleId
std::map<int64_t, Module*> modulesCache;
@@ -198,7 +79,9 @@
@@ -198,7 +80,9 @@
int64_t blockFrame = 0;
double blockTime = 0.0;
int blockFrames = 0;
@@ -234,7 +237,7 @@
// Meter
int meterCount = 0;
double meterTotal = 0.0;
@@ -206,6 +89,7 @@
@@ -206,6 +90,7 @@
double meterLastTime = -INFINITY;
double meterLastAverage = 0.0;
double meterLastMax = 0.0;
@@ -242,7 +245,7 @@
// Parameter smoothing
Module* smoothModule = NULL;
@@ -217,22 +101,6 @@
@@ -217,22 +102,6 @@
Readers lock when using the engine's state.
*/
SharedMutex mutex;
@@ -265,7 +268,7 @@
};
@@ -260,76 +128,11 @@
@@ -260,76 +129,11 @@
}
@@ -343,7 +346,7 @@
// Copy all voltages from output to input
for (int c = 0; c < channels; c++) {
float v = output->voltages[c];
@@ -346,6 +149,53 @@
@@ -346,6 +150,53 @@
}
@@ -397,7 +400,7 @@
/** Steps a single frame
*/
static void Engine_stepFrame(Engine* that) {
@@ -372,13 +222,8 @@
@@ -372,13 +223,8 @@
}
}
@@ -412,7 +415,7 @@
if (module->leftExpander.messageFlipRequested) {
std::swap(module->leftExpander.producerMessage, module->leftExpander.consumerMessage);
module->leftExpander.messageFlipRequested = false;
@@ -389,13 +234,32 @@
@@ -389,13 +235,32 @@
}
}
@@ -440,19 +443,90 @@
+ Cable_step(cable);
+ }
+ }
- internal->frame++;
+
+ // Process terminal outputs last
+ for (TerminalModule* terminalModule : internal->terminalModules) {
+ TerminalModule__doProcess(terminalModule, processArgs, false);
+ }
+
- internal->frame++;
+ ++internal->frame;
}
@@ -416,32 +280,45 @@
@@ -414,35 +279,119 @@
}
+template<typename T>
+using IdentityDictionary = std::unordered_map<T, T>;
+
+template<typename T>
+inline bool dictContains(IdentityDictionary<T>& dict, T key) {
+ return dict.find(key) != dict.end();
+}
+
+template<typename T>
+inline void dictAdd(IdentityDictionary<T>& dict, T key) {
+ dict[key] = key;
+}
+
+static void Engine_storeTerminalModulesIDs(std::vector<TerminalModule*> terminalModules, IdentityDictionary<int64_t>& terminalModulesIDs) {
+ for (TerminalModule* terminalModule : terminalModules)
+ dictAdd(terminalModulesIDs, terminalModule->id);
+}
+
+static void Engine_orderModule(Module* module, IdentityDictionary<Module*>& touchedModules, std::vector<Module*>& orderedModules, IdentityDictionary<int64_t>& terminalModulesIDs) {
+ if (!dictContains(touchedModules, module) && !dictContains(terminalModulesIDs, module->id)) { // Ignore feedback loops and terminal modules
+ dictAdd(touchedModules, module);
+ for (Output& output : module->outputs) {
+ for (Cable* cable : output.cables) {
+ Module* receiver = cable->inputModule; // The input to the cable is the receiving module
+ Engine_orderModule(receiver, touchedModules, orderedModules, terminalModulesIDs);
+ }
+ }
+ orderedModules.push_back(module);
+ }
+}
+
+static void Engine_assignOrderedModules(std::vector<Module*>& modules, std::vector<Module*>& orderedModules) {
+ std::reverse(orderedModules.begin(), orderedModules.end()); // These are stored bottom up
+ if (orderedModules.size() == modules.size()) {
+ for (unsigned int i = 0; i < orderedModules.size(); i++)
+ modules[i] = orderedModules[i];
+ }
+}
+
+#if DEBUG_ORDERED_MODULES
+static void Engine_debugOrderedModules(std::vector<Module*>& modules) {
+ printf("\n--- Ordered modules ---\n");
+ for (unsigned int i = 0; i < modules.size(); i++)
+ printf("%d) %s - %ld\n", i, modules[i]->model->getFullName().c_str(), modules[i]->id);
+}
+#endif
+
+/** Order the modules so that they always read the most recent sample from their inputs
+*/
+static void Engine_orderModules(Engine* that) {
+ Engine::Internal* internal = that->internal;
+
+ IdentityDictionary<int64_t> terminalModulesIDs;
+ Engine_storeTerminalModulesIDs(internal->terminalModules, terminalModulesIDs);
+
+ IdentityDictionary<Module*> touchedModules;
+ std::vector<Module*> orderedModules;
+ orderedModules.reserve(internal->modules.size());
+ for (Module* module : internal->modules)
+ Engine_orderModule(module, touchedModules, orderedModules, terminalModulesIDs);
+
+ Engine_assignOrderedModules(internal->modules, orderedModules);
+
+#if DEBUG_ORDERED_MODULES
+ Engine_debugOrderedModules(internal->modules);
+#endif
+}
+
+
static void Engine_updateConnected(Engine* that) {
// Find disconnected ports
- std::set<Port*> disconnectedPorts;
@@ -506,9 +580,12 @@
+ Port_setDisconnected(output);
+ DISTRHO_SAFE_ASSERT(output->cables.empty());
}
+ // Order the modules according to their connections
+ Engine_orderModules(that);
}
@@ -460,37 +337,23 @@
@@ -460,37 +409,23 @@
Engine::Engine() {
internal = new Internal;
@@ -554,7 +631,7 @@
delete internal;
}
@@ -519,18 +382,22 @@
@@ -519,18 +454,22 @@
removeModule_NoLock(module);
delete module;
}
@@ -580,7 +657,7 @@
random::init();
internal->blockFrame = internal->frame;
@@ -543,18 +410,14 @@
@@ -543,18 +482,14 @@
Engine_updateExpander_NoLock(this, module, true);
}
@@ -600,7 +677,7 @@
// Stop timer
double endTime = system::getTime();
double meter = (endTime - startTime) / (frames * internal->sampleTime);
@@ -572,47 +435,20 @@
@@ -572,47 +507,20 @@
internal->meterTotal = 0.0;
internal->meterMax = 0.0;
}
@@ -650,7 +727,7 @@
}
@@ -635,20 +471,13 @@
@@ -635,20 +543,13 @@
for (Module* module : internal->modules) {
module->onSampleRateChange(e);
}
@@ -674,7 +751,7 @@
}
@@ -658,7 +487,6 @@
@@ -658,7 +559,6 @@
void Engine::yieldWorkers() {
@@ -682,7 +759,7 @@
}
@@ -698,17 +526,25 @@
@@ -698,17 +598,25 @@
double Engine::getMeterAverage() {
@@ -709,7 +786,7 @@
}
@@ -718,8 +554,12 @@
@@ -718,8 +626,12 @@
for (Module* m : internal->modules) {
if (i >= len)
break;
@@ -724,7 +801,7 @@
}
return i;
}
@@ -728,27 +568,43 @@
@@ -728,27 +640,43 @@
std::vector<int64_t> Engine::getModuleIds() {
SharedLock<SharedMutex> lock(internal->mutex);
std::vector<int64_t> moduleIds;
@@ -772,7 +849,17 @@
internal->modulesCache[module->id] = module;
// Dispatch AddEvent
Module::AddEvent eAdd;
@@ -772,11 +628,11 @@
@@ -763,6 +691,9 @@
if (paramHandle->moduleId == module->id)
paramHandle->module = module;
}
+#if DEBUG_ORDERED_MODULES
+ printf("New module: %s - %ld\n", module->model->getFullName().c_str(), module->id);
+#endif
}
@@ -772,11 +703,11 @@
}
@@ -789,7 +876,7 @@
// Dispatch RemoveEvent
Module::RemoveEvent eRemove;
module->onRemove(eRemove);
@@ -785,18 +641,14 @@
@@ -785,18 +716,14 @@
if (paramHandle->moduleId == module->id)
paramHandle->module = NULL;
}
@@ -810,7 +897,7 @@
}
// Update expanders of other modules
for (Module* m : internal->modules) {
@@ -809,14 +661,31 @@
@@ -809,14 +736,31 @@
m->rightExpander.module = NULL;
}
}
@@ -845,7 +932,7 @@
}
@@ -824,7 +693,8 @@
@@ -824,7 +768,8 @@
SharedLock<SharedMutex> lock(internal->mutex);
// TODO Performance could be improved by searching modulesCache, but more testing would be needed to make sure it's always valid.
auto it = std::find(internal->modules.begin(), internal->modules.end(), module);
@@ -855,7 +942,7 @@
}
@@ -844,7 +714,7 @@
@@ -844,7 +789,7 @@
void Engine::resetModule(Module* module) {
std::lock_guard<SharedMutex> lock(internal->mutex);
@@ -864,7 +951,7 @@
Module::ResetEvent eReset;
module->onReset(eReset);
@@ -853,7 +723,7 @@
@@ -853,7 +798,7 @@
void Engine::randomizeModule(Module* module) {
std::lock_guard<SharedMutex> lock(internal->mutex);
@@ -873,7 +960,7 @@
Module::RandomizeEvent eRandomize;
module->onRandomize(eRandomize);
@@ -861,7 +731,7 @@
@@ -861,7 +806,7 @@
void Engine::bypassModule(Module* module, bool bypassed) {
@@ -882,7 +969,7 @@
if (module->isBypassed() == bypassed)
return;
@@ -907,11 +777,17 @@
@@ -907,11 +852,17 @@
void Engine::prepareSave() {
@@ -900,7 +987,7 @@
}
@@ -946,16 +822,16 @@
@@ -946,16 +897,16 @@
void Engine::addCable(Cable* cable) {
std::lock_guard<SharedMutex> lock(internal->mutex);
@@ -922,7 +1009,7 @@
// Get connected status of output, to decide whether we need to call a PortChangeEvent.
// It's best to not trust `cable->outputModule->outputs[cable->outputId]->isConnected()`
if (cable2->outputModule == cable->outputModule && cable2->outputId == cable->outputId)
@@ -969,6 +845,8 @@
@@ -969,6 +920,8 @@
// Add the cable
internal->cables.push_back(cable);
internal->cablesCache[cable->id] = cable;
@@ -931,7 +1018,7 @@
Engine_updateConnected(this);
// Dispatch input port event
{
@@ -996,10 +874,12 @@
@@ -996,10 +949,12 @@
void Engine::removeCable_NoLock(Cable* cable) {
@@ -946,7 +1033,7 @@
// Remove the cable
internal->cablesCache.erase(cable->id);
internal->cables.erase(it);
@@ -1085,11 +965,11 @@
@@ -1085,11 +1040,11 @@
std::lock_guard<SharedMutex> lock(internal->mutex);
// New ParamHandles must be blank.
// This means we don't have to refresh the cache.
@@ -960,7 +1047,7 @@
// Add it
internal->paramHandles.insert(paramHandle);
@@ -1106,7 +986,7 @@
@@ -1106,7 +1061,7 @@
void Engine::removeParamHandle_NoLock(ParamHandle* paramHandle) {
// Check that the ParamHandle is already added
auto it = internal->paramHandles.find(paramHandle);
@@ -969,7 +1056,7 @@
// Remove it
paramHandle->module = NULL;
@@ -1143,7 +1023,7 @@
@@ -1143,7 +1098,7 @@
void Engine::updateParamHandle_NoLock(ParamHandle* paramHandle, int64_t moduleId, int paramId, bool overwrite) {
// Check that it exists
auto it = internal->paramHandles.find(paramHandle);
@@ -978,7 +1065,7 @@
// Set IDs
paramHandle->moduleId = moduleId;
@@ -1187,6 +1067,10 @@
@@ -1187,6 +1142,10 @@
json_t* moduleJ = module->toJson();
json_array_append_new(modulesJ, moduleJ);
}
@@ -989,7 +1076,7 @@
json_object_set_new(rootJ, "modules", modulesJ);
// cables
@@ -1197,11 +1081,6 @@
@@ -1197,11 +1156,6 @@
}
json_object_set_new(rootJ, "cables", cablesJ);
@@ -1001,7 +1088,7 @@
return rootJ;
}
@@ -1225,14 +1104,20 @@
@@ -1225,14 +1179,20 @@
}
catch (Exception& e) {
WARN("Cannot load model: %s", e.what());
@@ -1026,7 +1113,7 @@
try {
// This doesn't need a lock because the Module is not added to the Engine yet.
@@ -1248,7 +1133,8 @@
@@ -1248,7 +1208,8 @@
}
catch (Exception& e) {
WARN("Cannot load module: %s", e.what());
@@ -1036,7 +1123,7 @@
delete module;
continue;
}
@@ -1285,67 +1171,15 @@
@@ -1285,67 +1246,15 @@
continue;
}
}
@@ -1047,9 +1134,9 @@
- Module* masterModule = getModule(json_integer_value(masterModuleIdJ));
- setMasterModule(masterModule);
- }
}
-}
-
-
-void EngineWorker::run() {
- // Configure thread
- contextSet(engine->internal->context);
@@ -1064,9 +1151,9 @@
- Engine_stepWorker(engine, id);
- engine->internal->workerBarrier.wait();
- }
-}
-
-
}
-static void Engine_fallbackRun(Engine* that) {
- system::setThreadName("Engine fallback");
- contextSet(that->internal->context);


+ 128
- 77
src/override/diffs/MenuBar.cpp.diff View File

@@ -1,5 +1,5 @@
--- ../Rack/src/app/MenuBar.cpp 2022-07-12 09:46:20.716165650 +0100
+++ MenuBar.cpp 2022-07-12 09:45:31.518663160 +0100
--- ../Rack/src/app/MenuBar.cpp 2022-09-21 19:49:12.198540676 +0100
+++ MenuBar.cpp 2022-09-21 19:41:45.883648777 +0100
@@ -1,8 +1,33 @@
+/*
+ * DISTRHO Cardinal Plugin
@@ -36,29 +36,40 @@
#include <app/MenuBar.hpp>
#include <app/TipWindow.hpp>
#include <widget/OpaqueWidget.hpp>
@@ -25,8 +50,21 @@
@@ -15,6 +40,7 @@
#include <ui/ProgressBar.hpp>
#include <ui/Label.hpp>
#include <engine/Engine.hpp>
+#include <widget/FramebufferWidget.hpp>
#include <window/Window.hpp>
#include <asset.hpp>
#include <context.hpp>
@@ -25,8 +51,24 @@
#include <patch.hpp>
#include <library.hpp>
+#include "../CardinalCommon.hpp"
+#include "DistrhoStandaloneUtils.hpp"
+
+#ifdef HAVE_LIBLO
+# include <lo/lo.h>
+#endif
+
+#ifdef DISTRHO_OS_WASM
+# include "DistrhoStandaloneUtils.hpp"
+#endif
+void switchDarkMode(bool darkMode);
namespace rack {
+namespace asset {
+std::string patchesPath();
+}
+
+namespace plugin {
+void updateStaticPluginsDarkMode();
+}
+
namespace app {
namespace menuBar {
@@ -48,79 +86,140 @@
@@ -48,79 +90,152 @@
};
@@ -82,12 +93,15 @@
struct FileButton : MenuButton {
+ const bool isStandalone;
+#if !(defined(DISTRHO_OS_WASM) && defined(STATIC_BUILD))
+ std::vector<std::string> demoPatches;
+#endif
+
+ FileButton(const bool standalone)
+ : MenuButton(), isStandalone(standalone)
+ {
+ const std::string patchesDir = asset::patchesPath();
+#if !(defined(DISTRHO_OS_WASM) && defined(STATIC_BUILD))
+ const std::string patchesDir = asset::patchesPath() + DISTRHO_OS_SEP_STR "examples";
+
+ if (system::isDirectory(patchesDir))
+ {
@@ -96,6 +110,7 @@
+ return string::lowercase(a) < string::lowercase(b);
+ });
+ }
+#endif
+ }
+
void onAction(const ActionEvent& e) override {
@@ -177,7 +192,7 @@
+ menu->addChild(createMenuItem("Deploy to MOD", "F7", []() {
+ patchUtils::deployToRemote();
+ }));
+
+ const bool autoDeploy = patchUtils::isRemoteAutoDeployed();
+ menu->addChild(createCheckMenuItem("Auto deploy to MOD", "",
+ [=]() {return autoDeploy;},
@@ -189,7 +204,7 @@
+ }));
+ }
+#endif
+
+#ifndef DISTRHO_OS_WASM
menu->addChild(new ui::MenuSeparator);
@@ -209,6 +224,7 @@
}));
+#endif
+
+#if !(defined(DISTRHO_OS_WASM) && defined(STATIC_BUILD))
+ if (!demoPatches.empty())
+ {
+ menu->addChild(new ui::MenuSeparator);
@@ -226,8 +242,15 @@
+ patchUtils::loadPathDialog(path, true);
+ }));
+ }
+
+ menu->addChild(new ui::MenuSeparator);
+
+ menu->addChild(createMenuItem("Open PatchStorage.com for more patches", "", []() {
+ patchUtils::openBrowser("https://patchstorage.com/platform/cardinal/");
+ }));
+ }));
+ }
+#endif
+
+#ifndef DISTRHO_OS_WASM
+ if (isStandalone) {
@@ -241,7 +264,7 @@
}
};
@@ -166,7 +265,7 @@
@@ -166,7 +281,7 @@
menu->addChild(new ui::MenuSeparator);
@@ -250,7 +273,7 @@
}
};
@@ -256,7 +355,7 @@
@@ -256,7 +371,7 @@
return settings::cableTension;
}
float getDefaultValue() override {
@@ -259,7 +282,27 @@
}
float getDisplayValue() override {
return getValue() * 100;
@@ -399,28 +498,6 @@
@@ -393,36 +508,37 @@
};
+static void setAllFramebufferWidgetsDirty(widget::Widget* const widget)
+{
+ for (widget::Widget* child : widget->children)
+ {
+ if (widget::FramebufferWidget* const fbw = dynamic_cast<widget::FramebufferWidget*>(child))
+ {
+ fbw->setDirty();
+ break;
+ }
+ setAllFramebufferWidgetsDirty(child);
+ }
+}
+
+
struct ViewButton : MenuButton {
void onAction(const ActionEvent& e) override {
ui::Menu* menu = createMenu();
menu->cornerFlags = BND_CORNER_TOP;
menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y));
@@ -272,7 +315,8 @@
- menu->addChild(createMenuItem("Fullscreen", fullscreenText, [=]() {
- APP->window->setFullScreen(!fullscreen);
- }));
-
+ menu->addChild(createMenuLabel("Appearance"));
- double frameRate = APP->window->getMonitorRefreshRate() / settings::frameSwapInterval;
- menu->addChild(createSubmenuItem("Frame rate", string::f("%.0f Hz", frameRate), [=](ui::Menu* menu) {
- for (int i = 1; i <= 6; i++) {
@@ -282,13 +326,22 @@
- [=]() {settings::frameSwapInterval = i;}
- ));
- }
- }));
-
- menu->addChild(new ui::MenuSeparator);
menu->addChild(createMenuLabel("Appearance"));
+ std::string darkModeText;
+ if (settings::darkMode)
+ darkModeText = CHECKMARK_STRING;
+ menu->addChild(createMenuItem("Dark Mode", darkModeText, []() {
+ switchDarkMode(!settings::darkMode);
+ plugin::updateStaticPluginsDarkMode();
+ setAllFramebufferWidgetsDirty(APP->scene);
}));
- menu->addChild(new ui::MenuSeparator);
- menu->addChild(createMenuLabel("Appearance"));
-
menu->addChild(createBoolPtrMenuItem("Show tooltips", "", &settings::tooltips));
@@ -446,9 +523,18 @@
ZoomSlider* zoomSlider = new ZoomSlider;
@@ -446,9 +562,18 @@
menu->addChild(haloBrightnessSlider);
menu->addChild(new ui::MenuSeparator);
@@ -307,7 +360,7 @@
static const std::vector<std::string> knobModeLabels = {
"Linear",
@@ -473,11 +559,34 @@
@@ -473,11 +598,34 @@
menu->addChild(knobScrollSensitivitySlider);
menu->addChild(new ui::MenuSeparator);
@@ -317,17 +370,17 @@
- menu->addChild(createBoolPtrMenuItem("Lock positions", "", &settings::lockModules));
+#ifdef DISTRHO_OS_WASM
+ const bool fullscreen = APP->window->isFullScreen();
+ std::string fullscreenText = "F11";
+ std::string rightText = "F11";
+ if (fullscreen)
+ fullscreenText += " " CHECKMARK_STRING;
+ menu->addChild(createMenuItem("Fullscreen", fullscreenText, [=]() {
+ rightText += " " CHECKMARK_STRING;
+ menu->addChild(createMenuItem("Fullscreen", rightText, [=]() {
+ APP->window->setFullScreen(!fullscreen);
+ }));
+#endif
+
+ menu->addChild(createBoolPtrMenuItem("Invert zoom", "", &settings::invertZoom));
- menu->addChild(createBoolPtrMenuItem("Auto-squeeze algorithm (experimental)", "", &settings::squeezeModules));
+ menu->addChild(createBoolPtrMenuItem("Invert zoom", "", &settings::invertZoom));
+
+ static const std::vector<std::string> rateLimitLabels = {
+ "None",
+ "2x",
@@ -345,7 +398,7 @@
}
};
@@ -487,47 +596,6 @@
@@ -487,47 +635,6 @@
////////////////////
@@ -393,7 +446,7 @@
struct EngineButton : MenuButton {
void onAction(const ActionEvent& e) override {
ui::Menu* menu = createMenu();
@@ -541,268 +609,42 @@
@@ -541,268 +648,40 @@
settings::cpuMeter ^= true;
}));
@@ -404,7 +457,10 @@
- int cores = system::getLogicalCoreCount() / 2;
-
- for (int i = 1; i <= 2 * cores; i++) {
- std::string rightText;
+ if (isUsingNativeAudio()) {
+ if (supportsAudioInput()) {
+ const bool enabled = isAudioInputEnabled();
std::string rightText;
- if (i == cores)
- rightText += "(most modules)";
- else if (i == 1)
@@ -538,12 +594,18 @@
- rightText += p->version + " → ";
- }
- rightText += update.version;
- }
+ if (enabled)
+ rightText = CHECKMARK_STRING;
+ menu->addChild(createMenuItem("Enable Audio Input", rightText, [enabled]() {
+ if (!enabled)
+ requestAudioInput();
+ }));
}
- }
-
- MenuItem::step();
- }
-
- void onAction(const ActionEvent& e) override {
- std::thread t([=] {
- library::syncUpdate(slug);
@@ -578,16 +640,7 @@
- else if (!library::isLoggedIn()) {
- addChild(createMenuItem("Register VCV account", "", [=]() {
- system::openBrowser("https://vcvrack.com/login");
+#ifdef DISTRHO_OS_WASM
+ if (supportsAudioInput()) {
+ const bool enabled = isAudioInputEnabled();
+ std::string text = "Enable Audio Input";
+ if (enabled)
+ text += " " CHECKMARK_STRING;
+ menu->addChild(createMenuItem(text, "", [enabled]() {
+ if (!enabled)
+ requestAudioInput();
}));
- }));
-
- ui::TextField* emailField = new ui::TextField;
- emailField->placeholder = "Email";
@@ -606,23 +659,15 @@
- logInItem->passwordField = passwordField;
- passwordField->logInItem = logInItem;
- addChild(logInItem);
}
- }
- else {
- addChild(createMenuItem("Log out", "", [=]() {
- library::logOut();
- }));
-
- addChild(createMenuItem("Browse VCV Library", "", [=]() {
- system::openBrowser("https://library.vcvrack.com/");
+ if (supportsMIDI()) {
+ const bool enabled = isMIDIEnabled();
+ std::string text = "Enable MIDI";
+ if (enabled)
+ text += " " CHECKMARK_STRING;
+ menu->addChild(createMenuItem(text, "", [enabled]() {
+ if (!enabled)
+ requestMIDI();
}));
- }));
-
- SyncUpdatesItem* syncItem = new SyncUpdatesItem;
- syncItem->text = "Update all";
@@ -637,12 +682,19 @@
- updateItem->setUpdate(pair.first);
- addChild(updateItem);
- }
- }
}
+ if (supportsMIDI()) {
+ std::string rightText;
+ if (isMIDIEnabled())
+ rightText = CHECKMARK_STRING;
+ menu->addChild(createMenuItem("Enable/Reconnect MIDI", rightText, []() {
+ requestMIDI();
+ }));
}
- }
- }
-};
-
-
-struct LibraryButton : MenuButton {
- NotificationIcon* notification;
-
@@ -662,7 +714,7 @@
- });
- t.detach();
- }
-
- void step() override {
- notification->box.pos = math::Vec(0, 0);
- notification->visible = library::hasUpdates();
@@ -672,26 +724,25 @@
- library::restartRequested = false;
- if (osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, "All plugins have been downloaded. Close and re-launch Rack to load new updates.")) {
- APP->window->close();
- }
+ if (supportsBufferSizeChanges()) {
+ static const std::vector<uint32_t> bufferSizes = {256, 512, 1024, 2048, 4096, 8192, 16384};
+ const uint32_t currentBufferSize = getBufferSize();
+ menu->addChild(createSubmenuItem("Buffer Size", std::to_string(currentBufferSize), [=](ui::Menu* menu) {
+ for (uint32_t bufferSize : bufferSizes) {
+ menu->addChild(createCheckMenuItem(std::to_string(bufferSize), "",
+ [=]() {return currentBufferSize == bufferSize;},
+ [=]() {requestBufferSizeChange(bufferSize);}
+ ));
+ }
+ }));
+ if (supportsBufferSizeChanges()) {
+ static const std::vector<uint32_t> bufferSizes = {256, 512, 1024, 2048, 4096, 8192, 16384};
+ const uint32_t currentBufferSize = getBufferSize();
+ menu->addChild(createSubmenuItem("Buffer Size", std::to_string(currentBufferSize), [=](ui::Menu* menu) {
+ for (uint32_t bufferSize : bufferSizes) {
+ menu->addChild(createCheckMenuItem(std::to_string(bufferSize), "",
+ [=]() {return currentBufferSize == bufferSize;},
+ [=]() {requestBufferSizeChange(bufferSize);}
+ ));
+ }
+ }));
}
}
-
- MenuButton::step();
+#endif
}
};
@@ -813,65 +655,23 @@
@@ -813,65 +692,23 @@
struct HelpButton : MenuButton {
@@ -709,14 +760,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");
- }));
@@ -763,7 +814,7 @@
}
};
@@ -921,7 +721,9 @@
@@ -921,7 +758,9 @@
struct MenuBar : widget::OpaqueWidget {
MeterLabel* meterLabel;
@@ -774,7 +825,7 @@
const float margin = 5;
box.size.y = BND_WIDGET_HEIGHT + 2 * margin;
@@ -930,7 +732,7 @@
@@ -930,7 +769,7 @@
layout->spacing = math::Vec(0, 0);
addChild(layout);
@@ -783,7 +834,7 @@
fileButton->text = "File";
layout->addChild(fileButton);
@@ -946,10 +748,6 @@
@@ -946,10 +785,6 @@
engineButton->text = "Engine";
layout->addChild(engineButton);
@@ -794,7 +845,7 @@
HelpButton* helpButton = new HelpButton;
helpButton->text = "Help";
layout->addChild(helpButton);
@@ -984,7 +782,11 @@
@@ -984,7 +819,11 @@
widget::Widget* createMenuBar() {


+ 2
- 2
src/override/diffs/Model.cpp.diff View File

@@ -1,5 +1,5 @@
--- ../Rack/src/plugin/Model.cpp 2022-07-12 09:46:20.716165650 +0100
+++ Model.cpp 2022-07-06 16:19:37.977002863 +0100
--- ../Rack/src/plugin/Model.cpp 2022-09-21 19:49:12.200540736 +0100
+++ Model.cpp 2022-09-21 19:41:45.883648777 +0100
@@ -1,3 +1,30 @@
+/*
+ * DISTRHO Cardinal Plugin


+ 2
- 2
src/override/diffs/OpenGlWidget.cpp.diff View File

@@ -1,5 +1,5 @@
--- ../Rack/src/widget/OpenGlWidget.cpp 2022-04-11 20:05:02.023283713 +0100
+++ OpenGlWidget.cpp 2022-07-14 01:14:57.028367786 +0100
--- ../Rack/src/widget/OpenGlWidget.cpp 2022-09-21 19:49:12.201540766 +0100
+++ OpenGlWidget.cpp 2022-09-21 19:41:45.883648777 +0100
@@ -1,3 +1,30 @@
+/*
+ * DISTRHO Cardinal Plugin


+ 2
- 2
src/override/diffs/Scene.cpp.diff View File

@@ -1,5 +1,5 @@
--- ../Rack/src/app/Scene.cpp 2022-04-11 20:05:02.007283878 +0100
+++ Scene.cpp 2022-07-12 09:45:31.518663160 +0100
--- ../Rack/src/app/Scene.cpp 2022-09-21 19:49:12.199540706 +0100
+++ Scene.cpp 2022-09-21 19:41:45.883648777 +0100
@@ -1,3 +1,30 @@
+/*
+ * DISTRHO Cardinal Plugin


+ 163
- 144
src/override/diffs/Window.cpp.diff View File

@@ -1,5 +1,5 @@
--- ../Rack/src/window/Window.cpp 2022-04-11 20:05:02.023283713 +0100
+++ Window.cpp 2022-07-12 09:45:31.518663160 +0100
--- ../Rack/src/window/Window.cpp 2022-09-21 19:49:12.202540796 +0100
+++ Window.cpp 2022-09-21 19:41:45.883648777 +0100
@@ -1,33 +1,87 @@
+/*
+ * DISTRHO Cardinal Plugin
@@ -112,7 +112,7 @@
throw Exception("Failed to load font %s", filename.c_str());
}
INFO("Loaded font %s", filename.c_str());
@@ -79,375 +132,325 @@
@@ -79,375 +132,347 @@
}
@@ -247,18 +247,6 @@
- APP->event->handleButton(APP->window->internal->lastMousePos, button, action, mods);
-}
-
-
-static void cursorPosCallback(GLFWwindow* win, double xpos, double ypos) {
- contextSet((Context*) glfwGetWindowUserPointer(win));
- math::Vec mousePos = math::Vec(xpos, ypos).div(APP->window->pixelRatio / APP->window->windowRatio).round();
- math::Vec mouseDelta = mousePos.minus(APP->window->internal->lastMousePos);
-
- // Workaround for GLFW warping mouse to a different position when the cursor is locked or unlocked.
- if (APP->window->internal->ignoreNextMouseDelta) {
- APP->window->internal->ignoreNextMouseDelta = false;
- mouseDelta = math::Vec();
- }
+ // Load default Blendish font
+#ifndef DGL_NO_SHARED_RESOURCES
+ uiFont = std::make_shared<Font>();
@@ -275,11 +263,43 @@
+ uiFont = loadFont(asset::system("res/fonts/DejaVuSans.ttf"));
+#endif
- int cursorMode = glfwGetInputMode(win, GLFW_CURSOR);
- (void) cursorMode;
+ if (uiFont != nullptr)
+ bndSetFont(uiFont->handle);
-static void cursorPosCallback(GLFWwindow* win, double xpos, double ypos) {
- contextSet((Context*) glfwGetWindowUserPointer(win));
- math::Vec mousePos = math::Vec(xpos, ypos).div(APP->window->pixelRatio / APP->window->windowRatio).round();
- math::Vec mouseDelta = mousePos.minus(APP->window->internal->lastMousePos);
+#ifdef DISTRHO_OS_WASM
+ emscripten_lock_orientation(EMSCRIPTEN_ORIENTATION_LANDSCAPE_PRIMARY);
+#endif
+}
- // Workaround for GLFW warping mouse to a different position when the cursor is locked or unlocked.
- if (APP->window->internal->ignoreNextMouseDelta) {
- APP->window->internal->ignoreNextMouseDelta = false;
- mouseDelta = math::Vec();
+void WindowSetPluginUI(Window* const window, DISTRHO_NAMESPACE::UI* const ui)
+{
+ // if nanovg context failed, init only bare minimum
+ if (window->vg == nullptr)
+ {
+ if (ui != nullptr)
+ {
+ window->internal->ui = ui;
+ window->internal->size = rack::math::Vec(ui->getWidth(), ui->getHeight());
+ }
+ else
+ {
+ window->internal->ui = nullptr;
+ window->internal->callback = nullptr;
+ }
+ return;
}
- int cursorMode = glfwGetInputMode(win, GLFW_CURSOR);
- (void) cursorMode;
-
-#if defined ARCH_MAC
- // Workaround for Mac. We can't use GLFW_CURSOR_DISABLED because it's buggy, so implement it on our own.
- // This is not an ideal implementation. For example, if the user drags off the screen, the new mouse position will be clamped.
@@ -291,16 +311,6 @@
- }
- // Because sometimes the cursor turns into an arrow when its position is on the boundary of the window
- glfwSetCursor(win, NULL);
+#ifdef DISTRHO_OS_WASM
+ emscripten_lock_orientation(EMSCRIPTEN_ORIENTATION_LANDSCAPE_PRIMARY);
#endif
+}
- APP->window->internal->lastMousePos = mousePos;
-
- APP->event->handleHover(mousePos, mouseDelta);
+void WindowSetPluginUI(Window* const window, DISTRHO_NAMESPACE::UI* const ui)
+{
+ if (ui != nullptr)
+ {
+ const GLubyte* vendor = glGetString(GL_VENDOR);
@@ -318,14 +328,9 @@
+ window->internal->r_fbVg = nvgCreateSharedGLES2(window->internal->r_vg, NVG_ANTIALIAS);
+#else
+ window->internal->r_fbVg = nvgCreateSharedGL2(window->internal->r_vg, NVG_ANTIALIAS);
+#endif
#endif
- // Keyboard/mouse MIDI driver
- int width, height;
- glfwGetWindowSize(win, &width, &height);
- math::Vec scaledPos(xpos / width, ypos / height);
- keyboard::mouseMove(scaledPos);
-}
- APP->window->internal->lastMousePos = mousePos;
+ // swap contexts
+ window->internal->o_vg = window->vg;
+ window->internal->o_fbVg = window->fbVg;
@@ -350,22 +355,24 @@
+ NVG_IMAGE_REPEATX | NVG_IMAGE_REPEATY);
+ }
- APP->event->handleHover(mousePos, mouseDelta);
+ // Init settings
+ WindowParametersRestore(window);
-static void cursorEnterCallback(GLFWwindow* win, int entered) {
- contextSet((Context*) glfwGetWindowUserPointer(win));
- if (!entered) {
- APP->event->handleLeave();
- // Keyboard/mouse MIDI driver
- int width, height;
- glfwGetWindowSize(win, &width, &height);
- math::Vec scaledPos(xpos / width, ypos / height);
- keyboard::mouseMove(scaledPos);
-}
+ widget::Widget::ContextCreateEvent e;
+ APP->scene->onContextCreate(e);
}
-}
+ }
+ else
+ {
+ widget::Widget::ContextDestroyEvent e;
+ APP->scene->onContextDestroy(e);
+
+ // swap contexts
+ window->uiFont->vg = window->internal->o_vg;
+ window->vg = window->internal->o_vg;
@@ -389,67 +396,88 @@
+ image.second->ohandle = -1;
+ }
+#if defined NANOVG_GLES2
+ nvgDeleteGLES2(window->internal->r_fbVg);
+#else
+ nvgDeleteGL2(window->internal->r_fbVg);
+#endif
-static void cursorEnterCallback(GLFWwindow* win, int entered) {
- contextSet((Context*) glfwGetWindowUserPointer(win));
- if (!entered) {
- APP->event->handleLeave();
+ window->internal->ui = nullptr;
+ window->internal->callback = nullptr;
}
}
+void WindowSetMods(Window* const window, const int mods)
+{
+ window->internal->mods = mods;
+}
-static void scrollCallback(GLFWwindow* win, double x, double y) {
- contextSet((Context*) glfwGetWindowUserPointer(win));
- math::Vec scrollDelta = math::Vec(x, y);
-#if defined ARCH_MAC
- scrollDelta = scrollDelta.mult(10.0);
+Window::~Window() {
+ {
+ DGL_NAMESPACE::Window::ScopedGraphicsContext sgc(internal->hiddenWindow);
+ internal->hiddenWindow.close();
+ internal->hiddenApp.idle();
+
+ // Fonts and Images in the cache must be deleted before the NanoVG context is deleted
+ internal->fontCache.clear();
+ internal->imageCache.clear();
+
+ if (vg != nullptr)
+ {
+#if defined NANOVG_GLES2
+ nvgDeleteGLES2(window->internal->r_fbVg);
+ nvgDeleteGLES2(internal->o_fbVg != nullptr ? internal->o_fbVg : fbVg);
+ nvgDeleteGLES2(internal->o_vg != nullptr ? internal->o_vg : vg);
#else
- scrollDelta = scrollDelta.mult(50.0);
+ nvgDeleteGL2(window->internal->r_fbVg);
+ nvgDeleteGL2(internal->o_fbVg != nullptr ? internal->o_fbVg : fbVg);
+ nvgDeleteGL2(internal->o_vg != nullptr ? internal->o_vg : vg);
#endif
+ }
+ }
- APP->event->handleScroll(APP->window->internal->lastMousePos, scrollDelta);
+ window->internal->ui = nullptr;
+ window->internal->callback = nullptr;
+ }
+ delete internal;
}
-
-static void charCallback(GLFWwindow* win, unsigned int codepoint) {
- contextSet((Context*) glfwGetWindowUserPointer(win));
- if (APP->event->handleText(APP->window->internal->lastMousePos, codepoint))
- return;
+void WindowSetMods(Window* const window, const int mods)
+{
+ window->internal->mods = mods;
+math::Vec Window::getSize() {
+ return internal->size;
}
-
-static void keyCallback(GLFWwindow* win, int key, int scancode, int action, int mods) {
- contextSet((Context*) glfwGetWindowUserPointer(win));
- if (APP->event->handleKey(APP->window->internal->lastMousePos, key, scancode, action, mods))
- return;
-
+void Window::setSize(math::Vec size) {
+ size = size.max(WINDOW_SIZE_MIN);
+ internal->size = size;
- // Keyboard/mouse MIDI driver
- if (action == GLFW_PRESS && (mods & RACK_MOD_MASK) == 0) {
- keyboard::press(key);
- }
- if (action == GLFW_RELEASE) {
- keyboard::release(key);
+Window::~Window() {
+ {
+ DGL_NAMESPACE::Window::ScopedGraphicsContext sgc(internal->hiddenWindow);
+ internal->hiddenWindow.close();
+ internal->hiddenApp.idle();
+
+ // Fonts and Images in the cache must be deleted before the NanoVG context is deleted
+ internal->fontCache.clear();
+ internal->imageCache.clear();
+
+#if defined NANOVG_GLES2
+ nvgDeleteGLES2(internal->o_fbVg != nullptr ? internal->o_fbVg : fbVg);
+ nvgDeleteGLES2(internal->o_vg != nullptr ? internal->o_vg : vg);
+#else
+ nvgDeleteGL2(internal->o_fbVg != nullptr ? internal->o_fbVg : fbVg);
+ nvgDeleteGL2(internal->o_vg != nullptr ? internal->o_vg : vg);
+#endif
}
-}
-
- }
+ if (DISTRHO_NAMESPACE::UI* const ui = internal->ui)
+ ui->setSize(internal->size.x, internal->size.y);
}
-
-static void dropCallback(GLFWwindow* win, int count, const char** paths) {
- contextSet((Context*) glfwGetWindowUserPointer(win));
- std::vector<std::string> pathsVec;
@@ -457,24 +485,23 @@
- pathsVec.push_back(paths[i]);
- }
- APP->event->handleDrop(APP->window->internal->lastMousePos, pathsVec);
+ delete internal;
+void WindowSetInternalSize(rack::window::Window* const window, math::Vec size) {
+ size = size.max(WINDOW_SIZE_MIN);
+ window->internal->size = size;
}
-static void errorCallback(int error, const char* description) {
- WARN("GLFW error %d: %s", error, description);
+math::Vec Window::getSize() {
+ return internal->size;
+void Window::run() {
+ internal->frame = 0;
}
-Window::Window() {
- internal = new Internal;
- int err;
+void Window::setSize(math::Vec size) {
+ size = size.max(WINDOW_SIZE_MIN);
+ internal->size = size;
-
- // Set window hints
-#if defined NANOVG_GL2
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
@@ -555,17 +582,10 @@
- const GLubyte* version = glGetString(GL_VERSION);
- INFO("Renderer: %s %s", vendor, renderer);
- INFO("OpenGL: %s", version);
+ if (DISTRHO_NAMESPACE::UI* const ui = internal->ui)
+ ui->setSize(internal->size.x, internal->size.y);
+}
-
- // GLEW generates GL error because it calls glGetString(GL_EXTENSIONS), we'll consume it here.
- glGetError();
+void WindowSetInternalSize(rack::window::Window* const window, math::Vec size) {
+ size = size.max(WINDOW_SIZE_MIN);
+ window->internal->size = size;
+}
-
- // Set up NanoVG
- int nvgFlags = NVG_ANTIALIAS;
-#if defined NANOVG_GL2
@@ -580,7 +600,7 @@
- osdialog_message(OSDIALOG_ERROR, OSDIALOG_OK, "Could not initialize NanoVG. Does your graphics card support OpenGL 2.0 or greater? If so, make sure you have the latest graphics drivers installed.");
- throw Exception("Could not initialize NanoVG");
- }
-
- // Load default Blendish font
- uiFont = loadFont(asset::system("res/fonts/DejaVuSans.ttf"));
- bndSetFont(uiFont->handle);
@@ -588,16 +608,6 @@
- if (APP->scene) {
- widget::Widget::ContextCreateEvent e;
- APP->scene->onContextCreate(e);
- }
+void Window::run() {
+ internal->frame = 0;
}
-Window::~Window() {
- if (APP->scene) {
- widget::Widget::ContextDestroyEvent e;
- APP->scene->onContextDestroy(e);
+#ifndef DGL_USE_GLES
+static void Window__flipBitmap(uint8_t* pixels, const int width, const int height, const int depth) {
+ for (int y = 0; y < height / 2; y++) {
@@ -607,33 +617,13 @@
+ std::memmove(&pixels[y * width * depth], &pixels[flipY * width * depth], width * depth);
+ std::memcpy(&pixels[flipY * width * depth], tmp, width * depth);
}
-
- // Fonts and Images in the cache must be deleted before the NanoVG context is deleted
- internal->fontCache.clear();
- internal->imageCache.clear();
-
- // nvgDeleteClone(fbVg);
-
-#if defined NANOVG_GL2
- nvgDeleteGL2(vg);
- nvgDeleteGL2(fbVg);
-#elif defined NANOVG_GL3
- nvgDeleteGL3(vg);
-#elif defined NANOVG_GLES2
- nvgDeleteGLES2(vg);
-#endif
-
- glfwDestroyWindow(win);
- delete internal;
}
-math::Vec Window::getSize() {
- int width, height;
- glfwGetWindowSize(win, &width, &height);
- return math::Vec(width, height);
-}
-
-Window::~Window() {
- if (APP->scene) {
- widget::Widget::ContextDestroyEvent e;
- APP->scene->onContextDestroy(e);
+#ifdef STBI_WRITE_NO_STDIO
+static void Window__downscaleBitmap(uint8_t* pixels, int& width, int& height) {
+ int targetWidth = width;
@@ -660,21 +650,40 @@
+ const int xs = static_cast<int>(x * scale);
+ std::memmove(pixels + (width * y + x) * 3, pixels + (width * ys + xs) * 3, 3);
+ }
+ }
}
-void Window::setSize(math::Vec size) {
- size = size.max(WINDOW_SIZE_MIN);
- glfwSetWindowSize(win, size.x, size.y);
- // Fonts and Images in the cache must be deleted before the NanoVG context is deleted
- internal->fontCache.clear();
- internal->imageCache.clear();
-
- // nvgDeleteClone(fbVg);
-
-#if defined NANOVG_GL2
- nvgDeleteGL2(vg);
- nvgDeleteGL2(fbVg);
-#elif defined NANOVG_GL3
- nvgDeleteGL3(vg);
-#elif defined NANOVG_GLES2
- nvgDeleteGLES2(vg);
-#endif
-
- glfwDestroyWindow(win);
- delete internal;
-}
-
-
-math::Vec Window::getSize() {
- int width, height;
- glfwGetWindowSize(win, &width, &height);
- return math::Vec(width, height);
+ width = targetWidth;
+ height = targetHeight;
}
-
-void Window::run() {
- internal->frame = 0;
- while (!glfwWindowShouldClose(win)) {
- step();
- }
-void Window::setSize(math::Vec size) {
- size = size.max(WINDOW_SIZE_MIN);
- glfwSetWindowSize(win, size.x, size.y);
+static void Window__writeImagePNG(void* context, void* data, int size) {
+ USE_NAMESPACE_DISTRHO
+ UI* const ui = static_cast<UI*>(context);
@@ -684,9 +693,19 @@
+#endif
void Window::step() {
-void Window::run() {
- internal->frame = 0;
- while (!glfwWindowShouldClose(win)) {
- step();
- }
-}
+void Window::step() {
+ DISTRHO_SAFE_ASSERT_RETURN(internal->ui != nullptr,);
+
+ if (vg == nullptr)
+ return;
-void Window::step() {
double frameTime = system::getTime();
double lastFrameTime = internal->frameTime;
internal->frameTime = frameTime;
@@ -729,7 +748,7 @@
if (APP->patch->path != "") {
windowTitle += " - ";
if (!APP->history->isSaved())
@@ -455,246 +458,189 @@
@@ -455,246 +480,189 @@
windowTitle += system::getFilename(APP->patch->path);
}
if (windowTitle != internal->lastWindowTitle) {
@@ -857,7 +876,7 @@
+ // glReadPixels defaults to GL_BACK, but the back-buffer is unstable, so use the front buffer (what the user sees)
+ glReadBuffer(GL_FRONT);
+ glReadPixels(0, 0, winWidth, winHeight, depth == 3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ if (internal->generateScreenshotStep == kScreenshotStepSaving)
+ {
+ // Write pixels to PNG
@@ -873,6 +892,11 @@
+ stbi_write_png("screenshot.png", winWidth, winHeight, depth, pixelsWithOffset, stride);
+#endif
+ internal->generateScreenshotStep = kScreenshotStepNone;
+ APP->scene->menuBar->show();
+ APP->scene->rack->children.front()->show();
+ }
-static void flipBitmap(uint8_t* pixels, int width, int height, int depth) {
- for (int y = 0; y < height / 2; y++) {
- int flipY = height - y - 1;
@@ -880,11 +904,6 @@
- std::memcpy(tmp, &pixels[y * width * depth], width * depth);
- std::memcpy(&pixels[y * width * depth], &pixels[flipY * width * depth], width * depth);
- std::memcpy(&pixels[flipY * width * depth], tmp, width * depth);
+ internal->generateScreenshotStep = kScreenshotStepNone;
+ APP->scene->menuBar->show();
+ APP->scene->rack->children.front()->show();
+ }
+
+ delete[] pixels;
}
+#endif
@@ -1078,7 +1097,7 @@
double Window::getMonitorRefreshRate() {
return internal->monitorRefreshRate;
}
@@ -722,14 +668,15 @@
@@ -722,14 +690,15 @@
return pair->second;
// Load font
@@ -1097,7 +1116,7 @@
}
internal->fontCache[filename] = font;
return font;
@@ -742,14 +689,15 @@
@@ -742,14 +711,15 @@
return pair->second;
// Load image
@@ -1116,7 +1135,7 @@
}
internal->imageCache[filename] = image;
return image;
@@ -766,28 +714,156 @@
@@ -766,28 +736,156 @@
}


+ 2
- 2
src/override/diffs/blendish.c.diff View File

@@ -1,5 +1,5 @@
--- ../Rack/dep/oui-blendish/blendish.c 2022-04-11 20:05:39.202902589 +0100
+++ blendish.c 2022-04-11 19:51:05.409742542 +0100
--- ../Rack/dep/oui-blendish/blendish.c 2022-09-21 19:49:29.973066921 +0100
+++ blendish.c 2022-09-21 19:41:45.883648777 +0100
@@ -61,7 +61,7 @@
}


+ 2
- 2
src/override/diffs/common.cpp.diff View File

@@ -1,5 +1,5 @@
--- ../Rack/src/common.cpp 2022-04-11 20:05:02.007283878 +0100
+++ common.cpp 2022-07-12 09:45:31.518663160 +0100
--- ../Rack/src/common.cpp 2022-09-21 19:49:12.199540706 +0100
+++ common.cpp 2022-09-21 19:41:45.883648777 +0100
@@ -1,33 +1,77 @@
+/*
+ * DISTRHO Cardinal Plugin


+ 2
- 2
src/override/diffs/context.cpp.diff View File

@@ -1,5 +1,5 @@
--- ../Rack/src/context.cpp 2022-04-11 20:05:02.007283878 +0100
+++ context.cpp 2022-04-11 19:51:05.409742542 +0100
--- ../Rack/src/context.cpp 2022-09-21 19:49:12.199540706 +0100
+++ context.cpp 2022-09-21 19:41:45.883648777 +0100
@@ -1,3 +1,30 @@
+/*
+ * DISTRHO Cardinal Plugin


+ 62
- 0
src/override/diffs/minblep.cpp.diff View File

@@ -0,0 +1,62 @@
--- ../Rack/src/dsp/minblep.cpp 2022-09-21 19:49:12.200540736 +0100
+++ minblep.cpp 2022-09-21 19:41:45.884648820 +0100
@@ -1,3 +1,30 @@
+/*
+ * DISTRHO Cardinal Plugin
+ * Copyright (C) 2021-2022 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
+ * published by the Free Software Foundation; either version 3 of
+ * the License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * For a full copy of the GNU General Public License see the LICENSE file.
+ */
+
+/**
+ * This file is an edited version of VCVRack's dsp/minblep.cpp
+ * Copyright (C) 2016-2021 VCV.
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ */
+
#include <dsp/minblep.hpp>
#include <dsp/fft.hpp>
#include <dsp/window.hpp>
@@ -10,7 +37,7 @@
void minBlepImpulse(int z, int o, float* output) {
// Symmetric sinc array with `z` zero-crossings on each side
int n = 2 * z * o;
- float* x = new float[n];
+ float* x = (float*) pffft_aligned_malloc(sizeof(float) * n);
for (int i = 0; i < n; i++) {
float p = math::rescale((float) i, 0.f, (float)(n - 1), (float) - z, (float) z);
x[i] = sinc(p);
@@ -20,7 +47,7 @@
blackmanHarrisWindow(x, n);
// Real cepstrum
- float* fx = new float[2 * n];
+ float* fx = (float*) pffft_aligned_malloc(sizeof(float) * 2 * n);
// Valgrind complains that the array is uninitialized for some reason, unless we clear it.
std::memset(fx, 0, sizeof(float) * 2 * n);
RealFFT rfft(n);
@@ -75,8 +102,8 @@
std::memcpy(output, x, n * sizeof(float));
// Cleanup
- delete[] x;
- delete[] fx;
+ pffft_aligned_free(x);
+ pffft_aligned_free(fx);
}

+ 2
- 2
src/override/diffs/plugin.cpp.diff View File

@@ -1,5 +1,5 @@
--- ../Rack/src/plugin.cpp 2022-07-12 09:46:20.716165650 +0100
+++ plugin.cpp 2022-05-27 23:15:35.681273727 +0100
--- ../Rack/src/plugin.cpp 2022-09-21 19:49:12.200540736 +0100
+++ plugin.cpp 2022-09-21 19:41:45.884648820 +0100
@@ -1,342 +1,41 @@
-#include <thread>
-#include <map>


Loading…
Cancel
Save