mirror of
https://github.com/Maschell/hid_to_vpad.git
synced 2024-11-28 01:04:14 +01:00
WIP, no idea
This commit is contained in:
parent
3d19f8dff6
commit
a7ce2839f6
@ -19,21 +19,22 @@
|
||||
#include "utils/StringTools.h"
|
||||
#include "utils/logger.h"
|
||||
#include <controller_patcher/ControllerPatcher.hpp>
|
||||
#include <coreinit/debug.h>
|
||||
#include <wups.h>
|
||||
#include <wups/config.h>
|
||||
#include <wups/config/WUPSConfigItemBoolean.h>
|
||||
|
||||
bool runNetworkClient = true;
|
||||
|
||||
|
||||
void loadMapping(std::string &persistedValue, UController_Type type);
|
||||
void loadMapping(const std::string &persistedValue, UController_Type type);
|
||||
|
||||
void ConfigLoad() {
|
||||
WUPS_OpenStorage();
|
||||
|
||||
bool rumble = 0;
|
||||
bool rumble = false;
|
||||
|
||||
if (WUPS_GetBool(nullptr, "rumble", &rumble) == WUPS_STORAGE_ERROR_SUCCESS) {
|
||||
DEBUG_FUNCTION_LINE("Set rumble to %d", rumble);
|
||||
ControllerPatcher::setRumbleActivated(rumble);
|
||||
} else {
|
||||
WUPS_StoreBool(nullptr, "rumble", ControllerPatcher::isRumbleActivated());
|
||||
@ -49,10 +50,27 @@ void ConfigLoad() {
|
||||
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();
|
||||
}
|
||||
|
||||
void loadMapping(std::string &persistedValue, UController_Type controllerType) {
|
||||
void loadMapping(const std::string &persistedValue, UController_Type controllerType) {
|
||||
if (persistedValue.empty()) {
|
||||
// No device mapped.
|
||||
return;
|
||||
@ -68,7 +86,6 @@ void loadMapping(std::string &persistedValue, UController_Type controllerType) {
|
||||
mappedPadInfo.pad = atoi(result.at(2).c_str());
|
||||
mappedPadInfo.type = CM_Type_Controller; //atoi(result.at(3).c_str());
|
||||
|
||||
ControllerPatcher::resetControllerMapping(controllerType);
|
||||
ControllerPatcher::addControllerMapping(controllerType, mappedPadInfo);
|
||||
}
|
||||
|
||||
@ -90,60 +107,51 @@ void networkClientChanged(ConfigItemBoolean *item, bool newValue) {
|
||||
}
|
||||
|
||||
void PadMappingUpdated(ConfigItemPadMapping *item) {
|
||||
ControllerPatcher::resetControllerMapping(item->controllerType);
|
||||
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);
|
||||
WUPS_StoreString(nullptr, item->configId, res.c_str());
|
||||
} else {
|
||||
loadMapping(res, item->controllerType);
|
||||
return;
|
||||
}
|
||||
WUPS_StoreString(nullptr, item->configId, "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool gConfigMenuOpen = false;
|
||||
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) \
|
||||
if (WUPSConfig_AddCategoryByName(config, name, callback) < 0) { \
|
||||
WUPSConfig_Destroy(config); \
|
||||
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) \
|
||||
#define CONFIG_PadMapping_AddToCategory(__config__, category, config_id, display_name, controller_type, callback) \
|
||||
if (!WUPSConfigItemPadMapping_AddToCategory(category, config_id, display_name, controller_type, callback)) { \
|
||||
WUPSConfig_Destroy(config); \
|
||||
WUPSConfig_Destroy(__config__); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
|
||||
WUPS_GET_CONFIG() {
|
||||
WUPS_OpenStorage();
|
||||
gConfigMenuOpen = true;
|
||||
|
||||
WUPSConfigHandle config;
|
||||
if (WUPSConfig_Create(&config, "HID to VPAD") < 0) {
|
||||
return 0;
|
||||
}
|
||||
WUPSConfig_CreateHandled(&config, "HID to VPAD");
|
||||
|
||||
WUPSConfigCategoryHandle catMapping;
|
||||
WUPSConfigCategoryHandle catOther;
|
||||
|
||||
CONFIG_AddCategoryByName(config, "Mapping", &catMapping);
|
||||
CONFIG_AddCategoryByName(config, "Other", &catOther);
|
||||
WUPSConfig_AddCategoryByNameHandled(config, "Mapping", &catMapping);
|
||||
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_Boolean_AddToCategoryEx(catOther, "networkclient", "Network Client", runNetworkClient, &networkClientChanged, "On", "Off");
|
||||
|
||||
CONFIG_PadMapping_AddToCategory(catMapping, "gamepadmapping", "Gamepad", UController_Type_Gamepad, &PadMappingUpdated);
|
||||
CONFIG_PadMapping_AddToCategory(catMapping, "gamepadmapping", "Pro Controller 1", UController_Type_Pro1, &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);
|
||||
CONFIG_PadMapping_AddToCategory(config, catMapping, "gamepadmapping", "Gamepad", UController_Type_Gamepad, &PadMappingUpdated);
|
||||
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(config, catMapping, "pro3", "Pro Controller 3", UController_Type_Pro3, &PadMappingUpdated);
|
||||
CONFIG_PadMapping_AddToCategory(config, catMapping, "pro4", "Pro Controller 4", UController_Type_Pro4, &PadMappingUpdated);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
@ -16,10 +16,18 @@
|
||||
****************************************************************************/
|
||||
#include <wups.h>
|
||||
|
||||
#include "utils/logger.h"
|
||||
#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) {
|
||||
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!
|
||||
ControllerPatcher::sampleKeyboardData();
|
||||
|
||||
@ -51,7 +59,14 @@ DECL_FUNCTION(int32_t, VPADRead, VPADChan chan, VPADStatus *buffer, uint32_t buf
|
||||
return result;
|
||||
}
|
||||
|
||||
DECL_FUNCTION(void, WPADInit) {
|
||||
real_WPADInit();
|
||||
ControllerPatcher::UpdateSamplingFunctionAddress();
|
||||
}
|
||||
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)) ||
|
||||
(chan == WPAD_CHAN_1 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro2)) ||
|
||||
(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) {
|
||||
//log_printf("WPADSetConnectCallback chan %d %08X",chan,callback);
|
||||
DEBUG_FUNCTION_LINE("WPADSetConnectCallback chan %d %08X", 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_3 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro4))) {
|
||||
if (callback != nullptr) {
|
||||
callback(chan, 0);
|
||||
//callback(chan, 0);
|
||||
}
|
||||
}
|
||||
return real_WPADSetConnectCallback(chan, 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);
|
||||
|
||||
@ -91,14 +106,14 @@ DECL_FUNCTION(WPADExtensionCallback, WPADSetExtensionCallback, WPADChan chan, WP
|
||||
(chan == WPAD_CHAN_2 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro3)) ||
|
||||
(chan == WPAD_CHAN_3 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro4))) {
|
||||
if (callback != nullptr) {
|
||||
callback(chan, WPAD_EXT_PRO_CONTROLLER);
|
||||
//callback(chan, WPAD_EXT_PRO_CONTROLLER);
|
||||
}
|
||||
}
|
||||
return real_WPADSetExtensionCallback(chan, 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);
|
||||
|
||||
@ -107,7 +122,7 @@ DECL_FUNCTION(WPADConnectCallback, KPADSetConnectCallback, WPADChan chan, WPADCo
|
||||
(chan == WPAD_CHAN_2 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro3)) ||
|
||||
(chan == WPAD_CHAN_3 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro4))) {
|
||||
if (callback != nullptr) {
|
||||
callback(chan, 0);
|
||||
//callback(chan, 0);
|
||||
}
|
||||
}
|
||||
return real_KPADSetConnectCallback(chan, callback);
|
||||
@ -127,7 +142,6 @@ DECL_FUNCTION(uint8_t, WPADGetBatteryLevel, WPADChan chan) {
|
||||
|
||||
//In case a game relies on this...
|
||||
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)) ||
|
||||
(chan == WPAD_CHAN_1 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro2)) ||
|
||||
(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) {
|
||||
if (gConfigMenuOpen) {
|
||||
real_WPADRead(chan, data);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((chan == WPAD_CHAN_0 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro1)) ||
|
||||
(chan == WPAD_CHAN_1 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro2)) ||
|
||||
(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) {
|
||||
if (gConfigMenuOpen) {
|
||||
real_WPADControlMotor(chan, status);
|
||||
return;
|
||||
}
|
||||
if (chan == WPAD_CHAN_0 && ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro1)) {
|
||||
ControllerPatcher::setRumble(UController_Type_Pro1, status);
|
||||
} 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(WPADControlMotor, WUPS_LOADER_LIBRARY_PADSCORE, WPADControlMotor);
|
||||
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 <controller_patcher/ControllerPatcher.hpp>
|
||||
#include <coreinit/debug.h>
|
||||
#include <padscore/wpad.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -58,12 +59,72 @@ bool updatePadInfo(ConfigItemPadMapping *item) {
|
||||
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;
|
||||
|
||||
void checkForInput(ConfigItemPadMapping *item) {
|
||||
int32_t inputsize = gHIDMaxDevices;
|
||||
auto *hiddata = (InputData *) malloc(sizeof(InputData) * inputsize);
|
||||
memset(hiddata, 0, sizeof(InputData) * inputsize);
|
||||
|
||||
ControllerMappingPADInfo pad_result = {};
|
||||
bool gotPress = false;
|
||||
|
||||
VPADStatus vpad_data = {};
|
||||
VPADReadError error;
|
||||
|
||||
bool unmap = false;
|
||||
while (!gotPress) {
|
||||
real_VPADRead(VPAD_CHAN_0, &vpad_data, 1, &error);
|
||||
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) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t result = ControllerPatcher::gettingInputAllDevices(hiddata, inputsize);
|
||||
if (result > 0) {
|
||||
for (int32_t i = 0; i < result; i++) {
|
||||
for (int32_t j = 0; j < HID_MAX_PADS_COUNT; j++) {
|
||||
if (hiddata[i].button_data[j].btn_h != 0) {
|
||||
pad_result.pad = j;
|
||||
pad_result.vidpid.vid = hiddata[i].device_info.vidpid.vid;
|
||||
pad_result.vidpid.pid = hiddata[i].device_info.vidpid.pid;
|
||||
pad_result.active = 1;
|
||||
pad_result.type = hiddata[i].type;
|
||||
|
||||
gotPress = true;
|
||||
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;
|
||||
}
|
||||
}
|
||||
if (gotPress) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gotPress) {
|
||||
ControllerPatcher::resetControllerMapping(item->controllerType);
|
||||
ControllerPatcher::addControllerMapping(item->controllerType, pad_result);
|
||||
updatePadInfo(item);
|
||||
WUPSConfigItemPadMapping_callCallback(item);
|
||||
} else if (unmap) {
|
||||
ControllerPatcher::resetControllerMapping(item->controllerType);
|
||||
updatePadInfo(item);
|
||||
WUPSConfigItemPadMapping_callCallback(item);
|
||||
}
|
||||
|
||||
free(hiddata);
|
||||
}
|
||||
|
||||
static std::string GetDeviceName(ConfigItemPadMapping *item) {
|
||||
if (!updatePadInfo(item)) {
|
||||
return "No Device";
|
||||
}
|
||||
|
||||
std::string name;
|
||||
std::string isConnectedString = "attached";
|
||||
|
||||
@ -75,12 +136,7 @@ int32_t WUPSConfigItemPadMapping_getCurrentValueDisplay(void *context, char *out
|
||||
|
||||
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());
|
||||
}
|
||||
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";
|
||||
@ -88,73 +144,38 @@ int32_t WUPSConfigItemPadMapping_getCurrentValueDisplay(void *context, char *out
|
||||
// currently this case can't happen.
|
||||
name = "Mouse / Keyboard";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
strncpy(out_buf, name.c_str(), out_size);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void checkForInput(ConfigItemPadMapping *item) {
|
||||
int32_t inputsize = gHIDMaxDevices;
|
||||
auto *hiddata = (InputData *) malloc(sizeof(InputData) * inputsize);
|
||||
memset(hiddata, 0, sizeof(InputData) * inputsize);
|
||||
|
||||
ControllerMappingPADInfo pad_result;
|
||||
memset(&pad_result, 0, sizeof(ControllerMappingPADInfo));
|
||||
bool gotPress = false;
|
||||
|
||||
VPADStatus vpad_data;
|
||||
VPADReadError error;
|
||||
|
||||
while (!gotPress) {
|
||||
real_VPADRead(VPAD_CHAN_0, &vpad_data, 1, &error);
|
||||
if (error != VPAD_READ_SUCCESS) {
|
||||
if (vpad_data.hold == VPAD_BUTTON_B || vpad_data.hold == VPAD_BUTTON_HOME) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t result = ControllerPatcher::gettingInputAllDevices(hiddata, inputsize);
|
||||
if (result > 0) {
|
||||
//log_printf("got %d results",result);
|
||||
for (int32_t i = 0; i < result; i++) {
|
||||
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) {
|
||||
//log_printf("It pressed a buttons!",result);
|
||||
pad_result.pad = j;
|
||||
pad_result.vidpid.vid = hiddata[i].device_info.vidpid.vid;
|
||||
pad_result.vidpid.pid = hiddata[i].device_info.vidpid.pid;
|
||||
pad_result.active = 1;
|
||||
pad_result.type = hiddata[i].type;
|
||||
|
||||
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);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (gotPress) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gotPress) {
|
||||
ControllerPatcher::addControllerMapping(item->controllerType, pad_result);
|
||||
updatePadInfo(item);
|
||||
WUPSConfigItemPadMapping_callCallback(item);
|
||||
}
|
||||
|
||||
free(hiddata);
|
||||
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) {
|
||||
auto *item = (ConfigItemPadMapping *) context;
|
||||
if (buttons & WUPS_CONFIG_BUTTON_A) {
|
||||
// Lets remove the old mapping.
|
||||
ControllerPatcher::resetControllerMapping(item->controllerType);
|
||||
|
||||
checkForInput(item);
|
||||
if (item->state == CONFIG_ITEM_PAD_MAPPING_STATE_NONE) {
|
||||
if ((buttons & WUPS_CONFIG_BUTTON_A) == WUPS_CONFIG_BUTTON_A) {
|
||||
item->state = CONFIG_ITEM_PAD_MAPPING_PREPARE_FOR_HOLD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -162,33 +183,48 @@ bool WUPSConfigItemPadMapping_isMovementAllowed(void *context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void WUPSConfigItemPadMapping_onSelected(void *context, bool isSelected) {
|
||||
}
|
||||
|
||||
|
||||
void WUPSConfigItemPadMapping_onDelete(void *context) {
|
||||
auto *item = (ConfigItemPadMapping *) context;
|
||||
|
||||
if (item->configId) {
|
||||
free(item->configId);
|
||||
}
|
||||
free(item);
|
||||
}
|
||||
|
||||
|
||||
extern "C" bool WUPSConfigItemPadMapping_AddToCategory(WUPSConfigCategoryHandle cat, const char *configID, const char *displayName, UController_Type controllerType, ConfigItemPadMappingChangedCallback callback) {
|
||||
if (cat == 0 || displayName == nullptr) {
|
||||
return false;
|
||||
}
|
||||
auto *item = (ConfigItemPadMapping *) malloc(sizeof(ConfigItemPadMapping));
|
||||
if (item == nullptr) {
|
||||
OSReport("WUPSConfigItemPadMapping_AddToCategory: Failed to allocate memory for item data.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
strncpy(item->configId, configID, sizeof(item->configId));
|
||||
if (configID != nullptr) {
|
||||
item->configId = strdup(configID);
|
||||
} else {
|
||||
item->configId = nullptr;
|
||||
}
|
||||
|
||||
item->controllerType = controllerType;
|
||||
item->callback = (void *) callback;
|
||||
item->state = CONFIG_ITEM_PAD_MAPPING_STATE_NONE;
|
||||
memset(&item->mappedPadInfo, 0, sizeof(item->mappedPadInfo));
|
||||
|
||||
WUPSConfigCallbacks_t callbacks = {
|
||||
.getCurrentValueDisplay = &WUPSConfigItemPadMapping_getCurrentValueDisplay,
|
||||
.getCurrentValueSelectedDisplay = &WUPSConfigItemPadMapping_getCurrentValueDisplay,
|
||||
.onSelected = nullptr,
|
||||
.getCurrentValueSelectedDisplay = &WUPSConfigItemPadMapping_getCurrentValueDisplaySelected,
|
||||
.onSelected = &WUPSConfigItemPadMapping_onSelected,
|
||||
.restoreDefault = &restoreDefault,
|
||||
.isMovementAllowed = &WUPSConfigItemPadMapping_isMovementAllowed,
|
||||
.callCallback = nullptr,
|
||||
.callCallback = &WUPSConfigItemPadMapping_callCallback,
|
||||
.onButtonPressed = &WUPSConfigItemPadMapping_onButtonPressed,
|
||||
.onDelete = &WUPSConfigItemPadMapping_onDelete};
|
||||
|
||||
|
@ -22,10 +22,18 @@
|
||||
extern "C" {
|
||||
#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 {
|
||||
char *configId;
|
||||
WUPSConfigItemHandle handle;
|
||||
char configId[32];
|
||||
UController_Type controllerType;
|
||||
ConfigItemPadMappingState state;
|
||||
ControllerMappingPADInfo mappedPadInfo;
|
||||
void *callback;
|
||||
} ConfigItemPadMapping;
|
||||
|
12
src/main.cpp
12
src/main.cpp
@ -21,26 +21,25 @@
|
||||
#include <cstring>
|
||||
#include <utils/logger.h>
|
||||
|
||||
|
||||
WUPS_PLUGIN_NAME("HID to VPAD lite");
|
||||
WUPS_PLUGIN_NAME("HID to VPAD");
|
||||
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_LICENSE("GPL");
|
||||
|
||||
WUPS_USE_WUT_DEVOPTAB();
|
||||
WUPS_USE_STORAGE("hid_to_vpad");
|
||||
|
||||
extern int32_t runNetworkClient;
|
||||
|
||||
#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;
|
||||
|
||||
void ConfigLoad();
|
||||
ON_APPLICATION_START() {
|
||||
WHBLogUdpInit();
|
||||
WHBLogCafeInit();
|
||||
|
||||
DEBUG_FUNCTION_LINE("Initializing the controller data");
|
||||
ControllerPatcher::Init(DEFAULT_CONTROLLER_PATCHER_PATCH);
|
||||
@ -60,7 +59,6 @@ INITIALIZE_PLUGIN() {
|
||||
}
|
||||
|
||||
DEINITIALIZE_PLUGIN() {
|
||||
//CursorDrawer::destroyInstance();
|
||||
ControllerPatcher::DeInit();
|
||||
ControllerPatcher::stopNetworkServer();
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ extern "C" {
|
||||
#include <cstring>
|
||||
#include <whb/log.h>
|
||||
#include <whb/log_udp.h>
|
||||
#include <whb/log_cafe.h>
|
||||
|
||||
#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
|
||||
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__)
|
||||
|
Loading…
Reference in New Issue
Block a user