From a72f8e3879083924764fee11f9154ecc12aaa084 Mon Sep 17 00:00:00 2001 From: Maschell Date: Sun, 23 Apr 2017 15:19:21 +0200 Subject: [PATCH] Added function to call the SamplingCallback and some minor tweaks --- ControllerPatcher.cpp | 45 +++++++++++------ ControllerPatcher.hpp | 2 + patcher/ControllerPatcherDefs.h | 4 +- patcher/ControllerPatcherHID.cpp | 28 +++++------ patcher/ControllerPatcherUtils.cpp | 79 ++++++++++++++++++++++-------- patcher/ControllerPatcherUtils.hpp | 2 + utils/CPRetainVars.cpp | 6 +++ utils/CPRetainVars.hpp | 3 ++ 8 files changed, 118 insertions(+), 51 deletions(-) diff --git a/ControllerPatcher.cpp b/ControllerPatcher.cpp index 4011763..e835076 100644 --- a/ControllerPatcher.cpp +++ b/ControllerPatcher.cpp @@ -86,6 +86,7 @@ void ControllerPatcher::ResetConfig(){ 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; @@ -129,6 +130,7 @@ void ControllerPatcher::ResetConfig(){ ControllerPatcherUtils::getNextSlotData(&slotdata); u32 ds4_slot = slotdata.deviceslot; u32 ds4_hid = slotdata.hidmask; + gHID_LIST_DS4 = ds4_hid; if(HID_DEBUG) log_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); @@ -141,11 +143,12 @@ void ControllerPatcher::ResetConfig(){ gHID_LIST_SWITCH_PRO = slotdata.hidmask; log_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] = ds4_hid; + 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; @@ -468,6 +471,17 @@ bool ControllerPatcher::Init(){ InitVPadFunctionPointers(); InitPadScoreFunctionPointers(); + gSamplingCallback = (wpad_sampling_callback_t)((u32)KPADRead + 0x1F0); + if(*(u32*)gSamplingCallback != FIRST_INSTRUCTION_IN_SAMPLING_CALLBACK){ + //In Firmware <= 5.1.2 the offset changes + gSamplingCallback = (wpad_sampling_callback_t)((u32)KPADRead + 0x1F8); + if(*(u32*)gSamplingCallback != FIRST_INSTRUCTION_IN_SAMPLING_CALLBACK){ + //Should never happen. I looked into the padscore.rpl of ALL firmwares. + gSamplingCallback = NULL; + } + } + log_printf("ControllerPatcher::Init(line %d): Found the gSamplingCallback at %08X \n",__LINE__,gSamplingCallback); + if(HID_DEBUG) log_printf("ControllerPatcher::Init(line %d): Init called! \n",__LINE__); if(syshid_handle == 0){ @@ -519,7 +533,6 @@ void ControllerPatcher::stopNetworkServer(){ TCPServer::destroyInstance(); } - void ControllerPatcher::DeInit(){ if(HID_DEBUG) log_printf("ControllerPatcher::DeInit(line %d) called! \n",__LINE__); @@ -550,6 +563,7 @@ void ControllerPatcher::DeInit(){ 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; @@ -648,7 +662,6 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::addControllerMapping(UCont return CONTROLLER_PATCHER_ERROR_NONE; } - s32 ControllerPatcher::getActiveMappingSlot(UController_Type type){ ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type); @@ -675,8 +688,7 @@ bool ControllerPatcher::isControllerConnectedAndActive(UController_Type type,s32 memset(&device_info,0,sizeof(device_info)); - device_info.vidpid.vid = padinfo->vidpid.vid; - device_info.vidpid.pid = padinfo->vidpid.pid; + device_info.vidpid = padinfo->vidpid; s32 res; if((res = ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info)) < 0){ @@ -751,11 +763,11 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::gettingInputAllDevices(Inp DeviceInfo * deviceinfo = &(output[result].device_info); InputButtonData * buttondata = output[result].button_data; - deviceinfo->slotdata.deviceslot = deviceslot; - deviceinfo->slotdata.hidmask = newhid; + deviceinfo->slotdata.deviceslot = deviceslot; + deviceinfo->slotdata.hidmask = newhid; - deviceinfo->vidpid.vid = config_controller[deviceslot][CONTRPS_VID][0] * 0x100 + config_controller[deviceslot][CONTRPS_VID][1]; - deviceinfo->vidpid.pid = config_controller[deviceslot][CONTRPS_PID][0] * 0x100 + config_controller[deviceslot][CONTRPS_PID][1]; + deviceinfo->vidpid.vid = config_controller[deviceslot][CONTRPS_VID][0] * 0x100 + config_controller[deviceslot][CONTRPS_VID][1]; + deviceinfo->vidpid.pid = config_controller[deviceslot][CONTRPS_PID][0] * 0x100 + config_controller[deviceslot][CONTRPS_PID][1]; if(config_controller[deviceslot][CONTRPS_PAD_COUNT][0] != CONTROLLER_PATCHER_INVALIDVALUE){ deviceinfo->pad_count = config_controller[deviceslot][CONTRPS_PAD_COUNT][1]; @@ -765,7 +777,7 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::gettingInputAllDevices(Inp s32 buttons_hold = 0; - for(s32 pad = 0;padpad_count;pad++){ buttons_hold = 0; buttondata[pad].btn_h = 0; buttondata[pad].btn_d = 0; @@ -833,8 +845,7 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setProControllerDataFromHI DeviceInfo device_info; memset(&device_info,0,sizeof(device_info)); - device_info.vidpid.vid = cm_map_pad_info.vidpid.vid; - device_info.vidpid.pid = cm_map_pad_info.vidpid.pid; + device_info.vidpid = cm_map_pad_info.vidpid; s32 res; if((res = ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info)) < 0){ @@ -893,10 +904,10 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setControllerDataFromHID(V }else{ for(s32 i = 0;i +#define FIRST_INSTRUCTION_IN_SAMPLING_CALLBACK 0x9421FFB8 + #define HID_INIT_NOT_DONE 0 #define HID_INIT_DONE 1 #define HID_SDCARD_READ 2 @@ -232,7 +234,7 @@ typedef struct _my_cb_user{ 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 rumbleForce[HID_MAX_PADS_COUNT]; + u8 forceRumbleInTicks[HID_MAX_PADS_COUNT]; }my_cb_user; /** diff --git a/patcher/ControllerPatcherHID.cpp b/patcher/ControllerPatcherHID.cpp index 264c634..909276c 100644 --- a/patcher/ControllerPatcherHID.cpp +++ b/patcher/ControllerPatcherHID.cpp @@ -95,17 +95,15 @@ void ControllerPatcherHID::myHIDMouseReadCallback(u32 handle, s32 error, unsigne } void ControllerPatcherHID::myHIDReadCallback(u32 handle, s32 error, unsigned char *buf, u32 bytes_transfered, void *p_user){ - if(error == 0 && p_user != NULL && gHIDAttached) - { + 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_GC){ - HIDRead(handle, usr->buf, bytes_transfered, myHIDReadCallback, usr); - }else if(usr->slotdata.hidmask != 0){ + + if(usr->slotdata.hidmask == gHID_LIST_DS4){ 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); } + HIDRead(handle, usr->buf, bytes_transfered, myHIDReadCallback, usr); } } @@ -147,7 +145,7 @@ s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p log_printf("ControllerPatcherHID::AttachDetachCallback(line %d): ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) failed %d \n",__LINE__,ret); return HID_DEVICE_DETACH; }else{ - log_printf("ControllerPatcherHID::AttachDetachCallback(line %d): ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) success %d \n",__LINE__,ret); + //log_printf("ControllerPatcherHID::AttachDetachCallback(line %d): ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) success %d \n",__LINE__,ret); } } @@ -175,7 +173,7 @@ s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p } s32 pad_count = config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1]; - if(pad_count > 0x0F) pad_count = 0; + if(pad_count > 0x0F) pad_count = 0; //??? s32 pad_slot = 0; @@ -340,6 +338,8 @@ s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p } void ControllerPatcherHID::HIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr){ + ControllerPatcherUtils::doSampling(usr->slotdata.deviceslot,usr->pad_slot,false); + //log_printf("my_read_cbInternal: %d %08X %d\n",bytes_transfered,usr->slotdata.hidmask,usr->slotdata.deviceslot); if(usr->slotdata.hidmask == gHID_LIST_GC){ @@ -615,11 +615,11 @@ void ControllerPatcherHID::HIDGCRumble(u32 handle,my_cb_user *usr){ usr->rumblestatus[i] = data_ptr->rumbleActive; usr->buf[i+1] = usr->rumblestatus[i]; } - usr->rumbleForce[0]--; - if(rumblechanged || usr->rumbleForce[0] <= 0){ + usr->forceRumbleInTicks[0]--; + if(rumblechanged || usr->forceRumbleInTicks[0] <= 0){ usr->buf[0] = 0x11; HIDWrite(handle, usr->buf, 5, NULL, NULL); - usr->rumbleForce[0] = 10; + usr->forceRumbleInTicks[0] = 10; } } @@ -632,8 +632,8 @@ void ControllerPatcherHID::HIDRumble(u32 handle,my_cb_user *usr,u32 pad){ usr->rumblestatus[pad] = data_ptr->rumbleActive; rumblechanged = 1; } - usr->rumbleForce[pad]--; - if(rumblechanged || usr->rumbleForce[pad] <= 0){ + usr->forceRumbleInTicks[pad]--; + if(rumblechanged || usr->forceRumbleInTicks[pad] <= 0){ //log_printf("Rumble: %d %d\n",usr->rumblestatus[pad],usr->rumbleForce[pad]); //Seding to the network client! char bytes[6]; @@ -657,7 +657,7 @@ void ControllerPatcherHID::HIDRumble(u32 handle,my_cb_user *usr,u32 pad){ }else{ // Not implemented for other devices =( } - usr->rumbleForce[pad] = 10; + usr->forceRumbleInTicks[pad] = 10; } } diff --git a/patcher/ControllerPatcherUtils.cpp b/patcher/ControllerPatcherUtils.cpp index e19f2d7..15bfe56 100644 --- a/patcher/ControllerPatcherUtils.cpp +++ b/patcher/ControllerPatcherUtils.cpp @@ -376,10 +376,10 @@ Vec2D ControllerPatcherUtils::getAnalogValueByButtons(u8 stick_values){ stick.x = 0.0f; stick.y = 0.0f; - u8 up = (stick_values & STICK_VALUE_UP); - u8 down = (stick_values & STICK_VALUE_DOWN); - u8 left = (stick_values & STICK_VALUE_LEFT); - u8 right = (stick_values & STICK_VALUE_RIGHT); + 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){ @@ -636,10 +636,6 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::translateToPro(VPADDa s32 buttons_hold = 0; - pro_buffer->pro.btns_h = 0; - pro_buffer->pro.btns_d = 0; - pro_buffer->pro.btns_r = 0; - if(vpad_buffer->btns_h & VPAD_BUTTON_A) buttons_hold |= WPAD_PRO_BUTTON_A; if(vpad_buffer->btns_h & VPAD_BUTTON_B) buttons_hold |= WPAD_PRO_BUTTON_B; if(vpad_buffer->btns_h & VPAD_BUTTON_X) buttons_hold |= WPAD_PRO_BUTTON_X; @@ -678,9 +674,19 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::translateToPro(VPADDa pro_buffer->pro.rstick_x = vpad_buffer->rstick.x; pro_buffer->pro.rstick_y = vpad_buffer->rstick.y; - pro_buffer->pro.btns_h |= buttons_hold; - pro_buffer->pro.btns_d |= (buttons_hold & (~*lastButtonsPressesPRO)); - pro_buffer->pro.btns_r |= (*lastButtonsPressesPRO & (~buttons_hold)); + /* + 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.btns_h = buttons_hold; + pro_buffer->pro.btns_d = (buttons_hold & (~*lastButtonsPressesPRO)); + pro_buffer->pro.btns_r = (*lastButtonsPressesPRO & (~buttons_hold)); *lastButtonsPressesPRO = buttons_hold; @@ -698,8 +704,6 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::translateToProWPADRea s32 buttons_hold = 0; - pro_buffer->buttons = 0; - if(vpad_buffer->btns_h & VPAD_BUTTON_A) buttons_hold |= WPAD_PRO_BUTTON_A; if(vpad_buffer->btns_h & VPAD_BUTTON_B) buttons_hold |= WPAD_PRO_BUTTON_B; if(vpad_buffer->btns_h & VPAD_BUTTON_X) buttons_hold |= WPAD_PRO_BUTTON_X; @@ -752,10 +756,6 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::translateToVPAD(VPADD s32 buttons_hold = 0; - vpad_buffer->btns_h = 0; - vpad_buffer->btns_d = 0; - vpad_buffer->btns_r = 0; - if(pro_buffer->pro.btns_h & WPAD_PRO_BUTTON_A) buttons_hold |= VPAD_BUTTON_A; if(pro_buffer->pro.btns_h & WPAD_PRO_BUTTON_B) buttons_hold |= VPAD_BUTTON_B; @@ -796,9 +796,9 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::translateToVPAD(VPADD vpad_buffer->rstick.x = pro_buffer->pro.rstick_x; vpad_buffer->rstick.y = pro_buffer->pro.rstick_y; - vpad_buffer->btns_h |= buttons_hold; - vpad_buffer->btns_d |= (buttons_hold & (~*lastButtonsPressesVPAD)); - vpad_buffer->btns_r |= (*lastButtonsPressesVPAD & (~buttons_hold)); + vpad_buffer->btns_h = buttons_hold; + vpad_buffer->btns_d = (buttons_hold & (~*lastButtonsPressesVPAD)); + vpad_buffer->btns_r = (*lastButtonsPressesVPAD & (~buttons_hold)); *lastButtonsPressesVPAD = buttons_hold; @@ -835,6 +835,14 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getDeviceInfoFromVidP 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; //log_printf("Found device: device: %s slot: %d\n",byte_to_binary(device),deviceSlot); break; @@ -857,7 +865,7 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getNextSlotData(HIDSl CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getVIDPIDbyDeviceSlot(s32 deviceslot, DeviceVIDPIDInfo * vidpid){ if(vidpid == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; - if(deviceslot >= gHIDMaxDevices) return CONTROLLER_PATCHER_ERROR_DEVICE_SLOT_NOT_FOUND; + 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; @@ -899,3 +907,32 @@ ControllerMappingPAD * ControllerPatcherUtils::getControllerMappingByType(UContr } return cm_map_pad; } + +CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::doSampling(u16 deviceslot,u8 padslot = 0,bool ignorePadSlot = false){ + if(gSamplingCallback != NULL){ + for(int i=0;i<4;i++){ + ControllerMappingPADInfo * padinfo = gProPadInfo[i]; + if(padinfo->active){ + 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/patcher/ControllerPatcherUtils.hpp b/patcher/ControllerPatcherUtils.hpp index 52d9c91..525723d 100644 --- a/patcher/ControllerPatcherUtils.hpp +++ b/patcher/ControllerPatcherUtils.hpp @@ -314,6 +314,8 @@ class ControllerPatcherUtils{ \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/utils/CPRetainVars.cpp b/utils/CPRetainVars.cpp index 9cec19b..85d48d3 100644 --- a/utils/CPRetainVars.cpp +++ b/utils/CPRetainVars.cpp @@ -42,6 +42,7 @@ 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; @@ -61,6 +62,11 @@ u8 gUsedProtocolVersion __attribute__((section(".data"))) = WIIU_CP_TCP_HANDSHA 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; 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/utils/CPRetainVars.hpp b/utils/CPRetainVars.hpp index 2a6475d..becc9bf 100644 --- a/utils/CPRetainVars.hpp +++ b/utils/CPRetainVars.hpp @@ -43,6 +43,7 @@ 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; @@ -63,8 +64,10 @@ 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 u32 gUDPClientip; +extern ControllerMappingPADInfo* gProPadInfo[4]; #endif // CP_RETAINS_VARS_H_