Format the files

This commit is contained in:
Maschell 2018-06-19 17:46:37 +02:00
parent a1ae51e073
commit c2e273f46f
17 changed files with 1551 additions and 1315 deletions

View File

@ -15,14 +15,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
/** /**
* @file ControllerPatcher.hpp * @file ControllerPatcher.hpp
* @author Maschell * @author Maschell
* @date 30 Mar 2017 * @date 30 Mar 2017
* \brief This files contain all public accessible functions of the controller patcher engine * \brief This files contain all public accessible functions of the controller patcher engine
* *
* @see https://github.com/Maschell/controller_patcher * @see https://github.com/Maschell/controller_patcher
*/ */
#ifndef _CONTROLLER_PATCHER_H_ #ifndef _CONTROLLER_PATCHER_H_
#define _CONTROLLER_PATCHER_H_ #define _CONTROLLER_PATCHER_H_
@ -33,219 +33,219 @@
#include <vpad/input.h> #include <vpad/input.h>
#include "ControllerPatcherDefs.h" #include "ControllerPatcherDefs.h"
class ControllerPatcher{ class ControllerPatcher {
public: public:
/*----------------------------------------------------------------------------------------------------------------------------------- /*-----------------------------------------------------------------------------------------------------------------------------------
* Initialization * Initialization
*----------------------------------------------------------------------------------------------------------------------------------*/ *----------------------------------------------------------------------------------------------------------------------------------*/
/** /**
\brief Resets the data thats used by the controller configuration \brief Resets the data thats used by the controller configuration
**/ **/
static void ResetConfig(); 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. \brief Initializes the libraries, functions, values and arrays. Need to be called on each start of an Application. Returns false on errors.
@param pathToConfig: The path of the directory containing the configuration files. The path needs already to be mounted and accessible via the @param pathToConfig: The path of the directory containing the configuration files. The path needs already to be mounted and accessible via the
devoptabs! If no configuration should be loaded from the SD Card, set this parameter to NULL. devoptabs! If no configuration should be loaded from the SD Card, set this parameter to NULL.
**/ **/
static bool Init(const char * pathToConfig); static bool Init(const char * pathToConfig);
/** /**
\brief De-Initialises the controller_patcher \brief De-Initialises the controller_patcher
**/ **/
static void DeInit(); static void DeInit();
/** /**
Initialises the button remapping Initialises the button remapping
**/ **/
static void InitButtonMapping(); static void InitButtonMapping();
/** /**
Starts the network server Starts the network server
**/ **/
static void startNetworkServer(); static void startNetworkServer();
/** /**
Stops the network server Stops the network server
**/ **/
static void stopNetworkServer(); static void stopNetworkServer();
/*----------------------------------------------------------------------------------------------------------------------------------- /*-----------------------------------------------------------------------------------------------------------------------------------
* Initialization * 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 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. 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 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 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 @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. @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); 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. 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 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. @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. @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); static CONTROLLER_PATCHER_RESULT_OR_ERROR setControllerDataFromHID(VPADStatus * buffer);
/*----------------------------------------------------------------------------------------------------------------------------------- /*-----------------------------------------------------------------------------------------------------------------------------------
* Useful functions * Useful functions
*----------------------------------------------------------------------------------------------------------------------------------*/ *----------------------------------------------------------------------------------------------------------------------------------*/
/** /**
Enable the Controller mapping. Enable the Controller mapping.
@return When the functions failed result < 0 is returned. If the result is == 0 the function was successful. @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(); static CONTROLLER_PATCHER_RESULT_OR_ERROR enableControllerMapping();
/** /**
Disbale the Controller mapping. Afterwards all connected controllers will be used for the gamepad. 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. @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(); static CONTROLLER_PATCHER_RESULT_OR_ERROR disableControllerMapping();
/** /**
Disables the energy settings for the WiiU. Settings can be restored via restoreWiiUEnergySetting. 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. @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(); static CONTROLLER_PATCHER_RESULT_OR_ERROR disableWiiUEnergySetting();
/** /**
Restores the WiiU Energy Settings. Restores the WiiU Energy Settings.
@return When the functions failed result < 0 is returned. If the result is == 0 the function was successful. @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(); static CONTROLLER_PATCHER_RESULT_OR_ERROR restoreWiiUEnergySetting();
/** /**
Resets the controller mapping for a given controller type. Resets the controller mapping for a given controller type.
@param type: The type of the controller. @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. @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); static CONTROLLER_PATCHER_RESULT_OR_ERROR resetControllerMapping(UController_Type type);
/** /**
Adds a controller mapping Adds a controller mapping
@param type: The type of the controller. @param type: The type of the controller.
@param config: information about the added 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. @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); 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. @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); static s32 getActiveMappingSlot(UController_Type type);
/** /**
@param type: The type of the controller. @param type: The type of the controller.
@param mapping_slot: information about the added 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. @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); static ControllerMappingPADInfo * getControllerMappingInfo(UController_Type type,s32 mapping_slot);
/** /**
Checks if a emulated controller is connected for the given controller type / mapping slot. Checks if a emulated controller is connected for the given controller type / mapping slot.
@param type: The type of the controller. @param type: The type of the controller.
@param mapping_slot: Slot of the controller mapped to this controller type (usually 0) @param mapping_slot: Slot of the controller mapped to this controller type (usually 0)
@return @return
**/ **/
static bool isControllerConnectedAndActive(UController_Type type,s32 mapping_slot = 0); static bool isControllerConnectedAndActive(UController_Type type,s32 mapping_slot = 0);
/** /**
Search for a connected mouse and returns a pointer to it's data. 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. @return A pointer to the first connected mouse that is found. NULL if no mouse is connected.
**/ **/
static HID_Mouse_Data * getMouseData(); static HID_Mouse_Data * getMouseData();
/** /**
Sets a rumble status for a controller. Sets a rumble status for a controller.
@param type: The type of the controller. @param type: The type of the controller.
@param status: status of the rumble. 0 for off, 1 for on. @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. @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); 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. 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 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. @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. @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); 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. 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. 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. @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. @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); 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.. 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. @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. @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 CONTROLLER_PATCHER_RESULT_OR_ERROR printVPADButtons(VPADStatus * buffer);
static std::string getIdentifierByVIDPID(u16 vid,u16 pid); static std::string getIdentifierByVIDPID(u16 vid,u16 pid);
static void destroyConfigHelper(); static void destroyConfigHelper();
static CONTROLLER_PATCHER_RESULT_OR_ERROR doSamplingForDeviceSlot(u16 device_slot); static CONTROLLER_PATCHER_RESULT_OR_ERROR doSamplingForDeviceSlot(u16 device_slot);
static CONTROLLER_PATCHER_RESULT_OR_ERROR setRumbleActivated(bool value); static CONTROLLER_PATCHER_RESULT_OR_ERROR setRumbleActivated(bool value);
static CONTROLLER_PATCHER_RESULT_OR_ERROR setNetworkControllerActivated(bool value); static CONTROLLER_PATCHER_RESULT_OR_ERROR setNetworkControllerActivated(bool value);
static bool isRumbleActivated(); static bool isRumbleActivated();
static bool isButtonRemappingDone(); static bool isButtonRemappingDone();
static bool isKeyboardConnected(); static bool isKeyboardConnected();
static bool areControllersConnected(); static bool areControllersConnected();
static CONTROLLER_PATCHER_RESULT_OR_ERROR sampleKeyboardData(); static CONTROLLER_PATCHER_RESULT_OR_ERROR sampleKeyboardData();
static CONTROLLER_PATCHER_RESULT_OR_ERROR resetCallbackData(); static CONTROLLER_PATCHER_RESULT_OR_ERROR resetCallbackData();
static CONTROLLER_PATCHER_RESULT_OR_ERROR setKPADConnectedCallback(s32 chan, WPADConnectCallback callback); static CONTROLLER_PATCHER_RESULT_OR_ERROR setKPADConnectedCallback(s32 chan, WPADConnectCallback callback);
static CONTROLLER_PATCHER_RESULT_OR_ERROR setKPADExtensionCallback(s32 chan, WPADConnectCallback callback); static CONTROLLER_PATCHER_RESULT_OR_ERROR setKPADExtensionCallback(s32 chan, WPADConnectCallback callback);
static CONTROLLER_PATCHER_RESULT_OR_ERROR setWPADConnectCallback(s32 chan, WPADConnectCallback callback); static CONTROLLER_PATCHER_RESULT_OR_ERROR setWPADConnectCallback(s32 chan, WPADConnectCallback callback);
static CONTROLLER_PATCHER_RESULT_OR_ERROR handleCallbackData(bool button_pressed); static CONTROLLER_PATCHER_RESULT_OR_ERROR handleCallbackData(bool button_pressed);
static CONTROLLER_PATCHER_RESULT_OR_ERROR handleCallbackDataInternal(WPADChan chan); static CONTROLLER_PATCHER_RESULT_OR_ERROR handleCallbackDataInternal(WPADChan chan);
}; };
#endif /* _CONTROLLER_PATCHER_H_ */ #endif /* _CONTROLLER_PATCHER_H_ */

View File

@ -80,8 +80,7 @@ typedef int CONTROLLER_PATCHER_RESULT_OR_ERROR;
/** /**
* @brief The enumeration of Controller sticks defines * @brief The enumeration of Controller sticks defines
*/ */
enum Controller_Stick_Defines enum Controller_Stick_Defines {
{
STICK_CONF_MAGIC_VERSION, /**< Version of the stick configuration. Changes with every format*/ 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_BYTE, /**< Byte where the stick-axis data is stored*/
STICK_CONF_DEFAULT, /**< Default value*/ STICK_CONF_DEFAULT, /**< Default value*/
@ -95,8 +94,7 @@ enum Controller_Stick_Defines
#define STICK_CONF_MAGIC_VALUE 0xF0 // When you change the enum above, Dont forget to change the magic version!!!! #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) //! most data has the format: byte,value (byte starting at 0)
enum Controller_Patcher_Settings enum Controller_Patcher_Settings {
{
CONTRPS_VID, //! pid: 0x451d would be 0x45,0x1d CONTRPS_VID, //! pid: 0x451d would be 0x45,0x1d
CONTRPS_PID, //! vid: 0x488d would be 0x48,0x8d CONTRPS_PID, //! vid: 0x488d would be 0x48,0x8d
CONTRPS_BUF_SIZE, //! To set: CONTROLLER_PATCHER_VALUE_SET, BUF_SIZE (default is 64) CONTRPS_BUF_SIZE, //! To set: CONTROLLER_PATCHER_VALUE_SET, BUF_SIZE (default is 64)
@ -203,8 +201,7 @@ enum Controller_Patcher_Settings
/** /**
* @brief The enumeration of different DPAD-Modes * @brief The enumeration of different DPAD-Modes
*/ */
enum Controller_Patcher_DPAD_MODE enum Controller_Patcher_DPAD_MODE {
{
CONTRPDM_Normal, /**< Normal mode */ CONTRPDM_Normal, /**< Normal mode */
CONTRPDM_Hat, /**< Hat mode */ CONTRPDM_Hat, /**< Hat mode */
CONTRPDM_Absolute_2Values, /**< DPAD Value stored in 2 values (one for each axis), acting like a stick */ CONTRPDM_Absolute_2Values, /**< DPAD Value stored in 2 values (one for each axis), acting like a stick */
@ -212,8 +209,7 @@ enum Controller_Patcher_DPAD_MODE
/** /**
* @brief The enumeration of DPAD Settings. Needed for saving both in the PADConst. * @brief The enumeration of DPAD Settings. Needed for saving both in the PADConst.
*/ */
enum Controller_Patcher_DPAD_Settings enum Controller_Patcher_DPAD_Settings {
{
CONTRDPAD_MODE = 0, /**< Byte where the DPAD Mode is stored */ CONTRDPAD_MODE = 0, /**< Byte where the DPAD Mode is stored */
CONTRDPAD_MASK = 1, /**< Byte where the DPAD Mask is stored */ CONTRDPAD_MASK = 1, /**< Byte where the DPAD Mask is stored */
}; };
@ -221,24 +217,24 @@ enum Controller_Patcher_DPAD_Settings
/** /**
* @brief Stores data if the Slot the device is using in gHID_Devices * @brief Stores data if the Slot the device is using in gHID_Devices
*/ */
typedef struct _HIDSlotData{ typedef struct _HIDSlotData {
u16 deviceslot; /**< deviceslot number */ u16 deviceslot; /**< deviceslot number */
u32 hidmask; /**< Used HID-Mask */ u32 hidmask; /**< Used HID-Mask */
}HIDSlotData; } HIDSlotData;
/** /**
* @brief Struct where the data for the callback funtion is stored * @brief Struct where the data for the callback funtion is stored
*/ */
typedef struct _my_cb_user{ typedef struct _my_cb_user {
u8 *buf; /**< pointer the buffer that is used */ u8 *buf; /**< pointer the buffer that is used */
u32 transfersize; /**< number of transfered data */ u32 transfersize; /**< number of transfered data */
u32 handle; /**< HID handle */ u32 handle; /**< HID handle */
HIDSlotData slotdata; /**< Information about the deviceslot and hidmask */ HIDSlotData slotdata; /**< Information about the deviceslot and hidmask */
u32 pads_per_device; /**< Number of maximum pads of this device */ u32 pads_per_device; /**< Number of maximum pads of this device */
u8 pad_slot; /**< number of the pad that will be used */ u8 pad_slot; /**< number of the pad that will be used */
u8 rumblestatus[HID_MAX_PADS_COUNT]; /**< Current status of the device rumble */ u8 rumblestatus[HID_MAX_PADS_COUNT]; /**< Current status of the device rumble */
u8 forceRumbleInTicks[HID_MAX_PADS_COUNT]; u8 forceRumbleInTicks[HID_MAX_PADS_COUNT];
}my_cb_user; } my_cb_user;
/** /**
* @brief Stores data for the mouse * @brief Stores data for the mouse
@ -256,8 +252,7 @@ typedef struct _HID_Mouse_Data {
/** /**
* @brief The enumeration of device types * @brief The enumeration of device types
*/ */
enum DEVICE_TYPE enum DEVICE_TYPE {
{
DEVICE_TYPE_CONTROLLER = 0, /**< Normal Controller */ DEVICE_TYPE_CONTROLLER = 0, /**< Normal Controller */
DEVICE_TYPE_MOUSE = 1, /**< Mouse */ DEVICE_TYPE_MOUSE = 1, /**< Mouse */
}; };
@ -269,16 +264,16 @@ typedef struct _HID_Data {
u32 handle; /**< The HID-handle this device is using */ u32 handle; /**< The HID-handle this device is using */
u8 rumbleActive; /**< 1 when rumble is active */ u8 rumbleActive; /**< 1 when rumble is active */
u32 last_buttons; /**< The last pressed buttons, based on VPAD_BUTTON_XXX data */ u32 last_buttons; /**< The last pressed buttons, based on VPAD_BUTTON_XXX data */
union{ union {
struct{ struct {
u8 cur_hid_data[HID_MAX_DATA_LENGTH_PER_PAD]; /**< Array where the current controller data is stored */ 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 */ 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. */ } controller; /**< Used when the device in a controller. Using u8 array where the raw data of the controller is placed. */
struct{ struct {
HID_Mouse_Data cur_mouse_data; /**< Struct where the current mouse data is stored */ 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 */ 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. */ } 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.*/ } data_union; /**< The data union where the current and last data is stored.*/
DEVICE_TYPE type; /**< The device type*/ DEVICE_TYPE type; /**< The device type*/
HIDSlotData slotdata; /**< Information about the deviceslot and his mask*/ HIDSlotData slotdata; /**< Information about the deviceslot and his mask*/
my_cb_user * user_data; /**< Pointer to the user data the read callback is using*/ my_cb_user * user_data; /**< Pointer to the user data the read callback is using*/
@ -296,24 +291,24 @@ typedef struct _HID_DEVICE_DATA {
/** /**
* @brief Stores a VID and PID * @brief Stores a VID and PID
*/ */
typedef struct _DeviceVIDPIDInfo{ typedef struct _DeviceVIDPIDInfo {
u16 vid; /**< Vendor ID of this device */ u16 vid; /**< Vendor ID of this device */
u16 pid; /**< Product ID of this device */ u16 pid; /**< Product ID of this device */
}DeviceVIDPIDInfo; } DeviceVIDPIDInfo;
/** /**
* @brief Infos of the device * @brief Infos of the device
*/ */
typedef struct _DeviceInfo{ typedef struct _DeviceInfo {
HIDSlotData slotdata; /**< The slot used by this device */ HIDSlotData slotdata; /**< The slot used by this device */
DeviceVIDPIDInfo vidpid; /**< The VID/PID of the device */ DeviceVIDPIDInfo vidpid; /**< The VID/PID of the device */
u8 pad_count; /**< Number of maximum pads this device can have*/ u8 pad_count; /**< Number of maximum pads this device can have*/
}DeviceInfo; } DeviceInfo;
/** /**
* @brief The enumeration of Controller-Mapping types * @brief The enumeration of Controller-Mapping types
*/ */
enum ControllerMapping_Type_Defines{ enum ControllerMapping_Type_Defines {
CM_Type_Controller = 0, /**< Device with single input */ CM_Type_Controller = 0, /**< Device with single input */
CM_Type_RealController = 1, /**< Real Pro Controller */ CM_Type_RealController = 1, /**< Real Pro Controller */
CM_Type_Mouse = 2, /**< Mouse */ CM_Type_Mouse = 2, /**< Mouse */
@ -323,52 +318,52 @@ enum ControllerMapping_Type_Defines{
/** /**
* @brief Infos of a mapped controller * @brief Infos of a mapped controller
*/ */
typedef struct _ControllerMappingPADInfo{ typedef struct _ControllerMappingPADInfo {
u8 active; /**< Set to one if mapped */ u8 active; /**< Set to one if mapped */
ControllerMapping_Type_Defines type; /**< Type of the controller mapping */ ControllerMapping_Type_Defines type; /**< Type of the controller mapping */
DeviceVIDPIDInfo vidpid; /**< The VID/PID of the device */ DeviceVIDPIDInfo vidpid; /**< The VID/PID of the device */
u8 pad; /**< Stores which pad it mapped */ u8 pad; /**< Stores which pad it mapped */
}ControllerMappingPADInfo; } ControllerMappingPADInfo;
/** /**
* @brief Infos of a mapped controller * @brief Infos of a mapped controller
*/ */
typedef struct _ControllerMappingPAD{ typedef struct _ControllerMappingPAD {
ControllerMappingPADInfo pad_infos[HID_MAX_DEVICES_PER_SLOT]; //lets limit this to HID_MAX_DEVICES_PER_SLOT. ControllerMappingPADInfo pad_infos[HID_MAX_DEVICES_PER_SLOT]; //lets limit this to HID_MAX_DEVICES_PER_SLOT.
u8 useAll; u8 useAll;
u8 rumble; /**< Set when the controller should rumble */ u8 rumble; /**< Set when the controller should rumble */
}ControllerMappingPAD; } ControllerMappingPAD;
/** /**
* @brief Stores informations about all mapped controller * @brief Stores informations about all mapped controller
*/ */
typedef struct _ControllerMapping{ typedef struct _ControllerMapping {
ControllerMappingPAD gamepad; /**< Information about the gamepad mapping */ ControllerMappingPAD gamepad; /**< Information about the gamepad mapping */
ControllerMappingPAD proController[4]; /**< Information about the Pro Controller mapping */ ControllerMappingPAD proController[4]; /**< Information about the Pro Controller mapping */
}ControllerMapping; } ControllerMapping;
/** /**
* @brief Pressed/Released/Down Button data. * @brief Pressed/Released/Down Button data.
*/ */
typedef struct _InputButtonData{ typedef struct _InputButtonData {
u32 btn_h; /**< Buttons beeing hold */ u32 btn_h; /**< Buttons beeing hold */
u32 btn_d; /**< Buttons that started pressing */ u32 btn_d; /**< Buttons that started pressing */
u32 btn_r; /**< Buttons that were button released */ u32 btn_r; /**< Buttons that were button released */
}InputButtonData; } InputButtonData;
/** /**
* @brief Struct where the inputdata of a device for all HID_MAX_PADS_COUNT pads can be stored * @brief Struct where the inputdata of a device for all HID_MAX_PADS_COUNT pads can be stored
*/ */
typedef struct _InputData{ typedef struct _InputData {
DeviceInfo device_info; /**< Infos about the device where the data is coming from */ DeviceInfo device_info; /**< Infos about the device where the data is coming from */
ControllerMapping_Type_Defines type; ControllerMapping_Type_Defines type;
InputButtonData button_data[HID_MAX_PADS_COUNT]; InputButtonData button_data[HID_MAX_PADS_COUNT];
}InputData; } InputData;
/** /**
* @brief The enumeration of WiiU Controller types * @brief The enumeration of WiiU Controller types
*/ */
enum UController_Type{ enum UController_Type {
UController_Type_Gamepad, UController_Type_Gamepad,
UController_Type_Pro1, UController_Type_Pro1,
UController_Type_Pro2, UController_Type_Pro2,

View File

@ -34,55 +34,63 @@
s32 ConfigReader::numberValidFiles = 0; s32 ConfigReader::numberValidFiles = 0;
ConfigReader *ConfigReader::instance = NULL; ConfigReader *ConfigReader::instance = NULL;
ConfigReader::ConfigReader(){ ConfigReader::ConfigReader() {
} }
bool ConfigReader::ReadConfigs(std::string path){ bool ConfigReader::ReadConfigs(std::string path) {
std::vector<std::string> fileList = ScanFolder(path); std::vector<std::string> fileList = ScanFolder(path);
if(fileList.size() == 1 && fileList[0].compare("ERROR") == 0){ if(fileList.size() == 1 && fileList[0].compare("ERROR") == 0) {
return false; return false;
} }
if(fileList.size() > 0){ if(fileList.size() > 0) {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Found %d config files\n",fileList.size()); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Found %d config files\n",fileList.size());
}
processFileList(fileList); processFileList(fileList);
} }
return true; return true;
} }
ConfigReader::~ConfigReader(){ ConfigReader::~ConfigReader() {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("~ConfigReader\n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("~ConfigReader\n");
}
} }
std::vector<std::string> ConfigReader::ScanFolder(std::string path){ std::vector<std::string> ConfigReader::ScanFolder(std::string path) {
std::vector<std::string> config_files; std::vector<std::string> config_files;
struct dirent *dirent = NULL; struct dirent *dirent = NULL;
DIR *dirHandle = opendir(path.c_str()); DIR *dirHandle = opendir(path.c_str());
if (dirHandle == NULL){ if (dirHandle == NULL) {
DEBUG_FUNCTION_LINE("Failed to open dir %s\n",path.c_str()); DEBUG_FUNCTION_LINE("Failed to open dir %s\n",path.c_str());
config_files.push_back("ERROR"); //TODO: Find a proper solution config_files.push_back("ERROR"); //TODO: Find a proper solution
return config_files; return config_files;
} }
while ((dirent = readdir(dirHandle)) != 0){ while ((dirent = readdir(dirHandle)) != 0) {
bool isDir = dirent->d_type & DT_DIR; bool isDir = dirent->d_type & DT_DIR;
const char *filename = dirent->d_name; const char *filename = dirent->d_name;
if(strcmp(filename,".") == 0 || strcmp(filename,"..") == 0){ continue; } if(strcmp(filename,".") == 0 || strcmp(filename,"..") == 0) {
continue;
}
std::string newPath = path + "/" + std::string(filename); std::string newPath = path + "/" + std::string(filename);
if(!isDir && StringTools::EndsWith(std::string(filename),".ini")){ if(!isDir && StringTools::EndsWith(std::string(filename),".ini")) {
config_files.push_back(newPath); config_files.push_back(newPath);
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Found ini: %s \n",newPath.c_str()); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Found ini: %s \n",newPath.c_str());
}
} }
} }
return config_files; return config_files;
} }
void ConfigReader::processFileList(std::vector<std::string> path){ void ConfigReader::processFileList(std::vector<std::string> path) {
for(std::vector<std::string>::iterator it = path.begin(); it != path.end(); ++it) { for(std::vector<std::string>::iterator it = path.begin(); it != path.end(); ++it) {
DEBUG_FUNCTION_LINE("Reading %s\n",it->c_str()); DEBUG_FUNCTION_LINE("Reading %s\n",it->c_str());
std::string result = loadFileToString(*it); std::string result = loadFileToString(*it);
@ -92,10 +100,10 @@ void ConfigReader::processFileList(std::vector<std::string> path){
} }
} }
std::string ConfigReader::loadFileToString(std::string path){ std::string ConfigReader::loadFileToString(std::string path) {
std::string strBuffer = ""; std::string strBuffer = "";
u8 * buffer = NULL; u8 * buffer = NULL;
if(FSUtils::LoadFileToMem(path.c_str(),&buffer,NULL) > 0){ if(FSUtils::LoadFileToMem(path.c_str(),&buffer,NULL) > 0) {
strBuffer = std::string((char *)buffer); strBuffer = std::string((char *)buffer);
strBuffer = StringTools::removeCharFromString(strBuffer,'\r'); strBuffer = StringTools::removeCharFromString(strBuffer,'\r');
strBuffer = StringTools::removeCharFromString(strBuffer,' '); strBuffer = StringTools::removeCharFromString(strBuffer,' ');

View File

@ -36,10 +36,14 @@ 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. // 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]; static VPADStatus myVPADBuffer[4];
void ControllerPatcher::InitButtonMapping(){ void ControllerPatcher::InitButtonMapping() {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Init called \n"); } if(HID_DEBUG) {
if(!gButtonRemappingConfigDone){ DEBUG_FUNCTION_LINE("Init called \n");
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Remapping is running! \n"); } }
if(!gButtonRemappingConfigDone) {
if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Remapping is running! \n");
}
gButtonRemappingConfigDone = 1; gButtonRemappingConfigDone = 1;
memset(gGamePadValues,0,sizeof(gGamePadValues)); // Init / Invalid everything memset(gGamePadValues,0,sizeof(gGamePadValues)); // Init / Invalid everything
@ -74,7 +78,7 @@ void ControllerPatcher::InitButtonMapping(){
} }
} }
void ControllerPatcher::ResetConfig(){ void ControllerPatcher::ResetConfig() {
memset(&gControllerMapping,0,sizeof(gControllerMapping)); memset(&gControllerMapping,0,sizeof(gControllerMapping));
disableControllerMapping(); disableControllerMapping();
memset(config_controller,CONTROLLER_PATCHER_INVALIDVALUE,sizeof(config_controller)); // Init / Invalid everything memset(config_controller,CONTROLLER_PATCHER_INVALIDVALUE,sizeof(config_controller)); // Init / Invalid everything
@ -102,12 +106,16 @@ void ControllerPatcher::ResetConfig(){
gHIDRegisteredDevices = 0; gHIDRegisteredDevices = 0;
ControllerPatcherUtils::getNextSlotData(&slotdata); ControllerPatcherUtils::getNextSlotData(&slotdata);
gGamePadSlot = slotdata.deviceslot; gGamePadSlot = slotdata.deviceslot;
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Register Gamepad-Config. HID-Mask %s Device-Slot: %d\n",StringTools::byte_to_binary(slotdata.hidmask),gGamePadSlot); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Register Gamepad-Config. HID-Mask %s Device-Slot: %d\n",StringTools::byte_to_binary(slotdata.hidmask),gGamePadSlot);
}
ControllerPatcherUtils::getNextSlotData(&slotdata); ControllerPatcherUtils::getNextSlotData(&slotdata);
gMouseSlot = slotdata.deviceslot; gMouseSlot = slotdata.deviceslot;
gHID_LIST_MOUSE = slotdata.hidmask; gHID_LIST_MOUSE = slotdata.hidmask;
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Register Mouse-Config. HID-Mask %s Device-Slot: %d\n",StringTools::byte_to_binary(gHID_LIST_MOUSE),gMouseSlot); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Register Mouse-Config. HID-Mask %s Device-Slot: %d\n",StringTools::byte_to_binary(gHID_LIST_MOUSE),gMouseSlot);
}
ControllerPatcherUtils::getNextSlotData(&slotdata); ControllerPatcherUtils::getNextSlotData(&slotdata);
u32 keyboard_slot = slotdata.deviceslot; u32 keyboard_slot = slotdata.deviceslot;
@ -115,31 +123,41 @@ void ControllerPatcher::ResetConfig(){
gHID_LIST_KEYBOARD = keyboard_hid; gHID_LIST_KEYBOARD = keyboard_hid;
gHID_SLOT_KEYBOARD = keyboard_slot; gHID_SLOT_KEYBOARD = keyboard_slot;
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Register Keyboard-Config. HID-Mask %s Device-Slot: %d\n",StringTools::byte_to_binary(gHID_LIST_KEYBOARD),gHID_SLOT_KEYBOARD); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Register Keyboard-Config. HID-Mask %s Device-Slot: %d\n",StringTools::byte_to_binary(gHID_LIST_KEYBOARD),gHID_SLOT_KEYBOARD);
}
ControllerPatcherUtils::getNextSlotData(&slotdata); ControllerPatcherUtils::getNextSlotData(&slotdata);
u32 gc_slot = slotdata.deviceslot; u32 gc_slot = slotdata.deviceslot;
u32 gc_hid = slotdata.hidmask; u32 gc_hid = slotdata.hidmask;
gHID_LIST_GC = gc_hid; gHID_LIST_GC = gc_hid;
gHID_SLOT_GC = gc_slot; gHID_SLOT_GC = gc_slot;
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Register GC-Adapter-Config. HID-Mask %s Device-Slot: %d\n",StringTools::byte_to_binary(gHID_LIST_GC),gHID_SLOT_GC); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Register GC-Adapter-Config. HID-Mask %s Device-Slot: %d\n",StringTools::byte_to_binary(gHID_LIST_GC),gHID_SLOT_GC);
}
ControllerPatcherUtils::getNextSlotData(&slotdata); ControllerPatcherUtils::getNextSlotData(&slotdata);
u32 ds3_slot = slotdata.deviceslot; u32 ds3_slot = slotdata.deviceslot;
u32 ds3_hid = slotdata.hidmask; u32 ds3_hid = slotdata.hidmask;
gHID_LIST_DS3 = ds3_hid; gHID_LIST_DS3 = ds3_hid;
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Register DS3-Config. HID-Mask %s Device-Slot: %d\n",StringTools::byte_to_binary(gHID_LIST_DS3),ds3_slot); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Register DS3-Config. HID-Mask %s Device-Slot: %d\n",StringTools::byte_to_binary(gHID_LIST_DS3),ds3_slot);
}
ControllerPatcherUtils::getNextSlotData(&slotdata); ControllerPatcherUtils::getNextSlotData(&slotdata);
u32 ds4_slot = slotdata.deviceslot; u32 ds4_slot = slotdata.deviceslot;
u32 ds4_hid = slotdata.hidmask; u32 ds4_hid = slotdata.hidmask;
gHID_LIST_DS4 = ds4_hid; gHID_LIST_DS4 = ds4_hid;
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Register DS4-Config. HID-Mask %s Device-Slot: %d\n",StringTools::byte_to_binary(ds4_hid),ds4_slot); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Register DS4-Config. HID-Mask %s Device-Slot: %d\n",StringTools::byte_to_binary(ds4_hid),ds4_slot);
}
ControllerPatcherUtils::getNextSlotData(&slotdata); ControllerPatcherUtils::getNextSlotData(&slotdata);
u32 xinput_slot = slotdata.deviceslot; u32 xinput_slot = slotdata.deviceslot;
u32 xinput_hid = slotdata.hidmask; u32 xinput_hid = slotdata.hidmask;
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Register XInput-Config. HID-Mask %s Device-Slot: %d\n",StringTools::byte_to_binary(xinput_hid),xinput_slot); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Register XInput-Config. HID-Mask %s Device-Slot: %d\n",StringTools::byte_to_binary(xinput_hid),xinput_slot);
}
ControllerPatcherUtils::getNextSlotData(&slotdata); ControllerPatcherUtils::getNextSlotData(&slotdata);
u32 switch_pro_slot = slotdata.deviceslot; u32 switch_pro_slot = slotdata.deviceslot;
@ -290,7 +308,7 @@ void ControllerPatcher::ResetConfig(){
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_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); 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 //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_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_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_3_RELEASED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_ZR);
@ -484,21 +502,28 @@ bool ControllerPatcher::Init(const char * pathToConfig) {
} }
DEBUG_FUNCTION_LINE("Found the gSamplingCallback at %08X \n",gSamplingCallback); DEBUG_FUNCTION_LINE("Found the gSamplingCallback at %08X \n",gSamplingCallback);
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Init called! \n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Init called! \n");
if(gConfig_done == HID_INIT_NOT_DONE){
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("First time calling the Init\n"); }
gConfig_done = HID_INIT_DONE;
ControllerPatcher::ResetConfig();
}else{
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Config already done!\n"); }
} }
if(pathToConfig != NULL && gConfig_done != HID_SDCARD_READ){ if(gConfig_done == HID_INIT_NOT_DONE) {
if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("First time calling the Init\n");
}
gConfig_done = HID_INIT_DONE;
ControllerPatcher::ResetConfig();
} else {
if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Config already done!\n");
}
}
if(pathToConfig != NULL && gConfig_done != HID_SDCARD_READ) {
DEBUG_FUNCTION_LINE("Reading config files from SD Card\n");
DEBUG_FUNCTION_LINE("Reading config files from SD Card\n"); DEBUG_FUNCTION_LINE("Reading config files from SD Card\n");
ConfigReader* reader = ConfigReader::getInstance(); ConfigReader* reader = ConfigReader::getInstance();
if(reader->ReadConfigs(pathToConfig)){ if(reader->ReadConfigs(pathToConfig)) {
DEBUG_FUNCTION_LINE("Done with reading config files from SD Card\n"); DEBUG_FUNCTION_LINE("Done with reading config files from SD Card\n");
gConfig_done = HID_SDCARD_READ; gConfig_done = HID_SDCARD_READ;
} }
@ -508,29 +533,31 @@ bool ControllerPatcher::Init(const char * pathToConfig) {
DEBUG_FUNCTION_LINE("Initializing the data for button remapping\n"); DEBUG_FUNCTION_LINE("Initializing the data for button remapping\n");
InitButtonMapping(); InitButtonMapping();
if(!gHIDAttached){ if(!gHIDAttached) {
HIDAddClient(&gHIDClient, ControllerPatcherHID::myAttachDetachCallback); HIDAddClient(&gHIDClient, ControllerPatcherHID::myAttachDetachCallback);
} }
return true; return true;
} }
void ControllerPatcher::startNetworkServer(){ void ControllerPatcher::startNetworkServer() {
if(!gNetworkControllerActivated) return; if(!gNetworkControllerActivated) return;
DEBUG_FUNCTION_LINE("statedNetworkServer! \n"); DEBUG_FUNCTION_LINE("statedNetworkServer! \n");
UDPServer::getInstance(); UDPServer::getInstance();
CPTCPServer::getInstance(); CPTCPServer::getInstance();
} }
void ControllerPatcher::stopNetworkServer(){ void ControllerPatcher::stopNetworkServer() {
DEBUG_FUNCTION_LINE("called! \n"); DEBUG_FUNCTION_LINE("called! \n");
UDPServer::destroyInstance(); UDPServer::destroyInstance();
UDPClient::destroyInstance(); UDPClient::destroyInstance();
CPTCPServer::destroyInstance(); CPTCPServer::destroyInstance();
} }
void ControllerPatcher::DeInit(){ void ControllerPatcher::DeInit() {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("called! \n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("called! \n");
}
if(gHIDAttached) HIDDelClient(&gHIDClient); if(gHIDAttached) HIDDelClient(&gHIDClient);
@ -577,28 +604,32 @@ void ControllerPatcher::DeInit(){
destroyConfigHelper(); destroyConfigHelper();
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::enableControllerMapping(){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::enableControllerMapping() {
gControllerMapping.gamepad.useAll = 0; gControllerMapping.gamepad.useAll = 0;
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::disableControllerMapping(){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::disableControllerMapping() {
gControllerMapping.gamepad.useAll = 1; gControllerMapping.gamepad.useAll = 1;
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::disableWiiUEnergySetting(){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::disableWiiUEnergySetting() {
s32 res; uint32_t res;
if(IMIsDimEnabled(&res) == 0){ if(IMIsDimEnabled(&res) == 0) {
if(res == 1){ if(res == 1) {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Dim was orignally enabled!\n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Dim was orignally enabled!\n");
}
gOriginalDimState = 1; gOriginalDimState = 1;
} }
} }
if(IMIsAPDEnabled(&res) == 0){ if(IMIsAPDEnabled(&res) == 0) {
if(res == 1){ if(res == 1) {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Auto power down was orignally enabled!\n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Auto power down was orignally enabled!\n");
}
gOriginalAPDState = 1; gOriginalAPDState = 1;
} }
} }
@ -609,37 +640,39 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::disableWiiUEnergySetting()
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::restoreWiiUEnergySetting(){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::restoreWiiUEnergySetting() {
//Check if we need to enable Auto Power down again on exiting //Check if we need to enable Auto Power down again on exiting
if(gOriginalAPDState == 1){ if(gOriginalAPDState == 1) {
DEBUG_FUNCTION_LINE("Auto shutdown was on before using HID to VPAD. Setting it to on again.\n"); DEBUG_FUNCTION_LINE("Auto shutdown was on before using HID to VPAD. Setting it to on again.\n");
IMEnableAPD(); IMEnableAPD();
} }
if(gOriginalDimState == 1){ if(gOriginalDimState == 1) {
DEBUG_FUNCTION_LINE("Burn-in reduction was on before using HID to VPAD. Setting it to on again.\n"); DEBUG_FUNCTION_LINE("Burn-in reduction was on before using HID to VPAD. Setting it to on again.\n");
IMEnableDim(); IMEnableDim();
} }
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::resetControllerMapping(UController_Type type){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::resetControllerMapping(UController_Type type) {
ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type); ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type);
if(cm_map_pad == NULL){return CONTROLLER_PATCHER_ERROR_NULL_POINTER;} if(cm_map_pad == NULL) {
return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
}
memset(cm_map_pad,0,sizeof(*cm_map_pad)); memset(cm_map_pad,0,sizeof(*cm_map_pad));
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::addControllerMapping(UController_Type type,ControllerMappingPADInfo config){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::addControllerMapping(UController_Type type,ControllerMappingPADInfo config) {
ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type); ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type);
s32 result = 0; s32 result = 0;
for(s32 i=0;i<HID_MAX_DEVICES_PER_SLOT;i++){ for(s32 i=0; i<HID_MAX_DEVICES_PER_SLOT; i++) {
ControllerMappingPADInfo * info = &(cm_map_pad->pad_infos[i]); ControllerMappingPADInfo * info = &(cm_map_pad->pad_infos[i]);
if(info != NULL && !info->active){ if(info != NULL && !info->active) {
info->active = 1; info->active = 1;
info->pad = config.pad; info->pad = config.pad;
info->type = config.type; info->type = config.type;
@ -650,7 +683,7 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::addControllerMapping(UCont
break; break;
} }
} }
if(result == 0){ if(result == 0) {
//No free slot. //No free slot.
return -1; return -1;
} }
@ -658,14 +691,16 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::addControllerMapping(UCont
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
s32 ControllerPatcher::getActiveMappingSlot(UController_Type type){ s32 ControllerPatcher::getActiveMappingSlot(UController_Type type) {
ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type); ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type);
if(cm_map_pad == NULL){return -1;} if(cm_map_pad == NULL) {
return -1;
}
s32 connected = -1; s32 connected = -1;
for(s32 i =0;i<HID_MAX_DEVICES_PER_SLOT;i++){ for(s32 i =0; i<HID_MAX_DEVICES_PER_SLOT; i++) {
if(cm_map_pad->pad_infos[i].active || cm_map_pad->pad_infos[i].type == CM_Type_RealController){ if(cm_map_pad->pad_infos[i].active || cm_map_pad->pad_infos[i].type == CM_Type_RealController) {
connected = i; connected = i;
break; break;
} }
@ -674,12 +709,12 @@ s32 ControllerPatcher::getActiveMappingSlot(UController_Type type){
return connected; return connected;
} }
bool ControllerPatcher::isControllerConnectedAndActive(UController_Type type,s32 mapping_slot){ bool ControllerPatcher::isControllerConnectedAndActive(UController_Type type,s32 mapping_slot) {
ControllerMappingPADInfo * padinfo = getControllerMappingInfo(type,mapping_slot); ControllerMappingPADInfo * padinfo = getControllerMappingInfo(type,mapping_slot);
if(!padinfo){ if(!padinfo) {
return false; return false;
} }
if(padinfo->active){ if(padinfo->active) {
DeviceInfo device_info; DeviceInfo device_info;
memset(&device_info,0,sizeof(device_info)); memset(&device_info,0,sizeof(device_info));
@ -687,7 +722,7 @@ bool ControllerPatcher::isControllerConnectedAndActive(UController_Type type,s32
device_info.vidpid = padinfo->vidpid; device_info.vidpid = padinfo->vidpid;
s32 res; s32 res;
if((res = ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info)) < 0){ if((res = ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info)) < 0) {
return false; return false;
} }
@ -697,7 +732,7 @@ bool ControllerPatcher::isControllerConnectedAndActive(UController_Type type,s32
HID_Data * data_cur; HID_Data * data_cur;
if((res = ControllerPatcherHID::getHIDData(hidmask,pad,&data_cur)) < 0) { if((res = ControllerPatcherHID::getHIDData(hidmask,pad,&data_cur)) < 0) {
return false; return false;
} }
return true; return true;
@ -705,32 +740,36 @@ bool ControllerPatcher::isControllerConnectedAndActive(UController_Type type,s32
return false; return false;
} }
ControllerMappingPADInfo * ControllerPatcher::getControllerMappingInfo(UController_Type type,s32 mapping_slot){ ControllerMappingPADInfo * ControllerPatcher::getControllerMappingInfo(UController_Type type,s32 mapping_slot) {
ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type); ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type);
if(cm_map_pad == NULL){return NULL;} if(cm_map_pad == NULL) {
return NULL;
}
if(mapping_slot < 0 || mapping_slot > HID_MAX_DEVICES_PER_SLOT-1){ return NULL;} if(mapping_slot < 0 || mapping_slot > HID_MAX_DEVICES_PER_SLOT-1) {
return NULL;
}
return &(cm_map_pad->pad_infos[mapping_slot]); return &(cm_map_pad->pad_infos[mapping_slot]);
} }
HID_Mouse_Data * ControllerPatcher::getMouseData(){ HID_Mouse_Data * ControllerPatcher::getMouseData() {
if(gHID_Mouse_Mode != HID_MOUSE_MODE_TOUCH) return NULL; if(gHID_Mouse_Mode != HID_MOUSE_MODE_TOUCH) return NULL;
ControllerMappingPAD * CMPAD = ControllerPatcherUtils::getControllerMappingByType(UController_Type_Gamepad); ControllerMappingPAD * CMPAD = ControllerPatcherUtils::getControllerMappingByType(UController_Type_Gamepad);
if(CMPAD == NULL){ if(CMPAD == NULL) {
return NULL; return NULL;
} }
HID_Mouse_Data * result = NULL; HID_Mouse_Data * result = NULL;
for(s32 i = 0;i<HID_MAX_DEVICES_PER_SLOT;i++){ for(s32 i = 0; i<HID_MAX_DEVICES_PER_SLOT; i++) {
ControllerMappingPADInfo * padinfo = &(CMPAD->pad_infos[i]); ControllerMappingPADInfo * padinfo = &(CMPAD->pad_infos[i]);
if(!padinfo->active){ if(!padinfo->active) {
break; break;
} }
if(padinfo->type == CM_Type_Mouse){ if(padinfo->type == CM_Type_Mouse) {
result = &(gHID_Devices[gMouseSlot].pad_data[padinfo->pad].data_union.mouse.cur_mouse_data); result = &(gHID_Devices[gMouseSlot].pad_data[padinfo->pad].data_union.mouse.cur_mouse_data);
DCFlushRange(&result,sizeof(result)); DCFlushRange(&result,sizeof(result));
DCInvalidateRange(&result,sizeof(result)); DCInvalidateRange(&result,sizeof(result));
@ -740,21 +779,23 @@ HID_Mouse_Data * ControllerPatcher::getMouseData(){
return result; return result;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setRumble(UController_Type type,u32 status){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setRumble(UController_Type type,u32 status) {
ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type); ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type);
if(cm_map_pad == NULL){return -1;} if(cm_map_pad == NULL) {
return -1;
}
cm_map_pad->rumble = !!status; //to make sure it's only 0 or 1. cm_map_pad->rumble = !!status; //to make sure it's only 0 or 1.
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::gettingInputAllDevices(InputData * output,s32 array_size){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::gettingInputAllDevices(InputData * output,s32 array_size) {
s32 hid = gHIDCurrentDevice; s32 hid = gHIDCurrentDevice;
HID_Data * data_cur; HID_Data * data_cur;
VPADStatus pad_buffer; VPADStatus pad_buffer;
VPADStatus * buffer = &pad_buffer; VPADStatus * buffer = &pad_buffer;
s32 result = CONTROLLER_PATCHER_ERROR_NONE; s32 result = CONTROLLER_PATCHER_ERROR_NONE;
for(s32 i = 0;i< gHIDMaxDevices;i++){ for(s32 i = 0; i< gHIDMaxDevices; i++) {
if((hid & (1 << i)) != 0){ if((hid & (1 << i)) != 0) {
memset(buffer,0,sizeof(*buffer)); memset(buffer,0,sizeof(*buffer));
s32 newhid = (1 << i); s32 newhid = (1 << i);
@ -769,9 +810,9 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::gettingInputAllDevices(Inp
deviceinfo->slotdata.deviceslot = deviceslot; deviceinfo->slotdata.deviceslot = deviceslot;
deviceinfo->slotdata.hidmask = newhid; deviceinfo->slotdata.hidmask = newhid;
if(newhid == gHID_LIST_MOUSE){ if(newhid == gHID_LIST_MOUSE) {
output[result].type = CM_Type_Mouse; output[result].type = CM_Type_Mouse;
} else if(newhid == gHID_LIST_KEYBOARD){ } else if(newhid == gHID_LIST_KEYBOARD) {
output[result].type = CM_Type_Keyboard; output[result].type = CM_Type_Keyboard;
} }
@ -787,15 +828,15 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::gettingInputAllDevices(Inp
s32 buttons_hold = 0; s32 buttons_hold = 0;
for(s32 pad = 0;pad<HID_MAX_PADS_COUNT;pad++){ for(s32 pad = 0; pad<HID_MAX_PADS_COUNT; pad++) {
buttons_hold = 0; buttons_hold = 0;
buttondata[pad].btn_h = 0; buttondata[pad].btn_h = 0;
buttondata[pad].btn_d = 0; buttondata[pad].btn_d = 0;
buttondata[pad].btn_r = 0; buttondata[pad].btn_r = 0;
s32 res; s32 res;
if((res = ControllerPatcherHID::getHIDData(deviceinfo->slotdata.hidmask,pad,&data_cur)) < 0){ if((res = ControllerPatcherHID::getHIDData(deviceinfo->slotdata.hidmask,pad,&data_cur)) < 0) {
continue; continue;
} }
res = ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_A); res = ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_A);
@ -828,7 +869,7 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::gettingInputAllDevices(Inp
} }
result++; result++;
if(result >= array_size){ if(result >= array_size) {
break; break;
} }
} }
@ -837,7 +878,7 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::gettingInputAllDevices(Inp
return result; return result;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setProControllerDataFromHID(void * data,s32 chan, s32 mode){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setProControllerDataFromHID(void * data,s32 chan, s32 mode) {
if(data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; if(data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
if(chan < 0 || chan > 3) return CONTROLLER_PATCHER_ERROR_INVALID_CHAN; if(chan < 0 || chan > 3) return CONTROLLER_PATCHER_ERROR_INVALID_CHAN;
//if(gControllerMapping.proController[chan].enabled == 0) return CONTROLLER_PATCHER_ERROR_MAPPING_DISABLED; //if(gControllerMapping.proController[chan].enabled == 0) return CONTROLLER_PATCHER_ERROR_MAPPING_DISABLED;
@ -847,9 +888,9 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setProControllerDataFromHI
std::vector<HID_Data *> data_list; std::vector<HID_Data *> data_list;
for(s32 i = 0;i<HID_MAX_DEVICES_PER_SLOT;i++){ for(s32 i = 0; i<HID_MAX_DEVICES_PER_SLOT; i++) {
ControllerMappingPADInfo cm_map_pad_info = gControllerMapping.proController[chan].pad_infos[i]; ControllerMappingPADInfo cm_map_pad_info = gControllerMapping.proController[chan].pad_infos[i];
if(!cm_map_pad_info.active){ if(!cm_map_pad_info.active) {
continue; continue;
} }
DeviceInfo device_info; DeviceInfo device_info;
@ -858,7 +899,7 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setProControllerDataFromHI
device_info.vidpid = cm_map_pad_info.vidpid; device_info.vidpid = cm_map_pad_info.vidpid;
s32 res; s32 res;
if((res = ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info)) < 0){ if((res = ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info)) < 0) {
DEBUG_FUNCTION_LINE("ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) = %d\n",res); DEBUG_FUNCTION_LINE("ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) = %d\n",res);
continue; continue;
} }
@ -875,7 +916,7 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setProControllerDataFromHI
data_list.push_back(data_cur); data_list.push_back(data_cur);
} }
if(data_list.empty()){ if(data_list.empty()) {
return CONTROLLER_PATCHER_ERROR_FAILED_TO_GET_HIDDATA; return CONTROLLER_PATCHER_ERROR_FAILED_TO_GET_HIDDATA;
} }
s32 res = 0; s32 res = 0;
@ -884,7 +925,7 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setProControllerDataFromHI
//ControllerPatcher::printVPADButtons(vpad_buffer); //Leads to random crashes on transitions. //ControllerPatcher::printVPADButtons(vpad_buffer); //Leads to random crashes on transitions.
//a bit hacky? //a bit hacky?
if(mode == PRO_CONTROLLER_MODE_KPADDATA){ if(mode == PRO_CONTROLLER_MODE_KPADDATA) {
KPADStatus * pro_buffer = (KPADStatus *) data; KPADStatus * pro_buffer = (KPADStatus *) data;
if((res = ControllerPatcherUtils::translateToPro(vpad_buffer,pro_buffer,&last_button_hold[chan])) < 0 ) return res; if((res = ControllerPatcherUtils::translateToPro(vpad_buffer,pro_buffer,&last_button_hold[chan])) < 0 ) return res;
} else if(mode == PRO_CONTROLLER_MODE_WPADReadData) { } else if(mode == PRO_CONTROLLER_MODE_WPADReadData) {
@ -899,7 +940,7 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setProControllerDataFromHI
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setControllerDataFromHID(VPADStatus * buffer){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setControllerDataFromHID(VPADStatus * buffer) {
if(buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; if(buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
//if(gControllerMapping.gamepad.enabled == 0) return CONTROLLER_PATCHER_ERROR_MAPPING_DISABLED; //if(gControllerMapping.gamepad.enabled == 0) return CONTROLLER_PATCHER_ERROR_MAPPING_DISABLED;
@ -911,15 +952,15 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setControllerDataFromHID(V
if (cm_map_pad.useAll == 1) { if (cm_map_pad.useAll == 1) {
data_list = ControllerPatcherHID::getHIDDataAll(); data_list = ControllerPatcherHID::getHIDDataAll();
}else{ } else {
for(s32 i = 0;i<HID_MAX_DEVICES_PER_SLOT;i++){ for(s32 i = 0; i<HID_MAX_DEVICES_PER_SLOT; i++) {
ControllerMappingPADInfo cm_map_pad_info = cm_map_pad.pad_infos[i]; ControllerMappingPADInfo cm_map_pad_info = cm_map_pad.pad_infos[i];
if(cm_map_pad_info.active){ if(cm_map_pad_info.active) {
DeviceInfo device_info; DeviceInfo device_info;
memset(&device_info,0,sizeof(device_info)); memset(&device_info,0,sizeof(device_info));
device_info.vidpid = cm_map_pad_info.vidpid; device_info.vidpid = cm_map_pad_info.vidpid;
if(ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) < 0){ if(ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) < 0) {
continue; continue;
//return CONTROLLER_PATCHER_ERROR_UNKNOWN_VID_PID; //return CONTROLLER_PATCHER_ERROR_UNKNOWN_VID_PID;
} }
@ -930,7 +971,7 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setControllerDataFromHID(V
pad = cm_map_pad_info.pad; pad = cm_map_pad_info.pad;
s32 res = ControllerPatcherHID::getHIDData(hidmask,pad,&data); s32 res = ControllerPatcherHID::getHIDData(hidmask,pad,&data);
if(res < 0){ if(res < 0) {
continue; continue;
//return CONTROLLER_PATCHER_ERROR_FAILED_TO_GET_HIDDATA; //return CONTROLLER_PATCHER_ERROR_FAILED_TO_GET_HIDDATA;
} }
@ -938,24 +979,24 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setControllerDataFromHID(V
} }
} }
} }
if(data_list.empty()){ if(data_list.empty()) {
return CONTROLLER_PATCHER_ERROR_FAILED_TO_GET_HIDDATA; return CONTROLLER_PATCHER_ERROR_FAILED_TO_GET_HIDDATA;
} }
ControllerPatcherHID::setVPADControllerData(buffer,data_list); ControllerPatcherHID::setVPADControllerData(buffer,data_list);
for(u32 i = 0; i < data_list.size();i++){ for(u32 i = 0; i < data_list.size(); i++) {
data_list[i]->rumbleActive = !!gControllerMapping.gamepad.rumble; data_list[i]->rumbleActive = !!gControllerMapping.gamepad.rumble;
} }
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::printVPADButtons(VPADStatus * buffer){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::printVPADButtons(VPADStatus * buffer) {
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
/* BROKEN on transitions.*/ /* BROKEN on transitions.*/
if(buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; if(buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
if(buffer->trigger != 0x00000000){ if(buffer->trigger != 0x00000000) {
char output[250]; char output[250];
output[0] = 0; //null terminate it. just in case. output[0] = 0; //null terminate it. just in case.
@ -987,15 +1028,15 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::printVPADButtons(VPADStatu
if((buffer->trigger & VPAD_STICK_L_EMULATION_UP) == VPAD_STICK_L_EMULATION_UP) strcat(output,"LE_Up "); 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 "); if((buffer->trigger & VPAD_STICK_L_EMULATION_DOWN) == VPAD_STICK_L_EMULATION_DOWN) strcat(output,"LE_Down ");
DEBUG_FUNCTION_LINE("%spressed Sticks: LX %f LY %f RX %f RY %f\n",output,buffer->lstick.x,buffer->lstick.y,buffer->rstick.x,buffer->rstick.y); DEBUG_FUNCTION_LINE("%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; return CONTROLLER_PATCHER_ERROR_NONE;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::buttonRemapping(VPADStatus * buffer,s32 buffer_count){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::buttonRemapping(VPADStatus * buffer,s32 buffer_count) {
if(!gButtonRemappingConfigDone) return CONTROLLER_PATCHER_ERROR_CONFIG_NOT_DONE; if(!gButtonRemappingConfigDone) return CONTROLLER_PATCHER_ERROR_CONFIG_NOT_DONE;
if(buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; if(buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
for(s32 i = 0;i < buffer_count;i++){ for(s32 i = 0; i < buffer_count; i++) {
VPADStatus new_data; VPADStatus new_data;
memset(&new_data,0,sizeof(new_data)); memset(&new_data,0,sizeof(new_data));
@ -1047,54 +1088,54 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::buttonRemapping(VPADStatus
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
std::string ControllerPatcher::getIdentifierByVIDPID(u16 vid,u16 pid){ std::string ControllerPatcher::getIdentifierByVIDPID(u16 vid,u16 pid) {
return ConfigValues::getStringByVIDPID(vid,pid); return ConfigValues::getStringByVIDPID(vid,pid);
} }
void ControllerPatcher::destroyConfigHelper(){ void ControllerPatcher::destroyConfigHelper() {
ConfigReader::destroyInstance(); ConfigReader::destroyInstance();
ConfigValues::destroyInstance(); ConfigValues::destroyInstance();
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::doSamplingForDeviceSlot(u16 device_slot){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::doSamplingForDeviceSlot(u16 device_slot) {
return ControllerPatcherUtils::doSampling(device_slot,0,true); return ControllerPatcherUtils::doSampling(device_slot,0,true);
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setRumbleActivated(bool value){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setRumbleActivated(bool value) {
gGlobalRumbleActivated = value; gGlobalRumbleActivated = value;
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setNetworkControllerActivated(bool value){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setNetworkControllerActivated(bool value) {
gNetworkControllerActivated = value; gNetworkControllerActivated = value;
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
bool ControllerPatcher::isRumbleActivated(){ bool ControllerPatcher::isRumbleActivated() {
return gGlobalRumbleActivated; return gGlobalRumbleActivated;
} }
bool ControllerPatcher::isButtonRemappingDone(){ bool ControllerPatcher::isButtonRemappingDone() {
return gButtonRemappingConfigDone; return gButtonRemappingConfigDone;
} }
bool ControllerPatcher::isKeyboardConnected(){ bool ControllerPatcher::isKeyboardConnected() {
return (gHIDCurrentDevice & gHID_LIST_KEYBOARD) == gHID_LIST_KEYBOARD; return (gHIDCurrentDevice & gHID_LIST_KEYBOARD) == gHID_LIST_KEYBOARD;
} }
bool ControllerPatcher::areControllersConnected(){ bool ControllerPatcher::areControllersConnected() {
return gHIDAttached > 0; return gHIDAttached > 0;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::sampleKeyboardData(){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::sampleKeyboardData() {
if(ControllerPatcher::isKeyboardConnected()){ if(ControllerPatcher::isKeyboardConnected()) {
ControllerPatcher::doSamplingForDeviceSlot(gHID_SLOT_KEYBOARD); ControllerPatcher::doSamplingForDeviceSlot(gHID_SLOT_KEYBOARD);
} }
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::resetCallbackData(){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::resetCallbackData() {
memset(gWPADConnectCallback,0,sizeof(gWPADConnectCallback)); memset(gWPADConnectCallback,0,sizeof(gWPADConnectCallback));
memset(gKPADConnectCallback,0,sizeof(gKPADConnectCallback)); memset(gKPADConnectCallback,0,sizeof(gKPADConnectCallback));
memset(gExtensionCallback,0,sizeof(gExtensionCallback)); memset(gExtensionCallback,0,sizeof(gExtensionCallback));
@ -1104,26 +1145,32 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::resetCallbackData(){
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setKPADConnectedCallback(s32 chan, wpad_connect_callback_t callback){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setKPADConnectedCallback(s32 chan, WPADConnectCallback callback) {
if(chan >= 4){ return CONTROLLER_PATCHER_ERROR_INVALID_CHAN; } if(chan >= 4) {
return CONTROLLER_PATCHER_ERROR_INVALID_CHAN;
}
gKPADConnectCallback[chan] = callback; gKPADConnectCallback[chan] = callback;
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setKPADExtensionCallback(s32 chan, wpad_connect_callback_t callback){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setKPADExtensionCallback(s32 chan, WPADConnectCallback callback) {
if(chan >= 4){ return CONTROLLER_PATCHER_ERROR_INVALID_CHAN; } if(chan >= 4) {
return CONTROLLER_PATCHER_ERROR_INVALID_CHAN;
}
gExtensionCallback[chan] = callback; gExtensionCallback[chan] = callback;
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setWPADConnectCallback(s32 chan, wpad_connect_callback_t callback){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setWPADConnectCallback(s32 chan, WPADConnectCallback callback) {
if(chan >= 4){ return CONTROLLER_PATCHER_ERROR_INVALID_CHAN; } if(chan >= 4) {
return CONTROLLER_PATCHER_ERROR_INVALID_CHAN;
}
gWPADConnectCallback[chan] = callback; gWPADConnectCallback[chan] = callback;
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::handleCallbackData(bool button_pressed){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::handleCallbackData(bool button_pressed) {
if(button_pressed && gCallbackCooldown == 0){ if(button_pressed && gCallbackCooldown == 0) {
gCallbackCooldown = 0xFF; gCallbackCooldown = 0xFF;
/*if(HID_DEBUG){ log_printf("my_VPADRead(line %d): Pressed the TV button. Maybe we can call the callbacks.!\n",__LINE__); } /*if(HID_DEBUG){ log_printf("my_VPADRead(line %d): Pressed the TV button. Maybe we can call the callbacks.!\n",__LINE__); }
@ -1131,32 +1178,38 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::handleCallbackData(bool bu
if(HID_DEBUG){ log_printf("my_VPADRead(line %d): gWPADConnectCallback = %08X %08X %08X %08X\n",__LINE__,gWPADConnectCallback[0],gWPADConnectCallback[1],gWPADConnectCallback[2],gWPADConnectCallback[3]); } if(HID_DEBUG){ log_printf("my_VPADRead(line %d): gWPADConnectCallback = %08X %08X %08X %08X\n",__LINE__,gWPADConnectCallback[0],gWPADConnectCallback[1],gWPADConnectCallback[2],gWPADConnectCallback[3]); }
if(HID_DEBUG){ log_printf("my_VPADRead(line %d): gKPADConnectCallback = %08X %08X %08X %08X\n",__LINE__,gKPADConnectCallback[0],gKPADConnectCallback[1],gKPADConnectCallback[2],gKPADConnectCallback[3]); }*/ if(HID_DEBUG){ log_printf("my_VPADRead(line %d): gKPADConnectCallback = %08X %08X %08X %08X\n",__LINE__,gKPADConnectCallback[0],gKPADConnectCallback[1],gKPADConnectCallback[2],gKPADConnectCallback[3]); }*/
for(s32 i = 0;i<4;i++){ if(ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro1)) {
bool doCall = false; ControllerPatcher::handleCallbackDataInternal(WPAD_CHAN_0);
if(i == 0){ doCall = ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro1); } }
if(i == 1){ doCall = ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro2); } if(ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro2)) {
if(i == 2){ doCall = ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro3); } ControllerPatcher::handleCallbackDataInternal(WPAD_CHAN_1);
if(i == 3){ doCall = ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro4); } }
if(doCall){ if(ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro3)) {
if(gWPADConnectCallback[i] != NULL){ ControllerPatcher::handleCallbackDataInternal(WPAD_CHAN_2);
log_printf("my_VPADRead(line %d): Called WPAD connect callback for pro controller in slot %d!\n",__LINE__,(i+1)); }
gWPADConnectCallback[i](i,0); if(ControllerPatcher::isControllerConnectedAndActive(UController_Type_Pro4)) {
} ControllerPatcher::handleCallbackDataInternal(WPAD_CHAN_3);
if(gKPADConnectCallback[i] != NULL){
log_printf("my_VPADRead(line %d): Called KPAD connect callback for pro controller in slot %d!\n",__LINE__,(i+1));
gKPADConnectCallback[i](i,0);
}
if(gExtensionCallback[i] != NULL){
log_printf("my_VPADRead(line %d): Called extension callback for pro controller in slot %d!\n",__LINE__,(i+1));
gExtensionCallback[i](i,WPAD_EXT_PRO_CONTROLLER);
}
}
} }
} }
if(gCallbackCooldown > 0){ if(gCallbackCooldown > 0) {
gCallbackCooldown--; gCallbackCooldown--;
} }
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::handleCallbackDataInternal(WPADChan chan) {
if(gWPADConnectCallback[chan] != NULL) {
log_printf("Called WPAD connect callback for pro controller in slot %d!\n",chan + 1);
gWPADConnectCallback[chan](chan,0);
}
if(gKPADConnectCallback[chan] != NULL) {
log_printf("Called KPAD connect callback for pro controller in slot %d!\n",chan + 1);
gKPADConnectCallback[chan](chan,0);
}
if(gExtensionCallback[chan] != NULL) {
log_printf("Called extension callback for pro controller in slot %d!\n",chan + 1);
gExtensionCallback[chan](chan,WPAD_EXT_PRO_CONTROLLER);
}
return CONTROLLER_PATCHER_ERROR_NONE;
}

View File

@ -21,18 +21,18 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
ConfigParser::ConfigParser(std::string configData){ ConfigParser::ConfigParser(std::string configData) {
this->content = configData; this->content = configData;
this->contentLines = StringTools::stringSplit(content, "\n"); this->contentLines = StringTools::stringSplit(content, "\n");
if(contentLines.empty()){ if(contentLines.empty()) {
return; return;
} }
//remove the comments and make everything uppercase //remove the comments and make everything uppercase
for(u32 i = 0; i < contentLines.size(); i++){ for(u32 i = 0; i < contentLines.size(); i++) {
std::vector<std::string> comments = StringTools::stringSplit(contentLines[i], "//"); std::vector<std::string> comments = StringTools::stringSplit(contentLines[i], "//");
if(!comments.empty()){ if(!comments.empty()) {
contentLines[i] = comments[0]; contentLines[i] = comments[0];
} }
//we want everything uppercase //we want everything uppercase
@ -41,78 +41,78 @@ ConfigParser::ConfigParser(std::string configData){
//remove empty lines //remove empty lines
std::vector<std::string> contentline2; std::vector<std::string> contentline2;
for(u32 i = 0; i < contentLines.size(); i++){ for(u32 i = 0; i < contentLines.size(); i++) {
if(strlen(contentLines[i].c_str()) > 0){ if(strlen(contentLines[i].c_str()) > 0) {
contentline2.push_back(contentLines[i]); contentline2.push_back(contentLines[i]);
} }
} }
contentLines = contentline2; contentLines = contentline2;
Init(); Init();
} }
ConfigParser::~ConfigParser(){ ConfigParser::~ConfigParser() {
} }
PARSE_TYPE ConfigParser::getType(){ PARSE_TYPE ConfigParser::getType() {
return type_b; return type_b;
} }
void ConfigParser::setType(PARSE_TYPE newType){ void ConfigParser::setType(PARSE_TYPE newType) {
this->type_b = newType; this->type_b = newType;
} }
u16 ConfigParser::getSlot(){ u16 ConfigParser::getSlot() {
return this->slot_b; return this->slot_b;
} }
void ConfigParser::setSlot(u16 newSlot){ void ConfigParser::setSlot(u16 newSlot) {
this->slot_b = newSlot; this->slot_b = newSlot;
} }
bool ConfigParser::Init(){ bool ConfigParser::Init() {
if(contentLines.size() == 0){ if(contentLines.size() == 0) {
DEBUG_FUNCTION_LINE("File seems to be empty. Make sure to have a proper header\n"); DEBUG_FUNCTION_LINE("File seems to be empty. Make sure to have a proper header\n");
return false; return false;
} }
const char * line = contentLines[0].c_str(); const char * line = contentLines[0].c_str();
s32 len = strlen(line); s32 len = strlen(line);
if(len <= 4){ if(len <= 4) {
DEBUG_FUNCTION_LINE("Header is too short.\n"); DEBUG_FUNCTION_LINE("Header is too short.\n");
return false; return false;
} }
std::string identify; std::string identify;
if(line[0] == '[' && line[len-1] == ']'){ if(line[0] == '[' && line[len-1] == ']') {
identify = contentLines[0].substr(1,len-2); identify = contentLines[0].substr(1,len-2);
}else{ } else {
DEBUG_FUNCTION_LINE("Not a proper config file!\n"); DEBUG_FUNCTION_LINE("Not a proper config file!\n");
return false; return false;
} }
if(identify.compare("GAMEPAD") == 0){ if(identify.compare("GAMEPAD") == 0) {
DEBUG_FUNCTION_LINE("Its a gamepad config file!\n"); DEBUG_FUNCTION_LINE("Its a gamepad config file!\n");
setSlot(gGamePadSlot); setSlot(gGamePadSlot);
setType(PARSE_GAMEPAD); setType(PARSE_GAMEPAD);
}else if(identify.compare("MOUSE") == 0){ } else if(identify.compare("MOUSE") == 0) {
DEBUG_FUNCTION_LINE("Its a mouse config file!\n"); DEBUG_FUNCTION_LINE("Its a mouse config file!\n");
setSlot(gMouseSlot); setSlot(gMouseSlot);
setType(PARSE_MOUSE); setType(PARSE_MOUSE);
this->vid = HID_MOUSE_VID; this->vid = HID_MOUSE_VID;
this->pid = HID_MOUSE_PID; this->pid = HID_MOUSE_PID;
}else if(identify.compare("KEYBOARD") == 0){ } else if(identify.compare("KEYBOARD") == 0) {
DEBUG_FUNCTION_LINE("Its a keyboard config file!\n"); DEBUG_FUNCTION_LINE("Its a keyboard config file!\n");
setSlot(gHID_SLOT_KEYBOARD); setSlot(gHID_SLOT_KEYBOARD);
setType(PARSE_KEYBOARD); setType(PARSE_KEYBOARD);
this->vid = HID_KEYBOARD_VID; this->vid = HID_KEYBOARD_VID;
this->pid = HID_KEYBOARD_PID; this->pid = HID_KEYBOARD_PID;
}else{ } else {
DEBUG_FUNCTION_LINE("Its a controller config file!\n"); DEBUG_FUNCTION_LINE("Its a controller config file!\n");
setSlot(getSlotController(identify)); setSlot(getSlotController(identify));
setType(PARSE_CONTROLLER); setType(PARSE_CONTROLLER);
} }
if(getSlot() == HID_INVALID_SLOT){ if(getSlot() == HID_INVALID_SLOT) {
return false; return false;
} }
@ -121,39 +121,54 @@ bool ConfigParser::Init(){
return true; return true;
} }
void ConfigParser::parseSingleLine(std::string line){ void ConfigParser::parseSingleLine(std::string line) {
if(line.empty()){DEBUG_FUNCTION_LINE("Can't parse line. it's empty\n"); return;} if(line.empty()) {
std::vector<std::string> cur_values = StringTools::stringSplit(line,"="); DEBUG_FUNCTION_LINE("Can't parse line. it's empty\n");
if(cur_values.size() != 2){
if(HID_DEBUG || cur_values.size() > 2){ DEBUG_FUNCTION_LINE("Not a valid key=pair line %s\n",line.c_str()); }
return; return;
}else{ }
std::vector<std::string> cur_values = StringTools::stringSplit(line,"=");
if(cur_values.size() != 2) {
if(HID_DEBUG || cur_values.size() > 2) {
DEBUG_FUNCTION_LINE("Not a valid key=pair line %s\n",line.c_str());
}
return;
} else {
u16 hid_slot = getSlot(); u16 hid_slot = getSlot();
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("leftpart = \"%s\" \n",cur_values[0].c_str()); } if(HID_DEBUG) {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("rightpart = \"%s\" \n",cur_values[1].c_str()); } DEBUG_FUNCTION_LINE("leftpart = \"%s\" \n",cur_values[0].c_str());
}
if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("rightpart = \"%s\" \n",cur_values[1].c_str());
}
s32 keyslot = -1; s32 keyslot = -1;
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Checking single value\n"); } if(HID_DEBUG) {
if(getType() == PARSE_GAMEPAD || getType() == PARSE_KEYBOARD){ DEBUG_FUNCTION_LINE("Checking single value\n");
}
if(getType() == PARSE_GAMEPAD || getType() == PARSE_KEYBOARD) {
keyslot = ConfigValues::getKeySlotGamePad(cur_values[0]); keyslot = ConfigValues::getKeySlotGamePad(cur_values[0]);
}else if(getType() == PARSE_MOUSE){ } else if(getType() == PARSE_MOUSE) {
keyslot = ConfigValues::getKeySlotMouse(cur_values[0]); keyslot = ConfigValues::getKeySlotMouse(cur_values[0]);
}else{ } else {
keyslot = ConfigValues::getKeySlotDefaultSingleValue(cur_values[0]); keyslot = ConfigValues::getKeySlotDefaultSingleValue(cur_values[0]);
} }
if(keyslot != -1){ if(keyslot != -1) {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Its a single value\n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Its a single value\n");
}
long rightValue = -1; long rightValue = -1;
bool valueSet = false; bool valueSet = false;
if(cur_values[0].compare("DPAD_MODE") == 0){ if(cur_values[0].compare("DPAD_MODE") == 0) {
const u8 * values_ = NULL; const u8 * values_ = NULL;
if((values_ = ConfigValues::getValuesStickPreset(cur_values[1])) != NULL){ if((values_ = ConfigValues::getValuesStickPreset(cur_values[1])) != NULL) {
if(values_[STICK_CONF_MAGIC_VERSION] != STICK_CONF_MAGIC_VALUE) if(values_[STICK_CONF_MAGIC_VERSION] != STICK_CONF_MAGIC_VALUE)
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Settings preset DPAD MODE and Mask\n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Settings preset DPAD MODE and Mask\n");
}
config_controller[hid_slot][CONTRPS_DPAD_MODE][0] = CONTROLLER_PATCHER_VALUE_SET; config_controller[hid_slot][CONTRPS_DPAD_MODE][0] = CONTROLLER_PATCHER_VALUE_SET;
config_controller[hid_slot][CONTRPS_DPAD_MODE][1] = values_[CONTRDPAD_MODE]; config_controller[hid_slot][CONTRPS_DPAD_MODE][1] = values_[CONTRDPAD_MODE];
if(values_[CONTRDPAD_MASK] != 0x00){ if(values_[CONTRDPAD_MASK] != 0x00) {
config_controller[hid_slot][CONTRPS_DPAD_MASK][0] = CONTROLLER_PATCHER_VALUE_SET; config_controller[hid_slot][CONTRPS_DPAD_MASK][0] = CONTROLLER_PATCHER_VALUE_SET;
config_controller[hid_slot][CONTRPS_DPAD_MASK][1] = values_[CONTRDPAD_MASK]; config_controller[hid_slot][CONTRPS_DPAD_MASK][1] = values_[CONTRDPAD_MASK];
} }
@ -161,47 +176,63 @@ void ConfigParser::parseSingleLine(std::string line){
} }
} }
if(!valueSet){ if(!valueSet) {
if(getType() == PARSE_KEYBOARD){ if(getType() == PARSE_KEYBOARD) {
if((rightValue = ConfigValues::getPresetValuesKeyboard(cur_values[1]))!= -1){ if((rightValue = ConfigValues::getPresetValuesKeyboard(cur_values[1]))!= -1) {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Used pre-defined Keyboard! \"%s\" is %d\n",cur_values[1].c_str(),rightValue);} if(HID_DEBUG) {
}else{ DEBUG_FUNCTION_LINE("Used pre-defined Keyboard! \"%s\" is %d\n",cur_values[1].c_str(),rightValue);
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("I need to parse %s\n",cur_values[1].c_str()); } }
} else {
if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("I need to parse %s\n",cur_values[1].c_str());
}
char * ptr; char * ptr;
rightValue = strtol(cur_values[1].c_str(),&ptr,16); rightValue = strtol(cur_values[1].c_str(),&ptr,16);
} }
}else{ } else {
rightValue = ConfigValues::getPresetValue(cur_values[1]); rightValue = ConfigValues::getPresetValue(cur_values[1]);
if(getType() == PARSE_MOUSE){ //No parsing for the mouse if(getType() == PARSE_MOUSE) { //No parsing for the mouse
if(rightValue == -1){ if(rightValue == -1) {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Invalid mouse value, lets skip it %s\n",cur_values[1].c_str()); } if(HID_DEBUG) {
return; DEBUG_FUNCTION_LINE("Invalid mouse value, lets skip it %s\n",cur_values[1].c_str());
} }
}else{ return;
if(rightValue == -1){ }
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("I need to parse %s\n",cur_values[1].c_str()); } } else {
if(rightValue == -1) {
if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("I need to parse %s\n",cur_values[1].c_str());
}
char * ptr; char * ptr;
rightValue = strtol(cur_values[1].c_str(),&ptr,16); rightValue = strtol(cur_values[1].c_str(),&ptr,16);
} }
} }
} }
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Setting value to %d\n",rightValue); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Setting value to %d\n",rightValue);
}
config_controller[hid_slot][keyslot][0] = CONTROLLER_PATCHER_VALUE_SET; config_controller[hid_slot][keyslot][0] = CONTROLLER_PATCHER_VALUE_SET;
config_controller[hid_slot][keyslot][1] = rightValue; config_controller[hid_slot][keyslot][1] = rightValue;
} }
}else{ } else {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Check pair value\n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Check pair value\n");
}
keyslot = ConfigValues::getKeySlotDefaultPairedValue(cur_values[0]); keyslot = ConfigValues::getKeySlotDefaultPairedValue(cur_values[0]);
if(keyslot != -1){ if(keyslot != -1) {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Its a pair value\n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Its a pair value\n");
}
if(!ConfigValues::getInstance()->setIfValueIsAControllerPreset(cur_values[1],getSlot(),keyslot)){ if(!ConfigValues::getInstance()->setIfValueIsAControllerPreset(cur_values[1],getSlot(),keyslot)) {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("And its no preset\n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("And its no preset\n");
}
std::vector<std::string> rightvalues = StringTools::stringSplit(cur_values[1],","); std::vector<std::string> rightvalues = StringTools::stringSplit(cur_values[1],",");
if(rightvalues.size() != 2){ if(rightvalues.size() != 2) {
DEBUG_FUNCTION_LINE("%d instead of 2 key=values pairs in line\n",rightvalues.size()); DEBUG_FUNCTION_LINE("%d instead of 2 key=values pairs in line\n",rightvalues.size());
return; return;
} }
@ -212,43 +243,49 @@ void ConfigParser::parseSingleLine(std::string line){
config_controller[hid_slot][keyslot][0] = firstValue; config_controller[hid_slot][keyslot][0] = firstValue;
config_controller[hid_slot][keyslot][1] = secondValue; config_controller[hid_slot][keyslot][1] = secondValue;
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Set %02X,%02X\n",firstValue,secondValue); } if(HID_DEBUG) {
}else{ DEBUG_FUNCTION_LINE("Set %02X,%02X\n",firstValue,secondValue);
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Found preset value!!\n"); } }
} else {
if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Found preset value!!\n");
}
} }
}else{ } else {
DEBUG_FUNCTION_LINE("The setting \"%s\" is unknown!\n",cur_values[0].c_str()); DEBUG_FUNCTION_LINE("The setting \"%s\" is unknown!\n",cur_values[0].c_str());
} }
} }
} }
} }
bool ConfigParser::resetConfig(){ bool ConfigParser::resetConfig() {
s32 slot = getSlot(); s32 slot = getSlot();
if((slot == HID_INVALID_SLOT) || (slot >= gHIDMaxDevices)) return false; if((slot == HID_INVALID_SLOT) || (slot >= gHIDMaxDevices)) return false;
for(s32 j = (CONTRPS_PID+1);j< CONTRPS_MAX_VALUE;j++){ for(s32 j = (CONTRPS_PID+1); j< CONTRPS_MAX_VALUE; j++) {
config_controller[slot][j][0] = CONTROLLER_PATCHER_INVALIDVALUE; config_controller[slot][j][0] = CONTROLLER_PATCHER_INVALIDVALUE;
config_controller[slot][j][1] = CONTROLLER_PATCHER_INVALIDVALUE; config_controller[slot][j][1] = CONTROLLER_PATCHER_INVALIDVALUE;
} }
return true; return true;
} }
s32 ConfigParser::getSlotController(std::string identify){ s32 ConfigParser::getSlotController(std::string identify) {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Getting Controller Slot\n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Getting Controller Slot\n");
}
std::vector<std::string> values = StringTools::stringSplit(identify,","); std::vector<std::string> values = StringTools::stringSplit(identify,",");
if(values.size() != 2){ if(values.size() != 2) {
DEBUG_FUNCTION_LINE("You need to provide a VID and PID. e.g. \"[vid=0x451,pid=0x152]\". (%s)\n",identify.c_str()); DEBUG_FUNCTION_LINE("You need to provide a VID and PID. e.g. \"[vid=0x451,pid=0x152]\". (%s)\n",identify.c_str());
return HID_INVALID_SLOT; return HID_INVALID_SLOT;
} }
s32 vid = getValueFromKeyValue(values[0],"VID","="); s32 vid = getValueFromKeyValue(values[0],"VID","=");
if(vid < 0){ if(vid < 0) {
return HID_INVALID_SLOT; return HID_INVALID_SLOT;
} }
s32 pid = getValueFromKeyValue(values[1],"PID","="); s32 pid = getValueFromKeyValue(values[1],"PID","=");
if(pid < 0){ if(pid < 0) {
return HID_INVALID_SLOT; return HID_INVALID_SLOT;
} }
DEBUG_FUNCTION_LINE("VID: %04x PID: %04x\n",vid,pid); DEBUG_FUNCTION_LINE("VID: %04x PID: %04x\n",vid,pid);
@ -262,8 +299,10 @@ s32 ConfigParser::getSlotController(std::string identify){
s32 result = ControllerPatcherUtils::getDeviceInfoFromVidPid(&deviceinfo); s32 result = ControllerPatcherUtils::getDeviceInfoFromVidPid(&deviceinfo);
s32 slot = deviceinfo.slotdata.deviceslot; s32 slot = deviceinfo.slotdata.deviceslot;
s32 hid = 0; s32 hid = 0;
if(result < 0){ if(result < 0) {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Its a new controller, lets save it\n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Its a new controller, lets save it\n");
}
HIDSlotData slotdata; HIDSlotData slotdata;
ControllerPatcherUtils::getNextSlotData(&slotdata); ControllerPatcherUtils::getNextSlotData(&slotdata);
@ -271,30 +310,37 @@ s32 ConfigParser::getSlotController(std::string identify){
slot = slotdata.deviceslot; slot = slotdata.deviceslot;
hid = slotdata.hidmask; hid = slotdata.hidmask;
if(slot >= gHIDMaxDevices){ if(slot >= gHIDMaxDevices) {
DEBUG_FUNCTION_LINE("We don't a space for a new controller, please delete .inis\n"); DEBUG_FUNCTION_LINE("We don't a space for a new controller, please delete .inis\n");
return HID_INVALID_SLOT; return HID_INVALID_SLOT;
} }
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Got new slot! slot: %d hid %s .. Lets registrate it!\n",slot,StringTools::byte_to_binary(hid)); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Got new slot! slot: %d hid %s .. Lets registrate it!\n",slot,StringTools::byte_to_binary(hid));
}
config_controller[slot][CONTRPS_VID][0] = (vid & 0xFF00) >> 8; config_controller[slot][CONTRPS_VID][0] = (vid & 0xFF00) >> 8;
config_controller[slot][CONTRPS_VID][1] = (vid & 0x00FF); config_controller[slot][CONTRPS_VID][1] = (vid & 0x00FF);
config_controller[slot][CONTRPS_PID][0] = (pid & 0xFF00) >> 8; config_controller[slot][CONTRPS_PID][0] = (pid & 0xFF00) >> 8;
config_controller[slot][CONTRPS_PID][1] = (pid & 0x00FF); config_controller[slot][CONTRPS_PID][1] = (pid & 0x00FF);
if(HID_DEBUG){ if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Saved vid: %04X pid: %04X\n", DEBUG_FUNCTION_LINE("Saved vid: %04X pid: %04X\n",
config_controller[slot][CONTRPS_VID][0] * 0x100 + config_controller[slot][CONTRPS_VID][1], 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[slot][CONTRPS_PID][0] * 0x100 + config_controller[slot][CONTRPS_PID][1]);
}
config_controller_hidmask[slot] = hid; config_controller_hidmask[slot] = hid;
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Saved the hid\n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Saved the hid\n");
}
}else{ } else {
if(slot < gHIDMaxDevices){ if(slot < gHIDMaxDevices) {
hid = config_controller_hidmask[slot]; hid = config_controller_hidmask[slot];
if(HID_DEBUG){ DEBUG_FUNCTION_LINE(">>>>>> found slot %d (hid:%s). Modifing existing data <<<<<<<<\n",slot,StringTools::byte_to_binary(hid)); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE(">>>>>> found slot %d (hid:%s). Modifing existing data <<<<<<<<\n",slot,StringTools::byte_to_binary(hid));
}
DEBUG_FUNCTION_LINE("We already have data of this controller, lets modify it\n"); DEBUG_FUNCTION_LINE("We already have data of this controller, lets modify it\n");
}else{ } else {
DEBUG_FUNCTION_LINE("Something really odd happend to the slots. %d is bigger then max (%d)\n",slot,gHIDMaxDevices); DEBUG_FUNCTION_LINE("Something really odd happend to the slots. %d is bigger then max (%d)\n",slot,gHIDMaxDevices);
return HID_INVALID_SLOT; return HID_INVALID_SLOT;
} }
@ -304,42 +350,50 @@ s32 ConfigParser::getSlotController(std::string identify){
return slot; return slot;
} }
bool ConfigParser::parseIni(){ bool ConfigParser::parseIni() {
if(getSlot() == HID_INVALID_SLOT){ if(getSlot() == HID_INVALID_SLOT) {
DEBUG_FUNCTION_LINE("Couldn't parse file. Not a valid slot. Probably broken config. Or you tried to have more than %d devices\n",getType(),gHIDMaxDevices); DEBUG_FUNCTION_LINE("Couldn't parse file. Not a valid slot. Probably broken config. Or you tried to have more than %d devices\n",getType(),gHIDMaxDevices);
return false; return false;
} }
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Parsing content, type %d\n",getType()); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Parsing content, type %d\n",getType());
}
s32 start = 1; s32 start = 1;
if(contentLines.size() <= 1){ if(contentLines.size() <= 1) {
DEBUG_FUNCTION_LINE("File only contains a header.\n"); DEBUG_FUNCTION_LINE("File only contains a header.\n");
return false; return false;
} }
if(contentLines[1].compare("[IGNOREDEFAULT]") == 0){ if(contentLines[1].compare("[IGNOREDEFAULT]") == 0) {
resetConfig(); resetConfig();
DEBUG_FUNCTION_LINE("Ignoring existing settings of this device\n"); DEBUG_FUNCTION_LINE("Ignoring existing settings of this device\n");
start++; start++;
} }
for(u32 i = start; i < contentLines.size(); i++){ for(u32 i = start; i < contentLines.size(); i++) {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("line %d: \"%s\" \n",(i+1),contentLines[i].c_str()); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("line %d: \"%s\" \n",(i+1),contentLines[i].c_str());
}
parseSingleLine(contentLines[i]); parseSingleLine(contentLines[i]);
} }
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Parsing of the file is done.\n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Parsing of the file is done.\n");
}
return true; return true;
} }
s32 ConfigParser::getValueFromKeyValue(std::string value_pair,std::string expectedKey,std::string delimiter){ s32 ConfigParser::getValueFromKeyValue(std::string value_pair,std::string expectedKey,std::string delimiter) {
std::vector<std::string> string_value = StringTools::stringSplit(value_pair,delimiter); std::vector<std::string> string_value = StringTools::stringSplit(value_pair,delimiter);
if(string_value.size() != 2){ if(string_value.size() != 2) {
if(HID_DEBUG || string_value.size() > 2){ DEBUG_FUNCTION_LINE("Not a valid key=pair line %s\n",value_pair.c_str()); } if(HID_DEBUG || string_value.size() > 2) {
DEBUG_FUNCTION_LINE("Not a valid key=pair line %s\n",value_pair.c_str());
}
return -1; return -1;
} }
if(string_value[0].compare(expectedKey) != 0){ if(string_value[0].compare(expectedKey) != 0) {
DEBUG_FUNCTION_LINE("Key part not %s, its %s",expectedKey.c_str(),string_value[0].c_str()); DEBUG_FUNCTION_LINE("Key part not %s, its %s",expectedKey.c_str(),string_value[0].c_str());
return -1; return -1;
} }

View File

@ -23,24 +23,26 @@
ConfigValues *ConfigValues::instance = NULL; ConfigValues *ConfigValues::instance = NULL;
ConfigValues::ConfigValues(){ ConfigValues::ConfigValues() {
InitValues(); InitValues();
} }
ConfigValues::~ConfigValues(){ ConfigValues::~ConfigValues() {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("\n");} if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("\n");
}
} }
const u8 * ConfigValues::getValuesForPreset(std::map<std::string,const u8*> values,std::string possibleValue){ const u8 * ConfigValues::getValuesForPreset(std::map<std::string,const u8*> values,std::string possibleValue) {
std::map<std::string,const u8*>::iterator it; std::map<std::string,const u8*>::iterator it;
it = values.find(possibleValue); it = values.find(possibleValue);
if (it != values.end()){ if (it != values.end()) {
return it->second; return it->second;
} }
return NULL; return NULL;
} }
bool ConfigValues::setIfValueIsAControllerPresetEx(std::string value,s32 slot,s32 keyslot){ bool ConfigValues::setIfValueIsAControllerPresetEx(std::string value,s32 slot,s32 keyslot) {
if(setIfValueIsPreset(presetGCValues,value,slot,keyslot)) return true; if(setIfValueIsPreset(presetGCValues,value,slot,keyslot)) return true;
if(setIfValueIsPreset(presetDS3Values,value,slot,keyslot)) return true; if(setIfValueIsPreset(presetDS3Values,value,slot,keyslot)) return true;
if(setIfValueIsPreset(presetDS4Values,value,slot,keyslot)) return true; if(setIfValueIsPreset(presetDS4Values,value,slot,keyslot)) return true;
@ -50,18 +52,22 @@ bool ConfigValues::setIfValueIsAControllerPresetEx(std::string value,s32 slot,s3
} }
//We need this function here so we can use preset sticks. //We need this function here so we can use preset sticks.
bool ConfigValues::setIfValueIsPreset(std::map<std::string,const u8*> values,std::string possibleValue,s32 slot,s32 keyslot){ bool ConfigValues::setIfValueIsPreset(std::map<std::string,const u8*> values,std::string possibleValue,s32 slot,s32 keyslot) {
if(slot > gHIDMaxDevices || slot < 0 || keyslot < 0 || keyslot >= CONTRPS_MAX_VALUE){ if(slot > gHIDMaxDevices || slot < 0 || keyslot < 0 || keyslot >= CONTRPS_MAX_VALUE) {
return false; return false;
} }
const u8 * values_ = NULL; const u8 * values_ = NULL;
if( keyslot == CONTRPS_VPAD_BUTTON_L_STICK_X || if( keyslot == CONTRPS_VPAD_BUTTON_L_STICK_X ||
keyslot == CONTRPS_VPAD_BUTTON_L_STICK_Y || keyslot == CONTRPS_VPAD_BUTTON_L_STICK_Y ||
keyslot == CONTRPS_VPAD_BUTTON_R_STICK_X || keyslot == CONTRPS_VPAD_BUTTON_R_STICK_X ||
keyslot == CONTRPS_VPAD_BUTTON_R_STICK_Y){ keyslot == CONTRPS_VPAD_BUTTON_R_STICK_Y) {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("This may be a predefined stick %s\n",possibleValue.c_str());} if(HID_DEBUG) {
if((values_ = ConfigValues::getValuesStickPreset(possibleValue)) != NULL){ DEBUG_FUNCTION_LINE("This may be a predefined stick %s\n",possibleValue.c_str());
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Found predefined stick!\n");} }
if((values_ = ConfigValues::getValuesStickPreset(possibleValue)) != NULL) {
if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Found predefined stick!\n");
}
config_controller[slot][keyslot][0] = values_[STICK_CONF_BYTE]; //CONTRPS_VPAD_BUTTON_L_STICK_X 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][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][0] = CONTROLLER_PATCHER_VALUE_SET; //CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT
@ -75,7 +81,7 @@ bool ConfigValues::setIfValueIsPreset(std::map<std::string,const u8*> values,std
} }
} }
if((values_ = getValuesForPreset(values,possibleValue)) != NULL){ if((values_ = getValuesForPreset(values,possibleValue)) != NULL) {
config_controller[slot][keyslot][0] = values_[0]; config_controller[slot][keyslot][0] = values_[0];
config_controller[slot][keyslot][1] = values_[1]; config_controller[slot][keyslot][1] = values_[1];
return true; return true;
@ -84,39 +90,43 @@ bool ConfigValues::setIfValueIsPreset(std::map<std::string,const u8*> values,std
} }
s32 ConfigValues::getValueFromMap(std::map<std::string,int> values,std::string nameOfString){ s32 ConfigValues::getValueFromMap(std::map<std::string,int> values,std::string nameOfString) {
std::map<std::string,int>::iterator it; std::map<std::string,int>::iterator it;
it = values.find(nameOfString); it = values.find(nameOfString);
if (it != values.end()){ if (it != values.end()) {
return it->second; return it->second;
} }
//Value not found //Value not found
return -1; return -1;
} }
s32 ConfigValues::getPresetValueEx(std::string possibleString){ s32 ConfigValues::getPresetValueEx(std::string possibleString) {
s32 rightValue = -1; s32 rightValue = -1;
if((rightValue = getValueFromMap(gGamePadValuesToCONTRPSString,possibleString))!= -1){ if((rightValue = getValueFromMap(gGamePadValuesToCONTRPSString,possibleString))!= -1) {
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Used pre-defined VPAD_VALUE! \"%s\" is %d\n",possibleString.c_str(),rightValue); } if(HID_DEBUG) {
}else if((rightValue = getValueFromMap(presetValues,possibleString))!= -1){ DEBUG_FUNCTION_LINE("Used pre-defined VPAD_VALUE! \"%s\" is %d\n",possibleString.c_str(),rightValue);
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Used pre-defined value! \"%s\" is %d\n",possibleString.c_str(),rightValue); } }
} else if((rightValue = getValueFromMap(presetValues,possibleString))!= -1) {
if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Used pre-defined value! \"%s\" is %d\n",possibleString.c_str(),rightValue);
}
} }
return rightValue; return rightValue;
} }
void ConfigValues::addDeviceNameEx(u16 vid,u16 pid,std::string value){ void ConfigValues::addDeviceNameEx(u16 vid,u16 pid,std::string value) {
deviceNames[StringTools::strfmt("%04X%04X",vid,pid).c_str()] = value; deviceNames[StringTools::strfmt("%04X%04X",vid,pid).c_str()] = value;
} }
std::string ConfigValues::getStringByVIDPIDEx(u16 vid,u16 pid){ std::string ConfigValues::getStringByVIDPIDEx(u16 vid,u16 pid) {
std::string result = ""; std::string result = "";
std::map<std::string,std::string>::iterator it; std::map<std::string,std::string>::iterator it;
it = deviceNames.find(StringTools::strfmt("%04X%04X",vid,pid)); it = deviceNames.find(StringTools::strfmt("%04X%04X",vid,pid));
if (it != deviceNames.end()){ if (it != deviceNames.end()) {
result = it->second; result = it->second;
}else{ } else {
result = StringTools::strfmt("VID: 0x%04X\nPID: 0x%04X",vid,pid); result = StringTools::strfmt("VID: 0x%04X\nPID: 0x%04X",vid,pid);
} }
return result; return result;

View File

@ -46,12 +46,12 @@
#define DEFAULT_TCP_PORT 8112 #define DEFAULT_TCP_PORT 8112
class CPTCPServer: TCPServer{ class CPTCPServer: TCPServer {
friend class ControllerPatcher; friend class ControllerPatcher;
private: private:
static CPTCPServer *getInstance() { static CPTCPServer *getInstance() {
if(!instance){ if(!instance) {
instance = new CPTCPServer(DEFAULT_TCP_PORT); instance = new CPTCPServer(DEFAULT_TCP_PORT);
} }
@ -59,19 +59,19 @@ private:
} }
static void destroyInstance() { static void destroyInstance() {
if(instance){ if(instance) {
delete instance; delete instance;
instance = NULL; instance = NULL;
} }
} }
static s32 getPriority(){ static s32 getPriority() {
s32 priority = 28; s32 priority = 28;
if(OSGetTitleID() == 0x00050000101c9300 || //The Legend of Zelda Breath of the Wild JPN if(OSGetTitleID() == 0x00050000101c9300 || //The Legend of Zelda Breath of the Wild JPN
OSGetTitleID() == 0x00050000101c9400 || //The Legend of Zelda Breath of the Wild USA OSGetTitleID() == 0x00050000101c9400 || //The Legend of Zelda Breath of the Wild USA
OSGetTitleID() == 0x00050000101c9500 || //The Legend of Zelda Breath of the Wild EUR OSGetTitleID() == 0x00050000101c9500 || //The Legend of Zelda Breath of the Wild EUR
OSGetTitleID() == 0x00050000101c9b00 || //The Binding of Isaac: Rebirth EUR OSGetTitleID() == 0x00050000101c9b00 || //The Binding of Isaac: Rebirth EUR
OSGetTitleID() == 0x00050000101a3c00){ //The Binding of Isaac: Rebirth USA OSGetTitleID() == 0x00050000101a3c00) { //The Binding of Isaac: Rebirth USA
priority = 10; priority = 10;
DEBUG_FUNCTION_LINE("This game needs higher thread priority. We set it to %d\n",priority); DEBUG_FUNCTION_LINE("This game needs higher thread priority. We set it to %d\n",priority);
} }

View File

@ -24,33 +24,34 @@
UDPClient * UDPClient::instance = NULL; UDPClient * UDPClient::instance = NULL;
UDPClient::UDPClient(u32 ip, s32 port){ UDPClient::UDPClient(u32 ip, s32 port) {
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sockfd < 0) if (sockfd < 0)
return; return;
struct sockaddr_in connect_addr; struct sockaddr_in connect_addr;
memset(&connect_addr, 0, sizeof(connect_addr)); memset(&connect_addr, 0, sizeof(connect_addr));
connect_addr.sin_family = AF_INET; connect_addr.sin_family = AF_INET;
connect_addr.sin_port = port; connect_addr.sin_port = port;
connect_addr.sin_addr.s_addr = ip; connect_addr.sin_addr.s_addr = ip;
if(connect(sockfd, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0) if(connect(sockfd, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0) {
{ socketclose(sockfd);
socketclose(sockfd); sockfd = -1;
sockfd = -1; }
}
} }
UDPClient::~UDPClient(){ UDPClient::~UDPClient() {
if (this->sockfd != -1){ if (this->sockfd != -1) {
socketclose(sockfd); socketclose(sockfd);
} }
if(HID_DEBUG){ log_printf("UDPClient::~UDPClient(line %d): Thread has been closed\n",__LINE__); } if(HID_DEBUG) {
log_printf("UDPClient::~UDPClient(line %d): Thread has been closed\n",__LINE__);
}
} }
bool UDPClient::sendData(char * data,s32 length){ bool UDPClient::sendData(char * data,s32 length) {
if(sockfd < 0 || data == 0 || length < 0 || gUsedProtocolVersion < WIIU_CP_TCP_HANDSHAKE_VERSION_3){ if(sockfd < 0 || data == 0 || length < 0 || gUsedProtocolVersion < WIIU_CP_TCP_HANDSHAKE_VERSION_3) {
return false; return false;
} }
if(length > 1400) length = 1400; if(length > 1400) length = 1400;

View File

@ -21,7 +21,7 @@
#define DEFAULT_UDP_CLIENT_PORT 8114 #define DEFAULT_UDP_CLIENT_PORT 8114
class UDPClient{ class UDPClient {
friend class ControllerPatcher; friend class ControllerPatcher;
friend class ControllerPatcherHID; friend class ControllerPatcherHID;
friend class CPTCPServer; friend class CPTCPServer;
@ -29,7 +29,7 @@ public:
private: private:
static UDPClient *getInstance() { static UDPClient *getInstance() {
if(instance == NULL){ if(instance == NULL) {
createInstance(); createInstance();
} }
return instance; return instance;
@ -37,7 +37,7 @@ private:
static UDPClient *createInstance() { static UDPClient *createInstance() {
if(instance != NULL){ if(instance != NULL) {
destroyInstance(); destroyInstance();
} }
instance = new UDPClient(gUDPClientip,DEFAULT_UDP_CLIENT_PORT); instance = new UDPClient(gUDPClientip,DEFAULT_UDP_CLIENT_PORT);
@ -46,7 +46,7 @@ private:
} }
static void destroyInstance() { static void destroyInstance() {
if(instance != NULL){ if(instance != NULL) {
delete instance; delete instance;
instance = NULL; instance = NULL;
} }

View File

@ -26,9 +26,9 @@
CThread * UDPServer::pThread = NULL; CThread * UDPServer::pThread = NULL;
UDPServer * UDPServer::instance = NULL; UDPServer * UDPServer::instance = NULL;
UDPServer::UDPServer(s32 port){ UDPServer::UDPServer(s32 port) {
s32 ret; s32 ret;
struct sockaddr_in addr; struct sockaddr_in addr;
addr.sin_family = AF_INET; addr.sin_family = AF_INET;
addr.sin_port = port; addr.sin_port = port;
@ -44,31 +44,33 @@ UDPServer::UDPServer(s32 port){
StartUDPThread(this); StartUDPThread(this);
} }
UDPServer::~UDPServer(){ UDPServer::~UDPServer() {
CThread * pThreadPointer = UDPServer::pThread; CThread * pThreadPointer = UDPServer::pThread;
if(pThreadPointer != NULL){ if(pThreadPointer != NULL) {
exitThread = 1; exitThread = 1;
if(pThreadPointer != NULL){ if(pThreadPointer != NULL) {
delete pThreadPointer; delete pThreadPointer;
UDPServer::pThread = NULL; UDPServer::pThread = NULL;
if (this->sockfd != -1){ if (this->sockfd != -1) {
socketclose(sockfd); socketclose(sockfd);
} }
this->sockfd = -1; this->sockfd = -1;
} }
} }
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Thread has been closed\n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Thread has been closed\n");
}
} }
void UDPServer::StartUDPThread(UDPServer * server){ void UDPServer::StartUDPThread(UDPServer * server) {
s32 priority = 28; s32 priority = 28;
if(OSGetTitleID() == 0x00050000101c9300 || //The Legend of Zelda Breath of the Wild JPN if(OSGetTitleID() == 0x00050000101c9300 || //The Legend of Zelda Breath of the Wild JPN
OSGetTitleID() == 0x00050000101c9400 || //The Legend of Zelda Breath of the Wild USA OSGetTitleID() == 0x00050000101c9400 || //The Legend of Zelda Breath of the Wild USA
OSGetTitleID() == 0x00050000101c9500 || //The Legend of Zelda Breath of the Wild EUR OSGetTitleID() == 0x00050000101c9500 || //The Legend of Zelda Breath of the Wild EUR
OSGetTitleID() == 0x00050000101c9b00 || //The Binding of Isaac: Rebirth EUR OSGetTitleID() == 0x00050000101c9b00 || //The Binding of Isaac: Rebirth EUR
OSGetTitleID() == 0x00050000101a3c00){ //The Binding of Isaac: Rebirth USA OSGetTitleID() == 0x00050000101a3c00) { //The Binding of Isaac: Rebirth USA
priority = 10; priority = 10;
DEBUG_FUNCTION_LINE("This game needs higher thread priority. We set it to %d\n",priority); DEBUG_FUNCTION_LINE("This game needs higher thread priority. We set it to %d\n",priority);
} }
@ -76,8 +78,8 @@ void UDPServer::StartUDPThread(UDPServer * server){
UDPServer::pThread->resumeThread(); UDPServer::pThread->resumeThread();
} }
bool UDPServer::cpyIncrementBufferOffset(void * target, void * source, s32 * offset, s32 typesize, s32 maximum){ bool UDPServer::cpyIncrementBufferOffset(void * target, void * source, s32 * offset, s32 typesize, s32 maximum) {
if(((int)*offset + typesize) > maximum){ if(((int)*offset + typesize) > maximum) {
DEBUG_FUNCTION_LINE("Transfer error. Excepted %04X bytes, but only got %04X\n",(*offset + typesize),maximum); DEBUG_FUNCTION_LINE("Transfer error. Excepted %04X bytes, but only got %04X\n",(*offset + typesize),maximum);
return false; return false;
} }
@ -86,82 +88,84 @@ bool UDPServer::cpyIncrementBufferOffset(void * target, void * source, s32 * off
return true; return true;
} }
void UDPServer::DoUDPThread(CThread *thread, void *arg){ void UDPServer::DoUDPThread(CThread *thread, void *arg) {
UDPServer * args = (UDPServer * )arg; UDPServer * args = (UDPServer * )arg;
args->DoUDPThreadInternal(); args->DoUDPThreadInternal();
} }
void UDPServer::DoUDPThreadInternal(){ void UDPServer::DoUDPThreadInternal() {
u8 buffer[MAX_UDP_SIZE]; u8 buffer[MAX_UDP_SIZE];
s32 n; s32 n;
my_cb_user user; my_cb_user user;
while(1){ while(1) {
//s32 usingVar = exitThread; //s32 usingVar = exitThread;
if(exitThread)break; if(exitThread)break;
memset(buffer,0,MAX_UDP_SIZE); memset(buffer,0,MAX_UDP_SIZE);
n = recv(sockfd,buffer,MAX_UDP_SIZE,0); n = recv(sockfd,buffer,MAX_UDP_SIZE,0);
if (n < 0){ if (n < 0) {
s32 errno_ = socketlasterr(); s32 errno_ = socketlasterr();
OSSleepTicks(OSMicrosecondsToTicks(2000)); OSSleepTicks(OSMicrosecondsToTicks(2000));
if(errno_ != 11 && errno_ != 9){ if(errno_ != 11 && errno_ != 9) {
break; break;
} }
continue; continue;
} }
s32 bufferoffset = 0; s32 bufferoffset = 0;
u8 type; u8 type;
memcpy((void *)&type,buffer,sizeof(type)); memcpy((void *)&type,buffer,sizeof(type));
bufferoffset += sizeof(type); bufferoffset += sizeof(type);
switch (buffer[0]) { switch (buffer[0]) {
case WIIU_CP_UDP_CONTROLLER_READ_DATA: { case WIIU_CP_UDP_CONTROLLER_READ_DATA: {
if(gUsedProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_1){ if(gUsedProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_1) {
u8 count_commands; u8 count_commands;
memcpy((void *)&count_commands,buffer+bufferoffset,sizeof(count_commands)); memcpy((void *)&count_commands,buffer+bufferoffset,sizeof(count_commands));
bufferoffset += sizeof(count_commands); bufferoffset += sizeof(count_commands);
for(s32 i = 0;i<count_commands;i++){ for(s32 i = 0; i<count_commands; i++) {
s32 handle; s32 handle;
u16 deviceSlot; u16 deviceSlot;
u32 hid; u32 hid;
u8 padslot; u8 padslot;
u8 datasize; u8 datasize;
if(!cpyIncrementBufferOffset((void *)&handle, (void *)buffer,&bufferoffset,sizeof(handle), n))continue; if(!cpyIncrementBufferOffset((void *)&handle, (void *)buffer,&bufferoffset,sizeof(handle), n))continue;
if(!cpyIncrementBufferOffset((void *)&deviceSlot, (void *)buffer,&bufferoffset,sizeof(deviceSlot),n))continue; if(!cpyIncrementBufferOffset((void *)&deviceSlot, (void *)buffer,&bufferoffset,sizeof(deviceSlot),n))continue;
hid = (1 << deviceSlot); hid = (1 << deviceSlot);
if(!cpyIncrementBufferOffset((void *)&padslot, (void *)buffer,&bufferoffset,sizeof(padslot), n))continue; if(!cpyIncrementBufferOffset((void *)&padslot, (void *)buffer,&bufferoffset,sizeof(padslot), n))continue;
if(!cpyIncrementBufferOffset((void *)&datasize, (void *)buffer,&bufferoffset,sizeof(datasize), n))continue; if(!cpyIncrementBufferOffset((void *)&datasize, (void *)buffer,&bufferoffset,sizeof(datasize), n))continue;
u8 * databuffer = (u8*) malloc(datasize * sizeof(u8)); u8 * databuffer = (u8*) malloc(datasize * sizeof(u8));
if(!databuffer){ if(!databuffer) {
DEBUG_FUNCTION_LINE("Allocating memory failed\n"); DEBUG_FUNCTION_LINE("Allocating memory failed\n");
continue; continue;
} }
if(!cpyIncrementBufferOffset((void *)databuffer, (void *)buffer,&bufferoffset,datasize, n))continue; if(!cpyIncrementBufferOffset((void *)databuffer, (void *)buffer,&bufferoffset,datasize, n))continue;
//DEBUG_FUNCTION_LINE("UDPServer::DoUDPThreadInternal(): Got handle: %d slot %04X hid %04X pad %02X datasize %02X\n",handle,deviceSlot,hid,padslot,datasize); //DEBUG_FUNCTION_LINE("UDPServer::DoUDPThreadInternal(): Got handle: %d slot %04X hid %04X pad %02X datasize %02X\n",handle,deviceSlot,hid,padslot,datasize);
user.pad_slot = padslot; user.pad_slot = padslot;
user.slotdata.deviceslot = deviceSlot; user.slotdata.deviceslot = deviceSlot;
user.slotdata.hidmask = hid; user.slotdata.hidmask = hid;
if(gNetworkController[deviceSlot][padslot][0] == 0){ if(gNetworkController[deviceSlot][padslot][0] == 0) {
DEBUG_FUNCTION_LINE("Ehm. Pad is not connected. STOP SENDING DATA ;) \n"); DEBUG_FUNCTION_LINE("Ehm. Pad is not connected. STOP SENDING DATA ;) \n");
}else{ } else {
ControllerPatcherHID::externHIDReadCallback(handle,databuffer,datasize,&user); ControllerPatcherHID::externHIDReadCallback(handle,databuffer,datasize,&user);
} }
if(databuffer){ if(databuffer) {
free(databuffer); free(databuffer);
databuffer = NULL; databuffer = NULL;
}
} }
break;
} }
break; break;
} }
default:{ break;
break; }
} default: {
break;
}
} }
} }
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("UDPServer Thread ended\n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("UDPServer Thread ended\n");
}
} }

View File

@ -23,7 +23,7 @@
#define WIIU_CP_UDP_CONTROLLER_READ_DATA 0x03 #define WIIU_CP_UDP_CONTROLLER_READ_DATA 0x03
class UDPServer{ class UDPServer {
friend class ControllerPatcher; friend class ControllerPatcher;
private: private:
@ -34,7 +34,7 @@ private:
} }
static void destroyInstance() { static void destroyInstance() {
if(instance != NULL){ if(instance != NULL) {
delete instance; delete instance;
instance = NULL; instance = NULL;
} }

View File

@ -26,13 +26,13 @@
* public implementation for the network controller * public implementation for the network controller
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
s32 ControllerPatcherHID::externAttachDetachCallback(HIDDevice *p_device, HIDAttachEvent attach){ s32 ControllerPatcherHID::externAttachDetachCallback(HIDDevice *p_device, HIDAttachEvent attach) {
HIDClient client; HIDClient client;
memset(&client,0,sizeof(client)); memset(&client,0,sizeof(client));
return AttachDetachCallback(&client,p_device,attach); return AttachDetachCallback(&client,p_device,attach);
} }
void ControllerPatcherHID::externHIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr){ void ControllerPatcherHID::externHIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr) {
HIDReadCallback(handle,buf,bytes_transfered,usr); HIDReadCallback(handle,buf,bytes_transfered,usr);
} }
@ -40,16 +40,16 @@ void ControllerPatcherHID::externHIDReadCallback(u32 handle, unsigned char *buf,
* private implementation for the HID Api. * private implementation for the HID Api.
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
s32 ControllerPatcherHID::myAttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, HIDAttachEvent attach){ s32 ControllerPatcherHID::myAttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, HIDAttachEvent attach) {
return AttachDetachCallback(p_client,p_device,attach); return AttachDetachCallback(p_client,p_device,attach);
} }
void ControllerPatcherHID::myHIDMouseReadCallback(u32 handle, s32 error, unsigned char *buf, u32 bytes_transfered, void *p_user){ void ControllerPatcherHID::myHIDMouseReadCallback(u32 handle, s32 error, unsigned char *buf, u32 bytes_transfered, void *p_user) {
if(error == 0){ if(error == 0) {
my_cb_user *usr = (my_cb_user*)p_user; my_cb_user *usr = (my_cb_user*)p_user;
u32 slot = 0; u32 slot = 0;
if(usr->pad_slot < HID_MAX_PADS_COUNT){ if(usr->pad_slot < HID_MAX_PADS_COUNT) {
slot = usr->pad_slot; slot = usr->pad_slot;
} }
@ -59,7 +59,7 @@ void ControllerPatcherHID::myHIDMouseReadCallback(u32 handle, s32 error, unsigne
data_ptr->type = DEVICE_TYPE_MOUSE; data_ptr->type = DEVICE_TYPE_MOUSE;
//DEBUG_FUNCTION_LINE("%02X %02X %02X %02X %02X bytes_transfered: %d\n",buf[0],buf[1],buf[2],buf[3],buf[4],bytes_transfered); //DEBUG_FUNCTION_LINE("%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 if(buf[0] == 2 && bytes_transfered > 3) { // using the other mouse mode
buf +=1; buf +=1;
} }
@ -76,7 +76,7 @@ void ControllerPatcherHID::myHIDMouseReadCallback(u32 handle, s32 error, unsigne
cur_mouse_data->deltaY = y_value; cur_mouse_data->deltaY = y_value;
cur_mouse_data->left_click = buf[0]; cur_mouse_data->left_click = buf[0];
cur_mouse_data->right_click = buf[0]>>1; cur_mouse_data->right_click = buf[0]>>1;
if(cur_mouse_data->X < 0) cur_mouse_data->X = 0; 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->X > 1280) cur_mouse_data->X = 1280;
@ -89,36 +89,38 @@ void ControllerPatcherHID::myHIDMouseReadCallback(u32 handle, s32 error, unsigne
//DEBUG_FUNCTION_LINE("%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); //DEBUG_FUNCTION_LINE("%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); HIDRead(handle, usr->buf, bytes_transfered, myHIDMouseReadCallback, usr);
} }
} }
void ControllerPatcherHID::myHIDReadCallback(u32 handle, s32 error, unsigned char *buf, u32 bytes_transfered, void *p_user){ 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; my_cb_user *usr = (my_cb_user*)p_user;
HIDReadCallback(handle,buf,bytes_transfered,usr); HIDReadCallback(handle,buf,bytes_transfered,usr);
if(usr->slotdata.hidmask == gHID_LIST_DS4){ if(usr->slotdata.hidmask == gHID_LIST_DS4) {
OSSleepTicks(OSMicrosecondsToTicks(2000)); //DS4 is way tooo fast. sleeping to reduce lag. (need to check the other pads) OSSleepTicks(OSMicrosecondsToTicks(2000)); //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);
} }
} }
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Intern Callback actions * Intern Callback actions
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, HIDAttachEvent attach){ s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, HIDAttachEvent attach) {
if(attach){ if(attach) {
DEBUG_FUNCTION_LINE("vid %04x pid %04x connected\n", SWAP16(p_device->vid),SWAP16(p_device->pid)); DEBUG_FUNCTION_LINE("vid %04x pid %04x connected\n", SWAP16(p_device->vid),SWAP16(p_device->pid));
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("interface index %02x\n", p_device->interfaceIndex); if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("sub class %02x\n", p_device->subClass); DEBUG_FUNCTION_LINE("interface index %02x\n", p_device->interfaceIndex);
DEBUG_FUNCTION_LINE("protocol %02x\n", p_device->protocol); DEBUG_FUNCTION_LINE("sub class %02x\n", p_device->subClass);
DEBUG_FUNCTION_LINE("max packet in %02x\n", p_device->maxPacketSizeRx); DEBUG_FUNCTION_LINE("protocol %02x\n", p_device->protocol);
DEBUG_FUNCTION_LINE("max packet out %02x\n", p_device->maxPacketSizeRx); } DEBUG_FUNCTION_LINE("max packet in %02x\n", p_device->maxPacketSizeRx);
DEBUG_FUNCTION_LINE("max packet out %02x\n", p_device->maxPacketSizeRx);
}
} }
if(!attach){ if(!attach) {
DEBUG_FUNCTION_LINE("vid %04x pid %04x disconnected\n", SWAP16(p_device->vid),SWAP16(p_device->pid)); DEBUG_FUNCTION_LINE("vid %04x pid %04x disconnected\n", SWAP16(p_device->vid),SWAP16(p_device->pid));
} }
DeviceInfo device_info; DeviceInfo device_info;
@ -133,24 +135,24 @@ s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p
slotdata->hidmask = gHID_LIST_KEYBOARD; slotdata->hidmask = gHID_LIST_KEYBOARD;
slotdata->deviceslot = gHID_SLOT_KEYBOARD; slotdata->deviceslot = gHID_SLOT_KEYBOARD;
//DEBUG_FUNCTION_LINE("Found Keyboard: device: %s slot: %d\n",byte_to_binary(device_info.slotdata.hidmask),device_info.slotdata.deviceslot); //DEBUG_FUNCTION_LINE("Found Keyboard: device: %s slot: %d\n",byte_to_binary(device_info.slotdata.hidmask),device_info.slotdata.deviceslot);
}else if ((p_device->subClass == 1) && (p_device->protocol == 2)){ // MOUSE } else if ((p_device->subClass == 1) && (p_device->protocol == 2)) { // MOUSE
slotdata->hidmask = gHID_LIST_MOUSE; slotdata->hidmask = gHID_LIST_MOUSE;
slotdata->deviceslot = gMouseSlot; slotdata->deviceslot = gMouseSlot;
//DEBUG_FUNCTION_LINE("Found Mouse: device: %s slot: %d\n",byte_to_binary(device_info.hid),device_info.slot); //DEBUG_FUNCTION_LINE("Found Mouse: device: %s slot: %d\n",byte_to_binary(device_info.hid),device_info.slot);
}else{ } else {
s32 ret; s32 ret;
if((ret = ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info)) < 0){ if((ret = ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info)) < 0) {
DEBUG_FUNCTION_LINE("ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) failed %d \n",ret); DEBUG_FUNCTION_LINE("ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) failed %d \n",ret);
return HID_DEVICE_DETACH; return HID_DEVICE_DETACH;
}else{ } else {
//DEBUG_FUNCTION_LINE("ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) success %d \n",ret); //DEBUG_FUNCTION_LINE("ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) success %d \n",ret);
} }
} }
if(slotdata->hidmask){ if(slotdata->hidmask) {
if(attach){ if(attach) {
s32 bufSize = 64; s32 bufSize = 64;
if(slotdata->hidmask != gHID_LIST_MOUSE && config_controller[slotdata->deviceslot][CONTRPS_BUF_SIZE][0] == CONTROLLER_PATCHER_VALUE_SET){ 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]; bufSize = config_controller[slotdata->deviceslot][CONTRPS_BUF_SIZE][1];
} }
unsigned char *buf = (unsigned char *) memalign(64,bufSize); unsigned char *buf = (unsigned char *) memalign(64,bufSize);
@ -163,9 +165,9 @@ s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p
gHIDAttached |= slotdata->hidmask; gHIDAttached |= slotdata->hidmask;
gHIDCurrentDevice |= slotdata->hidmask; gHIDCurrentDevice |= slotdata->hidmask;
s32 pads_per_device = 1; s32 pads_per_device = 1;
if(config_controller[slotdata->deviceslot][CONTRPS_PAD_COUNT][0] != CONTROLLER_PATCHER_INVALIDVALUE){ if(config_controller[slotdata->deviceslot][CONTRPS_PAD_COUNT][0] != CONTROLLER_PATCHER_INVALIDVALUE) {
pads_per_device = config_controller[slotdata->deviceslot][CONTRPS_PAD_COUNT][1]; 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 if(pads_per_device > HID_MAX_PADS_COUNT) { //maximum of HID_MAX_PADS_COUNT
pads_per_device = HID_MAX_PADS_COUNT; pads_per_device = HID_MAX_PADS_COUNT;
} }
} }
@ -177,8 +179,8 @@ s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p
s32 failed = 1; s32 failed = 1;
for(s32 i = 0;i<HID_MAX_PADS_COUNT;i += pads_per_device){ for(s32 i = 0; i<HID_MAX_PADS_COUNT; i += pads_per_device) {
if(!(pad_count & (1 << i))){ if(!(pad_count & (1 << i))) {
failed = 0; failed = 0;
pad_count |= (1 << i); pad_count |= (1 << i);
pad_slot = i; pad_slot = i;
@ -186,13 +188,13 @@ s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p
} }
} }
if(failed){ if(failed) {
DEBUG_FUNCTION_LINE("error: I can only handle %d devices of the same type. Sorry \n",HID_MAX_PADS_COUNT); DEBUG_FUNCTION_LINE("error: I can only handle %d devices of the same type. Sorry \n",HID_MAX_PADS_COUNT);
if(buf){ if(buf) {
free(buf); free(buf);
buf = NULL; buf = NULL;
} }
if(usr){ if(usr) {
free(usr); free(usr);
usr = NULL; usr = NULL;
} }
@ -207,7 +209,7 @@ s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p
usr->pads_per_device = pads_per_device; usr->pads_per_device = pads_per_device;
usr->pad_slot = pad_slot; usr->pad_slot = pad_slot;
for(s32 i = 0;i<pads_per_device;i++){ for(s32 i = 0; i<pads_per_device; i++) {
memset(&gHID_Devices[slotdata->deviceslot].pad_data[pad_slot+i],0,sizeof(HID_Data)); memset(&gHID_Devices[slotdata->deviceslot].pad_data[pad_slot+i],0,sizeof(HID_Data));
gHID_Devices[slotdata->deviceslot].pad_data[pad_slot+i].handle = p_device->handle; gHID_Devices[slotdata->deviceslot].pad_data[pad_slot+i].handle = p_device->handle;
@ -220,9 +222,11 @@ s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p
DCInvalidateRange(&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));
} }
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Device successfully attached\n"); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Device successfully attached\n");
}
if(slotdata->hidmask == gHID_LIST_GC){ // GC PAD if(slotdata->hidmask == gHID_LIST_GC) { // GC PAD
//The GC Adapter has all ports in one device. Set them all. //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[0].slotdata = device_info.slotdata;
gHID_Devices[slotdata->deviceslot].pad_data[1].slotdata = device_info.slotdata; gHID_Devices[slotdata->deviceslot].pad_data[1].slotdata = device_info.slotdata;
@ -232,16 +236,16 @@ s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p
buf[0] = 0x13; buf[0] = 0x13;
HIDWrite(p_device->handle, usr->buf, 1, NULL,NULL); HIDWrite(p_device->handle, usr->buf, 1, NULL,NULL);
HIDRead(p_device->handle, usr->buf, usr->transfersize, myHIDReadCallback, usr); HIDRead(p_device->handle, usr->buf, usr->transfersize, myHIDReadCallback, usr);
}else if (slotdata->hidmask == gHID_LIST_MOUSE){ } else if (slotdata->hidmask == gHID_LIST_MOUSE) {
HIDSetProtocol(p_device->handle, p_device->interfaceIndex, 0, 0, 0); HIDSetProtocol(p_device->handle, p_device->interfaceIndex, 0, 0, 0);
//HIDGetDescriptor(p_device->handle,0x22,0x00,0,my_buf,512,my_foo_cb,NULL); //HIDGetDescriptor(p_device->handle,0x22,0x00,0,my_buf,512,my_foo_cb,NULL);
HIDSetIdle(p_device->handle,p_device->interfaceIndex,1,NULL,NULL); HIDSetIdle(p_device->handle,p_device->interfaceIndex,1,NULL,NULL);
gHID_Mouse_Mode = HID_MOUSE_MODE_AIM; gHID_Mouse_Mode = HID_MOUSE_MODE_AIM;
HIDRead(p_device->handle, buf, p_device->maxPacketSizeRx, myHIDMouseReadCallback, usr); HIDRead(p_device->handle, buf, p_device->maxPacketSizeRx, myHIDMouseReadCallback, usr);
}else if (slotdata->hidmask == gHID_LIST_SWITCH_PRO){ } else if (slotdata->hidmask == gHID_LIST_SWITCH_PRO) {
s32 read_result = HIDRead(p_device->handle, usr->buf, usr->transfersize, NULL, NULL); s32 read_result = HIDRead(p_device->handle, usr->buf, usr->transfersize, NULL, NULL);
if(read_result == 64){ if(read_result == 64) {
if(usr->buf[01] == 0x01){ //We need to do the handshake if(usr->buf[01] == 0x01) { //We need to do the handshake
DEBUG_FUNCTION_LINE("Switch Pro Controller handshake needed\n"); DEBUG_FUNCTION_LINE("Switch Pro Controller handshake needed\n");
/** /**
Thanks to ShinyQuagsire23 for the values (https://github.com/shinyquagsire23/HID-Joy-Con-Whispering) Thanks to ShinyQuagsire23 for the values (https://github.com/shinyquagsire23/HID-Joy-Con-Whispering)
@ -261,31 +265,34 @@ s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p
buf[1] = 0x04; buf[1] = 0x04;
HIDWrite(p_device->handle, usr->buf, 2, NULL,NULL); HIDWrite(p_device->handle, usr->buf, 2, NULL,NULL);
HIDRead(p_device->handle, usr->buf, usr->transfersize, NULL, NULL); HIDRead(p_device->handle, usr->buf, usr->transfersize, NULL, NULL);
}else{ } else {
DEBUG_FUNCTION_LINE("Switch Pro Controller handshake already done\n"); DEBUG_FUNCTION_LINE("Switch Pro Controller handshake already done\n");
} }
HIDRead(p_device->handle, usr->buf, usr->transfersize, myHIDReadCallback, usr); HIDRead(p_device->handle, usr->buf, usr->transfersize, myHIDReadCallback, usr);
} }
}else if (slotdata->hidmask == gHID_LIST_KEYBOARD){ } else if (slotdata->hidmask == gHID_LIST_KEYBOARD) {
HIDSetProtocol(p_device->handle, p_device->interfaceIndex, 1, 0, 0); HIDSetProtocol(p_device->handle, p_device->interfaceIndex, 1, 0, 0);
HIDSetIdle(p_device->handle, p_device->interfaceIndex, 0, 0, 0); HIDSetIdle(p_device->handle, p_device->interfaceIndex, 0, 0, 0);
HIDRead(p_device->handle, buf, p_device->maxPacketSizeRx, myHIDReadCallback, usr); HIDRead(p_device->handle, buf, p_device->maxPacketSizeRx, myHIDReadCallback, usr);
}else if (slotdata->hidmask == gHID_LIST_DS3){ } else if (slotdata->hidmask == gHID_LIST_DS3) {
HIDSetProtocol(p_device->handle, p_device->interfaceIndex, 1, 0, 0); HIDSetProtocol(p_device->handle, p_device->interfaceIndex, 1, 0, 0);
HIDDS3Rumble(p_device->handle,usr,0); HIDDS3Rumble(p_device->handle,usr,0);
buf[0] = 0x42; buf[1] = 0x0c; buf[2] = 0x00; buf[3] = 0x00; 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); 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->maxPacketSizeRx, myHIDReadCallback, usr); HIDRead(p_device->handle, usr->buf, p_device->maxPacketSizeRx, myHIDReadCallback, usr);
}else{ } else {
HIDRead(p_device->handle, usr->buf, p_device->maxPacketSizeRx, myHIDReadCallback, usr); HIDRead(p_device->handle, usr->buf, p_device->maxPacketSizeRx, myHIDReadCallback, usr);
} }
return HID_DEVICE_ATTACH; return HID_DEVICE_ATTACH;
}else{ } else {
my_cb_user * user_data = NULL; my_cb_user * user_data = NULL;
s32 founddata = 0; s32 founddata = 0;
for(s32 i = 0;i<HID_MAX_PADS_COUNT;i++){ for(s32 i = 0; i<HID_MAX_PADS_COUNT; i++) {
if(gHID_Devices[slotdata->deviceslot].pad_data[i].handle == p_device->handle){ if(gHID_Devices[slotdata->deviceslot].pad_data[i].handle == p_device->handle) {
gHID_Devices[slotdata->deviceslot].pad_data[i].handle = 0; 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)); DCFlushRange(&gHID_Devices[slotdata->deviceslot].pad_data[i].handle,sizeof(gHID_Devices[slotdata->deviceslot].pad_data[i].handle));
@ -298,21 +305,23 @@ s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p
} }
} }
if(user_data){ if(user_data) {
config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1] &= ~ (1 << user_data->pad_slot); 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])); 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])); DCInvalidateRange(&config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1],sizeof(config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1]));
if(user_data->buf){ if(user_data->buf) {
free(user_data->buf); free(user_data->buf);
user_data->buf = NULL; user_data->buf = NULL;
} }
free(user_data); free(user_data);
user_data = NULL; user_data = NULL;
}else{ } else {
if(founddata){ DEBUG_FUNCTION_LINE("user_data null. You may have a memory leak.\n"); } if(founddata) {
DEBUG_FUNCTION_LINE("user_data null. You may have a memory leak.\n");
}
return HID_DEVICE_DETACH; return HID_DEVICE_DETACH;
} }
if(config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1] == 0){ if(config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1] == 0) {
gHIDAttached &= ~slotdata->hidmask; gHIDAttached &= ~slotdata->hidmask;
gHIDCurrentDevice &= ~slotdata->hidmask; gHIDCurrentDevice &= ~slotdata->hidmask;
@ -321,29 +330,33 @@ s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p
DCFlushRange(&gHIDCurrentDevice,sizeof(gHIDCurrentDevice)); DCFlushRange(&gHIDCurrentDevice,sizeof(gHIDCurrentDevice));
DCInvalidateRange(&gHIDCurrentDevice,sizeof(gHIDCurrentDevice)); DCInvalidateRange(&gHIDCurrentDevice,sizeof(gHIDCurrentDevice));
if (slotdata->hidmask == gHID_LIST_MOUSE){ if (slotdata->hidmask == gHID_LIST_MOUSE) {
gHID_Mouse_Mode = HID_MOUSE_MODE_AIM; gHID_Mouse_Mode = HID_MOUSE_MODE_AIM;
} }
}else{ } else {
if(HID_DEBUG){DEBUG_FUNCTION_LINE("We still have pad for deviceslot %d connected.\n",slotdata->deviceslot); } if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("We still have pad for deviceslot %d connected.\n",slotdata->deviceslot);
}
}
if(HID_DEBUG) {
DEBUG_FUNCTION_LINE("Device successfully detached\n");
} }
if(HID_DEBUG){DEBUG_FUNCTION_LINE("Device successfully detached\n"); }
} }
}else{ } else {
DEBUG_FUNCTION_LINE("HID-Device currently not supported! You can add support through config files\n"); DEBUG_FUNCTION_LINE("HID-Device currently not supported! You can add support through config files\n");
} }
return HID_DEVICE_DETACH; return HID_DEVICE_DETACH;
} }
void ControllerPatcherHID::HIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr){ void ControllerPatcherHID::HIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr) {
ControllerPatcherUtils::doSampling(usr->slotdata.deviceslot,usr->pad_slot,false); ControllerPatcherUtils::doSampling(usr->slotdata.deviceslot,usr->pad_slot,false);
//DEBUG_FUNCTION_LINE("my_read_cbInternal: %d %08X %d\n",bytes_transfered,usr->slotdata.hidmask,usr->slotdata.deviceslot); //DEBUG_FUNCTION_LINE("my_read_cbInternal: %d %08X %d\n",bytes_transfered,usr->slotdata.hidmask,usr->slotdata.deviceslot);
if(usr->slotdata.hidmask == gHID_LIST_GC){ if(usr->slotdata.hidmask == gHID_LIST_GC) {
HID_Data * data_ptr = NULL; HID_Data * data_ptr = NULL;
//Copy the data for all 4 pads //Copy the data for all 4 pads
for(s32 i = 0;i<4;i++){ for(s32 i = 0; i<4; i++) {
data_ptr = &(gHID_Devices[gHID_SLOT_GC].pad_data[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.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. memcpy(&(data_ptr->data_union.controller.cur_hid_data[0]),&buf[(i*9)+1],9); //save new data.
@ -357,10 +370,10 @@ void ControllerPatcherHID::HIDReadCallback(u32 handle, unsigned char *buf, u32 b
DEBUG_FUNCTION_LINE("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++; DEBUG_FUNCTION_LINE("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++;
DEBUG_FUNCTION_LINE("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]);*/ DEBUG_FUNCTION_LINE("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); HIDGCRumble(handle,usr);
}else if(usr->slotdata.hidmask != 0){ } 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 //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. //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){ if(usr->slotdata.hidmask == gHID_LIST_SWITCH_PRO && buf != NULL && bytes_transfered >= 0x20) {
u8 buffer[0x13]; u8 buffer[0x13];
memcpy(buffer,buf+0x0D,0x013); memcpy(buffer,buf+0x0D,0x013);
@ -379,7 +392,7 @@ void ControllerPatcherHID::HIDReadCallback(u32 handle, unsigned char *buf, u32 b
//We want to get the next input! //We want to get the next input!
s32 res = HIDWrite(handle, buf, 9, NULL,NULL); s32 res = HIDWrite(handle, buf, 9, NULL,NULL);
if(res == 9){ //Check if it's the USB data format. if(res == 9) { //Check if it's the USB data format.
if(buffer[1] == 0) return; if(buffer[1] == 0) return;
//Converting the buttons //Converting the buttons
u32 buttons = (((u32*)(buffer))[0]) & 0xFFFFFF00; u32 buttons = (((u32*)(buffer))[0]) & 0xFFFFFF00;
@ -407,24 +420,24 @@ void ControllerPatcherHID::HIDReadCallback(u32 handle, unsigned char *buf, u32 b
//Converting the DPAD //Converting the DPAD
if(((dpad & HID_SWITCH_PRO_USB_BUTTON_UP_VALUE) == HID_SWITCH_PRO_USB_BUTTON_UP_VALUE) && 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)){ ((dpad & HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE) == HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE)) {
dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_NE_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) && } 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)){ ((dpad & HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE) == HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE)) {
dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_SE_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) && } 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)){ ((dpad & HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE) == HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE)) {
dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_SW_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) && } 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)){ ((dpad & HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE) == HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE)) {
dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_NW_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){ } 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; 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){ } 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; 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){ } 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; 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){ } 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; dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_W_VALUE;
} }
@ -448,15 +461,15 @@ void ControllerPatcherHID::HIDReadCallback(u32 handle, unsigned char *buf, u32 b
s32 skip = 0; s32 skip = 0;
//Input filter //Input filter
if( config_controller[usr->slotdata.deviceslot][CONTRPS_INPUT_FILTER][0] != CONTROLLER_PATCHER_INVALIDVALUE){ 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]){ if(buf[config_controller[usr->slotdata.deviceslot][CONTRPS_INPUT_FILTER][0]] != config_controller[usr->slotdata.deviceslot][CONTRPS_INPUT_FILTER][1]) {
skip = 1; skip = 1;
} }
} }
if(!skip){ if(!skip) {
u32 slot = 0; u32 slot = 0;
if(usr->pad_slot < HID_MAX_PADS_COUNT){ if(usr->pad_slot < HID_MAX_PADS_COUNT) {
slot = usr->pad_slot; slot = usr->pad_slot;
} }
slot += ControllerPatcherUtils::getPadSlotInAdapter(usr->slotdata.deviceslot,buf); // If the controller has multiple slots, we need to use the right one. slot += ControllerPatcherUtils::getPadSlotInAdapter(usr->slotdata.deviceslot,buf); // If the controller has multiple slots, we need to use the right one.
@ -479,19 +492,19 @@ void ControllerPatcherHID::HIDReadCallback(u32 handle, unsigned char *buf, u32 b
* Other functions * Other functions
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherHID::setVPADControllerData(VPADStatus * buffer,std::vector<HID_Data *>& data){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherHID::setVPADControllerData(VPADStatus * buffer,std::vector<HID_Data *>& data) {
if(buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; if(buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
HID_Data * data_cur; HID_Data * data_cur;
s32 buttons_hold; s32 buttons_hold;
for(u32 i = 0;i<data.size();i++){ for(u32 i = 0; i<data.size(); i++) {
data_cur = data[i]; data_cur = data[i];
if(data_cur->slotdata.hidmask & gHID_LIST_MOUSE){ //Reset the input when we have no new inputs if(data_cur->slotdata.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; HID_Mouse_Data * mouse_data = &data_cur->data_union.mouse.cur_mouse_data;
if(mouse_data->valuedChanged == 1){ //Fix for the mouse cursor if(mouse_data->valuedChanged == 1) { //Fix for the mouse cursor
mouse_data->valuedChanged = 0; mouse_data->valuedChanged = 0;
}else{ } else {
mouse_data->deltaX = 0; mouse_data->deltaX = 0;
mouse_data->deltaY = 0; mouse_data->deltaY = 0;
} }
@ -540,7 +553,7 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherHID::setVPADControllerData(V
} }
// Caculates a valid stick position // Caculates a valid stick position
if(data.size() > 0){ if(data.size() > 0) {
ControllerPatcherUtils::normalizeStickValues(&buffer->leftStick); ControllerPatcherUtils::normalizeStickValues(&buffer->leftStick);
ControllerPatcherUtils::normalizeStickValues(&buffer->rightStick); ControllerPatcherUtils::normalizeStickValues(&buffer->rightStick);
} }
@ -548,17 +561,17 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherHID::setVPADControllerData(V
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
std::vector<HID_Data *> ControllerPatcherHID::getHIDDataAll(){ std::vector<HID_Data *> ControllerPatcherHID::getHIDDataAll() {
u32 hid = gHIDCurrentDevice; u32 hid = gHIDCurrentDevice;
std::vector<HID_Data *> data_list; std::vector<HID_Data *> data_list;
for(s32 i = 0;i < gHIDMaxDevices;i++){ for(s32 i = 0; i < gHIDMaxDevices; i++) {
if((hid & (1 << i)) != 0){ if((hid & (1 << i)) != 0) {
u32 cur_hidmask = config_controller_hidmask[i]; u32 cur_hidmask = config_controller_hidmask[i];
for(s32 pad = 0; pad < HID_MAX_PADS_COUNT; pad++){ for(s32 pad = 0; pad < HID_MAX_PADS_COUNT; pad++) {
s32 res; s32 res;
HID_Data * new_data = NULL; HID_Data * new_data = NULL;
if((res = ControllerPatcherHID::getHIDData(cur_hidmask,pad,&new_data)) < 0){ // Checks if the pad is invalid. if((res = ControllerPatcherHID::getHIDData(cur_hidmask,pad,&new_data)) < 0) { // Checks if the pad is invalid.
//DEBUG_FUNCTION_LINE("error: Error getting the HID data from HID(%s) CHAN(). Error %d\n",StringTools::byte_to_binary(cur_hidmask),pad,res); //DEBUG_FUNCTION_LINE("error: Error getting the HID data from HID(%s) CHAN(). Error %d\n",StringTools::byte_to_binary(cur_hidmask),pad,res);
continue; continue;
} }
@ -572,18 +585,18 @@ std::vector<HID_Data *> ControllerPatcherHID::getHIDDataAll(){
/* /*
The slotdata in the HID_Data pointer is empty. We need to provide the hidmask via the parameter 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){ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherHID::getHIDData(u32 hidmask, s32 pad, HID_Data ** data) {
if(data == NULL) return CONTROLLER_PATCHER_ERROR_INVALID_BUFFER; if(data == NULL) return CONTROLLER_PATCHER_ERROR_INVALID_BUFFER;
if(!(hidmask & gHIDCurrentDevice)) return CONTROLLER_PATCHER_ERROR_HID_NOT_CONNECTED; if(!(hidmask & gHIDCurrentDevice)) return CONTROLLER_PATCHER_ERROR_HID_NOT_CONNECTED;
if(pad < 0 && pad > 3) return CONTROLLER_PATCHER_ERROR_INVALID_CHAN; if(pad < 0 && pad > 3) return CONTROLLER_PATCHER_ERROR_INVALID_CHAN;
s32 device_slot = ControllerPatcherUtils::getDeviceSlot(hidmask); s32 device_slot = ControllerPatcherUtils::getDeviceSlot(hidmask);
if(device_slot < 0){ if(device_slot < 0) {
return CONTROLLER_PATCHER_ERROR_DEVICE_SLOT_NOT_FOUND; return CONTROLLER_PATCHER_ERROR_DEVICE_SLOT_NOT_FOUND;
} }
s32 real_pad = pad; s32 real_pad = pad;
if((device_slot != gHID_SLOT_GC) && config_controller[device_slot][CONTRPS_PAD_COUNT][0] != CONTROLLER_PATCHER_INVALIDVALUE){ 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]; s32 pad_count = config_controller[device_slot][CONTRPS_PAD_COUNT][1];
if(pad_count > HID_MAX_PADS_COUNT) pad_count = HID_MAX_PADS_COUNT; if(pad_count > HID_MAX_PADS_COUNT) pad_count = HID_MAX_PADS_COUNT;
pad = (pad/(pad_count))*pad_count; pad = (pad/(pad_count))*pad_count;
@ -591,7 +604,7 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherHID::getHIDData(u32 hidmask,
s32 result = ControllerPatcherUtils::checkActivePad(hidmask,pad); s32 result = ControllerPatcherUtils::checkActivePad(hidmask,pad);
if(result < 0){ //Not pad connected to adapter if(result < 0) { //Not pad connected to adapter
return CONTROLLER_PATCHER_ERROR_NO_PAD_CONNECTED; return CONTROLLER_PATCHER_ERROR_NO_PAD_CONNECTED;
} }
@ -601,40 +614,40 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherHID::getHIDData(u32 hidmask,
} }
void ControllerPatcherHID::HIDGCRumble(u32 handle,my_cb_user *usr){ void ControllerPatcherHID::HIDGCRumble(u32 handle,my_cb_user *usr) {
if(usr == NULL) return; if(usr == NULL) return;
if(!ControllerPatcher::isRumbleActivated()) return; if(!ControllerPatcher::isRumbleActivated()) return;
s32 rumblechanged = 0; s32 rumblechanged = 0;
for(s32 i = 0;i<HID_GC_PAD_COUNT;i++){ for(s32 i = 0; i<HID_GC_PAD_COUNT; i++) {
HID_Data * data_ptr = &(gHID_Devices[usr->slotdata.deviceslot].pad_data[i]); HID_Data * data_ptr = &(gHID_Devices[usr->slotdata.deviceslot].pad_data[i]);
if(data_ptr->rumbleActive != usr->rumblestatus[i]){ if(data_ptr->rumbleActive != usr->rumblestatus[i]) {
rumblechanged = 1; rumblechanged = 1;
} }
usr->rumblestatus[i] = data_ptr->rumbleActive; usr->rumblestatus[i] = data_ptr->rumbleActive;
usr->buf[i+1] = usr->rumblestatus[i]; usr->buf[i+1] = usr->rumblestatus[i];
} }
usr->forceRumbleInTicks[0]--; usr->forceRumbleInTicks[0]--;
if(rumblechanged || usr->forceRumbleInTicks[0] <= 0){ if(rumblechanged || usr->forceRumbleInTicks[0] <= 0) {
usr->buf[0] = 0x11; usr->buf[0] = 0x11;
HIDWrite(handle, usr->buf, 5, NULL, NULL); HIDWrite(handle, usr->buf, 5, NULL, NULL);
usr->forceRumbleInTicks[0] = 10; usr->forceRumbleInTicks[0] = 10;
} }
} }
void ControllerPatcherHID::HIDRumble(u32 handle,my_cb_user *usr,u32 pad){ void ControllerPatcherHID::HIDRumble(u32 handle,my_cb_user *usr,u32 pad) {
if(usr == NULL || pad > HID_MAX_PADS_COUNT) return; if(usr == NULL || pad > HID_MAX_PADS_COUNT) return;
if(!ControllerPatcher::isRumbleActivated()) return; if(!ControllerPatcher::isRumbleActivated()) return;
s32 rumblechanged = 0; s32 rumblechanged = 0;
HID_Data * data_ptr = &(gHID_Devices[usr->slotdata.deviceslot].pad_data[pad]); HID_Data * data_ptr = &(gHID_Devices[usr->slotdata.deviceslot].pad_data[pad]);
if(data_ptr->rumbleActive != usr->rumblestatus[pad]){ if(data_ptr->rumbleActive != usr->rumblestatus[pad]) {
usr->rumblestatus[pad] = data_ptr->rumbleActive; usr->rumblestatus[pad] = data_ptr->rumbleActive;
rumblechanged = 1; rumblechanged = 1;
} }
usr->forceRumbleInTicks[pad]--; usr->forceRumbleInTicks[pad]--;
if(rumblechanged || usr->forceRumbleInTicks[pad] <= 0){ if(rumblechanged || usr->forceRumbleInTicks[pad] <= 0) {
//DEBUG_FUNCTION_LINE("Rumble: %d %d\n",usr->rumblestatus[pad],usr->rumbleForce[pad]); //DEBUG_FUNCTION_LINE("Rumble: %d %d\n",usr->rumblestatus[pad],usr->rumbleForce[pad]);
//Seding to the network client! //Seding to the network client!
char bytes[6]; char bytes[6];
@ -648,22 +661,21 @@ void ControllerPatcherHID::HIDRumble(u32 handle,my_cb_user *usr,u32 pad){
bytes[i++] = usr->rumblestatus[pad]; bytes[i++] = usr->rumblestatus[pad];
UDPClient * instance = UDPClient::getInstance(); UDPClient * instance = UDPClient::getInstance();
if(instance != NULL){ if(instance != NULL) {
instance->sendData(bytes,6); instance->sendData(bytes,6);
} }
if(usr->slotdata.hidmask == gHID_LIST_DS3){ if(usr->slotdata.hidmask == gHID_LIST_DS3) {
HIDDS3Rumble(handle,usr,usr->rumblestatus[pad]); HIDDS3Rumble(handle,usr,usr->rumblestatus[pad]);
}else{ } else {
// Not implemented for other devices =( // Not implemented for other devices =(
} }
usr->forceRumbleInTicks[pad] = 10; usr->forceRumbleInTicks[pad] = 10;
} }
} }
static u8 ds3_rumble_Report[48] = static u8 ds3_rumble_Report[48] = {
{
0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0x27, 0x10, 0x00, 0x32, 0xFF, 0x27, 0x10, 0x00, 0x32,
@ -676,7 +688,7 @@ static u8 ds3_rumble_Report[48] =
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}; };
void ControllerPatcherHID::HIDDS3Rumble(u32 handle,my_cb_user *usr,s32 rumble){ void ControllerPatcherHID::HIDDS3Rumble(u32 handle,my_cb_user *usr,s32 rumble) {
memcpy(usr->buf, ds3_rumble_Report, 48); memcpy(usr->buf, ds3_rumble_Report, 48);
if (rumble) { if (rumble) {

View File

@ -40,38 +40,38 @@
#define SWAP16(x) ((x>>8) | ((x&0xFF)<<8)) #define SWAP16(x) ((x>>8) | ((x&0xFF)<<8))
#define SWAP8(x) ((x>>4) | ((x&0xF)<<4)) #define SWAP8(x) ((x>>4) | ((x&0xF)<<4))
class ControllerPatcherHID{ class ControllerPatcherHID {
friend class ControllerPatcher; friend class ControllerPatcher;
friend class ControllerPatcherUtils; friend class ControllerPatcherUtils;
public: public:
static s32 externAttachDetachCallback(HIDDevice *p_device, HIDAttachEvent attach); static s32 externAttachDetachCallback(HIDDevice *p_device, HIDAttachEvent attach);
static void externHIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr); static void externHIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr);
private: private:
static CONTROLLER_PATCHER_RESULT_OR_ERROR setVPADControllerData(VPADStatus * buffer,std::vector<HID_Data *>& data); static CONTROLLER_PATCHER_RESULT_OR_ERROR setVPADControllerData(VPADStatus * buffer,std::vector<HID_Data *>& data);
static std::vector<HID_Data *> getHIDDataAll(); static std::vector<HID_Data *> getHIDDataAll();
static CONTROLLER_PATCHER_RESULT_OR_ERROR getHIDData(u32 hidmask, s32 pad, HID_Data ** data); static CONTROLLER_PATCHER_RESULT_OR_ERROR getHIDData(u32 hidmask, s32 pad, HID_Data ** data);
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Rumble * Rumble
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
static void HIDRumble(u32 handle,my_cb_user *usr,u32 pad); static void HIDRumble(u32 handle,my_cb_user *usr,u32 pad);
static void HIDGCRumble(u32 handle,my_cb_user *usr); static void HIDGCRumble(u32 handle,my_cb_user *usr);
static void HIDDS3Rumble(u32 handle,my_cb_user *usr,s32 rumble); static void HIDDS3Rumble(u32 handle,my_cb_user *usr,s32 rumble);
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* HID Callbacks * HID Callbacks
*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
static s32 myAttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, HIDAttachEvent attach); static s32 myAttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, HIDAttachEvent attach);
static void myHIDMouseReadCallback(u32 handle, s32 error, unsigned char *buf, u32 bytes_transfered, void *p_user); 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 void myHIDReadCallback(u32 handle, s32 error, unsigned char *buf, u32 bytes_transfered, void *p_user);
static s32 AttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, HIDAttachEvent attach); static s32 AttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, HIDAttachEvent attach);
static void HIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr); static void HIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr);
}; };
#endif /* _CONTROLLER_PATCHER_HID_H_ */ #endif /* _CONTROLLER_PATCHER_HID_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -32,290 +32,290 @@
#include "../ControllerPatcherIncludes.hpp" #include "../ControllerPatcherIncludes.hpp"
class ControllerPatcherUtils{ class ControllerPatcherUtils {
//give the other classes access to the private functions. //give the other classes access to the private functions.
friend class ControllerPatcher; friend class ControllerPatcher;
friend class ControllerPatcherHID; friend class ControllerPatcherHID;
friend class ConfigParser; friend class ConfigParser;
public: public:
/** /**
\brief Returns the device slot for a given HID-Mask. \brief Returns the device slot for a given HID-Mask.
\param hidmask 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 \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); static CONTROLLER_PATCHER_RESULT_OR_ERROR getDeviceSlot(u32 hidmask);
/** /**
\brief Returns the device slot for a given HID-Mask. \brief Returns the device slot for a given HID-Mask.
\param handle Given HID-handle \param handle Given HID-handle
\param data Given my_cb_user ** where the result will be stored. Valid pointer when result is >= 0. \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 **. \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); static CONTROLLER_PATCHER_RESULT_OR_ERROR getDataByHandle(s32 handle, my_cb_user ** data);
/** /**
\brief Returns the VID/PID for the given device slot. \brief Returns the VID/PID for the given device slot.
\param deviceslot Given device slot \param deviceslot Given device slot
\param vidpid Pointer to the DeviceVIDPIDInfo struct where the result will be stored. \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 *. \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); static CONTROLLER_PATCHER_RESULT_OR_ERROR getVIDPIDbyDeviceSlot(s32 deviceslot, DeviceVIDPIDInfo * vidpid);
/** \brief Set the VPAD data for a given KPAD data. /** \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 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 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. * \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. * \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,KPADStatus * pro_buffer,u32 * lastButtonsPressesVPAD); static CONTROLLER_PATCHER_RESULT_OR_ERROR translateToVPAD(VPADStatus * vpad_buffer,KPADStatus * pro_buffer,u32 * lastButtonsPressesVPAD);
private: private:
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Analyse inputs * 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 /** \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 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 buttons_hold Pointer to the u32 where the result will be written to.
* \param VPADButton The button that will be checked * \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. * \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); 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. /** \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 data Pointer to the HID_Data from where the input is read.
* \param cur_config slot of the configuration array which will be checked. * \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. * \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); 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. /** \brief Checks if a given key in the keyboard data is pressed.
* *
* \param keyboardData A pointer to the keyboard data. * \param keyboardData A pointer to the keyboard data.
* \param key 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. * \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); static CONTROLLER_PATCHER_RESULT_OR_ERROR isInKeyboardData(unsigned char * keyboardData,s32 key);
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Utils for setting the Button data * 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 /** \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. * 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 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 new_buffer A pointer to a VPADStatus struct where the result will be written.
* \param VPADButton The buttons that will be may replaced * \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. * \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. * \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); 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 \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) 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 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 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 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. \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. \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); static CONTROLLER_PATCHER_RESULT_OR_ERROR setButtonData(VPADStatus * old_buffer, VPADStatus * new_buffer,u32 oldVPADButton,u32 newVPADButton);
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Pad Status functions * Pad Status functions
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/** /**
\brief Checks if a controller is attached for the given HID-Mask and pad. \brief Checks if a controller is attached for the given HID-Mask and pad.
\param hidmask Bit-Mask of the target hid-device. \param hidmask Bit-Mask of the target hid-device.
\param pad Defines for which pad the connection will be checked. \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. \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); 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. \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. \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. \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); static CONTROLLER_PATCHER_RESULT_OR_ERROR getActivePad(u32 hidmask);
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Stick functions * Stick functions
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/** /**
\brief Normalizes the stick to valid values. \brief Normalizes the stick to valid values.
\param stick Pointer to the stick that will be normalized \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. \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); 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. \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 value Given current value of the stick axis
\param default_val Value in neutral axis-position \param default_val Value in neutral axis-position
\param min Value that represents -1.0f \param min Value that represents -1.0f
\param max 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 invert Set to 1 if the axis needs to be inverted
\param deadzone Deadzone \param deadzone Deadzone
\return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. \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); 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. \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) \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. \return The VPADVec2D with the set values.
**/ **/
static VPADVec2D getAnalogValueByButtons(u8 stick_values); static VPADVec2D getAnalogValueByButtons(u8 stick_values);
/** /**
\brief Handles the analog-stick data of HID devices. The result will written in the VPADStatus buffer. \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 data Pointer to the current data of the HID device
\param buffer Pointer to VPADStatus where the analog-stick data will be set. \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. \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); static CONTROLLER_PATCHER_RESULT_OR_ERROR convertAnalogSticks(HID_Data * data,VPADStatus * buffer);
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Mouse functions * Mouse functions
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/** /**
\brief Set the touch data in the VPADStatus buffer. \brief Set the touch data in the VPADStatus buffer.
Currently its only possible to set the touch data from a Mouse Currently its only possible to set the touch data from a Mouse
\param data The current data of the HID device \param data The current data of the HID device
\param buffer Pointer to VPADStatus where the touch data will be set. \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. \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); 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. /** \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. * Currently the incoming data needs to be from a keyboard.
* *
* \param data HID_Data* Pointer to the current data * \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. * \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); static CONTROLLER_PATCHER_RESULT_OR_ERROR checkAndSetMouseMode(HID_Data * data);
/** /**
\brief Set the emulated sticks for a given VPAD data. \brief Set the emulated sticks for a given VPAD data.
\param buffer: A pointer to the 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. \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. \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); static CONTROLLER_PATCHER_RESULT_OR_ERROR setEmulatedSticks(VPADStatus * buffer, u32 * last_emulatedSticks);
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Other functions * Other functions
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/** \brief Set the Pro Controller for a given VPAD data. /** \brief Set the Pro Controller for a given VPAD data.
* *
* \param vpad_buffer VPADStatus* A pointer to the 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 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. * \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. * \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, KPADStatus * pro_buffer, u32 * lastButtonsPressesPRO); static CONTROLLER_PATCHER_RESULT_OR_ERROR translateToPro(VPADStatus * vpad_buffer, KPADStatus * pro_buffer, u32 * lastButtonsPressesPRO);
static CONTROLLER_PATCHER_RESULT_OR_ERROR translateToProWPADRead(VPADStatus * vpad_buffer,WPADStatusProController * pro_buffer); static CONTROLLER_PATCHER_RESULT_OR_ERROR translateToProWPADRead(VPADStatus * vpad_buffer,WPADStatusProController * pro_buffer);
/** /**
\brief Checks if the value at the given device + CONTRPS slot equals the expected value. \brief Checks if the value at the given device + CONTRPS slot equals the expected value.
\param device_slot \param device_slot
\param CONTRPS_slot \param CONTRPS_slot
\param expectedValue \param expectedValue
\return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. \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); static CONTROLLER_PATCHER_RESULT_OR_ERROR checkValueinConfigController(s32 device_slot,s32 CONTRPS_slot,s32 expectedValue);
/** /**
\brief Sets two u8 values to the given pointer. \brief Sets two u8 values to the given pointer.
\param dest: pointer to the destination array. \param dest: pointer to the destination array.
\param first: Value that will be written in @p dest[0] \param first: Value that will be written in @p dest[0]
\param second: Value that will be written in @p dest[1] \param second: Value that will be written in @p dest[1]
**/ **/
static void setConfigValue(u8 * dest , u8 first, u8 second); 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 \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. \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. \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); static CONTROLLER_PATCHER_RESULT_OR_ERROR getNextSlotData(HIDSlotData * slotdata);
/** /**
\brief Fills up a given DeviceInfo, which provides a valid VID/PID, with HIDSlotData. \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. \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. \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); 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 \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 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. slot number relative to this pad.
\param device slot \param device slot
\param current input data \param current input data
\return The relative slot in the device \return The relative slot in the device
**/ **/
static s32 getPadSlotInAdapter(s32 deviceslot, u8 * input_data); static s32 getPadSlotInAdapter(s32 deviceslot, u8 * input_data);
/** /**
\brief returns a pointer to the ControllerMapping to the given controller type \brief returns a pointer to the ControllerMapping to the given controller type
\param type controller type \param type controller type
\return pointer to ControllerMapping data, null is type was invalid \return pointer to ControllerMapping data, null is type was invalid
**/ **/
static ControllerMappingPAD * getControllerMappingByType(UController_Type type); static ControllerMappingPAD * getControllerMappingByType(UController_Type type);
static CONTROLLER_PATCHER_RESULT_OR_ERROR doSampling(u16 deviceslot,u8 padslot,bool ignorePadSlot); static CONTROLLER_PATCHER_RESULT_OR_ERROR doSampling(u16 deviceslot,u8 padslot,bool ignorePadSlot);
static CONTROLLER_PATCHER_RESULT_OR_ERROR doSamplingSingle(WPADChan chan, u16 deviceslot, u8 padslot, bool ignorePadSlot); static CONTROLLER_PATCHER_RESULT_OR_ERROR doSamplingSingle(WPADChan chan, u16 deviceslot, u8 padslot, bool ignorePadSlot);
}; };
#endif /* _CONTROLLER_PATCHER_UTIL_H_ */ #endif /* _CONTROLLER_PATCHER_UTIL_H_ */

View File

@ -70,6 +70,7 @@ u8 gGlobalRumbleActivated __attribute__((section(".data"))) = 0;
u32 gUDPClientip __attribute__((section(".data"))) = 0; u32 gUDPClientip __attribute__((section(".data"))) = 0;
ControllerMappingPADInfo* gProPadInfo[4] __attribute__((section(".data"))) = {&gControllerMapping.proController[0].pad_infos[0], ControllerMappingPADInfo* gProPadInfo[4] __attribute__((section(".data"))) = {&gControllerMapping.proController[0].pad_infos[0],
&gControllerMapping.proController[1].pad_infos[0], &gControllerMapping.proController[1].pad_infos[0],
&gControllerMapping.proController[2].pad_infos[0], &gControllerMapping.proController[2].pad_infos[0],
&gControllerMapping.proController[3].pad_infos[0]} ; &gControllerMapping.proController[3].pad_infos[0]
} ;

View File

@ -58,36 +58,40 @@ const uint8_t HID_GC_BUTTON_R[] = { 0x08,HID_GC_BUTTON_R_VALUE};
const uint8_t HID_GC_BUTTON_DPAD_TYPE[] = { CONTRPDM_Normal,0x00}; const uint8_t HID_GC_BUTTON_DPAD_TYPE[] = { CONTRPDM_Normal,0x00};
const uint8_t HID_GC_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_GC_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x03, //STICK_CONF_BYTE, 0x03, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x09, //STICK_CONF_DEADZONE, 0x09, //STICK_CONF_DEADZONE,
0x00, //STICK_CONF_INVERT, 0x00, //STICK_CONF_INVERT,
0x1A, //STICK_CONF_MIN, 0x1A, //STICK_CONF_MIN,
0xE4};//STICK_CONF_MAX, 0xE4
};//STICK_CONF_MAX,
const uint8_t HID_GC_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_GC_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x04, //STICK_CONF_BYTE, 0x04, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x09, //STICK_CONF_DEADZONE, 0x09, //STICK_CONF_DEADZONE,
0x00, //STICK_CONF_INVERT, 0x00, //STICK_CONF_INVERT,
0x11, //STICK_CONF_MIN, 0x11, //STICK_CONF_MIN,
0xE1};//STICK_CONF_MAX, 0xE1
};//STICK_CONF_MAX,
const uint8_t HID_GC_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_GC_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x05, //STICK_CONF_BYTE, 0x05, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x09, //STICK_CONF_DEADZONE, 0x09, //STICK_CONF_DEADZONE,
0x00, //STICK_CONF_INVERT, 0x00, //STICK_CONF_INVERT,
0x2B, //STICK_CONF_MIN, 0x2B, //STICK_CONF_MIN,
0xE2};//STICK_CONF_MAX, 0xE2
};//STICK_CONF_MAX,
const uint8_t HID_GC_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_GC_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x06, //STICK_CONF_BYTE, 0x06, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x09, //STICK_CONF_DEADZONE, 0x09, //STICK_CONF_DEADZONE,
0x00, //STICK_CONF_INVERT, 0x00, //STICK_CONF_INVERT,
0x1D, //STICK_CONF_MIN, 0x1D, //STICK_CONF_MIN,
0xDB};//STICK_CONF_MAX, 0xDB
};//STICK_CONF_MAX,
//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! DS3 //! DS3
@ -117,36 +121,40 @@ const uint8_t HID_DS3_BUTTON_GUIDE[] = { 0x04,HID_DS3_BUTTON_GUIDE_VALUE};
const uint8_t HID_DS3_BUTTON_DPAD_TYPE[] = { CONTRPDM_Normal,0x00}; const uint8_t HID_DS3_BUTTON_DPAD_TYPE[] = { CONTRPDM_Normal,0x00};
const uint8_t HID_DS3_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_DS3_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x06, //STICK_CONF_BYTE, 0x06, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x06, //STICK_CONF_DEADZONE, 0x06, //STICK_CONF_DEADZONE,
0x00, //STICK_CONF_INVERT, 0x00, //STICK_CONF_INVERT,
0x00, //STICK_CONF_MIN, 0x00, //STICK_CONF_MIN,
0xFF};//STICK_CONF_MAX, 0xFF
};//STICK_CONF_MAX,
const uint8_t HID_DS3_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_DS3_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x07, //STICK_CONF_BYTE, 0x07, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x06, //STICK_CONF_DEADZONE, 0x06, //STICK_CONF_DEADZONE,
0x01, //STICK_CONF_INVERT, 0x01, //STICK_CONF_INVERT,
0x00, //STICK_CONF_MIN, 0x00, //STICK_CONF_MIN,
0xFF};//STICK_CONF_MAX, 0xFF
};//STICK_CONF_MAX,
const uint8_t HID_DS3_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_DS3_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x08, //STICK_CONF_BYTE, 0x08, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x06, //STICK_CONF_DEADZONE, 0x06, //STICK_CONF_DEADZONE,
0x00, //STICK_CONF_INVERT, 0x00, //STICK_CONF_INVERT,
0x00, //STICK_CONF_MIN, 0x00, //STICK_CONF_MIN,
0xFF};//STICK_CONF_MAX, 0xFF
};//STICK_CONF_MAX,
const uint8_t HID_DS3_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_DS3_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x09, //STICK_CONF_BYTE, 0x09, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x06, //STICK_CONF_DEADZONE, 0x06, //STICK_CONF_DEADZONE,
0x01, //STICK_CONF_INVERT, 0x01, //STICK_CONF_INVERT,
0x00, //STICK_CONF_MIN, 0x00, //STICK_CONF_MIN,
0xFF};//STICK_CONF_MAX, 0xFF
};//STICK_CONF_MAX,
//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! DS4 //! DS4
@ -184,36 +192,40 @@ const uint8_t HID_DS4_BUTTON_GUIDE[] = { 0x07,HID_DS4_BUTTON_GUIDE_VALU
const uint8_t HID_DS4_BUTTON_T_PAD_CLICK[] = { 0x07,HID_DS4_BUTTON_T_PAD_CLICK_VALUE}; const uint8_t HID_DS4_BUTTON_T_PAD_CLICK[] = { 0x07,HID_DS4_BUTTON_T_PAD_CLICK_VALUE};
const uint8_t HID_DS4_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_DS4_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x01, //STICK_CONF_BYTE, 0x01, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x06, //STICK_CONF_DEADZONE, 0x06, //STICK_CONF_DEADZONE,
0x00, //STICK_CONF_INVERT, 0x00, //STICK_CONF_INVERT,
0x00, //STICK_CONF_MIN, 0x00, //STICK_CONF_MIN,
0xFF};//STICK_CONF_MAX, 0xFF
};//STICK_CONF_MAX,
const uint8_t HID_DS4_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_DS4_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x02, //STICK_CONF_BYTE, 0x02, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x05, //STICK_CONF_DEADZONE, 0x05, //STICK_CONF_DEADZONE,
0x01, //STICK_CONF_INVERT, 0x01, //STICK_CONF_INVERT,
0x00, //STICK_CONF_MIN, 0x00, //STICK_CONF_MIN,
0xFF};//STICK_CONF_MAX, 0xFF
};//STICK_CONF_MAX,
const uint8_t HID_DS4_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_DS4_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x03, //STICK_CONF_BYTE, 0x03, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x07, //STICK_CONF_DEADZONE, 0x07, //STICK_CONF_DEADZONE,
0x00, //STICK_CONF_INVERT, 0x00, //STICK_CONF_INVERT,
0x00, //STICK_CONF_MIN, 0x00, //STICK_CONF_MIN,
0xFF};//STICK_CONF_MAX, 0xFF
};//STICK_CONF_MAX,
const uint8_t HID_DS4_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_DS4_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x04, //STICK_CONF_BYTE, 0x04, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x09, //STICK_CONF_DEADZONE, 0x09, //STICK_CONF_DEADZONE,
0x01, //STICK_CONF_INVERT, 0x01, //STICK_CONF_INVERT,
0x00, //STICK_CONF_MIN, 0x00, //STICK_CONF_MIN,
0xFF};//STICK_CONF_MAX, 0xFF
};//STICK_CONF_MAX,
//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! XInput //! XInput
@ -243,36 +255,40 @@ const uint8_t HID_XINPUT_BUTTON_DOWN[] = { 0x07,HID_XINPUT_BUTTON_DOWN_VAL
const uint8_t HID_XINPUT_BUTTON_UP[] = { 0x07,HID_XINPUT_BUTTON_UP_VALUE}; const uint8_t HID_XINPUT_BUTTON_UP[] = { 0x07,HID_XINPUT_BUTTON_UP_VALUE};
const uint8_t HID_XINPUT_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_XINPUT_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x00, //STICK_CONF_BYTE, 0x00, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x10, //STICK_CONF_DEADZONE, 0x10, //STICK_CONF_DEADZONE,
0x00, //STICK_CONF_INVERT, 0x00, //STICK_CONF_INVERT,
0x00, //STICK_CONF_MIN, 0x00, //STICK_CONF_MIN,
0xFF};//STICK_CONF_MAX, 0xFF
};//STICK_CONF_MAX,
const uint8_t HID_XINPUT_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_XINPUT_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x01, //STICK_CONF_BYTE, 0x01, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x10, //STICK_CONF_DEADZONE, 0x10, //STICK_CONF_DEADZONE,
0x00, //STICK_CONF_INVERT, 0x00, //STICK_CONF_INVERT,
0x00, //STICK_CONF_MIN, 0x00, //STICK_CONF_MIN,
0xFF};//STICK_CONF_MAX, 0xFF
};//STICK_CONF_MAX,
const uint8_t HID_XINPUT_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_XINPUT_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x02, //STICK_CONF_BYTE, 0x02, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x10, //STICK_CONF_DEADZONE, 0x10, //STICK_CONF_DEADZONE,
0x00, //STICK_CONF_INVERT, 0x00, //STICK_CONF_INVERT,
0x00, //STICK_CONF_MIN, 0x00, //STICK_CONF_MIN,
0xFF};//STICK_CONF_MAX, 0xFF
};//STICK_CONF_MAX,
const uint8_t HID_XINPUT_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_XINPUT_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x03, //STICK_CONF_BYTE, 0x03, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x10, //STICK_CONF_DEADZONE, 0x10, //STICK_CONF_DEADZONE,
0x00, //STICK_CONF_INVERT, 0x00, //STICK_CONF_INVERT,
0x00, //STICK_CONF_MIN, 0x00, //STICK_CONF_MIN,
0xFF};//STICK_CONF_MAX, 0xFF
};//STICK_CONF_MAX,
@ -310,33 +326,37 @@ const uint8_t HID_SWITCH_PRO_BT_BUTTON_DPAD_NEUTRAL[] = { 0x02,HID_SWITCH_PRO_B
const uint8_t HID_SWITCH_PRO_BT_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_SWITCH_PRO_BT_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x04, //STICK_CONF_BYTE, 0x04, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x01, //STICK_CONF_DEADZONE, 0x01, //STICK_CONF_DEADZONE,
0x00, //STICK_CONF_INVERT, 0x00, //STICK_CONF_INVERT,
0x28, //STICK_CONF_MIN, 0x28, //STICK_CONF_MIN,
0xDF};//STICK_CONF_MAX, 0xDF
};//STICK_CONF_MAX,
const uint8_t HID_SWITCH_PRO_BT_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_SWITCH_PRO_BT_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x06, //STICK_CONF_BYTE, 0x06, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x06, //STICK_CONF_DEADZONE, 0x06, //STICK_CONF_DEADZONE,
0x01, //STICK_CONF_INVERT, 0x01, //STICK_CONF_INVERT,
0x16, //STICK_CONF_MIN, 0x16, //STICK_CONF_MIN,
0xD7};//STICK_CONF_MAX, 0xD7
};//STICK_CONF_MAX,
const uint8_t HID_SWITCH_PRO_BT_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_SWITCH_PRO_BT_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x08, //STICK_CONF_BYTE, 0x08, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x04, //STICK_CONF_DEADZONE, 0x04, //STICK_CONF_DEADZONE,
0x00, //STICK_CONF_INVERT, 0x00, //STICK_CONF_INVERT,
0x29, //STICK_CONF_MIN, 0x29, //STICK_CONF_MIN,
0xE2};//STICK_CONF_MAX, 0xE2
};//STICK_CONF_MAX,
const uint8_t HID_SWITCH_PRO_BT_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION const uint8_t HID_SWITCH_PRO_BT_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
0x0A, //STICK_CONF_BYTE, 0x0A, //STICK_CONF_BYTE,
0x80, //STICK_CONF_DEFAULT, 0x80, //STICK_CONF_DEFAULT,
0x08, //STICK_CONF_DEADZONE, 0x08, //STICK_CONF_DEADZONE,
0x01, //STICK_CONF_INVERT, 0x01, //STICK_CONF_INVERT,
0x22, //STICK_CONF_MIN, 0x22, //STICK_CONF_MIN,
0xE4};//STICK_CONF_MAX, 0xE4
};//STICK_CONF_MAX,