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:
Maschell 2017-10-14 15:45:45 +02:00
parent c9284c0238
commit 409871f29d
7 changed files with 135 additions and 132 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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");

View File

@ -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

View File

@ -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
View 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
View 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_ */