Updated the controller patcher engine for the new HID to VPAD update.

This commit is contained in:
Maschell 2017-03-30 17:53:36 +02:00
parent b1e2068829
commit 1c3935dd93
30 changed files with 4734 additions and 2182 deletions

View File

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (C) 2016 Maschell
* 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
@ -18,137 +18,37 @@
#include <stdlib.h>
#include <string.h>
#include "config_reader.h"
#include "config_parser.h"
#include "config_values.h"
#include "string_tools.hpp"
#include "ConfigReader.hpp"
#include "config/ConfigParser.hpp"
#include "config/ConfigValues.hpp"
#include "utils/CPStringTools.hpp"
int ConfigReader::numberValidFiles = 0;
ConfigReader *ConfigReader::instance = NULL;
ConfigReader::ConfigReader()
{
ConfigReader::ConfigReader(){
InitOSFunctionPointers();
InitFSFunctionPointers();
int status = 0;
if((status = InitSDCard()) == 0){
log_printf("SD Card mounted for controller config!\n");
std::vector<std::string> fileList;
if((fileList = ScanFolder()).size() > 0){
log_printf("Found %d config files\n",fileList.size());
processFileList(fileList);
}
if(HID_DEBUG) log_printf("ConfigReader::ConfigReader(): SD Card mounted for controller config!\n");
}else{
log_printf("SD mounting failed! %d\n",status);
log_printf("ConfigReader::ConfigReader() error: SD mounting failed! %d\n",status);
}
}
void ConfigReader::processFileList(std::vector<std::string> path){
for(std::vector<std::string>::iterator it = path.begin(); it != path.end(); ++it) {
log_printf("Reading %s\n",it->c_str());
std::string result = loadFileToString(*it);
ConfigParser parser(result);
parser.parseIni();
void ConfigReader::ReadAllConfigs(){
std::vector<std::string> fileList = ScanFolder();
if(fileList.size() > 0){
if(HID_DEBUG) log_printf("ConfigReader::ConfigReader(): Found %d config files\n",fileList.size());
processFileList(fileList);
}
}
std::string ConfigReader::loadFileToString(std::string path){
int handle = 0;
int status = 0;
std::string strBuffer;
FSStat stats;
if((status = FSGetStat(this->pClient,this->pCmd,path.c_str(),&stats,-1)) == FS_STATUS_OK){
char * file = (char *) malloc((sizeof(char)*stats.size)+1);
if(!file){
log_print("Failed to allocate space for reading the file\n");
return false;
}
file[stats.size] = '\0';
if((status = FSOpenFile(this->pClient,this->pCmd,path.c_str(),"r",&handle,-1)) == FS_STATUS_OK){
int total_read = 0;
int ret2 = 0;
while ((ret2 = FSReadFile(pClient, pCmd, file+total_read, 1, stats.size-total_read, handle, 0, FS_RET_ALL_ERROR)) > 0){
total_read += ret2;
}
}else{
log_printf("(FSOpenFile) Couldn't open file (%s), error: %d",path.c_str(),status);
free(file);
file=NULL;
return false;
}
FSCloseFile(this->pClient,this->pCmd,handle,-1);
strBuffer = std::string(file);
free(file);
file = NULL;
//! remove all windows crap signs
size_t position;
while(1)
{
position = strBuffer.find('\r');
if(position == std::string::npos)
break;
strBuffer.erase(position, 1);
}
while(1)
{
position = strBuffer.find(' ');
if(position == std::string::npos)
break;
strBuffer.erase(position, 1);
}
while(1)
{
position = strBuffer.find('\t');
if(position == std::string::npos)
break;
strBuffer.erase(position, 1);
}
}else{
log_printf("(GetStat) Couldn't open file (%s), error: %d",path.c_str(),status);
}
return strBuffer;
}
ConfigReader::~ConfigReader()
{
ConfigReader::~ConfigReader(){
if(HID_DEBUG) log_printf("~ConfigReader\n");
freeFSHandles();
if(HID_DEBUG) log_printf("~destroy the ConfigValues\n");
ConfigValues::destroyInstance();
}
std::vector<std::string> ConfigReader::ScanFolder()
{
std::string path = CONTROLLER_PATCHER_PATH;
int dirhandle = 0;
if(HID_DEBUG) log_printf("Opening %s\n",path.c_str());
std::vector<std::string> config_files;
if (this->pClient && this->pCmd){
int status = 0;
if((status = FSOpenDir(this->pClient,this->pCmd,path.c_str(),&dirhandle,-1)) == FS_STATUS_OK){
FSDirEntry dir_entry;
while (FSReadDir(this->pClient, this->pCmd, dirhandle, &dir_entry, FS_RET_ALL_ERROR) == FS_STATUS_OK){
std::string full_path = path + "/" + dir_entry.name;
if((dir_entry.stat.flag&FS_STAT_FLAG_IS_DIRECTORY) != FS_STAT_FLAG_IS_DIRECTORY){
if(EndsWith(std::string(dir_entry.name),".ini")){
config_files.push_back(full_path);
if(HID_DEBUG) log_printf("%s \n",full_path.c_str());
}
}
}
FSCloseDir(this->pClient,this->pCmd,dirhandle,-1);
}else{
log_printf("Failed to open %s!\n",path.c_str());
}
}
return config_files;
}
void ConfigReader::freeFSHandles(){
@ -163,6 +63,7 @@ void ConfigReader::freeFSHandles(){
}
}
// Mounting the sdcard without any external lib to be portable
int ConfigReader::InitSDCard(){
if(HID_DEBUG) log_printf("InitSDCard\n");
@ -193,13 +94,93 @@ int ConfigReader::InitSDCard(){
{
return 0;
}else{
log_printf("FSMount failed %d\n",status);
log_printf("ConfigReader::InitSDCard() error: FSMount failed %d\n",status);
return status;
}
}else{
log_printf("FSGetMountSource failed %d\n",status);
log_printf("ConfigReader::InitSDCard() error: FSGetMountSource failed %d\n",status);
return status;
}
}
return -1;
}
std::vector<std::string> ConfigReader::ScanFolder(){
std::string path = CONTROLLER_PATCHER_PATH;
int dirhandle = 0;
if(HID_DEBUG) log_printf("ConfigReader::ScanFolder(): Opening %s\n",path.c_str());
std::vector<std::string> config_files;
if (this->pClient && this->pCmd){
int status = 0;
if((status = FSOpenDir(this->pClient,this->pCmd,path.c_str(),&dirhandle,-1)) == FS_STATUS_OK){
FSDirEntry dir_entry;
while (FSReadDir(this->pClient, this->pCmd, dirhandle, &dir_entry, FS_RET_ALL_ERROR) == FS_STATUS_OK){
std::string full_path = path + "/" + dir_entry.name;
if((dir_entry.stat.flag&FS_STAT_FLAG_IS_DIRECTORY) != FS_STAT_FLAG_IS_DIRECTORY){
if(CPStringTools::EndsWith(std::string(dir_entry.name),".ini")){
config_files.push_back(full_path);
if(HID_DEBUG) log_printf("%s \n",full_path.c_str());
}
}
}
FSCloseDir(this->pClient,this->pCmd,dirhandle,-1);
}else{
log_printf("ConfigReader::ScanFolder(): Failed to open %s!\n",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) {
log_printf("Reading %s\n",it->c_str());
std::string result = loadFileToString(*it);
ConfigParser parser(result);
parser.parseIni();
}
}
std::string ConfigReader::loadFileToString(std::string path){
int handle = 0;
int status = 0;
std::string strBuffer;
FSStat stats;
if((status = FSGetStat(this->pClient,this->pCmd,path.c_str(),&stats,-1)) == FS_STATUS_OK){
char * file = (char *) malloc((sizeof(char)*stats.size)+1);
if(!file){
log_print("ConfigReader::loadFileToString error: Failed to allocate space for reading the file\n");
return "";
}
file[stats.size] = '\0';
if((status = FSOpenFile(this->pClient,this->pCmd,path.c_str(),"r",&handle,-1)) == FS_STATUS_OK){
int total_read = 0;
int ret2 = 0;
while ((ret2 = FSReadFile(pClient, pCmd, file+total_read, 1, stats.size-total_read, handle, 0, FS_RET_ALL_ERROR)) > 0){
total_read += ret2;
}
}else{
log_printf("ConfigReader::loadFileToString error: (FSOpenFile) Couldn't open file (%s), error: %d",path.c_str(),status);
free(file);
file=NULL;
return "";
}
FSCloseFile(this->pClient,this->pCmd,handle,-1);
strBuffer = std::string(file);
free(file);
file = NULL;
//! remove all windows crap signs
strBuffer = CPStringTools::removeCharFromString(strBuffer,'\r');
strBuffer = CPStringTools::removeCharFromString(strBuffer,' ');
strBuffer = CPStringTools::removeCharFromString(strBuffer,'\t');
}else{
log_printf("ConfigReader::loadFileToString error: (GetStat) Couldn't open file (%s), error: %d",path.c_str(),status);
}
return strBuffer;
}

82
ConfigReader.hpp Normal file
View File

@ -0,0 +1,82 @@
/****************************************************************************
* 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 <string>
#include <vector>
#include <map>
#include <stdio.h>
#include <gctypes.h>
#include "./ControllerPatcher.hpp"
#include "./utils/PadConst.hpp"
#include "./utils/CPRetainVars.hpp"
#include "dynamic_libs/fs_functions.h"
#include "utils/logger.h"
#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 int getNumberOfLoadedFiles(){
return ConfigReader::numberValidFiles;
}
static void increaseNumberOfLoadedFiles(){
ConfigReader::numberValidFiles++;
}
void ReadAllConfigs();
static int numberValidFiles;
//!Constructor
ConfigReader();
//!Destructor
~ConfigReader();
int 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

959
ControllerPatcher.cpp Normal file
View File

@ -0,0 +1,959 @@
/****************************************************************************
* 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 <malloc.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vector>
#include "ControllerPatcher.hpp"
// This stores the holded buttons for the gamepad after the button remapping.
static u32 buttonRemapping_lastButtonsHold = 0;
/* To set the controls of an Pro Controler, we first get the result for an Gamepad and convert them later. This way both can share the same functions.*/
// This arrays stores the last hold buttons of the Pro Controllers. One u32 for each channel of the controllers
static u32 last_button_hold[4] = {0,0,0,0};
// This arrays stores the VPADDATA that will be used to get the HID Data for the Pro Controllers. One for each channel.
static VPADData myVPADBuffer[4];
void ControllerPatcher::InitButtonMapping(){
if(HID_DEBUG) log_printf("init_button_remapping! called! \n");
if(!gButtonRemappingConfigDone){
if(HID_DEBUG) log_printf("init_button_remapping! Remapping is running! \n");
gButtonRemappingConfigDone = 1;
memset(gGamePadValues,0,sizeof(gGamePadValues)); // Init / Invalid everything
gGamePadValues[CONTRPS_VPAD_BUTTON_A] = VPAD_BUTTON_A;
gGamePadValues[CONTRPS_VPAD_BUTTON_B] = VPAD_BUTTON_B;
gGamePadValues[CONTRPS_VPAD_BUTTON_X] = VPAD_BUTTON_X;
gGamePadValues[CONTRPS_VPAD_BUTTON_Y] = VPAD_BUTTON_Y;
gGamePadValues[CONTRPS_VPAD_BUTTON_LEFT] = VPAD_BUTTON_LEFT;
gGamePadValues[CONTRPS_VPAD_BUTTON_RIGHT] = VPAD_BUTTON_RIGHT;
gGamePadValues[CONTRPS_VPAD_BUTTON_UP] = VPAD_BUTTON_UP;
gGamePadValues[CONTRPS_VPAD_BUTTON_DOWN] = VPAD_BUTTON_DOWN;
gGamePadValues[CONTRPS_VPAD_BUTTON_ZL] = VPAD_BUTTON_ZL;
gGamePadValues[CONTRPS_VPAD_BUTTON_ZR] = VPAD_BUTTON_ZR;
gGamePadValues[CONTRPS_VPAD_BUTTON_L] = VPAD_BUTTON_L;
gGamePadValues[CONTRPS_VPAD_BUTTON_R] = VPAD_BUTTON_R;
gGamePadValues[CONTRPS_VPAD_BUTTON_PLUS] = VPAD_BUTTON_PLUS;
gGamePadValues[CONTRPS_VPAD_BUTTON_MINUS] = VPAD_BUTTON_MINUS;
gGamePadValues[CONTRPS_VPAD_BUTTON_HOME] = VPAD_BUTTON_HOME;
gGamePadValues[CONTRPS_VPAD_BUTTON_SYNC] = VPAD_BUTTON_SYNC;
gGamePadValues[CONTRPS_VPAD_BUTTON_STICK_R] = VPAD_BUTTON_STICK_R;
gGamePadValues[CONTRPS_VPAD_BUTTON_STICK_L] = VPAD_BUTTON_STICK_L;
gGamePadValues[CONTRPS_VPAD_BUTTON_TV] = VPAD_BUTTON_TV;
gGamePadValues[CONTRPS_VPAD_STICK_R_EMULATION_LEFT] = VPAD_STICK_R_EMULATION_LEFT;
gGamePadValues[CONTRPS_VPAD_STICK_R_EMULATION_RIGHT] = VPAD_STICK_R_EMULATION_RIGHT;
gGamePadValues[CONTRPS_VPAD_STICK_R_EMULATION_UP] = VPAD_STICK_R_EMULATION_UP;
gGamePadValues[CONTRPS_VPAD_STICK_R_EMULATION_DOWN] = VPAD_STICK_R_EMULATION_DOWN;
gGamePadValues[CONTRPS_VPAD_STICK_L_EMULATION_LEFT] = VPAD_STICK_L_EMULATION_LEFT;
gGamePadValues[CONTRPS_VPAD_STICK_L_EMULATION_RIGHT] = VPAD_STICK_L_EMULATION_RIGHT;
gGamePadValues[CONTRPS_VPAD_STICK_L_EMULATION_UP] = VPAD_STICK_L_EMULATION_UP;
gGamePadValues[CONTRPS_VPAD_STICK_L_EMULATION_DOWN] = VPAD_STICK_L_EMULATION_DOWN;
}
}
void ControllerPatcher::ResetConfig(){
memset(&gControllerMapping,0,sizeof(ControllerMapping));
disableControllerMapping();
memset(config_controller,CONTROLLER_PATCHER_INVALIDVALUE,sizeof(config_controller)); // Init / Invalid everything
memset(config_controller_hidmask,0,sizeof(config_controller_hidmask)); // Init / Invalid everything
memset(gNetworkController,0,sizeof(gNetworkController)); // Init / Invalid everything
memset(gHID_Devices,0,sizeof(gHID_Devices)); // Init / Invalid everything
gHID_Mouse_Mode = HID_MOUSE_MODE_AIM;
gHID_LIST_GC = 0;
gHID_LIST_DS3 = 0;
gHID_LIST_KEYBOARD = 0;
gHID_LIST_MOUSE = 0;
gGamePadSlot = 0;
gHID_SLOT_GC = 0;
gHID_SLOT_KEYBOARD = 0;
gMouseSlot = 0;
HIDSlotData slotdata;
gHIDRegisteredDevices = 0;
ControllerPatcherUtils::getNextSlotData(&slotdata);
gGamePadSlot = slotdata.deviceslot;
u32 gGamePadHid = slotdata.hidmask;
if(HID_DEBUG) log_printf("Gamepad HID-Mask %s deviceslot: %d\n",CPStringTools::byte_to_binary(gGamePadHid),gGamePadSlot);
ControllerPatcherUtils::getNextSlotData(&slotdata);
gMouseSlot = slotdata.deviceslot;
gHID_LIST_MOUSE = slotdata.hidmask;
if(HID_DEBUG) log_printf("Mouse HID-Mask %s deviceslot: %d\n",CPStringTools::byte_to_binary(gHID_LIST_MOUSE),gMouseSlot);
ControllerPatcherUtils::getNextSlotData(&slotdata);
u32 keyboard_slot = slotdata.deviceslot;
u32 keyboard_hid = slotdata.hidmask;
gHID_LIST_KEYBOARD = keyboard_hid;
gHID_SLOT_KEYBOARD = keyboard_slot;
if(HID_DEBUG) log_printf("Keyboard HID-Mask %s deviceslot: %d\n",CPStringTools::byte_to_binary(gHID_LIST_KEYBOARD),gHID_SLOT_KEYBOARD);
ControllerPatcherUtils::getNextSlotData(&slotdata);
u32 gc_slot = slotdata.deviceslot;
u32 gc_hid = slotdata.hidmask;
gHID_LIST_GC = gc_hid;
gHID_SLOT_GC = gc_slot;
if(HID_DEBUG) log_printf("GC-Adapter HID-Mask %s deviceslot: %d\n",CPStringTools::byte_to_binary(gHID_LIST_GC),gHID_SLOT_GC);
ControllerPatcherUtils::getNextSlotData(&slotdata);
u32 ds3_slot = slotdata.deviceslot;
u32 ds3_hid = slotdata.hidmask;
gHID_LIST_DS3 = ds3_hid;
if(HID_DEBUG) log_printf("DS3 HID-Mask %s deviceslot: %d\n",CPStringTools::byte_to_binary(gHID_LIST_DS3),ds3_slot);
ControllerPatcherUtils::getNextSlotData(&slotdata);
u32 ds4_slot = slotdata.deviceslot;
u32 ds4_hid = slotdata.hidmask;
if(HID_DEBUG) log_printf("DS4 HID-Mask %s deviceslot: %d\n",CPStringTools::byte_to_binary(ds4_hid),ds4_slot);
ControllerPatcherUtils::getNextSlotData(&slotdata);
u32 xinput_slot = slotdata.deviceslot;
u32 xinput_hid = slotdata.hidmask;
if(HID_DEBUG) log_printf("XInput HID-Mask %s deviceslot: %d\n",CPStringTools::byte_to_binary(xinput_hid),xinput_slot);
config_controller_hidmask[gc_slot] = gHID_LIST_GC;
config_controller_hidmask[ds3_slot] = gHID_LIST_DS3;
config_controller_hidmask[keyboard_slot] = gHID_LIST_KEYBOARD;
config_controller_hidmask[gMouseSlot] = gHID_LIST_MOUSE;
config_controller_hidmask[ds4_slot] = ds4_hid;
config_controller_hidmask[xinput_slot] = xinput_hid;
/* We need to give the GamePad, Mouse and Keyboard a unique VID/PID to find the right slots.*/
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! GamePad
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gGamePadSlot][CONTRPS_VID], 0xAF,0xFE);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gGamePadSlot][CONTRPS_PID], 0xAA,0xAA);
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! Mouse
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gMouseSlot][CONTRPS_VID], (HID_MOUSE_VID>>8)&0xFF, HID_MOUSE_VID&0xFF);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gMouseSlot][CONTRPS_PID], (HID_MOUSE_PID>>8)&0xFF, HID_MOUSE_PID&0xFF);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gMouseSlot][CONTRPS_VPAD_BUTTON_LEFT], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_ZR);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gMouseSlot][CONTRPS_VPAD_BUTTON_RIGHT], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_R);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gMouseSlot][CONTRPS_PAD_COUNT], CONTROLLER_PATCHER_VALUE_SET, HID_MOUSE_PAD_COUNT);
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! Keyboard
//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VID], (HID_KEYBOARD_VID>>8)&0xFF, HID_KEYBOARD_VID&0xFF);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_PID], (HID_KEYBOARD_PID>>8)&0xFF, HID_KEYBOARD_PID&0xFF);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_A], 0x00, HID_KEYBOARD_BUTTON_E);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_B], 0x00, HID_KEYBOARD_BUTTON_Q);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_X], 0x00, HID_KEYBOARD_BUTTON_SPACEBAR);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_Y], 0x00, HID_KEYBOARD_BUTTON_R);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_DPAD_MODE], CONTROLLER_PATCHER_VALUE_SET,CONTRPDM_Normal);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_LEFT], 0x00, HID_KEYBOARD_BUTTON_LEFT);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_RIGHT], 0x00, HID_KEYBOARD_BUTTON_RIGHT);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_DOWN], 0x00, HID_KEYBOARD_BUTTON_DOWN);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_UP], 0x00, HID_KEYBOARD_BUTTON_UP);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_PLUS], 0x00, HID_KEYBOARD_BUTTON_RETURN);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_MINUS], 0x00, HID_KEYBOARD_KEYPAD_BUTTON_MINUS);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_L], 0x00, HID_KEYBOARD_BUTTON_V);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_R], 0x00, HID_KEYBOARD_BUTTON_B);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_ZL], 0x00, HID_KEYBOARD_BUTTON_SHIFT);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_ZR], 0x00, HID_KEYBOARD_BUTTON_N);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_STICK_L], 0x00, HID_KEYBOARD_BUTTON_F);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_STICK_R], 0x00, HID_KEYBOARD_BUTTON_TAB);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_L_STICK_UP], 0x00, HID_KEYBOARD_BUTTON_W);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_L_STICK_DOWN], 0x00, HID_KEYBOARD_BUTTON_S);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_L_STICK_LEFT], 0x00, HID_KEYBOARD_BUTTON_A);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_L_STICK_RIGHT], 0x00, HID_KEYBOARD_BUTTON_D);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_R_STICK_UP], 0x00, HID_KEYBOARD_KEYPAD_BUTTON_8);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_R_STICK_DOWN], 0x00, HID_KEYBOARD_KEYPAD_BUTTON_2);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_R_STICK_LEFT], 0x00, HID_KEYBOARD_KEYPAD_BUTTON_4);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_VPAD_BUTTON_R_STICK_RIGHT], 0x00, HID_KEYBOARD_KEYPAD_BUTTON_6);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_KEYBOARD][CONTRPS_PAD_COUNT], CONTROLLER_PATCHER_VALUE_SET,HID_KEYBOARD_PAD_COUNT);
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! GC-Adapter
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VID], (HID_GC_VID>>8)&0xFF, HID_GC_VID&0xFF);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_PID], (HID_GC_PID>>8)&0xFF, HID_GC_PID&0xFF);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_A], HID_GC_BUTTON_A[0], HID_GC_BUTTON_A[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_B], HID_GC_BUTTON_B[0], HID_GC_BUTTON_B[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_X], HID_GC_BUTTON_X[0], HID_GC_BUTTON_X[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_Y], HID_GC_BUTTON_Y[0], HID_GC_BUTTON_Y[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DPAD_MODE], CONTROLLER_PATCHER_VALUE_SET, HID_GC_BUTTON_DPAD_TYPE[CONTRDPAD_MODE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DPAD_MASK], CONTROLLER_PATCHER_VALUE_SET, HID_GC_BUTTON_DPAD_TYPE[CONTRDPAD_MASK]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_LEFT], HID_GC_BUTTON_LEFT[0], HID_GC_BUTTON_LEFT[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_RIGHT], HID_GC_BUTTON_RIGHT[0], HID_GC_BUTTON_RIGHT[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_DOWN], HID_GC_BUTTON_DOWN[0], HID_GC_BUTTON_DOWN[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_UP], HID_GC_BUTTON_UP[0], HID_GC_BUTTON_UP[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_MINUS], HID_GC_BUTTON_START[0], HID_GC_BUTTON_START[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L], HID_GC_BUTTON_L[0], HID_GC_BUTTON_L[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R], HID_GC_BUTTON_R[0], HID_GC_BUTTON_R[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_PLUS], HID_GC_BUTTON_START[0], HID_GC_BUTTON_START[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_ZL], HID_GC_BUTTON_L[0], HID_GC_BUTTON_L[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_ZR], HID_GC_BUTTON_R[0], HID_GC_BUTTON_R[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_STICK_L], HID_GC_BUTTON_A[0], HID_GC_BUTTON_A[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_STICK_R], HID_GC_BUTTON_B[0], HID_GC_BUTTON_B[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE], CONTROLLER_PATCHER_VALUE_SET, CONTROLLER_PATCHER_GC_DOUBLE_USE);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR], HID_GC_BUTTON_Z[0], HID_GC_BUTTON_Z[1]);
//Buttons that will be ignored when the CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR is pressed
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_1_PRESSED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_MINUS);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_2_PRESSED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_L);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_3_PRESSED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_R);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_4_PRESSED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_STICK_L);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_5_PRESSED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_STICK_R);
//Buttons that will be ignored when the CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR is released
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_1_RELEASED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_PLUS);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_2_RELEASED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_ZL);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_3_RELEASED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_ZR);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_4_RELEASED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_A);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_DOUBLE_USE_BUTTON_5_RELEASED], CONTROLLER_PATCHER_VALUE_SET, CONTRPS_VPAD_BUTTON_B);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_PAD_COUNT], CONTROLLER_PATCHER_VALUE_SET, HID_GC_PAD_COUNT);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L_STICK_X], HID_GC_STICK_L_X[STICK_CONF_BYTE],HID_GC_STICK_L_X[STICK_CONF_DEFAULT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_GC_STICK_L_X[STICK_CONF_DEADZONE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX], HID_GC_STICK_L_X[STICK_CONF_MIN], HID_GC_STICK_L_X[STICK_CONF_MAX]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_GC_STICK_L_X[STICK_CONF_INVERT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L_STICK_Y], HID_GC_STICK_L_Y[STICK_CONF_BYTE],HID_GC_STICK_L_Y[STICK_CONF_DEFAULT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_GC_STICK_L_Y[STICK_CONF_DEADZONE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX], HID_GC_STICK_L_Y[STICK_CONF_MIN], HID_GC_STICK_L_Y[STICK_CONF_MAX]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_GC_STICK_L_Y[STICK_CONF_INVERT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R_STICK_X], HID_GC_STICK_R_X[STICK_CONF_BYTE],HID_GC_STICK_R_X[STICK_CONF_DEFAULT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_GC_STICK_R_X[STICK_CONF_DEADZONE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX], HID_GC_STICK_R_X[STICK_CONF_MIN], HID_GC_STICK_R_X[STICK_CONF_MAX]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_GC_STICK_R_X[STICK_CONF_INVERT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R_STICK_Y], HID_GC_STICK_R_Y[STICK_CONF_BYTE],HID_GC_STICK_R_Y[STICK_CONF_DEFAULT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_GC_STICK_R_Y[STICK_CONF_DEADZONE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX], HID_GC_STICK_R_Y[STICK_CONF_MIN], HID_GC_STICK_R_Y[STICK_CONF_MAX]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[gHID_SLOT_GC][CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_GC_STICK_R_Y[STICK_CONF_INVERT]);
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! DS3
//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VID], (HID_DS3_VID>>8)&0xFF, HID_DS3_VID&0xFF);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_PID], (HID_DS3_PID>>8)&0xFF, HID_DS3_PID&0xFF);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_BUF_SIZE], CONTROLLER_PATCHER_VALUE_SET, 128);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_A], HID_DS3_BUTTON_CIRCLE[0], HID_DS3_BUTTON_CIRCLE[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_B], HID_DS3_BUTTON_CROSS[0], HID_DS3_BUTTON_CROSS[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_X], HID_DS3_BUTTON_TRIANGLE[0], HID_DS3_BUTTON_TRIANGLE[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_Y], HID_DS3_BUTTON_SQUARE[0], HID_DS3_BUTTON_SQUARE[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_DPAD_MODE], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_BUTTON_DPAD_TYPE[CONTRDPAD_MODE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_DPAD_MASK], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_BUTTON_DPAD_TYPE[CONTRDPAD_MASK]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_LEFT], HID_DS3_BUTTON_LEFT[0], HID_DS3_BUTTON_LEFT[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_RIGHT], HID_DS3_BUTTON_RIGHT[0], HID_DS3_BUTTON_RIGHT[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_DOWN], HID_DS3_BUTTON_DOWN[0], HID_DS3_BUTTON_DOWN[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_UP], HID_DS3_BUTTON_UP[0], HID_DS3_BUTTON_UP[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_PLUS], HID_DS3_BUTTON_START[0], HID_DS3_BUTTON_START[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_MINUS], HID_DS3_BUTTON_SELECT[0], HID_DS3_BUTTON_SELECT[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L], HID_DS3_BUTTON_L1[0], HID_DS3_BUTTON_L1[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R], HID_DS3_BUTTON_R1[0], HID_DS3_BUTTON_R1[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_ZL], HID_DS3_BUTTON_L2[0], HID_DS3_BUTTON_L2[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_ZR], HID_DS3_BUTTON_R2[0], HID_DS3_BUTTON_R2[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_STICK_L], HID_DS3_BUTTON_L3[0], HID_DS3_BUTTON_L3[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_STICK_R], HID_DS3_BUTTON_R3[0], HID_DS3_BUTTON_R3[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_HOME], HID_DS3_BUTTON_GUIDE[0], HID_DS3_BUTTON_GUIDE[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_PAD_COUNT], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_PAD_COUNT);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L_STICK_X], HID_DS3_STICK_L_X[STICK_CONF_BYTE], HID_DS3_STICK_L_X[STICK_CONF_DEFAULT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_STICK_L_X[STICK_CONF_DEADZONE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX], HID_DS3_STICK_L_X[STICK_CONF_MIN], HID_DS3_STICK_L_X[STICK_CONF_MAX]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_STICK_L_X[STICK_CONF_INVERT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y], HID_DS3_STICK_L_Y[STICK_CONF_BYTE], HID_DS3_STICK_L_Y[STICK_CONF_DEFAULT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_STICK_L_Y[STICK_CONF_DEADZONE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX], HID_DS3_STICK_L_Y[STICK_CONF_MIN], HID_DS3_STICK_L_Y[STICK_CONF_MAX]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_STICK_L_Y[STICK_CONF_INVERT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R_STICK_X], HID_DS3_STICK_R_X[STICK_CONF_BYTE], HID_DS3_STICK_R_X[STICK_CONF_DEFAULT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_STICK_R_X[STICK_CONF_DEADZONE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX], HID_DS3_STICK_R_X[STICK_CONF_MIN], HID_DS3_STICK_R_X[STICK_CONF_MAX]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_STICK_R_X[STICK_CONF_INVERT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y], HID_DS3_STICK_R_Y[STICK_CONF_BYTE], HID_DS3_STICK_R_Y[STICK_CONF_DEFAULT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_STICK_R_Y[STICK_CONF_DEADZONE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX], HID_DS3_STICK_R_Y[STICK_CONF_MIN], HID_DS3_STICK_R_Y[STICK_CONF_MAX]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds3_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_DS3_STICK_R_Y[STICK_CONF_INVERT]);
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! DS4
//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VID], (HID_DS4_VID>>8)&0xFF, HID_DS4_VID&0xFF);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_PID], (HID_DS4_PID>>8)&0xFF, HID_DS4_PID&0xFF);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_BUF_SIZE], CONTROLLER_PATCHER_VALUE_SET, 128);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_A], HID_DS4_BUTTON_CIRCLE[0], HID_DS4_BUTTON_CIRCLE[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_B], HID_DS4_BUTTON_CROSS[0], HID_DS4_BUTTON_CROSS[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_X], HID_DS4_BUTTON_TRIANGLE[0], HID_DS4_BUTTON_TRIANGLE[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_Y], HID_DS4_BUTTON_SQUARE[0], HID_DS4_BUTTON_SQUARE[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_DPAD_MODE], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_BUTTON_DPAD_TYPE[CONTRDPAD_MODE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_DPAD_MASK], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_BUTTON_DPAD_TYPE[CONTRDPAD_MASK]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_N], HID_DS4_BUTTON_DPAD_N[0], HID_DS4_BUTTON_DPAD_N[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_NE], HID_DS4_BUTTON_DPAD_NE[0], HID_DS4_BUTTON_DPAD_NE[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_E], HID_DS4_BUTTON_DPAD_E[0], HID_DS4_BUTTON_DPAD_E[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_SE], HID_DS4_BUTTON_DPAD_SE[0], HID_DS4_BUTTON_DPAD_SE[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_S], HID_DS4_BUTTON_DPAD_S[0], HID_DS4_BUTTON_DPAD_S[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_SW], HID_DS4_BUTTON_DPAD_SW[0], HID_DS4_BUTTON_DPAD_SW[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_W], HID_DS4_BUTTON_DPAD_W[0], HID_DS4_BUTTON_DPAD_W[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_NW], HID_DS4_BUTTON_DPAD_NW[0], HID_DS4_BUTTON_DPAD_NW[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_DPAD_NEUTRAL], HID_DS4_BUTTON_DPAD_NEUTRAL[0], HID_DS4_BUTTON_DPAD_NEUTRAL[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_PLUS], HID_DS4_BUTTON_OPTIONS[0], HID_DS4_BUTTON_OPTIONS[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_MINUS], HID_DS4_BUTTON_SHARE[0], HID_DS4_BUTTON_SHARE[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L], HID_DS4_BUTTON_L1[0], HID_DS4_BUTTON_L1[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R], HID_DS4_BUTTON_R1[0], HID_DS4_BUTTON_R1[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_ZL], HID_DS4_BUTTON_L2[0], HID_DS4_BUTTON_L2[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_ZR], HID_DS4_BUTTON_R2[0], HID_DS4_BUTTON_R2[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_STICK_L], HID_DS4_BUTTON_L3[0], HID_DS4_BUTTON_L3[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_STICK_R], HID_DS4_BUTTON_R3[0], HID_DS4_BUTTON_R3[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_HOME], HID_DS4_BUTTON_GUIDE[0], HID_DS4_BUTTON_GUIDE[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_PAD_COUNT], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_PAD_COUNT);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L_STICK_X], HID_DS4_STICK_L_X[STICK_CONF_BYTE], HID_DS4_STICK_L_X[STICK_CONF_DEFAULT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_STICK_L_X[STICK_CONF_DEADZONE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX], HID_DS4_STICK_L_X[STICK_CONF_MIN], HID_DS4_STICK_L_X[STICK_CONF_MAX]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_STICK_L_X[STICK_CONF_INVERT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y], HID_DS4_STICK_L_Y[STICK_CONF_BYTE], HID_DS4_STICK_L_Y[STICK_CONF_DEFAULT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_STICK_L_Y[STICK_CONF_DEADZONE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX], HID_DS4_STICK_L_Y[STICK_CONF_MIN], HID_DS4_STICK_L_Y[STICK_CONF_MAX]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_STICK_L_Y[STICK_CONF_INVERT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R_STICK_X], HID_DS4_STICK_R_X[STICK_CONF_BYTE], HID_DS4_STICK_R_X[STICK_CONF_DEFAULT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_STICK_R_X[STICK_CONF_DEADZONE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX], HID_DS4_STICK_R_X[STICK_CONF_MIN], HID_DS4_STICK_R_X[STICK_CONF_MAX]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_STICK_R_X[STICK_CONF_INVERT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y], HID_DS4_STICK_R_Y[STICK_CONF_BYTE], HID_DS4_STICK_R_Y[STICK_CONF_DEFAULT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_STICK_R_Y[STICK_CONF_DEADZONE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX], HID_DS4_STICK_R_Y[STICK_CONF_MIN], HID_DS4_STICK_R_Y[STICK_CONF_MAX]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[ds4_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_DS4_STICK_R_Y[STICK_CONF_INVERT]);
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! XInput
//!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VID], (HID_XINPUT_VID>>8)&0xFF, HID_XINPUT_VID&0xFF);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_PID], (HID_XINPUT_PID>>8)&0xFF, HID_XINPUT_PID&0xFF);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_BUF_SIZE], CONTROLLER_PATCHER_VALUE_SET, 128);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_A], HID_XINPUT_BUTTON_B[0], HID_XINPUT_BUTTON_B[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_B], HID_XINPUT_BUTTON_A[0], HID_XINPUT_BUTTON_A[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_X], HID_XINPUT_BUTTON_Y[0], HID_XINPUT_BUTTON_Y[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_Y], HID_XINPUT_BUTTON_X[0], HID_XINPUT_BUTTON_X[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_DPAD_MODE], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_BUTTON_DPAD_TYPE[CONTRDPAD_MODE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_DPAD_MASK], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_BUTTON_DPAD_TYPE[CONTRDPAD_MASK]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_UP], HID_XINPUT_BUTTON_UP[0], HID_XINPUT_BUTTON_UP[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_DOWN], HID_XINPUT_BUTTON_DOWN[0], HID_XINPUT_BUTTON_DOWN[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_LEFT], HID_XINPUT_BUTTON_LEFT[0], HID_XINPUT_BUTTON_LEFT[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_RIGHT], HID_XINPUT_BUTTON_RIGHT[0], HID_XINPUT_BUTTON_RIGHT[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_PLUS], HID_XINPUT_BUTTON_START[0], HID_XINPUT_BUTTON_START[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_MINUS], HID_XINPUT_BUTTON_BACK[0], HID_XINPUT_BUTTON_BACK[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L], HID_XINPUT_BUTTON_LB[0], HID_XINPUT_BUTTON_LB[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R], HID_XINPUT_BUTTON_RB[0], HID_XINPUT_BUTTON_RB[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_ZL], HID_XINPUT_BUTTON_LT[0], HID_XINPUT_BUTTON_LT[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_ZR], HID_XINPUT_BUTTON_RT[0], HID_XINPUT_BUTTON_RT[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_STICK_L], HID_XINPUT_BUTTON_L3[0], HID_XINPUT_BUTTON_L3[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_STICK_R], HID_XINPUT_BUTTON_R3[0], HID_XINPUT_BUTTON_R3[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_HOME], HID_XINPUT_BUTTON_GUIDE[0], HID_XINPUT_BUTTON_GUIDE[1]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_PAD_COUNT], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_PAD_COUNT);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L_STICK_X], HID_XINPUT_STICK_L_X[STICK_CONF_BYTE], HID_XINPUT_STICK_L_X[STICK_CONF_DEFAULT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_STICK_L_X[STICK_CONF_DEADZONE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX], HID_XINPUT_STICK_L_X[STICK_CONF_MIN], HID_XINPUT_STICK_L_X[STICK_CONF_MAX]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_STICK_L_X[STICK_CONF_INVERT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y], HID_XINPUT_STICK_L_Y[STICK_CONF_BYTE], HID_XINPUT_STICK_L_Y[STICK_CONF_DEFAULT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_STICK_L_Y[STICK_CONF_DEADZONE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX], HID_XINPUT_STICK_L_Y[STICK_CONF_MIN], HID_XINPUT_STICK_L_Y[STICK_CONF_MAX]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_STICK_L_Y[STICK_CONF_INVERT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R_STICK_X], HID_XINPUT_STICK_R_X[STICK_CONF_BYTE], HID_XINPUT_STICK_R_X[STICK_CONF_DEFAULT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_STICK_R_X[STICK_CONF_DEADZONE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX], HID_XINPUT_STICK_R_X[STICK_CONF_MIN], HID_XINPUT_STICK_R_X[STICK_CONF_MAX]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_STICK_R_X[STICK_CONF_INVERT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y], HID_XINPUT_STICK_R_Y[STICK_CONF_BYTE], HID_XINPUT_STICK_R_Y[STICK_CONF_DEFAULT]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_STICK_R_Y[STICK_CONF_DEADZONE]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX], HID_XINPUT_STICK_R_Y[STICK_CONF_MIN], HID_XINPUT_STICK_R_Y[STICK_CONF_MAX]);
ControllerPatcherUtils::setConfigValue((u8*)&config_controller[xinput_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT], CONTROLLER_PATCHER_VALUE_SET, HID_XINPUT_STICK_R_Y[STICK_CONF_INVERT]);
}
bool ControllerPatcher::Init(){
InitOSFunctionPointers();
InitSocketFunctionPointers();
InitSysHIDFunctionPointers();
InitVPadFunctionPointers();
InitPadScoreFunctionPointers();
if(HID_DEBUG) log_printf("ControllerPatcher::Init() called! \n");
if(syshid_handle == 0){
log_printf("Failed to load the HID API \n");
return false;
}
if(gConfig_done == HID_INIT_NOT_DONE){
if(HID_DEBUG) log_printf("First time calling the Init\n");
gConfig_done = HID_INIT_DONE;
ControllerPatcher::ResetConfig();
log_print("Reading config files from SD Card\n");
ConfigReader* reader = ConfigReader::getInstance();
reader->ReadAllConfigs();
log_print("Done with reading config files from SD Card\n");
ConfigReader::destroyInstance();
gConfig_done = HID_SDCARD_READ;
}else{
if(HID_DEBUG) log_print("Config already done!\n");
}
log_print("Initializing the data for button remapping\n");
InitButtonMapping();
if(!gHIDAttached){
HIDAddClient(&gHIDClient, ControllerPatcherHID::myAttachDetachCallback);
}
return true;
}
void ControllerPatcher::startNetworkServer(){
UDPServer::getInstance();
TCPServer::getInstance();
}
void ControllerPatcher::stopNetworkServer(){
UDPServer::destroyInstance();
TCPServer::destroyInstance();
}
void ControllerPatcher::DeInit(){
if(HID_DEBUG) log_printf("ControllerPatcher::DeInit() called! \n");
if(gHIDAttached) HIDDelClient(&gHIDClient);
//Resetting the state of the last pressed data.
buttonRemapping_lastButtonsHold = 0;
memset(last_button_hold,0,sizeof(u32)*4);
memset(myVPADBuffer,0,sizeof(VPADData)*4);
memset(&gControllerMapping,0,sizeof(ControllerMapping));
memset(&gHIDClient,0,sizeof(HIDClient));
memset(gHID_Devices,0,sizeof(HID_DEVICE_DATA) * gHIDMaxDevices);
memset(gGamePadValues,0,sizeof(u32) * CONTRPS_MAX_VALUE);
memset(config_controller,0,sizeof(u8) * gHIDMaxDevices * CONTRPS_MAX_VALUE * 2);
memset(config_controller_hidmask,0,sizeof(u16) * gHIDMaxDevices);
memset(gNetworkController,0,sizeof(u16) * gHIDMaxDevices * HID_MAX_PADS_COUNT * 4);
gConfig_done = HID_INIT_NOT_DONE;
gButtonRemappingConfigDone = 0;
gHIDAttached = 0;
gHIDCurrentDevice = 0;
gHIDRegisteredDevices = 0;
gHID_Mouse_Mode = HID_MOUSE_MODE_TOUCH;
gHID_LIST_GC = 0;
gHID_LIST_DS3 = 0;
gHID_LIST_KEYBOARD = 0;
gHID_LIST_MOUSE = 0;
gGamePadSlot = 0;
gHID_SLOT_GC = 0;
gHID_SLOT_KEYBOARD = 0;
gMouseSlot = 0;
gOriginalDimState = 0;
gOriginalAPDState = 0;
gHIDNetworkClientID = 0;
destroyConfigHelper();
}
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::enableControllerMapping(){
gControllerMapping.gamepad.useAll = 0;
return CONTROLLER_PATCHER_ERROR_NONE;
}
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::disableControllerMapping(){
gControllerMapping.gamepad.useAll = 1;
return CONTROLLER_PATCHER_ERROR_NONE;
}
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::disableWiiUEnergySetting(){
int res;
if(IMIsDimEnabled(&res) == 0){
if(res == 1){
log_print("Dim was orignally enabled!\n");
gOriginalDimState = 1;
}
}
if(IMIsAPDEnabled(&res) == 0){
if(res == 1){
log_print("Auto power down was orignally enabled!\n");
gOriginalAPDState = 1;
}
}
IMDisableDim();
IMDisableAPD();
log_print("Disable Energy savers\n");
return CONTROLLER_PATCHER_ERROR_NONE;
}
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::restoreWiiUEnergySetting(){
//Check if we need to enable Auto Power down again on exiting
if(gOriginalAPDState == 1){
log_print("Auto shutdown was on before using HID to VPAD. Setting it to on again.\n");
IMEnableAPD();
}
if(gOriginalDimState == 1){
log_print("Burn-in reduction was on before using HID to VPAD. Setting it to on again.\n");
IMEnableDim();
}
return CONTROLLER_PATCHER_ERROR_NONE;
}
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::resetControllerMapping(UController_Type type){
ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type);
if(cm_map_pad == NULL){return CONTROLLER_PATCHER_ERROR_NULL_POINTER;}
memset(cm_map_pad,0,sizeof(ControllerMappingPAD));
return CONTROLLER_PATCHER_ERROR_NONE;
}
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::addControllerMapping(UController_Type type,ControllerMappingPADInfo config){
ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type);
int result = 0;
for(int i=0;i<HID_MAX_DEVICES_PER_SLOT;i++){
ControllerMappingPADInfo * info = &(cm_map_pad->pad_infos[i]);
if(info != NULL && !info->active){
info->active = 1;
info->pad = config.pad;
info->type = config.type;
info->vidpid.vid = config.vidpid.vid;
info->vidpid.pid = config.vidpid.pid;
result = 1;
break;
}
}
if(result == 0){
//No free slot.
return -1;
}
return CONTROLLER_PATCHER_ERROR_NONE;
}
int ControllerPatcher::getActiveMappingSlot(UController_Type type){
ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type);
if(cm_map_pad == NULL){return -1;}
int connected = -1;
for(int i =0;i<HID_MAX_DEVICES_PER_SLOT;i++){
if(cm_map_pad->pad_infos[i].active || cm_map_pad->pad_infos[i].type == CM_Type_RealController){
connected = i;
break;
}
}
return connected;
}
bool ControllerPatcher::isControllerConnectedAndActive(UController_Type type,int mapping_slot){
ControllerMappingPADInfo * padinfo = getControllerMappingInfo(type,mapping_slot);
if(!padinfo){
return false;
}
if(padinfo->active){
DeviceInfo device_info;
memset(&device_info,0,sizeof(DeviceInfo));
device_info.vidpid.vid = padinfo->vidpid.vid;
device_info.vidpid.pid = padinfo->vidpid.pid;
int res;
if((res = ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info)) < 0){
return false;
}
int hidmask = device_info.slotdata.hidmask;
int pad = padinfo->pad;
HID_Data * data_cur;
if((res = ControllerPatcherHID::getHIDData(hidmask,pad,&data_cur)) < 0) {
return false;
}
return true;
}
return false;
}
ControllerMappingPADInfo * ControllerPatcher::getControllerMappingInfo(UController_Type type,int mapping_slot){
ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type);
if(cm_map_pad == NULL){return NULL;}
if(mapping_slot < 0 || mapping_slot > HID_MAX_DEVICES_PER_SLOT-1){ return NULL;}
return &(cm_map_pad->pad_infos[mapping_slot]);
}
HID_Mouse_Data * ControllerPatcher::getMouseData(){
ControllerMappingPAD * CMPAD = ControllerPatcherUtils::getControllerMappingByType(UController_Type_Gamepad);
if(CMPAD == NULL){
return NULL;
}
HID_Mouse_Data * result = NULL;
for(int i;i<HID_MAX_DEVICES_PER_SLOT;i++){
ControllerMappingPADInfo * padinfo = &(CMPAD->pad_infos[i]);
if(!padinfo->active){
break;
}
if(padinfo->type == CM_Type_Mouse){
result = &(gHID_Devices[gMouseSlot].pad_data[padinfo->pad].data_union.mouse.cur_mouse_data);
}
}
return result;
}
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setRumble(UController_Type type,u32 status){
ControllerMappingPAD * cm_map_pad = ControllerPatcherUtils::getControllerMappingByType(type);
if(cm_map_pad == NULL){return -1;}
cm_map_pad->rumble = !!status; //to make sure it's only 0 or 1.
return CONTROLLER_PATCHER_ERROR_NONE;
}
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::gettingInputAllDevices(InputData * output,int array_size){
int hid = gHIDCurrentDevice;
HID_Data * data_cur;
VPADData pad_buffer;
VPADData * buffer = &pad_buffer;
int result = CONTROLLER_PATCHER_ERROR_NONE;
for(int i = 0;i< gHIDMaxDevices;i++){
if((hid & (1 << i)) != 0){
memset(buffer,0,sizeof(VPADData));
int newhid = (1 << i);
int deviceslot = ControllerPatcherUtils::getDeviceSlot(newhid);
if(deviceslot < 0) continue;
DeviceInfo * deviceinfo = &(output[result].device_info);
InputButtonData * buttondata = output[result].button_data;
deviceinfo->slotdata.deviceslot = deviceslot;
deviceinfo->slotdata.hidmask = newhid;
deviceinfo->vidpid.vid = config_controller[deviceslot][CONTRPS_VID][0] * 0x100 + config_controller[deviceslot][CONTRPS_VID][1];
deviceinfo->vidpid.pid = config_controller[deviceslot][CONTRPS_PID][0] * 0x100 + config_controller[deviceslot][CONTRPS_PID][1];
if(config_controller[deviceslot][CONTRPS_PAD_COUNT][0] != CONTROLLER_PATCHER_INVALIDVALUE){
deviceinfo->pad_count = config_controller[deviceslot][CONTRPS_PAD_COUNT][1];
}else{
deviceinfo->pad_count = HID_MAX_PADS_COUNT;
}
int buttons_hold = 0;
for(int pad = 0;pad<deviceinfo->pad_count;pad++){
buttons_hold = 0;
buttondata[pad].btn_h = 0;
buttondata[pad].btn_d = 0;
buttondata[pad].btn_r = 0;
int res;
if((res = ControllerPatcherHID::getHIDData(deviceinfo->slotdata.hidmask,pad,&data_cur)) < 0){
continue;
}
res = ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_A);
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_B);
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_X);
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_Y);
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_LEFT);
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_RIGHT);
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_DOWN);
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_UP);
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_MINUS);
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_L);
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_R);
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_PLUS);
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_ZL);
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_ZR);
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_HOME);
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_STICK_L);
ControllerPatcherUtils::getButtonPressed(data_cur,&buttons_hold,VPAD_BUTTON_STICK_R);
buttondata[pad].btn_h |= buttons_hold;
buttondata[pad].btn_d |= (buttons_hold & (~(data_cur->last_buttons)));
buttondata[pad].btn_r |= ((data_cur->last_buttons) & (~buttons_hold));
data_cur->last_buttons = buttons_hold;
}
result++;
if(result >= array_size){
break;
}
}
}
return result;
}
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setProControllerDataFromHID(void * data,int chan, int mode){
if(chan < 0 || chan > 3) return CONTROLLER_PATCHER_ERROR_INVALID_CHAN;
//if(gControllerMapping.proController[chan].enabled == 0) return CONTROLLER_PATCHER_ERROR_MAPPING_DISABLED;
VPADData * vpad_buffer = &myVPADBuffer[chan];
memset(vpad_buffer,0,sizeof(VPADData));
std::vector<HID_Data *> data_list;
for(int i = 0;i<HID_MAX_DEVICES_PER_SLOT;i++){
ControllerMappingPADInfo cm_map_pad_info = gControllerMapping.proController[chan].pad_infos[i];
if(!cm_map_pad_info.active){
continue;
}
DeviceInfo device_info;
memset(&device_info,0,sizeof(DeviceInfo));
device_info.vidpid.vid = cm_map_pad_info.vidpid.vid;
device_info.vidpid.pid = cm_map_pad_info.vidpid.pid;
int res;
if((res = ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info)) < 0){
log_printf("ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) = %d\n",res);
continue;
}
int hidmask = device_info.slotdata.hidmask;
int pad = cm_map_pad_info.pad;
HID_Data * data_cur;
if((res = ControllerPatcherHID::getHIDData(hidmask,pad,&data_cur)) < 0) {
//log_printf("ControllerPatcherHID::getHIDData(hidmask,pad,&data_cur)) = %d\n",res);
continue;
}
data_list.push_back(data_cur);
}
if(data_list.empty()){
return CONTROLLER_PATCHER_ERROR_FAILED_TO_GET_HIDDATA;
}
int res = 0;
if((res = ControllerPatcherHID::setVPADControllerData(vpad_buffer,data_list)) < 0) return res;
//make it configurable?
//ControllerPatcher::printVPADButtons(vpad_buffer); //Leads to random crashes on transitions.
//a bit hacky?
if(mode == PRO_CONTROLLER_MODE_KPADDATA){
KPADData * pro_buffer = (KPADData *) data;
if((res = ControllerPatcherUtils::translateToPro(vpad_buffer,pro_buffer,&last_button_hold[chan])) < 0 ) return res;
}else if(mode == PRO_CONTROLLER_MODE_WPADReadData){
WPADReadData * pro_buffer = (WPADReadData *) data;
if((res = ControllerPatcherUtils::translateToProWPADRead(vpad_buffer,pro_buffer)) < 0 ) return res;
}
for(std::vector<HID_Data *>::iterator it = data_list.begin(); it != data_list.end(); ++it) {
HID_Data * cur_ptr = *it;
cur_ptr->rumbleActive = !!gControllerMapping.proController[chan].rumble;
}
return CONTROLLER_PATCHER_ERROR_NONE;
}
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setControllerDataFromHID(VPADData * buffer){
//if(gControllerMapping.gamepad.enabled == 0) return CONTROLLER_PATCHER_ERROR_MAPPING_DISABLED;
int hidmask = 0;
int pad = 0;
ControllerMappingPAD cm_map_pad = gControllerMapping.gamepad;
std::vector<HID_Data *> data_list;
if (cm_map_pad.useAll == 1) {
data_list = ControllerPatcherHID::getHIDDataAll();
}else{
for(int i = 0;i<HID_MAX_DEVICES_PER_SLOT;i++){
ControllerMappingPADInfo cm_map_pad_info = cm_map_pad.pad_infos[i];
if(cm_map_pad_info.active == 1){
DeviceInfo device_info;
device_info.vidpid.vid = cm_map_pad_info.vidpid.vid;
device_info.vidpid.pid = cm_map_pad_info.vidpid.pid;
if(ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) < 0){
continue;
//return CONTROLLER_PATCHER_ERROR_UNKNOWN_VID_PID;
}
hidmask = device_info.slotdata.hidmask;
HID_Data * data;
pad = cm_map_pad_info.pad;
int res = ControllerPatcherHID::getHIDData(hidmask,pad,&data);
if(res < 0){
continue;
//return CONTROLLER_PATCHER_ERROR_FAILED_TO_GET_HIDDATA;
}
if(data != NULL) data_list.push_back(data);
}
}
}
if(data_list.empty()){
return CONTROLLER_PATCHER_ERROR_FAILED_TO_GET_HIDDATA;
}
ControllerPatcherHID::setVPADControllerData(buffer,data_list);
for(u32 i = 0; i < data_list.size();i++){
data_list[i]->rumbleActive = !!gControllerMapping.gamepad.rumble;
}
return CONTROLLER_PATCHER_ERROR_NONE;
}
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::printVPADButtons(VPADData * buffer){
/* BROKEN on transitions.*/
if(buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
if(buffer->btns_d != 0x00000000){
char output[250];
output[0] = 0; //null terminate it. just in case.
if((buffer->btns_d & VPAD_BUTTON_A) == VPAD_BUTTON_A) strcat(output,"A ");
if((buffer->btns_d & VPAD_BUTTON_B) == VPAD_BUTTON_B) strcat(output,"B ");
if((buffer->btns_d & VPAD_BUTTON_X) == VPAD_BUTTON_X) strcat(output,"X ");
if((buffer->btns_d & VPAD_BUTTON_Y) == VPAD_BUTTON_Y) strcat(output,"Y ");
if((buffer->btns_d & VPAD_BUTTON_L) == VPAD_BUTTON_L) strcat(output,"L ");
if((buffer->btns_d & VPAD_BUTTON_R) == VPAD_BUTTON_R) strcat(output,"R ");
if((buffer->btns_d & VPAD_BUTTON_ZR) == VPAD_BUTTON_ZR) strcat(output,"ZR ");
if((buffer->btns_d & VPAD_BUTTON_ZL) == VPAD_BUTTON_ZL) strcat(output,"ZL ");
if((buffer->btns_d & VPAD_BUTTON_LEFT) == VPAD_BUTTON_LEFT) strcat(output,"Left ");
if((buffer->btns_d & VPAD_BUTTON_RIGHT) == VPAD_BUTTON_RIGHT) strcat(output,"Right ");
if((buffer->btns_d & VPAD_BUTTON_UP) == VPAD_BUTTON_UP) strcat(output,"Up ");
if((buffer->btns_d & VPAD_BUTTON_DOWN) == VPAD_BUTTON_DOWN) strcat(output,"Down ");
if((buffer->btns_d & VPAD_BUTTON_PLUS) == VPAD_BUTTON_PLUS) strcat(output,"+ ");
if((buffer->btns_d & VPAD_BUTTON_MINUS) == VPAD_BUTTON_MINUS) strcat(output,"- ");
if((buffer->btns_d & VPAD_BUTTON_TV) == VPAD_BUTTON_TV) strcat(output,"TV ");
if((buffer->btns_d & VPAD_BUTTON_HOME) == VPAD_BUTTON_HOME) strcat(output,"HOME ");
if((buffer->btns_d & VPAD_BUTTON_STICK_L) == VPAD_BUTTON_STICK_L) strcat(output,"SL ");
if((buffer->btns_d & VPAD_BUTTON_STICK_R) == VPAD_BUTTON_STICK_R) strcat(output,"SR ");
if((buffer->btns_d & VPAD_STICK_R_EMULATION_LEFT) == VPAD_STICK_R_EMULATION_LEFT) strcat(output,"RE_Left ");
if((buffer->btns_d & VPAD_STICK_R_EMULATION_RIGHT) == VPAD_STICK_R_EMULATION_RIGHT) strcat(output,"RE_Right ");
if((buffer->btns_d & VPAD_STICK_R_EMULATION_UP) == VPAD_STICK_R_EMULATION_UP) strcat(output,"RE_Up ");
if((buffer->btns_d & VPAD_STICK_R_EMULATION_DOWN) == VPAD_STICK_R_EMULATION_DOWN) strcat(output,"RE_Down ");
if((buffer->btns_d & VPAD_STICK_L_EMULATION_LEFT) == VPAD_STICK_L_EMULATION_LEFT) strcat(output,"LE_Left ");
if((buffer->btns_d & VPAD_STICK_L_EMULATION_RIGHT) == VPAD_STICK_L_EMULATION_RIGHT) strcat(output,"LE_Right ");
if((buffer->btns_d & VPAD_STICK_L_EMULATION_UP) == VPAD_STICK_L_EMULATION_UP) strcat(output,"LE_Up ");
if((buffer->btns_d & VPAD_STICK_L_EMULATION_DOWN) == VPAD_STICK_L_EMULATION_DOWN) strcat(output,"LE_Down ");
log_printf("%spressed Sticks: LX %f LY %f RX %f RY %f\n",output,buffer->lstick.x,buffer->lstick.y,buffer->rstick.x,buffer->rstick.y);
}
return CONTROLLER_PATCHER_ERROR_NONE;
}
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::buttonRemapping(VPADData * buffer,int buffer_count){
if(!gButtonRemappingConfigDone) return CONTROLLER_PATCHER_ERROR_CONFIG_NOT_DONE;
if(buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
for(int i = 0;i < buffer_count;i++){
VPADData new_data;
memset(&new_data,0,sizeof(new_data));
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_A, CONTRPS_VPAD_BUTTON_A);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_B, CONTRPS_VPAD_BUTTON_B);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_X, CONTRPS_VPAD_BUTTON_X);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_Y, CONTRPS_VPAD_BUTTON_Y);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_LEFT, CONTRPS_VPAD_BUTTON_LEFT);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_RIGHT, CONTRPS_VPAD_BUTTON_RIGHT);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_UP, CONTRPS_VPAD_BUTTON_UP);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_DOWN, CONTRPS_VPAD_BUTTON_DOWN);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_ZL, CONTRPS_VPAD_BUTTON_ZL);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_ZR, CONTRPS_VPAD_BUTTON_ZR);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_L, CONTRPS_VPAD_BUTTON_L);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_R, CONTRPS_VPAD_BUTTON_R);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_PLUS, CONTRPS_VPAD_BUTTON_PLUS);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_MINUS, CONTRPS_VPAD_BUTTON_MINUS);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_HOME, CONTRPS_VPAD_BUTTON_HOME);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_SYNC, CONTRPS_VPAD_BUTTON_SYNC);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_STICK_R, CONTRPS_VPAD_BUTTON_STICK_R);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_STICK_L, CONTRPS_VPAD_BUTTON_STICK_L);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_BUTTON_TV, CONTRPS_VPAD_BUTTON_TV);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_STICK_R_EMULATION_LEFT, CONTRPS_VPAD_STICK_R_EMULATION_LEFT);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_STICK_R_EMULATION_RIGHT, CONTRPS_VPAD_STICK_R_EMULATION_RIGHT);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_STICK_R_EMULATION_UP, CONTRPS_VPAD_STICK_R_EMULATION_UP);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_STICK_R_EMULATION_DOWN, CONTRPS_VPAD_STICK_R_EMULATION_DOWN);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_STICK_L_EMULATION_LEFT, CONTRPS_VPAD_STICK_L_EMULATION_LEFT);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_STICK_L_EMULATION_RIGHT, CONTRPS_VPAD_STICK_L_EMULATION_RIGHT);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_STICK_L_EMULATION_UP, CONTRPS_VPAD_STICK_L_EMULATION_UP);
ControllerPatcherUtils::setButtonRemappingData(&buffer[i],&new_data,VPAD_STICK_L_EMULATION_DOWN, CONTRPS_VPAD_STICK_L_EMULATION_DOWN);
//Even when you remap any Stick Emulation to a button, we still want to keep the emulated stick data. Some games like New Super Mario Bros. only work with the emulated stick data.
ControllerPatcherUtils::setButtonData(&buffer[i],&new_data,VPAD_STICK_L_EMULATION_LEFT, VPAD_STICK_L_EMULATION_LEFT);
ControllerPatcherUtils::setButtonData(&buffer[i],&new_data,VPAD_STICK_L_EMULATION_RIGHT, VPAD_STICK_L_EMULATION_RIGHT);
ControllerPatcherUtils::setButtonData(&buffer[i],&new_data,VPAD_STICK_L_EMULATION_UP, VPAD_STICK_L_EMULATION_UP);
ControllerPatcherUtils::setButtonData(&buffer[i],&new_data,VPAD_STICK_L_EMULATION_DOWN, VPAD_STICK_L_EMULATION_DOWN);
ControllerPatcherUtils::setButtonData(&buffer[i],&new_data,VPAD_STICK_R_EMULATION_LEFT, VPAD_STICK_R_EMULATION_LEFT);
ControllerPatcherUtils::setButtonData(&buffer[i],&new_data,VPAD_STICK_R_EMULATION_RIGHT, VPAD_STICK_R_EMULATION_RIGHT);
ControllerPatcherUtils::setButtonData(&buffer[i],&new_data,VPAD_STICK_R_EMULATION_UP, VPAD_STICK_R_EMULATION_UP);
ControllerPatcherUtils::setButtonData(&buffer[i],&new_data,VPAD_STICK_R_EMULATION_DOWN, VPAD_STICK_R_EMULATION_DOWN);
buffer[i].btns_h = new_data.btns_h;
buffer[i].btns_d = new_data.btns_d;
buffer[i].btns_r = new_data.btns_r;
}
return CONTROLLER_PATCHER_ERROR_NONE;
}
std::string ControllerPatcher::getIdentifierByVIDPID(u16 vid,u16 pid){
return ConfigValues::getStringByVIDPID(vid,pid);
}
void ControllerPatcher::destroyConfigHelper(){
ConfigReader::destroyInstance();
ConfigValues::destroyInstance();
}

239
ControllerPatcher.hpp Normal file
View File

@ -0,0 +1,239 @@
/****************************************************************************
* 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 <gctypes.h>
#include "./patcher/ControllerPatcherHID.hpp"
#include "./patcher/ControllerPatcherDefs.h"
#include "./utils/PadConst.hpp"
#include "./ConfigReader.hpp"
#include "./config/ConfigValues.hpp"
#include "network/TCPServer.hpp"
#include "network/UDPServer.hpp"
#include "dynamic_libs/syshid_functions.h"
#include "dynamic_libs/socket_functions.h"
#include "dynamic_libs/padscore_functions.h"
#include "dynamic_libs/vpad_functions.h"
#include "dynamic_libs/padscore_functions.h"
#include "./utils/CPRetainVars.hpp"
#include "utils/logger.h"
#include "./utils/CPStringTools.hpp"
#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,int chan,int mode = PRO_CONTROLLER_MODE_KPADDATA);
/**
Sets the data in a given VPADData 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(VPADData * 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 int 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,int 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,int 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,int array_size);
/**
Remaps the buttons in the given \p VPADData 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(VPADData * buffer, int buffer_count);
/**
Prints the current pressed down buttons of the given \p VPADData 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(VPADData * buffer);
static std::string getIdentifierByVIDPID(u16 vid,u16 pid);
static void destroyConfigHelper();
};
#endif /* _CONTROLLER_PATCHER_H_ */

View File

@ -7,7 +7,7 @@ Detailed information about creating config files and adding support for more con
# Where can I find config files
Configfiles for all controllers are collection in [this repository](https://github.com/Maschell/controller_patch_configs)
#Dependencies for including it in other applications
# Dependencies for including it in other applications
This controller_patcher is build to be used in serveral projects. It don't uses some ultra fancy external libraries. </br>
To be able to use in other projects, you will need some external data though.</br>
- At first, you need a copy of the [dynamic_libs](https://github.com/Maschell/dynamic_libs) in your src/dynamic_libs folder.
@ -15,64 +15,7 @@ To be able to use in other projects, you will need some external data though.</b
# Example implementation
### How to "install" it
In order to add hid support to your application, you need add these lines add each start up.
```
#include "controller_patcher/controller_patcher.h"
#include "controller_patcher/config_reader.h"
#include "controller_patcher/cp_retain_vars.h"
int __entry_menu(int argc, char **argv){
[...]
init_config_controller(); //Inits the data
init_button_remapping(); // inits the data for the buttons remapping
if(gConfig_done == HID_INIT_DONE){ // Only read the SD content once (When we're in the Mii Maker and have the rights to do it)
gConfig_done = HID_SDCARD_READ;
ConfigReader::getInstance(); //doing the magic automatically
ConfigReader::destroyInstance(); //destroying the SD reader
}
[...]
}
```
When you return back to the homebrew launcher, simply add the following line:
```
deinit_config_controller();
```
Take a look at the [HID to VPAD](https://github.com/Maschell/hid_to_vpad) sources for an actual example.
### How to use it:
Once you set up everything correctly, you can use the "setControllerDataFromHID" method to fill a VPADData pointer. Example:
```
#include "controller_patcher/controller_patcher.h"
VPADData buffer;
setControllerDataFromHID(&buffer,HID_ALL_CONNECTED_DEVICES);
```
This example will add the input from ALL connected HID devices into the created VPADData.
To remap the gamepad buttons. Use something like this:
```
#include "controller_patcher/cp_retain_vars.h"
#include "controller_patcher/controller_patcher.h"
if(gButtonRemappingConfigDone && gConfig_done){
buttonRemapping(buffer);
}
```
The postion of the mouse cursor can be read from here:
```
#include "controller_patcher/cp_retain_vars.h"
X Value gHID_Mouse.pad_data[0].data[0].X (0-1280)
Y Value gHID_Mouse.pad_data[0].data[0].Y (0-720)
```
TODO!
# Credits:
- Maschell

View File

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (C) 2016 Maschell
* 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
@ -19,22 +19,21 @@
#include <stdlib.h>
#include <string.h>
#include "config_parser.h"
#include "config_reader.h"
#include "config_values.h"
#include "string_tools.hpp"
#include "../ConfigReader.hpp"
#include "../utils/CPStringTools.hpp"
#include "./ConfigParser.hpp"
#include "./ConfigValues.hpp"
ConfigParser::ConfigParser(std::string configData)
{
ConfigParser::ConfigParser(std::string configData){
this->content = configData;
this->contentLines = MyStringSplit(content, "\n");
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 = MyStringSplit(contentLines[i], "//");
std::vector<std::string> comments = CPStringTools::StringSplit(contentLines[i], "//");
if(!comments.empty()){
contentLines[i] = comments[0];
}
@ -53,8 +52,7 @@ ConfigParser::ConfigParser(std::string configData)
Init();
}
ConfigParser::~ConfigParser()
{
ConfigParser::~ConfigParser(){
}
@ -75,30 +73,39 @@ void ConfigParser::setSlot(u16 newSlot){
}
bool ConfigParser::Init(){
if(contentLines.size() == 0){
log_printf("ConfigParser::Init(): Files seems to be empty. Make sure to have a proper header\n");
return false;
}
const char * line = contentLines[0].c_str();
int len = strlen(line);
std::string identify;
if(line[0] == '[' && line[len-1] == ']'){
identify = contentLines[0].substr(1,len-2);
}else{
log_printf("Not a proper config file!\n");
log_printf("ConfigParser::Init(): Not a proper config file!\n");
return false;
}
if(identify.compare("GAMEPAD") == 0){
log_printf("Its a gamepad config file!\n");
if(HID_DEBUG) log_printf("Its a gamepad config file!\n");
setSlot(gGamePadSlot);
setType(PARSE_GAMEPAD);
}else if(identify.compare("MOUSE") == 0){
log_printf("Its a mouse config file!\n");
if(HID_DEBUG) log_printf("Its a mouse config file!\n");
setSlot(gMouseSlot);
setType(PARSE_MOUSE);
this->vid = HID_MOUSE_VID;
this->pid = HID_MOUSE_PID;
}else if(identify.compare("KEYBOARD") == 0){
log_printf("Its a keyboard config file!\n");
if(HID_DEBUG) log_printf("Its a keyboard config file!\n");
setSlot(gHID_SLOT_KEYBOARD);
setType(PARSE_KEYBOARD);
this->vid = HID_KEYBOARD_VID;
this->pid = HID_KEYBOARD_PID;
}else{
log_printf("Its a controller config file!\n");
if(HID_DEBUG) log_printf("Its a controller config file!\n");
setSlot(getSlotController(identify));
setType(PARSE_CONTROLLER);
}
@ -113,12 +120,11 @@ bool ConfigParser::Init(){
}
void ConfigParser::parseSingleLine(std::string line){
std::vector<std::string> cur_values = MyStringSplit(line,"=");
std::vector<std::string> cur_values = CPStringTools::StringSplit(line,"=");
if(cur_values.size() != 2){
if(HID_DEBUG || cur_values.size() > 2) log_printf("Not a valid key=pair line %s\n",line.c_str());
return;
}else{
u16 hid_slot = getSlot();
if(HID_DEBUG) log_printf("leftpart = \"%s\" \n",cur_values[0].c_str());
@ -126,7 +132,7 @@ void ConfigParser::parseSingleLine(std::string line){
int keyslot = -1;
if(HID_DEBUG) log_printf("Checking single value\n");
if(getType() == PARSE_GAMEPAD || getType() == PARSE_KEYBOARD){
if(getType() == PARSE_GAMEPAD /*|| getType() == PARSE_KEYBOARD*/){
keyslot = ConfigValues::getKeySlotGamePad(cur_values[0]);
}else if(getType() == PARSE_MOUSE){
keyslot = ConfigValues::getKeySlotMouse(cur_values[0]);
@ -161,31 +167,6 @@ void ConfigParser::parseSingleLine(std::string line){
char * ptr;
rightValue = strtol(cur_values[1].c_str(),&ptr,16);
}
if(keyslot >= DEF_L_STICK_UP && keyslot <= DEF_R_STICK_RIGHT){
if(keyslot == DEF_L_STICK_UP){
config_controller[hid_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y][0] = rightValue;
}else if(keyslot == DEF_L_STICK_DOWN){
config_controller[hid_slot][CONTRPS_VPAD_BUTTON_L_STICK_Y][1] = rightValue;
}else if(keyslot == DEF_L_STICK_LEFT){
config_controller[hid_slot][CONTRPS_VPAD_BUTTON_L_STICK_X][0] = rightValue;
}else if(keyslot == DEF_L_STICK_RIGHT){
config_controller[hid_slot][CONTRPS_VPAD_BUTTON_L_STICK_X][1] = rightValue;
}else if(keyslot == DEF_R_STICK_UP){
config_controller[hid_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y][0] = rightValue;
}else if(keyslot == DEF_R_STICK_DOWN){
config_controller[hid_slot][CONTRPS_VPAD_BUTTON_R_STICK_Y][1] = rightValue;
}else if(keyslot == DEF_R_STICK_LEFT){
config_controller[hid_slot][CONTRPS_VPAD_BUTTON_R_STICK_X][0] = rightValue;
}else if(keyslot == DEF_R_STICK_RIGHT){
config_controller[hid_slot][CONTRPS_VPAD_BUTTON_R_STICK_X][1] = rightValue;
}else{
log_printf("Random error in Keyboard sticks\n");
}
if(HID_DEBUG) log_printf("Set stick for Keyboard (%d)\n",keyslot);
return;
}
}else{
rightValue = ConfigValues::getPresetValue(cur_values[1]);
@ -215,10 +196,10 @@ void ConfigParser::parseSingleLine(std::string line){
if(!ConfigValues::getInstance()->setIfValueIsAControllerPreset(cur_values[1],getSlot(),keyslot)){
if(HID_DEBUG) log_printf("And its no preset\n");
std::vector<std::string> rightvalues = MyStringSplit(cur_values[1],",");
std::vector<std::string> rightvalues = CPStringTools::StringSplit(cur_values[1],",");
if(rightvalues.size() != 2){
log_printf("%d instead of 2 key=values pairs in line\n",rightvalues.size());
log_printf("ConfigParser::parseSingleLine: %d instead of 2 key=values pairs in line\n",rightvalues.size());
return;
}
@ -233,7 +214,7 @@ void ConfigParser::parseSingleLine(std::string line){
if(HID_DEBUG) log_printf("Found preset value!!\n");
}
}else{
log_printf("The setting \"%s\" is unknown!\n",cur_values[0].c_str());
log_printf("ConfigParser::parseSingleLine: The setting \"%s\" is unknown!\n",cur_values[0].c_str());
}
}
}
@ -249,27 +230,13 @@ bool ConfigParser::resetConfig(){
return true;
}
int ConfigParser::checkExistingController(int vid, int pid){
for(int i = 0;i< gHIDMaxDevices;i++){
u16 used_vid = config_controller[i][CONTRPS_VID][0] * 0x100 + config_controller[i][CONTRPS_VID][1];
u16 used_pid = config_controller[i][CONTRPS_PID][0] * 0x100 + config_controller[i][CONTRPS_PID][1];
if((used_vid == 0x00) && (used_vid == 0x00)){
return -1;
}
if(vid == used_vid && pid == used_pid){
return i;
}
}
return -1;
}
int ConfigParser::getSlotController(std::string identify){
if(HID_DEBUG) log_printf("Getting Controller Slot\n");
std::vector<std::string> values = MyStringSplit(identify,",");
std::vector<std::string> values = CPStringTools::StringSplit(identify,",");
if(values.size() != 2){
log_printf("You need to provide a VID and PID. e.g. \"[vid=0x451,pid=0x152]\". (%s)\n",identify.c_str());
log_printf("ConfigParser::getSlotController: You need to provide a VID and PID. e.g. \"[vid=0x451,pid=0x152]\". (%s)\n",identify.c_str());
return HID_INVALID_SLOT;
}
@ -281,19 +248,29 @@ int ConfigParser::getSlotController(std::string identify){
if(pid < 0){
return HID_INVALID_SLOT;
}
log_printf("VID: %04x PID: %04x\n",vid,pid);
if(HID_DEBUG) log_printf("VID: %04x PID: %04x\n",vid,pid);
int slot = checkExistingController(vid,pid);
this->vid = vid;
this->pid = pid;
DeviceInfo deviceinfo;
memset(&deviceinfo,0,sizeof(deviceinfo));
int result = ControllerPatcherUtils::getDeviceInfoFromVidPid(&deviceinfo);
int slot = deviceinfo.slotdata.deviceslot;
int hid = 0;
if(slot < 0){
log_printf("Its a new controller, lets save it\n");
slot = gHIDRegisteredDevices;
hid = getNextDeviceSlot();
if(result < 0){
if(HID_DEBUG) log_printf("Its a new controller, lets save it\n");
HIDSlotData slotdata;
ControllerPatcherUtils::getNextSlotData(&slotdata);
slot = slotdata.deviceslot;
hid = slotdata.hidmask;
if(slot >= gHIDMaxDevices){
log_printf("We don't a space for a new controller, please delete .inis\n");
log_printf("ConfigParser::getSlotController: We don't a space for a new controller, please delete .inis\n");
return HID_INVALID_SLOT;
}
if(HID_DEBUG) log_printf("Got new slot! slot: %d hid %s .. Lets registrate it!\n",slot,byte_to_binary(hid));
if(HID_DEBUG) log_printf("Got new slot! slot: %d hid %s .. Lets registrate it!\n",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;
@ -304,35 +281,27 @@ int ConfigParser::getSlotController(std::string identify){
if(HID_DEBUG) log_printf("Saved vid: %04X pid: %04X\n",used_vid,used_pid);
config_controller_list[slot] = hid;
if(HID_DEBUG) log_printf("Saves the hid\n");
config_controller_data_ptr[slot][0] = (u32)&(gHID_Devices[slot]).pad_data[0];
config_controller_data_ptr[slot][1] = (u32)&(gHID_Devices[slot]).pad_data[1];
config_controller_data_ptr[slot][2] = (u32)&(gHID_Devices[slot]).pad_data[2];
config_controller_data_ptr[slot][3] = (u32)&(gHID_Devices[slot]).pad_data[3];
if(HID_DEBUG) log_printf("set data ptr\n");
config_controller_hidmask[slot] = hid;
if(HID_DEBUG) log_printf("Saved the hid\n");
}else{
if(slot < gHIDMaxDevices){
hid =config_controller_list[slot];
if(HID_DEBUG) log_printf(">>>>>> found slot %d (hid:%s). Modifing existing data <<<<<<<<\n",slot,byte_to_binary(hid));
log_printf("We already have data of this controller, lets modify it\n");
hid = config_controller_hidmask[slot];
if(HID_DEBUG) log_printf(">>>>>> found slot %d (hid:%s). Modifing existing data <<<<<<<<\n",slot,CPStringTools::byte_to_binary(hid));
if(HID_DEBUG) log_printf("We already have data of this controller, lets modify it\n");
}else{
log_printf("Something really odd happend to the slots. %d is bigger then max (%d)\n",slot,gHIDMaxDevices);
log_printf("ConfigParser::getSlotController: Something really odd happend to the slots. %d is bigger then max (%d)\n",slot,gHIDMaxDevices);
return HID_INVALID_SLOT;
}
}
if(HID_DEBUG) log_printf("using slot: %d hid %s\n",slot,byte_to_binary(hid));
if(HID_DEBUG) log_printf("using slot: %d hid %s\n",slot,CPStringTools::byte_to_binary(hid));
return slot;
}
bool ConfigParser::parseIni(){
if(getSlot() == HID_INVALID_SLOT){
log_printf("Couldn't parse file. Not a valid slot. Probably broken config. Or you tried to have more than %d devices\n",getType(),gHIDMaxDevices);
log_printf("ConfigParser::parseIni: Couldn't parse file. Not a valid slot. Probably broken config. Or you tried to have more than %d devices\n",getType(),gHIDMaxDevices);
}
if(HID_DEBUG) log_printf("Parsing content, type %d\n",getType());
@ -340,7 +309,7 @@ bool ConfigParser::parseIni(){
int start = 1;
if(contentLines[1].compare("[IGNOREDEFAULT]") == 0){
resetConfig();
log_printf("Overwriting existing settings of this device\n");
if(HID_DEBUG) log_printf("Overwriting existing settings of this device\n");
start++;
}
@ -349,18 +318,18 @@ bool ConfigParser::parseIni(){
parseSingleLine(contentLines[i]);
}
log_printf("Parsing of the file is done.\n");
if(HID_DEBUG) log_printf("Parsing of the file is done.\n");
return true;
}
int ConfigParser::getValueFromKeyValue(std::string value_pair,std::string expectedKey,std::string delimiter){
std::vector<std::string> string_value = MyStringSplit(value_pair,delimiter);
std::vector<std::string> string_value = CPStringTools::StringSplit(value_pair,delimiter);
if(string_value.size() != 2){
if(HID_DEBUG || string_value.size() > 2) log_printf("Not a valid key=pair line %s\n",value_pair.c_str());
return -1;
}
if(string_value[0].compare(expectedKey) != 0){
log_printf("Key part not %s, its %s",expectedKey.c_str(),string_value[0].c_str());
log_printf("ConfigParser::getValueFromKeyValue: Key part not %s, its %s",expectedKey.c_str(),string_value[0].c_str());
return -1;
}
char * ptr;

View File

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (C) 2016 Maschell
* 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
@ -24,11 +24,12 @@
#include <stdio.h>
#include <gctypes.h>
#include "controller_patcher.h"
#include "pad_const.h"
#include "../ControllerPatcher.hpp"
#include "../ConfigReader.hpp"
#include "../utils/PadConst.hpp"
#include "utils/logger.h"
#include "cp_retain_vars.h"
#include "../utils/CPRetainVars.hpp"
enum PARSE_TYPE{
PARSE_CONTROLLER,
@ -37,9 +38,10 @@ enum PARSE_TYPE{
PARSE_KEYBOARD
};
class ConfigParser
{
public:
class ConfigParser{
friend class ConfigReader;
friend class ControllerPatcher;
private:
//!Constructor
ConfigParser(std::string configData);
//!Destructor
@ -53,7 +55,6 @@ public:
bool parseIni();
private:
bool Init();
bool parseConfigString(std::string content);
@ -69,6 +70,10 @@ private:
void parseSingleLine(std::string line);
u16 slot_b;
PARSE_TYPE type_b;
u16 vid;
u16 pid;
std::string content;
std::vector<std::string> contentLines;
};

View File

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (C) 2016 Maschell
* 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
@ -17,20 +17,18 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config_values.h"
#include "./ConfigValues.hpp"
#include "../utils/CPRetainVars.hpp"
#include "utils/logger.h"
#include "cp_retain_vars.h"
ConfigValues *ConfigValues::instance = NULL;
ConfigValues::ConfigValues()
{
ConfigValues::ConfigValues(){
InitValues();
}
ConfigValues::~ConfigValues()
{
ConfigValues::~ConfigValues(){
if(HID_DEBUG) log_printf("ConfigValues::~ConfigValues(){\n");
}
const u8 * ConfigValues::getValuesForPreset(std::map<std::string,const u8*> values,std::string possibleValue){
@ -46,11 +44,15 @@ bool ConfigValues::setIfValueIsAControllerPresetEx(std::string value,int slot,in
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;
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,int slot,int 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 ||
@ -101,3 +103,20 @@ int ConfigValues::getPresetValueEx(std::string possibleString){
}
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;
}

View File

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (C) 2016 Maschell
* 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
@ -22,15 +22,22 @@
#include <map>
#include <gctypes.h>
#include "controller_patcher.h"
#include "pad_const.h"
#include "../utils/PadConst.hpp"
#include "../ControllerPatcher.hpp"
#include "../utils/CPStringTools.hpp"
#include "utils/logger.h"
class ConfigValues
{
public:
friend class ConfigParser;
friend class ControllerPatcher;
private:
static ConfigValues *getInstance() {
if(!instance)
if(instance == NULL){
log_printf("ConfigValues: We need a new instance!!!\n");
instance = new ConfigValues();
}
return instance;
}
@ -42,7 +49,7 @@ public:
}
/**
Returns NULL if no a preset!
Returns NULL if not a preset!
**/
static const u8 * getValuesStickPreset(std::string possibleValue)
{
@ -120,7 +127,22 @@ public:
return cur_instance->setIfValueIsAControllerPresetEx(value,slot,keyslot);
}
private:
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
@ -135,9 +157,12 @@ private:
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*> presetSticks;
int getValueFromMap(std::map<std::string,int> values,std::string nameOfString);
@ -147,7 +172,7 @@ private:
int getPresetValueEx(std::string possibleString);
void InitValues(){
CONTPRStringToValue["VPAD_BUTTON_A"] = CONTRPS_VPAD_BUTTON_A;
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;
@ -183,7 +208,6 @@ private:
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;
@ -191,17 +215,17 @@ private:
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_STICK_L_EMULATION_DOWN"] = CONTRPS_VPAD_STICK_L_EMULATION_DOWN;
CONTPRStringToValue["VPAD_L_STICK_UP"] = DEF_L_STICK_UP;
CONTPRStringToValue["VPAD_L_STICK_DOWN"] = DEF_L_STICK_DOWN;
CONTPRStringToValue["VPAD_L_STICK_LEFT"] = DEF_L_STICK_LEFT;
CONTPRStringToValue["VPAD_L_STICK_RIGHT"] = DEF_L_STICK_RIGHT;
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"] = DEF_R_STICK_UP;
CONTPRStringToValue["VPAD_R_STICK_DOWN"] = DEF_R_STICK_DOWN;
CONTPRStringToValue["VPAD_R_STICK_LEFT"] = DEF_R_STICK_LEFT;
CONTPRStringToValue["VPAD_R_STICK_RIGHT"] = DEF_R_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;
@ -215,6 +239,11 @@ private:
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;
@ -238,6 +267,7 @@ private:
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;
@ -309,6 +339,29 @@ private:
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;
presetKeyboardValues["KEYBOARD_SHIFT"] = HID_KEYBOARD_BUTTON_SHIFT;
presetKeyboardValues["KEYBOARD_A"] = HID_KEYBOARD_BUTTON_A;
presetKeyboardValues["KEYBOARD_B"] = HID_KEYBOARD_BUTTON_B;
@ -427,9 +480,15 @@ private:
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_L_X;
presetSticks["XINPUT_STICK_R_Y"] = HID_XINPUT_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["DS4_DPAD_MODE"] = HID_XINPUT_BUTTON_DPAD_TYPE;
presetSticks["XINPUT_DPAD_MODE"] = HID_XINPUT_BUTTON_DPAD_TYPE;
gGamePadValuesToCONTRPSString["VPAD_BUTTON_A"] = CONTRPS_VPAD_BUTTON_A;
gGamePadValuesToCONTRPSString["VPAD_BUTTON_B"] = CONTRPS_VPAD_BUTTON_B;
@ -451,8 +510,6 @@ private:
gGamePadValuesToCONTRPSString["VPAD_BUTTON_STICK_L"] = CONTRPS_VPAD_BUTTON_STICK_L;
gGamePadValuesToCONTRPSString["VPAD_BUTTON_TV"] = CONTRPS_VPAD_BUTTON_TV;
/*
//Todo: think about removing it
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;
@ -461,7 +518,17 @@ private:
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;
*/
log_printf("Value device names \n");
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;
log_printf("Value init done\n");
}
const u8 * getValuesForPreset(std::map<std::string,const u8*> values,std::string possibleValue);
@ -469,5 +536,7 @@ private:
bool setIfValueIsPreset(std::map<std::string,const u8*> values,std::string possibleValue,int slot,int keyslot);
bool setIfValueIsAControllerPresetEx(std::string value,int slot,int keyslot);
void addDeviceNameEx(u16 vid,u16 pid,std::string value);
std::string getStringByVIDPIDEx(u16 vid,u16 pid);
};
#endif

View File

@ -1,82 +0,0 @@
/****************************************************************************
* Copyright (C) 2016 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 <string>
#include <vector>
#include <map>
#include <stdio.h>
#include <gctypes.h>
#include "controller_patcher.h"
#include "pad_const.h"
#include "../dynamic_libs/os_functions.h"
#include "../dynamic_libs/fs_functions.h"
#include "cp_retain_vars.h"
#define CONTROLLER_PATCHER_PATH "/vol/external01/wiiu/controller";
class ConfigReader
{
public:
static ConfigReader *getInstance() {
if(!instance)
instance = new ConfigReader();
return instance;
}
static void destroyInstance() {
if(instance){
delete instance;
instance = NULL;
}
}
static int getNumberOfLoadedFiles(){
return ConfigReader::numberValidFiles;
}
static void increaseNumberOfLoadedFiles(){
ConfigReader::numberValidFiles++;
}
static int numberValidFiles;
private:
//!Constructor
ConfigReader();
//!Destructor
~ConfigReader();
int 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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
#include "dynamic_libs/os_functions.h"
#include "dynamic_libs/socket_functions.h"
#include "ControllerPatcherNet.hpp"
int ControllerPatcherNet::recvwait(int sock, void *buffer, int len) {
int ret;
while (len > 0) {
ret = recv(sock, buffer, len, 0);
if(ret < 0) return ret;
len -= ret;
buffer += ret;
}
return 0;
}
int ControllerPatcherNet::recvbyte(int sock) {
unsigned char buffer[1];
int ret;
ret = recvwait(sock, buffer, 1);
if (ret < 0) return ret;
return buffer[0];
}
int ControllerPatcherNet::checkbyte(int sock) {
unsigned char buffer[1];
int ret;
ret = recv(sock, buffer, 1, MSG_DONTWAIT);
if (ret < 0) return ret;
if (ret == 0) return -1;
return buffer[0];
}
int ControllerPatcherNet::sendwait(int sock, const void *buffer, int len) {
int ret;
while (len > 0) {
ret = send(sock, buffer, len, 0);
if(ret < 0) return ret;
len -= ret;
buffer += ret;
}
return 0;
}
int ControllerPatcherNet::sendbyte(int sock, unsigned char byte) {
unsigned char buffer[1];
buffer[0] = byte;
return sendwait(sock, buffer, 1);
}

View File

@ -0,0 +1,15 @@
#ifndef _CONTROLLERPATCHERNET_H_
#define _CONTROLLERPATCHERNET_H_
class ControllerPatcherNet{
friend class TCPServer;
friend class UDPServer;
private:
static int recvwait(int sock, void *buffer, int len);
static int recvbyte(int sock);
static int checkbyte(int sock);
static int sendwait(int sock, const void *buffer, int len);
static int sendbyte(int sock, unsigned char byte);
};
#endif

333
network/TCPServer.cpp Normal file
View File

@ -0,0 +1,333 @@
/****************************************************************************
* 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 <sys/time.h>
#include <string.h>
#include "../ControllerPatcher.hpp"
#include "./ControllerPatcherNet.hpp"
#define WIIU_CP_TCP_HANDSHAKE 0x12
#define WIIU_CP_TCP_SAME_CLIENT 0x20
#define WIIU_CP_TCP_NEW_CLIENT 0x21
#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_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 errno (*__gh_errno_ptr())
ControllerPatcherThread * TCPServer::pThread = NULL;
TCPServer * TCPServer::instance = NULL;
TCPServer::TCPServer(int 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) log_printf("TCPServer: Thread will be closed\n");
TCPServer::AttachDetach(DETACH);
exitThread = 1;
if(TCPServer::pThread != NULL){
if(HID_DEBUG) log_printf("TCPServer: Deleting it!\n");
delete TCPServer::pThread;
}
if(HID_DEBUG) log_printf("TCPServer: Thread done\n");
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){
TCPServer::pThread = ControllerPatcherThread::create(TCPServer::DoTCPThread, (void*)server, ControllerPatcherThread::eAttributeAffCore2,28);
TCPServer::pThread->resumeThread();
}
void TCPServer::AttachDetach(int attach){
if(HID_DEBUG){
if(attach){
log_printf("TCPServer: Network Attach\n");
}else{
log_printf("TCPServer: Network Detach\n");
}
}
for(int i= 0;i< gHIDMaxDevices;i++){
for(int j= 0;j< HID_MAX_PADS_COUNT;j++){
if(gNetworkController[i][j][NETWORK_CONTROLLER_ACTIVE] > 0){
log_printf("Found a registered pad in deviceslot %d and padslot %d! Lets detach it.\n",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){
log_printf("TCPServer: Network Attach DONE!\n");
}else{
log_printf("TCPServer: Network Detach DONE!\n");
}
}
}
void TCPServer::DetachAndDelete(){
TCPServer::AttachDetach(DETACH);
memset(&gNetworkController,0,sizeof(gNetworkController));
}
int TCPServer::RunTCP(){
int ret;
while (1) {
if(exitThread) break;
ret = ControllerPatcherNet::checkbyte(clientfd);
if (ret < 0) {
if(errno != 6) return ret;
usleep(1000);
continue;
}
//log_printf("got byte from tcp! %01X\n",ret);
switch (ret) {
case WIIU_CP_TCP_ATTACH: { /*attach */
int handle;
ret = ControllerPatcherNet::recvwait(clientfd, &handle, 4);
if(ret < 0){
log_printf("TCPServer::RunTCP() Error in %02X: recvwait handle\n",WIIU_CP_TCP_ATTACH);
return ret;
}
if(HID_DEBUG) log_printf("TCPServer: got handle %d\n",handle);
u16 vid = 0;
u16 pid = 0;
ret = ControllerPatcherNet::recvwait(clientfd, &vid, 2);
if(ret < 0){
log_printf("TCPServer::RunTCP() Error in %02X: recvwait vid\n",WIIU_CP_TCP_ATTACH);
return ret;
}
if(HID_DEBUG) log_printf("TCPServer: got vid %04X\n",vid);
ret = ControllerPatcherNet::recvwait(clientfd, &pid, 2);
if(ret < 0){
log_printf("TCPServer::RunTCP() Error in %02X: recvwait pid\n",WIIU_CP_TCP_ATTACH);
return ret;
}
if(HID_DEBUG) log_printf("TCPServer: 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){
log_printf("TCPServer::RunTCP() Error in %02X: getDataByHandle(%d,%08X).\n",WIIU_CP_TCP_ATTACH,handle,&user);
log_printf("TCPServer::RunTCP() Error in %02X: Config for the controller is missing.\n",WIIU_CP_TCP_ATTACH);
if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_CONFIG_NOT_FOUND) < 0)){
log_printf("TCPServer::RunTCP() Error in %02X: Sending the WIIU_CP_TCP_ATTACH_CONFIG_NOT_FOUND byte failed. Error: %d.\n",WIIU_CP_TCP_ATTACH,ret);
}
return -1;
}
if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_CONFIG_FOUND) < 0)){
log_printf("TCPServer::RunTCP() Error in %02X: Sending the WIIU_CP_TCP_ATTACH_CONFIG_FOUND byte failed. Error: %d.\n",WIIU_CP_TCP_ATTACH,ret);
return ret;
}
if(user != NULL){
if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_USER_DATA_OKAY) < 0)){
log_printf("TCPServer::RunTCP() Error in %02X: Sending the WIIU_CP_TCP_ATTACH_USER_DATA_OKAY byte failed. Error: %d.\n",WIIU_CP_TCP_ATTACH,ret);
return ret;
}
ret = ControllerPatcherNet::sendwait(clientfd,&user->slotdata.deviceslot,2);
if(ret < 0){
log_printf("TCPServer::RunTCP() Error in %02X: sendwait slotdata: %04X\n",WIIU_CP_TCP_ATTACH,user->slotdata.deviceslot);
return ret;
}
ret = ControllerPatcherNet::sendwait(clientfd,&user->pad_slot,1);
if(ret < 0){
log_printf("TCPServer::RunTCP() Error in %02X: sendwait pad_slot: %04X\n",WIIU_CP_TCP_ATTACH,user->pad_slot);
return ret;
}
}else{
log_printf("TCPServer::RunTCP() Error in %02X: invalid user data.\n",WIIU_CP_TCP_ATTACH);
if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_USER_DATA_BAD) < 0)){
log_printf("TCPServer::RunTCP() Error in %02X: Sending the WIIU_CP_TCP_ATTACH_USER_DATA_BAD byte failed. Error: %d.\n",WIIU_CP_TCP_ATTACH,ret);
return ret;
}
return -1;
break;
}
if(HID_DEBUG) log_printf("TCPServer: attachted to device slot: %d , pad slot is: %d\n",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) log_printf("TCPServer: handle %d connected! vid: %02X pid: %02X deviceslot %d, padslot %d\n",handle,vid,pid,user->slotdata.deviceslot,user->pad_slot);
break;
}
case WIIU_CP_TCP_DETACH: { /*detach */
int handle;
ret = ControllerPatcherNet::recvwait(clientfd, &handle, 4);
if(ret < 0){
log_printf("TCPServer::RunTCP() Error in %02X: recvwait handle\n",WIIU_CP_TCP_DETACH);
return ret;
break;
}
if(HID_DEBUG) log_printf("TCPServer: got detach for handle: %d\n",handle);
my_cb_user * user = NULL;
if(ControllerPatcherUtils::getDataByHandle(handle,&user) < 0){
log_printf("TCPServer::RunTCP() Error in %02X: getDataByHandle(%d,%08X).\n",WIIU_CP_TCP_DETACH,handle,&user);
return -1;
break;
}
if(user == NULL){
log_printf("TCPServer::RunTCP() Error in %02X: invalid user data.\n",WIIU_CP_TCP_DETACH);
return -1;
break;
}
int deviceslot = user->slotdata.deviceslot;
if(HID_DEBUG) log_printf("TCPServer: device slot is: %d , pad slot is: %d\n",deviceslot,user->pad_slot);
DeviceVIDPIDInfo vidpid;
int result;
if((result = ControllerPatcherUtils::getVIDPIDbyDeviceSlot(deviceslot,&vidpid)) < 0){
log_printf("TCPServer::RunTCP() Error in %02X: Couldn't find a valid VID/PID for device slot %d. Error: %d\n",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) log_printf("TCPServer: handle %d disconnected!\n",handle);
break;
}
case WIIU_CP_TCP_PING: { /*ping*/
if(HID_DEBUG) log_printf("TCPServer: GOT PING\n");
break;
}
default:
return -1;
break;
}
}
return 0;
}
void TCPServer::ErrorHandling(){
CloseSockets();
usleep(1000*1000*2);
}
void TCPServer::DoTCPThreadInternal(){
int 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;}
int 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) log_printf("TCPServer::DoTCPThreadInternal: Waiting for a connection\n");
if(exitThread) break;
len = 16;
clientfd = ret = accept(sockfd, (sockaddr *)&(sock_addr), &len);
if(HID_DEBUG) log_printf("TCPServer::DoTCPThreadInternal: Connection accepted\n");
if(ret == -1){ ErrorHandling(); break;}
int ret;
ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_HANDSHAKE); //Hey I'm a WiiU console!
if(ret < 0){ log_printf("TCPServer::DoTCPThreadInternal: Error sendbyte: %02X\n",WIIU_CP_TCP_HANDSHAKE); ErrorHandling(); break;}
if(ret < 0){ log_printf("TCPServer::DoTCPThreadInternal: Error sendbyte %02X/02X\n",WIIU_CP_TCP_NEW_CLIENT,WIIU_CP_TCP_SAME_CLIENT); ErrorHandling(); break;}
TCPServer::DetachAndDelete(); //Clear connected controller
RunTCP();
if(clientfd != -1){
socketclose(clientfd);
}
clientfd = -1;
}while(0);
TCPServer::DetachAndDelete(); //Clear connected controller
CloseSockets();
if(HID_DEBUG) log_printf("TCPServer: Connection closed\n");
continue;
}
}
void TCPServer::DoTCPThread(ControllerPatcherThread *thread, void *arg){
TCPServer * args = (TCPServer * )arg;
return args->DoTCPThreadInternal();
}

68
network/TCPServer.hpp Normal file
View File

@ -0,0 +1,68 @@
/****************************************************************************
* 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 "../utils/ControllerPatcherThread.hpp"
#include "dynamic_libs/socket_functions.h"
#include "utils/logger.h"
#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(int 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(int attach);
void DetachAndDelete();
static TCPServer *instance;
int RunTCP();
struct sockaddr_in sock_addr;
volatile int sockfd = -1;
volatile int clientfd = -1;
volatile int exitThread = 0;
static ControllerPatcherThread *pThread;
};
#endif //_TCPSERVER_WINDOW_H_

158
network/UDPServer.cpp Normal file
View 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 "UDPServer.hpp"
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include "../ControllerPatcher.hpp"
#define MAX_UDP_SIZE 0x578
#define errno (*__gh_errno_ptr())
ControllerPatcherThread * UDPServer::pThread = NULL;
UDPServer * UDPServer::instance = NULL;
UDPServer::UDPServer(int port){
int 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;
int 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;
log_printf("%08X\n",pThreadPointer);
if(pThreadPointer != NULL){
delete pThreadPointer;
UDPServer::pThread = NULL;
if (this->sockfd != -1){
socketclose(sockfd);
}
this->sockfd = -1;
}
}
if(HID_DEBUG) log_printf("UDPServer Thread has been closed\n");
}
void UDPServer::StartUDPThread(UDPServer * server){
UDPServer::pThread = ControllerPatcherThread::create(UDPServer::DoUDPThread, (void*)server, ControllerPatcherThread::eAttributeAffCore2,17);
UDPServer::pThread->resumeThread();
}
bool UDPServer::cpyIncrementBufferOffset(void * target, void * source, int * offset, int typesize, int maximum){
if(((int)*offset + typesize) > maximum){
log_printf("UDPServer::cpyIncrementBufferOffset: Transfer error. Excepted %04X bytes, but only got %04X\n",(*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];
int n;
my_cb_user user;
while(1){
int usingVar = exitThread;
if(exitThread)break;
memset(buffer,0,MAX_UDP_SIZE);
n = recv(sockfd,buffer,MAX_UDP_SIZE,0);
if (n < 0){
int errno_ = errno;
usleep(2000);
if(errno_ != 11 && errno_ != 9){
break;
}
continue;
}
int bufferoffset = 0;
u8 type;
memcpy((void *)&type,buffer,sizeof(type));
bufferoffset += sizeof(type);
switch (buffer[0]) {
case 0x03: {
u8 count_commands;
memcpy((void *)&count_commands,buffer+bufferoffset,sizeof(count_commands));
bufferoffset += sizeof(count_commands);
for(int i = 0;i<count_commands;i++){
int handle;
u16 deviceSlot;
u16 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){
log_printf("UDPServer::DoUDPThreadInternal(): Allocating memory failed\n");
continue;
}
//log_printf("UDPServer::DoUDPThreadInternal(): Got handle: %d slot %04X hid %04X pad %02X datasize %02X\n",handle,deviceSlot,hid,padslot,datasize);
if(!cpyIncrementBufferOffset((void *)databuffer, (void *)buffer,&bufferoffset,datasize, n))continue;
memset(&user,0,sizeof(user));
user.pad_slot = padslot;
user.slotdata.deviceslot = deviceSlot;
user.slotdata.hidmask = hid;
if(gNetworkController[deviceSlot][padslot][0] == 0){
log_printf("Ehm. Pad is not connected. STOP SENDING DATA ;) \n");
}else{
ControllerPatcherHID::externHIDReadCallback(handle,databuffer,datasize,&user);
}
if(databuffer){
free(databuffer);
databuffer = NULL;
}
}
break;
}
default:{
break;
}
}
}
if(HID_DEBUG) log_printf("UDPServer Thread ended\n");
}

57
network/UDPServer.hpp Normal file
View 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 "../utils/ControllerPatcherThread.hpp"
#include "dynamic_libs/socket_functions.h"
#include "utils/logger.h"
#define DEFAULT_UDP_PORT 8113
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(int port);
~UDPServer();
void StartUDPThread(UDPServer * server);
static void DoUDPThread(ControllerPatcherThread *thread, void *arg);
void DoUDPThreadInternal();
bool cpyIncrementBufferOffset(void * target, void * source, int * offset, int typesize, int maximum);
volatile int sockfd = -1;
volatile int exitThread = 0;
static UDPServer *instance;
static ControllerPatcherThread *pThread;
};
#endif //_UDPSERVER_WINDOW_H_

View File

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (C) 2016 Maschell
* 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
@ -15,55 +15,83 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef _CONTROLLER_PATCHER_H_
#define _CONTROLLER_PATCHER_H_
/**
* @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
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _CONTROLLER_PATCHER_DEFS_H_
#define _CONTROLLER_PATCHER_DEFS_H_
#include <gctypes.h>
#include "dynamic_libs/os_functions.h"
#include "dynamic_libs/syshid_functions.h"
#include "dynamic_libs/vpad_functions.h"
#define HID_DEBUG 0
#define HID_INIT_NOT_DONE 0
#define HID_INIT_DONE 1
#define HID_SDCARD_READ 2
typedef int HID_DEVICE_LIST;
#define HID_ALL_CONNECTED_DEVICES 0x10
#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 HID_INIT_DONE 1
#define HID_SDCARD_READ 2
#define NETWORK_CONTROLLER_VID 0
#define NETWORK_CONTROLLER_PID 1
#define NETWORK_CONTROLLER_ACTIVE 2
#define NETWORK_CONTROLLER_HANDLE 3
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! Don't forget to change this data!
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#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 0xFFFF
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,
STICK_CONF_BYTE,
STICK_CONF_DEFAULT,
STICK_CONF_DEADZONE,
STICK_CONF_INVERT,
STICK_CONF_MIN,
STICK_CONF_MAX,
STICK_CONF_ENUM_MAXVALUE
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!!!!
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! End
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#define HID_MAX_DATA_LENGTH_PER_PAD 10
#define HID_MAX_PADS_COUNT 4
typedef struct _HID_Data {
u8 rumbleActive;
u8 hid_data[HID_MAX_DATA_LENGTH_PER_PAD*2];
} HID_Data;
//! most data has the format: byte,value (byte starting at 0)
enum Controller_Patcher_Settings
{
@ -108,9 +136,6 @@ enum Controller_Patcher_Settings
CONTRPS_VPAD_BUTTON_STICK_R,
CONTRPS_VPAD_BUTTON_STICK_L,
/*
Currently not needed
CONTRPS_VPAD_STICK_R_EMULATION_LEFT,
CONTRPS_VPAD_STICK_R_EMULATION_RIGHT,
CONTRPS_VPAD_STICK_R_EMULATION_UP,
@ -120,7 +145,6 @@ enum Controller_Patcher_Settings
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
@ -137,6 +161,16 @@ enum Controller_Patcher_Settings
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,
@ -151,72 +185,222 @@ enum Controller_Patcher_Settings
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,
CONTRPDM_Hat,
CONTRPDM_Absolute_2Values,
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,
CONTRDPAD_MASK,
CONTRDPAD_MODE = 0, /**< Byte where the DPAD Mode is stored */
CONTRDPAD_MASK = 1, /**< Byte where the DPAD Mask is stored */
};
#define CONTROLLER_PATCHER_VALUE_SET 0x01
#define CONTROLLER_PATCHER_GC_DOUBLE_USE 0x01
#define CONTROLLER_PATCHER_INVALIDVALUE 0xFF
/**
* @brief Stores data if the Slot the device is using in gHID_Devices
*/
typedef struct _HIDSlotData{
u16 deviceslot; /**< deviceslot number */
u16 hidmask; /**< Used HID-Mask */
}HIDSlotData;
/**
* @brief Struct where the data for the callback funtion is stored
*/
typedef struct _my_cb_user{
unsigned char *buf;
unsigned int transfersize;
unsigned int rumblestatus[4];
unsigned int handle;
unsigned int hid;
unsigned int deviceSlot;
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 */
}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
*/
enum DEVICE_TYPE
{
DEVICE_TYPE_CONTROLLER = 0, /**< Normal Controller */
DEVICE_TYPE_MOUSE = 1, /**< Mouse */
};
/**
* @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 {
my_cb_user * user_data;
HID_Data pad_data[HID_MAX_PADS_COUNT];
} HID_DEVICE_DATA;
/**
* @brief Stores a VID and PID
*/
typedef struct _DeviceVIDPIDInfo{
u16 vid; /**< Vendor ID of this device */
u16 pid; /**< Product ID of this device */
}DeviceVIDPIDInfo;
typedef struct _HID_Data_Struct{
unsigned char *src;
int hid;
}HID_Data_Struct;
/**
* @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;
void setConfigValue(u8 * dest , u8 first, u8 second);
void init_config_controller();
void init_button_remapping();
void deinit_config_controller();
u32 getNextDeviceSlot();
void printButtons(VPADData * buffer);
void buttonRemapping(VPADData * buffer);
void setButtonRemappingData(VPADData * buffer, VPADData * new_data,u32 VPADButton, int CONTRPS_Value);
void setHoldButtonData(VPADData * buffer, VPADData * new_data,u32 oldVPADButton,u32 newVPADButton);
/**
* @brief The enumeration of Controller-Mapping types
*/
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 */
};
void setControllerReleasePressData(HID_Data_Struct data_cur, HID_Data_Struct data_last,VPADData * buffer,int VPADButton);
void setControllerDataFromHID(VPADData * buffer,HID_DEVICE_LIST hid_devices);
int checkDoubleUseGC();
void checkMouseMode(HID_Data_Struct data, HID_Data_Struct data_last);
/**
* @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;
void my_read_cb(unsigned int handle, int error, unsigned char *buf, unsigned int bytes_transfered, void *p_user);
/**
* @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;
int wasInKeyboard(unsigned char * src,int key);
/**
* @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;
const char *byte_to_binary(int x);
/**
* @brief Pressed/Released/Down Button data.
*/
typedef struct _InputButtonData{
u32 btn_h; /**< Buttons beeing hold */
u32 btn_d; /**< Buttons that started pressing */
u32 btn_r; /**< Buttons that were button released */
}InputButtonData;
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! GC-Adapter
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/**
* @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 */
InputButtonData button_data[HID_MAX_PADS_COUNT];
}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,
};
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* 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
@ -232,23 +416,20 @@ const char *byte_to_binary(int x);
#define HID_GC_BUTTON_R_VALUE 0x80
#define HID_GC_BUTTON_Z_VALUE 0x02
#define HID_GC_PAD_COUNT 4
#define HID_GC_PAD_COUNT 4
void HIDGCRumble(unsigned int handle,my_cb_user *usr,int rumble, u32 pad);
void my_gc_write_cb(unsigned int handle, int error, unsigned char *buf, unsigned int bytes_transfered, void *p_user);
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* DS3
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! 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 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
@ -269,12 +450,11 @@ void my_gc_write_cb(unsigned int handle, int error, unsigned char *buf, unsigned
#define HID_DS3_BUTTON_DOWN_VALUE 0x40 // 2
#define HID_DS3_BUTTON_GUIDE_VALUE 0x01 // 4
#define HID_DS3_PAD_COUNT 1
#define HID_DS3_PAD_COUNT 1
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! DS4
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* DS4
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define HID_DS4_BUTTON_CROSS_VALUE 0x20 // 5
#define HID_DS4_BUTTON_SQUARE_VALUE 0x10 // 5
@ -304,11 +484,41 @@ void my_gc_write_cb(unsigned int handle, int error, unsigned char *buf, unsigned
#define HID_DS4_BUTTON_GUIDE_VALUE 0x01 // 7
#define HID_DS4_BUTTON_T_PAD_CLICK_VALUE 0x02 // 7
#define HID_DS4_PAD_COUNT 1
#define HID_DS4_PAD_COUNT 1
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! Keyboard (Full list is on: http://www.freebsddiary.org/APC/usb_hid_usages.php)
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* 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
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Keyboard (Full list is on: http://www.freebsddiary.org/APC/usb_hid_usages.php)
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define HID_KEYBOARD_BUTTON_SHIFT 0x02
@ -404,64 +614,16 @@ void my_gc_write_cb(unsigned int handle, int error, unsigned char *buf, unsigned
#define HID_KEYBOARD_PAD_COUNT 1
#define HID_KEYBOARD_DATA_LENGTH 8
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! Mouse
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Mouse
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#define HID_MOUSE_BUTTON_LEFTCLICK 0x04
#define HID_MOUSE_BUTTON_RIGHTCLICK 0x05
#define HID_MOUSE_PAD_COUNT 1
#define HID_MOUSE_PAD_COUNT 1
#define HID_MOUSE_MODE_AIM 0x01
#define HID_MOUSE_MODE_TOUCH 0x02
struct _HID_Mouse_Data {
u8 left_click;
u8 right_click;
s16 X;
s16 Y;
s16 deltaX;
s16 deltaY;
u8 valuedChanged;
} __attribute__ ((packed));
typedef struct _HID_Mouse_Data HID_Mouse_Data;
typedef struct _HID_Mouse_Data_c {
HID_Mouse_Data data[2];
} HID_Mouse_Data_c;
typedef struct _HID_Mouse {
my_cb_user * user_data;
HID_Mouse_Data_c pad_data[HID_MOUSE_PAD_COUNT];
} HID_Mouse;
void my_ms_read_cb(unsigned int handle, int error, unsigned char *buf, unsigned int bytes_transfered, void *p_user);
void my_ms_write_cb(unsigned int handle, int error, unsigned char *buf, unsigned int bytes_transfered, void *p_user);
void my_ms_report_cb(unsigned int handle, int error, unsigned char *buf, unsigned int bytes_transfered, void *p_user);
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! Shared
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
int my_attach_cb(HIDClient *p_client, HIDDevice *p_device, unsigned int attach);
int getPadCount(int hid);
HID_Data_Struct * getLastData(HID_Data_Struct data);
int getButtonPressed(HID_Data_Struct data, int VPADButton);
void setLastData(HID_Data_Struct data,HID_Data_Struct data_last);
int getActivePad(int hid);
void setRumble(int hid,int rumble);
void convertAnalogSticks(HID_Data_Struct data,VPADData * buffer);
void setTouch(HID_Data_Struct data,VPADData * buffer);
HID_Data_Struct * getHIDDataAll(int hid,int * size);
#ifdef __cplusplus
}
#endif
#endif /* _CONTROLLER_PATCHER_H_ */
#endif /* _CONTROLLER_PATCHER_DEFS_H_ */

View File

@ -0,0 +1,549 @@
/****************************************************************************
* 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 <vector>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include "ControllerPatcherHID.hpp"
#include "dynamic_libs/os_functions.h"
#include "../utils/CPRetainVars.hpp"
#include "../utils/CPStringTools.hpp"
#include "utils/logger.h"
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* public implementation for the network controller
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
int ControllerPatcherHID::externAttachDetachCallback(HIDDevice *p_device, unsigned int attach){
log_printf("ControllerPatcherHID::externAttachDetachCallback called\n");
HIDClient client;
memset(&client,0,sizeof(client));
return AttachDetachCallback(&client,p_device,attach);
}
void ControllerPatcherHID::externHIDReadCallback(unsigned int handle, unsigned char *buf, unsigned int bytes_transfered, my_cb_user * usr){
HIDReadCallback(handle,buf,bytes_transfered,usr);
}
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* private implementation for the HID Api.
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
int ControllerPatcherHID::myAttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, unsigned int attach){
return AttachDetachCallback(p_client,p_device,attach);
}
void ControllerPatcherHID::myHIDMouseReadCallback(unsigned int handle, int error, unsigned char *buf, unsigned int 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;
//log_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;
//log_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(unsigned int handle, int error, unsigned char *buf, unsigned int 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_GC){
HIDRead(handle, usr->buf, bytes_transfered, myHIDReadCallback, usr);
}else if(usr->slotdata.hidmask != 0){
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
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
int ControllerPatcherHID::AttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, unsigned int attach){
if(attach){
log_printf("vid %04x pid %04x connected\n", SWAP16(p_device->vid),SWAP16(p_device->pid));
if(HID_DEBUG) log_printf("interface index %02x\n", p_device->interface_index);
if(HID_DEBUG) log_printf("sub class %02x\n", p_device->sub_class);
if(HID_DEBUG) log_printf("protocol %02x\n", p_device->protocol);
if(HID_DEBUG) log_printf("max packet in %02x\n", p_device->max_packet_size_rx);
if(HID_DEBUG) log_printf("max packet out %02x\n", p_device->max_packet_size_tx);
}
if(!attach){
log_printf("vid %04x pid %04x disconnected\n", 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;
//log_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;
//log_printf("Found Mouse: device: %s slot: %d\n",byte_to_binary(device_info.hid),device_info.slot);
}else{
int ret;
if((ret = ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info)) < 0){
log_printf("ControllerPatcherHID::AttachDetachCallback: ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) failed %d \n",ret);
return HID_DEVICE_DETACH;
}else{
if(HID_DEBUG) log_printf("ControllerPatcherUtils::getDeviceInfoFromVidPid(&device_info) success %d \n",ret);
}
}
if(slotdata->hidmask){
if(attach){
int 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;
gHIDAttached |= slotdata->hidmask;
gHIDCurrentDevice |= slotdata->hidmask;
int 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;
}
}
int pad_count = config_controller[slotdata->deviceslot][CONTRPS_CONNECTED_PADS][1];
if(pad_count > 0x0F) pad_count = 0;
int pad_slot = 0;
int failed = 1;
for(int 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){
log_printf("ControllerPatcherHID::AttachDetachCallback error: I can only handle %d devices of the same type. Sorry \n",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(int 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;
//log_printf("saved handle %d to slot %d and pad %d\n",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));
}
if(HID_DEBUG) log_print("AttachDetachCallback: Device successfully attached\n");
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_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;
int founddata = 0;
for(int 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){
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) log_print("ControllerPatcherHID::AttachDetachCallback: user_data null. You may have a memory leak.\n");
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)log_printf("ControllerPatcherHID::AttachDetachCallback: We still have pad for deviceslot %d connected.\n",slotdata->deviceslot);
}
if(HID_DEBUG)log_print("AttachDetachCallback: Device successfully detached\n");
}
}else{
log_print("ControllerPatcherHID::AttachDetachCallback: HID-Device currently not supported! You can add support through config files\n");
}
return HID_DEVICE_DETACH;
}
void ControllerPatcherHID::HIDReadCallback(unsigned int handle, unsigned char *buf, unsigned int bytes_transfered, my_cb_user * usr){
//log_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(int 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.
}
/*
int i = 0;
log_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++;
log_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++;
log_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++;
log_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){
int dsize = (HID_MAX_DATA_LENGTH_PER_PAD > bytes_transfered)? bytes_transfered : HID_MAX_DATA_LENGTH_PER_PAD;
int 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(VPADData * buffer,std::vector<HID_Data *>& data){
if(buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
HID_Data * data_cur;
int 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.
int last_realbuttons = (data_cur->last_buttons) & VPAD_MASK_BUTTONS;
buffer->btns_h |= buttons_hold;
buffer->btns_d |= (buttons_hold & (~last_realbuttons));
buffer->btns_r |= (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->lstick);
ControllerPatcherUtils::normalizeStickValues(&buffer->rstick);
}
return CONTROLLER_PATCHER_ERROR_NONE;
}
std::vector<HID_Data *> ControllerPatcherHID::getHIDDataAll(){
int hid = gHIDCurrentDevice;
std::vector<HID_Data *> data_list;
for(int i = 0;i < gHIDMaxDevices;i++){
if((hid & (1 << i)) != 0){
int cur_hidmask = config_controller_hidmask[i];
for(int pad = 0; pad < HID_MAX_PADS_COUNT; pad++){
int res;
HID_Data * new_data = NULL;
if((res = ControllerPatcherHID::getHIDData(cur_hidmask,pad,&new_data)) < 0){ // Checks if the pad is invalid.
log_printf("ControllerPatcherHID::getHIDDataAll() error: Error getting the HID data from HID(%s) CHAN(). Error %d\n",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(int hidmask, int 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;
int device_slot = ControllerPatcherUtils::getDeviceSlot(hidmask);
if(device_slot < 0){
return CONTROLLER_PATCHER_ERROR_DEVICE_SLOT_NOT_FOUND;
}
int real_pad = pad;
if(device_slot != gHID_SLOT_GC && config_controller[device_slot][CONTRPS_PAD_COUNT][0] != CONTROLLER_PATCHER_INVALIDVALUE){
int 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;
}
int 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(unsigned int handle,my_cb_user *usr){
int rumblechanged = 0;
for(int i = 0;i<HID_MAX_PADS_COUNT;i++){
HID_Data * data_ptr = &(gHID_Devices[usr->slotdata.deviceslot].pad_data[i]);
if(data_ptr->rumbleActive != usr->rumblestatus[i]){
usr->rumblestatus[i] = data_ptr->rumbleActive;
usr->buf[i+1] = usr->rumblestatus[i];
rumblechanged = 1;
}
}
if(rumblechanged){
usr->buf[0] = 0x11;
HIDWrite(handle, usr->buf, 5, NULL, NULL);
}
}
void ControllerPatcherHID::HIDRumble(unsigned int handle,my_cb_user *usr,u32 pad){
int 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;
}
if(rumblechanged){
if(usr->slotdata.hidmask == gHID_LIST_DS3){
HIDDS3Rumble(handle,usr,usr->rumblestatus[pad]);
}else{
// Not implemented for other devices =(
}
}
}
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(unsigned int handle,my_cb_user *usr,int 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);
}

View 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 <gctypes.h>
#include <vector>
#include "dynamic_libs/syshid_functions.h"
#include "dynamic_libs/vpad_functions.h"
#include "./ControllerPatcherUtils.hpp"
#include "./ControllerPatcherDefs.h"
#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 int externAttachDetachCallback(HIDDevice *p_device, unsigned int attach);
static void externHIDReadCallback(unsigned int handle, unsigned char *buf, unsigned int bytes_transfered, my_cb_user * usr);
private:
static CONTROLLER_PATCHER_RESULT_OR_ERROR setVPADControllerData(VPADData * buffer,std::vector<HID_Data *>& data);
static std::vector<HID_Data *> getHIDDataAll();
static CONTROLLER_PATCHER_RESULT_OR_ERROR getHIDData(int hidmask, int pad, HID_Data ** data);
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Rumble
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
static void HIDRumble(unsigned int handle,my_cb_user *usr,u32 pad);
static void HIDGCRumble(unsigned int handle,my_cb_user *usr);
static void HIDDS3Rumble(unsigned int handle,my_cb_user *usr,int rumble);
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* HID Callbacks
*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
static int myAttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, unsigned int attach);
static void myHIDMouseReadCallback(unsigned int handle, int error, unsigned char *buf, unsigned int bytes_transfered, void *p_user);
static void myHIDReadCallback(unsigned int handle, int error, unsigned char *buf, unsigned int bytes_transfered, void *p_user);
static int AttachDetachCallback(HIDClient *p_client, HIDDevice *p_device, unsigned int attach);
static void HIDReadCallback(unsigned int handle, unsigned char *buf, unsigned int bytes_transfered, my_cb_user * usr);
};
#endif /* _CONTROLLER_PATCHER_HID_H_ */

View File

@ -0,0 +1,901 @@
/****************************************************************************
* 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 <math.h>
#include <string.h>
#include "ControllerPatcherUtils.hpp"
#include "../utils/PadConst.hpp"
#include "utils/logger.h"
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getDataByHandle(int handle, my_cb_user ** data){
for(int i = 0;i< gHIDMaxDevices;i++){
for(int j = 0;j<4;j++){
//log_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, int * buttons_hold, int VPADButton){
if(data == NULL || buttons_hold == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
int deviceslot = data->slotdata.deviceslot;
int 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;
int 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){
int 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){
int 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{
//log_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,int 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;
int hidmask = data->slotdata.hidmask;
int deviceslot = data->slotdata.deviceslot;
int 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]){
result = 1;
}
}
}
return result;
}
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::isInKeyboardData(unsigned char * keyboardData,int key){
if(keyboardData == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
for(int 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(VPADData * old_buffer, VPADData * new_buffer,u32 VPADButton, int 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(VPADData * old_buffer, VPADData * new_buffer,u32 oldVPADButton,u32 newVPADButton){
if(old_buffer == NULL || new_buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
if((old_buffer->btns_h & oldVPADButton) == oldVPADButton){
new_buffer->btns_h |= newVPADButton;
}
if((old_buffer->btns_r & oldVPADButton) == oldVPADButton){
new_buffer->btns_r |= newVPADButton;
}
if((old_buffer->btns_d & oldVPADButton) == oldVPADButton){
new_buffer->btns_d |= newVPADButton;
}
return CONTROLLER_PATCHER_ERROR_NONE;
}
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Pad Status functions
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::checkActivePad(int hidmask,int 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{
int deviceslot = getDeviceSlot(hidmask);
if(deviceslot < 0 ) return CONTROLLER_PATCHER_ERROR_DEVICE_SLOT_NOT_FOUND;
int connected_pads = config_controller[deviceslot][CONTRPS_CONNECTED_PADS][1];
if(connected_pads & (1 << pad)){
return 1;
}
}
return CONTROLLER_PATCHER_ERROR_NO_PAD_CONNECTED;
}
/*
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getActivePad(int 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(Vec2D * 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));
}
}
Vec2D ControllerPatcherUtils::getAnalogValueByButtons(u8 stick_values){
Vec2D stick;
stick.x = 0.0f;
stick.y = 0.0f;
u8 up = (stick_values & STICK_VALUE_UP);
u8 down = (stick_values & STICK_VALUE_DOWN);
u8 left = (stick_values & STICK_VALUE_LEFT);
u8 right = (stick_values & STICK_VALUE_RIGHT);
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, VPADData * buffer){
if(buffer == NULL || data == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
int 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->lstick.x += x_value;
buffer->lstick.y += y_value;
return CONTROLLER_PATCHER_ERROR_NONE;
}
}
buffer->rstick.x += x_value;
buffer->rstick.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;
int 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->lstick.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->lstick.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->rstick.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->rstick.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 ){
Vec2D stick = getAnalogValueByButtons(stick_values);
buffer->lstick.x += stick.x;
buffer->lstick.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 ){
Vec2D stick = getAnalogValueByButtons(stick_values);
buffer->rstick.x += stick.x;
buffer->rstick.y += stick.y;
}
/*log_printf("LX %f(%02X) LY %f(%02X) RX %f(%02X) RY %f(%02X)\n",buffer->lstick.x,cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][0]],
buffer->lstick.y,cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][0]],
buffer->rstick.x,cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][0]],
buffer->rstick.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(VPADData * buffer, u32 * last_emulatedSticks){
if(buffer == NULL || last_emulatedSticks == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
u32 emulatedSticks = 0;
int l_x_full = (buffer->lstick.x > 0.5f || buffer->lstick.x < -0.5f)? 1:0;
int l_y_full = (buffer->lstick.y > 0.5f || buffer->lstick.y < -0.5f)? 1:0;
int r_x_full = (buffer->rstick.x > 0.5f || buffer->rstick.x < -0.5f)? 1:0;
int r_y_full = (buffer->rstick.y > 0.5f || buffer->rstick.y < -0.5f)? 1:0;
if((buffer->lstick.x > 0.5f) || (buffer->lstick.x > 0.1f && !l_y_full)){
emulatedSticks |= VPAD_STICK_L_EMULATION_RIGHT;
}
if((buffer->lstick.x < -0.5f) || (buffer->lstick.x < -0.1f && !l_y_full)){
emulatedSticks |= VPAD_STICK_L_EMULATION_LEFT;
}
if((buffer->lstick.y > 0.5f) || (buffer->lstick.y > 0.1f && !l_x_full)){
emulatedSticks |= VPAD_STICK_L_EMULATION_UP;
}
if((buffer->lstick.y < -0.5f) || (buffer->lstick.y < -0.1f && !l_x_full)){
emulatedSticks |= VPAD_STICK_L_EMULATION_DOWN;
}
if((buffer->rstick.x > 0.5f) || (buffer->rstick.x > 0.1f && !r_y_full)){
emulatedSticks |= VPAD_STICK_R_EMULATION_RIGHT;
}
if((buffer->rstick.x < -0.5f) || (buffer->rstick.x < -0.1f && !r_y_full)){
emulatedSticks |= VPAD_STICK_R_EMULATION_LEFT;
}
if((buffer->rstick.y > 0.5f) || (buffer->rstick.y > 0.1f && !r_x_full)){
emulatedSticks |= VPAD_STICK_R_EMULATION_UP;
}
if((buffer->rstick.y < -0.5f) || (buffer->rstick.y < -0.1f && !r_x_full)){
emulatedSticks |= VPAD_STICK_R_EMULATION_DOWN;
}
//Setting the emulated sticks
buffer->btns_h |= emulatedSticks;
buffer->btns_d |= (emulatedSticks & (~*last_emulatedSticks));
buffer->btns_r |= (*last_emulatedSticks & (~emulatedSticks));
*last_emulatedSticks = emulatedSticks;
return CONTROLLER_PATCHER_ERROR_NONE;
}
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Touch functions
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::setTouch(HID_Data * data,VPADData * 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){
int 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;
int x_mouse = 80 + ((int)(((ms_data->X)*1.0f/1280.0)*3890.0f));
int y_mouse = 3910 - ((int)(((ms_data->Y)*1.0f/720.0)*3760.0f));
buffer->tpdata.x = x_mouse;
buffer->tpdata.y = y_mouse;
buffer->tpdata.touched = 1;
buffer->tpdata.invalid = 0;
buffer->tpdata1.x = x_mouse;
buffer->tpdata1.y = y_mouse;
buffer->tpdata1.touched = 1;
buffer->tpdata1.invalid = 0;
buffer->tpdata2.x = x_mouse;
buffer->tpdata2.y = y_mouse;
buffer->tpdata2.touched = 1;
buffer->tpdata2.invalid = 0;
}
}
return CONTROLLER_PATCHER_ERROR_NONE;
}
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::checkAndSetMouseMode(HID_Data * data){
int 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) log_print("ControllerPatcherUtils::checkAndSetMouseMode: Mouse mode changed! to touch \n");
}else if(gHID_Mouse_Mode == HID_MOUSE_MODE_TOUCH){
if(HID_DEBUG) log_print("ControllerPatcherUtils::checkAndSetMouseMode: Mouse mode changed! to aim \n");
gHID_Mouse_Mode = HID_MOUSE_MODE_AIM;
}
}
}
return CONTROLLER_PATCHER_ERROR_NONE;
}
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Other functions
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::translateToPro(VPADData * vpad_buffer,KPADData * pro_buffer,u32 * lastButtonsPressesPRO){
if(vpad_buffer == NULL || pro_buffer == NULL || lastButtonsPressesPRO == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
int buttons_hold = 0;
pro_buffer->pro.btns_h = 0;
pro_buffer->pro.btns_d = 0;
pro_buffer->pro.btns_r = 0;
if(vpad_buffer->btns_h & VPAD_BUTTON_A) buttons_hold |= WPAD_PRO_BUTTON_A;
if(vpad_buffer->btns_h & VPAD_BUTTON_B) buttons_hold |= WPAD_PRO_BUTTON_B;
if(vpad_buffer->btns_h & VPAD_BUTTON_X) buttons_hold |= WPAD_PRO_BUTTON_X;
if(vpad_buffer->btns_h & VPAD_BUTTON_Y) buttons_hold |= WPAD_PRO_BUTTON_Y;
if(vpad_buffer->btns_h & VPAD_BUTTON_PLUS) buttons_hold |= WPAD_PRO_BUTTON_PLUS;
if(vpad_buffer->btns_h & VPAD_BUTTON_MINUS) buttons_hold |= WPAD_PRO_BUTTON_MINUS;
if(vpad_buffer->btns_h & VPAD_BUTTON_HOME) buttons_hold |= WPAD_PRO_BUTTON_HOME;
if(vpad_buffer->btns_h & VPAD_BUTTON_LEFT) buttons_hold |= WPAD_PRO_BUTTON_LEFT;
if(vpad_buffer->btns_h & VPAD_BUTTON_RIGHT) buttons_hold |= WPAD_PRO_BUTTON_RIGHT;
if(vpad_buffer->btns_h & VPAD_BUTTON_UP) buttons_hold |= WPAD_PRO_BUTTON_UP;
if(vpad_buffer->btns_h & VPAD_BUTTON_DOWN) buttons_hold |= WPAD_PRO_BUTTON_DOWN;
if(vpad_buffer->btns_h & VPAD_BUTTON_L) buttons_hold |= WPAD_PRO_TRIGGER_L;
if(vpad_buffer->btns_h & VPAD_BUTTON_ZL) buttons_hold |= WPAD_PRO_TRIGGER_ZL;
if(vpad_buffer->btns_h & VPAD_BUTTON_R) buttons_hold |= WPAD_PRO_TRIGGER_R;
if(vpad_buffer->btns_h & VPAD_BUTTON_ZR) buttons_hold |= WPAD_PRO_TRIGGER_ZR;
if(vpad_buffer->btns_h & VPAD_BUTTON_STICK_L) buttons_hold |= WPAD_PRO_BUTTON_STICK_L;
if(vpad_buffer->btns_h & VPAD_BUTTON_STICK_R) buttons_hold |= WPAD_PRO_BUTTON_STICK_R;
if(vpad_buffer->btns_h & VPAD_STICK_L_EMULATION_LEFT) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_LEFT;
if(vpad_buffer->btns_h & VPAD_STICK_L_EMULATION_RIGHT) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_RIGHT;
if(vpad_buffer->btns_h & VPAD_STICK_L_EMULATION_UP) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_UP;
if(vpad_buffer->btns_h & VPAD_STICK_L_EMULATION_DOWN) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_DOWN;
if(vpad_buffer->btns_h & VPAD_STICK_R_EMULATION_LEFT) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_LEFT;
if(vpad_buffer->btns_h & VPAD_STICK_R_EMULATION_RIGHT) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_RIGHT;
if(vpad_buffer->btns_h & VPAD_STICK_R_EMULATION_UP) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_UP;
if(vpad_buffer->btns_h & VPAD_STICK_R_EMULATION_DOWN) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_DOWN;
pro_buffer->pro.lstick_x = vpad_buffer->lstick.x;
pro_buffer->pro.lstick_y = vpad_buffer->lstick.y;
pro_buffer->pro.rstick_x = vpad_buffer->rstick.x;
pro_buffer->pro.rstick_y = vpad_buffer->rstick.y;
pro_buffer->pro.btns_h |= buttons_hold;
pro_buffer->pro.btns_d |= (buttons_hold & (~*lastButtonsPressesPRO));
pro_buffer->pro.btns_r |= (*lastButtonsPressesPRO & (~buttons_hold));
*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(VPADData * vpad_buffer,WPADReadData * pro_buffer){
if(vpad_buffer == NULL || pro_buffer == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
int buttons_hold = 0;
pro_buffer->buttons = 0;
if(vpad_buffer->btns_h & VPAD_BUTTON_A) buttons_hold |= WPAD_PRO_BUTTON_A;
if(vpad_buffer->btns_h & VPAD_BUTTON_B) buttons_hold |= WPAD_PRO_BUTTON_B;
if(vpad_buffer->btns_h & VPAD_BUTTON_X) buttons_hold |= WPAD_PRO_BUTTON_X;
if(vpad_buffer->btns_h & VPAD_BUTTON_Y) buttons_hold |= WPAD_PRO_BUTTON_Y;
if(vpad_buffer->btns_h & VPAD_BUTTON_PLUS) buttons_hold |= WPAD_PRO_BUTTON_PLUS;
if(vpad_buffer->btns_h & VPAD_BUTTON_MINUS) buttons_hold |= WPAD_PRO_BUTTON_MINUS;
if(vpad_buffer->btns_h & VPAD_BUTTON_HOME) buttons_hold |= WPAD_PRO_BUTTON_HOME;
if(vpad_buffer->btns_h & VPAD_BUTTON_LEFT) buttons_hold |= WPAD_PRO_BUTTON_LEFT;
if(vpad_buffer->btns_h & VPAD_BUTTON_RIGHT) buttons_hold |= WPAD_PRO_BUTTON_RIGHT;
if(vpad_buffer->btns_h & VPAD_BUTTON_UP) buttons_hold |= WPAD_PRO_BUTTON_UP;
if(vpad_buffer->btns_h & VPAD_BUTTON_DOWN) buttons_hold |= WPAD_PRO_BUTTON_DOWN;
if(vpad_buffer->btns_h & VPAD_BUTTON_L) buttons_hold |= WPAD_PRO_TRIGGER_L;
if(vpad_buffer->btns_h & VPAD_BUTTON_ZL) buttons_hold |= WPAD_PRO_TRIGGER_ZL;
if(vpad_buffer->btns_h & VPAD_BUTTON_R) buttons_hold |= WPAD_PRO_TRIGGER_R;
if(vpad_buffer->btns_h & VPAD_BUTTON_ZR) buttons_hold |= WPAD_PRO_TRIGGER_ZR;
if(vpad_buffer->btns_h & VPAD_BUTTON_STICK_L) buttons_hold |= WPAD_PRO_BUTTON_STICK_L;
if(vpad_buffer->btns_h & VPAD_BUTTON_STICK_R) buttons_hold |= WPAD_PRO_BUTTON_STICK_R;
if(vpad_buffer->btns_h & VPAD_STICK_L_EMULATION_LEFT) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_LEFT;
if(vpad_buffer->btns_h & VPAD_STICK_L_EMULATION_RIGHT) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_RIGHT;
if(vpad_buffer->btns_h & VPAD_STICK_L_EMULATION_UP) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_UP;
if(vpad_buffer->btns_h & VPAD_STICK_L_EMULATION_DOWN) buttons_hold |= WPAD_PRO_STICK_L_EMULATION_DOWN;
if(vpad_buffer->btns_h & VPAD_STICK_R_EMULATION_LEFT) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_LEFT;
if(vpad_buffer->btns_h & VPAD_STICK_R_EMULATION_RIGHT) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_RIGHT;
if(vpad_buffer->btns_h & VPAD_STICK_R_EMULATION_UP) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_UP;
if(vpad_buffer->btns_h & VPAD_STICK_R_EMULATION_DOWN) buttons_hold |= WPAD_PRO_STICK_R_EMULATION_DOWN;
pro_buffer->l_stick_x = (s16) (vpad_buffer->lstick.x * 1200.0f);
pro_buffer->l_stick_y = (s16) (vpad_buffer->lstick.y * 1200.0f);
pro_buffer->r_stick_x = (s16) (vpad_buffer->rstick.x * 1200.0f);
pro_buffer->r_stick_y = (s16) (vpad_buffer->rstick.y * 1200.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(VPADData * vpad_buffer,KPADData * pro_buffer,u32 * lastButtonsPressesVPAD){
if(vpad_buffer == NULL || pro_buffer == NULL || lastButtonsPressesVPAD == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
int buttons_hold = 0;
vpad_buffer->btns_h = 0;
vpad_buffer->btns_d = 0;
vpad_buffer->btns_r = 0;
if(pro_buffer->pro.btns_h & WPAD_PRO_BUTTON_A) buttons_hold |= VPAD_BUTTON_A;
if(pro_buffer->pro.btns_h & WPAD_PRO_BUTTON_B) buttons_hold |= VPAD_BUTTON_B;
if(pro_buffer->pro.btns_h & WPAD_PRO_BUTTON_X) buttons_hold |= VPAD_BUTTON_X;
if(pro_buffer->pro.btns_h & WPAD_PRO_BUTTON_Y) buttons_hold |= VPAD_BUTTON_Y;
if(pro_buffer->pro.btns_h & WPAD_PRO_BUTTON_PLUS) buttons_hold |= VPAD_BUTTON_PLUS;
if(pro_buffer->pro.btns_h & WPAD_PRO_BUTTON_MINUS) buttons_hold |= VPAD_BUTTON_MINUS;
if(pro_buffer->pro.btns_h & WPAD_PRO_BUTTON_HOME) buttons_hold |= VPAD_BUTTON_HOME;
if(pro_buffer->pro.btns_h & WPAD_PRO_BUTTON_LEFT) buttons_hold |= VPAD_BUTTON_LEFT;
if(pro_buffer->pro.btns_h & WPAD_PRO_BUTTON_RIGHT) buttons_hold |= VPAD_BUTTON_RIGHT;
if(pro_buffer->pro.btns_h & WPAD_PRO_BUTTON_UP) buttons_hold |= VPAD_BUTTON_UP;
if(pro_buffer->pro.btns_h & WPAD_PRO_BUTTON_DOWN) buttons_hold |= VPAD_BUTTON_DOWN;
if(pro_buffer->pro.btns_h & WPAD_PRO_TRIGGER_L) buttons_hold |= VPAD_BUTTON_L;
if(pro_buffer->pro.btns_h & WPAD_PRO_TRIGGER_ZL) buttons_hold |= VPAD_BUTTON_ZL;
if(pro_buffer->pro.btns_h & WPAD_PRO_TRIGGER_R) buttons_hold |= VPAD_BUTTON_R;
if(pro_buffer->pro.btns_h & WPAD_PRO_TRIGGER_ZR) buttons_hold |= VPAD_BUTTON_ZR;
if(pro_buffer->pro.btns_h & WPAD_PRO_BUTTON_STICK_L) buttons_hold |= VPAD_BUTTON_STICK_L;
if(pro_buffer->pro.btns_h & WPAD_PRO_BUTTON_STICK_R) buttons_hold |= VPAD_BUTTON_STICK_R;
if(pro_buffer->pro.btns_h & WPAD_PRO_STICK_L_EMULATION_LEFT) buttons_hold |= VPAD_STICK_L_EMULATION_LEFT;
if(pro_buffer->pro.btns_h & WPAD_PRO_STICK_L_EMULATION_RIGHT) buttons_hold |= VPAD_STICK_L_EMULATION_RIGHT;
if(pro_buffer->pro.btns_h & WPAD_PRO_STICK_L_EMULATION_UP) buttons_hold |= VPAD_STICK_L_EMULATION_UP;
if(pro_buffer->pro.btns_h & WPAD_PRO_STICK_L_EMULATION_DOWN) buttons_hold |= VPAD_STICK_L_EMULATION_DOWN;
if(pro_buffer->pro.btns_h & WPAD_PRO_STICK_R_EMULATION_LEFT) buttons_hold |= VPAD_STICK_R_EMULATION_LEFT;
if(pro_buffer->pro.btns_h & WPAD_PRO_STICK_R_EMULATION_RIGHT) buttons_hold |= VPAD_STICK_R_EMULATION_RIGHT;
if(pro_buffer->pro.btns_h & WPAD_PRO_STICK_R_EMULATION_UP) buttons_hold |= VPAD_STICK_R_EMULATION_UP;
if(pro_buffer->pro.btns_h & WPAD_PRO_STICK_R_EMULATION_DOWN) buttons_hold |= VPAD_STICK_R_EMULATION_DOWN;
vpad_buffer->lstick.x = pro_buffer->pro.lstick_x;
vpad_buffer->lstick.y = pro_buffer->pro.lstick_y;
vpad_buffer->rstick.x = pro_buffer->pro.rstick_x;
vpad_buffer->rstick.y = pro_buffer->pro.rstick_y;
vpad_buffer->btns_h |= buttons_hold;
vpad_buffer->btns_d |= (buttons_hold & (~*lastButtonsPressesVPAD));
vpad_buffer->btns_r |= (*lastButtonsPressesVPAD & (~buttons_hold));
*lastButtonsPressesVPAD = buttons_hold;
return CONTROLLER_PATCHER_ERROR_NONE;
}
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::checkValueinConfigController(int deviceslot,int CONTRPS_slot,int 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(int hidmask){
for(int 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(int 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];
//log_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;
return CONTROLLER_PATCHER_ERROR_NONE;
//log_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(int deviceslot, DeviceVIDPIDInfo * vidpid){
if(vidpid == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
if(deviceslot >= gHIDMaxDevices) 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;
}
int ControllerPatcherUtils::getPadSlotInAdapter(int deviceslot, u8 * input_data){
int slot_incr = 0;
if(config_controller[deviceslot][CONTRPS_PAD_COUNT][0] != CONTROLLER_PATCHER_INVALIDVALUE){
int pad_count = config_controller[deviceslot][CONTRPS_PAD_COUNT][1];
if(pad_count > HID_MAX_PADS_COUNT){
pad_count = HID_MAX_PADS_COUNT;
}
for(int 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;
}

View File

@ -0,0 +1,319 @@
/****************************************************************************
* 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 <gctypes.h>
#include "../ControllerPatcher.hpp"
#include "./ControllerPatcherHID.hpp"
#include "../utils/CPRetainVars.hpp"
#include "dynamic_libs/vpad_functions.h"
#include "dynamic_libs/padscore_functions.h"
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(int 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(int 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(int deviceslot, DeviceVIDPIDInfo * vidpid);
/** \brief Set the VPAD data for a given KPAD data.
*
* \param vpad_buffer VPADData* 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(VPADData * 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, int * buttons_hold, int 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,int 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,int 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 VPADData struct from which will be read.
* \param new_buffer A pointer to a VPADData 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(VPADData * old_buffer, VPADData * new_buffer,u32 VPADButton, int CONTRPS_SLOT);
/**
\brief Checks if a given button (oldVPADButton) is set in a given VPADData struct (old_buffer). If its set, it will set an other
button (newVPADButton) to the second given VPADData struct (new_buffer)
\param old_buffer A pointer to a VPADData struct from which will be read.
\param new_buffer A pointer to a VPADData struct where the result will be written.
\param oldVPADButton The buttons that need to be set in the first VPADData
\param newVPADButton The buttons that will be set in the second VPADData, 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(VPADData * old_buffer, VPADData * 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(int hidmask,int 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(int 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(Vec2D * 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 (Vec2D) 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 Vec2D with the set values.
**/
static Vec2D getAnalogValueByButtons(u8 stick_values);
/**
\brief Handles the analog-stick data of HID devices. The result will written in the VPADData buffer.
\param data Pointer to the current data of the HID device
\param buffer Pointer to VPADData 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,VPADData * buffer);
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Mouse functions
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/**
\brief Set the touch data in the VPADData 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 VPADData 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,VPADData * 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(VPADData * buffer, u32 * last_emulatedSticks);
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Other functions
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/** \brief Set the Pro Controller for a given VPAD data.
*
* \param vpad_buffer VPADData* 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(VPADData * vpad_buffer,KPADData * pro_buffer,u32 * lastButtonsPressesPRO);
static CONTROLLER_PATCHER_RESULT_OR_ERROR translateToProWPADRead(VPADData * 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(int device_slot,int CONTRPS_slot,int 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 int getPadSlotInAdapter(int 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);
};
#endif /* _CONTROLLER_PATCHER_UTIL_H_ */

View File

@ -1,19 +0,0 @@
#ifndef _STRING_TOOLS_H_
#define _STRING_TOOLS_H_
bool EndsWith(const std::string& a, const std::string& b);
std::vector<std::string> MyStringSplit(const std::string & inValue, const std::string & splitter);
/* Main */
#ifdef __cplusplus
extern "C" {
#endif
//! C wrapper for our C++ functions
const char *byte_to_binary(int x);
#ifdef __cplusplus
}
#endif
#endif /* _STRING_TOOLS_H_ */

View File

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (C) 2016 Maschell
* 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
@ -14,15 +14,15 @@
* 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 <gctypes.h>
#include "controller_patcher.h"
#include "cp_retain_vars.h"
#include "../patcher/ControllerPatcherDefs.h"
#include "../utils/CPRetainVars.hpp"
ControllerMapping gControllerMapping __attribute__((section(".data")));
u8 gConfig_done __attribute__((section(".data"))) = 0;
u8 gButtonRemappingConfigDone __attribute__((section(".data"))) = 0;
u8 gHIDSetupDone __attribute__((section(".data"))) = 0;
u16 gHIDAttached __attribute__((section(".data"))) = 0;
u16 gHIDCurrentDevice __attribute__((section(".data"))) = 0;
@ -32,15 +32,12 @@ HIDClient gHIDClient __attribute__((section(".data")));
HID_DEVICE_DATA gHID_Devices[gHIDMaxDevices] __attribute__((section(".data")));
HID_Mouse gHID_Mouse __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")));
u16 config_controller_list[gHIDMaxDevices] __attribute__((section(".data")));
u32 config_controller_data_ptr[gHIDMaxDevices][HID_MAX_PADS_COUNT] __attribute__((section(".data")));
u8 config_controller[gHIDMaxDevices][CONTRPS_MAX_VALUE][2] __attribute__((section(".data")));
u16 config_controller_hidmask[gHIDMaxDevices] __attribute__((section(".data")));
u16 gHID_LIST_GC __attribute__((section(".data"))) = 0;
u16 gHID_LIST_DS3 __attribute__((section(".data"))) = 0;
@ -51,3 +48,9 @@ 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;

View File

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (C) 2016 Maschell
* 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
@ -18,32 +18,27 @@
#define CP_RETAINS_VARS_H_
#include "dynamic_libs/syshid_functions.h"
#include "controller_patcher/controller_patcher.h"
#include "../patcher/ControllerPatcherDefs.h"
extern ControllerMapping gControllerMapping;
extern u8 gConfig_done;
extern u8 gButtonRemappingConfigDone;
extern u8 gHIDSetupDone;
extern u16 gHIDAttached;
extern u16 gHIDCurrentDevice;
extern HIDClient gHIDClient;
#define gHIDMaxDevices 16
#define HID_INVALID_SLOT 0xFFFF
extern u16 gHIDRegisteredDevices;
extern HID_DEVICE_DATA gHID_Devices[gHIDMaxDevices];
extern HID_Mouse gHID_Mouse;
extern u8 gHID_Mouse_Mode;
extern u32 gGamePadValues[CONTRPS_MAX_VALUE];
extern u8 config_controller[gHIDMaxDevices][CONTRPS_MAX_VALUE][2];
extern u16 config_controller_list[gHIDMaxDevices];
extern u32 config_controller_data_ptr[gHIDMaxDevices][4]; //currently max per device
extern u16 config_controller_hidmask[gHIDMaxDevices];
extern u16 gHID_LIST_GC;
extern u16 gHID_LIST_DS3;
@ -55,4 +50,10 @@ 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;
#endif // CP_RETAINS_VARS_H_

View File

@ -1,18 +1,19 @@
#include <string>
#include <vector>
#include <stdio.h>
#include <string.h>
#include <gctypes.h>
#include "string_tools.hpp"
#include "CPStringTools.hpp"
#include "PadConst.hpp"
#include <stdarg.h>
#include <stdlib.h>
bool EndsWith(const std::string& a, const std::string& b) {
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> MyStringSplit(const std::string & inValue, const std::string & splitter)
{
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) {
@ -35,9 +36,7 @@ std::vector<std::string> MyStringSplit(const std::string & inValue, const std::s
return result;
}
extern "C" const char *byte_to_binary(int x)
{
const char * CPStringTools::byte_to_binary(int x){
static char b[9];
b[0] = '\0';
@ -49,3 +48,36 @@ extern "C" const char *byte_to_binary(int x)
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

15
utils/CPStringTools.hpp Normal file
View File

@ -0,0 +1,15 @@
#ifndef _CPSTRING_TOOLS_H_
#define _CPSTRING_TOOLS_H_
#include <string>
#include <vector>
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(int x);
static std::string strfmt(const char * format, ...);
};
#endif /* _CPSTRING_TOOLS_H_ */

View File

@ -0,0 +1,121 @@
/****************************************************************************
* 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 <gctypes.h>
#include <malloc.h>
#include <unistd.h>
#include "dynamic_libs/os_functions.h"
#include "utils/logger.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 = memalign(8, 0x1000);
//! allocate the stack
pThreadStack = (u8 *) memalign(0x20, iStackSize);
//! create the thread
if(pThread && pThreadStack)
OSCreateThread(pThread, &ControllerPatcherThread::threadCallback, 1, this, (u32)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))
{
while(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 eCThreadAttributes
{
eAttributeNone = 0x07,
eAttributeAffCore0 = 0x01,
eAttributeAffCore1 = 0x02,
eAttributeAffCore2 = 0x04,
eAttributeDetach = 0x08,
eAttributePinnedAff = 0x10
};
private:
static int threadCallback(int argc, void *arg)
{
//! After call to start() continue with the internal function
((ControllerPatcherThread *) arg)->executeThread();
return 0;
}
int iAttributes;
void *pThread;
u8 *pThreadStack;
Callback pCallback;
void *pCallbackArg;
};
#endif

View File

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (C) 2016 Maschell
* 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
@ -15,25 +15,26 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "pad_const.h"
const u8 DEF_L_STICK_UP = 201;
const u8 DEF_L_STICK_DOWN = 202;
const u8 DEF_L_STICK_LEFT = 203;
const u8 DEF_L_STICK_RIGHT = 204;
const u8 DEF_R_STICK_UP = 205;
const u8 DEF_R_STICK_DOWN = 206;
const u8 DEF_R_STICK_LEFT = 207;
const u8 DEF_R_STICK_RIGHT = 208;
#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;
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
@ -214,4 +215,61 @@ const u8 HID_DS4_STICK_R_Y[STICK_CONF_ENUM_MAXVALUE] = { STICK_CONF_MAGIC_VAL
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,

View File

@ -1,5 +1,5 @@
/****************************************************************************
* Copyright (C) 2016 Maschell
* 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
@ -18,22 +18,9 @@
#ifndef _PAD_CONST_H_
#define _PAD_CONST_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <gctypes.h>
#include "controller_patcher.h"
extern const u8 DEF_L_STICK_UP;
extern const u8 DEF_L_STICK_DOWN;
extern const u8 DEF_L_STICK_LEFT;
extern const u8 DEF_L_STICK_RIGHT;
extern const u8 DEF_R_STICK_UP;
extern const u8 DEF_R_STICK_DOWN;
extern const u8 DEF_R_STICK_LEFT;
extern const u8 DEF_R_STICK_RIGHT;
#include <string>
#include "../patcher/ControllerPatcherDefs.h"
extern const u8 DEF_R_STICK;
extern const u8 DEF_L_STICK;
@ -42,6 +29,18 @@ 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
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -139,8 +138,37 @@ 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];
#ifdef __cplusplus
}
#endif
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//! 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];
#endif /* _PAD_CONST_H_ */