From da0f3620bc5fe8df4b7ed3f17d76a2fbe4ade85d Mon Sep 17 00:00:00 2001 From: Maschell Date: Mon, 8 May 2017 12:18:28 +0200 Subject: [PATCH 01/10] [Wii U] Adding missing includes and defines --- wiiu/include/wiiu/fs.h | 1 + wiiu/include/wiiu/kpad.h | 16 +++++++- wiiu/include/wiiu/os.h | 1 + wiiu/include/wiiu/os/energy.h | 18 +++++++++ wiiu/include/wiiu/os/systeminfo.h | 1 + wiiu/include/wiiu/syshid.h | 61 +++++++++++++++++++++++++++++++ wiiu/include/wiiu/vpad.h | 52 ++++++++++++++++---------- wiiu/include/wiiu/wpad.h | 56 +++++++++++++++++++++++++++- wiiu/system/imports.h | 41 +++++++++++++++++++++ 9 files changed, 225 insertions(+), 22 deletions(-) create mode 100644 wiiu/include/wiiu/os/energy.h create mode 100644 wiiu/include/wiiu/syshid.h diff --git a/wiiu/include/wiiu/fs.h b/wiiu/include/wiiu/fs.h index 0878f30f4f..863c3e62b2 100644 --- a/wiiu/include/wiiu/fs.h +++ b/wiiu/include/wiiu/fs.h @@ -164,6 +164,7 @@ void FSInit(); void FSShutdown(); FSStatus FSAddClient(FSClient *client, uint32_t flags); +FSStatus FSAddClientEx(FSClient *pClient, s32 unk_zero_param, uint32_t errHandling); FSStatus FSDelClient(FSClient *client, uint32_t flags); uint32_t FSGetClientNum(); void FSInitCmdBlock(FSCmdBlock *block); diff --git a/wiiu/include/wiiu/kpad.h b/wiiu/include/wiiu/kpad.h index 90343df6ce..17a97a527c 100644 --- a/wiiu/include/wiiu/kpad.h +++ b/wiiu/include/wiiu/kpad.h @@ -22,7 +22,7 @@ typedef struct _KPADData u8 device_type; u8 wpad_error; u8 pos_valid; - u8 unused_4[1]; + u8 format; union { @@ -45,6 +45,19 @@ typedef struct _KPADData f32 rtrigger; } classic; + struct + { + u32 hold; + u32 trigger; + u32 release; + f32 lstick_x; + f32 lstick_y; + f32 rstick_x; + f32 rstick_y; + s32 charging; + s32 wired; + } pro; + u32 unused_6[20]; }; u32 unused_7[16]; @@ -53,6 +66,7 @@ typedef struct _KPADData void KPADInit (void); s32 KPADRead(s32 chan, void * data, u32 size); +s32 KPADReadEx(s32 chan, KPADData * data, u32 size, s32 *error); #ifdef __cplusplus } diff --git a/wiiu/include/wiiu/os.h b/wiiu/include/wiiu/os.h index e824ee1dbb..52b4b11751 100644 --- a/wiiu/include/wiiu/os.h +++ b/wiiu/include/wiiu/os.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/wiiu/include/wiiu/os/energy.h b/wiiu/include/wiiu/os/energy.h new file mode 100644 index 0000000000..c4e350dad2 --- /dev/null +++ b/wiiu/include/wiiu/os/energy.h @@ -0,0 +1,18 @@ +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +s32 IMEnableDim(void); +s32 IMDisableDim(void); +s32 IMIsDimEnabled(s32 * result); +s32 IMEnableAPD(void); +s32 IMDisableAPD(void); +s32 IMIsAPDEnabled(s32 * result); +s32 IMIsAPDEnabledBySysSettings(s32 * result); + +#ifdef __cplusplus +} +#endif diff --git a/wiiu/include/wiiu/os/systeminfo.h b/wiiu/include/wiiu/os/systeminfo.h index e28c83634d..30952a2a7b 100644 --- a/wiiu/include/wiiu/os/systeminfo.h +++ b/wiiu/include/wiiu/os/systeminfo.h @@ -15,6 +15,7 @@ typedef struct }OSSystemInfo; OSSystemInfo *OSGetSystemInfo(); +s32 * __gh_errno_ptr(void); #ifdef __cplusplus } diff --git a/wiiu/include/wiiu/syshid.h b/wiiu/include/wiiu/syshid.h new file mode 100644 index 0000000000..9514a7d817 --- /dev/null +++ b/wiiu/include/wiiu/syshid.h @@ -0,0 +1,61 @@ +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct +{ + u32 handle; + u32 physical_device_inst; + u16 vid; + u16 pid; + u8 interface_index; + u8 sub_class; + u8 protocol; + + u16 max_packet_size_rx; + u16 max_packet_size_tx; + +} HIDDevice; + +#define HID_DEVICE_DETACH 0 +#define HID_DEVICE_ATTACH 1 + +typedef struct _HIDClient HIDClient; + +typedef s32 (*HIDAttachCallback)(HIDClient *p_hc,HIDDevice *p_hd,u32 attach); + +struct _HIDClient +{ + HIDClient *next; + HIDAttachCallback attach_cb; +}; + +typedef void HIDCallback(u32 handle,s32 error,u8 *p_buffer,u32 bytes_transferred,void *p_user); + +s32 HIDSetup(void); +s32 HIDTeardown(void); + +s32 HIDAddClient(HIDClient *p_client, HIDAttachCallback attach_callback); +s32 HIDDelClient(HIDClient *p_client); + +s32 HIDGetDescriptor(u32 handle,u8 descriptor_type,u8 descriptor_index, u16 language_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); +s32 HIDSetDescriptor(u32 handle,u8 descriptor_type,u8 descriptor_index, u16 language_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); + +s32 HIDGetReport(u32 handle, u8 report_type, u8 report_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); +s32 HIDSetReport(u32 handle, u8 report_type, u8 report_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); + +s32 HIDSetIdle(u32 handle, u8 interface_index,u8 duration, HIDCallback hc, void *p_user); + +s32 HIDSetProtocol(u32 handle,u8 interface_index,u8 protocol, HIDCallback hc, void *p_user); +s32 HIDGetProtocol(u32 handle,u8 interface_index,u8 * protocol, HIDCallback hc, void *p_user); + +s32 HIDRead(u32 handle, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); +s32 HIDWrite(u32 handle, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); + +#ifdef __cplusplus +} +#endif diff --git a/wiiu/include/wiiu/vpad.h b/wiiu/include/wiiu/vpad.h index f3887b2c3c..d322731cde 100644 --- a/wiiu/include/wiiu/vpad.h +++ b/wiiu/include/wiiu/vpad.h @@ -7,27 +7,41 @@ extern "C" { typedef enum VPADButtons { - VPAD_BUTTON_SYNC = 0x00000001, - VPAD_BUTTON_HOME = 0x00000002, - VPAD_BUTTON_MINUS = 0x00000004, - VPAD_BUTTON_PLUS = 0x00000008, - VPAD_BUTTON_R = 0x00000010, - VPAD_BUTTON_L = 0x00000020, - VPAD_BUTTON_ZR = 0x00000040, - VPAD_BUTTON_ZL = 0x00000080, - VPAD_BUTTON_DOWN = 0x00000100, - VPAD_BUTTON_UP = 0x00000200, - VPAD_BUTTON_RIGHT = 0x00000400, - VPAD_BUTTON_LEFT = 0x00000800, - VPAD_BUTTON_Y = 0x00001000, - VPAD_BUTTON_X = 0x00002000, - VPAD_BUTTON_B = 0x00004000, - VPAD_BUTTON_A = 0x00008000, - VPAD_BUTTON_TV = 0x00010000, - VPAD_BUTTON_STICK_R = 0x00020000, - VPAD_BUTTON_STICK_L = 0x00040000, + VPAD_BUTTON_SYNC = 0x00000001, + VPAD_BUTTON_HOME = 0x00000002, + VPAD_BUTTON_MINUS = 0x00000004, + VPAD_BUTTON_PLUS = 0x00000008, + VPAD_BUTTON_R = 0x00000010, + VPAD_BUTTON_L = 0x00000020, + VPAD_BUTTON_ZR = 0x00000040, + VPAD_BUTTON_ZL = 0x00000080, + VPAD_BUTTON_DOWN = 0x00000100, + VPAD_BUTTON_UP = 0x00000200, + VPAD_BUTTON_RIGHT = 0x00000400, + VPAD_BUTTON_LEFT = 0x00000800, + VPAD_BUTTON_Y = 0x00001000, + VPAD_BUTTON_X = 0x00002000, + VPAD_BUTTON_B = 0x00004000, + VPAD_BUTTON_A = 0x00008000, + VPAD_BUTTON_TV = 0x00010000, + VPAD_BUTTON_STICK_R = 0x00020000, + VPAD_BUTTON_STICK_L = 0x00040000, + VPAD_STICK_R_EMULATION_LEFT = 0x04000000, + VPAD_STICK_R_EMULATION_RIGHT = 0x02000000, + VPAD_STICK_R_EMULATION_UP = 0x01000000, + VPAD_STICK_R_EMULATION_DOWN = 0x00800000, + VPAD_STICK_L_EMULATION_LEFT = 0x40000000, + VPAD_STICK_L_EMULATION_RIGHT = 0x20000000, + VPAD_STICK_L_EMULATION_UP = 0x10000000, + VPAD_STICK_L_EMULATION_DOWN = 0x08000000, + + } VPADButtons; +#define VPAD_BUTTON_TOUCH 0x00080000 +#define VPAD_MASK_EMULATED_STICKS 0x7F800000 +#define VPAD_MASK_BUTTONS ~VPAD_MASK_EMULATED_STICKS + typedef enum VPADTouchPadValidity { //! Both X and Y touchpad positions are accurate diff --git a/wiiu/include/wiiu/wpad.h b/wiiu/include/wiiu/wpad.h index 64afc0ddef..dbf7d090bb 100644 --- a/wiiu/include/wiiu/wpad.h +++ b/wiiu/include/wiiu/wpad.h @@ -6,6 +6,16 @@ extern "C" { #include +#define WPAD_EXT_CORE 0 +#define WPAD_EXT_NUNCHUK 1 +#define WPAD_EXT_CLASSIC 2 +#define WPAD_EXT_MPLUS 5 +#define WPAD_EXT_MPLUS_NUNCHUK 6 +#define WPAD_EXT_MPLUS_CLASSIC 7 +#define WPAD_EXT_PRO_CONTROLLER 31 + +#define WPAD_FMT_PRO_CONTROLLER 22 + #define WPAD_BUTTON_LEFT 0x0001 #define WPAD_BUTTON_RIGHT 0x0002 #define WPAD_BUTTON_DOWN 0x0004 @@ -36,9 +46,51 @@ extern "C" { #define WPAD_CLASSIC_BUTTON_DOWN 0x4000 #define WPAD_CLASSIC_BUTTON_RIGHT 0x8000 -#define WPAD_PRO_BUTTON_STICK_R 0x10000 -#define WPAD_PRO_BUTTON_STICK_L 0x20000 +#define WPAD_PRO_BUTTON_UP 0x00000001 +#define WPAD_PRO_BUTTON_LEFT 0x00000002 +#define WPAD_PRO_TRIGGER_ZR 0x00000004 +#define WPAD_PRO_BUTTON_X 0x00000008 +#define WPAD_PRO_BUTTON_A 0x00000010 +#define WPAD_PRO_BUTTON_Y 0x00000020 +#define WPAD_PRO_BUTTON_B 0x00000040 +#define WPAD_PRO_TRIGGER_ZL 0x00000080 +#define WPAD_PRO_RESERVED 0x00000100 +#define WPAD_PRO_TRIGGER_R 0x00000200 +#define WPAD_PRO_BUTTON_PLUS 0x00000400 +#define WPAD_PRO_BUTTON_HOME 0x00000800 +#define WPAD_PRO_BUTTON_MINUS 0x00001000 +#define WPAD_PRO_TRIGGER_L 0x00002000 +#define WPAD_PRO_BUTTON_DOWN 0x00004000 +#define WPAD_PRO_BUTTON_RIGHT 0x00008000 +#define WPAD_PRO_BUTTON_STICK_R 0x00010000 +#define WPAD_PRO_BUTTON_STICK_L 0x00020000 +#define WPAD_PRO_STICK_L_EMULATION_UP 0x00200000 +#define WPAD_PRO_STICK_L_EMULATION_DOWN 0x00100000 +#define WPAD_PRO_STICK_L_EMULATION_LEFT 0x00040000 +#define WPAD_PRO_STICK_L_EMULATION_RIGHT 0x00080000 + +#define WPAD_PRO_STICK_R_EMULATION_UP 0x02000000 +#define WPAD_PRO_STICK_R_EMULATION_DOWN 0x01000000 +#define WPAD_PRO_STICK_R_EMULATION_LEFT 0x00400000 +#define WPAD_PRO_STICK_R_EMULATION_RIGHT 0x00800000 + +typedef struct WPADReadData_ { + u8 unknown[40]; + u8 dev; + u8 err; + u8 unknown1[2]; + u32 buttons; + s16 l_stick_x; + s16 l_stick_y; + s16 r_stick_x; + s16 r_stick_y; + u8 unknown2[8]; + u8 fmt; +}WPADReadData; + +typedef void (* wpad_sampling_callback_t)(s32 chan); +typedef void (* wpad_extension_callback_t)(s32 chan, s32 status); typedef void (* wpad_connect_callback_t)(s32 chan, s32 status); s32 WPADProbe (s32 chan, u32 * pad_type); diff --git a/wiiu/system/imports.h b/wiiu/system/imports.h index 665b6611d5..3a8db13ced 100644 --- a/wiiu/system/imports.h +++ b/wiiu/system/imports.h @@ -17,8 +17,13 @@ IMPORT(OSInitSpinLock); IMPORT(OSUninterruptibleSpinLock_Acquire); IMPORT(OSUninterruptibleSpinLock_Release); IMPORT(OSSleepTicks); +IMPORT(OSGetTitleID); +IMPORT(OSIsThreadTerminated); +IMPORT(OSSetThreadPriority); IMPORT(OSCreateThread); IMPORT(OSResumeThread); +IMPORT(OSIsThreadSuspended); +IMPORT(OSSuspendThread); IMPORT(OSJoinThread); IMPORT(OSYieldThread); IMPORT(OSGetSystemTime); @@ -31,10 +36,13 @@ IMPORT(_Exit); IMPORT(__os_snprintf); IMPORT(DisassemblePPCRange); +IMPORT(DCInvalidateRange); IMPORT(DCFlushRange); IMPORT(DCStoreRange); IMPORT(DCStoreRangeNoSync); +IMPORT(__gh_errno_ptr); + IMPORT(MEMGetBaseHeapHandle); IMPORT(MEMCreateExpHeapEx); IMPORT(MEMDestroyExpHeap); @@ -48,6 +56,7 @@ IMPORT(MEMGetAllocatableSizeForFrmHeapEx); IMPORT(FSInit); IMPORT(FSShutdown); IMPORT(FSAddClient); +IMPORT(FSAddClientEx); IMPORT(FSDelClient); IMPORT(FSInitCmdBlock); IMPORT(FSChangeDir); @@ -77,6 +86,13 @@ IMPORT(IOS_Close); IMPORT(IOS_Ioctl); IMPORT(IOS_IoctlAsync); +IMPORT(IMIsAPDEnabled); +IMPORT(IMIsDimEnabled); +IMPORT(IMEnableAPD); +IMPORT(IMEnableDim); +IMPORT(IMDisableAPD); +IMPORT(IMDisableDim); + IMPORT_END(); /* nsysnet */ @@ -84,6 +100,11 @@ IMPORT_BEGIN(nsysnet); IMPORT(socket_lib_init); IMPORT(socket); +IMPORT(setsockopt); +IMPORT(bind); +IMPORT(listen); +IMPORT(accept); +IMPORT(recv); IMPORT(socketclose); IMPORT(connect); IMPORT(send); @@ -191,6 +212,7 @@ IMPORT(WPADEnableURCC); IMPORT(WPADEnableWiiRemote); IMPORT(WPADRead); IMPORT(KPADRead); +IMPORT(KPADReadEx); IMPORT_END(); @@ -201,3 +223,22 @@ IMPORT(KBDSetup); IMPORT(KBDTeardown); IMPORT_END(); + +/* syshid */ +IMPORT_BEGIN(nsyshid); + +IMPORT(HIDSetup); +IMPORT(HIDTeardown); +IMPORT(HIDAddClient); +IMPORT(HIDDelClient); +IMPORT(HIDGetDescriptor); +IMPORT(HIDSetDescriptor); +IMPORT(HIDGetReport); +IMPORT(HIDSetReport); +IMPORT(HIDSetIdle); +IMPORT(HIDSetProtocol); +IMPORT(HIDGetProtocol); +IMPORT(HIDRead); +IMPORT(HIDWrite); + +IMPORT_END(); From e695d4e8ad47335a375ecda3f6bb20918b862882 Mon Sep 17 00:00:00 2001 From: Maschell Date: Mon, 8 May 2017 12:24:06 +0200 Subject: [PATCH 02/10] [WiiU] Initial controller patcher support (HID via USB and network) - Reading config from sd cards currently broken - Not implemeted as a driver, currently all devices will be mapped to the WiiU Gamepad driver --- Makefile.wiiu | 16 +++++++++++++++- frontend/drivers/platform_wiiu.c | 6 ++++++ input/drivers_joypad/wiiu_joypad.c | 6 ++++-- wiiu/controller_patcher | 1 + 4 files changed, 26 insertions(+), 3 deletions(-) create mode 160000 wiiu/controller_patcher diff --git a/Makefile.wiiu b/Makefile.wiiu index 25b1eb775c..c5547dbcb0 100644 --- a/Makefile.wiiu +++ b/Makefile.wiiu @@ -13,6 +13,20 @@ OBJ += wiiu/system/memory.o OBJ += wiiu/system/exception_handler.o OBJ += wiiu/fs/sd_fat_devoptab.o OBJ += wiiu/fs/fs_utils.o +OBJ += wiiu/controller_patcher/ControllerPatcher.o +OBJ += wiiu/controller_patcher/ControllerPatcherWrapper.o +OBJ += wiiu/controller_patcher/ConfigReader.o +OBJ += wiiu/controller_patcher/config/ConfigParser.o +OBJ += wiiu/controller_patcher/config/ConfigValues.o +OBJ += wiiu/controller_patcher/network/ControllerPatcherNet.o +OBJ += wiiu/controller_patcher/network/TCPServer.o +OBJ += wiiu/controller_patcher/network/UDPClient.o +OBJ += wiiu/controller_patcher/network/UDPServer.o +OBJ += wiiu/controller_patcher/patcher/ControllerPatcherUtils.o +OBJ += wiiu/controller_patcher/patcher/ControllerPatcherHID.o +OBJ += wiiu/controller_patcher/utils/CPRetainVars.o +OBJ += wiiu/controller_patcher/utils/CPStringTools.o +OBJ += wiiu/controller_patcher/utils/PadConst.o OBJ += wiiu/tex_shader.o OBJ += wiiu/hbl.o @@ -138,7 +152,7 @@ ifeq ($(WHOLE_ARCHIVE_LINK), 1) WHOLE_START := -Wl,--whole-archive WHOLE_END := -Wl,--no-whole-archive endif -CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions +CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -D_GNU_SOURCE LDFLAGS += -Wl,--gc-sections diff --git a/frontend/drivers/platform_wiiu.c b/frontend/drivers/platform_wiiu.c index 955a7f82d1..ce383019ab 100644 --- a/frontend/drivers/platform_wiiu.c +++ b/frontend/drivers/platform_wiiu.c @@ -54,6 +54,8 @@ #include #include +#include "wiiu/controller_patcher/ControllerPatcherWrapper.h" + #include #include @@ -405,6 +407,8 @@ int main(int argc, char **argv) #endif verbosity_enable(); + ControllerPatcherInit(); + printf("starting\n"); fflush(stdout); DEBUG_VAR(ARGV_PTR); @@ -458,6 +462,8 @@ int main(int argc, char **argv) } while (1); + ControllerPatcherDeInit(); + main_exit(NULL); #endif #endif diff --git a/input/drivers_joypad/wiiu_joypad.c b/input/drivers_joypad/wiiu_joypad.c index 2343d2514c..3c4414eb52 100644 --- a/input/drivers_joypad/wiiu_joypad.c +++ b/input/drivers_joypad/wiiu_joypad.c @@ -21,6 +21,8 @@ #include #include +#include "wiiu/controller_patcher/ControllerPatcherWrapper.h" + #include "../input_config.h" #include "../input_driver.h" #include "../input_joypad_driver.h" @@ -158,9 +160,9 @@ static void wiiu_joypad_poll(void) int c; VPADStatus vpad; VPADReadError vpadError; - VPADRead(0, &vpad, 1, &vpadError); - + setControllerDataFromHID(&vpad); + vpadError = VPAD_READ_SUCCESS; if (!vpadError) { pad_state[0] = vpad.hold & ~0x7F800000; /* clear out emulated analog sticks */ diff --git a/wiiu/controller_patcher b/wiiu/controller_patcher new file mode 160000 index 0000000000..9fb5404dd7 --- /dev/null +++ b/wiiu/controller_patcher @@ -0,0 +1 @@ +Subproject commit 9fb5404dd79feba855a730a9a2c33ca2d80989ad From 11a0610d13fb9ffd9a06f00730ca3fad15712aac Mon Sep 17 00:00:00 2001 From: Maschell Date: Mon, 8 May 2017 12:32:02 +0200 Subject: [PATCH 03/10] [Wii U] Updating to new controller patcher. Removing debug stuff. --- wiiu/controller_patcher | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wiiu/controller_patcher b/wiiu/controller_patcher index 9fb5404dd7..adfde9f3a9 160000 --- a/wiiu/controller_patcher +++ b/wiiu/controller_patcher @@ -1 +1 @@ -Subproject commit 9fb5404dd79feba855a730a9a2c33ca2d80989ad +Subproject commit adfde9f3a9c61a0191cdea0a9d5f510a45c9c321 From ad0953ac879cc5899fe98c66c840365bc053309f Mon Sep 17 00:00:00 2001 From: Maschell Date: Mon, 8 May 2017 12:35:03 +0200 Subject: [PATCH 04/10] [Wii U] Adding missing .gitmodules file --- .gitmodules | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..b1cfe5891f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "wiiu/controller_patcher"] + path = wiiu/controller_patcher + url = https://github.com/Maschell/controller_patcher + branch = retroarch From 4393e17ea73ea83938be2f76ec573530fcd67663 Mon Sep 17 00:00:00 2001 From: Maschell Date: Mon, 8 May 2017 21:46:34 +0200 Subject: [PATCH 05/10] [Wii U] Using the HID Controller as a own controller. Currently the stick only work when it's bind manually. Mapping from controller to retroarch input port may change when you attach a new device. --- frontend/drivers/platform_wiiu.c | 2 +- input/drivers_joypad/wiiu_joypad.c | 57 +++++++++++++++++++++++++----- input/input_autodetect_builtin.c | 1 + wiiu/controller_patcher | 2 +- 4 files changed, 52 insertions(+), 10 deletions(-) diff --git a/frontend/drivers/platform_wiiu.c b/frontend/drivers/platform_wiiu.c index ce383019ab..c7e2e06e98 100644 --- a/frontend/drivers/platform_wiiu.c +++ b/frontend/drivers/platform_wiiu.c @@ -407,9 +407,9 @@ int main(int argc, char **argv) #endif verbosity_enable(); + printf("starting\n"); ControllerPatcherInit(); - printf("starting\n"); fflush(stdout); DEBUG_VAR(ARGV_PTR); if(ARGV_PTR && ((u32)ARGV_PTR < 0x01000000)) diff --git a/input/drivers_joypad/wiiu_joypad.c b/input/drivers_joypad/wiiu_joypad.c index 3c4414eb52..790f09e114 100644 --- a/input/drivers_joypad/wiiu_joypad.c +++ b/input/drivers_joypad/wiiu_joypad.c @@ -35,7 +35,7 @@ #include "wiiu_dbg.h" #ifndef MAX_PADS -#define MAX_PADS 5 +#define MAX_PADS 16 #endif #define WIIUINPUT_TYPE_WIIMOTE 0x00 @@ -44,22 +44,31 @@ #define WIIUINPUT_TYPE_PRO_CONTROLLER 0x1F #define WIIUINPUT_TYPE_NONE 0xFD +#define GAMEPAD_COUNT 1 +#define KPAD_COUNT 4 +#define HID_COUNT (MAX_PADS - GAMEPAD_COUNT - KPAD_COUNT) +#define GAMEPAD_OFFSET 0 +#define KPAD_OFFSET (GAMEPAD_OFFSET + GAMEPAD_COUNT) +#define HID_OFFSET (KPAD_OFFSET + KPAD_COUNT) + static uint64_t pad_state[MAX_PADS]; -static u8 pad_type[MAX_PADS - 1] = {WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE}; +static u8 pad_type[KPAD_COUNT] = {WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE}; + +static u8 hid_status[HID_COUNT]; +static InputDataEx hid_data[HID_COUNT]; static int16_t analog_state[MAX_PADS][2][2]; extern uint64_t lifecycle_state; static bool wiiu_pad_inited = false; - - static const char* wiiu_joypad_name(unsigned pad) { if (pad == 0) return "WIIU Gamepad"; - if (pad < MAX_PADS) + if (pad < MAX_PADS && pad < (HID_OFFSET) && pad > GAMEPAD_OFFSET) { - switch (pad_type[pad - 1]) + int i = pad - KPAD_OFFSET; + switch (pad_type[i]) { case WIIUINPUT_TYPE_NONE: return "N/A"; @@ -78,6 +87,10 @@ static const char* wiiu_joypad_name(unsigned pad) } } + if(pad < MAX_PADS){ + return "HID Controller"; + } + return "unknown"; } @@ -91,7 +104,7 @@ static void wiiu_joypad_autodetect_add(unsigned autoconf_pad) 0, 0 )) - input_config_set_device_name(autoconf_pad, wiiu_joypad_name(autoconf_pad)); + input_config_set_device_name(autoconf_pad, wiiu_joypad_name(autoconf_pad)); } static bool wiiu_joypad_button(unsigned port_num, uint16_t key) @@ -161,7 +174,6 @@ static void wiiu_joypad_poll(void) VPADStatus vpad; VPADReadError vpadError; VPADRead(0, &vpad, 1, &vpadError); - setControllerDataFromHID(&vpad); vpadError = VPAD_READ_SUCCESS; if (!vpadError) { @@ -230,11 +242,40 @@ static void wiiu_joypad_poll(void) break; } } + + memset(hid_data,0,sizeof(hid_data)); + int result = gettingInputAllDevicesEx(hid_data,HID_COUNT); + + if(result+HID_OFFSET > MAX_PADS){ + result = MAX_PADS - HID_OFFSET; + } + for(int i = HID_OFFSET;i Date: Mon, 8 May 2017 21:49:24 +0200 Subject: [PATCH 06/10] [Wii U] Removed forcing Gamepad reading success --- input/drivers_joypad/wiiu_joypad.c | 1 - 1 file changed, 1 deletion(-) diff --git a/input/drivers_joypad/wiiu_joypad.c b/input/drivers_joypad/wiiu_joypad.c index 790f09e114..6acc2563b3 100644 --- a/input/drivers_joypad/wiiu_joypad.c +++ b/input/drivers_joypad/wiiu_joypad.c @@ -174,7 +174,6 @@ static void wiiu_joypad_poll(void) VPADStatus vpad; VPADReadError vpadError; VPADRead(0, &vpad, 1, &vpadError); - vpadError = VPAD_READ_SUCCESS; if (!vpadError) { pad_state[0] = vpad.hold & ~0x7F800000; /* clear out emulated analog sticks */ From fa0d82b18891ee75d669f0c97ac7a68989d481a0 Mon Sep 17 00:00:00 2001 From: Maschell Date: Sat, 20 May 2017 13:13:52 +0200 Subject: [PATCH 07/10] [Wii U] Fixing the .rpx build --- wiiu/controller_patcher | 2 +- wiiu/include/wiiu/syshid.h | 127 ++++++++++++++++++++++++++++--------- 2 files changed, 97 insertions(+), 32 deletions(-) diff --git a/wiiu/controller_patcher b/wiiu/controller_patcher index 48c554a9dd..cd06b1b44b 160000 --- a/wiiu/controller_patcher +++ b/wiiu/controller_patcher @@ -1 +1 @@ -Subproject commit 48c554a9dd2aa2e262ddd681fc50beb2be5c44b6 +Subproject commit cd06b1b44ba94b6ab5c277e9d2fdaae1e8b6da6a diff --git a/wiiu/include/wiiu/syshid.h b/wiiu/include/wiiu/syshid.h index 9514a7d817..e215975a27 100644 --- a/wiiu/include/wiiu/syshid.h +++ b/wiiu/include/wiiu/syshid.h @@ -1,32 +1,27 @@ #pragma once #include -#ifdef __cplusplus -extern "C" { -#endif - - typedef struct { - u32 handle; - u32 physical_device_inst; - u16 vid; - u16 pid; - u8 interface_index; - u8 sub_class; - u8 protocol; + uint32_t handle; + uint32_t physical_device_inst; + uint16_t vid; + uint16_t pid; + uint8_t interface_index; + uint8_t sub_class; + uint8_t protocol; - u16 max_packet_size_rx; - u16 max_packet_size_tx; + uint16_t max_packet_size_rx; + uint16_t max_packet_size_tx; } HIDDevice; +typedef struct _HIDClient HIDClient; + #define HID_DEVICE_DETACH 0 #define HID_DEVICE_ATTACH 1 -typedef struct _HIDClient HIDClient; - -typedef s32 (*HIDAttachCallback)(HIDClient *p_hc,HIDDevice *p_hd,u32 attach); +typedef int32_t (*HIDAttachCallback)(HIDClient *p_hc,HIDDevice *p_hd,uint32_t attach); struct _HIDClient { @@ -34,27 +29,97 @@ struct _HIDClient HIDAttachCallback attach_cb; }; -typedef void HIDCallback(u32 handle,s32 error,u8 *p_buffer,u32 bytes_transferred,void *p_user); +typedef void (*HIDCallback)(uint32_t handle,int32_t error,uint8_t *p_buffer,uint32_t bytes_transferred,void *p_user); -s32 HIDSetup(void); -s32 HIDTeardown(void); +#ifdef __cplusplus +extern "C" { +#endif -s32 HIDAddClient(HIDClient *p_client, HIDAttachCallback attach_callback); -s32 HIDDelClient(HIDClient *p_client); -s32 HIDGetDescriptor(u32 handle,u8 descriptor_type,u8 descriptor_index, u16 language_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); -s32 HIDSetDescriptor(u32 handle,u8 descriptor_type,u8 descriptor_index, u16 language_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); +int32_t +HIDSetup(void); -s32 HIDGetReport(u32 handle, u8 report_type, u8 report_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); -s32 HIDSetReport(u32 handle, u8 report_type, u8 report_id, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); +int32_t +HIDTeardown(void); -s32 HIDSetIdle(u32 handle, u8 interface_index,u8 duration, HIDCallback hc, void *p_user); +int32_t +HIDAddClient(HIDClient *p_client, + HIDAttachCallback attach_callback); +int32_t +HIDDelClient(HIDClient *p_client); -s32 HIDSetProtocol(u32 handle,u8 interface_index,u8 protocol, HIDCallback hc, void *p_user); -s32 HIDGetProtocol(u32 handle,u8 interface_index,u8 * protocol, HIDCallback hc, void *p_user); +int32_t +HIDGetDescriptor(uint32_t handle, + uint8_t descriptor_type, + uint8_t descriptor_index, + uint16_t language_id, + uint8_t *p_buffer, + uint32_t buffer_length, + HIDCallback hc, + void *p_user); + +int32_t +HIDSetDescriptor(uint32_t handle, + uint8_t descriptor_type, + uint8_t descriptor_index, + uint16_t language_id, + uint8_t *p_buffer, + uint32_t buffer_length, + HIDCallback hc, + void *p_user); -s32 HIDRead(u32 handle, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); -s32 HIDWrite(u32 handle, u8 *p_buffer, u32 buffer_length, HIDCallback hc, void *p_user); +int32_t +HIDGetReport(uint32_t handle, + uint8_t report_type, + uint8_t report_id, + uint8_t *p_buffer, + uint32_t buffer_length, + HIDCallback hc, + void *p_user); + +int32_t +HIDSetReport(uint32_t handle, + uint8_t report_type, + uint8_t report_id, + uint8_t *p_buffer, + uint32_t buffer_length, + HIDCallback hc, + void *p_user); + +int32_t +HIDSetIdle(uint32_t handle, + uint8_t interface_index, + uint8_t duration, + HIDCallback hc, + void *p_user); + +int32_t +HIDSetProtocol(uint32_t handle, + uint8_t int32_terface_index, + uint8_t protocol, + HIDCallback hc, + void *p_user); + +int32_t +HIDGetProtocol(uint32_t handle, + uint8_t interface_index, + uint8_t * protocol, + HIDCallback hc, + void *p_user); + +int32_t +HIDRead(uint32_t handle, + uint8_t *p_buffer, + uint32_t buffer_length, + HIDCallback hc, + void *p_user); + +int32_t +HIDWrite(uint32_t handle, + uint8_t *p_buffer, + uint32_t buffer_length, + HIDCallback hc, + void *p_user); #ifdef __cplusplus } From b34abd4c1783b39d50f5c9827714a1572458e09c Mon Sep 17 00:00:00 2001 From: Maschell Date: Sat, 20 May 2017 19:25:33 +0200 Subject: [PATCH 08/10] [Wii U] Added a missing target to the makefile --- Makefile.wiiu | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile.wiiu b/Makefile.wiiu index c5547dbcb0..2c835fbac8 100644 --- a/Makefile.wiiu +++ b/Makefile.wiiu @@ -1,12 +1,12 @@ TARGET := retroarch_wiiu BUILD_HBL_ELF = 1 -BUILD_RPX = 1 +BUILD_RPX = 1 DEBUG = 0 GRIFFIN_BUILD = 0 WHOLE_ARCHIVE_LINK = 0 -PC_DEVELOPMENT_IP_ADDRESS = -PC_DEVELOPMENT_TCP_PORT = +PC_DEVELOPMENT_IP_ADDRESS = +PC_DEVELOPMENT_TCP_PORT = OBJ := OBJ += wiiu/system/memory.o @@ -27,6 +27,7 @@ OBJ += wiiu/controller_patcher/patcher/ControllerPatcherHID.o OBJ += wiiu/controller_patcher/utils/CPRetainVars.o OBJ += wiiu/controller_patcher/utils/CPStringTools.o OBJ += wiiu/controller_patcher/utils/PadConst.o +OBJ += wiiu/controller_patcher/utils/FSHelper.o OBJ += wiiu/tex_shader.o OBJ += wiiu/hbl.o From 7a2c09e9ce2351cd1547a0c75f35d7c1b1f5664f Mon Sep 17 00:00:00 2001 From: Maschell Date: Sat, 20 May 2017 19:26:12 +0200 Subject: [PATCH 09/10] [Wii U ] Proper order of the HID devices. Added individual names for the HID devices. --- frontend/drivers/platform_wiiu.c | 2 -- input/drivers_joypad/wiiu_joypad.c | 10 +++++++--- wiiu/controller_patcher | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/frontend/drivers/platform_wiiu.c b/frontend/drivers/platform_wiiu.c index 5bfcbb6367..6623d5d4bd 100644 --- a/frontend/drivers/platform_wiiu.c +++ b/frontend/drivers/platform_wiiu.c @@ -58,7 +58,6 @@ #include #include - #include "wiiu_dbg.h" #include "hbl.h" @@ -407,7 +406,6 @@ int main(int argc, char **argv) #endif verbosity_enable(); - printf("starting\n"); ControllerPatcherInit(); fflush(stdout); diff --git a/input/drivers_joypad/wiiu_joypad.c b/input/drivers_joypad/wiiu_joypad.c index 6acc2563b3..b9eaae3416 100644 --- a/input/drivers_joypad/wiiu_joypad.c +++ b/input/drivers_joypad/wiiu_joypad.c @@ -55,11 +55,13 @@ static uint64_t pad_state[MAX_PADS]; static u8 pad_type[KPAD_COUNT] = {WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE}; static u8 hid_status[HID_COUNT]; -static InputDataEx hid_data[HID_COUNT]; +static InputData hid_data[HID_COUNT]; static int16_t analog_state[MAX_PADS][2][2]; extern uint64_t lifecycle_state; static bool wiiu_pad_inited = false; +static char hidName[HID_COUNT][255]; + static const char* wiiu_joypad_name(unsigned pad) { if (pad == 0) @@ -88,7 +90,9 @@ static const char* wiiu_joypad_name(unsigned pad) } if(pad < MAX_PADS){ - return "HID Controller"; + s32 hid_index = pad-HID_OFFSET; + sprintf(hidName[hid_index],"HID %04X/%04X",hid_data[hid_index].device_info.vidpid.vid,hid_data[hid_index].device_info.vidpid.pid); + return hidName[hid_index]; } return "unknown"; @@ -243,7 +247,7 @@ static void wiiu_joypad_poll(void) } memset(hid_data,0,sizeof(hid_data)); - int result = gettingInputAllDevicesEx(hid_data,HID_COUNT); + int result = gettingInputAllDevices(hid_data,HID_COUNT); if(result+HID_OFFSET > MAX_PADS){ result = MAX_PADS - HID_OFFSET; diff --git a/wiiu/controller_patcher b/wiiu/controller_patcher index cd06b1b44b..0d419a0064 160000 --- a/wiiu/controller_patcher +++ b/wiiu/controller_patcher @@ -1 +1 @@ -Subproject commit cd06b1b44ba94b6ab5c277e9d2fdaae1e8b6da6a +Subproject commit 0d419a0064bf95feec139e6484a00af20df08967 From bd8d3d66d7277b3deca4cacc9309906256eed34a Mon Sep 17 00:00:00 2001 From: Maschell Date: Sat, 20 May 2017 20:23:01 +0200 Subject: [PATCH 10/10] [Wii U] Using the controller_patcher lib files directly instead of including it as a submodule --- wiiu/controller_patcher | 1 - wiiu/controller_patcher/ConfigReader.cpp | 158 +++ wiiu/controller_patcher/ConfigReader.hpp | 74 ++ wiiu/controller_patcher/ControllerPatcher.cpp | 1086 +++++++++++++++++ wiiu/controller_patcher/ControllerPatcher.hpp | 251 ++++ .../ControllerPatcherWrapper.cpp | 39 + .../ControllerPatcherWrapper.h | 23 + .../config/ConfigParser.cpp | 337 +++++ .../config/ConfigParser.hpp | 74 ++ .../config/ConfigValues.cpp | 121 ++ .../config/ConfigValues.hpp | 569 +++++++++ .../network/ControllerPatcherNet.cpp | 50 + .../network/ControllerPatcherNet.hpp | 17 + wiiu/controller_patcher/network/TCPServer.cpp | 371 ++++++ wiiu/controller_patcher/network/TCPServer.hpp | 93 ++ wiiu/controller_patcher/network/UDPClient.cpp | 58 + wiiu/controller_patcher/network/UDPClient.hpp | 66 + wiiu/controller_patcher/network/UDPServer.cpp | 168 +++ wiiu/controller_patcher/network/UDPServer.hpp | 57 + .../patcher/ControllerPatcherDefs.h | 703 +++++++++++ .../patcher/ControllerPatcherHID.cpp | 707 +++++++++++ .../patcher/ControllerPatcherHID.hpp | 74 ++ .../patcher/ControllerPatcherUtils.cpp | 935 ++++++++++++++ .../patcher/ControllerPatcherUtils.hpp | 320 +++++ .../controller_patcher/utils/CPRetainVars.cpp | 73 ++ .../controller_patcher/utils/CPRetainVars.hpp | 76 ++ .../utils/CPStringTools.cpp | 85 ++ .../utils/CPStringTools.hpp | 17 + .../utils/ControllerPatcherThread.hpp | 119 ++ wiiu/controller_patcher/utils/FSHelper.c | 78 ++ wiiu/controller_patcher/utils/FSHelper.h | 17 + wiiu/controller_patcher/utils/PadConst.cpp | 341 ++++++ wiiu/controller_patcher/utils/PadConst.hpp | 211 ++++ 33 files changed, 7368 insertions(+), 1 deletion(-) delete mode 160000 wiiu/controller_patcher create mode 100644 wiiu/controller_patcher/ConfigReader.cpp create mode 100644 wiiu/controller_patcher/ConfigReader.hpp create mode 100644 wiiu/controller_patcher/ControllerPatcher.cpp create mode 100644 wiiu/controller_patcher/ControllerPatcher.hpp create mode 100644 wiiu/controller_patcher/ControllerPatcherWrapper.cpp create mode 100644 wiiu/controller_patcher/ControllerPatcherWrapper.h create mode 100644 wiiu/controller_patcher/config/ConfigParser.cpp create mode 100644 wiiu/controller_patcher/config/ConfigParser.hpp create mode 100644 wiiu/controller_patcher/config/ConfigValues.cpp create mode 100644 wiiu/controller_patcher/config/ConfigValues.hpp create mode 100644 wiiu/controller_patcher/network/ControllerPatcherNet.cpp create mode 100644 wiiu/controller_patcher/network/ControllerPatcherNet.hpp create mode 100644 wiiu/controller_patcher/network/TCPServer.cpp create mode 100644 wiiu/controller_patcher/network/TCPServer.hpp create mode 100644 wiiu/controller_patcher/network/UDPClient.cpp create mode 100644 wiiu/controller_patcher/network/UDPClient.hpp create mode 100644 wiiu/controller_patcher/network/UDPServer.cpp create mode 100644 wiiu/controller_patcher/network/UDPServer.hpp create mode 100644 wiiu/controller_patcher/patcher/ControllerPatcherDefs.h create mode 100644 wiiu/controller_patcher/patcher/ControllerPatcherHID.cpp create mode 100644 wiiu/controller_patcher/patcher/ControllerPatcherHID.hpp create mode 100644 wiiu/controller_patcher/patcher/ControllerPatcherUtils.cpp create mode 100644 wiiu/controller_patcher/patcher/ControllerPatcherUtils.hpp create mode 100644 wiiu/controller_patcher/utils/CPRetainVars.cpp create mode 100644 wiiu/controller_patcher/utils/CPRetainVars.hpp create mode 100644 wiiu/controller_patcher/utils/CPStringTools.cpp create mode 100644 wiiu/controller_patcher/utils/CPStringTools.hpp create mode 100644 wiiu/controller_patcher/utils/ControllerPatcherThread.hpp create mode 100644 wiiu/controller_patcher/utils/FSHelper.c create mode 100644 wiiu/controller_patcher/utils/FSHelper.h create mode 100644 wiiu/controller_patcher/utils/PadConst.cpp create mode 100644 wiiu/controller_patcher/utils/PadConst.hpp diff --git a/wiiu/controller_patcher b/wiiu/controller_patcher deleted file mode 160000 index 0d419a0064..0000000000 --- a/wiiu/controller_patcher +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 0d419a0064bf95feec139e6484a00af20df08967 diff --git a/wiiu/controller_patcher/ConfigReader.cpp b/wiiu/controller_patcher/ConfigReader.cpp new file mode 100644 index 0000000000..bc51064f5b --- /dev/null +++ b/wiiu/controller_patcher/ConfigReader.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#include "./ConfigReader.hpp" + +#include +#include +#include +#include + +#include "wiiu/fs.h" +#include "wiiu/controller_patcher/utils/FSHelper.h" + +#define FS_MOUNT_SOURCE_SIZE 0x300 +#define FS_MAX_MOUNTPATH_SIZE 12 + +#define FS_CLIENT_SIZE 0x1700 +#define FS_CMD_BLOCK_SIZE 0xA80 + +#define FS_SOURCETYPE_EXTERNAL 0 +#define FS_SOURCETYPE_HFIO 1 + +s32 ConfigReader::numberValidFiles = 0; +ConfigReader *ConfigReader::instance = NULL; + +ConfigReader::ConfigReader(){ +} + +void ConfigReader::ReadAllConfigs(){ + std::vector fileList = ScanFolder(); + if(fileList.size() > 0){ + if(HID_DEBUG){ printf("ConfigReader::ConfigReader(line %d): Found %d config files\n",__LINE__,fileList.size()); } + processFileList(fileList); + } +} + + +ConfigReader::~ConfigReader(){ + if(HID_DEBUG){ printf("ConfigReader::~ConfigReader(line %d): ~ConfigReader\n",__LINE__); } + freeFSHandles(); +} + +void ConfigReader::freeFSHandles(){ + if(this->pClient != NULL){ + FSDelClient((FSClient *)this->pClient,-1); + free(this->pClient); + this->pClient = NULL; + } + if(this->pCmd != NULL){ + free(this->pCmd); + this->pCmd = NULL; + } +} + + +// Mounting the sdcard without any external lib to be portable (Currently broken) +s32 ConfigReader::InitSDCard(){ + if(HID_DEBUG){ printf("ConfigReader::InitSDCard(line %d): InitSDCard\n",__LINE__); } + + int result = -1; + + // get command and client + this->pClient = malloc(sizeof(FSClient)); + this->pCmd = malloc(sizeof(FSCmdBlock)); + + if(!pClient || !pCmd) { + // just in case free if not 0 + if(pClient) + free(pClient); + if(pCmd) + free(pCmd); + return -2; + } + + FSInit(); + FSInitCmdBlock((FSCmdBlock*)pCmd); + FSAddClient((FSClient*)pClient, -1); + + char *mountPath = NULL; + + if((result = FS_Helper_MountFS(pClient, pCmd, &mountPath)) == 0) { + //free(mountPath); + } + + return result; +} + +std::vector ConfigReader::ScanFolder(){ + std::string path = CONTROLLER_PATCHER_PATH; + s32 dirhandle = 0; + if(HID_DEBUG){ printf("ConfigReader::ScanFolder(line %d): Opening %s\n",__LINE__,path.c_str()); } + std::vector config_files; + if (this->pClient && this->pCmd){ + s32 status = 0; + if((status = FSOpenDir((FSClient*)this->pClient,(FSCmdBlock*)this->pCmd,path.c_str(),(FSDirectoryHandle *)&dirhandle,-1)) == FS_STATUS_OK){ + FSDirectoryEntry dir_entry; + while (FSReadDir((FSClient*)this->pClient,(FSCmdBlock*)this->pCmd, dirhandle, &dir_entry, -1) == FS_STATUS_OK){ + std::string full_path = path + "/" + dir_entry.name; + if((dir_entry.info.flags&FS_STAT_DIRECTORY) != FS_STAT_DIRECTORY){ + if(CPStringTools::EndsWith(std::string(dir_entry.name),".ini")){ + config_files.push_back(full_path); + if(HID_DEBUG){ printf("ConfigReader::ScanFolder(line %d): %s \n",__LINE__,full_path.c_str()); } + } + } + } + FSCloseDir((FSClient*)this->pClient,(FSCmdBlock*)this->pCmd,dirhandle,-1); + }else{ + printf("ConfigReader::ScanFolder(line %d): Failed to open %s!\n",__LINE__,path.c_str()); + } + } + return config_files; +} + +void ConfigReader::processFileList(std::vector path){ + + for(std::vector::iterator it = path.begin(); it != path.end(); ++it) { + printf("ConfigReader::processFileList(line %d): Reading %s\n",__LINE__,it->c_str()); + std::string result = loadFileToString(*it); + + ConfigParser parser(result); + parser.parseIni(); + } +} + +std::string ConfigReader::loadFileToString(std::string path){ + FSFileHandle handle = 0; + s32 status = 0; + std::string strBuffer; + char * result = NULL; + if(FS_Helper_GetFile(this->pClient,this->pCmd,path.c_str(), &result) == 0){ + if(result != NULL){ + strBuffer = std::string((char *)result); + free(result); + result = NULL; + + //! remove all windows crap signs + strBuffer = CPStringTools::removeCharFromString(strBuffer,'\r'); + strBuffer = CPStringTools::removeCharFromString(strBuffer,' '); + strBuffer = CPStringTools::removeCharFromString(strBuffer,'\t'); + } + }else{ + printf("ConfigReader::loadFileToString(line %d): Failed to load %s\n",__LINE__,path.c_str()); + } + return strBuffer; +} diff --git a/wiiu/controller_patcher/ConfigReader.hpp b/wiiu/controller_patcher/ConfigReader.hpp new file mode 100644 index 0000000000..7a6906ce64 --- /dev/null +++ b/wiiu/controller_patcher/ConfigReader.hpp @@ -0,0 +1,74 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#ifndef _ConfigReader_H_ +#define _ConfigReader_H_ + +#include + +#include +#include + +#include "./ControllerPatcher.hpp" + +#define CONTROLLER_PATCHER_PATH "/vol/external01/wiiu/controller"; + +class ConfigReader{ + friend class ControllerPatcher; + friend class ConfigParser; + private: + static ConfigReader *getInstance() { + if(!instance){ + instance = new ConfigReader(); + } + return instance; + } + + static void destroyInstance() { + if(instance){ + delete instance; + instance = NULL; + } + } + + static s32 getNumberOfLoadedFiles(){ + return ConfigReader::numberValidFiles; + } + + static void increaseNumberOfLoadedFiles(){ + ConfigReader::numberValidFiles++; + } + void ReadAllConfigs(); + static s32 numberValidFiles; + + //!Constructor + ConfigReader(); + //!Destructor + ~ConfigReader(); + + s32 InitSDCard(); + void freeFSHandles(); + + void * pClient = NULL; + void * pCmd = NULL; + static ConfigReader *instance; + + std::string loadFileToString(std::string path); + void processFileList(std::vector path); + + std::vector ScanFolder(); +}; +#endif diff --git a/wiiu/controller_patcher/ControllerPatcher.cpp b/wiiu/controller_patcher/ControllerPatcher.cpp new file mode 100644 index 0000000000..7f5fb341ab --- /dev/null +++ b/wiiu/controller_patcher/ControllerPatcher.cpp @@ -0,0 +1,1086 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#include "ControllerPatcher.hpp" +#include +#include + +#include +#include +#include + +#include "wiiu/sysapp.h" +#include "wiiu/syshid.h" +#include "sys/socket.h" +#include "wiiu/kpad.h" + +#include "utils/CPRetainVars.hpp" + +// This stores the holded buttons for the gamepad after the button remapping. +static u32 buttonRemapping_lastButtonsHold = 0; + +/* To set the controls of an Pro Controler, we first get the result for an Gamepad and convert them later. This way both can share the same functions.*/ + +// This arrays stores the last hold buttons of the Pro Controllers. One u32 for each channel of the controllers +static u32 last_button_hold[4] = {0,0,0,0}; +// This arrays stores the VPADStatus that will be used to get the HID Data for the Pro Controllers. One for each channel. +static VPADStatus myVPADBuffer[4]; + +void ControllerPatcher::InitButtonMapping(){ + if(HID_DEBUG){ printf("ControllerPatcher::InitButtonMapping(line %d): Init called \n",__LINE__); } + if(!gButtonRemappingConfigDone){ + if(HID_DEBUG){ printf("ControllerPatcher::InitButtonMapping(line %d): Remapping is running! \n",__LINE__); } + gButtonRemappingConfigDone = 1; + memset(gGamePadValues,0,sizeof(gGamePadValues)); // Init / Invalid everything + + gGamePadValues[CONTRPS_VPAD_BUTTON_A] = VPAD_BUTTON_A; + gGamePadValues[CONTRPS_VPAD_BUTTON_B] = VPAD_BUTTON_B; + gGamePadValues[CONTRPS_VPAD_BUTTON_X] = VPAD_BUTTON_X; + gGamePadValues[CONTRPS_VPAD_BUTTON_Y] = VPAD_BUTTON_Y; + gGamePadValues[CONTRPS_VPAD_BUTTON_LEFT] = VPAD_BUTTON_LEFT; + gGamePadValues[CONTRPS_VPAD_BUTTON_RIGHT] = VPAD_BUTTON_RIGHT; + gGamePadValues[CONTRPS_VPAD_BUTTON_UP] = VPAD_BUTTON_UP; + gGamePadValues[CONTRPS_VPAD_BUTTON_DOWN] = VPAD_BUTTON_DOWN; + gGamePadValues[CONTRPS_VPAD_BUTTON_ZL] = VPAD_BUTTON_ZL; + gGamePadValues[CONTRPS_VPAD_BUTTON_ZR] = VPAD_BUTTON_ZR; + gGamePadValues[CONTRPS_VPAD_BUTTON_L] = VPAD_BUTTON_L; + gGamePadValues[CONTRPS_VPAD_BUTTON_R] = VPAD_BUTTON_R; + gGamePadValues[CONTRPS_VPAD_BUTTON_PLUS] = VPAD_BUTTON_PLUS; + gGamePadValues[CONTRPS_VPAD_BUTTON_MINUS] = VPAD_BUTTON_MINUS; + gGamePadValues[CONTRPS_VPAD_BUTTON_HOME] = VPAD_BUTTON_HOME; + gGamePadValues[CONTRPS_VPAD_BUTTON_SYNC] = VPAD_BUTTON_SYNC; + gGamePadValues[CONTRPS_VPAD_BUTTON_STICK_R] = VPAD_BUTTON_STICK_R; + gGamePadValues[CONTRPS_VPAD_BUTTON_STICK_L] = VPAD_BUTTON_STICK_L; + gGamePadValues[CONTRPS_VPAD_BUTTON_TV] = VPAD_BUTTON_TV; + + gGamePadValues[CONTRPS_VPAD_STICK_R_EMULATION_LEFT] = VPAD_STICK_R_EMULATION_LEFT; + gGamePadValues[CONTRPS_VPAD_STICK_R_EMULATION_RIGHT] = VPAD_STICK_R_EMULATION_RIGHT; + gGamePadValues[CONTRPS_VPAD_STICK_R_EMULATION_UP] = VPAD_STICK_R_EMULATION_UP; + gGamePadValues[CONTRPS_VPAD_STICK_R_EMULATION_DOWN] = VPAD_STICK_R_EMULATION_DOWN; + gGamePadValues[CONTRPS_VPAD_STICK_L_EMULATION_LEFT] = VPAD_STICK_L_EMULATION_LEFT; + gGamePadValues[CONTRPS_VPAD_STICK_L_EMULATION_RIGHT] = VPAD_STICK_L_EMULATION_RIGHT; + gGamePadValues[CONTRPS_VPAD_STICK_L_EMULATION_UP] = VPAD_STICK_L_EMULATION_UP; + gGamePadValues[CONTRPS_VPAD_STICK_L_EMULATION_DOWN] = VPAD_STICK_L_EMULATION_DOWN; + } +} + +void ControllerPatcher::ResetConfig(){ + memset(connectionOrderHelper,0,sizeof(connectionOrderHelper)); + memset(&gControllerMapping,0,sizeof(gControllerMapping)); // Init / Invalid everything + memset(config_controller,CONTROLLER_PATCHER_INVALIDVALUE,sizeof(config_controller)); // Init / Invalid everything + memset(config_controller_hidmask,0,sizeof(config_controller_hidmask)); // Init / Invalid everything + memset(gNetworkController,0,sizeof(gNetworkController)); // Init / Invalid everything + memset(gHID_Devices,0,sizeof(gHID_Devices)); // Init / Invalid everything + + memset(gWPADConnectCallback,0,sizeof(gWPADConnectCallback)); + memset(gKPADConnectCallback,0,sizeof(gKPADConnectCallback)); + memset(gExtensionCallback,0,sizeof(gExtensionCallback)); + gCallbackCooldown = 0; + + gHID_Mouse_Mode = HID_MOUSE_MODE_AIM; + gHID_LIST_GC = 0; + gHID_LIST_DS3 = 0; + gHID_LIST_DS4 = 0; + gHID_LIST_KEYBOARD = 0; + gHID_LIST_MOUSE = 0; + gGamePadSlot = 0; + gHID_SLOT_GC = 0; + gHID_SLOT_KEYBOARD = 0; + gMouseSlot = 0; + + HIDSlotData slotdata; + gHIDRegisteredDevices = 0; + ControllerPatcherUtils::getNextSlotData(&slotdata); + gGamePadSlot = slotdata.deviceslot; + if(HID_DEBUG){ printf("ControllerPatcher::ResetConfig(line %d): Register Gamepad-Config. HID-Mask %s Device-Slot: %d\n",__LINE__,CPStringTools::byte_to_binary(slotdata.hidmask),gGamePadSlot); } + + ControllerPatcherUtils::getNextSlotData(&slotdata); + gMouseSlot = slotdata.deviceslot; + gHID_LIST_MOUSE = slotdata.hidmask; + if(HID_DEBUG){ printf("ControllerPatcher::ResetConfig(line %d): Register Mouse-Config. HID-Mask %s Device-Slot: %d\n",__LINE__,CPStringTools::byte_to_binary(gHID_LIST_MOUSE),gMouseSlot); } + + ControllerPatcherUtils::getNextSlotData(&slotdata); + u32 keyboard_slot = slotdata.deviceslot; + u32 keyboard_hid = slotdata.hidmask; + gHID_LIST_KEYBOARD = keyboard_hid; + gHID_SLOT_KEYBOARD = keyboard_slot; + + if(HID_DEBUG){ printf("ControllerPatcher::ResetConfig(line %d): Register Keyboard-Config. HID-Mask %s Device-Slot: %d\n",__LINE__,CPStringTools::byte_to_binary(gHID_LIST_KEYBOARD),gHID_SLOT_KEYBOARD); } + + ControllerPatcherUtils::getNextSlotData(&slotdata); + u32 gc_slot = slotdata.deviceslot; + u32 gc_hid = slotdata.hidmask; + gHID_LIST_GC = gc_hid; + gHID_SLOT_GC = gc_slot; + if(HID_DEBUG){ printf("ControllerPatcher::ResetConfig(line %d): Register GC-Adapter-Config. HID-Mask %s Device-Slot: %d\n",__LINE__,CPStringTools::byte_to_binary(gHID_LIST_GC),gHID_SLOT_GC); } + + ControllerPatcherUtils::getNextSlotData(&slotdata); + u32 ds3_slot = slotdata.deviceslot; + u32 ds3_hid = slotdata.hidmask; + gHID_LIST_DS3 = ds3_hid; + if(HID_DEBUG){ printf("ControllerPatcher::ResetConfig(line %d): Register DS3-Config. HID-Mask %s Device-Slot: %d\n",__LINE__,CPStringTools::byte_to_binary(gHID_LIST_DS3),ds3_slot); } + + ControllerPatcherUtils::getNextSlotData(&slotdata); + u32 ds4_slot = slotdata.deviceslot; + u32 ds4_hid = slotdata.hidmask; + gHID_LIST_DS4 = ds4_hid; + if(HID_DEBUG){ printf("ControllerPatcher::ResetConfig(line %d): Register DS4-Config. HID-Mask %s Device-Slot: %d\n",__LINE__,CPStringTools::byte_to_binary(ds4_hid),ds4_slot); } + + ControllerPatcherUtils::getNextSlotData(&slotdata); + u32 xinput_slot = slotdata.deviceslot; + u32 xinput_hid = slotdata.hidmask; + if(HID_DEBUG){ printf("ControllerPatcher::ResetConfig(line %d): Register XInput-Config. HID-Mask %s Device-Slot: %d\n",__LINE__,CPStringTools::byte_to_binary(xinput_hid),xinput_slot); } + + ControllerPatcherUtils::getNextSlotData(&slotdata); + u32 switch_pro_slot = slotdata.deviceslot; + gHID_LIST_SWITCH_PRO = slotdata.hidmask; + if(HID_DEBUG){ printf("ControllerPatcher::ResetConfig(line %d): Register Switch-Pro-Config. HID-Mask %s Device-Slot: %d\n",__LINE__,CPStringTools::byte_to_binary(gHID_LIST_SWITCH_PRO),switch_pro_slot); } + + + config_controller_hidmask[gc_slot] = gHID_LIST_GC; + config_controller_hidmask[ds3_slot] = gHID_LIST_DS3; + config_controller_hidmask[keyboard_slot] = gHID_LIST_KEYBOARD; + config_controller_hidmask[gMouseSlot] = gHID_LIST_MOUSE; + config_controller_hidmask[ds4_slot] = gHID_LIST_DS4; + config_controller_hidmask[xinput_slot] = xinput_hid; + config_controller_hidmask[switch_pro_slot] = gHID_LIST_SWITCH_PRO; + + /* We need to give the GamePad, Mouse and Keyboard a unique VID/PID to find the right slots.*/ + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! GamePad + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gGamePadSlot][CONTRPS_VID], 0xAF,0xFE); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gGamePadSlot][CONTRPS_PID], 0xAA,0xAA); + + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! Switch Pro Controller + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VID], (HID_SWITCH_PRO_VID>>8)&0xFF, HID_SWITCH_PRO_VID&0xFF); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_PID], (HID_SWITCH_PRO_PID>>8)&0xFF, HID_SWITCH_PRO_PID&0xFF); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_A], HID_SWITCH_PRO_BT_BUTTON_A[0], HID_SWITCH_PRO_BT_BUTTON_A[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_B], HID_SWITCH_PRO_BT_BUTTON_B[0], HID_SWITCH_PRO_BT_BUTTON_B[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_X], HID_SWITCH_PRO_BT_BUTTON_X[0], HID_SWITCH_PRO_BT_BUTTON_X[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_Y], HID_SWITCH_PRO_BT_BUTTON_Y[0], HID_SWITCH_PRO_BT_BUTTON_Y[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_DPAD_MODE], CONTROLLER_PATCHER_VALUE_SET, HID_SWITCH_PRO_BT_BUTTON_DPAD_TYPE[CONTRDPAD_MODE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_DPAD_MASK], CONTROLLER_PATCHER_VALUE_SET, HID_SWITCH_PRO_BT_BUTTON_DPAD_TYPE[CONTRDPAD_MASK]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_DPAD_N], HID_SWITCH_PRO_BT_BUTTON_DPAD_N[0], HID_SWITCH_PRO_BT_BUTTON_DPAD_N[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_DPAD_NE], HID_SWITCH_PRO_BT_BUTTON_DPAD_NE[0], HID_SWITCH_PRO_BT_BUTTON_DPAD_NE[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_DPAD_E], HID_SWITCH_PRO_BT_BUTTON_DPAD_E[0], HID_SWITCH_PRO_BT_BUTTON_DPAD_E[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_DPAD_SE], HID_SWITCH_PRO_BT_BUTTON_DPAD_SE[0], HID_SWITCH_PRO_BT_BUTTON_DPAD_SE[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_DPAD_S], HID_SWITCH_PRO_BT_BUTTON_DPAD_S[0], HID_SWITCH_PRO_BT_BUTTON_DPAD_S[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_DPAD_SW], HID_SWITCH_PRO_BT_BUTTON_DPAD_SW[0], HID_SWITCH_PRO_BT_BUTTON_DPAD_SW[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_DPAD_W], HID_SWITCH_PRO_BT_BUTTON_DPAD_W[0], HID_SWITCH_PRO_BT_BUTTON_DPAD_W[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_DPAD_NW], HID_SWITCH_PRO_BT_BUTTON_DPAD_NW[0], HID_SWITCH_PRO_BT_BUTTON_DPAD_NW[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_DPAD_NEUTRAL], HID_SWITCH_PRO_BT_BUTTON_DPAD_NEUTRAL[0], HID_SWITCH_PRO_BT_BUTTON_DPAD_NEUTRAL[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_PLUS], HID_SWITCH_PRO_BT_BUTTON_PLUS[0], HID_SWITCH_PRO_BT_BUTTON_PLUS[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_MINUS], HID_SWITCH_PRO_BT_BUTTON_MINUS[0], HID_SWITCH_PRO_BT_BUTTON_MINUS[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_L], HID_SWITCH_PRO_BT_BUTTON_L[0], HID_SWITCH_PRO_BT_BUTTON_L[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_R], HID_SWITCH_PRO_BT_BUTTON_R[0], HID_SWITCH_PRO_BT_BUTTON_R[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_ZL], HID_SWITCH_PRO_BT_BUTTON_ZL[0], HID_SWITCH_PRO_BT_BUTTON_ZL[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_ZR], HID_SWITCH_PRO_BT_BUTTON_ZR[0], HID_SWITCH_PRO_BT_BUTTON_ZR[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_STICK_L], HID_SWITCH_PRO_BT_BUTTON_STICK_L[0], HID_SWITCH_PRO_BT_BUTTON_STICK_L[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_STICK_R], HID_SWITCH_PRO_BT_BUTTON_STICK_R[0], HID_SWITCH_PRO_BT_BUTTON_STICK_R[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_HOME], HID_SWITCH_PRO_BT_BUTTON_HOME[0], HID_SWITCH_PRO_BT_BUTTON_HOME[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_PAD_COUNT], CONTROLLER_PATCHER_VALUE_SET, HID_SWITCH_PRO_BT_PAD_COUNT); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_L_STICK_X], HID_SWITCH_PRO_BT_STICK_L_X[STICK_CONF_BYTE], HID_SWITCH_PRO_BT_STICK_L_X[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_SWITCH_PRO_BT_STICK_L_X[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX], HID_SWITCH_PRO_BT_STICK_L_X[STICK_CONF_MIN], HID_SWITCH_PRO_BT_STICK_L_X[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_SWITCH_PRO_BT_STICK_L_X[STICK_CONF_INVERT]); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y], HID_SWITCH_PRO_BT_STICK_L_Y[STICK_CONF_BYTE], HID_SWITCH_PRO_BT_STICK_L_Y[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_SWITCH_PRO_BT_STICK_L_Y[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX], HID_SWITCH_PRO_BT_STICK_L_Y[STICK_CONF_MIN], HID_SWITCH_PRO_BT_STICK_L_Y[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_SWITCH_PRO_BT_STICK_L_Y[STICK_CONF_INVERT]); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_R_STICK_X], HID_SWITCH_PRO_BT_STICK_R_X[STICK_CONF_BYTE], HID_SWITCH_PRO_BT_STICK_R_X[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_SWITCH_PRO_BT_STICK_R_X[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX], HID_SWITCH_PRO_BT_STICK_R_X[STICK_CONF_MIN], HID_SWITCH_PRO_BT_STICK_R_X[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_SWITCH_PRO_BT_STICK_R_X[STICK_CONF_INVERT]); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y], HID_SWITCH_PRO_BT_STICK_R_Y[STICK_CONF_BYTE], HID_SWITCH_PRO_BT_STICK_R_Y[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_SWITCH_PRO_BT_STICK_R_Y[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX], HID_SWITCH_PRO_BT_STICK_R_Y[STICK_CONF_MIN], HID_SWITCH_PRO_BT_STICK_R_Y[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[switch_pro_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_SWITCH_PRO_BT_STICK_R_Y[STICK_CONF_INVERT]); + + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! Mouse + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gMouseSlot][CONTRPS_VID], (HID_MOUSE_VID>>8)&0xFF, HID_MOUSE_VID&0xFF); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gMouseSlot][CONTRPS_PID], (HID_MOUSE_PID>>8)&0xFF, HID_MOUSE_PID&0xFF); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gMouseSlot][CONTRPS_VPAD_BUTTON_LEFT], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_ZR); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gMouseSlot][CONTRPS_VPAD_BUTTON_RIGHT], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_R); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gMouseSlot][CONTRPS_PAD_COUNT], CONTROLLER_PATCHER_VALUE_SET, HID_MOUSE_PAD_COUNT); + + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! Keyboard + //!--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VID], (HID_KEYBOARD_VID>>8)&0xFF, HID_KEYBOARD_VID&0xFF); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_PID], (HID_KEYBOARD_PID>>8)&0xFF, HID_KEYBOARD_PID&0xFF); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_A], 0x00, HID_KEYBOARD_BUTTON_E); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_B], 0x00, HID_KEYBOARD_BUTTON_Q); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_X], 0x00, HID_KEYBOARD_BUTTON_SPACEBAR); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_Y], 0x00, HID_KEYBOARD_BUTTON_R); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_DPAD_MODE], CONTROLLER_PATCHER_VALUE_SET,CONTRPDM_Normal); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_LEFT], 0x00, HID_KEYBOARD_BUTTON_LEFT); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_RIGHT], 0x00, HID_KEYBOARD_BUTTON_RIGHT); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_DOWN], 0x00, HID_KEYBOARD_BUTTON_DOWN); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_UP], 0x00, HID_KEYBOARD_BUTTON_UP); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_PLUS], 0x00, HID_KEYBOARD_BUTTON_RETURN); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_MINUS], 0x00, HID_KEYBOARD_KEYPAD_BUTTON_MINUS); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_L], 0x00, HID_KEYBOARD_BUTTON_V); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_R], 0x00, HID_KEYBOARD_BUTTON_B); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_ZL], 0x00, HID_KEYBOARD_BUTTON_SHIFT); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_ZR], 0x00, HID_KEYBOARD_BUTTON_N); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_STICK_L], 0x00, HID_KEYBOARD_BUTTON_F); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_STICK_R], 0x00, HID_KEYBOARD_BUTTON_TAB); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_L_STICK_UP], 0x00, HID_KEYBOARD_BUTTON_W); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_L_STICK_DOWN], 0x00, HID_KEYBOARD_BUTTON_S); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_L_STICK_LEFT], 0x00, HID_KEYBOARD_BUTTON_A); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_L_STICK_RIGHT], 0x00, HID_KEYBOARD_BUTTON_D); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_R_STICK_UP], 0x00, HID_KEYBOARD_KEYPAD_BUTTON_8); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_R_STICK_DOWN], 0x00, HID_KEYBOARD_KEYPAD_BUTTON_2); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_R_STICK_LEFT], 0x00, HID_KEYBOARD_KEYPAD_BUTTON_4); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_R_STICK_RIGHT], 0x00, HID_KEYBOARD_KEYPAD_BUTTON_6); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_PAD_COUNT], CONTROLLER_PATCHER_VALUE_SET,HID_KEYBOARD_PAD_COUNT); + + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! GC-Adapter + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VID], (HID_GC_VID>>8)&0xFF, HID_GC_VID&0xFF); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_PID], (HID_GC_PID>>8)&0xFF, HID_GC_PID&0xFF); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_A], HID_GC_BUTTON_A[0], HID_GC_BUTTON_A[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_B], HID_GC_BUTTON_B[0], HID_GC_BUTTON_B[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_X], HID_GC_BUTTON_X[0], HID_GC_BUTTON_X[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_Y], HID_GC_BUTTON_Y[0], HID_GC_BUTTON_Y[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DPAD_MODE], CONTROLLER_PATCHER_VALUE_SET, HID_GC_BUTTON_DPAD_TYPE[CONTRDPAD_MODE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DPAD_MASK], CONTROLLER_PATCHER_VALUE_SET, HID_GC_BUTTON_DPAD_TYPE[CONTRDPAD_MASK]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_LEFT], HID_GC_BUTTON_LEFT[0], HID_GC_BUTTON_LEFT[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_RIGHT], HID_GC_BUTTON_RIGHT[0], HID_GC_BUTTON_RIGHT[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_DOWN], HID_GC_BUTTON_DOWN[0], HID_GC_BUTTON_DOWN[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_UP], HID_GC_BUTTON_UP[0], HID_GC_BUTTON_UP[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_MINUS], HID_GC_BUTTON_START[0], HID_GC_BUTTON_START[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L], HID_GC_BUTTON_L[0], HID_GC_BUTTON_L[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R], HID_GC_BUTTON_R[0], HID_GC_BUTTON_R[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_PLUS], HID_GC_BUTTON_START[0], HID_GC_BUTTON_START[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_ZL], HID_GC_BUTTON_L[0], HID_GC_BUTTON_L[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_ZR], HID_GC_BUTTON_R[0], HID_GC_BUTTON_R[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_STICK_L], HID_GC_BUTTON_A[0], HID_GC_BUTTON_A[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_STICK_R], HID_GC_BUTTON_B[0], HID_GC_BUTTON_B[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE], CONTROLLER_PATCHER_VALUE_SET, CONTROLLER_PATCHER_GC_DOUBLE_USE); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR], HID_GC_BUTTON_Z[0], HID_GC_BUTTON_Z[1]); + + //Buttons that will be ignored when the CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR is pressed + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_1_PRESSED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_MINUS); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_2_PRESSED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_L); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_3_PRESSED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_R); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_4_PRESSED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_STICK_L); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_5_PRESSED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_STICK_R); + + //Buttons that will be ignored when the CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR is released + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_1_RELEASED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_PLUS); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_2_RELEASED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_ZL); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_3_RELEASED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_ZR); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_4_RELEASED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_A); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_5_RELEASED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_B); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_PAD_COUNT], CONTROLLER_PATCHER_VALUE_SET, HID_GC_PAD_COUNT); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L_STICK_X], HID_GC_STICK_L_X[STICK_CONF_BYTE],HID_GC_STICK_L_X[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_GC_STICK_L_X[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX], HID_GC_STICK_L_X[STICK_CONF_MIN], HID_GC_STICK_L_X[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_GC_STICK_L_X[STICK_CONF_INVERT]); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L_STICK_Y], HID_GC_STICK_L_Y[STICK_CONF_BYTE],HID_GC_STICK_L_Y[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_GC_STICK_L_Y[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX], HID_GC_STICK_L_Y[STICK_CONF_MIN], HID_GC_STICK_L_Y[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_GC_STICK_L_Y[STICK_CONF_INVERT]); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R_STICK_X], HID_GC_STICK_R_X[STICK_CONF_BYTE],HID_GC_STICK_R_X[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_GC_STICK_R_X[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX], HID_GC_STICK_R_X[STICK_CONF_MIN], HID_GC_STICK_R_X[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_GC_STICK_R_X[STICK_CONF_INVERT]); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R_STICK_Y], HID_GC_STICK_R_Y[STICK_CONF_BYTE],HID_GC_STICK_R_Y[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_GC_STICK_R_Y[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX], HID_GC_STICK_R_Y[STICK_CONF_MIN], HID_GC_STICK_R_Y[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_GC_STICK_R_Y[STICK_CONF_INVERT]); + + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! DS3 + //!--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VID], (HID_DS3_VID>>8)&0xFF, HID_DS3_VID&0xFF); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_PID], (HID_DS3_PID>>8)&0xFF, HID_DS3_PID&0xFF); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_BUF_SIZE], CONTROLLER_PATCHER_VALUE_SET, 128); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_A], HID_DS3_BUTTON_CIRCLE[0], HID_DS3_BUTTON_CIRCLE[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_B], HID_DS3_BUTTON_CROSS[0], HID_DS3_BUTTON_CROSS[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_X], HID_DS3_BUTTON_TRIANGLE[0], HID_DS3_BUTTON_TRIANGLE[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_Y], HID_DS3_BUTTON_SQUARE[0], HID_DS3_BUTTON_SQUARE[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_DPAD_MODE], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_BUTTON_DPAD_TYPE[CONTRDPAD_MODE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_DPAD_MASK], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_BUTTON_DPAD_TYPE[CONTRDPAD_MASK]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_LEFT], HID_DS3_BUTTON_LEFT[0], HID_DS3_BUTTON_LEFT[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_RIGHT], HID_DS3_BUTTON_RIGHT[0], HID_DS3_BUTTON_RIGHT[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_DOWN], HID_DS3_BUTTON_DOWN[0], HID_DS3_BUTTON_DOWN[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_UP], HID_DS3_BUTTON_UP[0], HID_DS3_BUTTON_UP[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_PLUS], HID_DS3_BUTTON_START[0], HID_DS3_BUTTON_START[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_MINUS], HID_DS3_BUTTON_SELECT[0], HID_DS3_BUTTON_SELECT[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L], HID_DS3_BUTTON_L1[0], HID_DS3_BUTTON_L1[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R], HID_DS3_BUTTON_R1[0], HID_DS3_BUTTON_R1[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_ZL], HID_DS3_BUTTON_L2[0], HID_DS3_BUTTON_L2[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_ZR], HID_DS3_BUTTON_R2[0], HID_DS3_BUTTON_R2[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_STICK_L], HID_DS3_BUTTON_L3[0], HID_DS3_BUTTON_L3[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_STICK_R], HID_DS3_BUTTON_R3[0], HID_DS3_BUTTON_R3[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_HOME], HID_DS3_BUTTON_GUIDE[0], HID_DS3_BUTTON_GUIDE[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_PAD_COUNT], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_PAD_COUNT); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L_STICK_X], HID_DS3_STICK_L_X[STICK_CONF_BYTE], HID_DS3_STICK_L_X[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_STICK_L_X[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX], HID_DS3_STICK_L_X[STICK_CONF_MIN], HID_DS3_STICK_L_X[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_STICK_L_X[STICK_CONF_INVERT]); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y], HID_DS3_STICK_L_Y[STICK_CONF_BYTE], HID_DS3_STICK_L_Y[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_STICK_L_Y[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX], HID_DS3_STICK_L_Y[STICK_CONF_MIN], HID_DS3_STICK_L_Y[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_STICK_L_Y[STICK_CONF_INVERT]); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R_STICK_X], HID_DS3_STICK_R_X[STICK_CONF_BYTE], HID_DS3_STICK_R_X[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_STICK_R_X[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX], HID_DS3_STICK_R_X[STICK_CONF_MIN], HID_DS3_STICK_R_X[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_STICK_R_X[STICK_CONF_INVERT]); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y], HID_DS3_STICK_R_Y[STICK_CONF_BYTE], HID_DS3_STICK_R_Y[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_STICK_R_Y[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX], HID_DS3_STICK_R_Y[STICK_CONF_MIN], HID_DS3_STICK_R_Y[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_STICK_R_Y[STICK_CONF_INVERT]); + + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! DS4 + //!--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VID], (HID_DS4_VID>>8)&0xFF, HID_DS4_VID&0xFF); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_PID], (HID_DS4_PID>>8)&0xFF, HID_DS4_PID&0xFF); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_BUF_SIZE], CONTROLLER_PATCHER_VALUE_SET, 128); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_A], HID_DS4_BUTTON_CIRCLE[0], HID_DS4_BUTTON_CIRCLE[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_B], HID_DS4_BUTTON_CROSS[0], HID_DS4_BUTTON_CROSS[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_X], HID_DS4_BUTTON_TRIANGLE[0], HID_DS4_BUTTON_TRIANGLE[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_Y], HID_DS4_BUTTON_SQUARE[0], HID_DS4_BUTTON_SQUARE[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_DPAD_MODE], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_BUTTON_DPAD_TYPE[CONTRDPAD_MODE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_DPAD_MASK], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_BUTTON_DPAD_TYPE[CONTRDPAD_MASK]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_N], HID_DS4_BUTTON_DPAD_N[0], HID_DS4_BUTTON_DPAD_N[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_NE], HID_DS4_BUTTON_DPAD_NE[0], HID_DS4_BUTTON_DPAD_NE[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_E], HID_DS4_BUTTON_DPAD_E[0], HID_DS4_BUTTON_DPAD_E[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_SE], HID_DS4_BUTTON_DPAD_SE[0], HID_DS4_BUTTON_DPAD_SE[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_S], HID_DS4_BUTTON_DPAD_S[0], HID_DS4_BUTTON_DPAD_S[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_SW], HID_DS4_BUTTON_DPAD_SW[0], HID_DS4_BUTTON_DPAD_SW[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_W], HID_DS4_BUTTON_DPAD_W[0], HID_DS4_BUTTON_DPAD_W[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_NW], HID_DS4_BUTTON_DPAD_NW[0], HID_DS4_BUTTON_DPAD_NW[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_NEUTRAL], HID_DS4_BUTTON_DPAD_NEUTRAL[0], HID_DS4_BUTTON_DPAD_NEUTRAL[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_PLUS], HID_DS4_BUTTON_OPTIONS[0], HID_DS4_BUTTON_OPTIONS[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_MINUS], HID_DS4_BUTTON_SHARE[0], HID_DS4_BUTTON_SHARE[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L], HID_DS4_BUTTON_L1[0], HID_DS4_BUTTON_L1[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R], HID_DS4_BUTTON_R1[0], HID_DS4_BUTTON_R1[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_ZL], HID_DS4_BUTTON_L2[0], HID_DS4_BUTTON_L2[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_ZR], HID_DS4_BUTTON_R2[0], HID_DS4_BUTTON_R2[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_STICK_L], HID_DS4_BUTTON_L3[0], HID_DS4_BUTTON_L3[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_STICK_R], HID_DS4_BUTTON_R3[0], HID_DS4_BUTTON_R3[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_HOME], HID_DS4_BUTTON_GUIDE[0], HID_DS4_BUTTON_GUIDE[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_PAD_COUNT], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_PAD_COUNT); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L_STICK_X], HID_DS4_STICK_L_X[STICK_CONF_BYTE], HID_DS4_STICK_L_X[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_STICK_L_X[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX], HID_DS4_STICK_L_X[STICK_CONF_MIN], HID_DS4_STICK_L_X[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_STICK_L_X[STICK_CONF_INVERT]); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y], HID_DS4_STICK_L_Y[STICK_CONF_BYTE], HID_DS4_STICK_L_Y[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_STICK_L_Y[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX], HID_DS4_STICK_L_Y[STICK_CONF_MIN], HID_DS4_STICK_L_Y[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_STICK_L_Y[STICK_CONF_INVERT]); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R_STICK_X], HID_DS4_STICK_R_X[STICK_CONF_BYTE], HID_DS4_STICK_R_X[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_STICK_R_X[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX], HID_DS4_STICK_R_X[STICK_CONF_MIN], HID_DS4_STICK_R_X[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_STICK_R_X[STICK_CONF_INVERT]); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y], HID_DS4_STICK_R_Y[STICK_CONF_BYTE], HID_DS4_STICK_R_Y[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_STICK_R_Y[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX], HID_DS4_STICK_R_Y[STICK_CONF_MIN], HID_DS4_STICK_R_Y[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_STICK_R_Y[STICK_CONF_INVERT]); + + //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + //! XInput + //!--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VID], (HID_XINPUT_VID>>8)&0xFF, HID_XINPUT_VID&0xFF); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_PID], (HID_XINPUT_PID>>8)&0xFF, HID_XINPUT_PID&0xFF); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_BUF_SIZE], CONTROLLER_PATCHER_VALUE_SET, 128); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_A], HID_XINPUT_BUTTON_B[0], HID_XINPUT_BUTTON_B[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_B], HID_XINPUT_BUTTON_A[0], HID_XINPUT_BUTTON_A[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_X], HID_XINPUT_BUTTON_Y[0], HID_XINPUT_BUTTON_Y[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_Y], HID_XINPUT_BUTTON_X[0], HID_XINPUT_BUTTON_X[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_DPAD_MODE], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_BUTTON_DPAD_TYPE[CONTRDPAD_MODE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_DPAD_MASK], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_BUTTON_DPAD_TYPE[CONTRDPAD_MASK]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_UP], HID_XINPUT_BUTTON_UP[0], HID_XINPUT_BUTTON_UP[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_DOWN], HID_XINPUT_BUTTON_DOWN[0], HID_XINPUT_BUTTON_DOWN[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_LEFT], HID_XINPUT_BUTTON_LEFT[0], HID_XINPUT_BUTTON_LEFT[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_RIGHT], HID_XINPUT_BUTTON_RIGHT[0], HID_XINPUT_BUTTON_RIGHT[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_PLUS], HID_XINPUT_BUTTON_START[0], HID_XINPUT_BUTTON_START[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_MINUS], HID_XINPUT_BUTTON_BACK[0], HID_XINPUT_BUTTON_BACK[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L], HID_XINPUT_BUTTON_LB[0], HID_XINPUT_BUTTON_LB[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R], HID_XINPUT_BUTTON_RB[0], HID_XINPUT_BUTTON_RB[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_ZL], HID_XINPUT_BUTTON_LT[0], HID_XINPUT_BUTTON_LT[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_ZR], HID_XINPUT_BUTTON_RT[0], HID_XINPUT_BUTTON_RT[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_STICK_L], HID_XINPUT_BUTTON_L3[0], HID_XINPUT_BUTTON_L3[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_STICK_R], HID_XINPUT_BUTTON_R3[0], HID_XINPUT_BUTTON_R3[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_HOME], HID_XINPUT_BUTTON_GUIDE[0], HID_XINPUT_BUTTON_GUIDE[1]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_PAD_COUNT], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_PAD_COUNT); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L_STICK_X], HID_XINPUT_STICK_L_X[STICK_CONF_BYTE], HID_XINPUT_STICK_L_X[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_STICK_L_X[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX], HID_XINPUT_STICK_L_X[STICK_CONF_MIN], HID_XINPUT_STICK_L_X[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_STICK_L_X[STICK_CONF_INVERT]); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y], HID_XINPUT_STICK_L_Y[STICK_CONF_BYTE], HID_XINPUT_STICK_L_Y[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_STICK_L_Y[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX], HID_XINPUT_STICK_L_Y[STICK_CONF_MIN], HID_XINPUT_STICK_L_Y[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_STICK_L_Y[STICK_CONF_INVERT]); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R_STICK_X], HID_XINPUT_STICK_R_X[STICK_CONF_BYTE], HID_XINPUT_STICK_R_X[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_STICK_R_X[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX], HID_XINPUT_STICK_R_X[STICK_CONF_MIN], HID_XINPUT_STICK_R_X[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_STICK_R_X[STICK_CONF_INVERT]); + + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y], HID_XINPUT_STICK_R_Y[STICK_CONF_BYTE], HID_XINPUT_STICK_R_Y[STICK_CONF_DEFAULT]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_STICK_R_Y[STICK_CONF_DEADZONE]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX], HID_XINPUT_STICK_R_Y[STICK_CONF_MIN], HID_XINPUT_STICK_R_Y[STICK_CONF_MAX]); + ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_STICK_R_Y[STICK_CONF_INVERT]); +} + +bool ControllerPatcher::Init(){ + /* + InitOSFunctionPointers(); + InitSocketFunctionPointers(); + InitSysHIDFunctionPointers(); + InitVPadFunctionPointers(); + InitPadScoreFunctionPointers();*/ + + OSDynLoadModule padscore_handle = 0; + OSDynLoad_Acquire("padscore.rpl", &padscore_handle); + void(*KPADRead_test)(); + OSDynLoad_FindExport(padscore_handle, 0, "KPADRead", (void**)&KPADRead_test); + printf("ControllerPatcher::Init(line %d): Found the KPADRead at %08X \n",__LINE__,KPADRead_test); + + gSamplingCallback = (wpad_sampling_callback_t)((u32)KPADRead_test + 0x1F0); + if(*(u32*)gSamplingCallback != FIRST_INSTRUCTION_IN_SAMPLING_CALLBACK){ + gSamplingCallback = NULL; + //In Firmware <= 5.1.2 the offset changes + gSamplingCallback = (wpad_sampling_callback_t)((u32)KPADRead_test + 0x1F8); + if(*(u32*)gSamplingCallback != FIRST_INSTRUCTION_IN_SAMPLING_CALLBACK){ + //Should never happen. I looked into the padscore.rpl of ALL firmwares. + gSamplingCallback = NULL; + } + } + printf("ControllerPatcher::Init(line %d): Found the gSamplingCallback at %08X \n",__LINE__,gSamplingCallback); + + if(HID_DEBUG){ printf("ControllerPatcher::Init(line %d): Init called! \n",__LINE__); } + + /* if(syshid_handle == 0){ + printf("ControllerPatcher::Init(line %d): Failed to load the HID API \n",__LINE__); + return false; + }*/ + + if(gConfig_done == HID_INIT_NOT_DONE){ + if(HID_DEBUG){ printf("ControllerPatcher::Init(line %d): First time calling the Init\n",__LINE__); } + gConfig_done = HID_INIT_DONE; + ControllerPatcher::ResetConfig(); + }else{ + if(HID_DEBUG){ printf("ControllerPatcher::Init(line %d): ControllerPatcher::Init(): Config already done!\n",__LINE__); } + } + + //Broken + if(gConfig_done != HID_SDCARD_READ){ + printf("ControllerPatcher::Init(line %d): Reading config files from SD Card\n",__LINE__); + ConfigReader* reader = ConfigReader::getInstance(); + s32 status = 0; + if((status = reader->InitSDCard()) == 0){ + if(HID_DEBUG){ printf("ControllerPatcher::Init(line %d): SD Card mounted for controller config!\n",__LINE__); } + reader->ReadAllConfigs(); + printf("ControllerPatcher::Init(line %d): Done with reading config files from SD Card\n",__LINE__); + gConfig_done = HID_SDCARD_READ; + }else{ + printf("ControllerPatcher::Init(line %d): SD mounting failed! %d\n",__LINE__,status); + } + ConfigReader::destroyInstance(); + } + + printf("ControllerPatcher::Init(line %d): Initializing the data for button remapping\n",__LINE__); + InitButtonMapping(); + + if(!gHIDAttached){ + HIDAddClient(&gHIDClient, ControllerPatcherHID::myAttachDetachCallback); + } + + return true; +} + +void ControllerPatcher::startNetworkServer(){ + UDPServer::getInstance(); + TCPServer::getInstance(); +} + +void ControllerPatcher::stopNetworkServer(){ + UDPServer::destroyInstance(); + UDPClient::destroyInstance(); + TCPServer::destroyInstance(); +} + +void ControllerPatcher::DeInit(){ + if(HID_DEBUG){ printf("ControllerPatcher::DeInit(line %d) called! \n",__LINE__); } + + if(gHIDAttached) HIDDelClient(&gHIDClient); + + //Resetting the state of the last pressed data. + buttonRemapping_lastButtonsHold = 0; + memset(last_button_hold,0,sizeof(last_button_hold)); + memset(myVPADBuffer,0,sizeof(myVPADBuffer)); + memset(&gControllerMapping,0,sizeof(gControllerMapping)); + memset(&gHIDClient,0,sizeof(gHIDClient)); + memset(gHID_Devices,0,sizeof(gHID_Devices)); + memset(gGamePadValues,0,sizeof(gGamePadValues)); + memset(config_controller,0,sizeof(config_controller)); + memset(config_controller_hidmask,0,sizeof(config_controller_hidmask)); + memset(gNetworkController,0,sizeof(gNetworkController)); + memset(connectionOrderHelper,0,sizeof(connectionOrderHelper)); + + memset(gWPADConnectCallback,0,sizeof(gWPADConnectCallback)); + memset(gKPADConnectCallback,0,sizeof(gKPADConnectCallback)); + memset(gExtensionCallback,0,sizeof(gExtensionCallback)); + gCallbackCooldown = 0; + + gConfig_done = HID_INIT_NOT_DONE; + gButtonRemappingConfigDone = 0; + gHIDAttached = 0; + gHIDCurrentDevice = 0; + gHIDRegisteredDevices = 0; + gHID_Mouse_Mode = HID_MOUSE_MODE_TOUCH; + gHID_LIST_GC = 0; + gHID_LIST_DS3 = 0; + gHID_LIST_DS4 = 0; + gHID_LIST_KEYBOARD = 0; + gHID_LIST_MOUSE = 0; + gHID_LIST_SWITCH_PRO = 0; + + gGamePadSlot = 0; + gHID_SLOT_GC = 0; + gHID_SLOT_KEYBOARD = 0; + gMouseSlot = 0; + + gOriginalDimState = 0; + gOriginalAPDState = 0; + + gHIDNetworkClientID = 0; + + destroyConfigHelper(); +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::enableControllerMapping(){ + gControllerMapping.gamepad.useAll = 0; + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::disableControllerMapping(){ + gControllerMapping.gamepad.useAll = 1; + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::disableWiiUEnergySetting(){ + s32 res; + if(IMIsDimEnabled(&res) == 0){ + if(res == 1){ + if(HID_DEBUG){ printf("ControllerPatcher::disableWiiUEnergySetting(): Dim was orignally enabled!\n"); } + gOriginalDimState = 1; + } + } + + if(IMIsAPDEnabled(&res) == 0){ + if(res == 1){ + if(HID_DEBUG){ printf("ControllerPatcher::disableWiiUEnergySetting(): Auto power down was orignally enabled!\n"); } + gOriginalAPDState = 1; + } + } + + IMDisableDim(); + IMDisableAPD(); + printf("ControllerPatcher::disableWiiUEnergySetting(): Disable Energy savers\n"); + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::restoreWiiUEnergySetting(){ + + //Check if we need to enable Auto Power down again on exiting + if(gOriginalAPDState == 1){ + printf("ControllerPatcher::restoreWiiUEnergySetting(): Auto shutdown was on before using HID to VPAD. Setting it to on again.\n"); + IMEnableAPD(); + } + if(gOriginalDimState == 1){ + printf("ControllerPatcher::restoreWiiUEnergySetting(): Burn-in reduction was on before using HID to VPAD. Setting it to on again.\n"); + IMEnableDim(); + } + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::resetControllerMapping(UController_Type type){ + ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type); + + if(cm_map_pad == NULL){return CONTROLLER_PATCHER_ERROR_NULL_POINTER;} + memset(cm_map_pad,0,sizeof(*cm_map_pad)); + + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::addControllerMapping(UController_Type type,ControllerMappingPADInfo config){ + ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type); + + s32 result = 0; + + for(s32 i=0;ipad_infos[i]); + if(info != NULL && !info->active){ + info->active = 1; + info->pad = config.pad; + info->type = config.type; + info->vidpid.vid = config.vidpid.vid; + info->vidpid.pid = config.vidpid.pid; + + result = 1; + break; + } + } + if(result == 0){ + //No free slot. + return -1; + } + + return CONTROLLER_PATCHER_ERROR_NONE; +} + +s32 ControllerPatcher::getActiveMappingSlot(UController_Type type){ + ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type); + + if(cm_map_pad == NULL){return -1;} + + s32 connected = -1; + for(s32 i =0;ipad_infos[i].active || cm_map_pad->pad_infos[i].type == CM_Type_RealController){ + connected = i; + break; + } + } + + return connected; +} + +bool ControllerPatcher::isControllerConnectedAndActive(UController_Type type,s32 mapping_slot){ + ControllerMappingPADInfo * padinfo = getControllerMappingInfo(type,mapping_slot); + if(!padinfo){ + return false; + } + if(padinfo->active){ + DeviceInfo device_info; + + memset(&device_info,0,sizeof(device_info)); + + device_info.vidpid = padinfo->vidpid; + + s32 res; + if((res = ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info)) < 0){ + return false; + } + + u32 hidmask = device_info.slotdata.hidmask; + u32 pad = padinfo->pad; + + HID_Data * data_cur; + + if((res = ControllerPatcherHID::getHIDData(hidmask,pad,&data_cur)) < 0) { + return false; + } + + return true; + } + return false; +} + +ControllerMappingPADInfo * ControllerPatcher::getControllerMappingInfo(UController_Type type,s32 mapping_slot){ + ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type); + + if(cm_map_pad == NULL){return NULL;} + + if(mapping_slot < 0 || mapping_slot > HID_MAX_DEVICES_PER_SLOT-1){ return NULL;} + + return &(cm_map_pad->pad_infos[mapping_slot]); +} + +HID_Mouse_Data * ControllerPatcher::getMouseData(){ + ControllerMappingPAD * CMPAD = ControllerPatcherUtils::getControllerMappingByType(UController_Type_Gamepad); + + if(CMPAD == NULL){ + return NULL; + } + + HID_Mouse_Data * result = NULL; + + for(s32 i;ipad_infos[i]); + if(!padinfo->active){ + break; + } + if(padinfo->type == CM_Type_Mouse){ + result = &(gHID_Devices[gMouseSlot].pad_data[padinfo->pad].data_union.mouse.cur_mouse_data); + } + } + return result; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setRumble(UController_Type type,u32 status){ + ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type); + if(cm_map_pad == NULL){return -1;} + cm_map_pad->rumble = !!status; //to make sure it's only 0 or 1. + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::gettingInputAllDevices(InputData * output,s32 array_size){ + HID_Data * data_cur; + VPADStatus pad_buffer; + VPADStatus * buffer = &pad_buffer; + s32 result = CONTROLLER_PATCHER_ERROR_NONE; + std::map pad_count; + //printf("fill in data\n"); + for(s32 i = 0;i < gHIDMaxDevices;i++){ + u8 * status = &output[result].status; + *status = 0; + if(connectionOrderHelper[i] != NULL){ + *status = 1; + + my_cb_user * usr = connectionOrderHelper[i]; + pad_count[usr] = pad_count[usr] +1; + s32 hid = usr->slotdata.hidmask; + //printf("result[%d] usr: %08X\n",result,usr); + + s32 realpad = pad_count[usr] - 1; + + output[result].device_info.pad_count = usr->pads_per_device; + output[result].device_info.slotdata = usr->slotdata; + output[result].device_info.vidpid = usr->vidpid; + + InputButtonData * buttondata = &output[result].button_data; + InputStickData * stickdata = &output[result].stick_data; + + s32 buttons_hold = 0; + buttondata->hold = 0; + buttondata->trigger = 0; + buttondata->release = 0; + + s32 res; + if((res = ControllerPatcherHID::getHIDData(hid,realpad,&data_cur)) == 0){ + res = ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_A); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_B); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_X); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_Y); + + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_LEFT); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_RIGHT); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_DOWN); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_UP); + + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_MINUS); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_L); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_R); + + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_PLUS); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_ZL); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_ZR); + + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_HOME); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_STICK_L); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_STICK_R); + + buttondata->hold |= buttons_hold; + buttondata->trigger |= (buttons_hold & (~(data_cur->last_buttons))); + buttondata->release |= ((data_cur->last_buttons) & (~buttons_hold)); + + buffer->leftStick.x = 0.0f; + buffer->leftStick.y = 0.0f; + buffer->rightStick.x = 0.0f; + buffer->rightStick.y = 0.0f; + + ControllerPatcherUtils::convertAnalogSticks(data_cur,buffer); + ControllerPatcherUtils::normalizeStickValues(&(buffer->leftStick)); + ControllerPatcherUtils::normalizeStickValues(&(buffer->rightStick)); + + stickdata->leftStickX = buffer->leftStick.x; + stickdata->leftStickY = buffer->leftStick.y; + stickdata->rightStickX = buffer->rightStick.x; + stickdata->rightStickY = buffer->rightStick.y; + + //printf("result[%d] buttons %08X\n",result,buttons_hold); + + data_cur->last_buttons = buttons_hold; + } + } + + result++; + if(result >= array_size){ + break; + } + } + + return result; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setProControllerDataFromHID(void * data,s32 chan, s32 mode){ + if(data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + if(chan < 0 || chan > 3) return CONTROLLER_PATCHER_ERROR_INVALID_CHAN; + //if(gControllerMapping.proController[chan].enabled == 0) return CONTROLLER_PATCHER_ERROR_MAPPING_DISABLED; + + VPADStatus * vpad_buffer = &myVPADBuffer[chan]; + memset(vpad_buffer,0,sizeof(*vpad_buffer)); + + std::vector data_list; + + for(s32 i = 0;i::iterator it = data_list.begin(); it != data_list.end(); ++it) { + HID_Data * cur_ptr = *it; + cur_ptr->rumbleActive = !!gControllerMapping.proController[chan].rumble; + } + + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setControllerDataFromHID(VPADStatus * buffer){ + if(buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + //if(gControllerMapping.gamepad.enabled == 0) return CONTROLLER_PATCHER_ERROR_MAPPING_DISABLED; + + s32 hidmask = 0; + s32 pad = 0; + + ControllerMappingPAD cm_map_pad = gControllerMapping.gamepad; + std::vector data_list; + + if (cm_map_pad.useAll == 1) { + data_list = ControllerPatcherHID::getHIDDataAll(); + }else{ + for(s32 i = 0;irumbleActive = !!gControllerMapping.gamepad.rumble; + } + + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::printVPADButtons(VPADStatus * buffer){ + return CONTROLLER_PATCHER_ERROR_NONE; + /* BROKEN on transitions.*/ + if(buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + if(buffer->trigger != 0x00000000){ + char output[250]; + + output[0] = 0; //null terminate it. just in case. + + if((buffer->trigger & VPAD_BUTTON_A) == VPAD_BUTTON_A) strcat(output,"A "); + if((buffer->trigger & VPAD_BUTTON_B) == VPAD_BUTTON_B) strcat(output,"B "); + if((buffer->trigger & VPAD_BUTTON_X) == VPAD_BUTTON_X) strcat(output,"X "); + if((buffer->trigger & VPAD_BUTTON_Y) == VPAD_BUTTON_Y) strcat(output,"Y "); + if((buffer->trigger & VPAD_BUTTON_L) == VPAD_BUTTON_L) strcat(output,"L "); + if((buffer->trigger & VPAD_BUTTON_R) == VPAD_BUTTON_R) strcat(output,"R "); + if((buffer->trigger & VPAD_BUTTON_ZR) == VPAD_BUTTON_ZR) strcat(output,"ZR "); + if((buffer->trigger & VPAD_BUTTON_ZL) == VPAD_BUTTON_ZL) strcat(output,"ZL "); + if((buffer->trigger & VPAD_BUTTON_LEFT) == VPAD_BUTTON_LEFT) strcat(output,"Left "); + if((buffer->trigger & VPAD_BUTTON_RIGHT) == VPAD_BUTTON_RIGHT) strcat(output,"Right "); + if((buffer->trigger & VPAD_BUTTON_UP) == VPAD_BUTTON_UP) strcat(output,"Up "); + if((buffer->trigger & VPAD_BUTTON_DOWN) == VPAD_BUTTON_DOWN) strcat(output,"Down "); + if((buffer->trigger & VPAD_BUTTON_PLUS) == VPAD_BUTTON_PLUS) strcat(output,"+ "); + if((buffer->trigger & VPAD_BUTTON_MINUS) == VPAD_BUTTON_MINUS) strcat(output,"- "); + if((buffer->trigger & VPAD_BUTTON_TV) == VPAD_BUTTON_TV) strcat(output,"TV "); + if((buffer->trigger & VPAD_BUTTON_HOME) == VPAD_BUTTON_HOME) strcat(output,"HOME "); + if((buffer->trigger & VPAD_BUTTON_STICK_L) == VPAD_BUTTON_STICK_L) strcat(output,"SL "); + if((buffer->trigger & VPAD_BUTTON_STICK_R) == VPAD_BUTTON_STICK_R) strcat(output,"SR "); + if((buffer->trigger & VPAD_STICK_R_EMULATION_LEFT) == VPAD_STICK_R_EMULATION_LEFT) strcat(output,"RE_Left "); + if((buffer->trigger & VPAD_STICK_R_EMULATION_RIGHT) == VPAD_STICK_R_EMULATION_RIGHT) strcat(output,"RE_Right "); + if((buffer->trigger & VPAD_STICK_R_EMULATION_UP) == VPAD_STICK_R_EMULATION_UP) strcat(output,"RE_Up "); + if((buffer->trigger & VPAD_STICK_R_EMULATION_DOWN) == VPAD_STICK_R_EMULATION_DOWN) strcat(output,"RE_Down "); + if((buffer->trigger & VPAD_STICK_L_EMULATION_LEFT) == VPAD_STICK_L_EMULATION_LEFT) strcat(output,"LE_Left "); + if((buffer->trigger & VPAD_STICK_L_EMULATION_RIGHT) == VPAD_STICK_L_EMULATION_RIGHT) strcat(output,"LE_Right "); + if((buffer->trigger & VPAD_STICK_L_EMULATION_UP) == VPAD_STICK_L_EMULATION_UP) strcat(output,"LE_Up "); + if((buffer->trigger & VPAD_STICK_L_EMULATION_DOWN) == VPAD_STICK_L_EMULATION_DOWN) strcat(output,"LE_Down "); + + printf("%spressed Sticks: LX %f LY %f RX %f RY %f\n",output,buffer->leftStick.x,buffer->leftStick.y,buffer->rightStick.x,buffer->rightStick.y); + } + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::buttonRemapping(VPADStatus * buffer,s32 buffer_count){ + if(!gButtonRemappingConfigDone) return CONTROLLER_PATCHER_ERROR_CONFIG_NOT_DONE; + if(buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + for(s32 i = 0;i < buffer_count;i++){ + VPADStatus new_data; + memset(&new_data,0,sizeof(new_data)); + + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_A, CONTRPS_VPAD_BUTTON_A); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_B, CONTRPS_VPAD_BUTTON_B); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_X, CONTRPS_VPAD_BUTTON_X); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_Y, CONTRPS_VPAD_BUTTON_Y); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_LEFT, CONTRPS_VPAD_BUTTON_LEFT); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_RIGHT, CONTRPS_VPAD_BUTTON_RIGHT); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_UP, CONTRPS_VPAD_BUTTON_UP); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_DOWN, CONTRPS_VPAD_BUTTON_DOWN); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_ZL, CONTRPS_VPAD_BUTTON_ZL); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_ZR, CONTRPS_VPAD_BUTTON_ZR); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_L, CONTRPS_VPAD_BUTTON_L); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_R, CONTRPS_VPAD_BUTTON_R); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_PLUS, CONTRPS_VPAD_BUTTON_PLUS); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_MINUS, CONTRPS_VPAD_BUTTON_MINUS); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_HOME, CONTRPS_VPAD_BUTTON_HOME); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_SYNC, CONTRPS_VPAD_BUTTON_SYNC); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_STICK_R, CONTRPS_VPAD_BUTTON_STICK_R); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_STICK_L, CONTRPS_VPAD_BUTTON_STICK_L); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_TV, CONTRPS_VPAD_BUTTON_TV); + + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_STICK_R_EMULATION_LEFT, CONTRPS_VPAD_STICK_R_EMULATION_LEFT); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_STICK_R_EMULATION_RIGHT, CONTRPS_VPAD_STICK_R_EMULATION_RIGHT); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_STICK_R_EMULATION_UP, CONTRPS_VPAD_STICK_R_EMULATION_UP); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_STICK_R_EMULATION_DOWN, CONTRPS_VPAD_STICK_R_EMULATION_DOWN); + + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_STICK_L_EMULATION_LEFT, CONTRPS_VPAD_STICK_L_EMULATION_LEFT); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_STICK_L_EMULATION_RIGHT, CONTRPS_VPAD_STICK_L_EMULATION_RIGHT); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_STICK_L_EMULATION_UP, CONTRPS_VPAD_STICK_L_EMULATION_UP); + ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_STICK_L_EMULATION_DOWN, CONTRPS_VPAD_STICK_L_EMULATION_DOWN); + + //Even when you remap any Stick Emulation to a button, we still want to keep the emulated stick data. Some games like New Super Mario Bros. only work with the emulated stick data. + ControllerPatcherUtils::setButtonData(&buffer[i],&new_data,VPAD_STICK_L_EMULATION_LEFT, VPAD_STICK_L_EMULATION_LEFT); + ControllerPatcherUtils::setButtonData(&buffer[i],&new_data,VPAD_STICK_L_EMULATION_RIGHT, VPAD_STICK_L_EMULATION_RIGHT); + ControllerPatcherUtils::setButtonData(&buffer[i],&new_data,VPAD_STICK_L_EMULATION_UP, VPAD_STICK_L_EMULATION_UP); + ControllerPatcherUtils::setButtonData(&buffer[i],&new_data,VPAD_STICK_L_EMULATION_DOWN, VPAD_STICK_L_EMULATION_DOWN); + + ControllerPatcherUtils::setButtonData(&buffer[i],&new_data,VPAD_STICK_R_EMULATION_LEFT, VPAD_STICK_R_EMULATION_LEFT); + ControllerPatcherUtils::setButtonData(&buffer[i],&new_data,VPAD_STICK_R_EMULATION_RIGHT, VPAD_STICK_R_EMULATION_RIGHT); + ControllerPatcherUtils::setButtonData(&buffer[i],&new_data,VPAD_STICK_R_EMULATION_UP, VPAD_STICK_R_EMULATION_UP); + ControllerPatcherUtils::setButtonData(&buffer[i],&new_data,VPAD_STICK_R_EMULATION_DOWN, VPAD_STICK_R_EMULATION_DOWN); + + buffer[i].hold = new_data.hold; + buffer[i].trigger = new_data.trigger; + buffer[i].release = new_data.release; + } + return CONTROLLER_PATCHER_ERROR_NONE; +} + +std::string ControllerPatcher::getIdentifierByVIDPID(u16 vid,u16 pid){ + return ConfigValues::getStringByVIDPID(vid,pid); +} + +void ControllerPatcher::destroyConfigHelper(){ + ConfigReader::destroyInstance(); + ConfigValues::destroyInstance(); +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::doSamplingForDeviceSlot(u16 device_slot){ + return ControllerPatcherUtils::doSampling(device_slot,0,true); +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setRumbleActivated(bool value){ + gGlobalRumbleActivated = value; + return CONTROLLER_PATCHER_ERROR_NONE; +} + +bool ControllerPatcher::isRumbleActivated(){ + return gGlobalRumbleActivated; +} + diff --git a/wiiu/controller_patcher/ControllerPatcher.hpp b/wiiu/controller_patcher/ControllerPatcher.hpp new file mode 100644 index 0000000000..58aaa65c9d --- /dev/null +++ b/wiiu/controller_patcher/ControllerPatcher.hpp @@ -0,0 +1,251 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ + + /** + * @file ControllerPatcher.hpp + * @author Maschell + * @date 30 Mar 2017 + * \brief This files contain all public accessible functions of the controller patcher engine + * + * @see https://github.com/Maschell/controller_patcher + */ + +#ifndef _CONTROLLER_PATCHER_H_ +#define _CONTROLLER_PATCHER_H_ + +#include + +#include "./patcher/ControllerPatcherDefs.h" +#include "./utils/ControllerPatcherThread.hpp" +#include "./utils/CPRetainVars.hpp" +#include "./utils/PadConst.hpp" +#include "./utils/CPStringTools.hpp" + +#include "./patcher/ControllerPatcherHID.hpp" +#include "./patcher/ControllerPatcherUtils.hpp" + +#include "./config/ConfigValues.hpp" +#include "./config/ConfigParser.hpp" + +#include "./network/ControllerPatcherNet.hpp" +#include "./network/TCPServer.hpp" +#include "./network/UDPServer.hpp" +#include "./network/UDPClient.hpp" +#include "./ConfigReader.hpp" + +#include "wiiu/vpad.h" + +#define BUS_SPEED 248625000 +#define SECS_TO_TICKS(sec) (((unsigned long long)(sec)) * (BUS_SPEED/4)) +#define MILLISECS_TO_TICKS(msec) (SECS_TO_TICKS(msec) / 1000) +#define MICROSECS_TO_TICKS(usec) (SECS_TO_TICKS(usec) / 1000000) + +#define wiiu_os_usleep(usecs) OSSleepTicks(MICROSECS_TO_TICKS(usecs)) + +#define HID_DEBUG 0 + +class ControllerPatcher{ + public: + /*----------------------------------------------------------------------------------------------------------------------------------- + * Initialization + *----------------------------------------------------------------------------------------------------------------------------------*/ + /** + \brief Resets the data thats used by the controller configuration + **/ + static void ResetConfig(); + /** + \brief Initializes the libraries, functions, values and arrays. Need to be called on each start of an Application. Returns false on errors. + **/ + static bool Init(); + + /** + \brief De-Initialises the controller_patcher + **/ + static void DeInit(); + /** + Initialises the button remapping + **/ + static void InitButtonMapping(); + + /** + Starts the network server + **/ + static void startNetworkServer(); + + /** + Stops the network server + **/ + static void stopNetworkServer(); + + /*----------------------------------------------------------------------------------------------------------------------------------- + * Initialization + *----------------------------------------------------------------------------------------------------------------------------------*/ + + /** + Sets the data in a given data from HID Devices. The information about which HID Device will be used is stored in the gControllerMapping array int slot 1-4 (counting starts at 0, which is the gamepad). The \p + chan provides the information of the channel from which the data will be used. The mode sets the type of the buffer. + + @param buffer: A pointer to the struct where the result will be stored. + @param chan: Indicates the channel from which slot the information about the mapped HID Device will be used. + @param mode: Sets the type of the buffer. PRO_CONTROLLER_MODE_KPADDATA or PRO_CONTROLLER_MODE_WPADReadData + + @return When the functions failed result < 0 is returned. If the result is == 0 the function was successful. + **/ + + static CONTROLLER_PATCHER_RESULT_OR_ERROR setProControllerDataFromHID(void * data,s32 chan,s32 mode = PRO_CONTROLLER_MODE_KPADDATA); + + + /** + Sets the data in a given VPADStatus from HID Devices. The information about which HID Device will be used is stored in the gControllerMapping array in slot 0. + + @param buffer: A pointer to an KPADData struct where the result will be stored. + @param chan: Indicates the channel from which slot the information about the mapped HID Device will be used. + + @return When the functions failed result < 0 is returned. If the result is == 0 the function was successful. + **/ + + static CONTROLLER_PATCHER_RESULT_OR_ERROR setControllerDataFromHID(VPADStatus * buffer); + + /*----------------------------------------------------------------------------------------------------------------------------------- + * Useful functions + *----------------------------------------------------------------------------------------------------------------------------------*/ + + /** + Enable the Controller mapping. + @return When the functions failed result < 0 is returned. If the result is == 0 the function was successful. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR enableControllerMapping(); + + /** + Disbale the Controller mapping. Afterwards all connected controllers will be used for the gamepad. + @return When the functions failed result < 0 is returned. If the result is == 0 the function was successful. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR disableControllerMapping(); + + /** + Disables the energy settings for the WiiU. Settings can be restored via restoreWiiUEnergySetting. + @return When the functions failed result < 0 is returned. If the result is == 0 the function was successful. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR disableWiiUEnergySetting(); + + /** + Restores the WiiU Energy Settings. + @return When the functions failed result < 0 is returned. If the result is == 0 the function was successful. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR restoreWiiUEnergySetting(); + + /** + Resets the controller mapping for a given controller type. + + @param type: The type of the controller. + + @return When the functions failed result < 0 is returned. If the result is == 0 the function was successful. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR resetControllerMapping(UController_Type type); + + + /** + Adds a controller mapping + + @param type: The type of the controller. + @param config: information about the added controller. + + @return When the functions failed result < 0 is returned. If the result is == 0 the function was successful. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR addControllerMapping(UController_Type type,ControllerMappingPADInfo config); + + + /** + + @return The first active mapping slot for the given controller type will be returned. If the controller type is not set active, -1 will be returned. + **/ + static s32 getActiveMappingSlot(UController_Type type); + + /** + @param type: The type of the controller. + @param mapping_slot: information about the added controller. + @return When the functions failed result < 0 is returned. Otherwise a pointer to a ControllerMappingPADInfo is returned. + **/ + static ControllerMappingPADInfo * getControllerMappingInfo(UController_Type type,s32 mapping_slot); + + /** + Checks if a emulated controller is connected for the given controller type / mapping slot. + + @param type: The type of the controller. + @param mapping_slot: Slot of the controller mapped to this controller type (usually 0) + + @return + **/ + static bool isControllerConnectedAndActive(UController_Type type,s32 mapping_slot = 0); + + /** + Search for a connected mouse and returns a pointer to it's data. + @return A pointer to the first connected mouse that is found. NULL if no mouse is connected. + **/ + static HID_Mouse_Data * getMouseData(); + + /** + Sets a rumble status for a controller. + + @param type: The type of the controller. + @param status: status of the rumble. 0 for off, 1 for on. + + @return When the functions failed result < 0 is returned. If the result is == 0 the function was successful. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR setRumble(UController_Type type,u32 status); + + /** + Reads the input of all connected HID devices. Each attached controller will write his date into given array until it's full. + + @param output: A pointer to an InputData array where the result will be stored. (Make sure to reset the array before using this function). + @param array_size: Size of the given InputData array. + + @return When the functions failed result < 0 is returned. If the result is == 0 the function was successful. If the result is > 0 the number of stored sets in the array is returned. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR gettingInputAllDevices(InputData * output,s32 array_size); + + /** + Remaps the buttons in the given \p VPADStatus pointer. InitButtonMapping() needs to be called before calling this. The information about the remapping is stored in the config_controller array. + One easy way to set it is using the a config file on the SD Card. + + @param buffer: A pointer to the buffer where the input will be read from and the result will be stored. + + @return When the functions failed result < 0 is returned. If the result is == 0 the function was successful. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR buttonRemapping(VPADStatus * buffer, s32 buffer_count); + + /** + Prints the current pressed down buttons of the given \p VPADStatus pointer. Uses the utils/logger.c UDP logger.. + + @param buffer: A pointer to the buffer where the input will be read from. + + @return When the functions failed result < 0 is returned. If the result is == 0 the function was successful. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR printVPADButtons(VPADStatus * buffer); + + static std::string getIdentifierByVIDPID(u16 vid,u16 pid); + + static void destroyConfigHelper(); + + static CONTROLLER_PATCHER_RESULT_OR_ERROR doSamplingForDeviceSlot(u16 device_slot); + + static CONTROLLER_PATCHER_RESULT_OR_ERROR setRumbleActivated(bool value); + + static bool isRumbleActivated(); +}; + +#endif /* _CONTROLLER_PATCHER_H_ */ diff --git a/wiiu/controller_patcher/ControllerPatcherWrapper.cpp b/wiiu/controller_patcher/ControllerPatcherWrapper.cpp new file mode 100644 index 0000000000..795dc13a60 --- /dev/null +++ b/wiiu/controller_patcher/ControllerPatcherWrapper.cpp @@ -0,0 +1,39 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ + #include "controller_patcher/ControllerPatcher.hpp" + #include "controller_patcher/ControllerPatcherWrapper.h" + +extern "C" void ControllerPatcherInit(void){ + ControllerPatcher::Init(); + ControllerPatcher::disableControllerMapping(); + ControllerPatcher::startNetworkServer(); + ControllerPatcher::disableWiiUEnergySetting(); +} + +extern "C" CONTROLLER_PATCHER_RESULT_OR_ERROR setControllerDataFromHID(VPADStatus * data){ + ControllerPatcher::setControllerDataFromHID(data); +} + +extern "C" CONTROLLER_PATCHER_RESULT_OR_ERROR gettingInputAllDevices(InputData * output,s32 array_size){ + ControllerPatcher::gettingInputAllDevices(output,array_size); +} + +extern "C" void ControllerPatcherDeInit(void){ + ControllerPatcher::restoreWiiUEnergySetting(); + ControllerPatcher::stopNetworkServer(); + ControllerPatcher::DeInit(); +} diff --git a/wiiu/controller_patcher/ControllerPatcherWrapper.h b/wiiu/controller_patcher/ControllerPatcherWrapper.h new file mode 100644 index 0000000000..106d2aa1e7 --- /dev/null +++ b/wiiu/controller_patcher/ControllerPatcherWrapper.h @@ -0,0 +1,23 @@ +#ifndef _CONTROLLER_PATCHER_WRAPPER_H_ +#define _CONTROLLER_PATCHER_WRAPPER_H_ + +#include "wiiu/vpad.h" + +/* Main */ +#ifdef __cplusplus +extern "C" { +#endif + +#include "./patcher/ControllerPatcherDefs.h" + +//! C wrapper for our C++ functions +void ControllerPatcherInit(void); +void ControllerPatcherDeInit(void); +CONTROLLER_PATCHER_RESULT_OR_ERROR setControllerDataFromHID(VPADStatus * data); +CONTROLLER_PATCHER_RESULT_OR_ERROR gettingInputAllDevices(InputData * output,s32 array_size); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/wiiu/controller_patcher/config/ConfigParser.cpp b/wiiu/controller_patcher/config/ConfigParser.cpp new file mode 100644 index 0000000000..ee6b17f282 --- /dev/null +++ b/wiiu/controller_patcher/config/ConfigParser.cpp @@ -0,0 +1,337 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#include "./ConfigParser.hpp" +#include +#include +#include +#include + +ConfigParser::ConfigParser(std::string configData){ + this->content = configData; + this->contentLines = CPStringTools::StringSplit(content, "\n"); + + if(contentLines.empty()) + return; + + //remove the comments and make everything uppercase + for(u32 i = 0; i < contentLines.size(); i++){ + std::vector comments = CPStringTools::StringSplit(contentLines[i], "//"); + if(!comments.empty()){ + contentLines[i] = comments[0]; + } + //we want everything uppercase + std::transform(contentLines[i].begin(), contentLines[i].end(),contentLines[i].begin(), ::toupper); + } + + //remove empty lines + std::vector contentline2; + for(u32 i = 0; i < contentLines.size(); i++){ + if(strlen(contentLines[i].c_str()) > 0){ + contentline2.push_back(contentLines[i]); + } + } + contentLines = contentline2; + Init(); +} + +ConfigParser::~ConfigParser(){ + +} + +PARSE_TYPE ConfigParser::getType(){ + return type_b; +} + +void ConfigParser::setType(PARSE_TYPE newType){ + this->type_b = newType; +} + +u16 ConfigParser::getSlot(){ + return this->slot_b; +} + +void ConfigParser::setSlot(u16 newSlot){ + this->slot_b = newSlot; +} + +bool ConfigParser::Init(){ + if(contentLines.size() == 0){ + printf("ConfigParser::Init(line %d): Files seems to be empty. Make sure to have a proper header\n",__LINE__); + return false; + } + const char * line = contentLines[0].c_str(); + s32 len = strlen(line); + std::string identify; + if(line[0] == '[' && line[len-1] == ']'){ + identify = contentLines[0].substr(1,len-2); + }else{ + printf("ConfigParser::Init((line %d): Not a proper config file!\n",__LINE__); + return false; + } + + if(identify.compare("GAMEPAD") == 0){ + printf("ConfigParser::Init((line %d): Its a gamepad config file!\n",__LINE__); + setSlot(gGamePadSlot); + setType(PARSE_GAMEPAD); + }else if(identify.compare("MOUSE") == 0){ + printf("ConfigParser::Init((line %d): Its a mouse config file!\n",__LINE__); + setSlot(gMouseSlot); + setType(PARSE_MOUSE); + this->vid = HID_MOUSE_VID; + this->pid = HID_MOUSE_PID; + }else if(identify.compare("KEYBOARD") == 0){ + printf("ConfigParser::Init((line %d): Its a keyboard config file!\n",__LINE__); + setSlot(gHID_SLOT_KEYBOARD); + setType(PARSE_KEYBOARD); + this->vid = HID_KEYBOARD_VID; + this->pid = HID_KEYBOARD_PID; + }else{ + printf("ConfigParser::Init((line %d): Its a controller config file!\n",__LINE__); + + setSlot(getSlotController(identify)); + setType(PARSE_CONTROLLER); + } + + if(getSlot() == HID_INVALID_SLOT){ + return false; + } + + ConfigReader::increaseNumberOfLoadedFiles(); + + return true; +} + +void ConfigParser::parseSingleLine(std::string line){ + std::vector cur_values = CPStringTools::StringSplit(line,"="); + if(cur_values.size() != 2){ + if(HID_DEBUG || cur_values.size() > 2){ printf("ConfigParser::parseSingleLine(line %d): Not a valid key=pair line %s\n",__LINE__,line.c_str()); } + return; + }else{ + u16 hid_slot = getSlot(); + + if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): leftpart = \"%s\" \n",__LINE__,cur_values[0].c_str()); } + if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): rightpart = \"%s\" \n",__LINE__,cur_values[1].c_str()); } + s32 keyslot = -1; + + if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Checking single value\n",__LINE__); } + if(getType() == PARSE_GAMEPAD || getType() == PARSE_KEYBOARD){ + keyslot = ConfigValues::getKeySlotGamePad(cur_values[0]); + }else if(getType() == PARSE_MOUSE){ + keyslot = ConfigValues::getKeySlotMouse(cur_values[0]); + }else{ + keyslot = ConfigValues::getKeySlotDefaultSingleValue(cur_values[0]); + } + if(keyslot != -1){ + if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Its a single value\n",__LINE__); } + long rightValue = -1; + bool valueSet = false; + if(cur_values[0].compare("DPAD_MODE") == 0){ + const u8 * values_ = NULL; + if((values_ = ConfigValues::getValuesStickPreset(cur_values[1])) != NULL){ + if(values_[STICK_CONF_MAGIC_VERSION] != STICK_CONF_MAGIC_VALUE) + if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Settings preset DPAD MODE and Mask\n",__LINE__); } + config_controller[hid_slot][CONTRPS_DPAD_MODE][0] = CONTROLLER_PATCHER_VALUE_SET; + config_controller[hid_slot][CONTRPS_DPAD_MODE][1] = values_[CONTRDPAD_MODE]; + if(values_[CONTRDPAD_MASK] != 0x00){ + config_controller[hid_slot][CONTRPS_DPAD_MASK][0] = CONTROLLER_PATCHER_VALUE_SET; + config_controller[hid_slot][CONTRPS_DPAD_MASK][1] = values_[CONTRDPAD_MASK]; + } + valueSet = true; + } + } + + if(!valueSet){ + if(getType() == PARSE_KEYBOARD){ + if((rightValue = ConfigValues::getPresetValuesKeyboard(cur_values[1]))!= -1){ + if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Used pre-defined Keyboard! \"%s\" is %d\n",__LINE__,cur_values[1].c_str(),rightValue);} + }else{ + if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): I need to parse %s\n",__LINE__,cur_values[1].c_str()); } + char * ptr; + rightValue = strtol(cur_values[1].c_str(),&ptr,16); + } + }else{ + rightValue = ConfigValues::getPresetValue(cur_values[1]); + + if(getType() == PARSE_MOUSE){ //No parsing for the mouse + if(rightValue == -1){ + if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Invalid mouse value, lets skip it %s\n",__LINE__,cur_values[1].c_str()); } + return; + } + }else{ + if(rightValue == -1){ + if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): I need to parse %s\n",__LINE__,cur_values[1].c_str()); } + char * ptr; + rightValue = strtol(cur_values[1].c_str(),&ptr,16); + } + } + } + if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Setting value to %d\n",__LINE__,rightValue); } + + config_controller[hid_slot][keyslot][0] = CONTROLLER_PATCHER_VALUE_SET; + config_controller[hid_slot][keyslot][1] = rightValue; + } + }else{ + if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Check pair value\n",__LINE__); } + keyslot = ConfigValues::getKeySlotDefaultPairedValue(cur_values[0]); + if(keyslot != -1){ + if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Its a pair value\n",__LINE__); } + + if(!ConfigValues::getInstance()->setIfValueIsAControllerPreset(cur_values[1],getSlot(),keyslot)){ + if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): And its no preset\n",__LINE__); } + std::vector rightvalues = CPStringTools::StringSplit(cur_values[1],","); + + if(rightvalues.size() != 2){ + printf("ConfigParser::parseSingleLine(line %d): %d instead of 2 key=values pairs in line\n",__LINE__,rightvalues.size()); + return; + } + + char * ptr; + long firstValue = strtol(rightvalues[0].c_str(),&ptr,16); + long secondValue = strtol(rightvalues[1].c_str(),&ptr,16); + config_controller[hid_slot][keyslot][0] = firstValue; + config_controller[hid_slot][keyslot][1] = secondValue; + + if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Set %02X,%02X\n",__LINE__,firstValue,secondValue); } + }else{ + if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Found preset value!!\n",__LINE__); } + } + }else{ + printf("ConfigParser::parseSingleLine(line %d): The setting \"%s\" is unknown!\n",__LINE__,cur_values[0].c_str()); + } + } + } +} + +bool ConfigParser::resetConfig(){ + s32 slot = getSlot(); + if(slot >= gHIDMaxDevices) return false; + for(s32 j = (CONTRPS_PID+1);j< CONTRPS_MAX_VALUE;j++){ + config_controller[slot][j][0] = CONTROLLER_PATCHER_INVALIDVALUE; + config_controller[slot][j][1] = CONTROLLER_PATCHER_INVALIDVALUE; + } + return true; +} + +s32 ConfigParser::getSlotController(std::string identify){ + if(HID_DEBUG){ printf("ConfigParser::getSlotController(line %d): Getting Controller Slot\n",__LINE__); } + + std::vector values = CPStringTools::StringSplit(identify,","); + + if(values.size() != 2){ + printf("ConfigParser::getSlotController(line %d): You need to provide a VID and PID. e.g. \"[vid=0x451,pid=0x152]\". (%s)\n",__LINE__,identify.c_str()); + return HID_INVALID_SLOT; + } + + s32 vid = getValueFromKeyValue(values[0],"VID","="); + if(vid < 0){ + return HID_INVALID_SLOT; + } + s32 pid = getValueFromKeyValue(values[1],"PID","="); + if(pid < 0){ + return HID_INVALID_SLOT; + } + printf("ConfigParser::getSlotController(line %d): VID: %04x PID: %04x\n",__LINE__,vid,pid); + + this->vid = vid; + this->pid = pid; + DeviceInfo deviceinfo; + memset(&deviceinfo,0,sizeof(deviceinfo)); + deviceinfo.vidpid.vid = vid; + deviceinfo.vidpid.pid = pid; + s32 result = ControllerPatcherUtils::getDeviceInfoFromVidPid(&deviceinfo); + s32 slot = deviceinfo.slotdata.deviceslot; + s32 hid = 0; + if(result < 0){ + if(HID_DEBUG){ printf("ConfigParser::getSlotController(line %d): Its a new controller, lets save it\n",__LINE__); } + + HIDSlotData slotdata; + ControllerPatcherUtils::getNextSlotData(&slotdata); + + slot = slotdata.deviceslot; + hid = slotdata.hidmask; + + if(slot >= gHIDMaxDevices){ + printf("ConfigParser::getSlotController(line %d): ConfigParser::getSlotController: We don't a space for a new controller, please delete .inis\n",__LINE__); + return HID_INVALID_SLOT; + } + if(HID_DEBUG){ printf("ConfigParser::getSlotController(line %d): Got new slot! slot: %d hid %s .. Lets registrate it!\n",__LINE__,slot,CPStringTools::byte_to_binary(hid)); } + config_controller[slot][CONTRPS_VID][0] = (vid & 0xFF00) >> 8; + config_controller[slot][CONTRPS_VID][1] = (vid & 0x00FF); + config_controller[slot][CONTRPS_PID][0] = (pid & 0xFF00) >> 8; + config_controller[slot][CONTRPS_PID][1] = (pid & 0x00FF); + + if(HID_DEBUG){ + printf("ConfigParser::getSlotController(line %d): Saved vid: %04X pid: %04X\n",__LINE__, + config_controller[slot][CONTRPS_VID][0] * 0x100 + config_controller[slot][CONTRPS_VID][1], + config_controller[slot][CONTRPS_PID][0] * 0x100 + config_controller[slot][CONTRPS_PID][1]); } + + config_controller_hidmask[slot] = hid; + if(HID_DEBUG){ printf("ConfigParser::getSlotController(line %d): Saved the hid\n",__LINE__); } + + }else{ + if(slot < gHIDMaxDevices){ + hid = config_controller_hidmask[slot]; + if(HID_DEBUG){ printf("ConfigParser::getSlotController(line %d): >>>>>> found slot %d (hid:%s). Modifing existing data <<<<<<<<\n",__LINE__,slot,CPStringTools::byte_to_binary(hid)); } + printf("ConfigParser::getSlotController(line %d): We already have data of this controller, lets modify it\n",__LINE__); + }else{ + printf("ConfigParser::getSlotController(line %d): Something really odd happend to the slots. %d is bigger then max (%d)\n",__LINE__,slot,gHIDMaxDevices); + return HID_INVALID_SLOT; + } + } + + printf("ConfigParser::getSlotController(line %d): using slot: %d hid %08X\n",__LINE__,slot,hid); + return slot; +} + +bool ConfigParser::parseIni(){ + if(getSlot() == HID_INVALID_SLOT){ + printf("ConfigParser::parseIni(line %d): Couldn't parse file. Not a valid slot. Probably broken config. Or you tried to have more than %d devices\n",__LINE__,getType(),gHIDMaxDevices); + } + + if(HID_DEBUG){ printf("ConfigParser::parseIni(line %d): Parsing content, type %d\n",__LINE__,getType()); } + + s32 start = 1; + if(contentLines[1].compare("[IGNOREDEFAULT]") == 0){ + resetConfig(); + printf("ConfigParser::parseIni(line %d): Ignoring existing settings of this device\n",__LINE__); + start++; + } + + for(u32 i = start; i < contentLines.size(); i++){ + if(HID_DEBUG){ printf("ConfigParser::parseIni(line %d): line %d: \"%s\" \n",__LINE__,(i+1),contentLines[i].c_str()); } + parseSingleLine(contentLines[i]); + } + + if(HID_DEBUG){ printf("ConfigParser::parseIni(line %d): Parsing of the file is done.\n",__LINE__); } + return true; +} + +s32 ConfigParser::getValueFromKeyValue(std::string value_pair,std::string expectedKey,std::string delimiter){ + std::vector string_value = CPStringTools::StringSplit(value_pair,delimiter); + if(string_value.size() != 2){ + if(HID_DEBUG || string_value.size() > 2){ printf("ConfigParser::getValueFromKeyValue(line %d): Not a valid key=pair line %s\n",__LINE__,value_pair.c_str()); } + return -1; + } + if(string_value[0].compare(expectedKey) != 0){ + printf("ConfigParser::getValueFromKeyValue(line %d): Key part not %s, its %s",__LINE__,expectedKey.c_str(),string_value[0].c_str()); + return -1; + } + char * ptr; + s32 value = strtol(string_value[1].c_str(),&ptr,16); + + return value; +} diff --git a/wiiu/controller_patcher/config/ConfigParser.hpp b/wiiu/controller_patcher/config/ConfigParser.hpp new file mode 100644 index 0000000000..d00a77ee7f --- /dev/null +++ b/wiiu/controller_patcher/config/ConfigParser.hpp @@ -0,0 +1,74 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#ifndef _ConfigParser_H_ +#define _ConfigParser_H_ + +#include +#include +#include + +#include + +#include "../ControllerPatcher.hpp" + +enum PARSE_TYPE{ + PARSE_CONTROLLER, + PARSE_GAMEPAD, + PARSE_MOUSE, + PARSE_KEYBOARD +}; + +class ConfigParser{ + friend class ConfigReader; + friend class ControllerPatcher; +private: + //!Constructor + ConfigParser(std::string configData); + //!Destructor + ~ConfigParser(); + + PARSE_TYPE getType(); + void setType(PARSE_TYPE newType); + + u16 getSlot(); + void setSlot(u16 newSlot); + + bool parseIni(); + + bool Init(); + + bool parseConfigString(std::string content); + + s32 getSlotController(std::string identify); + + s32 checkExistingController(s32 vid, s32 pid); + + s32 getValueFromKeyValue(std::string value_pair,std::string expectedKey,std::string delimiter); + + bool resetConfig(); + + void parseSingleLine(std::string line); + u16 slot_b; + PARSE_TYPE type_b; + + u16 vid; + u16 pid; + + std::string content; + std::vector contentLines; +}; +#endif diff --git a/wiiu/controller_patcher/config/ConfigValues.cpp b/wiiu/controller_patcher/config/ConfigValues.cpp new file mode 100644 index 0000000000..57de6e3b8b --- /dev/null +++ b/wiiu/controller_patcher/config/ConfigValues.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#include "./ConfigValues.hpp" +#include +#include +#include + +ConfigValues *ConfigValues::instance = NULL; + +ConfigValues::ConfigValues(){ + InitValues(); +} + +ConfigValues::~ConfigValues(){ + if(HID_DEBUG){ printf("ConfigValues::~ConfigValues(line %d){\n",__LINE__);} +} + +const u8 * ConfigValues::getValuesForPreset(std::map values,std::string possibleValue){ + std::map::iterator it; + it = values.find(possibleValue); + if (it != values.end()){ + return it->second; + } + return NULL; +} + +bool ConfigValues::setIfValueIsAControllerPresetEx(std::string value,s32 slot,s32 keyslot){ + if(setIfValueIsPreset(presetGCValues,value,slot,keyslot)) return true; + if(setIfValueIsPreset(presetDS3Values,value,slot,keyslot)) return true; + if(setIfValueIsPreset(presetDS4Values,value,slot,keyslot)) return true; + if(setIfValueIsPreset(presetXInputValues,value,slot,keyslot)) return true; + if(setIfValueIsPreset(presetSwitchProValues,value,slot,keyslot)) return true; + return false; +} + +//We need this function here so we can use preset sticks. +bool ConfigValues::setIfValueIsPreset(std::map values,std::string possibleValue,s32 slot,s32 keyslot){ + if(slot > gHIDMaxDevices || slot < 0 || keyslot < 0 || keyslot >= CONTRPS_MAX_VALUE){ + return false; + } + const u8 * values_ = NULL; + if( keyslot == CONTRPS_VPAD_BUTTON_L_STICK_X || + keyslot == CONTRPS_VPAD_BUTTON_L_STICK_Y || + keyslot == CONTRPS_VPAD_BUTTON_R_STICK_X || + keyslot == CONTRPS_VPAD_BUTTON_R_STICK_Y){ + if(HID_DEBUG){ printf("ConfigValues::setIfValueIsPreset(line %d): This may be a predefined stick %s\n",__LINE__,possibleValue.c_str());} + if((values_ = ConfigValues::getValuesStickPreset(possibleValue)) != NULL){ + if(HID_DEBUG){ printf("ConfigValues::setIfValueIsPreset(line %d): Found predefined stick!\n",__LINE__);} + config_controller[slot][keyslot][0] = values_[STICK_CONF_BYTE]; //CONTRPS_VPAD_BUTTON_L_STICK_X + config_controller[slot][keyslot][1] = values_[STICK_CONF_DEFAULT]; + config_controller[slot][keyslot+DEF_STICK_OFFSET_INVERT][0] = CONTROLLER_PATCHER_VALUE_SET; //CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT + config_controller[slot][keyslot+DEF_STICK_OFFSET_INVERT][1] = values_[STICK_CONF_INVERT]; + config_controller[slot][keyslot+DEF_STICK_OFFSET_DEADZONE][0] = CONTROLLER_PATCHER_VALUE_SET; //CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE + config_controller[slot][keyslot+DEF_STICK_OFFSET_DEADZONE][1] = values_[STICK_CONF_DEADZONE]; + config_controller[slot][keyslot+DEF_STICK_OFFSET_MINMAX][0] = values_[STICK_CONF_MIN]; //CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX + config_controller[slot][keyslot+DEF_STICK_OFFSET_MINMAX][1] = values_[STICK_CONF_MAX]; + + return true; + } + } + + if((values_ = getValuesForPreset(values,possibleValue)) != NULL){ + config_controller[slot][keyslot][0] = values_[0]; + config_controller[slot][keyslot][1] = values_[1]; + return true; + } + return false; +} + + +s32 ConfigValues::getValueFromMap(std::map values,std::string nameOfString){ + std::map::iterator it; + it = values.find(nameOfString); + if (it != values.end()){ + return it->second; + } + + //Value not found + return -1; +} + +s32 ConfigValues::getPresetValueEx(std::string possibleString){ + s32 rightValue = -1; + if((rightValue = getValueFromMap(gGamePadValuesToCONTRPSString,possibleString))!= -1){ + if(HID_DEBUG){ printf("ConfigValues::getPresetValueEx(line %d): Used pre-defined VPAD_VALUE! \"%s\" is %d\n",__LINE__,possibleString.c_str(),rightValue); } + }else if((rightValue = getValueFromMap(presetValues,possibleString))!= -1){ + if(HID_DEBUG){ printf("ConfigValues::getPresetValueEx(line %d): Used pre-defined value! \"%s\" is %d\n",__LINE__,possibleString.c_str(),rightValue); } + } + return rightValue; +} + + void ConfigValues::addDeviceNameEx(u16 vid,u16 pid,std::string value){ + deviceNames[CPStringTools::strfmt("%04X%04X",vid,pid).c_str()] = value; + } + +std::string ConfigValues::getStringByVIDPIDEx(u16 vid,u16 pid){ + std::string result = ""; + std::map::iterator it; + + it = deviceNames.find(CPStringTools::strfmt("%04X%04X",vid,pid)); + if (it != deviceNames.end()){ + result = it->second; + }else{ + result = CPStringTools::strfmt("VID: 0x%04X\nPID: 0x%04X",vid,pid); + } + return result; +} diff --git a/wiiu/controller_patcher/config/ConfigValues.hpp b/wiiu/controller_patcher/config/ConfigValues.hpp new file mode 100644 index 0000000000..27a835cf40 --- /dev/null +++ b/wiiu/controller_patcher/config/ConfigValues.hpp @@ -0,0 +1,569 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#ifndef _ConfigValues_H_ +#define _ConfigValues_H_ + +#include +#include +#include + +#include "../ControllerPatcher.hpp" + +class ConfigValues +{ +friend class ConfigParser; +friend class ControllerPatcher; +private: + static ConfigValues *getInstance() { + if(instance == NULL){ + printf("ConfigValues: We need a new instance!!!\n"); + instance = new ConfigValues(); + } + return instance; + } + + static void destroyInstance() { + if(instance){ + delete instance; + instance = NULL; + } + } + + /** + Returns NULL if not a preset! + **/ + static const u8 * getValuesStickPreset(std::string possibleValue) + { + ConfigValues * cur_instance = getInstance(); + if(cur_instance == NULL) return NULL; + return cur_instance->getValuesForPreset(cur_instance->presetSticks,possibleValue); + } + + /** + Returns -1 if not found + **/ + static s32 getKeySlotGamePad(std::string possibleValue) + { + ConfigValues * cur_instance = getInstance(); + if(cur_instance == NULL) return -1; + return cur_instance->getValueFromMap(cur_instance->CONTPRStringToValue,possibleValue); + } + /** + Returns -1 if not found + **/ + static s32 getKeySlotMouse(std::string possibleValue) + { + ConfigValues * cur_instance = getInstance(); + if(cur_instance == NULL) return -1; + return cur_instance->getValueFromMap(cur_instance->mouseLeftValues,possibleValue); + } + + /** + Returns -1 if not found + **/ + static s32 getKeySlotDefaultSingleValue(std::string possibleValue) + { + ConfigValues * cur_instance = getInstance(); + if(cur_instance == NULL) return -1; + return cur_instance->getValueFromMap(cur_instance->CONTPRStringToValueSingle,possibleValue); + } + + /** + Returns -1 if not found + **/ + static s32 getKeySlotDefaultPairedValue(std::string possibleValue) + { + ConfigValues * cur_instance = getInstance(); + if(cur_instance == NULL) return -1; + return cur_instance->getValueFromMap(cur_instance->CONTPRStringToValue,possibleValue); + } + + /** + Returns -1 if not found + **/ + static s32 getPresetValuesKeyboard(std::string possibleValue) + { + ConfigValues * cur_instance = getInstance(); + if(cur_instance == NULL) return -1; + return cur_instance->getValueFromMap(cur_instance->presetKeyboardValues,possibleValue); + } + + /** + Returns -1 if not found + **/ + static s32 getPresetValue(std::string possibleValue) + { + ConfigValues * cur_instance = getInstance(); + if(cur_instance == NULL) return -1; + return cur_instance->getPresetValueEx(possibleValue); + } + + /** + Returns -1 if not found + **/ + static s32 setIfValueIsAControllerPreset(std::string value,s32 slot,s32 keyslot) + { + ConfigValues * cur_instance = getInstance(); + if(cur_instance == NULL) return -1; + return cur_instance->setIfValueIsAControllerPresetEx(value,slot,keyslot); + } + + static void addDeviceName(u16 vid,u16 pid,std::string value){ + ConfigValues * cur_instance = getInstance(); + if(cur_instance != NULL){ + cur_instance->addDeviceNameEx(vid,pid,value); + } + } + + /** + Returns empty String if not found + **/ + static std::string getStringByVIDPID(u16 vid,u16 pid){ + ConfigValues * cur_instance = getInstance(); + if(cur_instance == NULL) return ""; + return cur_instance->getStringByVIDPIDEx(vid,pid); + } + + //!Constructor + ConfigValues(); + //!Destructor + ~ConfigValues(); + + static ConfigValues *instance; + + std::map mouseLeftValues; + std::map CONTPRStringToValue; + std::map CONTPRStringToValueSingle; + std::map presetValues; + std::map gGamePadValuesToCONTRPSString; + std::map presetKeyboardValues; + + std::map deviceNames; + + std::map presetGCValues; + std::map presetDS3Values; + std::map presetDS4Values; + std::map presetXInputValues; + std::map presetSwitchProValues; + std::map presetSticks; + + s32 getValueFromMap(std::map values,std::string nameOfString); + + bool checkIfValueIsAControllerPreset(std::string value,s32 slot,s32 keyslot); + + s32 getPresetValueEx(std::string possibleString); + + void InitValues(){ + printf("ConfigValues::InitValues: Init values for the configuration\n"); + CONTPRStringToValue["VPAD_BUTTON_A"] = CONTRPS_VPAD_BUTTON_A; + CONTPRStringToValue["VPAD_BUTTON_B"] = CONTRPS_VPAD_BUTTON_B; + CONTPRStringToValue["VPAD_BUTTON_X"] = CONTRPS_VPAD_BUTTON_X; + CONTPRStringToValue["VPAD_BUTTON_Y"] = CONTRPS_VPAD_BUTTON_Y; + /* Normal DPAD */ + CONTPRStringToValue["VPAD_BUTTON_LEFT"] = CONTRPS_VPAD_BUTTON_LEFT; + CONTPRStringToValue["VPAD_BUTTON_RIGHT"] = CONTRPS_VPAD_BUTTON_RIGHT; + CONTPRStringToValue["VPAD_BUTTON_UP"] = CONTRPS_VPAD_BUTTON_UP; + CONTPRStringToValue["VPAD_BUTTON_DOWN"] = CONTRPS_VPAD_BUTTON_DOWN; + /* DPAD hat mode */ + CONTPRStringToValue["VPAD_BUTTON_DPAD_N"] = CONTRPS_VPAD_BUTTON_DPAD_N; + CONTPRStringToValue["VPAD_BUTTON_DPAD_NE"] = CONTRPS_VPAD_BUTTON_DPAD_NE; + CONTPRStringToValue["VPAD_BUTTON_DPAD_E"] = CONTRPS_VPAD_BUTTON_DPAD_E; + CONTPRStringToValue["VPAD_BUTTON_DPAD_SE"] = CONTRPS_VPAD_BUTTON_DPAD_SE; + CONTPRStringToValue["VPAD_BUTTON_DPAD_S"] = CONTRPS_VPAD_BUTTON_DPAD_S; + CONTPRStringToValue["VPAD_BUTTON_DPAD_SW"] = CONTRPS_VPAD_BUTTON_DPAD_SW; + CONTPRStringToValue["VPAD_BUTTON_DPAD_W"] = CONTRPS_VPAD_BUTTON_DPAD_W; + CONTPRStringToValue["VPAD_BUTTON_DPAD_NW"] = CONTRPS_VPAD_BUTTON_DPAD_NW; + CONTPRStringToValue["VPAD_BUTTON_DPAD_NEUTRAL"] = CONTRPS_VPAD_BUTTON_DPAD_NEUTRAL; + /* DPAD Absolute mode */ + CONTPRStringToValue["VPAD_BUTTON_DPAD_ABS_UP"] = CONTRPS_VPAD_BUTTON_DPAD_ABS_UP; + CONTPRStringToValue["VPAD_BUTTON_DPAD_ABS_DOWN"] = CONTRPS_VPAD_BUTTON_DPAD_ABS_DOWN; + CONTPRStringToValue["VPAD_BUTTON_DPAD_ABS_LEFT"] = CONTRPS_VPAD_BUTTON_DPAD_ABS_LEFT; + CONTPRStringToValue["VPAD_BUTTON_DPAD_ABS_RIGHT"] = CONTRPS_VPAD_BUTTON_DPAD_ABS_RIGHT; + /* */ + CONTPRStringToValue["VPAD_BUTTON_ZL"] = CONTRPS_VPAD_BUTTON_ZL; + CONTPRStringToValue["VPAD_BUTTON_ZR"] = CONTRPS_VPAD_BUTTON_ZR; + CONTPRStringToValue["VPAD_BUTTON_L"] = CONTRPS_VPAD_BUTTON_L; + CONTPRStringToValue["VPAD_BUTTON_R"] = CONTRPS_VPAD_BUTTON_R; + CONTPRStringToValue["VPAD_BUTTON_PLUS"] = CONTRPS_VPAD_BUTTON_PLUS; + CONTPRStringToValue["VPAD_BUTTON_MINUS"] = CONTRPS_VPAD_BUTTON_MINUS; + CONTPRStringToValue["VPAD_BUTTON_HOME"] = CONTRPS_VPAD_BUTTON_HOME; + CONTPRStringToValue["VPAD_BUTTON_SYNC"] = CONTRPS_VPAD_BUTTON_SYNC; + CONTPRStringToValue["VPAD_BUTTON_STICK_R"] = CONTRPS_VPAD_BUTTON_STICK_R; + CONTPRStringToValue["VPAD_BUTTON_STICK_L"] = CONTRPS_VPAD_BUTTON_STICK_L; + + CONTPRStringToValue["VPAD_STICK_R_EMULATION_LEFT"] = CONTRPS_VPAD_STICK_R_EMULATION_LEFT; + CONTPRStringToValue["VPAD_STICK_R_EMULATION_RIGHT"] = CONTRPS_VPAD_STICK_R_EMULATION_RIGHT; + CONTPRStringToValue["VPAD_STICK_R_EMULATION_UP"] = CONTRPS_VPAD_STICK_R_EMULATION_UP; + CONTPRStringToValue["VPAD_STICK_R_EMULATION_DOWN"] = CONTRPS_VPAD_STICK_R_EMULATION_DOWN; + CONTPRStringToValue["VPAD_STICK_L_EMULATION_LEFT"] = CONTRPS_VPAD_STICK_L_EMULATION_LEFT; + CONTPRStringToValue["VPAD_STICK_L_EMULATION_RIGHT"] = CONTRPS_VPAD_STICK_L_EMULATION_RIGHT; + CONTPRStringToValue["VPAD_STICK_L_EMULATION_UP"] = CONTRPS_VPAD_STICK_L_EMULATION_UP; + CONTPRStringToValue["VPAD_STICK_L_EMULATION_DOWN"] = CONTRPS_VPAD_STICK_L_EMULATION_DOWN; + + CONTPRStringToValue["VPAD_L_STICK_UP"] = CONTRPS_VPAD_BUTTON_L_STICK_UP; + CONTPRStringToValue["VPAD_L_STICK_DOWN"] = CONTRPS_VPAD_BUTTON_L_STICK_DOWN; + CONTPRStringToValue["VPAD_L_STICK_LEFT"] = CONTRPS_VPAD_BUTTON_L_STICK_LEFT; + CONTPRStringToValue["VPAD_L_STICK_RIGHT"] = CONTRPS_VPAD_BUTTON_L_STICK_RIGHT; + + CONTPRStringToValue["VPAD_R_STICK_UP"] = CONTRPS_VPAD_BUTTON_R_STICK_UP; + CONTPRStringToValue["VPAD_R_STICK_DOWN"] = CONTRPS_VPAD_BUTTON_R_STICK_DOWN; + CONTPRStringToValue["VPAD_R_STICK_LEFT"] = CONTRPS_VPAD_BUTTON_R_STICK_LEFT; + CONTPRStringToValue["VPAD_R_STICK_RIGHT"] = CONTRPS_VPAD_BUTTON_R_STICK_RIGHT; + + CONTPRStringToValue["VPAD_L_STICK_X"] = CONTRPS_VPAD_BUTTON_L_STICK_X; + CONTPRStringToValue["VPAD_L_STICK_X_MINMAX"] = CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX; + CONTPRStringToValue["VPAD_L_STICK_Y"] = CONTRPS_VPAD_BUTTON_L_STICK_Y; + CONTPRStringToValue["VPAD_L_STICK_Y_MINMAX"] = CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX; + CONTPRStringToValue["VPAD_R_STICK_X"] = CONTRPS_VPAD_BUTTON_R_STICK_X; + CONTPRStringToValue["VPAD_R_STICK_X_MINMAX"] = CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX; + CONTPRStringToValue["VPAD_R_STICK_Y"] = CONTRPS_VPAD_BUTTON_R_STICK_Y; + CONTPRStringToValue["VPAD_R_STICK_Y_MINMAX"] = CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX; + CONTPRStringToValue["VPAD_BUTTON_TV"] = CONTRPS_VPAD_BUTTON_TV; + + CONTPRStringToValue["DOUBLE_USE_BUTTON_ACTIVATOR"] = CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR, + CONTPRStringToValue["INPUT_FILTER"] = CONTRPS_INPUT_FILTER; + CONTPRStringToValue["PAD1_FILTER"] = CONTRPS_PAD1_FILTER; + CONTPRStringToValue["PAD2_FILTER"] = CONTRPS_PAD2_FILTER; + CONTPRStringToValue["PAD3_FILTER"] = CONTRPS_PAD3_FILTER; + CONTPRStringToValue["PAD4_FILTER"] = CONTRPS_PAD4_FILTER; + CONTPRStringToValue["PAD5_FILTER"] = CONTRPS_PAD5_FILTER; + + CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_1_PRESSED"] = CONTRPS_DOUBLE_USE_BUTTON_1_PRESSED; + CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_2_PRESSED"] = CONTRPS_DOUBLE_USE_BUTTON_2_PRESSED; + CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_3_PRESSED"] = CONTRPS_DOUBLE_USE_BUTTON_3_PRESSED; + CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_4_PRESSED"] = CONTRPS_DOUBLE_USE_BUTTON_4_PRESSED; + CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_5_PRESSED"] = CONTRPS_DOUBLE_USE_BUTTON_5_PRESSED; + CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_1_RELEASED"] = CONTRPS_DOUBLE_USE_BUTTON_1_RELEASED; + CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_2_RELEASED"] = CONTRPS_DOUBLE_USE_BUTTON_2_RELEASED; + CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_3_RELEASED"] = CONTRPS_DOUBLE_USE_BUTTON_3_RELEASED; + CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_4_RELEASED"] = CONTRPS_DOUBLE_USE_BUTTON_4_RELEASED; + CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_5_RELEASED"] = CONTRPS_DOUBLE_USE_BUTTON_5_RELEASED; + + CONTPRStringToValueSingle["BUF_SIZE"] = CONTRPS_BUF_SIZE; + CONTPRStringToValueSingle["DPAD_MODE"] = CONTRPS_DPAD_MODE; + CONTPRStringToValueSingle["DPAD_MASK"] = CONTRPS_DPAD_MASK; + CONTPRStringToValueSingle["VPAD_L_STICK_X_DEADZONE"] = CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE; + CONTPRStringToValueSingle["VPAD_L_STICK_Y_DEADZONE"] = CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE; + CONTPRStringToValueSingle["VPAD_R_STICK_X_DEADZONE"] = CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE; + CONTPRStringToValueSingle["VPAD_R_STICK_Y_DEADZONE"] = CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE; + CONTPRStringToValueSingle["VPAD_L_STICK_X_INVERT"] = CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT; + CONTPRStringToValueSingle["VPAD_L_STICK_Y_INVERT"] = CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT; + CONTPRStringToValueSingle["VPAD_R_STICK_X_INVERT"] = CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT; + CONTPRStringToValueSingle["VPAD_R_STICK_Y_INVERT"] = CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT; + + CONTPRStringToValueSingle["DOUBLE_USE"] = CONTRPS_DOUBLE_USE; + CONTPRStringToValueSingle["PAD_COUNT"] = CONTRPS_PAD_COUNT; + + mouseLeftValues["LEFT_CLICK"] = CONTRPS_VPAD_BUTTON_LEFT; + mouseLeftValues["RIGHT_CLICK"] = CONTRPS_VPAD_BUTTON_RIGHT; + mouseLeftValues["EMULATED_STICK"] = CONTRPS_MOUSE_STICK; + + presetGCValues["GC_BUTTON_A"] = HID_GC_BUTTON_A; + presetGCValues["GC_BUTTON_B"] = HID_GC_BUTTON_B; + presetGCValues["GC_BUTTON_X"] = HID_GC_BUTTON_X; + presetGCValues["GC_BUTTON_Y"] = HID_GC_BUTTON_Y; + presetGCValues["GC_BUTTON_LEFT"] = HID_GC_BUTTON_LEFT; + presetGCValues["GC_BUTTON_RIGHT"] = HID_GC_BUTTON_RIGHT; + presetGCValues["GC_BUTTON_DOWN"] = HID_GC_BUTTON_DOWN; + presetGCValues["GC_BUTTON_UP"] = HID_GC_BUTTON_UP; + presetGCValues["GC_BUTTON_START"] = HID_GC_BUTTON_START; + presetGCValues["GC_BUTTON_Z"] = HID_GC_BUTTON_Z; + presetGCValues["GC_BUTTON_L"] = HID_GC_BUTTON_L; + presetGCValues["GC_BUTTON_R"] = HID_GC_BUTTON_R; + + presetDS3Values["DS3_BUTTON_CROSS"] = HID_DS3_BUTTON_CROSS; + presetDS3Values["DS3_BUTTON_CIRCLE"] = HID_DS3_BUTTON_CIRCLE; + presetDS3Values["DS3_BUTTON_SQUARE"] = HID_DS3_BUTTON_SQUARE; + presetDS3Values["DS3_BUTTON_TRIANGLE"] = HID_DS3_BUTTON_TRIANGLE; + + presetDS3Values["DS3_BUTTON_L1"] = HID_DS3_BUTTON_L1; + presetDS3Values["DS3_BUTTON_L2"] = HID_DS3_BUTTON_L2; + presetDS3Values["DS3_BUTTON_L3"] = HID_DS3_BUTTON_L3; + presetDS3Values["DS3_BUTTON_R1"] = HID_DS3_BUTTON_R1; + presetDS3Values["DS3_BUTTON_R2"] = HID_DS3_BUTTON_R2; + presetDS3Values["DS3_BUTTON_R3"] = HID_DS3_BUTTON_R3; + + presetDS3Values["DS3_BUTTON_SELECT"] = HID_DS3_BUTTON_SELECT; + presetDS3Values["DS3_BUTTON_START"] = HID_DS3_BUTTON_START; + presetDS3Values["DS3_BUTTON_LEFT"] = HID_DS3_BUTTON_LEFT; + presetDS3Values["DS3_BUTTON_RIGHT"] = HID_DS3_BUTTON_RIGHT; + presetDS3Values["DS3_BUTTON_UP"] = HID_DS3_BUTTON_UP; + presetDS3Values["DS3_BUTTON_DOWN"] = HID_DS3_BUTTON_DOWN; + presetDS3Values["DS3_BUTTON_GUIDE"] = HID_DS3_BUTTON_GUIDE; + + presetDS4Values["DS4_BUTTON_CROSS"] = HID_DS4_BUTTON_CROSS; + presetDS4Values["DS4_BUTTON_CIRCLE"] = HID_DS4_BUTTON_CIRCLE; + presetDS4Values["DS4_BUTTON_SQUARE"] = HID_DS4_BUTTON_SQUARE; + presetDS4Values["DS4_BUTTON_TRIANGLE"] = HID_DS4_BUTTON_TRIANGLE; + + presetDS4Values["DS4_BUTTON_L1"] = HID_DS4_BUTTON_L1; + presetDS4Values["DS4_BUTTON_L2"] = HID_DS4_BUTTON_L2; + presetDS4Values["DS4_BUTTON_L3"] = HID_DS4_BUTTON_L3; + presetDS4Values["DS4_BUTTON_R1"] = HID_DS4_BUTTON_R1; + presetDS4Values["DS4_BUTTON_R2"] = HID_DS4_BUTTON_R2; + presetDS4Values["DS4_BUTTON_R3"] = HID_DS4_BUTTON_R3; + + presetDS4Values["DS4_BUTTON_SHARE"] = HID_DS4_BUTTON_SHARE; + presetDS4Values["DS4_BUTTON_OPTIONS"] = HID_DS4_BUTTON_OPTIONS; + presetDS4Values["DS4_BUTTON_DPAD_TYPE"] = HID_DS4_BUTTON_DPAD_TYPE; + + presetDS4Values["DS4_BUTTON_DPAD_N"] = HID_DS4_BUTTON_DPAD_N; + presetDS4Values["DS4_BUTTON_DPAD_NE"] = HID_DS4_BUTTON_DPAD_NE; + presetDS4Values["DS4_BUTTON_DPAD_E"] = HID_DS4_BUTTON_DPAD_E; + presetDS4Values["DS4_BUTTON_DPAD_SE"] = HID_DS4_BUTTON_DPAD_SE; + presetDS4Values["DS4_BUTTON_DPAD_S"] = HID_DS4_BUTTON_DPAD_S; + presetDS4Values["DS4_BUTTON_DPAD_SW"] = HID_DS4_BUTTON_DPAD_SW; + presetDS4Values["DS4_BUTTON_DPAD_W"] = HID_DS4_BUTTON_DPAD_W; + presetDS4Values["DS4_BUTTON_DPAD_NW"] = HID_DS4_BUTTON_DPAD_NW; + presetDS4Values["DS4_BUTTON_DPAD_NEUTRAL"] = HID_DS4_BUTTON_DPAD_NEUTRAL; + + presetDS4Values["DS4_BUTTON_GUIDE"] = HID_DS4_BUTTON_GUIDE; + presetDS4Values["DS4_BUTTON_T_PAD_CLICK"] = HID_DS4_BUTTON_T_PAD_CLICK; + + presetXInputValues["XINPUT_BUTTON_A"] = HID_XINPUT_BUTTON_A; + presetXInputValues["XINPUT_BUTTON_B"] = HID_XINPUT_BUTTON_B; + presetXInputValues["XINPUT_BUTTON_X"] = HID_XINPUT_BUTTON_X; + presetXInputValues["XINPUT_BUTTON_Y"] = HID_XINPUT_BUTTON_Y; + + presetXInputValues["XINPUT_BUTTON_LB"] = HID_XINPUT_BUTTON_LB; + presetXInputValues["XINPUT_BUTTON_LT"] = HID_XINPUT_BUTTON_LT; + presetXInputValues["XINPUT_BUTTON_L3"] = HID_XINPUT_BUTTON_L3; + presetXInputValues["XINPUT_BUTTON_RB"] = HID_XINPUT_BUTTON_RB; + presetXInputValues["XINPUT_BUTTON_RT"] = HID_XINPUT_BUTTON_RT; + presetXInputValues["XINPUT_BUTTON_R3"] = HID_XINPUT_BUTTON_R3; + + presetXInputValues["XINPUT_BUTTON_START"] = HID_XINPUT_BUTTON_START; + presetXInputValues["XINPUT_BUTTON_BACK"] = HID_XINPUT_BUTTON_BACK; + presetXInputValues["XINPUT_BUTTON_DPAD_TYPE"] = HID_XINPUT_BUTTON_DPAD_TYPE; + + presetXInputValues["XINPUT_BUTTON_DPAD_UP"] = HID_XINPUT_BUTTON_UP; + presetXInputValues["XINPUT_BUTTON_DPAD_DOWN"] = HID_XINPUT_BUTTON_DOWN; + presetXInputValues["XINPUT_BUTTON_DPAD_LEFT"] = HID_XINPUT_BUTTON_LEFT; + presetXInputValues["XINPUT_BUTTON_DPAD_RIGHT"] = HID_XINPUT_BUTTON_RIGHT; + + presetXInputValues["XINPUT_BUTTON_GUIDE"] = HID_XINPUT_BUTTON_GUIDE; + + presetSwitchProValues["SWITCH_PRO_BUTTON_A"] = HID_SWITCH_PRO_BT_BUTTON_A; + presetSwitchProValues["SWITCH_PRO_BUTTON_B"] = HID_SWITCH_PRO_BT_BUTTON_B; + presetSwitchProValues["SWITCH_PRO_BUTTON_X"] = HID_SWITCH_PRO_BT_BUTTON_X; + presetSwitchProValues["SWITCH_PRO_BUTTON_Y"] = HID_SWITCH_PRO_BT_BUTTON_Y; + + presetSwitchProValues["SWITCH_PRO_BUTTON_PLUS"] = HID_SWITCH_PRO_BT_BUTTON_PLUS; + presetSwitchProValues["SWITCH_PRO_BUTTON_MINUS"] = HID_SWITCH_PRO_BT_BUTTON_MINUS; + presetSwitchProValues["SWITCH_PRO_BUTTON_HOME"] = HID_SWITCH_PRO_BT_BUTTON_HOME; + + presetSwitchProValues["SWITCH_PRO_BUTTON_L"] = HID_SWITCH_PRO_BT_BUTTON_L; + presetSwitchProValues["SWITCH_PRO_BUTTON_R"] = HID_SWITCH_PRO_BT_BUTTON_R; + + presetSwitchProValues["SWITCH_PRO_BUTTON_ZL"] = HID_SWITCH_PRO_BT_BUTTON_ZL; + presetSwitchProValues["SWITCH_PRO_BUTTON_ZR"] = HID_SWITCH_PRO_BT_BUTTON_ZR; + + presetSwitchProValues["SWITCH_PRO_BUTTON_STICK_L"] = HID_SWITCH_PRO_BT_BUTTON_STICK_L; + presetSwitchProValues["SWITCH_PRO_BUTTON_STICK_R"] = HID_SWITCH_PRO_BT_BUTTON_STICK_R; + + presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_N"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_N; + presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_NE"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_NE; + presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_E"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_E; + presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_SE"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_SE; + presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_S"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_S; + presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_SW"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_SW; + presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_W"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_W; + presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_NW"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_NW; + presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_NEUTRAL"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_NEUTRAL; + + presetKeyboardValues["KEYBOARD_SHIFT"] = HID_KEYBOARD_BUTTON_SHIFT; + presetKeyboardValues["KEYBOARD_A"] = HID_KEYBOARD_BUTTON_A; + presetKeyboardValues["KEYBOARD_B"] = HID_KEYBOARD_BUTTON_B; + presetKeyboardValues["KEYBOARD_C"] = HID_KEYBOARD_BUTTON_C; + presetKeyboardValues["KEYBOARD_D"] = HID_KEYBOARD_BUTTON_D; + presetKeyboardValues["KEYBOARD_E"] = HID_KEYBOARD_BUTTON_E; + presetKeyboardValues["KEYBOARD_F"] = HID_KEYBOARD_BUTTON_F; + presetKeyboardValues["KEYBOARD_G"] = HID_KEYBOARD_BUTTON_G; + presetKeyboardValues["KEYBOARD_H"] = HID_KEYBOARD_BUTTON_H; + presetKeyboardValues["KEYBOARD_I"] = HID_KEYBOARD_BUTTON_I; + presetKeyboardValues["KEYBOARD_J"] = HID_KEYBOARD_BUTTON_J; + presetKeyboardValues["KEYBOARD_K"] = HID_KEYBOARD_BUTTON_K; + presetKeyboardValues["KEYBOARD_L"] = HID_KEYBOARD_BUTTON_L; + presetKeyboardValues["KEYBOARD_M"] = HID_KEYBOARD_BUTTON_M; + presetKeyboardValues["KEYBOARD_N"] = HID_KEYBOARD_BUTTON_N; + presetKeyboardValues["KEYBOARD_O"] = HID_KEYBOARD_BUTTON_O; + presetKeyboardValues["KEYBOARD_P"] = HID_KEYBOARD_BUTTON_P; + presetKeyboardValues["KEYBOARD_Q"] = HID_KEYBOARD_BUTTON_Q; + presetKeyboardValues["KEYBOARD_R"] = HID_KEYBOARD_BUTTON_R; + presetKeyboardValues["KEYBOARD_S"] = HID_KEYBOARD_BUTTON_S; + presetKeyboardValues["KEYBOARD_T"] = HID_KEYBOARD_BUTTON_T; + presetKeyboardValues["KEYBOARD_U"] = HID_KEYBOARD_BUTTON_U; + presetKeyboardValues["KEYBOARD_V"] = HID_KEYBOARD_BUTTON_V; + presetKeyboardValues["KEYBOARD_W"] = HID_KEYBOARD_BUTTON_W; + presetKeyboardValues["KEYBOARD_X"] = HID_KEYBOARD_BUTTON_X; + presetKeyboardValues["KEYBOARD_Y"] = HID_KEYBOARD_BUTTON_Y; + presetKeyboardValues["KEYBOARD_Z"] = HID_KEYBOARD_BUTTON_Z; + presetKeyboardValues["KEYBOARD_F1"] = HID_KEYBOARD_BUTTON_F1; + presetKeyboardValues["KEYBOARD_F2"] = HID_KEYBOARD_BUTTON_F2; + presetKeyboardValues["KEYBOARD_F3"] = HID_KEYBOARD_BUTTON_F3; + presetKeyboardValues["KEYBOARD_F4"] = HID_KEYBOARD_BUTTON_F4; + presetKeyboardValues["KEYBOARD_F5"] = HID_KEYBOARD_BUTTON_F5; + presetKeyboardValues["KEYBOARD_F6"] = HID_KEYBOARD_BUTTON_F6; + presetKeyboardValues["KEYBOARD_F7"] = HID_KEYBOARD_BUTTON_F7; + presetKeyboardValues["KEYBOARD_F8"] = HID_KEYBOARD_BUTTON_F8; + presetKeyboardValues["KEYBOARD_F9"] = HID_KEYBOARD_BUTTON_F9; + presetKeyboardValues["KEYBOARD_F10"] = HID_KEYBOARD_BUTTON_F10; + presetKeyboardValues["KEYBOARD_F11"] = HID_KEYBOARD_BUTTON_F11; + presetKeyboardValues["KEYBOARD_F12"] = HID_KEYBOARD_BUTTON_F12; + presetKeyboardValues["KEYBOARD_1"] = HID_KEYBOARD_BUTTON_1; + presetKeyboardValues["KEYBOARD_2"] = HID_KEYBOARD_BUTTON_2; + presetKeyboardValues["KEYBOARD_3"] = HID_KEYBOARD_BUTTON_3; + presetKeyboardValues["KEYBOARD_4"] = HID_KEYBOARD_BUTTON_4; + presetKeyboardValues["KEYBOARD_5"] = HID_KEYBOARD_BUTTON_5; + presetKeyboardValues["KEYBOARD_6"] = HID_KEYBOARD_BUTTON_6; + presetKeyboardValues["KEYBOARD_7"] = HID_KEYBOARD_BUTTON_7; + presetKeyboardValues["KEYBOARD_8"] = HID_KEYBOARD_BUTTON_8; + presetKeyboardValues["KEYBOARD_9"] = HID_KEYBOARD_BUTTON_9; + presetKeyboardValues["KEYBOARD_0"] = HID_KEYBOARD_BUTTON_0; + + presetKeyboardValues["KEYBOARD_RETURN"] = HID_KEYBOARD_BUTTON_RETURN; + presetKeyboardValues["KEYBOARD_ESCAPE"] = HID_KEYBOARD_BUTTON_ESCAPE; + presetKeyboardValues["KEYBOARD_DELETE"] = HID_KEYBOARD_BUTTON_DELETE; + presetKeyboardValues["KEYBOARD_TAB"] = HID_KEYBOARD_BUTTON_TAB; + presetKeyboardValues["KEYBOARD_SPACEBAR"] = HID_KEYBOARD_BUTTON_SPACEBAR; + presetKeyboardValues["KEYBOARD_CAPSLOCK"] = HID_KEYBOARD_BUTTON_CAPSLOCK; + presetKeyboardValues["KEYBOARD_PRINTSCREEN"] = HID_KEYBOARD_BUTTON_PRINTSCREEN; + presetKeyboardValues["KEYBOARD_SCROLLLOCK"] = HID_KEYBOARD_BUTTON_SCROLLLOCK; + presetKeyboardValues["KEYBOARD_PAUSE"] = HID_KEYBOARD_BUTTON_PAUSE; + presetKeyboardValues["KEYBOARD_INSERT"] = HID_KEYBOARD_BUTTON_INSERT; + presetKeyboardValues["KEYBOARD_HOME"] = HID_KEYBOARD_BUTTON_HOME; + presetKeyboardValues["KEYBOARD_PAGEUP"] = HID_KEYBOARD_BUTTON_PAGEUP; + presetKeyboardValues["KEYBOARD_PAGEDOWN"] = HID_KEYBOARD_BUTTON_PAGEDOWN; + presetKeyboardValues["KEYBOARD_DELETEFORWARD"] = HID_KEYBOARD_BUTTON_DELETEFORWARD; + presetKeyboardValues["KEYBOARD_LEFT_CONTROL"] = HID_KEYBOARD_BUTTON_LEFT_CONTROL; + presetKeyboardValues["KEYBOARD_LEFT_ALT"] = HID_KEYBOARD_BUTTON_LEFT_ALT; + presetKeyboardValues["KEYBOARD_RIGHT_CONTROL"] = HID_KEYBOARD_BUTTON_RIGHT_CONTROL; + presetKeyboardValues["KEYBOARD_RIGHT_SHIFT"] = HID_KEYBOARD_BUTTON_RIGHT_SHIFT; + presetKeyboardValues["KEYBOARD_RIGHT_ALT"] = HID_KEYBOARD_BUTTON_RIGHT_ALT; + presetKeyboardValues["KEYBOARD_END"] = HID_KEYBOARD_BUTTON_END; + + presetKeyboardValues["KEYBOARD_LEFT"] = HID_KEYBOARD_BUTTON_LEFT; + presetKeyboardValues["KEYBOARD_RIGHT"] = HID_KEYBOARD_BUTTON_RIGHT; + presetKeyboardValues["KEYBOARD_DOWN"] = HID_KEYBOARD_BUTTON_DOWN; + presetKeyboardValues["KEYBOARD_UP"] = HID_KEYBOARD_BUTTON_UP; + + presetKeyboardValues["KEYBOARD_KEYPAD_1"] = HID_KEYBOARD_KEYPAD_BUTTON_1; + presetKeyboardValues["KEYBOARD_KEYPAD_2"] = HID_KEYBOARD_KEYPAD_BUTTON_2; + presetKeyboardValues["KEYBOARD_KEYPAD_3"] = HID_KEYBOARD_KEYPAD_BUTTON_3; + presetKeyboardValues["KEYBOARD_KEYPAD_4"] = HID_KEYBOARD_KEYPAD_BUTTON_4; + presetKeyboardValues["KEYBOARD_KEYPAD_5"] = HID_KEYBOARD_KEYPAD_BUTTON_5; + presetKeyboardValues["KEYBOARD_KEYPAD_6"] = HID_KEYBOARD_KEYPAD_BUTTON_6; + presetKeyboardValues["KEYBOARD_KEYPAD_7"] = HID_KEYBOARD_KEYPAD_BUTTON_7; + presetKeyboardValues["KEYBOARD_KEYPAD_8"] = HID_KEYBOARD_KEYPAD_BUTTON_8; + presetKeyboardValues["KEYBOARD_KEYPAD_9"] = HID_KEYBOARD_KEYPAD_BUTTON_9; + presetKeyboardValues["KEYBOARD_KEYPAD_0"] = HID_KEYBOARD_KEYPAD_BUTTON_0; + presetKeyboardValues["KEYBOARD_KEYPAD_NUMLOCK"] = HID_KEYBOARD_KEYPAD_BUTTON_NUMLOCK; + presetKeyboardValues["KEYBOARD_KEYPAD_MINUS"] = HID_KEYBOARD_KEYPAD_BUTTON_MINUS; + presetKeyboardValues["KEYBOARD_KEYPAD_PLUS"] = HID_KEYBOARD_KEYPAD_BUTTON_PLUS; + + presetValues["VPAD_L_STICK"] = DEF_L_STICK; + presetValues["VPAD_R_STICK"] = DEF_R_STICK; + + presetValues["DPAD_NORMAL"] = CONTRPDM_Normal; + presetValues["DPAD_HAT"] = CONTRPDM_Hat; + presetValues["DPAD_ABSOLUTE_2VALUES"] = CONTRPDM_Absolute_2Values; + presetValues["TRUE"] = 1; + presetValues["YES"] = 1; + presetValues["ON"] = 1; + presetValues["FALSE"] = 0; + presetValues["NO"] = 0; + presetValues["OFF"] = 0; + + presetSticks["GC_STICK_L_X"] = HID_GC_STICK_L_X; + presetSticks["GC_STICK_L_Y"] = HID_GC_STICK_L_Y; + presetSticks["GC_STICK_R_X"] = HID_GC_STICK_R_X; + presetSticks["GC_STICK_R_Y"] = HID_GC_STICK_R_Y; + + presetSticks["DS3_STICK_L_X"] = HID_DS3_STICK_L_X; + presetSticks["DS3_STICK_L_Y"] = HID_DS3_STICK_L_Y; + presetSticks["DS3_STICK_R_X"] = HID_DS3_STICK_R_X; + presetSticks["DS3_STICK_R_Y"] = HID_DS3_STICK_R_Y; + + presetSticks["DS4_STICK_L_X"] = HID_DS4_STICK_L_X; + presetSticks["DS4_STICK_L_Y"] = HID_DS4_STICK_L_Y; + presetSticks["DS4_STICK_R_X"] = HID_DS4_STICK_R_X; + presetSticks["DS4_STICK_R_Y"] = HID_DS4_STICK_R_Y; + + presetSticks["XINPUT_STICK_L_X"] = HID_XINPUT_STICK_L_X; + presetSticks["XINPUT_STICK_L_Y"] = HID_XINPUT_STICK_L_Y; + presetSticks["XINPUT_STICK_R_X"] = HID_XINPUT_STICK_R_X; + presetSticks["XINPUT_STICK_R_Y"] = HID_XINPUT_STICK_R_Y; + + presetSticks["SWITCH_PRO_STICK_L_X"] = HID_SWITCH_PRO_BT_STICK_L_X; + presetSticks["SWITCH_PRO_STICK_L_Y"] = HID_SWITCH_PRO_BT_STICK_L_Y; + presetSticks["SWITCH_PRO_STICK_R_X"] = HID_SWITCH_PRO_BT_STICK_R_X; + presetSticks["SWITCH_PRO_STICK_R_Y"] = HID_SWITCH_PRO_BT_STICK_R_Y; + + presetSticks["GC_DPAD_MODE"] = HID_GC_BUTTON_DPAD_TYPE; + presetSticks["DS3_DPAD_MODE"] = HID_DS3_BUTTON_DPAD_TYPE; + presetSticks["DS4_DPAD_MODE"] = HID_DS4_BUTTON_DPAD_TYPE; + presetSticks["XINPUT_DPAD_MODE"] = HID_XINPUT_BUTTON_DPAD_TYPE; + presetSticks["SWITCH_PRO_DPAD_MODE"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_TYPE; + + gGamePadValuesToCONTRPSString["VPAD_BUTTON_A"] = CONTRPS_VPAD_BUTTON_A; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_B"] = CONTRPS_VPAD_BUTTON_B; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_X"] = CONTRPS_VPAD_BUTTON_X; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_Y"] = CONTRPS_VPAD_BUTTON_Y; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_LEFT"] = CONTRPS_VPAD_BUTTON_LEFT; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_RIGHT"] = CONTRPS_VPAD_BUTTON_RIGHT; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_UP"] = CONTRPS_VPAD_BUTTON_UP; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_DOWN"] = CONTRPS_VPAD_BUTTON_DOWN; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_ZL"] = CONTRPS_VPAD_BUTTON_ZL; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_ZR"] = CONTRPS_VPAD_BUTTON_ZR; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_L"] = CONTRPS_VPAD_BUTTON_L; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_R"] = CONTRPS_VPAD_BUTTON_R; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_PLUS"] = CONTRPS_VPAD_BUTTON_PLUS; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_MINUS"] = CONTRPS_VPAD_BUTTON_MINUS; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_HOME"] = CONTRPS_VPAD_BUTTON_HOME; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_SYNC"] = CONTRPS_VPAD_BUTTON_SYNC; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_STICK_R"] = CONTRPS_VPAD_BUTTON_STICK_R; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_STICK_L"] = CONTRPS_VPAD_BUTTON_STICK_L; + gGamePadValuesToCONTRPSString["VPAD_BUTTON_TV"] = CONTRPS_VPAD_BUTTON_TV; + + gGamePadValuesToCONTRPSString["VPAD_STICK_R_EMULATION_LEFT"] = CONTRPS_VPAD_STICK_R_EMULATION_LEFT; + gGamePadValuesToCONTRPSString["VPAD_STICK_R_EMULATION_RIGHT"] = CONTRPS_VPAD_STICK_R_EMULATION_RIGHT; + gGamePadValuesToCONTRPSString["VPAD_STICK_R_EMULATION_UP"] = CONTRPS_VPAD_STICK_R_EMULATION_UP; + gGamePadValuesToCONTRPSString["VPAD_STICK_R_EMULATION_DOWN"] = CONTRPS_VPAD_STICK_R_EMULATION_DOWN; + gGamePadValuesToCONTRPSString["VPAD_STICK_L_EMULATION_LEFT"] = CONTRPS_VPAD_STICK_L_EMULATION_LEFT; + gGamePadValuesToCONTRPSString["VPAD_STICK_L_EMULATION_RIGHT"] = CONTRPS_VPAD_STICK_L_EMULATION_RIGHT; + gGamePadValuesToCONTRPSString["VPAD_STICK_L_EMULATION_UP"] = CONTRPS_VPAD_STICK_L_EMULATION_UP; + gGamePadValuesToCONTRPSString["VPAD_STICK_L_EMULATION_DOWN"] = CONTRPS_VPAD_STICK_L_EMULATION_DOWN; + + deviceNames[CPStringTools::strfmt("%04X%04X",HID_GC_VID, HID_GC_PID).c_str()] = HID_GC_STRING; + deviceNames[CPStringTools::strfmt("%04X%04X",HID_KEYBOARD_VID, HID_KEYBOARD_PID).c_str()] = HID_KEYBOARD_STRING; + deviceNames[CPStringTools::strfmt("%04X%04X",HID_MOUSE_VID, HID_MOUSE_PID).c_str()] = HID_MOUSE_STRING; + deviceNames[CPStringTools::strfmt("%04X%04X",HID_DS3_VID, HID_DS3_PID).c_str()] = HID_DS3_STRING; + deviceNames[CPStringTools::strfmt("%04X%04X",HID_NEW_DS4_VID, HID_NEW_DS4_PID).c_str()] = HID_NEW_DS4_STRING; + deviceNames[CPStringTools::strfmt("%04X%04X",HID_DS4_VID, HID_DS4_PID).c_str()] = HID_DS4_STRING; + deviceNames[CPStringTools::strfmt("%04X%04X",HID_XINPUT_VID, HID_XINPUT_PID).c_str()] = HID_XINPUT_STRING; + deviceNames[CPStringTools::strfmt("%04X%04X",HID_SWITCH_PRO_VID,HID_SWITCH_PRO_PID).c_str()] = HID_SWITCH_PRO_STRING; + } + + const u8 * getValuesForPreset(std::map values,std::string possibleValue); + + bool setIfValueIsPreset(std::map values,std::string possibleValue,s32 slot,s32 keyslot); + bool setIfValueIsAControllerPresetEx(std::string value,s32 slot,s32 keyslot); + + void addDeviceNameEx(u16 vid,u16 pid,std::string value); + std::string getStringByVIDPIDEx(u16 vid,u16 pid); +}; +#endif diff --git a/wiiu/controller_patcher/network/ControllerPatcherNet.cpp b/wiiu/controller_patcher/network/ControllerPatcherNet.cpp new file mode 100644 index 0000000000..8e5f7d109d --- /dev/null +++ b/wiiu/controller_patcher/network/ControllerPatcherNet.cpp @@ -0,0 +1,50 @@ +#include "ControllerPatcherNet.hpp" +#include "wiiu/os.h" +#include "sys/socket.h" + +s32 ControllerPatcherNet::recvwait(s32 sock, void *buffer, s32 len) { + s32 ret; + while (len > 0) { + ret = recv(sock, buffer, len, 0); + if(ret < 0) return ret; + len -= ret; + buffer = (void *)(((char *) buffer) + ret); + } + return 0; +} + +u8 ControllerPatcherNet::recvbyte(s32 sock) { + unsigned char buffer[1]; + s32 ret; + + ret = recvwait(sock, buffer, 1); + if (ret < 0) return ret; + return buffer[0]; +} + +s32 ControllerPatcherNet::checkbyte(s32 sock) { + unsigned char buffer[1]; + s32 ret; + + ret = recv(sock, buffer, 1, MSG_DONTWAIT); + if (ret < 0) return ret; + if (ret == 0) return -1; + return buffer[0]; +} + +s32 ControllerPatcherNet::sendwait(s32 sock, const void *buffer, s32 len) { + s32 ret; + while (len > 0) { + ret = send(sock, buffer, len, 0); + if(ret < 0) return ret; + len -= ret; + buffer = (void *)(((char *) buffer) + ret); + } + return 0; +} + +s32 ControllerPatcherNet::sendbyte(s32 sock, unsigned char byte) { + unsigned char buffer[1]; + buffer[0] = byte; + return sendwait(sock, buffer, 1); +} diff --git a/wiiu/controller_patcher/network/ControllerPatcherNet.hpp b/wiiu/controller_patcher/network/ControllerPatcherNet.hpp new file mode 100644 index 0000000000..331ad096a3 --- /dev/null +++ b/wiiu/controller_patcher/network/ControllerPatcherNet.hpp @@ -0,0 +1,17 @@ +#ifndef _CONTROLLERPATCHERNET_H_ +#define _CONTROLLERPATCHERNET_H_ + +#include "wiiu/types.h" + +class ControllerPatcherNet{ + friend class TCPServer; + friend class UDPServer; + private: + static s32 recvwait(s32 sock, void *buffer, s32 len); + static u8 recvbyte(s32 sock); + static s32 checkbyte(s32 sock); + static s32 sendwait(s32 sock, const void *buffer, s32 len); + static s32 sendbyte(s32 sock, unsigned char byte); +}; + +#endif diff --git a/wiiu/controller_patcher/network/TCPServer.cpp b/wiiu/controller_patcher/network/TCPServer.cpp new file mode 100644 index 0000000000..485544996d --- /dev/null +++ b/wiiu/controller_patcher/network/TCPServer.cpp @@ -0,0 +1,371 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#include "TCPServer.hpp" +#include +#include +#include + +#define wiiu_errno (*__gh_errno_ptr()) + +ControllerPatcherThread * TCPServer::pThread = NULL; +TCPServer * TCPServer::instance = NULL; + +TCPServer::TCPServer(s32 port){ + this->sockfd = -1; + this->clientfd = -1; + memset(&(this->sock_addr),0,sizeof(this->sock_addr)); + TCPServer::AttachDetach(DETACH); + StartTCPThread(this); +} + +TCPServer::~TCPServer(){ + CloseSockets(); + if(HID_DEBUG){ printf("TCPServer::~TCPServer(line %d): Thread will be closed\n",__LINE__); } + TCPServer::AttachDetach(DETACH); + exitThread = 1; + if(TCPServer::pThread != NULL){ + if(HID_DEBUG){ printf("TCPServer::~TCPServer(line %d): Deleting it!\n",__LINE__); } + delete TCPServer::pThread; + } + if(HID_DEBUG){ printf("TCPServer::~TCPServer(line %d): Thread done\n",__LINE__); } + TCPServer::pThread = NULL; +} + +void TCPServer::CloseSockets(){ + if (this->sockfd != -1){ + socketclose(this->sockfd); + } + if (this->clientfd != -1){ + socketclose(this->clientfd); + } + this->sockfd = -1; + this->clientfd = -1; +} + +void TCPServer::StartTCPThread(TCPServer * server){ + s32 priority = 28; + if(OSGetTitleID() == 0x00050000101c9300 || //The Legend of Zelda Breath of the Wild JPN + OSGetTitleID() == 0x00050000101c9400 || //The Legend of Zelda Breath of the Wild USA + OSGetTitleID() == 0x00050000101c9500 || //The Legend of Zelda Breath of the Wild EUR + OSGetTitleID() == 0x00050000101c9b00 || //The Binding of Isaac: Rebirth EUR + OSGetTitleID() == 0x00050000101a3c00){ //The Binding of Isaac: Rebirth USA + priority = 10; + printf("TCPServer::StartTCPThread(line %d): This game needs higher thread priority. We set it to %d\n",__LINE__,priority); + } + TCPServer::pThread = ControllerPatcherThread::create(TCPServer::DoTCPThread, (void*)server, ControllerPatcherThread::eAttributeAffCore2,priority); + TCPServer::pThread->resumeThread(); +} + +void TCPServer::AttachDetach(s32 attach){ + if(HID_DEBUG){ + if(attach){ + printf("TCPServer::AttachDetach(line %d): Network Attach\n",__LINE__); + }else{ + printf("TCPServer::AttachDetach(line %d): Network Detach\n",__LINE__); + } + } + + for(s32 i= 0;i< gHIDMaxDevices;i++){ + for(s32 j= 0;j< HID_MAX_PADS_COUNT;j++){ + if(gNetworkController[i][j][NETWORK_CONTROLLER_ACTIVE] > 0){ + printf("TCPServer::AttachDetach(line %d): Found a registered pad in deviceslot %d and padslot %d! Lets detach it.\n",__LINE__,i,j); + HIDDevice device; + memset(&device,0,sizeof(device)); + + device.interface_index = 0; + device.vid = gNetworkController[i][j][NETWORK_CONTROLLER_VID]; + device.pid = gNetworkController[i][j][NETWORK_CONTROLLER_PID]; + device.handle = gNetworkController[i][j][NETWORK_CONTROLLER_HANDLE]; + device.max_packet_size_rx = 8; + ControllerPatcherHID::externAttachDetachCallback(&device,attach); + memset(gNetworkController[i][j],0,sizeof(gNetworkController[i][j])); + } + } + } + + if(HID_DEBUG){ + if(attach){ + printf("TCPServer::AttachDetach(line %d): Network Attach DONE!\n",__LINE__); + }else{ + printf("TCPServer::AttachDetach(line %d): Network Detach DONE!\n",__LINE__); + } + } +} + +void TCPServer::DetachAndDelete(){ + TCPServer::AttachDetach(DETACH); + memset(&gNetworkController,0,sizeof(gNetworkController)); +} + +s32 TCPServer::RunTCP(){ + s32 ret; + while (1) { + if(exitThread) break; + ret = ControllerPatcherNet::checkbyte(clientfd); + if (ret < 0) { + if(wiiu_errno != 6) return ret; + wiiu_os_usleep(1000); + continue; + } + //printf("got byte from tcp! %01X\n",ret); + switch (ret) { + case WIIU_CP_TCP_ATTACH: { /*attach */ + if(gUsedProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_1){ + s32 handle; + ret = ControllerPatcherNet::recvwait(clientfd, &handle, 4); + if(ret < 0){ + printf("TCPServer::RunTCP(line %d): Error in %02X: recvwait handle\n",__LINE__,WIIU_CP_TCP_ATTACH); + return ret; + } + if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): got handle %d\n",handle); } + u16 vid = 0; + u16 pid = 0; + ret = ControllerPatcherNet::recvwait(clientfd, &vid, 2); + if(ret < 0){ + printf("TCPServer::RunTCP(line %d): Error in %02X: recvwait vid\n",__LINE__,WIIU_CP_TCP_ATTACH); + return ret; + } + if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): got vid %04X\n",vid); } + + ret = ControllerPatcherNet::recvwait(clientfd, &pid, 2); + if(ret < 0){ + printf("TCPServer::RunTCP(line %d): Error in %02X: recvwait pid\n",__LINE__,WIIU_CP_TCP_ATTACH); + return ret; + } + if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): got pid %04X\n",pid); } + HIDDevice device; + memset(&device,0,sizeof(device)); + device.handle = handle; + device.interface_index = 0; + device.vid = SWAP16(vid); + device.pid = SWAP16(pid); + device.max_packet_size_rx = 8; + + my_cb_user * user = NULL; + ControllerPatcherHID::externAttachDetachCallback(&device,1); + if((ret = ControllerPatcherUtils::getDataByHandle(handle,&user)) < 0){ + printf("TCPServer::RunTCP(line %d): Error in %02X: getDataByHandle(%d,%08X).\n",__LINE__,WIIU_CP_TCP_ATTACH,handle,&user); + printf("TCPServer::RunTCP(line %d): Error in %02X: Config for the controller is missing.\n",__LINE__,WIIU_CP_TCP_ATTACH); + if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_CONFIG_NOT_FOUND) < 0)){ + printf("TCPServer::RunTCP(line %d): Error in %02X: Sending the WIIU_CP_TCP_ATTACH_CONFIG_NOT_FOUND byte failed. Error: %d.\n",__LINE__,WIIU_CP_TCP_ATTACH,ret); + } + return -1; + } + if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_CONFIG_FOUND) < 0)){ + printf("TCPServer::RunTCP(line %d): Error in %02X: Sending the WIIU_CP_TCP_ATTACH_CONFIG_FOUND byte failed. Error: %d.\n",__LINE__,WIIU_CP_TCP_ATTACH,ret); + return ret; + } + if(user != NULL){ + if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_USER_DATA_OKAY) < 0)){ + printf("TCPServer::RunTCP(line %d): Error in %02X: Sending the WIIU_CP_TCP_ATTACH_USER_DATA_OKAY byte failed. Error: %d.\n",__LINE__,WIIU_CP_TCP_ATTACH,ret); + return ret; + } + + ret = ControllerPatcherNet::sendwait(clientfd,&user->slotdata.deviceslot,2); + if(ret < 0){ + printf("TCPServer::RunTCP(line %d): Error in %02X: sendwait slotdata: %04X\n",__LINE__,WIIU_CP_TCP_ATTACH,user->slotdata.deviceslot); + return ret; + } + ret = ControllerPatcherNet::sendwait(clientfd,&user->pad_slot,1); + if(ret < 0){ + printf("TCPServer::RunTCP(line %d): Error in %02X: sendwait pad_slot: %04X\n",__LINE__,WIIU_CP_TCP_ATTACH,user->pad_slot); + return ret; + } + }else{ + printf("TCPServer::RunTCP(line %d): Error in %02X: invalid user data.\n",__LINE__,WIIU_CP_TCP_ATTACH); + if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_USER_DATA_BAD) < 0)){ + printf("TCPServer::RunTCP(line %d): Error in %02X: Sending the WIIU_CP_TCP_ATTACH_USER_DATA_BAD byte failed. Error: %d.\n",__LINE__,WIIU_CP_TCP_ATTACH,ret); + return ret; + } + return -1; + break; + } + + if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): attachted to device slot: %d , pad slot is: %d\n",__LINE__,user->slotdata.deviceslot,user->pad_slot); } + + gNetworkController[user->slotdata.deviceslot][user->pad_slot][NETWORK_CONTROLLER_VID] = device.vid; + gNetworkController[user->slotdata.deviceslot][user->pad_slot][NETWORK_CONTROLLER_PID] = device.pid; + gNetworkController[user->slotdata.deviceslot][user->pad_slot][NETWORK_CONTROLLER_ACTIVE] = 1; + gNetworkController[user->slotdata.deviceslot][user->pad_slot][NETWORK_CONTROLLER_HANDLE] = handle; + + if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): handle %d connected! vid: %02X pid: %02X deviceslot %d, padslot %d\n",__LINE__,handle,vid,pid,user->slotdata.deviceslot,user->pad_slot); } + break; + } + break; + } + case WIIU_CP_TCP_DETACH: { /*detach */ + if(gUsedProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_1){ + s32 handle; + ret = ControllerPatcherNet::recvwait(clientfd, &handle, 4); + if(ret < 0){ + printf("TCPServer::RunTCP(line %d): Error in %02X: recvwait handle\n",__LINE__,WIIU_CP_TCP_DETACH); + return ret; + break; + } + + if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): got detach for handle: %d\n",__LINE__,handle); } + my_cb_user * user = NULL; + if(ControllerPatcherUtils::getDataByHandle(handle,&user) < 0){ + printf("TCPServer::RunTCP(line %d): Error in %02X: getDataByHandle(%d,%08X).\n",__LINE__,WIIU_CP_TCP_DETACH,handle,&user); + return -1; + break; + } + if(user == NULL){ + printf("TCPServer::RunTCP(line %d): Error in %02X: invalid user data.\n",__LINE__,WIIU_CP_TCP_DETACH); + return -1; + break; + } + s32 deviceslot = user->slotdata.deviceslot; + if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): device slot is: %d , pad slot is: %d\n",__LINE__,deviceslot,user->pad_slot); } + + DeviceVIDPIDInfo vidpid; + s32 result; + if((result = ControllerPatcherUtils::getVIDPIDbyDeviceSlot(deviceslot,&vidpid)) < 0){ + printf("TCPServer::RunTCP(line %d): Error in %02X: Couldn't find a valid VID/PID for device slot %d. Error: %d\n",__LINE__,WIIU_CP_TCP_DETACH,deviceslot,ret); + return -1; + break; + } + + HIDDevice device; + memset(&device,0,sizeof(device)); + device.handle = handle; + device.interface_index = 0; + device.vid = SWAP16(vidpid.vid); + device.pid = SWAP16(vidpid.pid); + device.max_packet_size_rx = 14; + + ControllerPatcherHID::externAttachDetachCallback(&device,DETACH); + memset(gNetworkController[deviceslot][user->pad_slot],0,sizeof(gNetworkController[deviceslot][user->pad_slot])); + if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): handle %d disconnected!\n",__LINE__,handle); } + break; + } + break; + } + case WIIU_CP_TCP_PING: { /*ping*/ + if(gUsedProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_1){ + if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): Got Ping, sending now a Pong\n",__LINE__); } + s32 ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_PONG); + if(ret < 0){ printf("TCPServer::RunTCP(line %d): Error in %02X: sendbyte PONG\n",__LINE__); return -1;} + + break; + } + break; + } + default: + return -1; + break; + } + } + return 0; +} + +void TCPServer::ErrorHandling(){ + CloseSockets(); + wiiu_os_usleep(1000*1000*2); +} + +void TCPServer::DoTCPThreadInternal(){ + s32 ret; + s32 len; + while (1) { + if(exitThread) break; + memset(&(this->sock_addr),0,sizeof(sock_addr)); + sock_addr.sin_family = AF_INET; + sock_addr.sin_port = DEFAULT_TCP_PORT; + sock_addr.sin_addr.s_addr = 0; + + this->sockfd = ret = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if(ret == -1){ ErrorHandling(); continue;} + s32 enable = 1; + + setsockopt(this->sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)); + + ret = bind(this->sockfd, (sockaddr *)&sock_addr, 16); + if(ret < 0) { ErrorHandling(); continue;} + ret = listen(this->sockfd, 1); + if(ret < 0){ ErrorHandling(); continue;} + + do{ + if(HID_DEBUG){ printf("TCPServer::DoTCPThreadInternal(line %d): Waiting for a connection\n",__LINE__); } + if(exitThread) break; + len = 16; + + /** + Handshake + 1. At first this server sends his protocol version + 2. The network clients answers with his preferred version (which needs to be equals or lower the version this server sent him) or an abort command. + 3a. If the client sent a abort, close the connection and wait for another connection + 3b. If the client sent his highest supported version, the server confirm that he is able to use this version (by sending the version back) or sending a abort command to disconnect. + **/ + + clientfd = ret = (s32)accept(sockfd, (sockaddr *)&(sock_addr),(socklen_t *) &len); + + if(ret == -1){ ErrorHandling(); break;} + printf("TCPServer::DoTCPThreadInternal(line %d): TCP Connection accepted! Sending my protocol version: %d (0x%02X)\n",__LINE__, (WIIU_CP_TCP_HANDSHAKE - WIIU_CP_TCP_HANDSHAKE_VERSION_1)+1,WIIU_CP_TCP_HANDSHAKE); + + gUDPClientip = sock_addr.sin_addr.s_addr; + UDPClient::createInstance(); + + s32 ret; + ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_HANDSHAKE); //Hey I'm a WiiU console! + if(ret < 0){ printf("TCPServer::DoTCPThreadInternal(line %d): Error sendbyte: %02X\n",__LINE__,WIIU_CP_TCP_HANDSHAKE); ErrorHandling(); break;} + + u8 clientProtocolVersion = ControllerPatcherNet::recvbyte(clientfd); + if(ret < 0){ printf("TCPServer::DoTCPThreadInternal(line %d): Error recvbyte: %02X\n",__LINE__,WIIU_CP_TCP_HANDSHAKE); ErrorHandling(); break;} + + if(clientProtocolVersion == WIIU_CP_TCP_HANDSHAKE_ABORT){ + printf("TCPServer::DoTCPThreadInternal(line %d): The network client wants to abort.\n",__LINE__); + ErrorHandling(); break; + } + + printf("TCPServer::DoTCPThreadInternal(line %d): received protocol version: %d (0x%02X)\n",__LINE__,(clientProtocolVersion - WIIU_CP_TCP_HANDSHAKE_VERSION_1)+1,clientProtocolVersion); + + if(clientProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_MIN && clientProtocolVersion <= WIIU_CP_TCP_HANDSHAKE_VERSION_MAX){ + printf("TCPServer::DoTCPThreadInternal(line %d): We support this protocol version. Let's confirm it to the network client.\n",__LINE__); + gUsedProtocolVersion = clientProtocolVersion; + ret = ControllerPatcherNet::sendbyte(clientfd, clientProtocolVersion); + if(ret < 0){ printf("TCPServer::DoTCPThreadInternal(line %d): Error sendbyte: %02X\n",__LINE__,clientProtocolVersion); ErrorHandling(); break;} + }else{ + printf("TCPServer::DoTCPThreadInternal(line %d): We don't support this protocol version. We need to abort =(.\n",__LINE__); + ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_HANDSHAKE_ABORT); + ErrorHandling(); break; + } + + printf("TCPServer::DoTCPThreadInternal(line %d): Handshake done! Success!\n",__LINE__); + + TCPServer::DetachAndDelete(); //Clear connected controller + RunTCP(); + + if(clientfd != -1){ + socketclose(clientfd); + } + clientfd = -1; + }while(0); + printf("TCPServer::DoTCPThreadInternal(line %d): Connection closed\n",__LINE__); + gUDPClientip = 0; + UDPClient::destroyInstance(); + TCPServer::DetachAndDelete(); //Clear connected controller + CloseSockets(); + continue; + } + +} + +void TCPServer::DoTCPThread(ControllerPatcherThread *thread, void *arg){ + TCPServer * args = (TCPServer * )arg; + return args->DoTCPThreadInternal(); +} diff --git a/wiiu/controller_patcher/network/TCPServer.hpp b/wiiu/controller_patcher/network/TCPServer.hpp new file mode 100644 index 0000000000..173ad93265 --- /dev/null +++ b/wiiu/controller_patcher/network/TCPServer.hpp @@ -0,0 +1,93 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#ifndef _TCPSERVER_WINDOW_H_ +#define _TCPSERVER_WINDOW_H_ + +#include "../ControllerPatcher.hpp" + +#include "sys/socket.h" +#include "wiiu/os.h" + +#define WIIU_CP_TCP_HANDSHAKE WIIU_CP_TCP_HANDSHAKE_VERSION_3 + +#define WIIU_CP_TCP_HANDSHAKE_VERSION_MIN WIIU_CP_TCP_HANDSHAKE_VERSION_1 +#define WIIU_CP_TCP_HANDSHAKE_VERSION_MAX WIIU_CP_TCP_HANDSHAKE_VERSION_3 + +#define WIIU_CP_TCP_HANDSHAKE_VERSION_1 0x12 +#define WIIU_CP_TCP_HANDSHAKE_VERSION_2 0x13 +#define WIIU_CP_TCP_HANDSHAKE_VERSION_3 0x14 + +#define WIIU_CP_TCP_HANDSHAKE_ABORT 0x30 + +#define ATTACH 0x01 +#define DETACH 0x00 + +#define WIIU_CP_TCP_ATTACH 0x01 +#define WIIU_CP_TCP_DETACH 0x02 +#define WIIU_CP_TCP_PING 0xF0 +#define WIIU_CP_TCP_PONG 0xF1 + +#define WIIU_CP_TCP_ATTACH_CONFIG_FOUND 0xE0 +#define WIIU_CP_TCP_ATTACH_CONFIG_NOT_FOUND 0xE1 +#define WIIU_CP_TCP_ATTACH_USER_DATA_OKAY 0xE8 +#define WIIU_CP_TCP_ATTACH_USER_DATA_BAD 0xE9 + +#define DEFAULT_TCP_PORT 8112 + +class TCPServer{ + friend class ControllerPatcher; + +private: + static TCPServer *getInstance() { + if(!instance) + instance = new TCPServer(DEFAULT_TCP_PORT); + return instance; + } + + static void destroyInstance() { + if(instance){ + delete instance; + instance = NULL; + } + } + + TCPServer(s32 port); + ~TCPServer(); + + void CloseSockets(); + void ErrorHandling(); + + void StartTCPThread(TCPServer * server); + static void DoTCPThread(ControllerPatcherThread *thread, void *arg); + void DoTCPThreadInternal(); + static void DetachConnectedNetworkController(); + static void AttachDetach(s32 attach); + void DetachAndDelete(); + static TCPServer *instance; + + s32 RunTCP(); + + struct sockaddr_in sock_addr; + volatile s32 sockfd = -1; + volatile s32 clientfd = -1; + + + volatile s32 exitThread = 0; + static ControllerPatcherThread *pThread; +}; + +#endif //_TCPSERVER_WINDOW_H_ diff --git a/wiiu/controller_patcher/network/UDPClient.cpp b/wiiu/controller_patcher/network/UDPClient.cpp new file mode 100644 index 0000000000..75d90e6aef --- /dev/null +++ b/wiiu/controller_patcher/network/UDPClient.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#include "UDPClient.hpp" +#include +#include + +#define MAX_UDP_SIZE 0x578 + +UDPClient * UDPClient::instance = NULL; + +UDPClient::UDPClient(u32 ip, s32 port){ + sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sockfd < 0) + return; + + struct sockaddr_in connect_addr; + memset(&connect_addr, 0, sizeof(connect_addr)); + connect_addr.sin_family = AF_INET; + connect_addr.sin_port = port; + connect_addr.sin_addr.s_addr = ip; + + if(connect(sockfd, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0) + { + socketclose(sockfd); + sockfd = -1; + } +} + +UDPClient::~UDPClient(){ + if (this->sockfd != -1){ + socketclose(sockfd); + } + if(HID_DEBUG){ printf("UDPClient::~UDPClient(line %d): Thread has been closed\n",__LINE__); } +} + +bool UDPClient::sendData(char * data,s32 length){ + if(sockfd < 0 || data == 0 || length < 0 || gUsedProtocolVersion < WIIU_CP_TCP_HANDSHAKE_VERSION_3){ + return false; + } + if(length > 1400) length = 1400; + + s32 ret = send(sockfd, data, length, 0); + return (ret >= 0); +} diff --git a/wiiu/controller_patcher/network/UDPClient.hpp b/wiiu/controller_patcher/network/UDPClient.hpp new file mode 100644 index 0000000000..cb75180570 --- /dev/null +++ b/wiiu/controller_patcher/network/UDPClient.hpp @@ -0,0 +1,66 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#ifndef _UDPCLIENT_WINDOW_H_ +#define _UDPCLIENT_WINDOW_H_ + +#include "../ControllerPatcher.hpp" + +#include "sys/socket.h" + +#define DEFAULT_UDP_CLIENT_PORT 8114 + +class UDPClient{ + friend class ControllerPatcher; + friend class ControllerPatcherHID; + friend class TCPServer; +public: + +private: + static UDPClient *getInstance() { + if(instance == NULL){ + createInstance(); + } + return instance; + } + + + static UDPClient *createInstance() { + if(instance != NULL){ + destroyInstance(); + } + instance = new UDPClient(gUDPClientip,DEFAULT_UDP_CLIENT_PORT); + + return getInstance(); + } + + static void destroyInstance() { + if(instance != NULL){ + delete instance; + instance = NULL; + } + } + + UDPClient(u32 ip,s32 port); + ~UDPClient(); + bool sendData(char * data, s32 length); + + volatile s32 sockfd = -1; + struct sockaddr_in addr; + static UDPClient *instance; +}; + +#endif //_UDPClient_WINDOW_H_ diff --git a/wiiu/controller_patcher/network/UDPServer.cpp b/wiiu/controller_patcher/network/UDPServer.cpp new file mode 100644 index 0000000000..d30e63109e --- /dev/null +++ b/wiiu/controller_patcher/network/UDPServer.cpp @@ -0,0 +1,168 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#include "UDPServer.hpp" +#include +#include +#include + +#include "sys/socket.h" + +#define MAX_UDP_SIZE 0x578 +#define wiiu_errno (*__gh_errno_ptr()) + +ControllerPatcherThread * UDPServer::pThread = NULL; +UDPServer * UDPServer::instance = NULL; + +UDPServer::UDPServer(s32 port){ + s32 ret; + struct sockaddr_in addr; + + addr.sin_family = AF_INET; + addr.sin_port = port; + addr.sin_addr.s_addr = 0; + + this->sockfd = ret = socket(AF_INET, SOCK_DGRAM, 0); + if(ret == -1) return; + s32 enable = 1; + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)); + ret = bind(sockfd, (sockaddr *)&addr, 16); + if(ret < 0) return; + + StartUDPThread(this); +} + +UDPServer::~UDPServer(){ + ControllerPatcherThread * pThreadPointer = UDPServer::pThread; + if(pThreadPointer != NULL){ + exitThread = 1; + if(pThreadPointer != NULL){ + delete pThreadPointer; + UDPServer::pThread = NULL; + if (this->sockfd != -1){ + socketclose(sockfd); + } + this->sockfd = -1; + } + } + if(HID_DEBUG){ printf("UDPServer::~UDPServer(line %d): Thread has been closed\n",__LINE__); } + + +} + +void UDPServer::StartUDPThread(UDPServer * server){ + s32 priority = 28; + if(OSGetTitleID() == 0x00050000101c9300 || //The Legend of Zelda Breath of the Wild JPN + OSGetTitleID() == 0x00050000101c9400 || //The Legend of Zelda Breath of the Wild USA + OSGetTitleID() == 0x00050000101c9500 || //The Legend of Zelda Breath of the Wild EUR + OSGetTitleID() == 0x00050000101c9b00 || //The Binding of Isaac: Rebirth EUR + OSGetTitleID() == 0x00050000101a3c00){ //The Binding of Isaac: Rebirth USA + priority = 10; + printf("UDPServer::StartUDPThread(line %d): This game needs higher thread priority. We set it to %d\n",__LINE__,priority); + } + UDPServer::pThread = ControllerPatcherThread::create(UDPServer::DoUDPThread, (void*)server, ControllerPatcherThread::eAttributeAffCore2,priority); + UDPServer::pThread->resumeThread(); +} + +bool UDPServer::cpyIncrementBufferOffset(void * target, void * source, s32 * offset, s32 typesize, s32 maximum){ + if(((int)*offset + typesize) > maximum){ + printf("UDPServer::cpyIncrementBufferOffset(line %d): Transfer error. Excepted %04X bytes, but only got %04X\n",__LINE__,(*offset + typesize),maximum); + return false; + } + memcpy(target,(void*)((u32)source+(*offset)),typesize); + *offset += typesize; + return true; +} + +void UDPServer::DoUDPThread(ControllerPatcherThread *thread, void *arg){ + UDPServer * args = (UDPServer * )arg; + args->DoUDPThreadInternal(); +} + +void UDPServer::DoUDPThreadInternal(){ + u8 buffer[MAX_UDP_SIZE]; + s32 n; + + my_cb_user user; + while(1){ + //s32 usingVar = exitThread; + if(exitThread)break; + memset(buffer,0,MAX_UDP_SIZE); + n = recv(sockfd,buffer,MAX_UDP_SIZE,0); + if (n < 0){ + s32 errno_ = wiiu_errno; + wiiu_os_usleep(2000); + if(errno_ != 11 && errno_ != 9){ + break; + } + continue; + } + s32 bufferoffset = 0; + u8 type; + memcpy((void *)&type,buffer,sizeof(type)); + bufferoffset += sizeof(type); + switch (buffer[0]) { + case WIIU_CP_UDP_CONTROLLER_READ_DATA: { + if(gUsedProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_1){ + u8 count_commands; + memcpy((void *)&count_commands,buffer+bufferoffset,sizeof(count_commands)); + bufferoffset += sizeof(count_commands); + for(s32 i = 0;i. + ****************************************************************************/ +#ifndef _UDPSERVER_WINDOW_H_ +#define _UDPSERVER_WINDOW_H_ + +#include "../ControllerPatcher.hpp" + +#define DEFAULT_UDP_PORT 8113 + +#define WIIU_CP_UDP_CONTROLLER_READ_DATA 0x03 + +class UDPServer{ + friend class ControllerPatcher; + +private: + static UDPServer *getInstance() { + if(instance == NULL) + instance = new UDPServer(DEFAULT_UDP_PORT); + return instance; + } + + static void destroyInstance() { + if(instance != NULL){ + delete instance; + instance = NULL; + } + } + + UDPServer(s32 port); + ~UDPServer(); + void StartUDPThread(UDPServer * server); + static void DoUDPThread(ControllerPatcherThread *thread, void *arg); + void DoUDPThreadInternal(); + bool cpyIncrementBufferOffset(void * target, void * source, s32 * offset, s32 typesize, s32 maximum); + + volatile s32 sockfd = -1; + volatile s32 exitThread = 0; + + static UDPServer *instance; + static ControllerPatcherThread *pThread; +}; + +#endif //_UDPSERVER_WINDOW_H_ diff --git a/wiiu/controller_patcher/patcher/ControllerPatcherDefs.h b/wiiu/controller_patcher/patcher/ControllerPatcherDefs.h new file mode 100644 index 0000000000..f005e39173 --- /dev/null +++ b/wiiu/controller_patcher/patcher/ControllerPatcherDefs.h @@ -0,0 +1,703 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ + +/** + * @file ControllerPatcherDefs.h + * @author Maschell + * @date 30 Mar 2017 + * \brief This files contain all definitions for the ControllerPatcher engine + * + * @see https://github.com/Maschell/controller_patcher + */ + +#ifndef _CONTROLLER_PATCHER_DEFS_H_ +#define _CONTROLLER_PATCHER_DEFS_H_ + +#include + +#define FIRST_INSTRUCTION_IN_SAMPLING_CALLBACK 0x9421FFB8 + +#define HID_INIT_NOT_DONE 0 +#define HID_INIT_DONE 1 +#define HID_SDCARD_READ 2 + +#define gHIDMaxDevices 32 +#define HID_MAX_DATA_LENGTH_PER_PAD 16 +#define HID_MAX_PADS_COUNT 5 +#define HID_MAX_DEVICES_PER_SLOT 2 + +#define NETWORK_CONTROLLER_VID 0 +#define NETWORK_CONTROLLER_PID 1 +#define NETWORK_CONTROLLER_ACTIVE 2 +#define NETWORK_CONTROLLER_HANDLE 3 + + +#define CONTROLLER_PATCHER_VALUE_SET 0x01 +#define CONTROLLER_PATCHER_GC_DOUBLE_USE 0x01 +#define CONTROLLER_PATCHER_INVALIDVALUE 0xFF + +#define HID_INVALID_SLOT 0xFFFF +#define HID_INVALID_HIDMASK 0xFFFFFFFF + +typedef int CONTROLLER_PATCHER_RESULT_OR_ERROR; + +#define CONTROLLER_PATCHER_ERROR_NONE 0 +#define CONTROLLER_PATCHER_ERROR_INVALID_CHAN -1 +#define CONTROLLER_PATCHER_ERROR_UNKNOWN_VID_PID -2 +#define CONTROLLER_PATCHER_ERROR_FAILED_TO_GET_HIDDATA -3 +#define CONTROLLER_PATCHER_ERROR_MAPPING_DISABLED -4 +#define CONTROLLER_PATCHER_ERROR_INVALID_BUFFER -5 +#define CONTROLLER_PATCHER_ERROR_HID_NOT_CONNECTED -6 +#define CONTROLLER_PATCHER_ERROR_NO_PAD_CONNECTED -7 +#define CONTROLLER_PATCHER_ERROR_DEVICE_SLOT_NOT_FOUND -8 +#define CONTROLLER_PATCHER_ERROR_NULL_POINTER -9 +#define CONTROLLER_PATCHER_ERROR_CONFIG_NOT_DONE -10 +#define CONTROLLER_PATCHER_ERROR_NO_FREE_SLOT -11 +#define CONTROLLER_PATCHER_ERROR_UNKNOWN -50 + +#define PRO_CONTROLLER_MODE_KPADDATA 0 +#define PRO_CONTROLLER_MODE_WPADReadData 1 + +#define STICK_VALUE_UP 1 << 1 +#define STICK_VALUE_DOWN 1 << 2 +#define STICK_VALUE_LEFT 1 << 3 +#define STICK_VALUE_RIGHT 1 << 4 + +/** + * @brief The enumeration of Controller sticks defines + */ +enum Controller_Stick_Defines +{ + STICK_CONF_MAGIC_VERSION, /**< Version of the stick configuration. Changes with every format*/ + STICK_CONF_BYTE, /**< Byte where the stick-axis data is stored*/ + STICK_CONF_DEFAULT, /**< Default value*/ + STICK_CONF_DEADZONE, /**< Size of the deadzone */ + STICK_CONF_INVERT, /**< Is 1 when the axis is inverted */ + STICK_CONF_MIN, /**< Value that represent the minimum value (-1.0f)*/ + STICK_CONF_MAX, /**< Value that represent the maximum value (1.0f) */ + STICK_CONF_ENUM_MAXVALUE /**< Maxmimum enum value for iteration*/ +}; + +#define STICK_CONF_MAGIC_VALUE 0xF0 // When you change the enum above, Dont forget to change the magic version!!!! + +//! most data has the format: byte,value (byte starting at 0) +enum Controller_Patcher_Settings +{ + CONTRPS_VID, //! pid: 0x451d would be 0x45,0x1d + CONTRPS_PID, //! vid: 0x488d would be 0x48,0x8d + CONTRPS_BUF_SIZE, //! To set: CONTROLLER_PATCHER_VALUE_SET, BUF_SIZE (default is 64) + CONTRPS_VPAD_BUTTON_A, + CONTRPS_VPAD_BUTTON_B, + CONTRPS_VPAD_BUTTON_X, + CONTRPS_VPAD_BUTTON_Y, + CONTRPS_DPAD_MODE, //! To set mode: CONTROLLER_PATCHER_VALUE_SET, Controller_Patcher_DPAD_MODE (default is normal mode) + CONTRPS_DPAD_MASK, //! Mask needed for hat mode: CONTROLLER_PATCHER_VALUE_SET, mask + /* Normal DPAD */ + CONTRPS_VPAD_BUTTON_LEFT, + CONTRPS_VPAD_BUTTON_RIGHT, + CONTRPS_VPAD_BUTTON_UP, + CONTRPS_VPAD_BUTTON_DOWN, + /* DPAD hat mode */ + CONTRPS_VPAD_BUTTON_DPAD_N, + CONTRPS_VPAD_BUTTON_DPAD_NE, + CONTRPS_VPAD_BUTTON_DPAD_E, + CONTRPS_VPAD_BUTTON_DPAD_SE, + CONTRPS_VPAD_BUTTON_DPAD_S, + CONTRPS_VPAD_BUTTON_DPAD_SW, + CONTRPS_VPAD_BUTTON_DPAD_W, + CONTRPS_VPAD_BUTTON_DPAD_NW, + CONTRPS_VPAD_BUTTON_DPAD_NEUTRAL, + /* DPAD Absolute mode */ + CONTRPS_VPAD_BUTTON_DPAD_ABS_UP, + CONTRPS_VPAD_BUTTON_DPAD_ABS_DOWN, + CONTRPS_VPAD_BUTTON_DPAD_ABS_LEFT, + CONTRPS_VPAD_BUTTON_DPAD_ABS_RIGHT, + /* */ + CONTRPS_VPAD_BUTTON_ZL, + CONTRPS_VPAD_BUTTON_ZR, + CONTRPS_VPAD_BUTTON_L, + CONTRPS_VPAD_BUTTON_R, + CONTRPS_VPAD_BUTTON_PLUS, + CONTRPS_VPAD_BUTTON_MINUS, + CONTRPS_VPAD_BUTTON_HOME, + CONTRPS_VPAD_BUTTON_SYNC, + CONTRPS_VPAD_BUTTON_STICK_R, + CONTRPS_VPAD_BUTTON_STICK_L, + + CONTRPS_VPAD_STICK_R_EMULATION_LEFT, + CONTRPS_VPAD_STICK_R_EMULATION_RIGHT, + CONTRPS_VPAD_STICK_R_EMULATION_UP, + CONTRPS_VPAD_STICK_R_EMULATION_DOWN, + CONTRPS_VPAD_STICK_L_EMULATION_LEFT, + CONTRPS_VPAD_STICK_L_EMULATION_RIGHT, + CONTRPS_VPAD_STICK_L_EMULATION_UP, + CONTRPS_VPAD_STICK_L_EMULATION_DOWN, + + CONTRPS_VPAD_BUTTON_L_STICK_X, //! byte, default value + CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT, //! To invert: CONTROLLER_PATCHER_VALUE_SET, 0x01 + CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE, //! Deadzone + CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX, //! min,max + CONTRPS_VPAD_BUTTON_L_STICK_Y, //! byte, default value + CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT, //! To invert: CONTROLLER_PATCHER_VALUE_SET, 0x01 + CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE, //! Deadzone + CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX, //! min,max + CONTRPS_VPAD_BUTTON_R_STICK_X, //! byte, default value + CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT, //! To invert: CONTROLLER_PATCHER_VALUE_SET, 0x01 + CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE, //! Deadzone + CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX, //! min,max + CONTRPS_VPAD_BUTTON_R_STICK_Y, //! byte, default value + CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT, //! To invert: CONTROLLER_PATCHER_VALUE_SET, 0x01 + CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE, //! Deadzone + CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX, //! min,max + + CONTRPS_VPAD_BUTTON_L_STICK_UP, + CONTRPS_VPAD_BUTTON_L_STICK_DOWN, + CONTRPS_VPAD_BUTTON_L_STICK_LEFT, + CONTRPS_VPAD_BUTTON_L_STICK_RIGHT, + CONTRPS_VPAD_BUTTON_R_STICK_UP, + CONTRPS_VPAD_BUTTON_R_STICK_DOWN, + CONTRPS_VPAD_BUTTON_R_STICK_LEFT, + CONTRPS_VPAD_BUTTON_R_STICK_RIGHT, + + CONTRPS_VPAD_BUTTON_TV, + CONTRPS_DOUBLE_USE, //!When used: e.g. CONTROLLER_PATCHER_VALUE_SET, CONTROLLER_PATCHER_GC_DOUBLE_USE + CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR, + CONTRPS_DOUBLE_USE_BUTTON_1_PRESSED, + CONTRPS_DOUBLE_USE_BUTTON_2_PRESSED, + CONTRPS_DOUBLE_USE_BUTTON_3_PRESSED, + CONTRPS_DOUBLE_USE_BUTTON_4_PRESSED, + CONTRPS_DOUBLE_USE_BUTTON_5_PRESSED, + CONTRPS_DOUBLE_USE_BUTTON_1_RELEASED, + CONTRPS_DOUBLE_USE_BUTTON_2_RELEASED, + CONTRPS_DOUBLE_USE_BUTTON_3_RELEASED, + CONTRPS_DOUBLE_USE_BUTTON_4_RELEASED, + CONTRPS_DOUBLE_USE_BUTTON_5_RELEASED, + CONTRPS_PAD_COUNT, //! + CONTRPS_CONNECTED_PADS, //! + CONTRPS_INPUT_FILTER, //! + CONTRPS_PAD1_FILTER, //! + CONTRPS_PAD2_FILTER, //! + CONTRPS_PAD3_FILTER, //! + CONTRPS_PAD4_FILTER, //! + CONTRPS_PAD5_FILTER, //! + CONTRPS_MOUSE_STICK, + CONTRPS_MAX_VALUE +}; +/** + * @brief The enumeration of different DPAD-Modes + */ +enum Controller_Patcher_DPAD_MODE +{ + CONTRPDM_Normal, /**< Normal mode */ + CONTRPDM_Hat, /**< Hat mode */ + CONTRPDM_Absolute_2Values, /**< DPAD Value stored in 2 values (one for each axis), acting like a stick */ +}; +/** + * @brief The enumeration of DPAD Settings. Needed for saving both in the PADConst. + */ +enum Controller_Patcher_DPAD_Settings +{ + CONTRDPAD_MODE = 0, /**< Byte where the DPAD Mode is stored */ + CONTRDPAD_MASK = 1, /**< Byte where the DPAD Mask is stored */ +}; + +/** + * @brief Stores data if the Slot the device is using in gHID_Devices + */ +typedef struct _HIDSlotData{ + u16 deviceslot; /**< deviceslot number */ + u32 hidmask; /**< Used HID-Mask */ +}HIDSlotData; + +/** + * @brief Stores a VID and PID + */ +typedef struct _DeviceVIDPIDInfo{ + u16 vid; /**< Vendor ID of this device */ + u16 pid; /**< Product ID of this device */ +}DeviceVIDPIDInfo; + +/** + * @brief Struct where the data for the callback funtion is stored + */ +typedef struct _my_cb_user{ + u8 *buf; /**< pointer the buffer that is used */ + u32 transfersize; /**< number of transfered data */ + u32 handle; /**< HID handle */ + HIDSlotData slotdata; /**< Information about the deviceslot and hidmask */ + u32 pads_per_device; /**< Number of maximum pads of this device */ + u8 pad_slot; /**< number of the pad that will be used */ + u8 rumblestatus[HID_MAX_PADS_COUNT]; /**< Current status of the device rumble */ + u8 forceRumbleInTicks[HID_MAX_PADS_COUNT]; + DeviceVIDPIDInfo vidpid; /**< The VID/PID of the device */ +}my_cb_user; + +/** + * @brief Stores data for the mouse + */ +typedef struct _HID_Mouse_Data { + u8 left_click; /**< Is 1 when the left mouse button is pressed */ + u8 right_click; /**< Is 1 when the right mouse button is pressed */ + s16 X; /**< X position of the cursor */ + s16 Y; /**< Y position of the cursor */ + s16 deltaX; /**< difference of the X value since the last call */ + s16 deltaY; /**< difference of the Y value since the last call */ + u8 valuedChanged; /**< Is 1 when the value has changed */ +} HID_Mouse_Data; + +/** + * @brief The enumeration of device types + */ +typedef enum DEVICE_TYPE_ +{ + DEVICE_TYPE_CONTROLLER = 0, /**< Normal Controller */ + DEVICE_TYPE_MOUSE = 1, /**< Mouse */ +}DEVICE_TYPE; + +/** + * @brief Stores all data of the HID Device for accessing + */ +typedef struct _HID_Data { + u32 handle; /**< The HID-handle this device is using */ + u8 rumbleActive; /**< 1 when rumble is active */ + u32 last_buttons; /**< The last pressed buttons, based on VPAD_BUTTON_XXX data */ + union{ + struct{ + u8 cur_hid_data[HID_MAX_DATA_LENGTH_PER_PAD]; /**< Array where the current controller data is stored */ + u8 last_hid_data[HID_MAX_DATA_LENGTH_PER_PAD]; /**< Array where the last controller data is stored */ + } controller; /**< Used when the device in a controller. Using u8 array where the raw data of the controller is placed. */ + struct{ + HID_Mouse_Data cur_mouse_data; /**< Struct where the current mouse data is stored */ + HID_Mouse_Data last_mouse_data; /**< Struct where the last mouse data is stored */ + } mouse; /**< Used when the device in a mouse. Using a new struct to store the data. */ + }data_union; /**< The data union where the current and last data is stored.*/ + DEVICE_TYPE type; /**< The device type*/ + HIDSlotData slotdata; /**< Information about the deviceslot and his mask*/ + my_cb_user * user_data; /**< Pointer to the user data the read callback is using*/ +} HID_Data; + + +/** + * @brief Struct where current hid data of one device type is stored + */ +typedef struct _HID_DEVICE_DATA { + HID_Data pad_data[HID_MAX_PADS_COUNT]; +} HID_DEVICE_DATA; + +/** + * @brief Infos of the device + */ +typedef struct _DeviceInfo{ + HIDSlotData slotdata; /**< The slot used by this device */ + DeviceVIDPIDInfo vidpid; /**< The VID/PID of the device */ + u8 pad_count; /**< Number of maximum pads this device can have*/ +}DeviceInfo; + +/** + * @brief The enumeration of Controller-Mapping types + */ +typedef enum ControllerMapping_Type_Defines_{ + CM_Type_Controller = 0, /**< Device with single input */ + CM_Type_RealController = 1, /**< Real Pro Controller */ + CM_Type_Mouse = 2, /**< Mouse */ + CM_Type_Keyboard = 3, /**< Keyboard */ +} ControllerMapping_Type_Defines; + +/** + * @brief Infos of a mapped controller + */ +typedef struct _ControllerMappingPADInfo{ + u8 active; /**< Set to one if mapped */ + ControllerMapping_Type_Defines type; /**< Type of the controller mapping */ + DeviceVIDPIDInfo vidpid; /**< The VID/PID of the device */ + u8 pad; /**< Stores which pad it mapped */ +}ControllerMappingPADInfo; + +/** + * @brief Infos of a mapped controller + */ +typedef struct _ControllerMappingPAD{ + ControllerMappingPADInfo pad_infos[HID_MAX_DEVICES_PER_SLOT]; //lets limit this to HID_MAX_DEVICES_PER_SLOT. + u8 useAll; + u8 rumble; /**< Set when the controller should rumble */ +}ControllerMappingPAD; + +/** + * @brief Stores informations about all mapped controller + */ +typedef struct _ControllerMapping{ + ControllerMappingPAD gamepad; /**< Information about the gamepad mapping */ + ControllerMappingPAD proController[4]; /**< Information about the Pro Controller mapping */ +}ControllerMapping; + +/** + * @brief Pressed/Released/Down Button data. + */ +typedef struct _InputButtonData{ + u32 hold; /**< Buttons beeing hold */ + u32 trigger; /**< Buttons that started pressing */ + u32 release; /**< Buttons that were button released */ +}InputButtonData; + +typedef struct _InputStickData{ + f32 leftStickX; + f32 leftStickY; + f32 rightStickX; + f32 rightStickY; +}InputStickData; + +/** + * @brief Struct where the inputdata of a device for all HID_MAX_PADS_COUNT pads can be stored + */ +typedef struct _InputData{ + DeviceInfo device_info; /**< Infos about the device where the data is coming from */ + u8 status; + InputButtonData button_data; + InputStickData stick_data; +}InputData; + +/** + * @brief The enumeration of WiiU Controller types + */ +enum UController_Type{ + UController_Type_Gamepad, + UController_Type_Pro1, + UController_Type_Pro2, + UController_Type_Pro3, + UController_Type_Pro4, +}; + +#define UController_Type_Gamepad_Name gettext("GamePad") +#define UController_Type_Pro1_Name gettext("Pro Controller 1") +#define UController_Type_Pro2_Name gettext("Pro Controller 2") +#define UController_Type_Pro3_Name gettext("Pro Controller 3") +#define UController_Type_Pro4_Name gettext("Pro Controller 4") + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * VID/PID values + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + + +#define HID_GC_VID 0x057e +#define HID_GC_PID 0x0337 + +#define HID_KEYBOARD_VID 0xAFFE +#define HID_KEYBOARD_PID 0XAAAC + +#define HID_MOUSE_VID 0xAFFE +#define HID_MOUSE_PID 0XAAAB + +#define HID_DS3_VID 0x054c +#define HID_DS3_PID 0x0268 + +#define HID_DS4_VID 0x054c +#define HID_DS4_PID 0x05c4 + +#define HID_NEW_DS4_VID 0x054c +#define HID_NEW_DS4_PID 0x09CC + +#define HID_XINPUT_VID 0x7331 +#define HID_XINPUT_PID 0x1337 + +#define HID_SWITCH_PRO_VID 0x057e +#define HID_SWITCH_PRO_PID 0x2009 + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * GC Adapter + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +#define HID_GC_BUTTON_A_VALUE 0x01 +#define HID_GC_BUTTON_B_VALUE 0x02 +#define HID_GC_BUTTON_X_VALUE 0x04 +#define HID_GC_BUTTON_Y_VALUE 0x08 +#define HID_GC_BUTTON_LEFT_VALUE 0x10 +#define HID_GC_BUTTON_RIGHT_VALUE 0x20 +#define HID_GC_BUTTON_DOWN_VALUE 0x40 +#define HID_GC_BUTTON_UP_VALUE 0x80 + +#define HID_GC_BUTTON_START_VALUE 0x01 +#define HID_GC_BUTTON_L_VALUE 0x80 +#define HID_GC_BUTTON_R_VALUE 0x80 +#define HID_GC_BUTTON_Z_VALUE 0x02 + +#define HID_GC_PAD_COUNT 4 + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * DS3 + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +#define PS3_F4_REPORT_LEN 4 +#define PS3_F5_REPORT_LEN 8 +#define PS3_01_REPORT_LEN 48 +#define HID_REPORT_FEATURE 3 +#define HID_REPORT_OUTPUT 2 +#define PS3_F4_REPORT_ID 0xF4 +#define PS3_01_REPORT_ID 0x01 +#define PS3_F5_REPORT_ID 0xF5 + +#define HID_DS3_BUTTON_CROSS_VALUE 0x40 // 3 +#define HID_DS3_BUTTON_CIRCLE_VALUE 0x20 // 3 +#define HID_DS3_BUTTON_SQUARE_VALUE 0x80 // 3 +#define HID_DS3_BUTTON_TRIANGLE_VALUE 0x10 // 3 +#define HID_DS3_BUTTON_L1_VALUE 0x04 // 3 +#define HID_DS3_BUTTON_L2_VALUE 0x01 // 3 +#define HID_DS3_BUTTON_R1_VALUE 0x08 // 3 +#define HID_DS3_BUTTON_R2_VALUE 0x02 // 3 + +#define HID_DS3_BUTTON_L3_VALUE 0x02 // 2 +#define HID_DS3_BUTTON_R3_VALUE 0x04 // 2 +#define HID_DS3_BUTTON_SELECT_VALUE 0x01 // 2 +#define HID_DS3_BUTTON_START_VALUE 0x08 // 2 +#define HID_DS3_BUTTON_LEFT_VALUE 0x80 // 2 +#define HID_DS3_BUTTON_RIGHT_VALUE 0x20 // 2 +#define HID_DS3_BUTTON_UP_VALUE 0x10 // 2 +#define HID_DS3_BUTTON_DOWN_VALUE 0x40 // 2 +#define HID_DS3_BUTTON_GUIDE_VALUE 0x01 // 4 + +#define HID_DS3_PAD_COUNT 1 + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * DS4 + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +#define HID_DS4_BUTTON_CROSS_VALUE 0x20 // 5 +#define HID_DS4_BUTTON_SQUARE_VALUE 0x10 // 5 +#define HID_DS4_BUTTON_CIRCLE_VALUE 0x40 // 5 +#define HID_DS4_BUTTON_TRIANGLE_VALUE 0x80 // 5 +#define HID_DS4_BUTTON_L1_VALUE 0x01 // 6 +#define HID_DS4_BUTTON_L2_VALUE 0x04 // 6 +#define HID_DS4_BUTTON_L3_VALUE 0x40 // 6 +#define HID_DS4_BUTTON_R1_VALUE 0x02 // 6 +#define HID_DS4_BUTTON_R2_VALUE 0x08 // 6 +#define HID_DS4_BUTTON_R3_VALUE 0x80 // 6 +#define HID_DS4_BUTTON_SHARE_VALUE 0x10 // 6 +#define HID_DS4_BUTTON_OPTIONS_VALUE 0x20 // 6 + +#define HID_DS4_BUTTON_DPAD_MASK_VALUE 0x0F + +#define HID_DS4_BUTTON_DPAD_N_VALUE 0x00 // 5 +#define HID_DS4_BUTTON_DPAD_NE_VALUE 0x01 // 5 +#define HID_DS4_BUTTON_DPAD_E_VALUE 0x02 // 5 +#define HID_DS4_BUTTON_DPAD_SE_VALUE 0x03 // 5 +#define HID_DS4_BUTTON_DPAD_S_VALUE 0x04 // 5 +#define HID_DS4_BUTTON_DPAD_SW_VALUE 0x05 // 5 +#define HID_DS4_BUTTON_DPAD_W_VALUE 0x06 // 5 +#define HID_DS4_BUTTON_DPAD_NW_VALUE 0x07 // 5 +#define HID_DS4_BUTTON_DPAD_NEUTRAL_VALUE 0x08 // 5 + +#define HID_DS4_BUTTON_GUIDE_VALUE 0x01 // 7 +#define HID_DS4_BUTTON_T_PAD_CLICK_VALUE 0x02 // 7 + +#define HID_DS4_PAD_COUNT 1 + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * XInput + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +#define HID_XINPUT_BUTTON_A_VALUE 0x01 // 7 +#define HID_XINPUT_BUTTON_B_VALUE 0x02 // 7 +#define HID_XINPUT_BUTTON_X_VALUE 0x04 // 7 +#define HID_XINPUT_BUTTON_Y_VALUE 0x08 // 7 + +#define HID_XINPUT_BUTTON_START_VALUE 0x02 // 6 +#define HID_XINPUT_BUTTON_BACK_VALUE 0x01 // 6 +#define HID_XINPUT_BUTTON_GUIDE_VALUE 0x80 // 6 + +#define HID_XINPUT_BUTTON_LB_VALUE 0x04 // 6 +#define HID_XINPUT_BUTTON_RB_VALUE 0x08 // 6 + +#define HID_XINPUT_BUTTON_L3_VALUE 0x10 // 6 +#define HID_XINPUT_BUTTON_R3_VALUE 0x20 // 6 + +#define HID_XINPUT_BUTTON_LT_VALUE 0x80 // 4 +#define HID_XINPUT_BUTTON_RT_VALUE 0x80 // 5 + +#define HID_XINPUT_BUTTON_DPAD_MASK_VALUE 0xF0 +#define HID_XINPUT_BUTTON_LEFT_VALUE 0x10 // 7 +#define HID_XINPUT_BUTTON_RIGHT_VALUE 0x40 // 7 +#define HID_XINPUT_BUTTON_DOWN_VALUE 0x80 // 7 +#define HID_XINPUT_BUTTON_UP_VALUE 0x20 // 7 + +#define HID_XINPUT_PAD_COUNT 1 + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Switch Pro Controller + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +#define HID_SWITCH_PRO_USB_BUTTON_A_VALUE 0x08000000 +#define HID_SWITCH_PRO_USB_BUTTON_B_VALUE 0x04000000 +#define HID_SWITCH_PRO_USB_BUTTON_X_VALUE 0x02000000 +#define HID_SWITCH_PRO_USB_BUTTON_Y_VALUE 0x01000000 +#define HID_SWITCH_PRO_USB_BUTTON_PLUS_VALUE 0x00020000 +#define HID_SWITCH_PRO_USB_BUTTON_MINUS_VALUE 0x00010000 +#define HID_SWITCH_PRO_USB_BUTTON_HOME_VALUE 0x00100000 +#define HID_SWITCH_PRO_USB_BUTTON_SCREENSHOT_VALUE 0x00200000 +#define HID_SWITCH_PRO_USB_BUTTON_R_VALUE 0x40000000 +#define HID_SWITCH_PRO_USB_BUTTON_ZR_VALUE 0x80000000 +#define HID_SWITCH_PRO_USB_BUTTON_STICK_R_VALUE 0x00040000 +#define HID_SWITCH_PRO_USB_BUTTON_L_VALUE 0x00004000 +#define HID_SWITCH_PRO_USB_BUTTON_ZL_VALUE 0x00008000 +#define HID_SWITCH_PRO_USB_BUTTON_STICK_L_VALUE 0x00080000 + +#define HID_SWITCH_PRO_USB_BUTTON_DPAD_MASK_VALUE 0x0F +#define HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE 0x08 // 2 +#define HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE 0x04 // 2 +#define HID_SWITCH_PRO_USB_BUTTON_DOWN_VALUE 0x01 // 2 +#define HID_SWITCH_PRO_USB_BUTTON_UP_VALUE 0x02 // 2 + +#define HID_SWITCH_PRO_BT_BUTTON_A_VALUE 0x02000000 +#define HID_SWITCH_PRO_BT_BUTTON_B_VALUE 0x01000000 +#define HID_SWITCH_PRO_BT_BUTTON_X_VALUE 0x08000000 +#define HID_SWITCH_PRO_BT_BUTTON_Y_VALUE 0x04000000 +#define HID_SWITCH_PRO_BT_BUTTON_PLUS_VALUE 0x00020000 +#define HID_SWITCH_PRO_BT_BUTTON_MINUS_VALUE 0x00010000 +#define HID_SWITCH_PRO_BT_BUTTON_HOME_VALUE 0x00100000 + +#define HID_SWITCH_PRO_BT_BUTTON_R_VALUE 0x20000000 +#define HID_SWITCH_PRO_BT_BUTTON_ZR_VALUE 0x80000000 +#define HID_SWITCH_PRO_BT_BUTTON_STICK_R_VALUE 0x00080000 + +#define HID_SWITCH_PRO_BT_BUTTON_L_VALUE 0x10000000 +#define HID_SWITCH_PRO_BT_BUTTON_ZL_VALUE 0x40000000 +#define HID_SWITCH_PRO_BT_BUTTON_STICK_L_VALUE 0x00040000 + + +#define HID_SWITCH_PRO_BT_BUTTON_DPAD_MASK_VALUE 0x0F +#define HID_SWITCH_PRO_BT_BUTTON_DPAD_N_VALUE 0x00 // 2 +#define HID_SWITCH_PRO_BT_BUTTON_DPAD_NE_VALUE 0x01 // 2 +#define HID_SWITCH_PRO_BT_BUTTON_DPAD_E_VALUE 0x02 // 2 +#define HID_SWITCH_PRO_BT_BUTTON_DPAD_SE_VALUE 0x03 // 2 +#define HID_SWITCH_PRO_BT_BUTTON_DPAD_S_VALUE 0x04 // 2 +#define HID_SWITCH_PRO_BT_BUTTON_DPAD_SW_VALUE 0x05 // 2 +#define HID_SWITCH_PRO_BT_BUTTON_DPAD_W_VALUE 0x06 // 2 +#define HID_SWITCH_PRO_BT_BUTTON_DPAD_NW_VALUE 0x07 // 2 +#define HID_SWITCH_PRO_BT_BUTTON_DPAD_NEUTRAL_VALUE 0x08 // 2 + + +#define HID_SWITCH_PRO_BT_PAD_COUNT 1 + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Keyboard (Full list is on: http://www.freebsddiary.org/APC/usb_hid_usages.php) + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +#define HID_KEYBOARD_BUTTON_SHIFT 0x02 + +#define HID_KEYBOARD_BUTTON_A 0x04 +#define HID_KEYBOARD_BUTTON_B 0x05 +#define HID_KEYBOARD_BUTTON_C 0x06 +#define HID_KEYBOARD_BUTTON_D 0x07 +#define HID_KEYBOARD_BUTTON_E 0x08 +#define HID_KEYBOARD_BUTTON_F 0x09 +#define HID_KEYBOARD_BUTTON_G 0x0A +#define HID_KEYBOARD_BUTTON_H 0x0B +#define HID_KEYBOARD_BUTTON_I 0x0C +#define HID_KEYBOARD_BUTTON_J 0x0D +#define HID_KEYBOARD_BUTTON_K 0x0E +#define HID_KEYBOARD_BUTTON_L 0x0F +#define HID_KEYBOARD_BUTTON_M 0x10 +#define HID_KEYBOARD_BUTTON_N 0x11 +#define HID_KEYBOARD_BUTTON_O 0x12 +#define HID_KEYBOARD_BUTTON_P 0x13 +#define HID_KEYBOARD_BUTTON_Q 0x14 +#define HID_KEYBOARD_BUTTON_R 0x15 +#define HID_KEYBOARD_BUTTON_S 0x16 +#define HID_KEYBOARD_BUTTON_T 0x17 +#define HID_KEYBOARD_BUTTON_U 0x18 +#define HID_KEYBOARD_BUTTON_V 0x19 +#define HID_KEYBOARD_BUTTON_W 0x1A +#define HID_KEYBOARD_BUTTON_X 0x1B +#define HID_KEYBOARD_BUTTON_Y 0x1C +#define HID_KEYBOARD_BUTTON_Z 0x1D +#define HID_KEYBOARD_BUTTON_F1 0x3A +#define HID_KEYBOARD_BUTTON_F2 0x3B +#define HID_KEYBOARD_BUTTON_F3 0x3C +#define HID_KEYBOARD_BUTTON_F4 0x3D +#define HID_KEYBOARD_BUTTON_F5 0x3E +#define HID_KEYBOARD_BUTTON_F6 0x3F +#define HID_KEYBOARD_BUTTON_F7 0x40 +#define HID_KEYBOARD_BUTTON_F8 0x41 +#define HID_KEYBOARD_BUTTON_F9 0x42 +#define HID_KEYBOARD_BUTTON_F10 0x43 +#define HID_KEYBOARD_BUTTON_F11 0x44 +#define HID_KEYBOARD_BUTTON_F12 0x45 +#define HID_KEYBOARD_BUTTON_1 0x1E +#define HID_KEYBOARD_BUTTON_2 0x1F +#define HID_KEYBOARD_BUTTON_3 0x20 +#define HID_KEYBOARD_BUTTON_4 0x21 +#define HID_KEYBOARD_BUTTON_5 0x22 +#define HID_KEYBOARD_BUTTON_6 0x23 +#define HID_KEYBOARD_BUTTON_7 0x24 +#define HID_KEYBOARD_BUTTON_8 0x25 +#define HID_KEYBOARD_BUTTON_9 0x26 +#define HID_KEYBOARD_BUTTON_0 0x27 + +#define HID_KEYBOARD_BUTTON_RETURN 0x28 +#define HID_KEYBOARD_BUTTON_ESCAPE 0x29 +#define HID_KEYBOARD_BUTTON_DELETE 0x2A +#define HID_KEYBOARD_BUTTON_TAB 0x2B +#define HID_KEYBOARD_BUTTON_SPACEBAR 0x2C +#define HID_KEYBOARD_BUTTON_CAPSLOCK 0x39 +#define HID_KEYBOARD_BUTTON_PRINTSCREEN 0x46 +#define HID_KEYBOARD_BUTTON_SCROLLLOCK 0x47 +#define HID_KEYBOARD_BUTTON_PAUSE 0x48 +#define HID_KEYBOARD_BUTTON_INSERT 0x49 +#define HID_KEYBOARD_BUTTON_HOME 0x4A +#define HID_KEYBOARD_BUTTON_PAGEUP 0x4B +#define HID_KEYBOARD_BUTTON_PAGEDOWN 0x4E +#define HID_KEYBOARD_BUTTON_DELETEFORWARD 0x4C +#define HID_KEYBOARD_BUTTON_END 0x4D +#define HID_KEYBOARD_BUTTON_LEFT_CONTROL 0xE0 +#define HID_KEYBOARD_BUTTON_LEFT_ALT 0xE2 +#define HID_KEYBOARD_BUTTON_RIGHT_CONTROL 0xE4 +#define HID_KEYBOARD_BUTTON_RIGHT_SHIFT 0xE5 +#define HID_KEYBOARD_BUTTON_RIGHT_ALT 0xE6 + +#define HID_KEYBOARD_BUTTON_LEFT 0x50 +#define HID_KEYBOARD_BUTTON_RIGHT 0x4f +#define HID_KEYBOARD_BUTTON_DOWN 0x51 +#define HID_KEYBOARD_BUTTON_UP 0x52 + +#define HID_KEYBOARD_KEYPAD_BUTTON_1 0x59 +#define HID_KEYBOARD_KEYPAD_BUTTON_2 0x5A +#define HID_KEYBOARD_KEYPAD_BUTTON_3 0x5B +#define HID_KEYBOARD_KEYPAD_BUTTON_4 0x5C +#define HID_KEYBOARD_KEYPAD_BUTTON_5 0x5D +#define HID_KEYBOARD_KEYPAD_BUTTON_6 0x5E +#define HID_KEYBOARD_KEYPAD_BUTTON_7 0x5F +#define HID_KEYBOARD_KEYPAD_BUTTON_8 0x60 +#define HID_KEYBOARD_KEYPAD_BUTTON_9 0x61 +#define HID_KEYBOARD_KEYPAD_BUTTON_0 0x62 +#define HID_KEYBOARD_KEYPAD_BUTTON_NUMLOCK 0x53 +#define HID_KEYBOARD_KEYPAD_BUTTON_MINUS 0x56 +#define HID_KEYBOARD_KEYPAD_BUTTON_PLUS 0x57 + +#define HID_KEYBOARD_PAD_COUNT 1 +#define HID_KEYBOARD_DATA_LENGTH 8 + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Mouse + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +#define HID_MOUSE_BUTTON_LEFTCLICK 0x04 +#define HID_MOUSE_BUTTON_RIGHTCLICK 0x05 + +#define HID_MOUSE_PAD_COUNT 1 + +#define HID_MOUSE_MODE_AIM 0x01 +#define HID_MOUSE_MODE_TOUCH 0x02 + +#endif /* _CONTROLLER_PATCHER_DEFS_H_ */ diff --git a/wiiu/controller_patcher/patcher/ControllerPatcherHID.cpp b/wiiu/controller_patcher/patcher/ControllerPatcherHID.cpp new file mode 100644 index 0000000000..7bafcd0176 --- /dev/null +++ b/wiiu/controller_patcher/patcher/ControllerPatcherHID.cpp @@ -0,0 +1,707 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#include "ControllerPatcherHID.hpp" + +#include +#include +#include + +#include "wiiu/os.h" + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * public implementation for the network controller + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +s32 ControllerPatcherHID::externAttachDetachCallback(HIDDevice *p_device, u32 attach){ + HIDClient client; + memset(&client,0,sizeof(client)); + return AttachDetachCallback(&client,p_device,attach); +} + +void ControllerPatcherHID::externHIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr){ + HIDReadCallback(handle,buf,bytes_transfered,usr); +} + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * private implementation for the HID Api. + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +s32 ControllerPatcherHID::myAttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, u32 attach){ + return AttachDetachCallback(p_client,p_device,attach); +} + +void ControllerPatcherHID::myHIDMouseReadCallback(u32 handle, s32 error, unsigned char *buf, u32 bytes_transfered, void *p_user){ + if(error == 0){ + my_cb_user *usr = (my_cb_user*)p_user; + + u32 slot = 0; + if(usr->pad_slot < HID_MAX_PADS_COUNT){ + slot = usr->pad_slot; + } + + HID_Data * data_ptr = &(gHID_Devices[usr->slotdata.deviceslot].pad_data[slot]); + HID_Mouse_Data * cur_mouse_data = &data_ptr->data_union.mouse.cur_mouse_data; + + data_ptr->type = DEVICE_TYPE_MOUSE; + //printf("%02X %02X %02X %02X %02X bytes_transfered: %d\n",buf[0],buf[1],buf[2],buf[3],buf[4],bytes_transfered); + + if(buf[0] == 2 && bytes_transfered > 3){ // using the other mouse mode + buf +=1; + } + + s8 x_value = 0; + s8 y_value = 0; + + x_value = buf[1]; + y_value = buf[2]; + + cur_mouse_data->X += x_value; + cur_mouse_data->deltaX = x_value; + + cur_mouse_data->Y += y_value; + cur_mouse_data->deltaY = y_value; + + cur_mouse_data->left_click = buf[0]; + cur_mouse_data->right_click = buf[0]>>1; + + if(cur_mouse_data->X < 0) cur_mouse_data->X = 0; + if(cur_mouse_data->X > 1280) cur_mouse_data->X = 1280; + + if(cur_mouse_data->Y < 0) cur_mouse_data->Y = 0; + if(cur_mouse_data->Y > 720) cur_mouse_data->Y = 720; + + cur_mouse_data->valuedChanged = 1; + + //printf("%02X %02X %02X %02X %02X %02X %02X %02X %d = X: %d Y: %d \n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],bytes_transfered,x_value,y_value); + + HIDRead(handle, usr->buf, bytes_transfered, myHIDMouseReadCallback, usr); + } +} + +void ControllerPatcherHID::myHIDReadCallback(u32 handle, s32 error, unsigned char *buf, u32 bytes_transfered, void *p_user){ + if(error == 0 && p_user != NULL && gHIDAttached){ + my_cb_user *usr = (my_cb_user*)p_user; + + HIDReadCallback(handle,buf,bytes_transfered,usr); + + if(usr->slotdata.hidmask == gHID_LIST_DS4){ + wiiu_os_usleep(1000*2); //DS4 is way tooo fast. sleeping to reduce lag. (need to check the other pads) + } + HIDRead(handle, usr->buf, bytes_transfered, myHIDReadCallback, usr); + } +} + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Intern Callback actions + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, u32 attach){ + if(attach){ + printf("ControllerPatcherHID::AttachDetachCallback(line %d): vid %04x pid %04x connected\n",__LINE__, SWAP16(p_device->vid),SWAP16(p_device->pid)); + if(HID_DEBUG){ printf("interface index %02x\n", p_device->interface_index); + printf("sub class %02x\n", p_device->sub_class); + printf("protocol %02x\n", p_device->protocol); + printf("max packet in %02x\n", p_device->max_packet_size_rx); + printf("max packet out %02x\n", p_device->max_packet_size_tx); } + } + if(!attach){ + printf("ControllerPatcherHID::AttachDetachCallback(line %d): vid %04x pid %04x disconnected\n",__LINE__, SWAP16(p_device->vid),SWAP16(p_device->pid)); + } + DeviceInfo device_info; + memset(&device_info,0,sizeof(DeviceInfo)); + device_info.slotdata.deviceslot = -1; + device_info.vidpid.vid = SWAP16(p_device->vid); + device_info.vidpid.pid = SWAP16(p_device->pid); + + HIDSlotData * slotdata = &(device_info.slotdata); + + if ((p_device->sub_class == 1) && (p_device->protocol == 1)) { //Keyboard + slotdata->hidmask = gHID_LIST_KEYBOARD; + slotdata->deviceslot = gHID_SLOT_KEYBOARD; + //printf("Found Keyboard: device: %s slot: %d\n",byte_to_binary(device_info.slotdata.hidmask),device_info.slotdata.deviceslot); + }else if ((p_device->sub_class == 1) && (p_device->protocol == 2)){ // MOUSE + slotdata->hidmask = gHID_LIST_MOUSE; + slotdata->deviceslot = gMouseSlot; + //printf("Found Mouse: device: %s slot: %d\n",byte_to_binary(device_info.hid),device_info.slot); + }else{ + s32 ret; + if((ret = ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info)) < 0){ + printf("ControllerPatcherHID::AttachDetachCallback(line %d): ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) failed %d \n",__LINE__,ret); + return HID_DEVICE_DETACH; + }else{ + //printf("ControllerPatcherHID::AttachDetachCallback(line %d): ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) success %d \n",__LINE__,ret); + } + } + + if(slotdata->hidmask){ + if(attach){ + s32 bufSize = 64; + if(slotdata->hidmask != gHID_LIST_MOUSE && config_controller[slotdata->deviceslot][CONTRPS_BUF_SIZE][0] == CONTROLLER_PATCHER_VALUE_SET){ + bufSize = config_controller[slotdata->deviceslot][CONTRPS_BUF_SIZE][1]; + } + unsigned char *buf = (unsigned char *) memalign(64,bufSize); + memset(buf,0,bufSize); + my_cb_user *usr = (my_cb_user *) memalign(64,sizeof(my_cb_user)); + usr->buf = buf; + usr->slotdata = device_info.slotdata; + usr->transfersize = p_device->max_packet_size_rx; + usr->handle = p_device->handle; + usr->vidpid = device_info.vidpid; + gHIDAttached |= slotdata->hidmask; + gHIDCurrentDevice |= slotdata->hidmask; + s32 pads_per_device = 1; + if(config_controller[slotdata->deviceslot][CONTRPS_PAD_COUNT][0] != CONTROLLER_PATCHER_INVALIDVALUE){ + pads_per_device = config_controller[slotdata->deviceslot][CONTRPS_PAD_COUNT][1]; + if(pads_per_device > HID_MAX_PADS_COUNT){//maximum of HID_MAX_PADS_COUNT + pads_per_device = HID_MAX_PADS_COUNT; + } + } + + s32 pad_count = config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1]; + if(pad_count > 0x0F) pad_count = 0; //??? + + s32 pad_slot = 0; + + s32 failed = 1; + + for(s32 i = 0;ideviceslot][CONTRPS_CONNECTED_PADS][1] = pad_count; + + DCFlushRange(&config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1],sizeof(config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1])); + DCInvalidateRange(&config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1],sizeof(config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1])); + + usr->pads_per_device = pads_per_device; + usr->pad_slot = pad_slot; + + for(s32 i = 0;ideviceslot].pad_data[pad_slot+i],0,sizeof(HID_Data)); + + gHID_Devices[slotdata->deviceslot].pad_data[pad_slot+i].handle = p_device->handle; + //printf("ControllerPatcherHID::AttachDetachCallback(line %d): saved handle %d to slot %d and pad %d\n",__LINE__,p_device->handle,slotdata->deviceslot,pad_slot); + + gHID_Devices[slotdata->deviceslot].pad_data[pad_slot+i].user_data = usr; + gHID_Devices[slotdata->deviceslot].pad_data[pad_slot+i].slotdata = device_info.slotdata; + + DCFlushRange(&gHID_Devices[slotdata->deviceslot].pad_data[pad_slot+i],sizeof(HID_Data)); + DCInvalidateRange(&gHID_Devices[slotdata->deviceslot].pad_data[pad_slot+i],sizeof(HID_Data)); + } + + for(s32 j = 0;j < pads_per_device; j++){ + for(s32 i = 0;i < gHIDMaxDevices; i++){ + if(connectionOrderHelper[i] == NULL){ + connectionOrderHelper[i] = usr; + break; + } + } + } + + if(HID_DEBUG){ printf("ControllerPatcherHID::AttachDetachCallback(line %d): Device successfully attached\n",__LINE__); } + + if(slotdata->hidmask == gHID_LIST_GC){ // GC PAD + //The GC Adapter has all ports in one device. Set them all. + gHID_Devices[slotdata->deviceslot].pad_data[0].slotdata = device_info.slotdata; + gHID_Devices[slotdata->deviceslot].pad_data[1].slotdata = device_info.slotdata; + gHID_Devices[slotdata->deviceslot].pad_data[2].slotdata = device_info.slotdata; + gHID_Devices[slotdata->deviceslot].pad_data[3].slotdata = device_info.slotdata; + + buf[0] = 0x13; + HIDWrite(p_device->handle, usr->buf, 1, NULL,NULL); + HIDRead(p_device->handle, usr->buf, usr->transfersize, myHIDReadCallback, usr); + }else if (slotdata->hidmask == gHID_LIST_MOUSE){ + HIDSetProtocol(p_device->handle, p_device->interface_index, 0, 0, 0); + //HIDGetDescriptor(p_device->handle,0x22,0x00,0,my_buf,512,my_foo_cb,NULL); + HIDSetIdle(p_device->handle,p_device->interface_index,1,NULL,NULL); + gHID_Mouse_Mode = HID_MOUSE_MODE_AIM; + HIDRead(p_device->handle, buf, p_device->max_packet_size_rx, myHIDMouseReadCallback, usr); + }else if (slotdata->hidmask == gHID_LIST_SWITCH_PRO){ + s32 read_result = HIDRead(p_device->handle, usr->buf, usr->transfersize, NULL, NULL); + if(read_result == 64){ + if(usr->buf[01] == 0x01){ //We need to do the handshake + printf("ControllerPatcherHID::AttachDetachCallback(line %d): Switch Pro Controller handshake needed\n",__LINE__); + /** + Thanks to ShinyQuagsire23 for the values (https://github.com/shinyquagsire23/HID-Joy-Con-Whispering) + **/ + //Get MAC + buf[0] = 0x80; + buf[1] = 0x01; + HIDWrite(p_device->handle, usr->buf, 2, NULL,NULL); + HIDRead(p_device->handle, usr->buf, usr->transfersize, NULL, NULL); + //Do handshake + buf[0] = 0x80; + buf[1] = 0x02; + HIDWrite(p_device->handle, usr->buf, 2, NULL,NULL); + HIDRead(p_device->handle, usr->buf, usr->transfersize, NULL, NULL); + //Talk over HID only. + buf[0] = 0x80; + buf[1] = 0x04; + HIDWrite(p_device->handle, usr->buf, 2, NULL,NULL); + HIDRead(p_device->handle, usr->buf, usr->transfersize, NULL, NULL); + }else{ + printf("ControllerPatcherHID::AttachDetachCallback(line %d): Switch Pro Controller handshake already done\n",__LINE__); + } + HIDRead(p_device->handle, usr->buf, usr->transfersize, myHIDReadCallback, usr); + } + }else if (slotdata->hidmask == gHID_LIST_KEYBOARD){ + HIDSetProtocol(p_device->handle, p_device->interface_index, 1, 0, 0); + HIDSetIdle(p_device->handle, p_device->interface_index, 0, 0, 0); + HIDRead(p_device->handle, buf, p_device->max_packet_size_rx, myHIDReadCallback, usr); + }else if (slotdata->hidmask == gHID_LIST_DS3){ + HIDSetProtocol(p_device->handle, p_device->interface_index, 1, 0, 0); + HIDDS3Rumble(p_device->handle,usr,0); + buf[0] = 0x42; buf[1] = 0x0c; buf[2] = 0x00; buf[3] = 0x00; + HIDSetReport(p_device->handle, HID_REPORT_FEATURE, PS3_F4_REPORT_ID, buf, PS3_F4_REPORT_LEN, NULL, NULL); + HIDRead(p_device->handle, usr->buf, p_device->max_packet_size_rx, myHIDReadCallback, usr); + }else{ + HIDRead(p_device->handle, usr->buf, p_device->max_packet_size_rx, myHIDReadCallback, usr); + } + return HID_DEVICE_ATTACH; + + }else{ + my_cb_user * user_data = NULL; + s32 founddata = 0; + for(s32 i = 0;ideviceslot].pad_data[i].handle == p_device->handle){ + gHID_Devices[slotdata->deviceslot].pad_data[i].handle = 0; + + DCFlushRange(&gHID_Devices[slotdata->deviceslot].pad_data[i].handle,sizeof(gHID_Devices[slotdata->deviceslot].pad_data[i].handle)); + DCInvalidateRange(&gHID_Devices[slotdata->deviceslot].pad_data[i].handle,sizeof(gHID_Devices[slotdata->deviceslot].pad_data[i].handle)); + + user_data = (my_cb_user *) gHID_Devices[slotdata->deviceslot].pad_data[i].user_data; + + founddata = 1; + break; + } + } + + if(user_data){ + for(s32 j = 0;j < user_data->pads_per_device; j++){ + for(s32 i = 0;i < gHIDMaxDevices; i++){ + if(connectionOrderHelper[i] == user_data){ + connectionOrderHelper[i] = NULL; + break; + } + } + } + + config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1] &= ~ (1 << user_data->pad_slot); + DCFlushRange(&config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1],sizeof(config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1])); + DCInvalidateRange(&config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1],sizeof(config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1])); + if(user_data->buf){ + free(user_data->buf); + user_data->buf = NULL; + } + free(user_data); + user_data = NULL; + }else{ + if(founddata){ printf("ControllerPatcherHID::AttachDetachCallback(line %d): user_data null. You may have a memory leak.\n",__LINE__); } + return HID_DEVICE_DETACH; + } + if(config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1] == 0){ + gHIDAttached &= ~slotdata->hidmask; + gHIDCurrentDevice &= ~slotdata->hidmask; + + DCFlushRange(&gHIDAttached,sizeof(gHIDAttached)); + DCInvalidateRange(&gHIDAttached,sizeof(gHIDAttached)); + DCFlushRange(&gHIDCurrentDevice,sizeof(gHIDCurrentDevice)); + DCInvalidateRange(&gHIDCurrentDevice,sizeof(gHIDCurrentDevice)); + + if (slotdata->hidmask == gHID_LIST_MOUSE){ + gHID_Mouse_Mode = HID_MOUSE_MODE_AIM; + } + }else{ + if(HID_DEBUG){printf("ControllerPatcherHID::AttachDetachCallback(line %d): We still have pad for deviceslot %d connected.\n",__LINE__,slotdata->deviceslot); } + } + if(HID_DEBUG){printf("ControllerPatcherHID::AttachDetachCallback(line %d): Device successfully detached\n",__LINE__); } + } + }else{ + printf("ControllerPatcherHID::AttachDetachCallback(line %d): HID-Device currently not supported! You can add support through config files\n",__LINE__); + } + return HID_DEVICE_DETACH; +} + +void ControllerPatcherHID::HIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr){ + ControllerPatcherUtils::doSampling(usr->slotdata.deviceslot,usr->pad_slot,false); + + //printf("my_read_cbInternal: %d %08X %d\n",bytes_transfered,usr->slotdata.hidmask,usr->slotdata.deviceslot); + if(usr->slotdata.hidmask == gHID_LIST_GC){ + + HID_Data * data_ptr = NULL; + //Copy the data for all 4 pads + for(s32 i = 0;i<4;i++){ + data_ptr = &(gHID_Devices[gHID_SLOT_GC].pad_data[i]); + memcpy(&(data_ptr->data_union.controller.last_hid_data[0]),&(data_ptr->data_union.controller.cur_hid_data[0]),10); //save last data. + memcpy(&(data_ptr->data_union.controller.cur_hid_data[0]),&buf[(i*9)+1],9); //save new data. + + } + + /* + s32 i = 0; + printf("GC1 %08X: %02X %02X %02X %02X %02X %02X %02X %02X %02X ", buf[i*9+0],buf[i*9+1],buf[i*9+2],buf[i*9+3],buf[i*9+4],buf[i*9+5],buf[i*9+6],buf[i*9+7],buf[i*9+8]);i++; + printf("GC2 %08X: %02X %02X %02X %02X %02X %02X %02X %02X %02X ", buf[i*9+0],buf[i*9+1],buf[i*9+2],buf[i*9+3],buf[i*9+4],buf[i*9+5],buf[i*9+6],buf[i*9+7],buf[i*9+8]);i++; + printf("GC3 %08X: %02X %02X %02X %02X %02X %02X %02X %02X %02X ", buf[i*9+0],buf[i*9+1],buf[i*9+2],buf[i*9+3],buf[i*9+4],buf[i*9+5],buf[i*9+6],buf[i*9+7],buf[i*9+8]);i++; + printf("GC4 %08X: %02X %02X %02X %02X %02X %02X %02X %02X %02X \n", buf[i*9+0],buf[i*9+1],buf[i*9+2],buf[i*9+3],buf[i*9+4],buf[i*9+5],buf[i*9+6],buf[i*9+7],buf[i*9+8]);*/ + HIDGCRumble(handle,usr); + }else if(usr->slotdata.hidmask != 0){ + //Depending on how the switch pro controller is connected, it has a different data format. At first we had the Bluetooth version, so we need to convert + //the USB one into it now. (When it's connected via USB). The network client always sends the BT version, even if connected via USB to the PC. + if(usr->slotdata.hidmask == gHID_LIST_SWITCH_PRO && buf != NULL && bytes_transfered >= 0x20){ + u8 buffer[0x13]; + memcpy(buffer,buf+0x0D,0x013); + + /** + Thanks to ShinyQuagsire23 for the values (https://github.com/shinyquagsire23/HID-Joy-Con-Whispering) + **/ + buf[0] = 0x80; + buf[1] = 0x92; + buf[2] = 0x00; + buf[3] = 0x01; + buf[4] = 0x00; + buf[5] = 0x00; + buf[6] = 0x00; + buf[7] = 0x00; + buf[8] = 0x1F; + //We want to get the next input! + s32 res = HIDWrite(handle, buf, 9, NULL,NULL); + + if(res == 9){ //Check if it's the USB data format. + if(buffer[1] == 0) return; + //Converting the buttons + u32 buttons = (((u32*)(buffer))[0]) & 0xFFFFFF00; + u32 newButtons = 0; + if((buttons & HID_SWITCH_PRO_USB_BUTTON_A_VALUE) == HID_SWITCH_PRO_USB_BUTTON_A_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_A_VALUE; + if((buttons & HID_SWITCH_PRO_USB_BUTTON_B_VALUE) == HID_SWITCH_PRO_USB_BUTTON_B_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_B_VALUE; + if((buttons & HID_SWITCH_PRO_USB_BUTTON_X_VALUE) == HID_SWITCH_PRO_USB_BUTTON_X_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_X_VALUE; + if((buttons & HID_SWITCH_PRO_USB_BUTTON_Y_VALUE) == HID_SWITCH_PRO_USB_BUTTON_Y_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_Y_VALUE; + + if((buttons & HID_SWITCH_PRO_USB_BUTTON_PLUS_VALUE) == HID_SWITCH_PRO_USB_BUTTON_PLUS_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_PLUS_VALUE; + if((buttons & HID_SWITCH_PRO_USB_BUTTON_MINUS_VALUE) == HID_SWITCH_PRO_USB_BUTTON_MINUS_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_MINUS_VALUE; + if((buttons & HID_SWITCH_PRO_USB_BUTTON_HOME_VALUE) == HID_SWITCH_PRO_USB_BUTTON_HOME_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_HOME_VALUE; + //if((buttons & SWITCH_PRO_USB_BUTTON_SCREENSHOT) == HID_SWITCH_PRO_USB_BUTTON_SCREENSHOT) newButtons |= HID_SWITCH_PRO_BT_BUTTON_SCREENSHOT; + + if((buttons & HID_SWITCH_PRO_USB_BUTTON_R_VALUE) == HID_SWITCH_PRO_USB_BUTTON_R_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_R_VALUE; + if((buttons & HID_SWITCH_PRO_USB_BUTTON_ZR_VALUE) == HID_SWITCH_PRO_USB_BUTTON_ZR_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_ZR_VALUE; + if((buttons & HID_SWITCH_PRO_USB_BUTTON_STICK_R_VALUE) == HID_SWITCH_PRO_USB_BUTTON_STICK_R_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_STICK_R_VALUE; + + if((buttons & HID_SWITCH_PRO_USB_BUTTON_L_VALUE) == HID_SWITCH_PRO_USB_BUTTON_L_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_L_VALUE; + if((buttons & HID_SWITCH_PRO_USB_BUTTON_ZL_VALUE) == HID_SWITCH_PRO_USB_BUTTON_ZL_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_ZL_VALUE; + if((buttons & HID_SWITCH_PRO_USB_BUTTON_STICK_L_VALUE) == HID_SWITCH_PRO_USB_BUTTON_STICK_L_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_STICK_L_VALUE; + + u8 dpad = buffer[2]; + u8 dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_NEUTRAL_VALUE; + + //Converting the DPAD + if(((dpad & HID_SWITCH_PRO_USB_BUTTON_UP_VALUE) == HID_SWITCH_PRO_USB_BUTTON_UP_VALUE) && + ((dpad & HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE) == HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE)){ + dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_NE_VALUE; + }else if(((dpad & HID_SWITCH_PRO_USB_BUTTON_DOWN_VALUE) == HID_SWITCH_PRO_USB_BUTTON_DOWN_VALUE) && + ((dpad & HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE) == HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE)){ + dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_SE_VALUE; + }else if(((dpad & HID_SWITCH_PRO_USB_BUTTON_DOWN_VALUE) == HID_SWITCH_PRO_USB_BUTTON_DOWN_VALUE) && + ((dpad & HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE) == HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE)){ + dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_SW_VALUE; + }else if(((dpad & HID_SWITCH_PRO_USB_BUTTON_UP_VALUE) == HID_SWITCH_PRO_USB_BUTTON_UP_VALUE) && + ((dpad & HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE) == HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE)){ + dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_NW_VALUE; + }else if((dpad & HID_SWITCH_PRO_USB_BUTTON_UP_VALUE) == HID_SWITCH_PRO_USB_BUTTON_UP_VALUE){ + dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_N_VALUE; + }else if((dpad & HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE) == HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE){ + dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_E_VALUE; + }else if((dpad & HID_SWITCH_PRO_USB_BUTTON_DOWN_VALUE) == HID_SWITCH_PRO_USB_BUTTON_DOWN_VALUE){ + dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_S_VALUE; + }else if((dpad & HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE) == HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE){ + dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_W_VALUE; + } + + //Converting the stick data + u8 LX = (u8) ((u16) ((buffer[0x04] << 8 &0xFF00) | (((u16)buffer[0x03])&0xFF)) >> 0x04); + u8 LY = (u8)((buffer[0x05] *-1)); + u8 RX = (u8) ((u16) ((buffer[0x07] << 8 &0xFF00) | (((u16)buffer[0x06])&0xFF)) >> 0x04); + u8 RY = (u8)((buffer[0x08] *-1)); + + buf[0] = (newButtons >> 24) & 0xFF; + buf[1] = (newButtons >> 16) & 0xFF; + buf[2] |= dpadResult; + buf[4] = LX; + buf[6] = LY; + buf[8] = RX; + buf[10] = RY; + } + } + + s32 dsize = (HID_MAX_DATA_LENGTH_PER_PAD > bytes_transfered)? bytes_transfered : HID_MAX_DATA_LENGTH_PER_PAD; + s32 skip = 0; + + //Input filter + if( config_controller[usr->slotdata.deviceslot][CONTRPS_INPUT_FILTER][0] != CONTROLLER_PATCHER_INVALIDVALUE){ + if(buf[config_controller[usr->slotdata.deviceslot][CONTRPS_INPUT_FILTER][0]] != config_controller[usr->slotdata.deviceslot][CONTRPS_INPUT_FILTER][1]){ + skip = 1; + } + } + + if(!skip){ + u32 slot = 0; + if(usr->pad_slot < HID_MAX_PADS_COUNT){ + slot = usr->pad_slot; + } + slot += ControllerPatcherUtils::getPadSlotInAdapter(usr->slotdata.deviceslot,buf); // If the controller has multiple slots, we need to use the right one. + + HID_Data * data_ptr = &(gHID_Devices[usr->slotdata.deviceslot].pad_data[slot]); + + memcpy(&(data_ptr->data_union.controller.last_hid_data[0]),&(data_ptr->data_union.controller.cur_hid_data[0]),dsize); // save the last data. + memcpy(&(data_ptr->data_union.controller.cur_hid_data[0]),&buf[0],dsize); // save the new data. + + DCFlushRange(&gHID_Devices[usr->slotdata.deviceslot].pad_data[slot],sizeof(HID_Data)); + + data_ptr = &(gHID_Devices[usr->slotdata.deviceslot].pad_data[slot]); + + HIDRumble(handle,usr,slot); + } + } +} + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Other functions + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherHID::setVPADControllerData(VPADStatus * buffer,std::vector& data){ + if(buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + HID_Data * data_cur; + + s32 buttons_hold; + for(u32 i = 0;islotdata.hidmask & gHID_LIST_MOUSE){ //Reset the input when we have no new inputs + HID_Mouse_Data * mouse_data = &data_cur->data_union.mouse.cur_mouse_data; + if(mouse_data->valuedChanged == 1){ //Fix for the mouse cursor + mouse_data->valuedChanged = 0; + }else{ + mouse_data->deltaX = 0; + mouse_data->deltaY = 0; + } + } + + buttons_hold = 0; + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_A); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_B); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_X); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_Y); + + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_LEFT); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_RIGHT); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_DOWN); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_UP); + + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_MINUS); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_L); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_R); + + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_PLUS); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_ZL); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_ZR); + + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_HOME); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_STICK_L); + ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_STICK_R); + + u32 last_emulate_stick = (data_cur->last_buttons) & VPAD_MASK_EMULATED_STICKS; // We should only need the emulated stick data. + s32 last_realbuttons = (data_cur->last_buttons) & VPAD_MASK_BUTTONS; + + buffer->hold |= buttons_hold; + buffer->trigger |= (buttons_hold & (~last_realbuttons)); + buffer->release |= (last_realbuttons & (~buttons_hold)); + + ControllerPatcherUtils::convertAnalogSticks(data_cur,buffer); + + ControllerPatcherUtils::setEmulatedSticks(buffer,&last_emulate_stick); + + ControllerPatcherUtils::checkAndSetMouseMode(data_cur); + + ControllerPatcherUtils::setTouch(data_cur,buffer); + + data_cur->last_buttons = buttons_hold & VPAD_MASK_BUTTONS; + data_cur->last_buttons |= last_emulate_stick; + } + + // Caculates a valid stick position + if(data.size() > 0){ + ControllerPatcherUtils::normalizeStickValues(&buffer->leftStick); + ControllerPatcherUtils::normalizeStickValues(&buffer->rightStick); + } + + return CONTROLLER_PATCHER_ERROR_NONE; +} + +std::vector ControllerPatcherHID::getHIDDataAll(){ + u32 hid = gHIDCurrentDevice; + + std::vector data_list; + for(s32 i = 0;i < gHIDMaxDevices;i++){ + if((hid & (1 << i)) != 0){ + u32 cur_hidmask = config_controller_hidmask[i]; + for(s32 pad = 0; pad < HID_MAX_PADS_COUNT; pad++){ + s32 res; + HID_Data * new_data = NULL; + if((res = ControllerPatcherHID::getHIDData(cur_hidmask,pad,&new_data)) < 0){ // Checks if the pad is invalid. + //printf("ControllerPatcherHID::getHIDDataAll(line %d): error: Error getting the HID data from HID(%s) CHAN(). Error %d\n",__LINE__,CPStringTools::byte_to_binary(cur_hidmask),pad,res); + continue; + } + if(new_data != NULL) data_list.push_back(new_data); + } + } + } + return data_list; +} + +/* +The slotdata in the HID_Data pointer is empty. We need to provide the hidmask via the parameter +*/ +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherHID::getHIDData(u32 hidmask, s32 pad, HID_Data ** data){ + if(data == NULL) return CONTROLLER_PATCHER_ERROR_INVALID_BUFFER; + if(!(hidmask & gHIDCurrentDevice)) return CONTROLLER_PATCHER_ERROR_HID_NOT_CONNECTED; + if(pad < 0 && pad > 3) return CONTROLLER_PATCHER_ERROR_INVALID_CHAN; + + s32 device_slot = ControllerPatcherUtils::getDeviceSlot(hidmask); + if(device_slot < 0){ + return CONTROLLER_PATCHER_ERROR_DEVICE_SLOT_NOT_FOUND; + } + + s32 real_pad = pad; + if((device_slot != gHID_SLOT_GC) && config_controller[device_slot][CONTRPS_PAD_COUNT][0] != CONTROLLER_PATCHER_INVALIDVALUE){ + s32 pad_count = config_controller[device_slot][CONTRPS_PAD_COUNT][1]; + if(pad_count > HID_MAX_PADS_COUNT) pad_count = HID_MAX_PADS_COUNT; + pad = (pad/(pad_count))*pad_count; + } + + s32 result = ControllerPatcherUtils::checkActivePad(hidmask,pad); + + if(result < 0){ //Not pad connected to adapter + return CONTROLLER_PATCHER_ERROR_NO_PAD_CONNECTED; + } + + *data = &gHID_Devices[device_slot].pad_data[real_pad]; + + return CONTROLLER_PATCHER_ERROR_NONE; +} + + +void ControllerPatcherHID::HIDGCRumble(u32 handle,my_cb_user *usr){ + if(usr == NULL) return; + if(!ControllerPatcher::isRumbleActivated()) return; + + s32 rumblechanged = 0; + + for(s32 i = 0;islotdata.deviceslot].pad_data[i]); + if(data_ptr->rumbleActive != usr->rumblestatus[i]){ + rumblechanged = 1; + } + usr->rumblestatus[i] = data_ptr->rumbleActive; + usr->buf[i+1] = usr->rumblestatus[i]; + } + usr->forceRumbleInTicks[0]--; + if(rumblechanged || usr->forceRumbleInTicks[0] <= 0){ + usr->buf[0] = 0x11; + HIDWrite(handle, usr->buf, 5, NULL, NULL); + usr->forceRumbleInTicks[0] = 10; + } +} + +void ControllerPatcherHID::HIDRumble(u32 handle,my_cb_user *usr,u32 pad){ + if(usr == NULL || pad > HID_MAX_PADS_COUNT) return; + if(!ControllerPatcher::isRumbleActivated()) return; + + s32 rumblechanged = 0; + HID_Data * data_ptr = &(gHID_Devices[usr->slotdata.deviceslot].pad_data[pad]); + if(data_ptr->rumbleActive != usr->rumblestatus[pad]){ + usr->rumblestatus[pad] = data_ptr->rumbleActive; + rumblechanged = 1; + } + usr->forceRumbleInTicks[pad]--; + if(rumblechanged || usr->forceRumbleInTicks[pad] <= 0){ + //printf("Rumble: %d %d\n",usr->rumblestatus[pad],usr->rumbleForce[pad]); + //Seding to the network client! + char bytes[6]; + + s32 i = 0; + bytes[i++] = 0x01; + bytes[i++] = (handle >> 24) & 0xFF; + bytes[i++] = (handle >> 16) & 0xFF; + bytes[i++] = (handle >> 8) & 0xFF; + bytes[i++] = handle & 0xFF; + bytes[i++] = usr->rumblestatus[pad]; + + UDPClient * instance = UDPClient::getInstance(); + if(instance != NULL){ + instance->sendData(bytes,6); + } + + + if(usr->slotdata.hidmask == gHID_LIST_DS3){ + HIDDS3Rumble(handle,usr,usr->rumblestatus[pad]); + }else{ + // Not implemented for other devices =( + } + usr->forceRumbleInTicks[pad] = 10; + } +} + +static u8 ds3_rumble_Report[48] = +{ + 0x00, 0xFF, 0x00, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0x27, 0x10, 0x00, 0x32, + 0xFF, 0x27, 0x10, 0x00, 0x32, + 0xFF, 0x27, 0x10, 0x00, 0x32, + 0xFF, 0x27, 0x10, 0x00, 0x32, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, +}; + +void ControllerPatcherHID::HIDDS3Rumble(u32 handle,my_cb_user *usr,s32 rumble){ + memcpy(usr->buf, ds3_rumble_Report, 48); + + if (rumble) { + usr->buf[2] = 0x01; + usr->buf[4] = 0xff; + } + + HIDSetReport(handle, HID_REPORT_OUTPUT, PS3_01_REPORT_ID, usr->buf, 48, NULL, NULL); +} diff --git a/wiiu/controller_patcher/patcher/ControllerPatcherHID.hpp b/wiiu/controller_patcher/patcher/ControllerPatcherHID.hpp new file mode 100644 index 0000000000..21ade01652 --- /dev/null +++ b/wiiu/controller_patcher/patcher/ControllerPatcherHID.hpp @@ -0,0 +1,74 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ + +/** + * @file ControllerPatcherHID.hpp + * @author Maschell + * @date 25 Aug 2016 + * \brief This files contain useful all function for the direct HID Access + * + * @see https://github.com/Maschell/controller_patcher + */ + +#ifndef _CONTROLLER_PATCHER_HID_H_ +#define _CONTROLLER_PATCHER_HID_H_ + +#include + +#include "wiiu/syshid.h" +#include "wiiu/vpad.h" + +#include "../ControllerPatcher.hpp" + +#define SWAP16(x) ((x>>8) | ((x&0xFF)<<8)) +#define SWAP8(x) ((x>>4) | ((x&0xF)<<4)) + +class ControllerPatcherHID{ + friend class ControllerPatcher; + friend class ControllerPatcherUtils; + public: + static s32 externAttachDetachCallback(HIDDevice *p_device, u32 attach); + static void externHIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr); + + private: + static CONTROLLER_PATCHER_RESULT_OR_ERROR setVPADControllerData(VPADStatus * buffer,std::vector& data); + static std::vector getHIDDataAll(); + static CONTROLLER_PATCHER_RESULT_OR_ERROR getHIDData(u32 hidmask, s32 pad, HID_Data ** data); + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Rumble + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + + static void HIDRumble(u32 handle,my_cb_user *usr,u32 pad); + + static void HIDGCRumble(u32 handle,my_cb_user *usr); + + static void HIDDS3Rumble(u32 handle,my_cb_user *usr,s32 rumble); + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * HID Callbacks + *--------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + static s32 myAttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, u32 attach); + + static void myHIDMouseReadCallback(u32 handle, s32 error, unsigned char *buf, u32 bytes_transfered, void *p_user); + static void myHIDReadCallback(u32 handle, s32 error, unsigned char *buf, u32 bytes_transfered, void *p_user); + + static s32 AttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, u32 attach); + static void HIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr); +}; + +#endif /* _CONTROLLER_PATCHER_HID_H_ */ diff --git a/wiiu/controller_patcher/patcher/ControllerPatcherUtils.cpp b/wiiu/controller_patcher/patcher/ControllerPatcherUtils.cpp new file mode 100644 index 0000000000..e4b66f5a79 --- /dev/null +++ b/wiiu/controller_patcher/patcher/ControllerPatcherUtils.cpp @@ -0,0 +1,935 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#include "ControllerPatcherUtils.hpp" +#include +#include + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getDataByHandle(s32 handle, my_cb_user ** data){ + for(s32 i = 0;i< gHIDMaxDevices;i++){ + for(s32 j = 0;j<4;j++){ + //printf("%d %d %d %d\n",i,j,gHID_Devices[i].pad_data[j].handle,(u32)handle); + if(gHID_Devices[i].pad_data[j].handle == (u32)handle){ + *data = gHID_Devices[i].pad_data[j].user_data; + return CONTROLLER_PATCHER_ERROR_NONE; + } + } + } + return CONTROLLER_PATCHER_ERROR_UNKNOWN; +} +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Analyse inputs + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getButtonPressed(HID_Data * data, s32 * buttons_hold, s32 VPADButton){ + if(data == NULL || buttons_hold == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + + s32 deviceslot = data->slotdata.deviceslot; + + s32 result = -1; + + do{ + if(data->type == DEVICE_TYPE_MOUSE){ + HID_Mouse_Data * ms_data = &data->data_union.mouse.cur_mouse_data; + if(ms_data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + if(gHID_Mouse_Mode == HID_MOUSE_MODE_TOUCH){ + if(VPADButton == VPAD_BUTTON_TOUCH){ + if(ms_data->left_click & 0x01){ + result = 1; break; + } + } + }else if(gHID_Mouse_Mode == HID_MOUSE_MODE_AIM){ + if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_LEFT][0] == CONTROLLER_PATCHER_VALUE_SET){ + if(VPADButton == (int)gGamePadValues[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_LEFT][1]]){ + if(ms_data->left_click & 0x01){ + result = 1; break; + } + } + } + if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_RIGHT][0] == CONTROLLER_PATCHER_VALUE_SET){ + if(VPADButton == (int)gGamePadValues[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_RIGHT][1]]){ + if(ms_data->right_click & 0x01){ + result = 1; break; + } + } + } + } + result = 0; break; + } + u8 * cur_data = &data->data_union.controller.cur_hid_data[0]; + if(cur_data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + + s32 cur_config = 0; + + if(VPADButton == VPAD_BUTTON_A){ + cur_config = CONTRPS_VPAD_BUTTON_A; + }else if(VPADButton == VPAD_BUTTON_B){ + cur_config = CONTRPS_VPAD_BUTTON_B; + }else if(VPADButton == VPAD_BUTTON_X){ + cur_config = CONTRPS_VPAD_BUTTON_X; + }else if(VPADButton == VPAD_BUTTON_Y){ + cur_config = CONTRPS_VPAD_BUTTON_Y; + }else if(VPADButton == VPAD_BUTTON_L){ + cur_config = CONTRPS_VPAD_BUTTON_L; + }else if(VPADButton == VPAD_BUTTON_R){ + cur_config = CONTRPS_VPAD_BUTTON_R; + }else if(VPADButton == VPAD_BUTTON_ZL){ + cur_config = CONTRPS_VPAD_BUTTON_ZL; + }else if(VPADButton == VPAD_BUTTON_ZR){ + cur_config = CONTRPS_VPAD_BUTTON_ZR; + }else if(VPADButton == VPAD_BUTTON_STICK_L){ + cur_config = CONTRPS_VPAD_BUTTON_STICK_L; + }else if(VPADButton == VPAD_BUTTON_STICK_R){ + cur_config = CONTRPS_VPAD_BUTTON_STICK_R; + }else if(VPADButton == VPAD_BUTTON_PLUS){ + cur_config = CONTRPS_VPAD_BUTTON_PLUS; + }else if(VPADButton == VPAD_BUTTON_MINUS){ + cur_config = CONTRPS_VPAD_BUTTON_MINUS; + }else if(VPADButton == VPAD_BUTTON_HOME){ + cur_config = CONTRPS_VPAD_BUTTON_HOME; + } + + //! Special DPAD treatment. + if(config_controller[deviceslot][CONTRPS_DPAD_MODE][0] == CONTROLLER_PATCHER_VALUE_SET){ + if(config_controller[deviceslot][CONTRPS_DPAD_MODE][1] == CONTRPDM_Hat){ + u8 mask = 0x0F; + if(config_controller[deviceslot][CONTRPS_DPAD_MASK][0] == CONTROLLER_PATCHER_VALUE_SET){ + mask = config_controller[deviceslot][CONTRPS_DPAD_MASK][1]; + } + if(cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NEUTRAL][0]] != config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NEUTRAL][1]){ // Not neutral + u8 dir1_0 = 0,dir1_1 = 0; + u8 dir2_0 = 0,dir2_1 = 0; + u8 dir3_0 = 0,dir3_1 = 0; + u8 direction = 0; + if(VPADButton == VPAD_BUTTON_LEFT){ + dir1_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_W][0]; + dir2_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NW][0]; + dir3_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_SW][0]; + dir1_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_W][1]; + dir2_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NW][1]; + dir3_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_SW][1]; + direction = 1; + }else if(VPADButton == VPAD_BUTTON_RIGHT){ + dir1_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_E][0]; + dir2_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_SE][0]; + dir3_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NE][0]; + dir1_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_E][1]; + dir2_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_SE][1]; + dir3_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NE][1]; + direction = 1; + }else if(VPADButton == VPAD_BUTTON_DOWN){ + dir1_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_S][0]; + dir2_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_SE][0]; + dir3_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_SW][0]; + dir1_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_S][1]; + dir2_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_SE][1]; + dir3_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_SW][1]; + direction = 1; + }else if(VPADButton == VPAD_BUTTON_UP){ + dir1_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_N][0]; + dir2_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NW][0]; + dir3_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NE][0]; + dir1_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_N][1]; + dir2_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NW][1]; + dir3_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NE][1]; + direction = 1; + } + if(direction && (((cur_data[dir1_0] & mask) == dir1_1) || + ((cur_data[dir2_0] & mask) == dir2_1) || + ((cur_data[dir3_0] & mask) == dir3_1))) {result = 1; break;} + } + + }else if(config_controller[deviceslot][CONTRPS_DPAD_MODE][1] == CONTRPDM_Absolute_2Values){ + s32 contrps_value = 0; + if(VPADButton == VPAD_BUTTON_LEFT){ + contrps_value = CONTRPS_VPAD_BUTTON_DPAD_ABS_LEFT; + }else if(VPADButton == VPAD_BUTTON_RIGHT){ + contrps_value = CONTRPS_VPAD_BUTTON_DPAD_ABS_RIGHT; + }else if(VPADButton == VPAD_BUTTON_UP){ + contrps_value = CONTRPS_VPAD_BUTTON_DPAD_ABS_UP; + }else if(VPADButton == VPAD_BUTTON_DOWN){ + contrps_value = CONTRPS_VPAD_BUTTON_DPAD_ABS_DOWN; + } + + if(contrps_value != 0){ + s32 value_byte = CONTROLLER_PATCHER_INVALIDVALUE; + if((value_byte = config_controller[deviceslot][contrps_value][0]) != CONTROLLER_PATCHER_INVALIDVALUE){ + if(cur_data[config_controller[deviceslot][contrps_value][0]] == config_controller[deviceslot][contrps_value][1]){ + result = 1; + break; + } + } + } + } + } + + //! Normal DPAD treatment. + if(VPADButton == VPAD_BUTTON_LEFT){ + cur_config = CONTRPS_VPAD_BUTTON_LEFT; + }else if(VPADButton == VPAD_BUTTON_RIGHT){ + cur_config = CONTRPS_VPAD_BUTTON_RIGHT; + }else if(VPADButton == VPAD_BUTTON_DOWN){ + cur_config = CONTRPS_VPAD_BUTTON_DOWN; + }else if(VPADButton == VPAD_BUTTON_UP){ + cur_config = CONTRPS_VPAD_BUTTON_UP; + } + if(result && config_controller[deviceslot][CONTRPS_DOUBLE_USE][0] == CONTROLLER_PATCHER_VALUE_SET){ + if(config_controller[deviceslot][CONTRPS_DOUBLE_USE][1] == CONTROLLER_PATCHER_GC_DOUBLE_USE){ + if(cur_data[config_controller[deviceslot][CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR][0]] & config_controller[deviceslot][CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR][1]){ + if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_1_RELEASED,cur_config)){result = 0; break;} + if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_2_RELEASED,cur_config)){result = 0; break;} + if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_3_RELEASED,cur_config)){result = 0; break;} + if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_4_RELEASED,cur_config)){result = 0; break;} + if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_5_RELEASED,cur_config)){result = 0; break;} + }else{ + if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_1_PRESSED,cur_config)){result = 0; break;} + if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_2_PRESSED,cur_config)){result = 0; break;} + if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_3_PRESSED,cur_config)){result = 0; break;} + if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_4_PRESSED,cur_config)){result = 0; break;} + if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_5_PRESSED,cur_config)){result = 0; break;} + } + } + } + + if(isValueSet(data,cur_config) == 1){ + result = 1; break; + }else{ + //printf("Invalid data! deviceslot(slot): %d config: %d\n",deviceslot,cur_config); + } + }while(0); //The break will become handy ;) + + + if(result == 1){ + *buttons_hold |= VPADButton; // -1 would be also true. + return 1; + } + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::isValueSet(HID_Data * data,s32 cur_config){ + if(data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + + u8 * cur_data = &data->data_union.controller.cur_hid_data[0]; + if(cur_data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + + u32 hidmask = data->slotdata.hidmask; + s32 deviceslot = data->slotdata.deviceslot; + + s32 result = CONTROLLER_PATCHER_ERROR_NONE; + if(config_controller[deviceslot][cur_config][0] != CONTROLLER_PATCHER_INVALIDVALUE){ //Invalid data + if(hidmask & gHID_LIST_KEYBOARD){ + if(isInKeyboardData(cur_data,config_controller[deviceslot][cur_config][1]) > 0) { + result = 1; + } + }else{ + if((cur_data[config_controller[deviceslot][cur_config][0]] & config_controller[deviceslot][cur_config][1]) == config_controller[deviceslot][cur_config][1]){ + result = 1; + } + } + } + return result; + } +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::isInKeyboardData(unsigned char * keyboardData,s32 key){ + if(keyboardData == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + for(s32 i = 0;i 1){ + break; + }else if (keyboardData[i] == key){ + return 1; + } + } + return 0; +} + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Utils for setting the Button data + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::setButtonRemappingData(VPADStatus * old_buffer, VPADStatus * new_buffer,u32 VPADButton, s32 CONTRPS_SLOT){ + if(old_buffer == NULL || new_buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + u32 new_value = VPADButton; + + if(config_controller[gGamePadSlot][CONTRPS_SLOT][0] != CONTROLLER_PATCHER_INVALIDVALUE){ //using new value! + new_value = gGamePadValues[config_controller[gGamePadSlot][CONTRPS_SLOT][1]]; + } + + setButtonData(old_buffer,new_buffer,VPADButton,new_value); + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::setButtonData(VPADStatus * old_buffer, VPADStatus * new_buffer,u32 oldVPADButton,u32 newVPADButton){ + if(old_buffer == NULL || new_buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + if((old_buffer->hold & oldVPADButton) == oldVPADButton){ + new_buffer->hold |= newVPADButton; + } + if((old_buffer->release & oldVPADButton) == oldVPADButton){ + new_buffer->release |= newVPADButton; + } + if((old_buffer->trigger & oldVPADButton) == oldVPADButton){ + new_buffer->trigger |= newVPADButton; + } + + return CONTROLLER_PATCHER_ERROR_NONE; +} + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Pad Status functions + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::checkActivePad(u32 hidmask,s32 pad){ + if(hidmask & gHID_LIST_GC && pad >= 0 && pad <= 3){ + if (!(((gHID_Devices[gHID_SLOT_GC].pad_data[pad].data_union.controller.cur_hid_data[0] & 0x10) == 0) && ((gHID_Devices[gHID_SLOT_GC].pad_data[pad].data_union.controller.cur_hid_data[0] & 0x22) != 0x22))) return 1; + return CONTROLLER_PATCHER_ERROR_NO_PAD_CONNECTED; + }else{ + s32 deviceslot = getDeviceSlot(hidmask); + if(deviceslot < 0 ) return CONTROLLER_PATCHER_ERROR_DEVICE_SLOT_NOT_FOUND; + s32 connected_pads = config_controller[deviceslot][CONTRPS_CONNECTED_PADS][1]; + + if((connected_pads & (1 << pad)) > 0){ + return 1; + } + } + return CONTROLLER_PATCHER_ERROR_NO_PAD_CONNECTED; +} + +/* +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getActivePad(u32 hidmask){ + if(hidmask & gHID_LIST_GC){ + if (!(((gHID_Devices[gHID_SLOT_GC].pad_data[0].data_union.controller.cur_hid_data[0] & 0x10) == 0) && ((gHID_Devices[gHID_SLOT_GC].pad_data[0].data_union.controller.cur_hid_data[0] & 0x22) != 0x22))) return 0; + if (!(((gHID_Devices[gHID_SLOT_GC].pad_data[1].data_union.controller.cur_hid_data[0] & 0x10) == 0) && ((gHID_Devices[gHID_SLOT_GC].pad_data[1].data_union.controller.cur_hid_data[0] & 0x22) != 0x22))) return 1; + if (!(((gHID_Devices[gHID_SLOT_GC].pad_data[2].data_union.controller.cur_hid_data[0] & 0x10) == 0) && ((gHID_Devices[gHID_SLOT_GC].pad_data[2].data_union.controller.cur_hid_data[0] & 0x22) != 0x22))) return 2; + if (!(((gHID_Devices[gHID_SLOT_GC].pad_data[3].data_union.controller.cur_hid_data[0] & 0x10) == 0) && ((gHID_Devices[gHID_SLOT_GC].pad_data[3].data_union.controller.cur_hid_data[0] & 0x22) != 0x22))) return 3; + + return CONTROLLER_PATCHER_ERROR_NO_PAD_CONNECTED; + } + return 0; +}*/ + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Stick functions + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::normalizeStickValues(VPADVec2D * stick){ + if(stick == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + + f32 max_val = 0.0f; + f32 mul_val = 0.0f; + + if((max_val = (fabs(stick->x)) + fabs(stick->y)) > 1.414f){ + mul_val = 1.414f / max_val; + stick->x *= mul_val; + stick->y *= mul_val; + } + + if(stick->x > 1.0f){ stick->x = 1.0f; } + if(stick->y > 1.0f){ stick->y = 1.0f; } + if(stick->x < -1.0f){ stick->x = -1.0f; } + if(stick->y < -1.0f){ stick->y = -1.0f; } + + return CONTROLLER_PATCHER_ERROR_NONE; +} + +f32 ControllerPatcherUtils::convertAnalogValue(u8 value, u8 default_val, u8 min, u8 max, u8 invert,u8 deadzone){ + s8 new_value = (s8)(value - default_val); + u8 range = 0; + if(value >= max){ + if(invert == 0x01) return -1.0f; + return 1.0f; + }else if(value <= min){ + if(invert == 0x01) return 1.0f; + return -1.0f; + } + if((value-deadzone) > default_val){ + new_value -= deadzone; + range = (max - (default_val + deadzone)); + }else if((value+deadzone) < default_val){ + new_value += deadzone; + range = ((default_val - deadzone) - min); + }else{ + return 0.0f; + } + if(invert != 0x01){ + return (new_value / (1.0f*range)); + }else{ + return -1.0f*(new_value / (1.0f*range)); + } +} + +VPADVec2D ControllerPatcherUtils::getAnalogValueByButtons(u8 stick_values){ + VPADVec2D stick; + stick.x = 0.0f; + stick.y = 0.0f; + + u8 up = ((stick_values & STICK_VALUE_UP) == STICK_VALUE_UP); + u8 down = ((stick_values & STICK_VALUE_DOWN) == STICK_VALUE_DOWN); + u8 left = ((stick_values & STICK_VALUE_LEFT) == STICK_VALUE_LEFT); + u8 right = ((stick_values & STICK_VALUE_RIGHT) == STICK_VALUE_RIGHT); + + if(up){ + if(!down){ + stick.y = 1.0f; + } + if(left || right){ + stick.y = 0.707f; + if(left) stick.x = -0.707f; + if(right) stick.x = 0.707f; + } + }else if(down){ + if(!up){ + stick.y = -1.0f; + } + if(left || right){ + stick.y = -0.707f; + if(left) stick.x = -0.707f; + if(right) stick.x = 0.707f; + } + }else{ + if(left){ + if(!right){ + stick.x = -1.0f; + } + + }else if(right){ + if(!down){ + stick.x = 1.0f; + } + } + } + return stick; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::convertAnalogSticks(HID_Data * data, VPADStatus * buffer){ + if(buffer == NULL || data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + + s32 deviceslot = data->slotdata.deviceslot; + if (data->type == DEVICE_TYPE_MOUSE){ + + if(gHID_Mouse_Mode == HID_MOUSE_MODE_AIM){ // TODO: tweak values + HID_Mouse_Data * ms_data = &data->data_union.mouse.cur_mouse_data; + if(ms_data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + + f32 x_value = ms_data->deltaX/10.0f; + f32 y_value = -1.0f*(ms_data->deltaY/10.0f); + + if(config_controller[deviceslot][CONTRPS_MOUSE_STICK][0] != CONTROLLER_PATCHER_INVALIDVALUE){ + if(config_controller[deviceslot][CONTRPS_MOUSE_STICK][1] == DEF_L_STICK){ + buffer->leftStick.x += x_value; + buffer->leftStick.y += y_value; + return CONTROLLER_PATCHER_ERROR_NONE; + } + } + + buffer->rightStick.x += x_value; + buffer->rightStick.y += y_value; + } + }else{ + u8 * cur_data = &data->data_union.controller.cur_hid_data[0]; + if(cur_data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + + s32 deadzone = 0; + + if( config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][0] != CONTROLLER_PATCHER_INVALIDVALUE){ + if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE][0] == CONTROLLER_PATCHER_VALUE_SET){ + deadzone = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE][1]; + } + + buffer->leftStick.x += convertAnalogValue(cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][0]], + config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][1], + config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX][0], + config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX][1], + config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT][1], + deadzone); + } + + if( config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][0] != CONTROLLER_PATCHER_INVALIDVALUE){ + deadzone = 0; + if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE][0] == CONTROLLER_PATCHER_VALUE_SET){ + deadzone = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE][1]; + } + buffer->leftStick.y += convertAnalogValue(cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][0]], + config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][1], + config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX][0], + config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX][1], + config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT][1], + deadzone); + } + + if( config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][0] != CONTROLLER_PATCHER_INVALIDVALUE){ + deadzone = 0; + if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE][0] == CONTROLLER_PATCHER_VALUE_SET){ + deadzone = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE][1]; + } + + buffer->rightStick.x += convertAnalogValue(cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][0]], + config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][1], + config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX][0], + config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX][1], + config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT][1], + deadzone); + } + + if( config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y][0] != CONTROLLER_PATCHER_INVALIDVALUE){ + deadzone = 0; + if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE][0] == CONTROLLER_PATCHER_VALUE_SET){ + deadzone = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE][1]; + } + + buffer->rightStick.y += convertAnalogValue(cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y][0]], + config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y][1], + config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX][0], + config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX][1], + config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT][1], + deadzone); + } + + u8 stick_values = 0; + + if(isValueSet(data,CONTRPS_VPAD_BUTTON_L_STICK_UP)){ stick_values |= STICK_VALUE_UP; } + if(isValueSet(data,CONTRPS_VPAD_BUTTON_L_STICK_DOWN)){ stick_values |= STICK_VALUE_DOWN; } + if(isValueSet(data,CONTRPS_VPAD_BUTTON_L_STICK_LEFT)){ stick_values |= STICK_VALUE_LEFT; } + if(isValueSet(data,CONTRPS_VPAD_BUTTON_L_STICK_RIGHT)){ stick_values |= STICK_VALUE_RIGHT; } + + if(stick_values > 0 ){ + VPADVec2D stick = getAnalogValueByButtons(stick_values); + buffer->leftStick.x += stick.x; + buffer->leftStick.y += stick.y; + } + + stick_values = 0; + if(isValueSet(data,CONTRPS_VPAD_BUTTON_R_STICK_UP)){ stick_values |= STICK_VALUE_UP; } + if(isValueSet(data,CONTRPS_VPAD_BUTTON_R_STICK_DOWN)){ stick_values |= STICK_VALUE_DOWN; } + if(isValueSet(data,CONTRPS_VPAD_BUTTON_R_STICK_LEFT)){ stick_values |= STICK_VALUE_LEFT; } + if(isValueSet(data,CONTRPS_VPAD_BUTTON_R_STICK_RIGHT)){ stick_values |= STICK_VALUE_RIGHT; } + + if(stick_values > 0 ){ + VPADVec2D stick = getAnalogValueByButtons(stick_values); + buffer->rightStick.x += stick.x; + buffer->rightStick.y += stick.y; + } + + /*printf("LX %f(%02X) LY %f(%02X) RX %f(%02X) RY %f(%02X)\n",buffer->leftStick.x,cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][0]], + buffer->leftStick.y,cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][0]], + buffer->rightStick.x,cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][0]], + buffer->rightStick.y,cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y][0]]);*/ + + } + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::setEmulatedSticks(VPADStatus * buffer, u32 * last_emulatedSticks){ + if(buffer == NULL || last_emulatedSticks == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + + u32 emulatedSticks = 0; + + s32 l_x_full = (buffer->leftStick.x > 0.5f || buffer->leftStick.x < -0.5f)? 1:0; + s32 l_y_full = (buffer->leftStick.y > 0.5f || buffer->leftStick.y < -0.5f)? 1:0; + s32 r_x_full = (buffer->rightStick.x > 0.5f || buffer->rightStick.x < -0.5f)? 1:0; + s32 r_y_full = (buffer->rightStick.y > 0.5f || buffer->rightStick.y < -0.5f)? 1:0; + + if((buffer->leftStick.x > 0.5f) || (buffer->leftStick.x > 0.1f && !l_y_full)){ + emulatedSticks |= VPAD_STICK_L_EMULATION_RIGHT; + } + if((buffer->leftStick.x < -0.5f) || (buffer->leftStick.x < -0.1f && !l_y_full)){ + emulatedSticks |= VPAD_STICK_L_EMULATION_LEFT; + } + if((buffer->leftStick.y > 0.5f) || (buffer->leftStick.y > 0.1f && !l_x_full)){ + emulatedSticks |= VPAD_STICK_L_EMULATION_UP; + } + if((buffer->leftStick.y < -0.5f) || (buffer->leftStick.y < -0.1f && !l_x_full)){ + emulatedSticks |= VPAD_STICK_L_EMULATION_DOWN; + } + + if((buffer->rightStick.x > 0.5f) || (buffer->rightStick.x > 0.1f && !r_y_full)){ + emulatedSticks |= VPAD_STICK_R_EMULATION_RIGHT; + } + if((buffer->rightStick.x < -0.5f) || (buffer->rightStick.x < -0.1f && !r_y_full)){ + emulatedSticks |= VPAD_STICK_R_EMULATION_LEFT; + } + if((buffer->rightStick.y > 0.5f) || (buffer->rightStick.y > 0.1f && !r_x_full)){ + emulatedSticks |= VPAD_STICK_R_EMULATION_UP; + } + if((buffer->rightStick.y < -0.5f) || (buffer->rightStick.y < -0.1f && !r_x_full)){ + emulatedSticks |= VPAD_STICK_R_EMULATION_DOWN; + } + + //Setting the emulated sticks + buffer->hold |= emulatedSticks; + buffer->trigger |= (emulatedSticks & (~*last_emulatedSticks)); + buffer->release |= (*last_emulatedSticks & (~emulatedSticks)); + + *last_emulatedSticks = emulatedSticks; + + return CONTROLLER_PATCHER_ERROR_NONE; +} + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Touch functions + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::setTouch(HID_Data * data,VPADStatus * buffer){ + if(buffer == NULL || data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + if(data->type == DEVICE_TYPE_MOUSE && gHID_Mouse_Mode == HID_MOUSE_MODE_TOUCH){ + s32 buttons_hold; + if(getButtonPressed(data,&buttons_hold,VPAD_BUTTON_TOUCH)){ + HID_Mouse_Data * ms_data = &data->data_union.mouse.cur_mouse_data; + if(ms_data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + s32 x_mouse = 80 + ((int)(((ms_data->X)*1.0f/1280.0)*3890.0f)); + s32 y_mouse = 3910 - ((int)(((ms_data->Y)*1.0f/720.0)*3760.0f)); + buffer->tpNormal.x = x_mouse; + buffer->tpNormal.y = y_mouse; + buffer->tpNormal.touched = 1; + buffer->tpNormal.validity = 0; + buffer->tpFiltered1.x = x_mouse; + buffer->tpFiltered1.y = y_mouse; + buffer->tpFiltered1.touched = 1; + buffer->tpFiltered1.validity = 0; + buffer->tpFiltered2.x = x_mouse; + buffer->tpFiltered2.y = y_mouse; + buffer->tpFiltered2.touched = 1; + buffer->tpFiltered2.validity = 0; + } + } + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::checkAndSetMouseMode(HID_Data * data){ + u32 hidmask = data->slotdata.hidmask; + + if(hidmask & gHID_LIST_KEYBOARD){ + u8 * cur_data = &data->data_union.controller.cur_hid_data[0]; + u8 * last_data = &data->data_union.controller.last_hid_data[0]; + if((isInKeyboardData(cur_data,HID_KEYBOARD_BUTTON_F1) > 0) && ((isInKeyboardData(cur_data,HID_KEYBOARD_BUTTON_F1) > 0) != (isInKeyboardData(last_data,HID_KEYBOARD_BUTTON_F1) > 0))){ + if(gHID_Mouse_Mode == HID_MOUSE_MODE_AIM){ + gHID_Mouse_Mode = HID_MOUSE_MODE_TOUCH; + if(HID_DEBUG){ printf("ControllerPatcherUtils::checkAndSetMouseMode(line %d): Mouse mode changed! to touch \n",__LINE__); } + }else if(gHID_Mouse_Mode == HID_MOUSE_MODE_TOUCH){ + if(HID_DEBUG){ printf("ControllerPatcherUtils::checkAndSetMouseMode(line %d): Mouse mode changed! to aim \n",__LINE__); } + gHID_Mouse_Mode = HID_MOUSE_MODE_AIM; + } + } + } + return CONTROLLER_PATCHER_ERROR_NONE; +} + +/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Other functions + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::translateToPro(VPADStatus * vpad_buffer,KPADData * pro_buffer,u32 * lastButtonsPressesPRO){ + if(vpad_buffer == NULL || pro_buffer == NULL || lastButtonsPressesPRO == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + + s32 buttons_hold = 0; + + if(vpad_buffer->hold & VPAD_BUTTON_A) buttons_hold |= WPAD_PRO_BUTTON_A; + if(vpad_buffer->hold & VPAD_BUTTON_B) buttons_hold |= WPAD_PRO_BUTTON_B; + if(vpad_buffer->hold & VPAD_BUTTON_X) buttons_hold |= WPAD_PRO_BUTTON_X; + if(vpad_buffer->hold & VPAD_BUTTON_Y) buttons_hold |= WPAD_PRO_BUTTON_Y; + + if(vpad_buffer->hold & VPAD_BUTTON_PLUS) buttons_hold |= WPAD_PRO_BUTTON_PLUS; + if(vpad_buffer->hold & VPAD_BUTTON_MINUS) buttons_hold |= WPAD_PRO_BUTTON_MINUS; + if(vpad_buffer->hold & VPAD_BUTTON_HOME) buttons_hold |= WPAD_PRO_BUTTON_HOME; + + if(vpad_buffer->hold & VPAD_BUTTON_LEFT) buttons_hold |= WPAD_PRO_BUTTON_LEFT; + if(vpad_buffer->hold & VPAD_BUTTON_RIGHT) buttons_hold |= WPAD_PRO_BUTTON_RIGHT; + if(vpad_buffer->hold & VPAD_BUTTON_UP) buttons_hold |= WPAD_PRO_BUTTON_UP; + if(vpad_buffer->hold & VPAD_BUTTON_DOWN) buttons_hold |= WPAD_PRO_BUTTON_DOWN; + + if(vpad_buffer->hold & VPAD_BUTTON_L) buttons_hold |= WPAD_PRO_TRIGGER_L; + if(vpad_buffer->hold & VPAD_BUTTON_ZL) buttons_hold |= WPAD_PRO_TRIGGER_ZL; + + if(vpad_buffer->hold & VPAD_BUTTON_R) buttons_hold |= WPAD_PRO_TRIGGER_R; + if(vpad_buffer->hold & VPAD_BUTTON_ZR) buttons_hold |= WPAD_PRO_TRIGGER_ZR; + + if(vpad_buffer->hold & VPAD_BUTTON_STICK_L) buttons_hold |= WPAD_PRO_BUTTON_STICK_L; + if(vpad_buffer->hold & VPAD_BUTTON_STICK_R) buttons_hold |= WPAD_PRO_BUTTON_STICK_R; + + if(vpad_buffer->hold & VPAD_STICK_L_EMULATION_LEFT) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_LEFT; + if(vpad_buffer->hold & VPAD_STICK_L_EMULATION_RIGHT) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_RIGHT; + if(vpad_buffer->hold & VPAD_STICK_L_EMULATION_UP) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_UP; + if(vpad_buffer->hold & VPAD_STICK_L_EMULATION_DOWN) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_DOWN; + + if(vpad_buffer->hold & VPAD_STICK_R_EMULATION_LEFT) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_LEFT; + if(vpad_buffer->hold & VPAD_STICK_R_EMULATION_RIGHT) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_RIGHT; + if(vpad_buffer->hold & VPAD_STICK_R_EMULATION_UP) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_UP; + if(vpad_buffer->hold & VPAD_STICK_R_EMULATION_DOWN) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_DOWN; + + pro_buffer->pro.lstick_x = vpad_buffer->leftStick.x; + pro_buffer->pro.lstick_x = vpad_buffer->leftStick.y; + pro_buffer->pro.rstick_x = vpad_buffer->rightStick.x; + pro_buffer->pro.rstick_x = vpad_buffer->rightStick.y; + + /* + pro_buffer->unused_1[1] = 0xBF800000; + pro_buffer->unused_1[3] = 0x3F800000; + pro_buffer->angle_x = 0x3F800000; + pro_buffer->unused_3[4] = 0x3F800000; + pro_buffer->unused_3[7] = 0x3F800000; + pro_buffer->unused_6[17] = 0x3F800000; + pro_buffer->unused_7[1] = 0x3F800000; + pro_buffer->unused_7[5] = 0x3F800000;*/ + + pro_buffer->pro.hold = buttons_hold; + pro_buffer->pro.trigger = (buttons_hold & (~*lastButtonsPressesPRO)); + pro_buffer->pro.release = (*lastButtonsPressesPRO & (~buttons_hold)); + + *lastButtonsPressesPRO = buttons_hold; + + pro_buffer->format = WPAD_FMT_PRO_CONTROLLER; + pro_buffer->wpad_error = 0x00; + pro_buffer->device_type = WPAD_EXT_PRO_CONTROLLER; + pro_buffer->pro.wired = 1; + pro_buffer->pro.charging = 1; + + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::translateToProWPADRead(VPADStatus * vpad_buffer,WPADReadData * pro_buffer){ + if(vpad_buffer == NULL || pro_buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + + s32 buttons_hold = 0; + + if(vpad_buffer->hold & VPAD_BUTTON_A) buttons_hold |= WPAD_PRO_BUTTON_A; + if(vpad_buffer->hold & VPAD_BUTTON_B) buttons_hold |= WPAD_PRO_BUTTON_B; + if(vpad_buffer->hold & VPAD_BUTTON_X) buttons_hold |= WPAD_PRO_BUTTON_X; + if(vpad_buffer->hold & VPAD_BUTTON_Y) buttons_hold |= WPAD_PRO_BUTTON_Y; + + if(vpad_buffer->hold & VPAD_BUTTON_PLUS) buttons_hold |= WPAD_PRO_BUTTON_PLUS; + if(vpad_buffer->hold & VPAD_BUTTON_MINUS) buttons_hold |= WPAD_PRO_BUTTON_MINUS; + if(vpad_buffer->hold & VPAD_BUTTON_HOME) buttons_hold |= WPAD_PRO_BUTTON_HOME; + + if(vpad_buffer->hold & VPAD_BUTTON_LEFT) buttons_hold |= WPAD_PRO_BUTTON_LEFT; + if(vpad_buffer->hold & VPAD_BUTTON_RIGHT) buttons_hold |= WPAD_PRO_BUTTON_RIGHT; + if(vpad_buffer->hold & VPAD_BUTTON_UP) buttons_hold |= WPAD_PRO_BUTTON_UP; + if(vpad_buffer->hold & VPAD_BUTTON_DOWN) buttons_hold |= WPAD_PRO_BUTTON_DOWN; + + if(vpad_buffer->hold & VPAD_BUTTON_L) buttons_hold |= WPAD_PRO_TRIGGER_L; + if(vpad_buffer->hold & VPAD_BUTTON_ZL) buttons_hold |= WPAD_PRO_TRIGGER_ZL; + + if(vpad_buffer->hold & VPAD_BUTTON_R) buttons_hold |= WPAD_PRO_TRIGGER_R; + if(vpad_buffer->hold & VPAD_BUTTON_ZR) buttons_hold |= WPAD_PRO_TRIGGER_ZR; + + if(vpad_buffer->hold & VPAD_BUTTON_STICK_L) buttons_hold |= WPAD_PRO_BUTTON_STICK_L; + if(vpad_buffer->hold & VPAD_BUTTON_STICK_R) buttons_hold |= WPAD_PRO_BUTTON_STICK_R; + + if(vpad_buffer->hold & VPAD_STICK_L_EMULATION_LEFT) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_LEFT; + if(vpad_buffer->hold & VPAD_STICK_L_EMULATION_RIGHT) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_RIGHT; + if(vpad_buffer->hold & VPAD_STICK_L_EMULATION_UP) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_UP; + if(vpad_buffer->hold & VPAD_STICK_L_EMULATION_DOWN) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_DOWN; + + if(vpad_buffer->hold & VPAD_STICK_R_EMULATION_LEFT) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_LEFT; + if(vpad_buffer->hold & VPAD_STICK_R_EMULATION_RIGHT) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_RIGHT; + if(vpad_buffer->hold & VPAD_STICK_R_EMULATION_UP) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_UP; + if(vpad_buffer->hold & VPAD_STICK_R_EMULATION_DOWN) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_DOWN; + + pro_buffer->l_stick_x = (s16) (vpad_buffer->leftStick.x * 950.0f); + pro_buffer->l_stick_y = (s16) (vpad_buffer->leftStick.y * 950.0f); + pro_buffer->r_stick_x = (s16) (vpad_buffer->rightStick.x * 950.0f); + pro_buffer->r_stick_y = (s16) (vpad_buffer->rightStick.y * 950.0f); + + pro_buffer->buttons = buttons_hold; + + pro_buffer->fmt = WPAD_FMT_PRO_CONTROLLER; + pro_buffer->err = 0x00; + pro_buffer->dev = WPAD_EXT_PRO_CONTROLLER; + + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::translateToVPAD(VPADStatus * vpad_buffer,KPADData * pro_buffer,u32 * lastButtonsPressesVPAD){ + if(vpad_buffer == NULL || pro_buffer == NULL || lastButtonsPressesVPAD == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + + s32 buttons_hold = 0; + + if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_A) buttons_hold |= VPAD_BUTTON_A; + + if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_B) buttons_hold |= VPAD_BUTTON_B; + if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_X) buttons_hold |= VPAD_BUTTON_X; + if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_Y) buttons_hold |= VPAD_BUTTON_Y; + + if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_PLUS) buttons_hold |= VPAD_BUTTON_PLUS; + if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_MINUS) buttons_hold |= VPAD_BUTTON_MINUS; + + if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_HOME) buttons_hold |= VPAD_BUTTON_HOME; + + if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_LEFT) buttons_hold |= VPAD_BUTTON_LEFT; + if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_RIGHT) buttons_hold |= VPAD_BUTTON_RIGHT; + if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_UP) buttons_hold |= VPAD_BUTTON_UP; + if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_DOWN) buttons_hold |= VPAD_BUTTON_DOWN; + + if(pro_buffer->pro.hold & WPAD_PRO_TRIGGER_L) buttons_hold |= VPAD_BUTTON_L; + if(pro_buffer->pro.hold & WPAD_PRO_TRIGGER_ZL) buttons_hold |= VPAD_BUTTON_ZL; + + if(pro_buffer->pro.hold & WPAD_PRO_TRIGGER_R) buttons_hold |= VPAD_BUTTON_R; + if(pro_buffer->pro.hold & WPAD_PRO_TRIGGER_ZR) buttons_hold |= VPAD_BUTTON_ZR; + + if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_STICK_L) buttons_hold |= VPAD_BUTTON_STICK_L; + if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_STICK_R) buttons_hold |= VPAD_BUTTON_STICK_R; + + if(pro_buffer->pro.hold & WPAD_PRO_STICK_L_EMULATION_LEFT) buttons_hold |= VPAD_STICK_L_EMULATION_LEFT; + if(pro_buffer->pro.hold & WPAD_PRO_STICK_L_EMULATION_RIGHT) buttons_hold |= VPAD_STICK_L_EMULATION_RIGHT; + if(pro_buffer->pro.hold & WPAD_PRO_STICK_L_EMULATION_UP) buttons_hold |= VPAD_STICK_L_EMULATION_UP; + if(pro_buffer->pro.hold & WPAD_PRO_STICK_L_EMULATION_DOWN) buttons_hold |= VPAD_STICK_L_EMULATION_DOWN; + + if(pro_buffer->pro.hold & WPAD_PRO_STICK_R_EMULATION_LEFT) buttons_hold |= VPAD_STICK_R_EMULATION_LEFT; + if(pro_buffer->pro.hold & WPAD_PRO_STICK_R_EMULATION_RIGHT) buttons_hold |= VPAD_STICK_R_EMULATION_RIGHT; + if(pro_buffer->pro.hold & WPAD_PRO_STICK_R_EMULATION_UP) buttons_hold |= VPAD_STICK_R_EMULATION_UP; + if(pro_buffer->pro.hold & WPAD_PRO_STICK_R_EMULATION_DOWN) buttons_hold |= VPAD_STICK_R_EMULATION_DOWN; + + vpad_buffer->leftStick.x = pro_buffer->pro.lstick_x; + vpad_buffer->leftStick.y = pro_buffer->pro.lstick_x; + vpad_buffer->rightStick.x = pro_buffer->pro.rstick_x; + vpad_buffer->rightStick.y = pro_buffer->pro.rstick_x; + + vpad_buffer->hold |= buttons_hold; + vpad_buffer->trigger |= (buttons_hold & (~*lastButtonsPressesVPAD)); + vpad_buffer->release |= (*lastButtonsPressesVPAD & (~buttons_hold)); + + *lastButtonsPressesVPAD = buttons_hold; + + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::checkValueinConfigController(s32 deviceslot,s32 CONTRPS_slot,s32 expectedValue){ + if(config_controller[deviceslot][CONTRPS_slot][0] != CONTROLLER_PATCHER_INVALIDVALUE){ + if(expectedValue == config_controller[deviceslot][CONTRPS_slot][1]) return 1; + } + return 0; +} + +void ControllerPatcherUtils::setConfigValue(u8 * dest, u8 first, u8 second){ + dest[0] = first; + dest[1] = second; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getDeviceSlot(u32 hidmask){ + for(s32 i = 0;i < gHIDMaxDevices;i++){ + if(hidmask & config_controller_hidmask[i]){ + return i; + } + } + return CONTROLLER_PATCHER_ERROR_DEVICE_SLOT_NOT_FOUND; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getDeviceInfoFromVidPid(DeviceInfo * info){ + if(info != NULL){ + for(s32 i = 0;i< gHIDMaxDevices;i++){ + u16 my_vid = config_controller[i][CONTRPS_VID][0] * 0x100 + config_controller[i][CONTRPS_VID][1]; + u16 my_pid = config_controller[i][CONTRPS_PID][0] * 0x100 + config_controller[i][CONTRPS_PID][1]; + //printf("info->vidpid.vid (%04X) == my_vid (%04X) && info->vidpid.pid (%04X) == my_pid (%04X)\n",info->vidpid.vid,my_vid,info->vidpid.pid,my_pid); + if(info->vidpid.vid == my_vid && info->vidpid.pid == my_pid){ + info->slotdata.hidmask = config_controller_hidmask[i]; + info->slotdata.deviceslot = i; + info->pad_count = 1; + if(config_controller[i][CONTRPS_PAD_COUNT][0] != CONTROLLER_PATCHER_INVALIDVALUE){ + info->pad_count = config_controller[i][CONTRPS_PAD_COUNT][1]; + if(info->pad_count > HID_MAX_PADS_COUNT){ + info->pad_count = HID_MAX_PADS_COUNT; + } + } + + return CONTROLLER_PATCHER_ERROR_NONE; + //printf("Found device: device: %s slot: %d\n",byte_to_binary(device),deviceSlot); + break; + } + } + return CONTROLLER_PATCHER_ERROR_UNKNOWN_VID_PID; + } + return CONTROLLER_PATCHER_ERROR_INVALID_BUFFER; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getNextSlotData(HIDSlotData * slotdata){ + if(slotdata == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + if(gHIDRegisteredDevices >= gHIDMaxDevices) return CONTROLLER_PATCHER_ERROR_NO_FREE_SLOT; + slotdata->deviceslot = gHIDRegisteredDevices; + slotdata->hidmask = (1 << (gHIDRegisteredDevices)); + gHIDRegisteredDevices++; + + return CONTROLLER_PATCHER_ERROR_NONE; +} + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getVIDPIDbyDeviceSlot(s32 deviceslot, DeviceVIDPIDInfo * vidpid){ + if(vidpid == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; + if(deviceslot >= gHIDMaxDevices || deviceslot < 0) return CONTROLLER_PATCHER_ERROR_DEVICE_SLOT_NOT_FOUND; + vidpid->vid = config_controller[deviceslot][CONTRPS_VID][0] * 0x100 + config_controller[deviceslot][CONTRPS_VID][1]; + vidpid->pid = config_controller[deviceslot][CONTRPS_PID][0] * 0x100 + config_controller[deviceslot][CONTRPS_PID][1]; + if(vidpid->vid == 0x0000) return CONTROLLER_PATCHER_ERROR_FAILED_TO_GET_HIDDATA; + return CONTROLLER_PATCHER_ERROR_NONE; +} + +s32 ControllerPatcherUtils::getPadSlotInAdapter(s32 deviceslot, u8 * input_data){ + s32 slot_incr = 0; + if(config_controller[deviceslot][CONTRPS_PAD_COUNT][0] != CONTROLLER_PATCHER_INVALIDVALUE){ + s32 pad_count = config_controller[deviceslot][CONTRPS_PAD_COUNT][1]; + if(pad_count > HID_MAX_PADS_COUNT){ + pad_count = HID_MAX_PADS_COUNT; + } + for(s32 i= 0;iactive){ + DeviceInfo device_info; + + memset(&device_info,0,sizeof(device_info)); + device_info.vidpid = padinfo->vidpid; + + s32 res = -1; + if((res = ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info)) >= 0){ + if(!ignorePadSlot){ + s32 real_pad = (padinfo->pad/(device_info.pad_count))*device_info.pad_count; + if(real_pad == padslot && device_info.slotdata.deviceslot == deviceslot){ + if(ControllerPatcherUtils::checkActivePad(device_info.slotdata.hidmask,padinfo->pad)){ + gSamplingCallback(i); + } + } + }else{ + gSamplingCallback(i); + } + } + } + } + } + return CONTROLLER_PATCHER_ERROR_NONE; +} diff --git a/wiiu/controller_patcher/patcher/ControllerPatcherUtils.hpp b/wiiu/controller_patcher/patcher/ControllerPatcherUtils.hpp new file mode 100644 index 0000000000..b026839c7f --- /dev/null +++ b/wiiu/controller_patcher/patcher/ControllerPatcherUtils.hpp @@ -0,0 +1,320 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ + +/** + * @file ControllerPatcherUtil.hpp + * @author Maschell + * @date 25 Aug 2016 + * \brief This files contain useful functions for the controller patcher engine + * + * @see https://github.com/Maschell/controller_patcher + */ + +#ifndef _CONTROLLER_PATCHER_UTIL_H_ +#define _CONTROLLER_PATCHER_UTIL_H_ + + +#include "wiiu/vpad.h" +#include "wiiu/kpad.h" + +#include "../ControllerPatcher.hpp" + +class ControllerPatcherUtils{ + //give the other classes access to the private functions. + friend class ControllerPatcher; + friend class ControllerPatcherHID; + friend class ConfigParser; + + public: + /** + \brief Returns the device slot for a given HID-Mask. + + \param hidmask Given HID-Mask + + \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. The returned value is the deviceslot of the given HID-Mask + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR getDeviceSlot(u32 hidmask); + + /** + \brief Returns the device slot for a given HID-Mask. + + \param handle Given HID-handle + \param data Given my_cb_user ** where the result will be stored. Valid pointer when result is >= 0. + + \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. The actual result will be store in the given my_cb_user **. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR getDataByHandle(s32 handle, my_cb_user ** data); + + /** + \brief Returns the VID/PID for the given device slot. + + \param deviceslot Given device slot + \param vidpid Pointer to the DeviceVIDPIDInfo struct where the result will be stored. + + \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. The actual result will be store in the given DeviceVIDPIDInfo *. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR getVIDPIDbyDeviceSlot(s32 deviceslot, DeviceVIDPIDInfo * vidpid); + + /** \brief Set the VPAD data for a given KPAD data. + * + * \param vpad_buffer VPADStatus* A pointer to the VPAD Data where the result will be stored. + * \param pro_buffer KPADData* A pointer to the given KPADData data. + * \param lastButtonsPressesPRO u32* A pointer to the button presses of the previous call. Will be updated while calling. + * \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. + * + */ + static CONTROLLER_PATCHER_RESULT_OR_ERROR translateToVPAD(VPADStatus * vpad_buffer,KPADData * pro_buffer,u32 * lastButtonsPressesVPAD); + private: + /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Analyse inputs + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + + /** \brief Checks if a the given @p VPADButton was pressed in the given HID @data. When it was pressed, the result will be set the in given @p buttons_hold + * + * \param data Pointer to the HID_Data from where the input is read. + * \param buttons_hold Pointer to the u32 where the result will be written to. + * \param VPADButton The button that will be checked + * \return When the functions failed result < 0 is returned.If the result is >= 0 the function was successful. + * + */ + static CONTROLLER_PATCHER_RESULT_OR_ERROR getButtonPressed(HID_Data * data, s32 * buttons_hold, s32 VPADButton); + + + /** \brief Checks if a given value is set in the HID_DATA given the data in the slot number provided by cur_config. + * + * \param data Pointer to the HID_Data from where the input is read. + * \param cur_config slot of the configuration array which will be checked. + * \return When the functions failed result < 0 is returned. If the value is set, 1 will be returned. Otherwise 0. + * + */ + static CONTROLLER_PATCHER_RESULT_OR_ERROR isValueSet(HID_Data * data,s32 cur_config); + + + /** \brief Checks if a given key in the keyboard data is pressed. + * + * \param keyboardData A pointer to the keyboard data. + * \param key A pointer to the keyboard data. + * \return When the functions failed result < 0 is returned. If the key is active pressed, 1 is returned. + * + */ + static CONTROLLER_PATCHER_RESULT_OR_ERROR isInKeyboardData(unsigned char * keyboardData,s32 key); + + /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Utils for setting the Button data + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + + /** \brief Checks if a @p VPADButton (VPAD_BUTTON_XXX) is set in the given @p CONTRPS_SLOT (usually the one for buttons remapping) of the GamePad. When its set it'll be + * set for the corresponding Button (aka button remapping). When the @p CONTRPS_SLOT is not valid, the normal buttons layout will be used. + * + * \param old_buffer A pointer to a VPADStatus struct from which will be read. + * \param new_buffer A pointer to a VPADStatus struct where the result will be written. + * \param VPADButton The buttons that will be may replaced + * \param CONTRPS_SLOT The CONTRPS_SLOT where the VPAD_Buttons we want to use instead of the parameter "VPADButton" could be saved. + * \return When the functions failed result < 0 is returned. If the pad is active/connected, 1 is returned. + * + */ + static CONTROLLER_PATCHER_RESULT_OR_ERROR setButtonRemappingData(VPADStatus * old_buffer, VPADStatus * new_buffer,u32 VPADButton, s32 CONTRPS_SLOT); + + /** + \brief Checks if a given button (oldVPADButton) is set in a given VPADStatus struct (old_buffer). If its set, it will set an other + button (newVPADButton) to the second given VPADStatus struct (new_buffer) + + \param old_buffer A pointer to a VPADStatus struct from which will be read. + \param new_buffer A pointer to a VPADStatus struct where the result will be written. + \param oldVPADButton The buttons that need to be set in the first VPADStatus + \param newVPADButton The buttons that will be set in the second VPADStatus, when the oldVPADButton is pressed in the first buffer. + + \return When the functions failed result < 0 is returned. If the pad is active/connected, 1 is returned. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR setButtonData(VPADStatus * old_buffer, VPADStatus * new_buffer,u32 oldVPADButton,u32 newVPADButton); + + /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Pad Status functions + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + /** + \brief Checks if a controller is attached for the given HID-Mask and pad. + + \param hidmask Bit-Mask of the target hid-device. + \param pad Defines for which pad the connection will be checked. + + \return When the functions failed result < 0 is returned. If the pad is active/connected, 1 is returned. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR checkActivePad(u32 hidmask,s32 pad); + + /** + \brief Returns the first active pad of devices with the given HID-Mask. Currently only implemented for the GC-Adapter. Every other pad will always return 0. + + \param hidmask Bit-Mask of the target hid-device. + + \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. The returned value is fist active pad. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR getActivePad(u32 hidmask); + + /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Stick functions + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + /** + \brief Normalizes the stick to valid values. + + \param stick Pointer to the stick that will be normalized + + \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR normalizeStickValues(VPADVec2D * stick); + + /** + \brief Converts the digital absolute stick data into a float value. It also applies the deadzones, and can invert the result. + + \param value Given current value of the stick axis + \param default_val Value in neutral axis-position + \param min Value that represents -1.0f + \param max Value that represents 1.0f + \param invert Set to 1 if the axis needs to be inverted + \param deadzone Deadzone + + \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. + **/ + static f32 convertAnalogValue(u8 value, u8 default_val, u8 min, u8 max, u8 invert,u8 deadzone); + + /** + \brief Calculates a the stick data (VPADVec2D) from given digital direction. + + \param stick_values bits need to set for each direction. (STICK_VALUE_UP,STICK_VALUE_DOWN,STICK_VALUE_LEFT,STICK_VALUE_RIGHT) + + \return The VPADVec2D with the set values. + **/ + static VPADVec2D getAnalogValueByButtons(u8 stick_values); + + /** + \brief Handles the analog-stick data of HID devices. The result will written in the VPADStatus buffer. + + \param data Pointer to the current data of the HID device + \param buffer Pointer to VPADStatus where the analog-stick data will be set. + + \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR convertAnalogSticks(HID_Data * data,VPADStatus * buffer); + + /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Mouse functions + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + /** + \brief Set the touch data in the VPADStatus buffer. + Currently its only possible to set the touch data from a Mouse + + \param data The current data of the HID device + \param buffer Pointer to VPADStatus where the touch data will be set. + + \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR setTouch(HID_Data * data,VPADStatus * buffer); + + /** \brief Checks if the mouse mode needs to be changed. Sets it to the new mode if necessary. + * Currently the incoming data needs to be from a keyboard. + * + * \param data HID_Data* Pointer to the current data + * \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. + * + */ + static CONTROLLER_PATCHER_RESULT_OR_ERROR checkAndSetMouseMode(HID_Data * data); + + /** + \brief Set the emulated sticks for a given VPAD data. + + \param buffer: A pointer to the given VPAD Data. + \param last_emulatedSticks: A pointer to the button presses of the previous call. Will be updated while calling. + + \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR setEmulatedSticks(VPADStatus * buffer, u32 * last_emulatedSticks); + + /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + * Other functions + *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ + /** \brief Set the Pro Controller for a given VPAD data. + * + * \param vpad_buffer VPADStatus* A pointer to the given VPAD Data. + * \param pro_buffer KPADData* A pointer to the KPADData where the result will be stored. + * \param lastButtonsPressesPRO u32* A pointer to the button presses of the previous call. Will be updated while calling. + * \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. + * + */ + static CONTROLLER_PATCHER_RESULT_OR_ERROR translateToPro(VPADStatus * vpad_buffer,KPADData * pro_buffer,u32 * lastButtonsPressesPRO); + static CONTROLLER_PATCHER_RESULT_OR_ERROR translateToProWPADRead(VPADStatus * vpad_buffer,WPADReadData * pro_buffer); + + /** + \brief Checks if the value at the given device + CONTRPS slot equals the expected value. + + \param device_slot + \param CONTRPS_slot + \param expectedValue + + \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR checkValueinConfigController(s32 device_slot,s32 CONTRPS_slot,s32 expectedValue); + + /** + \brief Sets two u8 values to the given pointer. + + \param dest: pointer to the destination array. + \param first: Value that will be written in @p dest[0] + \param second: Value that will be written in @p dest[1] + **/ + static void setConfigValue(u8 * dest , u8 first, u8 second); + + /** + \brief Saves a new free device slot and the corresponding HID-Mask in the given @p HIDSlotData pointer + + \param slotdata Pointer to the HIDSlotData struct where the result will be saved. + + \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR getNextSlotData(HIDSlotData * slotdata); + + /** + \brief Fills up a given DeviceInfo, which provides a valid VID/PID, with HIDSlotData. + + \param info Pointer the target DeviceInfo. The VID/PID need to be set, the HIDSlotData will be filled with data. + + \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. + **/ + static CONTROLLER_PATCHER_RESULT_OR_ERROR getDeviceInfoFromVidPid(DeviceInfo * info); + + /** + \brief returns the internal slot number of the device. Some adapters have multiple slot and send the data for each one + alternating (with an identifier at the beginning). This function searches for the identifier (if it's set) and returns the + slot number relative to this pad. + + \param device slot + \param current input data + \return The relative slot in the device + **/ + static s32 getPadSlotInAdapter(s32 deviceslot, u8 * input_data); + + /** + \brief returns a pointer to the ControllerMapping to the given controller type + + \param type controller type + + \return pointer to ControllerMapping data, null is type was invalid + **/ + static ControllerMappingPAD * getControllerMappingByType(UController_Type type); + + static CONTROLLER_PATCHER_RESULT_OR_ERROR doSampling(u16 deviceslot,u8 padslot,bool ignorePadSlot); +}; + +#endif /* _CONTROLLER_PATCHER_UTIL_H_ */ diff --git a/wiiu/controller_patcher/utils/CPRetainVars.cpp b/wiiu/controller_patcher/utils/CPRetainVars.cpp new file mode 100644 index 0000000000..164275381b --- /dev/null +++ b/wiiu/controller_patcher/utils/CPRetainVars.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#include "../ControllerPatcher.hpp" + +ControllerMapping gControllerMapping __attribute__((section(".data"))); + +u8 gConfig_done __attribute__((section(".data"))) = 0; +u8 gButtonRemappingConfigDone __attribute__((section(".data"))) = 0; + +u32 gHIDAttached __attribute__((section(".data"))) = 0; +u32 gHIDCurrentDevice __attribute__((section(".data"))) = 0; + +u16 gHIDRegisteredDevices __attribute__((section(".data"))) = 0; + +HIDClient gHIDClient __attribute__((section(".data"))); + +HID_DEVICE_DATA gHID_Devices[gHIDMaxDevices] __attribute__((section(".data"))); + +u8 gHID_Mouse_Mode __attribute__((section(".data"))) = HID_MOUSE_MODE_TOUCH; + +u32 gGamePadValues[CONTRPS_MAX_VALUE] __attribute__((section(".data"))); + +u8 config_controller[gHIDMaxDevices][CONTRPS_MAX_VALUE][2] __attribute__((section(".data"))); +u32 config_controller_hidmask[gHIDMaxDevices] __attribute__((section(".data"))); + +u32 gHID_LIST_GC __attribute__((section(".data"))) = 0; +u32 gHID_LIST_DS3 __attribute__((section(".data"))) = 0; +u32 gHID_LIST_DS4 __attribute__((section(".data"))) = 0; +u32 gHID_LIST_KEYBOARD __attribute__((section(".data"))) = 0; +u32 gHID_LIST_SWITCH_PRO __attribute__((section(".data"))) = 0; +u32 gHID_LIST_MOUSE __attribute__((section(".data"))) = 0; + +u16 gGamePadSlot __attribute__((section(".data"))) = 0; +u16 gHID_SLOT_GC __attribute__((section(".data"))) = 0; +u16 gHID_SLOT_KEYBOARD __attribute__((section(".data"))) = 0; +u16 gMouseSlot __attribute__((section(".data"))) = 0; + +u8 gOriginalDimState __attribute__((section(".data"))) = 0; +u8 gOriginalAPDState __attribute__((section(".data"))) = 0; + +u16 gNetworkController[gHIDMaxDevices][HID_MAX_PADS_COUNT][4] __attribute__((section(".data"))); +s32 gHIDNetworkClientID __attribute__((section(".data"))) = 0; +u8 gUsedProtocolVersion __attribute__((section(".data"))) = WIIU_CP_TCP_HANDSHAKE; + +wpad_connect_callback_t gWPADConnectCallback[4] __attribute__((section(".data"))); +wpad_connect_callback_t gKPADConnectCallback[4] __attribute__((section(".data"))); +wpad_extension_callback_t gExtensionCallback[4] __attribute__((section(".data"))); +wpad_sampling_callback_t gSamplingCallback __attribute__((section(".data"))) = 0; +u8 gCallbackCooldown __attribute__((section(".data"))) = 0; + +u8 gGlobalRumbleActivated __attribute__((section(".data"))) = 0; + +my_cb_user * connectionOrderHelper[gHIDMaxDevices] __attribute__((section(".data"))); + +u32 gUDPClientip __attribute__((section(".data"))) = 0; +ControllerMappingPADInfo* gProPadInfo[4] __attribute__((section(".data"))) = {&gControllerMapping.proController[0].pad_infos[0], + &gControllerMapping.proController[1].pad_infos[0], + &gControllerMapping.proController[2].pad_infos[0], + &gControllerMapping.proController[3].pad_infos[0]} ; diff --git a/wiiu/controller_patcher/utils/CPRetainVars.hpp b/wiiu/controller_patcher/utils/CPRetainVars.hpp new file mode 100644 index 0000000000..696212af68 --- /dev/null +++ b/wiiu/controller_patcher/utils/CPRetainVars.hpp @@ -0,0 +1,76 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#ifndef CP_RETAINS_VARS_H_ +#define CP_RETAINS_VARS_H_ + +#include "wiiu/syshid.h" +#include "wiiu/kpad.h" +#include "../patcher/ControllerPatcherDefs.h" + +extern ControllerMapping gControllerMapping; + +extern u8 gConfig_done; +extern u8 gButtonRemappingConfigDone; + +extern u32 gHIDAttached; +extern u32 gHIDCurrentDevice; +extern HIDClient gHIDClient; + +extern u16 gHIDRegisteredDevices; + +extern HID_DEVICE_DATA gHID_Devices[gHIDMaxDevices]; + +extern u8 gHID_Mouse_Mode; + +extern u32 gGamePadValues[CONTRPS_MAX_VALUE]; + +extern u8 config_controller[gHIDMaxDevices][CONTRPS_MAX_VALUE][2]; +extern u32 config_controller_hidmask[gHIDMaxDevices]; + +extern u32 gHID_LIST_GC; +extern u32 gHID_LIST_DS3; +extern u32 gHID_LIST_DS4; +extern u32 gHID_LIST_KEYBOARD; +extern u32 gHID_LIST_SWITCH_PRO; +extern u32 gHID_LIST_MOUSE; +extern u16 gGamePadSlot; + +extern u16 gHID_SLOT_GC; +extern u16 gHID_SLOT_KEYBOARD; +extern u16 gMouseSlot; + +extern u8 gOriginalDimState; +extern u8 gOriginalAPDState; + +extern u16 gNetworkController[gHIDMaxDevices][HID_MAX_PADS_COUNT][4]; +extern s32 gHIDNetworkClientID; + +extern u8 gUsedProtocolVersion; + +extern wpad_connect_callback_t gWPADConnectCallback[4]; +extern wpad_connect_callback_t gKPADConnectCallback[4]; +extern wpad_extension_callback_t gExtensionCallback[4]; +extern wpad_sampling_callback_t gSamplingCallback; +extern u8 gCallbackCooldown; +extern u8 gGlobalRumbleActivated; + +extern my_cb_user * connectionOrderHelper[gHIDMaxDevices]; + +extern u32 gUDPClientip; +extern ControllerMappingPADInfo* gProPadInfo[4]; + +#endif // CP_RETAINS_VARS_H_ diff --git a/wiiu/controller_patcher/utils/CPStringTools.cpp b/wiiu/controller_patcher/utils/CPStringTools.cpp new file mode 100644 index 0000000000..ab4a97a409 --- /dev/null +++ b/wiiu/controller_patcher/utils/CPStringTools.cpp @@ -0,0 +1,85 @@ +#include "CPStringTools.hpp" +#include +#include +#include +#include + +#include +#include + +#include "wiiu/types.h" + +bool CPStringTools::EndsWith(const std::string& a, const std::string& b) { + if (b.size() > a.size()) return false; + return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin()); +} + +std::vector CPStringTools::StringSplit(const std::string & inValue, const std::string & splitter){ + std::string value = inValue; + std::vector result; + while (true) { + u32 index = value.find(splitter); + if (index == std::string::npos) { + result.push_back(value); + break; + } + std::string first = value.substr(0, index); + result.push_back(first); + if (index + splitter.size() == value.length()) { + result.push_back(""); + break; + } + if(index + splitter.size() > value.length()) { + break; + } + value = value.substr(index + splitter.size(), value.length()); + } + return result; +} + +const char * CPStringTools::byte_to_binary(s32 x){ + static char b[9]; + b[0] = '\0'; + + s32 z; + for (z = 128; z > 0; z >>= 1) + { + strcat(b, ((x & z) == z) ? "1" : "0"); + } + + return b; +} + +std::string CPStringTools::removeCharFromString(std::string& input,char toBeRemoved){ + std::string output = input; + size_t position; + while(1){ + position = output.find(toBeRemoved); + if(position == std::string::npos) + break; + output.erase(position, 1); + } + return output; +} + + +std::string CPStringTools::strfmt(const char * format, ...){ + std::string str; + char * tmp = NULL; + + va_list va; + va_start(va, format); + if((vasprintf(&tmp, format, va) >= 0) && tmp) + { + str = tmp; + } + va_end(va); + + if(tmp){ + free(tmp); + tmp = NULL; + } + + return str; +} +//CPStringTools diff --git a/wiiu/controller_patcher/utils/CPStringTools.hpp b/wiiu/controller_patcher/utils/CPStringTools.hpp new file mode 100644 index 0000000000..7a3a13009f --- /dev/null +++ b/wiiu/controller_patcher/utils/CPStringTools.hpp @@ -0,0 +1,17 @@ +#ifndef _CPSTRING_TOOLS_H_ +#define _CPSTRING_TOOLS_H_ +#include +#include + +#include "wiiu/types.h" + +class CPStringTools{ + public: + static bool EndsWith(const std::string& a, const std::string& b); + static std::vector StringSplit(const std::string & inValue, const std::string & splitter); + static std::string removeCharFromString(std::string& input,char toBeRemoved); + static const char * byte_to_binary(s32 test); + static std::string strfmt(const char * format, ...); +}; + +#endif /* _CPSTRING_TOOLS_H_ */ diff --git a/wiiu/controller_patcher/utils/ControllerPatcherThread.hpp b/wiiu/controller_patcher/utils/ControllerPatcherThread.hpp new file mode 100644 index 0000000000..6cf101cec4 --- /dev/null +++ b/wiiu/controller_patcher/utils/ControllerPatcherThread.hpp @@ -0,0 +1,119 @@ +/**************************************************************************** + * Copyright (C) 2015 Dimok + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#ifndef ControllerPatcherThread_H_ +#define ControllerPatcherThread_H_ + +#include +#include +#include "wiiu/os/thread.h" + +class ControllerPatcherThread +{ +public: + typedef void (* Callback)(ControllerPatcherThread *thread, void *arg); + + //! constructor + ControllerPatcherThread(int iAttr, int iPriority = 16, int iStackSize = 0x8000, ControllerPatcherThread::Callback callback = NULL, void *callbackArg = NULL) + : pThread(NULL) + , pThreadStack(NULL) + , pCallback(callback) + , pCallbackArg(callbackArg) + { + //! save attribute assignment + iAttributes = iAttr; + //! allocate the thread + pThread = (OSThread*)memalign(8, sizeof(OSThread)); + //! allocate the stack + pThreadStack = (u8 *) memalign(0x20, iStackSize); + //! create the thread + if(pThread && pThreadStack) + OSCreateThread(pThread, &ControllerPatcherThread::threadCallback, 1, (char*)this, pThreadStack+iStackSize, iStackSize, iPriority, iAttributes); + } + + //! destructor + virtual ~ControllerPatcherThread() { shutdownThread(); } + + static ControllerPatcherThread *create(ControllerPatcherThread::Callback callback, void *callbackArg, int iAttr = eAttributeNone, int iPriority = 16, int iStackSize = 0x8000) + { + return ( new ControllerPatcherThread(iAttr, iPriority, iStackSize, callback, callbackArg) ); + } + + //! Get thread ID + virtual void* getThread() const { return pThread; } + //! Thread entry function + virtual void executeThread(void) + { + if(pCallback) + pCallback(this, pCallbackArg); + } + //! Suspend thread + virtual void suspendThread(void) { if(isThreadSuspended()) return; if(pThread) OSSuspendThread(pThread); } + //! Resume thread + virtual void resumeThread(void) { if(!isThreadSuspended()) return; if(pThread) OSResumeThread(pThread); } + //! Set thread priority + virtual void setThreadPriority(int prio) { if(pThread) OSSetThreadPriority(pThread, prio); } + //! Check if thread is suspended + virtual bool isThreadSuspended(void) const { if(pThread) return OSIsThreadSuspended(pThread); return false; } + //! Check if thread is terminated + virtual bool isThreadTerminated(void) const { if(pThread) return OSIsThreadTerminated(pThread); return false; } + //! Check if thread is running + virtual bool isThreadRunning(void) const { return !isThreadSuspended() && !isThreadRunning(); } + //! Shutdown thread + virtual void shutdownThread(void) + { + //! wait for thread to finish + if(pThread && !(iAttributes & eAttributeDetach)) + { + if(isThreadSuspended()) + resumeThread(); + + OSJoinThread(pThread, NULL); + } + //! free the thread stack buffer + if(pThreadStack) + free(pThreadStack); + if(pThread) + free(pThread); + + pThread = NULL; + pThreadStack = NULL; + } + //! Thread attributes + enum eControllerPatcherThreadAttributes + { + eAttributeNone = 0x07, + eAttributeAffCore0 = 0x01, + eAttributeAffCore1 = 0x02, + eAttributeAffCore2 = 0x04, + eAttributeDetach = 0x08, + eAttributePinnedAff = 0x10 + }; +private: + static int threadCallback(int argc, const char **argv) + { + //! After call to start() continue with the internal function + ((ControllerPatcherThread *) argv)->executeThread(); + return 0; + } + int iAttributes; + OSThread *pThread; + u8 *pThreadStack; + Callback pCallback; + void *pCallbackArg; +}; + +#endif diff --git a/wiiu/controller_patcher/utils/FSHelper.c b/wiiu/controller_patcher/utils/FSHelper.c new file mode 100644 index 0000000000..0b117c752e --- /dev/null +++ b/wiiu/controller_patcher/utils/FSHelper.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include +#define FS_MAX_MOUNTPATH_SIZE 128 +int FS_Helper_MountFS(void *pClient, void *pCmd, char **mount_path){ + int result = -1; + + void *mountSrc = malloc(sizeof(FSMountSource)); + if(!mountSrc) + return -3; + + char* mountPath = (char*) malloc(FS_MAX_MOUNTPATH_SIZE); + if(!mountPath) { + free(mountSrc); + return -4; + } + + memset(mountSrc, 0, sizeof(FSMountSource)); + memset(mountPath, 0, FS_MAX_MOUNTPATH_SIZE); + + // Mount sdcard + if (FSGetMountSource(pClient, pCmd, FS_MOUNT_SOURCE_SD, mountSrc, -1) == 0) + { + result = FSMount(pClient, pCmd, mountSrc, mountPath, FS_MAX_MOUNTPATH_SIZE, -1); + if((result == 0) && mount_path) { + *mount_path = (char*)malloc(strlen(mountPath) + 1); + if(*mount_path) + strcpy(*mount_path, mountPath); + } + } + + free(mountPath); + free(mountSrc); + return result; +} + +int FS_Helper_GetFile(void * pClient,void * pCmd,const char * path, char *(*result)){ + if(pClient == NULL || pCmd == NULL || path == NULL || result == NULL) return -2; + FSStat stats; + s32 status = -1; + s32 handle = 0; + if((status = FSGetStat(pClient,pCmd,path,&stats,-1)) == FS_STATUS_OK){ + (*result) = (uint8_t *) memalign(0x40, (sizeof(uint8_t)*stats.size)+1); + if(!(*result)){ + printf("FS_Helper_GetFile(line %d): error: Failed to allocate space for reading the file\n",__LINE__); + return -1; + } + (*result)[stats.size] = '\0'; + if((status = FSOpenFile(pClient,pCmd,path,"r",&handle,-1)) == FS_STATUS_OK){ + s32 total_read = 0; + s32 ret2 = 0; + + char * cur_result_pointer = *result; + s32 sizeToRead = stats.size; + + while ((ret2 = FSReadFile(pClient,pCmd, cur_result_pointer, 0x01, sizeToRead, handle, 0, -1)) > 0){ + total_read += ret2; + cur_result_pointer += ret2; + sizeToRead -= ret2; + } + + }else{ + printf("FS_Helper_GetFile(line %d): error: (FSOpenFile) Couldn't open file (%s), error: %d",__LINE__,path,status); + free((*result)); + (*result)=NULL; + return -1; + } + + FSCloseFile(pClient,pCmd,handle,-1); + return 0; + }else{ + printf("FS_Helper_GetFile(line %d): error: (GetStat) Couldn't open file (%s), error: %d",__LINE__,path,status); + } + return -1; +} diff --git a/wiiu/controller_patcher/utils/FSHelper.h b/wiiu/controller_patcher/utils/FSHelper.h new file mode 100644 index 0000000000..4f22024701 --- /dev/null +++ b/wiiu/controller_patcher/utils/FSHelper.h @@ -0,0 +1,17 @@ +#ifndef __FSHELPER_H_ +#define __FSHELPER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +int FS_Helper_MountFS(void *pClient, void *pCmd, char **mount_path); +int FS_Helper_GetFile(void * pClient,void * pCmd,const char *, char **result); + +#ifdef __cplusplus +} +#endif + +#endif // __FSHELPER_H_ diff --git a/wiiu/controller_patcher/utils/PadConst.cpp b/wiiu/controller_patcher/utils/PadConst.cpp new file mode 100644 index 0000000000..a4c8858ae7 --- /dev/null +++ b/wiiu/controller_patcher/utils/PadConst.cpp @@ -0,0 +1,341 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#include "PadConst.hpp" + +const u8 DEF_R_STICK = 220; +const u8 DEF_L_STICK = 221; + +const u8 DEF_STICK_OFFSET_INVERT = CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT - CONTRPS_VPAD_BUTTON_L_STICK_X; +const u8 DEF_STICK_OFFSET_DEADZONE = CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE - CONTRPS_VPAD_BUTTON_L_STICK_X; +const u8 DEF_STICK_OFFSET_MINMAX = CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX - CONTRPS_VPAD_BUTTON_L_STICK_X; + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Device names +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +const char *HID_GC_STRING = "GameCube\nUSB-Adapter"; +const char *HID_KEYBOARD_STRING = "Keyboard"; +const char *HID_MOUSE_STRING = "Mouse"; +const char *HID_DS3_STRING = "DualShock 3\nController"; +const char *HID_DS4_STRING = "DualShock 4\nController"; +const char *HID_NEW_DS4_STRING = "DualShock 4\nController"; +const char *HID_XINPUT_STRING = "XInput\nController"; +const char *HID_SWITCH_PRO_STRING = "Switch\nPro Controller"; + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! GC-Adapter +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +const u8 HID_GC_BUTTON_A[] = { 0x01,HID_GC_BUTTON_A_VALUE}; +const u8 HID_GC_BUTTON_B[] = { 0x01,HID_GC_BUTTON_B_VALUE}; +const u8 HID_GC_BUTTON_X[] = { 0x01,HID_GC_BUTTON_X_VALUE}; +const u8 HID_GC_BUTTON_Y[] = { 0x01,HID_GC_BUTTON_Y_VALUE}; +const u8 HID_GC_BUTTON_LEFT[] = { 0x01,HID_GC_BUTTON_LEFT_VALUE}; +const u8 HID_GC_BUTTON_RIGHT[] = { 0x01,HID_GC_BUTTON_RIGHT_VALUE}; +const u8 HID_GC_BUTTON_DOWN[] = { 0x01,HID_GC_BUTTON_DOWN_VALUE}; +const u8 HID_GC_BUTTON_UP[] = { 0x01,HID_GC_BUTTON_UP_VALUE}; + +const u8 HID_GC_BUTTON_START[] = { 0x02,HID_GC_BUTTON_START_VALUE}; +const u8 HID_GC_BUTTON_Z[] = { 0x02,HID_GC_BUTTON_Z_VALUE}; + +const u8 HID_GC_BUTTON_L[] = { 0x07,HID_GC_BUTTON_L_VALUE}; +const u8 HID_GC_BUTTON_R[] = { 0x08,HID_GC_BUTTON_R_VALUE}; + +const u8 HID_GC_BUTTON_DPAD_TYPE[] = { CONTRPDM_Normal,0x00}; + +const u8 HID_GC_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x03, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x09, //STICK_CONF_DEADZONE, + 0x00, //STICK_CONF_INVERT, + 0x1A, //STICK_CONF_MIN, + 0xE4};//STICK_CONF_MAX, + +const u8 HID_GC_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x04, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x09, //STICK_CONF_DEADZONE, + 0x00, //STICK_CONF_INVERT, + 0x11, //STICK_CONF_MIN, + 0xE1};//STICK_CONF_MAX, + +const u8 HID_GC_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x05, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x09, //STICK_CONF_DEADZONE, + 0x00, //STICK_CONF_INVERT, + 0x2B, //STICK_CONF_MIN, + 0xE2};//STICK_CONF_MAX, + +const u8 HID_GC_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x06, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x09, //STICK_CONF_DEADZONE, + 0x00, //STICK_CONF_INVERT, + 0x1D, //STICK_CONF_MIN, + 0xDB};//STICK_CONF_MAX, + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! DS3 +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +const u8 HID_DS3_BUTTON_CROSS[] = { 0x03,HID_DS3_BUTTON_CROSS_VALUE}; +const u8 HID_DS3_BUTTON_CIRCLE[] = { 0x03,HID_DS3_BUTTON_CIRCLE_VALUE}; +const u8 HID_DS3_BUTTON_SQUARE [] = { 0x03,HID_DS3_BUTTON_SQUARE_VALUE}; +const u8 HID_DS3_BUTTON_TRIANGLE[] = { 0x03,HID_DS3_BUTTON_TRIANGLE_VALUE}; + +const u8 HID_DS3_BUTTON_L1[] = { 0x03,HID_DS3_BUTTON_L1_VALUE}; +const u8 HID_DS3_BUTTON_L2[] = { 0x03,HID_DS3_BUTTON_L2_VALUE}; +const u8 HID_DS3_BUTTON_R1[] = { 0x03,HID_DS3_BUTTON_R1_VALUE}; +const u8 HID_DS3_BUTTON_R2[] = { 0x03,HID_DS3_BUTTON_R2_VALUE}; + +const u8 HID_DS3_BUTTON_L3[] = { 0x02,HID_DS3_BUTTON_L3_VALUE}; +const u8 HID_DS3_BUTTON_R3[] = { 0x02,HID_DS3_BUTTON_R3_VALUE}; +const u8 HID_DS3_BUTTON_SELECT[] = { 0x02,HID_DS3_BUTTON_SELECT_VALUE}; +const u8 HID_DS3_BUTTON_START[] = { 0x02,HID_DS3_BUTTON_START_VALUE}; +const u8 HID_DS3_BUTTON_LEFT[] = { 0x02,HID_DS3_BUTTON_LEFT_VALUE}; +const u8 HID_DS3_BUTTON_RIGHT[] = { 0x02,HID_DS3_BUTTON_RIGHT_VALUE}; +const u8 HID_DS3_BUTTON_UP[] = { 0x02,HID_DS3_BUTTON_UP_VALUE}; +const u8 HID_DS3_BUTTON_DOWN[] = { 0x02,HID_DS3_BUTTON_DOWN_VALUE}; + +const u8 HID_DS3_BUTTON_GUIDE[] = { 0x04,HID_DS3_BUTTON_GUIDE_VALUE}; + +const u8 HID_DS3_BUTTON_DPAD_TYPE[] = { CONTRPDM_Normal,0x00}; + +const u8 HID_DS3_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x06, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x06, //STICK_CONF_DEADZONE, + 0x00, //STICK_CONF_INVERT, + 0x00, //STICK_CONF_MIN, + 0xFF};//STICK_CONF_MAX, + +const u8 HID_DS3_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x07, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x06, //STICK_CONF_DEADZONE, + 0x01, //STICK_CONF_INVERT, + 0x00, //STICK_CONF_MIN, + 0xFF};//STICK_CONF_MAX, + +const u8 HID_DS3_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x08, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x06, //STICK_CONF_DEADZONE, + 0x00, //STICK_CONF_INVERT, + 0x00, //STICK_CONF_MIN, + 0xFF};//STICK_CONF_MAX, + +const u8 HID_DS3_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x09, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x06, //STICK_CONF_DEADZONE, + 0x01, //STICK_CONF_INVERT, + 0x00, //STICK_CONF_MIN, + 0xFF};//STICK_CONF_MAX, + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! DS4 +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +const u8 HID_DS4_BUTTON_CROSS[] = { 0x05,HID_DS4_BUTTON_CROSS_VALUE}; +const u8 HID_DS4_BUTTON_CIRCLE[] = { 0x05,HID_DS4_BUTTON_CIRCLE_VALUE}; +const u8 HID_DS4_BUTTON_SQUARE [] = { 0x05,HID_DS4_BUTTON_SQUARE_VALUE}; +const u8 HID_DS4_BUTTON_TRIANGLE[] = { 0x05,HID_DS4_BUTTON_TRIANGLE_VALUE}; + +const u8 HID_DS4_BUTTON_L1[] = { 0x06,HID_DS4_BUTTON_L1_VALUE}; +const u8 HID_DS4_BUTTON_L2[] = { 0x06,HID_DS4_BUTTON_L2_VALUE}; +const u8 HID_DS4_BUTTON_L3[] = { 0x06,HID_DS4_BUTTON_L3_VALUE}; + +const u8 HID_DS4_BUTTON_R1[] = { 0x06,HID_DS4_BUTTON_R1_VALUE}; +const u8 HID_DS4_BUTTON_R2[] = { 0x06,HID_DS4_BUTTON_R2_VALUE}; +const u8 HID_DS4_BUTTON_R3[] = { 0x06,HID_DS4_BUTTON_R3_VALUE}; + +const u8 HID_DS4_BUTTON_SHARE[] = { 0x06,HID_DS4_BUTTON_SHARE_VALUE}; +const u8 HID_DS4_BUTTON_OPTIONS[] = { 0x06,HID_DS4_BUTTON_OPTIONS_VALUE}; + + +const u8 HID_DS4_BUTTON_DPAD_TYPE[] = { CONTRPDM_Hat,HID_DS4_BUTTON_DPAD_MASK_VALUE}; +const u8 HID_DS4_BUTTON_DPAD_N[] = { 0x05,HID_DS4_BUTTON_DPAD_N_VALUE}; +const u8 HID_DS4_BUTTON_DPAD_NE[] = { 0x05,HID_DS4_BUTTON_DPAD_NE_VALUE}; +const u8 HID_DS4_BUTTON_DPAD_E[] = { 0x05,HID_DS4_BUTTON_DPAD_E_VALUE}; +const u8 HID_DS4_BUTTON_DPAD_SE[] = { 0x05,HID_DS4_BUTTON_DPAD_SE_VALUE}; +const u8 HID_DS4_BUTTON_DPAD_S[] = { 0x05,HID_DS4_BUTTON_DPAD_S_VALUE}; +const u8 HID_DS4_BUTTON_DPAD_SW[] = { 0x05,HID_DS4_BUTTON_DPAD_SW_VALUE}; +const u8 HID_DS4_BUTTON_DPAD_W[] = { 0x05,HID_DS4_BUTTON_DPAD_W_VALUE}; +const u8 HID_DS4_BUTTON_DPAD_NW[] = { 0x05,HID_DS4_BUTTON_DPAD_NW_VALUE}; +const u8 HID_DS4_BUTTON_DPAD_NEUTRAL[] = { 0x05,HID_DS4_BUTTON_DPAD_NEUTRAL_VALUE}; + +const u8 HID_DS4_BUTTON_GUIDE[] = { 0x07,HID_DS4_BUTTON_GUIDE_VALUE}; +const u8 HID_DS4_BUTTON_T_PAD_CLICK[] = { 0x07,HID_DS4_BUTTON_T_PAD_CLICK_VALUE}; + +const u8 HID_DS4_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x01, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x06, //STICK_CONF_DEADZONE, + 0x00, //STICK_CONF_INVERT, + 0x00, //STICK_CONF_MIN, + 0xFF};//STICK_CONF_MAX, + +const u8 HID_DS4_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x02, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x05, //STICK_CONF_DEADZONE, + 0x01, //STICK_CONF_INVERT, + 0x00, //STICK_CONF_MIN, + 0xFF};//STICK_CONF_MAX, + +const u8 HID_DS4_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x03, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x07, //STICK_CONF_DEADZONE, + 0x00, //STICK_CONF_INVERT, + 0x00, //STICK_CONF_MIN, + 0xFF};//STICK_CONF_MAX, + +const u8 HID_DS4_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x04, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x09, //STICK_CONF_DEADZONE, + 0x01, //STICK_CONF_INVERT, + 0x00, //STICK_CONF_MIN, + 0xFF};//STICK_CONF_MAX, + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! XInput +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +const u8 HID_XINPUT_BUTTON_A[] = { 0x07,HID_XINPUT_BUTTON_A_VALUE}; +const u8 HID_XINPUT_BUTTON_B[] = { 0x07,HID_XINPUT_BUTTON_B_VALUE}; +const u8 HID_XINPUT_BUTTON_X[] = { 0x07,HID_XINPUT_BUTTON_X_VALUE}; +const u8 HID_XINPUT_BUTTON_Y[] = { 0x07,HID_XINPUT_BUTTON_Y_VALUE}; + +const u8 HID_XINPUT_BUTTON_LB[] = { 0x06,HID_XINPUT_BUTTON_LB_VALUE}; +const u8 HID_XINPUT_BUTTON_LT[] = { 0x04,HID_XINPUT_BUTTON_LT_VALUE}; +const u8 HID_XINPUT_BUTTON_L3[] = { 0x06,HID_XINPUT_BUTTON_L3_VALUE}; + +const u8 HID_XINPUT_BUTTON_RB[] = { 0x06,HID_XINPUT_BUTTON_RB_VALUE}; +const u8 HID_XINPUT_BUTTON_RT[] = { 0x05,HID_XINPUT_BUTTON_RT_VALUE}; +const u8 HID_XINPUT_BUTTON_R3[] = { 0x06,HID_XINPUT_BUTTON_R3_VALUE}; + +const u8 HID_XINPUT_BUTTON_START[] = { 0x06,HID_XINPUT_BUTTON_START_VALUE}; +const u8 HID_XINPUT_BUTTON_BACK[] = { 0x06,HID_XINPUT_BUTTON_BACK_VALUE}; +const u8 HID_XINPUT_BUTTON_GUIDE[] = { 0x06,HID_XINPUT_BUTTON_GUIDE_VALUE}; + +const u8 HID_XINPUT_BUTTON_DPAD_TYPE[] = { CONTRPDM_Normal,HID_XINPUT_BUTTON_DPAD_MASK_VALUE}; +const u8 HID_XINPUT_BUTTON_LEFT[] = { 0x07,HID_XINPUT_BUTTON_LEFT_VALUE}; +const u8 HID_XINPUT_BUTTON_RIGHT[] = { 0x07,HID_XINPUT_BUTTON_RIGHT_VALUE}; +const u8 HID_XINPUT_BUTTON_DOWN[] = { 0x07,HID_XINPUT_BUTTON_DOWN_VALUE}; +const u8 HID_XINPUT_BUTTON_UP[] = { 0x07,HID_XINPUT_BUTTON_UP_VALUE}; + +const u8 HID_XINPUT_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x00, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x10, //STICK_CONF_DEADZONE, + 0x00, //STICK_CONF_INVERT, + 0x00, //STICK_CONF_MIN, + 0xFF};//STICK_CONF_MAX, + +const u8 HID_XINPUT_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x01, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x10, //STICK_CONF_DEADZONE, + 0x00, //STICK_CONF_INVERT, + 0x00, //STICK_CONF_MIN, + 0xFF};//STICK_CONF_MAX, + +const u8 HID_XINPUT_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x02, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x10, //STICK_CONF_DEADZONE, + 0x00, //STICK_CONF_INVERT, + 0x00, //STICK_CONF_MIN, + 0xFF};//STICK_CONF_MAX, + +const u8 HID_XINPUT_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x03, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x10, //STICK_CONF_DEADZONE, + 0x00, //STICK_CONF_INVERT, + 0x00, //STICK_CONF_MIN, + 0xFF};//STICK_CONF_MAX, + + + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Switch Pro Controller +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +const u8 HID_SWITCH_PRO_BT_BUTTON_A[] = { 0x00,(u8)((HID_SWITCH_PRO_BT_BUTTON_A_VALUE >> 24) & 0xFF)}; +const u8 HID_SWITCH_PRO_BT_BUTTON_B[] = { 0x00,(u8)((HID_SWITCH_PRO_BT_BUTTON_B_VALUE >> 24) & 0xFF)}; +const u8 HID_SWITCH_PRO_BT_BUTTON_X[] = { 0x00,(u8)((HID_SWITCH_PRO_BT_BUTTON_X_VALUE >> 24) & 0xFF)}; +const u8 HID_SWITCH_PRO_BT_BUTTON_Y[] = { 0x00,(u8)((HID_SWITCH_PRO_BT_BUTTON_Y_VALUE >> 24) & 0xFF)}; + +const u8 HID_SWITCH_PRO_BT_BUTTON_L[] = { 0x00,(u8)((HID_SWITCH_PRO_BT_BUTTON_L_VALUE >> 24) & 0xFF)}; +const u8 HID_SWITCH_PRO_BT_BUTTON_ZL[] = { 0x00,(u8)((HID_SWITCH_PRO_BT_BUTTON_ZL_VALUE >> 24) & 0xFF)}; +const u8 HID_SWITCH_PRO_BT_BUTTON_STICK_L[] = { 0x01,(u8)((HID_SWITCH_PRO_BT_BUTTON_STICK_L_VALUE >> 16) & 0xFF)}; + +const u8 HID_SWITCH_PRO_BT_BUTTON_R[] = { 0x00,(u8)((HID_SWITCH_PRO_BT_BUTTON_R_VALUE >> 24) & 0xFF)}; +const u8 HID_SWITCH_PRO_BT_BUTTON_ZR[] = { 0x00,(u8)((HID_SWITCH_PRO_BT_BUTTON_ZR_VALUE >> 24) & 0xFF)}; +const u8 HID_SWITCH_PRO_BT_BUTTON_STICK_R[] = { 0x01,(u8)((HID_SWITCH_PRO_BT_BUTTON_STICK_R_VALUE >> 16) & 0xFF)}; + +const u8 HID_SWITCH_PRO_BT_BUTTON_PLUS[] = { 0x01,(u8)((HID_SWITCH_PRO_BT_BUTTON_PLUS_VALUE >> 16) & 0xFF)}; +const u8 HID_SWITCH_PRO_BT_BUTTON_MINUS[] = { 0x01,(u8)((HID_SWITCH_PRO_BT_BUTTON_MINUS_VALUE >> 16) & 0xFF)}; +const u8 HID_SWITCH_PRO_BT_BUTTON_HOME[] = { 0x01,(u8)((HID_SWITCH_PRO_BT_BUTTON_HOME_VALUE >> 16) & 0xFF)}; + +const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_TYPE[] = { CONTRPDM_Hat,HID_SWITCH_PRO_BT_BUTTON_DPAD_MASK_VALUE}; +const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_N[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_N_VALUE}; +const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_NE[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_NE_VALUE}; +const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_E[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_E_VALUE}; +const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_SE[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_SE_VALUE}; +const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_S[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_S_VALUE}; +const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_SW[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_SW_VALUE}; +const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_W[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_W_VALUE}; +const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_NW[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_NW_VALUE}; +const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_NEUTRAL[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_NEUTRAL_VALUE}; + + +const u8 HID_SWITCH_PRO_BT_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x04, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x01, //STICK_CONF_DEADZONE, + 0x00, //STICK_CONF_INVERT, + 0x28, //STICK_CONF_MIN, + 0xDF};//STICK_CONF_MAX, + +const u8 HID_SWITCH_PRO_BT_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x06, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x06, //STICK_CONF_DEADZONE, + 0x01, //STICK_CONF_INVERT, + 0x16, //STICK_CONF_MIN, + 0xD7};//STICK_CONF_MAX, + +const u8 HID_SWITCH_PRO_BT_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x08, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x04, //STICK_CONF_DEADZONE, + 0x00, //STICK_CONF_INVERT, + 0x29, //STICK_CONF_MIN, + 0xE2};//STICK_CONF_MAX, + +const u8 HID_SWITCH_PRO_BT_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION + 0x0A, //STICK_CONF_BYTE, + 0x80, //STICK_CONF_DEFAULT, + 0x08, //STICK_CONF_DEADZONE, + 0x01, //STICK_CONF_INVERT, + 0x22, //STICK_CONF_MIN, + 0xE4};//STICK_CONF_MAX, diff --git a/wiiu/controller_patcher/utils/PadConst.hpp b/wiiu/controller_patcher/utils/PadConst.hpp new file mode 100644 index 0000000000..9e4fd3dcb9 --- /dev/null +++ b/wiiu/controller_patcher/utils/PadConst.hpp @@ -0,0 +1,211 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ + +#ifndef _PAD_CONST_H_ +#define _PAD_CONST_H_ + +#include +#include "../patcher/ControllerPatcherDefs.h" + +extern const u8 DEF_R_STICK; +extern const u8 DEF_L_STICK; + +extern const u8 DEF_STICK_OFFSET_INVERT; +extern const u8 DEF_STICK_OFFSET_DEADZONE; +extern const u8 DEF_STICK_OFFSET_MINMAX; + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Device names +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +extern const char *HID_GC_STRING; +extern const char *HID_KEYBOARD_STRING; +extern const char *HID_MOUSE_STRING; +extern const char *HID_DS3_STRING; +extern const char *HID_DS4_STRING; +extern const char *HID_NEW_DS4_STRING; +extern const char *HID_XINPUT_STRING; +extern const char *HID_SWITCH_PRO_STRING; + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! GC_Adapter +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +extern const u8 HID_GC_BUTTON_A[]; +extern const u8 HID_GC_BUTTON_B[]; +extern const u8 HID_GC_BUTTON_X[]; +extern const u8 HID_GC_BUTTON_Y[]; +extern const u8 HID_GC_BUTTON_LEFT[]; +extern const u8 HID_GC_BUTTON_RIGHT[]; +extern const u8 HID_GC_BUTTON_DOWN[]; +extern const u8 HID_GC_BUTTON_UP[]; + +extern const u8 HID_GC_BUTTON_START[]; +extern const u8 HID_GC_BUTTON_Z[]; + +extern const u8 HID_GC_BUTTON_L[]; +extern const u8 HID_GC_BUTTON_R[]; + +extern const u8 HID_GC_BUTTON_DPAD_TYPE[]; + +extern const u8 HID_GC_STICK_L_X[STICK_CONF_ENUM_MAXVALUE]; +extern const u8 HID_GC_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE]; +extern const u8 HID_GC_STICK_R_X[STICK_CONF_ENUM_MAXVALUE]; +extern const u8 HID_GC_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE]; + + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! DS3 +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +extern const u8 HID_DS3_BUTTON_CROSS[]; +extern const u8 HID_DS3_BUTTON_CIRCLE[]; +extern const u8 HID_DS3_BUTTON_SQUARE []; +extern const u8 HID_DS3_BUTTON_TRIANGLE[]; + +extern const u8 HID_DS3_BUTTON_L1[]; +extern const u8 HID_DS3_BUTTON_L2[]; +extern const u8 HID_DS3_BUTTON_R1[]; +extern const u8 HID_DS3_BUTTON_R2[]; + +extern const u8 HID_DS3_BUTTON_L3[]; +extern const u8 HID_DS3_BUTTON_R3[]; +extern const u8 HID_DS3_BUTTON_SELECT[]; +extern const u8 HID_DS3_BUTTON_START[]; +extern const u8 HID_DS3_BUTTON_LEFT[]; +extern const u8 HID_DS3_BUTTON_RIGHT[]; +extern const u8 HID_DS3_BUTTON_UP[]; +extern const u8 HID_DS3_BUTTON_DOWN[]; + +extern const u8 HID_DS3_BUTTON_GUIDE[]; + +extern const u8 HID_DS3_BUTTON_DPAD_TYPE[]; + +extern const u8 HID_DS3_STICK_L_X[STICK_CONF_ENUM_MAXVALUE]; +extern const u8 HID_DS3_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE]; +extern const u8 HID_DS3_STICK_R_X[STICK_CONF_ENUM_MAXVALUE]; +extern const u8 HID_DS3_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE]; + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! DS4 +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +extern const u8 HID_DS4_BUTTON_CROSS[]; +extern const u8 HID_DS4_BUTTON_CIRCLE[]; +extern const u8 HID_DS4_BUTTON_SQUARE []; +extern const u8 HID_DS4_BUTTON_TRIANGLE[]; + +extern const u8 HID_DS4_BUTTON_L1[]; +extern const u8 HID_DS4_BUTTON_L2[]; +extern const u8 HID_DS4_BUTTON_L3[]; +extern const u8 HID_DS4_BUTTON_R1[]; +extern const u8 HID_DS4_BUTTON_R2[]; +extern const u8 HID_DS4_BUTTON_R3[]; + +extern const u8 HID_DS4_BUTTON_SHARE[]; +extern const u8 HID_DS4_BUTTON_OPTIONS[]; + +extern const u8 HID_DS4_BUTTON_DPAD_TYPE[]; +extern const u8 HID_DS4_BUTTON_DPAD_N[]; +extern const u8 HID_DS4_BUTTON_DPAD_NE[]; +extern const u8 HID_DS4_BUTTON_DPAD_E[]; +extern const u8 HID_DS4_BUTTON_DPAD_SE[]; +extern const u8 HID_DS4_BUTTON_DPAD_S[]; +extern const u8 HID_DS4_BUTTON_DPAD_SW[]; +extern const u8 HID_DS4_BUTTON_DPAD_W[]; +extern const u8 HID_DS4_BUTTON_DPAD_NW[]; +extern const u8 HID_DS4_BUTTON_DPAD_NEUTRAL[]; + +extern const u8 HID_DS4_BUTTON_GUIDE[]; +extern const u8 HID_DS4_BUTTON_T_PAD_CLICK[]; + +extern const u8 HID_DS4_STICK_L_X[STICK_CONF_ENUM_MAXVALUE]; +extern const u8 HID_DS4_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE]; +extern const u8 HID_DS4_STICK_R_X[STICK_CONF_ENUM_MAXVALUE]; +extern const u8 HID_DS4_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE]; + + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! XInput +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +extern const u8 HID_XINPUT_BUTTON_A[]; +extern const u8 HID_XINPUT_BUTTON_B[]; +extern const u8 HID_XINPUT_BUTTON_X[]; +extern const u8 HID_XINPUT_BUTTON_Y[]; + +extern const u8 HID_XINPUT_BUTTON_LB[]; +extern const u8 HID_XINPUT_BUTTON_LT[]; +extern const u8 HID_XINPUT_BUTTON_L3[]; + +extern const u8 HID_XINPUT_BUTTON_RB[]; +extern const u8 HID_XINPUT_BUTTON_RT[]; +extern const u8 HID_XINPUT_BUTTON_R3[]; + +extern const u8 HID_XINPUT_BUTTON_START[]; +extern const u8 HID_XINPUT_BUTTON_BACK[]; +extern const u8 HID_XINPUT_BUTTON_GUIDE[]; + +extern const u8 HID_XINPUT_BUTTON_DPAD_TYPE[]; +extern const u8 HID_XINPUT_BUTTON_LEFT[]; +extern const u8 HID_XINPUT_BUTTON_RIGHT[]; +extern const u8 HID_XINPUT_BUTTON_DOWN[]; +extern const u8 HID_XINPUT_BUTTON_UP[]; + +extern const u8 HID_XINPUT_STICK_L_X[STICK_CONF_ENUM_MAXVALUE]; +extern const u8 HID_XINPUT_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE]; +extern const u8 HID_XINPUT_STICK_R_X[STICK_CONF_ENUM_MAXVALUE]; +extern const u8 HID_XINPUT_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE]; + +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +//! Switch Pro Controller +//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +extern const u8 HID_SWITCH_PRO_BT_BUTTON_A[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_B[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_X[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_Y[]; + +extern const u8 HID_SWITCH_PRO_BT_BUTTON_L[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_ZL[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_STICK_L[]; + +extern const u8 HID_SWITCH_PRO_BT_BUTTON_R[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_ZR[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_STICK_R[]; + +extern const u8 HID_SWITCH_PRO_BT_BUTTON_PLUS[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_MINUS[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_HOME[]; + +extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_TYPE[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_N[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_NE[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_E[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_SE[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_S[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_SW[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_W[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_NW[]; +extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_NEUTRAL[]; + + +extern const u8 HID_SWITCH_PRO_BT_STICK_L_X[STICK_CONF_ENUM_MAXVALUE]; +extern const u8 HID_SWITCH_PRO_BT_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE]; +extern const u8 HID_SWITCH_PRO_BT_STICK_R_X[STICK_CONF_ENUM_MAXVALUE]; +extern const u8 HID_SWITCH_PRO_BT_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE]; + +#endif /* _PAD_CONST_H_ */