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/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include "./ConfigReader.hpp" #include "./ConfigReader.hpp"
#include "./utils/CPFSUtils.hpp"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <map> #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 "dynamic_libs/fs_functions.h"
#include "utils/logger.h" #include "utils/logger.h"
@ -28,101 +36,50 @@ s32 ConfigReader::numberValidFiles = 0;
ConfigReader *ConfigReader::instance = NULL; ConfigReader *ConfigReader::instance = NULL;
ConfigReader::ConfigReader(){ ConfigReader::ConfigReader(){
InitOSFunctionPointers();
InitFSFunctionPointers();
} }
void ConfigReader::ReadAllConfigs(){ bool ConfigReader::ReadConfigs(std::string path){
std::vector<std::string> fileList = ScanFolder(); std::vector<std::string> fileList = ScanFolder(path);
if(fileList.size() == 1 && fileList[0].compare("ERROR") == 0){
return false;
}
if(fileList.size() > 0){ if(fileList.size() > 0){
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Found %d config files\n",fileList.size()); } if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Found %d config files\n",fileList.size()); }
processFileList(fileList); processFileList(fileList);
} }
return true;
} }
ConfigReader::~ConfigReader(){ ConfigReader::~ConfigReader(){
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("~ConfigReader\n"); } if(HID_DEBUG){ DEBUG_FUNCTION_LINE("~ConfigReader\n"); }
freeFSHandles();
} }
void ConfigReader::freeFSHandles(){ std::vector<std::string> ConfigReader::ScanFolder(std::string path){
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> config_files; std::vector<std::string> config_files;
if (this->pClient && this->pCmd){
s32 status = 0; struct dirent *dirent = NULL;
if((status = FSOpenDir(this->pClient,this->pCmd,path.c_str(),&dirhandle,-1)) == FS_STATUS_OK){ DIR *dirHandle = opendir(path.c_str());
FSDirEntry dir_entry; if (dirHandle == NULL){
while (FSReadDir(this->pClient, this->pCmd, dirhandle, &dir_entry, FS_RET_ALL_ERROR) == FS_STATUS_OK){ DEBUG_FUNCTION_LINE("Failed to open dir %s\n",path.c_str());
std::string full_path = path + "/" + dir_entry.name; config_files.push_back("ERROR"); //TODO: Find a proper solution
if((dir_entry.stat.flag&FS_STAT_FLAG_IS_DIRECTORY) != FS_STAT_FLAG_IS_DIRECTORY){ return config_files;
if(CPStringTools::EndsWith(std::string(dir_entry.name),".ini")){ }
config_files.push_back(full_path); while ((dirent = readdir(dirHandle)) != 0){
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Found ini: %s \n",full_path.c_str()); } bool isDir = dirent->d_type & DT_DIR;
} const char *filename = dirent->d_name;
}
} if(strcmp(filename,".") == 0 || strcmp(filename,"..") == 0){ continue; }
FSCloseDir(this->pClient,this->pCmd,dirhandle,-1);
}else{ std::string newPath = path + "/" + std::string(filename);
DEBUG_FUNCTION_LINE("Failed to open folder %s!\n",path.c_str());
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; return config_files;
} }
@ -137,45 +94,13 @@ void ConfigReader::processFileList(std::vector<std::string> path){
} }
std::string ConfigReader::loadFileToString(std::string path){ std::string ConfigReader::loadFileToString(std::string path){
s32 handle = 0;
s32 status = 0;
std::string strBuffer = ""; std::string strBuffer = "";
FSStat stats; u8 * buffer = NULL;
if((status = FSGetStat(this->pClient,this->pCmd,path.c_str(),&stats,-1)) == FS_STATUS_OK){ if(CPFSUtils::LoadFileToMem(path.c_str(),&buffer,NULL) > 0){
char * file = (char *) malloc((sizeof(char)*stats.size)+1); strBuffer = std::string((char *)buffer);
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
strBuffer = CPStringTools::removeCharFromString(strBuffer,'\r'); strBuffer = CPStringTools::removeCharFromString(strBuffer,'\r');
strBuffer = CPStringTools::removeCharFromString(strBuffer,' '); strBuffer = CPStringTools::removeCharFromString(strBuffer,' ');
strBuffer = CPStringTools::removeCharFromString(strBuffer,'\t'); strBuffer = CPStringTools::removeCharFromString(strBuffer,'\t');
}else{
DEBUG_FUNCTION_LINE("error: (GetStat) Couldn't open file (%s), error: %d",path.c_str(),status);
} }
return strBuffer; return strBuffer;
} }

View File

@ -23,8 +23,6 @@
#include "./ControllerPatcher.hpp" #include "./ControllerPatcher.hpp"
#define CONTROLLER_PATCHER_PATH "/vol/external01/wiiu/controller";
class ConfigReader{ class ConfigReader{
friend class ControllerPatcher; friend class ControllerPatcher;
friend class ConfigParser; friend class ConfigParser;
@ -50,7 +48,7 @@ class ConfigReader{
static void increaseNumberOfLoadedFiles(){ static void increaseNumberOfLoadedFiles(){
ConfigReader::numberValidFiles++; ConfigReader::numberValidFiles++;
} }
void ReadAllConfigs(); bool ReadConfigs(std::string path);
static s32 numberValidFiles; static s32 numberValidFiles;
//!Constructor //!Constructor
@ -59,15 +57,12 @@ class ConfigReader{
~ConfigReader(); ~ConfigReader();
s32 InitSDCard(); s32 InitSDCard();
void freeFSHandles();
void * pClient = NULL;
void * pCmd = NULL;
static ConfigReader *instance; static ConfigReader *instance;
std::string loadFileToString(std::string path); std::string loadFileToString(std::string path);
void processFileList(std::vector<std::string> path); void processFileList(std::vector<std::string> path);
std::vector<std::string> ScanFolder(); std::vector<std::string> ScanFolder(std::string path);
}; };
#endif #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]); 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(); InitOSFunctionPointers();
InitSocketFunctionPointers(); InitSocketFunctionPointers();
InitSysHIDFunctionPointers(); InitSysHIDFunctionPointers();
@ -503,19 +503,15 @@ bool ControllerPatcher::Init(){
if(HID_DEBUG){ DEBUG_FUNCTION_LINE("Config already done!\n"); } 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"); DEBUG_FUNCTION_LINE("Reading config files from SD Card\n");
ConfigReader* reader = ConfigReader::getInstance(); ConfigReader* reader = ConfigReader::getInstance();
s32 status = 0;
if((status = reader->InitSDCard()) == 0){ if(reader->ReadConfigs(pathToConfig)){
if(HID_DEBUG){ DEBUG_FUNCTION_LINE(" SD Card mounted for controller config!\n"); }
reader->ReadAllConfigs();
DEBUG_FUNCTION_LINE("Done with reading config files from SD Card\n"); DEBUG_FUNCTION_LINE("Done with reading config files from SD Card\n");
gConfig_done = HID_SDCARD_READ; 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"); DEBUG_FUNCTION_LINE("Initializing the data for button remapping\n");

View File

@ -65,8 +65,11 @@ class ControllerPatcher{
static void ResetConfig(); 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. \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 \brief De-Initialises the controller_patcher

View File

@ -372,6 +372,9 @@ enum UController_Type{
UController_Type_Pro4, UController_Type_Pro4,
}; };
#define CONTROLLER_PATCHER_PATH "sd:/wiiu/controller"
#define UController_Type_Gamepad_Name gettext("GamePad") #define UController_Type_Gamepad_Name gettext("GamePad")
#define UController_Type_Pro1_Name gettext("Pro Controller 1") #define UController_Type_Pro1_Name gettext("Pro Controller 1")
#define UController_Type_Pro2_Name gettext("Pro Controller 2") #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_ */