mirror of
https://github.com/libretro/RetroArch
synced 2025-01-31 06:32:48 +00:00
Merge pull request #4948 from Maschell/wiiu_controller_patcher
[Wii U] Adding support for HID Controllers
This commit is contained in:
commit
8b4c92291f
4
.gitmodules
vendored
Normal file
4
.gitmodules
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
[submodule "wiiu/controller_patcher"]
|
||||
path = wiiu/controller_patcher
|
||||
url = https://github.com/Maschell/controller_patcher
|
||||
branch = retroarch
|
@ -13,6 +13,21 @@ OBJ += wiiu/system/memory.o
|
||||
OBJ += wiiu/system/exception_handler.o
|
||||
OBJ += wiiu/fs/sd_fat_devoptab.o
|
||||
OBJ += wiiu/fs/fs_utils.o
|
||||
OBJ += wiiu/controller_patcher/ControllerPatcher.o
|
||||
OBJ += wiiu/controller_patcher/ControllerPatcherWrapper.o
|
||||
OBJ += wiiu/controller_patcher/ConfigReader.o
|
||||
OBJ += wiiu/controller_patcher/config/ConfigParser.o
|
||||
OBJ += wiiu/controller_patcher/config/ConfigValues.o
|
||||
OBJ += wiiu/controller_patcher/network/ControllerPatcherNet.o
|
||||
OBJ += wiiu/controller_patcher/network/TCPServer.o
|
||||
OBJ += wiiu/controller_patcher/network/UDPClient.o
|
||||
OBJ += wiiu/controller_patcher/network/UDPServer.o
|
||||
OBJ += wiiu/controller_patcher/patcher/ControllerPatcherUtils.o
|
||||
OBJ += wiiu/controller_patcher/patcher/ControllerPatcherHID.o
|
||||
OBJ += wiiu/controller_patcher/utils/CPRetainVars.o
|
||||
OBJ += wiiu/controller_patcher/utils/CPStringTools.o
|
||||
OBJ += wiiu/controller_patcher/utils/PadConst.o
|
||||
OBJ += wiiu/controller_patcher/utils/FSHelper.o
|
||||
OBJ += wiiu/tex_shader.o
|
||||
OBJ += wiiu/hbl.o
|
||||
|
||||
@ -138,7 +153,7 @@ ifeq ($(WHOLE_ARCHIVE_LINK), 1)
|
||||
WHOLE_START := -Wl,--whole-archive
|
||||
WHOLE_END := -Wl,--no-whole-archive
|
||||
endif
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions
|
||||
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -D_GNU_SOURCE
|
||||
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
|
||||
|
@ -54,9 +54,10 @@
|
||||
#include <wiiu/vpad.h>
|
||||
#include <wiiu/kpad.h>
|
||||
|
||||
#include "wiiu/controller_patcher/ControllerPatcherWrapper.h"
|
||||
|
||||
#include <fat.h>
|
||||
#include <iosuhax.h>
|
||||
|
||||
#include "wiiu_dbg.h"
|
||||
#include "hbl.h"
|
||||
|
||||
@ -405,7 +406,8 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
verbosity_enable();
|
||||
|
||||
printf("starting\n");
|
||||
ControllerPatcherInit();
|
||||
|
||||
fflush(stdout);
|
||||
DEBUG_VAR(ARGV_PTR);
|
||||
if(ARGV_PTR && ((u32)ARGV_PTR < 0x01000000))
|
||||
@ -458,6 +460,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
while (1);
|
||||
|
||||
ControllerPatcherDeInit();
|
||||
|
||||
main_exit(NULL);
|
||||
#endif
|
||||
#endif
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include <wiiu/vpad.h>
|
||||
#include <wiiu/kpad.h>
|
||||
|
||||
#include "wiiu/controller_patcher/ControllerPatcherWrapper.h"
|
||||
|
||||
#include "../input_config.h"
|
||||
#include "../input_driver.h"
|
||||
#include "../input_joypad_driver.h"
|
||||
@ -33,7 +35,7 @@
|
||||
#include "wiiu_dbg.h"
|
||||
|
||||
#ifndef MAX_PADS
|
||||
#define MAX_PADS 5
|
||||
#define MAX_PADS 16
|
||||
#endif
|
||||
|
||||
#define WIIUINPUT_TYPE_WIIMOTE 0x00
|
||||
@ -42,22 +44,33 @@
|
||||
#define WIIUINPUT_TYPE_PRO_CONTROLLER 0x1F
|
||||
#define WIIUINPUT_TYPE_NONE 0xFD
|
||||
|
||||
#define GAMEPAD_COUNT 1
|
||||
#define KPAD_COUNT 4
|
||||
#define HID_COUNT (MAX_PADS - GAMEPAD_COUNT - KPAD_COUNT)
|
||||
#define GAMEPAD_OFFSET 0
|
||||
#define KPAD_OFFSET (GAMEPAD_OFFSET + GAMEPAD_COUNT)
|
||||
#define HID_OFFSET (KPAD_OFFSET + KPAD_COUNT)
|
||||
|
||||
static uint64_t pad_state[MAX_PADS];
|
||||
static u8 pad_type[MAX_PADS - 1] = {WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE};
|
||||
static u8 pad_type[KPAD_COUNT] = {WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE, WIIUINPUT_TYPE_NONE};
|
||||
|
||||
static u8 hid_status[HID_COUNT];
|
||||
static InputData hid_data[HID_COUNT];
|
||||
static int16_t analog_state[MAX_PADS][2][2];
|
||||
extern uint64_t lifecycle_state;
|
||||
static bool wiiu_pad_inited = false;
|
||||
|
||||
|
||||
static char hidName[HID_COUNT][255];
|
||||
|
||||
static const char* wiiu_joypad_name(unsigned pad)
|
||||
{
|
||||
if (pad == 0)
|
||||
return "WIIU Gamepad";
|
||||
|
||||
if (pad < MAX_PADS)
|
||||
if (pad < MAX_PADS && pad < (HID_OFFSET) && pad > GAMEPAD_OFFSET)
|
||||
{
|
||||
switch (pad_type[pad - 1])
|
||||
int i = pad - KPAD_OFFSET;
|
||||
switch (pad_type[i])
|
||||
{
|
||||
case WIIUINPUT_TYPE_NONE:
|
||||
return "N/A";
|
||||
@ -76,6 +89,12 @@ static const char* wiiu_joypad_name(unsigned pad)
|
||||
}
|
||||
}
|
||||
|
||||
if(pad < MAX_PADS){
|
||||
s32 hid_index = pad-HID_OFFSET;
|
||||
sprintf(hidName[hid_index],"HID %04X/%04X",hid_data[hid_index].device_info.vidpid.vid,hid_data[hid_index].device_info.vidpid.pid);
|
||||
return hidName[hid_index];
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
@ -158,9 +177,7 @@ static void wiiu_joypad_poll(void)
|
||||
int c;
|
||||
VPADStatus vpad;
|
||||
VPADReadError vpadError;
|
||||
|
||||
VPADRead(0, &vpad, 1, &vpadError);
|
||||
|
||||
if (!vpadError)
|
||||
{
|
||||
pad_state[0] = vpad.hold & ~0x7F800000; /* clear out emulated analog sticks */
|
||||
@ -228,11 +245,40 @@ static void wiiu_joypad_poll(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memset(hid_data,0,sizeof(hid_data));
|
||||
int result = gettingInputAllDevices(hid_data,HID_COUNT);
|
||||
|
||||
if(result+HID_OFFSET > MAX_PADS){
|
||||
result = MAX_PADS - HID_OFFSET;
|
||||
}
|
||||
for(int i = HID_OFFSET;i<result+HID_OFFSET;i++){
|
||||
int hid_index = i-HID_OFFSET;
|
||||
u8 old_status = hid_status[hid_index];
|
||||
u8 new_status = hid_data[hid_index].status; //TODO: defines for the status.
|
||||
|
||||
if(old_status == 1 || new_status == 1){
|
||||
hid_status[hid_index] = new_status;
|
||||
if(old_status == 0 && new_status == 1){ //Pas was attached
|
||||
wiiu_joypad_autodetect_add(i);
|
||||
}else if(old_status == 1 && new_status == 0){ //Pad was detached
|
||||
input_autoconfigure_disconnect(i, wiiu_joypad.ident);
|
||||
}else if(old_status == 1 && new_status == 1){ // Pad is still connected
|
||||
pad_state[i] = hid_data[hid_index].button_data.hold & ~0x7F800000; /* clear out emulated analog sticks */
|
||||
analog_state[i][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_X] = hid_data[hid_index].stick_data.leftStickX * 0x7FF0;
|
||||
analog_state[i][RETRO_DEVICE_INDEX_ANALOG_LEFT] [RETRO_DEVICE_ID_ANALOG_Y] = hid_data[hid_index].stick_data.leftStickY * 0x7FF0;
|
||||
analog_state[i][RETRO_DEVICE_INDEX_ANALOG_RIGHT] [RETRO_DEVICE_ID_ANALOG_X] = hid_data[hid_index].stick_data.rightStickX * 0x7FF0;
|
||||
analog_state[i][RETRO_DEVICE_INDEX_ANALOG_RIGHT] [RETRO_DEVICE_ID_ANALOG_Y] = hid_data[hid_index].stick_data.rightStickY * 0x7FF0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool wiiu_joypad_init(void* data)
|
||||
{
|
||||
wiiu_joypad_autodetect_add(0);
|
||||
memset(hid_status,0,sizeof(hid_status));
|
||||
|
||||
wiiu_joypad_poll();
|
||||
wiiu_pad_inited = true;
|
||||
(void)data;
|
||||
|
@ -540,6 +540,7 @@ const char* const input_builtin_autoconfs[] =
|
||||
#endif
|
||||
#ifdef WIIU
|
||||
DECL_AUTOCONF_DEVICE("WIIU Gamepad", "wiiu", WIIUINPUT_GAMEPAD_DEFAULT_BINDS),
|
||||
DECL_AUTOCONF_DEVICE("HID Controller", "wiiu", WIIUINPUT_GAMEPAD_DEFAULT_BINDS),
|
||||
DECL_AUTOCONF_DEVICE("WIIU Pro Controller", "wiiu", WIIUINPUT_PRO_CONTROLLER_DEFAULT_BINDS),
|
||||
DECL_AUTOCONF_DEVICE("Wiimote Controller", "wiiu", WIIUINPUT_WIIMOTE_DEFAULT_BINDS),
|
||||
DECL_AUTOCONF_DEVICE("Nunchuk Controller", "wiiu", WIIUINPUT_NUNCHUK_DEFAULT_BINDS),
|
||||
|
158
wiiu/controller_patcher/ConfigReader.cpp
Normal file
158
wiiu/controller_patcher/ConfigReader.cpp
Normal file
@ -0,0 +1,158 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "./ConfigReader.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <map>
|
||||
|
||||
#include "wiiu/fs.h"
|
||||
#include "wiiu/controller_patcher/utils/FSHelper.h"
|
||||
|
||||
#define FS_MOUNT_SOURCE_SIZE 0x300
|
||||
#define FS_MAX_MOUNTPATH_SIZE 12
|
||||
|
||||
#define FS_CLIENT_SIZE 0x1700
|
||||
#define FS_CMD_BLOCK_SIZE 0xA80
|
||||
|
||||
#define FS_SOURCETYPE_EXTERNAL 0
|
||||
#define FS_SOURCETYPE_HFIO 1
|
||||
|
||||
s32 ConfigReader::numberValidFiles = 0;
|
||||
ConfigReader *ConfigReader::instance = NULL;
|
||||
|
||||
ConfigReader::ConfigReader(){
|
||||
}
|
||||
|
||||
void ConfigReader::ReadAllConfigs(){
|
||||
std::vector<std::string> fileList = ScanFolder();
|
||||
if(fileList.size() > 0){
|
||||
if(HID_DEBUG){ printf("ConfigReader::ConfigReader(line %d): Found %d config files\n",__LINE__,fileList.size()); }
|
||||
processFileList(fileList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ConfigReader::~ConfigReader(){
|
||||
if(HID_DEBUG){ printf("ConfigReader::~ConfigReader(line %d): ~ConfigReader\n",__LINE__); }
|
||||
freeFSHandles();
|
||||
}
|
||||
|
||||
void ConfigReader::freeFSHandles(){
|
||||
if(this->pClient != NULL){
|
||||
FSDelClient((FSClient *)this->pClient,-1);
|
||||
free(this->pClient);
|
||||
this->pClient = NULL;
|
||||
}
|
||||
if(this->pCmd != NULL){
|
||||
free(this->pCmd);
|
||||
this->pCmd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Mounting the sdcard without any external lib to be portable (Currently broken)
|
||||
s32 ConfigReader::InitSDCard(){
|
||||
if(HID_DEBUG){ printf("ConfigReader::InitSDCard(line %d): InitSDCard\n",__LINE__); }
|
||||
|
||||
int result = -1;
|
||||
|
||||
// get command and client
|
||||
this->pClient = malloc(sizeof(FSClient));
|
||||
this->pCmd = malloc(sizeof(FSCmdBlock));
|
||||
|
||||
if(!pClient || !pCmd) {
|
||||
// just in case free if not 0
|
||||
if(pClient)
|
||||
free(pClient);
|
||||
if(pCmd)
|
||||
free(pCmd);
|
||||
return -2;
|
||||
}
|
||||
|
||||
FSInit();
|
||||
FSInitCmdBlock((FSCmdBlock*)pCmd);
|
||||
FSAddClient((FSClient*)pClient, -1);
|
||||
|
||||
char *mountPath = NULL;
|
||||
|
||||
if((result = FS_Helper_MountFS(pClient, pCmd, &mountPath)) == 0) {
|
||||
//free(mountPath);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> ConfigReader::ScanFolder(){
|
||||
std::string path = CONTROLLER_PATCHER_PATH;
|
||||
s32 dirhandle = 0;
|
||||
if(HID_DEBUG){ printf("ConfigReader::ScanFolder(line %d): Opening %s\n",__LINE__,path.c_str()); }
|
||||
std::vector<std::string> config_files;
|
||||
if (this->pClient && this->pCmd){
|
||||
s32 status = 0;
|
||||
if((status = FSOpenDir((FSClient*)this->pClient,(FSCmdBlock*)this->pCmd,path.c_str(),(FSDirectoryHandle *)&dirhandle,-1)) == FS_STATUS_OK){
|
||||
FSDirectoryEntry dir_entry;
|
||||
while (FSReadDir((FSClient*)this->pClient,(FSCmdBlock*)this->pCmd, dirhandle, &dir_entry, -1) == FS_STATUS_OK){
|
||||
std::string full_path = path + "/" + dir_entry.name;
|
||||
if((dir_entry.info.flags&FS_STAT_DIRECTORY) != FS_STAT_DIRECTORY){
|
||||
if(CPStringTools::EndsWith(std::string(dir_entry.name),".ini")){
|
||||
config_files.push_back(full_path);
|
||||
if(HID_DEBUG){ printf("ConfigReader::ScanFolder(line %d): %s \n",__LINE__,full_path.c_str()); }
|
||||
}
|
||||
}
|
||||
}
|
||||
FSCloseDir((FSClient*)this->pClient,(FSCmdBlock*)this->pCmd,dirhandle,-1);
|
||||
}else{
|
||||
printf("ConfigReader::ScanFolder(line %d): Failed to open %s!\n",__LINE__,path.c_str());
|
||||
}
|
||||
}
|
||||
return config_files;
|
||||
}
|
||||
|
||||
void ConfigReader::processFileList(std::vector<std::string> path){
|
||||
|
||||
for(std::vector<std::string>::iterator it = path.begin(); it != path.end(); ++it) {
|
||||
printf("ConfigReader::processFileList(line %d): Reading %s\n",__LINE__,it->c_str());
|
||||
std::string result = loadFileToString(*it);
|
||||
|
||||
ConfigParser parser(result);
|
||||
parser.parseIni();
|
||||
}
|
||||
}
|
||||
|
||||
std::string ConfigReader::loadFileToString(std::string path){
|
||||
FSFileHandle handle = 0;
|
||||
s32 status = 0;
|
||||
std::string strBuffer;
|
||||
char * result = NULL;
|
||||
if(FS_Helper_GetFile(this->pClient,this->pCmd,path.c_str(), &result) == 0){
|
||||
if(result != NULL){
|
||||
strBuffer = std::string((char *)result);
|
||||
free(result);
|
||||
result = NULL;
|
||||
|
||||
//! remove all windows crap signs
|
||||
strBuffer = CPStringTools::removeCharFromString(strBuffer,'\r');
|
||||
strBuffer = CPStringTools::removeCharFromString(strBuffer,' ');
|
||||
strBuffer = CPStringTools::removeCharFromString(strBuffer,'\t');
|
||||
}
|
||||
}else{
|
||||
printf("ConfigReader::loadFileToString(line %d): Failed to load %s\n",__LINE__,path.c_str());
|
||||
}
|
||||
return strBuffer;
|
||||
}
|
74
wiiu/controller_patcher/ConfigReader.hpp
Normal file
74
wiiu/controller_patcher/ConfigReader.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#ifndef _ConfigReader_H_
|
||||
#define _ConfigReader_H_
|
||||
|
||||
#include <wiiu/types.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "./ControllerPatcher.hpp"
|
||||
|
||||
#define CONTROLLER_PATCHER_PATH "/vol/external01/wiiu/controller";
|
||||
|
||||
class ConfigReader{
|
||||
friend class ControllerPatcher;
|
||||
friend class ConfigParser;
|
||||
private:
|
||||
static ConfigReader *getInstance() {
|
||||
if(!instance){
|
||||
instance = new ConfigReader();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void destroyInstance() {
|
||||
if(instance){
|
||||
delete instance;
|
||||
instance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static s32 getNumberOfLoadedFiles(){
|
||||
return ConfigReader::numberValidFiles;
|
||||
}
|
||||
|
||||
static void increaseNumberOfLoadedFiles(){
|
||||
ConfigReader::numberValidFiles++;
|
||||
}
|
||||
void ReadAllConfigs();
|
||||
static s32 numberValidFiles;
|
||||
|
||||
//!Constructor
|
||||
ConfigReader();
|
||||
//!Destructor
|
||||
~ConfigReader();
|
||||
|
||||
s32 InitSDCard();
|
||||
void freeFSHandles();
|
||||
|
||||
void * pClient = NULL;
|
||||
void * pCmd = NULL;
|
||||
static ConfigReader *instance;
|
||||
|
||||
std::string loadFileToString(std::string path);
|
||||
void processFileList(std::vector<std::string> path);
|
||||
|
||||
std::vector<std::string> ScanFolder();
|
||||
};
|
||||
#endif
|
1086
wiiu/controller_patcher/ControllerPatcher.cpp
Normal file
1086
wiiu/controller_patcher/ControllerPatcher.cpp
Normal file
File diff suppressed because it is too large
Load Diff
251
wiiu/controller_patcher/ControllerPatcher.hpp
Normal file
251
wiiu/controller_patcher/ControllerPatcher.hpp
Normal file
@ -0,0 +1,251 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file ControllerPatcher.hpp
|
||||
* @author Maschell
|
||||
* @date 30 Mar 2017
|
||||
* \brief This files contain all public accessible functions of the controller patcher engine
|
||||
*
|
||||
* @see https://github.com/Maschell/controller_patcher
|
||||
*/
|
||||
|
||||
#ifndef _CONTROLLER_PATCHER_H_
|
||||
#define _CONTROLLER_PATCHER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "./patcher/ControllerPatcherDefs.h"
|
||||
#include "./utils/ControllerPatcherThread.hpp"
|
||||
#include "./utils/CPRetainVars.hpp"
|
||||
#include "./utils/PadConst.hpp"
|
||||
#include "./utils/CPStringTools.hpp"
|
||||
|
||||
#include "./patcher/ControllerPatcherHID.hpp"
|
||||
#include "./patcher/ControllerPatcherUtils.hpp"
|
||||
|
||||
#include "./config/ConfigValues.hpp"
|
||||
#include "./config/ConfigParser.hpp"
|
||||
|
||||
#include "./network/ControllerPatcherNet.hpp"
|
||||
#include "./network/TCPServer.hpp"
|
||||
#include "./network/UDPServer.hpp"
|
||||
#include "./network/UDPClient.hpp"
|
||||
#include "./ConfigReader.hpp"
|
||||
|
||||
#include "wiiu/vpad.h"
|
||||
|
||||
#define BUS_SPEED 248625000
|
||||
#define SECS_TO_TICKS(sec) (((unsigned long long)(sec)) * (BUS_SPEED/4))
|
||||
#define MILLISECS_TO_TICKS(msec) (SECS_TO_TICKS(msec) / 1000)
|
||||
#define MICROSECS_TO_TICKS(usec) (SECS_TO_TICKS(usec) / 1000000)
|
||||
|
||||
#define wiiu_os_usleep(usecs) OSSleepTicks(MICROSECS_TO_TICKS(usecs))
|
||||
|
||||
#define HID_DEBUG 0
|
||||
|
||||
class ControllerPatcher{
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------
|
||||
* Initialization
|
||||
*----------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
\brief Resets the data thats used by the controller configuration
|
||||
**/
|
||||
static void ResetConfig();
|
||||
/**
|
||||
\brief Initializes the libraries, functions, values and arrays. Need to be called on each start of an Application. Returns false on errors.
|
||||
**/
|
||||
static bool Init();
|
||||
|
||||
/**
|
||||
\brief De-Initialises the controller_patcher
|
||||
**/
|
||||
static void DeInit();
|
||||
/**
|
||||
Initialises the button remapping
|
||||
**/
|
||||
static void InitButtonMapping();
|
||||
|
||||
/**
|
||||
Starts the network server
|
||||
**/
|
||||
static void startNetworkServer();
|
||||
|
||||
/**
|
||||
Stops the network server
|
||||
**/
|
||||
static void stopNetworkServer();
|
||||
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------
|
||||
* Initialization
|
||||
*----------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
Sets the data in a given data from HID Devices. The information about which HID Device will be used is stored in the gControllerMapping array int slot 1-4 (counting starts at 0, which is the gamepad). The \p
|
||||
chan provides the information of the channel from which the data will be used. The mode sets the type of the buffer.
|
||||
|
||||
@param buffer: A pointer to the struct where the result will be stored.
|
||||
@param chan: Indicates the channel from which slot the information about the mapped HID Device will be used.
|
||||
@param mode: Sets the type of the buffer. PRO_CONTROLLER_MODE_KPADDATA or PRO_CONTROLLER_MODE_WPADReadData
|
||||
|
||||
@return When the functions failed result < 0 is returned. If the result is == 0 the function was successful.
|
||||
**/
|
||||
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR setProControllerDataFromHID(void * data,s32 chan,s32 mode = PRO_CONTROLLER_MODE_KPADDATA);
|
||||
|
||||
|
||||
/**
|
||||
Sets the data in a given VPADStatus from HID Devices. The information about which HID Device will be used is stored in the gControllerMapping array in slot 0.
|
||||
|
||||
@param buffer: A pointer to an KPADData struct where the result will be stored.
|
||||
@param chan: Indicates the channel from which slot the information about the mapped HID Device will be used.
|
||||
|
||||
@return When the functions failed result < 0 is returned. If the result is == 0 the function was successful.
|
||||
**/
|
||||
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR setControllerDataFromHID(VPADStatus * buffer);
|
||||
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------
|
||||
* Useful functions
|
||||
*----------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
Enable the Controller mapping.
|
||||
@return When the functions failed result < 0 is returned. If the result is == 0 the function was successful.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR enableControllerMapping();
|
||||
|
||||
/**
|
||||
Disbale the Controller mapping. Afterwards all connected controllers will be used for the gamepad.
|
||||
@return When the functions failed result < 0 is returned. If the result is == 0 the function was successful.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR disableControllerMapping();
|
||||
|
||||
/**
|
||||
Disables the energy settings for the WiiU. Settings can be restored via restoreWiiUEnergySetting.
|
||||
@return When the functions failed result < 0 is returned. If the result is == 0 the function was successful.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR disableWiiUEnergySetting();
|
||||
|
||||
/**
|
||||
Restores the WiiU Energy Settings.
|
||||
@return When the functions failed result < 0 is returned. If the result is == 0 the function was successful.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR restoreWiiUEnergySetting();
|
||||
|
||||
/**
|
||||
Resets the controller mapping for a given controller type.
|
||||
|
||||
@param type: The type of the controller.
|
||||
|
||||
@return When the functions failed result < 0 is returned. If the result is == 0 the function was successful.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR resetControllerMapping(UController_Type type);
|
||||
|
||||
|
||||
/**
|
||||
Adds a controller mapping
|
||||
|
||||
@param type: The type of the controller.
|
||||
@param config: information about the added controller.
|
||||
|
||||
@return When the functions failed result < 0 is returned. If the result is == 0 the function was successful.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR addControllerMapping(UController_Type type,ControllerMappingPADInfo config);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@return The first active mapping slot for the given controller type will be returned. If the controller type is not set active, -1 will be returned.
|
||||
**/
|
||||
static s32 getActiveMappingSlot(UController_Type type);
|
||||
|
||||
/**
|
||||
@param type: The type of the controller.
|
||||
@param mapping_slot: information about the added controller.
|
||||
@return When the functions failed result < 0 is returned. Otherwise a pointer to a ControllerMappingPADInfo is returned.
|
||||
**/
|
||||
static ControllerMappingPADInfo * getControllerMappingInfo(UController_Type type,s32 mapping_slot);
|
||||
|
||||
/**
|
||||
Checks if a emulated controller is connected for the given controller type / mapping slot.
|
||||
|
||||
@param type: The type of the controller.
|
||||
@param mapping_slot: Slot of the controller mapped to this controller type (usually 0)
|
||||
|
||||
@return
|
||||
**/
|
||||
static bool isControllerConnectedAndActive(UController_Type type,s32 mapping_slot = 0);
|
||||
|
||||
/**
|
||||
Search for a connected mouse and returns a pointer to it's data.
|
||||
@return A pointer to the first connected mouse that is found. NULL if no mouse is connected.
|
||||
**/
|
||||
static HID_Mouse_Data * getMouseData();
|
||||
|
||||
/**
|
||||
Sets a rumble status for a controller.
|
||||
|
||||
@param type: The type of the controller.
|
||||
@param status: status of the rumble. 0 for off, 1 for on.
|
||||
|
||||
@return When the functions failed result < 0 is returned. If the result is == 0 the function was successful.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR setRumble(UController_Type type,u32 status);
|
||||
|
||||
/**
|
||||
Reads the input of all connected HID devices. Each attached controller will write his date into given array until it's full.
|
||||
|
||||
@param output: A pointer to an InputData array where the result will be stored. (Make sure to reset the array before using this function).
|
||||
@param array_size: Size of the given InputData array.
|
||||
|
||||
@return When the functions failed result < 0 is returned. If the result is == 0 the function was successful. If the result is > 0 the number of stored sets in the array is returned.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR gettingInputAllDevices(InputData * output,s32 array_size);
|
||||
|
||||
/**
|
||||
Remaps the buttons in the given \p VPADStatus pointer. InitButtonMapping() needs to be called before calling this. The information about the remapping is stored in the config_controller array.
|
||||
One easy way to set it is using the a config file on the SD Card.
|
||||
|
||||
@param buffer: A pointer to the buffer where the input will be read from and the result will be stored.
|
||||
|
||||
@return When the functions failed result < 0 is returned. If the result is == 0 the function was successful.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR buttonRemapping(VPADStatus * buffer, s32 buffer_count);
|
||||
|
||||
/**
|
||||
Prints the current pressed down buttons of the given \p VPADStatus pointer. Uses the utils/logger.c UDP logger..
|
||||
|
||||
@param buffer: A pointer to the buffer where the input will be read from.
|
||||
|
||||
@return When the functions failed result < 0 is returned. If the result is == 0 the function was successful.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR printVPADButtons(VPADStatus * buffer);
|
||||
|
||||
static std::string getIdentifierByVIDPID(u16 vid,u16 pid);
|
||||
|
||||
static void destroyConfigHelper();
|
||||
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR doSamplingForDeviceSlot(u16 device_slot);
|
||||
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR setRumbleActivated(bool value);
|
||||
|
||||
static bool isRumbleActivated();
|
||||
};
|
||||
|
||||
#endif /* _CONTROLLER_PATCHER_H_ */
|
39
wiiu/controller_patcher/ControllerPatcherWrapper.cpp
Normal file
39
wiiu/controller_patcher/ControllerPatcherWrapper.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "controller_patcher/ControllerPatcher.hpp"
|
||||
#include "controller_patcher/ControllerPatcherWrapper.h"
|
||||
|
||||
extern "C" void ControllerPatcherInit(void){
|
||||
ControllerPatcher::Init();
|
||||
ControllerPatcher::disableControllerMapping();
|
||||
ControllerPatcher::startNetworkServer();
|
||||
ControllerPatcher::disableWiiUEnergySetting();
|
||||
}
|
||||
|
||||
extern "C" CONTROLLER_PATCHER_RESULT_OR_ERROR setControllerDataFromHID(VPADStatus * data){
|
||||
ControllerPatcher::setControllerDataFromHID(data);
|
||||
}
|
||||
|
||||
extern "C" CONTROLLER_PATCHER_RESULT_OR_ERROR gettingInputAllDevices(InputData * output,s32 array_size){
|
||||
ControllerPatcher::gettingInputAllDevices(output,array_size);
|
||||
}
|
||||
|
||||
extern "C" void ControllerPatcherDeInit(void){
|
||||
ControllerPatcher::restoreWiiUEnergySetting();
|
||||
ControllerPatcher::stopNetworkServer();
|
||||
ControllerPatcher::DeInit();
|
||||
}
|
23
wiiu/controller_patcher/ControllerPatcherWrapper.h
Normal file
23
wiiu/controller_patcher/ControllerPatcherWrapper.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef _CONTROLLER_PATCHER_WRAPPER_H_
|
||||
#define _CONTROLLER_PATCHER_WRAPPER_H_
|
||||
|
||||
#include "wiiu/vpad.h"
|
||||
|
||||
/* Main */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "./patcher/ControllerPatcherDefs.h"
|
||||
|
||||
//! C wrapper for our C++ functions
|
||||
void ControllerPatcherInit(void);
|
||||
void ControllerPatcherDeInit(void);
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR setControllerDataFromHID(VPADStatus * data);
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR gettingInputAllDevices(InputData * output,s32 array_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
337
wiiu/controller_patcher/config/ConfigParser.cpp
Normal file
337
wiiu/controller_patcher/config/ConfigParser.cpp
Normal file
@ -0,0 +1,337 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "./ConfigParser.hpp"
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
ConfigParser::ConfigParser(std::string configData){
|
||||
this->content = configData;
|
||||
this->contentLines = CPStringTools::StringSplit(content, "\n");
|
||||
|
||||
if(contentLines.empty())
|
||||
return;
|
||||
|
||||
//remove the comments and make everything uppercase
|
||||
for(u32 i = 0; i < contentLines.size(); i++){
|
||||
std::vector<std::string> comments = CPStringTools::StringSplit(contentLines[i], "//");
|
||||
if(!comments.empty()){
|
||||
contentLines[i] = comments[0];
|
||||
}
|
||||
//we want everything uppercase
|
||||
std::transform(contentLines[i].begin(), contentLines[i].end(),contentLines[i].begin(), ::toupper);
|
||||
}
|
||||
|
||||
//remove empty lines
|
||||
std::vector<std::string> contentline2;
|
||||
for(u32 i = 0; i < contentLines.size(); i++){
|
||||
if(strlen(contentLines[i].c_str()) > 0){
|
||||
contentline2.push_back(contentLines[i]);
|
||||
}
|
||||
}
|
||||
contentLines = contentline2;
|
||||
Init();
|
||||
}
|
||||
|
||||
ConfigParser::~ConfigParser(){
|
||||
|
||||
}
|
||||
|
||||
PARSE_TYPE ConfigParser::getType(){
|
||||
return type_b;
|
||||
}
|
||||
|
||||
void ConfigParser::setType(PARSE_TYPE newType){
|
||||
this->type_b = newType;
|
||||
}
|
||||
|
||||
u16 ConfigParser::getSlot(){
|
||||
return this->slot_b;
|
||||
}
|
||||
|
||||
void ConfigParser::setSlot(u16 newSlot){
|
||||
this->slot_b = newSlot;
|
||||
}
|
||||
|
||||
bool ConfigParser::Init(){
|
||||
if(contentLines.size() == 0){
|
||||
printf("ConfigParser::Init(line %d): Files seems to be empty. Make sure to have a proper header\n",__LINE__);
|
||||
return false;
|
||||
}
|
||||
const char * line = contentLines[0].c_str();
|
||||
s32 len = strlen(line);
|
||||
std::string identify;
|
||||
if(line[0] == '[' && line[len-1] == ']'){
|
||||
identify = contentLines[0].substr(1,len-2);
|
||||
}else{
|
||||
printf("ConfigParser::Init((line %d): Not a proper config file!\n",__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(identify.compare("GAMEPAD") == 0){
|
||||
printf("ConfigParser::Init((line %d): Its a gamepad config file!\n",__LINE__);
|
||||
setSlot(gGamePadSlot);
|
||||
setType(PARSE_GAMEPAD);
|
||||
}else if(identify.compare("MOUSE") == 0){
|
||||
printf("ConfigParser::Init((line %d): Its a mouse config file!\n",__LINE__);
|
||||
setSlot(gMouseSlot);
|
||||
setType(PARSE_MOUSE);
|
||||
this->vid = HID_MOUSE_VID;
|
||||
this->pid = HID_MOUSE_PID;
|
||||
}else if(identify.compare("KEYBOARD") == 0){
|
||||
printf("ConfigParser::Init((line %d): Its a keyboard config file!\n",__LINE__);
|
||||
setSlot(gHID_SLOT_KEYBOARD);
|
||||
setType(PARSE_KEYBOARD);
|
||||
this->vid = HID_KEYBOARD_VID;
|
||||
this->pid = HID_KEYBOARD_PID;
|
||||
}else{
|
||||
printf("ConfigParser::Init((line %d): Its a controller config file!\n",__LINE__);
|
||||
|
||||
setSlot(getSlotController(identify));
|
||||
setType(PARSE_CONTROLLER);
|
||||
}
|
||||
|
||||
if(getSlot() == HID_INVALID_SLOT){
|
||||
return false;
|
||||
}
|
||||
|
||||
ConfigReader::increaseNumberOfLoadedFiles();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ConfigParser::parseSingleLine(std::string line){
|
||||
std::vector<std::string> cur_values = CPStringTools::StringSplit(line,"=");
|
||||
if(cur_values.size() != 2){
|
||||
if(HID_DEBUG || cur_values.size() > 2){ printf("ConfigParser::parseSingleLine(line %d): Not a valid key=pair line %s\n",__LINE__,line.c_str()); }
|
||||
return;
|
||||
}else{
|
||||
u16 hid_slot = getSlot();
|
||||
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): leftpart = \"%s\" \n",__LINE__,cur_values[0].c_str()); }
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): rightpart = \"%s\" \n",__LINE__,cur_values[1].c_str()); }
|
||||
s32 keyslot = -1;
|
||||
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Checking single value\n",__LINE__); }
|
||||
if(getType() == PARSE_GAMEPAD || getType() == PARSE_KEYBOARD){
|
||||
keyslot = ConfigValues::getKeySlotGamePad(cur_values[0]);
|
||||
}else if(getType() == PARSE_MOUSE){
|
||||
keyslot = ConfigValues::getKeySlotMouse(cur_values[0]);
|
||||
}else{
|
||||
keyslot = ConfigValues::getKeySlotDefaultSingleValue(cur_values[0]);
|
||||
}
|
||||
if(keyslot != -1){
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Its a single value\n",__LINE__); }
|
||||
long rightValue = -1;
|
||||
bool valueSet = false;
|
||||
if(cur_values[0].compare("DPAD_MODE") == 0){
|
||||
const u8 * values_ = NULL;
|
||||
if((values_ = ConfigValues::getValuesStickPreset(cur_values[1])) != NULL){
|
||||
if(values_[STICK_CONF_MAGIC_VERSION] != STICK_CONF_MAGIC_VALUE)
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Settings preset DPAD MODE and Mask\n",__LINE__); }
|
||||
config_controller[hid_slot][CONTRPS_DPAD_MODE][0] = CONTROLLER_PATCHER_VALUE_SET;
|
||||
config_controller[hid_slot][CONTRPS_DPAD_MODE][1] = values_[CONTRDPAD_MODE];
|
||||
if(values_[CONTRDPAD_MASK] != 0x00){
|
||||
config_controller[hid_slot][CONTRPS_DPAD_MASK][0] = CONTROLLER_PATCHER_VALUE_SET;
|
||||
config_controller[hid_slot][CONTRPS_DPAD_MASK][1] = values_[CONTRDPAD_MASK];
|
||||
}
|
||||
valueSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!valueSet){
|
||||
if(getType() == PARSE_KEYBOARD){
|
||||
if((rightValue = ConfigValues::getPresetValuesKeyboard(cur_values[1]))!= -1){
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Used pre-defined Keyboard! \"%s\" is %d\n",__LINE__,cur_values[1].c_str(),rightValue);}
|
||||
}else{
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): I need to parse %s\n",__LINE__,cur_values[1].c_str()); }
|
||||
char * ptr;
|
||||
rightValue = strtol(cur_values[1].c_str(),&ptr,16);
|
||||
}
|
||||
}else{
|
||||
rightValue = ConfigValues::getPresetValue(cur_values[1]);
|
||||
|
||||
if(getType() == PARSE_MOUSE){ //No parsing for the mouse
|
||||
if(rightValue == -1){
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Invalid mouse value, lets skip it %s\n",__LINE__,cur_values[1].c_str()); }
|
||||
return;
|
||||
}
|
||||
}else{
|
||||
if(rightValue == -1){
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): I need to parse %s\n",__LINE__,cur_values[1].c_str()); }
|
||||
char * ptr;
|
||||
rightValue = strtol(cur_values[1].c_str(),&ptr,16);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Setting value to %d\n",__LINE__,rightValue); }
|
||||
|
||||
config_controller[hid_slot][keyslot][0] = CONTROLLER_PATCHER_VALUE_SET;
|
||||
config_controller[hid_slot][keyslot][1] = rightValue;
|
||||
}
|
||||
}else{
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Check pair value\n",__LINE__); }
|
||||
keyslot = ConfigValues::getKeySlotDefaultPairedValue(cur_values[0]);
|
||||
if(keyslot != -1){
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Its a pair value\n",__LINE__); }
|
||||
|
||||
if(!ConfigValues::getInstance()->setIfValueIsAControllerPreset(cur_values[1],getSlot(),keyslot)){
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): And its no preset\n",__LINE__); }
|
||||
std::vector<std::string> rightvalues = CPStringTools::StringSplit(cur_values[1],",");
|
||||
|
||||
if(rightvalues.size() != 2){
|
||||
printf("ConfigParser::parseSingleLine(line %d): %d instead of 2 key=values pairs in line\n",__LINE__,rightvalues.size());
|
||||
return;
|
||||
}
|
||||
|
||||
char * ptr;
|
||||
long firstValue = strtol(rightvalues[0].c_str(),&ptr,16);
|
||||
long secondValue = strtol(rightvalues[1].c_str(),&ptr,16);
|
||||
config_controller[hid_slot][keyslot][0] = firstValue;
|
||||
config_controller[hid_slot][keyslot][1] = secondValue;
|
||||
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Set %02X,%02X\n",__LINE__,firstValue,secondValue); }
|
||||
}else{
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseSingleLine(line %d): Found preset value!!\n",__LINE__); }
|
||||
}
|
||||
}else{
|
||||
printf("ConfigParser::parseSingleLine(line %d): The setting \"%s\" is unknown!\n",__LINE__,cur_values[0].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ConfigParser::resetConfig(){
|
||||
s32 slot = getSlot();
|
||||
if(slot >= gHIDMaxDevices) return false;
|
||||
for(s32 j = (CONTRPS_PID+1);j< CONTRPS_MAX_VALUE;j++){
|
||||
config_controller[slot][j][0] = CONTROLLER_PATCHER_INVALIDVALUE;
|
||||
config_controller[slot][j][1] = CONTROLLER_PATCHER_INVALIDVALUE;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
s32 ConfigParser::getSlotController(std::string identify){
|
||||
if(HID_DEBUG){ printf("ConfigParser::getSlotController(line %d): Getting Controller Slot\n",__LINE__); }
|
||||
|
||||
std::vector<std::string> values = CPStringTools::StringSplit(identify,",");
|
||||
|
||||
if(values.size() != 2){
|
||||
printf("ConfigParser::getSlotController(line %d): You need to provide a VID and PID. e.g. \"[vid=0x451,pid=0x152]\". (%s)\n",__LINE__,identify.c_str());
|
||||
return HID_INVALID_SLOT;
|
||||
}
|
||||
|
||||
s32 vid = getValueFromKeyValue(values[0],"VID","=");
|
||||
if(vid < 0){
|
||||
return HID_INVALID_SLOT;
|
||||
}
|
||||
s32 pid = getValueFromKeyValue(values[1],"PID","=");
|
||||
if(pid < 0){
|
||||
return HID_INVALID_SLOT;
|
||||
}
|
||||
printf("ConfigParser::getSlotController(line %d): VID: %04x PID: %04x\n",__LINE__,vid,pid);
|
||||
|
||||
this->vid = vid;
|
||||
this->pid = pid;
|
||||
DeviceInfo deviceinfo;
|
||||
memset(&deviceinfo,0,sizeof(deviceinfo));
|
||||
deviceinfo.vidpid.vid = vid;
|
||||
deviceinfo.vidpid.pid = pid;
|
||||
s32 result = ControllerPatcherUtils::getDeviceInfoFromVidPid(&deviceinfo);
|
||||
s32 slot = deviceinfo.slotdata.deviceslot;
|
||||
s32 hid = 0;
|
||||
if(result < 0){
|
||||
if(HID_DEBUG){ printf("ConfigParser::getSlotController(line %d): Its a new controller, lets save it\n",__LINE__); }
|
||||
|
||||
HIDSlotData slotdata;
|
||||
ControllerPatcherUtils::getNextSlotData(&slotdata);
|
||||
|
||||
slot = slotdata.deviceslot;
|
||||
hid = slotdata.hidmask;
|
||||
|
||||
if(slot >= gHIDMaxDevices){
|
||||
printf("ConfigParser::getSlotController(line %d): ConfigParser::getSlotController: We don't a space for a new controller, please delete .inis\n",__LINE__);
|
||||
return HID_INVALID_SLOT;
|
||||
}
|
||||
if(HID_DEBUG){ printf("ConfigParser::getSlotController(line %d): Got new slot! slot: %d hid %s .. Lets registrate it!\n",__LINE__,slot,CPStringTools::byte_to_binary(hid)); }
|
||||
config_controller[slot][CONTRPS_VID][0] = (vid & 0xFF00) >> 8;
|
||||
config_controller[slot][CONTRPS_VID][1] = (vid & 0x00FF);
|
||||
config_controller[slot][CONTRPS_PID][0] = (pid & 0xFF00) >> 8;
|
||||
config_controller[slot][CONTRPS_PID][1] = (pid & 0x00FF);
|
||||
|
||||
if(HID_DEBUG){
|
||||
printf("ConfigParser::getSlotController(line %d): Saved vid: %04X pid: %04X\n",__LINE__,
|
||||
config_controller[slot][CONTRPS_VID][0] * 0x100 + config_controller[slot][CONTRPS_VID][1],
|
||||
config_controller[slot][CONTRPS_PID][0] * 0x100 + config_controller[slot][CONTRPS_PID][1]); }
|
||||
|
||||
config_controller_hidmask[slot] = hid;
|
||||
if(HID_DEBUG){ printf("ConfigParser::getSlotController(line %d): Saved the hid\n",__LINE__); }
|
||||
|
||||
}else{
|
||||
if(slot < gHIDMaxDevices){
|
||||
hid = config_controller_hidmask[slot];
|
||||
if(HID_DEBUG){ printf("ConfigParser::getSlotController(line %d): >>>>>> found slot %d (hid:%s). Modifing existing data <<<<<<<<\n",__LINE__,slot,CPStringTools::byte_to_binary(hid)); }
|
||||
printf("ConfigParser::getSlotController(line %d): We already have data of this controller, lets modify it\n",__LINE__);
|
||||
}else{
|
||||
printf("ConfigParser::getSlotController(line %d): Something really odd happend to the slots. %d is bigger then max (%d)\n",__LINE__,slot,gHIDMaxDevices);
|
||||
return HID_INVALID_SLOT;
|
||||
}
|
||||
}
|
||||
|
||||
printf("ConfigParser::getSlotController(line %d): using slot: %d hid %08X\n",__LINE__,slot,hid);
|
||||
return slot;
|
||||
}
|
||||
|
||||
bool ConfigParser::parseIni(){
|
||||
if(getSlot() == HID_INVALID_SLOT){
|
||||
printf("ConfigParser::parseIni(line %d): Couldn't parse file. Not a valid slot. Probably broken config. Or you tried to have more than %d devices\n",__LINE__,getType(),gHIDMaxDevices);
|
||||
}
|
||||
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseIni(line %d): Parsing content, type %d\n",__LINE__,getType()); }
|
||||
|
||||
s32 start = 1;
|
||||
if(contentLines[1].compare("[IGNOREDEFAULT]") == 0){
|
||||
resetConfig();
|
||||
printf("ConfigParser::parseIni(line %d): Ignoring existing settings of this device\n",__LINE__);
|
||||
start++;
|
||||
}
|
||||
|
||||
for(u32 i = start; i < contentLines.size(); i++){
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseIni(line %d): line %d: \"%s\" \n",__LINE__,(i+1),contentLines[i].c_str()); }
|
||||
parseSingleLine(contentLines[i]);
|
||||
}
|
||||
|
||||
if(HID_DEBUG){ printf("ConfigParser::parseIni(line %d): Parsing of the file is done.\n",__LINE__); }
|
||||
return true;
|
||||
}
|
||||
|
||||
s32 ConfigParser::getValueFromKeyValue(std::string value_pair,std::string expectedKey,std::string delimiter){
|
||||
std::vector<std::string> string_value = CPStringTools::StringSplit(value_pair,delimiter);
|
||||
if(string_value.size() != 2){
|
||||
if(HID_DEBUG || string_value.size() > 2){ printf("ConfigParser::getValueFromKeyValue(line %d): Not a valid key=pair line %s\n",__LINE__,value_pair.c_str()); }
|
||||
return -1;
|
||||
}
|
||||
if(string_value[0].compare(expectedKey) != 0){
|
||||
printf("ConfigParser::getValueFromKeyValue(line %d): Key part not %s, its %s",__LINE__,expectedKey.c_str(),string_value[0].c_str());
|
||||
return -1;
|
||||
}
|
||||
char * ptr;
|
||||
s32 value = strtol(string_value[1].c_str(),&ptr,16);
|
||||
|
||||
return value;
|
||||
}
|
74
wiiu/controller_patcher/config/ConfigParser.hpp
Normal file
74
wiiu/controller_patcher/config/ConfigParser.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#ifndef _ConfigParser_H_
|
||||
#define _ConfigParser_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../ControllerPatcher.hpp"
|
||||
|
||||
enum PARSE_TYPE{
|
||||
PARSE_CONTROLLER,
|
||||
PARSE_GAMEPAD,
|
||||
PARSE_MOUSE,
|
||||
PARSE_KEYBOARD
|
||||
};
|
||||
|
||||
class ConfigParser{
|
||||
friend class ConfigReader;
|
||||
friend class ControllerPatcher;
|
||||
private:
|
||||
//!Constructor
|
||||
ConfigParser(std::string configData);
|
||||
//!Destructor
|
||||
~ConfigParser();
|
||||
|
||||
PARSE_TYPE getType();
|
||||
void setType(PARSE_TYPE newType);
|
||||
|
||||
u16 getSlot();
|
||||
void setSlot(u16 newSlot);
|
||||
|
||||
bool parseIni();
|
||||
|
||||
bool Init();
|
||||
|
||||
bool parseConfigString(std::string content);
|
||||
|
||||
s32 getSlotController(std::string identify);
|
||||
|
||||
s32 checkExistingController(s32 vid, s32 pid);
|
||||
|
||||
s32 getValueFromKeyValue(std::string value_pair,std::string expectedKey,std::string delimiter);
|
||||
|
||||
bool resetConfig();
|
||||
|
||||
void parseSingleLine(std::string line);
|
||||
u16 slot_b;
|
||||
PARSE_TYPE type_b;
|
||||
|
||||
u16 vid;
|
||||
u16 pid;
|
||||
|
||||
std::string content;
|
||||
std::vector<std::string> contentLines;
|
||||
};
|
||||
#endif
|
121
wiiu/controller_patcher/config/ConfigValues.cpp
Normal file
121
wiiu/controller_patcher/config/ConfigValues.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "./ConfigValues.hpp"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
ConfigValues *ConfigValues::instance = NULL;
|
||||
|
||||
ConfigValues::ConfigValues(){
|
||||
InitValues();
|
||||
}
|
||||
|
||||
ConfigValues::~ConfigValues(){
|
||||
if(HID_DEBUG){ printf("ConfigValues::~ConfigValues(line %d){\n",__LINE__);}
|
||||
}
|
||||
|
||||
const u8 * ConfigValues::getValuesForPreset(std::map<std::string,const u8*> values,std::string possibleValue){
|
||||
std::map<std::string,const u8*>::iterator it;
|
||||
it = values.find(possibleValue);
|
||||
if (it != values.end()){
|
||||
return it->second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool ConfigValues::setIfValueIsAControllerPresetEx(std::string value,s32 slot,s32 keyslot){
|
||||
if(setIfValueIsPreset(presetGCValues,value,slot,keyslot)) return true;
|
||||
if(setIfValueIsPreset(presetDS3Values,value,slot,keyslot)) return true;
|
||||
if(setIfValueIsPreset(presetDS4Values,value,slot,keyslot)) return true;
|
||||
if(setIfValueIsPreset(presetXInputValues,value,slot,keyslot)) return true;
|
||||
if(setIfValueIsPreset(presetSwitchProValues,value,slot,keyslot)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//We need this function here so we can use preset sticks.
|
||||
bool ConfigValues::setIfValueIsPreset(std::map<std::string,const u8*> values,std::string possibleValue,s32 slot,s32 keyslot){
|
||||
if(slot > gHIDMaxDevices || slot < 0 || keyslot < 0 || keyslot >= CONTRPS_MAX_VALUE){
|
||||
return false;
|
||||
}
|
||||
const u8 * values_ = NULL;
|
||||
if( keyslot == CONTRPS_VPAD_BUTTON_L_STICK_X ||
|
||||
keyslot == CONTRPS_VPAD_BUTTON_L_STICK_Y ||
|
||||
keyslot == CONTRPS_VPAD_BUTTON_R_STICK_X ||
|
||||
keyslot == CONTRPS_VPAD_BUTTON_R_STICK_Y){
|
||||
if(HID_DEBUG){ printf("ConfigValues::setIfValueIsPreset(line %d): This may be a predefined stick %s\n",__LINE__,possibleValue.c_str());}
|
||||
if((values_ = ConfigValues::getValuesStickPreset(possibleValue)) != NULL){
|
||||
if(HID_DEBUG){ printf("ConfigValues::setIfValueIsPreset(line %d): Found predefined stick!\n",__LINE__);}
|
||||
config_controller[slot][keyslot][0] = values_[STICK_CONF_BYTE]; //CONTRPS_VPAD_BUTTON_L_STICK_X
|
||||
config_controller[slot][keyslot][1] = values_[STICK_CONF_DEFAULT];
|
||||
config_controller[slot][keyslot+DEF_STICK_OFFSET_INVERT][0] = CONTROLLER_PATCHER_VALUE_SET; //CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT
|
||||
config_controller[slot][keyslot+DEF_STICK_OFFSET_INVERT][1] = values_[STICK_CONF_INVERT];
|
||||
config_controller[slot][keyslot+DEF_STICK_OFFSET_DEADZONE][0] = CONTROLLER_PATCHER_VALUE_SET; //CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE
|
||||
config_controller[slot][keyslot+DEF_STICK_OFFSET_DEADZONE][1] = values_[STICK_CONF_DEADZONE];
|
||||
config_controller[slot][keyslot+DEF_STICK_OFFSET_MINMAX][0] = values_[STICK_CONF_MIN]; //CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX
|
||||
config_controller[slot][keyslot+DEF_STICK_OFFSET_MINMAX][1] = values_[STICK_CONF_MAX];
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if((values_ = getValuesForPreset(values,possibleValue)) != NULL){
|
||||
config_controller[slot][keyslot][0] = values_[0];
|
||||
config_controller[slot][keyslot][1] = values_[1];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
s32 ConfigValues::getValueFromMap(std::map<std::string,int> values,std::string nameOfString){
|
||||
std::map<std::string,int>::iterator it;
|
||||
it = values.find(nameOfString);
|
||||
if (it != values.end()){
|
||||
return it->second;
|
||||
}
|
||||
|
||||
//Value not found
|
||||
return -1;
|
||||
}
|
||||
|
||||
s32 ConfigValues::getPresetValueEx(std::string possibleString){
|
||||
s32 rightValue = -1;
|
||||
if((rightValue = getValueFromMap(gGamePadValuesToCONTRPSString,possibleString))!= -1){
|
||||
if(HID_DEBUG){ printf("ConfigValues::getPresetValueEx(line %d): Used pre-defined VPAD_VALUE! \"%s\" is %d\n",__LINE__,possibleString.c_str(),rightValue); }
|
||||
}else if((rightValue = getValueFromMap(presetValues,possibleString))!= -1){
|
||||
if(HID_DEBUG){ printf("ConfigValues::getPresetValueEx(line %d): Used pre-defined value! \"%s\" is %d\n",__LINE__,possibleString.c_str(),rightValue); }
|
||||
}
|
||||
return rightValue;
|
||||
}
|
||||
|
||||
void ConfigValues::addDeviceNameEx(u16 vid,u16 pid,std::string value){
|
||||
deviceNames[CPStringTools::strfmt("%04X%04X",vid,pid).c_str()] = value;
|
||||
}
|
||||
|
||||
std::string ConfigValues::getStringByVIDPIDEx(u16 vid,u16 pid){
|
||||
std::string result = "";
|
||||
std::map<std::string,std::string>::iterator it;
|
||||
|
||||
it = deviceNames.find(CPStringTools::strfmt("%04X%04X",vid,pid));
|
||||
if (it != deviceNames.end()){
|
||||
result = it->second;
|
||||
}else{
|
||||
result = CPStringTools::strfmt("VID: 0x%04X\nPID: 0x%04X",vid,pid);
|
||||
}
|
||||
return result;
|
||||
}
|
569
wiiu/controller_patcher/config/ConfigValues.hpp
Normal file
569
wiiu/controller_patcher/config/ConfigValues.hpp
Normal file
@ -0,0 +1,569 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#ifndef _ConfigValues_H_
|
||||
#define _ConfigValues_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "../ControllerPatcher.hpp"
|
||||
|
||||
class ConfigValues
|
||||
{
|
||||
friend class ConfigParser;
|
||||
friend class ControllerPatcher;
|
||||
private:
|
||||
static ConfigValues *getInstance() {
|
||||
if(instance == NULL){
|
||||
printf("ConfigValues: We need a new instance!!!\n");
|
||||
instance = new ConfigValues();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void destroyInstance() {
|
||||
if(instance){
|
||||
delete instance;
|
||||
instance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Returns NULL if not a preset!
|
||||
**/
|
||||
static const u8 * getValuesStickPreset(std::string possibleValue)
|
||||
{
|
||||
ConfigValues * cur_instance = getInstance();
|
||||
if(cur_instance == NULL) return NULL;
|
||||
return cur_instance->getValuesForPreset(cur_instance->presetSticks,possibleValue);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns -1 if not found
|
||||
**/
|
||||
static s32 getKeySlotGamePad(std::string possibleValue)
|
||||
{
|
||||
ConfigValues * cur_instance = getInstance();
|
||||
if(cur_instance == NULL) return -1;
|
||||
return cur_instance->getValueFromMap(cur_instance->CONTPRStringToValue,possibleValue);
|
||||
}
|
||||
/**
|
||||
Returns -1 if not found
|
||||
**/
|
||||
static s32 getKeySlotMouse(std::string possibleValue)
|
||||
{
|
||||
ConfigValues * cur_instance = getInstance();
|
||||
if(cur_instance == NULL) return -1;
|
||||
return cur_instance->getValueFromMap(cur_instance->mouseLeftValues,possibleValue);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns -1 if not found
|
||||
**/
|
||||
static s32 getKeySlotDefaultSingleValue(std::string possibleValue)
|
||||
{
|
||||
ConfigValues * cur_instance = getInstance();
|
||||
if(cur_instance == NULL) return -1;
|
||||
return cur_instance->getValueFromMap(cur_instance->CONTPRStringToValueSingle,possibleValue);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns -1 if not found
|
||||
**/
|
||||
static s32 getKeySlotDefaultPairedValue(std::string possibleValue)
|
||||
{
|
||||
ConfigValues * cur_instance = getInstance();
|
||||
if(cur_instance == NULL) return -1;
|
||||
return cur_instance->getValueFromMap(cur_instance->CONTPRStringToValue,possibleValue);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns -1 if not found
|
||||
**/
|
||||
static s32 getPresetValuesKeyboard(std::string possibleValue)
|
||||
{
|
||||
ConfigValues * cur_instance = getInstance();
|
||||
if(cur_instance == NULL) return -1;
|
||||
return cur_instance->getValueFromMap(cur_instance->presetKeyboardValues,possibleValue);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns -1 if not found
|
||||
**/
|
||||
static s32 getPresetValue(std::string possibleValue)
|
||||
{
|
||||
ConfigValues * cur_instance = getInstance();
|
||||
if(cur_instance == NULL) return -1;
|
||||
return cur_instance->getPresetValueEx(possibleValue);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns -1 if not found
|
||||
**/
|
||||
static s32 setIfValueIsAControllerPreset(std::string value,s32 slot,s32 keyslot)
|
||||
{
|
||||
ConfigValues * cur_instance = getInstance();
|
||||
if(cur_instance == NULL) return -1;
|
||||
return cur_instance->setIfValueIsAControllerPresetEx(value,slot,keyslot);
|
||||
}
|
||||
|
||||
static void addDeviceName(u16 vid,u16 pid,std::string value){
|
||||
ConfigValues * cur_instance = getInstance();
|
||||
if(cur_instance != NULL){
|
||||
cur_instance->addDeviceNameEx(vid,pid,value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Returns empty String if not found
|
||||
**/
|
||||
static std::string getStringByVIDPID(u16 vid,u16 pid){
|
||||
ConfigValues * cur_instance = getInstance();
|
||||
if(cur_instance == NULL) return "";
|
||||
return cur_instance->getStringByVIDPIDEx(vid,pid);
|
||||
}
|
||||
|
||||
//!Constructor
|
||||
ConfigValues();
|
||||
//!Destructor
|
||||
~ConfigValues();
|
||||
|
||||
static ConfigValues *instance;
|
||||
|
||||
std::map<std::string,int> mouseLeftValues;
|
||||
std::map<std::string,int> CONTPRStringToValue;
|
||||
std::map<std::string,int> CONTPRStringToValueSingle;
|
||||
std::map<std::string,int> presetValues;
|
||||
std::map<std::string,int> gGamePadValuesToCONTRPSString;
|
||||
std::map<std::string,int> presetKeyboardValues;
|
||||
|
||||
std::map<std::string,std::string> deviceNames;
|
||||
|
||||
std::map<std::string,const u8*> presetGCValues;
|
||||
std::map<std::string,const u8*> presetDS3Values;
|
||||
std::map<std::string,const u8*> presetDS4Values;
|
||||
std::map<std::string,const u8*> presetXInputValues;
|
||||
std::map<std::string,const u8*> presetSwitchProValues;
|
||||
std::map<std::string,const u8*> presetSticks;
|
||||
|
||||
s32 getValueFromMap(std::map<std::string,int> values,std::string nameOfString);
|
||||
|
||||
bool checkIfValueIsAControllerPreset(std::string value,s32 slot,s32 keyslot);
|
||||
|
||||
s32 getPresetValueEx(std::string possibleString);
|
||||
|
||||
void InitValues(){
|
||||
printf("ConfigValues::InitValues: Init values for the configuration\n");
|
||||
CONTPRStringToValue["VPAD_BUTTON_A"] = CONTRPS_VPAD_BUTTON_A;
|
||||
CONTPRStringToValue["VPAD_BUTTON_B"] = CONTRPS_VPAD_BUTTON_B;
|
||||
CONTPRStringToValue["VPAD_BUTTON_X"] = CONTRPS_VPAD_BUTTON_X;
|
||||
CONTPRStringToValue["VPAD_BUTTON_Y"] = CONTRPS_VPAD_BUTTON_Y;
|
||||
/* Normal DPAD */
|
||||
CONTPRStringToValue["VPAD_BUTTON_LEFT"] = CONTRPS_VPAD_BUTTON_LEFT;
|
||||
CONTPRStringToValue["VPAD_BUTTON_RIGHT"] = CONTRPS_VPAD_BUTTON_RIGHT;
|
||||
CONTPRStringToValue["VPAD_BUTTON_UP"] = CONTRPS_VPAD_BUTTON_UP;
|
||||
CONTPRStringToValue["VPAD_BUTTON_DOWN"] = CONTRPS_VPAD_BUTTON_DOWN;
|
||||
/* DPAD hat mode */
|
||||
CONTPRStringToValue["VPAD_BUTTON_DPAD_N"] = CONTRPS_VPAD_BUTTON_DPAD_N;
|
||||
CONTPRStringToValue["VPAD_BUTTON_DPAD_NE"] = CONTRPS_VPAD_BUTTON_DPAD_NE;
|
||||
CONTPRStringToValue["VPAD_BUTTON_DPAD_E"] = CONTRPS_VPAD_BUTTON_DPAD_E;
|
||||
CONTPRStringToValue["VPAD_BUTTON_DPAD_SE"] = CONTRPS_VPAD_BUTTON_DPAD_SE;
|
||||
CONTPRStringToValue["VPAD_BUTTON_DPAD_S"] = CONTRPS_VPAD_BUTTON_DPAD_S;
|
||||
CONTPRStringToValue["VPAD_BUTTON_DPAD_SW"] = CONTRPS_VPAD_BUTTON_DPAD_SW;
|
||||
CONTPRStringToValue["VPAD_BUTTON_DPAD_W"] = CONTRPS_VPAD_BUTTON_DPAD_W;
|
||||
CONTPRStringToValue["VPAD_BUTTON_DPAD_NW"] = CONTRPS_VPAD_BUTTON_DPAD_NW;
|
||||
CONTPRStringToValue["VPAD_BUTTON_DPAD_NEUTRAL"] = CONTRPS_VPAD_BUTTON_DPAD_NEUTRAL;
|
||||
/* DPAD Absolute mode */
|
||||
CONTPRStringToValue["VPAD_BUTTON_DPAD_ABS_UP"] = CONTRPS_VPAD_BUTTON_DPAD_ABS_UP;
|
||||
CONTPRStringToValue["VPAD_BUTTON_DPAD_ABS_DOWN"] = CONTRPS_VPAD_BUTTON_DPAD_ABS_DOWN;
|
||||
CONTPRStringToValue["VPAD_BUTTON_DPAD_ABS_LEFT"] = CONTRPS_VPAD_BUTTON_DPAD_ABS_LEFT;
|
||||
CONTPRStringToValue["VPAD_BUTTON_DPAD_ABS_RIGHT"] = CONTRPS_VPAD_BUTTON_DPAD_ABS_RIGHT;
|
||||
/* */
|
||||
CONTPRStringToValue["VPAD_BUTTON_ZL"] = CONTRPS_VPAD_BUTTON_ZL;
|
||||
CONTPRStringToValue["VPAD_BUTTON_ZR"] = CONTRPS_VPAD_BUTTON_ZR;
|
||||
CONTPRStringToValue["VPAD_BUTTON_L"] = CONTRPS_VPAD_BUTTON_L;
|
||||
CONTPRStringToValue["VPAD_BUTTON_R"] = CONTRPS_VPAD_BUTTON_R;
|
||||
CONTPRStringToValue["VPAD_BUTTON_PLUS"] = CONTRPS_VPAD_BUTTON_PLUS;
|
||||
CONTPRStringToValue["VPAD_BUTTON_MINUS"] = CONTRPS_VPAD_BUTTON_MINUS;
|
||||
CONTPRStringToValue["VPAD_BUTTON_HOME"] = CONTRPS_VPAD_BUTTON_HOME;
|
||||
CONTPRStringToValue["VPAD_BUTTON_SYNC"] = CONTRPS_VPAD_BUTTON_SYNC;
|
||||
CONTPRStringToValue["VPAD_BUTTON_STICK_R"] = CONTRPS_VPAD_BUTTON_STICK_R;
|
||||
CONTPRStringToValue["VPAD_BUTTON_STICK_L"] = CONTRPS_VPAD_BUTTON_STICK_L;
|
||||
|
||||
CONTPRStringToValue["VPAD_STICK_R_EMULATION_LEFT"] = CONTRPS_VPAD_STICK_R_EMULATION_LEFT;
|
||||
CONTPRStringToValue["VPAD_STICK_R_EMULATION_RIGHT"] = CONTRPS_VPAD_STICK_R_EMULATION_RIGHT;
|
||||
CONTPRStringToValue["VPAD_STICK_R_EMULATION_UP"] = CONTRPS_VPAD_STICK_R_EMULATION_UP;
|
||||
CONTPRStringToValue["VPAD_STICK_R_EMULATION_DOWN"] = CONTRPS_VPAD_STICK_R_EMULATION_DOWN;
|
||||
CONTPRStringToValue["VPAD_STICK_L_EMULATION_LEFT"] = CONTRPS_VPAD_STICK_L_EMULATION_LEFT;
|
||||
CONTPRStringToValue["VPAD_STICK_L_EMULATION_RIGHT"] = CONTRPS_VPAD_STICK_L_EMULATION_RIGHT;
|
||||
CONTPRStringToValue["VPAD_STICK_L_EMULATION_UP"] = CONTRPS_VPAD_STICK_L_EMULATION_UP;
|
||||
CONTPRStringToValue["VPAD_STICK_L_EMULATION_DOWN"] = CONTRPS_VPAD_STICK_L_EMULATION_DOWN;
|
||||
|
||||
CONTPRStringToValue["VPAD_L_STICK_UP"] = CONTRPS_VPAD_BUTTON_L_STICK_UP;
|
||||
CONTPRStringToValue["VPAD_L_STICK_DOWN"] = CONTRPS_VPAD_BUTTON_L_STICK_DOWN;
|
||||
CONTPRStringToValue["VPAD_L_STICK_LEFT"] = CONTRPS_VPAD_BUTTON_L_STICK_LEFT;
|
||||
CONTPRStringToValue["VPAD_L_STICK_RIGHT"] = CONTRPS_VPAD_BUTTON_L_STICK_RIGHT;
|
||||
|
||||
CONTPRStringToValue["VPAD_R_STICK_UP"] = CONTRPS_VPAD_BUTTON_R_STICK_UP;
|
||||
CONTPRStringToValue["VPAD_R_STICK_DOWN"] = CONTRPS_VPAD_BUTTON_R_STICK_DOWN;
|
||||
CONTPRStringToValue["VPAD_R_STICK_LEFT"] = CONTRPS_VPAD_BUTTON_R_STICK_LEFT;
|
||||
CONTPRStringToValue["VPAD_R_STICK_RIGHT"] = CONTRPS_VPAD_BUTTON_R_STICK_RIGHT;
|
||||
|
||||
CONTPRStringToValue["VPAD_L_STICK_X"] = CONTRPS_VPAD_BUTTON_L_STICK_X;
|
||||
CONTPRStringToValue["VPAD_L_STICK_X_MINMAX"] = CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX;
|
||||
CONTPRStringToValue["VPAD_L_STICK_Y"] = CONTRPS_VPAD_BUTTON_L_STICK_Y;
|
||||
CONTPRStringToValue["VPAD_L_STICK_Y_MINMAX"] = CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX;
|
||||
CONTPRStringToValue["VPAD_R_STICK_X"] = CONTRPS_VPAD_BUTTON_R_STICK_X;
|
||||
CONTPRStringToValue["VPAD_R_STICK_X_MINMAX"] = CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX;
|
||||
CONTPRStringToValue["VPAD_R_STICK_Y"] = CONTRPS_VPAD_BUTTON_R_STICK_Y;
|
||||
CONTPRStringToValue["VPAD_R_STICK_Y_MINMAX"] = CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX;
|
||||
CONTPRStringToValue["VPAD_BUTTON_TV"] = CONTRPS_VPAD_BUTTON_TV;
|
||||
|
||||
CONTPRStringToValue["DOUBLE_USE_BUTTON_ACTIVATOR"] = CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR,
|
||||
CONTPRStringToValue["INPUT_FILTER"] = CONTRPS_INPUT_FILTER;
|
||||
CONTPRStringToValue["PAD1_FILTER"] = CONTRPS_PAD1_FILTER;
|
||||
CONTPRStringToValue["PAD2_FILTER"] = CONTRPS_PAD2_FILTER;
|
||||
CONTPRStringToValue["PAD3_FILTER"] = CONTRPS_PAD3_FILTER;
|
||||
CONTPRStringToValue["PAD4_FILTER"] = CONTRPS_PAD4_FILTER;
|
||||
CONTPRStringToValue["PAD5_FILTER"] = CONTRPS_PAD5_FILTER;
|
||||
|
||||
CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_1_PRESSED"] = CONTRPS_DOUBLE_USE_BUTTON_1_PRESSED;
|
||||
CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_2_PRESSED"] = CONTRPS_DOUBLE_USE_BUTTON_2_PRESSED;
|
||||
CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_3_PRESSED"] = CONTRPS_DOUBLE_USE_BUTTON_3_PRESSED;
|
||||
CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_4_PRESSED"] = CONTRPS_DOUBLE_USE_BUTTON_4_PRESSED;
|
||||
CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_5_PRESSED"] = CONTRPS_DOUBLE_USE_BUTTON_5_PRESSED;
|
||||
CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_1_RELEASED"] = CONTRPS_DOUBLE_USE_BUTTON_1_RELEASED;
|
||||
CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_2_RELEASED"] = CONTRPS_DOUBLE_USE_BUTTON_2_RELEASED;
|
||||
CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_3_RELEASED"] = CONTRPS_DOUBLE_USE_BUTTON_3_RELEASED;
|
||||
CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_4_RELEASED"] = CONTRPS_DOUBLE_USE_BUTTON_4_RELEASED;
|
||||
CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_5_RELEASED"] = CONTRPS_DOUBLE_USE_BUTTON_5_RELEASED;
|
||||
|
||||
CONTPRStringToValueSingle["BUF_SIZE"] = CONTRPS_BUF_SIZE;
|
||||
CONTPRStringToValueSingle["DPAD_MODE"] = CONTRPS_DPAD_MODE;
|
||||
CONTPRStringToValueSingle["DPAD_MASK"] = CONTRPS_DPAD_MASK;
|
||||
CONTPRStringToValueSingle["VPAD_L_STICK_X_DEADZONE"] = CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE;
|
||||
CONTPRStringToValueSingle["VPAD_L_STICK_Y_DEADZONE"] = CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE;
|
||||
CONTPRStringToValueSingle["VPAD_R_STICK_X_DEADZONE"] = CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE;
|
||||
CONTPRStringToValueSingle["VPAD_R_STICK_Y_DEADZONE"] = CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE;
|
||||
CONTPRStringToValueSingle["VPAD_L_STICK_X_INVERT"] = CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT;
|
||||
CONTPRStringToValueSingle["VPAD_L_STICK_Y_INVERT"] = CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT;
|
||||
CONTPRStringToValueSingle["VPAD_R_STICK_X_INVERT"] = CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT;
|
||||
CONTPRStringToValueSingle["VPAD_R_STICK_Y_INVERT"] = CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT;
|
||||
|
||||
CONTPRStringToValueSingle["DOUBLE_USE"] = CONTRPS_DOUBLE_USE;
|
||||
CONTPRStringToValueSingle["PAD_COUNT"] = CONTRPS_PAD_COUNT;
|
||||
|
||||
mouseLeftValues["LEFT_CLICK"] = CONTRPS_VPAD_BUTTON_LEFT;
|
||||
mouseLeftValues["RIGHT_CLICK"] = CONTRPS_VPAD_BUTTON_RIGHT;
|
||||
mouseLeftValues["EMULATED_STICK"] = CONTRPS_MOUSE_STICK;
|
||||
|
||||
presetGCValues["GC_BUTTON_A"] = HID_GC_BUTTON_A;
|
||||
presetGCValues["GC_BUTTON_B"] = HID_GC_BUTTON_B;
|
||||
presetGCValues["GC_BUTTON_X"] = HID_GC_BUTTON_X;
|
||||
presetGCValues["GC_BUTTON_Y"] = HID_GC_BUTTON_Y;
|
||||
presetGCValues["GC_BUTTON_LEFT"] = HID_GC_BUTTON_LEFT;
|
||||
presetGCValues["GC_BUTTON_RIGHT"] = HID_GC_BUTTON_RIGHT;
|
||||
presetGCValues["GC_BUTTON_DOWN"] = HID_GC_BUTTON_DOWN;
|
||||
presetGCValues["GC_BUTTON_UP"] = HID_GC_BUTTON_UP;
|
||||
presetGCValues["GC_BUTTON_START"] = HID_GC_BUTTON_START;
|
||||
presetGCValues["GC_BUTTON_Z"] = HID_GC_BUTTON_Z;
|
||||
presetGCValues["GC_BUTTON_L"] = HID_GC_BUTTON_L;
|
||||
presetGCValues["GC_BUTTON_R"] = HID_GC_BUTTON_R;
|
||||
|
||||
presetDS3Values["DS3_BUTTON_CROSS"] = HID_DS3_BUTTON_CROSS;
|
||||
presetDS3Values["DS3_BUTTON_CIRCLE"] = HID_DS3_BUTTON_CIRCLE;
|
||||
presetDS3Values["DS3_BUTTON_SQUARE"] = HID_DS3_BUTTON_SQUARE;
|
||||
presetDS3Values["DS3_BUTTON_TRIANGLE"] = HID_DS3_BUTTON_TRIANGLE;
|
||||
|
||||
presetDS3Values["DS3_BUTTON_L1"] = HID_DS3_BUTTON_L1;
|
||||
presetDS3Values["DS3_BUTTON_L2"] = HID_DS3_BUTTON_L2;
|
||||
presetDS3Values["DS3_BUTTON_L3"] = HID_DS3_BUTTON_L3;
|
||||
presetDS3Values["DS3_BUTTON_R1"] = HID_DS3_BUTTON_R1;
|
||||
presetDS3Values["DS3_BUTTON_R2"] = HID_DS3_BUTTON_R2;
|
||||
presetDS3Values["DS3_BUTTON_R3"] = HID_DS3_BUTTON_R3;
|
||||
|
||||
presetDS3Values["DS3_BUTTON_SELECT"] = HID_DS3_BUTTON_SELECT;
|
||||
presetDS3Values["DS3_BUTTON_START"] = HID_DS3_BUTTON_START;
|
||||
presetDS3Values["DS3_BUTTON_LEFT"] = HID_DS3_BUTTON_LEFT;
|
||||
presetDS3Values["DS3_BUTTON_RIGHT"] = HID_DS3_BUTTON_RIGHT;
|
||||
presetDS3Values["DS3_BUTTON_UP"] = HID_DS3_BUTTON_UP;
|
||||
presetDS3Values["DS3_BUTTON_DOWN"] = HID_DS3_BUTTON_DOWN;
|
||||
presetDS3Values["DS3_BUTTON_GUIDE"] = HID_DS3_BUTTON_GUIDE;
|
||||
|
||||
presetDS4Values["DS4_BUTTON_CROSS"] = HID_DS4_BUTTON_CROSS;
|
||||
presetDS4Values["DS4_BUTTON_CIRCLE"] = HID_DS4_BUTTON_CIRCLE;
|
||||
presetDS4Values["DS4_BUTTON_SQUARE"] = HID_DS4_BUTTON_SQUARE;
|
||||
presetDS4Values["DS4_BUTTON_TRIANGLE"] = HID_DS4_BUTTON_TRIANGLE;
|
||||
|
||||
presetDS4Values["DS4_BUTTON_L1"] = HID_DS4_BUTTON_L1;
|
||||
presetDS4Values["DS4_BUTTON_L2"] = HID_DS4_BUTTON_L2;
|
||||
presetDS4Values["DS4_BUTTON_L3"] = HID_DS4_BUTTON_L3;
|
||||
presetDS4Values["DS4_BUTTON_R1"] = HID_DS4_BUTTON_R1;
|
||||
presetDS4Values["DS4_BUTTON_R2"] = HID_DS4_BUTTON_R2;
|
||||
presetDS4Values["DS4_BUTTON_R3"] = HID_DS4_BUTTON_R3;
|
||||
|
||||
presetDS4Values["DS4_BUTTON_SHARE"] = HID_DS4_BUTTON_SHARE;
|
||||
presetDS4Values["DS4_BUTTON_OPTIONS"] = HID_DS4_BUTTON_OPTIONS;
|
||||
presetDS4Values["DS4_BUTTON_DPAD_TYPE"] = HID_DS4_BUTTON_DPAD_TYPE;
|
||||
|
||||
presetDS4Values["DS4_BUTTON_DPAD_N"] = HID_DS4_BUTTON_DPAD_N;
|
||||
presetDS4Values["DS4_BUTTON_DPAD_NE"] = HID_DS4_BUTTON_DPAD_NE;
|
||||
presetDS4Values["DS4_BUTTON_DPAD_E"] = HID_DS4_BUTTON_DPAD_E;
|
||||
presetDS4Values["DS4_BUTTON_DPAD_SE"] = HID_DS4_BUTTON_DPAD_SE;
|
||||
presetDS4Values["DS4_BUTTON_DPAD_S"] = HID_DS4_BUTTON_DPAD_S;
|
||||
presetDS4Values["DS4_BUTTON_DPAD_SW"] = HID_DS4_BUTTON_DPAD_SW;
|
||||
presetDS4Values["DS4_BUTTON_DPAD_W"] = HID_DS4_BUTTON_DPAD_W;
|
||||
presetDS4Values["DS4_BUTTON_DPAD_NW"] = HID_DS4_BUTTON_DPAD_NW;
|
||||
presetDS4Values["DS4_BUTTON_DPAD_NEUTRAL"] = HID_DS4_BUTTON_DPAD_NEUTRAL;
|
||||
|
||||
presetDS4Values["DS4_BUTTON_GUIDE"] = HID_DS4_BUTTON_GUIDE;
|
||||
presetDS4Values["DS4_BUTTON_T_PAD_CLICK"] = HID_DS4_BUTTON_T_PAD_CLICK;
|
||||
|
||||
presetXInputValues["XINPUT_BUTTON_A"] = HID_XINPUT_BUTTON_A;
|
||||
presetXInputValues["XINPUT_BUTTON_B"] = HID_XINPUT_BUTTON_B;
|
||||
presetXInputValues["XINPUT_BUTTON_X"] = HID_XINPUT_BUTTON_X;
|
||||
presetXInputValues["XINPUT_BUTTON_Y"] = HID_XINPUT_BUTTON_Y;
|
||||
|
||||
presetXInputValues["XINPUT_BUTTON_LB"] = HID_XINPUT_BUTTON_LB;
|
||||
presetXInputValues["XINPUT_BUTTON_LT"] = HID_XINPUT_BUTTON_LT;
|
||||
presetXInputValues["XINPUT_BUTTON_L3"] = HID_XINPUT_BUTTON_L3;
|
||||
presetXInputValues["XINPUT_BUTTON_RB"] = HID_XINPUT_BUTTON_RB;
|
||||
presetXInputValues["XINPUT_BUTTON_RT"] = HID_XINPUT_BUTTON_RT;
|
||||
presetXInputValues["XINPUT_BUTTON_R3"] = HID_XINPUT_BUTTON_R3;
|
||||
|
||||
presetXInputValues["XINPUT_BUTTON_START"] = HID_XINPUT_BUTTON_START;
|
||||
presetXInputValues["XINPUT_BUTTON_BACK"] = HID_XINPUT_BUTTON_BACK;
|
||||
presetXInputValues["XINPUT_BUTTON_DPAD_TYPE"] = HID_XINPUT_BUTTON_DPAD_TYPE;
|
||||
|
||||
presetXInputValues["XINPUT_BUTTON_DPAD_UP"] = HID_XINPUT_BUTTON_UP;
|
||||
presetXInputValues["XINPUT_BUTTON_DPAD_DOWN"] = HID_XINPUT_BUTTON_DOWN;
|
||||
presetXInputValues["XINPUT_BUTTON_DPAD_LEFT"] = HID_XINPUT_BUTTON_LEFT;
|
||||
presetXInputValues["XINPUT_BUTTON_DPAD_RIGHT"] = HID_XINPUT_BUTTON_RIGHT;
|
||||
|
||||
presetXInputValues["XINPUT_BUTTON_GUIDE"] = HID_XINPUT_BUTTON_GUIDE;
|
||||
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_A"] = HID_SWITCH_PRO_BT_BUTTON_A;
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_B"] = HID_SWITCH_PRO_BT_BUTTON_B;
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_X"] = HID_SWITCH_PRO_BT_BUTTON_X;
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_Y"] = HID_SWITCH_PRO_BT_BUTTON_Y;
|
||||
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_PLUS"] = HID_SWITCH_PRO_BT_BUTTON_PLUS;
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_MINUS"] = HID_SWITCH_PRO_BT_BUTTON_MINUS;
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_HOME"] = HID_SWITCH_PRO_BT_BUTTON_HOME;
|
||||
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_L"] = HID_SWITCH_PRO_BT_BUTTON_L;
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_R"] = HID_SWITCH_PRO_BT_BUTTON_R;
|
||||
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_ZL"] = HID_SWITCH_PRO_BT_BUTTON_ZL;
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_ZR"] = HID_SWITCH_PRO_BT_BUTTON_ZR;
|
||||
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_STICK_L"] = HID_SWITCH_PRO_BT_BUTTON_STICK_L;
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_STICK_R"] = HID_SWITCH_PRO_BT_BUTTON_STICK_R;
|
||||
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_N"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_N;
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_NE"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_NE;
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_E"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_E;
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_SE"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_SE;
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_S"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_S;
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_SW"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_SW;
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_W"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_W;
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_NW"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_NW;
|
||||
presetSwitchProValues["SWITCH_PRO_BUTTON_DPAD_NEUTRAL"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_NEUTRAL;
|
||||
|
||||
presetKeyboardValues["KEYBOARD_SHIFT"] = HID_KEYBOARD_BUTTON_SHIFT;
|
||||
presetKeyboardValues["KEYBOARD_A"] = HID_KEYBOARD_BUTTON_A;
|
||||
presetKeyboardValues["KEYBOARD_B"] = HID_KEYBOARD_BUTTON_B;
|
||||
presetKeyboardValues["KEYBOARD_C"] = HID_KEYBOARD_BUTTON_C;
|
||||
presetKeyboardValues["KEYBOARD_D"] = HID_KEYBOARD_BUTTON_D;
|
||||
presetKeyboardValues["KEYBOARD_E"] = HID_KEYBOARD_BUTTON_E;
|
||||
presetKeyboardValues["KEYBOARD_F"] = HID_KEYBOARD_BUTTON_F;
|
||||
presetKeyboardValues["KEYBOARD_G"] = HID_KEYBOARD_BUTTON_G;
|
||||
presetKeyboardValues["KEYBOARD_H"] = HID_KEYBOARD_BUTTON_H;
|
||||
presetKeyboardValues["KEYBOARD_I"] = HID_KEYBOARD_BUTTON_I;
|
||||
presetKeyboardValues["KEYBOARD_J"] = HID_KEYBOARD_BUTTON_J;
|
||||
presetKeyboardValues["KEYBOARD_K"] = HID_KEYBOARD_BUTTON_K;
|
||||
presetKeyboardValues["KEYBOARD_L"] = HID_KEYBOARD_BUTTON_L;
|
||||
presetKeyboardValues["KEYBOARD_M"] = HID_KEYBOARD_BUTTON_M;
|
||||
presetKeyboardValues["KEYBOARD_N"] = HID_KEYBOARD_BUTTON_N;
|
||||
presetKeyboardValues["KEYBOARD_O"] = HID_KEYBOARD_BUTTON_O;
|
||||
presetKeyboardValues["KEYBOARD_P"] = HID_KEYBOARD_BUTTON_P;
|
||||
presetKeyboardValues["KEYBOARD_Q"] = HID_KEYBOARD_BUTTON_Q;
|
||||
presetKeyboardValues["KEYBOARD_R"] = HID_KEYBOARD_BUTTON_R;
|
||||
presetKeyboardValues["KEYBOARD_S"] = HID_KEYBOARD_BUTTON_S;
|
||||
presetKeyboardValues["KEYBOARD_T"] = HID_KEYBOARD_BUTTON_T;
|
||||
presetKeyboardValues["KEYBOARD_U"] = HID_KEYBOARD_BUTTON_U;
|
||||
presetKeyboardValues["KEYBOARD_V"] = HID_KEYBOARD_BUTTON_V;
|
||||
presetKeyboardValues["KEYBOARD_W"] = HID_KEYBOARD_BUTTON_W;
|
||||
presetKeyboardValues["KEYBOARD_X"] = HID_KEYBOARD_BUTTON_X;
|
||||
presetKeyboardValues["KEYBOARD_Y"] = HID_KEYBOARD_BUTTON_Y;
|
||||
presetKeyboardValues["KEYBOARD_Z"] = HID_KEYBOARD_BUTTON_Z;
|
||||
presetKeyboardValues["KEYBOARD_F1"] = HID_KEYBOARD_BUTTON_F1;
|
||||
presetKeyboardValues["KEYBOARD_F2"] = HID_KEYBOARD_BUTTON_F2;
|
||||
presetKeyboardValues["KEYBOARD_F3"] = HID_KEYBOARD_BUTTON_F3;
|
||||
presetKeyboardValues["KEYBOARD_F4"] = HID_KEYBOARD_BUTTON_F4;
|
||||
presetKeyboardValues["KEYBOARD_F5"] = HID_KEYBOARD_BUTTON_F5;
|
||||
presetKeyboardValues["KEYBOARD_F6"] = HID_KEYBOARD_BUTTON_F6;
|
||||
presetKeyboardValues["KEYBOARD_F7"] = HID_KEYBOARD_BUTTON_F7;
|
||||
presetKeyboardValues["KEYBOARD_F8"] = HID_KEYBOARD_BUTTON_F8;
|
||||
presetKeyboardValues["KEYBOARD_F9"] = HID_KEYBOARD_BUTTON_F9;
|
||||
presetKeyboardValues["KEYBOARD_F10"] = HID_KEYBOARD_BUTTON_F10;
|
||||
presetKeyboardValues["KEYBOARD_F11"] = HID_KEYBOARD_BUTTON_F11;
|
||||
presetKeyboardValues["KEYBOARD_F12"] = HID_KEYBOARD_BUTTON_F12;
|
||||
presetKeyboardValues["KEYBOARD_1"] = HID_KEYBOARD_BUTTON_1;
|
||||
presetKeyboardValues["KEYBOARD_2"] = HID_KEYBOARD_BUTTON_2;
|
||||
presetKeyboardValues["KEYBOARD_3"] = HID_KEYBOARD_BUTTON_3;
|
||||
presetKeyboardValues["KEYBOARD_4"] = HID_KEYBOARD_BUTTON_4;
|
||||
presetKeyboardValues["KEYBOARD_5"] = HID_KEYBOARD_BUTTON_5;
|
||||
presetKeyboardValues["KEYBOARD_6"] = HID_KEYBOARD_BUTTON_6;
|
||||
presetKeyboardValues["KEYBOARD_7"] = HID_KEYBOARD_BUTTON_7;
|
||||
presetKeyboardValues["KEYBOARD_8"] = HID_KEYBOARD_BUTTON_8;
|
||||
presetKeyboardValues["KEYBOARD_9"] = HID_KEYBOARD_BUTTON_9;
|
||||
presetKeyboardValues["KEYBOARD_0"] = HID_KEYBOARD_BUTTON_0;
|
||||
|
||||
presetKeyboardValues["KEYBOARD_RETURN"] = HID_KEYBOARD_BUTTON_RETURN;
|
||||
presetKeyboardValues["KEYBOARD_ESCAPE"] = HID_KEYBOARD_BUTTON_ESCAPE;
|
||||
presetKeyboardValues["KEYBOARD_DELETE"] = HID_KEYBOARD_BUTTON_DELETE;
|
||||
presetKeyboardValues["KEYBOARD_TAB"] = HID_KEYBOARD_BUTTON_TAB;
|
||||
presetKeyboardValues["KEYBOARD_SPACEBAR"] = HID_KEYBOARD_BUTTON_SPACEBAR;
|
||||
presetKeyboardValues["KEYBOARD_CAPSLOCK"] = HID_KEYBOARD_BUTTON_CAPSLOCK;
|
||||
presetKeyboardValues["KEYBOARD_PRINTSCREEN"] = HID_KEYBOARD_BUTTON_PRINTSCREEN;
|
||||
presetKeyboardValues["KEYBOARD_SCROLLLOCK"] = HID_KEYBOARD_BUTTON_SCROLLLOCK;
|
||||
presetKeyboardValues["KEYBOARD_PAUSE"] = HID_KEYBOARD_BUTTON_PAUSE;
|
||||
presetKeyboardValues["KEYBOARD_INSERT"] = HID_KEYBOARD_BUTTON_INSERT;
|
||||
presetKeyboardValues["KEYBOARD_HOME"] = HID_KEYBOARD_BUTTON_HOME;
|
||||
presetKeyboardValues["KEYBOARD_PAGEUP"] = HID_KEYBOARD_BUTTON_PAGEUP;
|
||||
presetKeyboardValues["KEYBOARD_PAGEDOWN"] = HID_KEYBOARD_BUTTON_PAGEDOWN;
|
||||
presetKeyboardValues["KEYBOARD_DELETEFORWARD"] = HID_KEYBOARD_BUTTON_DELETEFORWARD;
|
||||
presetKeyboardValues["KEYBOARD_LEFT_CONTROL"] = HID_KEYBOARD_BUTTON_LEFT_CONTROL;
|
||||
presetKeyboardValues["KEYBOARD_LEFT_ALT"] = HID_KEYBOARD_BUTTON_LEFT_ALT;
|
||||
presetKeyboardValues["KEYBOARD_RIGHT_CONTROL"] = HID_KEYBOARD_BUTTON_RIGHT_CONTROL;
|
||||
presetKeyboardValues["KEYBOARD_RIGHT_SHIFT"] = HID_KEYBOARD_BUTTON_RIGHT_SHIFT;
|
||||
presetKeyboardValues["KEYBOARD_RIGHT_ALT"] = HID_KEYBOARD_BUTTON_RIGHT_ALT;
|
||||
presetKeyboardValues["KEYBOARD_END"] = HID_KEYBOARD_BUTTON_END;
|
||||
|
||||
presetKeyboardValues["KEYBOARD_LEFT"] = HID_KEYBOARD_BUTTON_LEFT;
|
||||
presetKeyboardValues["KEYBOARD_RIGHT"] = HID_KEYBOARD_BUTTON_RIGHT;
|
||||
presetKeyboardValues["KEYBOARD_DOWN"] = HID_KEYBOARD_BUTTON_DOWN;
|
||||
presetKeyboardValues["KEYBOARD_UP"] = HID_KEYBOARD_BUTTON_UP;
|
||||
|
||||
presetKeyboardValues["KEYBOARD_KEYPAD_1"] = HID_KEYBOARD_KEYPAD_BUTTON_1;
|
||||
presetKeyboardValues["KEYBOARD_KEYPAD_2"] = HID_KEYBOARD_KEYPAD_BUTTON_2;
|
||||
presetKeyboardValues["KEYBOARD_KEYPAD_3"] = HID_KEYBOARD_KEYPAD_BUTTON_3;
|
||||
presetKeyboardValues["KEYBOARD_KEYPAD_4"] = HID_KEYBOARD_KEYPAD_BUTTON_4;
|
||||
presetKeyboardValues["KEYBOARD_KEYPAD_5"] = HID_KEYBOARD_KEYPAD_BUTTON_5;
|
||||
presetKeyboardValues["KEYBOARD_KEYPAD_6"] = HID_KEYBOARD_KEYPAD_BUTTON_6;
|
||||
presetKeyboardValues["KEYBOARD_KEYPAD_7"] = HID_KEYBOARD_KEYPAD_BUTTON_7;
|
||||
presetKeyboardValues["KEYBOARD_KEYPAD_8"] = HID_KEYBOARD_KEYPAD_BUTTON_8;
|
||||
presetKeyboardValues["KEYBOARD_KEYPAD_9"] = HID_KEYBOARD_KEYPAD_BUTTON_9;
|
||||
presetKeyboardValues["KEYBOARD_KEYPAD_0"] = HID_KEYBOARD_KEYPAD_BUTTON_0;
|
||||
presetKeyboardValues["KEYBOARD_KEYPAD_NUMLOCK"] = HID_KEYBOARD_KEYPAD_BUTTON_NUMLOCK;
|
||||
presetKeyboardValues["KEYBOARD_KEYPAD_MINUS"] = HID_KEYBOARD_KEYPAD_BUTTON_MINUS;
|
||||
presetKeyboardValues["KEYBOARD_KEYPAD_PLUS"] = HID_KEYBOARD_KEYPAD_BUTTON_PLUS;
|
||||
|
||||
presetValues["VPAD_L_STICK"] = DEF_L_STICK;
|
||||
presetValues["VPAD_R_STICK"] = DEF_R_STICK;
|
||||
|
||||
presetValues["DPAD_NORMAL"] = CONTRPDM_Normal;
|
||||
presetValues["DPAD_HAT"] = CONTRPDM_Hat;
|
||||
presetValues["DPAD_ABSOLUTE_2VALUES"] = CONTRPDM_Absolute_2Values;
|
||||
presetValues["TRUE"] = 1;
|
||||
presetValues["YES"] = 1;
|
||||
presetValues["ON"] = 1;
|
||||
presetValues["FALSE"] = 0;
|
||||
presetValues["NO"] = 0;
|
||||
presetValues["OFF"] = 0;
|
||||
|
||||
presetSticks["GC_STICK_L_X"] = HID_GC_STICK_L_X;
|
||||
presetSticks["GC_STICK_L_Y"] = HID_GC_STICK_L_Y;
|
||||
presetSticks["GC_STICK_R_X"] = HID_GC_STICK_R_X;
|
||||
presetSticks["GC_STICK_R_Y"] = HID_GC_STICK_R_Y;
|
||||
|
||||
presetSticks["DS3_STICK_L_X"] = HID_DS3_STICK_L_X;
|
||||
presetSticks["DS3_STICK_L_Y"] = HID_DS3_STICK_L_Y;
|
||||
presetSticks["DS3_STICK_R_X"] = HID_DS3_STICK_R_X;
|
||||
presetSticks["DS3_STICK_R_Y"] = HID_DS3_STICK_R_Y;
|
||||
|
||||
presetSticks["DS4_STICK_L_X"] = HID_DS4_STICK_L_X;
|
||||
presetSticks["DS4_STICK_L_Y"] = HID_DS4_STICK_L_Y;
|
||||
presetSticks["DS4_STICK_R_X"] = HID_DS4_STICK_R_X;
|
||||
presetSticks["DS4_STICK_R_Y"] = HID_DS4_STICK_R_Y;
|
||||
|
||||
presetSticks["XINPUT_STICK_L_X"] = HID_XINPUT_STICK_L_X;
|
||||
presetSticks["XINPUT_STICK_L_Y"] = HID_XINPUT_STICK_L_Y;
|
||||
presetSticks["XINPUT_STICK_R_X"] = HID_XINPUT_STICK_R_X;
|
||||
presetSticks["XINPUT_STICK_R_Y"] = HID_XINPUT_STICK_R_Y;
|
||||
|
||||
presetSticks["SWITCH_PRO_STICK_L_X"] = HID_SWITCH_PRO_BT_STICK_L_X;
|
||||
presetSticks["SWITCH_PRO_STICK_L_Y"] = HID_SWITCH_PRO_BT_STICK_L_Y;
|
||||
presetSticks["SWITCH_PRO_STICK_R_X"] = HID_SWITCH_PRO_BT_STICK_R_X;
|
||||
presetSticks["SWITCH_PRO_STICK_R_Y"] = HID_SWITCH_PRO_BT_STICK_R_Y;
|
||||
|
||||
presetSticks["GC_DPAD_MODE"] = HID_GC_BUTTON_DPAD_TYPE;
|
||||
presetSticks["DS3_DPAD_MODE"] = HID_DS3_BUTTON_DPAD_TYPE;
|
||||
presetSticks["DS4_DPAD_MODE"] = HID_DS4_BUTTON_DPAD_TYPE;
|
||||
presetSticks["XINPUT_DPAD_MODE"] = HID_XINPUT_BUTTON_DPAD_TYPE;
|
||||
presetSticks["SWITCH_PRO_DPAD_MODE"] = HID_SWITCH_PRO_BT_BUTTON_DPAD_TYPE;
|
||||
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_A"] = CONTRPS_VPAD_BUTTON_A;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_B"] = CONTRPS_VPAD_BUTTON_B;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_X"] = CONTRPS_VPAD_BUTTON_X;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_Y"] = CONTRPS_VPAD_BUTTON_Y;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_LEFT"] = CONTRPS_VPAD_BUTTON_LEFT;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_RIGHT"] = CONTRPS_VPAD_BUTTON_RIGHT;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_UP"] = CONTRPS_VPAD_BUTTON_UP;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_DOWN"] = CONTRPS_VPAD_BUTTON_DOWN;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_ZL"] = CONTRPS_VPAD_BUTTON_ZL;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_ZR"] = CONTRPS_VPAD_BUTTON_ZR;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_L"] = CONTRPS_VPAD_BUTTON_L;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_R"] = CONTRPS_VPAD_BUTTON_R;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_PLUS"] = CONTRPS_VPAD_BUTTON_PLUS;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_MINUS"] = CONTRPS_VPAD_BUTTON_MINUS;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_HOME"] = CONTRPS_VPAD_BUTTON_HOME;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_SYNC"] = CONTRPS_VPAD_BUTTON_SYNC;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_STICK_R"] = CONTRPS_VPAD_BUTTON_STICK_R;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_STICK_L"] = CONTRPS_VPAD_BUTTON_STICK_L;
|
||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_TV"] = CONTRPS_VPAD_BUTTON_TV;
|
||||
|
||||
gGamePadValuesToCONTRPSString["VPAD_STICK_R_EMULATION_LEFT"] = CONTRPS_VPAD_STICK_R_EMULATION_LEFT;
|
||||
gGamePadValuesToCONTRPSString["VPAD_STICK_R_EMULATION_RIGHT"] = CONTRPS_VPAD_STICK_R_EMULATION_RIGHT;
|
||||
gGamePadValuesToCONTRPSString["VPAD_STICK_R_EMULATION_UP"] = CONTRPS_VPAD_STICK_R_EMULATION_UP;
|
||||
gGamePadValuesToCONTRPSString["VPAD_STICK_R_EMULATION_DOWN"] = CONTRPS_VPAD_STICK_R_EMULATION_DOWN;
|
||||
gGamePadValuesToCONTRPSString["VPAD_STICK_L_EMULATION_LEFT"] = CONTRPS_VPAD_STICK_L_EMULATION_LEFT;
|
||||
gGamePadValuesToCONTRPSString["VPAD_STICK_L_EMULATION_RIGHT"] = CONTRPS_VPAD_STICK_L_EMULATION_RIGHT;
|
||||
gGamePadValuesToCONTRPSString["VPAD_STICK_L_EMULATION_UP"] = CONTRPS_VPAD_STICK_L_EMULATION_UP;
|
||||
gGamePadValuesToCONTRPSString["VPAD_STICK_L_EMULATION_DOWN"] = CONTRPS_VPAD_STICK_L_EMULATION_DOWN;
|
||||
|
||||
deviceNames[CPStringTools::strfmt("%04X%04X",HID_GC_VID, HID_GC_PID).c_str()] = HID_GC_STRING;
|
||||
deviceNames[CPStringTools::strfmt("%04X%04X",HID_KEYBOARD_VID, HID_KEYBOARD_PID).c_str()] = HID_KEYBOARD_STRING;
|
||||
deviceNames[CPStringTools::strfmt("%04X%04X",HID_MOUSE_VID, HID_MOUSE_PID).c_str()] = HID_MOUSE_STRING;
|
||||
deviceNames[CPStringTools::strfmt("%04X%04X",HID_DS3_VID, HID_DS3_PID).c_str()] = HID_DS3_STRING;
|
||||
deviceNames[CPStringTools::strfmt("%04X%04X",HID_NEW_DS4_VID, HID_NEW_DS4_PID).c_str()] = HID_NEW_DS4_STRING;
|
||||
deviceNames[CPStringTools::strfmt("%04X%04X",HID_DS4_VID, HID_DS4_PID).c_str()] = HID_DS4_STRING;
|
||||
deviceNames[CPStringTools::strfmt("%04X%04X",HID_XINPUT_VID, HID_XINPUT_PID).c_str()] = HID_XINPUT_STRING;
|
||||
deviceNames[CPStringTools::strfmt("%04X%04X",HID_SWITCH_PRO_VID,HID_SWITCH_PRO_PID).c_str()] = HID_SWITCH_PRO_STRING;
|
||||
}
|
||||
|
||||
const u8 * getValuesForPreset(std::map<std::string,const u8*> values,std::string possibleValue);
|
||||
|
||||
bool setIfValueIsPreset(std::map<std::string,const u8*> values,std::string possibleValue,s32 slot,s32 keyslot);
|
||||
bool setIfValueIsAControllerPresetEx(std::string value,s32 slot,s32 keyslot);
|
||||
|
||||
void addDeviceNameEx(u16 vid,u16 pid,std::string value);
|
||||
std::string getStringByVIDPIDEx(u16 vid,u16 pid);
|
||||
};
|
||||
#endif
|
50
wiiu/controller_patcher/network/ControllerPatcherNet.cpp
Normal file
50
wiiu/controller_patcher/network/ControllerPatcherNet.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include "ControllerPatcherNet.hpp"
|
||||
#include "wiiu/os.h"
|
||||
#include "sys/socket.h"
|
||||
|
||||
s32 ControllerPatcherNet::recvwait(s32 sock, void *buffer, s32 len) {
|
||||
s32 ret;
|
||||
while (len > 0) {
|
||||
ret = recv(sock, buffer, len, 0);
|
||||
if(ret < 0) return ret;
|
||||
len -= ret;
|
||||
buffer = (void *)(((char *) buffer) + ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 ControllerPatcherNet::recvbyte(s32 sock) {
|
||||
unsigned char buffer[1];
|
||||
s32 ret;
|
||||
|
||||
ret = recvwait(sock, buffer, 1);
|
||||
if (ret < 0) return ret;
|
||||
return buffer[0];
|
||||
}
|
||||
|
||||
s32 ControllerPatcherNet::checkbyte(s32 sock) {
|
||||
unsigned char buffer[1];
|
||||
s32 ret;
|
||||
|
||||
ret = recv(sock, buffer, 1, MSG_DONTWAIT);
|
||||
if (ret < 0) return ret;
|
||||
if (ret == 0) return -1;
|
||||
return buffer[0];
|
||||
}
|
||||
|
||||
s32 ControllerPatcherNet::sendwait(s32 sock, const void *buffer, s32 len) {
|
||||
s32 ret;
|
||||
while (len > 0) {
|
||||
ret = send(sock, buffer, len, 0);
|
||||
if(ret < 0) return ret;
|
||||
len -= ret;
|
||||
buffer = (void *)(((char *) buffer) + ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 ControllerPatcherNet::sendbyte(s32 sock, unsigned char byte) {
|
||||
unsigned char buffer[1];
|
||||
buffer[0] = byte;
|
||||
return sendwait(sock, buffer, 1);
|
||||
}
|
17
wiiu/controller_patcher/network/ControllerPatcherNet.hpp
Normal file
17
wiiu/controller_patcher/network/ControllerPatcherNet.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef _CONTROLLERPATCHERNET_H_
|
||||
#define _CONTROLLERPATCHERNET_H_
|
||||
|
||||
#include "wiiu/types.h"
|
||||
|
||||
class ControllerPatcherNet{
|
||||
friend class TCPServer;
|
||||
friend class UDPServer;
|
||||
private:
|
||||
static s32 recvwait(s32 sock, void *buffer, s32 len);
|
||||
static u8 recvbyte(s32 sock);
|
||||
static s32 checkbyte(s32 sock);
|
||||
static s32 sendwait(s32 sock, const void *buffer, s32 len);
|
||||
static s32 sendbyte(s32 sock, unsigned char byte);
|
||||
};
|
||||
|
||||
#endif
|
371
wiiu/controller_patcher/network/TCPServer.cpp
Normal file
371
wiiu/controller_patcher/network/TCPServer.cpp
Normal file
@ -0,0 +1,371 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "TCPServer.hpp"
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define wiiu_errno (*__gh_errno_ptr())
|
||||
|
||||
ControllerPatcherThread * TCPServer::pThread = NULL;
|
||||
TCPServer * TCPServer::instance = NULL;
|
||||
|
||||
TCPServer::TCPServer(s32 port){
|
||||
this->sockfd = -1;
|
||||
this->clientfd = -1;
|
||||
memset(&(this->sock_addr),0,sizeof(this->sock_addr));
|
||||
TCPServer::AttachDetach(DETACH);
|
||||
StartTCPThread(this);
|
||||
}
|
||||
|
||||
TCPServer::~TCPServer(){
|
||||
CloseSockets();
|
||||
if(HID_DEBUG){ printf("TCPServer::~TCPServer(line %d): Thread will be closed\n",__LINE__); }
|
||||
TCPServer::AttachDetach(DETACH);
|
||||
exitThread = 1;
|
||||
if(TCPServer::pThread != NULL){
|
||||
if(HID_DEBUG){ printf("TCPServer::~TCPServer(line %d): Deleting it!\n",__LINE__); }
|
||||
delete TCPServer::pThread;
|
||||
}
|
||||
if(HID_DEBUG){ printf("TCPServer::~TCPServer(line %d): Thread done\n",__LINE__); }
|
||||
TCPServer::pThread = NULL;
|
||||
}
|
||||
|
||||
void TCPServer::CloseSockets(){
|
||||
if (this->sockfd != -1){
|
||||
socketclose(this->sockfd);
|
||||
}
|
||||
if (this->clientfd != -1){
|
||||
socketclose(this->clientfd);
|
||||
}
|
||||
this->sockfd = -1;
|
||||
this->clientfd = -1;
|
||||
}
|
||||
|
||||
void TCPServer::StartTCPThread(TCPServer * server){
|
||||
s32 priority = 28;
|
||||
if(OSGetTitleID() == 0x00050000101c9300 || //The Legend of Zelda Breath of the Wild JPN
|
||||
OSGetTitleID() == 0x00050000101c9400 || //The Legend of Zelda Breath of the Wild USA
|
||||
OSGetTitleID() == 0x00050000101c9500 || //The Legend of Zelda Breath of the Wild EUR
|
||||
OSGetTitleID() == 0x00050000101c9b00 || //The Binding of Isaac: Rebirth EUR
|
||||
OSGetTitleID() == 0x00050000101a3c00){ //The Binding of Isaac: Rebirth USA
|
||||
priority = 10;
|
||||
printf("TCPServer::StartTCPThread(line %d): This game needs higher thread priority. We set it to %d\n",__LINE__,priority);
|
||||
}
|
||||
TCPServer::pThread = ControllerPatcherThread::create(TCPServer::DoTCPThread, (void*)server, ControllerPatcherThread::eAttributeAffCore2,priority);
|
||||
TCPServer::pThread->resumeThread();
|
||||
}
|
||||
|
||||
void TCPServer::AttachDetach(s32 attach){
|
||||
if(HID_DEBUG){
|
||||
if(attach){
|
||||
printf("TCPServer::AttachDetach(line %d): Network Attach\n",__LINE__);
|
||||
}else{
|
||||
printf("TCPServer::AttachDetach(line %d): Network Detach\n",__LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
for(s32 i= 0;i< gHIDMaxDevices;i++){
|
||||
for(s32 j= 0;j< HID_MAX_PADS_COUNT;j++){
|
||||
if(gNetworkController[i][j][NETWORK_CONTROLLER_ACTIVE] > 0){
|
||||
printf("TCPServer::AttachDetach(line %d): Found a registered pad in deviceslot %d and padslot %d! Lets detach it.\n",__LINE__,i,j);
|
||||
HIDDevice device;
|
||||
memset(&device,0,sizeof(device));
|
||||
|
||||
device.interface_index = 0;
|
||||
device.vid = gNetworkController[i][j][NETWORK_CONTROLLER_VID];
|
||||
device.pid = gNetworkController[i][j][NETWORK_CONTROLLER_PID];
|
||||
device.handle = gNetworkController[i][j][NETWORK_CONTROLLER_HANDLE];
|
||||
device.max_packet_size_rx = 8;
|
||||
ControllerPatcherHID::externAttachDetachCallback(&device,attach);
|
||||
memset(gNetworkController[i][j],0,sizeof(gNetworkController[i][j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(HID_DEBUG){
|
||||
if(attach){
|
||||
printf("TCPServer::AttachDetach(line %d): Network Attach DONE!\n",__LINE__);
|
||||
}else{
|
||||
printf("TCPServer::AttachDetach(line %d): Network Detach DONE!\n",__LINE__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TCPServer::DetachAndDelete(){
|
||||
TCPServer::AttachDetach(DETACH);
|
||||
memset(&gNetworkController,0,sizeof(gNetworkController));
|
||||
}
|
||||
|
||||
s32 TCPServer::RunTCP(){
|
||||
s32 ret;
|
||||
while (1) {
|
||||
if(exitThread) break;
|
||||
ret = ControllerPatcherNet::checkbyte(clientfd);
|
||||
if (ret < 0) {
|
||||
if(wiiu_errno != 6) return ret;
|
||||
wiiu_os_usleep(1000);
|
||||
continue;
|
||||
}
|
||||
//printf("got byte from tcp! %01X\n",ret);
|
||||
switch (ret) {
|
||||
case WIIU_CP_TCP_ATTACH: { /*attach */
|
||||
if(gUsedProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_1){
|
||||
s32 handle;
|
||||
ret = ControllerPatcherNet::recvwait(clientfd, &handle, 4);
|
||||
if(ret < 0){
|
||||
printf("TCPServer::RunTCP(line %d): Error in %02X: recvwait handle\n",__LINE__,WIIU_CP_TCP_ATTACH);
|
||||
return ret;
|
||||
}
|
||||
if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): got handle %d\n",handle); }
|
||||
u16 vid = 0;
|
||||
u16 pid = 0;
|
||||
ret = ControllerPatcherNet::recvwait(clientfd, &vid, 2);
|
||||
if(ret < 0){
|
||||
printf("TCPServer::RunTCP(line %d): Error in %02X: recvwait vid\n",__LINE__,WIIU_CP_TCP_ATTACH);
|
||||
return ret;
|
||||
}
|
||||
if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): got vid %04X\n",vid); }
|
||||
|
||||
ret = ControllerPatcherNet::recvwait(clientfd, &pid, 2);
|
||||
if(ret < 0){
|
||||
printf("TCPServer::RunTCP(line %d): Error in %02X: recvwait pid\n",__LINE__,WIIU_CP_TCP_ATTACH);
|
||||
return ret;
|
||||
}
|
||||
if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): got pid %04X\n",pid); }
|
||||
HIDDevice device;
|
||||
memset(&device,0,sizeof(device));
|
||||
device.handle = handle;
|
||||
device.interface_index = 0;
|
||||
device.vid = SWAP16(vid);
|
||||
device.pid = SWAP16(pid);
|
||||
device.max_packet_size_rx = 8;
|
||||
|
||||
my_cb_user * user = NULL;
|
||||
ControllerPatcherHID::externAttachDetachCallback(&device,1);
|
||||
if((ret = ControllerPatcherUtils::getDataByHandle(handle,&user)) < 0){
|
||||
printf("TCPServer::RunTCP(line %d): Error in %02X: getDataByHandle(%d,%08X).\n",__LINE__,WIIU_CP_TCP_ATTACH,handle,&user);
|
||||
printf("TCPServer::RunTCP(line %d): Error in %02X: Config for the controller is missing.\n",__LINE__,WIIU_CP_TCP_ATTACH);
|
||||
if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_CONFIG_NOT_FOUND) < 0)){
|
||||
printf("TCPServer::RunTCP(line %d): Error in %02X: Sending the WIIU_CP_TCP_ATTACH_CONFIG_NOT_FOUND byte failed. Error: %d.\n",__LINE__,WIIU_CP_TCP_ATTACH,ret);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_CONFIG_FOUND) < 0)){
|
||||
printf("TCPServer::RunTCP(line %d): Error in %02X: Sending the WIIU_CP_TCP_ATTACH_CONFIG_FOUND byte failed. Error: %d.\n",__LINE__,WIIU_CP_TCP_ATTACH,ret);
|
||||
return ret;
|
||||
}
|
||||
if(user != NULL){
|
||||
if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_USER_DATA_OKAY) < 0)){
|
||||
printf("TCPServer::RunTCP(line %d): Error in %02X: Sending the WIIU_CP_TCP_ATTACH_USER_DATA_OKAY byte failed. Error: %d.\n",__LINE__,WIIU_CP_TCP_ATTACH,ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ControllerPatcherNet::sendwait(clientfd,&user->slotdata.deviceslot,2);
|
||||
if(ret < 0){
|
||||
printf("TCPServer::RunTCP(line %d): Error in %02X: sendwait slotdata: %04X\n",__LINE__,WIIU_CP_TCP_ATTACH,user->slotdata.deviceslot);
|
||||
return ret;
|
||||
}
|
||||
ret = ControllerPatcherNet::sendwait(clientfd,&user->pad_slot,1);
|
||||
if(ret < 0){
|
||||
printf("TCPServer::RunTCP(line %d): Error in %02X: sendwait pad_slot: %04X\n",__LINE__,WIIU_CP_TCP_ATTACH,user->pad_slot);
|
||||
return ret;
|
||||
}
|
||||
}else{
|
||||
printf("TCPServer::RunTCP(line %d): Error in %02X: invalid user data.\n",__LINE__,WIIU_CP_TCP_ATTACH);
|
||||
if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_USER_DATA_BAD) < 0)){
|
||||
printf("TCPServer::RunTCP(line %d): Error in %02X: Sending the WIIU_CP_TCP_ATTACH_USER_DATA_BAD byte failed. Error: %d.\n",__LINE__,WIIU_CP_TCP_ATTACH,ret);
|
||||
return ret;
|
||||
}
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): attachted to device slot: %d , pad slot is: %d\n",__LINE__,user->slotdata.deviceslot,user->pad_slot); }
|
||||
|
||||
gNetworkController[user->slotdata.deviceslot][user->pad_slot][NETWORK_CONTROLLER_VID] = device.vid;
|
||||
gNetworkController[user->slotdata.deviceslot][user->pad_slot][NETWORK_CONTROLLER_PID] = device.pid;
|
||||
gNetworkController[user->slotdata.deviceslot][user->pad_slot][NETWORK_CONTROLLER_ACTIVE] = 1;
|
||||
gNetworkController[user->slotdata.deviceslot][user->pad_slot][NETWORK_CONTROLLER_HANDLE] = handle;
|
||||
|
||||
if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): handle %d connected! vid: %02X pid: %02X deviceslot %d, padslot %d\n",__LINE__,handle,vid,pid,user->slotdata.deviceslot,user->pad_slot); }
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WIIU_CP_TCP_DETACH: { /*detach */
|
||||
if(gUsedProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_1){
|
||||
s32 handle;
|
||||
ret = ControllerPatcherNet::recvwait(clientfd, &handle, 4);
|
||||
if(ret < 0){
|
||||
printf("TCPServer::RunTCP(line %d): Error in %02X: recvwait handle\n",__LINE__,WIIU_CP_TCP_DETACH);
|
||||
return ret;
|
||||
break;
|
||||
}
|
||||
|
||||
if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): got detach for handle: %d\n",__LINE__,handle); }
|
||||
my_cb_user * user = NULL;
|
||||
if(ControllerPatcherUtils::getDataByHandle(handle,&user) < 0){
|
||||
printf("TCPServer::RunTCP(line %d): Error in %02X: getDataByHandle(%d,%08X).\n",__LINE__,WIIU_CP_TCP_DETACH,handle,&user);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
if(user == NULL){
|
||||
printf("TCPServer::RunTCP(line %d): Error in %02X: invalid user data.\n",__LINE__,WIIU_CP_TCP_DETACH);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
s32 deviceslot = user->slotdata.deviceslot;
|
||||
if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): device slot is: %d , pad slot is: %d\n",__LINE__,deviceslot,user->pad_slot); }
|
||||
|
||||
DeviceVIDPIDInfo vidpid;
|
||||
s32 result;
|
||||
if((result = ControllerPatcherUtils::getVIDPIDbyDeviceSlot(deviceslot,&vidpid)) < 0){
|
||||
printf("TCPServer::RunTCP(line %d): Error in %02X: Couldn't find a valid VID/PID for device slot %d. Error: %d\n",__LINE__,WIIU_CP_TCP_DETACH,deviceslot,ret);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
HIDDevice device;
|
||||
memset(&device,0,sizeof(device));
|
||||
device.handle = handle;
|
||||
device.interface_index = 0;
|
||||
device.vid = SWAP16(vidpid.vid);
|
||||
device.pid = SWAP16(vidpid.pid);
|
||||
device.max_packet_size_rx = 14;
|
||||
|
||||
ControllerPatcherHID::externAttachDetachCallback(&device,DETACH);
|
||||
memset(gNetworkController[deviceslot][user->pad_slot],0,sizeof(gNetworkController[deviceslot][user->pad_slot]));
|
||||
if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): handle %d disconnected!\n",__LINE__,handle); }
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WIIU_CP_TCP_PING: { /*ping*/
|
||||
if(gUsedProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_1){
|
||||
if(HID_DEBUG){ printf("TCPServer::RunTCP(line %d): Got Ping, sending now a Pong\n",__LINE__); }
|
||||
s32 ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_PONG);
|
||||
if(ret < 0){ printf("TCPServer::RunTCP(line %d): Error in %02X: sendbyte PONG\n",__LINE__); return -1;}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TCPServer::ErrorHandling(){
|
||||
CloseSockets();
|
||||
wiiu_os_usleep(1000*1000*2);
|
||||
}
|
||||
|
||||
void TCPServer::DoTCPThreadInternal(){
|
||||
s32 ret;
|
||||
s32 len;
|
||||
while (1) {
|
||||
if(exitThread) break;
|
||||
memset(&(this->sock_addr),0,sizeof(sock_addr));
|
||||
sock_addr.sin_family = AF_INET;
|
||||
sock_addr.sin_port = DEFAULT_TCP_PORT;
|
||||
sock_addr.sin_addr.s_addr = 0;
|
||||
|
||||
this->sockfd = ret = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if(ret == -1){ ErrorHandling(); continue;}
|
||||
s32 enable = 1;
|
||||
|
||||
setsockopt(this->sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
|
||||
|
||||
ret = bind(this->sockfd, (sockaddr *)&sock_addr, 16);
|
||||
if(ret < 0) { ErrorHandling(); continue;}
|
||||
ret = listen(this->sockfd, 1);
|
||||
if(ret < 0){ ErrorHandling(); continue;}
|
||||
|
||||
do{
|
||||
if(HID_DEBUG){ printf("TCPServer::DoTCPThreadInternal(line %d): Waiting for a connection\n",__LINE__); }
|
||||
if(exitThread) break;
|
||||
len = 16;
|
||||
|
||||
/**
|
||||
Handshake
|
||||
1. At first this server sends his protocol version
|
||||
2. The network clients answers with his preferred version (which needs to be equals or lower the version this server sent him) or an abort command.
|
||||
3a. If the client sent a abort, close the connection and wait for another connection
|
||||
3b. If the client sent his highest supported version, the server confirm that he is able to use this version (by sending the version back) or sending a abort command to disconnect.
|
||||
**/
|
||||
|
||||
clientfd = ret = (s32)accept(sockfd, (sockaddr *)&(sock_addr),(socklen_t *) &len);
|
||||
|
||||
if(ret == -1){ ErrorHandling(); break;}
|
||||
printf("TCPServer::DoTCPThreadInternal(line %d): TCP Connection accepted! Sending my protocol version: %d (0x%02X)\n",__LINE__, (WIIU_CP_TCP_HANDSHAKE - WIIU_CP_TCP_HANDSHAKE_VERSION_1)+1,WIIU_CP_TCP_HANDSHAKE);
|
||||
|
||||
gUDPClientip = sock_addr.sin_addr.s_addr;
|
||||
UDPClient::createInstance();
|
||||
|
||||
s32 ret;
|
||||
ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_HANDSHAKE); //Hey I'm a WiiU console!
|
||||
if(ret < 0){ printf("TCPServer::DoTCPThreadInternal(line %d): Error sendbyte: %02X\n",__LINE__,WIIU_CP_TCP_HANDSHAKE); ErrorHandling(); break;}
|
||||
|
||||
u8 clientProtocolVersion = ControllerPatcherNet::recvbyte(clientfd);
|
||||
if(ret < 0){ printf("TCPServer::DoTCPThreadInternal(line %d): Error recvbyte: %02X\n",__LINE__,WIIU_CP_TCP_HANDSHAKE); ErrorHandling(); break;}
|
||||
|
||||
if(clientProtocolVersion == WIIU_CP_TCP_HANDSHAKE_ABORT){
|
||||
printf("TCPServer::DoTCPThreadInternal(line %d): The network client wants to abort.\n",__LINE__);
|
||||
ErrorHandling(); break;
|
||||
}
|
||||
|
||||
printf("TCPServer::DoTCPThreadInternal(line %d): received protocol version: %d (0x%02X)\n",__LINE__,(clientProtocolVersion - WIIU_CP_TCP_HANDSHAKE_VERSION_1)+1,clientProtocolVersion);
|
||||
|
||||
if(clientProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_MIN && clientProtocolVersion <= WIIU_CP_TCP_HANDSHAKE_VERSION_MAX){
|
||||
printf("TCPServer::DoTCPThreadInternal(line %d): We support this protocol version. Let's confirm it to the network client.\n",__LINE__);
|
||||
gUsedProtocolVersion = clientProtocolVersion;
|
||||
ret = ControllerPatcherNet::sendbyte(clientfd, clientProtocolVersion);
|
||||
if(ret < 0){ printf("TCPServer::DoTCPThreadInternal(line %d): Error sendbyte: %02X\n",__LINE__,clientProtocolVersion); ErrorHandling(); break;}
|
||||
}else{
|
||||
printf("TCPServer::DoTCPThreadInternal(line %d): We don't support this protocol version. We need to abort =(.\n",__LINE__);
|
||||
ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_HANDSHAKE_ABORT);
|
||||
ErrorHandling(); break;
|
||||
}
|
||||
|
||||
printf("TCPServer::DoTCPThreadInternal(line %d): Handshake done! Success!\n",__LINE__);
|
||||
|
||||
TCPServer::DetachAndDelete(); //Clear connected controller
|
||||
RunTCP();
|
||||
|
||||
if(clientfd != -1){
|
||||
socketclose(clientfd);
|
||||
}
|
||||
clientfd = -1;
|
||||
}while(0);
|
||||
printf("TCPServer::DoTCPThreadInternal(line %d): Connection closed\n",__LINE__);
|
||||
gUDPClientip = 0;
|
||||
UDPClient::destroyInstance();
|
||||
TCPServer::DetachAndDelete(); //Clear connected controller
|
||||
CloseSockets();
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TCPServer::DoTCPThread(ControllerPatcherThread *thread, void *arg){
|
||||
TCPServer * args = (TCPServer * )arg;
|
||||
return args->DoTCPThreadInternal();
|
||||
}
|
93
wiiu/controller_patcher/network/TCPServer.hpp
Normal file
93
wiiu/controller_patcher/network/TCPServer.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#ifndef _TCPSERVER_WINDOW_H_
|
||||
#define _TCPSERVER_WINDOW_H_
|
||||
|
||||
#include "../ControllerPatcher.hpp"
|
||||
|
||||
#include "sys/socket.h"
|
||||
#include "wiiu/os.h"
|
||||
|
||||
#define WIIU_CP_TCP_HANDSHAKE WIIU_CP_TCP_HANDSHAKE_VERSION_3
|
||||
|
||||
#define WIIU_CP_TCP_HANDSHAKE_VERSION_MIN WIIU_CP_TCP_HANDSHAKE_VERSION_1
|
||||
#define WIIU_CP_TCP_HANDSHAKE_VERSION_MAX WIIU_CP_TCP_HANDSHAKE_VERSION_3
|
||||
|
||||
#define WIIU_CP_TCP_HANDSHAKE_VERSION_1 0x12
|
||||
#define WIIU_CP_TCP_HANDSHAKE_VERSION_2 0x13
|
||||
#define WIIU_CP_TCP_HANDSHAKE_VERSION_3 0x14
|
||||
|
||||
#define WIIU_CP_TCP_HANDSHAKE_ABORT 0x30
|
||||
|
||||
#define ATTACH 0x01
|
||||
#define DETACH 0x00
|
||||
|
||||
#define WIIU_CP_TCP_ATTACH 0x01
|
||||
#define WIIU_CP_TCP_DETACH 0x02
|
||||
#define WIIU_CP_TCP_PING 0xF0
|
||||
#define WIIU_CP_TCP_PONG 0xF1
|
||||
|
||||
#define WIIU_CP_TCP_ATTACH_CONFIG_FOUND 0xE0
|
||||
#define WIIU_CP_TCP_ATTACH_CONFIG_NOT_FOUND 0xE1
|
||||
#define WIIU_CP_TCP_ATTACH_USER_DATA_OKAY 0xE8
|
||||
#define WIIU_CP_TCP_ATTACH_USER_DATA_BAD 0xE9
|
||||
|
||||
#define DEFAULT_TCP_PORT 8112
|
||||
|
||||
class TCPServer{
|
||||
friend class ControllerPatcher;
|
||||
|
||||
private:
|
||||
static TCPServer *getInstance() {
|
||||
if(!instance)
|
||||
instance = new TCPServer(DEFAULT_TCP_PORT);
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void destroyInstance() {
|
||||
if(instance){
|
||||
delete instance;
|
||||
instance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TCPServer(s32 port);
|
||||
~TCPServer();
|
||||
|
||||
void CloseSockets();
|
||||
void ErrorHandling();
|
||||
|
||||
void StartTCPThread(TCPServer * server);
|
||||
static void DoTCPThread(ControllerPatcherThread *thread, void *arg);
|
||||
void DoTCPThreadInternal();
|
||||
static void DetachConnectedNetworkController();
|
||||
static void AttachDetach(s32 attach);
|
||||
void DetachAndDelete();
|
||||
static TCPServer *instance;
|
||||
|
||||
s32 RunTCP();
|
||||
|
||||
struct sockaddr_in sock_addr;
|
||||
volatile s32 sockfd = -1;
|
||||
volatile s32 clientfd = -1;
|
||||
|
||||
|
||||
volatile s32 exitThread = 0;
|
||||
static ControllerPatcherThread *pThread;
|
||||
};
|
||||
|
||||
#endif //_TCPSERVER_WINDOW_H_
|
58
wiiu/controller_patcher/network/UDPClient.cpp
Normal file
58
wiiu/controller_patcher/network/UDPClient.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "UDPClient.hpp"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_UDP_SIZE 0x578
|
||||
|
||||
UDPClient * UDPClient::instance = NULL;
|
||||
|
||||
UDPClient::UDPClient(u32 ip, s32 port){
|
||||
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (sockfd < 0)
|
||||
return;
|
||||
|
||||
struct sockaddr_in connect_addr;
|
||||
memset(&connect_addr, 0, sizeof(connect_addr));
|
||||
connect_addr.sin_family = AF_INET;
|
||||
connect_addr.sin_port = port;
|
||||
connect_addr.sin_addr.s_addr = ip;
|
||||
|
||||
if(connect(sockfd, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0)
|
||||
{
|
||||
socketclose(sockfd);
|
||||
sockfd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
UDPClient::~UDPClient(){
|
||||
if (this->sockfd != -1){
|
||||
socketclose(sockfd);
|
||||
}
|
||||
if(HID_DEBUG){ printf("UDPClient::~UDPClient(line %d): Thread has been closed\n",__LINE__); }
|
||||
}
|
||||
|
||||
bool UDPClient::sendData(char * data,s32 length){
|
||||
if(sockfd < 0 || data == 0 || length < 0 || gUsedProtocolVersion < WIIU_CP_TCP_HANDSHAKE_VERSION_3){
|
||||
return false;
|
||||
}
|
||||
if(length > 1400) length = 1400;
|
||||
|
||||
s32 ret = send(sockfd, data, length, 0);
|
||||
return (ret >= 0);
|
||||
}
|
66
wiiu/controller_patcher/network/UDPClient.hpp
Normal file
66
wiiu/controller_patcher/network/UDPClient.hpp
Normal file
@ -0,0 +1,66 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#ifndef _UDPCLIENT_WINDOW_H_
|
||||
#define _UDPCLIENT_WINDOW_H_
|
||||
|
||||
#include "../ControllerPatcher.hpp"
|
||||
|
||||
#include "sys/socket.h"
|
||||
|
||||
#define DEFAULT_UDP_CLIENT_PORT 8114
|
||||
|
||||
class UDPClient{
|
||||
friend class ControllerPatcher;
|
||||
friend class ControllerPatcherHID;
|
||||
friend class TCPServer;
|
||||
public:
|
||||
|
||||
private:
|
||||
static UDPClient *getInstance() {
|
||||
if(instance == NULL){
|
||||
createInstance();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
static UDPClient *createInstance() {
|
||||
if(instance != NULL){
|
||||
destroyInstance();
|
||||
}
|
||||
instance = new UDPClient(gUDPClientip,DEFAULT_UDP_CLIENT_PORT);
|
||||
|
||||
return getInstance();
|
||||
}
|
||||
|
||||
static void destroyInstance() {
|
||||
if(instance != NULL){
|
||||
delete instance;
|
||||
instance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
UDPClient(u32 ip,s32 port);
|
||||
~UDPClient();
|
||||
bool sendData(char * data, s32 length);
|
||||
|
||||
volatile s32 sockfd = -1;
|
||||
struct sockaddr_in addr;
|
||||
static UDPClient *instance;
|
||||
};
|
||||
|
||||
#endif //_UDPClient_WINDOW_H_
|
168
wiiu/controller_patcher/network/UDPServer.cpp
Normal file
168
wiiu/controller_patcher/network/UDPServer.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "UDPServer.hpp"
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sys/socket.h"
|
||||
|
||||
#define MAX_UDP_SIZE 0x578
|
||||
#define wiiu_errno (*__gh_errno_ptr())
|
||||
|
||||
ControllerPatcherThread * UDPServer::pThread = NULL;
|
||||
UDPServer * UDPServer::instance = NULL;
|
||||
|
||||
UDPServer::UDPServer(s32 port){
|
||||
s32 ret;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = port;
|
||||
addr.sin_addr.s_addr = 0;
|
||||
|
||||
this->sockfd = ret = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if(ret == -1) return;
|
||||
s32 enable = 1;
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
|
||||
ret = bind(sockfd, (sockaddr *)&addr, 16);
|
||||
if(ret < 0) return;
|
||||
|
||||
StartUDPThread(this);
|
||||
}
|
||||
|
||||
UDPServer::~UDPServer(){
|
||||
ControllerPatcherThread * pThreadPointer = UDPServer::pThread;
|
||||
if(pThreadPointer != NULL){
|
||||
exitThread = 1;
|
||||
if(pThreadPointer != NULL){
|
||||
delete pThreadPointer;
|
||||
UDPServer::pThread = NULL;
|
||||
if (this->sockfd != -1){
|
||||
socketclose(sockfd);
|
||||
}
|
||||
this->sockfd = -1;
|
||||
}
|
||||
}
|
||||
if(HID_DEBUG){ printf("UDPServer::~UDPServer(line %d): Thread has been closed\n",__LINE__); }
|
||||
|
||||
|
||||
}
|
||||
|
||||
void UDPServer::StartUDPThread(UDPServer * server){
|
||||
s32 priority = 28;
|
||||
if(OSGetTitleID() == 0x00050000101c9300 || //The Legend of Zelda Breath of the Wild JPN
|
||||
OSGetTitleID() == 0x00050000101c9400 || //The Legend of Zelda Breath of the Wild USA
|
||||
OSGetTitleID() == 0x00050000101c9500 || //The Legend of Zelda Breath of the Wild EUR
|
||||
OSGetTitleID() == 0x00050000101c9b00 || //The Binding of Isaac: Rebirth EUR
|
||||
OSGetTitleID() == 0x00050000101a3c00){ //The Binding of Isaac: Rebirth USA
|
||||
priority = 10;
|
||||
printf("UDPServer::StartUDPThread(line %d): This game needs higher thread priority. We set it to %d\n",__LINE__,priority);
|
||||
}
|
||||
UDPServer::pThread = ControllerPatcherThread::create(UDPServer::DoUDPThread, (void*)server, ControllerPatcherThread::eAttributeAffCore2,priority);
|
||||
UDPServer::pThread->resumeThread();
|
||||
}
|
||||
|
||||
bool UDPServer::cpyIncrementBufferOffset(void * target, void * source, s32 * offset, s32 typesize, s32 maximum){
|
||||
if(((int)*offset + typesize) > maximum){
|
||||
printf("UDPServer::cpyIncrementBufferOffset(line %d): Transfer error. Excepted %04X bytes, but only got %04X\n",__LINE__,(*offset + typesize),maximum);
|
||||
return false;
|
||||
}
|
||||
memcpy(target,(void*)((u32)source+(*offset)),typesize);
|
||||
*offset += typesize;
|
||||
return true;
|
||||
}
|
||||
|
||||
void UDPServer::DoUDPThread(ControllerPatcherThread *thread, void *arg){
|
||||
UDPServer * args = (UDPServer * )arg;
|
||||
args->DoUDPThreadInternal();
|
||||
}
|
||||
|
||||
void UDPServer::DoUDPThreadInternal(){
|
||||
u8 buffer[MAX_UDP_SIZE];
|
||||
s32 n;
|
||||
|
||||
my_cb_user user;
|
||||
while(1){
|
||||
//s32 usingVar = exitThread;
|
||||
if(exitThread)break;
|
||||
memset(buffer,0,MAX_UDP_SIZE);
|
||||
n = recv(sockfd,buffer,MAX_UDP_SIZE,0);
|
||||
if (n < 0){
|
||||
s32 errno_ = wiiu_errno;
|
||||
wiiu_os_usleep(2000);
|
||||
if(errno_ != 11 && errno_ != 9){
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
s32 bufferoffset = 0;
|
||||
u8 type;
|
||||
memcpy((void *)&type,buffer,sizeof(type));
|
||||
bufferoffset += sizeof(type);
|
||||
switch (buffer[0]) {
|
||||
case WIIU_CP_UDP_CONTROLLER_READ_DATA: {
|
||||
if(gUsedProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_1){
|
||||
u8 count_commands;
|
||||
memcpy((void *)&count_commands,buffer+bufferoffset,sizeof(count_commands));
|
||||
bufferoffset += sizeof(count_commands);
|
||||
for(s32 i = 0;i<count_commands;i++){
|
||||
s32 handle;
|
||||
u16 deviceSlot;
|
||||
u32 hid;
|
||||
u8 padslot;
|
||||
u8 datasize;
|
||||
|
||||
if(!cpyIncrementBufferOffset((void *)&handle, (void *)buffer,&bufferoffset,sizeof(handle), n))continue;
|
||||
if(!cpyIncrementBufferOffset((void *)&deviceSlot, (void *)buffer,&bufferoffset,sizeof(deviceSlot),n))continue;
|
||||
hid = (1 << deviceSlot);
|
||||
if(!cpyIncrementBufferOffset((void *)&padslot, (void *)buffer,&bufferoffset,sizeof(padslot), n))continue;
|
||||
if(!cpyIncrementBufferOffset((void *)&datasize, (void *)buffer,&bufferoffset,sizeof(datasize), n))continue;
|
||||
u8 * databuffer = (u8*) malloc(datasize * sizeof(u8));
|
||||
if(!databuffer){
|
||||
printf("UDPServer::DoUDPThreadInternal(line %d): Allocating memory failed\n",__LINE__);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!cpyIncrementBufferOffset((void *)databuffer, (void *)buffer,&bufferoffset,datasize, n))continue;
|
||||
//printf("UDPServer::DoUDPThreadInternal(): Got handle: %d slot %04X hid %04X pad %02X datasize %02X\n",handle,deviceSlot,hid,padslot,datasize);
|
||||
|
||||
user.pad_slot = padslot;
|
||||
user.slotdata.deviceslot = deviceSlot;
|
||||
user.slotdata.hidmask = hid;
|
||||
|
||||
if(gNetworkController[deviceSlot][padslot][0] == 0){
|
||||
printf("UDPServer::DoUDPThreadInternal(line %d): Ehm. Pad is not connected. STOP SENDING DATA ;) \n",__LINE__);
|
||||
}else{
|
||||
ControllerPatcherHID::externHIDReadCallback(handle,databuffer,datasize,&user);
|
||||
}
|
||||
if(databuffer){
|
||||
free(databuffer);
|
||||
databuffer = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(HID_DEBUG){ printf("UDPServer::DoUDPThreadInternal(line %d): UDPServer Thread ended\n",__LINE__); }
|
||||
}
|
57
wiiu/controller_patcher/network/UDPServer.hpp
Normal file
57
wiiu/controller_patcher/network/UDPServer.hpp
Normal file
@ -0,0 +1,57 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#ifndef _UDPSERVER_WINDOW_H_
|
||||
#define _UDPSERVER_WINDOW_H_
|
||||
|
||||
#include "../ControllerPatcher.hpp"
|
||||
|
||||
#define DEFAULT_UDP_PORT 8113
|
||||
|
||||
#define WIIU_CP_UDP_CONTROLLER_READ_DATA 0x03
|
||||
|
||||
class UDPServer{
|
||||
friend class ControllerPatcher;
|
||||
|
||||
private:
|
||||
static UDPServer *getInstance() {
|
||||
if(instance == NULL)
|
||||
instance = new UDPServer(DEFAULT_UDP_PORT);
|
||||
return instance;
|
||||
}
|
||||
|
||||
static void destroyInstance() {
|
||||
if(instance != NULL){
|
||||
delete instance;
|
||||
instance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
UDPServer(s32 port);
|
||||
~UDPServer();
|
||||
void StartUDPThread(UDPServer * server);
|
||||
static void DoUDPThread(ControllerPatcherThread *thread, void *arg);
|
||||
void DoUDPThreadInternal();
|
||||
bool cpyIncrementBufferOffset(void * target, void * source, s32 * offset, s32 typesize, s32 maximum);
|
||||
|
||||
volatile s32 sockfd = -1;
|
||||
volatile s32 exitThread = 0;
|
||||
|
||||
static UDPServer *instance;
|
||||
static ControllerPatcherThread *pThread;
|
||||
};
|
||||
|
||||
#endif //_UDPSERVER_WINDOW_H_
|
703
wiiu/controller_patcher/patcher/ControllerPatcherDefs.h
Normal file
703
wiiu/controller_patcher/patcher/ControllerPatcherDefs.h
Normal file
@ -0,0 +1,703 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file ControllerPatcherDefs.h
|
||||
* @author Maschell
|
||||
* @date 30 Mar 2017
|
||||
* \brief This files contain all definitions for the ControllerPatcher engine
|
||||
*
|
||||
* @see https://github.com/Maschell/controller_patcher
|
||||
*/
|
||||
|
||||
#ifndef _CONTROLLER_PATCHER_DEFS_H_
|
||||
#define _CONTROLLER_PATCHER_DEFS_H_
|
||||
|
||||
#include <wiiu/types.h>
|
||||
|
||||
#define FIRST_INSTRUCTION_IN_SAMPLING_CALLBACK 0x9421FFB8
|
||||
|
||||
#define HID_INIT_NOT_DONE 0
|
||||
#define HID_INIT_DONE 1
|
||||
#define HID_SDCARD_READ 2
|
||||
|
||||
#define gHIDMaxDevices 32
|
||||
#define HID_MAX_DATA_LENGTH_PER_PAD 16
|
||||
#define HID_MAX_PADS_COUNT 5
|
||||
#define HID_MAX_DEVICES_PER_SLOT 2
|
||||
|
||||
#define NETWORK_CONTROLLER_VID 0
|
||||
#define NETWORK_CONTROLLER_PID 1
|
||||
#define NETWORK_CONTROLLER_ACTIVE 2
|
||||
#define NETWORK_CONTROLLER_HANDLE 3
|
||||
|
||||
|
||||
#define CONTROLLER_PATCHER_VALUE_SET 0x01
|
||||
#define CONTROLLER_PATCHER_GC_DOUBLE_USE 0x01
|
||||
#define CONTROLLER_PATCHER_INVALIDVALUE 0xFF
|
||||
|
||||
#define HID_INVALID_SLOT 0xFFFF
|
||||
#define HID_INVALID_HIDMASK 0xFFFFFFFF
|
||||
|
||||
typedef int CONTROLLER_PATCHER_RESULT_OR_ERROR;
|
||||
|
||||
#define CONTROLLER_PATCHER_ERROR_NONE 0
|
||||
#define CONTROLLER_PATCHER_ERROR_INVALID_CHAN -1
|
||||
#define CONTROLLER_PATCHER_ERROR_UNKNOWN_VID_PID -2
|
||||
#define CONTROLLER_PATCHER_ERROR_FAILED_TO_GET_HIDDATA -3
|
||||
#define CONTROLLER_PATCHER_ERROR_MAPPING_DISABLED -4
|
||||
#define CONTROLLER_PATCHER_ERROR_INVALID_BUFFER -5
|
||||
#define CONTROLLER_PATCHER_ERROR_HID_NOT_CONNECTED -6
|
||||
#define CONTROLLER_PATCHER_ERROR_NO_PAD_CONNECTED -7
|
||||
#define CONTROLLER_PATCHER_ERROR_DEVICE_SLOT_NOT_FOUND -8
|
||||
#define CONTROLLER_PATCHER_ERROR_NULL_POINTER -9
|
||||
#define CONTROLLER_PATCHER_ERROR_CONFIG_NOT_DONE -10
|
||||
#define CONTROLLER_PATCHER_ERROR_NO_FREE_SLOT -11
|
||||
#define CONTROLLER_PATCHER_ERROR_UNKNOWN -50
|
||||
|
||||
#define PRO_CONTROLLER_MODE_KPADDATA 0
|
||||
#define PRO_CONTROLLER_MODE_WPADReadData 1
|
||||
|
||||
#define STICK_VALUE_UP 1 << 1
|
||||
#define STICK_VALUE_DOWN 1 << 2
|
||||
#define STICK_VALUE_LEFT 1 << 3
|
||||
#define STICK_VALUE_RIGHT 1 << 4
|
||||
|
||||
/**
|
||||
* @brief The enumeration of Controller sticks defines
|
||||
*/
|
||||
enum Controller_Stick_Defines
|
||||
{
|
||||
STICK_CONF_MAGIC_VERSION, /**< Version of the stick configuration. Changes with every format*/
|
||||
STICK_CONF_BYTE, /**< Byte where the stick-axis data is stored*/
|
||||
STICK_CONF_DEFAULT, /**< Default value*/
|
||||
STICK_CONF_DEADZONE, /**< Size of the deadzone */
|
||||
STICK_CONF_INVERT, /**< Is 1 when the axis is inverted */
|
||||
STICK_CONF_MIN, /**< Value that represent the minimum value (-1.0f)*/
|
||||
STICK_CONF_MAX, /**< Value that represent the maximum value (1.0f) */
|
||||
STICK_CONF_ENUM_MAXVALUE /**< Maxmimum enum value for iteration*/
|
||||
};
|
||||
|
||||
#define STICK_CONF_MAGIC_VALUE 0xF0 // When you change the enum above, Dont forget to change the magic version!!!!
|
||||
|
||||
//! most data has the format: byte,value (byte starting at 0)
|
||||
enum Controller_Patcher_Settings
|
||||
{
|
||||
CONTRPS_VID, //! pid: 0x451d would be 0x45,0x1d
|
||||
CONTRPS_PID, //! vid: 0x488d would be 0x48,0x8d
|
||||
CONTRPS_BUF_SIZE, //! To set: CONTROLLER_PATCHER_VALUE_SET, BUF_SIZE (default is 64)
|
||||
CONTRPS_VPAD_BUTTON_A,
|
||||
CONTRPS_VPAD_BUTTON_B,
|
||||
CONTRPS_VPAD_BUTTON_X,
|
||||
CONTRPS_VPAD_BUTTON_Y,
|
||||
CONTRPS_DPAD_MODE, //! To set mode: CONTROLLER_PATCHER_VALUE_SET, Controller_Patcher_DPAD_MODE (default is normal mode)
|
||||
CONTRPS_DPAD_MASK, //! Mask needed for hat mode: CONTROLLER_PATCHER_VALUE_SET, mask
|
||||
/* Normal DPAD */
|
||||
CONTRPS_VPAD_BUTTON_LEFT,
|
||||
CONTRPS_VPAD_BUTTON_RIGHT,
|
||||
CONTRPS_VPAD_BUTTON_UP,
|
||||
CONTRPS_VPAD_BUTTON_DOWN,
|
||||
/* DPAD hat mode */
|
||||
CONTRPS_VPAD_BUTTON_DPAD_N,
|
||||
CONTRPS_VPAD_BUTTON_DPAD_NE,
|
||||
CONTRPS_VPAD_BUTTON_DPAD_E,
|
||||
CONTRPS_VPAD_BUTTON_DPAD_SE,
|
||||
CONTRPS_VPAD_BUTTON_DPAD_S,
|
||||
CONTRPS_VPAD_BUTTON_DPAD_SW,
|
||||
CONTRPS_VPAD_BUTTON_DPAD_W,
|
||||
CONTRPS_VPAD_BUTTON_DPAD_NW,
|
||||
CONTRPS_VPAD_BUTTON_DPAD_NEUTRAL,
|
||||
/* DPAD Absolute mode */
|
||||
CONTRPS_VPAD_BUTTON_DPAD_ABS_UP,
|
||||
CONTRPS_VPAD_BUTTON_DPAD_ABS_DOWN,
|
||||
CONTRPS_VPAD_BUTTON_DPAD_ABS_LEFT,
|
||||
CONTRPS_VPAD_BUTTON_DPAD_ABS_RIGHT,
|
||||
/* */
|
||||
CONTRPS_VPAD_BUTTON_ZL,
|
||||
CONTRPS_VPAD_BUTTON_ZR,
|
||||
CONTRPS_VPAD_BUTTON_L,
|
||||
CONTRPS_VPAD_BUTTON_R,
|
||||
CONTRPS_VPAD_BUTTON_PLUS,
|
||||
CONTRPS_VPAD_BUTTON_MINUS,
|
||||
CONTRPS_VPAD_BUTTON_HOME,
|
||||
CONTRPS_VPAD_BUTTON_SYNC,
|
||||
CONTRPS_VPAD_BUTTON_STICK_R,
|
||||
CONTRPS_VPAD_BUTTON_STICK_L,
|
||||
|
||||
CONTRPS_VPAD_STICK_R_EMULATION_LEFT,
|
||||
CONTRPS_VPAD_STICK_R_EMULATION_RIGHT,
|
||||
CONTRPS_VPAD_STICK_R_EMULATION_UP,
|
||||
CONTRPS_VPAD_STICK_R_EMULATION_DOWN,
|
||||
CONTRPS_VPAD_STICK_L_EMULATION_LEFT,
|
||||
CONTRPS_VPAD_STICK_L_EMULATION_RIGHT,
|
||||
CONTRPS_VPAD_STICK_L_EMULATION_UP,
|
||||
CONTRPS_VPAD_STICK_L_EMULATION_DOWN,
|
||||
|
||||
CONTRPS_VPAD_BUTTON_L_STICK_X, //! byte, default value
|
||||
CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT, //! To invert: CONTROLLER_PATCHER_VALUE_SET, 0x01
|
||||
CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE, //! Deadzone
|
||||
CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX, //! min,max
|
||||
CONTRPS_VPAD_BUTTON_L_STICK_Y, //! byte, default value
|
||||
CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT, //! To invert: CONTROLLER_PATCHER_VALUE_SET, 0x01
|
||||
CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE, //! Deadzone
|
||||
CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX, //! min,max
|
||||
CONTRPS_VPAD_BUTTON_R_STICK_X, //! byte, default value
|
||||
CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT, //! To invert: CONTROLLER_PATCHER_VALUE_SET, 0x01
|
||||
CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE, //! Deadzone
|
||||
CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX, //! min,max
|
||||
CONTRPS_VPAD_BUTTON_R_STICK_Y, //! byte, default value
|
||||
CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT, //! To invert: CONTROLLER_PATCHER_VALUE_SET, 0x01
|
||||
CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE, //! Deadzone
|
||||
CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX, //! min,max
|
||||
|
||||
CONTRPS_VPAD_BUTTON_L_STICK_UP,
|
||||
CONTRPS_VPAD_BUTTON_L_STICK_DOWN,
|
||||
CONTRPS_VPAD_BUTTON_L_STICK_LEFT,
|
||||
CONTRPS_VPAD_BUTTON_L_STICK_RIGHT,
|
||||
CONTRPS_VPAD_BUTTON_R_STICK_UP,
|
||||
CONTRPS_VPAD_BUTTON_R_STICK_DOWN,
|
||||
CONTRPS_VPAD_BUTTON_R_STICK_LEFT,
|
||||
CONTRPS_VPAD_BUTTON_R_STICK_RIGHT,
|
||||
|
||||
CONTRPS_VPAD_BUTTON_TV,
|
||||
CONTRPS_DOUBLE_USE, //!When used: e.g. CONTROLLER_PATCHER_VALUE_SET, CONTROLLER_PATCHER_GC_DOUBLE_USE
|
||||
CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR,
|
||||
CONTRPS_DOUBLE_USE_BUTTON_1_PRESSED,
|
||||
CONTRPS_DOUBLE_USE_BUTTON_2_PRESSED,
|
||||
CONTRPS_DOUBLE_USE_BUTTON_3_PRESSED,
|
||||
CONTRPS_DOUBLE_USE_BUTTON_4_PRESSED,
|
||||
CONTRPS_DOUBLE_USE_BUTTON_5_PRESSED,
|
||||
CONTRPS_DOUBLE_USE_BUTTON_1_RELEASED,
|
||||
CONTRPS_DOUBLE_USE_BUTTON_2_RELEASED,
|
||||
CONTRPS_DOUBLE_USE_BUTTON_3_RELEASED,
|
||||
CONTRPS_DOUBLE_USE_BUTTON_4_RELEASED,
|
||||
CONTRPS_DOUBLE_USE_BUTTON_5_RELEASED,
|
||||
CONTRPS_PAD_COUNT, //!
|
||||
CONTRPS_CONNECTED_PADS, //!
|
||||
CONTRPS_INPUT_FILTER, //!
|
||||
CONTRPS_PAD1_FILTER, //!
|
||||
CONTRPS_PAD2_FILTER, //!
|
||||
CONTRPS_PAD3_FILTER, //!
|
||||
CONTRPS_PAD4_FILTER, //!
|
||||
CONTRPS_PAD5_FILTER, //!
|
||||
CONTRPS_MOUSE_STICK,
|
||||
CONTRPS_MAX_VALUE
|
||||
};
|
||||
/**
|
||||
* @brief The enumeration of different DPAD-Modes
|
||||
*/
|
||||
enum Controller_Patcher_DPAD_MODE
|
||||
{
|
||||
CONTRPDM_Normal, /**< Normal mode */
|
||||
CONTRPDM_Hat, /**< Hat mode */
|
||||
CONTRPDM_Absolute_2Values, /**< DPAD Value stored in 2 values (one for each axis), acting like a stick */
|
||||
};
|
||||
/**
|
||||
* @brief The enumeration of DPAD Settings. Needed for saving both in the PADConst.
|
||||
*/
|
||||
enum Controller_Patcher_DPAD_Settings
|
||||
{
|
||||
CONTRDPAD_MODE = 0, /**< Byte where the DPAD Mode is stored */
|
||||
CONTRDPAD_MASK = 1, /**< Byte where the DPAD Mask is stored */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Stores data if the Slot the device is using in gHID_Devices
|
||||
*/
|
||||
typedef struct _HIDSlotData{
|
||||
u16 deviceslot; /**< deviceslot number */
|
||||
u32 hidmask; /**< Used HID-Mask */
|
||||
}HIDSlotData;
|
||||
|
||||
/**
|
||||
* @brief Stores a VID and PID
|
||||
*/
|
||||
typedef struct _DeviceVIDPIDInfo{
|
||||
u16 vid; /**< Vendor ID of this device */
|
||||
u16 pid; /**< Product ID of this device */
|
||||
}DeviceVIDPIDInfo;
|
||||
|
||||
/**
|
||||
* @brief Struct where the data for the callback funtion is stored
|
||||
*/
|
||||
typedef struct _my_cb_user{
|
||||
u8 *buf; /**< pointer the buffer that is used */
|
||||
u32 transfersize; /**< number of transfered data */
|
||||
u32 handle; /**< HID handle */
|
||||
HIDSlotData slotdata; /**< Information about the deviceslot and hidmask */
|
||||
u32 pads_per_device; /**< Number of maximum pads of this device */
|
||||
u8 pad_slot; /**< number of the pad that will be used */
|
||||
u8 rumblestatus[HID_MAX_PADS_COUNT]; /**< Current status of the device rumble */
|
||||
u8 forceRumbleInTicks[HID_MAX_PADS_COUNT];
|
||||
DeviceVIDPIDInfo vidpid; /**< The VID/PID of the device */
|
||||
}my_cb_user;
|
||||
|
||||
/**
|
||||
* @brief Stores data for the mouse
|
||||
*/
|
||||
typedef struct _HID_Mouse_Data {
|
||||
u8 left_click; /**< Is 1 when the left mouse button is pressed */
|
||||
u8 right_click; /**< Is 1 when the right mouse button is pressed */
|
||||
s16 X; /**< X position of the cursor */
|
||||
s16 Y; /**< Y position of the cursor */
|
||||
s16 deltaX; /**< difference of the X value since the last call */
|
||||
s16 deltaY; /**< difference of the Y value since the last call */
|
||||
u8 valuedChanged; /**< Is 1 when the value has changed */
|
||||
} HID_Mouse_Data;
|
||||
|
||||
/**
|
||||
* @brief The enumeration of device types
|
||||
*/
|
||||
typedef enum DEVICE_TYPE_
|
||||
{
|
||||
DEVICE_TYPE_CONTROLLER = 0, /**< Normal Controller */
|
||||
DEVICE_TYPE_MOUSE = 1, /**< Mouse */
|
||||
}DEVICE_TYPE;
|
||||
|
||||
/**
|
||||
* @brief Stores all data of the HID Device for accessing
|
||||
*/
|
||||
typedef struct _HID_Data {
|
||||
u32 handle; /**< The HID-handle this device is using */
|
||||
u8 rumbleActive; /**< 1 when rumble is active */
|
||||
u32 last_buttons; /**< The last pressed buttons, based on VPAD_BUTTON_XXX data */
|
||||
union{
|
||||
struct{
|
||||
u8 cur_hid_data[HID_MAX_DATA_LENGTH_PER_PAD]; /**< Array where the current controller data is stored */
|
||||
u8 last_hid_data[HID_MAX_DATA_LENGTH_PER_PAD]; /**< Array where the last controller data is stored */
|
||||
} controller; /**< Used when the device in a controller. Using u8 array where the raw data of the controller is placed. */
|
||||
struct{
|
||||
HID_Mouse_Data cur_mouse_data; /**< Struct where the current mouse data is stored */
|
||||
HID_Mouse_Data last_mouse_data; /**< Struct where the last mouse data is stored */
|
||||
} mouse; /**< Used when the device in a mouse. Using a new struct to store the data. */
|
||||
}data_union; /**< The data union where the current and last data is stored.*/
|
||||
DEVICE_TYPE type; /**< The device type*/
|
||||
HIDSlotData slotdata; /**< Information about the deviceslot and his mask*/
|
||||
my_cb_user * user_data; /**< Pointer to the user data the read callback is using*/
|
||||
} HID_Data;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Struct where current hid data of one device type is stored
|
||||
*/
|
||||
typedef struct _HID_DEVICE_DATA {
|
||||
HID_Data pad_data[HID_MAX_PADS_COUNT];
|
||||
} HID_DEVICE_DATA;
|
||||
|
||||
/**
|
||||
* @brief Infos of the device
|
||||
*/
|
||||
typedef struct _DeviceInfo{
|
||||
HIDSlotData slotdata; /**< The slot used by this device */
|
||||
DeviceVIDPIDInfo vidpid; /**< The VID/PID of the device */
|
||||
u8 pad_count; /**< Number of maximum pads this device can have*/
|
||||
}DeviceInfo;
|
||||
|
||||
/**
|
||||
* @brief The enumeration of Controller-Mapping types
|
||||
*/
|
||||
typedef enum ControllerMapping_Type_Defines_{
|
||||
CM_Type_Controller = 0, /**< Device with single input */
|
||||
CM_Type_RealController = 1, /**< Real Pro Controller */
|
||||
CM_Type_Mouse = 2, /**< Mouse */
|
||||
CM_Type_Keyboard = 3, /**< Keyboard */
|
||||
} ControllerMapping_Type_Defines;
|
||||
|
||||
/**
|
||||
* @brief Infos of a mapped controller
|
||||
*/
|
||||
typedef struct _ControllerMappingPADInfo{
|
||||
u8 active; /**< Set to one if mapped */
|
||||
ControllerMapping_Type_Defines type; /**< Type of the controller mapping */
|
||||
DeviceVIDPIDInfo vidpid; /**< The VID/PID of the device */
|
||||
u8 pad; /**< Stores which pad it mapped */
|
||||
}ControllerMappingPADInfo;
|
||||
|
||||
/**
|
||||
* @brief Infos of a mapped controller
|
||||
*/
|
||||
typedef struct _ControllerMappingPAD{
|
||||
ControllerMappingPADInfo pad_infos[HID_MAX_DEVICES_PER_SLOT]; //lets limit this to HID_MAX_DEVICES_PER_SLOT.
|
||||
u8 useAll;
|
||||
u8 rumble; /**< Set when the controller should rumble */
|
||||
}ControllerMappingPAD;
|
||||
|
||||
/**
|
||||
* @brief Stores informations about all mapped controller
|
||||
*/
|
||||
typedef struct _ControllerMapping{
|
||||
ControllerMappingPAD gamepad; /**< Information about the gamepad mapping */
|
||||
ControllerMappingPAD proController[4]; /**< Information about the Pro Controller mapping */
|
||||
}ControllerMapping;
|
||||
|
||||
/**
|
||||
* @brief Pressed/Released/Down Button data.
|
||||
*/
|
||||
typedef struct _InputButtonData{
|
||||
u32 hold; /**< Buttons beeing hold */
|
||||
u32 trigger; /**< Buttons that started pressing */
|
||||
u32 release; /**< Buttons that were button released */
|
||||
}InputButtonData;
|
||||
|
||||
typedef struct _InputStickData{
|
||||
f32 leftStickX;
|
||||
f32 leftStickY;
|
||||
f32 rightStickX;
|
||||
f32 rightStickY;
|
||||
}InputStickData;
|
||||
|
||||
/**
|
||||
* @brief Struct where the inputdata of a device for all HID_MAX_PADS_COUNT pads can be stored
|
||||
*/
|
||||
typedef struct _InputData{
|
||||
DeviceInfo device_info; /**< Infos about the device where the data is coming from */
|
||||
u8 status;
|
||||
InputButtonData button_data;
|
||||
InputStickData stick_data;
|
||||
}InputData;
|
||||
|
||||
/**
|
||||
* @brief The enumeration of WiiU Controller types
|
||||
*/
|
||||
enum UController_Type{
|
||||
UController_Type_Gamepad,
|
||||
UController_Type_Pro1,
|
||||
UController_Type_Pro2,
|
||||
UController_Type_Pro3,
|
||||
UController_Type_Pro4,
|
||||
};
|
||||
|
||||
#define UController_Type_Gamepad_Name gettext("GamePad")
|
||||
#define UController_Type_Pro1_Name gettext("Pro Controller 1")
|
||||
#define UController_Type_Pro2_Name gettext("Pro Controller 2")
|
||||
#define UController_Type_Pro3_Name gettext("Pro Controller 3")
|
||||
#define UController_Type_Pro4_Name gettext("Pro Controller 4")
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* VID/PID values
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#define HID_GC_VID 0x057e
|
||||
#define HID_GC_PID 0x0337
|
||||
|
||||
#define HID_KEYBOARD_VID 0xAFFE
|
||||
#define HID_KEYBOARD_PID 0XAAAC
|
||||
|
||||
#define HID_MOUSE_VID 0xAFFE
|
||||
#define HID_MOUSE_PID 0XAAAB
|
||||
|
||||
#define HID_DS3_VID 0x054c
|
||||
#define HID_DS3_PID 0x0268
|
||||
|
||||
#define HID_DS4_VID 0x054c
|
||||
#define HID_DS4_PID 0x05c4
|
||||
|
||||
#define HID_NEW_DS4_VID 0x054c
|
||||
#define HID_NEW_DS4_PID 0x09CC
|
||||
|
||||
#define HID_XINPUT_VID 0x7331
|
||||
#define HID_XINPUT_PID 0x1337
|
||||
|
||||
#define HID_SWITCH_PRO_VID 0x057e
|
||||
#define HID_SWITCH_PRO_PID 0x2009
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* GC Adapter
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#define HID_GC_BUTTON_A_VALUE 0x01
|
||||
#define HID_GC_BUTTON_B_VALUE 0x02
|
||||
#define HID_GC_BUTTON_X_VALUE 0x04
|
||||
#define HID_GC_BUTTON_Y_VALUE 0x08
|
||||
#define HID_GC_BUTTON_LEFT_VALUE 0x10
|
||||
#define HID_GC_BUTTON_RIGHT_VALUE 0x20
|
||||
#define HID_GC_BUTTON_DOWN_VALUE 0x40
|
||||
#define HID_GC_BUTTON_UP_VALUE 0x80
|
||||
|
||||
#define HID_GC_BUTTON_START_VALUE 0x01
|
||||
#define HID_GC_BUTTON_L_VALUE 0x80
|
||||
#define HID_GC_BUTTON_R_VALUE 0x80
|
||||
#define HID_GC_BUTTON_Z_VALUE 0x02
|
||||
|
||||
#define HID_GC_PAD_COUNT 4
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* DS3
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#define PS3_F4_REPORT_LEN 4
|
||||
#define PS3_F5_REPORT_LEN 8
|
||||
#define PS3_01_REPORT_LEN 48
|
||||
#define HID_REPORT_FEATURE 3
|
||||
#define HID_REPORT_OUTPUT 2
|
||||
#define PS3_F4_REPORT_ID 0xF4
|
||||
#define PS3_01_REPORT_ID 0x01
|
||||
#define PS3_F5_REPORT_ID 0xF5
|
||||
|
||||
#define HID_DS3_BUTTON_CROSS_VALUE 0x40 // 3
|
||||
#define HID_DS3_BUTTON_CIRCLE_VALUE 0x20 // 3
|
||||
#define HID_DS3_BUTTON_SQUARE_VALUE 0x80 // 3
|
||||
#define HID_DS3_BUTTON_TRIANGLE_VALUE 0x10 // 3
|
||||
#define HID_DS3_BUTTON_L1_VALUE 0x04 // 3
|
||||
#define HID_DS3_BUTTON_L2_VALUE 0x01 // 3
|
||||
#define HID_DS3_BUTTON_R1_VALUE 0x08 // 3
|
||||
#define HID_DS3_BUTTON_R2_VALUE 0x02 // 3
|
||||
|
||||
#define HID_DS3_BUTTON_L3_VALUE 0x02 // 2
|
||||
#define HID_DS3_BUTTON_R3_VALUE 0x04 // 2
|
||||
#define HID_DS3_BUTTON_SELECT_VALUE 0x01 // 2
|
||||
#define HID_DS3_BUTTON_START_VALUE 0x08 // 2
|
||||
#define HID_DS3_BUTTON_LEFT_VALUE 0x80 // 2
|
||||
#define HID_DS3_BUTTON_RIGHT_VALUE 0x20 // 2
|
||||
#define HID_DS3_BUTTON_UP_VALUE 0x10 // 2
|
||||
#define HID_DS3_BUTTON_DOWN_VALUE 0x40 // 2
|
||||
#define HID_DS3_BUTTON_GUIDE_VALUE 0x01 // 4
|
||||
|
||||
#define HID_DS3_PAD_COUNT 1
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* DS4
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#define HID_DS4_BUTTON_CROSS_VALUE 0x20 // 5
|
||||
#define HID_DS4_BUTTON_SQUARE_VALUE 0x10 // 5
|
||||
#define HID_DS4_BUTTON_CIRCLE_VALUE 0x40 // 5
|
||||
#define HID_DS4_BUTTON_TRIANGLE_VALUE 0x80 // 5
|
||||
#define HID_DS4_BUTTON_L1_VALUE 0x01 // 6
|
||||
#define HID_DS4_BUTTON_L2_VALUE 0x04 // 6
|
||||
#define HID_DS4_BUTTON_L3_VALUE 0x40 // 6
|
||||
#define HID_DS4_BUTTON_R1_VALUE 0x02 // 6
|
||||
#define HID_DS4_BUTTON_R2_VALUE 0x08 // 6
|
||||
#define HID_DS4_BUTTON_R3_VALUE 0x80 // 6
|
||||
#define HID_DS4_BUTTON_SHARE_VALUE 0x10 // 6
|
||||
#define HID_DS4_BUTTON_OPTIONS_VALUE 0x20 // 6
|
||||
|
||||
#define HID_DS4_BUTTON_DPAD_MASK_VALUE 0x0F
|
||||
|
||||
#define HID_DS4_BUTTON_DPAD_N_VALUE 0x00 // 5
|
||||
#define HID_DS4_BUTTON_DPAD_NE_VALUE 0x01 // 5
|
||||
#define HID_DS4_BUTTON_DPAD_E_VALUE 0x02 // 5
|
||||
#define HID_DS4_BUTTON_DPAD_SE_VALUE 0x03 // 5
|
||||
#define HID_DS4_BUTTON_DPAD_S_VALUE 0x04 // 5
|
||||
#define HID_DS4_BUTTON_DPAD_SW_VALUE 0x05 // 5
|
||||
#define HID_DS4_BUTTON_DPAD_W_VALUE 0x06 // 5
|
||||
#define HID_DS4_BUTTON_DPAD_NW_VALUE 0x07 // 5
|
||||
#define HID_DS4_BUTTON_DPAD_NEUTRAL_VALUE 0x08 // 5
|
||||
|
||||
#define HID_DS4_BUTTON_GUIDE_VALUE 0x01 // 7
|
||||
#define HID_DS4_BUTTON_T_PAD_CLICK_VALUE 0x02 // 7
|
||||
|
||||
#define HID_DS4_PAD_COUNT 1
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* XInput
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#define HID_XINPUT_BUTTON_A_VALUE 0x01 // 7
|
||||
#define HID_XINPUT_BUTTON_B_VALUE 0x02 // 7
|
||||
#define HID_XINPUT_BUTTON_X_VALUE 0x04 // 7
|
||||
#define HID_XINPUT_BUTTON_Y_VALUE 0x08 // 7
|
||||
|
||||
#define HID_XINPUT_BUTTON_START_VALUE 0x02 // 6
|
||||
#define HID_XINPUT_BUTTON_BACK_VALUE 0x01 // 6
|
||||
#define HID_XINPUT_BUTTON_GUIDE_VALUE 0x80 // 6
|
||||
|
||||
#define HID_XINPUT_BUTTON_LB_VALUE 0x04 // 6
|
||||
#define HID_XINPUT_BUTTON_RB_VALUE 0x08 // 6
|
||||
|
||||
#define HID_XINPUT_BUTTON_L3_VALUE 0x10 // 6
|
||||
#define HID_XINPUT_BUTTON_R3_VALUE 0x20 // 6
|
||||
|
||||
#define HID_XINPUT_BUTTON_LT_VALUE 0x80 // 4
|
||||
#define HID_XINPUT_BUTTON_RT_VALUE 0x80 // 5
|
||||
|
||||
#define HID_XINPUT_BUTTON_DPAD_MASK_VALUE 0xF0
|
||||
#define HID_XINPUT_BUTTON_LEFT_VALUE 0x10 // 7
|
||||
#define HID_XINPUT_BUTTON_RIGHT_VALUE 0x40 // 7
|
||||
#define HID_XINPUT_BUTTON_DOWN_VALUE 0x80 // 7
|
||||
#define HID_XINPUT_BUTTON_UP_VALUE 0x20 // 7
|
||||
|
||||
#define HID_XINPUT_PAD_COUNT 1
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Switch Pro Controller
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_A_VALUE 0x08000000
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_B_VALUE 0x04000000
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_X_VALUE 0x02000000
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_Y_VALUE 0x01000000
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_PLUS_VALUE 0x00020000
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_MINUS_VALUE 0x00010000
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_HOME_VALUE 0x00100000
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_SCREENSHOT_VALUE 0x00200000
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_R_VALUE 0x40000000
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_ZR_VALUE 0x80000000
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_STICK_R_VALUE 0x00040000
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_L_VALUE 0x00004000
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_ZL_VALUE 0x00008000
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_STICK_L_VALUE 0x00080000
|
||||
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_DPAD_MASK_VALUE 0x0F
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE 0x08 // 2
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE 0x04 // 2
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_DOWN_VALUE 0x01 // 2
|
||||
#define HID_SWITCH_PRO_USB_BUTTON_UP_VALUE 0x02 // 2
|
||||
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_A_VALUE 0x02000000
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_B_VALUE 0x01000000
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_X_VALUE 0x08000000
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_Y_VALUE 0x04000000
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_PLUS_VALUE 0x00020000
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_MINUS_VALUE 0x00010000
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_HOME_VALUE 0x00100000
|
||||
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_R_VALUE 0x20000000
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_ZR_VALUE 0x80000000
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_STICK_R_VALUE 0x00080000
|
||||
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_L_VALUE 0x10000000
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_ZL_VALUE 0x40000000
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_STICK_L_VALUE 0x00040000
|
||||
|
||||
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_DPAD_MASK_VALUE 0x0F
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_DPAD_N_VALUE 0x00 // 2
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_DPAD_NE_VALUE 0x01 // 2
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_DPAD_E_VALUE 0x02 // 2
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_DPAD_SE_VALUE 0x03 // 2
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_DPAD_S_VALUE 0x04 // 2
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_DPAD_SW_VALUE 0x05 // 2
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_DPAD_W_VALUE 0x06 // 2
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_DPAD_NW_VALUE 0x07 // 2
|
||||
#define HID_SWITCH_PRO_BT_BUTTON_DPAD_NEUTRAL_VALUE 0x08 // 2
|
||||
|
||||
|
||||
#define HID_SWITCH_PRO_BT_PAD_COUNT 1
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Keyboard (Full list is on: http://www.freebsddiary.org/APC/usb_hid_usages.php)
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#define HID_KEYBOARD_BUTTON_SHIFT 0x02
|
||||
|
||||
#define HID_KEYBOARD_BUTTON_A 0x04
|
||||
#define HID_KEYBOARD_BUTTON_B 0x05
|
||||
#define HID_KEYBOARD_BUTTON_C 0x06
|
||||
#define HID_KEYBOARD_BUTTON_D 0x07
|
||||
#define HID_KEYBOARD_BUTTON_E 0x08
|
||||
#define HID_KEYBOARD_BUTTON_F 0x09
|
||||
#define HID_KEYBOARD_BUTTON_G 0x0A
|
||||
#define HID_KEYBOARD_BUTTON_H 0x0B
|
||||
#define HID_KEYBOARD_BUTTON_I 0x0C
|
||||
#define HID_KEYBOARD_BUTTON_J 0x0D
|
||||
#define HID_KEYBOARD_BUTTON_K 0x0E
|
||||
#define HID_KEYBOARD_BUTTON_L 0x0F
|
||||
#define HID_KEYBOARD_BUTTON_M 0x10
|
||||
#define HID_KEYBOARD_BUTTON_N 0x11
|
||||
#define HID_KEYBOARD_BUTTON_O 0x12
|
||||
#define HID_KEYBOARD_BUTTON_P 0x13
|
||||
#define HID_KEYBOARD_BUTTON_Q 0x14
|
||||
#define HID_KEYBOARD_BUTTON_R 0x15
|
||||
#define HID_KEYBOARD_BUTTON_S 0x16
|
||||
#define HID_KEYBOARD_BUTTON_T 0x17
|
||||
#define HID_KEYBOARD_BUTTON_U 0x18
|
||||
#define HID_KEYBOARD_BUTTON_V 0x19
|
||||
#define HID_KEYBOARD_BUTTON_W 0x1A
|
||||
#define HID_KEYBOARD_BUTTON_X 0x1B
|
||||
#define HID_KEYBOARD_BUTTON_Y 0x1C
|
||||
#define HID_KEYBOARD_BUTTON_Z 0x1D
|
||||
#define HID_KEYBOARD_BUTTON_F1 0x3A
|
||||
#define HID_KEYBOARD_BUTTON_F2 0x3B
|
||||
#define HID_KEYBOARD_BUTTON_F3 0x3C
|
||||
#define HID_KEYBOARD_BUTTON_F4 0x3D
|
||||
#define HID_KEYBOARD_BUTTON_F5 0x3E
|
||||
#define HID_KEYBOARD_BUTTON_F6 0x3F
|
||||
#define HID_KEYBOARD_BUTTON_F7 0x40
|
||||
#define HID_KEYBOARD_BUTTON_F8 0x41
|
||||
#define HID_KEYBOARD_BUTTON_F9 0x42
|
||||
#define HID_KEYBOARD_BUTTON_F10 0x43
|
||||
#define HID_KEYBOARD_BUTTON_F11 0x44
|
||||
#define HID_KEYBOARD_BUTTON_F12 0x45
|
||||
#define HID_KEYBOARD_BUTTON_1 0x1E
|
||||
#define HID_KEYBOARD_BUTTON_2 0x1F
|
||||
#define HID_KEYBOARD_BUTTON_3 0x20
|
||||
#define HID_KEYBOARD_BUTTON_4 0x21
|
||||
#define HID_KEYBOARD_BUTTON_5 0x22
|
||||
#define HID_KEYBOARD_BUTTON_6 0x23
|
||||
#define HID_KEYBOARD_BUTTON_7 0x24
|
||||
#define HID_KEYBOARD_BUTTON_8 0x25
|
||||
#define HID_KEYBOARD_BUTTON_9 0x26
|
||||
#define HID_KEYBOARD_BUTTON_0 0x27
|
||||
|
||||
#define HID_KEYBOARD_BUTTON_RETURN 0x28
|
||||
#define HID_KEYBOARD_BUTTON_ESCAPE 0x29
|
||||
#define HID_KEYBOARD_BUTTON_DELETE 0x2A
|
||||
#define HID_KEYBOARD_BUTTON_TAB 0x2B
|
||||
#define HID_KEYBOARD_BUTTON_SPACEBAR 0x2C
|
||||
#define HID_KEYBOARD_BUTTON_CAPSLOCK 0x39
|
||||
#define HID_KEYBOARD_BUTTON_PRINTSCREEN 0x46
|
||||
#define HID_KEYBOARD_BUTTON_SCROLLLOCK 0x47
|
||||
#define HID_KEYBOARD_BUTTON_PAUSE 0x48
|
||||
#define HID_KEYBOARD_BUTTON_INSERT 0x49
|
||||
#define HID_KEYBOARD_BUTTON_HOME 0x4A
|
||||
#define HID_KEYBOARD_BUTTON_PAGEUP 0x4B
|
||||
#define HID_KEYBOARD_BUTTON_PAGEDOWN 0x4E
|
||||
#define HID_KEYBOARD_BUTTON_DELETEFORWARD 0x4C
|
||||
#define HID_KEYBOARD_BUTTON_END 0x4D
|
||||
#define HID_KEYBOARD_BUTTON_LEFT_CONTROL 0xE0
|
||||
#define HID_KEYBOARD_BUTTON_LEFT_ALT 0xE2
|
||||
#define HID_KEYBOARD_BUTTON_RIGHT_CONTROL 0xE4
|
||||
#define HID_KEYBOARD_BUTTON_RIGHT_SHIFT 0xE5
|
||||
#define HID_KEYBOARD_BUTTON_RIGHT_ALT 0xE6
|
||||
|
||||
#define HID_KEYBOARD_BUTTON_LEFT 0x50
|
||||
#define HID_KEYBOARD_BUTTON_RIGHT 0x4f
|
||||
#define HID_KEYBOARD_BUTTON_DOWN 0x51
|
||||
#define HID_KEYBOARD_BUTTON_UP 0x52
|
||||
|
||||
#define HID_KEYBOARD_KEYPAD_BUTTON_1 0x59
|
||||
#define HID_KEYBOARD_KEYPAD_BUTTON_2 0x5A
|
||||
#define HID_KEYBOARD_KEYPAD_BUTTON_3 0x5B
|
||||
#define HID_KEYBOARD_KEYPAD_BUTTON_4 0x5C
|
||||
#define HID_KEYBOARD_KEYPAD_BUTTON_5 0x5D
|
||||
#define HID_KEYBOARD_KEYPAD_BUTTON_6 0x5E
|
||||
#define HID_KEYBOARD_KEYPAD_BUTTON_7 0x5F
|
||||
#define HID_KEYBOARD_KEYPAD_BUTTON_8 0x60
|
||||
#define HID_KEYBOARD_KEYPAD_BUTTON_9 0x61
|
||||
#define HID_KEYBOARD_KEYPAD_BUTTON_0 0x62
|
||||
#define HID_KEYBOARD_KEYPAD_BUTTON_NUMLOCK 0x53
|
||||
#define HID_KEYBOARD_KEYPAD_BUTTON_MINUS 0x56
|
||||
#define HID_KEYBOARD_KEYPAD_BUTTON_PLUS 0x57
|
||||
|
||||
#define HID_KEYBOARD_PAD_COUNT 1
|
||||
#define HID_KEYBOARD_DATA_LENGTH 8
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Mouse
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#define HID_MOUSE_BUTTON_LEFTCLICK 0x04
|
||||
#define HID_MOUSE_BUTTON_RIGHTCLICK 0x05
|
||||
|
||||
#define HID_MOUSE_PAD_COUNT 1
|
||||
|
||||
#define HID_MOUSE_MODE_AIM 0x01
|
||||
#define HID_MOUSE_MODE_TOUCH 0x02
|
||||
|
||||
#endif /* _CONTROLLER_PATCHER_DEFS_H_ */
|
707
wiiu/controller_patcher/patcher/ControllerPatcherHID.cpp
Normal file
707
wiiu/controller_patcher/patcher/ControllerPatcherHID.cpp
Normal file
@ -0,0 +1,707 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "ControllerPatcherHID.hpp"
|
||||
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "wiiu/os.h"
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* public implementation for the network controller
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
s32 ControllerPatcherHID::externAttachDetachCallback(HIDDevice *p_device, u32 attach){
|
||||
HIDClient client;
|
||||
memset(&client,0,sizeof(client));
|
||||
return AttachDetachCallback(&client,p_device,attach);
|
||||
}
|
||||
|
||||
void ControllerPatcherHID::externHIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr){
|
||||
HIDReadCallback(handle,buf,bytes_transfered,usr);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* private implementation for the HID Api.
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
s32 ControllerPatcherHID::myAttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, u32 attach){
|
||||
return AttachDetachCallback(p_client,p_device,attach);
|
||||
}
|
||||
|
||||
void ControllerPatcherHID::myHIDMouseReadCallback(u32 handle, s32 error, unsigned char *buf, u32 bytes_transfered, void *p_user){
|
||||
if(error == 0){
|
||||
my_cb_user *usr = (my_cb_user*)p_user;
|
||||
|
||||
u32 slot = 0;
|
||||
if(usr->pad_slot < HID_MAX_PADS_COUNT){
|
||||
slot = usr->pad_slot;
|
||||
}
|
||||
|
||||
HID_Data * data_ptr = &(gHID_Devices[usr->slotdata.deviceslot].pad_data[slot]);
|
||||
HID_Mouse_Data * cur_mouse_data = &data_ptr->data_union.mouse.cur_mouse_data;
|
||||
|
||||
data_ptr->type = DEVICE_TYPE_MOUSE;
|
||||
//printf("%02X %02X %02X %02X %02X bytes_transfered: %d\n",buf[0],buf[1],buf[2],buf[3],buf[4],bytes_transfered);
|
||||
|
||||
if(buf[0] == 2 && bytes_transfered > 3){ // using the other mouse mode
|
||||
buf +=1;
|
||||
}
|
||||
|
||||
s8 x_value = 0;
|
||||
s8 y_value = 0;
|
||||
|
||||
x_value = buf[1];
|
||||
y_value = buf[2];
|
||||
|
||||
cur_mouse_data->X += x_value;
|
||||
cur_mouse_data->deltaX = x_value;
|
||||
|
||||
cur_mouse_data->Y += y_value;
|
||||
cur_mouse_data->deltaY = y_value;
|
||||
|
||||
cur_mouse_data->left_click = buf[0];
|
||||
cur_mouse_data->right_click = buf[0]>>1;
|
||||
|
||||
if(cur_mouse_data->X < 0) cur_mouse_data->X = 0;
|
||||
if(cur_mouse_data->X > 1280) cur_mouse_data->X = 1280;
|
||||
|
||||
if(cur_mouse_data->Y < 0) cur_mouse_data->Y = 0;
|
||||
if(cur_mouse_data->Y > 720) cur_mouse_data->Y = 720;
|
||||
|
||||
cur_mouse_data->valuedChanged = 1;
|
||||
|
||||
//printf("%02X %02X %02X %02X %02X %02X %02X %02X %d = X: %d Y: %d \n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],bytes_transfered,x_value,y_value);
|
||||
|
||||
HIDRead(handle, usr->buf, bytes_transfered, myHIDMouseReadCallback, usr);
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerPatcherHID::myHIDReadCallback(u32 handle, s32 error, unsigned char *buf, u32 bytes_transfered, void *p_user){
|
||||
if(error == 0 && p_user != NULL && gHIDAttached){
|
||||
my_cb_user *usr = (my_cb_user*)p_user;
|
||||
|
||||
HIDReadCallback(handle,buf,bytes_transfered,usr);
|
||||
|
||||
if(usr->slotdata.hidmask == gHID_LIST_DS4){
|
||||
wiiu_os_usleep(1000*2); //DS4 is way tooo fast. sleeping to reduce lag. (need to check the other pads)
|
||||
}
|
||||
HIDRead(handle, usr->buf, bytes_transfered, myHIDReadCallback, usr);
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Intern Callback actions
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
s32 ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, u32 attach){
|
||||
if(attach){
|
||||
printf("ControllerPatcherHID::AttachDetachCallback(line %d): vid %04x pid %04x connected\n",__LINE__, SWAP16(p_device->vid),SWAP16(p_device->pid));
|
||||
if(HID_DEBUG){ printf("interface index %02x\n", p_device->interface_index);
|
||||
printf("sub class %02x\n", p_device->sub_class);
|
||||
printf("protocol %02x\n", p_device->protocol);
|
||||
printf("max packet in %02x\n", p_device->max_packet_size_rx);
|
||||
printf("max packet out %02x\n", p_device->max_packet_size_tx); }
|
||||
}
|
||||
if(!attach){
|
||||
printf("ControllerPatcherHID::AttachDetachCallback(line %d): vid %04x pid %04x disconnected\n",__LINE__, SWAP16(p_device->vid),SWAP16(p_device->pid));
|
||||
}
|
||||
DeviceInfo device_info;
|
||||
memset(&device_info,0,sizeof(DeviceInfo));
|
||||
device_info.slotdata.deviceslot = -1;
|
||||
device_info.vidpid.vid = SWAP16(p_device->vid);
|
||||
device_info.vidpid.pid = SWAP16(p_device->pid);
|
||||
|
||||
HIDSlotData * slotdata = &(device_info.slotdata);
|
||||
|
||||
if ((p_device->sub_class == 1) && (p_device->protocol == 1)) { //Keyboard
|
||||
slotdata->hidmask = gHID_LIST_KEYBOARD;
|
||||
slotdata->deviceslot = gHID_SLOT_KEYBOARD;
|
||||
//printf("Found Keyboard: device: %s slot: %d\n",byte_to_binary(device_info.slotdata.hidmask),device_info.slotdata.deviceslot);
|
||||
}else if ((p_device->sub_class == 1) && (p_device->protocol == 2)){ // MOUSE
|
||||
slotdata->hidmask = gHID_LIST_MOUSE;
|
||||
slotdata->deviceslot = gMouseSlot;
|
||||
//printf("Found Mouse: device: %s slot: %d\n",byte_to_binary(device_info.hid),device_info.slot);
|
||||
}else{
|
||||
s32 ret;
|
||||
if((ret = ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info)) < 0){
|
||||
printf("ControllerPatcherHID::AttachDetachCallback(line %d): ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) failed %d \n",__LINE__,ret);
|
||||
return HID_DEVICE_DETACH;
|
||||
}else{
|
||||
//printf("ControllerPatcherHID::AttachDetachCallback(line %d): ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) success %d \n",__LINE__,ret);
|
||||
}
|
||||
}
|
||||
|
||||
if(slotdata->hidmask){
|
||||
if(attach){
|
||||
s32 bufSize = 64;
|
||||
if(slotdata->hidmask != gHID_LIST_MOUSE && config_controller[slotdata->deviceslot][CONTRPS_BUF_SIZE][0] == CONTROLLER_PATCHER_VALUE_SET){
|
||||
bufSize = config_controller[slotdata->deviceslot][CONTRPS_BUF_SIZE][1];
|
||||
}
|
||||
unsigned char *buf = (unsigned char *) memalign(64,bufSize);
|
||||
memset(buf,0,bufSize);
|
||||
my_cb_user *usr = (my_cb_user *) memalign(64,sizeof(my_cb_user));
|
||||
usr->buf = buf;
|
||||
usr->slotdata = device_info.slotdata;
|
||||
usr->transfersize = p_device->max_packet_size_rx;
|
||||
usr->handle = p_device->handle;
|
||||
usr->vidpid = device_info.vidpid;
|
||||
gHIDAttached |= slotdata->hidmask;
|
||||
gHIDCurrentDevice |= slotdata->hidmask;
|
||||
s32 pads_per_device = 1;
|
||||
if(config_controller[slotdata->deviceslot][CONTRPS_PAD_COUNT][0] != CONTROLLER_PATCHER_INVALIDVALUE){
|
||||
pads_per_device = config_controller[slotdata->deviceslot][CONTRPS_PAD_COUNT][1];
|
||||
if(pads_per_device > HID_MAX_PADS_COUNT){//maximum of HID_MAX_PADS_COUNT
|
||||
pads_per_device = HID_MAX_PADS_COUNT;
|
||||
}
|
||||
}
|
||||
|
||||
s32 pad_count = config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1];
|
||||
if(pad_count > 0x0F) pad_count = 0; //???
|
||||
|
||||
s32 pad_slot = 0;
|
||||
|
||||
s32 failed = 1;
|
||||
|
||||
for(s32 i = 0;i<HID_MAX_PADS_COUNT;i += pads_per_device){
|
||||
if(!(pad_count & (1 << i))){
|
||||
failed = 0;
|
||||
pad_count |= (1 << i);
|
||||
pad_slot = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(failed){
|
||||
printf("ControllerPatcherHID::AttachDetachCallback(line %d) error: I can only handle %d devices of the same type. Sorry \n",__LINE__,HID_MAX_PADS_COUNT);
|
||||
if(buf){
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
}
|
||||
if(usr){
|
||||
free(usr);
|
||||
usr = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1] = pad_count;
|
||||
|
||||
DCFlushRange(&config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1],sizeof(config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1]));
|
||||
DCInvalidateRange(&config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1],sizeof(config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1]));
|
||||
|
||||
usr->pads_per_device = pads_per_device;
|
||||
usr->pad_slot = pad_slot;
|
||||
|
||||
for(s32 i = 0;i<pads_per_device;i++){
|
||||
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;
|
||||
//printf("ControllerPatcherHID::AttachDetachCallback(line %d): saved handle %d to slot %d and pad %d\n",__LINE__,p_device->handle,slotdata->deviceslot,pad_slot);
|
||||
|
||||
gHID_Devices[slotdata->deviceslot].pad_data[pad_slot+i].user_data = usr;
|
||||
gHID_Devices[slotdata->deviceslot].pad_data[pad_slot+i].slotdata = device_info.slotdata;
|
||||
|
||||
DCFlushRange(&gHID_Devices[slotdata->deviceslot].pad_data[pad_slot+i],sizeof(HID_Data));
|
||||
DCInvalidateRange(&gHID_Devices[slotdata->deviceslot].pad_data[pad_slot+i],sizeof(HID_Data));
|
||||
}
|
||||
|
||||
for(s32 j = 0;j < pads_per_device; j++){
|
||||
for(s32 i = 0;i < gHIDMaxDevices; i++){
|
||||
if(connectionOrderHelper[i] == NULL){
|
||||
connectionOrderHelper[i] = usr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(HID_DEBUG){ printf("ControllerPatcherHID::AttachDetachCallback(line %d): Device successfully attached\n",__LINE__); }
|
||||
|
||||
if(slotdata->hidmask == gHID_LIST_GC){ // GC PAD
|
||||
//The GC Adapter has all ports in one device. Set them all.
|
||||
gHID_Devices[slotdata->deviceslot].pad_data[0].slotdata = device_info.slotdata;
|
||||
gHID_Devices[slotdata->deviceslot].pad_data[1].slotdata = device_info.slotdata;
|
||||
gHID_Devices[slotdata->deviceslot].pad_data[2].slotdata = device_info.slotdata;
|
||||
gHID_Devices[slotdata->deviceslot].pad_data[3].slotdata = device_info.slotdata;
|
||||
|
||||
buf[0] = 0x13;
|
||||
HIDWrite(p_device->handle, usr->buf, 1, NULL,NULL);
|
||||
HIDRead(p_device->handle, usr->buf, usr->transfersize, myHIDReadCallback, usr);
|
||||
}else if (slotdata->hidmask == gHID_LIST_MOUSE){
|
||||
HIDSetProtocol(p_device->handle, p_device->interface_index, 0, 0, 0);
|
||||
//HIDGetDescriptor(p_device->handle,0x22,0x00,0,my_buf,512,my_foo_cb,NULL);
|
||||
HIDSetIdle(p_device->handle,p_device->interface_index,1,NULL,NULL);
|
||||
gHID_Mouse_Mode = HID_MOUSE_MODE_AIM;
|
||||
HIDRead(p_device->handle, buf, p_device->max_packet_size_rx, myHIDMouseReadCallback, usr);
|
||||
}else if (slotdata->hidmask == gHID_LIST_SWITCH_PRO){
|
||||
s32 read_result = HIDRead(p_device->handle, usr->buf, usr->transfersize, NULL, NULL);
|
||||
if(read_result == 64){
|
||||
if(usr->buf[01] == 0x01){ //We need to do the handshake
|
||||
printf("ControllerPatcherHID::AttachDetachCallback(line %d): Switch Pro Controller handshake needed\n",__LINE__);
|
||||
/**
|
||||
Thanks to ShinyQuagsire23 for the values (https://github.com/shinyquagsire23/HID-Joy-Con-Whispering)
|
||||
**/
|
||||
//Get MAC
|
||||
buf[0] = 0x80;
|
||||
buf[1] = 0x01;
|
||||
HIDWrite(p_device->handle, usr->buf, 2, NULL,NULL);
|
||||
HIDRead(p_device->handle, usr->buf, usr->transfersize, NULL, NULL);
|
||||
//Do handshake
|
||||
buf[0] = 0x80;
|
||||
buf[1] = 0x02;
|
||||
HIDWrite(p_device->handle, usr->buf, 2, NULL,NULL);
|
||||
HIDRead(p_device->handle, usr->buf, usr->transfersize, NULL, NULL);
|
||||
//Talk over HID only.
|
||||
buf[0] = 0x80;
|
||||
buf[1] = 0x04;
|
||||
HIDWrite(p_device->handle, usr->buf, 2, NULL,NULL);
|
||||
HIDRead(p_device->handle, usr->buf, usr->transfersize, NULL, NULL);
|
||||
}else{
|
||||
printf("ControllerPatcherHID::AttachDetachCallback(line %d): Switch Pro Controller handshake already done\n",__LINE__);
|
||||
}
|
||||
HIDRead(p_device->handle, usr->buf, usr->transfersize, myHIDReadCallback, usr);
|
||||
}
|
||||
}else if (slotdata->hidmask == gHID_LIST_KEYBOARD){
|
||||
HIDSetProtocol(p_device->handle, p_device->interface_index, 1, 0, 0);
|
||||
HIDSetIdle(p_device->handle, p_device->interface_index, 0, 0, 0);
|
||||
HIDRead(p_device->handle, buf, p_device->max_packet_size_rx, myHIDReadCallback, usr);
|
||||
}else if (slotdata->hidmask == gHID_LIST_DS3){
|
||||
HIDSetProtocol(p_device->handle, p_device->interface_index, 1, 0, 0);
|
||||
HIDDS3Rumble(p_device->handle,usr,0);
|
||||
buf[0] = 0x42; buf[1] = 0x0c; buf[2] = 0x00; buf[3] = 0x00;
|
||||
HIDSetReport(p_device->handle, HID_REPORT_FEATURE, PS3_F4_REPORT_ID, buf, PS3_F4_REPORT_LEN, NULL, NULL);
|
||||
HIDRead(p_device->handle, usr->buf, p_device->max_packet_size_rx, myHIDReadCallback, usr);
|
||||
}else{
|
||||
HIDRead(p_device->handle, usr->buf, p_device->max_packet_size_rx, myHIDReadCallback, usr);
|
||||
}
|
||||
return HID_DEVICE_ATTACH;
|
||||
|
||||
}else{
|
||||
my_cb_user * user_data = NULL;
|
||||
s32 founddata = 0;
|
||||
for(s32 i = 0;i<HID_MAX_PADS_COUNT;i++){
|
||||
if(gHID_Devices[slotdata->deviceslot].pad_data[i].handle == p_device->handle){
|
||||
gHID_Devices[slotdata->deviceslot].pad_data[i].handle = 0;
|
||||
|
||||
DCFlushRange(&gHID_Devices[slotdata->deviceslot].pad_data[i].handle,sizeof(gHID_Devices[slotdata->deviceslot].pad_data[i].handle));
|
||||
DCInvalidateRange(&gHID_Devices[slotdata->deviceslot].pad_data[i].handle,sizeof(gHID_Devices[slotdata->deviceslot].pad_data[i].handle));
|
||||
|
||||
user_data = (my_cb_user *) gHID_Devices[slotdata->deviceslot].pad_data[i].user_data;
|
||||
|
||||
founddata = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(user_data){
|
||||
for(s32 j = 0;j < user_data->pads_per_device; j++){
|
||||
for(s32 i = 0;i < gHIDMaxDevices; i++){
|
||||
if(connectionOrderHelper[i] == user_data){
|
||||
connectionOrderHelper[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1] &= ~ (1 << user_data->pad_slot);
|
||||
DCFlushRange(&config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1],sizeof(config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1]));
|
||||
DCInvalidateRange(&config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1],sizeof(config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1]));
|
||||
if(user_data->buf){
|
||||
free(user_data->buf);
|
||||
user_data->buf = NULL;
|
||||
}
|
||||
free(user_data);
|
||||
user_data = NULL;
|
||||
}else{
|
||||
if(founddata){ printf("ControllerPatcherHID::AttachDetachCallback(line %d): user_data null. You may have a memory leak.\n",__LINE__); }
|
||||
return HID_DEVICE_DETACH;
|
||||
}
|
||||
if(config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1] == 0){
|
||||
gHIDAttached &= ~slotdata->hidmask;
|
||||
gHIDCurrentDevice &= ~slotdata->hidmask;
|
||||
|
||||
DCFlushRange(&gHIDAttached,sizeof(gHIDAttached));
|
||||
DCInvalidateRange(&gHIDAttached,sizeof(gHIDAttached));
|
||||
DCFlushRange(&gHIDCurrentDevice,sizeof(gHIDCurrentDevice));
|
||||
DCInvalidateRange(&gHIDCurrentDevice,sizeof(gHIDCurrentDevice));
|
||||
|
||||
if (slotdata->hidmask == gHID_LIST_MOUSE){
|
||||
gHID_Mouse_Mode = HID_MOUSE_MODE_AIM;
|
||||
}
|
||||
}else{
|
||||
if(HID_DEBUG){printf("ControllerPatcherHID::AttachDetachCallback(line %d): We still have pad for deviceslot %d connected.\n",__LINE__,slotdata->deviceslot); }
|
||||
}
|
||||
if(HID_DEBUG){printf("ControllerPatcherHID::AttachDetachCallback(line %d): Device successfully detached\n",__LINE__); }
|
||||
}
|
||||
}else{
|
||||
printf("ControllerPatcherHID::AttachDetachCallback(line %d): HID-Device currently not supported! You can add support through config files\n",__LINE__);
|
||||
}
|
||||
return HID_DEVICE_DETACH;
|
||||
}
|
||||
|
||||
void ControllerPatcherHID::HIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr){
|
||||
ControllerPatcherUtils::doSampling(usr->slotdata.deviceslot,usr->pad_slot,false);
|
||||
|
||||
//printf("my_read_cbInternal: %d %08X %d\n",bytes_transfered,usr->slotdata.hidmask,usr->slotdata.deviceslot);
|
||||
if(usr->slotdata.hidmask == gHID_LIST_GC){
|
||||
|
||||
HID_Data * data_ptr = NULL;
|
||||
//Copy the data for all 4 pads
|
||||
for(s32 i = 0;i<4;i++){
|
||||
data_ptr = &(gHID_Devices[gHID_SLOT_GC].pad_data[i]);
|
||||
memcpy(&(data_ptr->data_union.controller.last_hid_data[0]),&(data_ptr->data_union.controller.cur_hid_data[0]),10); //save last data.
|
||||
memcpy(&(data_ptr->data_union.controller.cur_hid_data[0]),&buf[(i*9)+1],9); //save new data.
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
s32 i = 0;
|
||||
printf("GC1 %08X: %02X %02X %02X %02X %02X %02X %02X %02X %02X ", buf[i*9+0],buf[i*9+1],buf[i*9+2],buf[i*9+3],buf[i*9+4],buf[i*9+5],buf[i*9+6],buf[i*9+7],buf[i*9+8]);i++;
|
||||
printf("GC2 %08X: %02X %02X %02X %02X %02X %02X %02X %02X %02X ", buf[i*9+0],buf[i*9+1],buf[i*9+2],buf[i*9+3],buf[i*9+4],buf[i*9+5],buf[i*9+6],buf[i*9+7],buf[i*9+8]);i++;
|
||||
printf("GC3 %08X: %02X %02X %02X %02X %02X %02X %02X %02X %02X ", buf[i*9+0],buf[i*9+1],buf[i*9+2],buf[i*9+3],buf[i*9+4],buf[i*9+5],buf[i*9+6],buf[i*9+7],buf[i*9+8]);i++;
|
||||
printf("GC4 %08X: %02X %02X %02X %02X %02X %02X %02X %02X %02X \n", buf[i*9+0],buf[i*9+1],buf[i*9+2],buf[i*9+3],buf[i*9+4],buf[i*9+5],buf[i*9+6],buf[i*9+7],buf[i*9+8]);*/
|
||||
HIDGCRumble(handle,usr);
|
||||
}else if(usr->slotdata.hidmask != 0){
|
||||
//Depending on how the switch pro controller is connected, it has a different data format. At first we had the Bluetooth version, so we need to convert
|
||||
//the USB one into it now. (When it's connected via USB). The network client always sends the BT version, even if connected via USB to the PC.
|
||||
if(usr->slotdata.hidmask == gHID_LIST_SWITCH_PRO && buf != NULL && bytes_transfered >= 0x20){
|
||||
u8 buffer[0x13];
|
||||
memcpy(buffer,buf+0x0D,0x013);
|
||||
|
||||
/**
|
||||
Thanks to ShinyQuagsire23 for the values (https://github.com/shinyquagsire23/HID-Joy-Con-Whispering)
|
||||
**/
|
||||
buf[0] = 0x80;
|
||||
buf[1] = 0x92;
|
||||
buf[2] = 0x00;
|
||||
buf[3] = 0x01;
|
||||
buf[4] = 0x00;
|
||||
buf[5] = 0x00;
|
||||
buf[6] = 0x00;
|
||||
buf[7] = 0x00;
|
||||
buf[8] = 0x1F;
|
||||
//We want to get the next input!
|
||||
s32 res = HIDWrite(handle, buf, 9, NULL,NULL);
|
||||
|
||||
if(res == 9){ //Check if it's the USB data format.
|
||||
if(buffer[1] == 0) return;
|
||||
//Converting the buttons
|
||||
u32 buttons = (((u32*)(buffer))[0]) & 0xFFFFFF00;
|
||||
u32 newButtons = 0;
|
||||
if((buttons & HID_SWITCH_PRO_USB_BUTTON_A_VALUE) == HID_SWITCH_PRO_USB_BUTTON_A_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_A_VALUE;
|
||||
if((buttons & HID_SWITCH_PRO_USB_BUTTON_B_VALUE) == HID_SWITCH_PRO_USB_BUTTON_B_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_B_VALUE;
|
||||
if((buttons & HID_SWITCH_PRO_USB_BUTTON_X_VALUE) == HID_SWITCH_PRO_USB_BUTTON_X_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_X_VALUE;
|
||||
if((buttons & HID_SWITCH_PRO_USB_BUTTON_Y_VALUE) == HID_SWITCH_PRO_USB_BUTTON_Y_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_Y_VALUE;
|
||||
|
||||
if((buttons & HID_SWITCH_PRO_USB_BUTTON_PLUS_VALUE) == HID_SWITCH_PRO_USB_BUTTON_PLUS_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_PLUS_VALUE;
|
||||
if((buttons & HID_SWITCH_PRO_USB_BUTTON_MINUS_VALUE) == HID_SWITCH_PRO_USB_BUTTON_MINUS_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_MINUS_VALUE;
|
||||
if((buttons & HID_SWITCH_PRO_USB_BUTTON_HOME_VALUE) == HID_SWITCH_PRO_USB_BUTTON_HOME_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_HOME_VALUE;
|
||||
//if((buttons & SWITCH_PRO_USB_BUTTON_SCREENSHOT) == HID_SWITCH_PRO_USB_BUTTON_SCREENSHOT) newButtons |= HID_SWITCH_PRO_BT_BUTTON_SCREENSHOT;
|
||||
|
||||
if((buttons & HID_SWITCH_PRO_USB_BUTTON_R_VALUE) == HID_SWITCH_PRO_USB_BUTTON_R_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_R_VALUE;
|
||||
if((buttons & HID_SWITCH_PRO_USB_BUTTON_ZR_VALUE) == HID_SWITCH_PRO_USB_BUTTON_ZR_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_ZR_VALUE;
|
||||
if((buttons & HID_SWITCH_PRO_USB_BUTTON_STICK_R_VALUE) == HID_SWITCH_PRO_USB_BUTTON_STICK_R_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_STICK_R_VALUE;
|
||||
|
||||
if((buttons & HID_SWITCH_PRO_USB_BUTTON_L_VALUE) == HID_SWITCH_PRO_USB_BUTTON_L_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_L_VALUE;
|
||||
if((buttons & HID_SWITCH_PRO_USB_BUTTON_ZL_VALUE) == HID_SWITCH_PRO_USB_BUTTON_ZL_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_ZL_VALUE;
|
||||
if((buttons & HID_SWITCH_PRO_USB_BUTTON_STICK_L_VALUE) == HID_SWITCH_PRO_USB_BUTTON_STICK_L_VALUE) newButtons |= HID_SWITCH_PRO_BT_BUTTON_STICK_L_VALUE;
|
||||
|
||||
u8 dpad = buffer[2];
|
||||
u8 dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_NEUTRAL_VALUE;
|
||||
|
||||
//Converting the DPAD
|
||||
if(((dpad & HID_SWITCH_PRO_USB_BUTTON_UP_VALUE) == HID_SWITCH_PRO_USB_BUTTON_UP_VALUE) &&
|
||||
((dpad & HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE) == HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE)){
|
||||
dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_NE_VALUE;
|
||||
}else if(((dpad & HID_SWITCH_PRO_USB_BUTTON_DOWN_VALUE) == HID_SWITCH_PRO_USB_BUTTON_DOWN_VALUE) &&
|
||||
((dpad & HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE) == HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE)){
|
||||
dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_SE_VALUE;
|
||||
}else if(((dpad & HID_SWITCH_PRO_USB_BUTTON_DOWN_VALUE) == HID_SWITCH_PRO_USB_BUTTON_DOWN_VALUE) &&
|
||||
((dpad & HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE) == HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE)){
|
||||
dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_SW_VALUE;
|
||||
}else if(((dpad & HID_SWITCH_PRO_USB_BUTTON_UP_VALUE) == HID_SWITCH_PRO_USB_BUTTON_UP_VALUE) &&
|
||||
((dpad & HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE) == HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE)){
|
||||
dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_NW_VALUE;
|
||||
}else if((dpad & HID_SWITCH_PRO_USB_BUTTON_UP_VALUE) == HID_SWITCH_PRO_USB_BUTTON_UP_VALUE){
|
||||
dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_N_VALUE;
|
||||
}else if((dpad & HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE) == HID_SWITCH_PRO_USB_BUTTON_RIGHT_VALUE){
|
||||
dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_E_VALUE;
|
||||
}else if((dpad & HID_SWITCH_PRO_USB_BUTTON_DOWN_VALUE) == HID_SWITCH_PRO_USB_BUTTON_DOWN_VALUE){
|
||||
dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_S_VALUE;
|
||||
}else if((dpad & HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE) == HID_SWITCH_PRO_USB_BUTTON_LEFT_VALUE){
|
||||
dpadResult = HID_SWITCH_PRO_BT_BUTTON_DPAD_W_VALUE;
|
||||
}
|
||||
|
||||
//Converting the stick data
|
||||
u8 LX = (u8) ((u16) ((buffer[0x04] << 8 &0xFF00) | (((u16)buffer[0x03])&0xFF)) >> 0x04);
|
||||
u8 LY = (u8)((buffer[0x05] *-1));
|
||||
u8 RX = (u8) ((u16) ((buffer[0x07] << 8 &0xFF00) | (((u16)buffer[0x06])&0xFF)) >> 0x04);
|
||||
u8 RY = (u8)((buffer[0x08] *-1));
|
||||
|
||||
buf[0] = (newButtons >> 24) & 0xFF;
|
||||
buf[1] = (newButtons >> 16) & 0xFF;
|
||||
buf[2] |= dpadResult;
|
||||
buf[4] = LX;
|
||||
buf[6] = LY;
|
||||
buf[8] = RX;
|
||||
buf[10] = RY;
|
||||
}
|
||||
}
|
||||
|
||||
s32 dsize = (HID_MAX_DATA_LENGTH_PER_PAD > bytes_transfered)? bytes_transfered : HID_MAX_DATA_LENGTH_PER_PAD;
|
||||
s32 skip = 0;
|
||||
|
||||
//Input filter
|
||||
if( config_controller[usr->slotdata.deviceslot][CONTRPS_INPUT_FILTER][0] != CONTROLLER_PATCHER_INVALIDVALUE){
|
||||
if(buf[config_controller[usr->slotdata.deviceslot][CONTRPS_INPUT_FILTER][0]] != config_controller[usr->slotdata.deviceslot][CONTRPS_INPUT_FILTER][1]){
|
||||
skip = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(!skip){
|
||||
u32 slot = 0;
|
||||
if(usr->pad_slot < HID_MAX_PADS_COUNT){
|
||||
slot = usr->pad_slot;
|
||||
}
|
||||
slot += ControllerPatcherUtils::getPadSlotInAdapter(usr->slotdata.deviceslot,buf); // If the controller has multiple slots, we need to use the right one.
|
||||
|
||||
HID_Data * data_ptr = &(gHID_Devices[usr->slotdata.deviceslot].pad_data[slot]);
|
||||
|
||||
memcpy(&(data_ptr->data_union.controller.last_hid_data[0]),&(data_ptr->data_union.controller.cur_hid_data[0]),dsize); // save the last data.
|
||||
memcpy(&(data_ptr->data_union.controller.cur_hid_data[0]),&buf[0],dsize); // save the new data.
|
||||
|
||||
DCFlushRange(&gHID_Devices[usr->slotdata.deviceslot].pad_data[slot],sizeof(HID_Data));
|
||||
|
||||
data_ptr = &(gHID_Devices[usr->slotdata.deviceslot].pad_data[slot]);
|
||||
|
||||
HIDRumble(handle,usr,slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Other functions
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherHID::setVPADControllerData(VPADStatus * buffer,std::vector<HID_Data *>& data){
|
||||
if(buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
HID_Data * data_cur;
|
||||
|
||||
s32 buttons_hold;
|
||||
for(u32 i = 0;i<data.size();i++){
|
||||
data_cur = data[i];
|
||||
|
||||
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;
|
||||
if(mouse_data->valuedChanged == 1){ //Fix for the mouse cursor
|
||||
mouse_data->valuedChanged = 0;
|
||||
}else{
|
||||
mouse_data->deltaX = 0;
|
||||
mouse_data->deltaY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
buttons_hold = 0;
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_A);
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_B);
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_X);
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_Y);
|
||||
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_LEFT);
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_RIGHT);
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_DOWN);
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_UP);
|
||||
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_MINUS);
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_L);
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_R);
|
||||
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_PLUS);
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_ZL);
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_ZR);
|
||||
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_HOME);
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_STICK_L);
|
||||
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_STICK_R);
|
||||
|
||||
u32 last_emulate_stick = (data_cur->last_buttons) & VPAD_MASK_EMULATED_STICKS; // We should only need the emulated stick data.
|
||||
s32 last_realbuttons = (data_cur->last_buttons) & VPAD_MASK_BUTTONS;
|
||||
|
||||
buffer->hold |= buttons_hold;
|
||||
buffer->trigger |= (buttons_hold & (~last_realbuttons));
|
||||
buffer->release |= (last_realbuttons & (~buttons_hold));
|
||||
|
||||
ControllerPatcherUtils::convertAnalogSticks(data_cur,buffer);
|
||||
|
||||
ControllerPatcherUtils::setEmulatedSticks(buffer,&last_emulate_stick);
|
||||
|
||||
ControllerPatcherUtils::checkAndSetMouseMode(data_cur);
|
||||
|
||||
ControllerPatcherUtils::setTouch(data_cur,buffer);
|
||||
|
||||
data_cur->last_buttons = buttons_hold & VPAD_MASK_BUTTONS;
|
||||
data_cur->last_buttons |= last_emulate_stick;
|
||||
}
|
||||
|
||||
// Caculates a valid stick position
|
||||
if(data.size() > 0){
|
||||
ControllerPatcherUtils::normalizeStickValues(&buffer->leftStick);
|
||||
ControllerPatcherUtils::normalizeStickValues(&buffer->rightStick);
|
||||
}
|
||||
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
|
||||
std::vector<HID_Data *> ControllerPatcherHID::getHIDDataAll(){
|
||||
u32 hid = gHIDCurrentDevice;
|
||||
|
||||
std::vector<HID_Data *> data_list;
|
||||
for(s32 i = 0;i < gHIDMaxDevices;i++){
|
||||
if((hid & (1 << i)) != 0){
|
||||
u32 cur_hidmask = config_controller_hidmask[i];
|
||||
for(s32 pad = 0; pad < HID_MAX_PADS_COUNT; pad++){
|
||||
s32 res;
|
||||
HID_Data * new_data = NULL;
|
||||
if((res = ControllerPatcherHID::getHIDData(cur_hidmask,pad,&new_data)) < 0){ // Checks if the pad is invalid.
|
||||
//printf("ControllerPatcherHID::getHIDDataAll(line %d): error: Error getting the HID data from HID(%s) CHAN(). Error %d\n",__LINE__,CPStringTools::byte_to_binary(cur_hidmask),pad,res);
|
||||
continue;
|
||||
}
|
||||
if(new_data != NULL) data_list.push_back(new_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return data_list;
|
||||
}
|
||||
|
||||
/*
|
||||
The slotdata in the HID_Data pointer is empty. We need to provide the hidmask via the parameter
|
||||
*/
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherHID::getHIDData(u32 hidmask, s32 pad, HID_Data ** data){
|
||||
if(data == NULL) return CONTROLLER_PATCHER_ERROR_INVALID_BUFFER;
|
||||
if(!(hidmask & gHIDCurrentDevice)) return CONTROLLER_PATCHER_ERROR_HID_NOT_CONNECTED;
|
||||
if(pad < 0 && pad > 3) return CONTROLLER_PATCHER_ERROR_INVALID_CHAN;
|
||||
|
||||
s32 device_slot = ControllerPatcherUtils::getDeviceSlot(hidmask);
|
||||
if(device_slot < 0){
|
||||
return CONTROLLER_PATCHER_ERROR_DEVICE_SLOT_NOT_FOUND;
|
||||
}
|
||||
|
||||
s32 real_pad = pad;
|
||||
if((device_slot != gHID_SLOT_GC) && config_controller[device_slot][CONTRPS_PAD_COUNT][0] != CONTROLLER_PATCHER_INVALIDVALUE){
|
||||
s32 pad_count = config_controller[device_slot][CONTRPS_PAD_COUNT][1];
|
||||
if(pad_count > HID_MAX_PADS_COUNT) pad_count = HID_MAX_PADS_COUNT;
|
||||
pad = (pad/(pad_count))*pad_count;
|
||||
}
|
||||
|
||||
s32 result = ControllerPatcherUtils::checkActivePad(hidmask,pad);
|
||||
|
||||
if(result < 0){ //Not pad connected to adapter
|
||||
return CONTROLLER_PATCHER_ERROR_NO_PAD_CONNECTED;
|
||||
}
|
||||
|
||||
*data = &gHID_Devices[device_slot].pad_data[real_pad];
|
||||
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
|
||||
|
||||
void ControllerPatcherHID::HIDGCRumble(u32 handle,my_cb_user *usr){
|
||||
if(usr == NULL) return;
|
||||
if(!ControllerPatcher::isRumbleActivated()) return;
|
||||
|
||||
s32 rumblechanged = 0;
|
||||
|
||||
for(s32 i = 0;i<HID_GC_PAD_COUNT;i++){
|
||||
HID_Data * data_ptr = &(gHID_Devices[usr->slotdata.deviceslot].pad_data[i]);
|
||||
if(data_ptr->rumbleActive != usr->rumblestatus[i]){
|
||||
rumblechanged = 1;
|
||||
}
|
||||
usr->rumblestatus[i] = data_ptr->rumbleActive;
|
||||
usr->buf[i+1] = usr->rumblestatus[i];
|
||||
}
|
||||
usr->forceRumbleInTicks[0]--;
|
||||
if(rumblechanged || usr->forceRumbleInTicks[0] <= 0){
|
||||
usr->buf[0] = 0x11;
|
||||
HIDWrite(handle, usr->buf, 5, NULL, NULL);
|
||||
usr->forceRumbleInTicks[0] = 10;
|
||||
}
|
||||
}
|
||||
|
||||
void ControllerPatcherHID::HIDRumble(u32 handle,my_cb_user *usr,u32 pad){
|
||||
if(usr == NULL || pad > HID_MAX_PADS_COUNT) return;
|
||||
if(!ControllerPatcher::isRumbleActivated()) return;
|
||||
|
||||
s32 rumblechanged = 0;
|
||||
HID_Data * data_ptr = &(gHID_Devices[usr->slotdata.deviceslot].pad_data[pad]);
|
||||
if(data_ptr->rumbleActive != usr->rumblestatus[pad]){
|
||||
usr->rumblestatus[pad] = data_ptr->rumbleActive;
|
||||
rumblechanged = 1;
|
||||
}
|
||||
usr->forceRumbleInTicks[pad]--;
|
||||
if(rumblechanged || usr->forceRumbleInTicks[pad] <= 0){
|
||||
//printf("Rumble: %d %d\n",usr->rumblestatus[pad],usr->rumbleForce[pad]);
|
||||
//Seding to the network client!
|
||||
char bytes[6];
|
||||
|
||||
s32 i = 0;
|
||||
bytes[i++] = 0x01;
|
||||
bytes[i++] = (handle >> 24) & 0xFF;
|
||||
bytes[i++] = (handle >> 16) & 0xFF;
|
||||
bytes[i++] = (handle >> 8) & 0xFF;
|
||||
bytes[i++] = handle & 0xFF;
|
||||
bytes[i++] = usr->rumblestatus[pad];
|
||||
|
||||
UDPClient * instance = UDPClient::getInstance();
|
||||
if(instance != NULL){
|
||||
instance->sendData(bytes,6);
|
||||
}
|
||||
|
||||
|
||||
if(usr->slotdata.hidmask == gHID_LIST_DS3){
|
||||
HIDDS3Rumble(handle,usr,usr->rumblestatus[pad]);
|
||||
}else{
|
||||
// Not implemented for other devices =(
|
||||
}
|
||||
usr->forceRumbleInTicks[pad] = 10;
|
||||
}
|
||||
}
|
||||
|
||||
static u8 ds3_rumble_Report[48] =
|
||||
{
|
||||
0x00, 0xFF, 0x00, 0xFF, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0x27, 0x10, 0x00, 0x32,
|
||||
0xFF, 0x27, 0x10, 0x00, 0x32,
|
||||
0xFF, 0x27, 0x10, 0x00, 0x32,
|
||||
0xFF, 0x27, 0x10, 0x00, 0x32,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
void ControllerPatcherHID::HIDDS3Rumble(u32 handle,my_cb_user *usr,s32 rumble){
|
||||
memcpy(usr->buf, ds3_rumble_Report, 48);
|
||||
|
||||
if (rumble) {
|
||||
usr->buf[2] = 0x01;
|
||||
usr->buf[4] = 0xff;
|
||||
}
|
||||
|
||||
HIDSetReport(handle, HID_REPORT_OUTPUT, PS3_01_REPORT_ID, usr->buf, 48, NULL, NULL);
|
||||
}
|
74
wiiu/controller_patcher/patcher/ControllerPatcherHID.hpp
Normal file
74
wiiu/controller_patcher/patcher/ControllerPatcherHID.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file ControllerPatcherHID.hpp
|
||||
* @author Maschell
|
||||
* @date 25 Aug 2016
|
||||
* \brief This files contain useful all function for the direct HID Access
|
||||
*
|
||||
* @see https://github.com/Maschell/controller_patcher
|
||||
*/
|
||||
|
||||
#ifndef _CONTROLLER_PATCHER_HID_H_
|
||||
#define _CONTROLLER_PATCHER_HID_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "wiiu/syshid.h"
|
||||
#include "wiiu/vpad.h"
|
||||
|
||||
#include "../ControllerPatcher.hpp"
|
||||
|
||||
#define SWAP16(x) ((x>>8) | ((x&0xFF)<<8))
|
||||
#define SWAP8(x) ((x>>4) | ((x&0xF)<<4))
|
||||
|
||||
class ControllerPatcherHID{
|
||||
friend class ControllerPatcher;
|
||||
friend class ControllerPatcherUtils;
|
||||
public:
|
||||
static s32 externAttachDetachCallback(HIDDevice *p_device, u32 attach);
|
||||
static void externHIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr);
|
||||
|
||||
private:
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR setVPADControllerData(VPADStatus * buffer,std::vector<HID_Data *>& data);
|
||||
static std::vector<HID_Data *> getHIDDataAll();
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR getHIDData(u32 hidmask, s32 pad, HID_Data ** data);
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Rumble
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
static void HIDRumble(u32 handle,my_cb_user *usr,u32 pad);
|
||||
|
||||
static void HIDGCRumble(u32 handle,my_cb_user *usr);
|
||||
|
||||
static void HIDDS3Rumble(u32 handle,my_cb_user *usr,s32 rumble);
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* HID Callbacks
|
||||
*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
static s32 myAttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, u32 attach);
|
||||
|
||||
static void myHIDMouseReadCallback(u32 handle, s32 error, unsigned char *buf, u32 bytes_transfered, void *p_user);
|
||||
static void myHIDReadCallback(u32 handle, s32 error, unsigned char *buf, u32 bytes_transfered, void *p_user);
|
||||
|
||||
static s32 AttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, u32 attach);
|
||||
static void HIDReadCallback(u32 handle, unsigned char *buf, u32 bytes_transfered, my_cb_user * usr);
|
||||
};
|
||||
|
||||
#endif /* _CONTROLLER_PATCHER_HID_H_ */
|
935
wiiu/controller_patcher/patcher/ControllerPatcherUtils.cpp
Normal file
935
wiiu/controller_patcher/patcher/ControllerPatcherUtils.cpp
Normal file
@ -0,0 +1,935 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "ControllerPatcherUtils.hpp"
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getDataByHandle(s32 handle, my_cb_user ** data){
|
||||
for(s32 i = 0;i< gHIDMaxDevices;i++){
|
||||
for(s32 j = 0;j<4;j++){
|
||||
//printf("%d %d %d %d\n",i,j,gHID_Devices[i].pad_data[j].handle,(u32)handle);
|
||||
if(gHID_Devices[i].pad_data[j].handle == (u32)handle){
|
||||
*data = gHID_Devices[i].pad_data[j].user_data;
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CONTROLLER_PATCHER_ERROR_UNKNOWN;
|
||||
}
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Analyse inputs
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getButtonPressed(HID_Data * data, s32 * buttons_hold, s32 VPADButton){
|
||||
if(data == NULL || buttons_hold == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
|
||||
s32 deviceslot = data->slotdata.deviceslot;
|
||||
|
||||
s32 result = -1;
|
||||
|
||||
do{
|
||||
if(data->type == DEVICE_TYPE_MOUSE){
|
||||
HID_Mouse_Data * ms_data = &data->data_union.mouse.cur_mouse_data;
|
||||
if(ms_data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
if(gHID_Mouse_Mode == HID_MOUSE_MODE_TOUCH){
|
||||
if(VPADButton == VPAD_BUTTON_TOUCH){
|
||||
if(ms_data->left_click & 0x01){
|
||||
result = 1; break;
|
||||
}
|
||||
}
|
||||
}else if(gHID_Mouse_Mode == HID_MOUSE_MODE_AIM){
|
||||
if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_LEFT][0] == CONTROLLER_PATCHER_VALUE_SET){
|
||||
if(VPADButton == (int)gGamePadValues[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_LEFT][1]]){
|
||||
if(ms_data->left_click & 0x01){
|
||||
result = 1; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_RIGHT][0] == CONTROLLER_PATCHER_VALUE_SET){
|
||||
if(VPADButton == (int)gGamePadValues[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_RIGHT][1]]){
|
||||
if(ms_data->right_click & 0x01){
|
||||
result = 1; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result = 0; break;
|
||||
}
|
||||
u8 * cur_data = &data->data_union.controller.cur_hid_data[0];
|
||||
if(cur_data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
|
||||
s32 cur_config = 0;
|
||||
|
||||
if(VPADButton == VPAD_BUTTON_A){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_A;
|
||||
}else if(VPADButton == VPAD_BUTTON_B){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_B;
|
||||
}else if(VPADButton == VPAD_BUTTON_X){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_X;
|
||||
}else if(VPADButton == VPAD_BUTTON_Y){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_Y;
|
||||
}else if(VPADButton == VPAD_BUTTON_L){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_L;
|
||||
}else if(VPADButton == VPAD_BUTTON_R){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_R;
|
||||
}else if(VPADButton == VPAD_BUTTON_ZL){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_ZL;
|
||||
}else if(VPADButton == VPAD_BUTTON_ZR){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_ZR;
|
||||
}else if(VPADButton == VPAD_BUTTON_STICK_L){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_STICK_L;
|
||||
}else if(VPADButton == VPAD_BUTTON_STICK_R){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_STICK_R;
|
||||
}else if(VPADButton == VPAD_BUTTON_PLUS){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_PLUS;
|
||||
}else if(VPADButton == VPAD_BUTTON_MINUS){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_MINUS;
|
||||
}else if(VPADButton == VPAD_BUTTON_HOME){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_HOME;
|
||||
}
|
||||
|
||||
//! Special DPAD treatment.
|
||||
if(config_controller[deviceslot][CONTRPS_DPAD_MODE][0] == CONTROLLER_PATCHER_VALUE_SET){
|
||||
if(config_controller[deviceslot][CONTRPS_DPAD_MODE][1] == CONTRPDM_Hat){
|
||||
u8 mask = 0x0F;
|
||||
if(config_controller[deviceslot][CONTRPS_DPAD_MASK][0] == CONTROLLER_PATCHER_VALUE_SET){
|
||||
mask = config_controller[deviceslot][CONTRPS_DPAD_MASK][1];
|
||||
}
|
||||
if(cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NEUTRAL][0]] != config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NEUTRAL][1]){ // Not neutral
|
||||
u8 dir1_0 = 0,dir1_1 = 0;
|
||||
u8 dir2_0 = 0,dir2_1 = 0;
|
||||
u8 dir3_0 = 0,dir3_1 = 0;
|
||||
u8 direction = 0;
|
||||
if(VPADButton == VPAD_BUTTON_LEFT){
|
||||
dir1_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_W][0];
|
||||
dir2_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NW][0];
|
||||
dir3_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_SW][0];
|
||||
dir1_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_W][1];
|
||||
dir2_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NW][1];
|
||||
dir3_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_SW][1];
|
||||
direction = 1;
|
||||
}else if(VPADButton == VPAD_BUTTON_RIGHT){
|
||||
dir1_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_E][0];
|
||||
dir2_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_SE][0];
|
||||
dir3_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NE][0];
|
||||
dir1_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_E][1];
|
||||
dir2_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_SE][1];
|
||||
dir3_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NE][1];
|
||||
direction = 1;
|
||||
}else if(VPADButton == VPAD_BUTTON_DOWN){
|
||||
dir1_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_S][0];
|
||||
dir2_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_SE][0];
|
||||
dir3_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_SW][0];
|
||||
dir1_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_S][1];
|
||||
dir2_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_SE][1];
|
||||
dir3_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_SW][1];
|
||||
direction = 1;
|
||||
}else if(VPADButton == VPAD_BUTTON_UP){
|
||||
dir1_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_N][0];
|
||||
dir2_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NW][0];
|
||||
dir3_0 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NE][0];
|
||||
dir1_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_N][1];
|
||||
dir2_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NW][1];
|
||||
dir3_1 = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_DPAD_NE][1];
|
||||
direction = 1;
|
||||
}
|
||||
if(direction && (((cur_data[dir1_0] & mask) == dir1_1) ||
|
||||
((cur_data[dir2_0] & mask) == dir2_1) ||
|
||||
((cur_data[dir3_0] & mask) == dir3_1))) {result = 1; break;}
|
||||
}
|
||||
|
||||
}else if(config_controller[deviceslot][CONTRPS_DPAD_MODE][1] == CONTRPDM_Absolute_2Values){
|
||||
s32 contrps_value = 0;
|
||||
if(VPADButton == VPAD_BUTTON_LEFT){
|
||||
contrps_value = CONTRPS_VPAD_BUTTON_DPAD_ABS_LEFT;
|
||||
}else if(VPADButton == VPAD_BUTTON_RIGHT){
|
||||
contrps_value = CONTRPS_VPAD_BUTTON_DPAD_ABS_RIGHT;
|
||||
}else if(VPADButton == VPAD_BUTTON_UP){
|
||||
contrps_value = CONTRPS_VPAD_BUTTON_DPAD_ABS_UP;
|
||||
}else if(VPADButton == VPAD_BUTTON_DOWN){
|
||||
contrps_value = CONTRPS_VPAD_BUTTON_DPAD_ABS_DOWN;
|
||||
}
|
||||
|
||||
if(contrps_value != 0){
|
||||
s32 value_byte = CONTROLLER_PATCHER_INVALIDVALUE;
|
||||
if((value_byte = config_controller[deviceslot][contrps_value][0]) != CONTROLLER_PATCHER_INVALIDVALUE){
|
||||
if(cur_data[config_controller[deviceslot][contrps_value][0]] == config_controller[deviceslot][contrps_value][1]){
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! Normal DPAD treatment.
|
||||
if(VPADButton == VPAD_BUTTON_LEFT){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_LEFT;
|
||||
}else if(VPADButton == VPAD_BUTTON_RIGHT){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_RIGHT;
|
||||
}else if(VPADButton == VPAD_BUTTON_DOWN){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_DOWN;
|
||||
}else if(VPADButton == VPAD_BUTTON_UP){
|
||||
cur_config = CONTRPS_VPAD_BUTTON_UP;
|
||||
}
|
||||
if(result && config_controller[deviceslot][CONTRPS_DOUBLE_USE][0] == CONTROLLER_PATCHER_VALUE_SET){
|
||||
if(config_controller[deviceslot][CONTRPS_DOUBLE_USE][1] == CONTROLLER_PATCHER_GC_DOUBLE_USE){
|
||||
if(cur_data[config_controller[deviceslot][CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR][0]] & config_controller[deviceslot][CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR][1]){
|
||||
if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_1_RELEASED,cur_config)){result = 0; break;}
|
||||
if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_2_RELEASED,cur_config)){result = 0; break;}
|
||||
if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_3_RELEASED,cur_config)){result = 0; break;}
|
||||
if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_4_RELEASED,cur_config)){result = 0; break;}
|
||||
if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_5_RELEASED,cur_config)){result = 0; break;}
|
||||
}else{
|
||||
if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_1_PRESSED,cur_config)){result = 0; break;}
|
||||
if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_2_PRESSED,cur_config)){result = 0; break;}
|
||||
if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_3_PRESSED,cur_config)){result = 0; break;}
|
||||
if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_4_PRESSED,cur_config)){result = 0; break;}
|
||||
if(checkValueinConfigController(deviceslot,CONTRPS_DOUBLE_USE_BUTTON_5_PRESSED,cur_config)){result = 0; break;}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isValueSet(data,cur_config) == 1){
|
||||
result = 1; break;
|
||||
}else{
|
||||
//printf("Invalid data! deviceslot(slot): %d config: %d\n",deviceslot,cur_config);
|
||||
}
|
||||
}while(0); //The break will become handy ;)
|
||||
|
||||
|
||||
if(result == 1){
|
||||
*buttons_hold |= VPADButton; // -1 would be also true.
|
||||
return 1;
|
||||
}
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::isValueSet(HID_Data * data,s32 cur_config){
|
||||
if(data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
|
||||
u8 * cur_data = &data->data_union.controller.cur_hid_data[0];
|
||||
if(cur_data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
|
||||
u32 hidmask = data->slotdata.hidmask;
|
||||
s32 deviceslot = data->slotdata.deviceslot;
|
||||
|
||||
s32 result = CONTROLLER_PATCHER_ERROR_NONE;
|
||||
if(config_controller[deviceslot][cur_config][0] != CONTROLLER_PATCHER_INVALIDVALUE){ //Invalid data
|
||||
if(hidmask & gHID_LIST_KEYBOARD){
|
||||
if(isInKeyboardData(cur_data,config_controller[deviceslot][cur_config][1]) > 0) {
|
||||
result = 1;
|
||||
}
|
||||
}else{
|
||||
if((cur_data[config_controller[deviceslot][cur_config][0]] & config_controller[deviceslot][cur_config][1]) == config_controller[deviceslot][cur_config][1]){
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::isInKeyboardData(unsigned char * keyboardData,s32 key){
|
||||
if(keyboardData == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
for(s32 i = 0;i<HID_KEYBOARD_DATA_LENGTH;i++){
|
||||
if(keyboardData[i] == 0 && i > 1){
|
||||
break;
|
||||
}else if (keyboardData[i] == key){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Utils for setting the Button data
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::setButtonRemappingData(VPADStatus * old_buffer, VPADStatus * new_buffer,u32 VPADButton, s32 CONTRPS_SLOT){
|
||||
if(old_buffer == NULL || new_buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
u32 new_value = VPADButton;
|
||||
|
||||
if(config_controller[gGamePadSlot][CONTRPS_SLOT][0] != CONTROLLER_PATCHER_INVALIDVALUE){ //using new value!
|
||||
new_value = gGamePadValues[config_controller[gGamePadSlot][CONTRPS_SLOT][1]];
|
||||
}
|
||||
|
||||
setButtonData(old_buffer,new_buffer,VPADButton,new_value);
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::setButtonData(VPADStatus * old_buffer, VPADStatus * new_buffer,u32 oldVPADButton,u32 newVPADButton){
|
||||
if(old_buffer == NULL || new_buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
if((old_buffer->hold & oldVPADButton) == oldVPADButton){
|
||||
new_buffer->hold |= newVPADButton;
|
||||
}
|
||||
if((old_buffer->release & oldVPADButton) == oldVPADButton){
|
||||
new_buffer->release |= newVPADButton;
|
||||
}
|
||||
if((old_buffer->trigger & oldVPADButton) == oldVPADButton){
|
||||
new_buffer->trigger |= newVPADButton;
|
||||
}
|
||||
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Pad Status functions
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::checkActivePad(u32 hidmask,s32 pad){
|
||||
if(hidmask & gHID_LIST_GC && pad >= 0 && pad <= 3){
|
||||
if (!(((gHID_Devices[gHID_SLOT_GC].pad_data[pad].data_union.controller.cur_hid_data[0] & 0x10) == 0) && ((gHID_Devices[gHID_SLOT_GC].pad_data[pad].data_union.controller.cur_hid_data[0] & 0x22) != 0x22))) return 1;
|
||||
return CONTROLLER_PATCHER_ERROR_NO_PAD_CONNECTED;
|
||||
}else{
|
||||
s32 deviceslot = getDeviceSlot(hidmask);
|
||||
if(deviceslot < 0 ) return CONTROLLER_PATCHER_ERROR_DEVICE_SLOT_NOT_FOUND;
|
||||
s32 connected_pads = config_controller[deviceslot][CONTRPS_CONNECTED_PADS][1];
|
||||
|
||||
if((connected_pads & (1 << pad)) > 0){
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return CONTROLLER_PATCHER_ERROR_NO_PAD_CONNECTED;
|
||||
}
|
||||
|
||||
/*
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getActivePad(u32 hidmask){
|
||||
if(hidmask & gHID_LIST_GC){
|
||||
if (!(((gHID_Devices[gHID_SLOT_GC].pad_data[0].data_union.controller.cur_hid_data[0] & 0x10) == 0) && ((gHID_Devices[gHID_SLOT_GC].pad_data[0].data_union.controller.cur_hid_data[0] & 0x22) != 0x22))) return 0;
|
||||
if (!(((gHID_Devices[gHID_SLOT_GC].pad_data[1].data_union.controller.cur_hid_data[0] & 0x10) == 0) && ((gHID_Devices[gHID_SLOT_GC].pad_data[1].data_union.controller.cur_hid_data[0] & 0x22) != 0x22))) return 1;
|
||||
if (!(((gHID_Devices[gHID_SLOT_GC].pad_data[2].data_union.controller.cur_hid_data[0] & 0x10) == 0) && ((gHID_Devices[gHID_SLOT_GC].pad_data[2].data_union.controller.cur_hid_data[0] & 0x22) != 0x22))) return 2;
|
||||
if (!(((gHID_Devices[gHID_SLOT_GC].pad_data[3].data_union.controller.cur_hid_data[0] & 0x10) == 0) && ((gHID_Devices[gHID_SLOT_GC].pad_data[3].data_union.controller.cur_hid_data[0] & 0x22) != 0x22))) return 3;
|
||||
|
||||
return CONTROLLER_PATCHER_ERROR_NO_PAD_CONNECTED;
|
||||
}
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Stick functions
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::normalizeStickValues(VPADVec2D * stick){
|
||||
if(stick == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
|
||||
f32 max_val = 0.0f;
|
||||
f32 mul_val = 0.0f;
|
||||
|
||||
if((max_val = (fabs(stick->x)) + fabs(stick->y)) > 1.414f){
|
||||
mul_val = 1.414f / max_val;
|
||||
stick->x *= mul_val;
|
||||
stick->y *= mul_val;
|
||||
}
|
||||
|
||||
if(stick->x > 1.0f){ stick->x = 1.0f; }
|
||||
if(stick->y > 1.0f){ stick->y = 1.0f; }
|
||||
if(stick->x < -1.0f){ stick->x = -1.0f; }
|
||||
if(stick->y < -1.0f){ stick->y = -1.0f; }
|
||||
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
|
||||
f32 ControllerPatcherUtils::convertAnalogValue(u8 value, u8 default_val, u8 min, u8 max, u8 invert,u8 deadzone){
|
||||
s8 new_value = (s8)(value - default_val);
|
||||
u8 range = 0;
|
||||
if(value >= max){
|
||||
if(invert == 0x01) return -1.0f;
|
||||
return 1.0f;
|
||||
}else if(value <= min){
|
||||
if(invert == 0x01) return 1.0f;
|
||||
return -1.0f;
|
||||
}
|
||||
if((value-deadzone) > default_val){
|
||||
new_value -= deadzone;
|
||||
range = (max - (default_val + deadzone));
|
||||
}else if((value+deadzone) < default_val){
|
||||
new_value += deadzone;
|
||||
range = ((default_val - deadzone) - min);
|
||||
}else{
|
||||
return 0.0f;
|
||||
}
|
||||
if(invert != 0x01){
|
||||
return (new_value / (1.0f*range));
|
||||
}else{
|
||||
return -1.0f*(new_value / (1.0f*range));
|
||||
}
|
||||
}
|
||||
|
||||
VPADVec2D ControllerPatcherUtils::getAnalogValueByButtons(u8 stick_values){
|
||||
VPADVec2D stick;
|
||||
stick.x = 0.0f;
|
||||
stick.y = 0.0f;
|
||||
|
||||
u8 up = ((stick_values & STICK_VALUE_UP) == STICK_VALUE_UP);
|
||||
u8 down = ((stick_values & STICK_VALUE_DOWN) == STICK_VALUE_DOWN);
|
||||
u8 left = ((stick_values & STICK_VALUE_LEFT) == STICK_VALUE_LEFT);
|
||||
u8 right = ((stick_values & STICK_VALUE_RIGHT) == STICK_VALUE_RIGHT);
|
||||
|
||||
if(up){
|
||||
if(!down){
|
||||
stick.y = 1.0f;
|
||||
}
|
||||
if(left || right){
|
||||
stick.y = 0.707f;
|
||||
if(left) stick.x = -0.707f;
|
||||
if(right) stick.x = 0.707f;
|
||||
}
|
||||
}else if(down){
|
||||
if(!up){
|
||||
stick.y = -1.0f;
|
||||
}
|
||||
if(left || right){
|
||||
stick.y = -0.707f;
|
||||
if(left) stick.x = -0.707f;
|
||||
if(right) stick.x = 0.707f;
|
||||
}
|
||||
}else{
|
||||
if(left){
|
||||
if(!right){
|
||||
stick.x = -1.0f;
|
||||
}
|
||||
|
||||
}else if(right){
|
||||
if(!down){
|
||||
stick.x = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
return stick;
|
||||
}
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::convertAnalogSticks(HID_Data * data, VPADStatus * buffer){
|
||||
if(buffer == NULL || data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
|
||||
s32 deviceslot = data->slotdata.deviceslot;
|
||||
if (data->type == DEVICE_TYPE_MOUSE){
|
||||
|
||||
if(gHID_Mouse_Mode == HID_MOUSE_MODE_AIM){ // TODO: tweak values
|
||||
HID_Mouse_Data * ms_data = &data->data_union.mouse.cur_mouse_data;
|
||||
if(ms_data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
|
||||
f32 x_value = ms_data->deltaX/10.0f;
|
||||
f32 y_value = -1.0f*(ms_data->deltaY/10.0f);
|
||||
|
||||
if(config_controller[deviceslot][CONTRPS_MOUSE_STICK][0] != CONTROLLER_PATCHER_INVALIDVALUE){
|
||||
if(config_controller[deviceslot][CONTRPS_MOUSE_STICK][1] == DEF_L_STICK){
|
||||
buffer->leftStick.x += x_value;
|
||||
buffer->leftStick.y += y_value;
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
buffer->rightStick.x += x_value;
|
||||
buffer->rightStick.y += y_value;
|
||||
}
|
||||
}else{
|
||||
u8 * cur_data = &data->data_union.controller.cur_hid_data[0];
|
||||
if(cur_data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
|
||||
s32 deadzone = 0;
|
||||
|
||||
if( config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][0] != CONTROLLER_PATCHER_INVALIDVALUE){
|
||||
if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE][0] == CONTROLLER_PATCHER_VALUE_SET){
|
||||
deadzone = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE][1];
|
||||
}
|
||||
|
||||
buffer->leftStick.x += convertAnalogValue(cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][0]],
|
||||
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][1],
|
||||
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX][0],
|
||||
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX][1],
|
||||
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT][1],
|
||||
deadzone);
|
||||
}
|
||||
|
||||
if( config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][0] != CONTROLLER_PATCHER_INVALIDVALUE){
|
||||
deadzone = 0;
|
||||
if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE][0] == CONTROLLER_PATCHER_VALUE_SET){
|
||||
deadzone = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE][1];
|
||||
}
|
||||
buffer->leftStick.y += convertAnalogValue(cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][0]],
|
||||
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][1],
|
||||
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX][0],
|
||||
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX][1],
|
||||
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT][1],
|
||||
deadzone);
|
||||
}
|
||||
|
||||
if( config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][0] != CONTROLLER_PATCHER_INVALIDVALUE){
|
||||
deadzone = 0;
|
||||
if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE][0] == CONTROLLER_PATCHER_VALUE_SET){
|
||||
deadzone = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE][1];
|
||||
}
|
||||
|
||||
buffer->rightStick.x += convertAnalogValue(cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][0]],
|
||||
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][1],
|
||||
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX][0],
|
||||
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX][1],
|
||||
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT][1],
|
||||
deadzone);
|
||||
}
|
||||
|
||||
if( config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y][0] != CONTROLLER_PATCHER_INVALIDVALUE){
|
||||
deadzone = 0;
|
||||
if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE][0] == CONTROLLER_PATCHER_VALUE_SET){
|
||||
deadzone = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE][1];
|
||||
}
|
||||
|
||||
buffer->rightStick.y += convertAnalogValue(cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y][0]],
|
||||
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y][1],
|
||||
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX][0],
|
||||
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX][1],
|
||||
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT][1],
|
||||
deadzone);
|
||||
}
|
||||
|
||||
u8 stick_values = 0;
|
||||
|
||||
if(isValueSet(data,CONTRPS_VPAD_BUTTON_L_STICK_UP)){ stick_values |= STICK_VALUE_UP; }
|
||||
if(isValueSet(data,CONTRPS_VPAD_BUTTON_L_STICK_DOWN)){ stick_values |= STICK_VALUE_DOWN; }
|
||||
if(isValueSet(data,CONTRPS_VPAD_BUTTON_L_STICK_LEFT)){ stick_values |= STICK_VALUE_LEFT; }
|
||||
if(isValueSet(data,CONTRPS_VPAD_BUTTON_L_STICK_RIGHT)){ stick_values |= STICK_VALUE_RIGHT; }
|
||||
|
||||
if(stick_values > 0 ){
|
||||
VPADVec2D stick = getAnalogValueByButtons(stick_values);
|
||||
buffer->leftStick.x += stick.x;
|
||||
buffer->leftStick.y += stick.y;
|
||||
}
|
||||
|
||||
stick_values = 0;
|
||||
if(isValueSet(data,CONTRPS_VPAD_BUTTON_R_STICK_UP)){ stick_values |= STICK_VALUE_UP; }
|
||||
if(isValueSet(data,CONTRPS_VPAD_BUTTON_R_STICK_DOWN)){ stick_values |= STICK_VALUE_DOWN; }
|
||||
if(isValueSet(data,CONTRPS_VPAD_BUTTON_R_STICK_LEFT)){ stick_values |= STICK_VALUE_LEFT; }
|
||||
if(isValueSet(data,CONTRPS_VPAD_BUTTON_R_STICK_RIGHT)){ stick_values |= STICK_VALUE_RIGHT; }
|
||||
|
||||
if(stick_values > 0 ){
|
||||
VPADVec2D stick = getAnalogValueByButtons(stick_values);
|
||||
buffer->rightStick.x += stick.x;
|
||||
buffer->rightStick.y += stick.y;
|
||||
}
|
||||
|
||||
/*printf("LX %f(%02X) LY %f(%02X) RX %f(%02X) RY %f(%02X)\n",buffer->leftStick.x,cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][0]],
|
||||
buffer->leftStick.y,cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][0]],
|
||||
buffer->rightStick.x,cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][0]],
|
||||
buffer->rightStick.y,cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y][0]]);*/
|
||||
|
||||
}
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::setEmulatedSticks(VPADStatus * buffer, u32 * last_emulatedSticks){
|
||||
if(buffer == NULL || last_emulatedSticks == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
|
||||
u32 emulatedSticks = 0;
|
||||
|
||||
s32 l_x_full = (buffer->leftStick.x > 0.5f || buffer->leftStick.x < -0.5f)? 1:0;
|
||||
s32 l_y_full = (buffer->leftStick.y > 0.5f || buffer->leftStick.y < -0.5f)? 1:0;
|
||||
s32 r_x_full = (buffer->rightStick.x > 0.5f || buffer->rightStick.x < -0.5f)? 1:0;
|
||||
s32 r_y_full = (buffer->rightStick.y > 0.5f || buffer->rightStick.y < -0.5f)? 1:0;
|
||||
|
||||
if((buffer->leftStick.x > 0.5f) || (buffer->leftStick.x > 0.1f && !l_y_full)){
|
||||
emulatedSticks |= VPAD_STICK_L_EMULATION_RIGHT;
|
||||
}
|
||||
if((buffer->leftStick.x < -0.5f) || (buffer->leftStick.x < -0.1f && !l_y_full)){
|
||||
emulatedSticks |= VPAD_STICK_L_EMULATION_LEFT;
|
||||
}
|
||||
if((buffer->leftStick.y > 0.5f) || (buffer->leftStick.y > 0.1f && !l_x_full)){
|
||||
emulatedSticks |= VPAD_STICK_L_EMULATION_UP;
|
||||
}
|
||||
if((buffer->leftStick.y < -0.5f) || (buffer->leftStick.y < -0.1f && !l_x_full)){
|
||||
emulatedSticks |= VPAD_STICK_L_EMULATION_DOWN;
|
||||
}
|
||||
|
||||
if((buffer->rightStick.x > 0.5f) || (buffer->rightStick.x > 0.1f && !r_y_full)){
|
||||
emulatedSticks |= VPAD_STICK_R_EMULATION_RIGHT;
|
||||
}
|
||||
if((buffer->rightStick.x < -0.5f) || (buffer->rightStick.x < -0.1f && !r_y_full)){
|
||||
emulatedSticks |= VPAD_STICK_R_EMULATION_LEFT;
|
||||
}
|
||||
if((buffer->rightStick.y > 0.5f) || (buffer->rightStick.y > 0.1f && !r_x_full)){
|
||||
emulatedSticks |= VPAD_STICK_R_EMULATION_UP;
|
||||
}
|
||||
if((buffer->rightStick.y < -0.5f) || (buffer->rightStick.y < -0.1f && !r_x_full)){
|
||||
emulatedSticks |= VPAD_STICK_R_EMULATION_DOWN;
|
||||
}
|
||||
|
||||
//Setting the emulated sticks
|
||||
buffer->hold |= emulatedSticks;
|
||||
buffer->trigger |= (emulatedSticks & (~*last_emulatedSticks));
|
||||
buffer->release |= (*last_emulatedSticks & (~emulatedSticks));
|
||||
|
||||
*last_emulatedSticks = emulatedSticks;
|
||||
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Touch functions
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::setTouch(HID_Data * data,VPADStatus * buffer){
|
||||
if(buffer == NULL || data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
if(data->type == DEVICE_TYPE_MOUSE && gHID_Mouse_Mode == HID_MOUSE_MODE_TOUCH){
|
||||
s32 buttons_hold;
|
||||
if(getButtonPressed(data,&buttons_hold,VPAD_BUTTON_TOUCH)){
|
||||
HID_Mouse_Data * ms_data = &data->data_union.mouse.cur_mouse_data;
|
||||
if(ms_data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
s32 x_mouse = 80 + ((int)(((ms_data->X)*1.0f/1280.0)*3890.0f));
|
||||
s32 y_mouse = 3910 - ((int)(((ms_data->Y)*1.0f/720.0)*3760.0f));
|
||||
buffer->tpNormal.x = x_mouse;
|
||||
buffer->tpNormal.y = y_mouse;
|
||||
buffer->tpNormal.touched = 1;
|
||||
buffer->tpNormal.validity = 0;
|
||||
buffer->tpFiltered1.x = x_mouse;
|
||||
buffer->tpFiltered1.y = y_mouse;
|
||||
buffer->tpFiltered1.touched = 1;
|
||||
buffer->tpFiltered1.validity = 0;
|
||||
buffer->tpFiltered2.x = x_mouse;
|
||||
buffer->tpFiltered2.y = y_mouse;
|
||||
buffer->tpFiltered2.touched = 1;
|
||||
buffer->tpFiltered2.validity = 0;
|
||||
}
|
||||
}
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::checkAndSetMouseMode(HID_Data * data){
|
||||
u32 hidmask = data->slotdata.hidmask;
|
||||
|
||||
if(hidmask & gHID_LIST_KEYBOARD){
|
||||
u8 * cur_data = &data->data_union.controller.cur_hid_data[0];
|
||||
u8 * last_data = &data->data_union.controller.last_hid_data[0];
|
||||
if((isInKeyboardData(cur_data,HID_KEYBOARD_BUTTON_F1) > 0) && ((isInKeyboardData(cur_data,HID_KEYBOARD_BUTTON_F1) > 0) != (isInKeyboardData(last_data,HID_KEYBOARD_BUTTON_F1) > 0))){
|
||||
if(gHID_Mouse_Mode == HID_MOUSE_MODE_AIM){
|
||||
gHID_Mouse_Mode = HID_MOUSE_MODE_TOUCH;
|
||||
if(HID_DEBUG){ printf("ControllerPatcherUtils::checkAndSetMouseMode(line %d): Mouse mode changed! to touch \n",__LINE__); }
|
||||
}else if(gHID_Mouse_Mode == HID_MOUSE_MODE_TOUCH){
|
||||
if(HID_DEBUG){ printf("ControllerPatcherUtils::checkAndSetMouseMode(line %d): Mouse mode changed! to aim \n",__LINE__); }
|
||||
gHID_Mouse_Mode = HID_MOUSE_MODE_AIM;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Other functions
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::translateToPro(VPADStatus * vpad_buffer,KPADData * pro_buffer,u32 * lastButtonsPressesPRO){
|
||||
if(vpad_buffer == NULL || pro_buffer == NULL || lastButtonsPressesPRO == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
|
||||
s32 buttons_hold = 0;
|
||||
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_A) buttons_hold |= WPAD_PRO_BUTTON_A;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_B) buttons_hold |= WPAD_PRO_BUTTON_B;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_X) buttons_hold |= WPAD_PRO_BUTTON_X;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_Y) buttons_hold |= WPAD_PRO_BUTTON_Y;
|
||||
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_PLUS) buttons_hold |= WPAD_PRO_BUTTON_PLUS;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_MINUS) buttons_hold |= WPAD_PRO_BUTTON_MINUS;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_HOME) buttons_hold |= WPAD_PRO_BUTTON_HOME;
|
||||
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_LEFT) buttons_hold |= WPAD_PRO_BUTTON_LEFT;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_RIGHT) buttons_hold |= WPAD_PRO_BUTTON_RIGHT;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_UP) buttons_hold |= WPAD_PRO_BUTTON_UP;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_DOWN) buttons_hold |= WPAD_PRO_BUTTON_DOWN;
|
||||
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_L) buttons_hold |= WPAD_PRO_TRIGGER_L;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_ZL) buttons_hold |= WPAD_PRO_TRIGGER_ZL;
|
||||
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_R) buttons_hold |= WPAD_PRO_TRIGGER_R;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_ZR) buttons_hold |= WPAD_PRO_TRIGGER_ZR;
|
||||
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_STICK_L) buttons_hold |= WPAD_PRO_BUTTON_STICK_L;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_STICK_R) buttons_hold |= WPAD_PRO_BUTTON_STICK_R;
|
||||
|
||||
if(vpad_buffer->hold & VPAD_STICK_L_EMULATION_LEFT) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_LEFT;
|
||||
if(vpad_buffer->hold & VPAD_STICK_L_EMULATION_RIGHT) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_RIGHT;
|
||||
if(vpad_buffer->hold & VPAD_STICK_L_EMULATION_UP) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_UP;
|
||||
if(vpad_buffer->hold & VPAD_STICK_L_EMULATION_DOWN) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_DOWN;
|
||||
|
||||
if(vpad_buffer->hold & VPAD_STICK_R_EMULATION_LEFT) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_LEFT;
|
||||
if(vpad_buffer->hold & VPAD_STICK_R_EMULATION_RIGHT) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_RIGHT;
|
||||
if(vpad_buffer->hold & VPAD_STICK_R_EMULATION_UP) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_UP;
|
||||
if(vpad_buffer->hold & VPAD_STICK_R_EMULATION_DOWN) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_DOWN;
|
||||
|
||||
pro_buffer->pro.lstick_x = vpad_buffer->leftStick.x;
|
||||
pro_buffer->pro.lstick_x = vpad_buffer->leftStick.y;
|
||||
pro_buffer->pro.rstick_x = vpad_buffer->rightStick.x;
|
||||
pro_buffer->pro.rstick_x = vpad_buffer->rightStick.y;
|
||||
|
||||
/*
|
||||
pro_buffer->unused_1[1] = 0xBF800000;
|
||||
pro_buffer->unused_1[3] = 0x3F800000;
|
||||
pro_buffer->angle_x = 0x3F800000;
|
||||
pro_buffer->unused_3[4] = 0x3F800000;
|
||||
pro_buffer->unused_3[7] = 0x3F800000;
|
||||
pro_buffer->unused_6[17] = 0x3F800000;
|
||||
pro_buffer->unused_7[1] = 0x3F800000;
|
||||
pro_buffer->unused_7[5] = 0x3F800000;*/
|
||||
|
||||
pro_buffer->pro.hold = buttons_hold;
|
||||
pro_buffer->pro.trigger = (buttons_hold & (~*lastButtonsPressesPRO));
|
||||
pro_buffer->pro.release = (*lastButtonsPressesPRO & (~buttons_hold));
|
||||
|
||||
*lastButtonsPressesPRO = buttons_hold;
|
||||
|
||||
pro_buffer->format = WPAD_FMT_PRO_CONTROLLER;
|
||||
pro_buffer->wpad_error = 0x00;
|
||||
pro_buffer->device_type = WPAD_EXT_PRO_CONTROLLER;
|
||||
pro_buffer->pro.wired = 1;
|
||||
pro_buffer->pro.charging = 1;
|
||||
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::translateToProWPADRead(VPADStatus * vpad_buffer,WPADReadData * pro_buffer){
|
||||
if(vpad_buffer == NULL || pro_buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
|
||||
s32 buttons_hold = 0;
|
||||
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_A) buttons_hold |= WPAD_PRO_BUTTON_A;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_B) buttons_hold |= WPAD_PRO_BUTTON_B;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_X) buttons_hold |= WPAD_PRO_BUTTON_X;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_Y) buttons_hold |= WPAD_PRO_BUTTON_Y;
|
||||
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_PLUS) buttons_hold |= WPAD_PRO_BUTTON_PLUS;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_MINUS) buttons_hold |= WPAD_PRO_BUTTON_MINUS;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_HOME) buttons_hold |= WPAD_PRO_BUTTON_HOME;
|
||||
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_LEFT) buttons_hold |= WPAD_PRO_BUTTON_LEFT;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_RIGHT) buttons_hold |= WPAD_PRO_BUTTON_RIGHT;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_UP) buttons_hold |= WPAD_PRO_BUTTON_UP;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_DOWN) buttons_hold |= WPAD_PRO_BUTTON_DOWN;
|
||||
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_L) buttons_hold |= WPAD_PRO_TRIGGER_L;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_ZL) buttons_hold |= WPAD_PRO_TRIGGER_ZL;
|
||||
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_R) buttons_hold |= WPAD_PRO_TRIGGER_R;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_ZR) buttons_hold |= WPAD_PRO_TRIGGER_ZR;
|
||||
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_STICK_L) buttons_hold |= WPAD_PRO_BUTTON_STICK_L;
|
||||
if(vpad_buffer->hold & VPAD_BUTTON_STICK_R) buttons_hold |= WPAD_PRO_BUTTON_STICK_R;
|
||||
|
||||
if(vpad_buffer->hold & VPAD_STICK_L_EMULATION_LEFT) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_LEFT;
|
||||
if(vpad_buffer->hold & VPAD_STICK_L_EMULATION_RIGHT) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_RIGHT;
|
||||
if(vpad_buffer->hold & VPAD_STICK_L_EMULATION_UP) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_UP;
|
||||
if(vpad_buffer->hold & VPAD_STICK_L_EMULATION_DOWN) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_DOWN;
|
||||
|
||||
if(vpad_buffer->hold & VPAD_STICK_R_EMULATION_LEFT) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_LEFT;
|
||||
if(vpad_buffer->hold & VPAD_STICK_R_EMULATION_RIGHT) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_RIGHT;
|
||||
if(vpad_buffer->hold & VPAD_STICK_R_EMULATION_UP) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_UP;
|
||||
if(vpad_buffer->hold & VPAD_STICK_R_EMULATION_DOWN) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_DOWN;
|
||||
|
||||
pro_buffer->l_stick_x = (s16) (vpad_buffer->leftStick.x * 950.0f);
|
||||
pro_buffer->l_stick_y = (s16) (vpad_buffer->leftStick.y * 950.0f);
|
||||
pro_buffer->r_stick_x = (s16) (vpad_buffer->rightStick.x * 950.0f);
|
||||
pro_buffer->r_stick_y = (s16) (vpad_buffer->rightStick.y * 950.0f);
|
||||
|
||||
pro_buffer->buttons = buttons_hold;
|
||||
|
||||
pro_buffer->fmt = WPAD_FMT_PRO_CONTROLLER;
|
||||
pro_buffer->err = 0x00;
|
||||
pro_buffer->dev = WPAD_EXT_PRO_CONTROLLER;
|
||||
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::translateToVPAD(VPADStatus * vpad_buffer,KPADData * pro_buffer,u32 * lastButtonsPressesVPAD){
|
||||
if(vpad_buffer == NULL || pro_buffer == NULL || lastButtonsPressesVPAD == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
|
||||
s32 buttons_hold = 0;
|
||||
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_A) buttons_hold |= VPAD_BUTTON_A;
|
||||
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_B) buttons_hold |= VPAD_BUTTON_B;
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_X) buttons_hold |= VPAD_BUTTON_X;
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_Y) buttons_hold |= VPAD_BUTTON_Y;
|
||||
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_PLUS) buttons_hold |= VPAD_BUTTON_PLUS;
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_MINUS) buttons_hold |= VPAD_BUTTON_MINUS;
|
||||
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_HOME) buttons_hold |= VPAD_BUTTON_HOME;
|
||||
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_LEFT) buttons_hold |= VPAD_BUTTON_LEFT;
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_RIGHT) buttons_hold |= VPAD_BUTTON_RIGHT;
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_UP) buttons_hold |= VPAD_BUTTON_UP;
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_DOWN) buttons_hold |= VPAD_BUTTON_DOWN;
|
||||
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_TRIGGER_L) buttons_hold |= VPAD_BUTTON_L;
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_TRIGGER_ZL) buttons_hold |= VPAD_BUTTON_ZL;
|
||||
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_TRIGGER_R) buttons_hold |= VPAD_BUTTON_R;
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_TRIGGER_ZR) buttons_hold |= VPAD_BUTTON_ZR;
|
||||
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_STICK_L) buttons_hold |= VPAD_BUTTON_STICK_L;
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_BUTTON_STICK_R) buttons_hold |= VPAD_BUTTON_STICK_R;
|
||||
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_STICK_L_EMULATION_LEFT) buttons_hold |= VPAD_STICK_L_EMULATION_LEFT;
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_STICK_L_EMULATION_RIGHT) buttons_hold |= VPAD_STICK_L_EMULATION_RIGHT;
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_STICK_L_EMULATION_UP) buttons_hold |= VPAD_STICK_L_EMULATION_UP;
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_STICK_L_EMULATION_DOWN) buttons_hold |= VPAD_STICK_L_EMULATION_DOWN;
|
||||
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_STICK_R_EMULATION_LEFT) buttons_hold |= VPAD_STICK_R_EMULATION_LEFT;
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_STICK_R_EMULATION_RIGHT) buttons_hold |= VPAD_STICK_R_EMULATION_RIGHT;
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_STICK_R_EMULATION_UP) buttons_hold |= VPAD_STICK_R_EMULATION_UP;
|
||||
if(pro_buffer->pro.hold & WPAD_PRO_STICK_R_EMULATION_DOWN) buttons_hold |= VPAD_STICK_R_EMULATION_DOWN;
|
||||
|
||||
vpad_buffer->leftStick.x = pro_buffer->pro.lstick_x;
|
||||
vpad_buffer->leftStick.y = pro_buffer->pro.lstick_x;
|
||||
vpad_buffer->rightStick.x = pro_buffer->pro.rstick_x;
|
||||
vpad_buffer->rightStick.y = pro_buffer->pro.rstick_x;
|
||||
|
||||
vpad_buffer->hold |= buttons_hold;
|
||||
vpad_buffer->trigger |= (buttons_hold & (~*lastButtonsPressesVPAD));
|
||||
vpad_buffer->release |= (*lastButtonsPressesVPAD & (~buttons_hold));
|
||||
|
||||
*lastButtonsPressesVPAD = buttons_hold;
|
||||
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::checkValueinConfigController(s32 deviceslot,s32 CONTRPS_slot,s32 expectedValue){
|
||||
if(config_controller[deviceslot][CONTRPS_slot][0] != CONTROLLER_PATCHER_INVALIDVALUE){
|
||||
if(expectedValue == config_controller[deviceslot][CONTRPS_slot][1]) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ControllerPatcherUtils::setConfigValue(u8 * dest, u8 first, u8 second){
|
||||
dest[0] = first;
|
||||
dest[1] = second;
|
||||
}
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getDeviceSlot(u32 hidmask){
|
||||
for(s32 i = 0;i < gHIDMaxDevices;i++){
|
||||
if(hidmask & config_controller_hidmask[i]){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return CONTROLLER_PATCHER_ERROR_DEVICE_SLOT_NOT_FOUND;
|
||||
}
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getDeviceInfoFromVidPid(DeviceInfo * info){
|
||||
if(info != NULL){
|
||||
for(s32 i = 0;i< gHIDMaxDevices;i++){
|
||||
u16 my_vid = config_controller[i][CONTRPS_VID][0] * 0x100 + config_controller[i][CONTRPS_VID][1];
|
||||
u16 my_pid = config_controller[i][CONTRPS_PID][0] * 0x100 + config_controller[i][CONTRPS_PID][1];
|
||||
//printf("info->vidpid.vid (%04X) == my_vid (%04X) && info->vidpid.pid (%04X) == my_pid (%04X)\n",info->vidpid.vid,my_vid,info->vidpid.pid,my_pid);
|
||||
if(info->vidpid.vid == my_vid && info->vidpid.pid == my_pid){
|
||||
info->slotdata.hidmask = config_controller_hidmask[i];
|
||||
info->slotdata.deviceslot = i;
|
||||
info->pad_count = 1;
|
||||
if(config_controller[i][CONTRPS_PAD_COUNT][0] != CONTROLLER_PATCHER_INVALIDVALUE){
|
||||
info->pad_count = config_controller[i][CONTRPS_PAD_COUNT][1];
|
||||
if(info->pad_count > HID_MAX_PADS_COUNT){
|
||||
info->pad_count = HID_MAX_PADS_COUNT;
|
||||
}
|
||||
}
|
||||
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
//printf("Found device: device: %s slot: %d\n",byte_to_binary(device),deviceSlot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return CONTROLLER_PATCHER_ERROR_UNKNOWN_VID_PID;
|
||||
}
|
||||
return CONTROLLER_PATCHER_ERROR_INVALID_BUFFER;
|
||||
}
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getNextSlotData(HIDSlotData * slotdata){
|
||||
if(slotdata == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
if(gHIDRegisteredDevices >= gHIDMaxDevices) return CONTROLLER_PATCHER_ERROR_NO_FREE_SLOT;
|
||||
slotdata->deviceslot = gHIDRegisteredDevices;
|
||||
slotdata->hidmask = (1 << (gHIDRegisteredDevices));
|
||||
gHIDRegisteredDevices++;
|
||||
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getVIDPIDbyDeviceSlot(s32 deviceslot, DeviceVIDPIDInfo * vidpid){
|
||||
if(vidpid == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
|
||||
if(deviceslot >= gHIDMaxDevices || deviceslot < 0) return CONTROLLER_PATCHER_ERROR_DEVICE_SLOT_NOT_FOUND;
|
||||
vidpid->vid = config_controller[deviceslot][CONTRPS_VID][0] * 0x100 + config_controller[deviceslot][CONTRPS_VID][1];
|
||||
vidpid->pid = config_controller[deviceslot][CONTRPS_PID][0] * 0x100 + config_controller[deviceslot][CONTRPS_PID][1];
|
||||
if(vidpid->vid == 0x0000) return CONTROLLER_PATCHER_ERROR_FAILED_TO_GET_HIDDATA;
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
||||
|
||||
s32 ControllerPatcherUtils::getPadSlotInAdapter(s32 deviceslot, u8 * input_data){
|
||||
s32 slot_incr = 0;
|
||||
if(config_controller[deviceslot][CONTRPS_PAD_COUNT][0] != CONTROLLER_PATCHER_INVALIDVALUE){
|
||||
s32 pad_count = config_controller[deviceslot][CONTRPS_PAD_COUNT][1];
|
||||
if(pad_count > HID_MAX_PADS_COUNT){
|
||||
pad_count = HID_MAX_PADS_COUNT;
|
||||
}
|
||||
for(s32 i= 0;i<pad_count;i++){
|
||||
if( config_controller[deviceslot][CONTRPS_PAD1_FILTER + i][0] != CONTROLLER_PATCHER_INVALIDVALUE){
|
||||
if(input_data[config_controller[deviceslot][CONTRPS_PAD1_FILTER + i][0]] == config_controller[deviceslot][CONTRPS_PAD1_FILTER + i][1]){
|
||||
slot_incr = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return slot_incr;
|
||||
}
|
||||
|
||||
ControllerMappingPAD * ControllerPatcherUtils::getControllerMappingByType(UController_Type type){
|
||||
ControllerMappingPAD * cm_map_pad = NULL;
|
||||
|
||||
if(type == UController_Type_Gamepad){
|
||||
cm_map_pad = &(gControllerMapping.gamepad);
|
||||
}else if(type == UController_Type_Pro1){
|
||||
cm_map_pad = &(gControllerMapping.proController[0]);
|
||||
}else if(type == UController_Type_Pro2){
|
||||
cm_map_pad = &(gControllerMapping.proController[1]);
|
||||
}else if(type == UController_Type_Pro3){
|
||||
cm_map_pad = &(gControllerMapping.proController[2]);
|
||||
}else if(type == UController_Type_Pro4){
|
||||
cm_map_pad = &(gControllerMapping.proController[3]);
|
||||
}
|
||||
return cm_map_pad;
|
||||
}
|
||||
|
||||
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::doSampling(u16 deviceslot,u8 padslot = 0,bool ignorePadSlot = false){
|
||||
if(gSamplingCallback != NULL){
|
||||
for(int i=0;i<4;i++){
|
||||
ControllerMappingPADInfo * padinfo = &gControllerMapping.proController[i].pad_infos[0];
|
||||
if(padinfo->active){
|
||||
DeviceInfo device_info;
|
||||
|
||||
memset(&device_info,0,sizeof(device_info));
|
||||
device_info.vidpid = padinfo->vidpid;
|
||||
|
||||
s32 res = -1;
|
||||
if((res = ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info)) >= 0){
|
||||
if(!ignorePadSlot){
|
||||
s32 real_pad = (padinfo->pad/(device_info.pad_count))*device_info.pad_count;
|
||||
if(real_pad == padslot && device_info.slotdata.deviceslot == deviceslot){
|
||||
if(ControllerPatcherUtils::checkActivePad(device_info.slotdata.hidmask,padinfo->pad)){
|
||||
gSamplingCallback(i);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
gSamplingCallback(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return CONTROLLER_PATCHER_ERROR_NONE;
|
||||
}
|
320
wiiu/controller_patcher/patcher/ControllerPatcherUtils.hpp
Normal file
320
wiiu/controller_patcher/patcher/ControllerPatcherUtils.hpp
Normal file
@ -0,0 +1,320 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* @file ControllerPatcherUtil.hpp
|
||||
* @author Maschell
|
||||
* @date 25 Aug 2016
|
||||
* \brief This files contain useful functions for the controller patcher engine
|
||||
*
|
||||
* @see https://github.com/Maschell/controller_patcher
|
||||
*/
|
||||
|
||||
#ifndef _CONTROLLER_PATCHER_UTIL_H_
|
||||
#define _CONTROLLER_PATCHER_UTIL_H_
|
||||
|
||||
|
||||
#include "wiiu/vpad.h"
|
||||
#include "wiiu/kpad.h"
|
||||
|
||||
#include "../ControllerPatcher.hpp"
|
||||
|
||||
class ControllerPatcherUtils{
|
||||
//give the other classes access to the private functions.
|
||||
friend class ControllerPatcher;
|
||||
friend class ControllerPatcherHID;
|
||||
friend class ConfigParser;
|
||||
|
||||
public:
|
||||
/**
|
||||
\brief Returns the device slot for a given HID-Mask.
|
||||
|
||||
\param hidmask Given HID-Mask
|
||||
|
||||
\return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. The returned value is the deviceslot of the given HID-Mask
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR getDeviceSlot(u32 hidmask);
|
||||
|
||||
/**
|
||||
\brief Returns the device slot for a given HID-Mask.
|
||||
|
||||
\param handle Given HID-handle
|
||||
\param data Given my_cb_user ** where the result will be stored. Valid pointer when result is >= 0.
|
||||
|
||||
\return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. The actual result will be store in the given my_cb_user **.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR getDataByHandle(s32 handle, my_cb_user ** data);
|
||||
|
||||
/**
|
||||
\brief Returns the VID/PID for the given device slot.
|
||||
|
||||
\param deviceslot Given device slot
|
||||
\param vidpid Pointer to the DeviceVIDPIDInfo struct where the result will be stored.
|
||||
|
||||
\return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. The actual result will be store in the given DeviceVIDPIDInfo *.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR getVIDPIDbyDeviceSlot(s32 deviceslot, DeviceVIDPIDInfo * vidpid);
|
||||
|
||||
/** \brief Set the VPAD data for a given KPAD data.
|
||||
*
|
||||
* \param vpad_buffer VPADStatus* A pointer to the VPAD Data where the result will be stored.
|
||||
* \param pro_buffer KPADData* A pointer to the given KPADData data.
|
||||
* \param lastButtonsPressesPRO u32* A pointer to the button presses of the previous call. Will be updated while calling.
|
||||
* \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful.
|
||||
*
|
||||
*/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR translateToVPAD(VPADStatus * vpad_buffer,KPADData * pro_buffer,u32 * lastButtonsPressesVPAD);
|
||||
private:
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Analyse inputs
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/** \brief Checks if a the given @p VPADButton was pressed in the given HID @data. When it was pressed, the result will be set the in given @p buttons_hold
|
||||
*
|
||||
* \param data Pointer to the HID_Data from where the input is read.
|
||||
* \param buttons_hold Pointer to the u32 where the result will be written to.
|
||||
* \param VPADButton The button that will be checked
|
||||
* \return When the functions failed result < 0 is returned.If the result is >= 0 the function was successful.
|
||||
*
|
||||
*/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR getButtonPressed(HID_Data * data, s32 * buttons_hold, s32 VPADButton);
|
||||
|
||||
|
||||
/** \brief Checks if a given value is set in the HID_DATA given the data in the slot number provided by cur_config.
|
||||
*
|
||||
* \param data Pointer to the HID_Data from where the input is read.
|
||||
* \param cur_config slot of the configuration array which will be checked.
|
||||
* \return When the functions failed result < 0 is returned. If the value is set, 1 will be returned. Otherwise 0.
|
||||
*
|
||||
*/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR isValueSet(HID_Data * data,s32 cur_config);
|
||||
|
||||
|
||||
/** \brief Checks if a given key in the keyboard data is pressed.
|
||||
*
|
||||
* \param keyboardData A pointer to the keyboard data.
|
||||
* \param key A pointer to the keyboard data.
|
||||
* \return When the functions failed result < 0 is returned. If the key is active pressed, 1 is returned.
|
||||
*
|
||||
*/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR isInKeyboardData(unsigned char * keyboardData,s32 key);
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Utils for setting the Button data
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/** \brief Checks if a @p VPADButton (VPAD_BUTTON_XXX) is set in the given @p CONTRPS_SLOT (usually the one for buttons remapping) of the GamePad. When its set it'll be
|
||||
* set for the corresponding Button (aka button remapping). When the @p CONTRPS_SLOT is not valid, the normal buttons layout will be used.
|
||||
*
|
||||
* \param old_buffer A pointer to a VPADStatus struct from which will be read.
|
||||
* \param new_buffer A pointer to a VPADStatus struct where the result will be written.
|
||||
* \param VPADButton The buttons that will be may replaced
|
||||
* \param CONTRPS_SLOT The CONTRPS_SLOT where the VPAD_Buttons we want to use instead of the parameter "VPADButton" could be saved.
|
||||
* \return When the functions failed result < 0 is returned. If the pad is active/connected, 1 is returned.
|
||||
*
|
||||
*/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR setButtonRemappingData(VPADStatus * old_buffer, VPADStatus * new_buffer,u32 VPADButton, s32 CONTRPS_SLOT);
|
||||
|
||||
/**
|
||||
\brief Checks if a given button (oldVPADButton) is set in a given VPADStatus struct (old_buffer). If its set, it will set an other
|
||||
button (newVPADButton) to the second given VPADStatus struct (new_buffer)
|
||||
|
||||
\param old_buffer A pointer to a VPADStatus struct from which will be read.
|
||||
\param new_buffer A pointer to a VPADStatus struct where the result will be written.
|
||||
\param oldVPADButton The buttons that need to be set in the first VPADStatus
|
||||
\param newVPADButton The buttons that will be set in the second VPADStatus, when the oldVPADButton is pressed in the first buffer.
|
||||
|
||||
\return When the functions failed result < 0 is returned. If the pad is active/connected, 1 is returned.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR setButtonData(VPADStatus * old_buffer, VPADStatus * new_buffer,u32 oldVPADButton,u32 newVPADButton);
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Pad Status functions
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
\brief Checks if a controller is attached for the given HID-Mask and pad.
|
||||
|
||||
\param hidmask Bit-Mask of the target hid-device.
|
||||
\param pad Defines for which pad the connection will be checked.
|
||||
|
||||
\return When the functions failed result < 0 is returned. If the pad is active/connected, 1 is returned.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR checkActivePad(u32 hidmask,s32 pad);
|
||||
|
||||
/**
|
||||
\brief Returns the first active pad of devices with the given HID-Mask. Currently only implemented for the GC-Adapter. Every other pad will always return 0.
|
||||
|
||||
\param hidmask Bit-Mask of the target hid-device.
|
||||
|
||||
\return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. The returned value is fist active pad.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR getActivePad(u32 hidmask);
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Stick functions
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
\brief Normalizes the stick to valid values.
|
||||
|
||||
\param stick Pointer to the stick that will be normalized
|
||||
|
||||
\return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR normalizeStickValues(VPADVec2D * stick);
|
||||
|
||||
/**
|
||||
\brief Converts the digital absolute stick data into a float value. It also applies the deadzones, and can invert the result.
|
||||
|
||||
\param value Given current value of the stick axis
|
||||
\param default_val Value in neutral axis-position
|
||||
\param min Value that represents -1.0f
|
||||
\param max Value that represents 1.0f
|
||||
\param invert Set to 1 if the axis needs to be inverted
|
||||
\param deadzone Deadzone
|
||||
|
||||
\return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful.
|
||||
**/
|
||||
static f32 convertAnalogValue(u8 value, u8 default_val, u8 min, u8 max, u8 invert,u8 deadzone);
|
||||
|
||||
/**
|
||||
\brief Calculates a the stick data (VPADVec2D) from given digital direction.
|
||||
|
||||
\param stick_values bits need to set for each direction. (STICK_VALUE_UP,STICK_VALUE_DOWN,STICK_VALUE_LEFT,STICK_VALUE_RIGHT)
|
||||
|
||||
\return The VPADVec2D with the set values.
|
||||
**/
|
||||
static VPADVec2D getAnalogValueByButtons(u8 stick_values);
|
||||
|
||||
/**
|
||||
\brief Handles the analog-stick data of HID devices. The result will written in the VPADStatus buffer.
|
||||
|
||||
\param data Pointer to the current data of the HID device
|
||||
\param buffer Pointer to VPADStatus where the analog-stick data will be set.
|
||||
|
||||
\return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR convertAnalogSticks(HID_Data * data,VPADStatus * buffer);
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Mouse functions
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/**
|
||||
\brief Set the touch data in the VPADStatus buffer.
|
||||
Currently its only possible to set the touch data from a Mouse
|
||||
|
||||
\param data The current data of the HID device
|
||||
\param buffer Pointer to VPADStatus where the touch data will be set.
|
||||
|
||||
\return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR setTouch(HID_Data * data,VPADStatus * buffer);
|
||||
|
||||
/** \brief Checks if the mouse mode needs to be changed. Sets it to the new mode if necessary.
|
||||
* Currently the incoming data needs to be from a keyboard.
|
||||
*
|
||||
* \param data HID_Data* Pointer to the current data
|
||||
* \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful.
|
||||
*
|
||||
*/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR checkAndSetMouseMode(HID_Data * data);
|
||||
|
||||
/**
|
||||
\brief Set the emulated sticks for a given VPAD data.
|
||||
|
||||
\param buffer: A pointer to the given VPAD Data.
|
||||
\param last_emulatedSticks: A pointer to the button presses of the previous call. Will be updated while calling.
|
||||
|
||||
\return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR setEmulatedSticks(VPADStatus * buffer, u32 * last_emulatedSticks);
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
* Other functions
|
||||
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/** \brief Set the Pro Controller for a given VPAD data.
|
||||
*
|
||||
* \param vpad_buffer VPADStatus* A pointer to the given VPAD Data.
|
||||
* \param pro_buffer KPADData* A pointer to the KPADData where the result will be stored.
|
||||
* \param lastButtonsPressesPRO u32* A pointer to the button presses of the previous call. Will be updated while calling.
|
||||
* \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful.
|
||||
*
|
||||
*/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR translateToPro(VPADStatus * vpad_buffer,KPADData * pro_buffer,u32 * lastButtonsPressesPRO);
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR translateToProWPADRead(VPADStatus * vpad_buffer,WPADReadData * pro_buffer);
|
||||
|
||||
/**
|
||||
\brief Checks if the value at the given device + CONTRPS slot equals the expected value.
|
||||
|
||||
\param device_slot
|
||||
\param CONTRPS_slot
|
||||
\param expectedValue
|
||||
|
||||
\return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR checkValueinConfigController(s32 device_slot,s32 CONTRPS_slot,s32 expectedValue);
|
||||
|
||||
/**
|
||||
\brief Sets two u8 values to the given pointer.
|
||||
|
||||
\param dest: pointer to the destination array.
|
||||
\param first: Value that will be written in @p dest[0]
|
||||
\param second: Value that will be written in @p dest[1]
|
||||
**/
|
||||
static void setConfigValue(u8 * dest , u8 first, u8 second);
|
||||
|
||||
/**
|
||||
\brief Saves a new free device slot and the corresponding HID-Mask in the given @p HIDSlotData pointer
|
||||
|
||||
\param slotdata Pointer to the HIDSlotData struct where the result will be saved.
|
||||
|
||||
\return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR getNextSlotData(HIDSlotData * slotdata);
|
||||
|
||||
/**
|
||||
\brief Fills up a given DeviceInfo, which provides a valid VID/PID, with HIDSlotData.
|
||||
|
||||
\param info Pointer the target DeviceInfo. The VID/PID need to be set, the HIDSlotData will be filled with data.
|
||||
|
||||
\return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful.
|
||||
**/
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR getDeviceInfoFromVidPid(DeviceInfo * info);
|
||||
|
||||
/**
|
||||
\brief returns the internal slot number of the device. Some adapters have multiple slot and send the data for each one
|
||||
alternating (with an identifier at the beginning). This function searches for the identifier (if it's set) and returns the
|
||||
slot number relative to this pad.
|
||||
|
||||
\param device slot
|
||||
\param current input data
|
||||
\return The relative slot in the device
|
||||
**/
|
||||
static s32 getPadSlotInAdapter(s32 deviceslot, u8 * input_data);
|
||||
|
||||
/**
|
||||
\brief returns a pointer to the ControllerMapping to the given controller type
|
||||
|
||||
\param type controller type
|
||||
|
||||
\return pointer to ControllerMapping data, null is type was invalid
|
||||
**/
|
||||
static ControllerMappingPAD * getControllerMappingByType(UController_Type type);
|
||||
|
||||
static CONTROLLER_PATCHER_RESULT_OR_ERROR doSampling(u16 deviceslot,u8 padslot,bool ignorePadSlot);
|
||||
};
|
||||
|
||||
#endif /* _CONTROLLER_PATCHER_UTIL_H_ */
|
73
wiiu/controller_patcher/utils/CPRetainVars.cpp
Normal file
73
wiiu/controller_patcher/utils/CPRetainVars.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "../ControllerPatcher.hpp"
|
||||
|
||||
ControllerMapping gControllerMapping __attribute__((section(".data")));
|
||||
|
||||
u8 gConfig_done __attribute__((section(".data"))) = 0;
|
||||
u8 gButtonRemappingConfigDone __attribute__((section(".data"))) = 0;
|
||||
|
||||
u32 gHIDAttached __attribute__((section(".data"))) = 0;
|
||||
u32 gHIDCurrentDevice __attribute__((section(".data"))) = 0;
|
||||
|
||||
u16 gHIDRegisteredDevices __attribute__((section(".data"))) = 0;
|
||||
|
||||
HIDClient gHIDClient __attribute__((section(".data")));
|
||||
|
||||
HID_DEVICE_DATA gHID_Devices[gHIDMaxDevices] __attribute__((section(".data")));
|
||||
|
||||
u8 gHID_Mouse_Mode __attribute__((section(".data"))) = HID_MOUSE_MODE_TOUCH;
|
||||
|
||||
u32 gGamePadValues[CONTRPS_MAX_VALUE] __attribute__((section(".data")));
|
||||
|
||||
u8 config_controller[gHIDMaxDevices][CONTRPS_MAX_VALUE][2] __attribute__((section(".data")));
|
||||
u32 config_controller_hidmask[gHIDMaxDevices] __attribute__((section(".data")));
|
||||
|
||||
u32 gHID_LIST_GC __attribute__((section(".data"))) = 0;
|
||||
u32 gHID_LIST_DS3 __attribute__((section(".data"))) = 0;
|
||||
u32 gHID_LIST_DS4 __attribute__((section(".data"))) = 0;
|
||||
u32 gHID_LIST_KEYBOARD __attribute__((section(".data"))) = 0;
|
||||
u32 gHID_LIST_SWITCH_PRO __attribute__((section(".data"))) = 0;
|
||||
u32 gHID_LIST_MOUSE __attribute__((section(".data"))) = 0;
|
||||
|
||||
u16 gGamePadSlot __attribute__((section(".data"))) = 0;
|
||||
u16 gHID_SLOT_GC __attribute__((section(".data"))) = 0;
|
||||
u16 gHID_SLOT_KEYBOARD __attribute__((section(".data"))) = 0;
|
||||
u16 gMouseSlot __attribute__((section(".data"))) = 0;
|
||||
|
||||
u8 gOriginalDimState __attribute__((section(".data"))) = 0;
|
||||
u8 gOriginalAPDState __attribute__((section(".data"))) = 0;
|
||||
|
||||
u16 gNetworkController[gHIDMaxDevices][HID_MAX_PADS_COUNT][4] __attribute__((section(".data")));
|
||||
s32 gHIDNetworkClientID __attribute__((section(".data"))) = 0;
|
||||
u8 gUsedProtocolVersion __attribute__((section(".data"))) = WIIU_CP_TCP_HANDSHAKE;
|
||||
|
||||
wpad_connect_callback_t gWPADConnectCallback[4] __attribute__((section(".data")));
|
||||
wpad_connect_callback_t gKPADConnectCallback[4] __attribute__((section(".data")));
|
||||
wpad_extension_callback_t gExtensionCallback[4] __attribute__((section(".data")));
|
||||
wpad_sampling_callback_t gSamplingCallback __attribute__((section(".data"))) = 0;
|
||||
u8 gCallbackCooldown __attribute__((section(".data"))) = 0;
|
||||
|
||||
u8 gGlobalRumbleActivated __attribute__((section(".data"))) = 0;
|
||||
|
||||
my_cb_user * connectionOrderHelper[gHIDMaxDevices] __attribute__((section(".data")));
|
||||
|
||||
u32 gUDPClientip __attribute__((section(".data"))) = 0;
|
||||
ControllerMappingPADInfo* gProPadInfo[4] __attribute__((section(".data"))) = {&gControllerMapping.proController[0].pad_infos[0],
|
||||
&gControllerMapping.proController[1].pad_infos[0],
|
||||
&gControllerMapping.proController[2].pad_infos[0],
|
||||
&gControllerMapping.proController[3].pad_infos[0]} ;
|
76
wiiu/controller_patcher/utils/CPRetainVars.hpp
Normal file
76
wiiu/controller_patcher/utils/CPRetainVars.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#ifndef CP_RETAINS_VARS_H_
|
||||
#define CP_RETAINS_VARS_H_
|
||||
|
||||
#include "wiiu/syshid.h"
|
||||
#include "wiiu/kpad.h"
|
||||
#include "../patcher/ControllerPatcherDefs.h"
|
||||
|
||||
extern ControllerMapping gControllerMapping;
|
||||
|
||||
extern u8 gConfig_done;
|
||||
extern u8 gButtonRemappingConfigDone;
|
||||
|
||||
extern u32 gHIDAttached;
|
||||
extern u32 gHIDCurrentDevice;
|
||||
extern HIDClient gHIDClient;
|
||||
|
||||
extern u16 gHIDRegisteredDevices;
|
||||
|
||||
extern HID_DEVICE_DATA gHID_Devices[gHIDMaxDevices];
|
||||
|
||||
extern u8 gHID_Mouse_Mode;
|
||||
|
||||
extern u32 gGamePadValues[CONTRPS_MAX_VALUE];
|
||||
|
||||
extern u8 config_controller[gHIDMaxDevices][CONTRPS_MAX_VALUE][2];
|
||||
extern u32 config_controller_hidmask[gHIDMaxDevices];
|
||||
|
||||
extern u32 gHID_LIST_GC;
|
||||
extern u32 gHID_LIST_DS3;
|
||||
extern u32 gHID_LIST_DS4;
|
||||
extern u32 gHID_LIST_KEYBOARD;
|
||||
extern u32 gHID_LIST_SWITCH_PRO;
|
||||
extern u32 gHID_LIST_MOUSE;
|
||||
extern u16 gGamePadSlot;
|
||||
|
||||
extern u16 gHID_SLOT_GC;
|
||||
extern u16 gHID_SLOT_KEYBOARD;
|
||||
extern u16 gMouseSlot;
|
||||
|
||||
extern u8 gOriginalDimState;
|
||||
extern u8 gOriginalAPDState;
|
||||
|
||||
extern u16 gNetworkController[gHIDMaxDevices][HID_MAX_PADS_COUNT][4];
|
||||
extern s32 gHIDNetworkClientID;
|
||||
|
||||
extern u8 gUsedProtocolVersion;
|
||||
|
||||
extern wpad_connect_callback_t gWPADConnectCallback[4];
|
||||
extern wpad_connect_callback_t gKPADConnectCallback[4];
|
||||
extern wpad_extension_callback_t gExtensionCallback[4];
|
||||
extern wpad_sampling_callback_t gSamplingCallback;
|
||||
extern u8 gCallbackCooldown;
|
||||
extern u8 gGlobalRumbleActivated;
|
||||
|
||||
extern my_cb_user * connectionOrderHelper[gHIDMaxDevices];
|
||||
|
||||
extern u32 gUDPClientip;
|
||||
extern ControllerMappingPADInfo* gProPadInfo[4];
|
||||
|
||||
#endif // CP_RETAINS_VARS_H_
|
85
wiiu/controller_patcher/utils/CPStringTools.cpp
Normal file
85
wiiu/controller_patcher/utils/CPStringTools.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
#include "CPStringTools.hpp"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "wiiu/types.h"
|
||||
|
||||
bool CPStringTools::EndsWith(const std::string& a, const std::string& b) {
|
||||
if (b.size() > a.size()) return false;
|
||||
return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin());
|
||||
}
|
||||
|
||||
std::vector<std::string> CPStringTools::StringSplit(const std::string & inValue, const std::string & splitter){
|
||||
std::string value = inValue;
|
||||
std::vector<std::string> result;
|
||||
while (true) {
|
||||
u32 index = value.find(splitter);
|
||||
if (index == std::string::npos) {
|
||||
result.push_back(value);
|
||||
break;
|
||||
}
|
||||
std::string first = value.substr(0, index);
|
||||
result.push_back(first);
|
||||
if (index + splitter.size() == value.length()) {
|
||||
result.push_back("");
|
||||
break;
|
||||
}
|
||||
if(index + splitter.size() > value.length()) {
|
||||
break;
|
||||
}
|
||||
value = value.substr(index + splitter.size(), value.length());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const char * CPStringTools::byte_to_binary(s32 x){
|
||||
static char b[9];
|
||||
b[0] = '\0';
|
||||
|
||||
s32 z;
|
||||
for (z = 128; z > 0; z >>= 1)
|
||||
{
|
||||
strcat(b, ((x & z) == z) ? "1" : "0");
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
std::string CPStringTools::removeCharFromString(std::string& input,char toBeRemoved){
|
||||
std::string output = input;
|
||||
size_t position;
|
||||
while(1){
|
||||
position = output.find(toBeRemoved);
|
||||
if(position == std::string::npos)
|
||||
break;
|
||||
output.erase(position, 1);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
std::string CPStringTools::strfmt(const char * format, ...){
|
||||
std::string str;
|
||||
char * tmp = NULL;
|
||||
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
if((vasprintf(&tmp, format, va) >= 0) && tmp)
|
||||
{
|
||||
str = tmp;
|
||||
}
|
||||
va_end(va);
|
||||
|
||||
if(tmp){
|
||||
free(tmp);
|
||||
tmp = NULL;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
//CPStringTools
|
17
wiiu/controller_patcher/utils/CPStringTools.hpp
Normal file
17
wiiu/controller_patcher/utils/CPStringTools.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef _CPSTRING_TOOLS_H_
|
||||
#define _CPSTRING_TOOLS_H_
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "wiiu/types.h"
|
||||
|
||||
class CPStringTools{
|
||||
public:
|
||||
static bool EndsWith(const std::string& a, const std::string& b);
|
||||
static std::vector<std::string> StringSplit(const std::string & inValue, const std::string & splitter);
|
||||
static std::string removeCharFromString(std::string& input,char toBeRemoved);
|
||||
static const char * byte_to_binary(s32 test);
|
||||
static std::string strfmt(const char * format, ...);
|
||||
};
|
||||
|
||||
#endif /* _CPSTRING_TOOLS_H_ */
|
119
wiiu/controller_patcher/utils/ControllerPatcherThread.hpp
Normal file
119
wiiu/controller_patcher/utils/ControllerPatcherThread.hpp
Normal file
@ -0,0 +1,119 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2015 Dimok
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#ifndef ControllerPatcherThread_H_
|
||||
#define ControllerPatcherThread_H_
|
||||
|
||||
#include <malloc.h>
|
||||
#include <unistd.h>
|
||||
#include "wiiu/os/thread.h"
|
||||
|
||||
class ControllerPatcherThread
|
||||
{
|
||||
public:
|
||||
typedef void (* Callback)(ControllerPatcherThread *thread, void *arg);
|
||||
|
||||
//! constructor
|
||||
ControllerPatcherThread(int iAttr, int iPriority = 16, int iStackSize = 0x8000, ControllerPatcherThread::Callback callback = NULL, void *callbackArg = NULL)
|
||||
: pThread(NULL)
|
||||
, pThreadStack(NULL)
|
||||
, pCallback(callback)
|
||||
, pCallbackArg(callbackArg)
|
||||
{
|
||||
//! save attribute assignment
|
||||
iAttributes = iAttr;
|
||||
//! allocate the thread
|
||||
pThread = (OSThread*)memalign(8, sizeof(OSThread));
|
||||
//! allocate the stack
|
||||
pThreadStack = (u8 *) memalign(0x20, iStackSize);
|
||||
//! create the thread
|
||||
if(pThread && pThreadStack)
|
||||
OSCreateThread(pThread, &ControllerPatcherThread::threadCallback, 1, (char*)this, pThreadStack+iStackSize, iStackSize, iPriority, iAttributes);
|
||||
}
|
||||
|
||||
//! destructor
|
||||
virtual ~ControllerPatcherThread() { shutdownThread(); }
|
||||
|
||||
static ControllerPatcherThread *create(ControllerPatcherThread::Callback callback, void *callbackArg, int iAttr = eAttributeNone, int iPriority = 16, int iStackSize = 0x8000)
|
||||
{
|
||||
return ( new ControllerPatcherThread(iAttr, iPriority, iStackSize, callback, callbackArg) );
|
||||
}
|
||||
|
||||
//! Get thread ID
|
||||
virtual void* getThread() const { return pThread; }
|
||||
//! Thread entry function
|
||||
virtual void executeThread(void)
|
||||
{
|
||||
if(pCallback)
|
||||
pCallback(this, pCallbackArg);
|
||||
}
|
||||
//! Suspend thread
|
||||
virtual void suspendThread(void) { if(isThreadSuspended()) return; if(pThread) OSSuspendThread(pThread); }
|
||||
//! Resume thread
|
||||
virtual void resumeThread(void) { if(!isThreadSuspended()) return; if(pThread) OSResumeThread(pThread); }
|
||||
//! Set thread priority
|
||||
virtual void setThreadPriority(int prio) { if(pThread) OSSetThreadPriority(pThread, prio); }
|
||||
//! Check if thread is suspended
|
||||
virtual bool isThreadSuspended(void) const { if(pThread) return OSIsThreadSuspended(pThread); return false; }
|
||||
//! Check if thread is terminated
|
||||
virtual bool isThreadTerminated(void) const { if(pThread) return OSIsThreadTerminated(pThread); return false; }
|
||||
//! Check if thread is running
|
||||
virtual bool isThreadRunning(void) const { return !isThreadSuspended() && !isThreadRunning(); }
|
||||
//! Shutdown thread
|
||||
virtual void shutdownThread(void)
|
||||
{
|
||||
//! wait for thread to finish
|
||||
if(pThread && !(iAttributes & eAttributeDetach))
|
||||
{
|
||||
if(isThreadSuspended())
|
||||
resumeThread();
|
||||
|
||||
OSJoinThread(pThread, NULL);
|
||||
}
|
||||
//! free the thread stack buffer
|
||||
if(pThreadStack)
|
||||
free(pThreadStack);
|
||||
if(pThread)
|
||||
free(pThread);
|
||||
|
||||
pThread = NULL;
|
||||
pThreadStack = NULL;
|
||||
}
|
||||
//! Thread attributes
|
||||
enum eControllerPatcherThreadAttributes
|
||||
{
|
||||
eAttributeNone = 0x07,
|
||||
eAttributeAffCore0 = 0x01,
|
||||
eAttributeAffCore1 = 0x02,
|
||||
eAttributeAffCore2 = 0x04,
|
||||
eAttributeDetach = 0x08,
|
||||
eAttributePinnedAff = 0x10
|
||||
};
|
||||
private:
|
||||
static int threadCallback(int argc, const char **argv)
|
||||
{
|
||||
//! After call to start() continue with the internal function
|
||||
((ControllerPatcherThread *) argv)->executeThread();
|
||||
return 0;
|
||||
}
|
||||
int iAttributes;
|
||||
OSThread *pThread;
|
||||
u8 *pThreadStack;
|
||||
Callback pCallback;
|
||||
void *pCallbackArg;
|
||||
};
|
||||
|
||||
#endif
|
78
wiiu/controller_patcher/utils/FSHelper.c
Normal file
78
wiiu/controller_patcher/utils/FSHelper.c
Normal file
@ -0,0 +1,78 @@
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <wiiu/fs.h>
|
||||
#define FS_MAX_MOUNTPATH_SIZE 128
|
||||
int FS_Helper_MountFS(void *pClient, void *pCmd, char **mount_path){
|
||||
int result = -1;
|
||||
|
||||
void *mountSrc = malloc(sizeof(FSMountSource));
|
||||
if(!mountSrc)
|
||||
return -3;
|
||||
|
||||
char* mountPath = (char*) malloc(FS_MAX_MOUNTPATH_SIZE);
|
||||
if(!mountPath) {
|
||||
free(mountSrc);
|
||||
return -4;
|
||||
}
|
||||
|
||||
memset(mountSrc, 0, sizeof(FSMountSource));
|
||||
memset(mountPath, 0, FS_MAX_MOUNTPATH_SIZE);
|
||||
|
||||
// Mount sdcard
|
||||
if (FSGetMountSource(pClient, pCmd, FS_MOUNT_SOURCE_SD, mountSrc, -1) == 0)
|
||||
{
|
||||
result = FSMount(pClient, pCmd, mountSrc, mountPath, FS_MAX_MOUNTPATH_SIZE, -1);
|
||||
if((result == 0) && mount_path) {
|
||||
*mount_path = (char*)malloc(strlen(mountPath) + 1);
|
||||
if(*mount_path)
|
||||
strcpy(*mount_path, mountPath);
|
||||
}
|
||||
}
|
||||
|
||||
free(mountPath);
|
||||
free(mountSrc);
|
||||
return result;
|
||||
}
|
||||
|
||||
int FS_Helper_GetFile(void * pClient,void * pCmd,const char * path, char *(*result)){
|
||||
if(pClient == NULL || pCmd == NULL || path == NULL || result == NULL) return -2;
|
||||
FSStat stats;
|
||||
s32 status = -1;
|
||||
s32 handle = 0;
|
||||
if((status = FSGetStat(pClient,pCmd,path,&stats,-1)) == FS_STATUS_OK){
|
||||
(*result) = (uint8_t *) memalign(0x40, (sizeof(uint8_t)*stats.size)+1);
|
||||
if(!(*result)){
|
||||
printf("FS_Helper_GetFile(line %d): error: Failed to allocate space for reading the file\n",__LINE__);
|
||||
return -1;
|
||||
}
|
||||
(*result)[stats.size] = '\0';
|
||||
if((status = FSOpenFile(pClient,pCmd,path,"r",&handle,-1)) == FS_STATUS_OK){
|
||||
s32 total_read = 0;
|
||||
s32 ret2 = 0;
|
||||
|
||||
char * cur_result_pointer = *result;
|
||||
s32 sizeToRead = stats.size;
|
||||
|
||||
while ((ret2 = FSReadFile(pClient,pCmd, cur_result_pointer, 0x01, sizeToRead, handle, 0, -1)) > 0){
|
||||
total_read += ret2;
|
||||
cur_result_pointer += ret2;
|
||||
sizeToRead -= ret2;
|
||||
}
|
||||
|
||||
}else{
|
||||
printf("FS_Helper_GetFile(line %d): error: (FSOpenFile) Couldn't open file (%s), error: %d",__LINE__,path,status);
|
||||
free((*result));
|
||||
(*result)=NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
FSCloseFile(pClient,pCmd,handle,-1);
|
||||
return 0;
|
||||
}else{
|
||||
printf("FS_Helper_GetFile(line %d): error: (GetStat) Couldn't open file (%s), error: %d",__LINE__,path,status);
|
||||
}
|
||||
return -1;
|
||||
}
|
17
wiiu/controller_patcher/utils/FSHelper.h
Normal file
17
wiiu/controller_patcher/utils/FSHelper.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef __FSHELPER_H_
|
||||
#define __FSHELPER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <wiiu/types.h>
|
||||
|
||||
int FS_Helper_MountFS(void *pClient, void *pCmd, char **mount_path);
|
||||
int FS_Helper_GetFile(void * pClient,void * pCmd,const char *, char **result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __FSHELPER_H_
|
341
wiiu/controller_patcher/utils/PadConst.cpp
Normal file
341
wiiu/controller_patcher/utils/PadConst.cpp
Normal file
@ -0,0 +1,341 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "PadConst.hpp"
|
||||
|
||||
const u8 DEF_R_STICK = 220;
|
||||
const u8 DEF_L_STICK = 221;
|
||||
|
||||
const u8 DEF_STICK_OFFSET_INVERT = CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT - CONTRPS_VPAD_BUTTON_L_STICK_X;
|
||||
const u8 DEF_STICK_OFFSET_DEADZONE = CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE - CONTRPS_VPAD_BUTTON_L_STICK_X;
|
||||
const u8 DEF_STICK_OFFSET_MINMAX = CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX - CONTRPS_VPAD_BUTTON_L_STICK_X;
|
||||
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! Device names
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
const char *HID_GC_STRING = "GameCube\nUSB-Adapter";
|
||||
const char *HID_KEYBOARD_STRING = "Keyboard";
|
||||
const char *HID_MOUSE_STRING = "Mouse";
|
||||
const char *HID_DS3_STRING = "DualShock 3\nController";
|
||||
const char *HID_DS4_STRING = "DualShock 4\nController";
|
||||
const char *HID_NEW_DS4_STRING = "DualShock 4\nController";
|
||||
const char *HID_XINPUT_STRING = "XInput\nController";
|
||||
const char *HID_SWITCH_PRO_STRING = "Switch\nPro Controller";
|
||||
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! GC-Adapter
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
const u8 HID_GC_BUTTON_A[] = { 0x01,HID_GC_BUTTON_A_VALUE};
|
||||
const u8 HID_GC_BUTTON_B[] = { 0x01,HID_GC_BUTTON_B_VALUE};
|
||||
const u8 HID_GC_BUTTON_X[] = { 0x01,HID_GC_BUTTON_X_VALUE};
|
||||
const u8 HID_GC_BUTTON_Y[] = { 0x01,HID_GC_BUTTON_Y_VALUE};
|
||||
const u8 HID_GC_BUTTON_LEFT[] = { 0x01,HID_GC_BUTTON_LEFT_VALUE};
|
||||
const u8 HID_GC_BUTTON_RIGHT[] = { 0x01,HID_GC_BUTTON_RIGHT_VALUE};
|
||||
const u8 HID_GC_BUTTON_DOWN[] = { 0x01,HID_GC_BUTTON_DOWN_VALUE};
|
||||
const u8 HID_GC_BUTTON_UP[] = { 0x01,HID_GC_BUTTON_UP_VALUE};
|
||||
|
||||
const u8 HID_GC_BUTTON_START[] = { 0x02,HID_GC_BUTTON_START_VALUE};
|
||||
const u8 HID_GC_BUTTON_Z[] = { 0x02,HID_GC_BUTTON_Z_VALUE};
|
||||
|
||||
const u8 HID_GC_BUTTON_L[] = { 0x07,HID_GC_BUTTON_L_VALUE};
|
||||
const u8 HID_GC_BUTTON_R[] = { 0x08,HID_GC_BUTTON_R_VALUE};
|
||||
|
||||
const u8 HID_GC_BUTTON_DPAD_TYPE[] = { CONTRPDM_Normal,0x00};
|
||||
|
||||
const u8 HID_GC_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x03, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x09, //STICK_CONF_DEADZONE,
|
||||
0x00, //STICK_CONF_INVERT,
|
||||
0x1A, //STICK_CONF_MIN,
|
||||
0xE4};//STICK_CONF_MAX,
|
||||
|
||||
const u8 HID_GC_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x04, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x09, //STICK_CONF_DEADZONE,
|
||||
0x00, //STICK_CONF_INVERT,
|
||||
0x11, //STICK_CONF_MIN,
|
||||
0xE1};//STICK_CONF_MAX,
|
||||
|
||||
const u8 HID_GC_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x05, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x09, //STICK_CONF_DEADZONE,
|
||||
0x00, //STICK_CONF_INVERT,
|
||||
0x2B, //STICK_CONF_MIN,
|
||||
0xE2};//STICK_CONF_MAX,
|
||||
|
||||
const u8 HID_GC_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x06, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x09, //STICK_CONF_DEADZONE,
|
||||
0x00, //STICK_CONF_INVERT,
|
||||
0x1D, //STICK_CONF_MIN,
|
||||
0xDB};//STICK_CONF_MAX,
|
||||
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! DS3
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
const u8 HID_DS3_BUTTON_CROSS[] = { 0x03,HID_DS3_BUTTON_CROSS_VALUE};
|
||||
const u8 HID_DS3_BUTTON_CIRCLE[] = { 0x03,HID_DS3_BUTTON_CIRCLE_VALUE};
|
||||
const u8 HID_DS3_BUTTON_SQUARE [] = { 0x03,HID_DS3_BUTTON_SQUARE_VALUE};
|
||||
const u8 HID_DS3_BUTTON_TRIANGLE[] = { 0x03,HID_DS3_BUTTON_TRIANGLE_VALUE};
|
||||
|
||||
const u8 HID_DS3_BUTTON_L1[] = { 0x03,HID_DS3_BUTTON_L1_VALUE};
|
||||
const u8 HID_DS3_BUTTON_L2[] = { 0x03,HID_DS3_BUTTON_L2_VALUE};
|
||||
const u8 HID_DS3_BUTTON_R1[] = { 0x03,HID_DS3_BUTTON_R1_VALUE};
|
||||
const u8 HID_DS3_BUTTON_R2[] = { 0x03,HID_DS3_BUTTON_R2_VALUE};
|
||||
|
||||
const u8 HID_DS3_BUTTON_L3[] = { 0x02,HID_DS3_BUTTON_L3_VALUE};
|
||||
const u8 HID_DS3_BUTTON_R3[] = { 0x02,HID_DS3_BUTTON_R3_VALUE};
|
||||
const u8 HID_DS3_BUTTON_SELECT[] = { 0x02,HID_DS3_BUTTON_SELECT_VALUE};
|
||||
const u8 HID_DS3_BUTTON_START[] = { 0x02,HID_DS3_BUTTON_START_VALUE};
|
||||
const u8 HID_DS3_BUTTON_LEFT[] = { 0x02,HID_DS3_BUTTON_LEFT_VALUE};
|
||||
const u8 HID_DS3_BUTTON_RIGHT[] = { 0x02,HID_DS3_BUTTON_RIGHT_VALUE};
|
||||
const u8 HID_DS3_BUTTON_UP[] = { 0x02,HID_DS3_BUTTON_UP_VALUE};
|
||||
const u8 HID_DS3_BUTTON_DOWN[] = { 0x02,HID_DS3_BUTTON_DOWN_VALUE};
|
||||
|
||||
const u8 HID_DS3_BUTTON_GUIDE[] = { 0x04,HID_DS3_BUTTON_GUIDE_VALUE};
|
||||
|
||||
const u8 HID_DS3_BUTTON_DPAD_TYPE[] = { CONTRPDM_Normal,0x00};
|
||||
|
||||
const u8 HID_DS3_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x06, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x06, //STICK_CONF_DEADZONE,
|
||||
0x00, //STICK_CONF_INVERT,
|
||||
0x00, //STICK_CONF_MIN,
|
||||
0xFF};//STICK_CONF_MAX,
|
||||
|
||||
const u8 HID_DS3_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x07, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x06, //STICK_CONF_DEADZONE,
|
||||
0x01, //STICK_CONF_INVERT,
|
||||
0x00, //STICK_CONF_MIN,
|
||||
0xFF};//STICK_CONF_MAX,
|
||||
|
||||
const u8 HID_DS3_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x08, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x06, //STICK_CONF_DEADZONE,
|
||||
0x00, //STICK_CONF_INVERT,
|
||||
0x00, //STICK_CONF_MIN,
|
||||
0xFF};//STICK_CONF_MAX,
|
||||
|
||||
const u8 HID_DS3_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x09, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x06, //STICK_CONF_DEADZONE,
|
||||
0x01, //STICK_CONF_INVERT,
|
||||
0x00, //STICK_CONF_MIN,
|
||||
0xFF};//STICK_CONF_MAX,
|
||||
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! DS4
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
const u8 HID_DS4_BUTTON_CROSS[] = { 0x05,HID_DS4_BUTTON_CROSS_VALUE};
|
||||
const u8 HID_DS4_BUTTON_CIRCLE[] = { 0x05,HID_DS4_BUTTON_CIRCLE_VALUE};
|
||||
const u8 HID_DS4_BUTTON_SQUARE [] = { 0x05,HID_DS4_BUTTON_SQUARE_VALUE};
|
||||
const u8 HID_DS4_BUTTON_TRIANGLE[] = { 0x05,HID_DS4_BUTTON_TRIANGLE_VALUE};
|
||||
|
||||
const u8 HID_DS4_BUTTON_L1[] = { 0x06,HID_DS4_BUTTON_L1_VALUE};
|
||||
const u8 HID_DS4_BUTTON_L2[] = { 0x06,HID_DS4_BUTTON_L2_VALUE};
|
||||
const u8 HID_DS4_BUTTON_L3[] = { 0x06,HID_DS4_BUTTON_L3_VALUE};
|
||||
|
||||
const u8 HID_DS4_BUTTON_R1[] = { 0x06,HID_DS4_BUTTON_R1_VALUE};
|
||||
const u8 HID_DS4_BUTTON_R2[] = { 0x06,HID_DS4_BUTTON_R2_VALUE};
|
||||
const u8 HID_DS4_BUTTON_R3[] = { 0x06,HID_DS4_BUTTON_R3_VALUE};
|
||||
|
||||
const u8 HID_DS4_BUTTON_SHARE[] = { 0x06,HID_DS4_BUTTON_SHARE_VALUE};
|
||||
const u8 HID_DS4_BUTTON_OPTIONS[] = { 0x06,HID_DS4_BUTTON_OPTIONS_VALUE};
|
||||
|
||||
|
||||
const u8 HID_DS4_BUTTON_DPAD_TYPE[] = { CONTRPDM_Hat,HID_DS4_BUTTON_DPAD_MASK_VALUE};
|
||||
const u8 HID_DS4_BUTTON_DPAD_N[] = { 0x05,HID_DS4_BUTTON_DPAD_N_VALUE};
|
||||
const u8 HID_DS4_BUTTON_DPAD_NE[] = { 0x05,HID_DS4_BUTTON_DPAD_NE_VALUE};
|
||||
const u8 HID_DS4_BUTTON_DPAD_E[] = { 0x05,HID_DS4_BUTTON_DPAD_E_VALUE};
|
||||
const u8 HID_DS4_BUTTON_DPAD_SE[] = { 0x05,HID_DS4_BUTTON_DPAD_SE_VALUE};
|
||||
const u8 HID_DS4_BUTTON_DPAD_S[] = { 0x05,HID_DS4_BUTTON_DPAD_S_VALUE};
|
||||
const u8 HID_DS4_BUTTON_DPAD_SW[] = { 0x05,HID_DS4_BUTTON_DPAD_SW_VALUE};
|
||||
const u8 HID_DS4_BUTTON_DPAD_W[] = { 0x05,HID_DS4_BUTTON_DPAD_W_VALUE};
|
||||
const u8 HID_DS4_BUTTON_DPAD_NW[] = { 0x05,HID_DS4_BUTTON_DPAD_NW_VALUE};
|
||||
const u8 HID_DS4_BUTTON_DPAD_NEUTRAL[] = { 0x05,HID_DS4_BUTTON_DPAD_NEUTRAL_VALUE};
|
||||
|
||||
const u8 HID_DS4_BUTTON_GUIDE[] = { 0x07,HID_DS4_BUTTON_GUIDE_VALUE};
|
||||
const u8 HID_DS4_BUTTON_T_PAD_CLICK[] = { 0x07,HID_DS4_BUTTON_T_PAD_CLICK_VALUE};
|
||||
|
||||
const u8 HID_DS4_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x01, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x06, //STICK_CONF_DEADZONE,
|
||||
0x00, //STICK_CONF_INVERT,
|
||||
0x00, //STICK_CONF_MIN,
|
||||
0xFF};//STICK_CONF_MAX,
|
||||
|
||||
const u8 HID_DS4_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x02, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x05, //STICK_CONF_DEADZONE,
|
||||
0x01, //STICK_CONF_INVERT,
|
||||
0x00, //STICK_CONF_MIN,
|
||||
0xFF};//STICK_CONF_MAX,
|
||||
|
||||
const u8 HID_DS4_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x03, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x07, //STICK_CONF_DEADZONE,
|
||||
0x00, //STICK_CONF_INVERT,
|
||||
0x00, //STICK_CONF_MIN,
|
||||
0xFF};//STICK_CONF_MAX,
|
||||
|
||||
const u8 HID_DS4_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x04, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x09, //STICK_CONF_DEADZONE,
|
||||
0x01, //STICK_CONF_INVERT,
|
||||
0x00, //STICK_CONF_MIN,
|
||||
0xFF};//STICK_CONF_MAX,
|
||||
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! XInput
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
const u8 HID_XINPUT_BUTTON_A[] = { 0x07,HID_XINPUT_BUTTON_A_VALUE};
|
||||
const u8 HID_XINPUT_BUTTON_B[] = { 0x07,HID_XINPUT_BUTTON_B_VALUE};
|
||||
const u8 HID_XINPUT_BUTTON_X[] = { 0x07,HID_XINPUT_BUTTON_X_VALUE};
|
||||
const u8 HID_XINPUT_BUTTON_Y[] = { 0x07,HID_XINPUT_BUTTON_Y_VALUE};
|
||||
|
||||
const u8 HID_XINPUT_BUTTON_LB[] = { 0x06,HID_XINPUT_BUTTON_LB_VALUE};
|
||||
const u8 HID_XINPUT_BUTTON_LT[] = { 0x04,HID_XINPUT_BUTTON_LT_VALUE};
|
||||
const u8 HID_XINPUT_BUTTON_L3[] = { 0x06,HID_XINPUT_BUTTON_L3_VALUE};
|
||||
|
||||
const u8 HID_XINPUT_BUTTON_RB[] = { 0x06,HID_XINPUT_BUTTON_RB_VALUE};
|
||||
const u8 HID_XINPUT_BUTTON_RT[] = { 0x05,HID_XINPUT_BUTTON_RT_VALUE};
|
||||
const u8 HID_XINPUT_BUTTON_R3[] = { 0x06,HID_XINPUT_BUTTON_R3_VALUE};
|
||||
|
||||
const u8 HID_XINPUT_BUTTON_START[] = { 0x06,HID_XINPUT_BUTTON_START_VALUE};
|
||||
const u8 HID_XINPUT_BUTTON_BACK[] = { 0x06,HID_XINPUT_BUTTON_BACK_VALUE};
|
||||
const u8 HID_XINPUT_BUTTON_GUIDE[] = { 0x06,HID_XINPUT_BUTTON_GUIDE_VALUE};
|
||||
|
||||
const u8 HID_XINPUT_BUTTON_DPAD_TYPE[] = { CONTRPDM_Normal,HID_XINPUT_BUTTON_DPAD_MASK_VALUE};
|
||||
const u8 HID_XINPUT_BUTTON_LEFT[] = { 0x07,HID_XINPUT_BUTTON_LEFT_VALUE};
|
||||
const u8 HID_XINPUT_BUTTON_RIGHT[] = { 0x07,HID_XINPUT_BUTTON_RIGHT_VALUE};
|
||||
const u8 HID_XINPUT_BUTTON_DOWN[] = { 0x07,HID_XINPUT_BUTTON_DOWN_VALUE};
|
||||
const u8 HID_XINPUT_BUTTON_UP[] = { 0x07,HID_XINPUT_BUTTON_UP_VALUE};
|
||||
|
||||
const u8 HID_XINPUT_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x00, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x10, //STICK_CONF_DEADZONE,
|
||||
0x00, //STICK_CONF_INVERT,
|
||||
0x00, //STICK_CONF_MIN,
|
||||
0xFF};//STICK_CONF_MAX,
|
||||
|
||||
const u8 HID_XINPUT_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x01, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x10, //STICK_CONF_DEADZONE,
|
||||
0x00, //STICK_CONF_INVERT,
|
||||
0x00, //STICK_CONF_MIN,
|
||||
0xFF};//STICK_CONF_MAX,
|
||||
|
||||
const u8 HID_XINPUT_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x02, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x10, //STICK_CONF_DEADZONE,
|
||||
0x00, //STICK_CONF_INVERT,
|
||||
0x00, //STICK_CONF_MIN,
|
||||
0xFF};//STICK_CONF_MAX,
|
||||
|
||||
const u8 HID_XINPUT_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x03, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x10, //STICK_CONF_DEADZONE,
|
||||
0x00, //STICK_CONF_INVERT,
|
||||
0x00, //STICK_CONF_MIN,
|
||||
0xFF};//STICK_CONF_MAX,
|
||||
|
||||
|
||||
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! Switch Pro Controller
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_A[] = { 0x00,(u8)((HID_SWITCH_PRO_BT_BUTTON_A_VALUE >> 24) & 0xFF)};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_B[] = { 0x00,(u8)((HID_SWITCH_PRO_BT_BUTTON_B_VALUE >> 24) & 0xFF)};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_X[] = { 0x00,(u8)((HID_SWITCH_PRO_BT_BUTTON_X_VALUE >> 24) & 0xFF)};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_Y[] = { 0x00,(u8)((HID_SWITCH_PRO_BT_BUTTON_Y_VALUE >> 24) & 0xFF)};
|
||||
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_L[] = { 0x00,(u8)((HID_SWITCH_PRO_BT_BUTTON_L_VALUE >> 24) & 0xFF)};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_ZL[] = { 0x00,(u8)((HID_SWITCH_PRO_BT_BUTTON_ZL_VALUE >> 24) & 0xFF)};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_STICK_L[] = { 0x01,(u8)((HID_SWITCH_PRO_BT_BUTTON_STICK_L_VALUE >> 16) & 0xFF)};
|
||||
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_R[] = { 0x00,(u8)((HID_SWITCH_PRO_BT_BUTTON_R_VALUE >> 24) & 0xFF)};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_ZR[] = { 0x00,(u8)((HID_SWITCH_PRO_BT_BUTTON_ZR_VALUE >> 24) & 0xFF)};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_STICK_R[] = { 0x01,(u8)((HID_SWITCH_PRO_BT_BUTTON_STICK_R_VALUE >> 16) & 0xFF)};
|
||||
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_PLUS[] = { 0x01,(u8)((HID_SWITCH_PRO_BT_BUTTON_PLUS_VALUE >> 16) & 0xFF)};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_MINUS[] = { 0x01,(u8)((HID_SWITCH_PRO_BT_BUTTON_MINUS_VALUE >> 16) & 0xFF)};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_HOME[] = { 0x01,(u8)((HID_SWITCH_PRO_BT_BUTTON_HOME_VALUE >> 16) & 0xFF)};
|
||||
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_TYPE[] = { CONTRPDM_Hat,HID_SWITCH_PRO_BT_BUTTON_DPAD_MASK_VALUE};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_N[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_N_VALUE};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_NE[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_NE_VALUE};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_E[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_E_VALUE};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_SE[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_SE_VALUE};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_S[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_S_VALUE};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_SW[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_SW_VALUE};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_W[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_W_VALUE};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_NW[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_NW_VALUE};
|
||||
const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_NEUTRAL[] = { 0x02,HID_SWITCH_PRO_BT_BUTTON_DPAD_NEUTRAL_VALUE};
|
||||
|
||||
|
||||
const u8 HID_SWITCH_PRO_BT_STICK_L_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x04, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x01, //STICK_CONF_DEADZONE,
|
||||
0x00, //STICK_CONF_INVERT,
|
||||
0x28, //STICK_CONF_MIN,
|
||||
0xDF};//STICK_CONF_MAX,
|
||||
|
||||
const u8 HID_SWITCH_PRO_BT_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x06, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x06, //STICK_CONF_DEADZONE,
|
||||
0x01, //STICK_CONF_INVERT,
|
||||
0x16, //STICK_CONF_MIN,
|
||||
0xD7};//STICK_CONF_MAX,
|
||||
|
||||
const u8 HID_SWITCH_PRO_BT_STICK_R_X[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x08, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x04, //STICK_CONF_DEADZONE,
|
||||
0x00, //STICK_CONF_INVERT,
|
||||
0x29, //STICK_CONF_MIN,
|
||||
0xE2};//STICK_CONF_MAX,
|
||||
|
||||
const u8 HID_SWITCH_PRO_BT_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VALUE, //STICK_CONF_MAGIC_VERSION
|
||||
0x0A, //STICK_CONF_BYTE,
|
||||
0x80, //STICK_CONF_DEFAULT,
|
||||
0x08, //STICK_CONF_DEADZONE,
|
||||
0x01, //STICK_CONF_INVERT,
|
||||
0x22, //STICK_CONF_MIN,
|
||||
0xE4};//STICK_CONF_MAX,
|
211
wiiu/controller_patcher/utils/PadConst.hpp
Normal file
211
wiiu/controller_patcher/utils/PadConst.hpp
Normal file
@ -0,0 +1,211 @@
|
||||
/****************************************************************************
|
||||
* Copyright (C) 2016,2017 Maschell
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _PAD_CONST_H_
|
||||
#define _PAD_CONST_H_
|
||||
|
||||
#include <string>
|
||||
#include "../patcher/ControllerPatcherDefs.h"
|
||||
|
||||
extern const u8 DEF_R_STICK;
|
||||
extern const u8 DEF_L_STICK;
|
||||
|
||||
extern const u8 DEF_STICK_OFFSET_INVERT;
|
||||
extern const u8 DEF_STICK_OFFSET_DEADZONE;
|
||||
extern const u8 DEF_STICK_OFFSET_MINMAX;
|
||||
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! Device names
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
extern const char *HID_GC_STRING;
|
||||
extern const char *HID_KEYBOARD_STRING;
|
||||
extern const char *HID_MOUSE_STRING;
|
||||
extern const char *HID_DS3_STRING;
|
||||
extern const char *HID_DS4_STRING;
|
||||
extern const char *HID_NEW_DS4_STRING;
|
||||
extern const char *HID_XINPUT_STRING;
|
||||
extern const char *HID_SWITCH_PRO_STRING;
|
||||
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! GC_Adapter
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern const u8 HID_GC_BUTTON_A[];
|
||||
extern const u8 HID_GC_BUTTON_B[];
|
||||
extern const u8 HID_GC_BUTTON_X[];
|
||||
extern const u8 HID_GC_BUTTON_Y[];
|
||||
extern const u8 HID_GC_BUTTON_LEFT[];
|
||||
extern const u8 HID_GC_BUTTON_RIGHT[];
|
||||
extern const u8 HID_GC_BUTTON_DOWN[];
|
||||
extern const u8 HID_GC_BUTTON_UP[];
|
||||
|
||||
extern const u8 HID_GC_BUTTON_START[];
|
||||
extern const u8 HID_GC_BUTTON_Z[];
|
||||
|
||||
extern const u8 HID_GC_BUTTON_L[];
|
||||
extern const u8 HID_GC_BUTTON_R[];
|
||||
|
||||
extern const u8 HID_GC_BUTTON_DPAD_TYPE[];
|
||||
|
||||
extern const u8 HID_GC_STICK_L_X[STICK_CONF_ENUM_MAXVALUE];
|
||||
extern const u8 HID_GC_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE];
|
||||
extern const u8 HID_GC_STICK_R_X[STICK_CONF_ENUM_MAXVALUE];
|
||||
extern const u8 HID_GC_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE];
|
||||
|
||||
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! DS3
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern const u8 HID_DS3_BUTTON_CROSS[];
|
||||
extern const u8 HID_DS3_BUTTON_CIRCLE[];
|
||||
extern const u8 HID_DS3_BUTTON_SQUARE [];
|
||||
extern const u8 HID_DS3_BUTTON_TRIANGLE[];
|
||||
|
||||
extern const u8 HID_DS3_BUTTON_L1[];
|
||||
extern const u8 HID_DS3_BUTTON_L2[];
|
||||
extern const u8 HID_DS3_BUTTON_R1[];
|
||||
extern const u8 HID_DS3_BUTTON_R2[];
|
||||
|
||||
extern const u8 HID_DS3_BUTTON_L3[];
|
||||
extern const u8 HID_DS3_BUTTON_R3[];
|
||||
extern const u8 HID_DS3_BUTTON_SELECT[];
|
||||
extern const u8 HID_DS3_BUTTON_START[];
|
||||
extern const u8 HID_DS3_BUTTON_LEFT[];
|
||||
extern const u8 HID_DS3_BUTTON_RIGHT[];
|
||||
extern const u8 HID_DS3_BUTTON_UP[];
|
||||
extern const u8 HID_DS3_BUTTON_DOWN[];
|
||||
|
||||
extern const u8 HID_DS3_BUTTON_GUIDE[];
|
||||
|
||||
extern const u8 HID_DS3_BUTTON_DPAD_TYPE[];
|
||||
|
||||
extern const u8 HID_DS3_STICK_L_X[STICK_CONF_ENUM_MAXVALUE];
|
||||
extern const u8 HID_DS3_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE];
|
||||
extern const u8 HID_DS3_STICK_R_X[STICK_CONF_ENUM_MAXVALUE];
|
||||
extern const u8 HID_DS3_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE];
|
||||
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! DS4
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern const u8 HID_DS4_BUTTON_CROSS[];
|
||||
extern const u8 HID_DS4_BUTTON_CIRCLE[];
|
||||
extern const u8 HID_DS4_BUTTON_SQUARE [];
|
||||
extern const u8 HID_DS4_BUTTON_TRIANGLE[];
|
||||
|
||||
extern const u8 HID_DS4_BUTTON_L1[];
|
||||
extern const u8 HID_DS4_BUTTON_L2[];
|
||||
extern const u8 HID_DS4_BUTTON_L3[];
|
||||
extern const u8 HID_DS4_BUTTON_R1[];
|
||||
extern const u8 HID_DS4_BUTTON_R2[];
|
||||
extern const u8 HID_DS4_BUTTON_R3[];
|
||||
|
||||
extern const u8 HID_DS4_BUTTON_SHARE[];
|
||||
extern const u8 HID_DS4_BUTTON_OPTIONS[];
|
||||
|
||||
extern const u8 HID_DS4_BUTTON_DPAD_TYPE[];
|
||||
extern const u8 HID_DS4_BUTTON_DPAD_N[];
|
||||
extern const u8 HID_DS4_BUTTON_DPAD_NE[];
|
||||
extern const u8 HID_DS4_BUTTON_DPAD_E[];
|
||||
extern const u8 HID_DS4_BUTTON_DPAD_SE[];
|
||||
extern const u8 HID_DS4_BUTTON_DPAD_S[];
|
||||
extern const u8 HID_DS4_BUTTON_DPAD_SW[];
|
||||
extern const u8 HID_DS4_BUTTON_DPAD_W[];
|
||||
extern const u8 HID_DS4_BUTTON_DPAD_NW[];
|
||||
extern const u8 HID_DS4_BUTTON_DPAD_NEUTRAL[];
|
||||
|
||||
extern const u8 HID_DS4_BUTTON_GUIDE[];
|
||||
extern const u8 HID_DS4_BUTTON_T_PAD_CLICK[];
|
||||
|
||||
extern const u8 HID_DS4_STICK_L_X[STICK_CONF_ENUM_MAXVALUE];
|
||||
extern const u8 HID_DS4_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE];
|
||||
extern const u8 HID_DS4_STICK_R_X[STICK_CONF_ENUM_MAXVALUE];
|
||||
extern const u8 HID_DS4_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE];
|
||||
|
||||
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! XInput
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern const u8 HID_XINPUT_BUTTON_A[];
|
||||
extern const u8 HID_XINPUT_BUTTON_B[];
|
||||
extern const u8 HID_XINPUT_BUTTON_X[];
|
||||
extern const u8 HID_XINPUT_BUTTON_Y[];
|
||||
|
||||
extern const u8 HID_XINPUT_BUTTON_LB[];
|
||||
extern const u8 HID_XINPUT_BUTTON_LT[];
|
||||
extern const u8 HID_XINPUT_BUTTON_L3[];
|
||||
|
||||
extern const u8 HID_XINPUT_BUTTON_RB[];
|
||||
extern const u8 HID_XINPUT_BUTTON_RT[];
|
||||
extern const u8 HID_XINPUT_BUTTON_R3[];
|
||||
|
||||
extern const u8 HID_XINPUT_BUTTON_START[];
|
||||
extern const u8 HID_XINPUT_BUTTON_BACK[];
|
||||
extern const u8 HID_XINPUT_BUTTON_GUIDE[];
|
||||
|
||||
extern const u8 HID_XINPUT_BUTTON_DPAD_TYPE[];
|
||||
extern const u8 HID_XINPUT_BUTTON_LEFT[];
|
||||
extern const u8 HID_XINPUT_BUTTON_RIGHT[];
|
||||
extern const u8 HID_XINPUT_BUTTON_DOWN[];
|
||||
extern const u8 HID_XINPUT_BUTTON_UP[];
|
||||
|
||||
extern const u8 HID_XINPUT_STICK_L_X[STICK_CONF_ENUM_MAXVALUE];
|
||||
extern const u8 HID_XINPUT_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE];
|
||||
extern const u8 HID_XINPUT_STICK_R_X[STICK_CONF_ENUM_MAXVALUE];
|
||||
extern const u8 HID_XINPUT_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE];
|
||||
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
//! Switch Pro Controller
|
||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_A[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_B[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_X[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_Y[];
|
||||
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_L[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_ZL[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_STICK_L[];
|
||||
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_R[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_ZR[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_STICK_R[];
|
||||
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_PLUS[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_MINUS[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_HOME[];
|
||||
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_TYPE[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_N[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_NE[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_E[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_SE[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_S[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_SW[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_W[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_NW[];
|
||||
extern const u8 HID_SWITCH_PRO_BT_BUTTON_DPAD_NEUTRAL[];
|
||||
|
||||
|
||||
extern const u8 HID_SWITCH_PRO_BT_STICK_L_X[STICK_CONF_ENUM_MAXVALUE];
|
||||
extern const u8 HID_SWITCH_PRO_BT_STICK_L_Y[STICK_CONF_ENUM_MAXVALUE];
|
||||
extern const u8 HID_SWITCH_PRO_BT_STICK_R_X[STICK_CONF_ENUM_MAXVALUE];
|
||||
extern const u8 HID_SWITCH_PRO_BT_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE];
|
||||
|
||||
#endif /* _PAD_CONST_H_ */
|
@ -164,6 +164,7 @@ void FSInit();
|
||||
void FSShutdown();
|
||||
|
||||
FSStatus FSAddClient(FSClient *client, uint32_t flags);
|
||||
FSStatus FSAddClientEx(FSClient *pClient, s32 unk_zero_param, uint32_t errHandling);
|
||||
FSStatus FSDelClient(FSClient *client, uint32_t flags);
|
||||
uint32_t FSGetClientNum();
|
||||
void FSInitCmdBlock(FSCmdBlock *block);
|
||||
|
@ -22,7 +22,7 @@ typedef struct _KPADData
|
||||
u8 device_type;
|
||||
u8 wpad_error;
|
||||
u8 pos_valid;
|
||||
u8 unused_4[1];
|
||||
u8 format;
|
||||
|
||||
union
|
||||
{
|
||||
@ -45,6 +45,19 @@ typedef struct _KPADData
|
||||
f32 rtrigger;
|
||||
} classic;
|
||||
|
||||
struct
|
||||
{
|
||||
u32 hold;
|
||||
u32 trigger;
|
||||
u32 release;
|
||||
f32 lstick_x;
|
||||
f32 lstick_y;
|
||||
f32 rstick_x;
|
||||
f32 rstick_y;
|
||||
s32 charging;
|
||||
s32 wired;
|
||||
} pro;
|
||||
|
||||
u32 unused_6[20];
|
||||
};
|
||||
u32 unused_7[16];
|
||||
@ -53,6 +66,7 @@ typedef struct _KPADData
|
||||
|
||||
void KPADInit (void);
|
||||
s32 KPADRead(s32 chan, void * data, u32 size);
|
||||
s32 KPADReadEx(s32 chan, KPADData * data, u32 size, s32 *error);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <wiiu/os/coroutine.h>
|
||||
#include <wiiu/os/debug.h>
|
||||
#include <wiiu/os/dynload.h>
|
||||
#include <wiiu/os/energy.h>
|
||||
#include <wiiu/os/event.h>
|
||||
#include <wiiu/os/exception.h>
|
||||
#include <wiiu/os/fastcondition.h>
|
||||
|
18
wiiu/include/wiiu/os/energy.h
Normal file
18
wiiu/include/wiiu/os/energy.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <wiiu/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
s32 IMEnableDim(void);
|
||||
s32 IMDisableDim(void);
|
||||
s32 IMIsDimEnabled(s32 * result);
|
||||
s32 IMEnableAPD(void);
|
||||
s32 IMDisableAPD(void);
|
||||
s32 IMIsAPDEnabled(s32 * result);
|
||||
s32 IMIsAPDEnabledBySysSettings(s32 * result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -15,6 +15,7 @@ typedef struct
|
||||
}OSSystemInfo;
|
||||
|
||||
OSSystemInfo *OSGetSystemInfo();
|
||||
s32 * __gh_errno_ptr(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
126
wiiu/include/wiiu/syshid.h
Normal file
126
wiiu/include/wiiu/syshid.h
Normal file
@ -0,0 +1,126 @@
|
||||
#pragma once
|
||||
#include <wiiu/types.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t handle;
|
||||
uint32_t physical_device_inst;
|
||||
uint16_t vid;
|
||||
uint16_t pid;
|
||||
uint8_t interface_index;
|
||||
uint8_t sub_class;
|
||||
uint8_t protocol;
|
||||
|
||||
uint16_t max_packet_size_rx;
|
||||
uint16_t max_packet_size_tx;
|
||||
|
||||
} HIDDevice;
|
||||
|
||||
typedef struct _HIDClient HIDClient;
|
||||
|
||||
#define HID_DEVICE_DETACH 0
|
||||
#define HID_DEVICE_ATTACH 1
|
||||
|
||||
typedef int32_t (*HIDAttachCallback)(HIDClient *p_hc,HIDDevice *p_hd,uint32_t attach);
|
||||
|
||||
struct _HIDClient
|
||||
{
|
||||
HIDClient *next;
|
||||
HIDAttachCallback attach_cb;
|
||||
};
|
||||
|
||||
typedef void (*HIDCallback)(uint32_t handle,int32_t error,uint8_t *p_buffer,uint32_t bytes_transferred,void *p_user);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
int32_t
|
||||
HIDSetup(void);
|
||||
|
||||
int32_t
|
||||
HIDTeardown(void);
|
||||
|
||||
int32_t
|
||||
HIDAddClient(HIDClient *p_client,
|
||||
HIDAttachCallback attach_callback);
|
||||
int32_t
|
||||
HIDDelClient(HIDClient *p_client);
|
||||
|
||||
int32_t
|
||||
HIDGetDescriptor(uint32_t handle,
|
||||
uint8_t descriptor_type,
|
||||
uint8_t descriptor_index,
|
||||
uint16_t language_id,
|
||||
uint8_t *p_buffer,
|
||||
uint32_t buffer_length,
|
||||
HIDCallback hc,
|
||||
void *p_user);
|
||||
|
||||
int32_t
|
||||
HIDSetDescriptor(uint32_t handle,
|
||||
uint8_t descriptor_type,
|
||||
uint8_t descriptor_index,
|
||||
uint16_t language_id,
|
||||
uint8_t *p_buffer,
|
||||
uint32_t buffer_length,
|
||||
HIDCallback hc,
|
||||
void *p_user);
|
||||
|
||||
int32_t
|
||||
HIDGetReport(uint32_t handle,
|
||||
uint8_t report_type,
|
||||
uint8_t report_id,
|
||||
uint8_t *p_buffer,
|
||||
uint32_t buffer_length,
|
||||
HIDCallback hc,
|
||||
void *p_user);
|
||||
|
||||
int32_t
|
||||
HIDSetReport(uint32_t handle,
|
||||
uint8_t report_type,
|
||||
uint8_t report_id,
|
||||
uint8_t *p_buffer,
|
||||
uint32_t buffer_length,
|
||||
HIDCallback hc,
|
||||
void *p_user);
|
||||
|
||||
int32_t
|
||||
HIDSetIdle(uint32_t handle,
|
||||
uint8_t interface_index,
|
||||
uint8_t duration,
|
||||
HIDCallback hc,
|
||||
void *p_user);
|
||||
|
||||
int32_t
|
||||
HIDSetProtocol(uint32_t handle,
|
||||
uint8_t int32_terface_index,
|
||||
uint8_t protocol,
|
||||
HIDCallback hc,
|
||||
void *p_user);
|
||||
|
||||
int32_t
|
||||
HIDGetProtocol(uint32_t handle,
|
||||
uint8_t interface_index,
|
||||
uint8_t * protocol,
|
||||
HIDCallback hc,
|
||||
void *p_user);
|
||||
|
||||
int32_t
|
||||
HIDRead(uint32_t handle,
|
||||
uint8_t *p_buffer,
|
||||
uint32_t buffer_length,
|
||||
HIDCallback hc,
|
||||
void *p_user);
|
||||
|
||||
int32_t
|
||||
HIDWrite(uint32_t handle,
|
||||
uint8_t *p_buffer,
|
||||
uint32_t buffer_length,
|
||||
HIDCallback hc,
|
||||
void *p_user);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -26,8 +26,22 @@ typedef enum VPADButtons
|
||||
VPAD_BUTTON_TV = 0x00010000,
|
||||
VPAD_BUTTON_STICK_R = 0x00020000,
|
||||
VPAD_BUTTON_STICK_L = 0x00040000,
|
||||
VPAD_STICK_R_EMULATION_LEFT = 0x04000000,
|
||||
VPAD_STICK_R_EMULATION_RIGHT = 0x02000000,
|
||||
VPAD_STICK_R_EMULATION_UP = 0x01000000,
|
||||
VPAD_STICK_R_EMULATION_DOWN = 0x00800000,
|
||||
VPAD_STICK_L_EMULATION_LEFT = 0x40000000,
|
||||
VPAD_STICK_L_EMULATION_RIGHT = 0x20000000,
|
||||
VPAD_STICK_L_EMULATION_UP = 0x10000000,
|
||||
VPAD_STICK_L_EMULATION_DOWN = 0x08000000,
|
||||
|
||||
|
||||
} VPADButtons;
|
||||
|
||||
#define VPAD_BUTTON_TOUCH 0x00080000
|
||||
#define VPAD_MASK_EMULATED_STICKS 0x7F800000
|
||||
#define VPAD_MASK_BUTTONS ~VPAD_MASK_EMULATED_STICKS
|
||||
|
||||
typedef enum VPADTouchPadValidity
|
||||
{
|
||||
//! Both X and Y touchpad positions are accurate
|
||||
|
@ -6,6 +6,16 @@ extern "C" {
|
||||
|
||||
#include <wiiu/types.h>
|
||||
|
||||
#define WPAD_EXT_CORE 0
|
||||
#define WPAD_EXT_NUNCHUK 1
|
||||
#define WPAD_EXT_CLASSIC 2
|
||||
#define WPAD_EXT_MPLUS 5
|
||||
#define WPAD_EXT_MPLUS_NUNCHUK 6
|
||||
#define WPAD_EXT_MPLUS_CLASSIC 7
|
||||
#define WPAD_EXT_PRO_CONTROLLER 31
|
||||
|
||||
#define WPAD_FMT_PRO_CONTROLLER 22
|
||||
|
||||
#define WPAD_BUTTON_LEFT 0x0001
|
||||
#define WPAD_BUTTON_RIGHT 0x0002
|
||||
#define WPAD_BUTTON_DOWN 0x0004
|
||||
@ -36,9 +46,51 @@ extern "C" {
|
||||
#define WPAD_CLASSIC_BUTTON_DOWN 0x4000
|
||||
#define WPAD_CLASSIC_BUTTON_RIGHT 0x8000
|
||||
|
||||
#define WPAD_PRO_BUTTON_STICK_R 0x10000
|
||||
#define WPAD_PRO_BUTTON_STICK_L 0x20000
|
||||
#define WPAD_PRO_BUTTON_UP 0x00000001
|
||||
#define WPAD_PRO_BUTTON_LEFT 0x00000002
|
||||
#define WPAD_PRO_TRIGGER_ZR 0x00000004
|
||||
#define WPAD_PRO_BUTTON_X 0x00000008
|
||||
#define WPAD_PRO_BUTTON_A 0x00000010
|
||||
#define WPAD_PRO_BUTTON_Y 0x00000020
|
||||
#define WPAD_PRO_BUTTON_B 0x00000040
|
||||
#define WPAD_PRO_TRIGGER_ZL 0x00000080
|
||||
#define WPAD_PRO_RESERVED 0x00000100
|
||||
#define WPAD_PRO_TRIGGER_R 0x00000200
|
||||
#define WPAD_PRO_BUTTON_PLUS 0x00000400
|
||||
#define WPAD_PRO_BUTTON_HOME 0x00000800
|
||||
#define WPAD_PRO_BUTTON_MINUS 0x00001000
|
||||
#define WPAD_PRO_TRIGGER_L 0x00002000
|
||||
#define WPAD_PRO_BUTTON_DOWN 0x00004000
|
||||
#define WPAD_PRO_BUTTON_RIGHT 0x00008000
|
||||
#define WPAD_PRO_BUTTON_STICK_R 0x00010000
|
||||
#define WPAD_PRO_BUTTON_STICK_L 0x00020000
|
||||
|
||||
#define WPAD_PRO_STICK_L_EMULATION_UP 0x00200000
|
||||
#define WPAD_PRO_STICK_L_EMULATION_DOWN 0x00100000
|
||||
#define WPAD_PRO_STICK_L_EMULATION_LEFT 0x00040000
|
||||
#define WPAD_PRO_STICK_L_EMULATION_RIGHT 0x00080000
|
||||
|
||||
#define WPAD_PRO_STICK_R_EMULATION_UP 0x02000000
|
||||
#define WPAD_PRO_STICK_R_EMULATION_DOWN 0x01000000
|
||||
#define WPAD_PRO_STICK_R_EMULATION_LEFT 0x00400000
|
||||
#define WPAD_PRO_STICK_R_EMULATION_RIGHT 0x00800000
|
||||
|
||||
typedef struct WPADReadData_ {
|
||||
u8 unknown[40];
|
||||
u8 dev;
|
||||
u8 err;
|
||||
u8 unknown1[2];
|
||||
u32 buttons;
|
||||
s16 l_stick_x;
|
||||
s16 l_stick_y;
|
||||
s16 r_stick_x;
|
||||
s16 r_stick_y;
|
||||
u8 unknown2[8];
|
||||
u8 fmt;
|
||||
}WPADReadData;
|
||||
|
||||
typedef void (* wpad_sampling_callback_t)(s32 chan);
|
||||
typedef void (* wpad_extension_callback_t)(s32 chan, s32 status);
|
||||
typedef void (* wpad_connect_callback_t)(s32 chan, s32 status);
|
||||
|
||||
s32 WPADProbe (s32 chan, u32 * pad_type);
|
||||
|
@ -17,8 +17,13 @@ IMPORT(OSInitSpinLock);
|
||||
IMPORT(OSUninterruptibleSpinLock_Acquire);
|
||||
IMPORT(OSUninterruptibleSpinLock_Release);
|
||||
IMPORT(OSSleepTicks);
|
||||
IMPORT(OSGetTitleID);
|
||||
IMPORT(OSIsThreadTerminated);
|
||||
IMPORT(OSSetThreadPriority);
|
||||
IMPORT(OSCreateThread);
|
||||
IMPORT(OSResumeThread);
|
||||
IMPORT(OSIsThreadSuspended);
|
||||
IMPORT(OSSuspendThread);
|
||||
IMPORT(OSJoinThread);
|
||||
IMPORT(OSYieldThread);
|
||||
IMPORT(OSGetSystemTime);
|
||||
@ -31,10 +36,13 @@ IMPORT(_Exit);
|
||||
IMPORT(__os_snprintf);
|
||||
IMPORT(DisassemblePPCRange);
|
||||
|
||||
IMPORT(DCInvalidateRange);
|
||||
IMPORT(DCFlushRange);
|
||||
IMPORT(DCStoreRange);
|
||||
IMPORT(DCStoreRangeNoSync);
|
||||
|
||||
IMPORT(__gh_errno_ptr);
|
||||
|
||||
IMPORT(MEMGetBaseHeapHandle);
|
||||
IMPORT(MEMCreateExpHeapEx);
|
||||
IMPORT(MEMDestroyExpHeap);
|
||||
@ -48,6 +56,7 @@ IMPORT(MEMGetAllocatableSizeForFrmHeapEx);
|
||||
IMPORT(FSInit);
|
||||
IMPORT(FSShutdown);
|
||||
IMPORT(FSAddClient);
|
||||
IMPORT(FSAddClientEx);
|
||||
IMPORT(FSDelClient);
|
||||
IMPORT(FSInitCmdBlock);
|
||||
IMPORT(FSChangeDir);
|
||||
@ -77,6 +86,13 @@ IMPORT(IOS_Close);
|
||||
IMPORT(IOS_Ioctl);
|
||||
IMPORT(IOS_IoctlAsync);
|
||||
|
||||
IMPORT(IMIsAPDEnabled);
|
||||
IMPORT(IMIsDimEnabled);
|
||||
IMPORT(IMEnableAPD);
|
||||
IMPORT(IMEnableDim);
|
||||
IMPORT(IMDisableAPD);
|
||||
IMPORT(IMDisableDim);
|
||||
|
||||
IMPORT_END();
|
||||
|
||||
/* nsysnet */
|
||||
@ -84,6 +100,11 @@ IMPORT_BEGIN(nsysnet);
|
||||
|
||||
IMPORT(socket_lib_init);
|
||||
IMPORT(socket);
|
||||
IMPORT(setsockopt);
|
||||
IMPORT(bind);
|
||||
IMPORT(listen);
|
||||
IMPORT(accept);
|
||||
IMPORT(recv);
|
||||
IMPORT(socketclose);
|
||||
IMPORT(connect);
|
||||
IMPORT(send);
|
||||
@ -191,6 +212,7 @@ IMPORT(WPADEnableURCC);
|
||||
IMPORT(WPADEnableWiiRemote);
|
||||
IMPORT(WPADRead);
|
||||
IMPORT(KPADRead);
|
||||
IMPORT(KPADReadEx);
|
||||
|
||||
IMPORT_END();
|
||||
|
||||
@ -201,3 +223,22 @@ IMPORT(KBDSetup);
|
||||
IMPORT(KBDTeardown);
|
||||
|
||||
IMPORT_END();
|
||||
|
||||
/* syshid */
|
||||
IMPORT_BEGIN(nsyshid);
|
||||
|
||||
IMPORT(HIDSetup);
|
||||
IMPORT(HIDTeardown);
|
||||
IMPORT(HIDAddClient);
|
||||
IMPORT(HIDDelClient);
|
||||
IMPORT(HIDGetDescriptor);
|
||||
IMPORT(HIDSetDescriptor);
|
||||
IMPORT(HIDGetReport);
|
||||
IMPORT(HIDSetReport);
|
||||
IMPORT(HIDSetIdle);
|
||||
IMPORT(HIDSetProtocol);
|
||||
IMPORT(HIDGetProtocol);
|
||||
IMPORT(HIDRead);
|
||||
IMPORT(HIDWrite);
|
||||
|
||||
IMPORT_END();
|
||||
|
Loading…
x
Reference in New Issue
Block a user