Code cleanup

This commit is contained in:
Maschell 2024-11-27 20:44:36 +01:00
parent 5893ac2f18
commit 447e1eb218
95 changed files with 1517 additions and 1212 deletions

View File

@ -23,7 +23,7 @@ jobs:
git_hash=$(git rev-parse --short "$GITHUB_SHA") git_hash=$(git rev-parse --short "$GITHUB_SHA")
cat <<EOF > ./source/version.h cat <<EOF > ./source/version.h
#pragma once #pragma once
#define VERSION_EXTRA " (nightly-$git_hash)" #define MODULE_VERSION_EXTRA " (nightly-$git_hash)"
EOF EOF
- name: build binary - name: build binary
run: | run: |

View File

@ -31,7 +31,7 @@ jobs:
git_hash=$(git rev-parse --short "${{ github.event.pull_request.head.sha }}") git_hash=$(git rev-parse --short "${{ github.event.pull_request.head.sha }}")
cat <<EOF > ./source/version.h cat <<EOF > ./source/version.h
#pragma once #pragma once
#define VERSION_EXTRA " (nightly-$git_hash)" #define MODULE_VERSION_EXTRA " (nightly-$git_hash)"
EOF EOF
- name: build binary - name: build binary
run: | run: |

View File

@ -11,6 +11,7 @@
#include <coreinit/dynload.h> #include <coreinit/dynload.h>
#include <memory.h> #include <memory.h>
#include <memory> #include <memory>
#include <ranges>
std::vector<PluginContainer> std::vector<PluginContainer>
PluginManagement::loadPlugins(const std::set<std::shared_ptr<PluginData>> &pluginDataList, std::vector<relocation_trampoline_entry_t> &trampolineData) { PluginManagement::loadPlugins(const std::set<std::shared_ptr<PluginData>> &pluginDataList, std::vector<relocation_trampoline_entry_t> &trampolineData) {
@ -50,7 +51,7 @@ PluginManagement::loadPlugins(const std::set<std::shared_ptr<PluginData>> &plugi
bool PluginManagement::doRelocation(const std::vector<RelocationData> &relocData, bool PluginManagement::doRelocation(const std::vector<RelocationData> &relocData,
std::vector<relocation_trampoline_entry_t> &trampData, std::vector<relocation_trampoline_entry_t> &trampData,
uint32_t trampolineID, const uint32_t trampolineID,
std::map<std::string, OSDynLoad_Module> &usedRPls) { std::map<std::string, OSDynLoad_Module> &usedRPls) {
for (auto const &cur : relocData) { for (auto const &cur : relocData) {
uint32_t functionAddress = 0; uint32_t functionAddress = 0;

View File

@ -18,14 +18,12 @@
#pragma once #pragma once
#include "WUPSConfigCategory.h" #include "WUPSConfigCategory.h"
#include <optional> #include <string_view>
#include <string>
#include <vector>
namespace WUPSConfigAPIBackend { namespace WUPSConfigAPIBackend {
class WUPSConfig : public WUPSConfigCategory { class WUPSConfig final : public WUPSConfigCategory {
public: public:
explicit WUPSConfig(std::string_view name) : WUPSConfigCategory(name) { explicit WUPSConfig(const std::string_view name) : WUPSConfigCategory(name) {
} }
}; };
} // namespace WUPSConfigAPIBackend } // namespace WUPSConfigAPIBackend

View File

@ -6,16 +6,19 @@
#include "WUPSConfigItemV2.h" #include "WUPSConfigItemV2.h"
#include "globals.h" #include "globals.h"
#include "plugin/PluginConfigData.h" #include "plugin/PluginConfigData.h"
#include "plugin/PluginContainer.h"
#include "utils/logger.h" #include "utils/logger.h"
#include "utils/utils.h" #include "utils/utils.h"
#include <algorithm>
#include <memory> #include <memory>
#include <ranges>
#include <vector> #include <vector>
#include <wums/exports.h> #include <wums/exports.h>
#include <wups/config.h> #include <wups/config.h>
#include <wups/config_api.h> #include <wups/config_api.h>
namespace WUPSConfigAPIBackend { namespace WUPSConfigAPIBackend {
std::vector<std::unique_ptr<WUPSConfig>> sConfigs; std::vector<std::unique_ptr<WUPSConfig>> sConfigs;
std::mutex sConfigsMutex; std::mutex sConfigsMutex;
@ -28,7 +31,7 @@ namespace WUPSConfigAPIBackend {
namespace Intern { namespace Intern {
WUPSConfig *GetConfigByHandle(WUPSConfigHandle handle) { WUPSConfig *GetConfigByHandle(WUPSConfigHandle handle) {
std::lock_guard lock(sConfigsMutex); std::lock_guard lock(sConfigsMutex);
auto itr = std::find_if(sConfigs.begin(), sConfigs.end(), [&handle](auto &cur) { return handle == cur.get(); }); const auto itr = std::ranges::find_if(sConfigs, [&handle](auto &cur) { return handle == cur.get(); });
if (itr == sConfigs.end()) { if (itr == sConfigs.end()) {
return nullptr; return nullptr;
} }
@ -44,23 +47,21 @@ namespace WUPSConfigAPIBackend {
return category; return category;
} }
for (const auto &cat : category->getCategories()) { for (const auto &cat : category->getCategories()) {
auto res = GetCategoryByHandleRecursive(cat.get(), handle); if (const auto res = GetCategoryByHandleRecursive(cat.get(), handle)) {
if (res) {
return res; return res;
} }
} }
return nullptr; return nullptr;
} }
WUPSConfigCategory *GetCategoryByHandle(WUPSConfigCategoryHandle handle, bool checkRecursive) { WUPSConfigCategory *GetCategoryByHandle(WUPSConfigCategoryHandle handle, const bool checkRecursive) {
std::lock_guard lock(sConfigCategoryMutex); std::lock_guard lock(sConfigCategoryMutex);
auto itr = std::find_if(sConfigCategories.begin(), sConfigCategories.end(), [&handle](auto &cur) { return handle == cur.get(); }); const auto itr = std::ranges::find_if(sConfigCategories, [&handle](auto &cur) { return handle == cur.get(); });
if (itr == sConfigCategories.end()) { if (itr == sConfigCategories.end()) {
if (checkRecursive) { if (checkRecursive) {
std::lock_guard config_lock(sConfigsMutex); std::lock_guard config_lock(sConfigsMutex);
for (const auto &curConfig : sConfigs) { for (const auto &curConfig : sConfigs) {
auto *category = Intern::GetCategoryByHandleRecursive(curConfig.get(), handle); if (auto *category = GetCategoryByHandleRecursive(curConfig.get(), handle)) {
if (category) {
return category; return category;
} }
} }
@ -77,7 +78,7 @@ namespace WUPSConfigAPIBackend {
WUPSConfigItem *GetItemByHandle(WUPSConfigItemHandle handle) { WUPSConfigItem *GetItemByHandle(WUPSConfigItemHandle handle) {
std::lock_guard lock(sConfigItemsMutex); std::lock_guard lock(sConfigItemsMutex);
auto itr = std::find_if(sConfigItems.begin(), sConfigItems.end(), [&handle](auto &cur) { return handle == cur.get(); }); const auto itr = std::ranges::find_if(sConfigItems, [&handle](auto &cur) { return handle == cur.get(); });
if (itr == sConfigItems.end()) { if (itr == sConfigItems.end()) {
return nullptr; return nullptr;
} }
@ -135,7 +136,10 @@ namespace WUPSConfigAPIBackend {
* - WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION: The specified `options.version` is not supported. * - WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION: The specified `options.version` is not supported.
* - WUPSCONFIG_API_RESULT_NOT_FOUND: The plugin with the given identifier was not found. * - WUPSCONFIG_API_RESULT_NOT_FOUND: The plugin with the given identifier was not found.
*/ */
WUPSConfigAPIStatus InitEx(uint32_t pluginIdentifier, WUPSConfigAPIOptions options, WUPSConfigAPI_MenuOpenedCallback openedCallback, WUPSConfigAPI_MenuClosedCallback closedCallback) { WUPSConfigAPIStatus InitEx(const uint32_t pluginIdentifier,
const WUPSConfigAPIOptions options,
const WUPSConfigAPI_MenuOpenedCallback openedCallback,
const WUPSConfigAPI_MenuClosedCallback closedCallback) {
if (openedCallback == nullptr || closedCallback == nullptr) { if (openedCallback == nullptr || closedCallback == nullptr) {
return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT;
} }
@ -144,7 +148,7 @@ namespace WUPSConfigAPIBackend {
if (options.version != 1) { if (options.version != 1) {
return WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION; return WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION;
} }
auto configDat = PluginConfigData::create(options, openedCallback, closedCallback); const auto configDat = PluginConfigData::create(options, openedCallback, closedCallback);
if (!configDat) { if (!configDat) {
DEBUG_FUNCTION_LINE_WARN("Failed to create config data for %08X", pluginIdentifier); DEBUG_FUNCTION_LINE_WARN("Failed to create config data for %08X", pluginIdentifier);
return WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION; return WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION;
@ -188,7 +192,7 @@ namespace WUPSConfigAPIBackend {
{ {
// Ignore any attempts to destroy the root item. // Ignore any attempts to destroy the root item.
std::lock_guard lock(sConfigsMutex); std::lock_guard lock(sConfigsMutex);
if (std::any_of(sConfigs.begin(), sConfigs.end(), [&handle](auto &cur) { return handle == cur.get(); })) { if (std::ranges::any_of(sConfigs, [&handle](auto &cur) { return handle == cur.get(); })) {
return WUPSCONFIG_API_RESULT_SUCCESS; return WUPSCONFIG_API_RESULT_SUCCESS;
} }
} }
@ -198,7 +202,7 @@ namespace WUPSConfigAPIBackend {
return WUPSCONFIG_API_RESULT_SUCCESS; return WUPSCONFIG_API_RESULT_SUCCESS;
} }
WUPSConfigAPIStatus AddCategory(WUPSConfigCategoryHandle parentHandle, WUPSConfigCategoryHandle categoryHandle) { WUPSConfigAPIStatus AddCategory(const WUPSConfigCategoryHandle parentHandle, const WUPSConfigCategoryHandle categoryHandle) {
if (parentHandle == nullptr || categoryHandle == nullptr) { if (parentHandle == nullptr || categoryHandle == nullptr) {
DEBUG_FUNCTION_LINE("Invalid param: \"parentHandle\" or \"categoryHandle\" was NULL"); DEBUG_FUNCTION_LINE("Invalid param: \"parentHandle\" or \"categoryHandle\" was NULL");
return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT;
@ -228,7 +232,7 @@ namespace WUPSConfigAPIBackend {
return WUPSCONFIG_API_RESULT_SUCCESS; return WUPSCONFIG_API_RESULT_SUCCESS;
} }
WUPSConfigAPIStatus AddItem(WUPSConfigCategoryHandle parentHandle, WUPSConfigItemHandle itemHandle) { WUPSConfigAPIStatus AddItem(const WUPSConfigCategoryHandle parentHandle, const WUPSConfigItemHandle itemHandle) {
if (parentHandle == nullptr || itemHandle == nullptr) { if (parentHandle == nullptr || itemHandle == nullptr) {
DEBUG_FUNCTION_LINE("Invalid param: \"handle\" or \"item_Handle\" was NULL"); DEBUG_FUNCTION_LINE("Invalid param: \"handle\" or \"item_Handle\" was NULL");
return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT; return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT;

View File

@ -1,5 +1,6 @@
#include "WUPSConfig.h" #include "WUPSConfig.h"
#include "WUPSConfigAPI.h" #include "WUPSConfigAPI.h"
#include "utils/logger.h"
#include <wums.h> #include <wums.h>
#include <wups/config.h> #include <wups/config.h>

View File

@ -0,0 +1,36 @@
#include "WUPSConfigCategory.h"
namespace WUPSConfigAPIBackend {
WUPSConfigCategory::WUPSConfigCategory(const std::string_view name) : mName(name) {
}
WUPSConfigCategory::~WUPSConfigCategory() = default;
const std::string &WUPSConfigCategory::getName() const {
return mName;
}
bool WUPSConfigCategory::addItem(std::unique_ptr<WUPSConfigItem> &item) {
if (item != nullptr) {
mItems.push_back(std::move(item));
return true;
}
return false;
}
const std::vector<std::unique_ptr<WUPSConfigItem>> &WUPSConfigCategory::getItems() const {
return mItems;
}
const std::vector<std::unique_ptr<WUPSConfigCategory>> &WUPSConfigCategory::getCategories() const {
return mCategories;
}
bool WUPSConfigCategory::addCategory(std::unique_ptr<WUPSConfigCategory> &category) {
mCategories.push_back(std::move(category));
return true;
}
} // namespace WUPSConfigAPIBackend

View File

@ -16,27 +16,23 @@
****************************************************************************/ ****************************************************************************/
#pragma once #pragma once
#include "WUPSConfigItem.h" #include "WUPSConfigItem.h"
#include <optional>
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include <wups/config.h>
namespace WUPSConfigAPIBackend { namespace WUPSConfigAPIBackend {
class WUPSConfigCategory { class WUPSConfigCategory {
public: public:
explicit WUPSConfigCategory(std::string_view name) : mName(name) { explicit WUPSConfigCategory(std::string_view name);
}
virtual ~WUPSConfigCategory() = default; virtual ~WUPSConfigCategory();
/** /**
\return Returns the name of this WUPSConfigCategory \return Returns the name of this WUPSConfigCategory
**/ **/
[[nodiscard]] const std::string &getName() const { [[nodiscard]] const std::string &getName() const;
return mName;
}
/** /**
\brief Adds a given WUPSConfigItem to this WUPSConfigCategory. \brief Adds a given WUPSConfigItem to this WUPSConfigCategory.
@ -49,27 +45,17 @@ namespace WUPSConfigAPIBackend {
On error false will be returned. In this case the caller still has the responsibility On error false will be returned. In this case the caller still has the responsibility
for deleting the WUPSConfigItem instance. for deleting the WUPSConfigItem instance.
**/ **/
[[nodiscard]] bool addItem(std::unique_ptr<WUPSConfigItem> &item) { [[nodiscard]] bool addItem(std::unique_ptr<WUPSConfigItem> &item);
if (item != nullptr) {
mItems.push_back(std::move(item));
return true;
}
return false;
}
/** /**
\return Returns a vector with all items. \return Returns a vector with all items.
**/ **/
[[nodiscard]] const std::vector<std::unique_ptr<WUPSConfigItem>> &getItems() const { [[nodiscard]] const std::vector<std::unique_ptr<WUPSConfigItem>> &getItems() const;
return mItems;
}
/** /**
\return Returns a vector with all categories. \return Returns a vector with all categories.
**/ **/
[[nodiscard]] const std::vector<std::unique_ptr<WUPSConfigCategory>> &getCategories() const { [[nodiscard]] const std::vector<std::unique_ptr<WUPSConfigCategory>> &getCategories() const;
return mCategories;
}
/** /**
\brief Adds a given WUPSConfigCategory to this WUPSConfigCategory. \brief Adds a given WUPSConfigCategory to this WUPSConfigCategory.
@ -82,10 +68,7 @@ namespace WUPSConfigAPIBackend {
On error false will be returned. In this case the caller still has the responsibility On error false will be returned. In this case the caller still has the responsibility
for deleting the WUPSConfigCategory instance. for deleting the WUPSConfigCategory instance.
**/ **/
[[nodiscard]] bool addCategory(std::unique_ptr<WUPSConfigCategory> &category) { [[nodiscard]] bool addCategory(std::unique_ptr<WUPSConfigCategory> &category);
mCategories.push_back(std::move(category));
return true;
}
private: private:
std::string mName; std::string mName;

View File

@ -0,0 +1,27 @@
#include "WUPSConfigItem.h"
namespace WUPSConfigAPIBackend {
WUPSConfigItem::WUPSConfigItem(std::string displayName) : mDisplayName(std::move(displayName)) {
}
WUPSConfigItem::~WUPSConfigItem() = default;
void WUPSConfigItem::onButtonPressed(WUPSConfigButtons) const {}
const std::string &WUPSConfigItem::getDisplayName() const {
return mDisplayName;
}
void WUPSConfigItem::setConfigId(const std::string &) {}
const std::string &WUPSConfigItem::getConfigId() {
return mStubConfigId;
}
void WUPSConfigItem::setDisplayName(std::string displayName) {
mDisplayName = std::move(displayName);
}
void WUPSConfigItem::onInput(WUPSConfigSimplePadData) const {}
void WUPSConfigItem::onInputEx(WUPSConfigComplexPadData) const {}
} // namespace WUPSConfigAPIBackend

View File

@ -18,19 +18,13 @@
#pragma once #pragma once
#include <string> #include <string>
#include <utility>
#include <vector>
#include "utils/StringTools.h"
#include "utils/logger.h"
#include <wups/config.h> #include <wups/config.h>
namespace WUPSConfigAPIBackend { namespace WUPSConfigAPIBackend {
class WUPSConfigItem { class WUPSConfigItem {
public: public:
explicit WUPSConfigItem(std::string displayName) : mDisplayName(std::move(displayName)) { explicit WUPSConfigItem(std::string displayName);
} virtual ~WUPSConfigItem();
virtual ~WUPSConfigItem() = default;
[[nodiscard]] virtual std::string getCurrentValueDisplay() const = 0; [[nodiscard]] virtual std::string getCurrentValueDisplay() const = 0;
@ -38,7 +32,7 @@ namespace WUPSConfigAPIBackend {
virtual void onSelected(bool isSelected) const = 0; virtual void onSelected(bool isSelected) const = 0;
virtual void onButtonPressed(WUPSConfigButtons) const {} virtual void onButtonPressed(WUPSConfigButtons) const;
[[nodiscard]] virtual bool isMovementAllowed() const = 0; [[nodiscard]] virtual bool isMovementAllowed() const = 0;
@ -46,23 +40,17 @@ namespace WUPSConfigAPIBackend {
virtual void onCloseCallback() = 0; virtual void onCloseCallback() = 0;
[[nodiscard]] const std::string &getDisplayName() const { [[nodiscard]] const std::string &getDisplayName() const;
return mDisplayName;
}
virtual void setConfigId(const std::string &) {} virtual void setConfigId(const std::string &);
virtual const std::string &getConfigId() { virtual const std::string &getConfigId();
return mStubConfigId;
}
void setDisplayName(std::string displayName) { void setDisplayName(std::string displayName);
mDisplayName = std::move(displayName);
}
virtual void onInput(WUPSConfigSimplePadData) const {} virtual void onInput(WUPSConfigSimplePadData) const;
virtual void onInputEx(WUPSConfigComplexPadData) const {} virtual void onInputEx(WUPSConfigComplexPadData) const;
protected: protected:
std::string mDisplayName; std::string mDisplayName;

View File

@ -1,7 +1,12 @@
#include "WUPSConfigItemV1.h" #include "WUPSConfigItemV1.h"
#include "utils/StringTools.h"
#include "utils/logger.h"
namespace WUPSConfigAPIBackend { namespace WUPSConfigAPIBackend {
WUPSConfigItemV1::WUPSConfigItemV1(std::string_view configId, std::string_view _displayName, WUPSConfigAPIItemCallbacksV1 callbacks, void *context) : WUPSConfigItem(std::string(_displayName)) { WUPSConfigItemV1::WUPSConfigItemV1(const std::string_view configId,
const std::string_view displayName,
const WUPSConfigAPIItemCallbacksV1 &callbacks,
void *context) : WUPSConfigItem(std::string(displayName)) {
this->mConfigId = configId; this->mConfigId = configId;
this->mContext = context; this->mContext = context;
this->mCallbacks = callbacks; this->mCallbacks = callbacks;
@ -46,7 +51,7 @@ namespace WUPSConfigAPIBackend {
return buf; return buf;
} }
void WUPSConfigItemV1::onSelected(bool isSelected) const { void WUPSConfigItemV1::onSelected(const bool isSelected) const {
if (this->mCallbacks.onSelected == nullptr) { if (this->mCallbacks.onSelected == nullptr) {
DEBUG_FUNCTION_LINE_VERBOSE("onSelected callback not implemented. [%s]", mDisplayName.c_str()); DEBUG_FUNCTION_LINE_VERBOSE("onSelected callback not implemented. [%s]", mDisplayName.c_str());
return; return;
@ -54,7 +59,7 @@ namespace WUPSConfigAPIBackend {
this->mCallbacks.onSelected(mContext, isSelected); this->mCallbacks.onSelected(mContext, isSelected);
} }
void WUPSConfigItemV1::onButtonPressed(WUPSConfigButtons buttons) const { void WUPSConfigItemV1::onButtonPressed(const WUPSConfigButtons buttons) const {
if (this->mCallbacks.onButtonPressed == nullptr) { if (this->mCallbacks.onButtonPressed == nullptr) {
DEBUG_FUNCTION_LINE_VERBOSE("onButtonPressed callback not implemented. [%s]", mDisplayName.c_str()); DEBUG_FUNCTION_LINE_VERBOSE("onButtonPressed callback not implemented. [%s]", mDisplayName.c_str());
return; return;

View File

@ -1,12 +1,16 @@
#pragma once #pragma once
#include "WUPSConfigItem.h" #include "WUPSConfigItem.h"
#include <string> #include <string>
#include <wups/config.h> #include <wups/config.h>
namespace WUPSConfigAPIBackend { namespace WUPSConfigAPIBackend {
class WUPSConfigItemV1 : public WUPSConfigItem { class WUPSConfigItemV1 final : public WUPSConfigItem {
public: public:
WUPSConfigItemV1(std::string_view configId, std::string_view _displayName, WUPSConfigAPIItemCallbacksV1 callbacks, void *context); WUPSConfigItemV1(std::string_view configId,
std::string_view displayName,
const WUPSConfigAPIItemCallbacksV1 &callbacks,
void *context);
~WUPSConfigItemV1() override; ~WUPSConfigItemV1() override;

View File

@ -1,8 +1,14 @@
#include "WUPSConfigItemV2.h" #include "WUPSConfigItemV2.h"
#include "utils/StringTools.h"
#include "utils/logger.h"
#include <string> #include <string>
#include <wups/config.h> #include <wups/config.h>
namespace WUPSConfigAPIBackend { namespace WUPSConfigAPIBackend {
WUPSConfigItemV2::WUPSConfigItemV2(std::string_view displayName, WUPSConfigAPIItemCallbacksV2 callbacks, void *context) : WUPSConfigItem(std::string(displayName)) { WUPSConfigItemV2::WUPSConfigItemV2(const std::string_view displayName,
const WUPSConfigAPIItemCallbacksV2 &callbacks,
void *context) : WUPSConfigItem(std::string(displayName)) {
this->mDisplayName = displayName; this->mDisplayName = displayName;
this->mContext = context; this->mContext = context;
this->mCallbacks = callbacks; this->mCallbacks = callbacks;
@ -16,7 +22,7 @@ namespace WUPSConfigAPIBackend {
this->mCallbacks.onDelete(mContext); this->mCallbacks.onDelete(mContext);
} }
void WUPSConfigItemV2::onSelected(bool isSelected) const { void WUPSConfigItemV2::onSelected(const bool isSelected) const {
if (this->mCallbacks.onSelected == nullptr) { if (this->mCallbacks.onSelected == nullptr) {
DEBUG_FUNCTION_LINE_VERBOSE("onSelected callback not implemented. [%s]", mDisplayName.c_str()); DEBUG_FUNCTION_LINE_VERBOSE("onSelected callback not implemented. [%s]", mDisplayName.c_str());
return; return;
@ -50,7 +56,7 @@ namespace WUPSConfigAPIBackend {
return buf; return buf;
} }
void WUPSConfigItemV2::onInput(WUPSConfigSimplePadData input) const { void WUPSConfigItemV2::onInput(const WUPSConfigSimplePadData input) const {
if (this->mCallbacks.onInput == nullptr) { if (this->mCallbacks.onInput == nullptr) {
DEBUG_FUNCTION_LINE_VERBOSE("onInput callback not implemented. [%s]", mDisplayName.c_str()); DEBUG_FUNCTION_LINE_VERBOSE("onInput callback not implemented. [%s]", mDisplayName.c_str());
return; return;
@ -58,7 +64,7 @@ namespace WUPSConfigAPIBackend {
this->mCallbacks.onInput(mContext, input); this->mCallbacks.onInput(mContext, input);
} }
void WUPSConfigItemV2::onInputEx(WUPSConfigComplexPadData input) const { void WUPSConfigItemV2::onInputEx(const WUPSConfigComplexPadData input) const {
if (this->mCallbacks.onInputEx == nullptr) { if (this->mCallbacks.onInputEx == nullptr) {
DEBUG_FUNCTION_LINE_VERBOSE("onInputEx callback not implemented. [%s]", mDisplayName.c_str()); DEBUG_FUNCTION_LINE_VERBOSE("onInputEx callback not implemented. [%s]", mDisplayName.c_str());
return; return;

View File

@ -1,13 +1,13 @@
#pragma once #pragma once
#include "WUPSConfigItem.h" #include "WUPSConfigItem.h"
#include <string> #include <string>
#include <wups/config.h> #include <wups/config.h>
namespace WUPSConfigAPIBackend { namespace WUPSConfigAPIBackend {
class WUPSConfigItemV2 final : public WUPSConfigItem {
class WUPSConfigItemV2 : public WUPSConfigItem {
public: public:
WUPSConfigItemV2(std::string_view displayName, WUPSConfigAPIItemCallbacksV2 callbacks, void *context); WUPSConfigItemV2(std::string_view displayName, const WUPSConfigAPIItemCallbacksV2 &callbacks, void *context);
~WUPSConfigItemV2() override; ~WUPSConfigItemV2() override;

View File

@ -24,6 +24,7 @@ THE SOFTWARE.
#define ELFIO_UTILS_HPP #define ELFIO_UTILS_HPP
#include <cstdint> #include <cstdint>
#include <elfio/elf_types.hpp>
#define ELFIO_GET_ACCESS_DECL( TYPE, NAME ) virtual TYPE get_##NAME() const = 0 #define ELFIO_GET_ACCESS_DECL( TYPE, NAME ) virtual TYPE get_##NAME() const = 0

View File

@ -63,7 +63,7 @@ BOOL DirList::LoadPath(const std::string &folder, const char *filter, uint32_t f
uint32_t length = folderpath.size(); uint32_t length = folderpath.size();
//! clear path of double slashes //! clear path of double slashes
StringTools::RemoveDoubleSlashs(folderpath); StringTools::RemoveDoubleSlashes(folderpath);
//! remove last slash if exists //! remove last slash if exists
if (length > 0 && folderpath[length - 1] == '/') if (length > 0 && folderpath[length - 1] == '/')

View File

@ -1,4 +1,6 @@
#include "globals.h" #include "globals.h"
#include "plugin/PluginContainer.h"
#include "plugin/PluginData.h"
StoredBuffer gStoredTVBuffer = {}; StoredBuffer gStoredTVBuffer = {};
StoredBuffer gStoredDRCBuffer = {}; StoredBuffer gStoredDRCBuffer = {};

View File

@ -1,16 +1,20 @@
#pragma once #pragma once
#include "plugin/PluginContainer.h"
#include "utils/config/ConfigUtils.h" #include "utils/config/ConfigDefines.h"
#include "version.h" #include "version.h"
#include <coreinit/dynload.h> #include <coreinit/dynload.h>
#include <forward_list> #include <coreinit/thread.h>
#include <map>
#include <memory> #include <memory>
#include <mutex> #include <set>
#include <vector> #include <vector>
#include <wums/defines/relocation_defines.h> #include <wums/defines/relocation_defines.h>
#define VERSION "v0.3.4" #define MODULE_VERSION "v0.3.4"
#define VERSION_FULL VERSION VERSION_EXTRA #define MODULE_VERSION_FULL MODULE_VERSION MODULE_VERSION_EXTRA
class PluginData;
class PluginContainer;
extern StoredBuffer gStoredTVBuffer; extern StoredBuffer gStoredTVBuffer;
extern StoredBuffer gStoredDRCBuffer; extern StoredBuffer gStoredDRCBuffer;

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include "plugin/PluginContainer.h" #include "plugin/PluginContainer.h"
#include <memory>
#include <vector> #include <vector>
#include <wups/hooks.h> #include <wups/hooks.h>

View File

@ -5,9 +5,12 @@
#include "hooks.h" #include "hooks.h"
#include "patcher/hooks_patcher_static.h" #include "patcher/hooks_patcher_static.h"
#include "plugin/PluginDataFactory.h" #include "plugin/PluginDataFactory.h"
#include "utils/logger.h"
#include "utils/utils.h" #include "utils/utils.h"
#include <coreinit/debug.h> #include <coreinit/debug.h>
#include <notifications/notifications.h> #include <notifications/notifications.h>
#include <version.h>
#include <wums.h> #include <wums.h>
WUMS_MODULE_EXPORT_NAME("homebrew_wupsbackend"); WUMS_MODULE_EXPORT_NAME("homebrew_wupsbackend");
@ -75,7 +78,7 @@ WUMS_APPLICATION_STARTS() {
return; return;
} }
OSReport("Running WiiUPluginLoaderBackend " VERSION_FULL "\n"); OSReport("Running WiiUPluginLoaderBackend " MODULE_VERSION_FULL "\n");
gStoredTVBuffer = {}; gStoredTVBuffer = {};
gUsedRPLs.clear(); gUsedRPLs.clear();

View File

@ -1,12 +1,14 @@
#include "hooks_patcher_static.h" #include "hooks_patcher_static.h"
#include "globals.h"
#include "utils/config/ConfigUtils.h"
#include <coreinit/core.h> #include <coreinit/core.h>
#include <coreinit/messagequeue.h> #include <coreinit/messagequeue.h>
#include <hooks.h>
#include <padscore/wpad.h> #include <padscore/wpad.h>
#include <vpad/input.h> #include <vpad/input.h>
#include "../globals.h"
#include "../hooks.h"
static uint8_t sVpadPressCooldown = 0xFF; static uint8_t sVpadPressCooldown = 0xFF;
static bool sConfigMenuOpened = false; static bool sConfigMenuOpened = false;
static bool sWantsToOpenConfigMenu = false; static bool sWantsToOpenConfigMenu = false;
@ -57,7 +59,7 @@ DECL_FUNCTION(BOOL, OSSendMessage, OSMessageQueue *queue, OSMessage *message, OS
} }
DECL_FUNCTION(uint32_t, OSReceiveMessage, OSMessageQueue *queue, OSMessage *message, uint32_t flags) { DECL_FUNCTION(uint32_t, OSReceiveMessage, OSMessageQueue *queue, OSMessage *message, uint32_t flags) {
uint32_t res = real_OSReceiveMessage(queue, message, flags); const uint32_t res = real_OSReceiveMessage(queue, message, flags);
if (queue == OSGetSystemMessageQueue()) { if (queue == OSGetSystemMessageQueue()) {
if (message != nullptr && res) { if (message != nullptr && res) {
if (lastData0 != message->args[0]) { if (lastData0 != message->args[0]) {
@ -88,7 +90,7 @@ DECL_FUNCTION(int32_t, VPADRead, int32_t chan, VPADStatus *buffer, uint32_t buff
} }
} }
VPADReadError real_error = VPAD_READ_SUCCESS; VPADReadError real_error = VPAD_READ_SUCCESS;
int32_t result = real_VPADRead(chan, buffer, buffer_size, &real_error); const int32_t result = real_VPADRead(chan, buffer, buffer_size, &real_error);
if (result > 0 && real_error == VPAD_READ_SUCCESS && buffer && ((buffer[0].hold & 0xFFFFF) == (VPAD_BUTTON_L | VPAD_BUTTON_DOWN | VPAD_BUTTON_MINUS)) && sVpadPressCooldown == 0 && !sConfigMenuOpened) { if (result > 0 && real_error == VPAD_READ_SUCCESS && buffer && ((buffer[0].hold & 0xFFFFF) == (VPAD_BUTTON_L | VPAD_BUTTON_DOWN | VPAD_BUTTON_MINUS)) && sVpadPressCooldown == 0 && !sConfigMenuOpened) {
@ -106,24 +108,24 @@ DECL_FUNCTION(int32_t, VPADRead, int32_t chan, VPADStatus *buffer, uint32_t buff
return result; return result;
} }
DECL_FUNCTION(void, WPADRead, WPADChan chan, WPADStatusProController *data) { DECL_FUNCTION(void, WPADRead, WPADChan chan, WPADStatus *data) {
real_WPADRead(chan, data); real_WPADRead(chan, data);
if (!sConfigMenuOpened && data && data[0].err == 0) { if (!sConfigMenuOpened && data && data[0].error == 0) {
if (data[0].extensionType != 0xFF) { if (const auto extensionType = data[0].extensionType; extensionType != 0xFF) {
if (data[0].extensionType == WPAD_EXT_CORE || data[0].extensionType == WPAD_EXT_NUNCHUK || if (extensionType == WPAD_EXT_CORE || extensionType == WPAD_EXT_NUNCHUK ||
data[0].extensionType == WPAD_EXT_MPLUS || data[0].extensionType == WPAD_EXT_MPLUS_NUNCHUK) { extensionType == WPAD_EXT_MPLUS || extensionType == WPAD_EXT_MPLUS_NUNCHUK) {
// button data is in the first 2 bytes for wiimotes if (data->buttons == (WPAD_BUTTON_B | WPAD_BUTTON_DOWN | WPAD_BUTTON_MINUS)) {
if (((uint16_t *) data)[0] == (WPAD_BUTTON_B | WPAD_BUTTON_DOWN | WPAD_BUTTON_MINUS)) {
sWantsToOpenConfigMenu = true; sWantsToOpenConfigMenu = true;
} }
} else if (data[0].extensionType == WPAD_EXT_CLASSIC || data[0].extensionType == WPAD_EXT_MPLUS_CLASSIC) { } else if (extensionType == WPAD_EXT_CLASSIC || extensionType == WPAD_EXT_MPLUS_CLASSIC) {
// TODO: figure out the real struct.. const auto *classic = reinterpret_cast<WPADStatusClassic *>(data);
if ((((uint32_t *) data)[10] & 0xFFFF) == (WPAD_CLASSIC_BUTTON_L | WPAD_CLASSIC_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_MINUS)) { if (classic->buttons == (WPAD_CLASSIC_BUTTON_L | WPAD_CLASSIC_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_MINUS)) {
sWantsToOpenConfigMenu = true; sWantsToOpenConfigMenu = true;
} }
} else if (data[0].extensionType == WPAD_EXT_PRO_CONTROLLER) { } else if (extensionType == WPAD_EXT_PRO_CONTROLLER) {
if (data[0].buttons == (WPAD_PRO_TRIGGER_L | WPAD_PRO_BUTTON_DOWN | WPAD_PRO_BUTTON_MINUS)) { const auto *pro = reinterpret_cast<WPADStatusPro *>(data);
if (pro->buttons == (WPAD_PRO_TRIGGER_L | WPAD_PRO_BUTTON_DOWN | WPAD_PRO_BUTTON_MINUS)) {
sWantsToOpenConfigMenu = true; sWantsToOpenConfigMenu = true;
} }
} }
@ -156,11 +158,10 @@ DECL_FUNCTION(uint32_t, SC17_FindClosestSymbol,
} }
strncpy(moduleNameBuffer, plugin.getMetaInformation().getName().c_str(), moduleNameBufferLength - 1); strncpy(moduleNameBuffer, plugin.getMetaInformation().getName().c_str(), moduleNameBufferLength - 1);
auto functionSymbolData = plugin.getPluginInformation().getNearestFunctionSymbolData(addr); if (const auto functionSymbolData = plugin.getPluginInformation().getNearestFunctionSymbolData(addr)) {
if (functionSymbolData) {
strncpy(symbolNameBuffer, functionSymbolData->getName().c_str(), moduleNameBufferLength - 1); strncpy(symbolNameBuffer, functionSymbolData->getName().c_str(), moduleNameBufferLength - 1);
if (outDistance) { if (outDistance) {
*outDistance = addr - (uint32_t) functionSymbolData->getAddress(); *outDistance = addr - reinterpret_cast<uint32_t>(functionSymbolData->getAddress());
} }
return 0; return 0;
} }
@ -168,7 +169,7 @@ DECL_FUNCTION(uint32_t, SC17_FindClosestSymbol,
strncpy(symbolNameBuffer, ".text", symbolNameBufferLength); strncpy(symbolNameBuffer, ".text", symbolNameBufferLength);
if (outDistance) { if (outDistance) {
*outDistance = addr - (uint32_t) sectionInfo->getAddress(); *outDistance = addr - sectionInfo->getAddress();
} }
return 0; return 0;
@ -188,15 +189,14 @@ DECL_FUNCTION(uint32_t, KiGetAppSymbolName, uint32_t addr, char *buffer, int32_t
continue; continue;
} }
auto pluginNameLen = strlen(plugin.getMetaInformation().getName().c_str()); const auto pluginNameLen = strlen(plugin.getMetaInformation().getName().c_str());
int32_t spaceLeftInBuffer = (int32_t) bufSize - (int32_t) pluginNameLen - 1; int32_t spaceLeftInBuffer = bufSize - static_cast<int32_t>(pluginNameLen) - 1;
if (spaceLeftInBuffer < 0) { if (spaceLeftInBuffer < 0) {
spaceLeftInBuffer = 0; spaceLeftInBuffer = 0;
} }
strncpy(buffer, plugin.getMetaInformation().getName().c_str(), bufSize - 1); strncpy(buffer, plugin.getMetaInformation().getName().c_str(), bufSize - 1);
const auto functionSymbolData = plugin.getPluginInformation().getNearestFunctionSymbolData(addr); if (const auto functionSymbolData = plugin.getPluginInformation().getNearestFunctionSymbolData(addr)) {
if (functionSymbolData) {
buffer[pluginNameLen] = '|'; buffer[pluginNameLen] = '|';
buffer[pluginNameLen + 1] = '\0'; buffer[pluginNameLen + 1] = '\0';
strncpy(buffer + pluginNameLen + 1, functionSymbolData->getName().c_str(), spaceLeftInBuffer - 1); strncpy(buffer + pluginNameLen + 1, functionSymbolData->getName().c_str(), spaceLeftInBuffer - 1);
@ -221,7 +221,6 @@ function_replacement_data_t method_hooks_static[] __attribute__((section(".data"
REPLACE_FUNCTION(WPADRead, LIBRARY_PADSCORE, WPADRead), REPLACE_FUNCTION(WPADRead, LIBRARY_PADSCORE, WPADRead),
REPLACE_FUNCTION_VIA_ADDRESS(SC17_FindClosestSymbol, 0xfff10218, 0xfff10218), REPLACE_FUNCTION_VIA_ADDRESS(SC17_FindClosestSymbol, 0xfff10218, 0xfff10218),
REPLACE_FUNCTION_VIA_ADDRESS(KiGetAppSymbolName, 0xfff0e3a0, 0xfff0e3a0), REPLACE_FUNCTION_VIA_ADDRESS(KiGetAppSymbolName, 0xfff0e3a0, 0xfff0e3a0),
}; };
uint32_t method_hooks_static_size __attribute__((section(".data"))) = sizeof(method_hooks_static) / sizeof(function_replacement_data_t); uint32_t method_hooks_static_size __attribute__((section(".data"))) = sizeof(method_hooks_static) / sizeof(function_replacement_data_t);

View File

@ -1,67 +1,75 @@
#include "FunctionData.h" #include "FunctionData.h"
#include "utils/logger.h"
FunctionData::FunctionData(void *paddress, void *vaddress, std::string_view name, function_replacement_library_type_t library, void *replaceAddr, void *replaceCall, FunctionPatcherTargetProcess targetProcess) { #include <function_patcher/function_patching.h>
this->paddress = paddress; #include <string>
this->vaddress = vaddress;
this->name = name; FunctionData::FunctionData(void *paddress, void *vaddress,
this->library = library; const std::string_view name,
this->targetProcess = targetProcess; const function_replacement_library_type_t library,
this->replaceAddr = replaceAddr; void *replaceAddr, void *replaceCall,
this->replaceCall = replaceCall; const FunctionPatcherTargetProcess targetProcess) {
this->mPAddress = paddress;
this->mVAddress = vaddress;
this->mName = name;
this->mLibrary = library;
this->mTargetProcess = targetProcess;
this->mReplaceAddr = replaceAddr;
this->mReplaceCall = replaceCall;
} }
FunctionData::~FunctionData() { FunctionData::~FunctionData() {
if (handle != 0) { if (mHandle != 0) {
DEBUG_FUNCTION_LINE_WARN("Destroying FunctionData while it was still patched. This should never happen."); DEBUG_FUNCTION_LINE_WARN("Destroying FunctionData while it was still patched. This should never happen.");
RemovePatch(); RemovePatch();
} }
} }
const std::string &FunctionData::getName() const { const std::string &FunctionData::getName() const {
return this->name; return this->mName;
} }
function_replacement_library_type_t FunctionData::getLibrary() const { function_replacement_library_type_t FunctionData::getLibrary() const {
return this->library; return this->mLibrary;
} }
const void *FunctionData::getPhysicalAddress() const { const void *FunctionData::getPhysicalAddress() const {
return paddress; return mPAddress;
} }
const void *FunctionData::getVirtualAddress() const { const void *FunctionData::getVirtualAddress() const {
return vaddress; return mVAddress;
} }
const void *FunctionData::getReplaceAddress() const { const void *FunctionData::getReplaceAddress() const {
return replaceAddr; return mReplaceAddr;
} }
const void *FunctionData::getReplaceCall() const { const void *FunctionData::getReplaceCall() const {
return replaceCall; return mReplaceCall;
} }
FunctionPatcherTargetProcess FunctionData::getTargetProcess() const { FunctionPatcherTargetProcess FunctionData::getTargetProcess() const {
return targetProcess; return mTargetProcess;
} }
bool FunctionData::AddPatch() { bool FunctionData::AddPatch() {
if (handle == 0) { if (mHandle == 0) {
function_replacement_data_t functionData = { function_replacement_data_t functionData = {
.version = FUNCTION_REPLACEMENT_DATA_STRUCT_VERSION, .version = FUNCTION_REPLACEMENT_DATA_STRUCT_VERSION,
.type = FUNCTION_PATCHER_REPLACE_BY_LIB_OR_ADDRESS, .type = FUNCTION_PATCHER_REPLACE_BY_LIB_OR_ADDRESS,
.physicalAddr = reinterpret_cast<uint32_t>(this->paddress), .physicalAddr = reinterpret_cast<uint32_t>(this->mPAddress),
.virtualAddr = reinterpret_cast<uint32_t>(this->vaddress), .virtualAddr = reinterpret_cast<uint32_t>(this->mVAddress),
.replaceAddr = reinterpret_cast<uint32_t>(this->replaceAddr), .replaceAddr = reinterpret_cast<uint32_t>(this->mReplaceAddr),
.replaceCall = static_cast<uint32_t *>(this->replaceCall), .replaceCall = static_cast<uint32_t *>(this->mReplaceCall),
.targetProcess = this->targetProcess, .targetProcess = this->mTargetProcess,
.ReplaceInRPL = { .ReplaceInRPL = {
.function_name = this->name.c_str(), .function_name = this->mName.c_str(),
.library = this->library, .library = this->mLibrary,
}}; }};
if (FunctionPatcher_AddFunctionPatch(&functionData, &handle, nullptr) != FUNCTION_PATCHER_RESULT_SUCCESS) { if (FunctionPatcher_AddFunctionPatch(&functionData, &mHandle, nullptr) != FUNCTION_PATCHER_RESULT_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to add patch for function (\"%s\" PA:%08X VA:%08X)", this->name.c_str(), this->paddress, this->vaddress); DEBUG_FUNCTION_LINE_ERR("Failed to add patch for function (\"%s\" PA:%08X VA:%08X)", this->mName.c_str(), this->mPAddress, this->mVAddress);
return false; return false;
} }
} else { } else {
@ -71,12 +79,12 @@ bool FunctionData::AddPatch() {
} }
bool FunctionData::RemovePatch() { bool FunctionData::RemovePatch() {
if (handle != 0) { if (mHandle != 0) {
if (FunctionPatcher_RemoveFunctionPatch(handle) != FUNCTION_PATCHER_RESULT_SUCCESS) { if (FunctionPatcher_RemoveFunctionPatch(mHandle) != FUNCTION_PATCHER_RESULT_SUCCESS) {
DEBUG_FUNCTION_LINE_ERR("Failed to remove patch for function"); DEBUG_FUNCTION_LINE_ERR("Failed to remove patch for function");
return false; return false;
} }
handle = 0; mHandle = 0;
} else { } else {
DEBUG_FUNCTION_LINE_VERBOSE("Was not patched."); DEBUG_FUNCTION_LINE_VERBOSE("Was not patched.");
} }

View File

@ -16,45 +16,48 @@
****************************************************************************/ ****************************************************************************/
#pragma once #pragma once
#include "utils/logger.h"
#include <function_patcher/fpatching_defines.h> #include <function_patcher/fpatching_defines.h>
#include <function_patcher/function_patching.h>
#include <string> #include <string>
class FunctionData { class FunctionData {
public: public:
FunctionData(void *paddress, void *vaddress, std::string_view name, function_replacement_library_type_t library, void *replaceAddr, void *replaceCall, FunctionData(void *paddress,
void *vaddress,
std::string_view name,
function_replacement_library_type_t library,
void *replaceAddr,
void *replaceCall,
FunctionPatcherTargetProcess targetProcess); FunctionPatcherTargetProcess targetProcess);
~FunctionData(); ~FunctionData();
[[nodiscard]] const std::string &getName() const; [[nodiscard]] const std::string &getName() const;
[[maybe_unused]] [[nodiscard]] function_replacement_library_type_t getLibrary() const; [[nodiscard]] function_replacement_library_type_t getLibrary() const;
[[maybe_unused]] [[nodiscard]] const void *getPhysicalAddress() const; [[nodiscard]] const void *getPhysicalAddress() const;
[[maybe_unused]] [[nodiscard]] const void *getVirtualAddress() const; [[nodiscard]] const void *getVirtualAddress() const;
[[maybe_unused]] [[nodiscard]] const void *getReplaceAddress() const; [[nodiscard]] const void *getReplaceAddress() const;
[[maybe_unused]] [[nodiscard]] const void *getReplaceCall() const; [[nodiscard]] const void *getReplaceCall() const;
[[maybe_unused]] [[nodiscard]] FunctionPatcherTargetProcess getTargetProcess() const; [[nodiscard]] FunctionPatcherTargetProcess getTargetProcess() const;
bool AddPatch(); bool AddPatch();
bool RemovePatch(); bool RemovePatch();
private: private:
void *paddress = nullptr; void *mPAddress = nullptr;
void *vaddress = nullptr; void *mVAddress = nullptr;
std::string name; std::string mName;
function_replacement_library_type_t library; function_replacement_library_type_t mLibrary;
FunctionPatcherTargetProcess targetProcess; FunctionPatcherTargetProcess mTargetProcess;
void *replaceAddr = nullptr; void *mReplaceAddr = nullptr;
void *replaceCall = nullptr; void *mReplaceCall = nullptr;
PatchedFunctionHandle handle = 0; PatchedFunctionHandle mHandle = 0;
}; };

View File

@ -0,0 +1,26 @@
#include "FunctionSymbolData.h"
FunctionSymbolData::FunctionSymbolData(const FunctionSymbolData &o2) = default;
FunctionSymbolData::FunctionSymbolData(std::string_view name, void *address, uint32_t size) : mName(name),
mAddress(address),
mSize(size) {
}
bool FunctionSymbolData::operator<(const FunctionSymbolData &rhs) const {
return reinterpret_cast<uint32_t>(mAddress) < reinterpret_cast<uint32_t>(rhs.mAddress);
}
FunctionSymbolData::~FunctionSymbolData() = default;
[[nodiscard]] const std::string &FunctionSymbolData::getName() const {
return mName;
}
[[nodiscard]] void *FunctionSymbolData::getAddress() const {
return mAddress;
}
[[nodiscard]] uint32_t FunctionSymbolData::getSize() const {
return mSize;
}

View File

@ -17,35 +17,25 @@
#pragma once #pragma once
#include <cstdint>
#include <string> #include <string>
class FunctionSymbolData { class FunctionSymbolData {
public: public:
FunctionSymbolData(const FunctionSymbolData &o2) = default; FunctionSymbolData(const FunctionSymbolData &o2);
FunctionSymbolData(std::string_view name, void *address, uint32_t size) : mName(name), FunctionSymbolData(std::string_view name, void *address, uint32_t size);
mAddress(address),
mSize(size) {
}
bool operator<(const FunctionSymbolData &rhs) const { bool operator<(const FunctionSymbolData &rhs) const;
return (uint32_t) mAddress < (uint32_t) rhs.mAddress;
}
virtual ~FunctionSymbolData() = default; virtual ~FunctionSymbolData();
[[nodiscard]] const std::string &getName() const { [[nodiscard]] const std::string &getName() const;
return mName;
}
[[nodiscard]] void *getAddress() const { [[nodiscard]] void *getAddress() const;
return mAddress;
}
[[nodiscard]] uint32_t getSize() const { [[nodiscard]] uint32_t getSize() const;
return mSize;
}
private: private:
std::string mName; std::string mName;

View File

@ -0,0 +1,16 @@
#include "HookData.h"
HookData::HookData(void *functionPointer, const wups_loader_hook_type_t type) {
this->mFunctionPointer = functionPointer;
this->mType = type;
}
HookData::~HookData() = default;
[[nodiscard]] void *HookData::getFunctionPointer() const {
return mFunctionPointer;
}
[[nodiscard]] wups_loader_hook_type_t HookData::getType() const {
return mType;
}

View File

@ -17,27 +17,20 @@
#pragma once #pragma once
#include <string>
#include <wups/hooks.h> #include <wups/hooks.h>
class HookData { class HookData {
public: public:
HookData(void *function_pointer, wups_loader_hook_type_t type) { HookData(void *functionPointer, wups_loader_hook_type_t type);
this->function_pointer = function_pointer;
this->type = type;
}
~HookData() = default; ~HookData();
[[nodiscard]] void *getFunctionPointer() const { [[nodiscard]] void *getFunctionPointer() const;
return function_pointer;
}
[[nodiscard]] wups_loader_hook_type_t getType() const { [[nodiscard]] wups_loader_hook_type_t getType() const;
return this->type;
}
private: private:
void *function_pointer; void *mFunctionPointer;
wups_loader_hook_type_t type; wups_loader_hook_type_t mType;
}; };

View File

@ -0,0 +1,20 @@
#include "ImportRPLInformation.h"
#include <cstring>
ImportRPLInformation::ImportRPLInformation(std::string_view name) {
this->mName = name;
}
ImportRPLInformation::~ImportRPLInformation() = default;
[[nodiscard]] const std::string &ImportRPLInformation::getName() const {
return mName;
}
[[nodiscard]] std::string ImportRPLInformation::getRPLName() const {
return mName.substr(strlen(".dimport_"));
}
[[nodiscard]] bool ImportRPLInformation::isData() const {
return mName.starts_with(".dimport_");
}

View File

@ -17,30 +17,20 @@
#pragma once #pragma once
#include "../utils/logger.h"
#include <string> #include <string>
#include <utility>
class ImportRPLInformation { class ImportRPLInformation {
public: public:
explicit ImportRPLInformation(std::string_view name) { explicit ImportRPLInformation(std::string_view name);
this->mName = name;
}
~ImportRPLInformation() = default; ~ImportRPLInformation();
[[nodiscard]] const std::string &getName() const { [[nodiscard]] const std::string &getName() const;
return mName;
}
[[nodiscard]] std::string getRPLName() const { [[nodiscard]] std::string getRPLName() const;
return mName.substr(strlen(".dimport_"));
}
[[nodiscard]] bool isData() const { [[nodiscard]] bool isData() const;
return mName.starts_with(".dimport_");
}
private: private:
std::string mName; std::string mName;

View File

@ -1,6 +1,10 @@
#include "PluginConfigData.h" #include "PluginConfigData.h"
PluginConfigData::PluginConfigData(std::string_view name, WUPSConfigAPI_MenuOpenedCallback openedCallback, WUPSConfigAPI_MenuClosedCallback closedCallback) : mName(name), #include <config/WUPSConfigAPI.h>
PluginConfigData::PluginConfigData(const std::string_view name,
const WUPSConfigAPI_MenuOpenedCallback openedCallback,
const WUPSConfigAPI_MenuClosedCallback closedCallback) : mName(name),
mOpenedCallback(openedCallback), mOpenedCallback(openedCallback),
mClosedCallback(closedCallback) { mClosedCallback(closedCallback) {
} }
@ -13,7 +17,7 @@ std::optional<WUPSConfigHandle> PluginConfigData::createConfig() const {
return std::nullopt; return std::nullopt;
} }
WUPSConfigAPIStatus PluginConfigData::CallMenuOpenendCallback(WUPSConfigHandle config) const { WUPSConfigAPIStatus PluginConfigData::CallMenuOpenedCallback(const WUPSConfigHandle config) const {
if (mOpenedCallback == nullptr) { if (mOpenedCallback == nullptr) {
return WUPSCONFIG_API_RESULT_MISSING_CALLBACK; return WUPSCONFIG_API_RESULT_MISSING_CALLBACK;
} }
@ -31,7 +35,9 @@ WUPSConfigAPIStatus PluginConfigData::CallMenuClosedCallback() const {
return WUPSCONFIG_API_RESULT_SUCCESS; return WUPSCONFIG_API_RESULT_SUCCESS;
} }
std::optional<PluginConfigData> PluginConfigData::create(WUPSConfigAPIOptions options, WUPSConfigAPI_MenuOpenedCallback openedCallback, WUPSConfigAPI_MenuClosedCallback closedCallback) { std::optional<PluginConfigData> PluginConfigData::create(const WUPSConfigAPIOptions options,
const WUPSConfigAPI_MenuOpenedCallback openedCallback,
const WUPSConfigAPI_MenuClosedCallback closedCallback) {
if (options.version != 1) { if (options.version != 1) {
return std::nullopt; return std::nullopt;
} }

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include "config/WUPSConfigAPI.h"
#include <optional> #include <optional>
#include <string> #include <string>
#include <wups/config.h>
#include <wups/config_api.h> #include <wups/config_api.h>
class PluginConfigData { class PluginConfigData {
@ -13,7 +13,7 @@ public:
[[nodiscard]] std::optional<WUPSConfigHandle> createConfig() const; [[nodiscard]] std::optional<WUPSConfigHandle> createConfig() const;
[[nodiscard]] WUPSConfigAPIStatus CallMenuOpenendCallback(WUPSConfigHandle config) const; [[nodiscard]] WUPSConfigAPIStatus CallMenuOpenedCallback(WUPSConfigHandle config) const;
[[nodiscard]] WUPSConfigAPIStatus CallMenuClosedCallback() const; [[nodiscard]] WUPSConfigAPIStatus CallMenuClosedCallback() const;

View File

@ -1,12 +1,14 @@
#include "PluginContainer.h" #include "PluginContainer.h"
#include <utils/storage/StorageUtils.h>
PluginContainer::PluginContainer(PluginMetaInformation metaInformation, PluginInformation pluginInformation, std::shared_ptr<PluginData> pluginData) PluginContainer::PluginContainer(PluginMetaInformation metaInformation, PluginInformation pluginInformation, std::shared_ptr<PluginData> pluginData)
: mMetaInformation(std::move(metaInformation)), : mMetaInformation(std::move(metaInformation)),
mPluginInformation(std::move(pluginInformation)), mPluginInformation(std::move(pluginInformation)),
mPluginData(std::move(pluginData)) { mPluginData(std::move(pluginData)) {
} }
PluginContainer::PluginContainer(PluginContainer &&src) : mMetaInformation(std::move(src.mMetaInformation)), PluginContainer::PluginContainer(PluginContainer &&src) noexcept : mMetaInformation(std::move(src.mMetaInformation)),
mPluginInformation(std::move(src.mPluginInformation)), mPluginInformation(std::move(src.mPluginInformation)),
mPluginData(std::move(src.mPluginData)), mPluginData(std::move(src.mPluginData)),
mPluginConfigData(std::move(src.mPluginConfigData)), mPluginConfigData(std::move(src.mPluginConfigData)),
@ -16,7 +18,7 @@ PluginContainer::PluginContainer(PluginContainer &&src) : mMetaInformation(std::
src.storageRootItem = {}; src.storageRootItem = {};
} }
PluginContainer &PluginContainer::operator=(PluginContainer &&src) { PluginContainer &PluginContainer::operator=(PluginContainer &&src) noexcept {
if (this != &src) { if (this != &src) {
this->mMetaInformation = src.mMetaInformation; this->mMetaInformation = src.mMetaInformation;
this->mPluginInformation = std::move(src.mPluginInformation); this->mPluginInformation = std::move(src.mPluginInformation);

View File

@ -21,10 +21,10 @@
#include "PluginData.h" #include "PluginData.h"
#include "PluginInformation.h" #include "PluginInformation.h"
#include "PluginMetaInformation.h" #include "PluginMetaInformation.h"
#include "utils/storage/StorageUtils.h"
#include <memory> #include <memory>
#include <utility> #include <optional>
#include <wups/config_api.h> #include <wups/storage.h>
class PluginContainer { class PluginContainer {
public: public:
@ -34,9 +34,9 @@ public:
PluginContainer(const PluginContainer &) = delete; PluginContainer(const PluginContainer &) = delete;
PluginContainer(PluginContainer &&src); PluginContainer(PluginContainer &&src) noexcept;
PluginContainer &operator=(PluginContainer &&src); PluginContainer &operator=(PluginContainer &&src) noexcept;
[[nodiscard]] const PluginMetaInformation &getMetaInformation() const; [[nodiscard]] const PluginMetaInformation &getMetaInformation() const;

View File

@ -1,7 +1,26 @@
#include "PluginData.h" #include "PluginData.h"
PluginData::PluginData(std::vector<uint8_t> &&buffer, const std::string_view source) : mBuffer(std::move(buffer)), mSource(source) {
}
PluginData::PluginData(std::span<uint8_t> buffer, const std::string_view source) : mBuffer(buffer.begin(), buffer.end()), mSource(source) {
}
PluginData::PluginData(PluginData &&src) : mBuffer(std::move(src.mBuffer)),
mSource(std::move(src.mSource)) {
}
PluginData &PluginData::operator=(PluginData &&src) noexcept {
if (this != &src) {
this->mBuffer = std::move(src.mBuffer);
this->mSource = std::move(src.mSource);
}
return *this;
}
uint32_t PluginData::getHandle() const { uint32_t PluginData::getHandle() const {
return (uint32_t) this; return reinterpret_cast<uint32_t>(this);
} }
std::span<const uint8_t> PluginData::getBuffer() const { std::span<const uint8_t> PluginData::getBuffer() const {

View File

@ -17,21 +17,22 @@
#pragma once #pragma once
#include <coreinit/memexpheap.h> #include <cstdint>
#include <malloc.h>
#include <memory>
#include <optional>
#include <span> #include <span>
#include <utility> #include <string>
#include <vector> #include <vector>
class PluginData { class PluginData {
public: public:
explicit PluginData(std::vector<uint8_t> &&buffer, std::string_view source) : mBuffer(std::move(buffer)), mSource(source) { explicit PluginData(std::vector<uint8_t> &&buffer, std::string_view source);
}
explicit PluginData(std::span<uint8_t> buffer, std::string_view source) : mBuffer(buffer.begin(), buffer.end()), mSource(source) { explicit PluginData(std::span<uint8_t> buffer, std::string_view source);
}
PluginData(const PluginData &) = delete;
PluginData(PluginData &&src) noexcept;
PluginData &operator=(PluginData &&src) noexcept;
[[nodiscard]] uint32_t getHandle() const; [[nodiscard]] uint32_t getHandle() const;

View File

@ -14,19 +14,20 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include "PluginDataFactory.h" #include "PluginDataFactory.h"
#include "NotificationsUtils.h" #include "NotificationsUtils.h"
#include "fs/FSUtils.h" #include "fs/FSUtils.h"
#include "utils/StringTools.h" #include "utils/StringTools.h"
#include "utils/logger.h" #include "utils/logger.h"
#include "utils/utils.h"
#include <dirent.h>
#include <forward_list>
#include <memory>
std::set<std::shared_ptr<PluginData>> PluginDataFactory::loadDir(std::string_view path) { #include <memory>
#include <set>
#include <sys/dirent.h>
std::set<std::shared_ptr<PluginData>> PluginDataFactory::loadDir(const std::string_view path) {
std::set<std::shared_ptr<PluginData>> result; std::set<std::shared_ptr<PluginData>> result;
struct dirent *dp; dirent *dp;
DIR *dfd; DIR *dfd;
if (path.empty()) { if (path.empty()) {
@ -50,8 +51,7 @@ std::set<std::shared_ptr<PluginData>> PluginDataFactory::loadDir(std::string_vie
auto full_file_path = string_format("%s/%s", path.data(), dp->d_name); auto full_file_path = string_format("%s/%s", path.data(), dp->d_name);
DEBUG_FUNCTION_LINE("Loading plugin: %s", full_file_path.c_str()); DEBUG_FUNCTION_LINE("Loading plugin: %s", full_file_path.c_str());
auto pluginData = load(full_file_path); if (auto pluginData = load(full_file_path)) {
if (pluginData) {
result.insert(std::move(pluginData)); result.insert(std::move(pluginData));
} else { } else {
auto errMsg = string_format("Failed to load plugin: %s", full_file_path.c_str()); auto errMsg = string_format("Failed to load plugin: %s", full_file_path.c_str());
@ -65,15 +65,15 @@ std::set<std::shared_ptr<PluginData>> PluginDataFactory::loadDir(std::string_vie
return result; return result;
} }
std::unique_ptr<PluginData> PluginDataFactory::load(std::string_view filename) { std::unique_ptr<PluginData> PluginDataFactory::load(const std::string_view path) {
std::vector<uint8_t> buffer; std::vector<uint8_t> buffer;
if (FSUtils::LoadFileToMem(filename, buffer) < 0) { if (FSUtils::LoadFileToMem(path, buffer) < 0) {
DEBUG_FUNCTION_LINE_ERR("Failed to load %s into memory", filename.data()); DEBUG_FUNCTION_LINE_ERR("Failed to load %s into memory", path.data());
return nullptr; return nullptr;
} }
DEBUG_FUNCTION_LINE_VERBOSE("Loaded file!"); DEBUG_FUNCTION_LINE_VERBOSE("Loaded file!");
return load(std::move(buffer), filename); return load(std::move(buffer), path);
} }
std::unique_ptr<PluginData> PluginDataFactory::load(std::vector<uint8_t> &&buffer, std::string_view source) { std::unique_ptr<PluginData> PluginDataFactory::load(std::vector<uint8_t> &&buffer, std::string_view source) {

View File

@ -16,14 +16,10 @@
****************************************************************************/ ****************************************************************************/
#pragma once #pragma once
#include "PluginData.h" #include "PluginData.h"
#include <coreinit/memexpheap.h>
#include <forward_list>
#include <memory> #include <memory>
#include <optional>
#include <set> #include <set>
#include <string>
#include <vector> #include <vector>
class PluginDataFactory { class PluginDataFactory {

View File

@ -28,7 +28,7 @@ PluginInformation &PluginInformation::operator=(PluginInformation &&src) {
return *this; return *this;
} }
void PluginInformation::addHookData(HookData hook_data) { void PluginInformation::addHookData(const HookData &hook_data) {
mHookDataList.push_back(hook_data); mHookDataList.push_back(hook_data);
} }
@ -75,7 +75,7 @@ std::optional<SectionInfo> PluginInformation::getSectionInfo(const std::string &
return std::nullopt; return std::nullopt;
} }
void PluginInformation::setTrampolineId(uint8_t trampolineId) { void PluginInformation::setTrampolineId(const uint8_t trampolineId) {
this->mTrampolineId = trampolineId; this->mTrampolineId = trampolineId;
} }
@ -83,15 +83,15 @@ uint8_t PluginInformation::getTrampolineId() const {
return mTrampolineId; return mTrampolineId;
} }
const FunctionSymbolData *PluginInformation::getNearestFunctionSymbolData(uint32_t address) const { const FunctionSymbolData *PluginInformation::getNearestFunctionSymbolData(const uint32_t address) const {
const FunctionSymbolData *result = nullptr; const FunctionSymbolData *result = nullptr;
bool foundHit = false; bool foundHit = false;
for (auto &cur : mSymbolDataList) { for (auto &cur : mSymbolDataList) {
if (foundHit && address < (uint32_t) cur.getAddress()) { if (foundHit && address < reinterpret_cast<uint32_t>(cur.getAddress())) {
break; break;
} }
if (address >= (uint32_t) cur.getAddress()) { if (address >= reinterpret_cast<uint32_t>(cur.getAddress())) {
result = &cur; result = &cur;
foundHit = true; foundHit = true;
} }

View File

@ -20,15 +20,12 @@
#include "FunctionData.h" #include "FunctionData.h"
#include "FunctionSymbolData.h" #include "FunctionSymbolData.h"
#include "HookData.h" #include "HookData.h"
#include "PluginMetaInformation.h"
#include "RelocationData.h" #include "RelocationData.h"
#include "SectionInfo.h" #include "SectionInfo.h"
#include "utils/HeapMemoryFixedSize.h" #include "utils/HeapMemoryFixedSize.h"
#include "utils/utils.h" #include <cstdint>
#include <map> #include <map>
#include <memory>
#include <optional> #include <optional>
#include <ranges>
#include <set> #include <set>
#include <string> #include <string>
#include <vector> #include <vector>
@ -71,7 +68,7 @@ public:
private: private:
PluginInformation() = default; PluginInformation() = default;
void addHookData(HookData hook_data); void addHookData(const HookData &hook_data);
void addFunctionData(FunctionData function_data); void addFunctionData(FunctionData function_data);

View File

@ -16,13 +16,12 @@
****************************************************************************/ ****************************************************************************/
#include "PluginInformationFactory.h" #include "PluginInformationFactory.h"
#include "../utils/ElfUtils.h" #include "utils/ElfUtils.h"
#include "utils/HeapMemoryFixedSize.h" #include "utils/logger.h"
#include "utils/utils.h"
#include "utils/wiiu_zlib.hpp" #include "utils/wiiu_zlib.hpp"
#include <coreinit/cache.h> #include <coreinit/cache.h>
#include <map>
#include <memory>
#include <string>
#include <wups/function_patching.h> #include <wups/function_patching.h>
using namespace ELFIO; using namespace ELFIO;
@ -50,7 +49,7 @@ PluginInformationFactory::load(const PluginData &pluginData, std::vector<relocat
DEBUG_FUNCTION_LINE_ERR("Failed alloc memory for destinations array"); DEBUG_FUNCTION_LINE_ERR("Failed alloc memory for destinations array");
return std::nullopt; return std::nullopt;
} }
std::span<uint8_t *> destinations(destinationsData.get(), sec_num); std::span destinations(destinationsData.get(), sec_num);
uint32_t totalSize = 0; uint32_t totalSize = 0;
@ -265,7 +264,7 @@ PluginInformationFactory::load(const PluginData &pluginData, std::vector<relocat
return pluginInfo; return pluginInfo;
} }
bool PluginInformationFactory::addImportRelocationData(PluginInformation &pluginInfo, const elfio &reader, std::span<uint8_t *> destinations) { bool PluginInformationFactory::addImportRelocationData(PluginInformation &pluginInfo, const elfio &reader, const std::span<uint8_t *> destinations) {
std::map<uint32_t, std::shared_ptr<ImportRPLInformation>> infoMap; std::map<uint32_t, std::shared_ptr<ImportRPLInformation>> infoMap;
uint32_t sec_num = reader.sections.size(); uint32_t sec_num = reader.sections.size();

View File

@ -16,15 +16,11 @@
****************************************************************************/ ****************************************************************************/
#pragma once #pragma once
#include "PluginData.h"
#include "../elfio/elfio.hpp"
#include "PluginContainer.h"
#include "PluginInformation.h" #include "PluginInformation.h"
#include <coreinit/memheap.h>
#include <map> #include <elfio/elfio.hpp>
#include <optional> #include <optional>
#include <string>
#include <vector>
#include <wums/defines/relocation_defines.h> #include <wums/defines/relocation_defines.h>
class PluginInformationFactory { class PluginInformationFactory {

View File

@ -0,0 +1,79 @@
#include "PluginMetaInformation.h"
[[nodiscard]] const std::string &PluginMetaInformation::getName() const {
return mName;
}
[[nodiscard]] const std::string &PluginMetaInformation::getAuthor() const {
return mAuthor;
}
[[nodiscard]] const std::string &PluginMetaInformation::getVersion() const {
return mVersion;
}
[[nodiscard]] const std::string &PluginMetaInformation::getLicense() const {
return mLicense;
}
[[nodiscard]] const std::string &PluginMetaInformation::getBuildTimestamp() const {
return mBuildTimestamp;
}
[[nodiscard]] const std::string &PluginMetaInformation::getDescription() const {
return mDescription;
}
[[nodiscard]] const WUPSVersion &PluginMetaInformation::getWUPSVersion() const {
return this->mWUPSVersion;
}
[[nodiscard]] const std::string &PluginMetaInformation::getStorageId() const {
return mStorageId;
}
[[nodiscard]] size_t PluginMetaInformation::getSize() const {
return mSize;
}
PluginMetaInformation::PluginMetaInformation() = default;
void PluginMetaInformation::setName(std::string name) {
mName = std::move(name);
}
void PluginMetaInformation::setAuthor(std::string author) {
mAuthor = std::move(author);
}
void PluginMetaInformation::setVersion(std::string version) {
mVersion = std::move(version);
}
void PluginMetaInformation::setLicense(std::string license) {
mLicense = std::move(license);
}
void PluginMetaInformation::setBuildTimestamp(std::string buildTimestamp) {
mBuildTimestamp = std::move(buildTimestamp);
}
void PluginMetaInformation::setDescription(std::string description) {
mDescription = std::move(description);
}
void PluginMetaInformation::setWUPSVersion(const uint16_t major, const uint16_t minor, const uint16_t revision) {
mWUPSVersion = WUPSVersion(major, minor, revision);
}
void PluginMetaInformation::setWUPSVersion(const WUPSVersion &wupsVersion) {
mWUPSVersion = wupsVersion;
}
void PluginMetaInformation::setSize(const size_t size) {
mSize = size;
}
void PluginMetaInformation::setStorageId(std::string storageId) {
mStorageId = std::move(storageId);
}

View File

@ -19,98 +19,59 @@
#include "WUPSVersion.h" #include "WUPSVersion.h"
#include <string> #include <string>
#include <vector>
class PluginMetaInformation { class PluginMetaInformation {
public: public:
[[nodiscard]] const std::string &getName() const { [[nodiscard]] const std::string &getName() const;
return name;
}
[[nodiscard]] const std::string &getAuthor() const { [[nodiscard]] const std::string &getAuthor() const;
return this->author;
}
[[nodiscard]] const std::string &getVersion() const { [[nodiscard]] const std::string &getVersion() const;
return this->version;
}
[[nodiscard]] const std::string &getLicense() const { [[nodiscard]] const std::string &getLicense() const;
return this->license;
}
[[nodiscard]] const std::string &getBuildTimestamp() const { [[nodiscard]] const std::string &getBuildTimestamp() const;
return this->buildtimestamp;
}
[[nodiscard]] const std::string &getDescription() const { [[nodiscard]] const std::string &getDescription() const;
return this->description;
}
[[nodiscard]] const WUPSVersion &getWUPSVersion() const { [[nodiscard]] const WUPSVersion &getWUPSVersion() const;
return this->wupsversion;
}
[[nodiscard]] const std::string &getStorageId() const { [[nodiscard]] const std::string &getStorageId() const;
return this->storageId;
}
[[nodiscard]] size_t getSize() const { [[nodiscard]] size_t getSize() const;
return this->size;
}
private: private:
PluginMetaInformation() = default; PluginMetaInformation();
void setName(std::string _name) { void setName(std::string name);
this->name = std::move(_name);
}
void setAuthor(std::string _author) { void setAuthor(std::string author);
this->author = std::move(_author);
}
void setVersion(std::string _version) { void setVersion(std::string version);
this->version = std::move(_version);
}
void setLicense(std::string _license) { void setLicense(std::string license);
this->license = std::move(_license);
}
void setBuildTimestamp(std::string _buildtimestamp) { void setBuildTimestamp(std::string buildTimestamp);
this->buildtimestamp = std::move(_buildtimestamp);
}
void setDescription(std::string _description) { void setDescription(std::string description);
this->description = std::move(_description);
}
void setWUPSVersion(uint16_t major, uint16_t minor, uint16_t revision) { void setWUPSVersion(uint16_t major, uint16_t minor, uint16_t revision);
this->wupsversion = WUPSVersion(major, minor, revision);
}
void setWUPSVersion(WUPSVersion &_wupsversion) { void setWUPSVersion(const WUPSVersion &wupsVersion);
this->wupsversion = _wupsversion;
}
void setSize(size_t _size) { void setSize(size_t size);
this->size = _size;
}
void setStorageId(std::string _storageId) { void setStorageId(std::string storageId);
this->storageId = std::move(_storageId);
}
std::string name; std::string mName;
std::string author; std::string mAuthor;
std::string version; std::string mVersion;
std::string license; std::string mLicense;
std::string buildtimestamp; std::string mBuildTimestamp;
std::string description; std::string mDescription;
std::string storageId; std::string mStorageId;
size_t size{}; size_t mSize = {};
WUPSVersion wupsversion = WUPSVersion(0, 0, 0); WUPSVersion mWUPSVersion = WUPSVersion(0, 0, 0);
friend class PluginMetaInformationFactory; friend class PluginMetaInformationFactory;

View File

@ -16,11 +16,15 @@
****************************************************************************/ ****************************************************************************/
#include "PluginMetaInformationFactory.h" #include "PluginMetaInformationFactory.h"
#include "elfio/elfio.hpp"
#include "PluginData.h"
#include "PluginMetaInformation.h"
#include "fs/FSUtils.h" #include "fs/FSUtils.h"
#include "utils/logger.h" #include "utils/logger.h"
#include "utils/wiiu_zlib.hpp" #include "utils/wiiu_zlib.hpp"
#include <memory>
#include <elfio/elfio.hpp>
#include <optional>
std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(const PluginData &pluginData, PluginParseErrors &error) { std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(const PluginData &pluginData, PluginParseErrors &error) {
return loadPlugin(pluginData.getBuffer(), error); return loadPlugin(pluginData.getBuffer(), error);

View File

@ -19,11 +19,10 @@
#include "PluginData.h" #include "PluginData.h"
#include "PluginMetaInformation.h" #include "PluginMetaInformation.h"
#include "elfio/elfio.hpp"
#include <memory>
#include <optional> #include <optional>
#include <string> #include <span>
#include <vector> #include <string_view>
enum PluginParseErrors { enum PluginParseErrors {
PLUGIN_PARSE_ERROR_NONE, PLUGIN_PARSE_ERROR_NONE,

View File

@ -0,0 +1,42 @@
#include "RelocationData.h"
RelocationData::RelocationData(const char type,
const size_t offset,
const int32_t addend,
void *destination,
std::string name,
std::shared_ptr<ImportRPLInformation> rplInfo) : mType(type),
mOffset(offset),
mAddend(addend),
mDestination(destination),
mName(std::move(name)),
mRPLInfo(std::move(rplInfo)) {
}
RelocationData::RelocationData(const RelocationData &o2) = default;
RelocationData::~RelocationData() = default;
[[nodiscard]] char RelocationData::getType() const {
return mType;
}
[[nodiscard]] size_t RelocationData::getOffset() const {
return mOffset;
}
[[nodiscard]] int32_t RelocationData::getAddend() const {
return mAddend;
}
[[nodiscard]] const void *RelocationData::getDestination() const {
return mDestination;
}
[[nodiscard]] const std::string &RelocationData::getName() const {
return mName;
}
[[nodiscard]] const ImportRPLInformation &RelocationData::getImportRPLInformation() const {
return *mRPLInfo;
}

View File

@ -18,54 +18,36 @@
#pragma once #pragma once
#include "ImportRPLInformation.h" #include "ImportRPLInformation.h"
#include <cstdint>
#include <memory> #include <memory>
#include <string> #include <string>
#include <utility>
class RelocationData { class RelocationData {
public: public:
RelocationData(const char type, size_t offset, int32_t addend, void *destination, std::string name, std::shared_ptr<ImportRPLInformation> rplInfo) : type(type), RelocationData(char type, size_t offset, int32_t addend, void *destination, std::string name, std::shared_ptr<ImportRPLInformation> rplInfo);
offset(offset),
addend(addend),
destination(destination),
name(std::move(name)),
rplInfo(std::move(rplInfo)) {
}
RelocationData(const RelocationData &o2) = default; RelocationData(const RelocationData &o2);
virtual ~RelocationData() = default; virtual ~RelocationData();
[[nodiscard]] char getType() const { [[nodiscard]] char getType() const;
return type;
}
[[nodiscard]] size_t getOffset() const { [[nodiscard]] size_t getOffset() const;
return offset;
}
[[nodiscard]] int32_t getAddend() const { [[nodiscard]] int32_t getAddend() const;
return addend;
}
[[nodiscard]] const void *getDestination() const { [[nodiscard]] const void *getDestination() const;
return destination;
}
[[nodiscard]] const std::string &getName() const { [[nodiscard]] const std::string &getName() const;
return name;
}
[[nodiscard]] const ImportRPLInformation &getImportRPLInformation() const { [[nodiscard]] const ImportRPLInformation &getImportRPLInformation() const;
return *rplInfo;
}
private: private:
char type; char mType;
size_t offset; size_t mOffset;
int32_t addend; int32_t mAddend;
void *destination; void *mDestination;
std::string name; std::string mName;
std::shared_ptr<ImportRPLInformation> rplInfo; std::shared_ptr<ImportRPLInformation> mRPLInfo;
}; };

View File

@ -0,0 +1,24 @@
#include "SectionInfo.h"
SectionInfo::SectionInfo(std::string name,
const uint32_t address,
const uint32_t sectionSize) : mName(std::move(name)),
mAddress(address),
mSectionSize(sectionSize) {
}
[[nodiscard]] const std::string &SectionInfo::getName() const {
return mName;
}
[[nodiscard]] uint32_t SectionInfo::getAddress() const {
return mAddress;
}
[[nodiscard]] uint32_t SectionInfo::getSize() const {
return mSectionSize;
}
[[nodiscard]] uint32_t SectionInfo::isInSection(uint32_t addr) const {
return addr >= mAddress && addr < mAddress + mSectionSize;
}

View File

@ -17,34 +17,24 @@
#pragma once #pragma once
#include <cstdint>
#include <string> #include <string>
class SectionInfo { class SectionInfo {
public: public:
SectionInfo(std::string name, uint32_t address, uint32_t sectionSize) : name(std::move(name)), SectionInfo(std::string name, uint32_t address, uint32_t sectionSize);
address(address),
sectionSize(sectionSize) {
}
[[nodiscard]] const std::string &getName() const { [[nodiscard]] const std::string &getName() const;
return name;
}
[[nodiscard]] uint32_t getAddress() const { [[nodiscard]] uint32_t getAddress() const;
return address;
}
[[nodiscard]] uint32_t getSize() const { [[nodiscard]] uint32_t getSize() const;
return sectionSize;
}
[[nodiscard]] uint32_t isInSection(uint32_t addr) const { [[nodiscard]] uint32_t isInSection(uint32_t addr) const;
return addr >= address && addr < address + sectionSize;
}
private: private:
std::string name; std::string mName;
uint32_t address{}; uint32_t mAddress = {};
uint32_t sectionSize{}; uint32_t mSectionSize = {};
}; };

View File

@ -0,0 +1,41 @@
#include "WUPSVersion.h"
#include "utils/StringTools.h"
WUPSVersion::WUPSVersion(const int major, const int minor, const int revision)
: mMajor(major), mMinor(minor), mRevision(revision) {
}
std::optional<WUPSVersion> WUPSVersion::createFromString(const std::string &versionStr) {
char *end;
errno = 0; // Initialize errno before calling strtol
const auto major = strtol(versionStr.c_str(), &end, 10);
if (errno || *end != '.') {
return std::nullopt;
}
const auto minor = strtol(end + 1, &end, 10);
if (errno || *end != '.') {
return std::nullopt;
}
const auto revision = strtol(end + 1, &end, 10);
if (errno || *end != '\0') {
return std::nullopt;
}
return WUPSVersion(static_cast<int>(major), static_cast<int>(minor), static_cast<int>(revision));
}
std::strong_ordering WUPSVersion::operator<=>(const WUPSVersion &other) const {
if (const auto cmp = mMajor <=> other.mMajor; cmp != std::strong_ordering::equal) return cmp;
if (const auto cmp = mMinor <=> other.mMinor; cmp != std::strong_ordering::equal) return cmp;
return mRevision <=> other.mRevision;
}
[[nodiscard]] std::string WUPSVersion::toString() const {
return string_format("%d.%d.%d", mMajor,
mMinor,
mRevision);
}

View File

@ -1,47 +1,19 @@
#include "utils/StringTools.h"
#include <cstdint> #include <cstdint>
#include <optional> #include <optional>
#include <string>
class WUPSVersion { class WUPSVersion {
public: public:
WUPSVersion(int major, int minor, int revision) WUPSVersion(int major, int minor, int revision);
: mVersion((static_cast<uint64_t>(major) << 32) |
(static_cast<uint64_t>(minor) << 16) |
static_cast<uint64_t>(revision)) {}
static std::optional<WUPSVersion> createFromString(const std::string &versionStr) { static std::optional<WUPSVersion> createFromString(const std::string &versionStr);
char *end;
errno = 0; // Initialize errno before calling strtol
auto major = strtol(versionStr.c_str(), &end, 10); std::strong_ordering operator<=>(const WUPSVersion &other) const;
if (errno || *end != '.') {
return std::nullopt;
}
[[nodiscard]] std::string toString() const;
auto minor = strtol(end + 1, &end, 10);
if (errno || *end != '.') {
return std::nullopt;
}
auto revision = strtol(end + 1, &end, 10);
if (errno || *end != '\0') {
return std::nullopt;
}
return WUPSVersion(static_cast<int>(major), static_cast<int>(minor), static_cast<int>(revision));
}
std::strong_ordering operator<=>(const WUPSVersion &other) const {
return mVersion <=> other.mVersion;
}
[[nodiscard]] std::string toString() const {
return string_format("%d.%d.%d", static_cast<int>((mVersion >> 32) & 0xFFFF),
static_cast<int>((mVersion >> 16) & 0xFFFF),
static_cast<int>((mVersion) &0xFFFF));
}
private: private:
uint64_t mVersion{}; uint32_t mMajor;
uint32_t mMinor;
uint32_t mRevision;
}; };

View File

@ -13,23 +13,23 @@
// buffer width // buffer width
#define DRC_WIDTH 0x380 #define DRC_WIDTH 0x380
bool DrawUtils::isBackBuffer; bool DrawUtils::mIsBackBuffer;
uint8_t *DrawUtils::tvBuffer = nullptr; uint8_t *DrawUtils::mTVBuffer = nullptr;
uint32_t DrawUtils::tvSize = 0; uint32_t DrawUtils::mTVSize = 0;
uint8_t *DrawUtils::drcBuffer = nullptr; uint8_t *DrawUtils::mDRCBuffer = nullptr;
uint32_t DrawUtils::drcSize = 0; uint32_t DrawUtils::mDRCSize = 0;
uint32_t DrawUtils::usedTVWidth = 1280; uint32_t DrawUtils::mUsedTVWidth = 1280;
float DrawUtils::usedTVScale = 1.5f; float DrawUtils::mUsedTVScale = 1.5f;
static SFT pFont = {}; static SFT pFont = {};
static Color font_col(0xFFFFFFFF); static Color font_col(0xFFFFFFFF);
void DrawUtils::initBuffers(void *tvBuffer_, uint32_t tvSize_, void *drcBuffer_, uint32_t drcSize_) { void DrawUtils::initBuffers(void *tvBuffer, const uint32_t tvSize, void *drcBuffer, const uint32_t drcSize) {
DrawUtils::tvBuffer = (uint8_t *) tvBuffer_; DrawUtils::mTVBuffer = static_cast<uint8_t *>(tvBuffer);
DrawUtils::tvSize = tvSize_; DrawUtils::mTVSize = tvSize;
DrawUtils::drcBuffer = (uint8_t *) drcBuffer_; DrawUtils::mDRCBuffer = static_cast<uint8_t *>(drcBuffer);
DrawUtils::drcSize = drcSize_; DrawUtils::mDRCSize = drcSize;
bool bigScale = true; bool bigScale = true;
switch (TVEGetCurrentPort()) { switch (TVEGetCurrentPort()) {
@ -67,53 +67,53 @@ void DrawUtils::initBuffers(void *tvBuffer_, uint32_t tvSize_, void *drcBuffer_,
auto tvScanBufferWidth = DCReadReg32(SCREEN_TV, D1GRPH_X_END_REG); auto tvScanBufferWidth = DCReadReg32(SCREEN_TV, D1GRPH_X_END_REG);
if (tvScanBufferWidth == 640) { // 480i/480p/576i 4:3 if (tvScanBufferWidth == 640) { // 480i/480p/576i 4:3
DrawUtils::usedTVWidth = 640; DrawUtils::mUsedTVWidth = 640;
SetDCPitchReg(SCREEN_TV, 640); SetDCPitchReg(SCREEN_TV, 640);
DrawUtils::usedTVScale = bigScale ? 0.75 : 0.75f; DrawUtils::mUsedTVScale = bigScale ? 0.75 : 0.75f;
} else if (tvScanBufferWidth == 854) { // 480i/480p/576i 16:9 } else if (tvScanBufferWidth == 854) { // 480i/480p/576i 16:9
DrawUtils::usedTVWidth = 896; DrawUtils::mUsedTVWidth = 896;
SetDCPitchReg(SCREEN_TV, 896); SetDCPitchReg(SCREEN_TV, 896);
DrawUtils::usedTVScale = bigScale ? 1.0 : 1.0f; DrawUtils::mUsedTVScale = bigScale ? 1.0 : 1.0f;
} else if (tvScanBufferWidth == 1280) { // 720p 16:9 } else if (tvScanBufferWidth == 1280) { // 720p 16:9
DrawUtils::usedTVWidth = 1280; DrawUtils::mUsedTVWidth = 1280;
SetDCPitchReg(SCREEN_TV, 1280); SetDCPitchReg(SCREEN_TV, 1280);
if (bigScale) { if (bigScale) {
DrawUtils::usedTVScale = 1.5; DrawUtils::mUsedTVScale = 1.5;
} else { } else {
DrawUtils::usedTVScale = 0.75f; DrawUtils::mUsedTVScale = 0.75f;
if (tvResolution == AVM_TV_RESOLUTION_480I_PAL60 || tvResolution == AVM_TV_RESOLUTION_480I) { if (tvResolution == AVM_TV_RESOLUTION_480I_PAL60 || tvResolution == AVM_TV_RESOLUTION_480I) {
AVMTvAspectRatio tvAspectRatio; AVMTvAspectRatio tvAspectRatio;
if (AVMGetTVAspectRatio(&tvAspectRatio) && tvAspectRatio == AVM_TV_ASPECT_RATIO_16_9) { if (AVMGetTVAspectRatio(&tvAspectRatio) && tvAspectRatio == AVM_TV_ASPECT_RATIO_16_9) {
DEBUG_FUNCTION_LINE_WARN("force big scaling for 480i + 16:9"); DEBUG_FUNCTION_LINE_WARN("force big scaling for 480i + 16:9");
DrawUtils::usedTVScale = 1.5; DrawUtils::mUsedTVScale = 1.5;
} }
} }
} }
} else if (tvScanBufferWidth == 1920) { // 1080i/1080p 16:9 } else if (tvScanBufferWidth == 1920) { // 1080i/1080p 16:9
DrawUtils::usedTVWidth = 1920; DrawUtils::mUsedTVWidth = 1920;
SetDCPitchReg(SCREEN_TV, 1920); SetDCPitchReg(SCREEN_TV, 1920);
DrawUtils::usedTVScale = bigScale ? 2.25 : 1.125f; DrawUtils::mUsedTVScale = bigScale ? 2.25 : 1.125f;
} else { } else {
DrawUtils::usedTVWidth = tvScanBufferWidth; DrawUtils::mUsedTVWidth = tvScanBufferWidth;
SetDCPitchReg(SCREEN_TV, tvScanBufferWidth); SetDCPitchReg(SCREEN_TV, tvScanBufferWidth);
DrawUtils::usedTVScale = 1.0f; DrawUtils::mUsedTVScale = 1.0f;
DEBUG_FUNCTION_LINE_WARN("Unknown tv width detected, config menu might not show properly"); DEBUG_FUNCTION_LINE_WARN("Unknown tv width detected, config menu might not show properly");
} }
} }
void DrawUtils::beginDraw() { void DrawUtils::beginDraw() {
uint32_t pixel = *(uint32_t *) tvBuffer; const uint32_t pixel = *reinterpret_cast<uint32_t *>(mTVBuffer);
// check which buffer is currently used // check which buffer is currently used
OSScreenPutPixelEx(SCREEN_TV, 0, 0, 0xABCDEF90); OSScreenPutPixelEx(SCREEN_TV, 0, 0, 0xABCDEF90);
if (*(uint32_t *) tvBuffer == 0xABCDEF90) { if (*reinterpret_cast<uint32_t *>(mTVBuffer) == 0xABCDEF90) {
isBackBuffer = false; mIsBackBuffer = false;
} else { } else {
isBackBuffer = true; mIsBackBuffer = true;
} }
// restore the pixel we used for checking // restore the pixel we used for checking
*(uint32_t *) tvBuffer = pixel; *reinterpret_cast<uint32_t *>(mTVBuffer) = pixel;
} }
void DrawUtils::endDraw() { void DrawUtils::endDraw() {
@ -125,58 +125,58 @@ void DrawUtils::endDraw() {
OSScreenFlipBuffersEx(SCREEN_TV); OSScreenFlipBuffersEx(SCREEN_TV);
} }
void DrawUtils::clear(Color col) { void DrawUtils::clear(const Color col) {
OSScreenClearBufferEx(SCREEN_TV, col.color); OSScreenClearBufferEx(SCREEN_TV, col.color);
OSScreenClearBufferEx(SCREEN_DRC, col.color); OSScreenClearBufferEx(SCREEN_DRC, col.color);
} }
void DrawUtils::drawPixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { void DrawUtils::drawPixel(const uint32_t x, const uint32_t y, const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t a) {
if (a == 0) { if (a == 0) {
return; return;
} }
float opacity = a / 255.0f; const float opacity = a / 255.0f;
// put pixel in the drc buffer // put pixel in the drc buffer
uint32_t i = (x + y * DRC_WIDTH) * 4; uint32_t i = (x + y * DRC_WIDTH) * 4;
if (i + 3 < drcSize / 2) { if (i + 3 < mDRCSize / 2) {
if (isBackBuffer) { if (mIsBackBuffer) {
i += drcSize / 2; i += mDRCSize / 2;
} }
if (a == 0xFF) { if (a == 0xFF) {
drcBuffer[i] = r; mDRCBuffer[i] = r;
drcBuffer[i + 1] = g; mDRCBuffer[i + 1] = g;
drcBuffer[i + 2] = b; mDRCBuffer[i + 2] = b;
} else { } else {
drcBuffer[i] = r * opacity + drcBuffer[i] * (1 - opacity); mDRCBuffer[i] = r * opacity + mDRCBuffer[i] * (1 - opacity);
drcBuffer[i + 1] = g * opacity + drcBuffer[i + 1] * (1 - opacity); mDRCBuffer[i + 1] = g * opacity + mDRCBuffer[i + 1] * (1 - opacity);
drcBuffer[i + 2] = b * opacity + drcBuffer[i + 2] * (1 - opacity); mDRCBuffer[i + 2] = b * opacity + mDRCBuffer[i + 2] * (1 - opacity);
} }
} }
// scale and put pixel in the tv buffer // scale and put pixel in the tv buffer
for (uint32_t yy = (y * DrawUtils::usedTVScale); yy < ((y * DrawUtils::usedTVScale) + (uint32_t) DrawUtils::usedTVScale); yy++) { for (uint32_t yy = (y * DrawUtils::mUsedTVScale); yy < ((y * DrawUtils::mUsedTVScale) + (uint32_t) DrawUtils::mUsedTVScale); yy++) {
for (uint32_t xx = (x * DrawUtils::usedTVScale); xx < ((x * DrawUtils::usedTVScale) + (uint32_t) DrawUtils::usedTVScale); xx++) { for (uint32_t xx = (x * DrawUtils::mUsedTVScale); xx < ((x * DrawUtils::mUsedTVScale) + (uint32_t) DrawUtils::mUsedTVScale); xx++) {
uint32_t i = (xx + yy * DrawUtils::usedTVWidth) * 4; uint32_t i = (xx + yy * DrawUtils::mUsedTVWidth) * 4;
if (i + 3 < tvSize / 2) { if (i + 3 < mTVSize / 2) {
if (isBackBuffer) { if (mIsBackBuffer) {
i += tvSize / 2; i += mTVSize / 2;
} }
if (a == 0xFF) { if (a == 0xFF) {
tvBuffer[i] = r; mTVBuffer[i] = r;
tvBuffer[i + 1] = g; mTVBuffer[i + 1] = g;
tvBuffer[i + 2] = b; mTVBuffer[i + 2] = b;
} else { } else {
tvBuffer[i] = r * opacity + tvBuffer[i] * (1 - opacity); mTVBuffer[i] = r * opacity + mTVBuffer[i] * (1 - opacity);
tvBuffer[i + 1] = g * opacity + tvBuffer[i + 1] * (1 - opacity); mTVBuffer[i + 1] = g * opacity + mTVBuffer[i + 1] * (1 - opacity);
tvBuffer[i + 2] = b * opacity + tvBuffer[i + 2] * (1 - opacity); mTVBuffer[i + 2] = b * opacity + mTVBuffer[i + 2] * (1 - opacity);
} }
} }
} }
} }
} }
void DrawUtils::drawRectFilled(uint32_t x, uint32_t y, uint32_t w, uint32_t h, Color col) { void DrawUtils::drawRectFilled(const uint32_t x, const uint32_t y, const uint32_t w, const uint32_t h, const Color col) {
for (uint32_t yy = y; yy < y + h; yy++) { for (uint32_t yy = y; yy < y + h; yy++) {
for (uint32_t xx = x; xx < x + w; xx++) { for (uint32_t xx = x; xx < x + w; xx++) {
drawPixel(xx, yy, col); drawPixel(xx, yy, col);
@ -184,22 +184,22 @@ void DrawUtils::drawRectFilled(uint32_t x, uint32_t y, uint32_t w, uint32_t h, C
} }
} }
void DrawUtils::drawRect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t borderSize, Color col) { void DrawUtils::drawRect(const uint32_t x, const uint32_t y, const uint32_t w, const uint32_t h, const uint32_t borderSize, const Color col) {
drawRectFilled(x, y, w, borderSize, col); drawRectFilled(x, y, w, borderSize, col);
drawRectFilled(x, y + h - borderSize, w, borderSize, col); drawRectFilled(x, y + h - borderSize, w, borderSize, col);
drawRectFilled(x, y, borderSize, h, col); drawRectFilled(x, y, borderSize, h, col);
drawRectFilled(x + w - borderSize, y, borderSize, h, col); drawRectFilled(x + w - borderSize, y, borderSize, h, col);
} }
void DrawUtils::drawBitmap(uint32_t x, uint32_t y, uint32_t target_width, uint32_t target_height, const uint8_t *data) { void DrawUtils::drawBitmap(const uint32_t x, const uint32_t y, const uint32_t target_width, const uint32_t target_height, const uint8_t *data) {
if (data[0] != 'B' || data[1] != 'M') { if (data[0] != 'B' || data[1] != 'M') {
// invalid header // invalid header
return; return;
} }
uint32_t dataPos = __builtin_bswap32(*(uint32_t *) &(data[0x0A])); uint32_t dataPos = __builtin_bswap32(*(uint32_t *) &(data[0x0A]));
uint32_t width = __builtin_bswap32(*(uint32_t *) &(data[0x12])); const uint32_t width = __builtin_bswap32(*(uint32_t *) &(data[0x12]));
uint32_t height = __builtin_bswap32(*(uint32_t *) &(data[0x16])); const uint32_t height = __builtin_bswap32(*(uint32_t *) &(data[0x16]));
if (dataPos == 0) { if (dataPos == 0) {
dataPos = 54; dataPos = 54;
@ -218,13 +218,13 @@ void DrawUtils::drawBitmap(uint32_t x, uint32_t y, uint32_t target_width, uint32
} }
static void png_read_data(png_structp png_ptr, png_bytep outBytes, png_size_t byteCountToRead) { static void png_read_data(png_structp png_ptr, png_bytep outBytes, png_size_t byteCountToRead) {
void **data = (void **) png_get_io_ptr(png_ptr); void **data = static_cast<void **>(png_get_io_ptr(png_ptr));
memcpy(outBytes, *data, byteCountToRead); memcpy(outBytes, *data, byteCountToRead);
*((uint8_t **) data) += byteCountToRead; *reinterpret_cast<uint8_t **>(data) += byteCountToRead;
} }
void DrawUtils::drawPNG(uint32_t x, uint32_t y, const uint8_t *data) { void DrawUtils::drawPNG(const uint32_t x, const uint32_t y, const uint8_t *data) {
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
if (png_ptr == nullptr) { if (png_ptr == nullptr) {
return; return;
@ -244,12 +244,12 @@ void DrawUtils::drawPNG(uint32_t x, uint32_t y, const uint8_t *data) {
uint32_t height = 0; uint32_t height = 0;
int bitDepth = 0; int bitDepth = 0;
int colorType = -1; int colorType = -1;
uint32_t retval = png_get_IHDR(png_ptr, info_ptr, &width, &height, &bitDepth, &colorType, nullptr, nullptr, nullptr); const uint32_t retval = png_get_IHDR(png_ptr, info_ptr, &width, &height, &bitDepth, &colorType, nullptr, nullptr, nullptr);
if (retval != 1) { if (retval != 1) {
return; return;
} }
uint32_t bytesPerRow = png_get_rowbytes(png_ptr, info_ptr); const uint32_t bytesPerRow = png_get_rowbytes(png_ptr, info_ptr);
auto *rowData = new uint8_t[bytesPerRow]; auto *rowData = new uint8_t[bytesPerRow];
for (uint32_t yy = y; yy < y + height; yy++) { for (uint32_t yy = y; yy < y + height; yy++) {
@ -302,17 +302,17 @@ void DrawUtils::setFontSize(uint32_t size) {
sft_lmetrics(&pFont, &metrics); sft_lmetrics(&pFont, &metrics);
} }
void DrawUtils::setFontColor(Color col) { void DrawUtils::setFontColor(const Color col) {
font_col = col; font_col = col;
} }
static void draw_freetype_bitmap(SFT_Image *bmp, int32_t x, int32_t y) { static void draw_freetype_bitmap(const SFT_Image *bmp, const int32_t x, const int32_t y) {
int32_t i, j, p, q; int32_t i, j, p, q;
int32_t x_max = x + bmp->width; int32_t x_max = x + bmp->width;
int32_t y_max = y + bmp->height; int32_t y_max = y + bmp->height;
auto *src = (uint8_t *) bmp->pixels; const auto *src = static_cast<uint8_t *>(bmp->pixels);
for (i = x, p = 0; i < x_max; i++, p++) { for (i = x, p = 0; i < x_max; i++, p++) {
for (j = y, q = 0; j < y_max; j++, q++) { for (j = y, q = 0; j < y_max; j++, q++) {
@ -320,13 +320,13 @@ static void draw_freetype_bitmap(SFT_Image *bmp, int32_t x, int32_t y) {
continue; continue;
} }
float opacity = src[q * bmp->width + p] / 255.0f; const float opacity = src[q * bmp->width + p] / 255.0f;
DrawUtils::drawPixel(i, j, font_col.r, font_col.g, font_col.b, font_col.a * opacity); DrawUtils::drawPixel(i, j, font_col.r, font_col.g, font_col.b, font_col.a * opacity);
} }
} }
} }
void DrawUtils::print(uint32_t x, uint32_t y, const char *string, bool alignRight) { void DrawUtils::print(const uint32_t x, const uint32_t y, const char *string, const bool alignRight) {
auto *buffer = new wchar_t[strlen(string) + 1]; auto *buffer = new wchar_t[strlen(string) + 1];
size_t num = mbstowcs(buffer, string, strlen(string)); size_t num = mbstowcs(buffer, string, strlen(string));
@ -342,9 +342,9 @@ void DrawUtils::print(uint32_t x, uint32_t y, const char *string, bool alignRigh
delete[] buffer; delete[] buffer;
} }
void DrawUtils::print(uint32_t x, uint32_t y, const wchar_t *string, bool alignRight) { void DrawUtils::print(const uint32_t x, const uint32_t y, const wchar_t *string, const bool alignRight) {
auto penX = (int32_t) x; auto penX = static_cast<int32_t>(x);
auto penY = (int32_t) y; auto penY = static_cast<int32_t>(y);
if (alignRight) { if (alignRight) {
penX -= getTextWidth(string); penX -= getTextWidth(string);
@ -392,8 +392,8 @@ void DrawUtils::print(uint32_t x, uint32_t y, const wchar_t *string, bool alignR
DEBUG_FUNCTION_LINE_ERR("Failed to render glyph"); DEBUG_FUNCTION_LINE_ERR("Failed to render glyph");
return; return;
} else { } else {
draw_freetype_bitmap(&img, (int32_t) (penX + mtx.leftSideBearing), (int32_t) (penY + mtx.yOffset)); draw_freetype_bitmap(&img, static_cast<int32_t>(penX + mtx.leftSideBearing), penY + mtx.yOffset);
penX += (int32_t) mtx.advanceWidth; penX += static_cast<int32_t>(mtx.advanceWidth);
} }
} }
} }
@ -402,8 +402,7 @@ void DrawUtils::print(uint32_t x, uint32_t y, const wchar_t *string, bool alignR
uint32_t DrawUtils::getTextWidth(const char *string) { uint32_t DrawUtils::getTextWidth(const char *string) {
auto *buffer = new wchar_t[strlen(string) + 1]; auto *buffer = new wchar_t[strlen(string) + 1];
size_t num = mbstowcs(buffer, string, strlen(string)); if (const size_t num = mbstowcs(buffer, string, strlen(string)); num > 0) {
if (num > 0) {
buffer[num] = 0; buffer[num] = 0;
} else { } else {
wchar_t *tmp = buffer; wchar_t *tmp = buffer;
@ -411,7 +410,7 @@ uint32_t DrawUtils::getTextWidth(const char *string) {
; ;
} }
uint32_t width = getTextWidth(buffer); const uint32_t width = getTextWidth(buffer);
delete[] buffer; delete[] buffer;
return width; return width;
@ -427,9 +426,9 @@ uint32_t DrawUtils::getTextWidth(const wchar_t *string) {
if (sft_gmetrics(&pFont, gid, &mtx) < 0) { if (sft_gmetrics(&pFont, gid, &mtx) < 0) {
DEBUG_FUNCTION_LINE_ERR("bad glyph metrics"); DEBUG_FUNCTION_LINE_ERR("bad glyph metrics");
} }
width += (int32_t) mtx.advanceWidth; width += static_cast<int32_t>(mtx.advanceWidth);
} }
} }
return (uint32_t) width; return width;
} }

View File

@ -8,11 +8,11 @@
#define SCREEN_HEIGHT 480 #define SCREEN_HEIGHT 480
union Color { union Color {
explicit Color(uint32_t color) { explicit Color(const uint32_t color) {
this->color = color; this->color = color;
} }
Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { Color(const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t a) {
this->r = r; this->r = r;
this->g = g; this->g = g;
this->b = b; this->b = b;
@ -67,12 +67,12 @@ public:
static uint32_t getTextWidth(const wchar_t *string); static uint32_t getTextWidth(const wchar_t *string);
private: private:
static bool isBackBuffer; static bool mIsBackBuffer;
static uint8_t *tvBuffer; static uint8_t *mTVBuffer;
static uint32_t tvSize; static uint32_t mTVSize;
static uint8_t *drcBuffer; static uint8_t *mDRCBuffer;
static uint32_t drcSize; static uint32_t mDRCSize;
static uint32_t usedTVWidth; static uint32_t mUsedTVWidth;
static float usedTVScale; static float mUsedTVScale;
}; };

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <stdint.h> #include <cstdint>
#include <wums/defines/relocation_defines.h> #include <wums/defines/relocation_defines.h>
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -0,0 +1,32 @@
#include "HeapMemoryFixedSize.h"
#include "utils.h"
HeapMemoryFixedSize::HeapMemoryFixedSize() = default;
HeapMemoryFixedSize::HeapMemoryFixedSize(std::size_t size) : mData(make_unique_nothrow<uint8_t[]>(size)), mSize(mData ? size : 0) {}
HeapMemoryFixedSize::HeapMemoryFixedSize(HeapMemoryFixedSize &&other) noexcept
: mData(std::move(other.mData)), mSize(other.mSize) {
other.mSize = 0;
}
HeapMemoryFixedSize &HeapMemoryFixedSize::operator=(HeapMemoryFixedSize &&other) noexcept {
if (this != &other) {
mData = std::move(other.mData);
mSize = other.mSize;
other.mSize = 0;
}
return *this;
}
HeapMemoryFixedSize::operator bool() const {
return mData != nullptr;
}
[[nodiscard]] const void *HeapMemoryFixedSize::data() const {
return mData.get();
}
[[nodiscard]] std::size_t HeapMemoryFixedSize::size() const {
return mSize;
}

View File

@ -1,43 +1,27 @@
#pragma once #pragma once
#include "utils.h"
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
class HeapMemoryFixedSize { class HeapMemoryFixedSize {
public: public:
HeapMemoryFixedSize() = default; HeapMemoryFixedSize();
explicit HeapMemoryFixedSize(std::size_t size) : mData(make_unique_nothrow<uint8_t[]>(size)), mSize(mData ? size : 0) {} explicit HeapMemoryFixedSize(std::size_t size);
// Delete the copy constructor and copy assignment operator // Delete the copy constructor and copy assignment operator
HeapMemoryFixedSize(const HeapMemoryFixedSize &) = delete; HeapMemoryFixedSize(const HeapMemoryFixedSize &) = delete;
HeapMemoryFixedSize &operator=(const HeapMemoryFixedSize &) = delete; HeapMemoryFixedSize &operator=(const HeapMemoryFixedSize &) = delete;
HeapMemoryFixedSize(HeapMemoryFixedSize &&other) noexcept HeapMemoryFixedSize(HeapMemoryFixedSize &&other) noexcept;
: mData(std::move(other.mData)), mSize(other.mSize) {
other.mSize = 0;
}
HeapMemoryFixedSize &operator=(HeapMemoryFixedSize &&other) noexcept { HeapMemoryFixedSize &operator=(HeapMemoryFixedSize &&other) noexcept;
if (this != &other) {
mData = std::move(other.mData);
mSize = other.mSize;
other.mSize = 0;
}
return *this;
}
explicit operator bool() const { explicit operator bool() const;
return mData != nullptr;
}
[[nodiscard]] const void *data() const { [[nodiscard]] const void *data() const;
return mData.get();
}
[[nodiscard]] std::size_t size() const { [[nodiscard]] std::size_t size() const;
return mSize;
}
private: private:
std::unique_ptr<uint8_t[]> mData{}; std::unique_ptr<uint8_t[]> mData{};

View File

@ -7,6 +7,8 @@
#include "utils/json.hpp" #include "utils/json.hpp"
#include "utils/logger.h" #include "utils/logger.h"
#include <malloc.h>
namespace WUPSStorageDeprecated { namespace WUPSStorageDeprecated {
static void processJson(wups_storage_item_t *items, nlohmann::json json) { static void processJson(wups_storage_item_t *items, nlohmann::json json) {
if (items == nullptr) { if (items == nullptr) {

View File

@ -24,13 +24,12 @@
* for WiiXplorer 2010 * for WiiXplorer 2010
***************************************************************************/ ***************************************************************************/
#include "StringTools.h"
#include <cstring> #include <cstring>
#include <string> #include <string>
#include <strings.h> #include <strings.h>
#include <utils/StringTools.h>
#include <wut_types.h>
std::string StringTools::truncate(const std::string &str, size_t width, bool show_ellipsis) { std::string StringTools::truncate(const std::string &str, const size_t width, const bool show_ellipsis) {
if (str.length() > width - 3) { if (str.length() > width - 3) {
if (show_ellipsis) { if (show_ellipsis) {
return str.substr(0, width - 3) + "..."; return str.substr(0, width - 3) + "...";
@ -60,3 +59,33 @@ int32_t StringTools::strtokcmp(const char *string, const char *compare, const ch
return -1; return -1;
} }
const char *StringTools::FullpathToFilename(const char *path) {
if (!path)
return path;
const char *ptr = path;
const char *Filename = ptr;
while (*ptr != '\0') {
if (ptr[0] == '/' && ptr[1] != '\0')
Filename = ptr + 1;
++ptr;
}
return Filename;
}
void StringTools::RemoveDoubleSlashes(std::string &str) {
uint32_t length = str.size();
//! clear path of double slashes
for (uint32_t i = 1; i < length; ++i) {
if (str[i - 1] == '/' && str[i] == '/') {
str.erase(i, 1);
i--;
length--;
}
}
}

View File

@ -30,14 +30,12 @@
#include <coreinit/debug.h> #include <coreinit/debug.h>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector>
#include <wut_types.h>
template<typename... Args> template<typename... Args>
std::string string_format(std::string_view format, Args... args) { std::string string_format(const std::string_view format, Args... args) {
int size_s = std::snprintf(nullptr, 0, format.data(), args...) + 1; // Extra space for '\0' const int size_s = std::snprintf(nullptr, 0, format.data(), args...) + 1; // Extra space for '\0'
auto size = static_cast<size_t>(size_s); const auto size = static_cast<size_t>(size_s);
auto buf = make_unique_nothrow<char[]>(size); const auto buf = make_unique_nothrow<char[]>(size);
if (!buf) { if (!buf) {
DEBUG_FUNCTION_LINE_ERR("string_format failed, not enough memory"); DEBUG_FUNCTION_LINE_ERR("string_format failed, not enough memory");
OSFatal("string_format failed, not enough memory"); OSFatal("string_format failed, not enough memory");
@ -53,33 +51,7 @@ public:
static int32_t strtokcmp(const char *string, const char *compare, const char *separator); static int32_t strtokcmp(const char *string, const char *compare, const char *separator);
static const char *FullpathToFilename(const char *path) { static const char *FullpathToFilename(const char *path);
if (!path)
return path;
const char *ptr = path; static void RemoveDoubleSlashes(std::string &str);
const char *Filename = ptr;
while (*ptr != '\0') {
if (ptr[0] == '/' && ptr[1] != '\0')
Filename = ptr + 1;
++ptr;
}
return Filename;
}
static void RemoveDoubleSlashs(std::string &str) {
uint32_t length = str.size();
//! clear path of double slashes
for (uint32_t i = 1; i < length; ++i) {
if (str[i - 1] == '/' && str[i] == '/') {
str.erase(i, 1);
i--;
length--;
}
}
}
}; };

View File

@ -1,6 +1,8 @@
#include "base64.h" #include "base64.h"
#include <string.h> #include <cstddef>
#include <cstdlib>
#include <cstring>
static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <stdint.h> #include <cstddef>
#include <stdlib.h> #include <cstdint>
// based on https://nachtimwald.com/2017/11/18/base64-encode-and-decode-in-c/ // based on https://nachtimwald.com/2017/11/18/base64-encode-and-decode-in-c/

View File

@ -1,12 +1,13 @@
#include "CategoryRenderer.h" #include "CategoryRenderer.h"
#include "ConfigDefines.h" #include "ConfigRendererItem.h"
#include "config/WUPSConfigCategory.h" #include "ConfigRendererItemCategory.h"
#include "utils/input/Input.h" #include "ConfigUtils.h"
#include "utils/DrawUtils.h"
#include "utils/StringTools.h"
#include "utils/logger.h"
#include "utils/utils.h" #include "utils/utils.h"
#include <vector>
#include <wups/config.h>
CategoryRenderer::CategoryRenderer(const GeneralConfigInformation *info, const WUPSConfigAPIBackend::WUPSConfigCategory *cat, bool isRoot) CategoryRenderer::CategoryRenderer(const GeneralConfigInformation *info, const WUPSConfigAPIBackend::WUPSConfigCategory *cat, const bool isRoot)
: mInfo(info), mCat(cat), mIsRoot(isRoot) { : mInfo(info), mCat(cat), mIsRoot(isRoot) {
for (uint32_t i = 0; i < cat->getCategories().size() + cat->getItems().size(); i++) { for (uint32_t i = 0; i < cat->getCategories().size() + cat->getItems().size(); i++) {
if (i < cat->getCategories().size()) { if (i < cat->getCategories().size()) {
@ -14,8 +15,8 @@ CategoryRenderer::CategoryRenderer(const GeneralConfigInformation *info, const W
assert(item); assert(item);
mItemRenderer.push_back(std::move(item)); mItemRenderer.push_back(std::move(item));
} else { } else {
auto itemIndex = (int32_t) (i - cat->getCategories().size()); const auto itemIndex = static_cast<int32_t>(i - cat->getCategories().size());
if (itemIndex < 0 || itemIndex >= (int32_t) cat->getItems().size()) { if (itemIndex < 0 || itemIndex >= static_cast<int32_t>(cat->getItems().size())) {
assert(false); assert(false);
} }
auto item = make_unique_nothrow<ConfigRendererItem>(cat->getItems()[itemIndex].get()); auto item = make_unique_nothrow<ConfigRendererItem>(cat->getItems()[itemIndex].get());
@ -31,13 +32,13 @@ CategoryRenderer::CategoryRenderer(const GeneralConfigInformation *info, const W
// Make sure to call Update to get the current text of an item. // Make sure to call Update to get the current text of an item.
for (uint32_t i = 0; i < mItemRenderer.size(); i++) { for (uint32_t i = 0; i < mItemRenderer.size(); i++) {
bool isHighlighted = ((int) i == mCursorPos); const bool isHighlighted = (static_cast<int>(i) == mCursorPos);
mItemRenderer[i]->Update(isHighlighted); mItemRenderer[i]->Update(isHighlighted);
} }
} }
CategoryRenderer::~CategoryRenderer() { CategoryRenderer::~CategoryRenderer() {
if (mCursorPos < (int32_t) mItemRenderer.size()) { if (mCursorPos < static_cast<int32_t>(mItemRenderer.size())) {
mItemRenderer[mCursorPos]->SetIsSelected(false); mItemRenderer[mCursorPos]->SetIsSelected(false);
} }
} }
@ -45,14 +46,13 @@ CategoryRenderer::~CategoryRenderer() {
ConfigSubState CategoryRenderer::Update(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData) { ConfigSubState CategoryRenderer::Update(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData) {
switch (mState) { switch (mState) {
case STATE_MAIN: { case STATE_MAIN: {
auto res = UpdateStateMain(input, simpleInputData, complexInputData); const auto res = UpdateStateMain(input, simpleInputData, complexInputData);
mFirstFrame = false; mFirstFrame = false;
return res; return res;
} }
case STATE_SUB: { case STATE_SUB: {
if (mSubCategoryRenderer) { if (mSubCategoryRenderer) {
auto subResult = mSubCategoryRenderer->Update(input, simpleInputData, complexInputData); if (const auto subResult = mSubCategoryRenderer->Update(input, simpleInputData, complexInputData); subResult != SUB_STATE_RUNNING) {
if (subResult != SUB_STATE_RUNNING) {
mNeedsRedraw = true; mNeedsRedraw = true;
mState = STATE_MAIN; mState = STATE_MAIN;
mFirstFrame = true; mFirstFrame = true;
@ -69,7 +69,7 @@ ConfigSubState CategoryRenderer::Update(Input &input, const WUPSConfigSimplePadD
return SUB_STATE_ERROR; return SUB_STATE_ERROR;
} }
ConfigSubState CategoryRenderer::UpdateStateMain(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData) { ConfigSubState CategoryRenderer::UpdateStateMain(const Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData) {
if (mIsItemMovementAllowed && input.data.buttons_d & Input::eButtons::BUTTON_B) { if (mIsItemMovementAllowed && input.data.buttons_d & Input::eButtons::BUTTON_B) {
return SUB_STATE_RETURN; return SUB_STATE_RETURN;
} }
@ -77,8 +77,8 @@ ConfigSubState CategoryRenderer::UpdateStateMain(Input &input, const WUPSConfigS
return SUB_STATE_RUNNING; return SUB_STATE_RUNNING;
} }
auto totalElementSize = mItemRenderer.size(); const auto totalElementSize = mItemRenderer.size();
int32_t prevSelectedItem = mCursorPos; const int32_t prevSelectedItem = mCursorPos;
if (mIsItemMovementAllowed) { if (mIsItemMovementAllowed) {
if (input.data.buttons_d & Input::eButtons::BUTTON_DOWN) { if (input.data.buttons_d & Input::eButtons::BUTTON_DOWN) {
@ -86,7 +86,7 @@ ConfigSubState CategoryRenderer::UpdateStateMain(Input &input, const WUPSConfigS
} else if (input.data.buttons_d & Input::eButtons::BUTTON_UP) { } else if (input.data.buttons_d & Input::eButtons::BUTTON_UP) {
mCursorPos--; mCursorPos--;
} else if (input.data.buttons_d & Input::eButtons::BUTTON_A) { } else if (input.data.buttons_d & Input::eButtons::BUTTON_A) {
if (mCursorPos < (int32_t) mCat->getCategories().size()) { if (mCursorPos < static_cast<int32_t>(mCat->getCategories().size())) {
if (mCurrentOpen != mCursorPos) { if (mCurrentOpen != mCursorPos) {
mSubCategoryRenderer.reset(); mSubCategoryRenderer.reset();
mSubCategoryRenderer = make_unique_nothrow<CategoryRenderer>(mInfo, mCat->getCategories()[mCursorPos].get(), false); mSubCategoryRenderer = make_unique_nothrow<CategoryRenderer>(mInfo, mCat->getCategories()[mCursorPos].get(), false);
@ -100,8 +100,8 @@ ConfigSubState CategoryRenderer::UpdateStateMain(Input &input, const WUPSConfigS
} }
if (mCursorPos < 0) { if (mCursorPos < 0) {
mCursorPos = (int32_t) totalElementSize - 1; mCursorPos = static_cast<int32_t>(totalElementSize) - 1;
} else if (mCursorPos > (int32_t) (totalElementSize - 1)) { } else if (mCursorPos > static_cast<int32_t>(totalElementSize - 1)) {
mCursorPos = 0; mCursorPos = 0;
} }
@ -139,7 +139,7 @@ ConfigSubState CategoryRenderer::UpdateStateMain(Input &input, const WUPSConfigS
mIsItemMovementAllowed = mItemRenderer[mCursorPos]->IsMovementAllowed(); mIsItemMovementAllowed = mItemRenderer[mCursorPos]->IsMovementAllowed();
for (uint32_t i = 0; i < mItemRenderer.size(); i++) { for (uint32_t i = 0; i < mItemRenderer.size(); i++) {
bool isHighlighted = ((int) i == mCursorPos); const bool isHighlighted = (static_cast<int>(i) == mCursorPos);
mItemRenderer[i]->Update(isHighlighted); mItemRenderer[i]->Update(isHighlighted);
} }
@ -152,7 +152,7 @@ void CategoryRenderer::ResetNeedsRedraw() {
if (mSubCategoryRenderer) { if (mSubCategoryRenderer) {
mSubCategoryRenderer->ResetNeedsRedraw(); mSubCategoryRenderer->ResetNeedsRedraw();
} }
for (auto &item : mItemRenderer) { for (const auto &item : mItemRenderer) {
item->ResetNeedsRedraw(); item->ResetNeedsRedraw();
} }
} }
@ -196,20 +196,20 @@ void CategoryRenderer::RenderStateMain() const {
DrawUtils::beginDraw(); DrawUtils::beginDraw();
RenderMainLayout(); RenderMainLayout();
std::string text(mIsRoot ? "This plugin can not be configured" : "This category is empty"); const std::string text(mIsRoot ? "This plugin can not be configured" : "This category is empty");
DrawUtils::setFontSize(24); DrawUtils::setFontSize(24);
uint32_t sz = DrawUtils::getTextWidth(text.c_str()); const uint32_t sz = DrawUtils::getTextWidth(text.c_str());
DrawUtils::print((SCREEN_WIDTH / 2) - (sz / 2), (SCREEN_HEIGHT / 2), text.c_str()); DrawUtils::print((SCREEN_WIDTH / 2) - (sz / 2), (SCREEN_HEIGHT / 2), text.c_str());
DrawUtils::endDraw(); DrawUtils::endDraw();
return; return;
} }
auto totalElementSize = static_cast<int>(mItemRenderer.size()); const auto totalElementSize = static_cast<int>(mItemRenderer.size());
// Calculate the range of items to display // Calculate the range of items to display
int start = std::max(0, mRenderOffset); const int start = std::max(0, mRenderOffset);
int end = std::min(start + MAX_BUTTONS_ON_SCREEN, totalElementSize); const int end = std::min(start + MAX_BUTTONS_ON_SCREEN, totalElementSize);
DrawUtils::beginDraw(); DrawUtils::beginDraw();
@ -217,7 +217,7 @@ void CategoryRenderer::RenderStateMain() const {
uint32_t yOffset = 8 + 24 + 8 + 4; uint32_t yOffset = 8 + 24 + 8 + 4;
for (int32_t i = start; i < end; i++) { for (int32_t i = start; i < end; i++) {
bool isHighlighted = (i == mCursorPos); const bool isHighlighted = (i == mCursorPos);
mItemRenderer[i]->Draw(yOffset, isHighlighted); mItemRenderer[i]->Draw(yOffset, isHighlighted);
yOffset += 42 + 8; yOffset += 42 + 8;
} }
@ -253,6 +253,6 @@ void CategoryRenderer::RenderMainLayout() const {
// draw home button // draw home button
DrawUtils::setFontSize(18); DrawUtils::setFontSize(18);
const char *exitHint = "\ue001 Back"; const auto exitHint = "\ue001 Back";
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHint) / 2, SCREEN_HEIGHT - 10, exitHint, true); DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHint) / 2, SCREEN_HEIGHT - 10, exitHint, true);
} }

View File

@ -1,12 +1,14 @@
#pragma once #pragma once
#include "../DrawUtils.h"
#include "ConfigRendererItem.h" #include "ConfigDefines.h"
#include "ConfigRendererItemCategory.h" #include "ConfigDisplayItem.h"
#include "ConfigRendererItemGeneric.h" #include "ConfigRendererItemGeneric.h"
#include "ConfigUtils.h"
#include "config/WUPSConfigCategory.h" #include "config/WUPSConfigCategory.h"
#include "utils/input/Input.h" #include "utils/input/Input.h"
#include <cstdint>
#include <memory> #include <memory>
#include <vector>
class CategoryRenderer { class CategoryRenderer {
@ -24,7 +26,7 @@ public:
void ResetNeedsRedraw(); void ResetNeedsRedraw();
private: private:
ConfigSubState UpdateStateMain(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData); ConfigSubState UpdateStateMain(const Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData);
void RenderStateMain() const; void RenderStateMain() const;

View File

@ -2,7 +2,6 @@
#include <cstdint> #include <cstdint>
#include <gx2/surface.h> #include <gx2/surface.h>
#include <string>
#define COLOR_BACKGROUND Color(238, 238, 238, 255) #define COLOR_BACKGROUND Color(238, 238, 238, 255)
#define COLOR_TEXT Color(51, 51, 51, 255) #define COLOR_TEXT Color(51, 51, 51, 255)
@ -23,7 +22,6 @@ struct StoredBuffer {
GX2BufferingMode buffering_mode; GX2BufferingMode buffering_mode;
}; };
enum ConfigSubState { enum ConfigSubState {
SUB_STATE_RUNNING = 0, SUB_STATE_RUNNING = 0,
SUB_STATE_RETURN = 1, SUB_STATE_RETURN = 1,

View File

@ -0,0 +1,12 @@
#include "ConfigDisplayItem.h"
#include "config/WUPSConfig.h"
ConfigDisplayItem::ConfigDisplayItem(GeneralConfigInformation &info, std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> config) : mConfig(std::move(config)), mInfo(std::move(info)) {
assert(mConfig);
}
const GeneralConfigInformation &ConfigDisplayItem::getConfigInformation() const {
return mInfo;
}
const WUPSConfigAPIBackend::WUPSConfig &ConfigDisplayItem::getConfig() const {
return *mConfig;
}

View File

@ -1,6 +1,8 @@
#pragma once #pragma once
#include "config/WUPSConfig.h" #include "config/WUPSConfig.h"
#include <memory> #include <memory>
#include <string>
struct GeneralConfigInformation { struct GeneralConfigInformation {
std::string name; std::string name;
@ -10,15 +12,11 @@ struct GeneralConfigInformation {
class ConfigDisplayItem { class ConfigDisplayItem {
public: public:
ConfigDisplayItem(GeneralConfigInformation &info, std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> config) : mConfig(std::move(config)), mInfo(std::move(info)) { ConfigDisplayItem(GeneralConfigInformation &info, std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> config);
assert(mConfig);
} [[nodiscard]] const GeneralConfigInformation &getConfigInformation() const;
[[nodiscard]] const GeneralConfigInformation &getConfigInformation() const {
return mInfo; [[nodiscard]] const WUPSConfigAPIBackend::WUPSConfig &getConfig() const;
}
[[nodiscard]] const WUPSConfigAPIBackend::WUPSConfig &getConfig() const {
return *mConfig;
}
private: private:
std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> mConfig; std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> mConfig;

View File

@ -1,67 +1,67 @@
#include "ConfigRenderer.h" #include "ConfigRenderer.h"
#include "globals.h"
#include "utils/DrawUtils.h"
#include "utils/logger.h"
#include "utils/utils.h"
void ConfigRenderer::RenderStateMain() const { ConfigRenderer::ConfigRenderer(std::vector<ConfigDisplayItem> &&vec) : mConfigs(std::move(vec)) {
auto totalElementSize = (int32_t) mConfigs.size();
// Calculate the range of items to display
int start = std::max(0, mRenderOffset);
int end = std::min(start + MAX_BUTTONS_ON_SCREEN, totalElementSize);
DrawUtils::beginDraw();
DrawUtils::clear(COLOR_BACKGROUND);
uint32_t yOffset = 8 + 24 + 8 + 4;
for (int32_t i = start; i < end; i++) {
drawConfigEntry(yOffset, mConfigs[i].getConfigInformation(), i == mCursorPos);
yOffset += 42 + 8;
} }
DrawUtils::setFontColor(COLOR_TEXT); ConfigRenderer::~ConfigRenderer() = default;
// draw top bar ConfigSubState ConfigRenderer::Update(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData) {
DrawUtils::setFontSize(24); switch (mState) {
DrawUtils::print(16, 6 + 24, "Wii U Plugin System Config Menu"); case STATE_MAIN:
DrawUtils::setFontSize(18); return UpdateStateMain(input);
DrawUtils::print(SCREEN_WIDTH - 16, 8 + 24, VERSION_FULL, true); case STATE_SUB: {
DrawUtils::drawRectFilled(8, 8 + 24 + 4, SCREEN_WIDTH - 8 * 2, 3, COLOR_BLACK); if (mCategoryRenderer) {
if (const auto subResult = mCategoryRenderer->Update(input, simpleInputData, complexInputData); subResult != SUB_STATE_RUNNING) {
// draw bottom bar mNeedRedraw = true;
DrawUtils::drawRectFilled(8, SCREEN_HEIGHT - 24 - 8 - 4, SCREEN_WIDTH - 8 * 2, 3, COLOR_BLACK); mState = STATE_MAIN;
DrawUtils::setFontSize(18); return SUB_STATE_RUNNING;
DrawUtils::print(16, SCREEN_HEIGHT - 10, "\ue07d/\ue07e Navigate ");
DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, "\ue000 Select", true);
// draw scroll indicator
DrawUtils::setFontSize(24);
if (end < totalElementSize) {
DrawUtils::print(SCREEN_WIDTH / 2 + 12, SCREEN_HEIGHT - 32, "\ufe3e", true);
} }
if (start > 0) { return SUB_STATE_RUNNING;
DrawUtils::print(SCREEN_WIDTH / 2 + 12, 32 + 20, "\ufe3d", true);
}
// draw home button
DrawUtils::setFontSize(18);
const char *exitHint = "\ue044 Exit";
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHint) / 2, SCREEN_HEIGHT - 10, exitHint, true);
DrawUtils::endDraw();
}
void ConfigRenderer::drawConfigEntry(uint32_t yOffset, const GeneralConfigInformation &configInformation, bool isHighlighted) const {
DrawUtils::setFontColor(COLOR_TEXT);
if (isHighlighted) {
DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 4, COLOR_BORDER_HIGHLIGHTED);
} else { } else {
DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 2, COLOR_BORDER); DEBUG_FUNCTION_LINE_WARN("State is RENDERER_STATE_CAT but mCategoryRenderer is null. Resetting state.");
mState = STATE_MAIN;
mCursorPos = 0;
}
}
}
return SUB_STATE_ERROR;
} }
DrawUtils::setFontSize(24); void ConfigRenderer::Render() const {
DrawUtils::print(16 * 2, yOffset + 8 + 24, configInformation.name.c_str()); switch (mState) {
uint32_t sz = DrawUtils::getTextWidth(configInformation.name.c_str()); case STATE_MAIN:
DrawUtils::setFontSize(12); RenderStateMain();
DrawUtils::print(16 * 2 + sz + 4, yOffset + 8 + 24, configInformation.author.c_str()); break;
DrawUtils::print(SCREEN_WIDTH - 16 * 2, yOffset + 8 + 24, configInformation.version.c_str(), true); case STATE_SUB: {
if (mCategoryRenderer) {
mCategoryRenderer->Render();
} else {
DEBUG_FUNCTION_LINE_WARN("render failed: state was RENDERER_STATE_CAT but mCategoryRenderer is NULL");
}
break;
}
}
}
bool ConfigRenderer::NeedsRedraw() const {
if (mNeedRedraw) {
return true;
}
if (mCategoryRenderer) {
return mCategoryRenderer->NeedsRedraw();
}
return false;
}
void ConfigRenderer::ResetNeedsRedraw() {
mNeedRedraw = false;
if (mCategoryRenderer) {
mCategoryRenderer->ResetNeedsRedraw();
}
} }
ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) { ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) {
@ -69,9 +69,9 @@ ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) {
mNeedRedraw = true; mNeedRedraw = true;
return SUB_STATE_ERROR; return SUB_STATE_ERROR;
} }
auto prevSelectedItem = mCursorPos; const auto prevSelectedItem = mCursorPos;
auto totalElementSize = (int32_t) mConfigs.size(); const auto totalElementSize = static_cast<int32_t>(mConfigs.size());
if (input.data.buttons_d & Input::eButtons::BUTTON_DOWN) { if (input.data.buttons_d & Input::eButtons::BUTTON_DOWN) {
mCursorPos++; mCursorPos++;
} else if (input.data.buttons_d & Input::eButtons::BUTTON_LEFT) { } else if (input.data.buttons_d & Input::eButtons::BUTTON_LEFT) {
@ -126,59 +126,68 @@ ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) {
return SUB_STATE_RUNNING; return SUB_STATE_RUNNING;
} }
bool ConfigRenderer::NeedsRedraw() const { void ConfigRenderer::RenderStateMain() const {
if (mNeedRedraw) { const auto totalElementSize = static_cast<int32_t>(mConfigs.size());
return true; // Calculate the range of items to display
} else if (mCategoryRenderer) { const int start = std::max(0, mRenderOffset);
return mCategoryRenderer->NeedsRedraw(); const int end = std::min(start + MAX_BUTTONS_ON_SCREEN, totalElementSize);
}
return false; DrawUtils::beginDraw();
DrawUtils::clear(COLOR_BACKGROUND);
uint32_t yOffset = 8 + 24 + 8 + 4;
for (int32_t i = start; i < end; i++) {
DrawConfigEntry(yOffset, mConfigs[i].getConfigInformation(), i == mCursorPos);
yOffset += 42 + 8;
} }
void ConfigRenderer::ResetNeedsRedraw() { DrawUtils::setFontColor(COLOR_TEXT);
mNeedRedraw = false;
if (mCategoryRenderer) { // draw top bar
mCategoryRenderer->ResetNeedsRedraw(); DrawUtils::setFontSize(24);
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);
// draw bottom bar
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/\ue07e Navigate ");
DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, "\ue000 Select", true);
// draw scroll indicator
DrawUtils::setFontSize(24);
if (end < totalElementSize) {
DrawUtils::print(SCREEN_WIDTH / 2 + 12, SCREEN_HEIGHT - 32, "\ufe3e", true);
} }
if (start > 0) {
DrawUtils::print(SCREEN_WIDTH / 2 + 12, 32 + 20, "\ufe3d", true);
} }
void ConfigRenderer::Render() const { // draw home button
switch (mState) { DrawUtils::setFontSize(18);
case STATE_MAIN: const auto exitHint = "\ue044 Exit";
RenderStateMain(); DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHint) / 2, SCREEN_HEIGHT - 10, exitHint, true);
break;
case STATE_SUB: { DrawUtils::endDraw();
if (mCategoryRenderer) { }
mCategoryRenderer->Render();
void ConfigRenderer::DrawConfigEntry(const uint32_t yOffset, const GeneralConfigInformation &configInformation, const bool isHighlighted) const {
DrawUtils::setFontColor(COLOR_TEXT);
if (isHighlighted) {
DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 4, COLOR_BORDER_HIGHLIGHTED);
} else { } else {
DEBUG_FUNCTION_LINE_WARN("render failed: state was RENDERER_STATE_CAT but mCategoryRenderer is NULL"); DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 2, COLOR_BORDER);
}
break;
}
}
} }
ConfigSubState ConfigRenderer::Update(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData) { DrawUtils::setFontSize(24);
switch (mState) { DrawUtils::print(16 * 2, yOffset + 8 + 24, configInformation.name.c_str());
case STATE_MAIN: const uint32_t sz = DrawUtils::getTextWidth(configInformation.name.c_str());
return UpdateStateMain(input); DrawUtils::setFontSize(12);
case STATE_SUB: { DrawUtils::print(16 * 2 + sz + 4, yOffset + 8 + 24, configInformation.author.c_str());
if (mCategoryRenderer) { DrawUtils::print(SCREEN_WIDTH - 16 * 2, yOffset + 8 + 24, configInformation.version.c_str(), true);
auto subResult = mCategoryRenderer->Update(input, simpleInputData, complexInputData);
if (subResult != SUB_STATE_RUNNING) {
mNeedRedraw = true;
mState = STATE_MAIN;
return SUB_STATE_RUNNING;
}
return SUB_STATE_RUNNING;
} else {
DEBUG_FUNCTION_LINE_WARN("State is RENDERER_STATE_CAT but mCategoryRenderer is null. Resetting state.");
mState = STATE_MAIN;
mCursorPos = 0;
}
}
}
return SUB_STATE_ERROR;
} }
void ConfigRenderer::CallOnCloseCallback(const GeneralConfigInformation &info, const std::vector<std::unique_ptr<WUPSConfigAPIBackend::WUPSConfigCategory>> &categories) { void ConfigRenderer::CallOnCloseCallback(const GeneralConfigInformation &info, const std::vector<std::unique_ptr<WUPSConfigAPIBackend::WUPSConfigCategory>> &categories) {

View File

@ -1,18 +1,21 @@
#pragma once #pragma once
#include "../DrawUtils.h"
#include "../input/Input.h"
#include "../logger.h"
#include "CategoryRenderer.h" #include "CategoryRenderer.h"
#include "globals.h" #include "ConfigDefines.h"
#include "ConfigDisplayItem.h"
#include "utils/input/Input.h"
#include <cstdint>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <wups/config.h>
class ConfigRenderer { class ConfigRenderer {
public: public:
explicit ConfigRenderer(std::vector<ConfigDisplayItem> &&vec) : mConfigs(std::move(vec)) { explicit ConfigRenderer(std::vector<ConfigDisplayItem> &&vec);
}
~ConfigRenderer() = default; ~ConfigRenderer();
ConfigSubState Update(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData); ConfigSubState Update(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData);
@ -27,7 +30,10 @@ private:
void RenderStateMain() const; void RenderStateMain() const;
void drawConfigEntry(uint32_t yOffset, const GeneralConfigInformation &configInformation, bool isHighlighted) const; void DrawConfigEntry(uint32_t yOffset, const GeneralConfigInformation &configInformation, bool isHighlighted) const;
void CallOnCloseCallback(const GeneralConfigInformation &info, const std::vector<std::unique_ptr<WUPSConfigAPIBackend::WUPSConfigCategory>> &categories);
void CallOnCloseCallback(const GeneralConfigInformation &info, const WUPSConfigAPIBackend::WUPSConfig &config);
enum State { enum State {
STATE_MAIN = 0, STATE_MAIN = 0,
@ -42,8 +48,6 @@ private:
int32_t mCursorPos = 0; int32_t mCursorPos = 0;
int32_t mRenderOffset = 0; int32_t mRenderOffset = 0;
int32_t mCurrentOpen = -1; int32_t mCurrentOpen = -1;
void CallOnCloseCallback(const GeneralConfigInformation &info, const std::vector<std::unique_ptr<WUPSConfigAPIBackend::WUPSConfigCategory>> &categories);
void CallOnCloseCallback(const GeneralConfigInformation &info, const WUPSConfigAPIBackend::WUPSConfig &config);
bool mNeedRedraw = true; bool mNeedRedraw = true;
}; };

View File

@ -0,0 +1,55 @@
#include "ConfigRendererItem.h"
#include "utils/DrawUtils.h"
#include <cassert>
ConfigRendererItem::ConfigRendererItem(const WUPSConfigAPIBackend::WUPSConfigItem *item) : mItem(item) {
assert(item);
}
void ConfigRendererItem::Draw(const uint32_t yOffset, const bool isHighlighted) const {
assert(mItem);
drawGenericBoxAndText(yOffset, mItem->getDisplayName(), isHighlighted);
DrawUtils::setFontSize(24);
DrawUtils::print(SCREEN_WIDTH - 16 * 2, yOffset + 8 + 24, mCurItemText.c_str(), true);
}
std::string ConfigRendererItem::GetValueToPrint(const bool isHighlighted) const {
return isHighlighted ? mItem->getCurrentValueSelectedDisplay() : mItem->getCurrentValueDisplay();
}
void ConfigRendererItem::Update(const bool isHighlighted) {
const auto newText = GetValueToPrint(isHighlighted);
if (mCurItemText != newText) {
mNeedsDraw = true;
}
mCurItemText = newText;
}
void ConfigRendererItem::ResetNeedsRedraw() {
mNeedsDraw = false;
}
[[nodiscard]] bool ConfigRendererItem::NeedsRedraw() const {
return mNeedsDraw;
}
void ConfigRendererItem::SetIsSelected(const bool isSelected) {
mItem->onSelected(isSelected);
}
void ConfigRendererItem::OnButtonPressed(const WUPSConfigButtons buttons) {
mItem->onButtonPressed(buttons);
}
[[nodiscard]] bool ConfigRendererItem::IsMovementAllowed() const {
return mItem->isMovementAllowed();
}
void ConfigRendererItem::OnInput(const WUPSConfigSimplePadData input) {
mItem->onInput(input);
}
void ConfigRendererItem::OnInputEx(const WUPSConfigComplexPadData input) {
mItem->onInputEx(input);
}

View File

@ -1,62 +1,38 @@
#pragma once #pragma once
#include "ConfigRendererItemGeneric.h" #include "ConfigRendererItemGeneric.h"
#include "config/WUPSConfigItem.h" #include "config/WUPSConfigItem.h"
class ConfigRendererItem : public ConfigRendererItemGeneric { #include <cstdint>
#include <string>
#include <wups/config.h>
class ConfigRendererItem final : public ConfigRendererItemGeneric {
public: public:
explicit ConfigRendererItem(const WUPSConfigAPIBackend::WUPSConfigItem *item) : mItem(item) { explicit ConfigRendererItem(const WUPSConfigAPIBackend::WUPSConfigItem *item);
assert(item);
}
void Draw(uint32_t yOffset, bool isHighlighted) const override { void Draw(uint32_t yOffset, bool isHighlighted) const override;
assert(mItem);
drawGenericBoxAndText(yOffset, mItem->getDisplayName(), isHighlighted);
DrawUtils::setFontSize(24);
DrawUtils::print(SCREEN_WIDTH - 16 * 2, yOffset + 8 + 24, mCurItemText.c_str(), true);
}
std::string GetValueToPrint(bool isHighlighted) { [[nodiscard]] std::string GetValueToPrint(bool isHighlighted) const;
return isHighlighted ? mItem->getCurrentValueSelectedDisplay() : mItem->getCurrentValueDisplay();
}
void Update(bool isHighlighted) override { void Update(bool isHighlighted) override;
const auto newText = GetValueToPrint(isHighlighted);
if (mCurItemText != newText) { void ResetNeedsRedraw() override;
mNeedsDraw = true;
}
mCurItemText = newText;
}
void ResetNeedsRedraw() override { [[nodiscard]] bool NeedsRedraw() const override;
mNeedsDraw = false;
}
[[nodiscard]] bool NeedsRedraw() const override { void SetIsSelected(bool isSelected) override;
return mNeedsDraw;
}
void SetIsSelected(bool isSelected) override { void OnButtonPressed(WUPSConfigButtons buttons) override;
mItem->onSelected(isSelected);
}
void OnButtonPressed(WUPSConfigButtons buttons) override { [[nodiscard]] bool IsMovementAllowed() const override;
mItem->onButtonPressed(buttons);
}
[[nodiscard]] bool IsMovementAllowed() const override { void OnInput(WUPSConfigSimplePadData input) override;
return mItem->isMovementAllowed();
}
void OnInput(WUPSConfigSimplePadData input) override { void OnInputEx(WUPSConfigComplexPadData input) override;
mItem->onInput(input);
}
void OnInputEx(WUPSConfigComplexPadData input) override {
mItem->onInputEx(input);
}
private: private:
const WUPSConfigAPIBackend::WUPSConfigItem *mItem; const WUPSConfigAPIBackend::WUPSConfigItem *mItem = nullptr;
std::string mCurItemText; std::string mCurItemText;
bool mNeedsDraw = true; bool mNeedsDraw = true;
}; };

View File

@ -1,8 +1,9 @@
#pragma once #pragma once
#include "ConfigRendererItemGeneric.h" #include "ConfigRendererItemGeneric.h"
#include "config/WUPSConfigCategory.h" #include "config/WUPSConfigCategory.h"
#include <cassert>
class ConfigRendererItemCategory : public ConfigRendererItemGeneric { class ConfigRendererItemCategory final : public ConfigRendererItemGeneric {
public: public:
explicit ConfigRendererItemCategory(const WUPSConfigAPIBackend::WUPSConfigCategory *category) : mCategory(category) { explicit ConfigRendererItemCategory(const WUPSConfigAPIBackend::WUPSConfigCategory *category) : mCategory(category) {
assert(category); assert(category);

View File

@ -0,0 +1,34 @@
#include "ConfigRendererItemGeneric.h"
#include "ConfigDefines.h"
#include "utils/DrawUtils.h"
ConfigRendererItemGeneric::~ConfigRendererItemGeneric() = default;
void ConfigRendererItemGeneric::drawGenericBoxAndText(const uint32_t yOffset, const std::string &displayName, const bool isHighlighted) const {
if (isHighlighted) {
DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 4, COLOR_BORDER_HIGHLIGHTED);
} else {
DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 2, COLOR_BORDER);
}
DrawUtils::setFontSize(24);
DrawUtils::setFontColor(COLOR_TEXT);
DrawUtils::print(16 * 2, yOffset + 8 + 24, displayName.c_str());
}
void ConfigRendererItemGeneric::SetIsSelected(bool) {
}
void ConfigRendererItemGeneric::OnButtonPressed(WUPSConfigButtons) {
}
void ConfigRendererItemGeneric::OnInput(WUPSConfigSimplePadData) {
}
void ConfigRendererItemGeneric::OnInputEx(WUPSConfigComplexPadData) {
}
bool ConfigRendererItemGeneric::IsMovementAllowed() const {
return true;
}

View File

@ -1,22 +1,14 @@
#pragma once #pragma once
#include "../DrawUtils.h"
#include "ConfigDefines.h" #include <cstdint>
#include <string>
#include <wups/config.h> #include <wups/config.h>
class ConfigRendererItemGeneric { class ConfigRendererItemGeneric {
public: public:
virtual ~ConfigRendererItemGeneric() = default; virtual ~ConfigRendererItemGeneric();
virtual void drawGenericBoxAndText(uint32_t yOffset, const std::string &displayName, bool isHighlighted) const {
if (isHighlighted) {
DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 4, COLOR_BORDER_HIGHLIGHTED);
} else {
DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 2, COLOR_BORDER);
}
DrawUtils::setFontSize(24); virtual void drawGenericBoxAndText(uint32_t yOffset, const std::string &displayName, bool isHighlighted) const;
DrawUtils::setFontColor(COLOR_TEXT);
DrawUtils::print(16 * 2, yOffset + 8 + 24, displayName.c_str());
}
virtual void Draw(uint32_t yOffset, bool isHighlighted) const = 0; virtual void Draw(uint32_t yOffset, bool isHighlighted) const = 0;
@ -26,17 +18,13 @@ public:
virtual void ResetNeedsRedraw() = 0; virtual void ResetNeedsRedraw() = 0;
virtual void SetIsSelected(bool) { virtual void SetIsSelected(bool);
}
virtual void OnButtonPressed(WUPSConfigButtons) { virtual void OnButtonPressed(WUPSConfigButtons);
}
virtual void OnInput(WUPSConfigSimplePadData) {
}
virtual void OnInputEx(WUPSConfigComplexPadData) {
}
[[nodiscard]] virtual bool IsMovementAllowed() const { virtual void OnInput(WUPSConfigSimplePadData);
return true;
} virtual void OnInputEx(WUPSConfigComplexPadData);
[[nodiscard]] virtual bool IsMovementAllowed() const;
}; };

View File

@ -1,24 +1,25 @@
#include "ConfigUtils.h" #include "ConfigUtils.h"
#include "../../globals.h"
#include "../DrawUtils.h"
#include "../dc.h"
#include "../logger.h"
#include "ConfigRenderer.h" #include "ConfigRenderer.h"
#include "config/WUPSConfigAPI.h" #include "config/WUPSConfigAPI.h"
#include "hooks.h" #include "hooks.h"
#include "utils/DrawUtils.h"
#include "utils/dc.h"
#include "utils/input/CombinedInput.h" #include "utils/input/CombinedInput.h"
#include "utils/input/Input.h"
#include "utils/input/VPADInput.h" #include "utils/input/VPADInput.h"
#include "utils/input/WPADInput.h" #include "utils/input/WPADInput.h"
#include "utils/logger.h"
#include "utils/utils.h"
#include "version.h"
#include <avm/tv.h> #include <algorithm>
#include <coreinit/screen.h> #include <globals.h>
#include <gx2/display.h>
#include <memory/mappedmemory.h> #include <memory/mappedmemory.h>
#include <ranges> #include <memory>
#include <string>
#include <vector> #include <vector>
#include <wups/config.h>
WUPS_CONFIG_SIMPLE_INPUT ConfigUtils::convertInputs(uint32_t buttons) { WUPS_CONFIG_SIMPLE_INPUT ConfigUtils::convertInputs(const uint32_t buttons) {
WUPSConfigButtons pressedButtons = WUPS_CONFIG_BUTTON_NONE; WUPSConfigButtons pressedButtons = WUPS_CONFIG_BUTTON_NONE;
if (buttons & Input::eButtons::BUTTON_A) { if (buttons & Input::eButtons::BUTTON_A) {
pressedButtons |= WUPS_CONFIG_BUTTON_A; pressedButtons |= WUPS_CONFIG_BUTTON_A;
@ -68,7 +69,7 @@ WUPS_CONFIG_SIMPLE_INPUT ConfigUtils::convertInputs(uint32_t buttons) {
if (buttons & Input::eButtons::BUTTON_DOWN) { if (buttons & Input::eButtons::BUTTON_DOWN) {
pressedButtons |= WUPS_CONFIG_BUTTON_DOWN; pressedButtons |= WUPS_CONFIG_BUTTON_DOWN;
} }
return (WUPS_CONFIG_SIMPLE_INPUT) pressedButtons; return static_cast<WUPS_CONFIG_SIMPLE_INPUT>(pressedButtons);
} }
void ConfigUtils::displayMenu() { void ConfigUtils::displayMenu() {
@ -82,11 +83,9 @@ void ConfigUtils::displayMenu() {
info.version = plugin.getMetaInformation().getVersion(); info.version = plugin.getMetaInformation().getVersion();
std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> config; std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> config;
const auto configData = plugin.getConfigData(); if (const auto configData = plugin.getConfigData()) {
if (configData) { if (const auto configHandleOpt = configData->createConfig()) {
const auto configHandleOpt = configData->createConfig(); WUPSConfigAPIStatus callbackResult = configData->CallMenuOpenedCallback(configHandleOpt.value());
if (configHandleOpt) {
WUPSConfigAPIStatus callbackResult = configData->CallMenuOpenendCallback(configHandleOpt.value());
config = WUPSConfigAPIBackend::Intern::PopConfigByHandle(configHandleOpt.value()); config = WUPSConfigAPIBackend::Intern::PopConfigByHandle(configHandleOpt.value());
if (!config) { if (!config) {
DEBUG_FUNCTION_LINE_ERR("Failed to get config for handle: %08X", configHandleOpt.value().handle); DEBUG_FUNCTION_LINE_ERR("Failed to get config for handle: %08X", configHandleOpt.value().handle);
@ -106,7 +105,7 @@ void ConfigUtils::displayMenu() {
DEBUG_FUNCTION_LINE_ERR("Hook had invalid ptr"); DEBUG_FUNCTION_LINE_ERR("Hook had invalid ptr");
break; break;
} }
auto cur_config_handle = ((void *(*) ())((uint32_t *) hook.getFunctionPointer()))(); auto cur_config_handle = reinterpret_cast<void *(*) ()>(static_cast<uint32_t *>(hook.getFunctionPointer()))();
if (cur_config_handle == nullptr) { if (cur_config_handle == nullptr) {
DEBUG_FUNCTION_LINE_WARN("Hook returned empty handle"); DEBUG_FUNCTION_LINE_WARN("Hook returned empty handle");
break; break;
@ -127,15 +126,11 @@ void ConfigUtils::displayMenu() {
} }
// Sort Configs by name // Sort Configs by name
std::sort( std::ranges::sort(configs,
configs.begin(),
configs.end(),
[](const ConfigDisplayItem &lhs, const ConfigDisplayItem &rhs) { [](const ConfigDisplayItem &lhs, const ConfigDisplayItem &rhs) {
auto &str1 = lhs.getConfigInformation().name; auto &str1 = lhs.getConfigInformation().name;
auto &str2 = rhs.getConfigInformation().name; auto &str2 = rhs.getConfigInformation().name;
return lexicographical_compare( return std::ranges::lexicographical_compare(str1, str2,
begin(str1), end(str1),
begin(str2), end(str2),
[](const char &char1, const char &char2) { [](const char &char1, const char &char2) {
return tolower(char1) < tolower(char2); return tolower(char1) < tolower(char2);
}); });
@ -156,7 +151,7 @@ void ConfigUtils::displayMenu() {
WPAD_CHAN_6, WPAD_CHAN_6,
}; };
auto startTime = OSGetTime(); OSTime startTime;
bool skipFirstInput = true; bool skipFirstInput = true;
gOnlyAcceptFromThread = OSGetCurrentThread(); gOnlyAcceptFromThread = OSGetCurrentThread();
@ -239,23 +234,23 @@ void ConfigUtils::displayMenu() {
void ConfigUtils::openConfigMenu() { void ConfigUtils::openConfigMenu() {
gOnlyAcceptFromThread = OSGetCurrentThread(); gOnlyAcceptFromThread = OSGetCurrentThread();
bool wasHomeButtonMenuEnabled = OSIsHomeButtonMenuEnabled(); const bool wasHomeButtonMenuEnabled = OSIsHomeButtonMenuEnabled();
// Save copy of DC reg values // Save copy of DC reg values
auto tvRender1 = DCReadReg32(SCREEN_TV, D1GRPH_CONTROL_REG); const auto tvRender1 = DCReadReg32(SCREEN_TV, D1GRPH_CONTROL_REG);
auto tvRender2 = DCReadReg32(SCREEN_TV, D1GRPH_ENABLE_REG); const auto tvRender2 = DCReadReg32(SCREEN_TV, D1GRPH_ENABLE_REG);
auto tvPitch1 = DCReadReg32(SCREEN_TV, D1GRPH_PITCH_REG); const auto tvPitch1 = DCReadReg32(SCREEN_TV, D1GRPH_PITCH_REG);
auto tvPitch2 = DCReadReg32(SCREEN_TV, D1OVL_PITCH_REG); const auto tvPitch2 = DCReadReg32(SCREEN_TV, D1OVL_PITCH_REG);
auto drcRender1 = DCReadReg32(SCREEN_DRC, D1GRPH_CONTROL_REG); const auto drcRender1 = DCReadReg32(SCREEN_DRC, D1GRPH_CONTROL_REG);
auto drcRender2 = DCReadReg32(SCREEN_DRC, D1GRPH_ENABLE_REG); const auto drcRender2 = DCReadReg32(SCREEN_DRC, D1GRPH_ENABLE_REG);
auto drcPitch1 = DCReadReg32(SCREEN_DRC, D1GRPH_PITCH_REG); const auto drcPitch1 = DCReadReg32(SCREEN_DRC, D1GRPH_PITCH_REG);
auto drcPitch2 = DCReadReg32(SCREEN_DRC, D1OVL_PITCH_REG); const auto drcPitch2 = DCReadReg32(SCREEN_DRC, D1OVL_PITCH_REG);
OSScreenInit(); OSScreenInit();
uint32_t screen_buf0_size = OSScreenGetBufferSizeEx(SCREEN_TV); const uint32_t screen_buf0_size = OSScreenGetBufferSizeEx(SCREEN_TV);
uint32_t screen_buf1_size = OSScreenGetBufferSizeEx(SCREEN_DRC); const uint32_t screen_buf1_size = OSScreenGetBufferSizeEx(SCREEN_DRC);
void *screenbuffer0 = MEMAllocFromMappedMemoryForGX2Ex(screen_buf0_size, 0x100); void *screenbuffer0 = MEMAllocFromMappedMemoryForGX2Ex(screen_buf0_size, 0x100);
void *screenbuffer1 = MEMAllocFromMappedMemoryForGX2Ex(screen_buf1_size, 0x100); void *screenbuffer1 = MEMAllocFromMappedMemoryForGX2Ex(screen_buf1_size, 0x100);
@ -363,7 +358,7 @@ void ConfigUtils::renderBasicScreen(std::string_view text) {
DrawUtils::setFontSize(24); DrawUtils::setFontSize(24);
DrawUtils::print(16, 6 + 24, "Wii U Plugin System Config Menu"); DrawUtils::print(16, 6 + 24, "Wii U Plugin System Config Menu");
DrawUtils::setFontSize(18); DrawUtils::setFontSize(18);
DrawUtils::print(SCREEN_WIDTH - 16, 8 + 24, VERSION_FULL, true); DrawUtils::print(SCREEN_WIDTH - 16, 8 + 24, MODULE_VERSION_FULL, true);
DrawUtils::drawRectFilled(8, 8 + 24 + 4, SCREEN_WIDTH - 8 * 2, 3, COLOR_BLACK); DrawUtils::drawRectFilled(8, 8 + 24 + 4, SCREEN_WIDTH - 8 * 2, 3, COLOR_BLACK);
// draw bottom bar // draw bottom bar
@ -373,13 +368,13 @@ void ConfigUtils::renderBasicScreen(std::string_view text) {
DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, "\ue000 Select", true); DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, "\ue000 Select", true);
DrawUtils::setFontSize(24); DrawUtils::setFontSize(24);
uint32_t sz = DrawUtils::getTextWidth(text.data()); const uint32_t sz = DrawUtils::getTextWidth(text.data());
DrawUtils::print((SCREEN_WIDTH / 2) - (sz / 2), (SCREEN_HEIGHT / 2), text.data()); DrawUtils::print((SCREEN_WIDTH / 2) - (sz / 2), (SCREEN_HEIGHT / 2), text.data());
// draw home button // draw home button
DrawUtils::setFontSize(18); DrawUtils::setFontSize(18);
const char *exitHint = "\ue044 Exit"; const auto exitHint = "\ue044 Exit";
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHint) / 2, SCREEN_HEIGHT - 10, exitHint, true); DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHint) / 2, SCREEN_HEIGHT - 10, exitHint, true);
DrawUtils::endDraw(); DrawUtils::endDraw();

View File

@ -1,13 +1,8 @@
#pragma once #pragma once
#include "ConfigDefines.h" #include <cstdint>
#include "ConfigDisplayItem.h" #include <string_view>
#include "config/WUPSConfig.h" #include <wups/config.h>
#include "utils/input/Input.h"
#include <gx2/enum.h>
#include <memory>
#include <string>
#define MOVE_ITEM_INPUT_MASK (WUPS_CONFIG_BUTTON_B | WUPS_CONFIG_BUTTON_DOWN | WUPS_CONFIG_BUTTON_UP) #define MOVE_ITEM_INPUT_MASK (WUPS_CONFIG_BUTTON_B | WUPS_CONFIG_BUTTON_DOWN | WUPS_CONFIG_BUTTON_UP)

View File

@ -5,20 +5,20 @@
extern "C" uint32_t __OSPhysicalToEffectiveUncached(uint32_t); extern "C" uint32_t __OSPhysicalToEffectiveUncached(uint32_t);
static inline uint32_t DCReadReg32(OSScreenID screen, uint32_t index) { static uint32_t DCReadReg32(const OSScreenID screen, const uint32_t index) {
if (OSIsECOMode()) { if (OSIsECOMode()) {
return 0; return 0;
} }
auto regs = (uint32_t *) __OSPhysicalToEffectiveUncached(0xc200000); const auto regs = reinterpret_cast<uint32_t *>(__OSPhysicalToEffectiveUncached(0xc200000));
return regs[index + (screen * 0x200)]; return regs[index + (screen * 0x200)];
} }
static inline void DCWriteReg32(OSScreenID screen, uint32_t index, uint32_t val) { static void DCWriteReg32(const OSScreenID screen, const uint32_t index, const uint32_t val) {
if (OSIsECOMode()) { if (OSIsECOMode()) {
return; return;
} }
auto regs = (uint32_t *) __OSPhysicalToEffectiveUncached(0xc200000); const auto regs = reinterpret_cast<uint32_t *>(__OSPhysicalToEffectiveUncached(0xc200000));
regs[index + (screen * 0x200)] = val; regs[index + (screen * 0x200)] = val;
} }
@ -30,7 +30,7 @@ static inline void DCWriteReg32(OSScreenID screen, uint32_t index, uint32_t val)
#define D1GRPH_X_END_REG 0x184d #define D1GRPH_X_END_REG 0x184d
#define D1GRPH_Y_END_REG 0x184e #define D1GRPH_Y_END_REG 0x184e
static inline void SetDCPitchReg(OSScreenID screen, uint16_t pitch) { static void SetDCPitchReg(const OSScreenID screen, const uint16_t pitch) {
DCWriteReg32(screen, D1GRPH_PITCH_REG, pitch); DCWriteReg32(screen, D1GRPH_PITCH_REG, pitch);
DCWriteReg32(screen, D1OVL_PITCH_REG, pitch); DCWriteReg32(screen, D1OVL_PITCH_REG, pitch);
} }

View File

@ -1,8 +1,13 @@
#include "../PluginManagement.h" #include "globals.h"
#include "../globals.h" #include "logger.h"
#include "../plugin/PluginDataFactory.h" #include "plugin/PluginContainer.h"
#include "../plugin/PluginMetaInformationFactory.h" #include "plugin/PluginData.h"
#include "plugin/PluginDataFactory.h"
#include "plugin/PluginMetaInformation.h"
#include "plugin/PluginMetaInformationFactory.h"
#include "utils.h" #include "utils.h"
#include <ranges>
#include <wums.h> #include <wums.h>
#include <wups_backend/import_defines.h> #include <wups_backend/import_defines.h>
@ -23,9 +28,9 @@ extern "C" PluginBackendApiErrorType WUPSLoadAndLinkByDataHandle(const wups_back
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG; return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
} }
std::lock_guard<std::mutex> lock(gLoadedDataMutex); std::lock_guard lock(gLoadedDataMutex);
for (uint32_t i = 0; i < plugin_data_handle_list_size; i++) { for (uint32_t i = 0; i < plugin_data_handle_list_size; i++) {
auto handle = plugin_data_handle_list[i]; const auto handle = plugin_data_handle_list[i];
bool found = false; bool found = false;
for (const auto &pluginData : gLoadedData) { for (const auto &pluginData : gLoadedData) {
@ -65,7 +70,7 @@ extern "C" PluginBackendApiErrorType WUPSLoadPluginAsData(WUPSBackendGetPluginIn
if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) { if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) {
pluginData = PluginDataFactory::load(path); pluginData = PluginDataFactory::load(path);
} else if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_BUFFER && buffer != nullptr && size > 0) { } else if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_BUFFER && buffer != nullptr && size > 0) {
pluginData = make_unique_nothrow<PluginData>(std::span((uint8_t *) buffer, size), "<UNKNOWN>"); pluginData = make_unique_nothrow<PluginData>(std::span(reinterpret_cast<uint8_t *>(buffer), size), "<UNKNOWN>");
} else { } else {
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG; return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
} }
@ -103,7 +108,7 @@ extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformationEx(WUPSBackendG
if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) { if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) {
pluginInfo = PluginMetaInformationFactory::loadPlugin(path, error); pluginInfo = PluginMetaInformationFactory::loadPlugin(path, error);
} else if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_BUFFER && buffer != nullptr && size > 0) { } else if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_BUFFER && buffer != nullptr && size > 0) {
pluginInfo = PluginMetaInformationFactory::loadPlugin(std::span<uint8_t const>((uint8_t *) buffer, size), error); pluginInfo = PluginMetaInformationFactory::loadPlugin(std::span<uint8_t const>(reinterpret_cast<uint8_t *>(buffer), size), error);
} else { } else {
if (errOut) { if (errOut) {
*errOut = PLUGIN_BACKEND_PLUGIN_PARSE_ERROR_UNKNOWN; *errOut = PLUGIN_BACKEND_PLUGIN_PARSE_ERROR_UNKNOWN;
@ -153,19 +158,18 @@ extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformationByBuffer(wups_b
} }
extern "C" PluginBackendApiErrorType WUPSGetPluginDataForContainerHandles(const wups_backend_plugin_container_handle *plugin_container_handle_list, wups_backend_plugin_data_handle *plugin_data_list, uint32_t buffer_size) { extern "C" PluginBackendApiErrorType WUPSGetPluginDataForContainerHandles(const wups_backend_plugin_container_handle *plugin_container_handle_list, wups_backend_plugin_data_handle *plugin_data_list, uint32_t buffer_size) {
PluginBackendApiErrorType res = PLUGIN_BACKEND_API_ERROR_NONE;
if (plugin_container_handle_list == nullptr || buffer_size == 0) { if (plugin_container_handle_list == nullptr || buffer_size == 0) {
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG; return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
} }
std::lock_guard<std::mutex> lock(gLoadedDataMutex); std::lock_guard lock(gLoadedDataMutex);
for (uint32_t i = 0; i < buffer_size; i++) { for (uint32_t i = 0; i < buffer_size; i++) {
auto handle = plugin_container_handle_list[i]; const auto handle = plugin_container_handle_list[i];
bool found = false; bool found = false;
for (const auto &curContainer : gLoadedPlugins) { for (const auto &curContainer : gLoadedPlugins) {
if (curContainer.getHandle() == handle) { if (curContainer.getHandle() == handle) {
auto pluginData = curContainer.getPluginDataCopy(); auto pluginData = curContainer.getPluginDataCopy();
plugin_data_list[i] = (uint32_t) pluginData->getHandle(); plugin_data_list[i] = pluginData->getHandle();
gLoadedData.insert(std::move(pluginData)); gLoadedData.insert(std::move(pluginData));
found = true; found = true;
break; break;
@ -177,7 +181,7 @@ extern "C" PluginBackendApiErrorType WUPSGetPluginDataForContainerHandles(const
} }
} }
return res; return PLUGIN_BACKEND_API_ERROR_NONE;
} }
extern "C" PluginBackendApiErrorType WUPSGetMetaInformation(const wups_backend_plugin_container_handle *plugin_container_handle_list, wups_backend_plugin_information *plugin_information_list, uint32_t buffer_size) { extern "C" PluginBackendApiErrorType WUPSGetMetaInformation(const wups_backend_plugin_container_handle *plugin_container_handle_list, wups_backend_plugin_information *plugin_information_list, uint32_t buffer_size) {
@ -264,7 +268,7 @@ extern "C" PluginBackendApiErrorType WUPSGetNumberOfLoadedPlugins(uint32_t *outC
return PLUGIN_BACKEND_API_ERROR_NONE; return PLUGIN_BACKEND_API_ERROR_NONE;
} }
extern "C" PluginBackendApiErrorType WUPSGetSectionInformationForPlugin(const wups_backend_plugin_container_handle handle, wups_backend_plugin_section_info *plugin_section_list, uint32_t buffer_size, uint32_t *out_count) { extern "C" PluginBackendApiErrorType WUPSGetSectionInformationForPlugin(const wups_backend_plugin_container_handle handle, wups_backend_plugin_section_info *plugin_section_list, const uint32_t buffer_size, uint32_t *out_count) {
PluginBackendApiErrorType res = PLUGIN_BACKEND_API_ERROR_NONE; PluginBackendApiErrorType res = PLUGIN_BACKEND_API_ERROR_NONE;
if (out_count != nullptr) { if (out_count != nullptr) {
*out_count = 0; *out_count = 0;
@ -277,13 +281,13 @@ extern "C" PluginBackendApiErrorType WUPSGetSectionInformationForPlugin(const wu
const auto &sectionInfoList = curContainer.getPluginInformation().getSectionInfoList(); const auto &sectionInfoList = curContainer.getPluginInformation().getSectionInfoList();
uint32_t offset = 0; uint32_t offset = 0;
for (auto const &[key, sectionInfo] : sectionInfoList) { for (auto const &sectionInfo : sectionInfoList | std::views::values) {
if (offset >= buffer_size) { if (offset >= buffer_size) {
break; break;
} }
plugin_section_list[offset].plugin_section_info_version = WUPS_BACKEND_PLUGIN_SECTION_INFORMATION_VERSION; plugin_section_list[offset].plugin_section_info_version = WUPS_BACKEND_PLUGIN_SECTION_INFORMATION_VERSION;
strncpy(plugin_section_list[offset].name, sectionInfo.getName().c_str(), sizeof(plugin_section_list[offset].name) - 1); strncpy(plugin_section_list[offset].name, sectionInfo.getName().c_str(), sizeof(plugin_section_list[offset].name) - 1);
plugin_section_list[offset].address = (void *) sectionInfo.getAddress(); plugin_section_list[offset].address = reinterpret_cast<void *>(sectionInfo.getAddress());
plugin_section_list[offset].size = sectionInfo.getSize(); plugin_section_list[offset].size = sectionInfo.getSize();
offset++; offset++;
} }
@ -306,19 +310,19 @@ extern "C" PluginBackendApiErrorType WUPSWillReloadPluginsOnNextLaunch(bool *out
if (out == nullptr) { if (out == nullptr) {
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG; return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
} }
std::lock_guard<std::mutex> lock(gLoadedDataMutex); std::lock_guard lock(gLoadedDataMutex);
*out = !gLoadOnNextLaunch.empty(); *out = !gLoadOnNextLaunch.empty();
return PLUGIN_BACKEND_API_ERROR_NONE; return PLUGIN_BACKEND_API_ERROR_NONE;
} }
extern "C" PluginBackendApiErrorType WUPSGetSectionMemoryAddresses(wups_backend_plugin_container_handle handle, void **textAddress, void **dataAddress) { extern "C" PluginBackendApiErrorType WUPSGetSectionMemoryAddresses(const wups_backend_plugin_container_handle handle, void **textAddress, void **dataAddress) {
if (handle == 0 || textAddress == nullptr || dataAddress == nullptr) { if (handle == 0 || textAddress == nullptr || dataAddress == nullptr) {
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG; return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
} }
for (const auto &curContainer : gLoadedPlugins) { for (const auto &curContainer : gLoadedPlugins) {
if (curContainer.getHandle() == handle) { if (curContainer.getHandle() == handle) {
*textAddress = (void *) curContainer.getPluginInformation().getTextMemory().data(); *textAddress = const_cast<void *>(curContainer.getPluginInformation().getTextMemory().data());
*dataAddress = (void *) curContainer.getPluginInformation().getDataMemory().data(); *dataAddress = const_cast<void *>(curContainer.getPluginInformation().getDataMemory().data());
return PLUGIN_BACKEND_API_ERROR_NONE; return PLUGIN_BACKEND_API_ERROR_NONE;
} }
} }
@ -336,7 +340,7 @@ extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformationByPathEx(wups_b
return WUPSGetPluginMetaInformationEx(PLUGIN_INFORMATION_INPUT_TYPE_PATH, path, nullptr, 0, output, err); return WUPSGetPluginMetaInformationEx(PLUGIN_INFORMATION_INPUT_TYPE_PATH, path, nullptr, 0, output, err);
} }
extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformationByBufferEx(wups_backend_plugin_information *output, char *buffer, size_t size, PluginBackendPluginParseError *err) { extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformationByBufferEx(wups_backend_plugin_information *output, char *buffer, const size_t size, PluginBackendPluginParseError *err) {
return WUPSGetPluginMetaInformationEx(PLUGIN_INFORMATION_INPUT_TYPE_BUFFER, nullptr, buffer, size, output, err); return WUPSGetPluginMetaInformationEx(PLUGIN_INFORMATION_INPUT_TYPE_BUFFER, nullptr, buffer, size, output, err);
} }

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "Input.h" #include "Input.h"
class CombinedInput : public Input { class CombinedInput final : public Input {
public: public:
void combine(const Input &b) { void combine(const Input &b) {
data.buttons_d |= b.data.buttons_d; data.buttons_d |= b.data.buttons_d;

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <cstring>
class Input { class Input {
public: public:
@ -11,7 +10,7 @@ public:
//!Destructor //!Destructor
virtual ~Input() = default; virtual ~Input() = default;
enum eButtons { enum eButtons : uint32_t {
BUTTON_NONE = 0x0000, BUTTON_NONE = 0x0000,
VPAD_TOUCH = 0x80000000, VPAD_TOUCH = 0x80000000,
BUTTON_STICK_L = 0x80000, BUTTON_STICK_L = 0x80000,

View File

@ -19,7 +19,7 @@
#include "Input.h" #include "Input.h"
#include <vpad/input.h> #include <vpad/input.h>
class VPadInput : public Input { class VPadInput final : public Input {
public: public:
//!Constructor //!Constructor
VPadInput() = default; VPadInput() = default;
@ -27,7 +27,7 @@ public:
//!Destructor //!Destructor
~VPadInput() override = default; ~VPadInput() override = default;
bool update(int32_t width, int32_t height) { bool update(const int32_t width, const int32_t height) {
lastData = data; lastData = data;
data = {}; data = {};

View File

@ -20,15 +20,15 @@
#include <padscore/kpad.h> #include <padscore/kpad.h>
#include <padscore/wpad.h> #include <padscore/wpad.h>
class WPADInput : public Input { class WPADInput final : public Input {
public: public:
WPADInput(KPADChan channel) { WPADInput(const KPADChan channel) {
this->channel = channel; this->channel = channel;
} }
~WPADInput() override {} ~WPADInput() override = default;
uint32_t remapWiiMoteButtons(uint32_t buttons) { uint32_t remapWiiMoteButtons(const uint32_t buttons) {
uint32_t conv_buttons = 0; uint32_t conv_buttons = 0;
if (buttons & WPAD_BUTTON_LEFT) if (buttons & WPAD_BUTTON_LEFT)
@ -73,7 +73,7 @@ public:
return conv_buttons; return conv_buttons;
} }
uint32_t remapClassicButtons(uint32_t buttons) { uint32_t remapClassicButtons(const uint32_t buttons) {
uint32_t conv_buttons = 0; uint32_t conv_buttons = 0;
if (buttons & WPAD_CLASSIC_BUTTON_LEFT) if (buttons & WPAD_CLASSIC_BUTTON_LEFT)
@ -124,7 +124,7 @@ public:
return conv_buttons; return conv_buttons;
} }
bool update(int32_t width, int32_t height) { bool update(const int32_t width, const int32_t height) {
lastData = data; lastData = data;
kpadError = KPAD_ERROR_UNINITIALIZED; kpadError = KPAD_ERROR_UNINITIALIZED;

View File

@ -1108,11 +1108,11 @@ simple_outline(SFT_Font *font, uint_fast32_t offset, unsigned int numContours, O
goto failure; goto failure;
} }
endPts = calloc(sizeof(uint_fast16_t), numContours); endPts = calloc(numContours, sizeof(uint_fast16_t));
if (endPts == NULL) { if (endPts == NULL) {
goto failure; goto failure;
} }
flags = calloc(sizeof(uint8_t), numPts); flags = calloc(numPts, sizeof(uint8_t));
if (flags == NULL) { if (flags == NULL) {
goto failure; goto failure;
} }
@ -1433,7 +1433,7 @@ render_outline(Outline *outl, double transform[6], SFT_Image image) {
numPixels = (unsigned int) image.width * (unsigned int) image.height; numPixels = (unsigned int) image.width * (unsigned int) image.height;
cells = calloc(sizeof(Cell), numPixels); cells = calloc(numPixels, sizeof(Cell));
if (!cells) { if (!cells) {
return -1; return -1;
} }

View File

@ -1,5 +1,15 @@
#include "StorageItem.h" #include "StorageItem.h"
#include "utils/base64.h"
#include "utils/logger.h"
StorageItem::StorageItem(const std::string_view key) : mKey(key) {
}
uint32_t StorageItem::getHandle() const {
return reinterpret_cast<uint32_t>(this);
}
void StorageItem::setValue(const std::string &value) { void StorageItem::setValue(const std::string &value) {
mData = value; mData = value;
mType = StorageItemType::String; mType = StorageItemType::String;
@ -12,8 +22,8 @@ void StorageItem::setValue(bool value) {
mBinaryConversionDone = true; mBinaryConversionDone = true;
} }
void StorageItem::setValue(int32_t value) { void StorageItem::setValue(const int32_t value) {
mData = (int64_t) value; mData = static_cast<int64_t>(value);
mType = StorageItemType::S64; mType = StorageItemType::S64;
mBinaryConversionDone = true; mBinaryConversionDone = true;
} }
@ -30,14 +40,14 @@ void StorageItem::setValue(uint64_t value) {
mBinaryConversionDone = true; mBinaryConversionDone = true;
} }
void StorageItem::setValue(uint32_t value) { void StorageItem::setValue(const uint32_t value) {
mData = (uint64_t) value; mData = static_cast<uint64_t>(value);
mType = StorageItemType::U64; mType = StorageItemType::U64;
mBinaryConversionDone = true; mBinaryConversionDone = true;
} }
void StorageItem::setValue(float value) { void StorageItem::setValue(const float value) {
mData = (double) value; mData = static_cast<double>(value);
mType = StorageItemType::Double; mType = StorageItemType::Double;
mBinaryConversionDone = true; mBinaryConversionDone = true;
} }
@ -54,8 +64,8 @@ void StorageItem::setValue(const std::vector<uint8_t> &data) {
mBinaryConversionDone = true; mBinaryConversionDone = true;
} }
void StorageItem::setValue(const uint8_t *data, size_t size) { void StorageItem::setValue(const uint8_t *data, const size_t size) {
setValue(std::vector<uint8_t>(data, data + size)); setValue(std::vector(data, data + size));
} }
bool StorageItem::getValue(bool &result) const { bool StorageItem::getValue(bool &result) const {
@ -74,10 +84,10 @@ bool StorageItem::getValue(bool &result) const {
bool StorageItem::getValue(int32_t &result) const { bool StorageItem::getValue(int32_t &result) const {
if (mType == StorageItemType::S64) { if (mType == StorageItemType::S64) {
result = (int32_t) std::get<int64_t>(mData); result = static_cast<int32_t>(std::get<int64_t>(mData));
return true; return true;
} else if (mType == StorageItemType::U64) { } else if (mType == StorageItemType::U64) {
result = (int32_t) std::get<uint64_t>(mData); result = static_cast<int32_t>(std::get<uint64_t>(mData));
return true; return true;
} }
return false; return false;
@ -109,7 +119,7 @@ bool StorageItem::getValue(double &result) const {
bool StorageItem::getValue(float &result) const { bool StorageItem::getValue(float &result) const {
if (mType == StorageItemType::Double) { if (mType == StorageItemType::Double) {
result = (float) std::get<double>(mData); result = static_cast<float>(std::get<double>(mData));
return true; return true;
} }
return false; return false;
@ -120,7 +130,7 @@ bool StorageItem::getValue(uint64_t &result) const {
result = std::get<uint64_t>(mData); result = std::get<uint64_t>(mData);
return true; return true;
} else if (mType == StorageItemType::S64) { } else if (mType == StorageItemType::S64) {
result = (uint64_t) std::get<int64_t>(mData); result = static_cast<uint64_t>(std::get<int64_t>(mData));
return true; return true;
} }
return false; return false;
@ -128,10 +138,10 @@ bool StorageItem::getValue(uint64_t &result) const {
bool StorageItem::getValue(uint32_t &result) const { bool StorageItem::getValue(uint32_t &result) const {
if (mType == StorageItemType::U64) { if (mType == StorageItemType::U64) {
result = (uint32_t) std::get<uint64_t>(mData); result = static_cast<uint32_t>(std::get<uint64_t>(mData));
return true; return true;
} else if (mType == StorageItemType::S64) { } else if (mType == StorageItemType::S64) {
result = (uint32_t) std::get<int64_t>(mData); result = static_cast<uint32_t>(std::get<int64_t>(mData));
return true; return true;
} }
return false; return false;
@ -142,7 +152,7 @@ bool StorageItem::getValue(int64_t &result) const {
result = std::get<int64_t>(mData); result = std::get<int64_t>(mData);
return true; return true;
} else if (mType == StorageItemType::U64) { } else if (mType == StorageItemType::U64) {
result = (int64_t) std::get<uint64_t>(mData); result = static_cast<int64_t>(std::get<uint64_t>(mData));
return true; return true;
} }
return false; return false;
@ -169,11 +179,9 @@ bool StorageItem::attemptBinaryConversion() {
return true; return true;
} }
if (mType == StorageItemType::String) { if (mType == StorageItemType::String) {
auto &tmp = std::get<std::string>(mData); const auto &tmp = std::get<std::string>(mData);
auto dec_size = b64_decoded_size(tmp.c_str()); if (const auto dec_size = b64_decoded_size(tmp.c_str()); dec_size > 0) {
if (dec_size > 0) { if (auto *dec = static_cast<uint8_t *>(malloc(dec_size))) {
auto *dec = (uint8_t *) malloc(dec_size);
if (dec) {
if (b64_decode(tmp.c_str(), dec, dec_size)) { if (b64_decode(tmp.c_str(), dec, dec_size)) {
setValue(dec, dec_size); setValue(dec, dec_size);
} }

View File

@ -1,14 +1,10 @@
#pragma once #pragma once
#include "utils/base64.h"
#include "utils/logger.h"
#include <cstdint> #include <cstdint>
#include <memory>
#include <string> #include <string>
#include <utility>
#include <variant> #include <variant>
#include <vector> #include <vector>
enum class StorageItemType { None, enum class StorageItemType { None,
Boolean, Boolean,
String, String,
@ -19,12 +15,9 @@ enum class StorageItemType { None,
class StorageItem { class StorageItem {
public: public:
explicit StorageItem(std::string_view key) : mData(std::monostate{}), mType(StorageItemType::None), mKey(key) { explicit StorageItem(std::string_view key);
}
[[nodiscard]] uint32_t getHandle() const { [[nodiscard]] uint32_t getHandle() const;
return (uint32_t) this;
}
// Setters for different types // Setters for different types
void setValue(bool value); void setValue(bool value);

View File

@ -0,0 +1,13 @@
#include "StorageItemRoot.h"
StorageItemRoot::StorageItemRoot(const std::string_view plugin_name) : StorageSubItem(plugin_name), mPluginName(plugin_name) {
}
[[nodiscard]] const std::string &StorageItemRoot::getPluginId() const {
return mPluginName;
}
void StorageItemRoot::wipe() {
mSubCategories.clear();
mItems.clear();
}

View File

@ -1,28 +1,15 @@
#pragma once #pragma once
#include "StorageItem.h"
#include "StorageSubItem.h" #include "StorageSubItem.h"
#include "utils/logger.h"
#include <memory>
#include <optional>
#include <string> #include <string>
#include <utility>
#include <vector>
#include <wups/storage.h>
class StorageItemRoot : public StorageSubItem { class StorageItemRoot : public StorageSubItem {
public: public:
explicit StorageItemRoot(std::string_view plugin_name) : StorageSubItem(plugin_name), mPluginName(plugin_name) { explicit StorageItemRoot(std::string_view plugin_name);
}
[[nodiscard]] const std::string &getPluginId() const { [[nodiscard]] const std::string &getPluginId() const;
return mPluginName;
}
void wipe() { void wipe();
mSubCategories.clear();
mItems.clear();
}
private: private:
std::string mPluginName; std::string mPluginName;

View File

@ -1,17 +1,21 @@
#include "StorageSubItem.h" #include "StorageSubItem.h"
#include <utils/utils.h>
StorageSubItem::StorageSubItem(const std::string_view key) : StorageItem(key) {
}
StorageSubItem *StorageSubItem::getSubItem(wups_storage_item item) { StorageSubItem *StorageSubItem::getSubItem(wups_storage_item item) {
// Try to find the sub-item based on item handle. // Try to find the sub-item based on item handle.
for (auto &cur : mSubCategories) { for (auto &cur : mSubCategories) {
if (cur.getHandle() == (uint32_t) item) { if (cur.getHandle() == reinterpret_cast<uint32_t>(item)) {
return &cur; return &cur;
} }
} }
// If not found in current category, recursively search in sub-categories. // If not found in current category, recursively search in sub-categories.
for (auto &cur : mSubCategories) { for (auto &cur : mSubCategories) {
auto res = cur.getSubItem(item); if (const auto res = cur.getSubItem(item)) {
if (res) {
return res; return res;
} }
} }
@ -35,50 +39,47 @@ bool StorageSubItem::deleteItem(const char *key) {
return true; return true;
} }
auto itemItr = mItems.find(key); if (const auto itemItr = mItems.find(key); itemItr != mItems.end()) {
if (itemItr != mItems.end()) {
mItems.erase(itemItr); mItems.erase(itemItr);
return true; // Item found and deleted. return true; // Item found and deleted.
} }
return false; return false;
} }
StorageItem *StorageSubItem::createItem(const char *key, StorageSubItem::StorageSubItemError &error) { StorageItem *StorageSubItem::createItem(const char *key, StorageSubItemError &error) {
for (const auto &cur : mSubCategories) { if (getSubItem(key) != nullptr) {
if (cur.getKey() == key) {
error = STORAGE_SUB_ITEM_KEY_ALREADY_IN_USE; error = STORAGE_SUB_ITEM_KEY_ALREADY_IN_USE;
return nullptr; return nullptr;
} }
}
auto result = mItems.insert({key, StorageItem(key)});
if (result.second) {
return &result.first->second;
}
return nullptr;
}
StorageSubItem *StorageSubItem::createSubItem(const char *key, StorageSubItem::StorageSubItemError &error) { if (const auto [addedItem, itemAdded] = mItems.insert({key, StorageItem(key)}); itemAdded) {
auto resItr = mItems.find(key); return &addedItem->second;
if (resItr != mItems.end()) { }
error = STORAGE_SUB_ITEM_KEY_ALREADY_IN_USE; error = STORAGE_SUB_ITEM_KEY_ALREADY_IN_USE;
return nullptr; return nullptr;
} }
for (const auto &cur : mSubCategories) {
if (cur.getKey() == key) { StorageSubItem *StorageSubItem::createSubItem(const char *key, StorageSubItemError &error) {
if (getItem(key) != nullptr || getSubItem(key) != nullptr) {
error = STORAGE_SUB_ITEM_KEY_ALREADY_IN_USE; error = STORAGE_SUB_ITEM_KEY_ALREADY_IN_USE;
return nullptr; return nullptr;
} }
}
mSubCategories.emplace_front(key); mSubCategories.emplace_front(key);
return &mSubCategories.front(); return &mSubCategories.front();
} }
StorageItem *StorageSubItem::getItem(const char *name) { StorageItem *StorageSubItem::getItem(const char *name) {
auto resItr = mItems.find(name); if (const auto resItr = mItems.find(name); resItr != mItems.end()) {
if (resItr != mItems.end()) {
return &resItr->second; return &resItr->second;
} }
return nullptr; return nullptr;
} }
const std::forward_list<StorageSubItem> &StorageSubItem::getSubItems() const {
return mSubCategories;
}
const std::map<std::string, StorageItem> &StorageSubItem::getItems() const {
return mItems;
}

View File

@ -1,12 +1,10 @@
#pragma once #pragma once
#include "StorageItem.h" #include "StorageItem.h"
#include "utils/utils.h"
#include <forward_list>
#include <map> #include <map>
#include <memory> #include <string>
#include <optional>
#include <utility>
#include <vector>
#include <wups/storage.h> #include <wups/storage.h>
class StorageSubItem : public StorageItem { class StorageSubItem : public StorageItem {
@ -17,8 +15,7 @@ public:
STORAGE_SUB_ITEM_KEY_ALREADY_IN_USE = 2, STORAGE_SUB_ITEM_KEY_ALREADY_IN_USE = 2,
}; };
explicit StorageSubItem(std::string_view key) : StorageItem(key) { explicit StorageSubItem(std::string_view key);
}
StorageSubItem *getSubItem(wups_storage_item item); StorageSubItem *getSubItem(wups_storage_item item);
@ -26,19 +23,15 @@ public:
bool deleteItem(const char *key); bool deleteItem(const char *key);
StorageItem *createItem(const char *key, StorageSubItem::StorageSubItemError &error); StorageItem *createItem(const char *key, StorageSubItemError &error);
StorageSubItem *createSubItem(const char *key, StorageSubItem::StorageSubItemError &error); StorageSubItem *createSubItem(const char *key, StorageSubItemError &error);
StorageItem *getItem(const char *name); StorageItem *getItem(const char *name);
[[nodiscard]] const std::forward_list<StorageSubItem> &getSubItems() const { [[nodiscard]] const std::forward_list<StorageSubItem> &getSubItems() const;
return mSubCategories;
}
[[nodiscard]] const std::map<std::string, StorageItem> &getItems() const { [[nodiscard]] const std::map<std::string, StorageItem> &getItems() const;
return mItems;
}
protected: protected:
std::forward_list<StorageSubItem> mSubCategories; std::forward_list<StorageSubItem> mSubCategories;

View File

@ -1,15 +1,18 @@
#include "StorageUtils.h" #include "StorageItem.h"
#include "NotificationsUtils.h"
#include "StorageItemRoot.h" #include "StorageItemRoot.h"
#include "StorageSubItem.h"
#include "fs/CFile.hpp" #include "fs/CFile.hpp"
#include "fs/FSUtils.h" #include "fs/FSUtils.h"
#include "utils/StringTools.h"
#include "utils/base64.h" #include "utils/base64.h"
#include "utils/json.hpp" #include "utils/json.hpp"
#include "utils/logger.h" #include "utils/logger.h"
#include "utils/utils.h" #include "utils/utils.h"
#include <memory>
#include <string> #include <forward_list>
#include <malloc.h>
#include <mutex>
#include <wups/storage.h>
namespace StorageUtils { namespace StorageUtils {
std::forward_list<StorageItemRoot> gStorage; std::forward_list<StorageItemRoot> gStorage;
std::mutex gStorageMutex; std::mutex gStorageMutex;
@ -76,8 +79,7 @@ namespace StorageUtils {
if (json.empty() || !json.is_object()) { if (json.empty() || !json.is_object()) {
return nullptr; return nullptr;
} }
auto root = make_unique_nothrow<StorageItemRoot>(key); if (auto root = make_unique_nothrow<StorageItemRoot>(key)) {
if (root) {
if (deserializeFromJson(json, *root)) { if (deserializeFromJson(json, *root)) {
return root; return root;
} }
@ -132,8 +134,7 @@ namespace StorageUtils {
case StorageItemType::Binary: { case StorageItemType::Binary: {
std::vector<uint8_t> tmp; std::vector<uint8_t> tmp;
if (value.getValue(tmp)) { if (value.getValue(tmp)) {
auto *enc = b64_encode(tmp.data(), tmp.size()); if (auto *enc = b64_encode(tmp.data(), tmp.size())) {
if (enc) {
json[key] = enc; json[key] = enc;
free(enc); free(enc);
} else { } else {
@ -153,7 +154,7 @@ namespace StorageUtils {
static StorageItemRoot *getRootItem(wups_storage_root_item root) { static StorageItemRoot *getRootItem(wups_storage_root_item root) {
for (auto &cur : gStorage) { for (auto &cur : gStorage) {
if (cur.getHandle() == (uint32_t) root) { if (cur.getHandle() == reinterpret_cast<uint32_t>(root)) {
return &cur; return &cur;
} }
} }
@ -162,8 +163,7 @@ namespace StorageUtils {
} }
static StorageSubItem *getSubItem(wups_storage_root_item root, wups_storage_item parent) { static StorageSubItem *getSubItem(wups_storage_root_item root, wups_storage_item parent) {
auto rootItem = getRootItem(root); if (auto rootItem = getRootItem(root)) {
if (rootItem) {
if (parent == nullptr) { if (parent == nullptr) {
return rootItem; return rootItem;
} }
@ -173,18 +173,17 @@ namespace StorageUtils {
} }
WUPSStorageError LoadFromFile(std::string_view plugin_id, nlohmann::json &outJson) { WUPSStorageError LoadFromFile(std::string_view plugin_id, nlohmann::json &outJson) {
std::string filePath = getPluginPath() + "/config/" + plugin_id.data() + ".json"; const std::string filePath = getPluginPath() + "/config/" + plugin_id.data() + ".json";
CFile file(filePath, CFile::ReadOnly); CFile file(filePath, CFile::ReadOnly);
if (!file.isOpen() || file.size() == 0) { if (!file.isOpen() || file.size() == 0) {
return WUPS_STORAGE_ERROR_NOT_FOUND; return WUPS_STORAGE_ERROR_NOT_FOUND;
} }
auto *json_data = (uint8_t *) memalign(0x40, ROUNDUP(file.size() + 1, 0x40)); auto *json_data = static_cast<uint8_t *>(memalign(0x40, ROUNDUP(file.size() + 1, 0x40)));
if (!json_data) { if (!json_data) {
return WUPS_STORAGE_ERROR_MALLOC_FAILED; return WUPS_STORAGE_ERROR_MALLOC_FAILED;
} }
WUPSStorageError result = WUPS_STORAGE_ERROR_SUCCESS; WUPSStorageError result = WUPS_STORAGE_ERROR_SUCCESS;
uint64_t readRes = file.read(json_data, file.size()); if (const uint64_t readRes = file.read(json_data, file.size()); readRes == file.size()) {
if (readRes == file.size()) {
json_data[file.size()] = '\0'; json_data[file.size()] = '\0';
outJson = nlohmann::json::parse(json_data, nullptr, false); outJson = nlohmann::json::parse(json_data, nullptr, false);
} else { } else {
@ -197,9 +196,8 @@ namespace StorageUtils {
WUPSStorageError LoadFromFile(std::string_view plugin_id, StorageItemRoot &rootItem) { WUPSStorageError LoadFromFile(std::string_view plugin_id, StorageItemRoot &rootItem) {
nlohmann::json j; nlohmann::json j;
WUPSStorageError err;
if ((err = LoadFromFile(plugin_id, j)) != WUPS_STORAGE_ERROR_SUCCESS) { if (WUPSStorageError err; (err = LoadFromFile(plugin_id, j)) != WUPS_STORAGE_ERROR_SUCCESS) {
return err; return err;
} }
@ -219,7 +217,7 @@ namespace StorageUtils {
static WUPSStorageError WriteStorageToSD(wups_storage_root_item root, bool forceSave) { static WUPSStorageError WriteStorageToSD(wups_storage_root_item root, bool forceSave) {
const StorageItemRoot *rootItem = nullptr; const StorageItemRoot *rootItem = nullptr;
for (const auto &cur : gStorage) { for (const auto &cur : gStorage) {
if (cur.getHandle() == (uint32_t) root) { if (cur.getHandle() == reinterpret_cast<uint32_t>(root)) {
rootItem = &cur; rootItem = &cur;
break; break;
} }
@ -228,8 +226,8 @@ namespace StorageUtils {
return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED;
} }
std::string folderPath = getPluginPath() + "/config/"; const std::string folderPath = getPluginPath() + "/config/";
std::string filePath = folderPath + rootItem->getPluginId() + ".json"; const std::string filePath = folderPath + rootItem->getPluginId() + ".json";
nlohmann::json j; nlohmann::json j;
j["storageitems"] = serializeToJson(*rootItem); j["storageitems"] = serializeToJson(*rootItem);
@ -260,19 +258,19 @@ namespace StorageUtils {
return WUPS_STORAGE_ERROR_IO_ERROR; return WUPS_STORAGE_ERROR_IO_ERROR;
} }
std::string jsonString = j.dump(4, ' ', false, nlohmann::json::error_handler_t::ignore); const std::string jsonString = j.dump(4, ' ', false, nlohmann::json::error_handler_t::ignore);
auto writeResult = file.write((const uint8_t *) jsonString.c_str(), jsonString.size()); const auto writeResult = file.write(reinterpret_cast<const uint8_t *>(jsonString.c_str()), jsonString.size());
file.close(); file.close();
if (writeResult != (int32_t) jsonString.size()) { if (writeResult != static_cast<int32_t>(jsonString.size())) {
return WUPS_STORAGE_ERROR_IO_ERROR; return WUPS_STORAGE_ERROR_IO_ERROR;
} }
return WUPS_STORAGE_ERROR_SUCCESS; return WUPS_STORAGE_ERROR_SUCCESS;
} }
static StorageItem *createOrGetItem(wups_storage_root_item root, wups_storage_item parent, const char *key, WUPSStorageError &error) { static StorageItem *createOrGetItem(wups_storage_root_item root, wups_storage_item parent, const char *key, WUPSStorageError &error) {
auto subItem = getSubItem(root, parent); const auto subItem = getSubItem(root, parent);
if (!subItem) { if (!subItem) {
error = WUPS_STORAGE_ERROR_NOT_FOUND; error = WUPS_STORAGE_ERROR_NOT_FOUND;
return {}; return {};
@ -280,8 +278,9 @@ namespace StorageUtils {
auto res = subItem->getItem(key); auto res = subItem->getItem(key);
StorageSubItem::StorageSubItemError subItemError = StorageSubItem::STORAGE_SUB_ITEM_ERROR_NONE; StorageSubItem::StorageSubItemError subItemError = StorageSubItem::STORAGE_SUB_ITEM_ERROR_NONE;
if (!res) { if (!res) {
if (!(res = subItem->createItem(key, subItemError))) { res = subItem->createItem(key, subItemError);
error = StorageUtils::Helper::ConvertToWUPSError(subItemError); if (!res) {
error = ConvertToWUPSError(subItemError);
} }
} }
if (res) { if (res) {
@ -291,10 +290,9 @@ namespace StorageUtils {
} }
template<typename T> template<typename T>
WUPSStorageError StoreItemGeneric(wups_storage_root_item root, wups_storage_item parent, const char *key, T value) { WUPSStorageError StoreItemGeneric(wups_storage_root_item root, wups_storage_item parent, const char *key, const T &value) {
WUPSStorageError err; WUPSStorageError err;
auto item = createOrGetItem(root, parent, key, err); if (auto item = createOrGetItem(root, parent, key, err); item && err == WUPS_STORAGE_ERROR_SUCCESS) {
if (item && err == WUPS_STORAGE_ERROR_SUCCESS) {
item->setValue(value); item->setValue(value);
return WUPS_STORAGE_ERROR_SUCCESS; return WUPS_STORAGE_ERROR_SUCCESS;
} }
@ -303,12 +301,11 @@ namespace StorageUtils {
template<typename T> template<typename T>
WUPSStorageError GetItemEx(wups_storage_root_item root, wups_storage_item parent, const char *key, T &result) { WUPSStorageError GetItemEx(wups_storage_root_item root, wups_storage_item parent, const char *key, T &result) {
auto subItem = getSubItem(root, parent); const auto subItem = getSubItem(root, parent);
if (!subItem) { if (!subItem) {
return WUPS_STORAGE_ERROR_NOT_FOUND; return WUPS_STORAGE_ERROR_NOT_FOUND;
} }
auto item = subItem->getItem(key); if (auto item = subItem->getItem(key)) {
if (item) {
if (item->getValue(result)) { if (item->getValue(result)) {
return WUPS_STORAGE_ERROR_SUCCESS; return WUPS_STORAGE_ERROR_SUCCESS;
} }
@ -338,13 +335,11 @@ namespace StorageUtils {
* Binary items are serialized as base64 encoded string. The first time they are read they'll get converted into binary data. * Binary items are serialized as base64 encoded string. The first time they are read they'll get converted into binary data.
*/ */
WUPSStorageError GetAndFixBinaryItem(wups_storage_root_item root, wups_storage_item parent, const char *key, std::vector<uint8_t> &result) { WUPSStorageError GetAndFixBinaryItem(wups_storage_root_item root, wups_storage_item parent, const char *key, std::vector<uint8_t> &result) {
auto subItem = getSubItem(root, parent); const auto subItem = getSubItem(root, parent);
if (!subItem) { if (!subItem) {
return WUPS_STORAGE_ERROR_NOT_FOUND; return WUPS_STORAGE_ERROR_NOT_FOUND;
} }
WUPSStorageError err = WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE; if (const auto item = subItem->getItem(key)) {
auto item = subItem->getItem(key);
if (item) {
// Trigger potential string->binary conversion // Trigger potential string->binary conversion
if (!item->attemptBinaryConversion()) { if (!item->attemptBinaryConversion()) {
return WUPS_STORAGE_ERROR_MALLOC_FAILED; return WUPS_STORAGE_ERROR_MALLOC_FAILED;
@ -352,22 +347,22 @@ namespace StorageUtils {
if (item->getValue(result)) { if (item->getValue(result)) {
return WUPS_STORAGE_ERROR_SUCCESS; return WUPS_STORAGE_ERROR_SUCCESS;
} }
return err; return WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE;
} }
return WUPS_STORAGE_ERROR_NOT_FOUND; return WUPS_STORAGE_ERROR_NOT_FOUND;
} }
static WUPSStorageError GetStringItem(wups_storage_root_item root, wups_storage_item parent, const char *key, void *data, uint32_t maxSize, uint32_t *outSize) { static WUPSStorageError GetStringItem(wups_storage_root_item root, wups_storage_item parent, const char *key, void *data, uint32_t maxSize, uint32_t *outSize) {
std::string tmp; std::string tmp;
auto res = GetItemEx<std::string>(root, parent, key, tmp); const auto res = GetItemEx<std::string>(root, parent, key, tmp);
if (res == WUPS_STORAGE_ERROR_SUCCESS) { if (res == WUPS_STORAGE_ERROR_SUCCESS) {
if (maxSize <= tmp.size()) { // maxSize needs to be bigger because of the null-terminator if (maxSize <= tmp.size()) { // maxSize needs to be bigger because of the null-terminator
return WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL; return WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL;
} }
strncpy((char *) data, tmp.c_str(), tmp.size()); strncpy(static_cast<char *>(data), tmp.c_str(), tmp.size());
((char *) data)[maxSize - 1] = '\0'; static_cast<char *>(data)[maxSize - 1] = '\0';
if (outSize) { if (outSize) {
*outSize = strlen((char *) data) + 1; *outSize = strlen(static_cast<char *>(data)) + 1;
} }
return WUPS_STORAGE_ERROR_SUCCESS; return WUPS_STORAGE_ERROR_SUCCESS;
} }
@ -376,7 +371,7 @@ namespace StorageUtils {
static WUPSStorageError GetBinaryItem(wups_storage_root_item root, wups_storage_item parent, const char *key, const void *data, uint32_t maxSize, uint32_t *outSize) { static WUPSStorageError GetBinaryItem(wups_storage_root_item root, wups_storage_item parent, const char *key, const void *data, uint32_t maxSize, uint32_t *outSize) {
std::vector<uint8_t> tmp; std::vector<uint8_t> tmp;
auto res = GetAndFixBinaryItem(root, parent, key, tmp); const auto res = GetAndFixBinaryItem(root, parent, key, tmp);
if (res == WUPS_STORAGE_ERROR_SUCCESS) { if (res == WUPS_STORAGE_ERROR_SUCCESS) {
if (tmp.empty()) { // we need this to support getting empty std::vector if (tmp.empty()) { // we need this to support getting empty std::vector
return WUPS_STORAGE_ERROR_SUCCESS; return WUPS_STORAGE_ERROR_SUCCESS;
@ -404,8 +399,7 @@ namespace StorageUtils {
gStorage.emplace_front(plugin_id); gStorage.emplace_front(plugin_id);
auto &root = gStorage.front(); auto &root = gStorage.front();
WUPSStorageError err = Helper::LoadFromFile(plugin_id, root); if (const WUPSStorageError err = Helper::LoadFromFile(plugin_id, root); err == WUPS_STORAGE_ERROR_NOT_FOUND) {
if (err == WUPS_STORAGE_ERROR_NOT_FOUND) {
// Create new clean StorageItemRoot if no existing storage was found // Create new clean StorageItemRoot if no existing storage was found
root = StorageItemRoot(plugin_id); root = StorageItemRoot(plugin_id);
} else if (err != WUPS_STORAGE_ERROR_SUCCESS) { } else if (err != WUPS_STORAGE_ERROR_SUCCESS) {
@ -414,7 +408,7 @@ namespace StorageUtils {
return err; return err;
} }
outItem = (wups_storage_root_item) root.getHandle(); outItem = reinterpret_cast<wups_storage_root_item>(root.getHandle());
return WUPS_STORAGE_ERROR_SUCCESS; return WUPS_STORAGE_ERROR_SUCCESS;
} }
@ -422,10 +416,10 @@ namespace StorageUtils {
WUPSStorageError CloseStorage(wups_storage_root_item root) { WUPSStorageError CloseStorage(wups_storage_root_item root) {
std::lock_guard lock(gStorageMutex); std::lock_guard lock(gStorageMutex);
auto res = StorageUtils::Helper::WriteStorageToSD(root, false); const auto res = Helper::WriteStorageToSD(root, false);
// TODO: handle write error? // TODO: handle write error?
if (!remove_first_if(gStorage, [&root](auto &cur) { return cur.getHandle() == (uint32_t) root; })) { if (!remove_first_if(gStorage, [&root](auto &cur) { return cur.getHandle() == reinterpret_cast<uint32_t>(root); })) {
DEBUG_FUNCTION_LINE_WARN("Failed to close storage: Not opened (\"%08X\")", root); DEBUG_FUNCTION_LINE_WARN("Failed to close storage: Not opened (\"%08X\")", root);
return WUPS_STORAGE_ERROR_NOT_FOUND; return WUPS_STORAGE_ERROR_NOT_FOUND;
} }
@ -433,7 +427,7 @@ namespace StorageUtils {
} }
} // namespace Internal } // namespace Internal
WUPSStorageError SaveStorage(wups_storage_root_item root, bool force) { WUPSStorageError SaveStorage(wups_storage_root_item root, const bool force) {
std::lock_guard lock(gStorageMutex); std::lock_guard lock(gStorageMutex);
return StorageUtils::Helper::WriteStorageToSD(root, force); return StorageUtils::Helper::WriteStorageToSD(root, force);
} }
@ -441,7 +435,7 @@ namespace StorageUtils {
WUPSStorageError ForceReloadStorage(wups_storage_root_item root) { WUPSStorageError ForceReloadStorage(wups_storage_root_item root) {
std::lock_guard lock(gStorageMutex); std::lock_guard lock(gStorageMutex);
auto rootItem = Helper::getRootItem(root); const auto rootItem = Helper::getRootItem(root);
if (!rootItem) { if (!rootItem) {
return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED; return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED;
} }
@ -456,7 +450,7 @@ namespace StorageUtils {
WUPSStorageError WipeStorage(wups_storage_root_item root) { WUPSStorageError WipeStorage(wups_storage_root_item root) {
std::lock_guard lock(gStorageMutex); std::lock_guard lock(gStorageMutex);
auto rootItem = Helper::getRootItem(root); const auto rootItem = Helper::getRootItem(root);
if (!rootItem) { if (!rootItem) {
return WUPS_STORAGE_ERROR_NOT_FOUND; return WUPS_STORAGE_ERROR_NOT_FOUND;
} }
@ -471,14 +465,13 @@ namespace StorageUtils {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
std::lock_guard lock(gStorageMutex); std::lock_guard lock(gStorageMutex);
auto subItem = StorageUtils::Helper::getSubItem(root, parent); if (const auto subItem = StorageUtils::Helper::getSubItem(root, parent)) {
if (subItem) {
StorageSubItem::StorageSubItemError error = StorageSubItem::STORAGE_SUB_ITEM_ERROR_NONE; StorageSubItem::StorageSubItemError error = StorageSubItem::STORAGE_SUB_ITEM_ERROR_NONE;
auto res = subItem->createSubItem(key, error); const auto res = subItem->createSubItem(key, error);
if (!res) { if (!res) {
return StorageUtils::Helper::ConvertToWUPSError(error); return StorageUtils::Helper::ConvertToWUPSError(error);
} }
*outItem = (wups_storage_item) res->getHandle(); *outItem = reinterpret_cast<wups_storage_item>(res->getHandle());
return WUPS_STORAGE_ERROR_SUCCESS; return WUPS_STORAGE_ERROR_SUCCESS;
} }
return WUPS_STORAGE_ERROR_NOT_FOUND; return WUPS_STORAGE_ERROR_NOT_FOUND;
@ -489,13 +482,12 @@ namespace StorageUtils {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
std::lock_guard lock(gStorageMutex); std::lock_guard lock(gStorageMutex);
auto subItem = StorageUtils::Helper::getSubItem(root, parent); if (const auto subItem = StorageUtils::Helper::getSubItem(root, parent)) {
if (subItem) { const auto res = subItem->getSubItem(key);
auto res = subItem->getSubItem(key);
if (!res) { if (!res) {
return WUPS_STORAGE_ERROR_NOT_FOUND; return WUPS_STORAGE_ERROR_NOT_FOUND;
} }
*outItem = (wups_storage_item) res->getHandle(); *outItem = reinterpret_cast<wups_storage_item>(res->getHandle());
return WUPS_STORAGE_ERROR_SUCCESS; return WUPS_STORAGE_ERROR_SUCCESS;
} }
return WUPS_STORAGE_ERROR_NOT_FOUND; return WUPS_STORAGE_ERROR_NOT_FOUND;
@ -503,10 +495,8 @@ namespace StorageUtils {
WUPSStorageError DeleteItem(wups_storage_root_item root, wups_storage_item parent, const char *key) { WUPSStorageError DeleteItem(wups_storage_root_item root, wups_storage_item parent, const char *key) {
std::lock_guard lock(gStorageMutex); std::lock_guard lock(gStorageMutex);
auto subItem = StorageUtils::Helper::getSubItem(root, parent); if (const auto subItem = StorageUtils::Helper::getSubItem(root, parent)) {
if (subItem) { if (const auto res = subItem->deleteItem(key); !res) {
auto res = subItem->deleteItem(key);
if (!res) {
return WUPS_STORAGE_ERROR_NOT_FOUND; return WUPS_STORAGE_ERROR_NOT_FOUND;
} }
return WUPS_STORAGE_ERROR_SUCCESS; return WUPS_STORAGE_ERROR_SUCCESS;
@ -514,7 +504,7 @@ namespace StorageUtils {
return WUPS_STORAGE_ERROR_NOT_FOUND; return WUPS_STORAGE_ERROR_NOT_FOUND;
} }
WUPSStorageError GetItemSize(wups_storage_root_item root, wups_storage_item parent, const char *key, WUPSStorageItemType itemType, uint32_t *outSize) { WUPSStorageError GetItemSize(wups_storage_root_item root, wups_storage_item parent, const char *key, const WUPSStorageItemType itemType, uint32_t *outSize) {
if (!outSize) { if (!outSize) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
@ -522,12 +512,11 @@ namespace StorageUtils {
return WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE; return WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE;
} }
std::lock_guard lock(gStorageMutex); std::lock_guard lock(gStorageMutex);
auto subItem = StorageUtils::Helper::getSubItem(root, parent); const auto subItem = StorageUtils::Helper::getSubItem(root, parent);
if (!subItem) { if (!subItem) {
return WUPS_STORAGE_ERROR_NOT_FOUND; return WUPS_STORAGE_ERROR_NOT_FOUND;
} }
auto item = subItem->getItem(key); if (const auto item = subItem->getItem(key)) {
if (item) {
if (itemType == WUPS_STORAGE_ITEM_BINARY) { if (itemType == WUPS_STORAGE_ITEM_BINARY) {
// Trigger potential string -> binary conversion. // Trigger potential string -> binary conversion.
if (!item->attemptBinaryConversion()) { if (!item->attemptBinaryConversion()) {
@ -551,42 +540,42 @@ namespace StorageUtils {
return WUPS_STORAGE_ERROR_NOT_FOUND; return WUPS_STORAGE_ERROR_NOT_FOUND;
} }
WUPSStorageError StoreItem(wups_storage_root_item root, wups_storage_item parent, const char *key, WUPSStorageItemType itemType, void *data, uint32_t length) { WUPSStorageError StoreItem(wups_storage_root_item root, wups_storage_item parent, const char *key, WUPSStorageItemType itemType, void *data, const uint32_t length) {
std::lock_guard lock(gStorageMutex); std::lock_guard lock(gStorageMutex);
switch ((WUPSStorageItemTypes) itemType) { switch (static_cast<WUPSStorageItemTypes>(itemType)) {
case WUPS_STORAGE_ITEM_S32: { case WUPS_STORAGE_ITEM_S32: {
if (data == nullptr || length != sizeof(int32_t)) { if (data == nullptr || length != sizeof(int32_t)) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as S32: %d", key, *(int32_t *) data); DEBUG_FUNCTION_LINE_VERBOSE("Store %s as S32: %d", key, *(int32_t *) data);
return StorageUtils::Helper::StoreItemGeneric<int32_t>(root, parent, key, *(int32_t *) data); return StorageUtils::Helper::StoreItemGeneric<int32_t>(root, parent, key, *static_cast<int32_t *>(data));
} }
case WUPS_STORAGE_ITEM_S64: { case WUPS_STORAGE_ITEM_S64: {
if (data == nullptr || length != sizeof(int64_t)) { if (data == nullptr || length != sizeof(int64_t)) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as S64: %lld", key, *(int64_t *) data); DEBUG_FUNCTION_LINE_VERBOSE("Store %s as S64: %lld", key, *(int64_t *) data);
return StorageUtils::Helper::StoreItemGeneric<int64_t>(root, parent, key, *(int64_t *) data); return StorageUtils::Helper::StoreItemGeneric<int64_t>(root, parent, key, *static_cast<int64_t *>(data));
} }
case WUPS_STORAGE_ITEM_U32: { case WUPS_STORAGE_ITEM_U32: {
if (data == nullptr || length != sizeof(uint32_t)) { if (data == nullptr || length != sizeof(uint32_t)) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as u32: %u", key, *(uint32_t *) data); DEBUG_FUNCTION_LINE_VERBOSE("Store %s as u32: %u", key, *(uint32_t *) data);
return StorageUtils::Helper::StoreItemGeneric<uint32_t>(root, parent, key, *(uint32_t *) data); return StorageUtils::Helper::StoreItemGeneric<uint32_t>(root, parent, key, *static_cast<uint32_t *>(data));
} }
case WUPS_STORAGE_ITEM_U64: { case WUPS_STORAGE_ITEM_U64: {
if (data == nullptr || length != sizeof(uint64_t)) { if (data == nullptr || length != sizeof(uint64_t)) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as u64: %llu", key, *(uint64_t *) data); DEBUG_FUNCTION_LINE_VERBOSE("Store %s as u64: %llu", key, *(uint64_t *) data);
return StorageUtils::Helper::StoreItemGeneric<uint64_t>(root, parent, key, *(uint64_t *) data); return StorageUtils::Helper::StoreItemGeneric<uint64_t>(root, parent, key, *static_cast<uint64_t *>(data));
} }
case WUPS_STORAGE_ITEM_STRING: { case WUPS_STORAGE_ITEM_STRING: {
if (data == nullptr) { if (data == nullptr) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
std::string tmp = length > 0 ? std::string((const char *) data, length) : std::string(); const std::string tmp = length > 0 ? std::string(static_cast<const char *>(data), length) : std::string();
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as string: %s", key, tmp.c_str()); DEBUG_FUNCTION_LINE_VERBOSE("Store %s as string: %s", key, tmp.c_str());
return StorageUtils::Helper::StoreItemGeneric<std::string>(root, parent, key, tmp); return StorageUtils::Helper::StoreItemGeneric<std::string>(root, parent, key, tmp);
@ -595,7 +584,7 @@ namespace StorageUtils {
if (data == nullptr && length > 0) { if (data == nullptr && length > 0) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
std::vector<uint8_t> tmp = (data != nullptr && length > 0) ? std::vector<uint8_t>((uint8_t *) data, ((uint8_t *) data) + length) : std::vector<uint8_t>(); const std::vector<uint8_t> tmp = (data != nullptr && length > 0) ? std::vector(static_cast<uint8_t *>(data), static_cast<uint8_t *>(data) + length) : std::vector<uint8_t>();
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as binary: size %d", key, tmp.size()); DEBUG_FUNCTION_LINE_VERBOSE("Store %s as binary: size %d", key, tmp.size());
return StorageUtils::Helper::StoreItemGeneric<std::vector<uint8_t>>(root, parent, key, tmp); return StorageUtils::Helper::StoreItemGeneric<std::vector<uint8_t>>(root, parent, key, tmp);
@ -605,33 +594,39 @@ namespace StorageUtils {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as bool: %d", key, *(bool *) data); DEBUG_FUNCTION_LINE_VERBOSE("Store %s as bool: %d", key, *(bool *) data);
return StorageUtils::Helper::StoreItemGeneric<bool>(root, parent, key, *(bool *) data); return StorageUtils::Helper::StoreItemGeneric<bool>(root, parent, key, *static_cast<bool *>(data));
} }
case WUPS_STORAGE_ITEM_FLOAT: { case WUPS_STORAGE_ITEM_FLOAT: {
if (data == nullptr || length != sizeof(float)) { if (data == nullptr || length != sizeof(float)) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as float: %f", key, *(float *) data); DEBUG_FUNCTION_LINE_VERBOSE("Store %s as float: %f", key, *(float *) data);
return StorageUtils::Helper::StoreItemGeneric<float>(root, parent, key, *(float *) data); return StorageUtils::Helper::StoreItemGeneric<float>(root, parent, key, *static_cast<float *>(data));
} }
case WUPS_STORAGE_ITEM_DOUBLE: { case WUPS_STORAGE_ITEM_DOUBLE: {
if (data == nullptr || length != sizeof(double)) { if (data == nullptr || length != sizeof(double)) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as double: %f", key, *(double *) data); DEBUG_FUNCTION_LINE_VERBOSE("Store %s as double: %f", key, *(double *) data);
return StorageUtils::Helper::StoreItemGeneric<double>(root, parent, key, *(double *) data); return StorageUtils::Helper::StoreItemGeneric<double>(root, parent, key, *static_cast<double *>(data));
} }
} }
DEBUG_FUNCTION_LINE_ERR("Store failed!"); DEBUG_FUNCTION_LINE_ERR("Store failed!");
return WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE; return WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE;
} }
WUPSStorageError GetItem(wups_storage_root_item root, wups_storage_item parent, const char *key, WUPSStorageItemType itemType, void *data, uint32_t maxSize, uint32_t *outSize) { WUPSStorageError GetItem(wups_storage_root_item root,
wups_storage_item parent,
const char *key,
WUPSStorageItemType itemType,
void *data,
const uint32_t maxSize,
uint32_t *outSize) {
std::lock_guard lock(gStorageMutex); std::lock_guard lock(gStorageMutex);
if (outSize) { if (outSize) {
*outSize = 0; *outSize = 0;
} }
switch ((WUPSStorageItemTypes) itemType) { switch (static_cast<WUPSStorageItemTypes>(itemType)) {
case WUPS_STORAGE_ITEM_STRING: { case WUPS_STORAGE_ITEM_STRING: {
if (!data || maxSize == 0) { if (!data || maxSize == 0) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
@ -645,43 +640,43 @@ namespace StorageUtils {
if (!data || maxSize != sizeof(bool)) { if (!data || maxSize != sizeof(bool)) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
return StorageUtils::Helper::GetItemGeneric<bool>(root, parent, key, (bool *) data, outSize); return StorageUtils::Helper::GetItemGeneric<bool>(root, parent, key, static_cast<bool *>(data), outSize);
} }
case WUPS_STORAGE_ITEM_S32: { case WUPS_STORAGE_ITEM_S32: {
if (!data || maxSize != sizeof(int32_t)) { if (!data || maxSize != sizeof(int32_t)) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
return StorageUtils::Helper::GetItemGeneric<int32_t>(root, parent, key, (int32_t *) data, outSize); return StorageUtils::Helper::GetItemGeneric<int32_t>(root, parent, key, static_cast<int32_t *>(data), outSize);
} }
case WUPS_STORAGE_ITEM_S64: { case WUPS_STORAGE_ITEM_S64: {
if (!data || maxSize != sizeof(int64_t)) { if (!data || maxSize != sizeof(int64_t)) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
return StorageUtils::Helper::GetItemGeneric<int64_t>(root, parent, key, (int64_t *) data, outSize); return StorageUtils::Helper::GetItemGeneric<int64_t>(root, parent, key, static_cast<int64_t *>(data), outSize);
} }
case WUPS_STORAGE_ITEM_U32: { case WUPS_STORAGE_ITEM_U32: {
if (!data || maxSize != sizeof(uint32_t)) { if (!data || maxSize != sizeof(uint32_t)) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
return StorageUtils::Helper::GetItemGeneric<uint32_t>(root, parent, key, (uint32_t *) data, outSize); return StorageUtils::Helper::GetItemGeneric<uint32_t>(root, parent, key, static_cast<uint32_t *>(data), outSize);
} }
case WUPS_STORAGE_ITEM_U64: { case WUPS_STORAGE_ITEM_U64: {
if (!data || maxSize != sizeof(uint64_t)) { if (!data || maxSize != sizeof(uint64_t)) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
return StorageUtils::Helper::GetItemGeneric<uint64_t>(root, parent, key, (uint64_t *) data, outSize); return StorageUtils::Helper::GetItemGeneric<uint64_t>(root, parent, key, static_cast<uint64_t *>(data), outSize);
} }
case WUPS_STORAGE_ITEM_FLOAT: { case WUPS_STORAGE_ITEM_FLOAT: {
if (!data || maxSize != sizeof(float)) { if (!data || maxSize != sizeof(float)) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
return StorageUtils::Helper::GetItemGeneric<float>(root, parent, key, (float *) data, outSize); return StorageUtils::Helper::GetItemGeneric<float>(root, parent, key, static_cast<float *>(data), outSize);
} }
case WUPS_STORAGE_ITEM_DOUBLE: { case WUPS_STORAGE_ITEM_DOUBLE: {
if (!data || maxSize != sizeof(double)) { if (!data || maxSize != sizeof(double)) {
return WUPS_STORAGE_ERROR_INVALID_ARGS; return WUPS_STORAGE_ERROR_INVALID_ARGS;
} }
return StorageUtils::Helper::GetItemGeneric<double>(root, parent, key, (double *) data, outSize); return StorageUtils::Helper::GetItemGeneric<double>(root, parent, key, static_cast<double *>(data), outSize);
} }
} }
return WUPS_STORAGE_ERROR_NOT_FOUND; return WUPS_STORAGE_ERROR_NOT_FOUND;

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <cstdint>
#include <string_view>
#include <wups/storage.h> #include <wups/storage.h>
namespace StorageUtils::API { namespace StorageUtils::API {

View File

@ -3,6 +3,7 @@
#include "logger.h" #include "logger.h"
#include <algorithm> #include <algorithm>
#include <coreinit/ios.h> #include <coreinit/ios.h>
#include <malloc.h>
#include <string> #include <string>
static std::string sPluginPath; static std::string sPluginPath;
@ -10,11 +11,9 @@ std::string getPluginPath() {
if (!sPluginPath.empty()) { if (!sPluginPath.empty()) {
return sPluginPath; return sPluginPath;
} }
char environmentPath[0x100]; char environmentPath[0x100] = {};
memset(environmentPath, 0, sizeof(environmentPath));
auto handle = IOS_Open("/dev/mcp", IOS_OPEN_READ); if (const auto handle = IOS_Open("/dev/mcp", IOS_OPEN_READ); handle >= 0) {
if (handle >= 0) {
int in = 0xF9; // IPC_CUSTOM_COPY_ENVIRONMENT_PATH int in = 0xF9; // IPC_CUSTOM_COPY_ENVIRONMENT_PATH
if (IOS_Ioctl(handle, 100, &in, sizeof(in), environmentPath, sizeof(environmentPath)) != IOS_ERROR_OK) { if (IOS_Ioctl(handle, 100, &in, sizeof(in), environmentPath, sizeof(environmentPath)) != IOS_ERROR_OK) {
return "fs:/vol/external01/wiiu/plugins"; return "fs:/vol/external01/wiiu/plugins";
@ -27,7 +26,7 @@ std::string getPluginPath() {
} }
// https://gist.github.com/ccbrown/9722406 // https://gist.github.com/ccbrown/9722406
void dumpHex(const void *data, size_t size) { void dumpHex(const void *data, const size_t size) {
char ascii[17]; char ascii[17];
size_t i, j; size_t i, j;
ascii[16] = '\0'; ascii[16] = '\0';
@ -71,7 +70,7 @@ OSDynLoad_Error CustomDynLoadAlloc(int32_t size, int32_t align, void **outAddr)
align = -4; align = -4;
} }
if (!(*outAddr = memalign(align, size))) { if (*outAddr = memalign(align, size); !*outAddr) {
return OS_DYNLOAD_OUT_OF_MEMORY; return OS_DYNLOAD_OUT_OF_MEMORY;
} }
// keep track of allocated memory to clean it up if RPLs won't get unloaded properly // keep track of allocated memory to clean it up if RPLs won't get unloaded properly
@ -84,8 +83,7 @@ void CustomDynLoadFree(void *addr) {
free(addr); free(addr);
// Remove from list // Remove from list
auto it = std::find(gAllocatedAddresses.begin(), gAllocatedAddresses.end(), addr); if (const auto it = std::ranges::find(gAllocatedAddresses, addr); it != gAllocatedAddresses.end()) {
if (it != gAllocatedAddresses.end()) {
gAllocatedAddresses.erase(it); gAllocatedAddresses.erase(it);
} }
} }

View File

@ -4,7 +4,6 @@
#include <coreinit/dynload.h> #include <coreinit/dynload.h>
#include <cstdint> #include <cstdint>
#include <forward_list> #include <forward_list>
#include <malloc.h>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <set> #include <set>

View File

@ -0,0 +1,94 @@
#include "wiiu_zlib.hpp"
#include "utils.h"
#include <cstring>
#include <zlib.h>
std::unique_ptr<char[]> wiiu_zlib::inflate(const char *data, const ELFIO::endianess_convertor *convertor, const ELFIO::Elf_Xword compressed_size, ELFIO::Elf_Xword &uncompressed_size) const {
read_uncompressed_size(data, convertor, uncompressed_size);
auto result = make_unique_nothrow<char[]>(static_cast<uint32_t>(uncompressed_size + 1));
if (result == nullptr) {
return nullptr;
}
z_stream s = {};
s.zalloc = Z_NULL;
s.zfree = Z_NULL;
s.opaque = Z_NULL;
if (inflateInit_(&s, ZLIB_VERSION, sizeof(s)) != Z_OK) {
return nullptr;
}
s.avail_in = compressed_size - 4;
s.next_in = (Bytef *) data;
s.avail_out = uncompressed_size;
s.next_out = (Bytef *) result.get();
const int z_ret = ::inflate(&s, Z_FINISH);
inflateEnd(&s);
if (z_ret != Z_OK && z_ret != Z_STREAM_END) {
return nullptr;
}
result[uncompressed_size] = '\0';
return result;
}
std::unique_ptr<char[]> wiiu_zlib::deflate(const char *data, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword decompressed_size, ELFIO::Elf_Xword &compressed_size) const {
auto result = make_unique_nothrow<char[]>(static_cast<uint32_t>(decompressed_size));
if (result == nullptr) {
return nullptr;
}
int z_ret;
z_stream s = {};
s.zalloc = Z_NULL;
s.zfree = Z_NULL;
s.opaque = Z_NULL;
if ((z_ret = deflateInit(&s, Z_DEFAULT_COMPRESSION)) != Z_OK) {
return nullptr;
}
s.avail_in = decompressed_size;
s.next_in = (Bytef *) data;
s.avail_out = decompressed_size - 4;
s.next_out = (Bytef *) result.get() + 4;
z_ret = ::deflate(&s, Z_FINISH);
compressed_size = decompressed_size - s.avail_out;
deflateEnd(&s);
if (z_ret != Z_OK && z_ret != Z_STREAM_END) {
compressed_size = 0;
return nullptr;
}
write_compressed_size(result, convertor, compressed_size);
result[compressed_size] = '\0';
return result;
}
void wiiu_zlib::read_uncompressed_size(const char *&data, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword &uncompressed_size) {
union _int32buffer {
uint32_t word;
char bytes[4];
} int32buffer = {};
memcpy(int32buffer.bytes, data, 4);
data += 4;
uncompressed_size = (*convertor)(int32buffer.word);
}
void wiiu_zlib::write_compressed_size(std::unique_ptr<char[]> &result, const ELFIO::endianess_convertor *convertor, const ELFIO::Elf_Xword compressed_size) {
union _int32buffer {
uint32_t word;
char bytes[4];
} int32buffer = {};
int32buffer.word = (*convertor)(compressed_size);
memcpy(result.get(), int32buffer.bytes, 4);
}

View File

@ -19,101 +19,16 @@
#include <memory> #include <memory>
#include "elfio/elfio_utils.hpp" #include <elfio/elfio_utils.hpp>
#include "logger.h"
#include "utils.h"
#include <zlib.h>
class wiiu_zlib : public ELFIO::compression_interface { class wiiu_zlib final : public ELFIO::compression_interface {
public: public:
std::unique_ptr<char[]> inflate(const char *data, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword compressed_size, ELFIO::Elf_Xword &uncompressed_size) const override { std::unique_ptr<char[]> inflate(const char *data, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword compressed_size, ELFIO::Elf_Xword &uncompressed_size) const override;
read_uncompressed_size(data, convertor, uncompressed_size);
auto result = make_unique_nothrow<char[]>((uint32_t) (uncompressed_size + 1));
if (result == nullptr) {
return nullptr;
}
int z_ret; std::unique_ptr<char[]> deflate(const char *data, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword decompressed_size, ELFIO::Elf_Xword &compressed_size) const override;
z_stream s = {};
s.zalloc = Z_NULL;
s.zfree = Z_NULL;
s.opaque = Z_NULL;
if (inflateInit_(&s, ZLIB_VERSION, sizeof(s)) != Z_OK) {
return nullptr;
}
s.avail_in = compressed_size - 4;
s.next_in = (Bytef *) data;
s.avail_out = uncompressed_size;
s.next_out = (Bytef *) result.get();
z_ret = ::inflate(&s, Z_FINISH);
inflateEnd(&s);
if (z_ret != Z_OK && z_ret != Z_STREAM_END) {
return nullptr;
}
result[uncompressed_size] = '\0';
return result;
}
std::unique_ptr<char[]> deflate(const char *data, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword decompressed_size, ELFIO::Elf_Xword &compressed_size) const override {
auto result = make_unique_nothrow<char[]>((uint32_t) (decompressed_size));
if (result == nullptr) {
return nullptr;
}
int z_ret;
z_stream s = {};
s.zalloc = Z_NULL;
s.zfree = Z_NULL;
s.opaque = Z_NULL;
if ((z_ret = deflateInit(&s, Z_DEFAULT_COMPRESSION)) != Z_OK) {
return nullptr;
}
s.avail_in = decompressed_size;
s.next_in = (Bytef *) data;
s.avail_out = decompressed_size - 4;
s.next_out = (Bytef *) result.get() + 4;
z_ret = ::deflate(&s, Z_FINISH);
compressed_size = decompressed_size - s.avail_out;
deflateEnd(&s);
if (z_ret != Z_OK && z_ret != Z_STREAM_END) {
compressed_size = 0;
return nullptr;
}
write_compressed_size(result, convertor, compressed_size);
result[compressed_size] = '\0';
return result;
}
private: private:
static void read_uncompressed_size(const char *&data, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword &uncompressed_size) { static void read_uncompressed_size(const char *&data, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword &uncompressed_size);
union _int32buffer {
uint32_t word;
char bytes[4];
} int32buffer;
memcpy(int32buffer.bytes, data, 4);
data += 4;
uncompressed_size = (*convertor)(int32buffer.word);
}
static void write_compressed_size(std::unique_ptr<char[]> &result, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword compressed_size) { static void write_compressed_size(std::unique_ptr<char[]> &result, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword compressed_size);
union _int32buffer {
uint32_t word;
char bytes[4];
} int32buffer;
int32buffer.word = (*convertor)(compressed_size);
memcpy(result.get(), int32buffer.bytes, 4);
}
}; };

View File

@ -1,2 +1,2 @@
#pragma once #pragma once
#define VERSION_EXTRA "" #define MODULE_VERSION_EXTRA ""