WIP, no idea

This commit is contained in:
Maschell 2024-10-13 10:35:27 +02:00
parent 3d19f8dff6
commit a7ce2839f6
6 changed files with 184 additions and 109 deletions

View File

@ -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;
} }

View File

@ -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);

View File

@ -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};

View File

@ -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;

View File

@ -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();
} }

View File

@ -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__)