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")
cat <<EOF > ./source/version.h
#pragma once
#define VERSION_EXTRA " (nightly-$git_hash)"
#define MODULE_VERSION_EXTRA " (nightly-$git_hash)"
EOF
- name: build binary
run: |

View File

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

View File

@ -11,6 +11,7 @@
#include <coreinit/dynload.h>
#include <memory.h>
#include <memory>
#include <ranges>
std::vector<PluginContainer>
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,
std::vector<relocation_trampoline_entry_t> &trampData,
uint32_t trampolineID,
const uint32_t trampolineID,
std::map<std::string, OSDynLoad_Module> &usedRPls) {
for (auto const &cur : relocData) {
uint32_t functionAddress = 0;

View File

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

View File

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

View File

@ -1,5 +1,6 @@
#include "WUPSConfig.h"
#include "WUPSConfigAPI.h"
#include "utils/logger.h"
#include <wums.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
#include "WUPSConfigItem.h"
#include <optional>
#include <memory>
#include <string>
#include <vector>
#include <wups/config.h>
namespace WUPSConfigAPIBackend {
class WUPSConfigCategory {
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
**/
[[nodiscard]] const std::string &getName() const {
return mName;
}
[[nodiscard]] const std::string &getName() const;
/**
\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
for deleting the WUPSConfigItem instance.
**/
[[nodiscard]] bool addItem(std::unique_ptr<WUPSConfigItem> &item) {
if (item != nullptr) {
mItems.push_back(std::move(item));
return true;
}
return false;
}
[[nodiscard]] bool addItem(std::unique_ptr<WUPSConfigItem> &item);
/**
\return Returns a vector with all items.
**/
[[nodiscard]] const std::vector<std::unique_ptr<WUPSConfigItem>> &getItems() const {
return mItems;
}
[[nodiscard]] const std::vector<std::unique_ptr<WUPSConfigItem>> &getItems() const;
/**
\return Returns a vector with all categories.
**/
[[nodiscard]] const std::vector<std::unique_ptr<WUPSConfigCategory>> &getCategories() const {
return mCategories;
}
[[nodiscard]] const std::vector<std::unique_ptr<WUPSConfigCategory>> &getCategories() const;
/**
\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
for deleting the WUPSConfigCategory instance.
**/
[[nodiscard]] bool addCategory(std::unique_ptr<WUPSConfigCategory> &category) {
mCategories.push_back(std::move(category));
return true;
}
[[nodiscard]] bool addCategory(std::unique_ptr<WUPSConfigCategory> &category);
private:
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
#include <string>
#include <utility>
#include <vector>
#include "utils/StringTools.h"
#include "utils/logger.h"
#include <wups/config.h>
namespace WUPSConfigAPIBackend {
class WUPSConfigItem {
public:
explicit WUPSConfigItem(std::string displayName) : mDisplayName(std::move(displayName)) {
}
virtual ~WUPSConfigItem() = default;
explicit WUPSConfigItem(std::string displayName);
virtual ~WUPSConfigItem();
[[nodiscard]] virtual std::string getCurrentValueDisplay() const = 0;
@ -38,7 +32,7 @@ namespace WUPSConfigAPIBackend {
virtual void onSelected(bool isSelected) const = 0;
virtual void onButtonPressed(WUPSConfigButtons) const {}
virtual void onButtonPressed(WUPSConfigButtons) const;
[[nodiscard]] virtual bool isMovementAllowed() const = 0;
@ -46,23 +40,17 @@ namespace WUPSConfigAPIBackend {
virtual void onCloseCallback() = 0;
[[nodiscard]] const std::string &getDisplayName() const {
return mDisplayName;
}
[[nodiscard]] const std::string &getDisplayName() const;
virtual void setConfigId(const std::string &) {}
virtual void setConfigId(const std::string &);
virtual const std::string &getConfigId() {
return mStubConfigId;
}
virtual const std::string &getConfigId();
void setDisplayName(std::string displayName) {
mDisplayName = std::move(displayName);
}
void setDisplayName(std::string displayName);
virtual void onInput(WUPSConfigSimplePadData) const {}
virtual void onInput(WUPSConfigSimplePadData) const;
virtual void onInputEx(WUPSConfigComplexPadData) const {}
virtual void onInputEx(WUPSConfigComplexPadData) const;
protected:
std::string mDisplayName;

View File

@ -1,7 +1,12 @@
#include "WUPSConfigItemV1.h"
#include "utils/StringTools.h"
#include "utils/logger.h"
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->mContext = context;
this->mCallbacks = callbacks;
@ -46,7 +51,7 @@ namespace WUPSConfigAPIBackend {
return buf;
}
void WUPSConfigItemV1::onSelected(bool isSelected) const {
void WUPSConfigItemV1::onSelected(const bool isSelected) const {
if (this->mCallbacks.onSelected == nullptr) {
DEBUG_FUNCTION_LINE_VERBOSE("onSelected callback not implemented. [%s]", mDisplayName.c_str());
return;
@ -54,7 +59,7 @@ namespace WUPSConfigAPIBackend {
this->mCallbacks.onSelected(mContext, isSelected);
}
void WUPSConfigItemV1::onButtonPressed(WUPSConfigButtons buttons) const {
void WUPSConfigItemV1::onButtonPressed(const WUPSConfigButtons buttons) const {
if (this->mCallbacks.onButtonPressed == nullptr) {
DEBUG_FUNCTION_LINE_VERBOSE("onButtonPressed callback not implemented. [%s]", mDisplayName.c_str());
return;

View File

@ -1,12 +1,16 @@
#pragma once
#include "WUPSConfigItem.h"
#include <string>
#include <wups/config.h>
namespace WUPSConfigAPIBackend {
class WUPSConfigItemV1 : public WUPSConfigItem {
class WUPSConfigItemV1 final : public WUPSConfigItem {
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;

View File

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

View File

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

View File

@ -24,6 +24,7 @@ THE SOFTWARE.
#define ELFIO_UTILS_HPP
#include <cstdint>
#include <elfio/elf_types.hpp>
#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();
//! clear path of double slashes
StringTools::RemoveDoubleSlashs(folderpath);
StringTools::RemoveDoubleSlashes(folderpath);
//! remove last slash if exists
if (length > 0 && folderpath[length - 1] == '/')

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,45 +16,48 @@
****************************************************************************/
#pragma once
#include "utils/logger.h"
#include <function_patcher/fpatching_defines.h>
#include <function_patcher/function_patching.h>
#include <string>
class FunctionData {
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);
~FunctionData();
[[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 RemovePatch();
private:
void *paddress = nullptr;
void *vaddress = nullptr;
std::string name;
function_replacement_library_type_t library;
FunctionPatcherTargetProcess targetProcess;
void *replaceAddr = nullptr;
void *replaceCall = nullptr;
void *mPAddress = nullptr;
void *mVAddress = nullptr;
std::string mName;
function_replacement_library_type_t mLibrary;
FunctionPatcherTargetProcess mTargetProcess;
void *mReplaceAddr = 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
#include <cstdint>
#include <string>
class FunctionSymbolData {
public:
FunctionSymbolData(const FunctionSymbolData &o2) = default;
FunctionSymbolData(const FunctionSymbolData &o2);
FunctionSymbolData(std::string_view name, void *address, uint32_t size) : mName(name),
mAddress(address),
mSize(size) {
}
FunctionSymbolData(std::string_view name, void *address, uint32_t size);
bool operator<(const FunctionSymbolData &rhs) const {
return (uint32_t) mAddress < (uint32_t) rhs.mAddress;
}
bool operator<(const FunctionSymbolData &rhs) const;
virtual ~FunctionSymbolData() = default;
virtual ~FunctionSymbolData();
[[nodiscard]] const std::string &getName() const {
return mName;
}
[[nodiscard]] const std::string &getName() const;
[[nodiscard]] void *getAddress() const {
return mAddress;
}
[[nodiscard]] void *getAddress() const;
[[nodiscard]] uint32_t getSize() const {
return mSize;
}
[[nodiscard]] uint32_t getSize() const;
private:
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
#include <string>
#include <wups/hooks.h>
class HookData {
public:
HookData(void *function_pointer, wups_loader_hook_type_t type) {
this->function_pointer = function_pointer;
this->type = type;
}
HookData(void *functionPointer, wups_loader_hook_type_t type);
~HookData() = default;
~HookData();
[[nodiscard]] void *getFunctionPointer() const {
return function_pointer;
}
[[nodiscard]] void *getFunctionPointer() const;
[[nodiscard]] wups_loader_hook_type_t getType() const {
return this->type;
}
[[nodiscard]] wups_loader_hook_type_t getType() const;
private:
void *function_pointer;
wups_loader_hook_type_t type;
void *mFunctionPointer;
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
#include "../utils/logger.h"
#include <string>
#include <utility>
class ImportRPLInformation {
public:
explicit ImportRPLInformation(std::string_view name) {
this->mName = name;
}
explicit ImportRPLInformation(std::string_view name);
~ImportRPLInformation() = default;
~ImportRPLInformation();
[[nodiscard]] const std::string &getName() const {
return mName;
}
[[nodiscard]] const std::string &getName() const;
[[nodiscard]] std::string getRPLName() const {
return mName.substr(strlen(".dimport_"));
}
[[nodiscard]] std::string getRPLName() const;
[[nodiscard]] bool isData() const {
return mName.starts_with(".dimport_");
}
[[nodiscard]] bool isData() const;
private:
std::string mName;

View File

@ -1,6 +1,10 @@
#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),
mClosedCallback(closedCallback) {
}
@ -13,7 +17,7 @@ std::optional<WUPSConfigHandle> PluginConfigData::createConfig() const {
return std::nullopt;
}
WUPSConfigAPIStatus PluginConfigData::CallMenuOpenendCallback(WUPSConfigHandle config) const {
WUPSConfigAPIStatus PluginConfigData::CallMenuOpenedCallback(const WUPSConfigHandle config) const {
if (mOpenedCallback == nullptr) {
return WUPSCONFIG_API_RESULT_MISSING_CALLBACK;
}
@ -31,7 +35,9 @@ WUPSConfigAPIStatus PluginConfigData::CallMenuClosedCallback() const {
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) {
return std::nullopt;
}

View File

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

View File

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

View File

@ -21,10 +21,10 @@
#include "PluginData.h"
#include "PluginInformation.h"
#include "PluginMetaInformation.h"
#include "utils/storage/StorageUtils.h"
#include <memory>
#include <utility>
#include <wups/config_api.h>
#include <optional>
#include <wups/storage.h>
class PluginContainer {
public:
@ -34,9 +34,9 @@ public:
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;

View File

@ -1,7 +1,26 @@
#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 {
return (uint32_t) this;
return reinterpret_cast<uint32_t>(this);
}
std::span<const uint8_t> PluginData::getBuffer() const {

View File

@ -17,21 +17,22 @@
#pragma once
#include <coreinit/memexpheap.h>
#include <malloc.h>
#include <memory>
#include <optional>
#include <cstdint>
#include <span>
#include <utility>
#include <string>
#include <vector>
class PluginData {
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;

View File

@ -14,19 +14,20 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "PluginDataFactory.h"
#include "NotificationsUtils.h"
#include "fs/FSUtils.h"
#include "utils/StringTools.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;
struct dirent *dp;
dirent *dp;
DIR *dfd;
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);
DEBUG_FUNCTION_LINE("Loading plugin: %s", full_file_path.c_str());
auto pluginData = load(full_file_path);
if (pluginData) {
if (auto pluginData = load(full_file_path)) {
result.insert(std::move(pluginData));
} else {
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;
}
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;
if (FSUtils::LoadFileToMem(filename, buffer) < 0) {
DEBUG_FUNCTION_LINE_ERR("Failed to load %s into memory", filename.data());
if (FSUtils::LoadFileToMem(path, buffer) < 0) {
DEBUG_FUNCTION_LINE_ERR("Failed to load %s into memory", path.data());
return nullptr;
}
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) {

View File

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

View File

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

View File

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

View File

@ -16,13 +16,12 @@
****************************************************************************/
#include "PluginInformationFactory.h"
#include "../utils/ElfUtils.h"
#include "utils/HeapMemoryFixedSize.h"
#include "utils/ElfUtils.h"
#include "utils/logger.h"
#include "utils/utils.h"
#include "utils/wiiu_zlib.hpp"
#include <coreinit/cache.h>
#include <map>
#include <memory>
#include <string>
#include <wups/function_patching.h>
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");
return std::nullopt;
}
std::span<uint8_t *> destinations(destinationsData.get(), sec_num);
std::span destinations(destinationsData.get(), sec_num);
uint32_t totalSize = 0;
@ -265,7 +264,7 @@ PluginInformationFactory::load(const PluginData &pluginData, std::vector<relocat
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;
uint32_t sec_num = reader.sections.size();

View File

@ -16,15 +16,11 @@
****************************************************************************/
#pragma once
#include "../elfio/elfio.hpp"
#include "PluginContainer.h"
#include "PluginData.h"
#include "PluginInformation.h"
#include <coreinit/memheap.h>
#include <map>
#include <elfio/elfio.hpp>
#include <optional>
#include <string>
#include <vector>
#include <wums/defines/relocation_defines.h>
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 <string>
#include <vector>
class PluginMetaInformation {
public:
[[nodiscard]] const std::string &getName() const {
return name;
}
[[nodiscard]] const std::string &getName() const;
[[nodiscard]] const std::string &getAuthor() const {
return this->author;
}
[[nodiscard]] const std::string &getAuthor() const;
[[nodiscard]] const std::string &getVersion() const {
return this->version;
}
[[nodiscard]] const std::string &getVersion() const;
[[nodiscard]] const std::string &getLicense() const {
return this->license;
}
[[nodiscard]] const std::string &getLicense() const;
[[nodiscard]] const std::string &getBuildTimestamp() const {
return this->buildtimestamp;
}
[[nodiscard]] const std::string &getBuildTimestamp() const;
[[nodiscard]] const std::string &getDescription() const {
return this->description;
}
[[nodiscard]] const std::string &getDescription() const;
[[nodiscard]] const WUPSVersion &getWUPSVersion() const {
return this->wupsversion;
}
[[nodiscard]] const WUPSVersion &getWUPSVersion() const;
[[nodiscard]] const std::string &getStorageId() const {
return this->storageId;
}
[[nodiscard]] const std::string &getStorageId() const;
[[nodiscard]] size_t getSize() const {
return this->size;
}
[[nodiscard]] size_t getSize() const;
private:
PluginMetaInformation() = default;
PluginMetaInformation();
void setName(std::string _name) {
this->name = std::move(_name);
}
void setName(std::string name);
void setAuthor(std::string _author) {
this->author = std::move(_author);
}
void setAuthor(std::string author);
void setVersion(std::string _version) {
this->version = std::move(_version);
}
void setVersion(std::string version);
void setLicense(std::string _license) {
this->license = std::move(_license);
}
void setLicense(std::string license);
void setBuildTimestamp(std::string _buildtimestamp) {
this->buildtimestamp = std::move(_buildtimestamp);
}
void setBuildTimestamp(std::string buildTimestamp);
void setDescription(std::string _description) {
this->description = std::move(_description);
}
void setDescription(std::string description);
void setWUPSVersion(uint16_t major, uint16_t minor, uint16_t revision) {
this->wupsversion = WUPSVersion(major, minor, revision);
}
void setWUPSVersion(uint16_t major, uint16_t minor, uint16_t revision);
void setWUPSVersion(WUPSVersion &_wupsversion) {
this->wupsversion = _wupsversion;
}
void setWUPSVersion(const WUPSVersion &wupsVersion);
void setSize(size_t _size) {
this->size = _size;
}
void setSize(size_t size);
void setStorageId(std::string _storageId) {
this->storageId = std::move(_storageId);
}
void setStorageId(std::string storageId);
std::string name;
std::string author;
std::string version;
std::string license;
std::string buildtimestamp;
std::string description;
std::string storageId;
size_t size{};
WUPSVersion wupsversion = WUPSVersion(0, 0, 0);
std::string mName;
std::string mAuthor;
std::string mVersion;
std::string mLicense;
std::string mBuildTimestamp;
std::string mDescription;
std::string mStorageId;
size_t mSize = {};
WUPSVersion mWUPSVersion = WUPSVersion(0, 0, 0);
friend class PluginMetaInformationFactory;

View File

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

View File

@ -19,11 +19,10 @@
#include "PluginData.h"
#include "PluginMetaInformation.h"
#include "elfio/elfio.hpp"
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include <span>
#include <string_view>
enum PluginParseErrors {
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
#include "ImportRPLInformation.h"
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
class RelocationData {
public:
RelocationData(const char type, size_t offset, int32_t addend, void *destination, std::string name, std::shared_ptr<ImportRPLInformation> rplInfo) : type(type),
offset(offset),
addend(addend),
destination(destination),
name(std::move(name)),
rplInfo(std::move(rplInfo)) {
}
RelocationData(char type, size_t offset, int32_t addend, void *destination, std::string name, std::shared_ptr<ImportRPLInformation> rplInfo);
RelocationData(const RelocationData &o2) = default;
RelocationData(const RelocationData &o2);
virtual ~RelocationData() = default;
virtual ~RelocationData();
[[nodiscard]] char getType() const {
return type;
}
[[nodiscard]] char getType() const;
[[nodiscard]] size_t getOffset() const {
return offset;
}
[[nodiscard]] size_t getOffset() const;
[[nodiscard]] int32_t getAddend() const {
return addend;
}
[[nodiscard]] int32_t getAddend() const;
[[nodiscard]] const void *getDestination() const {
return destination;
}
[[nodiscard]] const void *getDestination() const;
[[nodiscard]] const std::string &getName() const {
return name;
}
[[nodiscard]] const std::string &getName() const;
[[nodiscard]] const ImportRPLInformation &getImportRPLInformation() const {
return *rplInfo;
}
[[nodiscard]] const ImportRPLInformation &getImportRPLInformation() const;
private:
char type;
size_t offset;
int32_t addend;
void *destination;
std::string name;
std::shared_ptr<ImportRPLInformation> rplInfo;
char mType;
size_t mOffset;
int32_t mAddend;
void *mDestination;
std::string mName;
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
#include <cstdint>
#include <string>
class SectionInfo {
public:
SectionInfo(std::string name, uint32_t address, uint32_t sectionSize) : name(std::move(name)),
address(address),
sectionSize(sectionSize) {
}
SectionInfo(std::string name, uint32_t address, uint32_t sectionSize);
[[nodiscard]] const std::string &getName() const {
return name;
}
[[nodiscard]] const std::string &getName() const;
[[nodiscard]] uint32_t getAddress() const {
return address;
}
[[nodiscard]] uint32_t getAddress() const;
[[nodiscard]] uint32_t getSize() const {
return sectionSize;
}
[[nodiscard]] uint32_t getSize() const;
[[nodiscard]] uint32_t isInSection(uint32_t addr) const {
return addr >= address && addr < address + sectionSize;
}
[[nodiscard]] uint32_t isInSection(uint32_t addr) const;
private:
std::string name;
uint32_t address{};
uint32_t sectionSize{};
std::string mName;
uint32_t mAddress = {};
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 <optional>
#include <string>
class WUPSVersion {
public:
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)) {}
WUPSVersion(int major, int minor, int revision);
static std::optional<WUPSVersion> createFromString(const std::string &versionStr) {
char *end;
errno = 0; // Initialize errno before calling strtol
static std::optional<WUPSVersion> createFromString(const std::string &versionStr);
auto major = strtol(versionStr.c_str(), &end, 10);
if (errno || *end != '.') {
return std::nullopt;
}
std::strong_ordering operator<=>(const WUPSVersion &other) 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));
}
[[nodiscard]] std::string toString() const;
private:
uint64_t mVersion{};
uint32_t mMajor;
uint32_t mMinor;
uint32_t mRevision;
};

View File

@ -13,23 +13,23 @@
// buffer width
#define DRC_WIDTH 0x380
bool DrawUtils::isBackBuffer;
bool DrawUtils::mIsBackBuffer;
uint8_t *DrawUtils::tvBuffer = nullptr;
uint32_t DrawUtils::tvSize = 0;
uint8_t *DrawUtils::drcBuffer = nullptr;
uint32_t DrawUtils::drcSize = 0;
uint32_t DrawUtils::usedTVWidth = 1280;
float DrawUtils::usedTVScale = 1.5f;
uint8_t *DrawUtils::mTVBuffer = nullptr;
uint32_t DrawUtils::mTVSize = 0;
uint8_t *DrawUtils::mDRCBuffer = nullptr;
uint32_t DrawUtils::mDRCSize = 0;
uint32_t DrawUtils::mUsedTVWidth = 1280;
float DrawUtils::mUsedTVScale = 1.5f;
static SFT pFont = {};
static Color font_col(0xFFFFFFFF);
void DrawUtils::initBuffers(void *tvBuffer_, uint32_t tvSize_, void *drcBuffer_, uint32_t drcSize_) {
DrawUtils::tvBuffer = (uint8_t *) tvBuffer_;
DrawUtils::tvSize = tvSize_;
DrawUtils::drcBuffer = (uint8_t *) drcBuffer_;
DrawUtils::drcSize = drcSize_;
void DrawUtils::initBuffers(void *tvBuffer, const uint32_t tvSize, void *drcBuffer, const uint32_t drcSize) {
DrawUtils::mTVBuffer = static_cast<uint8_t *>(tvBuffer);
DrawUtils::mTVSize = tvSize;
DrawUtils::mDRCBuffer = static_cast<uint8_t *>(drcBuffer);
DrawUtils::mDRCSize = drcSize;
bool bigScale = true;
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);
if (tvScanBufferWidth == 640) { // 480i/480p/576i 4:3
DrawUtils::usedTVWidth = 640;
DrawUtils::mUsedTVWidth = 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
DrawUtils::usedTVWidth = 896;
DrawUtils::mUsedTVWidth = 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
DrawUtils::usedTVWidth = 1280;
DrawUtils::mUsedTVWidth = 1280;
SetDCPitchReg(SCREEN_TV, 1280);
if (bigScale) {
DrawUtils::usedTVScale = 1.5;
DrawUtils::mUsedTVScale = 1.5;
} else {
DrawUtils::usedTVScale = 0.75f;
DrawUtils::mUsedTVScale = 0.75f;
if (tvResolution == AVM_TV_RESOLUTION_480I_PAL60 || tvResolution == AVM_TV_RESOLUTION_480I) {
AVMTvAspectRatio tvAspectRatio;
if (AVMGetTVAspectRatio(&tvAspectRatio) && tvAspectRatio == AVM_TV_ASPECT_RATIO_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
DrawUtils::usedTVWidth = 1920;
DrawUtils::mUsedTVWidth = 1920;
SetDCPitchReg(SCREEN_TV, 1920);
DrawUtils::usedTVScale = bigScale ? 2.25 : 1.125f;
DrawUtils::mUsedTVScale = bigScale ? 2.25 : 1.125f;
} else {
DrawUtils::usedTVWidth = tvScanBufferWidth;
DrawUtils::mUsedTVWidth = 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");
}
}
void DrawUtils::beginDraw() {
uint32_t pixel = *(uint32_t *) tvBuffer;
const uint32_t pixel = *reinterpret_cast<uint32_t *>(mTVBuffer);
// check which buffer is currently used
OSScreenPutPixelEx(SCREEN_TV, 0, 0, 0xABCDEF90);
if (*(uint32_t *) tvBuffer == 0xABCDEF90) {
isBackBuffer = false;
if (*reinterpret_cast<uint32_t *>(mTVBuffer) == 0xABCDEF90) {
mIsBackBuffer = false;
} else {
isBackBuffer = true;
mIsBackBuffer = true;
}
// restore the pixel we used for checking
*(uint32_t *) tvBuffer = pixel;
*reinterpret_cast<uint32_t *>(mTVBuffer) = pixel;
}
void DrawUtils::endDraw() {
@ -125,58 +125,58 @@ void DrawUtils::endDraw() {
OSScreenFlipBuffersEx(SCREEN_TV);
}
void DrawUtils::clear(Color col) {
void DrawUtils::clear(const Color col) {
OSScreenClearBufferEx(SCREEN_TV, 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) {
return;
}
float opacity = a / 255.0f;
const float opacity = a / 255.0f;
// put pixel in the drc buffer
uint32_t i = (x + y * DRC_WIDTH) * 4;
if (i + 3 < drcSize / 2) {
if (isBackBuffer) {
i += drcSize / 2;
if (i + 3 < mDRCSize / 2) {
if (mIsBackBuffer) {
i += mDRCSize / 2;
}
if (a == 0xFF) {
drcBuffer[i] = r;
drcBuffer[i + 1] = g;
drcBuffer[i + 2] = b;
mDRCBuffer[i] = r;
mDRCBuffer[i + 1] = g;
mDRCBuffer[i + 2] = b;
} else {
drcBuffer[i] = r * opacity + drcBuffer[i] * (1 - opacity);
drcBuffer[i + 1] = g * opacity + drcBuffer[i + 1] * (1 - opacity);
drcBuffer[i + 2] = b * opacity + drcBuffer[i + 2] * (1 - opacity);
mDRCBuffer[i] = r * opacity + mDRCBuffer[i] * (1 - opacity);
mDRCBuffer[i + 1] = g * opacity + mDRCBuffer[i + 1] * (1 - opacity);
mDRCBuffer[i + 2] = b * opacity + mDRCBuffer[i + 2] * (1 - opacity);
}
}
// 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 xx = (x * DrawUtils::usedTVScale); xx < ((x * DrawUtils::usedTVScale) + (uint32_t) DrawUtils::usedTVScale); xx++) {
uint32_t i = (xx + yy * DrawUtils::usedTVWidth) * 4;
if (i + 3 < tvSize / 2) {
if (isBackBuffer) {
i += tvSize / 2;
for (uint32_t yy = (y * DrawUtils::mUsedTVScale); yy < ((y * DrawUtils::mUsedTVScale) + (uint32_t) DrawUtils::mUsedTVScale); yy++) {
for (uint32_t xx = (x * DrawUtils::mUsedTVScale); xx < ((x * DrawUtils::mUsedTVScale) + (uint32_t) DrawUtils::mUsedTVScale); xx++) {
uint32_t i = (xx + yy * DrawUtils::mUsedTVWidth) * 4;
if (i + 3 < mTVSize / 2) {
if (mIsBackBuffer) {
i += mTVSize / 2;
}
if (a == 0xFF) {
tvBuffer[i] = r;
tvBuffer[i + 1] = g;
tvBuffer[i + 2] = b;
mTVBuffer[i] = r;
mTVBuffer[i + 1] = g;
mTVBuffer[i + 2] = b;
} else {
tvBuffer[i] = r * opacity + tvBuffer[i] * (1 - opacity);
tvBuffer[i + 1] = g * opacity + tvBuffer[i + 1] * (1 - opacity);
tvBuffer[i + 2] = b * opacity + tvBuffer[i + 2] * (1 - opacity);
mTVBuffer[i] = r * opacity + mTVBuffer[i] * (1 - opacity);
mTVBuffer[i + 1] = g * opacity + mTVBuffer[i + 1] * (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 xx = x; xx < x + w; xx++) {
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 + h - borderSize, w, borderSize, col);
drawRectFilled(x, 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') {
// invalid header
return;
}
uint32_t dataPos = __builtin_bswap32(*(uint32_t *) &(data[0x0A]));
uint32_t width = __builtin_bswap32(*(uint32_t *) &(data[0x12]));
uint32_t height = __builtin_bswap32(*(uint32_t *) &(data[0x16]));
const uint32_t width = __builtin_bswap32(*(uint32_t *) &(data[0x12]));
const uint32_t height = __builtin_bswap32(*(uint32_t *) &(data[0x16]));
if (dataPos == 0) {
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) {
void **data = (void **) png_get_io_ptr(png_ptr);
void **data = static_cast<void **>(png_get_io_ptr(png_ptr));
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);
if (png_ptr == nullptr) {
return;
@ -244,12 +244,12 @@ void DrawUtils::drawPNG(uint32_t x, uint32_t y, const uint8_t *data) {
uint32_t height = 0;
int bitDepth = 0;
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) {
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];
for (uint32_t yy = y; yy < y + height; yy++) {
@ -302,17 +302,17 @@ void DrawUtils::setFontSize(uint32_t size) {
sft_lmetrics(&pFont, &metrics);
}
void DrawUtils::setFontColor(Color col) {
void DrawUtils::setFontColor(const Color 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 x_max = x + bmp->width;
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 (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;
}
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);
}
}
}
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];
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;
}
void DrawUtils::print(uint32_t x, uint32_t y, const wchar_t *string, bool alignRight) {
auto penX = (int32_t) x;
auto penY = (int32_t) y;
void DrawUtils::print(const uint32_t x, const uint32_t y, const wchar_t *string, const bool alignRight) {
auto penX = static_cast<int32_t>(x);
auto penY = static_cast<int32_t>(y);
if (alignRight) {
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");
return;
} else {
draw_freetype_bitmap(&img, (int32_t) (penX + mtx.leftSideBearing), (int32_t) (penY + mtx.yOffset));
penX += (int32_t) mtx.advanceWidth;
draw_freetype_bitmap(&img, static_cast<int32_t>(penX + mtx.leftSideBearing), penY + mtx.yOffset);
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) {
auto *buffer = new wchar_t[strlen(string) + 1];
size_t num = mbstowcs(buffer, string, strlen(string));
if (num > 0) {
if (const size_t num = mbstowcs(buffer, string, strlen(string)); num > 0) {
buffer[num] = 0;
} else {
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;
return width;
@ -427,9 +426,9 @@ uint32_t DrawUtils::getTextWidth(const wchar_t *string) {
if (sft_gmetrics(&pFont, gid, &mtx) < 0) {
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
union Color {
explicit Color(uint32_t color) {
explicit Color(const uint32_t 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->g = g;
this->b = b;
@ -67,12 +67,12 @@ public:
static uint32_t getTextWidth(const wchar_t *string);
private:
static bool isBackBuffer;
static bool mIsBackBuffer;
static uint8_t *tvBuffer;
static uint32_t tvSize;
static uint8_t *drcBuffer;
static uint32_t drcSize;
static uint32_t usedTVWidth;
static float usedTVScale;
static uint8_t *mTVBuffer;
static uint32_t mTVSize;
static uint8_t *mDRCBuffer;
static uint32_t mDRCSize;
static uint32_t mUsedTVWidth;
static float mUsedTVScale;
};

View File

@ -1,6 +1,6 @@
#pragma once
#include <stdint.h>
#include <cstdint>
#include <wums/defines/relocation_defines.h>
#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
#include "utils.h"
#include <cstdint>
#include <memory>
class HeapMemoryFixedSize {
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
HeapMemoryFixedSize(const HeapMemoryFixedSize &) = delete;
HeapMemoryFixedSize &operator=(const HeapMemoryFixedSize &) = delete;
HeapMemoryFixedSize(HeapMemoryFixedSize &&other) noexcept
: mData(std::move(other.mData)), mSize(other.mSize) {
other.mSize = 0;
}
HeapMemoryFixedSize(HeapMemoryFixedSize &&other) noexcept;
HeapMemoryFixedSize &operator=(HeapMemoryFixedSize &&other) noexcept {
if (this != &other) {
mData = std::move(other.mData);
mSize = other.mSize;
other.mSize = 0;
}
return *this;
}
HeapMemoryFixedSize &operator=(HeapMemoryFixedSize &&other) noexcept;
explicit operator bool() const {
return mData != nullptr;
}
explicit operator bool() const;
[[nodiscard]] const void *data() const {
return mData.get();
}
[[nodiscard]] const void *data() const;
[[nodiscard]] std::size_t size() const {
return mSize;
}
[[nodiscard]] std::size_t size() const;
private:
std::unique_ptr<uint8_t[]> mData{};

View File

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

View File

@ -24,13 +24,12 @@
* for WiiXplorer 2010
***************************************************************************/
#include "StringTools.h"
#include <cstring>
#include <string>
#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 (show_ellipsis) {
return str.substr(0, width - 3) + "...";
@ -60,3 +59,33 @@ int32_t StringTools::strtokcmp(const char *string, const char *compare, const ch
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 <memory>
#include <string>
#include <vector>
#include <wut_types.h>
template<typename... Args>
std::string string_format(std::string_view format, Args... args) {
int size_s = std::snprintf(nullptr, 0, format.data(), args...) + 1; // Extra space for '\0'
auto size = static_cast<size_t>(size_s);
auto buf = make_unique_nothrow<char[]>(size);
std::string string_format(const std::string_view format, Args... args) {
const int size_s = std::snprintf(nullptr, 0, format.data(), args...) + 1; // Extra space for '\0'
const auto size = static_cast<size_t>(size_s);
const auto buf = make_unique_nothrow<char[]>(size);
if (!buf) {
DEBUG_FUNCTION_LINE_ERR("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 const char *FullpathToFilename(const char *path) {
if (!path)
return path;
static const char *FullpathToFilename(const char *path);
const char *ptr = path;
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--;
}
}
}
static void RemoveDoubleSlashes(std::string &str);
};

View File

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

View File

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

View File

@ -1,12 +1,13 @@
#include "CategoryRenderer.h"
#include "ConfigDefines.h"
#include "config/WUPSConfigCategory.h"
#include "utils/input/Input.h"
#include "ConfigRendererItem.h"
#include "ConfigRendererItemCategory.h"
#include "ConfigUtils.h"
#include "utils/DrawUtils.h"
#include "utils/StringTools.h"
#include "utils/logger.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) {
for (uint32_t i = 0; i < cat->getCategories().size() + cat->getItems().size(); i++) {
if (i < cat->getCategories().size()) {
@ -14,8 +15,8 @@ CategoryRenderer::CategoryRenderer(const GeneralConfigInformation *info, const W
assert(item);
mItemRenderer.push_back(std::move(item));
} else {
auto itemIndex = (int32_t) (i - cat->getCategories().size());
if (itemIndex < 0 || itemIndex >= (int32_t) cat->getItems().size()) {
const auto itemIndex = static_cast<int32_t>(i - cat->getCategories().size());
if (itemIndex < 0 || itemIndex >= static_cast<int32_t>(cat->getItems().size())) {
assert(false);
}
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.
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);
}
}
CategoryRenderer::~CategoryRenderer() {
if (mCursorPos < (int32_t) mItemRenderer.size()) {
if (mCursorPos < static_cast<int32_t>(mItemRenderer.size())) {
mItemRenderer[mCursorPos]->SetIsSelected(false);
}
}
@ -45,14 +46,13 @@ CategoryRenderer::~CategoryRenderer() {
ConfigSubState CategoryRenderer::Update(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData) {
switch (mState) {
case STATE_MAIN: {
auto res = UpdateStateMain(input, simpleInputData, complexInputData);
const auto res = UpdateStateMain(input, simpleInputData, complexInputData);
mFirstFrame = false;
return res;
}
case STATE_SUB: {
if (mSubCategoryRenderer) {
auto subResult = mSubCategoryRenderer->Update(input, simpleInputData, complexInputData);
if (subResult != SUB_STATE_RUNNING) {
if (const auto subResult = mSubCategoryRenderer->Update(input, simpleInputData, complexInputData); subResult != SUB_STATE_RUNNING) {
mNeedsRedraw = true;
mState = STATE_MAIN;
mFirstFrame = true;
@ -69,7 +69,7 @@ ConfigSubState CategoryRenderer::Update(Input &input, const WUPSConfigSimplePadD
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) {
return SUB_STATE_RETURN;
}
@ -77,8 +77,8 @@ ConfigSubState CategoryRenderer::UpdateStateMain(Input &input, const WUPSConfigS
return SUB_STATE_RUNNING;
}
auto totalElementSize = mItemRenderer.size();
int32_t prevSelectedItem = mCursorPos;
const auto totalElementSize = mItemRenderer.size();
const int32_t prevSelectedItem = mCursorPos;
if (mIsItemMovementAllowed) {
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) {
mCursorPos--;
} 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) {
mSubCategoryRenderer.reset();
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) {
mCursorPos = (int32_t) totalElementSize - 1;
} else if (mCursorPos > (int32_t) (totalElementSize - 1)) {
mCursorPos = static_cast<int32_t>(totalElementSize) - 1;
} else if (mCursorPos > static_cast<int32_t>(totalElementSize - 1)) {
mCursorPos = 0;
}
@ -139,7 +139,7 @@ ConfigSubState CategoryRenderer::UpdateStateMain(Input &input, const WUPSConfigS
mIsItemMovementAllowed = mItemRenderer[mCursorPos]->IsMovementAllowed();
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);
}
@ -152,7 +152,7 @@ void CategoryRenderer::ResetNeedsRedraw() {
if (mSubCategoryRenderer) {
mSubCategoryRenderer->ResetNeedsRedraw();
}
for (auto &item : mItemRenderer) {
for (const auto &item : mItemRenderer) {
item->ResetNeedsRedraw();
}
}
@ -196,20 +196,20 @@ void CategoryRenderer::RenderStateMain() const {
DrawUtils::beginDraw();
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);
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::endDraw();
return;
}
auto totalElementSize = static_cast<int>(mItemRenderer.size());
const auto totalElementSize = static_cast<int>(mItemRenderer.size());
// Calculate the range of items to display
int start = std::max(0, mRenderOffset);
int end = std::min(start + MAX_BUTTONS_ON_SCREEN, totalElementSize);
const int start = std::max(0, mRenderOffset);
const int end = std::min(start + MAX_BUTTONS_ON_SCREEN, totalElementSize);
DrawUtils::beginDraw();
@ -217,7 +217,7 @@ void CategoryRenderer::RenderStateMain() const {
uint32_t yOffset = 8 + 24 + 8 + 4;
for (int32_t i = start; i < end; i++) {
bool isHighlighted = (i == mCursorPos);
const bool isHighlighted = (i == mCursorPos);
mItemRenderer[i]->Draw(yOffset, isHighlighted);
yOffset += 42 + 8;
}
@ -253,6 +253,6 @@ void CategoryRenderer::RenderMainLayout() const {
// draw home button
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);
}

View File

@ -1,12 +1,14 @@
#pragma once
#include "../DrawUtils.h"
#include "ConfigRendererItem.h"
#include "ConfigRendererItemCategory.h"
#include "ConfigDefines.h"
#include "ConfigDisplayItem.h"
#include "ConfigRendererItemGeneric.h"
#include "ConfigUtils.h"
#include "config/WUPSConfigCategory.h"
#include "utils/input/Input.h"
#include <cstdint>
#include <memory>
#include <vector>
class CategoryRenderer {
@ -24,7 +26,7 @@ public:
void ResetNeedsRedraw();
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;

View File

@ -2,7 +2,6 @@
#include <cstdint>
#include <gx2/surface.h>
#include <string>
#define COLOR_BACKGROUND Color(238, 238, 238, 255)
#define COLOR_TEXT Color(51, 51, 51, 255)
@ -23,7 +22,6 @@ struct StoredBuffer {
GX2BufferingMode buffering_mode;
};
enum ConfigSubState {
SUB_STATE_RUNNING = 0,
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
#include "config/WUPSConfig.h"
#include <memory>
#include <string>
struct GeneralConfigInformation {
std::string name;
@ -10,15 +12,11 @@ struct GeneralConfigInformation {
class ConfigDisplayItem {
public:
ConfigDisplayItem(GeneralConfigInformation &info, std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> config) : mConfig(std::move(config)), mInfo(std::move(info)) {
assert(mConfig);
}
[[nodiscard]] const GeneralConfigInformation &getConfigInformation() const {
return mInfo;
}
[[nodiscard]] const WUPSConfigAPIBackend::WUPSConfig &getConfig() const {
return *mConfig;
}
ConfigDisplayItem(GeneralConfigInformation &info, std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> config);
[[nodiscard]] const GeneralConfigInformation &getConfigInformation() const;
[[nodiscard]] const WUPSConfigAPIBackend::WUPSConfig &getConfig() const;
private:
std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> mConfig;

View File

@ -1,67 +1,67 @@
#include "ConfigRenderer.h"
#include "globals.h"
#include "utils/DrawUtils.h"
#include "utils/logger.h"
#include "utils/utils.h"
void ConfigRenderer::RenderStateMain() const {
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);
// draw top bar
DrawUtils::setFontSize(24);
DrawUtils::print(16, 6 + 24, "Wii U Plugin System Config Menu");
DrawUtils::setFontSize(18);
DrawUtils::print(SCREEN_WIDTH - 16, 8 + 24, 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);
}
// 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();
ConfigRenderer::ConfigRenderer(std::vector<ConfigDisplayItem> &&vec) : mConfigs(std::move(vec)) {
}
void ConfigRenderer::drawConfigEntry(uint32_t yOffset, const GeneralConfigInformation &configInformation, bool isHighlighted) const {
DrawUtils::setFontColor(COLOR_TEXT);
ConfigRenderer::~ConfigRenderer() = default;
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);
ConfigSubState ConfigRenderer::Update(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData) {
switch (mState) {
case STATE_MAIN:
return UpdateStateMain(input);
case STATE_SUB: {
if (mCategoryRenderer) {
if (const auto subResult = mCategoryRenderer->Update(input, simpleInputData, complexInputData); 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;
}
DrawUtils::setFontSize(24);
DrawUtils::print(16 * 2, yOffset + 8 + 24, configInformation.name.c_str());
uint32_t sz = DrawUtils::getTextWidth(configInformation.name.c_str());
DrawUtils::setFontSize(12);
DrawUtils::print(16 * 2 + sz + 4, yOffset + 8 + 24, configInformation.author.c_str());
DrawUtils::print(SCREEN_WIDTH - 16 * 2, yOffset + 8 + 24, configInformation.version.c_str(), true);
void ConfigRenderer::Render() const {
switch (mState) {
case STATE_MAIN:
RenderStateMain();
break;
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) {
@ -69,9 +69,9 @@ ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) {
mNeedRedraw = true;
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) {
mCursorPos++;
} else if (input.data.buttons_d & Input::eButtons::BUTTON_LEFT) {
@ -126,59 +126,68 @@ ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) {
return SUB_STATE_RUNNING;
}
bool ConfigRenderer::NeedsRedraw() const {
if (mNeedRedraw) {
return true;
} else if (mCategoryRenderer) {
return mCategoryRenderer->NeedsRedraw();
void ConfigRenderer::RenderStateMain() const {
const auto totalElementSize = static_cast<int32_t>(mConfigs.size());
// Calculate the range of items to display
const int start = std::max(0, mRenderOffset);
const 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;
}
return false;
DrawUtils::setFontColor(COLOR_TEXT);
// draw top bar
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);
}
// draw home button
DrawUtils::setFontSize(18);
const auto exitHint = "\ue044 Exit";
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHint) / 2, SCREEN_HEIGHT - 10, exitHint, true);
DrawUtils::endDraw();
}
void ConfigRenderer::ResetNeedsRedraw() {
mNeedRedraw = false;
if (mCategoryRenderer) {
mCategoryRenderer->ResetNeedsRedraw();
}
}
void ConfigRenderer::DrawConfigEntry(const uint32_t yOffset, const GeneralConfigInformation &configInformation, const bool isHighlighted) const {
DrawUtils::setFontColor(COLOR_TEXT);
void ConfigRenderer::Render() const {
switch (mState) {
case STATE_MAIN:
RenderStateMain();
break;
case STATE_SUB: {
if (mCategoryRenderer) {
mCategoryRenderer->Render();
if (isHighlighted) {
DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 4, COLOR_BORDER_HIGHLIGHTED);
} 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) {
switch (mState) {
case STATE_MAIN:
return UpdateStateMain(input);
case STATE_SUB: {
if (mCategoryRenderer) {
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;
DrawUtils::setFontSize(24);
DrawUtils::print(16 * 2, yOffset + 8 + 24, configInformation.name.c_str());
const uint32_t sz = DrawUtils::getTextWidth(configInformation.name.c_str());
DrawUtils::setFontSize(12);
DrawUtils::print(16 * 2 + sz + 4, yOffset + 8 + 24, configInformation.author.c_str());
DrawUtils::print(SCREEN_WIDTH - 16 * 2, yOffset + 8 + 24, configInformation.version.c_str(), true);
}
void ConfigRenderer::CallOnCloseCallback(const GeneralConfigInformation &info, const std::vector<std::unique_ptr<WUPSConfigAPIBackend::WUPSConfigCategory>> &categories) {

View File

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

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
#include "ConfigRendererItemGeneric.h"
#include "config/WUPSConfigItem.h"
class ConfigRendererItem : public ConfigRendererItemGeneric {
#include <cstdint>
#include <string>
#include <wups/config.h>
class ConfigRendererItem final : public ConfigRendererItemGeneric {
public:
explicit ConfigRendererItem(const WUPSConfigAPIBackend::WUPSConfigItem *item) : mItem(item) {
assert(item);
}
explicit ConfigRendererItem(const WUPSConfigAPIBackend::WUPSConfigItem *item);
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);
}
void Draw(uint32_t yOffset, bool isHighlighted) const override;
std::string GetValueToPrint(bool isHighlighted) {
return isHighlighted ? mItem->getCurrentValueSelectedDisplay() : mItem->getCurrentValueDisplay();
}
[[nodiscard]] std::string GetValueToPrint(bool isHighlighted) const;
void Update(bool isHighlighted) override {
const auto newText = GetValueToPrint(isHighlighted);
void Update(bool isHighlighted) override;
if (mCurItemText != newText) {
mNeedsDraw = true;
}
mCurItemText = newText;
}
void ResetNeedsRedraw() override;
void ResetNeedsRedraw() override {
mNeedsDraw = false;
}
[[nodiscard]] bool NeedsRedraw() const override;
[[nodiscard]] bool NeedsRedraw() const override {
return mNeedsDraw;
}
void SetIsSelected(bool isSelected) override;
void SetIsSelected(bool isSelected) override {
mItem->onSelected(isSelected);
}
void OnButtonPressed(WUPSConfigButtons buttons) override;
void OnButtonPressed(WUPSConfigButtons buttons) override {
mItem->onButtonPressed(buttons);
}
[[nodiscard]] bool IsMovementAllowed() const override;
[[nodiscard]] bool IsMovementAllowed() const override {
return mItem->isMovementAllowed();
}
void OnInput(WUPSConfigSimplePadData input) override;
void OnInput(WUPSConfigSimplePadData input) override {
mItem->onInput(input);
}
void OnInputEx(WUPSConfigComplexPadData input) override {
mItem->onInputEx(input);
}
void OnInputEx(WUPSConfigComplexPadData input) override;
private:
const WUPSConfigAPIBackend::WUPSConfigItem *mItem;
const WUPSConfigAPIBackend::WUPSConfigItem *mItem = nullptr;
std::string mCurItemText;
bool mNeedsDraw = true;
};

View File

@ -1,8 +1,9 @@
#pragma once
#include "ConfigRendererItemGeneric.h"
#include "config/WUPSConfigCategory.h"
#include <cassert>
class ConfigRendererItemCategory : public ConfigRendererItemGeneric {
class ConfigRendererItemCategory final : public ConfigRendererItemGeneric {
public:
explicit ConfigRendererItemCategory(const WUPSConfigAPIBackend::WUPSConfigCategory *category) : mCategory(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
#include "../DrawUtils.h"
#include "ConfigDefines.h"
#include <cstdint>
#include <string>
#include <wups/config.h>
class ConfigRendererItemGeneric {
public:
virtual ~ConfigRendererItemGeneric() = default;
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);
}
virtual ~ConfigRendererItemGeneric();
DrawUtils::setFontSize(24);
DrawUtils::setFontColor(COLOR_TEXT);
DrawUtils::print(16 * 2, yOffset + 8 + 24, displayName.c_str());
}
virtual void drawGenericBoxAndText(uint32_t yOffset, const std::string &displayName, bool isHighlighted) const;
virtual void Draw(uint32_t yOffset, bool isHighlighted) const = 0;
@ -26,17 +18,13 @@ public:
virtual void ResetNeedsRedraw() = 0;
virtual void SetIsSelected(bool) {
}
virtual void SetIsSelected(bool);
virtual void OnButtonPressed(WUPSConfigButtons) {
}
virtual void OnInput(WUPSConfigSimplePadData) {
}
virtual void OnInputEx(WUPSConfigComplexPadData) {
}
virtual void OnButtonPressed(WUPSConfigButtons);
[[nodiscard]] virtual bool IsMovementAllowed() const {
return true;
}
virtual void OnInput(WUPSConfigSimplePadData);
virtual void OnInputEx(WUPSConfigComplexPadData);
[[nodiscard]] virtual bool IsMovementAllowed() const;
};

View File

@ -1,24 +1,25 @@
#include "ConfigUtils.h"
#include "../../globals.h"
#include "../DrawUtils.h"
#include "../dc.h"
#include "../logger.h"
#include "ConfigRenderer.h"
#include "config/WUPSConfigAPI.h"
#include "hooks.h"
#include "utils/DrawUtils.h"
#include "utils/dc.h"
#include "utils/input/CombinedInput.h"
#include "utils/input/Input.h"
#include "utils/input/VPADInput.h"
#include "utils/input/WPADInput.h"
#include "utils/logger.h"
#include "utils/utils.h"
#include "version.h"
#include <avm/tv.h>
#include <coreinit/screen.h>
#include <gx2/display.h>
#include <algorithm>
#include <globals.h>
#include <memory/mappedmemory.h>
#include <ranges>
#include <string>
#include <memory>
#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;
if (buttons & Input::eButtons::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) {
pressedButtons |= WUPS_CONFIG_BUTTON_DOWN;
}
return (WUPS_CONFIG_SIMPLE_INPUT) pressedButtons;
return static_cast<WUPS_CONFIG_SIMPLE_INPUT>(pressedButtons);
}
void ConfigUtils::displayMenu() {
@ -82,11 +83,9 @@ void ConfigUtils::displayMenu() {
info.version = plugin.getMetaInformation().getVersion();
std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> config;
const auto configData = plugin.getConfigData();
if (configData) {
const auto configHandleOpt = configData->createConfig();
if (configHandleOpt) {
WUPSConfigAPIStatus callbackResult = configData->CallMenuOpenendCallback(configHandleOpt.value());
if (const auto configData = plugin.getConfigData()) {
if (const auto configHandleOpt = configData->createConfig()) {
WUPSConfigAPIStatus callbackResult = configData->CallMenuOpenedCallback(configHandleOpt.value());
config = WUPSConfigAPIBackend::Intern::PopConfigByHandle(configHandleOpt.value());
if (!config) {
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");
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) {
DEBUG_FUNCTION_LINE_WARN("Hook returned empty handle");
break;
@ -127,15 +126,11 @@ void ConfigUtils::displayMenu() {
}
// Sort Configs by name
std::sort(
configs.begin(),
configs.end(),
std::ranges::sort(configs,
[](const ConfigDisplayItem &lhs, const ConfigDisplayItem &rhs) {
auto &str1 = lhs.getConfigInformation().name;
auto &str2 = rhs.getConfigInformation().name;
return lexicographical_compare(
begin(str1), end(str1),
begin(str2), end(str2),
return std::ranges::lexicographical_compare(str1, str2,
[](const char &char1, const char &char2) {
return tolower(char1) < tolower(char2);
});
@ -156,7 +151,7 @@ void ConfigUtils::displayMenu() {
WPAD_CHAN_6,
};
auto startTime = OSGetTime();
OSTime startTime;
bool skipFirstInput = true;
gOnlyAcceptFromThread = OSGetCurrentThread();
@ -239,23 +234,23 @@ void ConfigUtils::displayMenu() {
void ConfigUtils::openConfigMenu() {
gOnlyAcceptFromThread = OSGetCurrentThread();
bool wasHomeButtonMenuEnabled = OSIsHomeButtonMenuEnabled();
const bool wasHomeButtonMenuEnabled = OSIsHomeButtonMenuEnabled();
// Save copy of DC reg values
auto tvRender1 = DCReadReg32(SCREEN_TV, D1GRPH_CONTROL_REG);
auto tvRender2 = DCReadReg32(SCREEN_TV, D1GRPH_ENABLE_REG);
auto tvPitch1 = DCReadReg32(SCREEN_TV, D1GRPH_PITCH_REG);
auto tvPitch2 = DCReadReg32(SCREEN_TV, D1OVL_PITCH_REG);
const auto tvRender1 = DCReadReg32(SCREEN_TV, D1GRPH_CONTROL_REG);
const auto tvRender2 = DCReadReg32(SCREEN_TV, D1GRPH_ENABLE_REG);
const auto tvPitch1 = DCReadReg32(SCREEN_TV, D1GRPH_PITCH_REG);
const auto tvPitch2 = DCReadReg32(SCREEN_TV, D1OVL_PITCH_REG);
auto drcRender1 = DCReadReg32(SCREEN_DRC, D1GRPH_CONTROL_REG);
auto drcRender2 = DCReadReg32(SCREEN_DRC, D1GRPH_ENABLE_REG);
auto drcPitch1 = DCReadReg32(SCREEN_DRC, D1GRPH_PITCH_REG);
auto drcPitch2 = DCReadReg32(SCREEN_DRC, D1OVL_PITCH_REG);
const auto drcRender1 = DCReadReg32(SCREEN_DRC, D1GRPH_CONTROL_REG);
const auto drcRender2 = DCReadReg32(SCREEN_DRC, D1GRPH_ENABLE_REG);
const auto drcPitch1 = DCReadReg32(SCREEN_DRC, D1GRPH_PITCH_REG);
const auto drcPitch2 = DCReadReg32(SCREEN_DRC, D1OVL_PITCH_REG);
OSScreenInit();
uint32_t screen_buf0_size = OSScreenGetBufferSizeEx(SCREEN_TV);
uint32_t screen_buf1_size = OSScreenGetBufferSizeEx(SCREEN_DRC);
const uint32_t screen_buf0_size = OSScreenGetBufferSizeEx(SCREEN_TV);
const uint32_t screen_buf1_size = OSScreenGetBufferSizeEx(SCREEN_DRC);
void *screenbuffer0 = MEMAllocFromMappedMemoryForGX2Ex(screen_buf0_size, 0x100);
void *screenbuffer1 = MEMAllocFromMappedMemoryForGX2Ex(screen_buf1_size, 0x100);
@ -363,7 +358,7 @@ void ConfigUtils::renderBasicScreen(std::string_view text) {
DrawUtils::setFontSize(24);
DrawUtils::print(16, 6 + 24, "Wii U Plugin System Config Menu");
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);
// 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::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());
// draw home button
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::endDraw();

View File

@ -1,13 +1,8 @@
#pragma once
#include "ConfigDefines.h"
#include "ConfigDisplayItem.h"
#include "config/WUPSConfig.h"
#include "utils/input/Input.h"
#include <gx2/enum.h>
#include <memory>
#include <string>
#include <cstdint>
#include <string_view>
#include <wups/config.h>
#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);
static inline uint32_t DCReadReg32(OSScreenID screen, uint32_t index) {
static uint32_t DCReadReg32(const OSScreenID screen, const uint32_t index) {
if (OSIsECOMode()) {
return 0;
}
auto regs = (uint32_t *) __OSPhysicalToEffectiveUncached(0xc200000);
const auto regs = reinterpret_cast<uint32_t *>(__OSPhysicalToEffectiveUncached(0xc200000));
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()) {
return;
}
auto regs = (uint32_t *) __OSPhysicalToEffectiveUncached(0xc200000);
const auto regs = reinterpret_cast<uint32_t *>(__OSPhysicalToEffectiveUncached(0xc200000));
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_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, D1OVL_PITCH_REG, pitch);
}

View File

@ -1,8 +1,13 @@
#include "../PluginManagement.h"
#include "../globals.h"
#include "../plugin/PluginDataFactory.h"
#include "../plugin/PluginMetaInformationFactory.h"
#include "globals.h"
#include "logger.h"
#include "plugin/PluginContainer.h"
#include "plugin/PluginData.h"
#include "plugin/PluginDataFactory.h"
#include "plugin/PluginMetaInformation.h"
#include "plugin/PluginMetaInformationFactory.h"
#include "utils.h"
#include <ranges>
#include <wums.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;
}
std::lock_guard<std::mutex> lock(gLoadedDataMutex);
std::lock_guard lock(gLoadedDataMutex);
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;
for (const auto &pluginData : gLoadedData) {
@ -65,7 +70,7 @@ extern "C" PluginBackendApiErrorType WUPSLoadPluginAsData(WUPSBackendGetPluginIn
if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) {
pluginData = PluginDataFactory::load(path);
} 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 {
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) {
pluginInfo = PluginMetaInformationFactory::loadPlugin(path, error);
} 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 {
if (errOut) {
*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) {
PluginBackendApiErrorType res = PLUGIN_BACKEND_API_ERROR_NONE;
if (plugin_container_handle_list == nullptr || buffer_size == 0) {
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++) {
auto handle = plugin_container_handle_list[i];
const auto handle = plugin_container_handle_list[i];
bool found = false;
for (const auto &curContainer : gLoadedPlugins) {
if (curContainer.getHandle() == handle) {
auto pluginData = curContainer.getPluginDataCopy();
plugin_data_list[i] = (uint32_t) pluginData->getHandle();
plugin_data_list[i] = pluginData->getHandle();
gLoadedData.insert(std::move(pluginData));
found = true;
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) {
@ -264,7 +268,7 @@ extern "C" PluginBackendApiErrorType WUPSGetNumberOfLoadedPlugins(uint32_t *outC
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;
if (out_count != nullptr) {
*out_count = 0;
@ -277,13 +281,13 @@ extern "C" PluginBackendApiErrorType WUPSGetSectionInformationForPlugin(const wu
const auto &sectionInfoList = curContainer.getPluginInformation().getSectionInfoList();
uint32_t offset = 0;
for (auto const &[key, sectionInfo] : sectionInfoList) {
for (auto const &sectionInfo : sectionInfoList | std::views::values) {
if (offset >= buffer_size) {
break;
}
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);
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();
offset++;
}
@ -306,19 +310,19 @@ extern "C" PluginBackendApiErrorType WUPSWillReloadPluginsOnNextLaunch(bool *out
if (out == nullptr) {
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
}
std::lock_guard<std::mutex> lock(gLoadedDataMutex);
std::lock_guard lock(gLoadedDataMutex);
*out = !gLoadOnNextLaunch.empty();
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) {
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
}
for (const auto &curContainer : gLoadedPlugins) {
if (curContainer.getHandle() == handle) {
*textAddress = (void *) curContainer.getPluginInformation().getTextMemory().data();
*dataAddress = (void *) curContainer.getPluginInformation().getDataMemory().data();
*textAddress = const_cast<void *>(curContainer.getPluginInformation().getTextMemory().data());
*dataAddress = const_cast<void *>(curContainer.getPluginInformation().getDataMemory().data());
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);
}
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);
}

View File

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

View File

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

View File

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

View File

@ -20,15 +20,15 @@
#include <padscore/kpad.h>
#include <padscore/wpad.h>
class WPADInput : public Input {
class WPADInput final : public Input {
public:
WPADInput(KPADChan channel) {
WPADInput(const KPADChan 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;
if (buttons & WPAD_BUTTON_LEFT)
@ -73,7 +73,7 @@ public:
return conv_buttons;
}
uint32_t remapClassicButtons(uint32_t buttons) {
uint32_t remapClassicButtons(const uint32_t buttons) {
uint32_t conv_buttons = 0;
if (buttons & WPAD_CLASSIC_BUTTON_LEFT)
@ -124,7 +124,7 @@ public:
return conv_buttons;
}
bool update(int32_t width, int32_t height) {
bool update(const int32_t width, const int32_t height) {
lastData = data;
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;
}
endPts = calloc(sizeof(uint_fast16_t), numContours);
endPts = calloc(numContours, sizeof(uint_fast16_t));
if (endPts == NULL) {
goto failure;
}
flags = calloc(sizeof(uint8_t), numPts);
flags = calloc(numPts, sizeof(uint8_t));
if (flags == NULL) {
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;
cells = calloc(sizeof(Cell), numPixels);
cells = calloc(numPixels, sizeof(Cell));
if (!cells) {
return -1;
}

View File

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

View File

@ -1,14 +1,10 @@
#pragma once
#include "utils/base64.h"
#include "utils/logger.h"
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <variant>
#include <vector>
enum class StorageItemType { None,
Boolean,
String,
@ -19,12 +15,9 @@ enum class StorageItemType { None,
class StorageItem {
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 {
return (uint32_t) this;
}
[[nodiscard]] uint32_t getHandle() const;
// Setters for different types
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
#include "StorageItem.h"
#include "StorageSubItem.h"
#include "utils/logger.h"
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>
#include <wups/storage.h>
class StorageItemRoot : public StorageSubItem {
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 {
return mPluginName;
}
[[nodiscard]] const std::string &getPluginId() const;
void wipe() {
mSubCategories.clear();
mItems.clear();
}
void wipe();
private:
std::string mPluginName;

View File

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

View File

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

View File

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

View File

@ -3,6 +3,7 @@
#include "logger.h"
#include <algorithm>
#include <coreinit/ios.h>
#include <malloc.h>
#include <string>
static std::string sPluginPath;
@ -10,11 +11,9 @@ std::string getPluginPath() {
if (!sPluginPath.empty()) {
return sPluginPath;
}
char environmentPath[0x100];
memset(environmentPath, 0, sizeof(environmentPath));
char environmentPath[0x100] = {};
auto handle = IOS_Open("/dev/mcp", IOS_OPEN_READ);
if (handle >= 0) {
if (const auto handle = IOS_Open("/dev/mcp", IOS_OPEN_READ); handle >= 0) {
int in = 0xF9; // IPC_CUSTOM_COPY_ENVIRONMENT_PATH
if (IOS_Ioctl(handle, 100, &in, sizeof(in), environmentPath, sizeof(environmentPath)) != IOS_ERROR_OK) {
return "fs:/vol/external01/wiiu/plugins";
@ -27,7 +26,7 @@ std::string getPluginPath() {
}
// 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];
size_t i, j;
ascii[16] = '\0';
@ -71,7 +70,7 @@ OSDynLoad_Error CustomDynLoadAlloc(int32_t size, int32_t align, void **outAddr)
align = -4;
}
if (!(*outAddr = memalign(align, size))) {
if (*outAddr = memalign(align, size); !*outAddr) {
return OS_DYNLOAD_OUT_OF_MEMORY;
}
// 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);
// Remove from list
auto it = std::find(gAllocatedAddresses.begin(), gAllocatedAddresses.end(), addr);
if (it != gAllocatedAddresses.end()) {
if (const auto it = std::ranges::find(gAllocatedAddresses, addr); it != gAllocatedAddresses.end()) {
gAllocatedAddresses.erase(it);
}
}

View File

@ -4,7 +4,6 @@
#include <coreinit/dynload.h>
#include <cstdint>
#include <forward_list>
#include <malloc.h>
#include <memory>
#include <mutex>
#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 "elfio/elfio_utils.hpp"
#include "logger.h"
#include "utils.h"
#include <zlib.h>
#include <elfio/elfio_utils.hpp>
class wiiu_zlib : public ELFIO::compression_interface {
class wiiu_zlib final : public ELFIO::compression_interface {
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 {
read_uncompressed_size(data, convertor, uncompressed_size);
auto result = make_unique_nothrow<char[]>((uint32_t) (uncompressed_size + 1));
if (result == nullptr) {
return nullptr;
}
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;
int z_ret;
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;
}
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;
private:
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 read_uncompressed_size(const char *&data, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword &uncompressed_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);
}
static void write_compressed_size(std::unique_ptr<char[]> &result, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword compressed_size);
};

View File

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