diff --git a/source/PluginManagement.cpp b/source/PluginManagement.cpp index 249b884..2f5f79d 100644 --- a/source/PluginManagement.cpp +++ b/source/PluginManagement.cpp @@ -3,6 +3,7 @@ #include "hooks.h" #include "plugin/PluginContainer.h" #include "plugin/PluginLinkInformationFactory.h" +#include "plugin/PluginLoadWrapper.h" #include "plugin/PluginMetaInformationFactory.h" #include "utils/ElfUtils.h" #include "utils/StringTools.h" @@ -10,49 +11,35 @@ #include #include #include -#include #include static uint32_t sTrampolineID = 0; -bool CheckIfAllowed(const PluginMetaInformation &metaInfo) { - std::vector> allowList = { - {"Maschell", "Aroma Base Plugin"}, - {"Maschell", "DRC Region Free Plugin"}, - {"Maschell", "Homebrew on Wii U menu"}, - {"Maschell", "Region Free Plugin"}, - {"Maschell", "Wiiload"}, - {"mtheall, Maschell", "ftpiiu"}, - }; - return std::any_of(allowList.begin(), allowList.end(), [&metaInfo](const auto &cur) { - return metaInfo.getAuthor() == cur.first && metaInfo.getName() == cur.second; - }); -} - std::vector -PluginManagement::loadPlugins(const std::set, PluginDataSharedPtrComparator> &pluginDataList, std::vector &trampolineData) { +PluginManagement::loadPlugins(const std::vector &pluginDataList, std::vector &trampolineData) { std::vector plugins; - for (const auto &pluginData : pluginDataList) { + for (const auto &pluginDataWrapper : pluginDataList) { PluginParseErrors error = PLUGIN_PARSE_ERROR_UNKNOWN; - auto metaInfo = PluginMetaInformationFactory::loadPlugin(*pluginData, error); + auto metaInfo = PluginMetaInformationFactory::loadPlugin(*pluginDataWrapper.getPluginData(), error); if (metaInfo && error == PLUGIN_PARSE_ERROR_NONE) { - if (!pluginData->getSource().ends_with(".wps") || CheckIfAllowed(*metaInfo)) { + if (pluginDataWrapper.isLoadAndLink()) { DEBUG_FUNCTION_LINE_INFO("We want to link %s by %s", metaInfo->getName().c_str(), metaInfo->getAuthor().c_str()); - auto linkInfo = PluginLinkInformationFactory::load(*pluginData, trampolineData, sTrampolineID++); + + auto linkInfo = PluginLinkInformationFactory::load(*pluginDataWrapper.getPluginData(), trampolineData, sTrampolineID++); if (!linkInfo) { - auto errMsg = string_format("Failed to load plugin: %s", pluginData->getSource().c_str()); + auto errMsg = string_format("Failed to load plugin: %s", pluginDataWrapper.getPluginData()->getSource().c_str()); DEBUG_FUNCTION_LINE_ERR("%s", errMsg.c_str()); DisplayErrorNotificationMessage(errMsg, 15.0f); continue; } - plugins.emplace_back(std::move(*metaInfo), std::move(*linkInfo), pluginData); + plugins.emplace_back(std::move(*metaInfo), std::move(*linkInfo), pluginDataWrapper.getPluginData()); } else { DEBUG_FUNCTION_LINE_INFO("We want to skip %s by %s", metaInfo->getName().c_str(), metaInfo->getAuthor().c_str()); - plugins.emplace_back(std::move(*metaInfo), PluginLinkInformation::CreateStub(), pluginData); + plugins.emplace_back(std::move(*metaInfo), PluginLinkInformation::CreateStub(), pluginDataWrapper.getPluginData()); } } else { - auto errMsg = string_format("Failed to load plugin: %s", pluginData->getSource().c_str()); + auto errMsg = string_format("Failed to load plugin: %s", *pluginDataWrapper.getPluginData()->getSource().c_str()); if (error == PLUGIN_PARSE_ERROR_INCOMPATIBLE_VERSION) { errMsg += ". Incompatible version."; } diff --git a/source/PluginManagement.h b/source/PluginManagement.h index f5a4691..4d1c170 100644 --- a/source/PluginManagement.h +++ b/source/PluginManagement.h @@ -1,18 +1,17 @@ #pragma once #include "plugin/PluginContainer.h" - +#include "plugin/PluginLoadWrapper.h" #include #include #include -#include #include #include class PluginManagement { public: static std::vector loadPlugins( - const std::set, PluginDataSharedPtrComparator> &pluginDataList, + const std::vector &pluginDataList, std::vector &trampolineData); static void callInitHooks(const std::vector &plugins, const std::function &pred); diff --git a/source/globals.cpp b/source/globals.cpp index 9046d00..04cd563 100644 --- a/source/globals.cpp +++ b/source/globals.cpp @@ -1,6 +1,7 @@ #include "globals.h" #include "plugin/PluginContainer.h" #include "plugin/PluginData.h" +#include "plugin/PluginLoadWrapper.h" StoredBuffer gStoredTVBuffer = {}; StoredBuffer gStoredDRCBuffer = {}; @@ -9,7 +10,7 @@ std::vector gLoadedPlugins; std::vector gTrampData; std::set, PluginDataSharedPtrComparator> gLoadedData; -std::vector> gLoadOnNextLaunch; +std::vector gLoadOnNextLaunch; std::mutex gLoadedDataMutex; std::map gUsedRPLs; std::vector gAllocatedAddresses; diff --git a/source/globals.h b/source/globals.h index 786c5d2..2a6b632 100644 --- a/source/globals.h +++ b/source/globals.h @@ -16,6 +16,7 @@ class PluginDataSharedPtrComparator; class PluginData; class PluginContainer; +class PluginLoadWrapper; extern StoredBuffer gStoredTVBuffer; extern StoredBuffer gStoredDRCBuffer; @@ -25,7 +26,7 @@ extern std::vector gTrampData; extern std::vector gLoadedPlugins; extern std::set, PluginDataSharedPtrComparator> gLoadedData; -extern std::vector> gLoadOnNextLaunch; +extern std::vector gLoadOnNextLaunch; extern std::mutex gLoadedDataMutex; extern std::map gUsedRPLs; extern std::vector gAllocatedAddresses; diff --git a/source/main.cpp b/source/main.cpp index a65d221..ee61093 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -81,7 +81,8 @@ WUMS_APPLICATION_STARTS() { } OSReport("Running WiiUPluginLoaderBackend " MODULE_VERSION_FULL "\n"); - gStoredTVBuffer = {}; + gStoredTVBuffer = {}; + gConfigMenuShouldClose = false; gUsedRPLs.clear(); @@ -117,21 +118,21 @@ WUMS_APPLICATION_STARTS() { if (!gLoadOnNextLaunch.empty()) { std::vector pluginsToKeep; - std::set, PluginDataSharedPtrComparator> toBeLoaded; + std::vector toBeLoaded; // Check which plugins are already loaded and which needs to be - for (const auto &pluginData : gLoadOnNextLaunch) { + for (const auto &pluginLoadWrapper : gLoadOnNextLaunch) { // Check if the plugin data is already loaded if (auto it = std::ranges::find_if(gLoadedPlugins, - [&pluginData](const PluginContainer &container) { - return container.getPluginDataCopy()->getHandle() == pluginData->getHandle(); + [&pluginLoadWrapper](const PluginContainer &container) { + return container.getPluginDataCopy()->getHandle() == pluginLoadWrapper.getPluginData()->getHandle(); }); it != gLoadedPlugins.end()) { pluginsToKeep.push_back(std::move(*it)); gLoadedPlugins.erase(it); } else { // Load it if it's not already loaded - toBeLoaded.insert(pluginData); + toBeLoaded.push_back(pluginLoadWrapper); } } diff --git a/source/patcher/hooks_patcher_static.cpp b/source/patcher/hooks_patcher_static.cpp index 7ba7468..d01d042 100644 --- a/source/patcher/hooks_patcher_static.cpp +++ b/source/patcher/hooks_patcher_static.cpp @@ -50,7 +50,7 @@ static uint32_t lastData0 = 0; DECL_FUNCTION(BOOL, OSSendMessage, OSMessageQueue *queue, OSMessage *message, OSMessageFlags flags) { if (sConfigMenuOpened && queue == OSGetSystemMessageQueue()) { if (message != nullptr) { - if (message->args[0] == 0xfacebacc) { // Release foreground + if (message->args[0] == 0xfacebacc && sConfigMenuOpened) { // Release foreground gConfigMenuShouldClose = true; } } diff --git a/source/plugin/PluginDataFactory.cpp b/source/plugin/PluginDataFactory.cpp index 7ada625..134433c 100644 --- a/source/plugin/PluginDataFactory.cpp +++ b/source/plugin/PluginDataFactory.cpp @@ -17,6 +17,7 @@ #include "PluginDataFactory.h" #include "NotificationsUtils.h" +#include "PluginLoadWrapper.h" #include "fs/FSUtils.h" #include "utils/StringTools.h" #include "utils/logger.h" @@ -25,8 +26,8 @@ #include #include -std::set, PluginDataSharedPtrComparator> PluginDataFactory::loadDir(const std::string_view path) { - std::set, PluginDataSharedPtrComparator> result; +std::vector PluginDataFactory::loadDir(std::string_view path) { + std::vector result; dirent *dp; DIR *dfd; @@ -51,8 +52,18 @@ std::set, PluginDataSharedPtrComparator> PluginDataF auto full_file_path = string_format("%s/%s", path.data(), dp->d_name); DEBUG_FUNCTION_LINE("Loading plugin: %s", full_file_path.c_str()); + if (auto pluginData = load(full_file_path)) { - result.insert(std::move(pluginData)); + // TODO: This is only for testing. Remove me!c + bool shouldBeLoadedAndLinked = false; + if (full_file_path.ends_with("AromaBasePlugin.wps") || + full_file_path.ends_with("drc_region_free.wps") || + full_file_path.ends_with("regionfree.wps") || + full_file_path.ends_with("ftpiiu.wps") || + full_file_path.ends_with("wiiload.wps")) { + shouldBeLoadedAndLinked = true; + } + result.emplace_back(std::move(pluginData), shouldBeLoadedAndLinked); } else { auto errMsg = string_format("Failed to load plugin: %s", full_file_path.c_str()); DEBUG_FUNCTION_LINE_ERR("%s", errMsg.c_str()); diff --git a/source/plugin/PluginDataFactory.h b/source/plugin/PluginDataFactory.h index 38b8117..fbefd01 100644 --- a/source/plugin/PluginDataFactory.h +++ b/source/plugin/PluginDataFactory.h @@ -17,6 +17,7 @@ #pragma once #include "PluginData.h" +#include "PluginLoadWrapper.h" #include #include @@ -24,7 +25,7 @@ class PluginDataFactory { public: - static std::set, PluginDataSharedPtrComparator> loadDir(std::string_view path); + static std::vector loadDir(std::string_view path); static std::unique_ptr load(std::string_view path); diff --git a/source/plugin/PluginLoadWrapper.h b/source/plugin/PluginLoadWrapper.h new file mode 100644 index 0000000..3ac3ec4 --- /dev/null +++ b/source/plugin/PluginLoadWrapper.h @@ -0,0 +1,21 @@ +#pragma once +#include "PluginData.h" +#include + +class PluginLoadWrapper { +public: + PluginLoadWrapper(std::shared_ptr pluginData, const bool linkAndLoad) : mPluginData(std::move(pluginData)), mIsLoadAndLink(linkAndLoad) { + } + + [[nodiscard]] const std::shared_ptr &getPluginData() const { + return mPluginData; + } + + [[nodiscard]] bool isLoadAndLink() const { + return mIsLoadAndLink; + } + +private: + std::shared_ptr mPluginData; + bool mIsLoadAndLink = false; +}; \ No newline at end of file diff --git a/source/utils/config/ConfigDisplayItem.cpp b/source/utils/config/ConfigDisplayItem.cpp index cd3b244..f9cf21f 100644 --- a/source/utils/config/ConfigDisplayItem.cpp +++ b/source/utils/config/ConfigDisplayItem.cpp @@ -19,4 +19,8 @@ const WUPSConfigAPIBackend::WUPSConfig &ConfigDisplayItem::getConfig() const { bool ConfigDisplayItem::isActivePlugin() const { return mIsActivePlugin; +} + +void ConfigDisplayItem::toggleIsActivePlugin() { + mIsActivePlugin = !mIsActivePlugin; } \ No newline at end of file diff --git a/source/utils/config/ConfigDisplayItem.h b/source/utils/config/ConfigDisplayItem.h index 03ebb95..d714c82 100644 --- a/source/utils/config/ConfigDisplayItem.h +++ b/source/utils/config/ConfigDisplayItem.h @@ -22,6 +22,8 @@ public: [[nodiscard]] bool isActivePlugin() const; + void toggleIsActivePlugin(); + private: std::unique_ptr mConfig; GeneralConfigInformation mInfo; diff --git a/source/utils/config/ConfigRenderer.cpp b/source/utils/config/ConfigRenderer.cpp index 395d0d3..9eb6433 100644 --- a/source/utils/config/ConfigRenderer.cpp +++ b/source/utils/config/ConfigRenderer.cpp @@ -1,10 +1,16 @@ #include "ConfigRenderer.h" #include "globals.h" +#include "plugin/PluginLoadWrapper.h" #include "utils/DrawUtils.h" #include "utils/logger.h" #include "utils/utils.h" +#include +#include + ConfigRenderer::ConfigRenderer(std::vector &&vec) : mConfigs(std::move(vec)) { + std::copy(mConfigs.begin(), mConfigs.end(), + std::back_inserter(mAllConfigs)); std::copy_if(mConfigs.begin(), mConfigs.end(), std::back_inserter(mActiveConfigs), [&](const auto &value) { @@ -20,7 +26,8 @@ ConfigSubState ConfigRenderer::Update(Input &input, const WUPSConfigSimplePadDat return UpdateStateMain(input); case STATE_SUB: { if (mCategoryRenderer) { - if (const auto subResult = mCategoryRenderer->Update(input, simpleInputData, complexInputData); subResult != SUB_STATE_RUNNING) { + auto subResult = mCategoryRenderer->Update(input, simpleInputData, complexInputData); + if (subResult != SUB_STATE_RUNNING) { mNeedRedraw = true; mState = STATE_MAIN; return SUB_STATE_RUNNING; @@ -55,8 +62,7 @@ void ConfigRenderer::Render() const { bool ConfigRenderer::NeedsRedraw() const { if (mNeedRedraw) { return true; - } - if (mCategoryRenderer) { + } else if (mCategoryRenderer) { return mCategoryRenderer->NeedsRedraw(); } return false; @@ -70,52 +76,60 @@ void ConfigRenderer::ResetNeedsRedraw() { } ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) { - if (mActiveConfigs.empty()) { + auto &configs = GetConfigList(); + if (configs.empty()) { mNeedRedraw = true; return SUB_STATE_ERROR; } - const auto prevSelectedItem = mCursorPos; + auto prevSelectedItem = mCursorPos; - const auto totalElementSize = mActiveConfigs.size(); + auto totalElementSize = configs.size(); if (input.data.buttons_d & Input::eButtons::BUTTON_DOWN) { mCursorPos++; - } else if (input.data.buttons_d & Input::eButtons::BUTTON_LEFT) { - // Paging up - mCursorPos -= MAX_BUTTONS_ON_SCREEN - 1; - // Don't jump past the top - if (mCursorPos < 0) - mCursorPos = 0; - } else if (input.data.buttons_d & Input::eButtons::BUTTON_RIGHT) { - // Paging down - mCursorPos += MAX_BUTTONS_ON_SCREEN - 1; - // Don't jump past the bottom - if (mCursorPos >= totalElementSize) - mCursorPos = totalElementSize - 1; } else if (input.data.buttons_d & Input::eButtons::BUTTON_UP) { mCursorPos--; + } else if (input.data.buttons_d & Input::eButtons::BUTTON_PLUS) { + if (mSetActivePluginsMode) { + if (mActivePluginsDirty) { + for (const auto &cur : mConfigs) { + gLoadOnNextLaunch.emplace_back(cur.getConfigInformation().pluginData, cur.isActivePlugin()); + } + _SYSLaunchTitleWithStdArgsInNoSplash(OSGetTitleID(), nullptr); + } + mNeedRedraw = true; + mCategoryRenderer.reset(); + return SUB_STATE_RETURN; + } } else if (input.data.buttons_d & Input::eButtons::BUTTON_X) { mSetActivePluginsMode = !mSetActivePluginsMode; } else if (input.data.buttons_d & Input::eButtons::BUTTON_A) { - if (mCursorPos != mCurrentOpen) { - mCategoryRenderer.reset(); - mCategoryRenderer = make_unique_nothrow(&(mActiveConfigs[mCursorPos].get().getConfigInformation()), &(mActiveConfigs[mCursorPos].get().getConfig()), true); + if (mSetActivePluginsMode) { + mActivePluginsDirty = true; + mNeedRedraw = true; + configs[mCursorPos].get().toggleIsActivePlugin(); + return SUB_STATE_RUNNING; + } else { + if (mCursorPos != mCurrentOpen) { + mCategoryRenderer.reset(); + mCategoryRenderer = make_unique_nothrow(&(configs[mCursorPos].get().getConfigInformation()), &(configs[mCursorPos].get().getConfig()), true); + } + mNeedRedraw = true; + mCurrentOpen = mCursorPos; + mState = STATE_SUB; + return SUB_STATE_RUNNING; } - mNeedRedraw = true; - mCurrentOpen = mCursorPos; - mState = STATE_SUB; - return SUB_STATE_RUNNING; } else if (input.data.buttons_d & (Input::eButtons::BUTTON_B | Input::eButtons::BUTTON_HOME)) { mNeedRedraw = true; mCategoryRenderer.reset(); - for (const auto &element : mActiveConfigs) { + for (const auto &element : configs) { CallOnCloseCallback(element.get().getConfigInformation(), element.get().getConfig()); } return SUB_STATE_RETURN; } if (mCursorPos < 0) { - mCursorPos = totalElementSize - 1; - } else if (mCursorPos > totalElementSize - 1) { + mCursorPos = (int32_t) totalElementSize - 1; + } else if (mCursorPos > (int32_t) (totalElementSize - 1)) { mCursorPos = 0; } @@ -133,9 +147,9 @@ ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) { return SUB_STATE_RUNNING; } - void ConfigRenderer::RenderStateMain() const { - auto totalElementSize = (int32_t) mActiveConfigs.size(); + auto &configs = GetConfigList(); + auto totalElementSize = (int32_t) configs.size(); // Calculate the range of items to display int start = std::max(0, mRenderOffset); int end = std::min(start + MAX_BUTTONS_ON_SCREEN, totalElementSize); @@ -145,7 +159,7 @@ void ConfigRenderer::RenderStateMain() const { uint32_t yOffset = 8 + 24 + 8 + 4; for (int32_t i = start; i < end; i++) { - DrawConfigEntry(yOffset, mActiveConfigs[i].get().getConfigInformation(), i == mCursorPos); + DrawConfigEntry(yOffset, configs[i].get().getConfigInformation(), i == mCursorPos, configs[i].get().isActivePlugin()); yOffset += 42 + 8; } @@ -153,7 +167,11 @@ void ConfigRenderer::RenderStateMain() const { // draw top bar DrawUtils::setFontSize(24); - DrawUtils::print(16, 6 + 24, "Wii U Plugin System Config Menu"); + if (mSetActivePluginsMode) { + DrawUtils::print(16, 6 + 24, "Please select the plugin that should be active"); + } else { + DrawUtils::print(16, 6 + 24, "Wii U Plugin System Config Menu"); + } DrawUtils::setFontSize(18); DrawUtils::print(SCREEN_WIDTH - 16, 8 + 24, MODULE_VERSION_FULL, true); DrawUtils::drawRectFilled(8, 8 + 24 + 4, SCREEN_WIDTH - 8 * 2, 3, COLOR_BLACK); @@ -162,7 +180,11 @@ void ConfigRenderer::RenderStateMain() const { DrawUtils::drawRectFilled(8, SCREEN_HEIGHT - 24 - 8 - 4, SCREEN_WIDTH - 8 * 2, 3, COLOR_BLACK); DrawUtils::setFontSize(18); DrawUtils::print(16, SCREEN_HEIGHT - 10, "\ue07d Navigate "); - DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, "\ue000 Select", true); + if (mSetActivePluginsMode) { + DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, "\ue000 Select | \uE045 Apply", true); + } else { + DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, "\ue000 Activate", true); + } // draw scroll indicator DrawUtils::setFontSize(24); @@ -181,7 +203,7 @@ void ConfigRenderer::RenderStateMain() const { DrawUtils::endDraw(); } -void ConfigRenderer::DrawConfigEntry(const uint32_t yOffset, const GeneralConfigInformation &configInformation, const bool isHighlighted) const { +void ConfigRenderer::DrawConfigEntry(uint32_t yOffset, const GeneralConfigInformation &configInformation, bool isHighlighted, bool isActive) const { DrawUtils::setFontColor(COLOR_TEXT); if (isHighlighted) { @@ -190,11 +212,21 @@ void ConfigRenderer::DrawConfigEntry(const uint32_t yOffset, const GeneralConfig DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 2, COLOR_BORDER); } + int textXOffset = 16 * 2; + if (mSetActivePluginsMode) { + DrawUtils::setFontSize(24); + if (isActive) { + DrawUtils::print(textXOffset, yOffset + 8 + 24, "x"); + } + textXOffset += 32; + } + DrawUtils::setFontSize(24); - DrawUtils::print(16 * 2, yOffset + 8 + 24, configInformation.name.c_str()); - const uint32_t sz = DrawUtils::getTextWidth(configInformation.name.c_str()); + + DrawUtils::print(textXOffset, yOffset + 8 + 24, configInformation.name.c_str()); + uint32_t sz = DrawUtils::getTextWidth(configInformation.name.c_str()); DrawUtils::setFontSize(12); - DrawUtils::print(16 * 2 + sz + 4, yOffset + 8 + 24, configInformation.author.c_str()); + DrawUtils::print(textXOffset + sz + 4, yOffset + 8 + 24, configInformation.author.c_str()); DrawUtils::print(SCREEN_WIDTH - 16 * 2, yOffset + 8 + 24, configInformation.version.c_str(), true); } @@ -215,3 +247,10 @@ void ConfigRenderer::CallOnCloseCallback(const GeneralConfigInformation &info, c item->onCloseCallback(); } } + +const std::vector> &ConfigRenderer::GetConfigList() const { + if (mSetActivePluginsMode) { + return mAllConfigs; + } + return mActiveConfigs; +} \ No newline at end of file diff --git a/source/utils/config/ConfigRenderer.h b/source/utils/config/ConfigRenderer.h index 367fae1..91014e3 100644 --- a/source/utils/config/ConfigRenderer.h +++ b/source/utils/config/ConfigRenderer.h @@ -8,6 +8,7 @@ #include #include #include +#include #include class ConfigRenderer { @@ -30,17 +31,20 @@ private: void RenderStateMain() const; - void DrawConfigEntry(uint32_t yOffset, const GeneralConfigInformation &configInformation, bool isHighlighted) const; + void DrawConfigEntry(uint32_t yOffset, const GeneralConfigInformation &configInformation, bool isHighlighted, bool isActive) const; void CallOnCloseCallback(const GeneralConfigInformation &info, const std::vector> &categories); void CallOnCloseCallback(const GeneralConfigInformation &info, const WUPSConfigAPIBackend::WUPSConfig &config); + const std::vector> &GetConfigList() const; + enum State { STATE_MAIN = 0, STATE_SUB = 1, }; std::vector mConfigs; + std::vector> mAllConfigs; std::vector> mActiveConfigs; std::unique_ptr mCategoryRenderer = {}; @@ -50,6 +54,7 @@ private: int32_t mRenderOffset = 0; int32_t mCurrentOpen = -1; - bool mSetActivePluginsMode = false; bool mNeedRedraw = true; + bool mSetActivePluginsMode = false; + bool mActivePluginsDirty = false; }; diff --git a/source/utils/config/ConfigUtils.cpp b/source/utils/config/ConfigUtils.cpp index b720a72..ea89ae3 100644 --- a/source/utils/config/ConfigUtils.cpp +++ b/source/utils/config/ConfigUtils.cpp @@ -125,6 +125,7 @@ void ConfigUtils::displayMenu() { if (!config) { config = make_unique_nothrow(info.name); } + configs.emplace_back(info, std::move(config), plugin.isLinkedAndLoaded()); } diff --git a/source/utils/exports.cpp b/source/utils/exports.cpp index 5f56053..08e384d 100644 --- a/source/utils/exports.cpp +++ b/source/utils/exports.cpp @@ -35,7 +35,7 @@ extern "C" PluginBackendApiErrorType WUPSLoadAndLinkByDataHandle(const wups_back for (const auto &pluginData : gLoadedData) { if (pluginData->getHandle() == handle) { - gLoadOnNextLaunch.push_back(pluginData); + gLoadOnNextLaunch.emplace_back(pluginData, true); found = true; break; }