mirror of
https://github.com/Maschell/hid_to_vpad.git
synced 2024-11-24 07:19:16 +01:00
WIP, no idea
This commit is contained in:
parent
3d19f8dff6
commit
a7ce2839f6
@ -19,21 +19,22 @@
|
|||||||
#include "utils/StringTools.h"
|
#include "utils/StringTools.h"
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
#include <controller_patcher/ControllerPatcher.hpp>
|
#include <controller_patcher/ControllerPatcher.hpp>
|
||||||
|
#include <coreinit/debug.h>
|
||||||
#include <wups.h>
|
#include <wups.h>
|
||||||
#include <wups/config.h>
|
|
||||||
#include <wups/config/WUPSConfigItemBoolean.h>
|
#include <wups/config/WUPSConfigItemBoolean.h>
|
||||||
|
|
||||||
bool runNetworkClient = true;
|
bool runNetworkClient = true;
|
||||||
|
|
||||||
|
|
||||||
void loadMapping(std::string &persistedValue, UController_Type type);
|
void loadMapping(const std::string &persistedValue, UController_Type type);
|
||||||
|
|
||||||
void ConfigLoad() {
|
void ConfigLoad() {
|
||||||
WUPS_OpenStorage();
|
WUPS_OpenStorage();
|
||||||
|
|
||||||
bool rumble = 0;
|
bool rumble = false;
|
||||||
|
|
||||||
if (WUPS_GetBool(nullptr, "rumble", &rumble) == WUPS_STORAGE_ERROR_SUCCESS) {
|
if (WUPS_GetBool(nullptr, "rumble", &rumble) == WUPS_STORAGE_ERROR_SUCCESS) {
|
||||||
|
DEBUG_FUNCTION_LINE("Set rumble to %d", rumble);
|
||||||
ControllerPatcher::setRumbleActivated(rumble);
|
ControllerPatcher::setRumbleActivated(rumble);
|
||||||
} else {
|
} else {
|
||||||
WUPS_StoreBool(nullptr, "rumble", ControllerPatcher::isRumbleActivated());
|
WUPS_StoreBool(nullptr, "rumble", ControllerPatcher::isRumbleActivated());
|
||||||
@ -49,10 +50,27 @@ void ConfigLoad() {
|
|||||||
loadMapping(stringWrapper, UController_Type_Gamepad);
|
loadMapping(stringWrapper, UController_Type_Gamepad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (WUPS_GetString(nullptr, "pro1", buffer, sizeof(buffer)) == WUPS_STORAGE_ERROR_SUCCESS) {
|
||||||
|
std::string stringWrapper = buffer;
|
||||||
|
loadMapping(stringWrapper, UController_Type_Pro1);
|
||||||
|
}
|
||||||
|
if (WUPS_GetString(nullptr, "pro2", buffer, sizeof(buffer)) == WUPS_STORAGE_ERROR_SUCCESS) {
|
||||||
|
std::string stringWrapper = buffer;
|
||||||
|
loadMapping(stringWrapper, UController_Type_Pro2);
|
||||||
|
}
|
||||||
|
if (WUPS_GetString(nullptr, "pro3", buffer, sizeof(buffer)) == WUPS_STORAGE_ERROR_SUCCESS) {
|
||||||
|
std::string stringWrapper = buffer;
|
||||||
|
loadMapping(stringWrapper, UController_Type_Pro3);
|
||||||
|
}
|
||||||
|
if (WUPS_GetString(nullptr, "pro4", buffer, sizeof(buffer)) == WUPS_STORAGE_ERROR_SUCCESS) {
|
||||||
|
std::string stringWrapper = buffer;
|
||||||
|
loadMapping(stringWrapper, UController_Type_Pro4);
|
||||||
|
}
|
||||||
|
|
||||||
WUPS_CloseStorage();
|
WUPS_CloseStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadMapping(std::string &persistedValue, UController_Type controllerType) {
|
void loadMapping(const std::string &persistedValue, UController_Type controllerType) {
|
||||||
if (persistedValue.empty()) {
|
if (persistedValue.empty()) {
|
||||||
// No device mapped.
|
// No device mapped.
|
||||||
return;
|
return;
|
||||||
@ -68,7 +86,6 @@ void loadMapping(std::string &persistedValue, UController_Type controllerType) {
|
|||||||
mappedPadInfo.pad = atoi(result.at(2).c_str());
|
mappedPadInfo.pad = atoi(result.at(2).c_str());
|
||||||
mappedPadInfo.type = CM_Type_Controller; //atoi(result.at(3).c_str());
|
mappedPadInfo.type = CM_Type_Controller; //atoi(result.at(3).c_str());
|
||||||
|
|
||||||
ControllerPatcher::resetControllerMapping(controllerType);
|
|
||||||
ControllerPatcher::addControllerMapping(controllerType, mappedPadInfo);
|
ControllerPatcher::addControllerMapping(controllerType, mappedPadInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,60 +107,51 @@ void networkClientChanged(ConfigItemBoolean *item, bool newValue) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PadMappingUpdated(ConfigItemPadMapping *item) {
|
void PadMappingUpdated(ConfigItemPadMapping *item) {
|
||||||
|
ControllerPatcher::resetControllerMapping(item->controllerType);
|
||||||
if (item->mappedPadInfo.active && item->mappedPadInfo.type == CM_Type_Controller) {
|
if (item->mappedPadInfo.active && item->mappedPadInfo.type == CM_Type_Controller) {
|
||||||
auto res = StringTools::strfmt("%d,%d,%d,%d", item->mappedPadInfo.vidpid.vid, item->mappedPadInfo.vidpid.pid, item->mappedPadInfo.pad, item->mappedPadInfo.type);
|
auto res = StringTools::strfmt("%d,%d,%d,%d", item->mappedPadInfo.vidpid.vid, item->mappedPadInfo.vidpid.pid, item->mappedPadInfo.pad, item->mappedPadInfo.type);
|
||||||
WUPS_StoreString(nullptr, item->configId, res.c_str());
|
WUPS_StoreString(nullptr, item->configId, res.c_str());
|
||||||
} else {
|
loadMapping(res, item->controllerType);
|
||||||
WUPS_StoreString(nullptr, item->configId, "");
|
return;
|
||||||
}
|
}
|
||||||
|
WUPS_StoreString(nullptr, item->configId, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool gConfigMenuOpen = false;
|
||||||
WUPS_CONFIG_CLOSED() {
|
WUPS_CONFIG_CLOSED() {
|
||||||
WUPS_CloseStorage();
|
gConfigMenuOpen = false;
|
||||||
|
// Save all changes
|
||||||
|
if (WUPS_CloseStorage() != WUPS_STORAGE_ERROR_SUCCESS) {
|
||||||
|
OSReport("Failed to close storage\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CONFIG_AddCategoryByName(config, name, callback) \
|
#define CONFIG_PadMapping_AddToCategory(__config__, category, config_id, display_name, controller_type, callback) \
|
||||||
if (WUPSConfig_AddCategoryByName(config, name, callback) < 0) { \
|
if (!WUPSConfigItemPadMapping_AddToCategory(category, config_id, display_name, controller_type, callback)) { \
|
||||||
WUPSConfig_Destroy(config); \
|
WUPSConfig_Destroy(__config__); \
|
||||||
return 0; \
|
return 0; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CONFIG_Boolean_AddToCategoryEx(category, config_id, display_name, default_value, callback, true_value, false_value) \
|
|
||||||
if (!WUPSConfigItemBoolean_AddToCategoryEx(category, config_id, display_name, default_value, callback, true_value, false_value)) { \
|
|
||||||
WUPSConfig_Destroy(config); \
|
|
||||||
return 0; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CONFIG_PadMapping_AddToCategory(category, config_id, display_name, controller_type, callback) \
|
|
||||||
if (!WUPSConfigItemPadMapping_AddToCategory(category, config_id, display_name, controller_type, callback)) { \
|
|
||||||
WUPSConfig_Destroy(config); \
|
|
||||||
return 0; \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
WUPS_GET_CONFIG() {
|
WUPS_GET_CONFIG() {
|
||||||
WUPS_OpenStorage();
|
WUPS_OpenStorage();
|
||||||
|
gConfigMenuOpen = true;
|
||||||
|
|
||||||
WUPSConfigHandle config;
|
WUPSConfigHandle config;
|
||||||
if (WUPSConfig_Create(&config, "HID to VPAD") < 0) {
|
WUPSConfig_CreateHandled(&config, "HID to VPAD");
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
WUPSConfigCategoryHandle catMapping;
|
WUPSConfigCategoryHandle catMapping;
|
||||||
WUPSConfigCategoryHandle catOther;
|
WUPSConfigCategoryHandle catOther;
|
||||||
|
|
||||||
CONFIG_AddCategoryByName(config, "Mapping", &catMapping);
|
WUPSConfig_AddCategoryByNameHandled(config, "Mapping", &catMapping);
|
||||||
CONFIG_AddCategoryByName(config, "Other", &catOther);
|
WUPSConfig_AddCategoryByNameHandled(config, "Other", &catOther);
|
||||||
|
WUPSConfigItemBoolean_AddToCategoryHandledEx(config, catOther, "rumble", "Rumble", ControllerPatcher::isRumbleActivated(), &rumbleChanged, "On", "Off");
|
||||||
|
WUPSConfigItemBoolean_AddToCategoryHandledEx(config, catOther, "networkclient", "Network Client", runNetworkClient, &networkClientChanged, "On", "Off");
|
||||||
|
|
||||||
CONFIG_Boolean_AddToCategoryEx(catOther, "rumble", "Rumble", ControllerPatcher::isRumbleActivated(), &rumbleChanged, "On", "Off");
|
CONFIG_PadMapping_AddToCategory(config, catMapping, "gamepadmapping", "Gamepad", UController_Type_Gamepad, &PadMappingUpdated);
|
||||||
CONFIG_Boolean_AddToCategoryEx(catOther, "networkclient", "Network Client", runNetworkClient, &networkClientChanged, "On", "Off");
|
CONFIG_PadMapping_AddToCategory(config, catMapping, "pro1", "Pro Controller 1", UController_Type_Pro1, &PadMappingUpdated);
|
||||||
|
CONFIG_PadMapping_AddToCategory(config, catMapping, "pro2", "Pro Controller 2", UController_Type_Pro2, &PadMappingUpdated);
|
||||||
CONFIG_PadMapping_AddToCategory(catMapping, "gamepadmapping", "Gamepad", UController_Type_Gamepad, &PadMappingUpdated);
|
CONFIG_PadMapping_AddToCategory(config, catMapping, "pro3", "Pro Controller 3", UController_Type_Pro3, &PadMappingUpdated);
|
||||||
CONFIG_PadMapping_AddToCategory(catMapping, "gamepadmapping", "Pro Controller 1", UController_Type_Pro1, &PadMappingUpdated);
|
CONFIG_PadMapping_AddToCategory(config, catMapping, "pro4", "Pro Controller 4", UController_Type_Pro4, &PadMappingUpdated);
|
||||||
CONFIG_PadMapping_AddToCategory(catMapping, "gamepadmapping", "Pro Controller 2", UController_Type_Pro2, &PadMappingUpdated);
|
|
||||||
CONFIG_PadMapping_AddToCategory(catMapping, "gamepadmapping", "Pro Controller 3", UController_Type_Pro3, &PadMappingUpdated);
|
|
||||||
CONFIG_PadMapping_AddToCategory(catMapping, "gamepadmapping", "Pro Controller 4", UController_Type_Pro4, &PadMappingUpdated);
|
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,18 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include <wups.h>
|
#include <wups.h>
|
||||||
|
|
||||||
|
#include "utils/logger.h"
|
||||||
#include <controller_patcher/ControllerPatcher.hpp>
|
#include <controller_patcher/ControllerPatcher.hpp>
|
||||||
|
#include <coreinit/cache.h>
|
||||||
|
#include <coreinit/debug.h>
|
||||||
|
#include <coreinit/thread.h>
|
||||||
|
|
||||||
|
extern bool gConfigMenuOpen;
|
||||||
DECL_FUNCTION(int32_t, VPADRead, VPADChan chan, VPADStatus *buffer, uint32_t buffer_size, VPADReadError *error) {
|
DECL_FUNCTION(int32_t, VPADRead, VPADChan chan, VPADStatus *buffer, uint32_t buffer_size, VPADReadError *error) {
|
||||||
int32_t result = real_VPADRead(chan, buffer, buffer_size, error);
|
int32_t result = real_VPADRead(chan, buffer, buffer_size, error);
|
||||||
|
if (gConfigMenuOpen) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
//A keyboard only sends data when the state changes. We force it to call the sampling callback on each frame!
|
//A keyboard only sends data when the state changes. We force it to call the sampling callback on each frame!
|
||||||
ControllerPatcher::sampleKeyboardData();
|
ControllerPatcher::sampleKeyboardData();
|
||||||
|
|
||||||
@ -51,7 +59,14 @@ DECL_FUNCTION(int32_t, VPADRead, VPADChan chan, VPADStatus *buffer, uint32_t buf
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECL_FUNCTION(void, WPADInit) {
|
||||||
|
real_WPADInit();
|
||||||
|
ControllerPatcher::UpdateSamplingFunctionAddress();
|
||||||
|
}
|
||||||
DECL_FUNCTION(int32_t, WPADProbe, WPADChan chan, uint32_t *result) {
|
DECL_FUNCTION(int32_t, WPADProbe, WPADChan chan, uint32_t *result) {
|
||||||
|
if (gConfigMenuOpen) {
|
||||||
|
return real_WPADProbe(chan, result);
|
||||||
|
}
|
||||||
if ((chan == WPAD_CHAN_0 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro1)) ||
|
if ((chan == WPAD_CHAN_0 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro1)) ||
|
||||||
(chan == WPAD_CHAN_1 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro2)) ||
|
(chan == WPAD_CHAN_1 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro2)) ||
|
||||||
(chan == WPAD_CHAN_2 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro3)) ||
|
(chan == WPAD_CHAN_2 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro3)) ||
|
||||||
@ -66,7 +81,7 @@ DECL_FUNCTION(int32_t, WPADProbe, WPADChan chan, uint32_t *result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DECL_FUNCTION(WPADConnectCallback, WPADSetConnectCallback, WPADChan chan, WPADConnectCallback callback) {
|
DECL_FUNCTION(WPADConnectCallback, WPADSetConnectCallback, WPADChan chan, WPADConnectCallback callback) {
|
||||||
//log_printf("WPADSetConnectCallback chan %d %08X",chan,callback);
|
DEBUG_FUNCTION_LINE("WPADSetConnectCallback chan %d %08X", chan, callback);
|
||||||
|
|
||||||
ControllerPatcher::setWPADConnectCallback(chan, callback);
|
ControllerPatcher::setWPADConnectCallback(chan, callback);
|
||||||
|
|
||||||
@ -75,14 +90,14 @@ DECL_FUNCTION(WPADConnectCallback, WPADSetConnectCallback, WPADChan chan, WPADCo
|
|||||||
(chan == WPAD_CHAN_2 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro3)) ||
|
(chan == WPAD_CHAN_2 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro3)) ||
|
||||||
(chan == WPAD_CHAN_3 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro4))) {
|
(chan == WPAD_CHAN_3 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro4))) {
|
||||||
if (callback != nullptr) {
|
if (callback != nullptr) {
|
||||||
callback(chan, 0);
|
//callback(chan, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return real_WPADSetConnectCallback(chan, callback);
|
return real_WPADSetConnectCallback(chan, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
DECL_FUNCTION(WPADExtensionCallback, WPADSetExtensionCallback, WPADChan chan, WPADExtensionCallback callback) {
|
DECL_FUNCTION(WPADExtensionCallback, WPADSetExtensionCallback, WPADChan chan, WPADExtensionCallback callback) {
|
||||||
//log_printf("WPADSetExtensionCallback chan %d %08X",chan,callback);
|
DEBUG_FUNCTION_LINE("WPADSetExtensionCallback chan %d %08X", chan, callback);
|
||||||
|
|
||||||
ControllerPatcher::setKPADExtensionCallback(chan, callback);
|
ControllerPatcher::setKPADExtensionCallback(chan, callback);
|
||||||
|
|
||||||
@ -91,14 +106,14 @@ DECL_FUNCTION(WPADExtensionCallback, WPADSetExtensionCallback, WPADChan chan, WP
|
|||||||
(chan == WPAD_CHAN_2 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro3)) ||
|
(chan == WPAD_CHAN_2 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro3)) ||
|
||||||
(chan == WPAD_CHAN_3 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro4))) {
|
(chan == WPAD_CHAN_3 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro4))) {
|
||||||
if (callback != nullptr) {
|
if (callback != nullptr) {
|
||||||
callback(chan, WPAD_EXT_PRO_CONTROLLER);
|
//callback(chan, WPAD_EXT_PRO_CONTROLLER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return real_WPADSetExtensionCallback(chan, callback);
|
return real_WPADSetExtensionCallback(chan, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
DECL_FUNCTION(WPADConnectCallback, KPADSetConnectCallback, WPADChan chan, WPADConnectCallback callback) {
|
DECL_FUNCTION(WPADConnectCallback, KPADSetConnectCallback, WPADChan chan, WPADConnectCallback callback) {
|
||||||
//log_printf("KPADSetConnectCallback chan %d %08X",chan,callback);
|
DEBUG_FUNCTION_LINE("KPADSetConnectCallback chan %d %08X", chan, callback);
|
||||||
|
|
||||||
ControllerPatcher::setKPADConnectedCallback(chan, callback);
|
ControllerPatcher::setKPADConnectedCallback(chan, callback);
|
||||||
|
|
||||||
@ -107,7 +122,7 @@ DECL_FUNCTION(WPADConnectCallback, KPADSetConnectCallback, WPADChan chan, WPADCo
|
|||||||
(chan == WPAD_CHAN_2 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro3)) ||
|
(chan == WPAD_CHAN_2 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro3)) ||
|
||||||
(chan == WPAD_CHAN_3 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro4))) {
|
(chan == WPAD_CHAN_3 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro4))) {
|
||||||
if (callback != nullptr) {
|
if (callback != nullptr) {
|
||||||
callback(chan, 0);
|
//callback(chan, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return real_KPADSetConnectCallback(chan, callback);
|
return real_KPADSetConnectCallback(chan, callback);
|
||||||
@ -127,7 +142,6 @@ DECL_FUNCTION(uint8_t, WPADGetBatteryLevel, WPADChan chan) {
|
|||||||
|
|
||||||
//In case a game relies on this...
|
//In case a game relies on this...
|
||||||
DECL_FUNCTION(uint32_t, WPADGetDataFormat, WPADChan chan) {
|
DECL_FUNCTION(uint32_t, WPADGetDataFormat, WPADChan chan) {
|
||||||
//log_printf("WPADGetDataFormat chan: %d result: %d",chan,result);
|
|
||||||
if ((chan == WPAD_CHAN_0 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro1)) ||
|
if ((chan == WPAD_CHAN_0 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro1)) ||
|
||||||
(chan == WPAD_CHAN_1 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro2)) ||
|
(chan == WPAD_CHAN_1 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro2)) ||
|
||||||
(chan == WPAD_CHAN_2 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro3)) ||
|
(chan == WPAD_CHAN_2 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro3)) ||
|
||||||
@ -151,6 +165,11 @@ DECL_FUNCTION(int32_t, WPADSetDataFormat, WPADChan chan, WPADDataFormat fmt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DECL_FUNCTION(void, WPADRead, WPADChan chan, WPADStatusProController *data) {
|
DECL_FUNCTION(void, WPADRead, WPADChan chan, WPADStatusProController *data) {
|
||||||
|
if (gConfigMenuOpen) {
|
||||||
|
real_WPADRead(chan, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((chan == WPAD_CHAN_0 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro1)) ||
|
if ((chan == WPAD_CHAN_0 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro1)) ||
|
||||||
(chan == WPAD_CHAN_1 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro2)) ||
|
(chan == WPAD_CHAN_1 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro2)) ||
|
||||||
(chan == WPAD_CHAN_2 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro3)) ||
|
(chan == WPAD_CHAN_2 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro3)) ||
|
||||||
@ -162,6 +181,10 @@ DECL_FUNCTION(void, WPADRead, WPADChan chan, WPADStatusProController *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DECL_FUNCTION(void, WPADControlMotor, WPADChan chan, uint32_t status) {
|
DECL_FUNCTION(void, WPADControlMotor, WPADChan chan, uint32_t status) {
|
||||||
|
if (gConfigMenuOpen) {
|
||||||
|
real_WPADControlMotor(chan, status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (chan == WPAD_CHAN_0 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro1)) {
|
if (chan == WPAD_CHAN_0 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro1)) {
|
||||||
ControllerPatcher::setRumble(UController_Type_Pro1, status);
|
ControllerPatcher::setRumble(UController_Type_Pro1, status);
|
||||||
} else if (chan == WPAD_CHAN_1 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro2)) {
|
} else if (chan == WPAD_CHAN_1 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro2)) {
|
||||||
@ -184,3 +207,4 @@ WUPS_MUST_REPLACE(WPADGetDataFormat, WUPS_LOADER_LIBRARY_PADSCORE, WPADGetDataFo
|
|||||||
WUPS_MUST_REPLACE(WPADSetDataFormat, WUPS_LOADER_LIBRARY_PADSCORE, WPADSetDataFormat);
|
WUPS_MUST_REPLACE(WPADSetDataFormat, WUPS_LOADER_LIBRARY_PADSCORE, WPADSetDataFormat);
|
||||||
WUPS_MUST_REPLACE(WPADControlMotor, WUPS_LOADER_LIBRARY_PADSCORE, WPADControlMotor);
|
WUPS_MUST_REPLACE(WPADControlMotor, WUPS_LOADER_LIBRARY_PADSCORE, WPADControlMotor);
|
||||||
WUPS_MUST_REPLACE(WPADProbe, WUPS_LOADER_LIBRARY_PADSCORE, WPADProbe);
|
WUPS_MUST_REPLACE(WPADProbe, WUPS_LOADER_LIBRARY_PADSCORE, WPADProbe);
|
||||||
|
WUPS_MUST_REPLACE(WPADInit, WUPS_LOADER_LIBRARY_PADSCORE, WPADInit);
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
#include "WUPSConfigItemPadMapping.h"
|
#include "WUPSConfigItemPadMapping.h"
|
||||||
#include <controller_patcher/ControllerPatcher.hpp>
|
#include <controller_patcher/ControllerPatcher.hpp>
|
||||||
|
#include <coreinit/debug.h>
|
||||||
#include <padscore/wpad.h>
|
#include <padscore/wpad.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -58,57 +59,26 @@ bool updatePadInfo(ConfigItemPadMapping *item) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t WUPSConfigItemPadMapping_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) {
|
|
||||||
auto *item = (ConfigItemPadMapping *) context;
|
|
||||||
if (!updatePadInfo(item)) {
|
|
||||||
snprintf(out_buf, out_size, "No Device");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
std::string name;
|
|
||||||
std::string isConnectedString = "attached";
|
|
||||||
|
|
||||||
if (!ControllerPatcher::isControllerConnectedAndActive(item->controllerType)) {
|
|
||||||
isConnectedString = "detached";
|
|
||||||
}
|
|
||||||
|
|
||||||
ControllerMappingPADInfo *info = &item->mappedPadInfo;
|
|
||||||
|
|
||||||
if (info->type == CM_Type_Controller) {
|
|
||||||
std::string titleString = ControllerPatcher::getIdentifierByVIDPID(info->vidpid.vid, info->vidpid.pid);
|
|
||||||
std::vector<std::string> result = StringTools::stringSplit(titleString, "\n");
|
|
||||||
if (result.size() == 1) {
|
|
||||||
name = titleString;
|
|
||||||
} else if (result.size() == 2) {
|
|
||||||
name = StringTools::strfmt("0x%04X / 0x%04X(%d) %s", info->vidpid.vid, info->vidpid.pid, info->pad, isConnectedString.c_str());
|
|
||||||
}
|
|
||||||
} else if (info->type == CM_Type_RealController) {
|
|
||||||
// currently this case can't happen.
|
|
||||||
name = "Real (Pro) Controller";
|
|
||||||
} else if (info->type == CM_Type_Mouse || info->type == CM_Type_Keyboard) {
|
|
||||||
// currently this case can't happen.
|
|
||||||
name = "Mouse / Keyboard";
|
|
||||||
}
|
|
||||||
|
|
||||||
strncpy(out_buf, name.c_str(), out_size);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkForInput(ConfigItemPadMapping *item) {
|
void checkForInput(ConfigItemPadMapping *item) {
|
||||||
int32_t inputsize = gHIDMaxDevices;
|
int32_t inputsize = gHIDMaxDevices;
|
||||||
auto *hiddata = (InputData *) malloc(sizeof(InputData) * inputsize);
|
auto *hiddata = (InputData *) malloc(sizeof(InputData) * inputsize);
|
||||||
memset(hiddata, 0, sizeof(InputData) * inputsize);
|
memset(hiddata, 0, sizeof(InputData) * inputsize);
|
||||||
|
|
||||||
ControllerMappingPADInfo pad_result;
|
ControllerMappingPADInfo pad_result = {};
|
||||||
memset(&pad_result, 0, sizeof(ControllerMappingPADInfo));
|
bool gotPress = false;
|
||||||
bool gotPress = false;
|
|
||||||
|
|
||||||
VPADStatus vpad_data;
|
VPADStatus vpad_data = {};
|
||||||
VPADReadError error;
|
VPADReadError error;
|
||||||
|
|
||||||
|
bool unmap = false;
|
||||||
while (!gotPress) {
|
while (!gotPress) {
|
||||||
real_VPADRead(VPAD_CHAN_0, &vpad_data, 1, &error);
|
real_VPADRead(VPAD_CHAN_0, &vpad_data, 1, &error);
|
||||||
if (error != VPAD_READ_SUCCESS) {
|
if (error != VPAD_READ_SUCCESS) {
|
||||||
|
if (vpad_data.hold == VPAD_BUTTON_X || vpad_data.hold == VPAD_BUTTON_HOME) {
|
||||||
|
unmap = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (vpad_data.hold == VPAD_BUTTON_B || vpad_data.hold == VPAD_BUTTON_HOME) {
|
if (vpad_data.hold == VPAD_BUTTON_B || vpad_data.hold == VPAD_BUTTON_HOME) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -116,12 +86,9 @@ void checkForInput(ConfigItemPadMapping *item) {
|
|||||||
|
|
||||||
int32_t result = ControllerPatcher::gettingInputAllDevices(hiddata, inputsize);
|
int32_t result = ControllerPatcher::gettingInputAllDevices(hiddata, inputsize);
|
||||||
if (result > 0) {
|
if (result > 0) {
|
||||||
//log_printf("got %d results",result);
|
|
||||||
for (int32_t i = 0; i < result; i++) {
|
for (int32_t i = 0; i < result; i++) {
|
||||||
for (int32_t j = 0; j < HID_MAX_PADS_COUNT; j++) {
|
for (int32_t j = 0; j < HID_MAX_PADS_COUNT; j++) {
|
||||||
//log_printf("check pad %d. %08X",j,hiddata[i].button_data[j].btn_h);
|
|
||||||
if (hiddata[i].button_data[j].btn_h != 0) {
|
if (hiddata[i].button_data[j].btn_h != 0) {
|
||||||
//log_printf("It pressed a buttons!",result);
|
|
||||||
pad_result.pad = j;
|
pad_result.pad = j;
|
||||||
pad_result.vidpid.vid = hiddata[i].device_info.vidpid.vid;
|
pad_result.vidpid.vid = hiddata[i].device_info.vidpid.vid;
|
||||||
pad_result.vidpid.pid = hiddata[i].device_info.vidpid.pid;
|
pad_result.vidpid.pid = hiddata[i].device_info.vidpid.pid;
|
||||||
@ -129,7 +96,7 @@ void checkForInput(ConfigItemPadMapping *item) {
|
|||||||
pad_result.type = hiddata[i].type;
|
pad_result.type = hiddata[i].type;
|
||||||
|
|
||||||
gotPress = true;
|
gotPress = true;
|
||||||
DEBUG_FUNCTION_LINE("%04X %04X (PAD: %d) pressed a buttons %08X", hiddata[i].device_info.vidpid.vid, hiddata[i].device_info.vidpid.pid, j, hiddata[i].button_data[j].btn_h);
|
DEBUG_FUNCTION_LINE("%04X %04X (PAD: %d) pressed a buttons %08X", pad_result.vidpid.vid, pad_result.vidpid.pid, pad_result.pad, hiddata[i].button_data[j].btn_h);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,21 +107,75 @@ void checkForInput(ConfigItemPadMapping *item) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (gotPress) {
|
if (gotPress) {
|
||||||
|
ControllerPatcher::resetControllerMapping(item->controllerType);
|
||||||
ControllerPatcher::addControllerMapping(item->controllerType, pad_result);
|
ControllerPatcher::addControllerMapping(item->controllerType, pad_result);
|
||||||
updatePadInfo(item);
|
updatePadInfo(item);
|
||||||
WUPSConfigItemPadMapping_callCallback(item);
|
WUPSConfigItemPadMapping_callCallback(item);
|
||||||
|
} else if (unmap) {
|
||||||
|
ControllerPatcher::resetControllerMapping(item->controllerType);
|
||||||
|
updatePadInfo(item);
|
||||||
|
WUPSConfigItemPadMapping_callCallback(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(hiddata);
|
free(hiddata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string GetDeviceName(ConfigItemPadMapping *item) {
|
||||||
|
if (!updatePadInfo(item)) {
|
||||||
|
return "No Device";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
std::string isConnectedString = "attached";
|
||||||
|
|
||||||
|
if (!ControllerPatcher::isControllerConnectedAndActive(item->controllerType)) {
|
||||||
|
isConnectedString = "detached";
|
||||||
|
}
|
||||||
|
|
||||||
|
ControllerMappingPADInfo *info = &item->mappedPadInfo;
|
||||||
|
|
||||||
|
if (info->type == CM_Type_Controller) {
|
||||||
|
std::string titleString = ControllerPatcher::getIdentifierByVIDPID(info->vidpid.vid, info->vidpid.pid);
|
||||||
|
name = StringTools::strfmt("%s (%d) %s", titleString.c_str(), info->pad, isConnectedString.c_str());
|
||||||
|
} else if (info->type == CM_Type_RealController) {
|
||||||
|
// currently this case can't happen.
|
||||||
|
name = "Real (Pro) Controller";
|
||||||
|
} else if (info->type == CM_Type_Mouse || info->type == CM_Type_Keyboard) {
|
||||||
|
// currently this case can't happen.
|
||||||
|
name = "Mouse / Keyboard";
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t WUPSConfigItemPadMapping_getCurrentValueDisplaySelected(void *context, char *out_buf, int32_t out_size) {
|
||||||
|
auto *item = (ConfigItemPadMapping *) context;
|
||||||
|
if (item->state == CONFIG_ITEM_PAD_MAPPING_PREPARE_FOR_HOLD || item->state == CONFIG_ITEM_PAD_MAPPING_WAIT_FOR_HOLD) {
|
||||||
|
if (item->state == CONFIG_ITEM_PAD_MAPPING_PREPARE_FOR_HOLD) {
|
||||||
|
item->state = CONFIG_ITEM_PAD_MAPPING_WAIT_FOR_HOLD;
|
||||||
|
snprintf(out_buf, out_size, "<Waiting for input on HID> (\ue001: Abort, \ue002 Reset)");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
checkForInput(item);
|
||||||
|
item->state = CONFIG_ITEM_PAD_MAPPING_STATE_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snprintf(out_buf, out_size, "> %s", GetDeviceName(item).c_str());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t WUPSConfigItemPadMapping_getCurrentValueDisplay(void *context, char *out_buf, int32_t out_size) {
|
||||||
|
auto *item = (ConfigItemPadMapping *) context;
|
||||||
|
std::string name = GetDeviceName(item);
|
||||||
|
snprintf(out_buf, out_size, " %s", GetDeviceName(item).c_str());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void WUPSConfigItemPadMapping_onButtonPressed(void *context, WUPSConfigButtons buttons) {
|
void WUPSConfigItemPadMapping_onButtonPressed(void *context, WUPSConfigButtons buttons) {
|
||||||
auto *item = (ConfigItemPadMapping *) context;
|
auto *item = (ConfigItemPadMapping *) context;
|
||||||
if (buttons & WUPS_CONFIG_BUTTON_A) {
|
if (item->state == CONFIG_ITEM_PAD_MAPPING_STATE_NONE) {
|
||||||
// Lets remove the old mapping.
|
if ((buttons & WUPS_CONFIG_BUTTON_A) == WUPS_CONFIG_BUTTON_A) {
|
||||||
ControllerPatcher::resetControllerMapping(item->controllerType);
|
item->state = CONFIG_ITEM_PAD_MAPPING_PREPARE_FOR_HOLD;
|
||||||
|
}
|
||||||
checkForInput(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,33 +183,48 @@ bool WUPSConfigItemPadMapping_isMovementAllowed(void *context) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WUPSConfigItemPadMapping_onSelected(void *context, bool isSelected) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void WUPSConfigItemPadMapping_onDelete(void *context) {
|
void WUPSConfigItemPadMapping_onDelete(void *context) {
|
||||||
auto *item = (ConfigItemPadMapping *) context;
|
auto *item = (ConfigItemPadMapping *) context;
|
||||||
|
if (item->configId) {
|
||||||
|
free(item->configId);
|
||||||
|
}
|
||||||
free(item);
|
free(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern "C" bool WUPSConfigItemPadMapping_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName, UController_Type controllerType, ConfigItemPadMappingChangedCallback callback) {
|
extern "C" bool WUPSConfigItemPadMapping_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName, UController_Type controllerType, ConfigItemPadMappingChangedCallback callback) {
|
||||||
if (cat == 0 || displayName == nullptr) {
|
if (cat == 0 || displayName == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto *item = (ConfigItemPadMapping *) malloc(sizeof(ConfigItemPadMapping));
|
auto *item = (ConfigItemPadMapping *) malloc(sizeof(ConfigItemPadMapping));
|
||||||
if (item == nullptr) {
|
if (item == nullptr) {
|
||||||
|
OSReport("WUPSConfigItemPadMapping_AddToCategory: Failed to allocate memory for item data.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(item->configId, configID, sizeof(item->configId));
|
if (configID != nullptr) {
|
||||||
|
item->configId = strdup(configID);
|
||||||
|
} else {
|
||||||
|
item->configId = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
item->controllerType = controllerType;
|
item->controllerType = controllerType;
|
||||||
item->callback = (void *) callback;
|
item->callback = (void *) callback;
|
||||||
|
item->state = CONFIG_ITEM_PAD_MAPPING_STATE_NONE;
|
||||||
memset(&item->mappedPadInfo, 0, sizeof(item->mappedPadInfo));
|
memset(&item->mappedPadInfo, 0, sizeof(item->mappedPadInfo));
|
||||||
|
|
||||||
WUPSConfigCallbacks_t callbacks = {
|
WUPSConfigCallbacks_t callbacks = {
|
||||||
.getCurrentValueDisplay = &WUPSConfigItemPadMapping_getCurrentValueDisplay,
|
.getCurrentValueDisplay = &WUPSConfigItemPadMapping_getCurrentValueDisplay,
|
||||||
.getCurrentValueSelectedDisplay = &WUPSConfigItemPadMapping_getCurrentValueDisplay,
|
.getCurrentValueSelectedDisplay = &WUPSConfigItemPadMapping_getCurrentValueDisplaySelected,
|
||||||
.onSelected = nullptr,
|
.onSelected = &WUPSConfigItemPadMapping_onSelected,
|
||||||
.restoreDefault = &restoreDefault,
|
.restoreDefault = &restoreDefault,
|
||||||
.isMovementAllowed = &WUPSConfigItemPadMapping_isMovementAllowed,
|
.isMovementAllowed = &WUPSConfigItemPadMapping_isMovementAllowed,
|
||||||
.callCallback = nullptr,
|
.callCallback = &WUPSConfigItemPadMapping_callCallback,
|
||||||
.onButtonPressed = &WUPSConfigItemPadMapping_onButtonPressed,
|
.onButtonPressed = &WUPSConfigItemPadMapping_onButtonPressed,
|
||||||
.onDelete = &WUPSConfigItemPadMapping_onDelete};
|
.onDelete = &WUPSConfigItemPadMapping_onDelete};
|
||||||
|
|
||||||
|
@ -22,10 +22,18 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum ConfigItemPadMappingState {
|
||||||
|
CONFIG_ITEM_PAD_MAPPING_STATE_NONE,
|
||||||
|
CONFIG_ITEM_PAD_MAPPING_PREPARE_FOR_HOLD,
|
||||||
|
CONFIG_ITEM_PAD_MAPPING_WAIT_FOR_HOLD,
|
||||||
|
} ConfigItemPadMappingState;
|
||||||
|
|
||||||
typedef struct ConfigItemPadMapping {
|
typedef struct ConfigItemPadMapping {
|
||||||
|
char *configId;
|
||||||
WUPSConfigItemHandle handle;
|
WUPSConfigItemHandle handle;
|
||||||
char configId[32];
|
|
||||||
UController_Type controllerType;
|
UController_Type controllerType;
|
||||||
|
ConfigItemPadMappingState state;
|
||||||
ControllerMappingPADInfo mappedPadInfo;
|
ControllerMappingPADInfo mappedPadInfo;
|
||||||
void *callback;
|
void *callback;
|
||||||
} ConfigItemPadMapping;
|
} ConfigItemPadMapping;
|
||||||
|
16
src/main.cpp
16
src/main.cpp
@ -21,26 +21,25 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <utils/logger.h>
|
#include <utils/logger.h>
|
||||||
|
|
||||||
|
WUPS_PLUGIN_NAME("HID to VPAD");
|
||||||
WUPS_PLUGIN_NAME("HID to VPAD lite");
|
|
||||||
WUPS_PLUGIN_DESCRIPTION("Enables HID devices as controllers on your Wii U");
|
WUPS_PLUGIN_DESCRIPTION("Enables HID devices as controllers on your Wii U");
|
||||||
WUPS_PLUGIN_VERSION("v1.0");
|
WUPS_PLUGIN_VERSION("0.1.1-alpha");
|
||||||
WUPS_PLUGIN_AUTHOR("Maschell");
|
WUPS_PLUGIN_AUTHOR("Maschell");
|
||||||
WUPS_PLUGIN_LICENSE("GPL");
|
WUPS_PLUGIN_LICENSE("GPL");
|
||||||
|
|
||||||
WUPS_USE_WUT_DEVOPTAB();
|
WUPS_USE_WUT_DEVOPTAB();
|
||||||
WUPS_USE_STORAGE("hid_to_vpad");
|
WUPS_USE_STORAGE("hid_to_vpad");
|
||||||
|
|
||||||
#define SD_PATH "fs:/vol/external01"
|
|
||||||
#define WIIU_PATH "/wiiu"
|
|
||||||
#define DEFAULT_HID_TO_VPAD_PATH SD_PATH WIIU_PATH "/apps/hidtovpad"
|
|
||||||
#define DEFAULT_CONTROLLER_PATCHER_PATCH SD_PATH WIIU_PATH "/controller"
|
|
||||||
|
|
||||||
extern int32_t runNetworkClient;
|
extern int32_t runNetworkClient;
|
||||||
|
|
||||||
|
#define SD_PATH "fs:/vol/external01"
|
||||||
|
#define WIIU_PATH "/wiiu"
|
||||||
|
#define DEFAULT_CONTROLLER_PATCHER_PATCH SD_PATH WIIU_PATH "/controller"
|
||||||
|
|
||||||
void ConfigLoad();
|
void ConfigLoad();
|
||||||
ON_APPLICATION_START() {
|
ON_APPLICATION_START() {
|
||||||
WHBLogUdpInit();
|
WHBLogUdpInit();
|
||||||
|
WHBLogCafeInit();
|
||||||
|
|
||||||
DEBUG_FUNCTION_LINE("Initializing the controller data");
|
DEBUG_FUNCTION_LINE("Initializing the controller data");
|
||||||
ControllerPatcher::Init(DEFAULT_CONTROLLER_PATCHER_PATCH);
|
ControllerPatcher::Init(DEFAULT_CONTROLLER_PATCHER_PATCH);
|
||||||
@ -60,7 +59,6 @@ INITIALIZE_PLUGIN() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEINITIALIZE_PLUGIN() {
|
DEINITIALIZE_PLUGIN() {
|
||||||
//CursorDrawer::destroyInstance();
|
|
||||||
ControllerPatcher::DeInit();
|
ControllerPatcher::DeInit();
|
||||||
ControllerPatcher::stopNetworkServer();
|
ControllerPatcher::stopNetworkServer();
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ extern "C" {
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <whb/log.h>
|
#include <whb/log.h>
|
||||||
#include <whb/log_udp.h>
|
#include <whb/log_udp.h>
|
||||||
|
#include <whb/log_cafe.h>
|
||||||
|
|
||||||
#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
|
#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
|
||||||
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__)
|
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__)
|
||||||
|
Loading…
Reference in New Issue
Block a user