diff --git a/ConfigReader.cpp b/ConfigReader.cpp index b388187..5e4a4fa 100644 --- a/ConfigReader.cpp +++ b/ConfigReader.cpp @@ -15,11 +15,19 @@ * along with this program. If not, see . ****************************************************************************/ #include "./ConfigReader.hpp" +#include "./utils/CPFSUtils.hpp" #include #include #include #include +#include +#include +#include +#include +#include + +#include #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 fileList = ScanFolder(); +bool ConfigReader::ReadConfigs(std::string path){ + std::vector 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 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 ConfigReader::ScanFolder(std::string path){ std::vector 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 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; } diff --git a/ConfigReader.hpp b/ConfigReader.hpp index c793021..4a97088 100644 --- a/ConfigReader.hpp +++ b/ConfigReader.hpp @@ -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 path); - std::vector ScanFolder(); + std::vector ScanFolder(std::string path); }; #endif diff --git a/ControllerPatcher.cpp b/ControllerPatcher.cpp index f716b75..439c478 100644 --- a/ControllerPatcher.cpp +++ b/ControllerPatcher.cpp @@ -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"); diff --git a/ControllerPatcher.hpp b/ControllerPatcher.hpp index 2d9fd02..d975adc 100644 --- a/ControllerPatcher.hpp +++ b/ControllerPatcher.hpp @@ -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 diff --git a/patcher/ControllerPatcherDefs.h b/patcher/ControllerPatcherDefs.h index 1e72182..121e8a9 100644 --- a/patcher/ControllerPatcherDefs.h +++ b/patcher/ControllerPatcherDefs.h @@ -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") diff --git a/utils/CPFSUtils.cpp b/utils/CPFSUtils.cpp new file mode 100644 index 0000000..aed5628 --- /dev/null +++ b/utils/CPFSUtils.cpp @@ -0,0 +1,69 @@ +#include "CPFSUtils.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//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 diff --git a/utils/CPFSUtils.hpp b/utils/CPFSUtils.hpp new file mode 100644 index 0000000..c690b60 --- /dev/null +++ b/utils/CPFSUtils.hpp @@ -0,0 +1,12 @@ +#ifndef _CPFS_UTILS_H_ +#define _CPFS_UTILS_H_ +#include +#include +#include + +class CPFSUtils{ + public: + static s32 LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size); +}; + +#endif /* _CPFS_UTILS_H_ */