mirror of
https://github.com/wiiu-env/WiiUPluginLoaderBackend.git
synced 2024-12-22 02:51:56 +01:00
Code cleanup
This commit is contained in:
parent
5893ac2f18
commit
447e1eb218
.github/workflows
source
PluginManagement.cpp
config
WUPSConfig.hWUPSConfigAPI.cppWUPSConfigAPIDeprecated.cppWUPSConfigCategory.cppWUPSConfigCategory.hWUPSConfigItem.cppWUPSConfigItem.hWUPSConfigItemV1.cppWUPSConfigItemV1.hWUPSConfigItemV2.cppWUPSConfigItemV2.h
elfio
fs
globals.cppglobals.hhooks.hmain.cpppatcher
plugin
FunctionData.cppFunctionData.hFunctionSymbolData.cppFunctionSymbolData.hHookData.cppHookData.hImportRPLInformation.cppImportRPLInformation.hPluginConfigData.cppPluginConfigData.hPluginContainer.cppPluginContainer.hPluginData.cppPluginData.hPluginDataFactory.cppPluginDataFactory.hPluginInformation.cppPluginInformation.hPluginInformationFactory.cppPluginInformationFactory.hPluginMetaInformation.cppPluginMetaInformation.hPluginMetaInformationFactory.cppPluginMetaInformationFactory.hRelocationData.cppRelocationData.hSectionInfo.cppSectionInfo.hWUPSVersion.cppWUPSVersion.h
utils
DrawUtils.cppDrawUtils.hElfUtils.hHeapMemoryFixedSize.cppHeapMemoryFixedSize.hStorageUtilsDeprecated.cppStringTools.cppStringTools.hbase64.cppbase64.h
version.hconfig
CategoryRenderer.cppCategoryRenderer.hConfigDefines.hConfigDisplayItem.cppConfigDisplayItem.hConfigRenderer.cppConfigRenderer.hConfigRendererItem.cppConfigRendererItem.hConfigRendererItemCategory.hConfigRendererItemGeneric.cppConfigRendererItemGeneric.hConfigUtils.cppConfigUtils.h
dc.hexports.cppinput
schrift.cstorage
StorageItem.cppStorageItem.hStorageItemRoot.cppStorageItemRoot.hStorageSubItem.cppStorageSubItem.hStorageUtils.cppStorageUtils.h
utils.cpputils.hwiiu_zlib.cppwiiu_zlib.hpp
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -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: |
|
||||
|
2
.github/workflows/pr.yml
vendored
2
.github/workflows/pr.yml
vendored
@ -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: |
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "WUPSConfig.h"
|
||||
#include "WUPSConfigAPI.h"
|
||||
#include "utils/logger.h"
|
||||
#include <wums.h>
|
||||
#include <wups/config.h>
|
||||
|
||||
|
36
source/config/WUPSConfigCategory.cpp
Normal file
36
source/config/WUPSConfigCategory.cpp
Normal 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
|
@ -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;
|
||||
}
|
||||
\return Returns the name of this WUPSConfigCategory
|
||||
**/
|
||||
[[nodiscard]] const std::string &getName() const;
|
||||
|
||||
/**
|
||||
\brief Adds a given WUPSConfigItem to this WUPSConfigCategory.
|
||||
@ -48,28 +44,18 @@ namespace WUPSConfigAPIBackend {
|
||||
\return On success, true will be returned.
|
||||
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;
|
||||
}
|
||||
\return Returns a vector with all items.
|
||||
**/
|
||||
[[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.
|
||||
@ -81,11 +67,8 @@ namespace WUPSConfigAPIBackend {
|
||||
\return On success, true will be returned.
|
||||
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;
|
||||
|
27
source/config/WUPSConfigItem.cpp
Normal file
27
source/config/WUPSConfigItem.cpp
Normal 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
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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] == '/')
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include "globals.h"
|
||||
#include "plugin/PluginContainer.h"
|
||||
#include "plugin/PluginData.h"
|
||||
|
||||
StoredBuffer gStoredTVBuffer = {};
|
||||
StoredBuffer gStoredDRCBuffer = {};
|
||||
|
@ -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;
|
||||
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "plugin/PluginContainer.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <wups/hooks.h>
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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.");
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
26
source/plugin/FunctionSymbolData.cpp
Normal file
26
source/plugin/FunctionSymbolData.cpp
Normal 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;
|
||||
}
|
@ -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;
|
||||
|
16
source/plugin/HookData.cpp
Normal file
16
source/plugin/HookData.cpp
Normal 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;
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
20
source/plugin/ImportRPLInformation.cpp
Normal file
20
source/plugin/ImportRPLInformation.cpp
Normal 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_");
|
||||
}
|
@ -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;
|
||||
|
@ -1,8 +1,12 @@
|
||||
#include "PluginConfigData.h"
|
||||
|
||||
PluginConfigData::PluginConfigData(std::string_view name, WUPSConfigAPI_MenuOpenedCallback openedCallback, WUPSConfigAPI_MenuClosedCallback closedCallback) : mName(name),
|
||||
mOpenedCallback(openedCallback),
|
||||
mClosedCallback(closedCallback) {
|
||||
#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) {
|
||||
}
|
||||
|
||||
std::optional<WUPSConfigHandle> PluginConfigData::createConfig() const {
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1,22 +1,24 @@
|
||||
#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)),
|
||||
mPluginInformation(std::move(src.mPluginInformation)),
|
||||
mPluginData(std::move(src.mPluginData)),
|
||||
mPluginConfigData(std::move(src.mPluginConfigData)),
|
||||
storageRootItem(src.storageRootItem)
|
||||
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)),
|
||||
storageRootItem(src.storageRootItem)
|
||||
|
||||
{
|
||||
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);
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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 {
|
||||
|
79
source/plugin/PluginMetaInformation.cpp
Normal file
79
source/plugin/PluginMetaInformation.cpp
Normal 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);
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
42
source/plugin/RelocationData.cpp
Normal file
42
source/plugin/RelocationData.cpp
Normal 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;
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
24
source/plugin/SectionInfo.cpp
Normal file
24
source/plugin/SectionInfo.cpp
Normal 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;
|
||||
}
|
@ -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 = {};
|
||||
};
|
||||
|
41
source/plugin/WUPSVersion.cpp
Normal file
41
source/plugin/WUPSVersion.cpp
Normal 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);
|
||||
}
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
static SFT pFont = {};
|
||||
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]));
|
||||
uint32_t dataPos = __builtin_bswap32(*(uint32_t *) &(data[0x0A]));
|
||||
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;
|
||||
@ -240,17 +240,17 @@ void DrawUtils::drawPNG(uint32_t x, uint32_t y, const uint8_t *data) {
|
||||
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
uint32_t width = 0;
|
||||
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);
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
int bitDepth = 0;
|
||||
int colorType = -1;
|
||||
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);
|
||||
auto *rowData = new uint8_t[bytesPerRow];
|
||||
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++) {
|
||||
png_read_row(png_ptr, (png_bytep) rowData, nullptr);
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstdint>
|
||||
#include <wums/defines/relocation_defines.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
32
source/utils/HeapMemoryFixedSize.cpp
Normal file
32
source/utils/HeapMemoryFixedSize.cpp
Normal 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;
|
||||
}
|
@ -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{};
|
||||
|
@ -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) {
|
||||
|
@ -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--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
@ -1,6 +1,8 @@
|
||||
#include "base64.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
|
@ -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/
|
||||
|
||||
|
@ -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);
|
||||
mFirstFrame = false;
|
||||
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);
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
12
source/utils/config/ConfigDisplayItem.cpp
Normal file
12
source/utils/config/ConfigDisplayItem.cpp
Normal 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;
|
||||
}
|
@ -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;
|
||||
|
@ -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();
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE_WARN("render failed: state was RENDERER_STATE_CAT but mCategoryRenderer is NULL");
|
||||
}
|
||||
break;
|
||||
}
|
||||
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) {
|
||||
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) {
|
||||
|
@ -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;
|
||||
};
|
||||
|
55
source/utils/config/ConfigRendererItem.cpp
Normal file
55
source/utils/config/ConfigRendererItem.cpp
Normal 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);
|
||||
}
|
@ -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;
|
||||
};
|
@ -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);
|
||||
|
34
source/utils/config/ConfigRendererItemGeneric.cpp
Normal file
34
source/utils/config/ConfigRendererItemGeneric.cpp
Normal 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;
|
||||
}
|
@ -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;
|
||||
};
|
@ -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,19 +126,15 @@ void ConfigUtils::displayMenu() {
|
||||
}
|
||||
|
||||
// Sort Configs by name
|
||||
std::sort(
|
||||
configs.begin(),
|
||||
configs.end(),
|
||||
[](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),
|
||||
[](const char &char1, const char &char2) {
|
||||
return tolower(char1) < tolower(char2);
|
||||
});
|
||||
});
|
||||
std::ranges::sort(configs,
|
||||
[](const ConfigDisplayItem &lhs, const ConfigDisplayItem &rhs) {
|
||||
auto &str1 = lhs.getConfigInformation().name;
|
||||
auto &str2 = rhs.getConfigInformation().name;
|
||||
return std::ranges::lexicographical_compare(str1, str2,
|
||||
[](const char &char1, const char &char2) {
|
||||
return tolower(char1) < tolower(char2);
|
||||
});
|
||||
});
|
||||
|
||||
ConfigRenderer renderer(std::move(configs));
|
||||
configs.clear();
|
||||
@ -156,7 +151,7 @@ void ConfigUtils::displayMenu() {
|
||||
WPAD_CHAN_6,
|
||||
};
|
||||
|
||||
auto startTime = OSGetTime();
|
||||
OSTime startTime;
|
||||
bool skipFirstInput = true;
|
||||
|
||||
gOnlyAcceptFromThread = OSGetCurrentThread();
|
||||
@ -238,26 +233,26 @@ void ConfigUtils::displayMenu() {
|
||||
}
|
||||
|
||||
void ConfigUtils::openConfigMenu() {
|
||||
gOnlyAcceptFromThread = OSGetCurrentThread();
|
||||
bool wasHomeButtonMenuEnabled = OSIsHomeButtonMenuEnabled();
|
||||
gOnlyAcceptFromThread = OSGetCurrentThread();
|
||||
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);
|
||||
void *screenbuffer0 = MEMAllocFromMappedMemoryForGX2Ex(screen_buf0_size, 0x100);
|
||||
void *screenbuffer1 = MEMAllocFromMappedMemoryForGX2Ex(screen_buf1_size, 0x100);
|
||||
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);
|
||||
|
||||
bool skipScreen0Free = false;
|
||||
bool skipScreen1Free = false;
|
||||
@ -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();
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
}
|
@ -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,10 +28,10 @@ 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];
|
||||
bool found = false;
|
||||
const auto handle = plugin_data_handle_list[i];
|
||||
bool found = false;
|
||||
|
||||
for (const auto &pluginData : gLoadedData) {
|
||||
if (pluginData->getHandle() == handle) {
|
||||
@ -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];
|
||||
bool found = false;
|
||||
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 §ionInfoList = curContainer.getPluginInformation().getSectionInfoList();
|
||||
|
||||
uint32_t offset = 0;
|
||||
for (auto const &[key, sectionInfo] : sectionInfoList) {
|
||||
for (auto const §ionInfo : 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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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 = {};
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
13
source/utils/storage/StorageItemRoot.cpp
Normal file
13
source/utils/storage/StorageItemRoot.cpp
Normal 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();
|
||||
}
|
@ -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;
|
||||
|
@ -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,40 +39,30 @@ 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) {
|
||||
error = STORAGE_SUB_ITEM_KEY_ALREADY_IN_USE;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto result = mItems.insert({key, StorageItem(key)});
|
||||
if (result.second) {
|
||||
return &result.first->second;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StorageSubItem *StorageSubItem::createSubItem(const char *key, StorageSubItem::StorageSubItemError &error) {
|
||||
auto resItr = mItems.find(key);
|
||||
if (resItr != mItems.end()) {
|
||||
StorageItem *StorageSubItem::createItem(const char *key, StorageSubItemError &error) {
|
||||
if (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;
|
||||
}
|
||||
|
||||
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, StorageSubItemError &error) {
|
||||
if (getItem(key) != nullptr || getSubItem(key) != nullptr) {
|
||||
error = STORAGE_SUB_ITEM_KEY_ALREADY_IN_USE;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mSubCategories.emplace_front(key);
|
||||
@ -76,9 +70,16 @@ StorageSubItem *StorageSubItem::createSubItem(const char *key, StorageSubItem::S
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
#include <wups/storage.h>
|
||||
|
||||
namespace StorageUtils::API {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@
|
||||
#include <coreinit/dynload.h>
|
||||
#include <cstdint>
|
||||
#include <forward_list>
|
||||
#include <malloc.h>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
|
94
source/utils/wiiu_zlib.cpp
Normal file
94
source/utils/wiiu_zlib.cpp
Normal 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);
|
||||
}
|
@ -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);
|
||||
};
|
@ -1,2 +1,2 @@
|
||||
#pragma once
|
||||
#define VERSION_EXTRA ""
|
||||
#define MODULE_VERSION_EXTRA ""
|
Loading…
Reference in New Issue
Block a user