mirror of
https://github.com/Maschell/controller_patcher.git
synced 2024-11-24 21:16:52 +01:00
Updated the controller patcher engine for the new HID to VPAD update.
This commit is contained in:
parent
b1e2068829
commit
1c3935dd93
@ -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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -18,137 +18,37 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "config_reader.h"
|
#include "ConfigReader.hpp"
|
||||||
#include "config_parser.h"
|
#include "config/ConfigParser.hpp"
|
||||||
#include "config_values.h"
|
#include "config/ConfigValues.hpp"
|
||||||
#include "string_tools.hpp"
|
#include "utils/CPStringTools.hpp"
|
||||||
|
|
||||||
int ConfigReader::numberValidFiles = 0;
|
int ConfigReader::numberValidFiles = 0;
|
||||||
ConfigReader *ConfigReader::instance = NULL;
|
ConfigReader *ConfigReader::instance = NULL;
|
||||||
|
|
||||||
ConfigReader::ConfigReader()
|
ConfigReader::ConfigReader(){
|
||||||
{
|
|
||||||
InitOSFunctionPointers();
|
InitOSFunctionPointers();
|
||||||
InitFSFunctionPointers();
|
InitFSFunctionPointers();
|
||||||
int status = 0;
|
int status = 0;
|
||||||
if((status = InitSDCard()) == 0){
|
if((status = InitSDCard()) == 0){
|
||||||
log_printf("SD Card mounted for controller config!\n");
|
if(HID_DEBUG) log_printf("ConfigReader::ConfigReader(): 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);
|
|
||||||
}
|
|
||||||
}else{
|
}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){
|
void ConfigReader::ReadAllConfigs(){
|
||||||
for(std::vector<std::string>::iterator it = path.begin(); it != path.end(); ++it) {
|
std::vector<std::string> fileList = ScanFolder();
|
||||||
log_printf("Reading %s\n",it->c_str());
|
if(fileList.size() > 0){
|
||||||
std::string result = loadFileToString(*it);
|
if(HID_DEBUG) log_printf("ConfigReader::ConfigReader(): Found %d config files\n",fileList.size());
|
||||||
|
processFileList(fileList);
|
||||||
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("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{
|
ConfigReader::~ConfigReader(){
|
||||||
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()
|
|
||||||
{
|
|
||||||
if(HID_DEBUG) log_printf("~ConfigReader\n");
|
if(HID_DEBUG) log_printf("~ConfigReader\n");
|
||||||
freeFSHandles();
|
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(){
|
void ConfigReader::freeFSHandles(){
|
||||||
@ -163,6 +63,7 @@ void ConfigReader::freeFSHandles(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mounting the sdcard without any external lib to be portable
|
||||||
int ConfigReader::InitSDCard(){
|
int ConfigReader::InitSDCard(){
|
||||||
if(HID_DEBUG) log_printf("InitSDCard\n");
|
if(HID_DEBUG) log_printf("InitSDCard\n");
|
||||||
|
|
||||||
@ -193,13 +94,93 @@ int ConfigReader::InitSDCard(){
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}else{
|
}else{
|
||||||
log_printf("FSMount failed %d\n",status);
|
log_printf("ConfigReader::InitSDCard() error: FSMount failed %d\n",status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
log_printf("FSGetMountSource failed %d\n",status);
|
log_printf("ConfigReader::InitSDCard() error: FSGetMountSource failed %d\n",status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
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
82
ConfigReader.hpp
Normal 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
959
ControllerPatcher.cpp
Normal 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
239
ControllerPatcher.hpp
Normal 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_ */
|
61
README.md
61
README.md
@ -7,7 +7,7 @@ Detailed information about creating config files and adding support for more con
|
|||||||
# Where can I find config files
|
# Where can I find config files
|
||||||
Configfiles for all controllers are collection in [this repository](https://github.com/Maschell/controller_patch_configs)
|
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>
|
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>
|
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.
|
- 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
|
# Example implementation
|
||||||
### How to "install" it
|
### How to "install" it
|
||||||
In order to add hid support to your application, you need add these lines add each start up.
|
TODO!
|
||||||
```
|
|
||||||
#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)
|
|
||||||
```
|
|
||||||
|
|
||||||
# Credits:
|
# Credits:
|
||||||
- Maschell
|
- Maschell
|
||||||
|
@ -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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -19,22 +19,21 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "config_parser.h"
|
#include "../ConfigReader.hpp"
|
||||||
#include "config_reader.h"
|
#include "../utils/CPStringTools.hpp"
|
||||||
#include "config_values.h"
|
#include "./ConfigParser.hpp"
|
||||||
#include "string_tools.hpp"
|
#include "./ConfigValues.hpp"
|
||||||
|
|
||||||
ConfigParser::ConfigParser(std::string configData)
|
ConfigParser::ConfigParser(std::string configData){
|
||||||
{
|
|
||||||
this->content = configData;
|
this->content = configData;
|
||||||
this->contentLines = MyStringSplit(content, "\n");
|
this->contentLines = CPStringTools::StringSplit(content, "\n");
|
||||||
|
|
||||||
if(contentLines.empty())
|
if(contentLines.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//remove the comments and make everything uppercase
|
//remove the comments and make everything uppercase
|
||||||
for(u32 i = 0; i < contentLines.size(); i++){
|
for(u32 i = 0; i < contentLines.size(); i++){
|
||||||
std::vector<std::string> comments = MyStringSplit(contentLines[i], "//");
|
std::vector<std::string> comments = CPStringTools::StringSplit(contentLines[i], "//");
|
||||||
if(!comments.empty()){
|
if(!comments.empty()){
|
||||||
contentLines[i] = comments[0];
|
contentLines[i] = comments[0];
|
||||||
}
|
}
|
||||||
@ -53,8 +52,7 @@ ConfigParser::ConfigParser(std::string configData)
|
|||||||
Init();
|
Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigParser::~ConfigParser()
|
ConfigParser::~ConfigParser(){
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,30 +73,39 @@ void ConfigParser::setSlot(u16 newSlot){
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigParser::Init(){
|
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();
|
const char * line = contentLines[0].c_str();
|
||||||
int len = strlen(line);
|
int len = strlen(line);
|
||||||
std::string identify;
|
std::string identify;
|
||||||
if(line[0] == '[' && line[len-1] == ']'){
|
if(line[0] == '[' && line[len-1] == ']'){
|
||||||
identify = contentLines[0].substr(1,len-2);
|
identify = contentLines[0].substr(1,len-2);
|
||||||
}else{
|
}else{
|
||||||
log_printf("Not a proper config file!\n");
|
log_printf("ConfigParser::Init(): Not a proper config file!\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(identify.compare("GAMEPAD") == 0){
|
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);
|
setSlot(gGamePadSlot);
|
||||||
setType(PARSE_GAMEPAD);
|
setType(PARSE_GAMEPAD);
|
||||||
}else if(identify.compare("MOUSE") == 0){
|
}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);
|
setSlot(gMouseSlot);
|
||||||
setType(PARSE_MOUSE);
|
setType(PARSE_MOUSE);
|
||||||
|
this->vid = HID_MOUSE_VID;
|
||||||
|
this->pid = HID_MOUSE_PID;
|
||||||
}else if(identify.compare("KEYBOARD") == 0){
|
}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);
|
setSlot(gHID_SLOT_KEYBOARD);
|
||||||
setType(PARSE_KEYBOARD);
|
setType(PARSE_KEYBOARD);
|
||||||
|
this->vid = HID_KEYBOARD_VID;
|
||||||
|
this->pid = HID_KEYBOARD_PID;
|
||||||
}else{
|
}else{
|
||||||
log_printf("Its a controller config file!\n");
|
if(HID_DEBUG) log_printf("Its a controller config file!\n");
|
||||||
|
|
||||||
setSlot(getSlotController(identify));
|
setSlot(getSlotController(identify));
|
||||||
setType(PARSE_CONTROLLER);
|
setType(PARSE_CONTROLLER);
|
||||||
}
|
}
|
||||||
@ -113,12 +120,11 @@ bool ConfigParser::Init(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConfigParser::parseSingleLine(std::string line){
|
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(cur_values.size() != 2){
|
||||||
if(HID_DEBUG || cur_values.size() > 2) log_printf("Not a valid key=pair line %s\n",line.c_str());
|
if(HID_DEBUG || cur_values.size() > 2) log_printf("Not a valid key=pair line %s\n",line.c_str());
|
||||||
return;
|
return;
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
u16 hid_slot = getSlot();
|
u16 hid_slot = getSlot();
|
||||||
|
|
||||||
if(HID_DEBUG) log_printf("leftpart = \"%s\" \n",cur_values[0].c_str());
|
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;
|
int keyslot = -1;
|
||||||
|
|
||||||
if(HID_DEBUG) log_printf("Checking single value\n");
|
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]);
|
keyslot = ConfigValues::getKeySlotGamePad(cur_values[0]);
|
||||||
}else if(getType() == PARSE_MOUSE){
|
}else if(getType() == PARSE_MOUSE){
|
||||||
keyslot = ConfigValues::getKeySlotMouse(cur_values[0]);
|
keyslot = ConfigValues::getKeySlotMouse(cur_values[0]);
|
||||||
@ -161,31 +167,6 @@ void ConfigParser::parseSingleLine(std::string line){
|
|||||||
char * ptr;
|
char * ptr;
|
||||||
rightValue = strtol(cur_values[1].c_str(),&ptr,16);
|
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{
|
}else{
|
||||||
rightValue = ConfigValues::getPresetValue(cur_values[1]);
|
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(!ConfigValues::getInstance()->setIfValueIsAControllerPreset(cur_values[1],getSlot(),keyslot)){
|
||||||
if(HID_DEBUG) log_printf("And its no preset\n");
|
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){
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,7 +214,7 @@ void ConfigParser::parseSingleLine(std::string line){
|
|||||||
if(HID_DEBUG) log_printf("Found preset value!!\n");
|
if(HID_DEBUG) log_printf("Found preset value!!\n");
|
||||||
}
|
}
|
||||||
}else{
|
}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;
|
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){
|
int ConfigParser::getSlotController(std::string identify){
|
||||||
if(HID_DEBUG) log_printf("Getting Controller Slot\n");
|
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){
|
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;
|
return HID_INVALID_SLOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,19 +248,29 @@ int ConfigParser::getSlotController(std::string identify){
|
|||||||
if(pid < 0){
|
if(pid < 0){
|
||||||
return HID_INVALID_SLOT;
|
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;
|
int hid = 0;
|
||||||
if(slot < 0){
|
if(result < 0){
|
||||||
log_printf("Its a new controller, lets save it\n");
|
if(HID_DEBUG) log_printf("Its a new controller, lets save it\n");
|
||||||
slot = gHIDRegisteredDevices;
|
|
||||||
hid = getNextDeviceSlot();
|
HIDSlotData slotdata;
|
||||||
|
ControllerPatcherUtils::getNextSlotData(&slotdata);
|
||||||
|
|
||||||
|
slot = slotdata.deviceslot;
|
||||||
|
hid = slotdata.hidmask;
|
||||||
|
|
||||||
if(slot >= gHIDMaxDevices){
|
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;
|
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][0] = (vid & 0xFF00) >> 8;
|
||||||
config_controller[slot][CONTRPS_VID][1] = (vid & 0x00FF);
|
config_controller[slot][CONTRPS_VID][1] = (vid & 0x00FF);
|
||||||
config_controller[slot][CONTRPS_PID][0] = (pid & 0xFF00) >> 8;
|
config_controller[slot][CONTRPS_PID][0] = (pid & 0xFF00) >> 8;
|
||||||
@ -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);
|
if(HID_DEBUG) log_printf("Saved vid: %04X pid: %04X\n",used_vid,used_pid);
|
||||||
|
|
||||||
config_controller_list[slot] = hid;
|
config_controller_hidmask[slot] = hid;
|
||||||
|
if(HID_DEBUG) log_printf("Saved the hid\n");
|
||||||
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");
|
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
if(slot < gHIDMaxDevices){
|
if(slot < gHIDMaxDevices){
|
||||||
hid =config_controller_list[slot];
|
hid = config_controller_hidmask[slot];
|
||||||
if(HID_DEBUG) log_printf(">>>>>> found slot %d (hid:%s). Modifing existing data <<<<<<<<\n",slot,byte_to_binary(hid));
|
if(HID_DEBUG) log_printf(">>>>>> found slot %d (hid:%s). Modifing existing data <<<<<<<<\n",slot,CPStringTools::byte_to_binary(hid));
|
||||||
log_printf("We already have data of this controller, lets modify it\n");
|
if(HID_DEBUG) log_printf("We already have data of this controller, lets modify it\n");
|
||||||
}else{
|
}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;
|
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;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConfigParser::parseIni(){
|
bool ConfigParser::parseIni(){
|
||||||
if(getSlot() == HID_INVALID_SLOT){
|
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());
|
if(HID_DEBUG) log_printf("Parsing content, type %d\n",getType());
|
||||||
@ -340,7 +309,7 @@ bool ConfigParser::parseIni(){
|
|||||||
int start = 1;
|
int start = 1;
|
||||||
if(contentLines[1].compare("[IGNOREDEFAULT]") == 0){
|
if(contentLines[1].compare("[IGNOREDEFAULT]") == 0){
|
||||||
resetConfig();
|
resetConfig();
|
||||||
log_printf("Overwriting existing settings of this device\n");
|
if(HID_DEBUG) log_printf("Overwriting existing settings of this device\n");
|
||||||
start++;
|
start++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,18 +318,18 @@ bool ConfigParser::parseIni(){
|
|||||||
parseSingleLine(contentLines[i]);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ConfigParser::getValueFromKeyValue(std::string value_pair,std::string expectedKey,std::string delimiter){
|
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(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());
|
if(HID_DEBUG || string_value.size() > 2) log_printf("Not a valid key=pair line %s\n",value_pair.c_str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(string_value[0].compare(expectedKey) != 0){
|
if(string_value[0].compare(expectedKey) != 0){
|
||||||
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;
|
return -1;
|
||||||
}
|
}
|
||||||
char * ptr;
|
char * ptr;
|
@ -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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -24,11 +24,12 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <gctypes.h>
|
#include <gctypes.h>
|
||||||
|
|
||||||
#include "controller_patcher.h"
|
#include "../ControllerPatcher.hpp"
|
||||||
#include "pad_const.h"
|
#include "../ConfigReader.hpp"
|
||||||
|
#include "../utils/PadConst.hpp"
|
||||||
|
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
#include "cp_retain_vars.h"
|
#include "../utils/CPRetainVars.hpp"
|
||||||
|
|
||||||
enum PARSE_TYPE{
|
enum PARSE_TYPE{
|
||||||
PARSE_CONTROLLER,
|
PARSE_CONTROLLER,
|
||||||
@ -37,9 +38,10 @@ enum PARSE_TYPE{
|
|||||||
PARSE_KEYBOARD
|
PARSE_KEYBOARD
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConfigParser
|
class ConfigParser{
|
||||||
{
|
friend class ConfigReader;
|
||||||
public:
|
friend class ControllerPatcher;
|
||||||
|
private:
|
||||||
//!Constructor
|
//!Constructor
|
||||||
ConfigParser(std::string configData);
|
ConfigParser(std::string configData);
|
||||||
//!Destructor
|
//!Destructor
|
||||||
@ -53,7 +55,6 @@ public:
|
|||||||
|
|
||||||
bool parseIni();
|
bool parseIni();
|
||||||
|
|
||||||
private:
|
|
||||||
bool Init();
|
bool Init();
|
||||||
|
|
||||||
bool parseConfigString(std::string content);
|
bool parseConfigString(std::string content);
|
||||||
@ -69,6 +70,10 @@ private:
|
|||||||
void parseSingleLine(std::string line);
|
void parseSingleLine(std::string line);
|
||||||
u16 slot_b;
|
u16 slot_b;
|
||||||
PARSE_TYPE type_b;
|
PARSE_TYPE type_b;
|
||||||
|
|
||||||
|
u16 vid;
|
||||||
|
u16 pid;
|
||||||
|
|
||||||
std::string content;
|
std::string content;
|
||||||
std::vector<std::string> contentLines;
|
std::vector<std::string> contentLines;
|
||||||
};
|
};
|
@ -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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -17,20 +17,18 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "config_values.h"
|
#include "./ConfigValues.hpp"
|
||||||
|
#include "../utils/CPRetainVars.hpp"
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
#include "cp_retain_vars.h"
|
|
||||||
|
|
||||||
ConfigValues *ConfigValues::instance = NULL;
|
ConfigValues *ConfigValues::instance = NULL;
|
||||||
|
|
||||||
ConfigValues::ConfigValues()
|
ConfigValues::ConfigValues(){
|
||||||
{
|
|
||||||
InitValues();
|
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){
|
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(presetGCValues,value,slot,keyslot)) return true;
|
||||||
if(setIfValueIsPreset(presetDS3Values,value,slot,keyslot)) return true;
|
if(setIfValueIsPreset(presetDS3Values,value,slot,keyslot)) return true;
|
||||||
if(setIfValueIsPreset(presetDS4Values,value,slot,keyslot)) return true;
|
if(setIfValueIsPreset(presetDS4Values,value,slot,keyslot)) return true;
|
||||||
|
if(setIfValueIsPreset(presetXInputValues,value,slot,keyslot)) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//We need this function here so we can use preset sticks.
|
//We need this function here so we can use preset sticks.
|
||||||
bool ConfigValues::setIfValueIsPreset(std::map<std::string,const u8*> values,std::string possibleValue,int slot,int keyslot){
|
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;
|
const u8 * values_ = NULL;
|
||||||
if( keyslot == CONTRPS_VPAD_BUTTON_L_STICK_X ||
|
if( keyslot == CONTRPS_VPAD_BUTTON_L_STICK_X ||
|
||||||
keyslot == CONTRPS_VPAD_BUTTON_L_STICK_Y ||
|
keyslot == CONTRPS_VPAD_BUTTON_L_STICK_Y ||
|
||||||
@ -101,3 +103,20 @@ int ConfigValues::getPresetValueEx(std::string possibleString){
|
|||||||
}
|
}
|
||||||
return rightValue;
|
return rightValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConfigValues::addDeviceNameEx(u16 vid,u16 pid,std::string value){
|
||||||
|
deviceNames[CPStringTools::strfmt("%04X%04X",vid,pid).c_str()] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ConfigValues::getStringByVIDPIDEx(u16 vid,u16 pid){
|
||||||
|
std::string result = "";
|
||||||
|
std::map<std::string,std::string>::iterator it;
|
||||||
|
|
||||||
|
it = deviceNames.find(CPStringTools::strfmt("%04X%04X",vid,pid));
|
||||||
|
if (it != deviceNames.end()){
|
||||||
|
result = it->second;
|
||||||
|
}else{
|
||||||
|
result = CPStringTools::strfmt("VID: 0x%04X\nPID: 0x%04X",vid,pid);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
@ -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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -22,15 +22,22 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <gctypes.h>
|
#include <gctypes.h>
|
||||||
|
|
||||||
#include "controller_patcher.h"
|
#include "../utils/PadConst.hpp"
|
||||||
#include "pad_const.h"
|
#include "../ControllerPatcher.hpp"
|
||||||
|
|
||||||
|
#include "../utils/CPStringTools.hpp"
|
||||||
|
#include "utils/logger.h"
|
||||||
|
|
||||||
class ConfigValues
|
class ConfigValues
|
||||||
{
|
{
|
||||||
public:
|
friend class ConfigParser;
|
||||||
|
friend class ControllerPatcher;
|
||||||
|
private:
|
||||||
static ConfigValues *getInstance() {
|
static ConfigValues *getInstance() {
|
||||||
if(!instance)
|
if(instance == NULL){
|
||||||
|
log_printf("ConfigValues: We need a new instance!!!\n");
|
||||||
instance = new ConfigValues();
|
instance = new ConfigValues();
|
||||||
|
}
|
||||||
return instance;
|
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)
|
static const u8 * getValuesStickPreset(std::string possibleValue)
|
||||||
{
|
{
|
||||||
@ -120,7 +127,22 @@ public:
|
|||||||
return cur_instance->setIfValueIsAControllerPresetEx(value,slot,keyslot);
|
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
|
//!Constructor
|
||||||
ConfigValues();
|
ConfigValues();
|
||||||
//!Destructor
|
//!Destructor
|
||||||
@ -135,9 +157,12 @@ private:
|
|||||||
std::map<std::string,int> gGamePadValuesToCONTRPSString;
|
std::map<std::string,int> gGamePadValuesToCONTRPSString;
|
||||||
std::map<std::string,int> presetKeyboardValues;
|
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*> presetGCValues;
|
||||||
std::map<std::string,const u8*> presetDS3Values;
|
std::map<std::string,const u8*> presetDS3Values;
|
||||||
std::map<std::string,const u8*> presetDS4Values;
|
std::map<std::string,const u8*> presetDS4Values;
|
||||||
|
std::map<std::string,const u8*> presetXInputValues;
|
||||||
std::map<std::string,const u8*> presetSticks;
|
std::map<std::string,const u8*> presetSticks;
|
||||||
|
|
||||||
int getValueFromMap(std::map<std::string,int> values,std::string nameOfString);
|
int getValueFromMap(std::map<std::string,int> values,std::string nameOfString);
|
||||||
@ -147,7 +172,7 @@ private:
|
|||||||
int getPresetValueEx(std::string possibleString);
|
int getPresetValueEx(std::string possibleString);
|
||||||
|
|
||||||
void InitValues(){
|
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_B"] = CONTRPS_VPAD_BUTTON_B;
|
||||||
CONTPRStringToValue["VPAD_BUTTON_X"] = CONTRPS_VPAD_BUTTON_X;
|
CONTPRStringToValue["VPAD_BUTTON_X"] = CONTRPS_VPAD_BUTTON_X;
|
||||||
CONTPRStringToValue["VPAD_BUTTON_Y"] = CONTRPS_VPAD_BUTTON_Y;
|
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_R"] = CONTRPS_VPAD_BUTTON_STICK_R;
|
||||||
CONTPRStringToValue["VPAD_BUTTON_STICK_L"] = CONTRPS_VPAD_BUTTON_STICK_L;
|
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_LEFT"] = CONTRPS_VPAD_STICK_R_EMULATION_LEFT;
|
||||||
CONTPRStringToValue["VPAD_STICK_R_EMULATION_RIGHT"] = CONTRPS_VPAD_STICK_R_EMULATION_RIGHT;
|
CONTPRStringToValue["VPAD_STICK_R_EMULATION_RIGHT"] = CONTRPS_VPAD_STICK_R_EMULATION_RIGHT;
|
||||||
CONTPRStringToValue["VPAD_STICK_R_EMULATION_UP"] = CONTRPS_VPAD_STICK_R_EMULATION_UP;
|
CONTPRStringToValue["VPAD_STICK_R_EMULATION_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_LEFT"] = CONTRPS_VPAD_STICK_L_EMULATION_LEFT;
|
||||||
CONTPRStringToValue["VPAD_STICK_L_EMULATION_RIGHT"] = CONTRPS_VPAD_STICK_L_EMULATION_RIGHT;
|
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_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_UP"] = CONTRPS_VPAD_BUTTON_L_STICK_UP;
|
||||||
CONTPRStringToValue["VPAD_L_STICK_DOWN"] = DEF_L_STICK_DOWN;
|
CONTPRStringToValue["VPAD_L_STICK_DOWN"] = CONTRPS_VPAD_BUTTON_L_STICK_DOWN;
|
||||||
CONTPRStringToValue["VPAD_L_STICK_LEFT"] = DEF_L_STICK_LEFT;
|
CONTPRStringToValue["VPAD_L_STICK_LEFT"] = CONTRPS_VPAD_BUTTON_L_STICK_LEFT;
|
||||||
CONTPRStringToValue["VPAD_L_STICK_RIGHT"] = DEF_L_STICK_RIGHT;
|
CONTPRStringToValue["VPAD_L_STICK_RIGHT"] = CONTRPS_VPAD_BUTTON_L_STICK_RIGHT;
|
||||||
|
|
||||||
CONTPRStringToValue["VPAD_R_STICK_UP"] = DEF_R_STICK_UP;
|
CONTPRStringToValue["VPAD_R_STICK_UP"] = CONTRPS_VPAD_BUTTON_R_STICK_UP;
|
||||||
CONTPRStringToValue["VPAD_R_STICK_DOWN"] = DEF_R_STICK_DOWN;
|
CONTPRStringToValue["VPAD_R_STICK_DOWN"] = CONTRPS_VPAD_BUTTON_R_STICK_DOWN;
|
||||||
CONTPRStringToValue["VPAD_R_STICK_LEFT"] = DEF_R_STICK_LEFT;
|
CONTPRStringToValue["VPAD_R_STICK_LEFT"] = CONTRPS_VPAD_BUTTON_R_STICK_LEFT;
|
||||||
CONTPRStringToValue["VPAD_R_STICK_RIGHT"] = DEF_R_STICK_RIGHT;
|
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"] = CONTRPS_VPAD_BUTTON_L_STICK_X;
|
||||||
CONTPRStringToValue["VPAD_L_STICK_X_MINMAX"] = CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX;
|
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["DOUBLE_USE_BUTTON_ACTIVATOR"] = CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR,
|
||||||
CONTPRStringToValue["INPUT_FILTER"] = CONTRPS_INPUT_FILTER;
|
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_1_PRESSED"] = CONTRPS_DOUBLE_USE_BUTTON_1_PRESSED;
|
||||||
CONTPRStringToValueSingle["DOUBLE_USE_BUTTON_2_PRESSED"] = CONTRPS_DOUBLE_USE_BUTTON_2_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_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_X_INVERT"] = CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT;
|
||||||
CONTPRStringToValueSingle["VPAD_R_STICK_Y_INVERT"] = CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT;
|
CONTPRStringToValueSingle["VPAD_R_STICK_Y_INVERT"] = CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT;
|
||||||
|
|
||||||
CONTPRStringToValueSingle["DOUBLE_USE"] = CONTRPS_DOUBLE_USE;
|
CONTPRStringToValueSingle["DOUBLE_USE"] = CONTRPS_DOUBLE_USE;
|
||||||
CONTPRStringToValueSingle["PAD_COUNT"] = CONTRPS_PAD_COUNT;
|
CONTPRStringToValueSingle["PAD_COUNT"] = CONTRPS_PAD_COUNT;
|
||||||
|
|
||||||
@ -309,6 +339,29 @@ private:
|
|||||||
presetDS4Values["DS4_BUTTON_GUIDE"] = HID_DS4_BUTTON_GUIDE;
|
presetDS4Values["DS4_BUTTON_GUIDE"] = HID_DS4_BUTTON_GUIDE;
|
||||||
presetDS4Values["DS4_BUTTON_T_PAD_CLICK"] = HID_DS4_BUTTON_T_PAD_CLICK;
|
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_SHIFT"] = HID_KEYBOARD_BUTTON_SHIFT;
|
||||||
presetKeyboardValues["KEYBOARD_A"] = HID_KEYBOARD_BUTTON_A;
|
presetKeyboardValues["KEYBOARD_A"] = HID_KEYBOARD_BUTTON_A;
|
||||||
presetKeyboardValues["KEYBOARD_B"] = HID_KEYBOARD_BUTTON_B;
|
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_X"] = HID_DS4_STICK_R_X;
|
||||||
presetSticks["DS4_STICK_R_Y"] = HID_DS4_STICK_R_Y;
|
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["GC_DPAD_MODE"] = HID_GC_BUTTON_DPAD_TYPE;
|
||||||
presetSticks["DS3_DPAD_MODE"] = HID_DS3_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_A"] = CONTRPS_VPAD_BUTTON_A;
|
||||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_B"] = CONTRPS_VPAD_BUTTON_B;
|
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_STICK_L"] = CONTRPS_VPAD_BUTTON_STICK_L;
|
||||||
gGamePadValuesToCONTRPSString["VPAD_BUTTON_TV"] = CONTRPS_VPAD_BUTTON_TV;
|
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_LEFT"] = CONTRPS_VPAD_STICK_R_EMULATION_LEFT;
|
||||||
gGamePadValuesToCONTRPSString["VPAD_STICK_R_EMULATION_RIGHT"] = CONTRPS_VPAD_STICK_R_EMULATION_RIGHT;
|
gGamePadValuesToCONTRPSString["VPAD_STICK_R_EMULATION_RIGHT"] = CONTRPS_VPAD_STICK_R_EMULATION_RIGHT;
|
||||||
gGamePadValuesToCONTRPSString["VPAD_STICK_R_EMULATION_UP"] = CONTRPS_VPAD_STICK_R_EMULATION_UP;
|
gGamePadValuesToCONTRPSString["VPAD_STICK_R_EMULATION_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_RIGHT"] = CONTRPS_VPAD_STICK_L_EMULATION_RIGHT;
|
||||||
gGamePadValuesToCONTRPSString["VPAD_STICK_L_EMULATION_UP"] = CONTRPS_VPAD_STICK_L_EMULATION_UP;
|
gGamePadValuesToCONTRPSString["VPAD_STICK_L_EMULATION_UP"] = CONTRPS_VPAD_STICK_L_EMULATION_UP;
|
||||||
gGamePadValuesToCONTRPSString["VPAD_STICK_L_EMULATION_DOWN"] = CONTRPS_VPAD_STICK_L_EMULATION_DOWN;
|
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);
|
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 setIfValueIsPreset(std::map<std::string,const u8*> values,std::string possibleValue,int slot,int keyslot);
|
||||||
bool setIfValueIsAControllerPresetEx(std::string value,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
|
#endif
|
@ -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
|
|
1557
controller_patcher.c
1557
controller_patcher.c
File diff suppressed because it is too large
Load Diff
50
network/ControllerPatcherNet.cpp
Normal file
50
network/ControllerPatcherNet.cpp
Normal 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);
|
||||||
|
}
|
15
network/ControllerPatcherNet.hpp
Normal file
15
network/ControllerPatcherNet.hpp
Normal 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
333
network/TCPServer.cpp
Normal 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
68
network/TCPServer.hpp
Normal 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
158
network/UDPServer.cpp
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2016,2017 Maschell
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#include "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
57
network/UDPServer.hpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2016,2017 Maschell
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef _UDPSERVER_WINDOW_H_
|
||||||
|
#define _UDPSERVER_WINDOW_H_
|
||||||
|
|
||||||
|
#include "../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_
|
@ -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
|
* 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
|
* 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/>.
|
* 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
|
#ifndef _CONTROLLER_PATCHER_DEFS_H_
|
||||||
extern "C" {
|
#define _CONTROLLER_PATCHER_DEFS_H_
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <gctypes.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 gHIDMaxDevices 32
|
||||||
#define HID_ALL_CONNECTED_DEVICES 0x10
|
#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 NETWORK_CONTROLLER_VID 0
|
||||||
#define HID_SDCARD_READ 2
|
#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
|
enum Controller_Stick_Defines
|
||||||
{
|
{
|
||||||
STICK_CONF_MAGIC_VERSION,
|
STICK_CONF_MAGIC_VERSION, /**< Version of the stick configuration. Changes with every format*/
|
||||||
STICK_CONF_BYTE,
|
STICK_CONF_BYTE, /**< Byte where the stick-axis data is stored*/
|
||||||
STICK_CONF_DEFAULT,
|
STICK_CONF_DEFAULT, /**< Default value*/
|
||||||
STICK_CONF_DEADZONE,
|
STICK_CONF_DEADZONE, /**< Size of the deadzone */
|
||||||
STICK_CONF_INVERT,
|
STICK_CONF_INVERT, /**< Is 1 when the axis is inverted */
|
||||||
STICK_CONF_MIN,
|
STICK_CONF_MIN, /**< Value that represent the minimum value (-1.0f)*/
|
||||||
STICK_CONF_MAX,
|
STICK_CONF_MAX, /**< Value that represent the maximum value (1.0f) */
|
||||||
STICK_CONF_ENUM_MAXVALUE
|
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!!!!
|
#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)
|
//! most data has the format: byte,value (byte starting at 0)
|
||||||
enum Controller_Patcher_Settings
|
enum Controller_Patcher_Settings
|
||||||
{
|
{
|
||||||
@ -108,9 +136,6 @@ enum Controller_Patcher_Settings
|
|||||||
CONTRPS_VPAD_BUTTON_STICK_R,
|
CONTRPS_VPAD_BUTTON_STICK_R,
|
||||||
CONTRPS_VPAD_BUTTON_STICK_L,
|
CONTRPS_VPAD_BUTTON_STICK_L,
|
||||||
|
|
||||||
/*
|
|
||||||
Currently not needed
|
|
||||||
|
|
||||||
CONTRPS_VPAD_STICK_R_EMULATION_LEFT,
|
CONTRPS_VPAD_STICK_R_EMULATION_LEFT,
|
||||||
CONTRPS_VPAD_STICK_R_EMULATION_RIGHT,
|
CONTRPS_VPAD_STICK_R_EMULATION_RIGHT,
|
||||||
CONTRPS_VPAD_STICK_R_EMULATION_UP,
|
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_UP,
|
||||||
CONTRPS_VPAD_STICK_L_EMULATION_DOWN,
|
CONTRPS_VPAD_STICK_L_EMULATION_DOWN,
|
||||||
|
|
||||||
*/
|
|
||||||
CONTRPS_VPAD_BUTTON_L_STICK_X, //! byte, default value
|
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_INVERT, //! To invert: CONTROLLER_PATCHER_VALUE_SET, 0x01
|
||||||
CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE, //! Deadzone
|
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_INVERT, //! To invert: CONTROLLER_PATCHER_VALUE_SET, 0x01
|
||||||
CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE, //! Deadzone
|
CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE, //! Deadzone
|
||||||
CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX, //! min,max
|
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_VPAD_BUTTON_TV,
|
||||||
CONTRPS_DOUBLE_USE, //!When used: e.g. CONTROLLER_PATCHER_VALUE_SET, CONTROLLER_PATCHER_GC_DOUBLE_USE
|
CONTRPS_DOUBLE_USE, //!When used: e.g. CONTROLLER_PATCHER_VALUE_SET, CONTROLLER_PATCHER_GC_DOUBLE_USE
|
||||||
CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR,
|
CONTRPS_DOUBLE_USE_BUTTON_ACTIVATOR,
|
||||||
@ -151,72 +185,222 @@ enum Controller_Patcher_Settings
|
|||||||
CONTRPS_DOUBLE_USE_BUTTON_4_RELEASED,
|
CONTRPS_DOUBLE_USE_BUTTON_4_RELEASED,
|
||||||
CONTRPS_DOUBLE_USE_BUTTON_5_RELEASED,
|
CONTRPS_DOUBLE_USE_BUTTON_5_RELEASED,
|
||||||
CONTRPS_PAD_COUNT, //!
|
CONTRPS_PAD_COUNT, //!
|
||||||
|
CONTRPS_CONNECTED_PADS, //!
|
||||||
CONTRPS_INPUT_FILTER, //!
|
CONTRPS_INPUT_FILTER, //!
|
||||||
|
CONTRPS_PAD1_FILTER, //!
|
||||||
|
CONTRPS_PAD2_FILTER, //!
|
||||||
|
CONTRPS_PAD3_FILTER, //!
|
||||||
|
CONTRPS_PAD4_FILTER, //!
|
||||||
|
CONTRPS_PAD5_FILTER, //!
|
||||||
CONTRPS_MOUSE_STICK,
|
CONTRPS_MOUSE_STICK,
|
||||||
CONTRPS_MAX_VALUE
|
CONTRPS_MAX_VALUE
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* @brief The enumeration of different DPAD-Modes
|
||||||
|
*/
|
||||||
enum Controller_Patcher_DPAD_MODE
|
enum Controller_Patcher_DPAD_MODE
|
||||||
{
|
{
|
||||||
CONTRPDM_Normal,
|
CONTRPDM_Normal, /**< Normal mode */
|
||||||
CONTRPDM_Hat,
|
CONTRPDM_Hat, /**< Hat mode */
|
||||||
CONTRPDM_Absolute_2Values,
|
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
|
enum Controller_Patcher_DPAD_Settings
|
||||||
{
|
{
|
||||||
CONTRDPAD_MODE,
|
CONTRDPAD_MODE = 0, /**< Byte where the DPAD Mode is stored */
|
||||||
CONTRDPAD_MASK,
|
CONTRDPAD_MASK = 1, /**< Byte where the DPAD Mask is stored */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CONTROLLER_PATCHER_VALUE_SET 0x01
|
/**
|
||||||
#define CONTROLLER_PATCHER_GC_DOUBLE_USE 0x01
|
* @brief Stores data if the Slot the device is using in gHID_Devices
|
||||||
#define CONTROLLER_PATCHER_INVALIDVALUE 0xFF
|
*/
|
||||||
|
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{
|
typedef struct _my_cb_user{
|
||||||
unsigned char *buf;
|
u8 *buf; /**< pointer the buffer that is used */
|
||||||
unsigned int transfersize;
|
u32 transfersize; /**< number of transfered data */
|
||||||
unsigned int rumblestatus[4];
|
u32 handle; /**< HID handle */
|
||||||
unsigned int handle;
|
HIDSlotData slotdata; /**< Information about the deviceslot and hidmask */
|
||||||
unsigned int hid;
|
u32 pads_per_device; /**< Number of maximum pads of this device */
|
||||||
unsigned int deviceSlot;
|
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;
|
}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 {
|
typedef struct _HID_DEVICE_DATA {
|
||||||
my_cb_user * user_data;
|
|
||||||
HID_Data pad_data[HID_MAX_PADS_COUNT];
|
HID_Data pad_data[HID_MAX_PADS_COUNT];
|
||||||
} HID_DEVICE_DATA;
|
} 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;
|
* @brief Infos of the device
|
||||||
int hid;
|
*/
|
||||||
}HID_Data_Struct;
|
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();
|
* @brief The enumeration of Controller-Mapping types
|
||||||
void init_button_remapping();
|
*/
|
||||||
void deinit_config_controller();
|
enum ControllerMapping_Type_Defines{
|
||||||
u32 getNextDeviceSlot();
|
CM_Type_Controller = 0, /**< Device with single input */
|
||||||
void printButtons(VPADData * buffer);
|
CM_Type_RealController = 1, /**< Real Pro Controller */
|
||||||
void buttonRemapping(VPADData * buffer);
|
CM_Type_Mouse = 2, /**< Mouse */
|
||||||
void setButtonRemappingData(VPADData * buffer, VPADData * new_data,u32 VPADButton, int CONTRPS_Value);
|
CM_Type_Keyboard = 3, /**< Keyboard */
|
||||||
void setHoldButtonData(VPADData * buffer, VPADData * new_data,u32 oldVPADButton,u32 newVPADButton);
|
};
|
||||||
|
|
||||||
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);
|
* @brief Infos of a mapped controller
|
||||||
int checkDoubleUseGC();
|
*/
|
||||||
void checkMouseMode(HID_Data_Struct data, HID_Data_Struct data_last);
|
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_A_VALUE 0x01
|
||||||
#define HID_GC_BUTTON_B_VALUE 0x02
|
#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_R_VALUE 0x80
|
||||||
#define HID_GC_BUTTON_Z_VALUE 0x02
|
#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
|
||||||
|
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
#define PS3_F4_REPORT_LEN 4
|
||||||
//! DS3
|
#define PS3_F5_REPORT_LEN 8
|
||||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
#define PS3_01_REPORT_LEN 48
|
||||||
|
#define HID_REPORT_FEATURE 3
|
||||||
#define PS3_F4_REPORT_LEN 4
|
#define HID_REPORT_OUTPUT 2
|
||||||
#define PS3_F5_REPORT_LEN 8
|
#define PS3_F4_REPORT_ID 0xF4
|
||||||
#define PS3_01_REPORT_LEN 48
|
#define PS3_01_REPORT_ID 0x01
|
||||||
#define HID_REPORT_FEATURE 3
|
#define PS3_F5_REPORT_ID 0xF5
|
||||||
#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_CROSS_VALUE 0x40 // 3
|
||||||
#define HID_DS3_BUTTON_CIRCLE_VALUE 0x20 // 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_DOWN_VALUE 0x40 // 2
|
||||||
#define HID_DS3_BUTTON_GUIDE_VALUE 0x01 // 4
|
#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_CROSS_VALUE 0x20 // 5
|
||||||
#define HID_DS4_BUTTON_SQUARE_VALUE 0x10 // 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_GUIDE_VALUE 0x01 // 7
|
||||||
#define HID_DS4_BUTTON_T_PAD_CLICK_VALUE 0x02 // 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
|
#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_PAD_COUNT 1
|
||||||
#define HID_KEYBOARD_DATA_LENGTH 8
|
#define HID_KEYBOARD_DATA_LENGTH 8
|
||||||
|
|
||||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
//! Mouse
|
* Mouse
|
||||||
//!----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define HID_MOUSE_BUTTON_LEFTCLICK 0x04
|
#define HID_MOUSE_BUTTON_LEFTCLICK 0x04
|
||||||
#define HID_MOUSE_BUTTON_RIGHTCLICK 0x05
|
#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_AIM 0x01
|
||||||
#define HID_MOUSE_MODE_TOUCH 0x02
|
#define HID_MOUSE_MODE_TOUCH 0x02
|
||||||
|
|
||||||
struct _HID_Mouse_Data {
|
#endif /* _CONTROLLER_PATCHER_DEFS_H_ */
|
||||||
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_ */
|
|
549
patcher/ControllerPatcherHID.cpp
Normal file
549
patcher/ControllerPatcherHID.cpp
Normal 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);
|
||||||
|
}
|
74
patcher/ControllerPatcherHID.hpp
Normal file
74
patcher/ControllerPatcherHID.hpp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2016,2017 Maschell
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file ControllerPatcherHID.hpp
|
||||||
|
* @author Maschell
|
||||||
|
* @date 25 Aug 2016
|
||||||
|
* \brief This files contain useful all function for the direct HID Access
|
||||||
|
*
|
||||||
|
* @see https://github.com/Maschell/controller_patcher
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CONTROLLER_PATCHER_HID_H_
|
||||||
|
#define _CONTROLLER_PATCHER_HID_H_
|
||||||
|
|
||||||
|
#include <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_ */
|
901
patcher/ControllerPatcherUtils.cpp
Normal file
901
patcher/ControllerPatcherUtils.cpp
Normal 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;
|
||||||
|
}
|
319
patcher/ControllerPatcherUtils.hpp
Normal file
319
patcher/ControllerPatcherUtils.hpp
Normal 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_ */
|
@ -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_ */
|
|
@ -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
|
* 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
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <gctypes.h>
|
#include <gctypes.h>
|
||||||
#include "controller_patcher.h"
|
#include "../patcher/ControllerPatcherDefs.h"
|
||||||
#include "cp_retain_vars.h"
|
#include "../utils/CPRetainVars.hpp"
|
||||||
|
|
||||||
|
ControllerMapping gControllerMapping __attribute__((section(".data")));
|
||||||
|
|
||||||
u8 gConfig_done __attribute__((section(".data"))) = 0;
|
u8 gConfig_done __attribute__((section(".data"))) = 0;
|
||||||
u8 gButtonRemappingConfigDone __attribute__((section(".data"))) = 0;
|
u8 gButtonRemappingConfigDone __attribute__((section(".data"))) = 0;
|
||||||
|
|
||||||
u8 gHIDSetupDone __attribute__((section(".data"))) = 0;
|
|
||||||
u16 gHIDAttached __attribute__((section(".data"))) = 0;
|
u16 gHIDAttached __attribute__((section(".data"))) = 0;
|
||||||
u16 gHIDCurrentDevice __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_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;
|
u8 gHID_Mouse_Mode __attribute__((section(".data"))) = HID_MOUSE_MODE_TOUCH;
|
||||||
|
|
||||||
u32 gGamePadValues[CONTRPS_MAX_VALUE] __attribute__((section(".data")));
|
u32 gGamePadValues[CONTRPS_MAX_VALUE] __attribute__((section(".data")));
|
||||||
|
|
||||||
u8 config_controller[gHIDMaxDevices][CONTRPS_MAX_VALUE][2] __attribute__((section(".data")));
|
u8 config_controller[gHIDMaxDevices][CONTRPS_MAX_VALUE][2] __attribute__((section(".data")));
|
||||||
u16 config_controller_list[gHIDMaxDevices] __attribute__((section(".data")));
|
u16 config_controller_hidmask[gHIDMaxDevices] __attribute__((section(".data")));
|
||||||
u32 config_controller_data_ptr[gHIDMaxDevices][HID_MAX_PADS_COUNT] __attribute__((section(".data")));
|
|
||||||
|
|
||||||
u16 gHID_LIST_GC __attribute__((section(".data"))) = 0;
|
u16 gHID_LIST_GC __attribute__((section(".data"))) = 0;
|
||||||
u16 gHID_LIST_DS3 __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_GC __attribute__((section(".data"))) = 0;
|
||||||
u16 gHID_SLOT_KEYBOARD __attribute__((section(".data"))) = 0;
|
u16 gHID_SLOT_KEYBOARD __attribute__((section(".data"))) = 0;
|
||||||
u16 gMouseSlot __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;
|
@ -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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -18,32 +18,27 @@
|
|||||||
#define CP_RETAINS_VARS_H_
|
#define CP_RETAINS_VARS_H_
|
||||||
|
|
||||||
#include "dynamic_libs/syshid_functions.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 gConfig_done;
|
||||||
extern u8 gButtonRemappingConfigDone;
|
extern u8 gButtonRemappingConfigDone;
|
||||||
|
|
||||||
extern u8 gHIDSetupDone;
|
|
||||||
extern u16 gHIDAttached;
|
extern u16 gHIDAttached;
|
||||||
extern u16 gHIDCurrentDevice;
|
extern u16 gHIDCurrentDevice;
|
||||||
extern HIDClient gHIDClient;
|
extern HIDClient gHIDClient;
|
||||||
|
|
||||||
#define gHIDMaxDevices 16
|
|
||||||
#define HID_INVALID_SLOT 0xFFFF
|
|
||||||
|
|
||||||
extern u16 gHIDRegisteredDevices;
|
extern u16 gHIDRegisteredDevices;
|
||||||
|
|
||||||
extern HID_DEVICE_DATA gHID_Devices[gHIDMaxDevices];
|
extern HID_DEVICE_DATA gHID_Devices[gHIDMaxDevices];
|
||||||
|
|
||||||
extern HID_Mouse gHID_Mouse;
|
|
||||||
|
|
||||||
extern u8 gHID_Mouse_Mode;
|
extern u8 gHID_Mouse_Mode;
|
||||||
|
|
||||||
extern u32 gGamePadValues[CONTRPS_MAX_VALUE];
|
extern u32 gGamePadValues[CONTRPS_MAX_VALUE];
|
||||||
|
|
||||||
extern u8 config_controller[gHIDMaxDevices][CONTRPS_MAX_VALUE][2];
|
extern u8 config_controller[gHIDMaxDevices][CONTRPS_MAX_VALUE][2];
|
||||||
extern u16 config_controller_list[gHIDMaxDevices];
|
extern u16 config_controller_hidmask[gHIDMaxDevices];
|
||||||
extern u32 config_controller_data_ptr[gHIDMaxDevices][4]; //currently max per device
|
|
||||||
|
|
||||||
extern u16 gHID_LIST_GC;
|
extern u16 gHID_LIST_GC;
|
||||||
extern u16 gHID_LIST_DS3;
|
extern u16 gHID_LIST_DS3;
|
||||||
@ -55,4 +50,10 @@ extern u16 gHID_SLOT_GC;
|
|||||||
extern u16 gHID_SLOT_KEYBOARD;
|
extern u16 gHID_SLOT_KEYBOARD;
|
||||||
extern u16 gMouseSlot;
|
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_
|
#endif // CP_RETAINS_VARS_H_
|
@ -1,18 +1,19 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <gctypes.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;
|
if (b.size() > a.size()) return false;
|
||||||
return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin());
|
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::string value = inValue;
|
||||||
std::vector<std::string> result;
|
std::vector<std::string> result;
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -35,9 +36,7 @@ std::vector<std::string> MyStringSplit(const std::string & inValue, const std::s
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char * CPStringTools::byte_to_binary(int x){
|
||||||
extern "C" const char *byte_to_binary(int x)
|
|
||||||
{
|
|
||||||
static char b[9];
|
static char b[9];
|
||||||
b[0] = '\0';
|
b[0] = '\0';
|
||||||
|
|
||||||
@ -49,3 +48,36 @@ extern "C" const char *byte_to_binary(int x)
|
|||||||
|
|
||||||
return b;
|
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
15
utils/CPStringTools.hpp
Normal 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_ */
|
121
utils/ControllerPatcherThread.hpp
Normal file
121
utils/ControllerPatcherThread.hpp
Normal 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
|
@ -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
|
* 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
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "pad_const.h"
|
#include "PadConst.hpp"
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
const u8 DEF_R_STICK = 220;
|
const u8 DEF_R_STICK = 220;
|
||||||
const u8 DEF_L_STICK = 221;
|
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_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_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_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
|
//! 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,
|
0x00, //STICK_CONF_MIN,
|
||||||
0xFF};//STICK_CONF_MAX,
|
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,
|
@ -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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -18,22 +18,9 @@
|
|||||||
#ifndef _PAD_CONST_H_
|
#ifndef _PAD_CONST_H_
|
||||||
#define _PAD_CONST_H_
|
#define _PAD_CONST_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <gctypes.h>
|
#include <gctypes.h>
|
||||||
#include "controller_patcher.h"
|
#include <string>
|
||||||
|
#include "../patcher/ControllerPatcherDefs.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;
|
|
||||||
|
|
||||||
extern const u8 DEF_R_STICK;
|
extern const u8 DEF_R_STICK;
|
||||||
extern const u8 DEF_L_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_DEADZONE;
|
||||||
extern const u8 DEF_STICK_OFFSET_MINMAX;
|
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
|
//! 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_X[STICK_CONF_ENUM_MAXVALUE];
|
||||||
extern const u8 HID_DS4_STICK_R_Y[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_ */
|
#endif /* _PAD_CONST_H_ */
|
Loading…
Reference in New Issue
Block a user