Add ButtonComboAPI support

This commit is contained in:
Maschell
2024-12-18 16:11:14 +01:00
parent 6565585d18
commit cd92e47b9d
18 changed files with 1028 additions and 45 deletions

View File

@@ -3,7 +3,7 @@
HeapMemoryFixedSize::HeapMemoryFixedSize() = default;
HeapMemoryFixedSize::HeapMemoryFixedSize(std::size_t size) : mData(make_unique_nothrow<uint8_t[]>(size)), mSize(mData ? size : 0) {}
HeapMemoryFixedSize::HeapMemoryFixedSize(const 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) {

View File

@@ -0,0 +1,200 @@
#include "ButtonComboUtils.h"
#include <forward_list>
#include <mutex>
#include <plugin/ButtonComboManager.h>
#include <plugin/PluginContainer.h>
#include <utils/logger.h>
#include <utils/utils.h>
namespace ButtonComboUtils::API {
static std::forward_list<ButtonComboManager> sButtonComboManager;
static std::mutex sButtonComboMutex;
namespace Internal {
uint32_t CreateButtonComboData() {
std::lock_guard lock(sButtonComboMutex);
sButtonComboManager.emplace_front();
return sButtonComboManager.front().getHandle();
}
void RemoveButtonComboData(uint32_t buttonComboManagerHandle) {
if (!remove_locked_first_if(sButtonComboMutex, sButtonComboManager, [buttonComboManagerHandle](const ButtonComboManager &buttonComboData) { return buttonComboData.getHandle() == buttonComboManagerHandle; })) {
DEBUG_FUNCTION_LINE_WARN("Tried to remove ButtonComboManager by invalid handle: %08X", buttonComboManagerHandle);
}
}
} // namespace Internal
namespace {
WUPSButtonCombo_Error ExecuteForIdentifierLocked(void *identifier, const std::function<WUPSButtonCombo_Error(ButtonComboManager &)> &callback) {
if (identifier == nullptr) {
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
}
std::lock_guard lock(sButtonComboMutex);
for (auto &manager : sButtonComboManager) {
if (manager.getHandle() == reinterpret_cast<uint32_t>(identifier)) {
return callback(manager);
}
}
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
}
} // namespace
WUPSButtonCombo_Error AddButtonCombo(void *identifier,
const WUPSButtonCombo_ComboOptions *options,
WUPSButtonCombo_ComboHandle *outHandle,
WUPSButtonCombo_ComboStatus *outStatus) {
if (options == nullptr || outHandle == nullptr) {
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
}
WUPSButtonCombo_ComboStatus tmpStatus;
const auto res = ExecuteForIdentifierLocked(identifier,
[&](ButtonComboManager &manager) {
return manager.AddButtonComboHandle(*options, *outHandle, tmpStatus);
});
if (outStatus) { *outStatus = tmpStatus; }
return res;
}
WUPSButtonCombo_Error RemoveButtonCombo(void *identifier,
const WUPSButtonCombo_ComboHandle handle) {
if (identifier == nullptr || handle == nullptr) {
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
}
return ExecuteForIdentifierLocked(identifier,
[&](ButtonComboManager &manager) {
return manager.RemoveButtonCombo(handle);
});
}
WUPSButtonCombo_Error GetButtonComboStatus(void *identifier,
const WUPSButtonCombo_ComboHandle handle,
WUPSButtonCombo_ComboStatus *outStatus) {
if (identifier == nullptr || handle == nullptr || outStatus == nullptr) {
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
}
return ExecuteForIdentifierLocked(identifier,
[&](ButtonComboManager &manager) {
return manager.GetButtonComboStatus(handle, *outStatus);
});
}
WUPSButtonCombo_Error UpdateButtonComboMeta(void *identifier,
const WUPSButtonCombo_ComboHandle handle,
const WUPSButtonCombo_MetaOptions *metaOptions) {
if (metaOptions == nullptr) {
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
}
return ExecuteForIdentifierLocked(identifier,
[&](ButtonComboManager &manager) {
return manager.UpdateButtonComboMeta(handle, *metaOptions);
});
}
WUPSButtonCombo_Error UpdateButtonComboCallback(void *identifier,
const WUPSButtonCombo_ComboHandle handle,
const WUPSButtonCombo_CallbackOptions *callbackOptions) {
if (callbackOptions == nullptr) {
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
}
return ExecuteForIdentifierLocked(identifier,
[&](ButtonComboManager &manager) {
return manager.UpdateButtonComboCallback(handle, *callbackOptions);
});
}
WUPSButtonCombo_Error UpdateControllerMask(void *identifier,
const WUPSButtonCombo_ComboHandle handle,
const WUPSButtonCombo_ControllerTypes controllerMask,
WUPSButtonCombo_ComboStatus *outStatus) {
WUPSButtonCombo_ComboStatus tmpStatus;
const auto res = ExecuteForIdentifierLocked(identifier,
[&](ButtonComboManager &manager) {
return manager.UpdateControllerMask(handle, controllerMask, tmpStatus);
});
if (outStatus) { *outStatus = tmpStatus; }
return res;
}
WUPSButtonCombo_Error UpdateButtonCombo(void *identifier,
const WUPSButtonCombo_ComboHandle handle,
WUPSButtonCombo_Buttons combo,
WUPSButtonCombo_ComboStatus *outStatus) {
WUPSButtonCombo_ComboStatus tmpStatus;
const auto res = ExecuteForIdentifierLocked(identifier,
[&](ButtonComboManager &manager) {
return manager.UpdateButtonCombo(handle, combo, tmpStatus);
});
if (outStatus) { *outStatus = tmpStatus; }
return res;
}
WUPSButtonCombo_Error UpdateHoldDuration(void *identifier,
const WUPSButtonCombo_ComboHandle handle,
const uint32_t holdDurationInFrames) {
const auto res = ExecuteForIdentifierLocked(identifier,
[&](ButtonComboManager &manager) {
return manager.UpdateHoldDuration(handle, holdDurationInFrames);
});
return res;
}
WUPSButtonCombo_Error GetButtonComboMeta(void *identifier,
const WUPSButtonCombo_ComboHandle handle,
WUPSButtonCombo_MetaOptionsOut *outOptions) {
if (outOptions == nullptr) {
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
}
return ExecuteForIdentifierLocked(identifier,
[&](ButtonComboManager &manager) {
return manager.GetButtonComboMeta(handle, *outOptions);
});
}
WUPSButtonCombo_Error GetButtonComboCallback(void *identifier,
const WUPSButtonCombo_ComboHandle handle,
WUPSButtonCombo_CallbackOptions *outOptions) {
if (outOptions == nullptr) {
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
}
return ExecuteForIdentifierLocked(identifier,
[&](ButtonComboManager &manager) {
return manager.GetButtonComboCallback(handle, *outOptions);
});
}
WUPSButtonCombo_Error GetButtonComboInfoEx(void *identifier,
const WUPSButtonCombo_ComboHandle handle,
WUPSButtonCombo_ButtonComboInfoEx *outOptions) {
if (outOptions == nullptr) {
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
}
return ExecuteForIdentifierLocked(identifier,
[&](ButtonComboManager &manager) {
return manager.GetButtonComboInfoEx(handle, *outOptions);
});
}
WUPSButtonCombo_Error CheckComboAvailable(void *identifier,
const WUPSButtonCombo_ButtonComboOptions *options,
WUPSButtonCombo_ComboStatus *outStatus) {
if (outStatus == nullptr) {
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
}
return ExecuteForIdentifierLocked(identifier,
[&](ButtonComboManager &manager) {
return manager.CheckComboAvailable(*options, *outStatus);
});
}
WUPSButtonCombo_Error DetectButtonCombo_Blocking(void *identifier,
const WUPSButtonCombo_DetectButtonComboOptions *options,
WUPSButtonCombo_Buttons *outButtonCombo) {
if (options == nullptr || outButtonCombo == nullptr) {
return WUPS_BUTTON_COMBO_ERROR_INVALID_ARGS;
}
return ExecuteForIdentifierLocked(identifier,
[&](ButtonComboManager &manager) {
return manager.DetectButtonCombo_Blocking(*options, *outButtonCombo);
});
}
} // namespace ButtonComboUtils::API

View File

@@ -0,0 +1,65 @@
#pragma once
#include <wups/button_combo.h>
namespace ButtonComboUtils::API {
namespace Internal {
uint32_t CreateButtonComboData();
void RemoveButtonComboData(uint32_t buttonComboManagerHandle);
} // namespace Internal
WUPSButtonCombo_Error AddButtonCombo(void *identifier,
const WUPSButtonCombo_ComboOptions *options,
WUPSButtonCombo_ComboHandle *outHandle,
WUPSButtonCombo_ComboStatus *outStatus);
WUPSButtonCombo_Error RemoveButtonCombo(void *identifier,
WUPSButtonCombo_ComboHandle handle);
WUPSButtonCombo_Error GetButtonComboStatus(void *identifier,
WUPSButtonCombo_ComboHandle handle,
WUPSButtonCombo_ComboStatus *outStatus);
WUPSButtonCombo_Error UpdateButtonComboMeta(void *identifier,
WUPSButtonCombo_ComboHandle handle,
const WUPSButtonCombo_MetaOptions *metaOptions);
WUPSButtonCombo_Error UpdateButtonComboCallback(void *identifier,
WUPSButtonCombo_ComboHandle handle,
const WUPSButtonCombo_CallbackOptions *callbackOptions);
WUPSButtonCombo_Error UpdateControllerMask(void *identifier,
WUPSButtonCombo_ComboHandle handle,
WUPSButtonCombo_ControllerTypes controllerMask,
WUPSButtonCombo_ComboStatus *outStatus);
WUPSButtonCombo_Error UpdateButtonCombo(void *identifier,
WUPSButtonCombo_ComboHandle handle,
WUPSButtonCombo_Buttons combo,
WUPSButtonCombo_ComboStatus *outStatus);
WUPSButtonCombo_Error UpdateHoldDuration(void *identifier,
WUPSButtonCombo_ComboHandle handle,
uint32_t holdDurationInFrames);
WUPSButtonCombo_Error GetButtonComboMeta(void *identifier,
WUPSButtonCombo_ComboHandle handle,
WUPSButtonCombo_MetaOptionsOut *outOptions);
WUPSButtonCombo_Error GetButtonComboCallback(void *identifier,
WUPSButtonCombo_ComboHandle handle,
WUPSButtonCombo_CallbackOptions *outOptions);
WUPSButtonCombo_Error GetButtonComboInfoEx(void *identifier,
WUPSButtonCombo_ComboHandle handle,
WUPSButtonCombo_ButtonComboInfoEx *outOptions);
WUPSButtonCombo_Error CheckComboAvailable(void *identifier,
const WUPSButtonCombo_ButtonComboOptions *options,
WUPSButtonCombo_ComboStatus *outStatus);
WUPSButtonCombo_Error DetectButtonCombo_Blocking(void *identifier,
const WUPSButtonCombo_DetectButtonComboOptions *options,
WUPSButtonCombo_Buttons *outButtonCombo);
} // namespace ButtonComboUtils::API

View File

@@ -108,12 +108,10 @@ void ConfigUtils::displayMenu() {
for (const auto &hook : plugin.getPluginLinkInformation().getHookDataList()) {
if (hook.getType() == WUPS_LOADER_HOOK_GET_CONFIG_DEPRECATED) {
if (hook.getFunctionPointer() == nullptr) {
DEBUG_FUNCTION_LINE_ERR("Hook had invalid ptr");
break;
}
auto cur_config_handle = ((void *(*) ())((uint32_t *) hook.getFunctionPointer()))();
if (cur_config_handle == nullptr) {
DEBUG_FUNCTION_LINE_WARN("Hook returned empty handle");
break;
}
config = WUPSConfigAPIBackend::Intern::PopConfigByHandle(WUPSConfigHandle(cur_config_handle));
@@ -238,11 +236,6 @@ void ConfigUtils::displayMenu() {
}
}
}
DEBUG_FUNCTION_LINE_INFO("Save new plugin list");
for (const auto &cur : newActivePluginsList) {
DEBUG_FUNCTION_LINE_ERR("%08X %s", cur.getPluginData()->getHandle(), cur.isLoadAndLink() ? "active" : "inactive");
}
DEBUG_FUNCTION_LINE_INFO("===");
gLoadOnNextLaunch = newActivePluginsList;
WUPSBackendSettings::SetInactivePluginFilenames(newInactivePluginsList);
if (!WUPSBackendSettings::SaveSettings()) {

View File

@@ -4,10 +4,12 @@
#include "utils/logger.h"
StorageItem::StorageItem(const std::string_view key) : mKey(key) {
// Abuse this as a stable handle that references itself and survives std::move
*mHandle = reinterpret_cast<uint32_t>(mHandle.get());
}
uint32_t StorageItem::getHandle() const {
return reinterpret_cast<uint32_t>(this);
return *mHandle;
}
void StorageItem::setValue(const std::string &value) {

View File

@@ -1,5 +1,6 @@
#pragma once
#include <cstdint>
#include <memory>
#include <string>
#include <variant>
#include <vector>
@@ -78,4 +79,6 @@ private:
std::string mKey = {};
bool mBinaryConversionDone = true;
std::unique_ptr<uint32_t> mHandle = std::make_unique<uint32_t>();
};