mirror of
https://github.com/Maschell/controller_patcher.git
synced 2024-11-21 19:49:16 +01:00
Changed the way configuration files are loaded.
- Now the app using the controller_patcher_lib is responseable for mounting the device. This give the application the freedom to load it from any place. (Which implements devoptabs)
This commit is contained in:
parent
c9284c0238
commit
409871f29d
153
ConfigReader.cpp
153
ConfigReader.cpp
@ -15,11 +15,19 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
****************************************************************************/
|
||||
#include "./ConfigReader.hpp"
|
||||
#include "./utils/CPFSUtils.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <map>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
#include "dynamic_libs/fs_functions.h"
|
||||
#include "utils/logger.h"
|
||||
@ -28,101 +36,50 @@ s32 ConfigReader::numberValidFiles = 0;
|
||||
ConfigReader *ConfigReader::instance = NULL;
|
||||
|
||||
ConfigReader::ConfigReader(){
|
||||
InitOSFunctionPointers();
|
||||
InitFSFunctionPointers();
|
||||
}
|
||||
|
||||
void ConfigReader::ReadAllConfigs(){
|
||||
std::vector<std::string> fileList = ScanFolder();
|
||||
bool ConfigReader::ReadConfigs(std::string path){
|
||||
std::vector<std::string> fileList = ScanFolder(path);
|
||||
if(fileList.size() == 1 && fileList[0].compare("ERROR") == 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fileList.size() > 0){
|
||||
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Found %d config files\n",fileList.size()); }
|
||||
processFileList(fileList);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
ConfigReader::~ConfigReader(){
|
||||
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("~ConfigReader\n"); }
|
||||
freeFSHandles();
|
||||
}
|
||||
|
||||
void ConfigReader::freeFSHandles(){
|
||||
if(this->pClient != NULL){
|
||||
FSDelClient(this->pClient);
|
||||
free(this->pClient);
|
||||
this->pClient = NULL;
|
||||
}
|
||||
if(this->pCmd != NULL){
|
||||
free(this->pCmd);
|
||||
this->pCmd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Mounting the sdcard without any external lib to be portable
|
||||
s32 ConfigReader::InitSDCard(){
|
||||
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("InitSDCard\n"); }
|
||||
|
||||
char mountSrc[FS_MOUNT_SOURCE_SIZE];
|
||||
char mountPath[FS_MAX_MOUNTPATH_SIZE];
|
||||
|
||||
freeFSHandles();
|
||||
|
||||
this->pClient = malloc(FS_CLIENT_SIZE);
|
||||
this->pCmd = malloc(FS_CMD_BLOCK_SIZE);
|
||||
|
||||
s32 status = 0;
|
||||
|
||||
if (this->pClient && this->pCmd)
|
||||
{
|
||||
// Do an FSInit first
|
||||
FSInit();
|
||||
// Add client to FS.
|
||||
FSAddClientEx(this->pClient, FS_RET_NO_ERROR,-1);
|
||||
|
||||
// Init command block.
|
||||
FSInitCmdBlock(this->pCmd);
|
||||
|
||||
// Mount sdcard
|
||||
if ((status = FSGetMountSource(this->pClient, this->pCmd, FS_SOURCETYPE_EXTERNAL, &mountSrc, FS_RET_NO_ERROR)) == FS_STATUS_OK)
|
||||
{
|
||||
if ((status = FSMount(this->pClient, this->pCmd, &mountSrc, mountPath, FS_MAX_MOUNTPATH_SIZE, FS_RET_UNSUPPORTED_CMD)) == FS_STATUS_OK)
|
||||
{
|
||||
return 0;
|
||||
}else{
|
||||
DEBUG_FUNCTION_LINE("error: FSMount failed %d\n",status);
|
||||
return status;
|
||||
}
|
||||
}else{
|
||||
DEBUG_FUNCTION_LINE("error: FSGetMountSource failed %d\n",status);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::vector<std::string> ConfigReader::ScanFolder(){
|
||||
std::string path = CONTROLLER_PATCHER_PATH;
|
||||
s32 dirhandle = 0;
|
||||
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Opening %s\n",path.c_str()); }
|
||||
std::vector<std::string> ConfigReader::ScanFolder(std::string path){
|
||||
std::vector<std::string> config_files;
|
||||
if (this->pClient && this->pCmd){
|
||||
s32 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){ DEBUG_FUNCTION_LINE("Found ini: %s \n",full_path.c_str()); }
|
||||
}
|
||||
}
|
||||
}
|
||||
FSCloseDir(this->pClient,this->pCmd,dirhandle,-1);
|
||||
}else{
|
||||
DEBUG_FUNCTION_LINE("Failed to open folder %s!\n",path.c_str());
|
||||
|
||||
struct dirent *dirent = NULL;
|
||||
DIR *dirHandle = opendir(path.c_str());
|
||||
if (dirHandle == NULL){
|
||||
DEBUG_FUNCTION_LINE("Failed to open dir %s\n",path.c_str());
|
||||
config_files.push_back("ERROR"); //TODO: Find a proper solution
|
||||
return config_files;
|
||||
}
|
||||
while ((dirent = readdir(dirHandle)) != 0){
|
||||
bool isDir = dirent->d_type & DT_DIR;
|
||||
const char *filename = dirent->d_name;
|
||||
|
||||
if(strcmp(filename,".") == 0 || strcmp(filename,"..") == 0){ continue; }
|
||||
|
||||
std::string newPath = path + "/" + std::string(filename);
|
||||
|
||||
if(!isDir && CPStringTools::EndsWith(std::string(filename),".ini")){
|
||||
config_files.push_back(newPath);
|
||||
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Found ini: %s \n",newPath.c_str()); }
|
||||
}
|
||||
}
|
||||
|
||||
return config_files;
|
||||
}
|
||||
|
||||
@ -137,45 +94,13 @@ void ConfigReader::processFileList(std::vector<std::string> path){
|
||||
}
|
||||
|
||||
std::string ConfigReader::loadFileToString(std::string path){
|
||||
s32 handle = 0;
|
||||
s32 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){
|
||||
DEBUG_FUNCTION_LINE("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){
|
||||
s32 total_read = 0;
|
||||
s32 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{
|
||||
DEBUG_FUNCTION_LINE("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
|
||||
u8 * buffer = NULL;
|
||||
if(CPFSUtils::LoadFileToMem(path.c_str(),&buffer,NULL) > 0){
|
||||
strBuffer = std::string((char *)buffer);
|
||||
strBuffer = CPStringTools::removeCharFromString(strBuffer,'\r');
|
||||
strBuffer = CPStringTools::removeCharFromString(strBuffer,' ');
|
||||
strBuffer = CPStringTools::removeCharFromString(strBuffer,'\t');
|
||||
|
||||
}else{
|
||||
DEBUG_FUNCTION_LINE("error: (GetStat) Couldn't open file (%s), error: %d",path.c_str(),status);
|
||||
}
|
||||
|
||||
return strBuffer;
|
||||
}
|
||||
|
@ -23,8 +23,6 @@
|
||||
|
||||
#include "./ControllerPatcher.hpp"
|
||||
|
||||
#define CONTROLLER_PATCHER_PATH "/vol/external01/wiiu/controller";
|
||||
|
||||
class ConfigReader{
|
||||
friend class ControllerPatcher;
|
||||
friend class ConfigParser;
|
||||
@ -50,7 +48,7 @@ class ConfigReader{
|
||||
static void increaseNumberOfLoadedFiles(){
|
||||
ConfigReader::numberValidFiles++;
|
||||
}
|
||||
void ReadAllConfigs();
|
||||
bool ReadConfigs(std::string path);
|
||||
static s32 numberValidFiles;
|
||||
|
||||
//!Constructor
|
||||
@ -59,15 +57,12 @@ class ConfigReader{
|
||||
~ConfigReader();
|
||||
|
||||
s32 InitSDCard();
|
||||
void freeFSHandles();
|
||||
|
||||
void * pClient = NULL;
|
||||
void * pCmd = NULL;
|
||||
static ConfigReader *instance;
|
||||
|
||||
std::string loadFileToString(std::string path);
|
||||
void processFileList(std::vector<std::string> path);
|
||||
|
||||
std::vector<std::string> ScanFolder();
|
||||
std::vector<std::string> ScanFolder(std::string path);
|
||||
};
|
||||
#endif
|
||||
|
@ -470,7 +470,7 @@ void ControllerPatcher::ResetConfig(){
|
||||
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(){
|
||||
bool ControllerPatcher::Init(const char * pathToConfig){
|
||||
InitOSFunctionPointers();
|
||||
InitSocketFunctionPointers();
|
||||
InitSysHIDFunctionPointers();
|
||||
@ -503,19 +503,15 @@ bool ControllerPatcher::Init(){
|
||||
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Config already done!\n"); }
|
||||
}
|
||||
|
||||
if(gConfig_done != HID_SDCARD_READ){
|
||||
if(pathToConfig != NULL && gConfig_done != HID_SDCARD_READ){
|
||||
DEBUG_FUNCTION_LINE("Reading config files from SD Card\n");
|
||||
ConfigReader* reader = ConfigReader::getInstance();
|
||||
s32 status = 0;
|
||||
if((status = reader->InitSDCard()) == 0){
|
||||
if(HID_DEBUG){ DEBUG_FUNCTION_LINE(" SD Card mounted for controller config!\n"); }
|
||||
reader->ReadAllConfigs();
|
||||
|
||||
if(reader->ReadConfigs(pathToConfig)){
|
||||
DEBUG_FUNCTION_LINE("Done with reading config files from SD Card\n");
|
||||
gConfig_done = HID_SDCARD_READ;
|
||||
}else{
|
||||
DEBUG_FUNCTION_LINE("SD mounting failed! %d\n",status);
|
||||
}
|
||||
ConfigReader::destroyInstance();
|
||||
|
||||
}
|
||||
|
||||
DEBUG_FUNCTION_LINE("Initializing the data for button remapping\n");
|
||||
|
@ -65,8 +65,11 @@ class ControllerPatcher{
|
||||
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.
|
||||
@param pathToConfig: The path of the directory containing the configuration files. The path needs already to be mounted and accessible via the
|
||||
devoptabs! If no configuration should be loaded from the SD Card, set this parameter to NULL.
|
||||
**/
|
||||
static bool Init();
|
||||
|
||||
static bool Init(const char * pathToConfig);
|
||||
|
||||
/**
|
||||
\brief De-Initialises the controller_patcher
|
||||
|
@ -372,6 +372,9 @@ enum UController_Type{
|
||||
UController_Type_Pro4,
|
||||
};
|
||||
|
||||
|
||||
#define CONTROLLER_PATCHER_PATH "sd:/wiiu/controller"
|
||||
|
||||
#define UController_Type_Gamepad_Name gettext("GamePad")
|
||||
#define UController_Type_Pro1_Name gettext("Pro Controller 1")
|
||||
#define UController_Type_Pro2_Name gettext("Pro Controller 2")
|
||||
|
69
utils/CPFSUtils.cpp
Normal file
69
utils/CPFSUtils.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
#include "CPFSUtils.hpp"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//Copy pasted from dimoks sources. Thanks!!!
|
||||
s32 CPFSUtils::LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size){
|
||||
//! always initialze input
|
||||
*inbuffer = NULL;
|
||||
if(size){
|
||||
*size = 0;
|
||||
}
|
||||
|
||||
s32 iFd = open(filepath, O_RDONLY);
|
||||
if (iFd < 0)
|
||||
return -1;
|
||||
|
||||
u32 filesize = lseek(iFd, 0, SEEK_END);
|
||||
lseek(iFd, 0, SEEK_SET);
|
||||
|
||||
u8 *buffer = (u8 *) malloc(filesize);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
close(iFd);
|
||||
return -2;
|
||||
}
|
||||
|
||||
u32 blocksize = 0x4000;
|
||||
u32 done = 0;
|
||||
s32 readBytes = 0;
|
||||
|
||||
while(done < filesize)
|
||||
{
|
||||
if(done + blocksize > filesize) {
|
||||
blocksize = filesize - done;
|
||||
}
|
||||
readBytes = read(iFd, buffer + done, blocksize);
|
||||
if(readBytes <= 0)
|
||||
break;
|
||||
done += readBytes;
|
||||
}
|
||||
|
||||
close(iFd);
|
||||
|
||||
if (done != filesize)
|
||||
{
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
return -3;
|
||||
}
|
||||
|
||||
*inbuffer = buffer;
|
||||
|
||||
//! size is optional input
|
||||
if(size){
|
||||
*size = filesize;
|
||||
}
|
||||
|
||||
return filesize;
|
||||
}
|
||||
|
||||
//CPFSUtils
|
12
utils/CPFSUtils.hpp
Normal file
12
utils/CPFSUtils.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _CPFS_UTILS_H_
|
||||
#define _CPFS_UTILS_H_
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <gctypes.h>
|
||||
|
||||
class CPFSUtils{
|
||||
public:
|
||||
static s32 LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size);
|
||||
};
|
||||
|
||||
#endif /* _CPFS_UTILS_H_ */
|
Loading…
Reference in New Issue
Block a user