diff --git a/source/PluginManagement.cpp b/source/PluginManagement.cpp index 2f5f79d..2d22f67 100644 --- a/source/PluginManagement.cpp +++ b/source/PluginManagement.cpp @@ -24,7 +24,7 @@ PluginManagement::loadPlugins(const std::vector &pluginDataLi auto metaInfo = PluginMetaInformationFactory::loadPlugin(*pluginDataWrapper.getPluginData(), error); if (metaInfo && error == PLUGIN_PARSE_ERROR_NONE) { if (pluginDataWrapper.isLoadAndLink()) { - DEBUG_FUNCTION_LINE_INFO("We want to link %s by %s", metaInfo->getName().c_str(), metaInfo->getAuthor().c_str()); + DEBUG_FUNCTION_LINE_INFO("LOAD (ACTIVE) %s", metaInfo->getName().c_str()); auto linkInfo = PluginLinkInformationFactory::load(*pluginDataWrapper.getPluginData(), trampolineData, sTrampolineID++); if (!linkInfo) { @@ -35,7 +35,7 @@ PluginManagement::loadPlugins(const std::vector &pluginDataLi } 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()); + DEBUG_FUNCTION_LINE_INFO("LOAD (INACTIVE) %s", metaInfo->getName().c_str()); plugins.emplace_back(std::move(*metaInfo), PluginLinkInformation::CreateStub(), pluginDataWrapper.getPluginData()); } } else { diff --git a/source/main.cpp b/source/main.cpp index 1d443a0..addae80 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -48,8 +48,8 @@ WUMS_INITIALIZE() { VPadInput vpadInput; vpadInput.update(1280, 720); - auto buttomComboSafeMode = Input::eButtons::BUTTON_L | Input::eButtons::BUTTON_UP | Input::eButtons::BUTTON_MINUS; - if ((vpadInput.data.buttons_h & (buttomComboSafeMode)) == buttomComboSafeMode) { + constexpr auto buttonComboSafeMode = Input::eButtons::BUTTON_L | Input::eButtons::BUTTON_UP | Input::eButtons::BUTTON_MINUS; + if ((vpadInput.data.buttons_h & (buttonComboSafeMode)) == buttonComboSafeMode) { DrawUtils::RenderScreen([&vpadInput] { DrawUtils::beginDraw(); DrawUtils::clear(COLOR_BACKGROUND_WARN); @@ -57,12 +57,12 @@ WUMS_INITIALIZE() { // draw top bar DrawUtils::setFontSize(48); - const char *title = "! Plugin System Safe Mode triggered !"; + const auto title = "! Plugin System Safe Mode triggered !"; DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(title) / 2, 48 + 8, title, true); DrawUtils::drawRectFilled(8, 48 + 8 + 16, SCREEN_WIDTH - 8 * 2, 3, COLOR_WHITE); DrawUtils::setFontSize(24); - const char *message = "The Safe Mode of the Plugin System has been triggered."; + auto message = "The Safe Mode of the Plugin System has been triggered."; DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(message) / 2, SCREEN_HEIGHT / 2 - 48, message, true); message = "Any plugins 3rd party plugins have been disabled!"; DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(message) / 2, SCREEN_HEIGHT / 2 - 24, message, true); @@ -75,7 +75,7 @@ WUMS_INITIALIZE() { // draw bottom bar DrawUtils::drawRectFilled(8, SCREEN_HEIGHT - 24 - 8 - 4, SCREEN_WIDTH - 8 * 2, 3, COLOR_WHITE); DrawUtils::setFontSize(18); - const char *exitHints = "Continuing in 10 seconds."; + const auto exitHints = "Continuing in 10 seconds."; DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHints) / 2, SCREEN_HEIGHT - 8, exitHints, true); DrawUtils::endDraw(); @@ -87,6 +87,9 @@ WUMS_INITIALIZE() { } std::this_thread::sleep_for(16ms); } + DrawUtils::beginDraw(); + DrawUtils::clear(COLOR_BLACK); + DrawUtils::endDraw(); }); DEBUG_FUNCTION_LINE_INFO("Safe Mode activated!"); auto tobeIgnoredFilePath = getNonBaseAromaPluginFilenames(getPluginPath()); @@ -94,8 +97,8 @@ WUMS_INITIALIZE() { std::set inactivePlugins = WUPSBackendSettings::GetInactivePluginFilenames(); inactivePlugins.insert(tobeIgnoredFilePath.begin(), tobeIgnoredFilePath.end()); - for (const auto &d : inactivePlugins) { - DEBUG_FUNCTION_LINE_INFO("safemode: %s should be ignored", d.c_str()); + for (const auto &plugin : inactivePlugins) { + DEBUG_FUNCTION_LINE_INFO("safemode: %s will be deactivated", plugin.c_str()); } WUPSBackendSettings::SetInactivePluginFilenames(inactivePlugins); WUPSBackendSettings::SaveSettings(); @@ -179,16 +182,18 @@ WUMS_APPLICATION_STARTS() { } if (!gLoadOnNextLaunch.empty()) { + DEBUG_FUNCTION_LINE_INFO("Got new list of plugins to load"); std::vector pluginsToKeep; std::vector toBeLoaded; // Check which plugins are already loaded and which needs to be for (const auto &pluginLoadWrapper : gLoadOnNextLaunch) { + const auto &pluginNeedsNoReloadFn = [&pluginLoadWrapper](const PluginContainer &container) { + return (container.getPluginDataCopy()->getHandle() == pluginLoadWrapper.getPluginData()->getHandle()) && + (container.isLinkedAndLoaded() == pluginLoadWrapper.isLoadAndLink()); + }; // Check if the plugin data is already loaded - if (auto it = std::ranges::find_if(gLoadedPlugins, - [&pluginLoadWrapper](const PluginContainer &container) { - return container.getPluginDataCopy()->getHandle() == pluginLoadWrapper.getPluginData()->getHandle(); - }); + if (auto it = std::ranges::find_if(gLoadedPlugins, pluginNeedsNoReloadFn); it != gLoadedPlugins.end()) { pluginsToKeep.push_back(std::move(*it)); gLoadedPlugins.erase(it); @@ -198,9 +203,18 @@ WUMS_APPLICATION_STARTS() { } } + // deinit all plugins that are still in gLoadedPlugins list. std::vector pluginsToDeinit = std::move(gLoadedPlugins); gLoadedPlugins = std::move(pluginsToKeep); + for (const auto &p : pluginsToKeep) { + DEBUG_FUNCTION_LINE_INFO("KEEP: %s", p.getMetaInformation().getName().c_str()); + } + + for (const auto &p : pluginsToDeinit) { + DEBUG_FUNCTION_LINE_ERR("DEINIT: %s", p.getMetaInformation().getName().c_str()); + } + DEBUG_FUNCTION_LINE("Deinit unused plugins"); CleanupPlugins(std::move(pluginsToDeinit)); diff --git a/source/plugin/PluginContainer.cpp b/source/plugin/PluginContainer.cpp index 26f10f1..f88e154 100644 --- a/source/plugin/PluginContainer.cpp +++ b/source/plugin/PluginContainer.cpp @@ -76,7 +76,8 @@ WUPSStorageError PluginContainer::OpenStorage() { if (storageId.empty()) { return WUPS_STORAGE_ERROR_SUCCESS; } - auto res = StorageUtils::API::Internal::OpenStorage(storageId, mStorageRootItem); + + const auto res = StorageUtils::API::Internal::OpenStorage(storageId, mStorageRootItem); if (res != WUPS_STORAGE_ERROR_SUCCESS) { mStorageRootItem = nullptr; } diff --git a/source/utils/DrawUtils.cpp b/source/utils/DrawUtils.cpp index 955d392..12a9c1f 100644 --- a/source/utils/DrawUtils.cpp +++ b/source/utils/DrawUtils.cpp @@ -436,8 +436,8 @@ uint32_t DrawUtils::getTextWidth(const wchar_t *string) { return width; } -void DrawUtils::RenderScreen(const std::function& callback) { - gOnlyAcceptFromThread = OSGetCurrentThread(); +void DrawUtils::RenderScreen(const std::function &callback) { + gOnlyAcceptFromThread = OSGetCurrentThread(); bool wasHomeButtonMenuEnabled = OSIsHomeButtonMenuEnabled(); // Save copy of DC reg values diff --git a/source/utils/DrawUtils.h b/source/utils/DrawUtils.h index 843e361..22055fb 100644 --- a/source/utils/DrawUtils.h +++ b/source/utils/DrawUtils.h @@ -5,8 +5,8 @@ #include // visible screen sizes -#define SCREEN_WIDTH 854 -#define SCREEN_HEIGHT 480 +#define SCREEN_WIDTH 854 +#define SCREEN_HEIGHT 480 #define COLOR_BACKGROUND Color(238, 238, 238, 255) #define COLOR_BACKGROUND_WARN Color(255, 251, 4, 255) @@ -78,7 +78,7 @@ public: static uint32_t getTextWidth(const wchar_t *string); - static void RenderScreen(const std::function& callback); + static void RenderScreen(const std::function &callback); private: static bool mIsBackBuffer; diff --git a/source/utils/WUPSBackendSettings.cpp b/source/utils/WUPSBackendSettings.cpp index 1d3f483..b3e8b84 100644 --- a/source/utils/WUPSBackendSettings.cpp +++ b/source/utils/WUPSBackendSettings.cpp @@ -19,7 +19,7 @@ namespace WUPSBackendSettings { std::string folderPath = getModulePath() + "/configs/"; std::string filePath = folderPath + "wupsbackend.json"; - if (!ParseJsonFromFile(filePath, j)) { + if (ParseJsonFromFile(filePath, j) != UTILS_IO_ERROR_SUCCESS) { return false; } diff --git a/source/utils/config/ConfigDefines.h b/source/utils/config/ConfigDefines.h index b5f9325..a702632 100644 --- a/source/utils/config/ConfigDefines.h +++ b/source/utils/config/ConfigDefines.h @@ -3,7 +3,7 @@ #include #include -#define MAX_BUTTONS_ON_SCREEN 8 +#define MAX_BUTTONS_ON_SCREEN 8 struct StoredBuffer { void *buffer; @@ -16,6 +16,6 @@ struct StoredBuffer { enum ConfigSubState { SUB_STATE_RUNNING = 0, SUB_STATE_RETURN = 1, - SUB_STATE_RETURN_WITH_PLUGIN_RELOAD = 1, - SUB_STATE_ERROR = 2, + SUB_STATE_RETURN_WITH_PLUGIN_RELOAD = 2, + SUB_STATE_ERROR = 3, }; \ No newline at end of file diff --git a/source/utils/config/ConfigRenderer.cpp b/source/utils/config/ConfigRenderer.cpp index 91720e5..670a4c0 100644 --- a/source/utils/config/ConfigRenderer.cpp +++ b/source/utils/config/ConfigRenderer.cpp @@ -26,8 +26,9 @@ ConfigSubState ConfigRenderer::Update(Input &input, const WUPSConfigSimplePadDat if (mCategoryRenderer) { auto subResult = mCategoryRenderer->Update(input, simpleInputData, complexInputData); if (subResult != SUB_STATE_RUNNING) { - mNeedRedraw = true; - mState = STATE_MAIN; + mNeedRedraw = true; + mActivePluginsDirty = false; + mState = STATE_MAIN; return SUB_STATE_RUNNING; } return SUB_STATE_RUNNING; @@ -76,7 +77,13 @@ void ConfigRenderer::ResetNeedsRedraw() { ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) { auto &configs = GetConfigList(); - auto prevSelectedItem = mCursorPos; + const auto prevSelectedItem = mCursorPos; + + const auto &savePendingConfigFn = [&configs, this]() { + for (const auto &element : configs) { + CallOnCloseCallback(element.get().getConfigInformation(), element.get().getConfig()); + } + }; if (input.data.buttons_d & Input::eButtons::BUTTON_DOWN) { mCursorPos++; @@ -86,6 +93,7 @@ ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) { if (mSetActivePluginsMode) { mNeedRedraw = true; mCategoryRenderer.reset(); + savePendingConfigFn(); return SUB_STATE_RETURN_WITH_PLUGIN_RELOAD; } } else if (input.data.buttons_d & Input::eButtons::BUTTON_X) { @@ -115,15 +123,14 @@ ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) { for (auto &cur : mConfigs) { cur.resetIsActivePlugin(); } + mActivePluginsDirty = false; mNeedRedraw = true; mSetActivePluginsMode = false; return SUB_STATE_RUNNING; } else { mNeedRedraw = true; mCategoryRenderer.reset(); - for (const auto &element : configs) { - CallOnCloseCallback(element.get().getConfigInformation(), element.get().getConfig()); - } + savePendingConfigFn(); return SUB_STATE_RETURN; } } diff --git a/source/utils/config/ConfigUtils.cpp b/source/utils/config/ConfigUtils.cpp index 9ee5f06..8b36b19 100644 --- a/source/utils/config/ConfigUtils.cpp +++ b/source/utils/config/ConfigUtils.cpp @@ -238,6 +238,11 @@ void ConfigUtils::displayMenu() { } } } + DEBUG_FUNCTION_LINE_INFO("Save new plugin list"); + for (const auto &cur : newActivePluginsList) { + DEBUG_FUNCTION_LINE_ERR("%08X %s", cur.getPluginData()->getHandle(), cur.isLoadAndLink() ? "active" : "inactive"); + } + DEBUG_FUNCTION_LINE_INFO("==="); gLoadOnNextLaunch = newActivePluginsList; WUPSBackendSettings::SetInactivePluginFilenames(newInactivePluginsList); if (!WUPSBackendSettings::SaveSettings()) { @@ -255,8 +260,7 @@ void ConfigUtils::displayMenu() { renderBasicScreen("Saving configs..."); } for (const auto &plugin : gLoadedPlugins) { - const auto configData = plugin.getConfigData(); - if (configData) { + if (const auto configData = plugin.getConfigData()) { if (configData->CallMenuClosedCallback() == WUPSCONFIG_API_RESULT_MISSING_CALLBACK) { DEBUG_FUNCTION_LINE_WARN("CallMenuClosedCallback is missing for %s", plugin.getMetaInformation().getName().c_str()); } @@ -265,7 +269,6 @@ void ConfigUtils::displayMenu() { } } - WUPSConfigAPIBackend::Intern::CleanAllHandles(); // we want wait at least 300ms to avoid leaking inputs from the config menu to the application diff --git a/source/utils/dc.h b/source/utils/dc.h index 90429d7..bf65266 100644 --- a/source/utils/dc.h +++ b/source/utils/dc.h @@ -5,7 +5,7 @@ extern "C" uint32_t __OSPhysicalToEffectiveUncached(uint32_t); -static uint32_t DCReadReg32(const OSScreenID screen, const uint32_t index) { +inline uint32_t DCReadReg32(const OSScreenID screen, const uint32_t index) { if (OSIsECOMode()) { return 0; } @@ -14,7 +14,7 @@ static uint32_t DCReadReg32(const OSScreenID screen, const uint32_t index) { } -static void DCWriteReg32(const OSScreenID screen, const uint32_t index, const uint32_t val) { +inline void DCWriteReg32(const OSScreenID screen, const uint32_t index, const uint32_t val) { if (OSIsECOMode()) { return; } @@ -30,7 +30,7 @@ static void DCWriteReg32(const OSScreenID screen, const uint32_t index, const ui #define D1GRPH_X_END_REG 0x184d #define D1GRPH_Y_END_REG 0x184e -static void SetDCPitchReg(const OSScreenID screen, const uint16_t pitch) { +inline void SetDCPitchReg(const OSScreenID screen, const uint16_t pitch) { DCWriteReg32(screen, D1GRPH_PITCH_REG, pitch); DCWriteReg32(screen, D1OVL_PITCH_REG, pitch); } \ No newline at end of file diff --git a/source/utils/storage/StorageUtils.cpp b/source/utils/storage/StorageUtils.cpp index d7f7eb1..59b68de 100644 --- a/source/utils/storage/StorageUtils.cpp +++ b/source/utils/storage/StorageUtils.cpp @@ -172,11 +172,20 @@ namespace StorageUtils { return nullptr; } - WUPSStorageError LoadFromFile(std::string_view plugin_id, nlohmann::json &outJson) { - const std::string filePath = getPluginPath() + "/config/" + plugin_id.data() + ".json"; - if (ParseJsonFromFile(filePath, outJson)) { - return WUPS_STORAGE_ERROR_SUCCESS; + WUPSStorageError LoadFromFile(const std::string_view plugin_id, nlohmann::json &outJson) { + switch (const std::string filePath = getPluginPath() + "/config/" + plugin_id.data() + ".json"; ParseJsonFromFile(filePath, outJson)) { + case UTILS_IO_ERROR_SUCCESS: + return WUPS_STORAGE_ERROR_SUCCESS; + case UTILS_IO_ERROR_INVALID_ARGS: + return WUPS_STORAGE_ERROR_INVALID_ARGS; + case UTILS_IO_ERROR_MALLOC_FAILED: + return WUPS_STORAGE_ERROR_MALLOC_FAILED; + case UTILS_IO_ERROR_GENERIC: + return WUPS_STORAGE_ERROR_IO_ERROR; + case UTILS_IO_ERROR_NOT_FOUND: + return WUPS_STORAGE_ERROR_NOT_FOUND; } + return WUPS_STORAGE_ERROR_IO_ERROR; } diff --git a/source/utils/utils.cpp b/source/utils/utils.cpp index 5cd464c..8f3a80b 100644 --- a/source/utils/utils.cpp +++ b/source/utils/utils.cpp @@ -116,22 +116,22 @@ void CustomDynLoadFree(void *addr) { } } -bool ParseJsonFromFile(const std::string &filePath, nlohmann::json &outJson) { +UtilsIOError ParseJsonFromFile(const std::string &filePath, nlohmann::json &outJson) { CFile file(filePath, CFile::ReadOnly); if (!file.isOpen() || file.size() == 0) { - return false; + return UTILS_IO_ERROR_NOT_FOUND; } - auto *json_data = (uint8_t *) memalign(0x40, ROUNDUP(file.size() + 1, 0x40)); + auto *json_data = static_cast(memalign(0x40, ROUNDUP(file.size() + 1, 0x40))); if (!json_data) { - return false; + return UTILS_IO_ERROR_MALLOC_FAILED; } - bool result = true; + auto result = UTILS_IO_ERROR_SUCCESS; uint64_t readRes = file.read(json_data, file.size()); if (readRes == file.size()) { json_data[file.size()] = '\0'; outJson = nlohmann::json::parse(json_data, nullptr, false); } else { - result = false; + result = UTILS_IO_ERROR_GENERIC; } file.close(); free(json_data); diff --git a/source/utils/utils.h b/source/utils/utils.h index 2539d54..dafdd3d 100644 --- a/source/utils/utils.h +++ b/source/utils/utils.h @@ -136,6 +136,14 @@ void append_move_all_values(Container &dest, Container &src) { src.clear(); } +typedef enum { + UTILS_IO_ERROR_SUCCESS = 0, /**< Success. */ + UTILS_IO_ERROR_INVALID_ARGS = -0x01, /**< Invalid arguments passed to the function. */ + UTILS_IO_ERROR_MALLOC_FAILED = -0x02, /**< Memory allocation failed. */ + UTILS_IO_ERROR_GENERIC = -0x03, /**< Generic IO error during saving or loading. */ + UTILS_IO_ERROR_NOT_FOUND = -0x4, /**< Item not found. */ +} UtilsIOError; + std::string getPluginPath(); std::string getModulePath(); @@ -144,7 +152,7 @@ OSDynLoad_Error CustomDynLoadAlloc(int32_t size, int32_t align, void **outAddr); void CustomDynLoadFree(void *addr); -bool ParseJsonFromFile(const std::string &filePath, nlohmann::json &outJson); +UtilsIOError ParseJsonFromFile(const std::string &filePath, nlohmann::json &outJson); std::vector getPluginFilePaths(std::string_view basePath);