| @@ -324,13 +324,13 @@ void WindowSetPluginRemote(Window* const window, NanoTopLevelWidget* const tlw) | |||
| // Init settings | |||
| WindowParametersRestore(window); | |||
| widget::Widget::ContextCreateEvent e; | |||
| widget::Widget::ContextCreateEvent e = {}; | |||
| e.vg = window->vg; | |||
| APP->scene->onContextCreate(e); | |||
| } | |||
| else | |||
| { | |||
| widget::Widget::ContextDestroyEvent e; | |||
| widget::Widget::ContextDestroyEvent e = {}; | |||
| e.vg = window->vg; | |||
| APP->scene->onContextDestroy(e); | |||
| @@ -437,13 +437,13 @@ void WindowSetPluginUI(Window* const window, CardinalBaseUI* const ui) | |||
| // Init settings | |||
| WindowParametersRestore(window); | |||
| widget::Widget::ContextCreateEvent e; | |||
| widget::Widget::ContextCreateEvent e = {}; | |||
| e.vg = window->vg; | |||
| APP->scene->onContextCreate(e); | |||
| } | |||
| else | |||
| { | |||
| widget::Widget::ContextDestroyEvent e; | |||
| widget::Widget::ContextDestroyEvent e = {}; | |||
| e.vg = window->vg; | |||
| APP->scene->onContextDestroy(e); | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/engine/Engine.cpp 2023-06-11 21:02:02.644002965 +0200 | |||
| +++ Engine.cpp 2023-06-11 20:56:09.472002797 +0200 | |||
| --- ../Rack/src/engine/Engine.cpp 2023-05-20 17:03:33.006081772 +0200 | |||
| +++ Engine.cpp 2023-05-22 04:26:39.902464764 +0200 | |||
| @@ -1,3 +1,30 @@ | |||
| +/* | |||
| + * DISTRHO Cardinal Plugin | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/app/MenuBar.cpp 2023-06-11 21:02:02.640002965 +0200 | |||
| +++ MenuBar.cpp 2023-07-11 19:18:16.204016531 +0200 | |||
| --- ../Rack/src/app/MenuBar.cpp 2023-05-20 17:03:33.005081737 +0200 | |||
| +++ MenuBar.cpp 2023-08-15 17:56:23.782915145 +0200 | |||
| @@ -1,8 +1,33 @@ | |||
| +/* | |||
| + * DISTRHO Cardinal Plugin | |||
| @@ -44,12 +44,13 @@ | |||
| #include <window/Window.hpp> | |||
| #include <asset.hpp> | |||
| #include <context.hpp> | |||
| @@ -25,8 +51,28 @@ | |||
| @@ -25,8 +51,29 @@ | |||
| #include <patch.hpp> | |||
| #include <library.hpp> | |||
| +#include "../CardinalCommon.hpp" | |||
| +#include "../CardinalRemote.hpp" | |||
| +#include "../PluginContext.hpp" | |||
| +#include "DistrhoPlugin.hpp" | |||
| +#include "DistrhoStandaloneUtils.hpp" | |||
| + | |||
| @@ -73,7 +74,7 @@ | |||
| namespace app { | |||
| namespace menuBar { | |||
| @@ -48,79 +94,238 @@ | |||
| @@ -48,79 +95,238 @@ | |||
| }; | |||
| @@ -349,7 +350,7 @@ | |||
| } | |||
| }; | |||
| @@ -166,7 +371,7 @@ | |||
| @@ -166,7 +372,7 @@ | |||
| menu->addChild(new ui::MenuSeparator); | |||
| @@ -358,7 +359,7 @@ | |||
| } | |||
| }; | |||
| @@ -256,7 +461,7 @@ | |||
| @@ -256,7 +462,7 @@ | |||
| return settings::cableTension; | |||
| } | |||
| float getDefaultValue() override { | |||
| @@ -367,7 +368,7 @@ | |||
| } | |||
| float getDisplayValue() override { | |||
| return getValue() * 100; | |||
| @@ -393,49 +598,39 @@ | |||
| @@ -393,49 +599,39 @@ | |||
| }; | |||
| @@ -442,7 +443,7 @@ | |||
| menu->addChild(createBoolPtrMenuItem("Show tooltips", "", &settings::tooltips)); | |||
| @@ -460,9 +655,18 @@ | |||
| @@ -460,9 +656,18 @@ | |||
| menu->addChild(haloBrightnessSlider); | |||
| menu->addChild(new ui::MenuSeparator); | |||
| @@ -461,7 +462,7 @@ | |||
| static const std::vector<std::string> knobModeLabels = { | |||
| "Linear", | |||
| @@ -487,11 +691,34 @@ | |||
| @@ -487,11 +692,34 @@ | |||
| menu->addChild(knobScrollSensitivitySlider); | |||
| menu->addChild(new ui::MenuSeparator); | |||
| @@ -499,7 +500,7 @@ | |||
| } | |||
| }; | |||
| @@ -501,47 +728,6 @@ | |||
| @@ -501,48 +729,11 @@ | |||
| //////////////////// | |||
| @@ -545,9 +546,14 @@ | |||
| - | |||
| - | |||
| struct EngineButton : MenuButton { | |||
| +#ifdef HAVE_LIBLO | |||
| + bool remoteServerStarted = false; | |||
| +#endif | |||
| + | |||
| void onAction(const ActionEvent& e) override { | |||
| ui::Menu* menu = createMenu(); | |||
| @@ -555,268 +741,46 @@ | |||
| menu->cornerFlags = BND_CORNER_TOP; | |||
| @@ -555,269 +746,87 @@ | |||
| settings::cpuMeter ^= true; | |||
| })); | |||
| @@ -558,10 +564,7 @@ | |||
| - int cores = system::getLogicalCoreCount() / 2; | |||
| - | |||
| - for (int i = 1; i <= 2 * cores; i++) { | |||
| + if (isUsingNativeAudio()) { | |||
| + if (supportsAudioInput()) { | |||
| + const bool enabled = isAudioInputEnabled(); | |||
| std::string rightText; | |||
| - std::string rightText; | |||
| - if (i == cores) | |||
| - rightText += "(most modules)"; | |||
| - else if (i == 1) | |||
| @@ -693,17 +696,24 @@ | |||
| - plugin::Plugin* p = plugin::getPlugin(slug); | |||
| - if (p) { | |||
| - rightText += p->version + " → "; | |||
| - } | |||
| +#ifdef HAVE_LIBLO | |||
| + if (isStandalone()) { | |||
| + CardinalPluginContext* const context = static_cast<CardinalPluginContext*>(APP); | |||
| + CardinalBasePlugin* const plugin = static_cast<CardinalBasePlugin*>(context->plugin); | |||
| + | |||
| + // const bool remoteServerStarted = this->remoteServerStarted; | |||
| + const std::string remoteControlText = remoteServerStarted ? " " CHECKMARK_STRING : ""; | |||
| + | |||
| + menu->addChild(createMenuItem("Enable OSC remote control", remoteControlText, [=]() { | |||
| + if (remoteServerStarted) { | |||
| + remoteServerStarted = false; | |||
| + plugin->stopRemoteServer(); | |||
| + return; | |||
| } | |||
| - rightText += update.version; | |||
| + if (enabled) | |||
| + rightText = CHECKMARK_STRING; | |||
| + menu->addChild(createMenuItem("Enable Audio Input", rightText, [enabled]() { | |||
| + if (!enabled) | |||
| + requestAudioInput(); | |||
| + })); | |||
| } | |||
| - } | |||
| - } | |||
| - | |||
| - MenuItem::step(); | |||
| - } | |||
| - | |||
| @@ -715,8 +725,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(); | |||
| @@ -741,8 +756,12 @@ | |||
| - else if (!library::isLoggedIn()) { | |||
| - addChild(createMenuItem("Register VCV account", "", [=]() { | |||
| - system::openBrowser("https://vcvrack.com/login"); | |||
| - })); | |||
| - | |||
| + std::free(port); | |||
| + }); | |||
| })); | |||
| + } | |||
| +#endif | |||
| - ui::TextField* emailField = new ui::TextField; | |||
| - emailField->placeholder = "Email"; | |||
| - emailField->box.size.x = 240.0; | |||
| @@ -765,10 +784,29 @@ | |||
| - addChild(createMenuItem("Log out", "", [=]() { | |||
| - library::logOut(); | |||
| - })); | |||
| - | |||
| + if (isUsingNativeAudio()) { | |||
| + if (supportsAudioInput()) { | |||
| + const bool enabled = isAudioInputEnabled(); | |||
| + std::string rightText; | |||
| + if (enabled) | |||
| + rightText = CHECKMARK_STRING; | |||
| + menu->addChild(createMenuItem("Enable Audio Input", rightText, [enabled]() { | |||
| + if (!enabled) | |||
| + requestAudioInput(); | |||
| + })); | |||
| + } | |||
| - addChild(createMenuItem("Browse VCV Library", "", [=]() { | |||
| - system::openBrowser("https://library.vcvrack.com/"); | |||
| - })); | |||
| + if (supportsMIDI()) { | |||
| + std::string rightText; | |||
| + if (isMIDIEnabled()) | |||
| + rightText = CHECKMARK_STRING; | |||
| + menu->addChild(createMenuItem("Enable/Reconnect MIDI", rightText, []() { | |||
| + requestMIDI(); | |||
| + })); | |||
| + } | |||
| - SyncUpdatesItem* syncItem = new SyncUpdatesItem; | |||
| - syncItem->text = "Update all"; | |||
| @@ -783,22 +821,32 @@ | |||
| - updateItem->setUpdate(pair.first); | |||
| - addChild(updateItem); | |||
| - } | |||
| + if (supportsMIDI()) { | |||
| + std::string rightText; | |||
| + if (isMIDIEnabled()) | |||
| + rightText = CHECKMARK_STRING; | |||
| + menu->addChild(createMenuItem("Enable/Reconnect MIDI", rightText, []() { | |||
| + requestMIDI(); | |||
| + if (supportsBufferSizeChanges()) { | |||
| + static const std::vector<uint32_t> bufferSizes = { | |||
| + #ifdef DISTRHO_OS_WASM | |||
| + 256, 512, 1024, 2048, 4096, 8192, 16384 | |||
| + #else | |||
| + 128, 256, 512, 1024, 2048, 4096, 8192 | |||
| + #endif | |||
| + }; | |||
| + 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);} | |||
| + )); | |||
| + } | |||
| + })); | |||
| } | |||
| - } | |||
| - } | |||
| } | |||
| } | |||
| -}; | |||
| - | |||
| - | |||
| -struct LibraryButton : MenuButton { | |||
| - NotificationIcon* notification; | |||
| - | |||
| - LibraryButton() { | |||
| - notification = new NotificationIcon; | |||
| - addChild(notification); | |||
| @@ -815,41 +863,32 @@ | |||
| - }); | |||
| - t.detach(); | |||
| - } | |||
| - | |||
| - void step() override { | |||
| +#ifdef HAVE_LIBLO | |||
| void step() override { | |||
| - notification->box.pos = math::Vec(0, 0); | |||
| - notification->visible = library::hasUpdates(); | |||
| - | |||
| + MenuButton::step(); | |||
| - // Popup when updates finish downloading | |||
| - if (library::restartRequested) { | |||
| - 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 = { | |||
| + #ifdef DISTRHO_OS_WASM | |||
| + 256, 512, 1024, 2048, 4096, 8192, 16384 | |||
| + #else | |||
| + 128, 256, 512, 1024, 2048, 4096, 8192 | |||
| + #endif | |||
| + }; | |||
| + 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 (remoteServerStarted) { | |||
| + CardinalPluginContext* const context = static_cast<CardinalPluginContext*>(APP); | |||
| + CardinalBasePlugin* const plugin = static_cast<CardinalBasePlugin*>(context->plugin); | |||
| + plugin->stepRemoteServer(); | |||
| } | |||
| - | |||
| - MenuButton::step(); | |||
| } | |||
| +#endif | |||
| }; | |||
| @@ -827,63 +791,30 @@ | |||
| @@ -827,63 +836,30 @@ | |||
| struct HelpButton : MenuButton { | |||
| @@ -867,14 +906,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"); | |||
| - })); | |||
| @@ -921,7 +960,7 @@ | |||
| } | |||
| }; | |||
| @@ -926,15 +857,19 @@ | |||
| @@ -926,15 +902,19 @@ | |||
| text = ""; | |||
| @@ -944,7 +983,7 @@ | |||
| Label::step(); | |||
| } | |||
| @@ -944,7 +879,9 @@ | |||
| @@ -944,7 +924,9 @@ | |||
| struct MenuBar : widget::OpaqueWidget { | |||
| InfoLabel* infoLabel; | |||
| @@ -955,7 +994,7 @@ | |||
| const float margin = 5; | |||
| box.size.y = BND_WIDGET_HEIGHT + 2 * margin; | |||
| @@ -953,7 +890,7 @@ | |||
| @@ -953,7 +935,7 @@ | |||
| layout->spacing = math::Vec(0, 0); | |||
| addChild(layout); | |||
| @@ -964,7 +1003,7 @@ | |||
| fileButton->text = "File"; | |||
| layout->addChild(fileButton); | |||
| @@ -965,13 +902,11 @@ | |||
| @@ -965,13 +947,11 @@ | |||
| viewButton->text = "View"; | |||
| layout->addChild(viewButton); | |||
| @@ -980,7 +1019,7 @@ | |||
| HelpButton* helpButton = new HelpButton; | |||
| helpButton->text = "Help"; | |||
| @@ -1003,7 +938,7 @@ | |||
| @@ -1003,7 +983,7 @@ | |||
| widget::Widget* createMenuBar() { | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/plugin/Model.cpp 2023-06-11 21:02:02.644002965 +0200 | |||
| +++ Model.cpp 2023-06-11 20:56:09.472002797 +0200 | |||
| --- ../Rack/src/plugin/Model.cpp 2023-05-20 17:03:33.007081806 +0200 | |||
| +++ Model.cpp 2023-05-20 18:29:51.484669742 +0200 | |||
| @@ -1,3 +1,30 @@ | |||
| +/* | |||
| + * DISTRHO Cardinal Plugin | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/app/ModuleWidget.cpp 2023-06-11 21:02:02.640002965 +0200 | |||
| +++ ModuleWidget.cpp 2023-06-11 20:56:09.476002797 +0200 | |||
| --- ../Rack/src/app/ModuleWidget.cpp 2023-05-20 17:03:33.005081737 +0200 | |||
| +++ ModuleWidget.cpp 2023-05-20 18:40:08.948302802 +0200 | |||
| @@ -1,8 +1,35 @@ | |||
| +/* | |||
| + * DISTRHO Cardinal Plugin | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/widget/OpenGlWidget.cpp 2023-06-11 21:02:02.644002965 +0200 | |||
| +++ OpenGlWidget.cpp 2023-06-11 20:56:09.476002797 +0200 | |||
| --- ../Rack/src/widget/OpenGlWidget.cpp 2022-09-21 20:49:12.201540766 +0200 | |||
| +++ OpenGlWidget.cpp 2023-05-20 18:41:22.249200486 +0200 | |||
| @@ -1,3 +1,30 @@ | |||
| +/* | |||
| + * DISTRHO Cardinal Plugin | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/app/Scene.cpp 2023-06-11 21:02:02.640002965 +0200 | |||
| +++ Scene.cpp 2023-06-11 20:56:09.476002797 +0200 | |||
| --- ../Rack/src/app/Scene.cpp 2022-09-21 20:49:12.199540706 +0200 | |||
| +++ Scene.cpp 2023-07-03 09:30:14.548718644 +0200 | |||
| @@ -1,12 +1,36 @@ | |||
| -#include <thread> | |||
| - | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/window/Window.cpp 2023-06-11 21:02:02.648002965 +0200 | |||
| +++ Window.cpp 2023-07-13 17:01:53.848000425 +0200 | |||
| --- ../Rack/src/window/Window.cpp 2023-05-20 17:03:33.007081806 +0200 | |||
| +++ Window.cpp 2023-08-28 09:55:57.292032175 +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,475 @@ | |||
| @@ -79,338 +139,478 @@ | |||
| } | |||
| @@ -141,7 +141,7 @@ | |||
| - int lastWindowY = 0; | |||
| - int lastWindowWidth = 0; | |||
| - int lastWindowHeight = 0; | |||
| + DISTRHO_NAMESPACE::UI* ui = nullptr; | |||
| + CardinalBaseUI* ui = nullptr; | |||
| + DGL_NAMESPACE::NanoTopLevelWidget* tlw = nullptr; | |||
| + DISTRHO_NAMESPACE::WindowParameters params; | |||
| + DISTRHO_NAMESPACE::WindowParametersCallback* callback = nullptr; | |||
| @@ -410,12 +410,14 @@ | |||
| - if (APP->event->handleText(APP->window->internal->lastMousePos, codepoint)) | |||
| - return; | |||
| -} | |||
| + widget::Widget::ContextCreateEvent e; | |||
| + widget::Widget::ContextCreateEvent e = {}; | |||
| + e.vg = window->vg; | |||
| + APP->scene->onContextCreate(e); | |||
| + } | |||
| + else | |||
| + { | |||
| + widget::Widget::ContextDestroyEvent e; | |||
| + widget::Widget::ContextDestroyEvent e = {}; | |||
| + e.vg = window->vg; | |||
| + APP->scene->onContextDestroy(e); | |||
| +#if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS | |||
| @@ -470,7 +472,7 @@ | |||
| - std::vector<std::string> pathsVec; | |||
| - for (int i = 0; i < count; i++) { | |||
| - pathsVec.push_back(paths[i]); | |||
| +void WindowSetPluginUI(Window* const window, DISTRHO_NAMESPACE::UI* const ui) | |||
| +void WindowSetPluginUI(Window* const window, CardinalBaseUI* const ui) | |||
| +{ | |||
| + // if nanovg context failed, init only bare minimum | |||
| + if (window->vg == nullptr) | |||
| @@ -643,12 +645,14 @@ | |||
| - if (!vg) { | |||
| - 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"); | |||
| + widget::Widget::ContextCreateEvent e; | |||
| + widget::Widget::ContextCreateEvent e = {}; | |||
| + e.vg = window->vg; | |||
| + APP->scene->onContextCreate(e); | |||
| } | |||
| + else | |||
| + { | |||
| + widget::Widget::ContextDestroyEvent e; | |||
| + widget::Widget::ContextDestroyEvent e = {}; | |||
| + e.vg = window->vg; | |||
| + APP->scene->onContextDestroy(e); | |||
| - // Load default Blendish font | |||
| @@ -832,7 +836,8 @@ | |||
| + CardinalBaseUI* const ui = static_cast<CardinalBaseUI*>(context); | |||
| + if (char* const screenshot = String::asBase64(data, size).getAndReleaseBuffer()) { | |||
| + ui->setState("screenshot", screenshot); | |||
| + remoteUtils::sendScreenshotToRemote(ui->remoteDetails, screenshot); | |||
| + if (ui->remoteDetails != nullptr) | |||
| + remoteUtils::sendScreenshotToRemote(ui->remoteDetails, screenshot); | |||
| + std::free(screenshot); | |||
| } | |||
| } | |||
| @@ -841,15 +846,13 @@ | |||
| void Window::step() { | |||
| + DISTRHO_SAFE_ASSERT_RETURN(internal->tlw != nullptr,); | |||
| + | |||
| + if (vg == nullptr) | |||
| + if (internal->tlw == nullptr || vg == nullptr) | |||
| + return; | |||
| + | |||
| double frameTime = system::getTime(); | |||
| if (std::isfinite(internal->frameTime)) { | |||
| internal->lastFrameDuration = frameTime - internal->frameTime; | |||
| @@ -422,57 +619,48 @@ | |||
| @@ -422,57 +622,52 @@ | |||
| // Make event handlers and step() have a clean NanoVG context | |||
| nvgReset(vg); | |||
| @@ -886,7 +889,11 @@ | |||
| - glfwSetWindowTitle(win, windowTitle.c_str()); | |||
| - internal->lastWindowTitle = windowTitle; | |||
| + if (isStandalone()) { | |||
| +#if CARDINAL_VARIANT_MINI | |||
| + std::string windowTitle = "Cardinal Mini"; | |||
| +#else | |||
| + std::string windowTitle = "Cardinal"; | |||
| +#endif | |||
| + if (APP->patch->path != "") { | |||
| + windowTitle += " - "; | |||
| + if (!APP->history->isSaved()) | |||
| @@ -938,7 +945,7 @@ | |||
| windowRatio = (float)fbWidth / winWidth; | |||
| // t1 = system::getTime(); | |||
| @@ -486,10 +674,8 @@ | |||
| @@ -486,10 +681,8 @@ | |||
| // t2 = system::getTime(); | |||
| // Render scene | |||
| @@ -950,7 +957,7 @@ | |||
| nvgScale(vg, pixelRatio, pixelRatio); | |||
| // Draw scene | |||
| @@ -500,23 +686,16 @@ | |||
| @@ -500,23 +693,16 @@ | |||
| // t3 = system::getTime(); | |||
| glViewport(0, 0, fbWidth, fbHeight); | |||
| @@ -978,14 +985,14 @@ | |||
| // 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 +705,130 @@ | |||
| @@ -526,163 +712,132 @@ | |||
| // (t5 - t4) * 1e3f, | |||
| // (t5 - frameTime) * 1e3f | |||
| // ); | |||
| - internal->frame++; | |||
| -} | |||
| + ++internal->frame; | |||
| + | |||
| +#ifdef CARDINAL_WINDOW_CAN_GENERATE_SCREENSHOTS | |||
| + if (internal->generateScreenshotStep != kScreenshotStepNone) { | |||
| + ++internal->generateScreenshotStep; | |||
| @@ -998,6 +1005,9 @@ | |||
| + constexpr const int depth = 3; | |||
| +#endif | |||
| + // Allocate pixel color buffer | |||
| + uint8_t* const pixels = new uint8_t[winHeight * winWidth * 4]; | |||
| -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; | |||
| @@ -1005,9 +1015,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); | |||
| + // Allocate pixel color buffer | |||
| + uint8_t* const pixels = new uint8_t[winHeight * winWidth * 4]; | |||
| + | |||
| + // 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); | |||
| @@ -1015,10 +1022,10 @@ | |||
| + if (internal->generateScreenshotStep == kScreenshotStepSaving) | |||
| + { | |||
| + // Write pixels to PNG | |||
| + const int stride = winWidth * depth; | |||
| + uint8_t* const pixelsWithOffset = pixels + (stride * y); | |||
| + Window__flipBitmap(pixels, winWidth, winHeight, depth); | |||
| + winHeight -= y; | |||
| + const int stride = winWidth * depth; | |||
| + uint8_t* const pixelsWithOffset = pixels + (stride * y); | |||
| +#ifdef STBI_WRITE_NO_STDIO | |||
| + Window__downscaleBitmap(pixelsWithOffset, winWidth, winHeight); | |||
| + stbi_write_png_to_func(Window__writeImagePNG, internal->ui, | |||
| @@ -1028,8 +1035,10 @@ | |||
| +#endif | |||
| + | |||
| + internal->generateScreenshotStep = kScreenshotStepNone; | |||
| +#ifdef CARDINAL_TRANSPARENT_SCREENSHOTS | |||
| + APP->scene->menuBar->show(); | |||
| + APP->scene->rack->children.front()->show(); | |||
| +#endif | |||
| + } | |||
| + | |||
| + delete[] pixels; | |||
| @@ -1218,7 +1227,7 @@ | |||
| } | |||
| @@ -702,7 +848,7 @@ | |||
| @@ -702,7 +857,7 @@ | |||
| double Window::getFrameDurationRemaining() { | |||
| @@ -1227,7 +1236,7 @@ | |||
| return frameDuration - (system::getTime() - internal->frameTime); | |||
| } | |||
| @@ -713,14 +859,15 @@ | |||
| @@ -713,14 +868,15 @@ | |||
| return pair->second; | |||
| // Load font | |||
| @@ -1246,7 +1255,7 @@ | |||
| } | |||
| internal->fontCache[filename] = font; | |||
| return font; | |||
| @@ -733,14 +880,15 @@ | |||
| @@ -733,14 +889,15 @@ | |||
| return pair->second; | |||
| // Load image | |||
| @@ -1265,7 +1274,7 @@ | |||
| } | |||
| internal->imageCache[filename] = image; | |||
| return image; | |||
| @@ -757,28 +905,156 @@ | |||
| @@ -757,28 +914,156 @@ | |||
| } | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/dep/oui-blendish/blendish.c 2023-06-11 21:02:28.136002978 +0200 | |||
| +++ blendish.c 2023-06-11 20:56:09.476002797 +0200 | |||
| --- ../Rack/dep/oui-blendish/blendish.c 2022-09-21 20:49:29.973066921 +0200 | |||
| +++ blendish.c 2022-09-21 20:41:45.883648777 +0200 | |||
| @@ -61,7 +61,7 @@ | |||
| } | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/common.cpp 2023-06-11 21:02:02.640002965 +0200 | |||
| +++ common.cpp 2023-06-11 20:56:09.476002797 +0200 | |||
| --- ../Rack/src/common.cpp 2023-05-20 17:03:33.006081772 +0200 | |||
| +++ common.cpp 2023-05-20 19:44:40.371645493 +0200 | |||
| @@ -1,12 +1,57 @@ | |||
| +/* | |||
| + * DISTRHO Cardinal Plugin | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/context.cpp 2023-06-11 21:02:02.640002965 +0200 | |||
| +++ context.cpp 2023-06-11 20:56:09.476002797 +0200 | |||
| --- ../Rack/src/context.cpp 2023-05-20 17:03:33.006081772 +0200 | |||
| +++ context.cpp 2023-05-20 18:08:56.497736615 +0200 | |||
| @@ -1,14 +1,44 @@ | |||
| +/* | |||
| + * DISTRHO Cardinal Plugin | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/dsp/minblep.cpp 2023-06-11 21:02:02.644002965 +0200 | |||
| +++ minblep.cpp 2023-06-11 20:56:09.476002797 +0200 | |||
| --- ../Rack/src/dsp/minblep.cpp 2022-09-21 20:49:12.200540736 +0200 | |||
| +++ minblep.cpp 2023-05-20 18:21:44.019059009 +0200 | |||
| @@ -1,3 +1,30 @@ | |||
| +/* | |||
| + * DISTRHO Cardinal Plugin | |||
| @@ -1,5 +1,5 @@ | |||
| --- ../Rack/src/plugin.cpp 2023-06-11 21:02:02.644002965 +0200 | |||
| +++ plugin.cpp 2023-06-11 20:56:09.476002797 +0200 | |||
| --- ../Rack/src/plugin.cpp 2023-05-20 17:03:33.006081772 +0200 | |||
| +++ plugin.cpp 2023-05-20 18:43:27.496323540 +0200 | |||
| @@ -1,356 +1,46 @@ | |||
| -#include <thread> | |||
| -#include <map> | |||