mirror of
https://github.com/wiiu-env/WiiUPluginLoaderBackend.git
synced 2024-12-18 17:11:54 +01:00
Code cleanup
This commit is contained in:
parent
5893ac2f18
commit
447e1eb218
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")
|
git_hash=$(git rev-parse --short "$GITHUB_SHA")
|
||||||
cat <<EOF > ./source/version.h
|
cat <<EOF > ./source/version.h
|
||||||
#pragma once
|
#pragma once
|
||||||
#define VERSION_EXTRA " (nightly-$git_hash)"
|
#define MODULE_VERSION_EXTRA " (nightly-$git_hash)"
|
||||||
EOF
|
EOF
|
||||||
- name: build binary
|
- name: build binary
|
||||||
run: |
|
run: |
|
||||||
|
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 }}")
|
git_hash=$(git rev-parse --short "${{ github.event.pull_request.head.sha }}")
|
||||||
cat <<EOF > ./source/version.h
|
cat <<EOF > ./source/version.h
|
||||||
#pragma once
|
#pragma once
|
||||||
#define VERSION_EXTRA " (nightly-$git_hash)"
|
#define MODULE_VERSION_EXTRA " (nightly-$git_hash)"
|
||||||
EOF
|
EOF
|
||||||
- name: build binary
|
- name: build binary
|
||||||
run: |
|
run: |
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <coreinit/dynload.h>
|
#include <coreinit/dynload.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
std::vector<PluginContainer>
|
std::vector<PluginContainer>
|
||||||
PluginManagement::loadPlugins(const std::set<std::shared_ptr<PluginData>> &pluginDataList, std::vector<relocation_trampoline_entry_t> &trampolineData) {
|
PluginManagement::loadPlugins(const std::set<std::shared_ptr<PluginData>> &pluginDataList, std::vector<relocation_trampoline_entry_t> &trampolineData) {
|
||||||
@ -50,7 +51,7 @@ PluginManagement::loadPlugins(const std::set<std::shared_ptr<PluginData>> &plugi
|
|||||||
|
|
||||||
bool PluginManagement::doRelocation(const std::vector<RelocationData> &relocData,
|
bool PluginManagement::doRelocation(const std::vector<RelocationData> &relocData,
|
||||||
std::vector<relocation_trampoline_entry_t> &trampData,
|
std::vector<relocation_trampoline_entry_t> &trampData,
|
||||||
uint32_t trampolineID,
|
const uint32_t trampolineID,
|
||||||
std::map<std::string, OSDynLoad_Module> &usedRPls) {
|
std::map<std::string, OSDynLoad_Module> &usedRPls) {
|
||||||
for (auto const &cur : relocData) {
|
for (auto const &cur : relocData) {
|
||||||
uint32_t functionAddress = 0;
|
uint32_t functionAddress = 0;
|
||||||
|
@ -18,14 +18,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "WUPSConfigCategory.h"
|
#include "WUPSConfigCategory.h"
|
||||||
#include <optional>
|
#include <string_view>
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace WUPSConfigAPIBackend {
|
namespace WUPSConfigAPIBackend {
|
||||||
class WUPSConfig : public WUPSConfigCategory {
|
class WUPSConfig final : public WUPSConfigCategory {
|
||||||
public:
|
public:
|
||||||
explicit WUPSConfig(std::string_view name) : WUPSConfigCategory(name) {
|
explicit WUPSConfig(const std::string_view name) : WUPSConfigCategory(name) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace WUPSConfigAPIBackend
|
} // namespace WUPSConfigAPIBackend
|
||||||
|
@ -6,16 +6,19 @@
|
|||||||
#include "WUPSConfigItemV2.h"
|
#include "WUPSConfigItemV2.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "plugin/PluginConfigData.h"
|
#include "plugin/PluginConfigData.h"
|
||||||
|
#include "plugin/PluginContainer.h"
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
#include "utils/utils.h"
|
#include "utils/utils.h"
|
||||||
#include <algorithm>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <ranges>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wums/exports.h>
|
#include <wums/exports.h>
|
||||||
#include <wups/config.h>
|
#include <wups/config.h>
|
||||||
#include <wups/config_api.h>
|
#include <wups/config_api.h>
|
||||||
|
|
||||||
namespace WUPSConfigAPIBackend {
|
namespace WUPSConfigAPIBackend {
|
||||||
|
|
||||||
std::vector<std::unique_ptr<WUPSConfig>> sConfigs;
|
std::vector<std::unique_ptr<WUPSConfig>> sConfigs;
|
||||||
std::mutex sConfigsMutex;
|
std::mutex sConfigsMutex;
|
||||||
|
|
||||||
@ -28,7 +31,7 @@ namespace WUPSConfigAPIBackend {
|
|||||||
namespace Intern {
|
namespace Intern {
|
||||||
WUPSConfig *GetConfigByHandle(WUPSConfigHandle handle) {
|
WUPSConfig *GetConfigByHandle(WUPSConfigHandle handle) {
|
||||||
std::lock_guard lock(sConfigsMutex);
|
std::lock_guard lock(sConfigsMutex);
|
||||||
auto itr = std::find_if(sConfigs.begin(), sConfigs.end(), [&handle](auto &cur) { return handle == cur.get(); });
|
const auto itr = std::ranges::find_if(sConfigs, [&handle](auto &cur) { return handle == cur.get(); });
|
||||||
if (itr == sConfigs.end()) {
|
if (itr == sConfigs.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -44,23 +47,21 @@ namespace WUPSConfigAPIBackend {
|
|||||||
return category;
|
return category;
|
||||||
}
|
}
|
||||||
for (const auto &cat : category->getCategories()) {
|
for (const auto &cat : category->getCategories()) {
|
||||||
auto res = GetCategoryByHandleRecursive(cat.get(), handle);
|
if (const auto res = GetCategoryByHandleRecursive(cat.get(), handle)) {
|
||||||
if (res) {
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
WUPSConfigCategory *GetCategoryByHandle(WUPSConfigCategoryHandle handle, bool checkRecursive) {
|
WUPSConfigCategory *GetCategoryByHandle(WUPSConfigCategoryHandle handle, const bool checkRecursive) {
|
||||||
std::lock_guard lock(sConfigCategoryMutex);
|
std::lock_guard lock(sConfigCategoryMutex);
|
||||||
auto itr = std::find_if(sConfigCategories.begin(), sConfigCategories.end(), [&handle](auto &cur) { return handle == cur.get(); });
|
const auto itr = std::ranges::find_if(sConfigCategories, [&handle](auto &cur) { return handle == cur.get(); });
|
||||||
if (itr == sConfigCategories.end()) {
|
if (itr == sConfigCategories.end()) {
|
||||||
if (checkRecursive) {
|
if (checkRecursive) {
|
||||||
std::lock_guard config_lock(sConfigsMutex);
|
std::lock_guard config_lock(sConfigsMutex);
|
||||||
for (const auto &curConfig : sConfigs) {
|
for (const auto &curConfig : sConfigs) {
|
||||||
auto *category = Intern::GetCategoryByHandleRecursive(curConfig.get(), handle);
|
if (auto *category = GetCategoryByHandleRecursive(curConfig.get(), handle)) {
|
||||||
if (category) {
|
|
||||||
return category;
|
return category;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,7 +78,7 @@ namespace WUPSConfigAPIBackend {
|
|||||||
|
|
||||||
WUPSConfigItem *GetItemByHandle(WUPSConfigItemHandle handle) {
|
WUPSConfigItem *GetItemByHandle(WUPSConfigItemHandle handle) {
|
||||||
std::lock_guard lock(sConfigItemsMutex);
|
std::lock_guard lock(sConfigItemsMutex);
|
||||||
auto itr = std::find_if(sConfigItems.begin(), sConfigItems.end(), [&handle](auto &cur) { return handle == cur.get(); });
|
const auto itr = std::ranges::find_if(sConfigItems, [&handle](auto &cur) { return handle == cur.get(); });
|
||||||
if (itr == sConfigItems.end()) {
|
if (itr == sConfigItems.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -135,7 +136,10 @@ namespace WUPSConfigAPIBackend {
|
|||||||
* - WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION: The specified `options.version` is not supported.
|
* - WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION: The specified `options.version` is not supported.
|
||||||
* - WUPSCONFIG_API_RESULT_NOT_FOUND: The plugin with the given identifier was not found.
|
* - WUPSCONFIG_API_RESULT_NOT_FOUND: The plugin with the given identifier was not found.
|
||||||
*/
|
*/
|
||||||
WUPSConfigAPIStatus InitEx(uint32_t pluginIdentifier, WUPSConfigAPIOptions options, WUPSConfigAPI_MenuOpenedCallback openedCallback, WUPSConfigAPI_MenuClosedCallback closedCallback) {
|
WUPSConfigAPIStatus InitEx(const uint32_t pluginIdentifier,
|
||||||
|
const WUPSConfigAPIOptions options,
|
||||||
|
const WUPSConfigAPI_MenuOpenedCallback openedCallback,
|
||||||
|
const WUPSConfigAPI_MenuClosedCallback closedCallback) {
|
||||||
if (openedCallback == nullptr || closedCallback == nullptr) {
|
if (openedCallback == nullptr || closedCallback == nullptr) {
|
||||||
return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT;
|
return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
@ -144,7 +148,7 @@ namespace WUPSConfigAPIBackend {
|
|||||||
if (options.version != 1) {
|
if (options.version != 1) {
|
||||||
return WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION;
|
return WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION;
|
||||||
}
|
}
|
||||||
auto configDat = PluginConfigData::create(options, openedCallback, closedCallback);
|
const auto configDat = PluginConfigData::create(options, openedCallback, closedCallback);
|
||||||
if (!configDat) {
|
if (!configDat) {
|
||||||
DEBUG_FUNCTION_LINE_WARN("Failed to create config data for %08X", pluginIdentifier);
|
DEBUG_FUNCTION_LINE_WARN("Failed to create config data for %08X", pluginIdentifier);
|
||||||
return WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION;
|
return WUPSCONFIG_API_RESULT_UNSUPPORTED_VERSION;
|
||||||
@ -188,7 +192,7 @@ namespace WUPSConfigAPIBackend {
|
|||||||
{
|
{
|
||||||
// Ignore any attempts to destroy the root item.
|
// Ignore any attempts to destroy the root item.
|
||||||
std::lock_guard lock(sConfigsMutex);
|
std::lock_guard lock(sConfigsMutex);
|
||||||
if (std::any_of(sConfigs.begin(), sConfigs.end(), [&handle](auto &cur) { return handle == cur.get(); })) {
|
if (std::ranges::any_of(sConfigs, [&handle](auto &cur) { return handle == cur.get(); })) {
|
||||||
return WUPSCONFIG_API_RESULT_SUCCESS;
|
return WUPSCONFIG_API_RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -198,7 +202,7 @@ namespace WUPSConfigAPIBackend {
|
|||||||
return WUPSCONFIG_API_RESULT_SUCCESS;
|
return WUPSCONFIG_API_RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
WUPSConfigAPIStatus AddCategory(WUPSConfigCategoryHandle parentHandle, WUPSConfigCategoryHandle categoryHandle) {
|
WUPSConfigAPIStatus AddCategory(const WUPSConfigCategoryHandle parentHandle, const WUPSConfigCategoryHandle categoryHandle) {
|
||||||
if (parentHandle == nullptr || categoryHandle == nullptr) {
|
if (parentHandle == nullptr || categoryHandle == nullptr) {
|
||||||
DEBUG_FUNCTION_LINE("Invalid param: \"parentHandle\" or \"categoryHandle\" was NULL");
|
DEBUG_FUNCTION_LINE("Invalid param: \"parentHandle\" or \"categoryHandle\" was NULL");
|
||||||
return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT;
|
return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT;
|
||||||
@ -228,7 +232,7 @@ namespace WUPSConfigAPIBackend {
|
|||||||
return WUPSCONFIG_API_RESULT_SUCCESS;
|
return WUPSCONFIG_API_RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
WUPSConfigAPIStatus AddItem(WUPSConfigCategoryHandle parentHandle, WUPSConfigItemHandle itemHandle) {
|
WUPSConfigAPIStatus AddItem(const WUPSConfigCategoryHandle parentHandle, const WUPSConfigItemHandle itemHandle) {
|
||||||
if (parentHandle == nullptr || itemHandle == nullptr) {
|
if (parentHandle == nullptr || itemHandle == nullptr) {
|
||||||
DEBUG_FUNCTION_LINE("Invalid param: \"handle\" or \"item_Handle\" was NULL");
|
DEBUG_FUNCTION_LINE("Invalid param: \"handle\" or \"item_Handle\" was NULL");
|
||||||
return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT;
|
return WUPSCONFIG_API_RESULT_INVALID_ARGUMENT;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "WUPSConfig.h"
|
#include "WUPSConfig.h"
|
||||||
#include "WUPSConfigAPI.h"
|
#include "WUPSConfigAPI.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
#include <wums.h>
|
#include <wums.h>
|
||||||
#include <wups/config.h>
|
#include <wups/config.h>
|
||||||
|
|
||||||
|
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
|
#pragma once
|
||||||
|
|
||||||
#include "WUPSConfigItem.h"
|
#include "WUPSConfigItem.h"
|
||||||
#include <optional>
|
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wups/config.h>
|
|
||||||
|
|
||||||
namespace WUPSConfigAPIBackend {
|
namespace WUPSConfigAPIBackend {
|
||||||
class WUPSConfigCategory {
|
class WUPSConfigCategory {
|
||||||
public:
|
public:
|
||||||
explicit WUPSConfigCategory(std::string_view name) : mName(name) {
|
explicit WUPSConfigCategory(std::string_view name);
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~WUPSConfigCategory() = default;
|
virtual ~WUPSConfigCategory();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\return Returns the name of this WUPSConfigCategory
|
\return Returns the name of this WUPSConfigCategory
|
||||||
**/
|
**/
|
||||||
[[nodiscard]] const std::string &getName() const {
|
[[nodiscard]] const std::string &getName() const;
|
||||||
return mName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Adds a given WUPSConfigItem to this WUPSConfigCategory.
|
\brief Adds a given WUPSConfigItem to this WUPSConfigCategory.
|
||||||
@ -48,28 +44,18 @@ namespace WUPSConfigAPIBackend {
|
|||||||
\return On success, true will be returned.
|
\return On success, true will be returned.
|
||||||
On error false will be returned. In this case the caller still has the responsibility
|
On error false will be returned. In this case the caller still has the responsibility
|
||||||
for deleting the WUPSConfigItem instance.
|
for deleting the WUPSConfigItem instance.
|
||||||
**/
|
**/
|
||||||
[[nodiscard]] bool addItem(std::unique_ptr<WUPSConfigItem> &item) {
|
[[nodiscard]] bool addItem(std::unique_ptr<WUPSConfigItem> &item);
|
||||||
if (item != nullptr) {
|
|
||||||
mItems.push_back(std::move(item));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\return Returns a vector with all items.
|
\return Returns a vector with all items.
|
||||||
**/
|
**/
|
||||||
[[nodiscard]] const std::vector<std::unique_ptr<WUPSConfigItem>> &getItems() const {
|
[[nodiscard]] const std::vector<std::unique_ptr<WUPSConfigItem>> &getItems() const;
|
||||||
return mItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\return Returns a vector with all categories.
|
\return Returns a vector with all categories.
|
||||||
**/
|
**/
|
||||||
[[nodiscard]] const std::vector<std::unique_ptr<WUPSConfigCategory>> &getCategories() const {
|
[[nodiscard]] const std::vector<std::unique_ptr<WUPSConfigCategory>> &getCategories() const;
|
||||||
return mCategories;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Adds a given WUPSConfigCategory to this WUPSConfigCategory.
|
\brief Adds a given WUPSConfigCategory to this WUPSConfigCategory.
|
||||||
@ -81,11 +67,8 @@ namespace WUPSConfigAPIBackend {
|
|||||||
\return On success, true will be returned.
|
\return On success, true will be returned.
|
||||||
On error false will be returned. In this case the caller still has the responsibility
|
On error false will be returned. In this case the caller still has the responsibility
|
||||||
for deleting the WUPSConfigCategory instance.
|
for deleting the WUPSConfigCategory instance.
|
||||||
**/
|
**/
|
||||||
[[nodiscard]] bool addCategory(std::unique_ptr<WUPSConfigCategory> &category) {
|
[[nodiscard]] bool addCategory(std::unique_ptr<WUPSConfigCategory> &category);
|
||||||
mCategories.push_back(std::move(category));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
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
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "utils/StringTools.h"
|
|
||||||
#include "utils/logger.h"
|
|
||||||
#include <wups/config.h>
|
#include <wups/config.h>
|
||||||
|
|
||||||
namespace WUPSConfigAPIBackend {
|
namespace WUPSConfigAPIBackend {
|
||||||
class WUPSConfigItem {
|
class WUPSConfigItem {
|
||||||
public:
|
public:
|
||||||
explicit WUPSConfigItem(std::string displayName) : mDisplayName(std::move(displayName)) {
|
explicit WUPSConfigItem(std::string displayName);
|
||||||
}
|
virtual ~WUPSConfigItem();
|
||||||
virtual ~WUPSConfigItem() = default;
|
|
||||||
|
|
||||||
[[nodiscard]] virtual std::string getCurrentValueDisplay() const = 0;
|
[[nodiscard]] virtual std::string getCurrentValueDisplay() const = 0;
|
||||||
|
|
||||||
@ -38,7 +32,7 @@ namespace WUPSConfigAPIBackend {
|
|||||||
|
|
||||||
virtual void onSelected(bool isSelected) const = 0;
|
virtual void onSelected(bool isSelected) const = 0;
|
||||||
|
|
||||||
virtual void onButtonPressed(WUPSConfigButtons) const {}
|
virtual void onButtonPressed(WUPSConfigButtons) const;
|
||||||
|
|
||||||
[[nodiscard]] virtual bool isMovementAllowed() const = 0;
|
[[nodiscard]] virtual bool isMovementAllowed() const = 0;
|
||||||
|
|
||||||
@ -46,23 +40,17 @@ namespace WUPSConfigAPIBackend {
|
|||||||
|
|
||||||
virtual void onCloseCallback() = 0;
|
virtual void onCloseCallback() = 0;
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getDisplayName() const {
|
[[nodiscard]] const std::string &getDisplayName() const;
|
||||||
return mDisplayName;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void setConfigId(const std::string &) {}
|
virtual void setConfigId(const std::string &);
|
||||||
|
|
||||||
virtual const std::string &getConfigId() {
|
virtual const std::string &getConfigId();
|
||||||
return mStubConfigId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setDisplayName(std::string displayName) {
|
void setDisplayName(std::string displayName);
|
||||||
mDisplayName = std::move(displayName);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void onInput(WUPSConfigSimplePadData) const {}
|
virtual void onInput(WUPSConfigSimplePadData) const;
|
||||||
|
|
||||||
virtual void onInputEx(WUPSConfigComplexPadData) const {}
|
virtual void onInputEx(WUPSConfigComplexPadData) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::string mDisplayName;
|
std::string mDisplayName;
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
#include "WUPSConfigItemV1.h"
|
#include "WUPSConfigItemV1.h"
|
||||||
|
#include "utils/StringTools.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
|
||||||
namespace WUPSConfigAPIBackend {
|
namespace WUPSConfigAPIBackend {
|
||||||
WUPSConfigItemV1::WUPSConfigItemV1(std::string_view configId, std::string_view _displayName, WUPSConfigAPIItemCallbacksV1 callbacks, void *context) : WUPSConfigItem(std::string(_displayName)) {
|
WUPSConfigItemV1::WUPSConfigItemV1(const std::string_view configId,
|
||||||
|
const std::string_view displayName,
|
||||||
|
const WUPSConfigAPIItemCallbacksV1 &callbacks,
|
||||||
|
void *context) : WUPSConfigItem(std::string(displayName)) {
|
||||||
this->mConfigId = configId;
|
this->mConfigId = configId;
|
||||||
this->mContext = context;
|
this->mContext = context;
|
||||||
this->mCallbacks = callbacks;
|
this->mCallbacks = callbacks;
|
||||||
@ -46,7 +51,7 @@ namespace WUPSConfigAPIBackend {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WUPSConfigItemV1::onSelected(bool isSelected) const {
|
void WUPSConfigItemV1::onSelected(const bool isSelected) const {
|
||||||
if (this->mCallbacks.onSelected == nullptr) {
|
if (this->mCallbacks.onSelected == nullptr) {
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("onSelected callback not implemented. [%s]", mDisplayName.c_str());
|
DEBUG_FUNCTION_LINE_VERBOSE("onSelected callback not implemented. [%s]", mDisplayName.c_str());
|
||||||
return;
|
return;
|
||||||
@ -54,7 +59,7 @@ namespace WUPSConfigAPIBackend {
|
|||||||
this->mCallbacks.onSelected(mContext, isSelected);
|
this->mCallbacks.onSelected(mContext, isSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WUPSConfigItemV1::onButtonPressed(WUPSConfigButtons buttons) const {
|
void WUPSConfigItemV1::onButtonPressed(const WUPSConfigButtons buttons) const {
|
||||||
if (this->mCallbacks.onButtonPressed == nullptr) {
|
if (this->mCallbacks.onButtonPressed == nullptr) {
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("onButtonPressed callback not implemented. [%s]", mDisplayName.c_str());
|
DEBUG_FUNCTION_LINE_VERBOSE("onButtonPressed callback not implemented. [%s]", mDisplayName.c_str());
|
||||||
return;
|
return;
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "WUPSConfigItem.h"
|
#include "WUPSConfigItem.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <wups/config.h>
|
#include <wups/config.h>
|
||||||
|
|
||||||
namespace WUPSConfigAPIBackend {
|
namespace WUPSConfigAPIBackend {
|
||||||
class WUPSConfigItemV1 : public WUPSConfigItem {
|
class WUPSConfigItemV1 final : public WUPSConfigItem {
|
||||||
public:
|
public:
|
||||||
WUPSConfigItemV1(std::string_view configId, std::string_view _displayName, WUPSConfigAPIItemCallbacksV1 callbacks, void *context);
|
WUPSConfigItemV1(std::string_view configId,
|
||||||
|
std::string_view displayName,
|
||||||
|
const WUPSConfigAPIItemCallbacksV1 &callbacks,
|
||||||
|
void *context);
|
||||||
|
|
||||||
~WUPSConfigItemV1() override;
|
~WUPSConfigItemV1() override;
|
||||||
|
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
#include "WUPSConfigItemV2.h"
|
#include "WUPSConfigItemV2.h"
|
||||||
|
#include "utils/StringTools.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <wups/config.h>
|
#include <wups/config.h>
|
||||||
|
|
||||||
namespace WUPSConfigAPIBackend {
|
namespace WUPSConfigAPIBackend {
|
||||||
WUPSConfigItemV2::WUPSConfigItemV2(std::string_view displayName, WUPSConfigAPIItemCallbacksV2 callbacks, void *context) : WUPSConfigItem(std::string(displayName)) {
|
WUPSConfigItemV2::WUPSConfigItemV2(const std::string_view displayName,
|
||||||
|
const WUPSConfigAPIItemCallbacksV2 &callbacks,
|
||||||
|
void *context) : WUPSConfigItem(std::string(displayName)) {
|
||||||
this->mDisplayName = displayName;
|
this->mDisplayName = displayName;
|
||||||
this->mContext = context;
|
this->mContext = context;
|
||||||
this->mCallbacks = callbacks;
|
this->mCallbacks = callbacks;
|
||||||
@ -16,7 +22,7 @@ namespace WUPSConfigAPIBackend {
|
|||||||
this->mCallbacks.onDelete(mContext);
|
this->mCallbacks.onDelete(mContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WUPSConfigItemV2::onSelected(bool isSelected) const {
|
void WUPSConfigItemV2::onSelected(const bool isSelected) const {
|
||||||
if (this->mCallbacks.onSelected == nullptr) {
|
if (this->mCallbacks.onSelected == nullptr) {
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("onSelected callback not implemented. [%s]", mDisplayName.c_str());
|
DEBUG_FUNCTION_LINE_VERBOSE("onSelected callback not implemented. [%s]", mDisplayName.c_str());
|
||||||
return;
|
return;
|
||||||
@ -50,7 +56,7 @@ namespace WUPSConfigAPIBackend {
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WUPSConfigItemV2::onInput(WUPSConfigSimplePadData input) const {
|
void WUPSConfigItemV2::onInput(const WUPSConfigSimplePadData input) const {
|
||||||
if (this->mCallbacks.onInput == nullptr) {
|
if (this->mCallbacks.onInput == nullptr) {
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("onInput callback not implemented. [%s]", mDisplayName.c_str());
|
DEBUG_FUNCTION_LINE_VERBOSE("onInput callback not implemented. [%s]", mDisplayName.c_str());
|
||||||
return;
|
return;
|
||||||
@ -58,7 +64,7 @@ namespace WUPSConfigAPIBackend {
|
|||||||
this->mCallbacks.onInput(mContext, input);
|
this->mCallbacks.onInput(mContext, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WUPSConfigItemV2::onInputEx(WUPSConfigComplexPadData input) const {
|
void WUPSConfigItemV2::onInputEx(const WUPSConfigComplexPadData input) const {
|
||||||
if (this->mCallbacks.onInputEx == nullptr) {
|
if (this->mCallbacks.onInputEx == nullptr) {
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("onInputEx callback not implemented. [%s]", mDisplayName.c_str());
|
DEBUG_FUNCTION_LINE_VERBOSE("onInputEx callback not implemented. [%s]", mDisplayName.c_str());
|
||||||
return;
|
return;
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "WUPSConfigItem.h"
|
#include "WUPSConfigItem.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <wups/config.h>
|
#include <wups/config.h>
|
||||||
|
|
||||||
namespace WUPSConfigAPIBackend {
|
namespace WUPSConfigAPIBackend {
|
||||||
|
class WUPSConfigItemV2 final : public WUPSConfigItem {
|
||||||
class WUPSConfigItemV2 : public WUPSConfigItem {
|
|
||||||
public:
|
public:
|
||||||
WUPSConfigItemV2(std::string_view displayName, WUPSConfigAPIItemCallbacksV2 callbacks, void *context);
|
WUPSConfigItemV2(std::string_view displayName, const WUPSConfigAPIItemCallbacksV2 &callbacks, void *context);
|
||||||
|
|
||||||
~WUPSConfigItemV2() override;
|
~WUPSConfigItemV2() override;
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ THE SOFTWARE.
|
|||||||
#define ELFIO_UTILS_HPP
|
#define ELFIO_UTILS_HPP
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <elfio/elf_types.hpp>
|
||||||
|
|
||||||
#define ELFIO_GET_ACCESS_DECL( TYPE, NAME ) virtual TYPE get_##NAME() const = 0
|
#define ELFIO_GET_ACCESS_DECL( TYPE, NAME ) virtual TYPE get_##NAME() const = 0
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ BOOL DirList::LoadPath(const std::string &folder, const char *filter, uint32_t f
|
|||||||
uint32_t length = folderpath.size();
|
uint32_t length = folderpath.size();
|
||||||
|
|
||||||
//! clear path of double slashes
|
//! clear path of double slashes
|
||||||
StringTools::RemoveDoubleSlashs(folderpath);
|
StringTools::RemoveDoubleSlashes(folderpath);
|
||||||
|
|
||||||
//! remove last slash if exists
|
//! remove last slash if exists
|
||||||
if (length > 0 && folderpath[length - 1] == '/')
|
if (length > 0 && folderpath[length - 1] == '/')
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
#include "plugin/PluginContainer.h"
|
||||||
|
#include "plugin/PluginData.h"
|
||||||
|
|
||||||
StoredBuffer gStoredTVBuffer = {};
|
StoredBuffer gStoredTVBuffer = {};
|
||||||
StoredBuffer gStoredDRCBuffer = {};
|
StoredBuffer gStoredDRCBuffer = {};
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "plugin/PluginContainer.h"
|
|
||||||
#include "utils/config/ConfigUtils.h"
|
#include "utils/config/ConfigDefines.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include <coreinit/dynload.h>
|
#include <coreinit/dynload.h>
|
||||||
#include <forward_list>
|
#include <coreinit/thread.h>
|
||||||
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wums/defines/relocation_defines.h>
|
#include <wums/defines/relocation_defines.h>
|
||||||
|
|
||||||
#define VERSION "v0.3.4"
|
#define MODULE_VERSION "v0.3.4"
|
||||||
#define VERSION_FULL VERSION VERSION_EXTRA
|
#define MODULE_VERSION_FULL MODULE_VERSION MODULE_VERSION_EXTRA
|
||||||
|
|
||||||
|
class PluginData;
|
||||||
|
class PluginContainer;
|
||||||
|
|
||||||
extern StoredBuffer gStoredTVBuffer;
|
extern StoredBuffer gStoredTVBuffer;
|
||||||
extern StoredBuffer gStoredDRCBuffer;
|
extern StoredBuffer gStoredDRCBuffer;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "plugin/PluginContainer.h"
|
#include "plugin/PluginContainer.h"
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wups/hooks.h>
|
#include <wups/hooks.h>
|
||||||
|
|
||||||
|
@ -5,9 +5,12 @@
|
|||||||
#include "hooks.h"
|
#include "hooks.h"
|
||||||
#include "patcher/hooks_patcher_static.h"
|
#include "patcher/hooks_patcher_static.h"
|
||||||
#include "plugin/PluginDataFactory.h"
|
#include "plugin/PluginDataFactory.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
#include "utils/utils.h"
|
#include "utils/utils.h"
|
||||||
|
|
||||||
#include <coreinit/debug.h>
|
#include <coreinit/debug.h>
|
||||||
#include <notifications/notifications.h>
|
#include <notifications/notifications.h>
|
||||||
|
#include <version.h>
|
||||||
#include <wums.h>
|
#include <wums.h>
|
||||||
|
|
||||||
WUMS_MODULE_EXPORT_NAME("homebrew_wupsbackend");
|
WUMS_MODULE_EXPORT_NAME("homebrew_wupsbackend");
|
||||||
@ -75,7 +78,7 @@ WUMS_APPLICATION_STARTS() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OSReport("Running WiiUPluginLoaderBackend " VERSION_FULL "\n");
|
OSReport("Running WiiUPluginLoaderBackend " MODULE_VERSION_FULL "\n");
|
||||||
gStoredTVBuffer = {};
|
gStoredTVBuffer = {};
|
||||||
|
|
||||||
gUsedRPLs.clear();
|
gUsedRPLs.clear();
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
#include "hooks_patcher_static.h"
|
#include "hooks_patcher_static.h"
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
|
#include "utils/config/ConfigUtils.h"
|
||||||
|
|
||||||
#include <coreinit/core.h>
|
#include <coreinit/core.h>
|
||||||
#include <coreinit/messagequeue.h>
|
#include <coreinit/messagequeue.h>
|
||||||
|
#include <hooks.h>
|
||||||
#include <padscore/wpad.h>
|
#include <padscore/wpad.h>
|
||||||
#include <vpad/input.h>
|
#include <vpad/input.h>
|
||||||
|
|
||||||
#include "../globals.h"
|
|
||||||
#include "../hooks.h"
|
|
||||||
|
|
||||||
static uint8_t sVpadPressCooldown = 0xFF;
|
static uint8_t sVpadPressCooldown = 0xFF;
|
||||||
static bool sConfigMenuOpened = false;
|
static bool sConfigMenuOpened = false;
|
||||||
static bool sWantsToOpenConfigMenu = false;
|
static bool sWantsToOpenConfigMenu = false;
|
||||||
@ -57,7 +59,7 @@ DECL_FUNCTION(BOOL, OSSendMessage, OSMessageQueue *queue, OSMessage *message, OS
|
|||||||
}
|
}
|
||||||
|
|
||||||
DECL_FUNCTION(uint32_t, OSReceiveMessage, OSMessageQueue *queue, OSMessage *message, uint32_t flags) {
|
DECL_FUNCTION(uint32_t, OSReceiveMessage, OSMessageQueue *queue, OSMessage *message, uint32_t flags) {
|
||||||
uint32_t res = real_OSReceiveMessage(queue, message, flags);
|
const uint32_t res = real_OSReceiveMessage(queue, message, flags);
|
||||||
if (queue == OSGetSystemMessageQueue()) {
|
if (queue == OSGetSystemMessageQueue()) {
|
||||||
if (message != nullptr && res) {
|
if (message != nullptr && res) {
|
||||||
if (lastData0 != message->args[0]) {
|
if (lastData0 != message->args[0]) {
|
||||||
@ -88,7 +90,7 @@ DECL_FUNCTION(int32_t, VPADRead, int32_t chan, VPADStatus *buffer, uint32_t buff
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
VPADReadError real_error = VPAD_READ_SUCCESS;
|
VPADReadError real_error = VPAD_READ_SUCCESS;
|
||||||
int32_t result = real_VPADRead(chan, buffer, buffer_size, &real_error);
|
const int32_t result = real_VPADRead(chan, buffer, buffer_size, &real_error);
|
||||||
|
|
||||||
if (result > 0 && real_error == VPAD_READ_SUCCESS && buffer && ((buffer[0].hold & 0xFFFFF) == (VPAD_BUTTON_L | VPAD_BUTTON_DOWN | VPAD_BUTTON_MINUS)) && sVpadPressCooldown == 0 && !sConfigMenuOpened) {
|
if (result > 0 && real_error == VPAD_READ_SUCCESS && buffer && ((buffer[0].hold & 0xFFFFF) == (VPAD_BUTTON_L | VPAD_BUTTON_DOWN | VPAD_BUTTON_MINUS)) && sVpadPressCooldown == 0 && !sConfigMenuOpened) {
|
||||||
|
|
||||||
@ -106,24 +108,24 @@ DECL_FUNCTION(int32_t, VPADRead, int32_t chan, VPADStatus *buffer, uint32_t buff
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DECL_FUNCTION(void, WPADRead, WPADChan chan, WPADStatusProController *data) {
|
DECL_FUNCTION(void, WPADRead, WPADChan chan, WPADStatus *data) {
|
||||||
real_WPADRead(chan, data);
|
real_WPADRead(chan, data);
|
||||||
|
|
||||||
if (!sConfigMenuOpened && data && data[0].err == 0) {
|
if (!sConfigMenuOpened && data && data[0].error == 0) {
|
||||||
if (data[0].extensionType != 0xFF) {
|
if (const auto extensionType = data[0].extensionType; extensionType != 0xFF) {
|
||||||
if (data[0].extensionType == WPAD_EXT_CORE || data[0].extensionType == WPAD_EXT_NUNCHUK ||
|
if (extensionType == WPAD_EXT_CORE || extensionType == WPAD_EXT_NUNCHUK ||
|
||||||
data[0].extensionType == WPAD_EXT_MPLUS || data[0].extensionType == WPAD_EXT_MPLUS_NUNCHUK) {
|
extensionType == WPAD_EXT_MPLUS || extensionType == WPAD_EXT_MPLUS_NUNCHUK) {
|
||||||
// button data is in the first 2 bytes for wiimotes
|
if (data->buttons == (WPAD_BUTTON_B | WPAD_BUTTON_DOWN | WPAD_BUTTON_MINUS)) {
|
||||||
if (((uint16_t *) data)[0] == (WPAD_BUTTON_B | WPAD_BUTTON_DOWN | WPAD_BUTTON_MINUS)) {
|
|
||||||
sWantsToOpenConfigMenu = true;
|
sWantsToOpenConfigMenu = true;
|
||||||
}
|
}
|
||||||
} else if (data[0].extensionType == WPAD_EXT_CLASSIC || data[0].extensionType == WPAD_EXT_MPLUS_CLASSIC) {
|
} else if (extensionType == WPAD_EXT_CLASSIC || extensionType == WPAD_EXT_MPLUS_CLASSIC) {
|
||||||
// TODO: figure out the real struct..
|
const auto *classic = reinterpret_cast<WPADStatusClassic *>(data);
|
||||||
if ((((uint32_t *) data)[10] & 0xFFFF) == (WPAD_CLASSIC_BUTTON_L | WPAD_CLASSIC_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_MINUS)) {
|
if (classic->buttons == (WPAD_CLASSIC_BUTTON_L | WPAD_CLASSIC_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_MINUS)) {
|
||||||
sWantsToOpenConfigMenu = true;
|
sWantsToOpenConfigMenu = true;
|
||||||
}
|
}
|
||||||
} else if (data[0].extensionType == WPAD_EXT_PRO_CONTROLLER) {
|
} else if (extensionType == WPAD_EXT_PRO_CONTROLLER) {
|
||||||
if (data[0].buttons == (WPAD_PRO_TRIGGER_L | WPAD_PRO_BUTTON_DOWN | WPAD_PRO_BUTTON_MINUS)) {
|
const auto *pro = reinterpret_cast<WPADStatusPro *>(data);
|
||||||
|
if (pro->buttons == (WPAD_PRO_TRIGGER_L | WPAD_PRO_BUTTON_DOWN | WPAD_PRO_BUTTON_MINUS)) {
|
||||||
sWantsToOpenConfigMenu = true;
|
sWantsToOpenConfigMenu = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,11 +158,10 @@ DECL_FUNCTION(uint32_t, SC17_FindClosestSymbol,
|
|||||||
}
|
}
|
||||||
|
|
||||||
strncpy(moduleNameBuffer, plugin.getMetaInformation().getName().c_str(), moduleNameBufferLength - 1);
|
strncpy(moduleNameBuffer, plugin.getMetaInformation().getName().c_str(), moduleNameBufferLength - 1);
|
||||||
auto functionSymbolData = plugin.getPluginInformation().getNearestFunctionSymbolData(addr);
|
if (const auto functionSymbolData = plugin.getPluginInformation().getNearestFunctionSymbolData(addr)) {
|
||||||
if (functionSymbolData) {
|
|
||||||
strncpy(symbolNameBuffer, functionSymbolData->getName().c_str(), moduleNameBufferLength - 1);
|
strncpy(symbolNameBuffer, functionSymbolData->getName().c_str(), moduleNameBufferLength - 1);
|
||||||
if (outDistance) {
|
if (outDistance) {
|
||||||
*outDistance = addr - (uint32_t) functionSymbolData->getAddress();
|
*outDistance = addr - reinterpret_cast<uint32_t>(functionSymbolData->getAddress());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -168,7 +169,7 @@ DECL_FUNCTION(uint32_t, SC17_FindClosestSymbol,
|
|||||||
strncpy(symbolNameBuffer, ".text", symbolNameBufferLength);
|
strncpy(symbolNameBuffer, ".text", symbolNameBufferLength);
|
||||||
|
|
||||||
if (outDistance) {
|
if (outDistance) {
|
||||||
*outDistance = addr - (uint32_t) sectionInfo->getAddress();
|
*outDistance = addr - sectionInfo->getAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -188,15 +189,14 @@ DECL_FUNCTION(uint32_t, KiGetAppSymbolName, uint32_t addr, char *buffer, int32_t
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pluginNameLen = strlen(plugin.getMetaInformation().getName().c_str());
|
const auto pluginNameLen = strlen(plugin.getMetaInformation().getName().c_str());
|
||||||
int32_t spaceLeftInBuffer = (int32_t) bufSize - (int32_t) pluginNameLen - 1;
|
int32_t spaceLeftInBuffer = bufSize - static_cast<int32_t>(pluginNameLen) - 1;
|
||||||
if (spaceLeftInBuffer < 0) {
|
if (spaceLeftInBuffer < 0) {
|
||||||
spaceLeftInBuffer = 0;
|
spaceLeftInBuffer = 0;
|
||||||
}
|
}
|
||||||
strncpy(buffer, plugin.getMetaInformation().getName().c_str(), bufSize - 1);
|
strncpy(buffer, plugin.getMetaInformation().getName().c_str(), bufSize - 1);
|
||||||
|
|
||||||
const auto functionSymbolData = plugin.getPluginInformation().getNearestFunctionSymbolData(addr);
|
if (const auto functionSymbolData = plugin.getPluginInformation().getNearestFunctionSymbolData(addr)) {
|
||||||
if (functionSymbolData) {
|
|
||||||
buffer[pluginNameLen] = '|';
|
buffer[pluginNameLen] = '|';
|
||||||
buffer[pluginNameLen + 1] = '\0';
|
buffer[pluginNameLen + 1] = '\0';
|
||||||
strncpy(buffer + pluginNameLen + 1, functionSymbolData->getName().c_str(), spaceLeftInBuffer - 1);
|
strncpy(buffer + pluginNameLen + 1, functionSymbolData->getName().c_str(), spaceLeftInBuffer - 1);
|
||||||
@ -221,7 +221,6 @@ function_replacement_data_t method_hooks_static[] __attribute__((section(".data"
|
|||||||
REPLACE_FUNCTION(WPADRead, LIBRARY_PADSCORE, WPADRead),
|
REPLACE_FUNCTION(WPADRead, LIBRARY_PADSCORE, WPADRead),
|
||||||
REPLACE_FUNCTION_VIA_ADDRESS(SC17_FindClosestSymbol, 0xfff10218, 0xfff10218),
|
REPLACE_FUNCTION_VIA_ADDRESS(SC17_FindClosestSymbol, 0xfff10218, 0xfff10218),
|
||||||
REPLACE_FUNCTION_VIA_ADDRESS(KiGetAppSymbolName, 0xfff0e3a0, 0xfff0e3a0),
|
REPLACE_FUNCTION_VIA_ADDRESS(KiGetAppSymbolName, 0xfff0e3a0, 0xfff0e3a0),
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t method_hooks_static_size __attribute__((section(".data"))) = sizeof(method_hooks_static) / sizeof(function_replacement_data_t);
|
uint32_t method_hooks_static_size __attribute__((section(".data"))) = sizeof(method_hooks_static) / sizeof(function_replacement_data_t);
|
||||||
|
@ -1,67 +1,75 @@
|
|||||||
#include "FunctionData.h"
|
#include "FunctionData.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
|
||||||
FunctionData::FunctionData(void *paddress, void *vaddress, std::string_view name, function_replacement_library_type_t library, void *replaceAddr, void *replaceCall, FunctionPatcherTargetProcess targetProcess) {
|
#include <function_patcher/function_patching.h>
|
||||||
this->paddress = paddress;
|
#include <string>
|
||||||
this->vaddress = vaddress;
|
|
||||||
this->name = name;
|
FunctionData::FunctionData(void *paddress, void *vaddress,
|
||||||
this->library = library;
|
const std::string_view name,
|
||||||
this->targetProcess = targetProcess;
|
const function_replacement_library_type_t library,
|
||||||
this->replaceAddr = replaceAddr;
|
void *replaceAddr, void *replaceCall,
|
||||||
this->replaceCall = replaceCall;
|
const FunctionPatcherTargetProcess targetProcess) {
|
||||||
|
this->mPAddress = paddress;
|
||||||
|
this->mVAddress = vaddress;
|
||||||
|
this->mName = name;
|
||||||
|
this->mLibrary = library;
|
||||||
|
this->mTargetProcess = targetProcess;
|
||||||
|
this->mReplaceAddr = replaceAddr;
|
||||||
|
this->mReplaceCall = replaceCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionData::~FunctionData() {
|
FunctionData::~FunctionData() {
|
||||||
if (handle != 0) {
|
if (mHandle != 0) {
|
||||||
DEBUG_FUNCTION_LINE_WARN("Destroying FunctionData while it was still patched. This should never happen.");
|
DEBUG_FUNCTION_LINE_WARN("Destroying FunctionData while it was still patched. This should never happen.");
|
||||||
RemovePatch();
|
RemovePatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &FunctionData::getName() const {
|
const std::string &FunctionData::getName() const {
|
||||||
return this->name;
|
return this->mName;
|
||||||
}
|
}
|
||||||
|
|
||||||
function_replacement_library_type_t FunctionData::getLibrary() const {
|
function_replacement_library_type_t FunctionData::getLibrary() const {
|
||||||
return this->library;
|
return this->mLibrary;
|
||||||
}
|
}
|
||||||
|
|
||||||
const void *FunctionData::getPhysicalAddress() const {
|
const void *FunctionData::getPhysicalAddress() const {
|
||||||
return paddress;
|
return mPAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
const void *FunctionData::getVirtualAddress() const {
|
const void *FunctionData::getVirtualAddress() const {
|
||||||
return vaddress;
|
return mVAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
const void *FunctionData::getReplaceAddress() const {
|
const void *FunctionData::getReplaceAddress() const {
|
||||||
return replaceAddr;
|
return mReplaceAddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const void *FunctionData::getReplaceCall() const {
|
const void *FunctionData::getReplaceCall() const {
|
||||||
return replaceCall;
|
return mReplaceCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionPatcherTargetProcess FunctionData::getTargetProcess() const {
|
FunctionPatcherTargetProcess FunctionData::getTargetProcess() const {
|
||||||
return targetProcess;
|
return mTargetProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FunctionData::AddPatch() {
|
bool FunctionData::AddPatch() {
|
||||||
if (handle == 0) {
|
if (mHandle == 0) {
|
||||||
function_replacement_data_t functionData = {
|
function_replacement_data_t functionData = {
|
||||||
.version = FUNCTION_REPLACEMENT_DATA_STRUCT_VERSION,
|
.version = FUNCTION_REPLACEMENT_DATA_STRUCT_VERSION,
|
||||||
.type = FUNCTION_PATCHER_REPLACE_BY_LIB_OR_ADDRESS,
|
.type = FUNCTION_PATCHER_REPLACE_BY_LIB_OR_ADDRESS,
|
||||||
.physicalAddr = reinterpret_cast<uint32_t>(this->paddress),
|
.physicalAddr = reinterpret_cast<uint32_t>(this->mPAddress),
|
||||||
.virtualAddr = reinterpret_cast<uint32_t>(this->vaddress),
|
.virtualAddr = reinterpret_cast<uint32_t>(this->mVAddress),
|
||||||
.replaceAddr = reinterpret_cast<uint32_t>(this->replaceAddr),
|
.replaceAddr = reinterpret_cast<uint32_t>(this->mReplaceAddr),
|
||||||
.replaceCall = static_cast<uint32_t *>(this->replaceCall),
|
.replaceCall = static_cast<uint32_t *>(this->mReplaceCall),
|
||||||
.targetProcess = this->targetProcess,
|
.targetProcess = this->mTargetProcess,
|
||||||
.ReplaceInRPL = {
|
.ReplaceInRPL = {
|
||||||
.function_name = this->name.c_str(),
|
.function_name = this->mName.c_str(),
|
||||||
.library = this->library,
|
.library = this->mLibrary,
|
||||||
}};
|
}};
|
||||||
|
|
||||||
if (FunctionPatcher_AddFunctionPatch(&functionData, &handle, nullptr) != FUNCTION_PATCHER_RESULT_SUCCESS) {
|
if (FunctionPatcher_AddFunctionPatch(&functionData, &mHandle, nullptr) != FUNCTION_PATCHER_RESULT_SUCCESS) {
|
||||||
DEBUG_FUNCTION_LINE_ERR("Failed to add patch for function (\"%s\" PA:%08X VA:%08X)", this->name.c_str(), this->paddress, this->vaddress);
|
DEBUG_FUNCTION_LINE_ERR("Failed to add patch for function (\"%s\" PA:%08X VA:%08X)", this->mName.c_str(), this->mPAddress, this->mVAddress);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -71,12 +79,12 @@ bool FunctionData::AddPatch() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool FunctionData::RemovePatch() {
|
bool FunctionData::RemovePatch() {
|
||||||
if (handle != 0) {
|
if (mHandle != 0) {
|
||||||
if (FunctionPatcher_RemoveFunctionPatch(handle) != FUNCTION_PATCHER_RESULT_SUCCESS) {
|
if (FunctionPatcher_RemoveFunctionPatch(mHandle) != FUNCTION_PATCHER_RESULT_SUCCESS) {
|
||||||
DEBUG_FUNCTION_LINE_ERR("Failed to remove patch for function");
|
DEBUG_FUNCTION_LINE_ERR("Failed to remove patch for function");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
handle = 0;
|
mHandle = 0;
|
||||||
} else {
|
} else {
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("Was not patched.");
|
DEBUG_FUNCTION_LINE_VERBOSE("Was not patched.");
|
||||||
}
|
}
|
||||||
|
@ -16,45 +16,48 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "utils/logger.h"
|
|
||||||
#include <function_patcher/fpatching_defines.h>
|
#include <function_patcher/fpatching_defines.h>
|
||||||
#include <function_patcher/function_patching.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class FunctionData {
|
class FunctionData {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FunctionData(void *paddress, void *vaddress, std::string_view name, function_replacement_library_type_t library, void *replaceAddr, void *replaceCall,
|
FunctionData(void *paddress,
|
||||||
|
void *vaddress,
|
||||||
|
std::string_view name,
|
||||||
|
function_replacement_library_type_t library,
|
||||||
|
void *replaceAddr,
|
||||||
|
void *replaceCall,
|
||||||
FunctionPatcherTargetProcess targetProcess);
|
FunctionPatcherTargetProcess targetProcess);
|
||||||
|
|
||||||
~FunctionData();
|
~FunctionData();
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getName() const;
|
[[nodiscard]] const std::string &getName() const;
|
||||||
|
|
||||||
[[maybe_unused]] [[nodiscard]] function_replacement_library_type_t getLibrary() const;
|
[[nodiscard]] function_replacement_library_type_t getLibrary() const;
|
||||||
|
|
||||||
[[maybe_unused]] [[nodiscard]] const void *getPhysicalAddress() const;
|
[[nodiscard]] const void *getPhysicalAddress() const;
|
||||||
|
|
||||||
[[maybe_unused]] [[nodiscard]] const void *getVirtualAddress() const;
|
[[nodiscard]] const void *getVirtualAddress() const;
|
||||||
|
|
||||||
[[maybe_unused]] [[nodiscard]] const void *getReplaceAddress() const;
|
[[nodiscard]] const void *getReplaceAddress() const;
|
||||||
|
|
||||||
[[maybe_unused]] [[nodiscard]] const void *getReplaceCall() const;
|
[[nodiscard]] const void *getReplaceCall() const;
|
||||||
|
|
||||||
[[maybe_unused]] [[nodiscard]] FunctionPatcherTargetProcess getTargetProcess() const;
|
[[nodiscard]] FunctionPatcherTargetProcess getTargetProcess() const;
|
||||||
|
|
||||||
bool AddPatch();
|
bool AddPatch();
|
||||||
|
|
||||||
bool RemovePatch();
|
bool RemovePatch();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void *paddress = nullptr;
|
void *mPAddress = nullptr;
|
||||||
void *vaddress = nullptr;
|
void *mVAddress = nullptr;
|
||||||
std::string name;
|
std::string mName;
|
||||||
function_replacement_library_type_t library;
|
function_replacement_library_type_t mLibrary;
|
||||||
FunctionPatcherTargetProcess targetProcess;
|
FunctionPatcherTargetProcess mTargetProcess;
|
||||||
void *replaceAddr = nullptr;
|
void *mReplaceAddr = nullptr;
|
||||||
void *replaceCall = nullptr;
|
void *mReplaceCall = nullptr;
|
||||||
|
|
||||||
PatchedFunctionHandle handle = 0;
|
PatchedFunctionHandle mHandle = 0;
|
||||||
};
|
};
|
||||||
|
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
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class FunctionSymbolData {
|
class FunctionSymbolData {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FunctionSymbolData(const FunctionSymbolData &o2) = default;
|
FunctionSymbolData(const FunctionSymbolData &o2);
|
||||||
|
|
||||||
FunctionSymbolData(std::string_view name, void *address, uint32_t size) : mName(name),
|
FunctionSymbolData(std::string_view name, void *address, uint32_t size);
|
||||||
mAddress(address),
|
|
||||||
mSize(size) {
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator<(const FunctionSymbolData &rhs) const {
|
bool operator<(const FunctionSymbolData &rhs) const;
|
||||||
return (uint32_t) mAddress < (uint32_t) rhs.mAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~FunctionSymbolData() = default;
|
virtual ~FunctionSymbolData();
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getName() const {
|
[[nodiscard]] const std::string &getName() const;
|
||||||
return mName;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] void *getAddress() const {
|
[[nodiscard]] void *getAddress() const;
|
||||||
return mAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] uint32_t getSize() const {
|
[[nodiscard]] uint32_t getSize() const;
|
||||||
return mSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
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
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <wups/hooks.h>
|
#include <wups/hooks.h>
|
||||||
|
|
||||||
class HookData {
|
class HookData {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HookData(void *function_pointer, wups_loader_hook_type_t type) {
|
HookData(void *functionPointer, wups_loader_hook_type_t type);
|
||||||
this->function_pointer = function_pointer;
|
|
||||||
this->type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
~HookData() = default;
|
~HookData();
|
||||||
|
|
||||||
[[nodiscard]] void *getFunctionPointer() const {
|
[[nodiscard]] void *getFunctionPointer() const;
|
||||||
return function_pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] wups_loader_hook_type_t getType() const {
|
[[nodiscard]] wups_loader_hook_type_t getType() const;
|
||||||
return this->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void *function_pointer;
|
void *mFunctionPointer;
|
||||||
wups_loader_hook_type_t type;
|
wups_loader_hook_type_t mType;
|
||||||
};
|
};
|
||||||
|
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
|
#pragma once
|
||||||
|
|
||||||
#include "../utils/logger.h"
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
class ImportRPLInformation {
|
class ImportRPLInformation {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ImportRPLInformation(std::string_view name) {
|
explicit ImportRPLInformation(std::string_view name);
|
||||||
this->mName = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
~ImportRPLInformation() = default;
|
~ImportRPLInformation();
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getName() const {
|
[[nodiscard]] const std::string &getName() const;
|
||||||
return mName;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] std::string getRPLName() const {
|
[[nodiscard]] std::string getRPLName() const;
|
||||||
return mName.substr(strlen(".dimport_"));
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] bool isData() const {
|
[[nodiscard]] bool isData() const;
|
||||||
return mName.starts_with(".dimport_");
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
#include "PluginConfigData.h"
|
#include "PluginConfigData.h"
|
||||||
|
|
||||||
PluginConfigData::PluginConfigData(std::string_view name, WUPSConfigAPI_MenuOpenedCallback openedCallback, WUPSConfigAPI_MenuClosedCallback closedCallback) : mName(name),
|
#include <config/WUPSConfigAPI.h>
|
||||||
mOpenedCallback(openedCallback),
|
|
||||||
mClosedCallback(closedCallback) {
|
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 {
|
std::optional<WUPSConfigHandle> PluginConfigData::createConfig() const {
|
||||||
@ -13,7 +17,7 @@ std::optional<WUPSConfigHandle> PluginConfigData::createConfig() const {
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
WUPSConfigAPIStatus PluginConfigData::CallMenuOpenendCallback(WUPSConfigHandle config) const {
|
WUPSConfigAPIStatus PluginConfigData::CallMenuOpenedCallback(const WUPSConfigHandle config) const {
|
||||||
if (mOpenedCallback == nullptr) {
|
if (mOpenedCallback == nullptr) {
|
||||||
return WUPSCONFIG_API_RESULT_MISSING_CALLBACK;
|
return WUPSCONFIG_API_RESULT_MISSING_CALLBACK;
|
||||||
}
|
}
|
||||||
@ -31,7 +35,9 @@ WUPSConfigAPIStatus PluginConfigData::CallMenuClosedCallback() const {
|
|||||||
return WUPSCONFIG_API_RESULT_SUCCESS;
|
return WUPSCONFIG_API_RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<PluginConfigData> PluginConfigData::create(WUPSConfigAPIOptions options, WUPSConfigAPI_MenuOpenedCallback openedCallback, WUPSConfigAPI_MenuClosedCallback closedCallback) {
|
std::optional<PluginConfigData> PluginConfigData::create(const WUPSConfigAPIOptions options,
|
||||||
|
const WUPSConfigAPI_MenuOpenedCallback openedCallback,
|
||||||
|
const WUPSConfigAPI_MenuClosedCallback closedCallback) {
|
||||||
if (options.version != 1) {
|
if (options.version != 1) {
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "config/WUPSConfigAPI.h"
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <wups/config.h>
|
||||||
#include <wups/config_api.h>
|
#include <wups/config_api.h>
|
||||||
|
|
||||||
class PluginConfigData {
|
class PluginConfigData {
|
||||||
@ -13,7 +13,7 @@ public:
|
|||||||
|
|
||||||
[[nodiscard]] std::optional<WUPSConfigHandle> createConfig() const;
|
[[nodiscard]] std::optional<WUPSConfigHandle> createConfig() const;
|
||||||
|
|
||||||
[[nodiscard]] WUPSConfigAPIStatus CallMenuOpenendCallback(WUPSConfigHandle config) const;
|
[[nodiscard]] WUPSConfigAPIStatus CallMenuOpenedCallback(WUPSConfigHandle config) const;
|
||||||
|
|
||||||
[[nodiscard]] WUPSConfigAPIStatus CallMenuClosedCallback() const;
|
[[nodiscard]] WUPSConfigAPIStatus CallMenuClosedCallback() const;
|
||||||
|
|
||||||
|
@ -1,22 +1,24 @@
|
|||||||
#include "PluginContainer.h"
|
#include "PluginContainer.h"
|
||||||
|
|
||||||
|
#include <utils/storage/StorageUtils.h>
|
||||||
|
|
||||||
PluginContainer::PluginContainer(PluginMetaInformation metaInformation, PluginInformation pluginInformation, std::shared_ptr<PluginData> pluginData)
|
PluginContainer::PluginContainer(PluginMetaInformation metaInformation, PluginInformation pluginInformation, std::shared_ptr<PluginData> pluginData)
|
||||||
: mMetaInformation(std::move(metaInformation)),
|
: mMetaInformation(std::move(metaInformation)),
|
||||||
mPluginInformation(std::move(pluginInformation)),
|
mPluginInformation(std::move(pluginInformation)),
|
||||||
mPluginData(std::move(pluginData)) {
|
mPluginData(std::move(pluginData)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginContainer::PluginContainer(PluginContainer &&src) : mMetaInformation(std::move(src.mMetaInformation)),
|
PluginContainer::PluginContainer(PluginContainer &&src) noexcept : mMetaInformation(std::move(src.mMetaInformation)),
|
||||||
mPluginInformation(std::move(src.mPluginInformation)),
|
mPluginInformation(std::move(src.mPluginInformation)),
|
||||||
mPluginData(std::move(src.mPluginData)),
|
mPluginData(std::move(src.mPluginData)),
|
||||||
mPluginConfigData(std::move(src.mPluginConfigData)),
|
mPluginConfigData(std::move(src.mPluginConfigData)),
|
||||||
storageRootItem(src.storageRootItem)
|
storageRootItem(src.storageRootItem)
|
||||||
|
|
||||||
{
|
{
|
||||||
src.storageRootItem = {};
|
src.storageRootItem = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginContainer &PluginContainer::operator=(PluginContainer &&src) {
|
PluginContainer &PluginContainer::operator=(PluginContainer &&src) noexcept {
|
||||||
if (this != &src) {
|
if (this != &src) {
|
||||||
this->mMetaInformation = src.mMetaInformation;
|
this->mMetaInformation = src.mMetaInformation;
|
||||||
this->mPluginInformation = std::move(src.mPluginInformation);
|
this->mPluginInformation = std::move(src.mPluginInformation);
|
||||||
|
@ -21,10 +21,10 @@
|
|||||||
#include "PluginData.h"
|
#include "PluginData.h"
|
||||||
#include "PluginInformation.h"
|
#include "PluginInformation.h"
|
||||||
#include "PluginMetaInformation.h"
|
#include "PluginMetaInformation.h"
|
||||||
#include "utils/storage/StorageUtils.h"
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <optional>
|
||||||
#include <wups/config_api.h>
|
#include <wups/storage.h>
|
||||||
|
|
||||||
class PluginContainer {
|
class PluginContainer {
|
||||||
public:
|
public:
|
||||||
@ -34,9 +34,9 @@ public:
|
|||||||
PluginContainer(const PluginContainer &) = delete;
|
PluginContainer(const PluginContainer &) = delete;
|
||||||
|
|
||||||
|
|
||||||
PluginContainer(PluginContainer &&src);
|
PluginContainer(PluginContainer &&src) noexcept;
|
||||||
|
|
||||||
PluginContainer &operator=(PluginContainer &&src);
|
PluginContainer &operator=(PluginContainer &&src) noexcept;
|
||||||
|
|
||||||
|
|
||||||
[[nodiscard]] const PluginMetaInformation &getMetaInformation() const;
|
[[nodiscard]] const PluginMetaInformation &getMetaInformation() const;
|
||||||
|
@ -1,7 +1,26 @@
|
|||||||
#include "PluginData.h"
|
#include "PluginData.h"
|
||||||
|
|
||||||
|
PluginData::PluginData(std::vector<uint8_t> &&buffer, const std::string_view source) : mBuffer(std::move(buffer)), mSource(source) {
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginData::PluginData(std::span<uint8_t> buffer, const std::string_view source) : mBuffer(buffer.begin(), buffer.end()), mSource(source) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PluginData::PluginData(PluginData &&src) : mBuffer(std::move(src.mBuffer)),
|
||||||
|
mSource(std::move(src.mSource)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginData &PluginData::operator=(PluginData &&src) noexcept {
|
||||||
|
if (this != &src) {
|
||||||
|
this->mBuffer = std::move(src.mBuffer);
|
||||||
|
this->mSource = std::move(src.mSource);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t PluginData::getHandle() const {
|
uint32_t PluginData::getHandle() const {
|
||||||
return (uint32_t) this;
|
return reinterpret_cast<uint32_t>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::span<const uint8_t> PluginData::getBuffer() const {
|
std::span<const uint8_t> PluginData::getBuffer() const {
|
||||||
|
@ -17,21 +17,22 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <coreinit/memexpheap.h>
|
#include <cstdint>
|
||||||
#include <malloc.h>
|
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <utility>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class PluginData {
|
class PluginData {
|
||||||
public:
|
public:
|
||||||
explicit PluginData(std::vector<uint8_t> &&buffer, std::string_view source) : mBuffer(std::move(buffer)), mSource(source) {
|
explicit PluginData(std::vector<uint8_t> &&buffer, std::string_view source);
|
||||||
}
|
|
||||||
|
|
||||||
explicit PluginData(std::span<uint8_t> buffer, std::string_view source) : mBuffer(buffer.begin(), buffer.end()), mSource(source) {
|
explicit PluginData(std::span<uint8_t> buffer, std::string_view source);
|
||||||
}
|
|
||||||
|
PluginData(const PluginData &) = delete;
|
||||||
|
|
||||||
|
PluginData(PluginData &&src) noexcept;
|
||||||
|
|
||||||
|
PluginData &operator=(PluginData &&src) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] uint32_t getHandle() const;
|
[[nodiscard]] uint32_t getHandle() const;
|
||||||
|
|
||||||
|
@ -14,19 +14,20 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "PluginDataFactory.h"
|
#include "PluginDataFactory.h"
|
||||||
#include "NotificationsUtils.h"
|
#include "NotificationsUtils.h"
|
||||||
#include "fs/FSUtils.h"
|
#include "fs/FSUtils.h"
|
||||||
#include "utils/StringTools.h"
|
#include "utils/StringTools.h"
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
#include "utils/utils.h"
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <forward_list>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
std::set<std::shared_ptr<PluginData>> PluginDataFactory::loadDir(std::string_view path) {
|
#include <memory>
|
||||||
|
#include <set>
|
||||||
|
#include <sys/dirent.h>
|
||||||
|
|
||||||
|
std::set<std::shared_ptr<PluginData>> PluginDataFactory::loadDir(const std::string_view path) {
|
||||||
std::set<std::shared_ptr<PluginData>> result;
|
std::set<std::shared_ptr<PluginData>> result;
|
||||||
struct dirent *dp;
|
dirent *dp;
|
||||||
DIR *dfd;
|
DIR *dfd;
|
||||||
|
|
||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
@ -50,8 +51,7 @@ std::set<std::shared_ptr<PluginData>> PluginDataFactory::loadDir(std::string_vie
|
|||||||
|
|
||||||
auto full_file_path = string_format("%s/%s", path.data(), dp->d_name);
|
auto full_file_path = string_format("%s/%s", path.data(), dp->d_name);
|
||||||
DEBUG_FUNCTION_LINE("Loading plugin: %s", full_file_path.c_str());
|
DEBUG_FUNCTION_LINE("Loading plugin: %s", full_file_path.c_str());
|
||||||
auto pluginData = load(full_file_path);
|
if (auto pluginData = load(full_file_path)) {
|
||||||
if (pluginData) {
|
|
||||||
result.insert(std::move(pluginData));
|
result.insert(std::move(pluginData));
|
||||||
} else {
|
} else {
|
||||||
auto errMsg = string_format("Failed to load plugin: %s", full_file_path.c_str());
|
auto errMsg = string_format("Failed to load plugin: %s", full_file_path.c_str());
|
||||||
@ -65,15 +65,15 @@ std::set<std::shared_ptr<PluginData>> PluginDataFactory::loadDir(std::string_vie
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<PluginData> PluginDataFactory::load(std::string_view filename) {
|
std::unique_ptr<PluginData> PluginDataFactory::load(const std::string_view path) {
|
||||||
std::vector<uint8_t> buffer;
|
std::vector<uint8_t> buffer;
|
||||||
if (FSUtils::LoadFileToMem(filename, buffer) < 0) {
|
if (FSUtils::LoadFileToMem(path, buffer) < 0) {
|
||||||
DEBUG_FUNCTION_LINE_ERR("Failed to load %s into memory", filename.data());
|
DEBUG_FUNCTION_LINE_ERR("Failed to load %s into memory", path.data());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("Loaded file!");
|
DEBUG_FUNCTION_LINE_VERBOSE("Loaded file!");
|
||||||
return load(std::move(buffer), filename);
|
return load(std::move(buffer), path);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<PluginData> PluginDataFactory::load(std::vector<uint8_t> &&buffer, std::string_view source) {
|
std::unique_ptr<PluginData> PluginDataFactory::load(std::vector<uint8_t> &&buffer, std::string_view source) {
|
||||||
|
@ -16,14 +16,10 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "PluginData.h"
|
#include "PluginData.h"
|
||||||
#include <coreinit/memexpheap.h>
|
|
||||||
#include <forward_list>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class PluginDataFactory {
|
class PluginDataFactory {
|
||||||
|
@ -28,7 +28,7 @@ PluginInformation &PluginInformation::operator=(PluginInformation &&src) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginInformation::addHookData(HookData hook_data) {
|
void PluginInformation::addHookData(const HookData &hook_data) {
|
||||||
mHookDataList.push_back(hook_data);
|
mHookDataList.push_back(hook_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ std::optional<SectionInfo> PluginInformation::getSectionInfo(const std::string &
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginInformation::setTrampolineId(uint8_t trampolineId) {
|
void PluginInformation::setTrampolineId(const uint8_t trampolineId) {
|
||||||
this->mTrampolineId = trampolineId;
|
this->mTrampolineId = trampolineId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,15 +83,15 @@ uint8_t PluginInformation::getTrampolineId() const {
|
|||||||
return mTrampolineId;
|
return mTrampolineId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FunctionSymbolData *PluginInformation::getNearestFunctionSymbolData(uint32_t address) const {
|
const FunctionSymbolData *PluginInformation::getNearestFunctionSymbolData(const uint32_t address) const {
|
||||||
const FunctionSymbolData *result = nullptr;
|
const FunctionSymbolData *result = nullptr;
|
||||||
|
|
||||||
bool foundHit = false;
|
bool foundHit = false;
|
||||||
for (auto &cur : mSymbolDataList) {
|
for (auto &cur : mSymbolDataList) {
|
||||||
if (foundHit && address < (uint32_t) cur.getAddress()) {
|
if (foundHit && address < reinterpret_cast<uint32_t>(cur.getAddress())) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (address >= (uint32_t) cur.getAddress()) {
|
if (address >= reinterpret_cast<uint32_t>(cur.getAddress())) {
|
||||||
result = &cur;
|
result = &cur;
|
||||||
foundHit = true;
|
foundHit = true;
|
||||||
}
|
}
|
||||||
|
@ -20,15 +20,12 @@
|
|||||||
#include "FunctionData.h"
|
#include "FunctionData.h"
|
||||||
#include "FunctionSymbolData.h"
|
#include "FunctionSymbolData.h"
|
||||||
#include "HookData.h"
|
#include "HookData.h"
|
||||||
#include "PluginMetaInformation.h"
|
|
||||||
#include "RelocationData.h"
|
#include "RelocationData.h"
|
||||||
#include "SectionInfo.h"
|
#include "SectionInfo.h"
|
||||||
#include "utils/HeapMemoryFixedSize.h"
|
#include "utils/HeapMemoryFixedSize.h"
|
||||||
#include "utils/utils.h"
|
#include <cstdint>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <ranges>
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -71,7 +68,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
PluginInformation() = default;
|
PluginInformation() = default;
|
||||||
|
|
||||||
void addHookData(HookData hook_data);
|
void addHookData(const HookData &hook_data);
|
||||||
|
|
||||||
void addFunctionData(FunctionData function_data);
|
void addFunctionData(FunctionData function_data);
|
||||||
|
|
||||||
|
@ -16,13 +16,12 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "PluginInformationFactory.h"
|
#include "PluginInformationFactory.h"
|
||||||
#include "../utils/ElfUtils.h"
|
#include "utils/ElfUtils.h"
|
||||||
#include "utils/HeapMemoryFixedSize.h"
|
#include "utils/logger.h"
|
||||||
|
#include "utils/utils.h"
|
||||||
#include "utils/wiiu_zlib.hpp"
|
#include "utils/wiiu_zlib.hpp"
|
||||||
|
|
||||||
#include <coreinit/cache.h>
|
#include <coreinit/cache.h>
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <wups/function_patching.h>
|
#include <wups/function_patching.h>
|
||||||
|
|
||||||
using namespace ELFIO;
|
using namespace ELFIO;
|
||||||
@ -50,7 +49,7 @@ PluginInformationFactory::load(const PluginData &pluginData, std::vector<relocat
|
|||||||
DEBUG_FUNCTION_LINE_ERR("Failed alloc memory for destinations array");
|
DEBUG_FUNCTION_LINE_ERR("Failed alloc memory for destinations array");
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
std::span<uint8_t *> destinations(destinationsData.get(), sec_num);
|
std::span destinations(destinationsData.get(), sec_num);
|
||||||
|
|
||||||
uint32_t totalSize = 0;
|
uint32_t totalSize = 0;
|
||||||
|
|
||||||
@ -265,7 +264,7 @@ PluginInformationFactory::load(const PluginData &pluginData, std::vector<relocat
|
|||||||
return pluginInfo;
|
return pluginInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PluginInformationFactory::addImportRelocationData(PluginInformation &pluginInfo, const elfio &reader, std::span<uint8_t *> destinations) {
|
bool PluginInformationFactory::addImportRelocationData(PluginInformation &pluginInfo, const elfio &reader, const std::span<uint8_t *> destinations) {
|
||||||
std::map<uint32_t, std::shared_ptr<ImportRPLInformation>> infoMap;
|
std::map<uint32_t, std::shared_ptr<ImportRPLInformation>> infoMap;
|
||||||
|
|
||||||
uint32_t sec_num = reader.sections.size();
|
uint32_t sec_num = reader.sections.size();
|
||||||
|
@ -16,15 +16,11 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "PluginData.h"
|
||||||
#include "../elfio/elfio.hpp"
|
|
||||||
#include "PluginContainer.h"
|
|
||||||
#include "PluginInformation.h"
|
#include "PluginInformation.h"
|
||||||
#include <coreinit/memheap.h>
|
|
||||||
#include <map>
|
#include <elfio/elfio.hpp>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <wums/defines/relocation_defines.h>
|
#include <wums/defines/relocation_defines.h>
|
||||||
|
|
||||||
class PluginInformationFactory {
|
class PluginInformationFactory {
|
||||||
|
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 "WUPSVersion.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class PluginMetaInformation {
|
class PluginMetaInformation {
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] const std::string &getName() const {
|
[[nodiscard]] const std::string &getName() const;
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getAuthor() const {
|
[[nodiscard]] const std::string &getAuthor() const;
|
||||||
return this->author;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getVersion() const {
|
[[nodiscard]] const std::string &getVersion() const;
|
||||||
return this->version;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getLicense() const {
|
[[nodiscard]] const std::string &getLicense() const;
|
||||||
return this->license;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getBuildTimestamp() const {
|
[[nodiscard]] const std::string &getBuildTimestamp() const;
|
||||||
return this->buildtimestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getDescription() const {
|
[[nodiscard]] const std::string &getDescription() const;
|
||||||
return this->description;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const WUPSVersion &getWUPSVersion() const {
|
[[nodiscard]] const WUPSVersion &getWUPSVersion() const;
|
||||||
return this->wupsversion;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getStorageId() const {
|
[[nodiscard]] const std::string &getStorageId() const;
|
||||||
return this->storageId;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] size_t getSize() const {
|
[[nodiscard]] size_t getSize() const;
|
||||||
return this->size;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PluginMetaInformation() = default;
|
PluginMetaInformation();
|
||||||
|
|
||||||
void setName(std::string _name) {
|
void setName(std::string name);
|
||||||
this->name = std::move(_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAuthor(std::string _author) {
|
void setAuthor(std::string author);
|
||||||
this->author = std::move(_author);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setVersion(std::string _version) {
|
void setVersion(std::string version);
|
||||||
this->version = std::move(_version);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setLicense(std::string _license) {
|
void setLicense(std::string license);
|
||||||
this->license = std::move(_license);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setBuildTimestamp(std::string _buildtimestamp) {
|
void setBuildTimestamp(std::string buildTimestamp);
|
||||||
this->buildtimestamp = std::move(_buildtimestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setDescription(std::string _description) {
|
void setDescription(std::string description);
|
||||||
this->description = std::move(_description);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setWUPSVersion(uint16_t major, uint16_t minor, uint16_t revision) {
|
void setWUPSVersion(uint16_t major, uint16_t minor, uint16_t revision);
|
||||||
this->wupsversion = WUPSVersion(major, minor, revision);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setWUPSVersion(WUPSVersion &_wupsversion) {
|
void setWUPSVersion(const WUPSVersion &wupsVersion);
|
||||||
this->wupsversion = _wupsversion;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setSize(size_t _size) {
|
void setSize(size_t size);
|
||||||
this->size = _size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setStorageId(std::string _storageId) {
|
void setStorageId(std::string storageId);
|
||||||
this->storageId = std::move(_storageId);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string name;
|
std::string mName;
|
||||||
std::string author;
|
std::string mAuthor;
|
||||||
std::string version;
|
std::string mVersion;
|
||||||
std::string license;
|
std::string mLicense;
|
||||||
std::string buildtimestamp;
|
std::string mBuildTimestamp;
|
||||||
std::string description;
|
std::string mDescription;
|
||||||
std::string storageId;
|
std::string mStorageId;
|
||||||
size_t size{};
|
size_t mSize = {};
|
||||||
WUPSVersion wupsversion = WUPSVersion(0, 0, 0);
|
WUPSVersion mWUPSVersion = WUPSVersion(0, 0, 0);
|
||||||
|
|
||||||
friend class PluginMetaInformationFactory;
|
friend class PluginMetaInformationFactory;
|
||||||
|
|
||||||
|
@ -16,11 +16,15 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "PluginMetaInformationFactory.h"
|
#include "PluginMetaInformationFactory.h"
|
||||||
#include "elfio/elfio.hpp"
|
|
||||||
|
#include "PluginData.h"
|
||||||
|
#include "PluginMetaInformation.h"
|
||||||
#include "fs/FSUtils.h"
|
#include "fs/FSUtils.h"
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
#include "utils/wiiu_zlib.hpp"
|
#include "utils/wiiu_zlib.hpp"
|
||||||
#include <memory>
|
|
||||||
|
#include <elfio/elfio.hpp>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(const PluginData &pluginData, PluginParseErrors &error) {
|
std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(const PluginData &pluginData, PluginParseErrors &error) {
|
||||||
return loadPlugin(pluginData.getBuffer(), error);
|
return loadPlugin(pluginData.getBuffer(), error);
|
||||||
|
@ -19,11 +19,10 @@
|
|||||||
|
|
||||||
#include "PluginData.h"
|
#include "PluginData.h"
|
||||||
#include "PluginMetaInformation.h"
|
#include "PluginMetaInformation.h"
|
||||||
#include "elfio/elfio.hpp"
|
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <span>
|
||||||
#include <vector>
|
#include <string_view>
|
||||||
|
|
||||||
enum PluginParseErrors {
|
enum PluginParseErrors {
|
||||||
PLUGIN_PARSE_ERROR_NONE,
|
PLUGIN_PARSE_ERROR_NONE,
|
||||||
|
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
|
#pragma once
|
||||||
|
|
||||||
#include "ImportRPLInformation.h"
|
#include "ImportRPLInformation.h"
|
||||||
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
class RelocationData {
|
class RelocationData {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RelocationData(const char type, size_t offset, int32_t addend, void *destination, std::string name, std::shared_ptr<ImportRPLInformation> rplInfo) : type(type),
|
RelocationData(char type, size_t offset, int32_t addend, void *destination, std::string name, std::shared_ptr<ImportRPLInformation> rplInfo);
|
||||||
offset(offset),
|
|
||||||
addend(addend),
|
|
||||||
destination(destination),
|
|
||||||
name(std::move(name)),
|
|
||||||
rplInfo(std::move(rplInfo)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
RelocationData(const RelocationData &o2) = default;
|
RelocationData(const RelocationData &o2);
|
||||||
|
|
||||||
virtual ~RelocationData() = default;
|
virtual ~RelocationData();
|
||||||
|
|
||||||
[[nodiscard]] char getType() const {
|
[[nodiscard]] char getType() const;
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] size_t getOffset() const {
|
[[nodiscard]] size_t getOffset() const;
|
||||||
return offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] int32_t getAddend() const {
|
[[nodiscard]] int32_t getAddend() const;
|
||||||
return addend;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const void *getDestination() const {
|
[[nodiscard]] const void *getDestination() const;
|
||||||
return destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getName() const {
|
[[nodiscard]] const std::string &getName() const;
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const ImportRPLInformation &getImportRPLInformation() const {
|
[[nodiscard]] const ImportRPLInformation &getImportRPLInformation() const;
|
||||||
return *rplInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char type;
|
char mType;
|
||||||
size_t offset;
|
size_t mOffset;
|
||||||
int32_t addend;
|
int32_t mAddend;
|
||||||
void *destination;
|
void *mDestination;
|
||||||
std::string name;
|
std::string mName;
|
||||||
std::shared_ptr<ImportRPLInformation> rplInfo;
|
std::shared_ptr<ImportRPLInformation> mRPLInfo;
|
||||||
};
|
};
|
||||||
|
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
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
class SectionInfo {
|
class SectionInfo {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SectionInfo(std::string name, uint32_t address, uint32_t sectionSize) : name(std::move(name)),
|
SectionInfo(std::string name, uint32_t address, uint32_t sectionSize);
|
||||||
address(address),
|
|
||||||
sectionSize(sectionSize) {
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getName() const {
|
[[nodiscard]] const std::string &getName() const;
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] uint32_t getAddress() const {
|
[[nodiscard]] uint32_t getAddress() const;
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] uint32_t getSize() const {
|
[[nodiscard]] uint32_t getSize() const;
|
||||||
return sectionSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] uint32_t isInSection(uint32_t addr) const {
|
[[nodiscard]] uint32_t isInSection(uint32_t addr) const;
|
||||||
return addr >= address && addr < address + sectionSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string name;
|
std::string mName;
|
||||||
uint32_t address{};
|
uint32_t mAddress = {};
|
||||||
uint32_t sectionSize{};
|
uint32_t mSectionSize = {};
|
||||||
};
|
};
|
||||||
|
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 <cstdint>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
class WUPSVersion {
|
class WUPSVersion {
|
||||||
public:
|
public:
|
||||||
WUPSVersion(int major, int minor, int revision)
|
WUPSVersion(int major, int minor, int revision);
|
||||||
: mVersion((static_cast<uint64_t>(major) << 32) |
|
|
||||||
(static_cast<uint64_t>(minor) << 16) |
|
|
||||||
static_cast<uint64_t>(revision)) {}
|
|
||||||
|
|
||||||
static std::optional<WUPSVersion> createFromString(const std::string &versionStr) {
|
static std::optional<WUPSVersion> createFromString(const std::string &versionStr);
|
||||||
char *end;
|
|
||||||
errno = 0; // Initialize errno before calling strtol
|
|
||||||
|
|
||||||
auto major = strtol(versionStr.c_str(), &end, 10);
|
std::strong_ordering operator<=>(const WUPSVersion &other) const;
|
||||||
if (errno || *end != '.') {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
[[nodiscard]] std::string toString() const;
|
||||||
auto minor = strtol(end + 1, &end, 10);
|
|
||||||
if (errno || *end != '.') {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto revision = strtol(end + 1, &end, 10);
|
|
||||||
if (errno || *end != '\0') {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
return WUPSVersion(static_cast<int>(major), static_cast<int>(minor), static_cast<int>(revision));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::strong_ordering operator<=>(const WUPSVersion &other) const {
|
|
||||||
return mVersion <=> other.mVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] std::string toString() const {
|
|
||||||
return string_format("%d.%d.%d", static_cast<int>((mVersion >> 32) & 0xFFFF),
|
|
||||||
static_cast<int>((mVersion >> 16) & 0xFFFF),
|
|
||||||
static_cast<int>((mVersion) &0xFFFF));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t mVersion{};
|
uint32_t mMajor;
|
||||||
|
uint32_t mMinor;
|
||||||
|
uint32_t mRevision;
|
||||||
};
|
};
|
||||||
|
@ -13,23 +13,23 @@
|
|||||||
// buffer width
|
// buffer width
|
||||||
#define DRC_WIDTH 0x380
|
#define DRC_WIDTH 0x380
|
||||||
|
|
||||||
bool DrawUtils::isBackBuffer;
|
bool DrawUtils::mIsBackBuffer;
|
||||||
|
|
||||||
uint8_t *DrawUtils::tvBuffer = nullptr;
|
uint8_t *DrawUtils::mTVBuffer = nullptr;
|
||||||
uint32_t DrawUtils::tvSize = 0;
|
uint32_t DrawUtils::mTVSize = 0;
|
||||||
uint8_t *DrawUtils::drcBuffer = nullptr;
|
uint8_t *DrawUtils::mDRCBuffer = nullptr;
|
||||||
uint32_t DrawUtils::drcSize = 0;
|
uint32_t DrawUtils::mDRCSize = 0;
|
||||||
uint32_t DrawUtils::usedTVWidth = 1280;
|
uint32_t DrawUtils::mUsedTVWidth = 1280;
|
||||||
float DrawUtils::usedTVScale = 1.5f;
|
float DrawUtils::mUsedTVScale = 1.5f;
|
||||||
static SFT pFont = {};
|
static SFT pFont = {};
|
||||||
|
|
||||||
static Color font_col(0xFFFFFFFF);
|
static Color font_col(0xFFFFFFFF);
|
||||||
|
|
||||||
void DrawUtils::initBuffers(void *tvBuffer_, uint32_t tvSize_, void *drcBuffer_, uint32_t drcSize_) {
|
void DrawUtils::initBuffers(void *tvBuffer, const uint32_t tvSize, void *drcBuffer, const uint32_t drcSize) {
|
||||||
DrawUtils::tvBuffer = (uint8_t *) tvBuffer_;
|
DrawUtils::mTVBuffer = static_cast<uint8_t *>(tvBuffer);
|
||||||
DrawUtils::tvSize = tvSize_;
|
DrawUtils::mTVSize = tvSize;
|
||||||
DrawUtils::drcBuffer = (uint8_t *) drcBuffer_;
|
DrawUtils::mDRCBuffer = static_cast<uint8_t *>(drcBuffer);
|
||||||
DrawUtils::drcSize = drcSize_;
|
DrawUtils::mDRCSize = drcSize;
|
||||||
|
|
||||||
bool bigScale = true;
|
bool bigScale = true;
|
||||||
switch (TVEGetCurrentPort()) {
|
switch (TVEGetCurrentPort()) {
|
||||||
@ -67,53 +67,53 @@ void DrawUtils::initBuffers(void *tvBuffer_, uint32_t tvSize_, void *drcBuffer_,
|
|||||||
auto tvScanBufferWidth = DCReadReg32(SCREEN_TV, D1GRPH_X_END_REG);
|
auto tvScanBufferWidth = DCReadReg32(SCREEN_TV, D1GRPH_X_END_REG);
|
||||||
|
|
||||||
if (tvScanBufferWidth == 640) { // 480i/480p/576i 4:3
|
if (tvScanBufferWidth == 640) { // 480i/480p/576i 4:3
|
||||||
DrawUtils::usedTVWidth = 640;
|
DrawUtils::mUsedTVWidth = 640;
|
||||||
SetDCPitchReg(SCREEN_TV, 640);
|
SetDCPitchReg(SCREEN_TV, 640);
|
||||||
DrawUtils::usedTVScale = bigScale ? 0.75 : 0.75f;
|
DrawUtils::mUsedTVScale = bigScale ? 0.75 : 0.75f;
|
||||||
} else if (tvScanBufferWidth == 854) { // 480i/480p/576i 16:9
|
} else if (tvScanBufferWidth == 854) { // 480i/480p/576i 16:9
|
||||||
DrawUtils::usedTVWidth = 896;
|
DrawUtils::mUsedTVWidth = 896;
|
||||||
SetDCPitchReg(SCREEN_TV, 896);
|
SetDCPitchReg(SCREEN_TV, 896);
|
||||||
DrawUtils::usedTVScale = bigScale ? 1.0 : 1.0f;
|
DrawUtils::mUsedTVScale = bigScale ? 1.0 : 1.0f;
|
||||||
} else if (tvScanBufferWidth == 1280) { // 720p 16:9
|
} else if (tvScanBufferWidth == 1280) { // 720p 16:9
|
||||||
DrawUtils::usedTVWidth = 1280;
|
DrawUtils::mUsedTVWidth = 1280;
|
||||||
SetDCPitchReg(SCREEN_TV, 1280);
|
SetDCPitchReg(SCREEN_TV, 1280);
|
||||||
if (bigScale) {
|
if (bigScale) {
|
||||||
DrawUtils::usedTVScale = 1.5;
|
DrawUtils::mUsedTVScale = 1.5;
|
||||||
} else {
|
} else {
|
||||||
DrawUtils::usedTVScale = 0.75f;
|
DrawUtils::mUsedTVScale = 0.75f;
|
||||||
if (tvResolution == AVM_TV_RESOLUTION_480I_PAL60 || tvResolution == AVM_TV_RESOLUTION_480I) {
|
if (tvResolution == AVM_TV_RESOLUTION_480I_PAL60 || tvResolution == AVM_TV_RESOLUTION_480I) {
|
||||||
AVMTvAspectRatio tvAspectRatio;
|
AVMTvAspectRatio tvAspectRatio;
|
||||||
if (AVMGetTVAspectRatio(&tvAspectRatio) && tvAspectRatio == AVM_TV_ASPECT_RATIO_16_9) {
|
if (AVMGetTVAspectRatio(&tvAspectRatio) && tvAspectRatio == AVM_TV_ASPECT_RATIO_16_9) {
|
||||||
DEBUG_FUNCTION_LINE_WARN("force big scaling for 480i + 16:9");
|
DEBUG_FUNCTION_LINE_WARN("force big scaling for 480i + 16:9");
|
||||||
DrawUtils::usedTVScale = 1.5;
|
DrawUtils::mUsedTVScale = 1.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (tvScanBufferWidth == 1920) { // 1080i/1080p 16:9
|
} else if (tvScanBufferWidth == 1920) { // 1080i/1080p 16:9
|
||||||
DrawUtils::usedTVWidth = 1920;
|
DrawUtils::mUsedTVWidth = 1920;
|
||||||
SetDCPitchReg(SCREEN_TV, 1920);
|
SetDCPitchReg(SCREEN_TV, 1920);
|
||||||
DrawUtils::usedTVScale = bigScale ? 2.25 : 1.125f;
|
DrawUtils::mUsedTVScale = bigScale ? 2.25 : 1.125f;
|
||||||
} else {
|
} else {
|
||||||
DrawUtils::usedTVWidth = tvScanBufferWidth;
|
DrawUtils::mUsedTVWidth = tvScanBufferWidth;
|
||||||
SetDCPitchReg(SCREEN_TV, tvScanBufferWidth);
|
SetDCPitchReg(SCREEN_TV, tvScanBufferWidth);
|
||||||
DrawUtils::usedTVScale = 1.0f;
|
DrawUtils::mUsedTVScale = 1.0f;
|
||||||
DEBUG_FUNCTION_LINE_WARN("Unknown tv width detected, config menu might not show properly");
|
DEBUG_FUNCTION_LINE_WARN("Unknown tv width detected, config menu might not show properly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawUtils::beginDraw() {
|
void DrawUtils::beginDraw() {
|
||||||
uint32_t pixel = *(uint32_t *) tvBuffer;
|
const uint32_t pixel = *reinterpret_cast<uint32_t *>(mTVBuffer);
|
||||||
|
|
||||||
// check which buffer is currently used
|
// check which buffer is currently used
|
||||||
OSScreenPutPixelEx(SCREEN_TV, 0, 0, 0xABCDEF90);
|
OSScreenPutPixelEx(SCREEN_TV, 0, 0, 0xABCDEF90);
|
||||||
if (*(uint32_t *) tvBuffer == 0xABCDEF90) {
|
if (*reinterpret_cast<uint32_t *>(mTVBuffer) == 0xABCDEF90) {
|
||||||
isBackBuffer = false;
|
mIsBackBuffer = false;
|
||||||
} else {
|
} else {
|
||||||
isBackBuffer = true;
|
mIsBackBuffer = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore the pixel we used for checking
|
// restore the pixel we used for checking
|
||||||
*(uint32_t *) tvBuffer = pixel;
|
*reinterpret_cast<uint32_t *>(mTVBuffer) = pixel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawUtils::endDraw() {
|
void DrawUtils::endDraw() {
|
||||||
@ -125,58 +125,58 @@ void DrawUtils::endDraw() {
|
|||||||
OSScreenFlipBuffersEx(SCREEN_TV);
|
OSScreenFlipBuffersEx(SCREEN_TV);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawUtils::clear(Color col) {
|
void DrawUtils::clear(const Color col) {
|
||||||
OSScreenClearBufferEx(SCREEN_TV, col.color);
|
OSScreenClearBufferEx(SCREEN_TV, col.color);
|
||||||
OSScreenClearBufferEx(SCREEN_DRC, col.color);
|
OSScreenClearBufferEx(SCREEN_DRC, col.color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawUtils::drawPixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
|
void DrawUtils::drawPixel(const uint32_t x, const uint32_t y, const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t a) {
|
||||||
if (a == 0) {
|
if (a == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float opacity = a / 255.0f;
|
const float opacity = a / 255.0f;
|
||||||
|
|
||||||
// put pixel in the drc buffer
|
// put pixel in the drc buffer
|
||||||
uint32_t i = (x + y * DRC_WIDTH) * 4;
|
uint32_t i = (x + y * DRC_WIDTH) * 4;
|
||||||
if (i + 3 < drcSize / 2) {
|
if (i + 3 < mDRCSize / 2) {
|
||||||
if (isBackBuffer) {
|
if (mIsBackBuffer) {
|
||||||
i += drcSize / 2;
|
i += mDRCSize / 2;
|
||||||
}
|
}
|
||||||
if (a == 0xFF) {
|
if (a == 0xFF) {
|
||||||
drcBuffer[i] = r;
|
mDRCBuffer[i] = r;
|
||||||
drcBuffer[i + 1] = g;
|
mDRCBuffer[i + 1] = g;
|
||||||
drcBuffer[i + 2] = b;
|
mDRCBuffer[i + 2] = b;
|
||||||
} else {
|
} else {
|
||||||
drcBuffer[i] = r * opacity + drcBuffer[i] * (1 - opacity);
|
mDRCBuffer[i] = r * opacity + mDRCBuffer[i] * (1 - opacity);
|
||||||
drcBuffer[i + 1] = g * opacity + drcBuffer[i + 1] * (1 - opacity);
|
mDRCBuffer[i + 1] = g * opacity + mDRCBuffer[i + 1] * (1 - opacity);
|
||||||
drcBuffer[i + 2] = b * opacity + drcBuffer[i + 2] * (1 - opacity);
|
mDRCBuffer[i + 2] = b * opacity + mDRCBuffer[i + 2] * (1 - opacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// scale and put pixel in the tv buffer
|
// scale and put pixel in the tv buffer
|
||||||
for (uint32_t yy = (y * DrawUtils::usedTVScale); yy < ((y * DrawUtils::usedTVScale) + (uint32_t) DrawUtils::usedTVScale); yy++) {
|
for (uint32_t yy = (y * DrawUtils::mUsedTVScale); yy < ((y * DrawUtils::mUsedTVScale) + (uint32_t) DrawUtils::mUsedTVScale); yy++) {
|
||||||
for (uint32_t xx = (x * DrawUtils::usedTVScale); xx < ((x * DrawUtils::usedTVScale) + (uint32_t) DrawUtils::usedTVScale); xx++) {
|
for (uint32_t xx = (x * DrawUtils::mUsedTVScale); xx < ((x * DrawUtils::mUsedTVScale) + (uint32_t) DrawUtils::mUsedTVScale); xx++) {
|
||||||
uint32_t i = (xx + yy * DrawUtils::usedTVWidth) * 4;
|
uint32_t i = (xx + yy * DrawUtils::mUsedTVWidth) * 4;
|
||||||
if (i + 3 < tvSize / 2) {
|
if (i + 3 < mTVSize / 2) {
|
||||||
if (isBackBuffer) {
|
if (mIsBackBuffer) {
|
||||||
i += tvSize / 2;
|
i += mTVSize / 2;
|
||||||
}
|
}
|
||||||
if (a == 0xFF) {
|
if (a == 0xFF) {
|
||||||
tvBuffer[i] = r;
|
mTVBuffer[i] = r;
|
||||||
tvBuffer[i + 1] = g;
|
mTVBuffer[i + 1] = g;
|
||||||
tvBuffer[i + 2] = b;
|
mTVBuffer[i + 2] = b;
|
||||||
} else {
|
} else {
|
||||||
tvBuffer[i] = r * opacity + tvBuffer[i] * (1 - opacity);
|
mTVBuffer[i] = r * opacity + mTVBuffer[i] * (1 - opacity);
|
||||||
tvBuffer[i + 1] = g * opacity + tvBuffer[i + 1] * (1 - opacity);
|
mTVBuffer[i + 1] = g * opacity + mTVBuffer[i + 1] * (1 - opacity);
|
||||||
tvBuffer[i + 2] = b * opacity + tvBuffer[i + 2] * (1 - opacity);
|
mTVBuffer[i + 2] = b * opacity + mTVBuffer[i + 2] * (1 - opacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawUtils::drawRectFilled(uint32_t x, uint32_t y, uint32_t w, uint32_t h, Color col) {
|
void DrawUtils::drawRectFilled(const uint32_t x, const uint32_t y, const uint32_t w, const uint32_t h, const Color col) {
|
||||||
for (uint32_t yy = y; yy < y + h; yy++) {
|
for (uint32_t yy = y; yy < y + h; yy++) {
|
||||||
for (uint32_t xx = x; xx < x + w; xx++) {
|
for (uint32_t xx = x; xx < x + w; xx++) {
|
||||||
drawPixel(xx, yy, col);
|
drawPixel(xx, yy, col);
|
||||||
@ -184,22 +184,22 @@ void DrawUtils::drawRectFilled(uint32_t x, uint32_t y, uint32_t w, uint32_t h, C
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawUtils::drawRect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t borderSize, Color col) {
|
void DrawUtils::drawRect(const uint32_t x, const uint32_t y, const uint32_t w, const uint32_t h, const uint32_t borderSize, const Color col) {
|
||||||
drawRectFilled(x, y, w, borderSize, col);
|
drawRectFilled(x, y, w, borderSize, col);
|
||||||
drawRectFilled(x, y + h - borderSize, w, borderSize, col);
|
drawRectFilled(x, y + h - borderSize, w, borderSize, col);
|
||||||
drawRectFilled(x, y, borderSize, h, col);
|
drawRectFilled(x, y, borderSize, h, col);
|
||||||
drawRectFilled(x + w - borderSize, y, borderSize, h, col);
|
drawRectFilled(x + w - borderSize, y, borderSize, h, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawUtils::drawBitmap(uint32_t x, uint32_t y, uint32_t target_width, uint32_t target_height, const uint8_t *data) {
|
void DrawUtils::drawBitmap(const uint32_t x, const uint32_t y, const uint32_t target_width, const uint32_t target_height, const uint8_t *data) {
|
||||||
if (data[0] != 'B' || data[1] != 'M') {
|
if (data[0] != 'B' || data[1] != 'M') {
|
||||||
// invalid header
|
// invalid header
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t dataPos = __builtin_bswap32(*(uint32_t *) &(data[0x0A]));
|
uint32_t dataPos = __builtin_bswap32(*(uint32_t *) &(data[0x0A]));
|
||||||
uint32_t width = __builtin_bswap32(*(uint32_t *) &(data[0x12]));
|
const uint32_t width = __builtin_bswap32(*(uint32_t *) &(data[0x12]));
|
||||||
uint32_t height = __builtin_bswap32(*(uint32_t *) &(data[0x16]));
|
const uint32_t height = __builtin_bswap32(*(uint32_t *) &(data[0x16]));
|
||||||
|
|
||||||
if (dataPos == 0) {
|
if (dataPos == 0) {
|
||||||
dataPos = 54;
|
dataPos = 54;
|
||||||
@ -218,13 +218,13 @@ void DrawUtils::drawBitmap(uint32_t x, uint32_t y, uint32_t target_width, uint32
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void png_read_data(png_structp png_ptr, png_bytep outBytes, png_size_t byteCountToRead) {
|
static void png_read_data(png_structp png_ptr, png_bytep outBytes, png_size_t byteCountToRead) {
|
||||||
void **data = (void **) png_get_io_ptr(png_ptr);
|
void **data = static_cast<void **>(png_get_io_ptr(png_ptr));
|
||||||
|
|
||||||
memcpy(outBytes, *data, byteCountToRead);
|
memcpy(outBytes, *data, byteCountToRead);
|
||||||
*((uint8_t **) data) += byteCountToRead;
|
*reinterpret_cast<uint8_t **>(data) += byteCountToRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawUtils::drawPNG(uint32_t x, uint32_t y, const uint8_t *data) {
|
void DrawUtils::drawPNG(const uint32_t x, const uint32_t y, const uint8_t *data) {
|
||||||
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||||
if (png_ptr == nullptr) {
|
if (png_ptr == nullptr) {
|
||||||
return;
|
return;
|
||||||
@ -240,17 +240,17 @@ void DrawUtils::drawPNG(uint32_t x, uint32_t y, const uint8_t *data) {
|
|||||||
|
|
||||||
png_read_info(png_ptr, info_ptr);
|
png_read_info(png_ptr, info_ptr);
|
||||||
|
|
||||||
uint32_t width = 0;
|
uint32_t width = 0;
|
||||||
uint32_t height = 0;
|
uint32_t height = 0;
|
||||||
int bitDepth = 0;
|
int bitDepth = 0;
|
||||||
int colorType = -1;
|
int colorType = -1;
|
||||||
uint32_t retval = png_get_IHDR(png_ptr, info_ptr, &width, &height, &bitDepth, &colorType, nullptr, nullptr, nullptr);
|
const uint32_t retval = png_get_IHDR(png_ptr, info_ptr, &width, &height, &bitDepth, &colorType, nullptr, nullptr, nullptr);
|
||||||
if (retval != 1) {
|
if (retval != 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t bytesPerRow = png_get_rowbytes(png_ptr, info_ptr);
|
const uint32_t bytesPerRow = png_get_rowbytes(png_ptr, info_ptr);
|
||||||
auto *rowData = new uint8_t[bytesPerRow];
|
auto *rowData = new uint8_t[bytesPerRow];
|
||||||
|
|
||||||
for (uint32_t yy = y; yy < y + height; yy++) {
|
for (uint32_t yy = y; yy < y + height; yy++) {
|
||||||
png_read_row(png_ptr, (png_bytep) rowData, nullptr);
|
png_read_row(png_ptr, (png_bytep) rowData, nullptr);
|
||||||
@ -302,17 +302,17 @@ void DrawUtils::setFontSize(uint32_t size) {
|
|||||||
sft_lmetrics(&pFont, &metrics);
|
sft_lmetrics(&pFont, &metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawUtils::setFontColor(Color col) {
|
void DrawUtils::setFontColor(const Color col) {
|
||||||
font_col = col;
|
font_col = col;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_freetype_bitmap(SFT_Image *bmp, int32_t x, int32_t y) {
|
static void draw_freetype_bitmap(const SFT_Image *bmp, const int32_t x, const int32_t y) {
|
||||||
int32_t i, j, p, q;
|
int32_t i, j, p, q;
|
||||||
|
|
||||||
int32_t x_max = x + bmp->width;
|
int32_t x_max = x + bmp->width;
|
||||||
int32_t y_max = y + bmp->height;
|
int32_t y_max = y + bmp->height;
|
||||||
|
|
||||||
auto *src = (uint8_t *) bmp->pixels;
|
const auto *src = static_cast<uint8_t *>(bmp->pixels);
|
||||||
|
|
||||||
for (i = x, p = 0; i < x_max; i++, p++) {
|
for (i = x, p = 0; i < x_max; i++, p++) {
|
||||||
for (j = y, q = 0; j < y_max; j++, q++) {
|
for (j = y, q = 0; j < y_max; j++, q++) {
|
||||||
@ -320,13 +320,13 @@ static void draw_freetype_bitmap(SFT_Image *bmp, int32_t x, int32_t y) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
float opacity = src[q * bmp->width + p] / 255.0f;
|
const float opacity = src[q * bmp->width + p] / 255.0f;
|
||||||
DrawUtils::drawPixel(i, j, font_col.r, font_col.g, font_col.b, font_col.a * opacity);
|
DrawUtils::drawPixel(i, j, font_col.r, font_col.g, font_col.b, font_col.a * opacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawUtils::print(uint32_t x, uint32_t y, const char *string, bool alignRight) {
|
void DrawUtils::print(const uint32_t x, const uint32_t y, const char *string, const bool alignRight) {
|
||||||
auto *buffer = new wchar_t[strlen(string) + 1];
|
auto *buffer = new wchar_t[strlen(string) + 1];
|
||||||
|
|
||||||
size_t num = mbstowcs(buffer, string, strlen(string));
|
size_t num = mbstowcs(buffer, string, strlen(string));
|
||||||
@ -342,9 +342,9 @@ void DrawUtils::print(uint32_t x, uint32_t y, const char *string, bool alignRigh
|
|||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawUtils::print(uint32_t x, uint32_t y, const wchar_t *string, bool alignRight) {
|
void DrawUtils::print(const uint32_t x, const uint32_t y, const wchar_t *string, const bool alignRight) {
|
||||||
auto penX = (int32_t) x;
|
auto penX = static_cast<int32_t>(x);
|
||||||
auto penY = (int32_t) y;
|
auto penY = static_cast<int32_t>(y);
|
||||||
|
|
||||||
if (alignRight) {
|
if (alignRight) {
|
||||||
penX -= getTextWidth(string);
|
penX -= getTextWidth(string);
|
||||||
@ -392,8 +392,8 @@ void DrawUtils::print(uint32_t x, uint32_t y, const wchar_t *string, bool alignR
|
|||||||
DEBUG_FUNCTION_LINE_ERR("Failed to render glyph");
|
DEBUG_FUNCTION_LINE_ERR("Failed to render glyph");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
draw_freetype_bitmap(&img, (int32_t) (penX + mtx.leftSideBearing), (int32_t) (penY + mtx.yOffset));
|
draw_freetype_bitmap(&img, static_cast<int32_t>(penX + mtx.leftSideBearing), penY + mtx.yOffset);
|
||||||
penX += (int32_t) mtx.advanceWidth;
|
penX += static_cast<int32_t>(mtx.advanceWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -402,8 +402,7 @@ void DrawUtils::print(uint32_t x, uint32_t y, const wchar_t *string, bool alignR
|
|||||||
uint32_t DrawUtils::getTextWidth(const char *string) {
|
uint32_t DrawUtils::getTextWidth(const char *string) {
|
||||||
auto *buffer = new wchar_t[strlen(string) + 1];
|
auto *buffer = new wchar_t[strlen(string) + 1];
|
||||||
|
|
||||||
size_t num = mbstowcs(buffer, string, strlen(string));
|
if (const size_t num = mbstowcs(buffer, string, strlen(string)); num > 0) {
|
||||||
if (num > 0) {
|
|
||||||
buffer[num] = 0;
|
buffer[num] = 0;
|
||||||
} else {
|
} else {
|
||||||
wchar_t *tmp = buffer;
|
wchar_t *tmp = buffer;
|
||||||
@ -411,7 +410,7 @@ uint32_t DrawUtils::getTextWidth(const char *string) {
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t width = getTextWidth(buffer);
|
const uint32_t width = getTextWidth(buffer);
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
@ -427,9 +426,9 @@ uint32_t DrawUtils::getTextWidth(const wchar_t *string) {
|
|||||||
if (sft_gmetrics(&pFont, gid, &mtx) < 0) {
|
if (sft_gmetrics(&pFont, gid, &mtx) < 0) {
|
||||||
DEBUG_FUNCTION_LINE_ERR("bad glyph metrics");
|
DEBUG_FUNCTION_LINE_ERR("bad glyph metrics");
|
||||||
}
|
}
|
||||||
width += (int32_t) mtx.advanceWidth;
|
width += static_cast<int32_t>(mtx.advanceWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (uint32_t) width;
|
return width;
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,11 @@
|
|||||||
#define SCREEN_HEIGHT 480
|
#define SCREEN_HEIGHT 480
|
||||||
|
|
||||||
union Color {
|
union Color {
|
||||||
explicit Color(uint32_t color) {
|
explicit Color(const uint32_t color) {
|
||||||
this->color = color;
|
this->color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
|
Color(const uint8_t r, const uint8_t g, const uint8_t b, const uint8_t a) {
|
||||||
this->r = r;
|
this->r = r;
|
||||||
this->g = g;
|
this->g = g;
|
||||||
this->b = b;
|
this->b = b;
|
||||||
@ -67,12 +67,12 @@ public:
|
|||||||
static uint32_t getTextWidth(const wchar_t *string);
|
static uint32_t getTextWidth(const wchar_t *string);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool isBackBuffer;
|
static bool mIsBackBuffer;
|
||||||
|
|
||||||
static uint8_t *tvBuffer;
|
static uint8_t *mTVBuffer;
|
||||||
static uint32_t tvSize;
|
static uint32_t mTVSize;
|
||||||
static uint8_t *drcBuffer;
|
static uint8_t *mDRCBuffer;
|
||||||
static uint32_t drcSize;
|
static uint32_t mDRCSize;
|
||||||
static uint32_t usedTVWidth;
|
static uint32_t mUsedTVWidth;
|
||||||
static float usedTVScale;
|
static float mUsedTVScale;
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <cstdint>
|
||||||
#include <wums/defines/relocation_defines.h>
|
#include <wums/defines/relocation_defines.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
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
|
#pragma once
|
||||||
#include "utils.h"
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class HeapMemoryFixedSize {
|
class HeapMemoryFixedSize {
|
||||||
public:
|
public:
|
||||||
HeapMemoryFixedSize() = default;
|
HeapMemoryFixedSize();
|
||||||
|
|
||||||
explicit HeapMemoryFixedSize(std::size_t size) : mData(make_unique_nothrow<uint8_t[]>(size)), mSize(mData ? size : 0) {}
|
explicit HeapMemoryFixedSize(std::size_t size);
|
||||||
|
|
||||||
// Delete the copy constructor and copy assignment operator
|
// Delete the copy constructor and copy assignment operator
|
||||||
HeapMemoryFixedSize(const HeapMemoryFixedSize &) = delete;
|
HeapMemoryFixedSize(const HeapMemoryFixedSize &) = delete;
|
||||||
HeapMemoryFixedSize &operator=(const HeapMemoryFixedSize &) = delete;
|
HeapMemoryFixedSize &operator=(const HeapMemoryFixedSize &) = delete;
|
||||||
|
|
||||||
HeapMemoryFixedSize(HeapMemoryFixedSize &&other) noexcept
|
HeapMemoryFixedSize(HeapMemoryFixedSize &&other) noexcept;
|
||||||
: mData(std::move(other.mData)), mSize(other.mSize) {
|
|
||||||
other.mSize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
HeapMemoryFixedSize &operator=(HeapMemoryFixedSize &&other) noexcept {
|
HeapMemoryFixedSize &operator=(HeapMemoryFixedSize &&other) noexcept;
|
||||||
if (this != &other) {
|
|
||||||
mData = std::move(other.mData);
|
|
||||||
mSize = other.mSize;
|
|
||||||
other.mSize = 0;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit operator bool() const {
|
explicit operator bool() const;
|
||||||
return mData != nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const void *data() const {
|
[[nodiscard]] const void *data() const;
|
||||||
return mData.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] std::size_t size() const {
|
[[nodiscard]] std::size_t size() const;
|
||||||
return mSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<uint8_t[]> mData{};
|
std::unique_ptr<uint8_t[]> mData{};
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#include "utils/json.hpp"
|
#include "utils/json.hpp"
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
|
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
namespace WUPSStorageDeprecated {
|
namespace WUPSStorageDeprecated {
|
||||||
static void processJson(wups_storage_item_t *items, nlohmann::json json) {
|
static void processJson(wups_storage_item_t *items, nlohmann::json json) {
|
||||||
if (items == nullptr) {
|
if (items == nullptr) {
|
||||||
|
@ -24,13 +24,12 @@
|
|||||||
* for WiiXplorer 2010
|
* for WiiXplorer 2010
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "StringTools.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <utils/StringTools.h>
|
|
||||||
#include <wut_types.h>
|
|
||||||
|
|
||||||
std::string StringTools::truncate(const std::string &str, size_t width, bool show_ellipsis) {
|
std::string StringTools::truncate(const std::string &str, const size_t width, const bool show_ellipsis) {
|
||||||
if (str.length() > width - 3) {
|
if (str.length() > width - 3) {
|
||||||
if (show_ellipsis) {
|
if (show_ellipsis) {
|
||||||
return str.substr(0, width - 3) + "...";
|
return str.substr(0, width - 3) + "...";
|
||||||
@ -60,3 +59,33 @@ int32_t StringTools::strtokcmp(const char *string, const char *compare, const ch
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *StringTools::FullpathToFilename(const char *path) {
|
||||||
|
if (!path)
|
||||||
|
return path;
|
||||||
|
|
||||||
|
const char *ptr = path;
|
||||||
|
const char *Filename = ptr;
|
||||||
|
|
||||||
|
while (*ptr != '\0') {
|
||||||
|
if (ptr[0] == '/' && ptr[1] != '\0')
|
||||||
|
Filename = ptr + 1;
|
||||||
|
|
||||||
|
++ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringTools::RemoveDoubleSlashes(std::string &str) {
|
||||||
|
uint32_t length = str.size();
|
||||||
|
|
||||||
|
//! clear path of double slashes
|
||||||
|
for (uint32_t i = 1; i < length; ++i) {
|
||||||
|
if (str[i - 1] == '/' && str[i] == '/') {
|
||||||
|
str.erase(i, 1);
|
||||||
|
i--;
|
||||||
|
length--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -30,14 +30,12 @@
|
|||||||
#include <coreinit/debug.h>
|
#include <coreinit/debug.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
|
||||||
#include <wut_types.h>
|
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
std::string string_format(std::string_view format, Args... args) {
|
std::string string_format(const std::string_view format, Args... args) {
|
||||||
int size_s = std::snprintf(nullptr, 0, format.data(), args...) + 1; // Extra space for '\0'
|
const int size_s = std::snprintf(nullptr, 0, format.data(), args...) + 1; // Extra space for '\0'
|
||||||
auto size = static_cast<size_t>(size_s);
|
const auto size = static_cast<size_t>(size_s);
|
||||||
auto buf = make_unique_nothrow<char[]>(size);
|
const auto buf = make_unique_nothrow<char[]>(size);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
DEBUG_FUNCTION_LINE_ERR("string_format failed, not enough memory");
|
DEBUG_FUNCTION_LINE_ERR("string_format failed, not enough memory");
|
||||||
OSFatal("string_format failed, not enough memory");
|
OSFatal("string_format failed, not enough memory");
|
||||||
@ -53,33 +51,7 @@ public:
|
|||||||
|
|
||||||
static int32_t strtokcmp(const char *string, const char *compare, const char *separator);
|
static int32_t strtokcmp(const char *string, const char *compare, const char *separator);
|
||||||
|
|
||||||
static const char *FullpathToFilename(const char *path) {
|
static const char *FullpathToFilename(const char *path);
|
||||||
if (!path)
|
|
||||||
return path;
|
|
||||||
|
|
||||||
const char *ptr = path;
|
static void RemoveDoubleSlashes(std::string &str);
|
||||||
const char *Filename = ptr;
|
|
||||||
|
|
||||||
while (*ptr != '\0') {
|
|
||||||
if (ptr[0] == '/' && ptr[1] != '\0')
|
|
||||||
Filename = ptr + 1;
|
|
||||||
|
|
||||||
++ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void RemoveDoubleSlashs(std::string &str) {
|
|
||||||
uint32_t length = str.size();
|
|
||||||
|
|
||||||
//! clear path of double slashes
|
|
||||||
for (uint32_t i = 1; i < length; ++i) {
|
|
||||||
if (str[i - 1] == '/' && str[i] == '/') {
|
|
||||||
str.erase(i, 1);
|
|
||||||
i--;
|
|
||||||
length--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
@ -1,6 +1,8 @@
|
|||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <cstddef>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <cstddef>
|
||||||
#include <stdlib.h>
|
#include <cstdint>
|
||||||
|
|
||||||
// based on https://nachtimwald.com/2017/11/18/base64-encode-and-decode-in-c/
|
// based on https://nachtimwald.com/2017/11/18/base64-encode-and-decode-in-c/
|
||||||
|
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
#include "CategoryRenderer.h"
|
#include "CategoryRenderer.h"
|
||||||
#include "ConfigDefines.h"
|
#include "ConfigRendererItem.h"
|
||||||
#include "config/WUPSConfigCategory.h"
|
#include "ConfigRendererItemCategory.h"
|
||||||
#include "utils/input/Input.h"
|
#include "ConfigUtils.h"
|
||||||
|
#include "utils/DrawUtils.h"
|
||||||
|
#include "utils/StringTools.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
#include "utils/utils.h"
|
#include "utils/utils.h"
|
||||||
#include <vector>
|
|
||||||
#include <wups/config.h>
|
|
||||||
|
|
||||||
CategoryRenderer::CategoryRenderer(const GeneralConfigInformation *info, const WUPSConfigAPIBackend::WUPSConfigCategory *cat, bool isRoot)
|
CategoryRenderer::CategoryRenderer(const GeneralConfigInformation *info, const WUPSConfigAPIBackend::WUPSConfigCategory *cat, const bool isRoot)
|
||||||
: mInfo(info), mCat(cat), mIsRoot(isRoot) {
|
: mInfo(info), mCat(cat), mIsRoot(isRoot) {
|
||||||
for (uint32_t i = 0; i < cat->getCategories().size() + cat->getItems().size(); i++) {
|
for (uint32_t i = 0; i < cat->getCategories().size() + cat->getItems().size(); i++) {
|
||||||
if (i < cat->getCategories().size()) {
|
if (i < cat->getCategories().size()) {
|
||||||
@ -14,8 +15,8 @@ CategoryRenderer::CategoryRenderer(const GeneralConfigInformation *info, const W
|
|||||||
assert(item);
|
assert(item);
|
||||||
mItemRenderer.push_back(std::move(item));
|
mItemRenderer.push_back(std::move(item));
|
||||||
} else {
|
} else {
|
||||||
auto itemIndex = (int32_t) (i - cat->getCategories().size());
|
const auto itemIndex = static_cast<int32_t>(i - cat->getCategories().size());
|
||||||
if (itemIndex < 0 || itemIndex >= (int32_t) cat->getItems().size()) {
|
if (itemIndex < 0 || itemIndex >= static_cast<int32_t>(cat->getItems().size())) {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
auto item = make_unique_nothrow<ConfigRendererItem>(cat->getItems()[itemIndex].get());
|
auto item = make_unique_nothrow<ConfigRendererItem>(cat->getItems()[itemIndex].get());
|
||||||
@ -31,13 +32,13 @@ CategoryRenderer::CategoryRenderer(const GeneralConfigInformation *info, const W
|
|||||||
|
|
||||||
// Make sure to call Update to get the current text of an item.
|
// Make sure to call Update to get the current text of an item.
|
||||||
for (uint32_t i = 0; i < mItemRenderer.size(); i++) {
|
for (uint32_t i = 0; i < mItemRenderer.size(); i++) {
|
||||||
bool isHighlighted = ((int) i == mCursorPos);
|
const bool isHighlighted = (static_cast<int>(i) == mCursorPos);
|
||||||
mItemRenderer[i]->Update(isHighlighted);
|
mItemRenderer[i]->Update(isHighlighted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CategoryRenderer::~CategoryRenderer() {
|
CategoryRenderer::~CategoryRenderer() {
|
||||||
if (mCursorPos < (int32_t) mItemRenderer.size()) {
|
if (mCursorPos < static_cast<int32_t>(mItemRenderer.size())) {
|
||||||
mItemRenderer[mCursorPos]->SetIsSelected(false);
|
mItemRenderer[mCursorPos]->SetIsSelected(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,14 +46,13 @@ CategoryRenderer::~CategoryRenderer() {
|
|||||||
ConfigSubState CategoryRenderer::Update(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData) {
|
ConfigSubState CategoryRenderer::Update(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData) {
|
||||||
switch (mState) {
|
switch (mState) {
|
||||||
case STATE_MAIN: {
|
case STATE_MAIN: {
|
||||||
auto res = UpdateStateMain(input, simpleInputData, complexInputData);
|
const auto res = UpdateStateMain(input, simpleInputData, complexInputData);
|
||||||
mFirstFrame = false;
|
mFirstFrame = false;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
case STATE_SUB: {
|
case STATE_SUB: {
|
||||||
if (mSubCategoryRenderer) {
|
if (mSubCategoryRenderer) {
|
||||||
auto subResult = mSubCategoryRenderer->Update(input, simpleInputData, complexInputData);
|
if (const auto subResult = mSubCategoryRenderer->Update(input, simpleInputData, complexInputData); subResult != SUB_STATE_RUNNING) {
|
||||||
if (subResult != SUB_STATE_RUNNING) {
|
|
||||||
mNeedsRedraw = true;
|
mNeedsRedraw = true;
|
||||||
mState = STATE_MAIN;
|
mState = STATE_MAIN;
|
||||||
mFirstFrame = true;
|
mFirstFrame = true;
|
||||||
@ -69,7 +69,7 @@ ConfigSubState CategoryRenderer::Update(Input &input, const WUPSConfigSimplePadD
|
|||||||
return SUB_STATE_ERROR;
|
return SUB_STATE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigSubState CategoryRenderer::UpdateStateMain(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData) {
|
ConfigSubState CategoryRenderer::UpdateStateMain(const Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData) {
|
||||||
if (mIsItemMovementAllowed && input.data.buttons_d & Input::eButtons::BUTTON_B) {
|
if (mIsItemMovementAllowed && input.data.buttons_d & Input::eButtons::BUTTON_B) {
|
||||||
return SUB_STATE_RETURN;
|
return SUB_STATE_RETURN;
|
||||||
}
|
}
|
||||||
@ -77,8 +77,8 @@ ConfigSubState CategoryRenderer::UpdateStateMain(Input &input, const WUPSConfigS
|
|||||||
return SUB_STATE_RUNNING;
|
return SUB_STATE_RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto totalElementSize = mItemRenderer.size();
|
const auto totalElementSize = mItemRenderer.size();
|
||||||
int32_t prevSelectedItem = mCursorPos;
|
const int32_t prevSelectedItem = mCursorPos;
|
||||||
|
|
||||||
if (mIsItemMovementAllowed) {
|
if (mIsItemMovementAllowed) {
|
||||||
if (input.data.buttons_d & Input::eButtons::BUTTON_DOWN) {
|
if (input.data.buttons_d & Input::eButtons::BUTTON_DOWN) {
|
||||||
@ -86,7 +86,7 @@ ConfigSubState CategoryRenderer::UpdateStateMain(Input &input, const WUPSConfigS
|
|||||||
} else if (input.data.buttons_d & Input::eButtons::BUTTON_UP) {
|
} else if (input.data.buttons_d & Input::eButtons::BUTTON_UP) {
|
||||||
mCursorPos--;
|
mCursorPos--;
|
||||||
} else if (input.data.buttons_d & Input::eButtons::BUTTON_A) {
|
} else if (input.data.buttons_d & Input::eButtons::BUTTON_A) {
|
||||||
if (mCursorPos < (int32_t) mCat->getCategories().size()) {
|
if (mCursorPos < static_cast<int32_t>(mCat->getCategories().size())) {
|
||||||
if (mCurrentOpen != mCursorPos) {
|
if (mCurrentOpen != mCursorPos) {
|
||||||
mSubCategoryRenderer.reset();
|
mSubCategoryRenderer.reset();
|
||||||
mSubCategoryRenderer = make_unique_nothrow<CategoryRenderer>(mInfo, mCat->getCategories()[mCursorPos].get(), false);
|
mSubCategoryRenderer = make_unique_nothrow<CategoryRenderer>(mInfo, mCat->getCategories()[mCursorPos].get(), false);
|
||||||
@ -100,8 +100,8 @@ ConfigSubState CategoryRenderer::UpdateStateMain(Input &input, const WUPSConfigS
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mCursorPos < 0) {
|
if (mCursorPos < 0) {
|
||||||
mCursorPos = (int32_t) totalElementSize - 1;
|
mCursorPos = static_cast<int32_t>(totalElementSize) - 1;
|
||||||
} else if (mCursorPos > (int32_t) (totalElementSize - 1)) {
|
} else if (mCursorPos > static_cast<int32_t>(totalElementSize - 1)) {
|
||||||
mCursorPos = 0;
|
mCursorPos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ ConfigSubState CategoryRenderer::UpdateStateMain(Input &input, const WUPSConfigS
|
|||||||
mIsItemMovementAllowed = mItemRenderer[mCursorPos]->IsMovementAllowed();
|
mIsItemMovementAllowed = mItemRenderer[mCursorPos]->IsMovementAllowed();
|
||||||
|
|
||||||
for (uint32_t i = 0; i < mItemRenderer.size(); i++) {
|
for (uint32_t i = 0; i < mItemRenderer.size(); i++) {
|
||||||
bool isHighlighted = ((int) i == mCursorPos);
|
const bool isHighlighted = (static_cast<int>(i) == mCursorPos);
|
||||||
mItemRenderer[i]->Update(isHighlighted);
|
mItemRenderer[i]->Update(isHighlighted);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ void CategoryRenderer::ResetNeedsRedraw() {
|
|||||||
if (mSubCategoryRenderer) {
|
if (mSubCategoryRenderer) {
|
||||||
mSubCategoryRenderer->ResetNeedsRedraw();
|
mSubCategoryRenderer->ResetNeedsRedraw();
|
||||||
}
|
}
|
||||||
for (auto &item : mItemRenderer) {
|
for (const auto &item : mItemRenderer) {
|
||||||
item->ResetNeedsRedraw();
|
item->ResetNeedsRedraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,20 +196,20 @@ void CategoryRenderer::RenderStateMain() const {
|
|||||||
DrawUtils::beginDraw();
|
DrawUtils::beginDraw();
|
||||||
RenderMainLayout();
|
RenderMainLayout();
|
||||||
|
|
||||||
std::string text(mIsRoot ? "This plugin can not be configured" : "This category is empty");
|
const std::string text(mIsRoot ? "This plugin can not be configured" : "This category is empty");
|
||||||
|
|
||||||
DrawUtils::setFontSize(24);
|
DrawUtils::setFontSize(24);
|
||||||
uint32_t sz = DrawUtils::getTextWidth(text.c_str());
|
const uint32_t sz = DrawUtils::getTextWidth(text.c_str());
|
||||||
DrawUtils::print((SCREEN_WIDTH / 2) - (sz / 2), (SCREEN_HEIGHT / 2), text.c_str());
|
DrawUtils::print((SCREEN_WIDTH / 2) - (sz / 2), (SCREEN_HEIGHT / 2), text.c_str());
|
||||||
|
|
||||||
DrawUtils::endDraw();
|
DrawUtils::endDraw();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto totalElementSize = static_cast<int>(mItemRenderer.size());
|
const auto totalElementSize = static_cast<int>(mItemRenderer.size());
|
||||||
|
|
||||||
// Calculate the range of items to display
|
// Calculate the range of items to display
|
||||||
int start = std::max(0, mRenderOffset);
|
const int start = std::max(0, mRenderOffset);
|
||||||
int end = std::min(start + MAX_BUTTONS_ON_SCREEN, totalElementSize);
|
const int end = std::min(start + MAX_BUTTONS_ON_SCREEN, totalElementSize);
|
||||||
|
|
||||||
DrawUtils::beginDraw();
|
DrawUtils::beginDraw();
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ void CategoryRenderer::RenderStateMain() const {
|
|||||||
|
|
||||||
uint32_t yOffset = 8 + 24 + 8 + 4;
|
uint32_t yOffset = 8 + 24 + 8 + 4;
|
||||||
for (int32_t i = start; i < end; i++) {
|
for (int32_t i = start; i < end; i++) {
|
||||||
bool isHighlighted = (i == mCursorPos);
|
const bool isHighlighted = (i == mCursorPos);
|
||||||
mItemRenderer[i]->Draw(yOffset, isHighlighted);
|
mItemRenderer[i]->Draw(yOffset, isHighlighted);
|
||||||
yOffset += 42 + 8;
|
yOffset += 42 + 8;
|
||||||
}
|
}
|
||||||
@ -253,6 +253,6 @@ void CategoryRenderer::RenderMainLayout() const {
|
|||||||
|
|
||||||
// draw home button
|
// draw home button
|
||||||
DrawUtils::setFontSize(18);
|
DrawUtils::setFontSize(18);
|
||||||
const char *exitHint = "\ue001 Back";
|
const auto exitHint = "\ue001 Back";
|
||||||
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHint) / 2, SCREEN_HEIGHT - 10, exitHint, true);
|
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHint) / 2, SCREEN_HEIGHT - 10, exitHint, true);
|
||||||
}
|
}
|
@ -1,12 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "../DrawUtils.h"
|
|
||||||
#include "ConfigRendererItem.h"
|
#include "ConfigDefines.h"
|
||||||
#include "ConfigRendererItemCategory.h"
|
#include "ConfigDisplayItem.h"
|
||||||
#include "ConfigRendererItemGeneric.h"
|
#include "ConfigRendererItemGeneric.h"
|
||||||
#include "ConfigUtils.h"
|
|
||||||
#include "config/WUPSConfigCategory.h"
|
#include "config/WUPSConfigCategory.h"
|
||||||
#include "utils/input/Input.h"
|
#include "utils/input/Input.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class CategoryRenderer {
|
class CategoryRenderer {
|
||||||
|
|
||||||
@ -24,7 +26,7 @@ public:
|
|||||||
void ResetNeedsRedraw();
|
void ResetNeedsRedraw();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigSubState UpdateStateMain(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData);
|
ConfigSubState UpdateStateMain(const Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData);
|
||||||
|
|
||||||
void RenderStateMain() const;
|
void RenderStateMain() const;
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <gx2/surface.h>
|
#include <gx2/surface.h>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#define COLOR_BACKGROUND Color(238, 238, 238, 255)
|
#define COLOR_BACKGROUND Color(238, 238, 238, 255)
|
||||||
#define COLOR_TEXT Color(51, 51, 51, 255)
|
#define COLOR_TEXT Color(51, 51, 51, 255)
|
||||||
@ -23,7 +22,6 @@ struct StoredBuffer {
|
|||||||
GX2BufferingMode buffering_mode;
|
GX2BufferingMode buffering_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum ConfigSubState {
|
enum ConfigSubState {
|
||||||
SUB_STATE_RUNNING = 0,
|
SUB_STATE_RUNNING = 0,
|
||||||
SUB_STATE_RETURN = 1,
|
SUB_STATE_RETURN = 1,
|
||||||
|
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
|
#pragma once
|
||||||
|
|
||||||
#include "config/WUPSConfig.h"
|
#include "config/WUPSConfig.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
struct GeneralConfigInformation {
|
struct GeneralConfigInformation {
|
||||||
std::string name;
|
std::string name;
|
||||||
@ -10,15 +12,11 @@ struct GeneralConfigInformation {
|
|||||||
|
|
||||||
class ConfigDisplayItem {
|
class ConfigDisplayItem {
|
||||||
public:
|
public:
|
||||||
ConfigDisplayItem(GeneralConfigInformation &info, std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> config) : mConfig(std::move(config)), mInfo(std::move(info)) {
|
ConfigDisplayItem(GeneralConfigInformation &info, std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> config);
|
||||||
assert(mConfig);
|
|
||||||
}
|
[[nodiscard]] const GeneralConfigInformation &getConfigInformation() const;
|
||||||
[[nodiscard]] const GeneralConfigInformation &getConfigInformation() const {
|
|
||||||
return mInfo;
|
[[nodiscard]] const WUPSConfigAPIBackend::WUPSConfig &getConfig() const;
|
||||||
}
|
|
||||||
[[nodiscard]] const WUPSConfigAPIBackend::WUPSConfig &getConfig() const {
|
|
||||||
return *mConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> mConfig;
|
std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> mConfig;
|
||||||
|
@ -1,67 +1,67 @@
|
|||||||
#include "ConfigRenderer.h"
|
#include "ConfigRenderer.h"
|
||||||
|
#include "globals.h"
|
||||||
|
#include "utils/DrawUtils.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
#include "utils/utils.h"
|
||||||
|
|
||||||
void ConfigRenderer::RenderStateMain() const {
|
ConfigRenderer::ConfigRenderer(std::vector<ConfigDisplayItem> &&vec) : mConfigs(std::move(vec)) {
|
||||||
auto totalElementSize = (int32_t) mConfigs.size();
|
|
||||||
// Calculate the range of items to display
|
|
||||||
int start = std::max(0, mRenderOffset);
|
|
||||||
int end = std::min(start + MAX_BUTTONS_ON_SCREEN, totalElementSize);
|
|
||||||
|
|
||||||
DrawUtils::beginDraw();
|
|
||||||
DrawUtils::clear(COLOR_BACKGROUND);
|
|
||||||
|
|
||||||
uint32_t yOffset = 8 + 24 + 8 + 4;
|
|
||||||
for (int32_t i = start; i < end; i++) {
|
|
||||||
drawConfigEntry(yOffset, mConfigs[i].getConfigInformation(), i == mCursorPos);
|
|
||||||
yOffset += 42 + 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawUtils::setFontColor(COLOR_TEXT);
|
|
||||||
|
|
||||||
// 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigRenderer::drawConfigEntry(uint32_t yOffset, const GeneralConfigInformation &configInformation, bool isHighlighted) const {
|
ConfigRenderer::~ConfigRenderer() = default;
|
||||||
DrawUtils::setFontColor(COLOR_TEXT);
|
|
||||||
|
|
||||||
if (isHighlighted) {
|
ConfigSubState ConfigRenderer::Update(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData) {
|
||||||
DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 4, COLOR_BORDER_HIGHLIGHTED);
|
switch (mState) {
|
||||||
} else {
|
case STATE_MAIN:
|
||||||
DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 2, COLOR_BORDER);
|
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);
|
void ConfigRenderer::Render() const {
|
||||||
DrawUtils::print(16 * 2, yOffset + 8 + 24, configInformation.name.c_str());
|
switch (mState) {
|
||||||
uint32_t sz = DrawUtils::getTextWidth(configInformation.name.c_str());
|
case STATE_MAIN:
|
||||||
DrawUtils::setFontSize(12);
|
RenderStateMain();
|
||||||
DrawUtils::print(16 * 2 + sz + 4, yOffset + 8 + 24, configInformation.author.c_str());
|
break;
|
||||||
DrawUtils::print(SCREEN_WIDTH - 16 * 2, yOffset + 8 + 24, configInformation.version.c_str(), true);
|
case STATE_SUB: {
|
||||||
|
if (mCategoryRenderer) {
|
||||||
|
mCategoryRenderer->Render();
|
||||||
|
} else {
|
||||||
|
DEBUG_FUNCTION_LINE_WARN("render failed: state was RENDERER_STATE_CAT but mCategoryRenderer is NULL");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigRenderer::NeedsRedraw() const {
|
||||||
|
if (mNeedRedraw) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (mCategoryRenderer) {
|
||||||
|
return mCategoryRenderer->NeedsRedraw();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigRenderer::ResetNeedsRedraw() {
|
||||||
|
mNeedRedraw = false;
|
||||||
|
if (mCategoryRenderer) {
|
||||||
|
mCategoryRenderer->ResetNeedsRedraw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) {
|
ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) {
|
||||||
@ -69,9 +69,9 @@ ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) {
|
|||||||
mNeedRedraw = true;
|
mNeedRedraw = true;
|
||||||
return SUB_STATE_ERROR;
|
return SUB_STATE_ERROR;
|
||||||
}
|
}
|
||||||
auto prevSelectedItem = mCursorPos;
|
const auto prevSelectedItem = mCursorPos;
|
||||||
|
|
||||||
auto totalElementSize = (int32_t) mConfigs.size();
|
const auto totalElementSize = static_cast<int32_t>(mConfigs.size());
|
||||||
if (input.data.buttons_d & Input::eButtons::BUTTON_DOWN) {
|
if (input.data.buttons_d & Input::eButtons::BUTTON_DOWN) {
|
||||||
mCursorPos++;
|
mCursorPos++;
|
||||||
} else if (input.data.buttons_d & Input::eButtons::BUTTON_LEFT) {
|
} else if (input.data.buttons_d & Input::eButtons::BUTTON_LEFT) {
|
||||||
@ -126,59 +126,68 @@ ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) {
|
|||||||
return SUB_STATE_RUNNING;
|
return SUB_STATE_RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigRenderer::NeedsRedraw() const {
|
void ConfigRenderer::RenderStateMain() const {
|
||||||
if (mNeedRedraw) {
|
const auto totalElementSize = static_cast<int32_t>(mConfigs.size());
|
||||||
return true;
|
// Calculate the range of items to display
|
||||||
} else if (mCategoryRenderer) {
|
const int start = std::max(0, mRenderOffset);
|
||||||
return mCategoryRenderer->NeedsRedraw();
|
const int end = std::min(start + MAX_BUTTONS_ON_SCREEN, totalElementSize);
|
||||||
|
|
||||||
|
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() {
|
void ConfigRenderer::DrawConfigEntry(const uint32_t yOffset, const GeneralConfigInformation &configInformation, const bool isHighlighted) const {
|
||||||
mNeedRedraw = false;
|
DrawUtils::setFontColor(COLOR_TEXT);
|
||||||
if (mCategoryRenderer) {
|
|
||||||
mCategoryRenderer->ResetNeedsRedraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigRenderer::Render() const {
|
if (isHighlighted) {
|
||||||
switch (mState) {
|
DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 4, COLOR_BORDER_HIGHLIGHTED);
|
||||||
case STATE_MAIN:
|
} else {
|
||||||
RenderStateMain();
|
DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 2, COLOR_BORDER);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ConfigSubState ConfigRenderer::Update(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData) {
|
DrawUtils::setFontSize(24);
|
||||||
switch (mState) {
|
DrawUtils::print(16 * 2, yOffset + 8 + 24, configInformation.name.c_str());
|
||||||
case STATE_MAIN:
|
const uint32_t sz = DrawUtils::getTextWidth(configInformation.name.c_str());
|
||||||
return UpdateStateMain(input);
|
DrawUtils::setFontSize(12);
|
||||||
case STATE_SUB: {
|
DrawUtils::print(16 * 2 + sz + 4, yOffset + 8 + 24, configInformation.author.c_str());
|
||||||
if (mCategoryRenderer) {
|
DrawUtils::print(SCREEN_WIDTH - 16 * 2, yOffset + 8 + 24, configInformation.version.c_str(), true);
|
||||||
auto subResult = mCategoryRenderer->Update(input, simpleInputData, complexInputData);
|
|
||||||
if (subResult != SUB_STATE_RUNNING) {
|
|
||||||
mNeedRedraw = true;
|
|
||||||
mState = STATE_MAIN;
|
|
||||||
return SUB_STATE_RUNNING;
|
|
||||||
}
|
|
||||||
return SUB_STATE_RUNNING;
|
|
||||||
} else {
|
|
||||||
DEBUG_FUNCTION_LINE_WARN("State is RENDERER_STATE_CAT but mCategoryRenderer is null. Resetting state.");
|
|
||||||
mState = STATE_MAIN;
|
|
||||||
mCursorPos = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return SUB_STATE_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigRenderer::CallOnCloseCallback(const GeneralConfigInformation &info, const std::vector<std::unique_ptr<WUPSConfigAPIBackend::WUPSConfigCategory>> &categories) {
|
void ConfigRenderer::CallOnCloseCallback(const GeneralConfigInformation &info, const std::vector<std::unique_ptr<WUPSConfigAPIBackend::WUPSConfigCategory>> &categories) {
|
||||||
|
@ -1,18 +1,21 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "../DrawUtils.h"
|
|
||||||
#include "../input/Input.h"
|
|
||||||
#include "../logger.h"
|
|
||||||
#include "CategoryRenderer.h"
|
#include "CategoryRenderer.h"
|
||||||
#include "globals.h"
|
#include "ConfigDefines.h"
|
||||||
|
#include "ConfigDisplayItem.h"
|
||||||
|
#include "utils/input/Input.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <wups/config.h>
|
||||||
|
|
||||||
class ConfigRenderer {
|
class ConfigRenderer {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ConfigRenderer(std::vector<ConfigDisplayItem> &&vec) : mConfigs(std::move(vec)) {
|
explicit ConfigRenderer(std::vector<ConfigDisplayItem> &&vec);
|
||||||
}
|
|
||||||
~ConfigRenderer() = default;
|
~ConfigRenderer();
|
||||||
|
|
||||||
ConfigSubState Update(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData);
|
ConfigSubState Update(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData);
|
||||||
|
|
||||||
@ -27,7 +30,10 @@ private:
|
|||||||
|
|
||||||
void RenderStateMain() const;
|
void RenderStateMain() const;
|
||||||
|
|
||||||
void drawConfigEntry(uint32_t yOffset, const GeneralConfigInformation &configInformation, bool isHighlighted) const;
|
void DrawConfigEntry(uint32_t yOffset, const GeneralConfigInformation &configInformation, bool isHighlighted) const;
|
||||||
|
|
||||||
|
void CallOnCloseCallback(const GeneralConfigInformation &info, const std::vector<std::unique_ptr<WUPSConfigAPIBackend::WUPSConfigCategory>> &categories);
|
||||||
|
void CallOnCloseCallback(const GeneralConfigInformation &info, const WUPSConfigAPIBackend::WUPSConfig &config);
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
STATE_MAIN = 0,
|
STATE_MAIN = 0,
|
||||||
@ -42,8 +48,6 @@ private:
|
|||||||
int32_t mCursorPos = 0;
|
int32_t mCursorPos = 0;
|
||||||
int32_t mRenderOffset = 0;
|
int32_t mRenderOffset = 0;
|
||||||
int32_t mCurrentOpen = -1;
|
int32_t mCurrentOpen = -1;
|
||||||
void CallOnCloseCallback(const GeneralConfigInformation &info, const std::vector<std::unique_ptr<WUPSConfigAPIBackend::WUPSConfigCategory>> &categories);
|
|
||||||
void CallOnCloseCallback(const GeneralConfigInformation &info, const WUPSConfigAPIBackend::WUPSConfig &config);
|
|
||||||
|
|
||||||
bool mNeedRedraw = true;
|
bool mNeedRedraw = true;
|
||||||
};
|
};
|
||||||
|
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
|
#pragma once
|
||||||
|
|
||||||
#include "ConfigRendererItemGeneric.h"
|
#include "ConfigRendererItemGeneric.h"
|
||||||
#include "config/WUPSConfigItem.h"
|
#include "config/WUPSConfigItem.h"
|
||||||
|
|
||||||
class ConfigRendererItem : public ConfigRendererItemGeneric {
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <wups/config.h>
|
||||||
|
|
||||||
|
class ConfigRendererItem final : public ConfigRendererItemGeneric {
|
||||||
public:
|
public:
|
||||||
explicit ConfigRendererItem(const WUPSConfigAPIBackend::WUPSConfigItem *item) : mItem(item) {
|
explicit ConfigRendererItem(const WUPSConfigAPIBackend::WUPSConfigItem *item);
|
||||||
assert(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Draw(uint32_t yOffset, bool isHighlighted) const override {
|
void Draw(uint32_t yOffset, bool isHighlighted) const override;
|
||||||
assert(mItem);
|
|
||||||
drawGenericBoxAndText(yOffset, mItem->getDisplayName(), isHighlighted);
|
|
||||||
DrawUtils::setFontSize(24);
|
|
||||||
DrawUtils::print(SCREEN_WIDTH - 16 * 2, yOffset + 8 + 24, mCurItemText.c_str(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string GetValueToPrint(bool isHighlighted) {
|
[[nodiscard]] std::string GetValueToPrint(bool isHighlighted) const;
|
||||||
return isHighlighted ? mItem->getCurrentValueSelectedDisplay() : mItem->getCurrentValueDisplay();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Update(bool isHighlighted) override {
|
void Update(bool isHighlighted) override;
|
||||||
const auto newText = GetValueToPrint(isHighlighted);
|
|
||||||
|
|
||||||
if (mCurItemText != newText) {
|
void ResetNeedsRedraw() override;
|
||||||
mNeedsDraw = true;
|
|
||||||
}
|
|
||||||
mCurItemText = newText;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResetNeedsRedraw() override {
|
[[nodiscard]] bool NeedsRedraw() const override;
|
||||||
mNeedsDraw = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] bool NeedsRedraw() const override {
|
void SetIsSelected(bool isSelected) override;
|
||||||
return mNeedsDraw;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetIsSelected(bool isSelected) override {
|
void OnButtonPressed(WUPSConfigButtons buttons) override;
|
||||||
mItem->onSelected(isSelected);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnButtonPressed(WUPSConfigButtons buttons) override {
|
[[nodiscard]] bool IsMovementAllowed() const override;
|
||||||
mItem->onButtonPressed(buttons);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] bool IsMovementAllowed() const override {
|
void OnInput(WUPSConfigSimplePadData input) override;
|
||||||
return mItem->isMovementAllowed();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnInput(WUPSConfigSimplePadData input) override {
|
void OnInputEx(WUPSConfigComplexPadData input) override;
|
||||||
mItem->onInput(input);
|
|
||||||
}
|
|
||||||
void OnInputEx(WUPSConfigComplexPadData input) override {
|
|
||||||
mItem->onInputEx(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const WUPSConfigAPIBackend::WUPSConfigItem *mItem;
|
const WUPSConfigAPIBackend::WUPSConfigItem *mItem = nullptr;
|
||||||
std::string mCurItemText;
|
std::string mCurItemText;
|
||||||
bool mNeedsDraw = true;
|
bool mNeedsDraw = true;
|
||||||
};
|
};
|
@ -1,8 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "ConfigRendererItemGeneric.h"
|
#include "ConfigRendererItemGeneric.h"
|
||||||
#include "config/WUPSConfigCategory.h"
|
#include "config/WUPSConfigCategory.h"
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
class ConfigRendererItemCategory : public ConfigRendererItemGeneric {
|
class ConfigRendererItemCategory final : public ConfigRendererItemGeneric {
|
||||||
public:
|
public:
|
||||||
explicit ConfigRendererItemCategory(const WUPSConfigAPIBackend::WUPSConfigCategory *category) : mCategory(category) {
|
explicit ConfigRendererItemCategory(const WUPSConfigAPIBackend::WUPSConfigCategory *category) : mCategory(category) {
|
||||||
assert(category);
|
assert(category);
|
||||||
|
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
|
#pragma once
|
||||||
#include "../DrawUtils.h"
|
|
||||||
#include "ConfigDefines.h"
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
#include <wups/config.h>
|
#include <wups/config.h>
|
||||||
|
|
||||||
class ConfigRendererItemGeneric {
|
class ConfigRendererItemGeneric {
|
||||||
public:
|
public:
|
||||||
virtual ~ConfigRendererItemGeneric() = default;
|
virtual ~ConfigRendererItemGeneric();
|
||||||
virtual void drawGenericBoxAndText(uint32_t yOffset, const std::string &displayName, bool isHighlighted) const {
|
|
||||||
if (isHighlighted) {
|
|
||||||
DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 4, COLOR_BORDER_HIGHLIGHTED);
|
|
||||||
} else {
|
|
||||||
DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 2, COLOR_BORDER);
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawUtils::setFontSize(24);
|
virtual void drawGenericBoxAndText(uint32_t yOffset, const std::string &displayName, bool isHighlighted) const;
|
||||||
DrawUtils::setFontColor(COLOR_TEXT);
|
|
||||||
DrawUtils::print(16 * 2, yOffset + 8 + 24, displayName.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void Draw(uint32_t yOffset, bool isHighlighted) const = 0;
|
virtual void Draw(uint32_t yOffset, bool isHighlighted) const = 0;
|
||||||
|
|
||||||
@ -26,17 +18,13 @@ public:
|
|||||||
|
|
||||||
virtual void ResetNeedsRedraw() = 0;
|
virtual void ResetNeedsRedraw() = 0;
|
||||||
|
|
||||||
virtual void SetIsSelected(bool) {
|
virtual void SetIsSelected(bool);
|
||||||
}
|
|
||||||
|
|
||||||
virtual void OnButtonPressed(WUPSConfigButtons) {
|
virtual void OnButtonPressed(WUPSConfigButtons);
|
||||||
}
|
|
||||||
virtual void OnInput(WUPSConfigSimplePadData) {
|
|
||||||
}
|
|
||||||
virtual void OnInputEx(WUPSConfigComplexPadData) {
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] virtual bool IsMovementAllowed() const {
|
virtual void OnInput(WUPSConfigSimplePadData);
|
||||||
return true;
|
|
||||||
}
|
virtual void OnInputEx(WUPSConfigComplexPadData);
|
||||||
|
|
||||||
|
[[nodiscard]] virtual bool IsMovementAllowed() const;
|
||||||
};
|
};
|
@ -1,24 +1,25 @@
|
|||||||
#include "ConfigUtils.h"
|
#include "ConfigUtils.h"
|
||||||
#include "../../globals.h"
|
|
||||||
#include "../DrawUtils.h"
|
|
||||||
#include "../dc.h"
|
|
||||||
#include "../logger.h"
|
|
||||||
#include "ConfigRenderer.h"
|
#include "ConfigRenderer.h"
|
||||||
#include "config/WUPSConfigAPI.h"
|
#include "config/WUPSConfigAPI.h"
|
||||||
#include "hooks.h"
|
#include "hooks.h"
|
||||||
|
#include "utils/DrawUtils.h"
|
||||||
|
#include "utils/dc.h"
|
||||||
#include "utils/input/CombinedInput.h"
|
#include "utils/input/CombinedInput.h"
|
||||||
|
#include "utils/input/Input.h"
|
||||||
#include "utils/input/VPADInput.h"
|
#include "utils/input/VPADInput.h"
|
||||||
#include "utils/input/WPADInput.h"
|
#include "utils/input/WPADInput.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
#include "utils/utils.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
#include <avm/tv.h>
|
#include <algorithm>
|
||||||
#include <coreinit/screen.h>
|
#include <globals.h>
|
||||||
#include <gx2/display.h>
|
|
||||||
#include <memory/mappedmemory.h>
|
#include <memory/mappedmemory.h>
|
||||||
#include <ranges>
|
#include <memory>
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <wups/config.h>
|
||||||
|
|
||||||
WUPS_CONFIG_SIMPLE_INPUT ConfigUtils::convertInputs(uint32_t buttons) {
|
WUPS_CONFIG_SIMPLE_INPUT ConfigUtils::convertInputs(const uint32_t buttons) {
|
||||||
WUPSConfigButtons pressedButtons = WUPS_CONFIG_BUTTON_NONE;
|
WUPSConfigButtons pressedButtons = WUPS_CONFIG_BUTTON_NONE;
|
||||||
if (buttons & Input::eButtons::BUTTON_A) {
|
if (buttons & Input::eButtons::BUTTON_A) {
|
||||||
pressedButtons |= WUPS_CONFIG_BUTTON_A;
|
pressedButtons |= WUPS_CONFIG_BUTTON_A;
|
||||||
@ -68,7 +69,7 @@ WUPS_CONFIG_SIMPLE_INPUT ConfigUtils::convertInputs(uint32_t buttons) {
|
|||||||
if (buttons & Input::eButtons::BUTTON_DOWN) {
|
if (buttons & Input::eButtons::BUTTON_DOWN) {
|
||||||
pressedButtons |= WUPS_CONFIG_BUTTON_DOWN;
|
pressedButtons |= WUPS_CONFIG_BUTTON_DOWN;
|
||||||
}
|
}
|
||||||
return (WUPS_CONFIG_SIMPLE_INPUT) pressedButtons;
|
return static_cast<WUPS_CONFIG_SIMPLE_INPUT>(pressedButtons);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigUtils::displayMenu() {
|
void ConfigUtils::displayMenu() {
|
||||||
@ -82,11 +83,9 @@ void ConfigUtils::displayMenu() {
|
|||||||
info.version = plugin.getMetaInformation().getVersion();
|
info.version = plugin.getMetaInformation().getVersion();
|
||||||
|
|
||||||
std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> config;
|
std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> config;
|
||||||
const auto configData = plugin.getConfigData();
|
if (const auto configData = plugin.getConfigData()) {
|
||||||
if (configData) {
|
if (const auto configHandleOpt = configData->createConfig()) {
|
||||||
const auto configHandleOpt = configData->createConfig();
|
WUPSConfigAPIStatus callbackResult = configData->CallMenuOpenedCallback(configHandleOpt.value());
|
||||||
if (configHandleOpt) {
|
|
||||||
WUPSConfigAPIStatus callbackResult = configData->CallMenuOpenendCallback(configHandleOpt.value());
|
|
||||||
config = WUPSConfigAPIBackend::Intern::PopConfigByHandle(configHandleOpt.value());
|
config = WUPSConfigAPIBackend::Intern::PopConfigByHandle(configHandleOpt.value());
|
||||||
if (!config) {
|
if (!config) {
|
||||||
DEBUG_FUNCTION_LINE_ERR("Failed to get config for handle: %08X", configHandleOpt.value().handle);
|
DEBUG_FUNCTION_LINE_ERR("Failed to get config for handle: %08X", configHandleOpt.value().handle);
|
||||||
@ -106,7 +105,7 @@ void ConfigUtils::displayMenu() {
|
|||||||
DEBUG_FUNCTION_LINE_ERR("Hook had invalid ptr");
|
DEBUG_FUNCTION_LINE_ERR("Hook had invalid ptr");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto cur_config_handle = ((void *(*) ())((uint32_t *) hook.getFunctionPointer()))();
|
auto cur_config_handle = reinterpret_cast<void *(*) ()>(static_cast<uint32_t *>(hook.getFunctionPointer()))();
|
||||||
if (cur_config_handle == nullptr) {
|
if (cur_config_handle == nullptr) {
|
||||||
DEBUG_FUNCTION_LINE_WARN("Hook returned empty handle");
|
DEBUG_FUNCTION_LINE_WARN("Hook returned empty handle");
|
||||||
break;
|
break;
|
||||||
@ -127,19 +126,15 @@ void ConfigUtils::displayMenu() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sort Configs by name
|
// Sort Configs by name
|
||||||
std::sort(
|
std::ranges::sort(configs,
|
||||||
configs.begin(),
|
[](const ConfigDisplayItem &lhs, const ConfigDisplayItem &rhs) {
|
||||||
configs.end(),
|
auto &str1 = lhs.getConfigInformation().name;
|
||||||
[](const ConfigDisplayItem &lhs, const ConfigDisplayItem &rhs) {
|
auto &str2 = rhs.getConfigInformation().name;
|
||||||
auto &str1 = lhs.getConfigInformation().name;
|
return std::ranges::lexicographical_compare(str1, str2,
|
||||||
auto &str2 = rhs.getConfigInformation().name;
|
[](const char &char1, const char &char2) {
|
||||||
return lexicographical_compare(
|
return tolower(char1) < tolower(char2);
|
||||||
begin(str1), end(str1),
|
});
|
||||||
begin(str2), end(str2),
|
});
|
||||||
[](const char &char1, const char &char2) {
|
|
||||||
return tolower(char1) < tolower(char2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
ConfigRenderer renderer(std::move(configs));
|
ConfigRenderer renderer(std::move(configs));
|
||||||
configs.clear();
|
configs.clear();
|
||||||
@ -156,7 +151,7 @@ void ConfigUtils::displayMenu() {
|
|||||||
WPAD_CHAN_6,
|
WPAD_CHAN_6,
|
||||||
};
|
};
|
||||||
|
|
||||||
auto startTime = OSGetTime();
|
OSTime startTime;
|
||||||
bool skipFirstInput = true;
|
bool skipFirstInput = true;
|
||||||
|
|
||||||
gOnlyAcceptFromThread = OSGetCurrentThread();
|
gOnlyAcceptFromThread = OSGetCurrentThread();
|
||||||
@ -238,26 +233,26 @@ void ConfigUtils::displayMenu() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConfigUtils::openConfigMenu() {
|
void ConfigUtils::openConfigMenu() {
|
||||||
gOnlyAcceptFromThread = OSGetCurrentThread();
|
gOnlyAcceptFromThread = OSGetCurrentThread();
|
||||||
bool wasHomeButtonMenuEnabled = OSIsHomeButtonMenuEnabled();
|
const bool wasHomeButtonMenuEnabled = OSIsHomeButtonMenuEnabled();
|
||||||
|
|
||||||
// Save copy of DC reg values
|
// Save copy of DC reg values
|
||||||
auto tvRender1 = DCReadReg32(SCREEN_TV, D1GRPH_CONTROL_REG);
|
const auto tvRender1 = DCReadReg32(SCREEN_TV, D1GRPH_CONTROL_REG);
|
||||||
auto tvRender2 = DCReadReg32(SCREEN_TV, D1GRPH_ENABLE_REG);
|
const auto tvRender2 = DCReadReg32(SCREEN_TV, D1GRPH_ENABLE_REG);
|
||||||
auto tvPitch1 = DCReadReg32(SCREEN_TV, D1GRPH_PITCH_REG);
|
const auto tvPitch1 = DCReadReg32(SCREEN_TV, D1GRPH_PITCH_REG);
|
||||||
auto tvPitch2 = DCReadReg32(SCREEN_TV, D1OVL_PITCH_REG);
|
const auto tvPitch2 = DCReadReg32(SCREEN_TV, D1OVL_PITCH_REG);
|
||||||
|
|
||||||
auto drcRender1 = DCReadReg32(SCREEN_DRC, D1GRPH_CONTROL_REG);
|
const auto drcRender1 = DCReadReg32(SCREEN_DRC, D1GRPH_CONTROL_REG);
|
||||||
auto drcRender2 = DCReadReg32(SCREEN_DRC, D1GRPH_ENABLE_REG);
|
const auto drcRender2 = DCReadReg32(SCREEN_DRC, D1GRPH_ENABLE_REG);
|
||||||
auto drcPitch1 = DCReadReg32(SCREEN_DRC, D1GRPH_PITCH_REG);
|
const auto drcPitch1 = DCReadReg32(SCREEN_DRC, D1GRPH_PITCH_REG);
|
||||||
auto drcPitch2 = DCReadReg32(SCREEN_DRC, D1OVL_PITCH_REG);
|
const auto drcPitch2 = DCReadReg32(SCREEN_DRC, D1OVL_PITCH_REG);
|
||||||
|
|
||||||
OSScreenInit();
|
OSScreenInit();
|
||||||
|
|
||||||
uint32_t screen_buf0_size = OSScreenGetBufferSizeEx(SCREEN_TV);
|
const uint32_t screen_buf0_size = OSScreenGetBufferSizeEx(SCREEN_TV);
|
||||||
uint32_t screen_buf1_size = OSScreenGetBufferSizeEx(SCREEN_DRC);
|
const uint32_t screen_buf1_size = OSScreenGetBufferSizeEx(SCREEN_DRC);
|
||||||
void *screenbuffer0 = MEMAllocFromMappedMemoryForGX2Ex(screen_buf0_size, 0x100);
|
void *screenbuffer0 = MEMAllocFromMappedMemoryForGX2Ex(screen_buf0_size, 0x100);
|
||||||
void *screenbuffer1 = MEMAllocFromMappedMemoryForGX2Ex(screen_buf1_size, 0x100);
|
void *screenbuffer1 = MEMAllocFromMappedMemoryForGX2Ex(screen_buf1_size, 0x100);
|
||||||
|
|
||||||
bool skipScreen0Free = false;
|
bool skipScreen0Free = false;
|
||||||
bool skipScreen1Free = false;
|
bool skipScreen1Free = false;
|
||||||
@ -363,7 +358,7 @@ void ConfigUtils::renderBasicScreen(std::string_view text) {
|
|||||||
DrawUtils::setFontSize(24);
|
DrawUtils::setFontSize(24);
|
||||||
DrawUtils::print(16, 6 + 24, "Wii U Plugin System Config Menu");
|
DrawUtils::print(16, 6 + 24, "Wii U Plugin System Config Menu");
|
||||||
DrawUtils::setFontSize(18);
|
DrawUtils::setFontSize(18);
|
||||||
DrawUtils::print(SCREEN_WIDTH - 16, 8 + 24, VERSION_FULL, true);
|
DrawUtils::print(SCREEN_WIDTH - 16, 8 + 24, MODULE_VERSION_FULL, true);
|
||||||
DrawUtils::drawRectFilled(8, 8 + 24 + 4, SCREEN_WIDTH - 8 * 2, 3, COLOR_BLACK);
|
DrawUtils::drawRectFilled(8, 8 + 24 + 4, SCREEN_WIDTH - 8 * 2, 3, COLOR_BLACK);
|
||||||
|
|
||||||
// draw bottom bar
|
// draw bottom bar
|
||||||
@ -373,13 +368,13 @@ void ConfigUtils::renderBasicScreen(std::string_view text) {
|
|||||||
DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, "\ue000 Select", true);
|
DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, "\ue000 Select", true);
|
||||||
|
|
||||||
DrawUtils::setFontSize(24);
|
DrawUtils::setFontSize(24);
|
||||||
uint32_t sz = DrawUtils::getTextWidth(text.data());
|
const uint32_t sz = DrawUtils::getTextWidth(text.data());
|
||||||
|
|
||||||
DrawUtils::print((SCREEN_WIDTH / 2) - (sz / 2), (SCREEN_HEIGHT / 2), text.data());
|
DrawUtils::print((SCREEN_WIDTH / 2) - (sz / 2), (SCREEN_HEIGHT / 2), text.data());
|
||||||
|
|
||||||
// draw home button
|
// draw home button
|
||||||
DrawUtils::setFontSize(18);
|
DrawUtils::setFontSize(18);
|
||||||
const char *exitHint = "\ue044 Exit";
|
const auto exitHint = "\ue044 Exit";
|
||||||
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHint) / 2, SCREEN_HEIGHT - 10, exitHint, true);
|
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHint) / 2, SCREEN_HEIGHT - 10, exitHint, true);
|
||||||
|
|
||||||
DrawUtils::endDraw();
|
DrawUtils::endDraw();
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ConfigDefines.h"
|
#include <cstdint>
|
||||||
#include "ConfigDisplayItem.h"
|
#include <string_view>
|
||||||
#include "config/WUPSConfig.h"
|
#include <wups/config.h>
|
||||||
|
|
||||||
#include "utils/input/Input.h"
|
|
||||||
#include <gx2/enum.h>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#define MOVE_ITEM_INPUT_MASK (WUPS_CONFIG_BUTTON_B | WUPS_CONFIG_BUTTON_DOWN | WUPS_CONFIG_BUTTON_UP)
|
#define MOVE_ITEM_INPUT_MASK (WUPS_CONFIG_BUTTON_B | WUPS_CONFIG_BUTTON_DOWN | WUPS_CONFIG_BUTTON_UP)
|
||||||
|
|
||||||
|
@ -5,20 +5,20 @@
|
|||||||
|
|
||||||
extern "C" uint32_t __OSPhysicalToEffectiveUncached(uint32_t);
|
extern "C" uint32_t __OSPhysicalToEffectiveUncached(uint32_t);
|
||||||
|
|
||||||
static inline uint32_t DCReadReg32(OSScreenID screen, uint32_t index) {
|
static uint32_t DCReadReg32(const OSScreenID screen, const uint32_t index) {
|
||||||
if (OSIsECOMode()) {
|
if (OSIsECOMode()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
auto regs = (uint32_t *) __OSPhysicalToEffectiveUncached(0xc200000);
|
const auto regs = reinterpret_cast<uint32_t *>(__OSPhysicalToEffectiveUncached(0xc200000));
|
||||||
return regs[index + (screen * 0x200)];
|
return regs[index + (screen * 0x200)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void DCWriteReg32(OSScreenID screen, uint32_t index, uint32_t val) {
|
static void DCWriteReg32(const OSScreenID screen, const uint32_t index, const uint32_t val) {
|
||||||
if (OSIsECOMode()) {
|
if (OSIsECOMode()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto regs = (uint32_t *) __OSPhysicalToEffectiveUncached(0xc200000);
|
const auto regs = reinterpret_cast<uint32_t *>(__OSPhysicalToEffectiveUncached(0xc200000));
|
||||||
regs[index + (screen * 0x200)] = val;
|
regs[index + (screen * 0x200)] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ static inline void DCWriteReg32(OSScreenID screen, uint32_t index, uint32_t val)
|
|||||||
#define D1GRPH_X_END_REG 0x184d
|
#define D1GRPH_X_END_REG 0x184d
|
||||||
#define D1GRPH_Y_END_REG 0x184e
|
#define D1GRPH_Y_END_REG 0x184e
|
||||||
|
|
||||||
static inline void SetDCPitchReg(OSScreenID screen, uint16_t pitch) {
|
static void SetDCPitchReg(const OSScreenID screen, const uint16_t pitch) {
|
||||||
DCWriteReg32(screen, D1GRPH_PITCH_REG, pitch);
|
DCWriteReg32(screen, D1GRPH_PITCH_REG, pitch);
|
||||||
DCWriteReg32(screen, D1OVL_PITCH_REG, pitch);
|
DCWriteReg32(screen, D1OVL_PITCH_REG, pitch);
|
||||||
}
|
}
|
@ -1,8 +1,13 @@
|
|||||||
#include "../PluginManagement.h"
|
#include "globals.h"
|
||||||
#include "../globals.h"
|
#include "logger.h"
|
||||||
#include "../plugin/PluginDataFactory.h"
|
#include "plugin/PluginContainer.h"
|
||||||
#include "../plugin/PluginMetaInformationFactory.h"
|
#include "plugin/PluginData.h"
|
||||||
|
#include "plugin/PluginDataFactory.h"
|
||||||
|
#include "plugin/PluginMetaInformation.h"
|
||||||
|
#include "plugin/PluginMetaInformationFactory.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <ranges>
|
||||||
#include <wums.h>
|
#include <wums.h>
|
||||||
#include <wups_backend/import_defines.h>
|
#include <wups_backend/import_defines.h>
|
||||||
|
|
||||||
@ -23,10 +28,10 @@ extern "C" PluginBackendApiErrorType WUPSLoadAndLinkByDataHandle(const wups_back
|
|||||||
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(gLoadedDataMutex);
|
std::lock_guard lock(gLoadedDataMutex);
|
||||||
for (uint32_t i = 0; i < plugin_data_handle_list_size; i++) {
|
for (uint32_t i = 0; i < plugin_data_handle_list_size; i++) {
|
||||||
auto handle = plugin_data_handle_list[i];
|
const auto handle = plugin_data_handle_list[i];
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
for (const auto &pluginData : gLoadedData) {
|
for (const auto &pluginData : gLoadedData) {
|
||||||
if (pluginData->getHandle() == handle) {
|
if (pluginData->getHandle() == handle) {
|
||||||
@ -65,7 +70,7 @@ extern "C" PluginBackendApiErrorType WUPSLoadPluginAsData(WUPSBackendGetPluginIn
|
|||||||
if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) {
|
if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) {
|
||||||
pluginData = PluginDataFactory::load(path);
|
pluginData = PluginDataFactory::load(path);
|
||||||
} else if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_BUFFER && buffer != nullptr && size > 0) {
|
} else if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_BUFFER && buffer != nullptr && size > 0) {
|
||||||
pluginData = make_unique_nothrow<PluginData>(std::span((uint8_t *) buffer, size), "<UNKNOWN>");
|
pluginData = make_unique_nothrow<PluginData>(std::span(reinterpret_cast<uint8_t *>(buffer), size), "<UNKNOWN>");
|
||||||
} else {
|
} else {
|
||||||
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
@ -103,7 +108,7 @@ extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformationEx(WUPSBackendG
|
|||||||
if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) {
|
if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) {
|
||||||
pluginInfo = PluginMetaInformationFactory::loadPlugin(path, error);
|
pluginInfo = PluginMetaInformationFactory::loadPlugin(path, error);
|
||||||
} else if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_BUFFER && buffer != nullptr && size > 0) {
|
} else if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_BUFFER && buffer != nullptr && size > 0) {
|
||||||
pluginInfo = PluginMetaInformationFactory::loadPlugin(std::span<uint8_t const>((uint8_t *) buffer, size), error);
|
pluginInfo = PluginMetaInformationFactory::loadPlugin(std::span<uint8_t const>(reinterpret_cast<uint8_t *>(buffer), size), error);
|
||||||
} else {
|
} else {
|
||||||
if (errOut) {
|
if (errOut) {
|
||||||
*errOut = PLUGIN_BACKEND_PLUGIN_PARSE_ERROR_UNKNOWN;
|
*errOut = PLUGIN_BACKEND_PLUGIN_PARSE_ERROR_UNKNOWN;
|
||||||
@ -153,19 +158,18 @@ extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformationByBuffer(wups_b
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" PluginBackendApiErrorType WUPSGetPluginDataForContainerHandles(const wups_backend_plugin_container_handle *plugin_container_handle_list, wups_backend_plugin_data_handle *plugin_data_list, uint32_t buffer_size) {
|
extern "C" PluginBackendApiErrorType WUPSGetPluginDataForContainerHandles(const wups_backend_plugin_container_handle *plugin_container_handle_list, wups_backend_plugin_data_handle *plugin_data_list, uint32_t buffer_size) {
|
||||||
PluginBackendApiErrorType res = PLUGIN_BACKEND_API_ERROR_NONE;
|
|
||||||
if (plugin_container_handle_list == nullptr || buffer_size == 0) {
|
if (plugin_container_handle_list == nullptr || buffer_size == 0) {
|
||||||
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(gLoadedDataMutex);
|
std::lock_guard lock(gLoadedDataMutex);
|
||||||
for (uint32_t i = 0; i < buffer_size; i++) {
|
for (uint32_t i = 0; i < buffer_size; i++) {
|
||||||
auto handle = plugin_container_handle_list[i];
|
const auto handle = plugin_container_handle_list[i];
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (const auto &curContainer : gLoadedPlugins) {
|
for (const auto &curContainer : gLoadedPlugins) {
|
||||||
if (curContainer.getHandle() == handle) {
|
if (curContainer.getHandle() == handle) {
|
||||||
auto pluginData = curContainer.getPluginDataCopy();
|
auto pluginData = curContainer.getPluginDataCopy();
|
||||||
plugin_data_list[i] = (uint32_t) pluginData->getHandle();
|
plugin_data_list[i] = pluginData->getHandle();
|
||||||
gLoadedData.insert(std::move(pluginData));
|
gLoadedData.insert(std::move(pluginData));
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
@ -177,7 +181,7 @@ extern "C" PluginBackendApiErrorType WUPSGetPluginDataForContainerHandles(const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return PLUGIN_BACKEND_API_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" PluginBackendApiErrorType WUPSGetMetaInformation(const wups_backend_plugin_container_handle *plugin_container_handle_list, wups_backend_plugin_information *plugin_information_list, uint32_t buffer_size) {
|
extern "C" PluginBackendApiErrorType WUPSGetMetaInformation(const wups_backend_plugin_container_handle *plugin_container_handle_list, wups_backend_plugin_information *plugin_information_list, uint32_t buffer_size) {
|
||||||
@ -264,7 +268,7 @@ extern "C" PluginBackendApiErrorType WUPSGetNumberOfLoadedPlugins(uint32_t *outC
|
|||||||
return PLUGIN_BACKEND_API_ERROR_NONE;
|
return PLUGIN_BACKEND_API_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" PluginBackendApiErrorType WUPSGetSectionInformationForPlugin(const wups_backend_plugin_container_handle handle, wups_backend_plugin_section_info *plugin_section_list, uint32_t buffer_size, uint32_t *out_count) {
|
extern "C" PluginBackendApiErrorType WUPSGetSectionInformationForPlugin(const wups_backend_plugin_container_handle handle, wups_backend_plugin_section_info *plugin_section_list, const uint32_t buffer_size, uint32_t *out_count) {
|
||||||
PluginBackendApiErrorType res = PLUGIN_BACKEND_API_ERROR_NONE;
|
PluginBackendApiErrorType res = PLUGIN_BACKEND_API_ERROR_NONE;
|
||||||
if (out_count != nullptr) {
|
if (out_count != nullptr) {
|
||||||
*out_count = 0;
|
*out_count = 0;
|
||||||
@ -277,13 +281,13 @@ extern "C" PluginBackendApiErrorType WUPSGetSectionInformationForPlugin(const wu
|
|||||||
const auto §ionInfoList = curContainer.getPluginInformation().getSectionInfoList();
|
const auto §ionInfoList = curContainer.getPluginInformation().getSectionInfoList();
|
||||||
|
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
for (auto const &[key, sectionInfo] : sectionInfoList) {
|
for (auto const §ionInfo : sectionInfoList | std::views::values) {
|
||||||
if (offset >= buffer_size) {
|
if (offset >= buffer_size) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
plugin_section_list[offset].plugin_section_info_version = WUPS_BACKEND_PLUGIN_SECTION_INFORMATION_VERSION;
|
plugin_section_list[offset].plugin_section_info_version = WUPS_BACKEND_PLUGIN_SECTION_INFORMATION_VERSION;
|
||||||
strncpy(plugin_section_list[offset].name, sectionInfo.getName().c_str(), sizeof(plugin_section_list[offset].name) - 1);
|
strncpy(plugin_section_list[offset].name, sectionInfo.getName().c_str(), sizeof(plugin_section_list[offset].name) - 1);
|
||||||
plugin_section_list[offset].address = (void *) sectionInfo.getAddress();
|
plugin_section_list[offset].address = reinterpret_cast<void *>(sectionInfo.getAddress());
|
||||||
plugin_section_list[offset].size = sectionInfo.getSize();
|
plugin_section_list[offset].size = sectionInfo.getSize();
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
@ -306,19 +310,19 @@ extern "C" PluginBackendApiErrorType WUPSWillReloadPluginsOnNextLaunch(bool *out
|
|||||||
if (out == nullptr) {
|
if (out == nullptr) {
|
||||||
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
std::lock_guard<std::mutex> lock(gLoadedDataMutex);
|
std::lock_guard lock(gLoadedDataMutex);
|
||||||
*out = !gLoadOnNextLaunch.empty();
|
*out = !gLoadOnNextLaunch.empty();
|
||||||
return PLUGIN_BACKEND_API_ERROR_NONE;
|
return PLUGIN_BACKEND_API_ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" PluginBackendApiErrorType WUPSGetSectionMemoryAddresses(wups_backend_plugin_container_handle handle, void **textAddress, void **dataAddress) {
|
extern "C" PluginBackendApiErrorType WUPSGetSectionMemoryAddresses(const wups_backend_plugin_container_handle handle, void **textAddress, void **dataAddress) {
|
||||||
if (handle == 0 || textAddress == nullptr || dataAddress == nullptr) {
|
if (handle == 0 || textAddress == nullptr || dataAddress == nullptr) {
|
||||||
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
for (const auto &curContainer : gLoadedPlugins) {
|
for (const auto &curContainer : gLoadedPlugins) {
|
||||||
if (curContainer.getHandle() == handle) {
|
if (curContainer.getHandle() == handle) {
|
||||||
*textAddress = (void *) curContainer.getPluginInformation().getTextMemory().data();
|
*textAddress = const_cast<void *>(curContainer.getPluginInformation().getTextMemory().data());
|
||||||
*dataAddress = (void *) curContainer.getPluginInformation().getDataMemory().data();
|
*dataAddress = const_cast<void *>(curContainer.getPluginInformation().getDataMemory().data());
|
||||||
return PLUGIN_BACKEND_API_ERROR_NONE;
|
return PLUGIN_BACKEND_API_ERROR_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -336,7 +340,7 @@ extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformationByPathEx(wups_b
|
|||||||
return WUPSGetPluginMetaInformationEx(PLUGIN_INFORMATION_INPUT_TYPE_PATH, path, nullptr, 0, output, err);
|
return WUPSGetPluginMetaInformationEx(PLUGIN_INFORMATION_INPUT_TYPE_PATH, path, nullptr, 0, output, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformationByBufferEx(wups_backend_plugin_information *output, char *buffer, size_t size, PluginBackendPluginParseError *err) {
|
extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformationByBufferEx(wups_backend_plugin_information *output, char *buffer, const size_t size, PluginBackendPluginParseError *err) {
|
||||||
return WUPSGetPluginMetaInformationEx(PLUGIN_INFORMATION_INPUT_TYPE_BUFFER, nullptr, buffer, size, output, err);
|
return WUPSGetPluginMetaInformationEx(PLUGIN_INFORMATION_INPUT_TYPE_BUFFER, nullptr, buffer, size, output, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Input.h"
|
#include "Input.h"
|
||||||
class CombinedInput : public Input {
|
class CombinedInput final : public Input {
|
||||||
public:
|
public:
|
||||||
void combine(const Input &b) {
|
void combine(const Input &b) {
|
||||||
data.buttons_d |= b.data.buttons_d;
|
data.buttons_d |= b.data.buttons_d;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
class Input {
|
class Input {
|
||||||
public:
|
public:
|
||||||
@ -11,7 +10,7 @@ public:
|
|||||||
//!Destructor
|
//!Destructor
|
||||||
virtual ~Input() = default;
|
virtual ~Input() = default;
|
||||||
|
|
||||||
enum eButtons {
|
enum eButtons : uint32_t {
|
||||||
BUTTON_NONE = 0x0000,
|
BUTTON_NONE = 0x0000,
|
||||||
VPAD_TOUCH = 0x80000000,
|
VPAD_TOUCH = 0x80000000,
|
||||||
BUTTON_STICK_L = 0x80000,
|
BUTTON_STICK_L = 0x80000,
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#include "Input.h"
|
#include "Input.h"
|
||||||
#include <vpad/input.h>
|
#include <vpad/input.h>
|
||||||
|
|
||||||
class VPadInput : public Input {
|
class VPadInput final : public Input {
|
||||||
public:
|
public:
|
||||||
//!Constructor
|
//!Constructor
|
||||||
VPadInput() = default;
|
VPadInput() = default;
|
||||||
@ -27,7 +27,7 @@ public:
|
|||||||
//!Destructor
|
//!Destructor
|
||||||
~VPadInput() override = default;
|
~VPadInput() override = default;
|
||||||
|
|
||||||
bool update(int32_t width, int32_t height) {
|
bool update(const int32_t width, const int32_t height) {
|
||||||
lastData = data;
|
lastData = data;
|
||||||
|
|
||||||
data = {};
|
data = {};
|
||||||
|
@ -20,15 +20,15 @@
|
|||||||
#include <padscore/kpad.h>
|
#include <padscore/kpad.h>
|
||||||
#include <padscore/wpad.h>
|
#include <padscore/wpad.h>
|
||||||
|
|
||||||
class WPADInput : public Input {
|
class WPADInput final : public Input {
|
||||||
public:
|
public:
|
||||||
WPADInput(KPADChan channel) {
|
WPADInput(const KPADChan channel) {
|
||||||
this->channel = channel;
|
this->channel = channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
~WPADInput() override {}
|
~WPADInput() override = default;
|
||||||
|
|
||||||
uint32_t remapWiiMoteButtons(uint32_t buttons) {
|
uint32_t remapWiiMoteButtons(const uint32_t buttons) {
|
||||||
uint32_t conv_buttons = 0;
|
uint32_t conv_buttons = 0;
|
||||||
|
|
||||||
if (buttons & WPAD_BUTTON_LEFT)
|
if (buttons & WPAD_BUTTON_LEFT)
|
||||||
@ -73,7 +73,7 @@ public:
|
|||||||
return conv_buttons;
|
return conv_buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t remapClassicButtons(uint32_t buttons) {
|
uint32_t remapClassicButtons(const uint32_t buttons) {
|
||||||
uint32_t conv_buttons = 0;
|
uint32_t conv_buttons = 0;
|
||||||
|
|
||||||
if (buttons & WPAD_CLASSIC_BUTTON_LEFT)
|
if (buttons & WPAD_CLASSIC_BUTTON_LEFT)
|
||||||
@ -124,7 +124,7 @@ public:
|
|||||||
return conv_buttons;
|
return conv_buttons;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update(int32_t width, int32_t height) {
|
bool update(const int32_t width, const int32_t height) {
|
||||||
lastData = data;
|
lastData = data;
|
||||||
|
|
||||||
kpadError = KPAD_ERROR_UNINITIALIZED;
|
kpadError = KPAD_ERROR_UNINITIALIZED;
|
||||||
|
@ -1108,11 +1108,11 @@ simple_outline(SFT_Font *font, uint_fast32_t offset, unsigned int numContours, O
|
|||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
endPts = calloc(sizeof(uint_fast16_t), numContours);
|
endPts = calloc(numContours, sizeof(uint_fast16_t));
|
||||||
if (endPts == NULL) {
|
if (endPts == NULL) {
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
flags = calloc(sizeof(uint8_t), numPts);
|
flags = calloc(numPts, sizeof(uint8_t));
|
||||||
if (flags == NULL) {
|
if (flags == NULL) {
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
@ -1433,7 +1433,7 @@ render_outline(Outline *outl, double transform[6], SFT_Image image) {
|
|||||||
|
|
||||||
numPixels = (unsigned int) image.width * (unsigned int) image.height;
|
numPixels = (unsigned int) image.width * (unsigned int) image.height;
|
||||||
|
|
||||||
cells = calloc(sizeof(Cell), numPixels);
|
cells = calloc(numPixels, sizeof(Cell));
|
||||||
if (!cells) {
|
if (!cells) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
#include "StorageItem.h"
|
#include "StorageItem.h"
|
||||||
|
|
||||||
|
#include "utils/base64.h"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
|
||||||
|
StorageItem::StorageItem(const std::string_view key) : mKey(key) {
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t StorageItem::getHandle() const {
|
||||||
|
return reinterpret_cast<uint32_t>(this);
|
||||||
|
}
|
||||||
|
|
||||||
void StorageItem::setValue(const std::string &value) {
|
void StorageItem::setValue(const std::string &value) {
|
||||||
mData = value;
|
mData = value;
|
||||||
mType = StorageItemType::String;
|
mType = StorageItemType::String;
|
||||||
@ -12,8 +22,8 @@ void StorageItem::setValue(bool value) {
|
|||||||
mBinaryConversionDone = true;
|
mBinaryConversionDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StorageItem::setValue(int32_t value) {
|
void StorageItem::setValue(const int32_t value) {
|
||||||
mData = (int64_t) value;
|
mData = static_cast<int64_t>(value);
|
||||||
mType = StorageItemType::S64;
|
mType = StorageItemType::S64;
|
||||||
mBinaryConversionDone = true;
|
mBinaryConversionDone = true;
|
||||||
}
|
}
|
||||||
@ -30,14 +40,14 @@ void StorageItem::setValue(uint64_t value) {
|
|||||||
mBinaryConversionDone = true;
|
mBinaryConversionDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StorageItem::setValue(uint32_t value) {
|
void StorageItem::setValue(const uint32_t value) {
|
||||||
mData = (uint64_t) value;
|
mData = static_cast<uint64_t>(value);
|
||||||
mType = StorageItemType::U64;
|
mType = StorageItemType::U64;
|
||||||
mBinaryConversionDone = true;
|
mBinaryConversionDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StorageItem::setValue(float value) {
|
void StorageItem::setValue(const float value) {
|
||||||
mData = (double) value;
|
mData = static_cast<double>(value);
|
||||||
mType = StorageItemType::Double;
|
mType = StorageItemType::Double;
|
||||||
mBinaryConversionDone = true;
|
mBinaryConversionDone = true;
|
||||||
}
|
}
|
||||||
@ -54,8 +64,8 @@ void StorageItem::setValue(const std::vector<uint8_t> &data) {
|
|||||||
mBinaryConversionDone = true;
|
mBinaryConversionDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StorageItem::setValue(const uint8_t *data, size_t size) {
|
void StorageItem::setValue(const uint8_t *data, const size_t size) {
|
||||||
setValue(std::vector<uint8_t>(data, data + size));
|
setValue(std::vector(data, data + size));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StorageItem::getValue(bool &result) const {
|
bool StorageItem::getValue(bool &result) const {
|
||||||
@ -74,10 +84,10 @@ bool StorageItem::getValue(bool &result) const {
|
|||||||
|
|
||||||
bool StorageItem::getValue(int32_t &result) const {
|
bool StorageItem::getValue(int32_t &result) const {
|
||||||
if (mType == StorageItemType::S64) {
|
if (mType == StorageItemType::S64) {
|
||||||
result = (int32_t) std::get<int64_t>(mData);
|
result = static_cast<int32_t>(std::get<int64_t>(mData));
|
||||||
return true;
|
return true;
|
||||||
} else if (mType == StorageItemType::U64) {
|
} else if (mType == StorageItemType::U64) {
|
||||||
result = (int32_t) std::get<uint64_t>(mData);
|
result = static_cast<int32_t>(std::get<uint64_t>(mData));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -109,7 +119,7 @@ bool StorageItem::getValue(double &result) const {
|
|||||||
|
|
||||||
bool StorageItem::getValue(float &result) const {
|
bool StorageItem::getValue(float &result) const {
|
||||||
if (mType == StorageItemType::Double) {
|
if (mType == StorageItemType::Double) {
|
||||||
result = (float) std::get<double>(mData);
|
result = static_cast<float>(std::get<double>(mData));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -120,7 +130,7 @@ bool StorageItem::getValue(uint64_t &result) const {
|
|||||||
result = std::get<uint64_t>(mData);
|
result = std::get<uint64_t>(mData);
|
||||||
return true;
|
return true;
|
||||||
} else if (mType == StorageItemType::S64) {
|
} else if (mType == StorageItemType::S64) {
|
||||||
result = (uint64_t) std::get<int64_t>(mData);
|
result = static_cast<uint64_t>(std::get<int64_t>(mData));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -128,10 +138,10 @@ bool StorageItem::getValue(uint64_t &result) const {
|
|||||||
|
|
||||||
bool StorageItem::getValue(uint32_t &result) const {
|
bool StorageItem::getValue(uint32_t &result) const {
|
||||||
if (mType == StorageItemType::U64) {
|
if (mType == StorageItemType::U64) {
|
||||||
result = (uint32_t) std::get<uint64_t>(mData);
|
result = static_cast<uint32_t>(std::get<uint64_t>(mData));
|
||||||
return true;
|
return true;
|
||||||
} else if (mType == StorageItemType::S64) {
|
} else if (mType == StorageItemType::S64) {
|
||||||
result = (uint32_t) std::get<int64_t>(mData);
|
result = static_cast<uint32_t>(std::get<int64_t>(mData));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -142,7 +152,7 @@ bool StorageItem::getValue(int64_t &result) const {
|
|||||||
result = std::get<int64_t>(mData);
|
result = std::get<int64_t>(mData);
|
||||||
return true;
|
return true;
|
||||||
} else if (mType == StorageItemType::U64) {
|
} else if (mType == StorageItemType::U64) {
|
||||||
result = (int64_t) std::get<uint64_t>(mData);
|
result = static_cast<int64_t>(std::get<uint64_t>(mData));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -169,11 +179,9 @@ bool StorageItem::attemptBinaryConversion() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (mType == StorageItemType::String) {
|
if (mType == StorageItemType::String) {
|
||||||
auto &tmp = std::get<std::string>(mData);
|
const auto &tmp = std::get<std::string>(mData);
|
||||||
auto dec_size = b64_decoded_size(tmp.c_str());
|
if (const auto dec_size = b64_decoded_size(tmp.c_str()); dec_size > 0) {
|
||||||
if (dec_size > 0) {
|
if (auto *dec = static_cast<uint8_t *>(malloc(dec_size))) {
|
||||||
auto *dec = (uint8_t *) malloc(dec_size);
|
|
||||||
if (dec) {
|
|
||||||
if (b64_decode(tmp.c_str(), dec, dec_size)) {
|
if (b64_decode(tmp.c_str(), dec, dec_size)) {
|
||||||
setValue(dec, dec_size);
|
setValue(dec, dec_size);
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "utils/base64.h"
|
|
||||||
#include "utils/logger.h"
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
enum class StorageItemType { None,
|
enum class StorageItemType { None,
|
||||||
Boolean,
|
Boolean,
|
||||||
String,
|
String,
|
||||||
@ -19,12 +15,9 @@ enum class StorageItemType { None,
|
|||||||
|
|
||||||
class StorageItem {
|
class StorageItem {
|
||||||
public:
|
public:
|
||||||
explicit StorageItem(std::string_view key) : mData(std::monostate{}), mType(StorageItemType::None), mKey(key) {
|
explicit StorageItem(std::string_view key);
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] uint32_t getHandle() const {
|
[[nodiscard]] uint32_t getHandle() const;
|
||||||
return (uint32_t) this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setters for different types
|
// Setters for different types
|
||||||
void setValue(bool value);
|
void setValue(bool value);
|
||||||
|
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
|
#pragma once
|
||||||
|
|
||||||
#include "StorageItem.h"
|
|
||||||
#include "StorageSubItem.h"
|
#include "StorageSubItem.h"
|
||||||
#include "utils/logger.h"
|
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
#include <wups/storage.h>
|
|
||||||
|
|
||||||
class StorageItemRoot : public StorageSubItem {
|
class StorageItemRoot : public StorageSubItem {
|
||||||
public:
|
public:
|
||||||
explicit StorageItemRoot(std::string_view plugin_name) : StorageSubItem(plugin_name), mPluginName(plugin_name) {
|
explicit StorageItemRoot(std::string_view plugin_name);
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const std::string &getPluginId() const {
|
[[nodiscard]] const std::string &getPluginId() const;
|
||||||
return mPluginName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wipe() {
|
void wipe();
|
||||||
mSubCategories.clear();
|
|
||||||
mItems.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string mPluginName;
|
std::string mPluginName;
|
||||||
|
@ -1,17 +1,21 @@
|
|||||||
#include "StorageSubItem.h"
|
#include "StorageSubItem.h"
|
||||||
|
|
||||||
|
#include <utils/utils.h>
|
||||||
|
|
||||||
|
StorageSubItem::StorageSubItem(const std::string_view key) : StorageItem(key) {
|
||||||
|
}
|
||||||
|
|
||||||
StorageSubItem *StorageSubItem::getSubItem(wups_storage_item item) {
|
StorageSubItem *StorageSubItem::getSubItem(wups_storage_item item) {
|
||||||
// Try to find the sub-item based on item handle.
|
// Try to find the sub-item based on item handle.
|
||||||
for (auto &cur : mSubCategories) {
|
for (auto &cur : mSubCategories) {
|
||||||
if (cur.getHandle() == (uint32_t) item) {
|
if (cur.getHandle() == reinterpret_cast<uint32_t>(item)) {
|
||||||
return &cur;
|
return &cur;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not found in current category, recursively search in sub-categories.
|
// If not found in current category, recursively search in sub-categories.
|
||||||
for (auto &cur : mSubCategories) {
|
for (auto &cur : mSubCategories) {
|
||||||
auto res = cur.getSubItem(item);
|
if (const auto res = cur.getSubItem(item)) {
|
||||||
if (res) {
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -35,40 +39,30 @@ bool StorageSubItem::deleteItem(const char *key) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto itemItr = mItems.find(key);
|
if (const auto itemItr = mItems.find(key); itemItr != mItems.end()) {
|
||||||
if (itemItr != mItems.end()) {
|
|
||||||
mItems.erase(itemItr);
|
mItems.erase(itemItr);
|
||||||
return true; // Item found and deleted.
|
return true; // Item found and deleted.
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
StorageItem *StorageSubItem::createItem(const char *key, StorageSubItem::StorageSubItemError &error) {
|
StorageItem *StorageSubItem::createItem(const char *key, StorageSubItemError &error) {
|
||||||
for (const auto &cur : mSubCategories) {
|
if (getSubItem(key) != nullptr) {
|
||||||
if (cur.getKey() == key) {
|
|
||||||
error = STORAGE_SUB_ITEM_KEY_ALREADY_IN_USE;
|
|
||||||
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()) {
|
|
||||||
error = STORAGE_SUB_ITEM_KEY_ALREADY_IN_USE;
|
error = STORAGE_SUB_ITEM_KEY_ALREADY_IN_USE;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
for (const auto &cur : mSubCategories) {
|
|
||||||
if (cur.getKey() == key) {
|
if (const auto [addedItem, itemAdded] = mItems.insert({key, StorageItem(key)}); itemAdded) {
|
||||||
error = STORAGE_SUB_ITEM_KEY_ALREADY_IN_USE;
|
return &addedItem->second;
|
||||||
return nullptr;
|
}
|
||||||
}
|
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);
|
mSubCategories.emplace_front(key);
|
||||||
@ -76,9 +70,16 @@ StorageSubItem *StorageSubItem::createSubItem(const char *key, StorageSubItem::S
|
|||||||
}
|
}
|
||||||
|
|
||||||
StorageItem *StorageSubItem::getItem(const char *name) {
|
StorageItem *StorageSubItem::getItem(const char *name) {
|
||||||
auto resItr = mItems.find(name);
|
if (const auto resItr = mItems.find(name); resItr != mItems.end()) {
|
||||||
if (resItr != mItems.end()) {
|
|
||||||
return &resItr->second;
|
return &resItr->second;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::forward_list<StorageSubItem> &StorageSubItem::getSubItems() const {
|
||||||
|
return mSubCategories;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::map<std::string, StorageItem> &StorageSubItem::getItems() const {
|
||||||
|
return mItems;
|
||||||
|
}
|
@ -1,12 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "StorageItem.h"
|
#include "StorageItem.h"
|
||||||
#include "utils/utils.h"
|
|
||||||
|
#include <forward_list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <string>
|
||||||
#include <optional>
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
#include <wups/storage.h>
|
#include <wups/storage.h>
|
||||||
|
|
||||||
class StorageSubItem : public StorageItem {
|
class StorageSubItem : public StorageItem {
|
||||||
@ -17,8 +15,7 @@ public:
|
|||||||
STORAGE_SUB_ITEM_KEY_ALREADY_IN_USE = 2,
|
STORAGE_SUB_ITEM_KEY_ALREADY_IN_USE = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit StorageSubItem(std::string_view key) : StorageItem(key) {
|
explicit StorageSubItem(std::string_view key);
|
||||||
}
|
|
||||||
|
|
||||||
StorageSubItem *getSubItem(wups_storage_item item);
|
StorageSubItem *getSubItem(wups_storage_item item);
|
||||||
|
|
||||||
@ -26,19 +23,15 @@ public:
|
|||||||
|
|
||||||
bool deleteItem(const char *key);
|
bool deleteItem(const char *key);
|
||||||
|
|
||||||
StorageItem *createItem(const char *key, StorageSubItem::StorageSubItemError &error);
|
StorageItem *createItem(const char *key, StorageSubItemError &error);
|
||||||
|
|
||||||
StorageSubItem *createSubItem(const char *key, StorageSubItem::StorageSubItemError &error);
|
StorageSubItem *createSubItem(const char *key, StorageSubItemError &error);
|
||||||
|
|
||||||
StorageItem *getItem(const char *name);
|
StorageItem *getItem(const char *name);
|
||||||
|
|
||||||
[[nodiscard]] const std::forward_list<StorageSubItem> &getSubItems() const {
|
[[nodiscard]] const std::forward_list<StorageSubItem> &getSubItems() const;
|
||||||
return mSubCategories;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] const std::map<std::string, StorageItem> &getItems() const {
|
[[nodiscard]] const std::map<std::string, StorageItem> &getItems() const;
|
||||||
return mItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::forward_list<StorageSubItem> mSubCategories;
|
std::forward_list<StorageSubItem> mSubCategories;
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
#include "StorageUtils.h"
|
#include "StorageItem.h"
|
||||||
#include "NotificationsUtils.h"
|
|
||||||
#include "StorageItemRoot.h"
|
#include "StorageItemRoot.h"
|
||||||
|
#include "StorageSubItem.h"
|
||||||
#include "fs/CFile.hpp"
|
#include "fs/CFile.hpp"
|
||||||
#include "fs/FSUtils.h"
|
#include "fs/FSUtils.h"
|
||||||
#include "utils/StringTools.h"
|
|
||||||
#include "utils/base64.h"
|
#include "utils/base64.h"
|
||||||
#include "utils/json.hpp"
|
#include "utils/json.hpp"
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
#include "utils/utils.h"
|
#include "utils/utils.h"
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
#include <forward_list>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <mutex>
|
||||||
|
#include <wups/storage.h>
|
||||||
|
|
||||||
namespace StorageUtils {
|
namespace StorageUtils {
|
||||||
std::forward_list<StorageItemRoot> gStorage;
|
std::forward_list<StorageItemRoot> gStorage;
|
||||||
std::mutex gStorageMutex;
|
std::mutex gStorageMutex;
|
||||||
@ -76,8 +79,7 @@ namespace StorageUtils {
|
|||||||
if (json.empty() || !json.is_object()) {
|
if (json.empty() || !json.is_object()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto root = make_unique_nothrow<StorageItemRoot>(key);
|
if (auto root = make_unique_nothrow<StorageItemRoot>(key)) {
|
||||||
if (root) {
|
|
||||||
if (deserializeFromJson(json, *root)) {
|
if (deserializeFromJson(json, *root)) {
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
@ -132,8 +134,7 @@ namespace StorageUtils {
|
|||||||
case StorageItemType::Binary: {
|
case StorageItemType::Binary: {
|
||||||
std::vector<uint8_t> tmp;
|
std::vector<uint8_t> tmp;
|
||||||
if (value.getValue(tmp)) {
|
if (value.getValue(tmp)) {
|
||||||
auto *enc = b64_encode(tmp.data(), tmp.size());
|
if (auto *enc = b64_encode(tmp.data(), tmp.size())) {
|
||||||
if (enc) {
|
|
||||||
json[key] = enc;
|
json[key] = enc;
|
||||||
free(enc);
|
free(enc);
|
||||||
} else {
|
} else {
|
||||||
@ -153,7 +154,7 @@ namespace StorageUtils {
|
|||||||
|
|
||||||
static StorageItemRoot *getRootItem(wups_storage_root_item root) {
|
static StorageItemRoot *getRootItem(wups_storage_root_item root) {
|
||||||
for (auto &cur : gStorage) {
|
for (auto &cur : gStorage) {
|
||||||
if (cur.getHandle() == (uint32_t) root) {
|
if (cur.getHandle() == reinterpret_cast<uint32_t>(root)) {
|
||||||
return &cur;
|
return &cur;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,8 +163,7 @@ namespace StorageUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static StorageSubItem *getSubItem(wups_storage_root_item root, wups_storage_item parent) {
|
static StorageSubItem *getSubItem(wups_storage_root_item root, wups_storage_item parent) {
|
||||||
auto rootItem = getRootItem(root);
|
if (auto rootItem = getRootItem(root)) {
|
||||||
if (rootItem) {
|
|
||||||
if (parent == nullptr) {
|
if (parent == nullptr) {
|
||||||
return rootItem;
|
return rootItem;
|
||||||
}
|
}
|
||||||
@ -173,18 +173,17 @@ namespace StorageUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
WUPSStorageError LoadFromFile(std::string_view plugin_id, nlohmann::json &outJson) {
|
WUPSStorageError LoadFromFile(std::string_view plugin_id, nlohmann::json &outJson) {
|
||||||
std::string filePath = getPluginPath() + "/config/" + plugin_id.data() + ".json";
|
const std::string filePath = getPluginPath() + "/config/" + plugin_id.data() + ".json";
|
||||||
CFile file(filePath, CFile::ReadOnly);
|
CFile file(filePath, CFile::ReadOnly);
|
||||||
if (!file.isOpen() || file.size() == 0) {
|
if (!file.isOpen() || file.size() == 0) {
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
auto *json_data = (uint8_t *) memalign(0x40, ROUNDUP(file.size() + 1, 0x40));
|
auto *json_data = static_cast<uint8_t *>(memalign(0x40, ROUNDUP(file.size() + 1, 0x40)));
|
||||||
if (!json_data) {
|
if (!json_data) {
|
||||||
return WUPS_STORAGE_ERROR_MALLOC_FAILED;
|
return WUPS_STORAGE_ERROR_MALLOC_FAILED;
|
||||||
}
|
}
|
||||||
WUPSStorageError result = WUPS_STORAGE_ERROR_SUCCESS;
|
WUPSStorageError result = WUPS_STORAGE_ERROR_SUCCESS;
|
||||||
uint64_t readRes = file.read(json_data, file.size());
|
if (const uint64_t readRes = file.read(json_data, file.size()); readRes == file.size()) {
|
||||||
if (readRes == file.size()) {
|
|
||||||
json_data[file.size()] = '\0';
|
json_data[file.size()] = '\0';
|
||||||
outJson = nlohmann::json::parse(json_data, nullptr, false);
|
outJson = nlohmann::json::parse(json_data, nullptr, false);
|
||||||
} else {
|
} else {
|
||||||
@ -197,9 +196,8 @@ namespace StorageUtils {
|
|||||||
|
|
||||||
WUPSStorageError LoadFromFile(std::string_view plugin_id, StorageItemRoot &rootItem) {
|
WUPSStorageError LoadFromFile(std::string_view plugin_id, StorageItemRoot &rootItem) {
|
||||||
nlohmann::json j;
|
nlohmann::json j;
|
||||||
WUPSStorageError err;
|
|
||||||
|
|
||||||
if ((err = LoadFromFile(plugin_id, j)) != WUPS_STORAGE_ERROR_SUCCESS) {
|
if (WUPSStorageError err; (err = LoadFromFile(plugin_id, j)) != WUPS_STORAGE_ERROR_SUCCESS) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +217,7 @@ namespace StorageUtils {
|
|||||||
static WUPSStorageError WriteStorageToSD(wups_storage_root_item root, bool forceSave) {
|
static WUPSStorageError WriteStorageToSD(wups_storage_root_item root, bool forceSave) {
|
||||||
const StorageItemRoot *rootItem = nullptr;
|
const StorageItemRoot *rootItem = nullptr;
|
||||||
for (const auto &cur : gStorage) {
|
for (const auto &cur : gStorage) {
|
||||||
if (cur.getHandle() == (uint32_t) root) {
|
if (cur.getHandle() == reinterpret_cast<uint32_t>(root)) {
|
||||||
rootItem = &cur;
|
rootItem = &cur;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -228,8 +226,8 @@ namespace StorageUtils {
|
|||||||
return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED;
|
return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string folderPath = getPluginPath() + "/config/";
|
const std::string folderPath = getPluginPath() + "/config/";
|
||||||
std::string filePath = folderPath + rootItem->getPluginId() + ".json";
|
const std::string filePath = folderPath + rootItem->getPluginId() + ".json";
|
||||||
|
|
||||||
nlohmann::json j;
|
nlohmann::json j;
|
||||||
j["storageitems"] = serializeToJson(*rootItem);
|
j["storageitems"] = serializeToJson(*rootItem);
|
||||||
@ -260,19 +258,19 @@ namespace StorageUtils {
|
|||||||
return WUPS_STORAGE_ERROR_IO_ERROR;
|
return WUPS_STORAGE_ERROR_IO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string jsonString = j.dump(4, ' ', false, nlohmann::json::error_handler_t::ignore);
|
const std::string jsonString = j.dump(4, ' ', false, nlohmann::json::error_handler_t::ignore);
|
||||||
auto writeResult = file.write((const uint8_t *) jsonString.c_str(), jsonString.size());
|
const auto writeResult = file.write(reinterpret_cast<const uint8_t *>(jsonString.c_str()), jsonString.size());
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
if (writeResult != (int32_t) jsonString.size()) {
|
if (writeResult != static_cast<int32_t>(jsonString.size())) {
|
||||||
return WUPS_STORAGE_ERROR_IO_ERROR;
|
return WUPS_STORAGE_ERROR_IO_ERROR;
|
||||||
}
|
}
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static StorageItem *createOrGetItem(wups_storage_root_item root, wups_storage_item parent, const char *key, WUPSStorageError &error) {
|
static StorageItem *createOrGetItem(wups_storage_root_item root, wups_storage_item parent, const char *key, WUPSStorageError &error) {
|
||||||
auto subItem = getSubItem(root, parent);
|
const auto subItem = getSubItem(root, parent);
|
||||||
if (!subItem) {
|
if (!subItem) {
|
||||||
error = WUPS_STORAGE_ERROR_NOT_FOUND;
|
error = WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||||
return {};
|
return {};
|
||||||
@ -280,8 +278,9 @@ namespace StorageUtils {
|
|||||||
auto res = subItem->getItem(key);
|
auto res = subItem->getItem(key);
|
||||||
StorageSubItem::StorageSubItemError subItemError = StorageSubItem::STORAGE_SUB_ITEM_ERROR_NONE;
|
StorageSubItem::StorageSubItemError subItemError = StorageSubItem::STORAGE_SUB_ITEM_ERROR_NONE;
|
||||||
if (!res) {
|
if (!res) {
|
||||||
if (!(res = subItem->createItem(key, subItemError))) {
|
res = subItem->createItem(key, subItemError);
|
||||||
error = StorageUtils::Helper::ConvertToWUPSError(subItemError);
|
if (!res) {
|
||||||
|
error = ConvertToWUPSError(subItemError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (res) {
|
if (res) {
|
||||||
@ -291,10 +290,9 @@ namespace StorageUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
WUPSStorageError StoreItemGeneric(wups_storage_root_item root, wups_storage_item parent, const char *key, T value) {
|
WUPSStorageError StoreItemGeneric(wups_storage_root_item root, wups_storage_item parent, const char *key, const T &value) {
|
||||||
WUPSStorageError err;
|
WUPSStorageError err;
|
||||||
auto item = createOrGetItem(root, parent, key, err);
|
if (auto item = createOrGetItem(root, parent, key, err); item && err == WUPS_STORAGE_ERROR_SUCCESS) {
|
||||||
if (item && err == WUPS_STORAGE_ERROR_SUCCESS) {
|
|
||||||
item->setValue(value);
|
item->setValue(value);
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -303,12 +301,11 @@ namespace StorageUtils {
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
WUPSStorageError GetItemEx(wups_storage_root_item root, wups_storage_item parent, const char *key, T &result) {
|
WUPSStorageError GetItemEx(wups_storage_root_item root, wups_storage_item parent, const char *key, T &result) {
|
||||||
auto subItem = getSubItem(root, parent);
|
const auto subItem = getSubItem(root, parent);
|
||||||
if (!subItem) {
|
if (!subItem) {
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
auto item = subItem->getItem(key);
|
if (auto item = subItem->getItem(key)) {
|
||||||
if (item) {
|
|
||||||
if (item->getValue(result)) {
|
if (item->getValue(result)) {
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -338,13 +335,11 @@ namespace StorageUtils {
|
|||||||
* Binary items are serialized as base64 encoded string. The first time they are read they'll get converted into binary data.
|
* Binary items are serialized as base64 encoded string. The first time they are read they'll get converted into binary data.
|
||||||
*/
|
*/
|
||||||
WUPSStorageError GetAndFixBinaryItem(wups_storage_root_item root, wups_storage_item parent, const char *key, std::vector<uint8_t> &result) {
|
WUPSStorageError GetAndFixBinaryItem(wups_storage_root_item root, wups_storage_item parent, const char *key, std::vector<uint8_t> &result) {
|
||||||
auto subItem = getSubItem(root, parent);
|
const auto subItem = getSubItem(root, parent);
|
||||||
if (!subItem) {
|
if (!subItem) {
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
WUPSStorageError err = WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE;
|
if (const auto item = subItem->getItem(key)) {
|
||||||
auto item = subItem->getItem(key);
|
|
||||||
if (item) {
|
|
||||||
// Trigger potential string->binary conversion
|
// Trigger potential string->binary conversion
|
||||||
if (!item->attemptBinaryConversion()) {
|
if (!item->attemptBinaryConversion()) {
|
||||||
return WUPS_STORAGE_ERROR_MALLOC_FAILED;
|
return WUPS_STORAGE_ERROR_MALLOC_FAILED;
|
||||||
@ -352,22 +347,22 @@ namespace StorageUtils {
|
|||||||
if (item->getValue(result)) {
|
if (item->getValue(result)) {
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
return err;
|
return WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE;
|
||||||
}
|
}
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WUPSStorageError GetStringItem(wups_storage_root_item root, wups_storage_item parent, const char *key, void *data, uint32_t maxSize, uint32_t *outSize) {
|
static WUPSStorageError GetStringItem(wups_storage_root_item root, wups_storage_item parent, const char *key, void *data, uint32_t maxSize, uint32_t *outSize) {
|
||||||
std::string tmp;
|
std::string tmp;
|
||||||
auto res = GetItemEx<std::string>(root, parent, key, tmp);
|
const auto res = GetItemEx<std::string>(root, parent, key, tmp);
|
||||||
if (res == WUPS_STORAGE_ERROR_SUCCESS) {
|
if (res == WUPS_STORAGE_ERROR_SUCCESS) {
|
||||||
if (maxSize <= tmp.size()) { // maxSize needs to be bigger because of the null-terminator
|
if (maxSize <= tmp.size()) { // maxSize needs to be bigger because of the null-terminator
|
||||||
return WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL;
|
return WUPS_STORAGE_ERROR_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
strncpy((char *) data, tmp.c_str(), tmp.size());
|
strncpy(static_cast<char *>(data), tmp.c_str(), tmp.size());
|
||||||
((char *) data)[maxSize - 1] = '\0';
|
static_cast<char *>(data)[maxSize - 1] = '\0';
|
||||||
if (outSize) {
|
if (outSize) {
|
||||||
*outSize = strlen((char *) data) + 1;
|
*outSize = strlen(static_cast<char *>(data)) + 1;
|
||||||
}
|
}
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -376,7 +371,7 @@ namespace StorageUtils {
|
|||||||
|
|
||||||
static WUPSStorageError GetBinaryItem(wups_storage_root_item root, wups_storage_item parent, const char *key, const void *data, uint32_t maxSize, uint32_t *outSize) {
|
static WUPSStorageError GetBinaryItem(wups_storage_root_item root, wups_storage_item parent, const char *key, const void *data, uint32_t maxSize, uint32_t *outSize) {
|
||||||
std::vector<uint8_t> tmp;
|
std::vector<uint8_t> tmp;
|
||||||
auto res = GetAndFixBinaryItem(root, parent, key, tmp);
|
const auto res = GetAndFixBinaryItem(root, parent, key, tmp);
|
||||||
if (res == WUPS_STORAGE_ERROR_SUCCESS) {
|
if (res == WUPS_STORAGE_ERROR_SUCCESS) {
|
||||||
if (tmp.empty()) { // we need this to support getting empty std::vector
|
if (tmp.empty()) { // we need this to support getting empty std::vector
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||||
@ -404,8 +399,7 @@ namespace StorageUtils {
|
|||||||
gStorage.emplace_front(plugin_id);
|
gStorage.emplace_front(plugin_id);
|
||||||
auto &root = gStorage.front();
|
auto &root = gStorage.front();
|
||||||
|
|
||||||
WUPSStorageError err = Helper::LoadFromFile(plugin_id, root);
|
if (const WUPSStorageError err = Helper::LoadFromFile(plugin_id, root); err == WUPS_STORAGE_ERROR_NOT_FOUND) {
|
||||||
if (err == WUPS_STORAGE_ERROR_NOT_FOUND) {
|
|
||||||
// Create new clean StorageItemRoot if no existing storage was found
|
// Create new clean StorageItemRoot if no existing storage was found
|
||||||
root = StorageItemRoot(plugin_id);
|
root = StorageItemRoot(plugin_id);
|
||||||
} else if (err != WUPS_STORAGE_ERROR_SUCCESS) {
|
} else if (err != WUPS_STORAGE_ERROR_SUCCESS) {
|
||||||
@ -414,7 +408,7 @@ namespace StorageUtils {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
outItem = (wups_storage_root_item) root.getHandle();
|
outItem = reinterpret_cast<wups_storage_root_item>(root.getHandle());
|
||||||
|
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -422,10 +416,10 @@ namespace StorageUtils {
|
|||||||
WUPSStorageError CloseStorage(wups_storage_root_item root) {
|
WUPSStorageError CloseStorage(wups_storage_root_item root) {
|
||||||
std::lock_guard lock(gStorageMutex);
|
std::lock_guard lock(gStorageMutex);
|
||||||
|
|
||||||
auto res = StorageUtils::Helper::WriteStorageToSD(root, false);
|
const auto res = Helper::WriteStorageToSD(root, false);
|
||||||
// TODO: handle write error?
|
// TODO: handle write error?
|
||||||
|
|
||||||
if (!remove_first_if(gStorage, [&root](auto &cur) { return cur.getHandle() == (uint32_t) root; })) {
|
if (!remove_first_if(gStorage, [&root](auto &cur) { return cur.getHandle() == reinterpret_cast<uint32_t>(root); })) {
|
||||||
DEBUG_FUNCTION_LINE_WARN("Failed to close storage: Not opened (\"%08X\")", root);
|
DEBUG_FUNCTION_LINE_WARN("Failed to close storage: Not opened (\"%08X\")", root);
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
@ -433,7 +427,7 @@ namespace StorageUtils {
|
|||||||
}
|
}
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|
||||||
WUPSStorageError SaveStorage(wups_storage_root_item root, bool force) {
|
WUPSStorageError SaveStorage(wups_storage_root_item root, const bool force) {
|
||||||
std::lock_guard lock(gStorageMutex);
|
std::lock_guard lock(gStorageMutex);
|
||||||
return StorageUtils::Helper::WriteStorageToSD(root, force);
|
return StorageUtils::Helper::WriteStorageToSD(root, force);
|
||||||
}
|
}
|
||||||
@ -441,7 +435,7 @@ namespace StorageUtils {
|
|||||||
WUPSStorageError ForceReloadStorage(wups_storage_root_item root) {
|
WUPSStorageError ForceReloadStorage(wups_storage_root_item root) {
|
||||||
std::lock_guard lock(gStorageMutex);
|
std::lock_guard lock(gStorageMutex);
|
||||||
|
|
||||||
auto rootItem = Helper::getRootItem(root);
|
const auto rootItem = Helper::getRootItem(root);
|
||||||
if (!rootItem) {
|
if (!rootItem) {
|
||||||
return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED;
|
return WUPS_STORAGE_ERROR_INTERNAL_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
@ -456,7 +450,7 @@ namespace StorageUtils {
|
|||||||
WUPSStorageError WipeStorage(wups_storage_root_item root) {
|
WUPSStorageError WipeStorage(wups_storage_root_item root) {
|
||||||
std::lock_guard lock(gStorageMutex);
|
std::lock_guard lock(gStorageMutex);
|
||||||
|
|
||||||
auto rootItem = Helper::getRootItem(root);
|
const auto rootItem = Helper::getRootItem(root);
|
||||||
if (!rootItem) {
|
if (!rootItem) {
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
@ -471,14 +465,13 @@ namespace StorageUtils {
|
|||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
std::lock_guard lock(gStorageMutex);
|
std::lock_guard lock(gStorageMutex);
|
||||||
auto subItem = StorageUtils::Helper::getSubItem(root, parent);
|
if (const auto subItem = StorageUtils::Helper::getSubItem(root, parent)) {
|
||||||
if (subItem) {
|
|
||||||
StorageSubItem::StorageSubItemError error = StorageSubItem::STORAGE_SUB_ITEM_ERROR_NONE;
|
StorageSubItem::StorageSubItemError error = StorageSubItem::STORAGE_SUB_ITEM_ERROR_NONE;
|
||||||
auto res = subItem->createSubItem(key, error);
|
const auto res = subItem->createSubItem(key, error);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
return StorageUtils::Helper::ConvertToWUPSError(error);
|
return StorageUtils::Helper::ConvertToWUPSError(error);
|
||||||
}
|
}
|
||||||
*outItem = (wups_storage_item) res->getHandle();
|
*outItem = reinterpret_cast<wups_storage_item>(res->getHandle());
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||||
@ -489,13 +482,12 @@ namespace StorageUtils {
|
|||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
std::lock_guard lock(gStorageMutex);
|
std::lock_guard lock(gStorageMutex);
|
||||||
auto subItem = StorageUtils::Helper::getSubItem(root, parent);
|
if (const auto subItem = StorageUtils::Helper::getSubItem(root, parent)) {
|
||||||
if (subItem) {
|
const auto res = subItem->getSubItem(key);
|
||||||
auto res = subItem->getSubItem(key);
|
|
||||||
if (!res) {
|
if (!res) {
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
*outItem = (wups_storage_item) res->getHandle();
|
*outItem = reinterpret_cast<wups_storage_item>(res->getHandle());
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||||
@ -503,10 +495,8 @@ namespace StorageUtils {
|
|||||||
|
|
||||||
WUPSStorageError DeleteItem(wups_storage_root_item root, wups_storage_item parent, const char *key) {
|
WUPSStorageError DeleteItem(wups_storage_root_item root, wups_storage_item parent, const char *key) {
|
||||||
std::lock_guard lock(gStorageMutex);
|
std::lock_guard lock(gStorageMutex);
|
||||||
auto subItem = StorageUtils::Helper::getSubItem(root, parent);
|
if (const auto subItem = StorageUtils::Helper::getSubItem(root, parent)) {
|
||||||
if (subItem) {
|
if (const auto res = subItem->deleteItem(key); !res) {
|
||||||
auto res = subItem->deleteItem(key);
|
|
||||||
if (!res) {
|
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
return WUPS_STORAGE_ERROR_SUCCESS;
|
return WUPS_STORAGE_ERROR_SUCCESS;
|
||||||
@ -514,7 +504,7 @@ namespace StorageUtils {
|
|||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
WUPSStorageError GetItemSize(wups_storage_root_item root, wups_storage_item parent, const char *key, WUPSStorageItemType itemType, uint32_t *outSize) {
|
WUPSStorageError GetItemSize(wups_storage_root_item root, wups_storage_item parent, const char *key, const WUPSStorageItemType itemType, uint32_t *outSize) {
|
||||||
if (!outSize) {
|
if (!outSize) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
@ -522,12 +512,11 @@ namespace StorageUtils {
|
|||||||
return WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE;
|
return WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE;
|
||||||
}
|
}
|
||||||
std::lock_guard lock(gStorageMutex);
|
std::lock_guard lock(gStorageMutex);
|
||||||
auto subItem = StorageUtils::Helper::getSubItem(root, parent);
|
const auto subItem = StorageUtils::Helper::getSubItem(root, parent);
|
||||||
if (!subItem) {
|
if (!subItem) {
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
auto item = subItem->getItem(key);
|
if (const auto item = subItem->getItem(key)) {
|
||||||
if (item) {
|
|
||||||
if (itemType == WUPS_STORAGE_ITEM_BINARY) {
|
if (itemType == WUPS_STORAGE_ITEM_BINARY) {
|
||||||
// Trigger potential string -> binary conversion.
|
// Trigger potential string -> binary conversion.
|
||||||
if (!item->attemptBinaryConversion()) {
|
if (!item->attemptBinaryConversion()) {
|
||||||
@ -551,42 +540,42 @@ namespace StorageUtils {
|
|||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
WUPSStorageError StoreItem(wups_storage_root_item root, wups_storage_item parent, const char *key, WUPSStorageItemType itemType, void *data, uint32_t length) {
|
WUPSStorageError StoreItem(wups_storage_root_item root, wups_storage_item parent, const char *key, WUPSStorageItemType itemType, void *data, const uint32_t length) {
|
||||||
std::lock_guard lock(gStorageMutex);
|
std::lock_guard lock(gStorageMutex);
|
||||||
switch ((WUPSStorageItemTypes) itemType) {
|
switch (static_cast<WUPSStorageItemTypes>(itemType)) {
|
||||||
case WUPS_STORAGE_ITEM_S32: {
|
case WUPS_STORAGE_ITEM_S32: {
|
||||||
if (data == nullptr || length != sizeof(int32_t)) {
|
if (data == nullptr || length != sizeof(int32_t)) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as S32: %d", key, *(int32_t *) data);
|
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as S32: %d", key, *(int32_t *) data);
|
||||||
return StorageUtils::Helper::StoreItemGeneric<int32_t>(root, parent, key, *(int32_t *) data);
|
return StorageUtils::Helper::StoreItemGeneric<int32_t>(root, parent, key, *static_cast<int32_t *>(data));
|
||||||
}
|
}
|
||||||
case WUPS_STORAGE_ITEM_S64: {
|
case WUPS_STORAGE_ITEM_S64: {
|
||||||
if (data == nullptr || length != sizeof(int64_t)) {
|
if (data == nullptr || length != sizeof(int64_t)) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as S64: %lld", key, *(int64_t *) data);
|
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as S64: %lld", key, *(int64_t *) data);
|
||||||
return StorageUtils::Helper::StoreItemGeneric<int64_t>(root, parent, key, *(int64_t *) data);
|
return StorageUtils::Helper::StoreItemGeneric<int64_t>(root, parent, key, *static_cast<int64_t *>(data));
|
||||||
}
|
}
|
||||||
case WUPS_STORAGE_ITEM_U32: {
|
case WUPS_STORAGE_ITEM_U32: {
|
||||||
if (data == nullptr || length != sizeof(uint32_t)) {
|
if (data == nullptr || length != sizeof(uint32_t)) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as u32: %u", key, *(uint32_t *) data);
|
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as u32: %u", key, *(uint32_t *) data);
|
||||||
return StorageUtils::Helper::StoreItemGeneric<uint32_t>(root, parent, key, *(uint32_t *) data);
|
return StorageUtils::Helper::StoreItemGeneric<uint32_t>(root, parent, key, *static_cast<uint32_t *>(data));
|
||||||
}
|
}
|
||||||
case WUPS_STORAGE_ITEM_U64: {
|
case WUPS_STORAGE_ITEM_U64: {
|
||||||
if (data == nullptr || length != sizeof(uint64_t)) {
|
if (data == nullptr || length != sizeof(uint64_t)) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as u64: %llu", key, *(uint64_t *) data);
|
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as u64: %llu", key, *(uint64_t *) data);
|
||||||
return StorageUtils::Helper::StoreItemGeneric<uint64_t>(root, parent, key, *(uint64_t *) data);
|
return StorageUtils::Helper::StoreItemGeneric<uint64_t>(root, parent, key, *static_cast<uint64_t *>(data));
|
||||||
}
|
}
|
||||||
case WUPS_STORAGE_ITEM_STRING: {
|
case WUPS_STORAGE_ITEM_STRING: {
|
||||||
if (data == nullptr) {
|
if (data == nullptr) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
std::string tmp = length > 0 ? std::string((const char *) data, length) : std::string();
|
const std::string tmp = length > 0 ? std::string(static_cast<const char *>(data), length) : std::string();
|
||||||
|
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as string: %s", key, tmp.c_str());
|
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as string: %s", key, tmp.c_str());
|
||||||
return StorageUtils::Helper::StoreItemGeneric<std::string>(root, parent, key, tmp);
|
return StorageUtils::Helper::StoreItemGeneric<std::string>(root, parent, key, tmp);
|
||||||
@ -595,7 +584,7 @@ namespace StorageUtils {
|
|||||||
if (data == nullptr && length > 0) {
|
if (data == nullptr && length > 0) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
std::vector<uint8_t> tmp = (data != nullptr && length > 0) ? std::vector<uint8_t>((uint8_t *) data, ((uint8_t *) data) + length) : std::vector<uint8_t>();
|
const std::vector<uint8_t> tmp = (data != nullptr && length > 0) ? std::vector(static_cast<uint8_t *>(data), static_cast<uint8_t *>(data) + length) : std::vector<uint8_t>();
|
||||||
|
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as binary: size %d", key, tmp.size());
|
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as binary: size %d", key, tmp.size());
|
||||||
return StorageUtils::Helper::StoreItemGeneric<std::vector<uint8_t>>(root, parent, key, tmp);
|
return StorageUtils::Helper::StoreItemGeneric<std::vector<uint8_t>>(root, parent, key, tmp);
|
||||||
@ -605,33 +594,39 @@ namespace StorageUtils {
|
|||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as bool: %d", key, *(bool *) data);
|
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as bool: %d", key, *(bool *) data);
|
||||||
return StorageUtils::Helper::StoreItemGeneric<bool>(root, parent, key, *(bool *) data);
|
return StorageUtils::Helper::StoreItemGeneric<bool>(root, parent, key, *static_cast<bool *>(data));
|
||||||
}
|
}
|
||||||
case WUPS_STORAGE_ITEM_FLOAT: {
|
case WUPS_STORAGE_ITEM_FLOAT: {
|
||||||
if (data == nullptr || length != sizeof(float)) {
|
if (data == nullptr || length != sizeof(float)) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as float: %f", key, *(float *) data);
|
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as float: %f", key, *(float *) data);
|
||||||
return StorageUtils::Helper::StoreItemGeneric<float>(root, parent, key, *(float *) data);
|
return StorageUtils::Helper::StoreItemGeneric<float>(root, parent, key, *static_cast<float *>(data));
|
||||||
}
|
}
|
||||||
case WUPS_STORAGE_ITEM_DOUBLE: {
|
case WUPS_STORAGE_ITEM_DOUBLE: {
|
||||||
if (data == nullptr || length != sizeof(double)) {
|
if (data == nullptr || length != sizeof(double)) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as double: %f", key, *(double *) data);
|
DEBUG_FUNCTION_LINE_VERBOSE("Store %s as double: %f", key, *(double *) data);
|
||||||
return StorageUtils::Helper::StoreItemGeneric<double>(root, parent, key, *(double *) data);
|
return StorageUtils::Helper::StoreItemGeneric<double>(root, parent, key, *static_cast<double *>(data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DEBUG_FUNCTION_LINE_ERR("Store failed!");
|
DEBUG_FUNCTION_LINE_ERR("Store failed!");
|
||||||
return WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE;
|
return WUPS_STORAGE_ERROR_UNEXPECTED_DATA_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
WUPSStorageError GetItem(wups_storage_root_item root, wups_storage_item parent, const char *key, WUPSStorageItemType itemType, void *data, uint32_t maxSize, uint32_t *outSize) {
|
WUPSStorageError GetItem(wups_storage_root_item root,
|
||||||
|
wups_storage_item parent,
|
||||||
|
const char *key,
|
||||||
|
WUPSStorageItemType itemType,
|
||||||
|
void *data,
|
||||||
|
const uint32_t maxSize,
|
||||||
|
uint32_t *outSize) {
|
||||||
std::lock_guard lock(gStorageMutex);
|
std::lock_guard lock(gStorageMutex);
|
||||||
if (outSize) {
|
if (outSize) {
|
||||||
*outSize = 0;
|
*outSize = 0;
|
||||||
}
|
}
|
||||||
switch ((WUPSStorageItemTypes) itemType) {
|
switch (static_cast<WUPSStorageItemTypes>(itemType)) {
|
||||||
case WUPS_STORAGE_ITEM_STRING: {
|
case WUPS_STORAGE_ITEM_STRING: {
|
||||||
if (!data || maxSize == 0) {
|
if (!data || maxSize == 0) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
@ -645,43 +640,43 @@ namespace StorageUtils {
|
|||||||
if (!data || maxSize != sizeof(bool)) {
|
if (!data || maxSize != sizeof(bool)) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
return StorageUtils::Helper::GetItemGeneric<bool>(root, parent, key, (bool *) data, outSize);
|
return StorageUtils::Helper::GetItemGeneric<bool>(root, parent, key, static_cast<bool *>(data), outSize);
|
||||||
}
|
}
|
||||||
case WUPS_STORAGE_ITEM_S32: {
|
case WUPS_STORAGE_ITEM_S32: {
|
||||||
if (!data || maxSize != sizeof(int32_t)) {
|
if (!data || maxSize != sizeof(int32_t)) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
return StorageUtils::Helper::GetItemGeneric<int32_t>(root, parent, key, (int32_t *) data, outSize);
|
return StorageUtils::Helper::GetItemGeneric<int32_t>(root, parent, key, static_cast<int32_t *>(data), outSize);
|
||||||
}
|
}
|
||||||
case WUPS_STORAGE_ITEM_S64: {
|
case WUPS_STORAGE_ITEM_S64: {
|
||||||
if (!data || maxSize != sizeof(int64_t)) {
|
if (!data || maxSize != sizeof(int64_t)) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
return StorageUtils::Helper::GetItemGeneric<int64_t>(root, parent, key, (int64_t *) data, outSize);
|
return StorageUtils::Helper::GetItemGeneric<int64_t>(root, parent, key, static_cast<int64_t *>(data), outSize);
|
||||||
}
|
}
|
||||||
case WUPS_STORAGE_ITEM_U32: {
|
case WUPS_STORAGE_ITEM_U32: {
|
||||||
if (!data || maxSize != sizeof(uint32_t)) {
|
if (!data || maxSize != sizeof(uint32_t)) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
return StorageUtils::Helper::GetItemGeneric<uint32_t>(root, parent, key, (uint32_t *) data, outSize);
|
return StorageUtils::Helper::GetItemGeneric<uint32_t>(root, parent, key, static_cast<uint32_t *>(data), outSize);
|
||||||
}
|
}
|
||||||
case WUPS_STORAGE_ITEM_U64: {
|
case WUPS_STORAGE_ITEM_U64: {
|
||||||
if (!data || maxSize != sizeof(uint64_t)) {
|
if (!data || maxSize != sizeof(uint64_t)) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
return StorageUtils::Helper::GetItemGeneric<uint64_t>(root, parent, key, (uint64_t *) data, outSize);
|
return StorageUtils::Helper::GetItemGeneric<uint64_t>(root, parent, key, static_cast<uint64_t *>(data), outSize);
|
||||||
}
|
}
|
||||||
case WUPS_STORAGE_ITEM_FLOAT: {
|
case WUPS_STORAGE_ITEM_FLOAT: {
|
||||||
if (!data || maxSize != sizeof(float)) {
|
if (!data || maxSize != sizeof(float)) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
return StorageUtils::Helper::GetItemGeneric<float>(root, parent, key, (float *) data, outSize);
|
return StorageUtils::Helper::GetItemGeneric<float>(root, parent, key, static_cast<float *>(data), outSize);
|
||||||
}
|
}
|
||||||
case WUPS_STORAGE_ITEM_DOUBLE: {
|
case WUPS_STORAGE_ITEM_DOUBLE: {
|
||||||
if (!data || maxSize != sizeof(double)) {
|
if (!data || maxSize != sizeof(double)) {
|
||||||
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
return WUPS_STORAGE_ERROR_INVALID_ARGS;
|
||||||
}
|
}
|
||||||
return StorageUtils::Helper::GetItemGeneric<double>(root, parent, key, (double *) data, outSize);
|
return StorageUtils::Helper::GetItemGeneric<double>(root, parent, key, static_cast<double *>(data), outSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
return WUPS_STORAGE_ERROR_NOT_FOUND;
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string_view>
|
||||||
#include <wups/storage.h>
|
#include <wups/storage.h>
|
||||||
|
|
||||||
namespace StorageUtils::API {
|
namespace StorageUtils::API {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <coreinit/ios.h>
|
#include <coreinit/ios.h>
|
||||||
|
#include <malloc.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
static std::string sPluginPath;
|
static std::string sPluginPath;
|
||||||
@ -10,11 +11,9 @@ std::string getPluginPath() {
|
|||||||
if (!sPluginPath.empty()) {
|
if (!sPluginPath.empty()) {
|
||||||
return sPluginPath;
|
return sPluginPath;
|
||||||
}
|
}
|
||||||
char environmentPath[0x100];
|
char environmentPath[0x100] = {};
|
||||||
memset(environmentPath, 0, sizeof(environmentPath));
|
|
||||||
|
|
||||||
auto handle = IOS_Open("/dev/mcp", IOS_OPEN_READ);
|
if (const auto handle = IOS_Open("/dev/mcp", IOS_OPEN_READ); handle >= 0) {
|
||||||
if (handle >= 0) {
|
|
||||||
int in = 0xF9; // IPC_CUSTOM_COPY_ENVIRONMENT_PATH
|
int in = 0xF9; // IPC_CUSTOM_COPY_ENVIRONMENT_PATH
|
||||||
if (IOS_Ioctl(handle, 100, &in, sizeof(in), environmentPath, sizeof(environmentPath)) != IOS_ERROR_OK) {
|
if (IOS_Ioctl(handle, 100, &in, sizeof(in), environmentPath, sizeof(environmentPath)) != IOS_ERROR_OK) {
|
||||||
return "fs:/vol/external01/wiiu/plugins";
|
return "fs:/vol/external01/wiiu/plugins";
|
||||||
@ -27,7 +26,7 @@ std::string getPluginPath() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// https://gist.github.com/ccbrown/9722406
|
// https://gist.github.com/ccbrown/9722406
|
||||||
void dumpHex(const void *data, size_t size) {
|
void dumpHex(const void *data, const size_t size) {
|
||||||
char ascii[17];
|
char ascii[17];
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
ascii[16] = '\0';
|
ascii[16] = '\0';
|
||||||
@ -71,7 +70,7 @@ OSDynLoad_Error CustomDynLoadAlloc(int32_t size, int32_t align, void **outAddr)
|
|||||||
align = -4;
|
align = -4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(*outAddr = memalign(align, size))) {
|
if (*outAddr = memalign(align, size); !*outAddr) {
|
||||||
return OS_DYNLOAD_OUT_OF_MEMORY;
|
return OS_DYNLOAD_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
// keep track of allocated memory to clean it up if RPLs won't get unloaded properly
|
// keep track of allocated memory to clean it up if RPLs won't get unloaded properly
|
||||||
@ -84,8 +83,7 @@ void CustomDynLoadFree(void *addr) {
|
|||||||
free(addr);
|
free(addr);
|
||||||
|
|
||||||
// Remove from list
|
// Remove from list
|
||||||
auto it = std::find(gAllocatedAddresses.begin(), gAllocatedAddresses.end(), addr);
|
if (const auto it = std::ranges::find(gAllocatedAddresses, addr); it != gAllocatedAddresses.end()) {
|
||||||
if (it != gAllocatedAddresses.end()) {
|
|
||||||
gAllocatedAddresses.erase(it);
|
gAllocatedAddresses.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,7 +4,6 @@
|
|||||||
#include <coreinit/dynload.h>
|
#include <coreinit/dynload.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <forward_list>
|
#include <forward_list>
|
||||||
#include <malloc.h>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
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 <memory>
|
||||||
|
|
||||||
#include "elfio/elfio_utils.hpp"
|
#include <elfio/elfio_utils.hpp>
|
||||||
#include "logger.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include <zlib.h>
|
|
||||||
|
|
||||||
class wiiu_zlib : public ELFIO::compression_interface {
|
class wiiu_zlib final : public ELFIO::compression_interface {
|
||||||
public:
|
public:
|
||||||
std::unique_ptr<char[]> inflate(const char *data, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword compressed_size, ELFIO::Elf_Xword &uncompressed_size) const override {
|
std::unique_ptr<char[]> inflate(const char *data, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword compressed_size, ELFIO::Elf_Xword &uncompressed_size) const override;
|
||||||
read_uncompressed_size(data, convertor, uncompressed_size);
|
|
||||||
auto result = make_unique_nothrow<char[]>((uint32_t) (uncompressed_size + 1));
|
|
||||||
if (result == nullptr) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
int z_ret;
|
std::unique_ptr<char[]> deflate(const char *data, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword decompressed_size, ELFIO::Elf_Xword &compressed_size) const override;
|
||||||
z_stream s = {};
|
|
||||||
|
|
||||||
s.zalloc = Z_NULL;
|
|
||||||
s.zfree = Z_NULL;
|
|
||||||
s.opaque = Z_NULL;
|
|
||||||
|
|
||||||
if (inflateInit_(&s, ZLIB_VERSION, sizeof(s)) != Z_OK) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
s.avail_in = compressed_size - 4;
|
|
||||||
s.next_in = (Bytef *) data;
|
|
||||||
s.avail_out = uncompressed_size;
|
|
||||||
s.next_out = (Bytef *) result.get();
|
|
||||||
|
|
||||||
z_ret = ::inflate(&s, Z_FINISH);
|
|
||||||
inflateEnd(&s);
|
|
||||||
|
|
||||||
if (z_ret != Z_OK && z_ret != Z_STREAM_END) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
result[uncompressed_size] = '\0';
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<char[]> deflate(const char *data, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword decompressed_size, ELFIO::Elf_Xword &compressed_size) const override {
|
|
||||||
auto result = make_unique_nothrow<char[]>((uint32_t) (decompressed_size));
|
|
||||||
if (result == nullptr) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
int z_ret;
|
|
||||||
z_stream s = {};
|
|
||||||
|
|
||||||
s.zalloc = Z_NULL;
|
|
||||||
s.zfree = Z_NULL;
|
|
||||||
s.opaque = Z_NULL;
|
|
||||||
|
|
||||||
if ((z_ret = deflateInit(&s, Z_DEFAULT_COMPRESSION)) != Z_OK) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
s.avail_in = decompressed_size;
|
|
||||||
s.next_in = (Bytef *) data;
|
|
||||||
s.avail_out = decompressed_size - 4;
|
|
||||||
s.next_out = (Bytef *) result.get() + 4;
|
|
||||||
|
|
||||||
z_ret = ::deflate(&s, Z_FINISH);
|
|
||||||
compressed_size = decompressed_size - s.avail_out;
|
|
||||||
deflateEnd(&s);
|
|
||||||
|
|
||||||
if (z_ret != Z_OK && z_ret != Z_STREAM_END) {
|
|
||||||
compressed_size = 0;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
write_compressed_size(result, convertor, compressed_size);
|
|
||||||
result[compressed_size] = '\0';
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void read_uncompressed_size(const char *&data, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword &uncompressed_size) {
|
static void read_uncompressed_size(const char *&data, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword &uncompressed_size);
|
||||||
union _int32buffer {
|
|
||||||
uint32_t word;
|
|
||||||
char bytes[4];
|
|
||||||
} int32buffer;
|
|
||||||
memcpy(int32buffer.bytes, data, 4);
|
|
||||||
data += 4;
|
|
||||||
uncompressed_size = (*convertor)(int32buffer.word);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void write_compressed_size(std::unique_ptr<char[]> &result, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword compressed_size) {
|
static void write_compressed_size(std::unique_ptr<char[]> &result, const ELFIO::endianess_convertor *convertor, ELFIO::Elf_Xword compressed_size);
|
||||||
union _int32buffer {
|
|
||||||
uint32_t word;
|
|
||||||
char bytes[4];
|
|
||||||
} int32buffer;
|
|
||||||
|
|
||||||
int32buffer.word = (*convertor)(compressed_size);
|
|
||||||
memcpy(result.get(), int32buffer.bytes, 4);
|
|
||||||
}
|
|
||||||
};
|
};
|
@ -1,2 +1,2 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#define VERSION_EXTRA ""
|
#define MODULE_VERSION_EXTRA ""
|
Loading…
Reference in New Issue
Block a user