mirror of
https://github.com/wiiu-env/WiiUPluginSystem.git
synced 2024-11-16 15:49:23 +01:00
Add the possibility of configurations to the plugins!
Adds the configuration menu.
This commit is contained in:
parent
97536e1ee3
commit
e6e488a453
@ -1,6 +1,12 @@
|
|||||||
|
msgid "Press HOME to return."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Press B to return to the plugin overview."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
# English translations for Wii U Plugin System loader
|
# English translations for Wii U Plugin System loader
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the PACKAGE package.
|
||||||
msgid ""
|
msgid ""
|
||||||
@ -16,14 +22,33 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
#: src/menu/content/ContentHome.cpp:23
|
msgid "Press B to return to the plugin overview, HOME to return to the running application."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/menu/content/ContentHome.cpp:24
|
||||||
msgid "Welcome to the Wii U plugin loader"
|
msgid "Welcome to the Wii U plugin loader"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/menu/content/ContentHome.cpp:32
|
#: src/menu/content/ContentHome.cpp:33
|
||||||
msgid "Exit to HBL "
|
msgid "Exit to HBL "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/menu/content/ContentHome.cpp:35
|
#: src/menu/content/ContentHome.cpp:36
|
||||||
msgid "Apply Patches"
|
msgid "Apply Patches"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/myutils/ConfigUtils.cpp:113
|
||||||
|
msgid "Press HOME to return to the running application."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/myutils/ConfigUtils.cpp:114
|
||||||
|
msgid "Configurable running plugins:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/myutils/ConfigUtils.cpp:118
|
||||||
|
msgid "No configurable running plugins found."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/myutils/ConfigUtils.cpp:243
|
||||||
|
msgid "B = plugin overview, HOME = back to running application."
|
||||||
|
msgstr ""
|
||||||
|
@ -28,6 +28,7 @@ extern "C" {
|
|||||||
#define DEFAULT_WUPSLOADER_PATH SD_PATH WIIU_PATH "/apps/wiiupluginsystem"
|
#define DEFAULT_WUPSLOADER_PATH SD_PATH WIIU_PATH "/apps/wiiupluginsystem"
|
||||||
#define DEFAULT_LANG_PATH DEFAULT_WUPSLOADER_PATH "/languages"
|
#define DEFAULT_LANG_PATH DEFAULT_WUPSLOADER_PATH "/languages"
|
||||||
#define LANGUAGE_FILE_EXT ".lang"
|
#define LANGUAGE_FILE_EXT ".lang"
|
||||||
|
#define PLUGIN_CONFIG_FILE_EXT ".cfg"
|
||||||
#define PLUGIN_FILE_EXT ".mod"
|
#define PLUGIN_FILE_EXT ".mod"
|
||||||
|
|
||||||
#define WUPS_PLUGIN_PATH SD_PATH WIIU_PATH "/plugins"
|
#define WUPS_PLUGIN_PATH SD_PATH WIIU_PATH "/plugins"
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
#include "myutils/libntfs.h"
|
#include "myutils/libntfs.h"
|
||||||
#include "myutils/libfat.h"
|
#include "myutils/libfat.h"
|
||||||
#include "myutils/overlay_helper.h"
|
#include "myutils/overlay_helper.h"
|
||||||
|
#include "myutils/ConfigUtils.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "settings/CSettings.h"
|
#include "settings/CSettings.h"
|
||||||
|
|
||||||
@ -65,7 +66,6 @@ static void RestorePatches();
|
|||||||
int32_t isInMiiMakerHBL();
|
int32_t isInMiiMakerHBL();
|
||||||
void readAndPrintSegmentRegister(CThread *thread, void *arg);
|
void readAndPrintSegmentRegister(CThread *thread, void *arg);
|
||||||
|
|
||||||
|
|
||||||
extern "C" int32_t Menu_Main(int32_t argc, char **argv) {
|
extern "C" int32_t Menu_Main(int32_t argc, char **argv) {
|
||||||
if(gAppStatus == 2) {
|
if(gAppStatus == 2) {
|
||||||
//"No, we don't want to patch stuff again.");
|
//"No, we don't want to patch stuff again.");
|
||||||
@ -142,14 +142,14 @@ extern "C" int32_t Menu_Main(int32_t argc, char **argv) {
|
|||||||
std::vector<dyn_linking_relocation_entry_t *> relocations = DynamicLinkingHelper::getInstance()->getAllValidDynamicLinkingRelocations();
|
std::vector<dyn_linking_relocation_entry_t *> relocations = DynamicLinkingHelper::getInstance()->getAllValidDynamicLinkingRelocations();
|
||||||
DEBUG_FUNCTION_LINE("Found relocation information for %d functions\n",relocations.size());
|
DEBUG_FUNCTION_LINE("Found relocation information for %d functions\n",relocations.size());
|
||||||
|
|
||||||
if(!DynamicLinkingHelper::getInstance()->fillRelocations(relocations)){
|
if(!DynamicLinkingHelper::getInstance()->fillRelocations(relocations)) {
|
||||||
OSFatal("fillRelocations failed.");
|
OSFatal("fillRelocations failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isInMiiMakerHBL()) {
|
if(!isInMiiMakerHBL()) {
|
||||||
DEBUG_FUNCTION_LINE("Apply patches.\n");
|
DEBUG_FUNCTION_LINE("Apply patches.\n");
|
||||||
ApplyPatchesAndCallHookStartingApp();
|
ApplyPatchesAndCallHookStartingApp();
|
||||||
|
ConfigUtils::loadConfigFromSD();
|
||||||
|
|
||||||
if(MemoryMapping::isMemoryMapped()) {
|
if(MemoryMapping::isMemoryMapped()) {
|
||||||
DEBUG_FUNCTION_LINE("Mapping was already done. Running %016llX\n",gGameTitleID);
|
DEBUG_FUNCTION_LINE("Mapping was already done. Running %016llX\n",gGameTitleID);
|
||||||
|
113
loader/src/myutils/ConfigInformation.cpp
Normal file
113
loader/src/myutils/ConfigInformation.cpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2018 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 <map>
|
||||||
|
#include <string>
|
||||||
|
#include <wups/config/WUPSConfig.h>
|
||||||
|
#include "ConfigInformation.h"
|
||||||
|
|
||||||
|
ConfigInformation::ConfigInformation(WUPSConfig * config, std::string persistPath, std::string persistFileName) {
|
||||||
|
this->config = config;
|
||||||
|
this->persistPath = persistPath;
|
||||||
|
this->persistFileName = persistFileName;
|
||||||
|
createConfigSettings();
|
||||||
|
loadValuesFromSD();
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigInformation::~ConfigInformation() {
|
||||||
|
if(configSettings != NULL) {
|
||||||
|
updateAndSaveSettings();
|
||||||
|
delete configSettings;
|
||||||
|
configSettings = NULL;
|
||||||
|
}
|
||||||
|
if(config != NULL) {
|
||||||
|
delete config;
|
||||||
|
config = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigInformation::createConfigSettings() {
|
||||||
|
if(this->config == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this->configSettings != NULL) {
|
||||||
|
delete this->configSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<int32_t,std::string> defaultValues;
|
||||||
|
std::map<int32_t,std::string> settingsNames;
|
||||||
|
int32_t index = 0;
|
||||||
|
for (auto & curCat : this->config->getCategories()) {
|
||||||
|
for (auto & curItem : curCat->getItems()) {
|
||||||
|
std::string configID = curItem->getConfigID();
|
||||||
|
std::string defaultValue = curItem->persistValue();
|
||||||
|
|
||||||
|
defaultValues[index] = defaultValue;
|
||||||
|
settingsNames[index] = configID;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configSettings = new ConfigSettings(persistPath, persistFileName, defaultValues, settingsNames);
|
||||||
|
|
||||||
|
return (configSettings != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigInformation::loadValuesFromSD() {
|
||||||
|
if(this->config == NULL || this->configSettings == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto & curCat : this->config->getCategories()) {
|
||||||
|
for (auto & curItem : curCat->getItems()) {
|
||||||
|
std::string configID = curItem->getConfigID();
|
||||||
|
std::string prevValue = curItem->persistValue();
|
||||||
|
std::string loadedValue = this->configSettings->getValueAsString(this->configSettings->getIdByName(configID));
|
||||||
|
//DEBUG_FUNCTION_LINE("Loaded %s(%d) to %s. Previous value was %s \n",configID.c_str(),this->configSettings->getIdByName(configID), loadedValue.c_str(), prevValue.c_str());
|
||||||
|
if(prevValue.compare(loadedValue) != 0) {
|
||||||
|
//DEBUG_FUNCTION_LINE("Call loadValue\n");
|
||||||
|
curItem->loadValue(loadedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigInformation::updateAndSaveSettings() {
|
||||||
|
if(this->config == NULL || this->configSettings == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateConfigSettings();
|
||||||
|
configSettings->Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigInformation::updateConfigSettings() {
|
||||||
|
if(this->config == NULL || this->configSettings == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto & curCat : this->config->getCategories()) {
|
||||||
|
for (auto & curItem : curCat->getItems()) {
|
||||||
|
std::string configID = curItem->getConfigID();
|
||||||
|
std::string newValue = curItem->persistValue();
|
||||||
|
this->configSettings->setValueAsString(this->configSettings->getIdByName(configID), newValue);
|
||||||
|
//DEBUG_FUNCTION_LINE("Set %s(%d) to %s\n",configID.c_str(),this->configSettings->getIdByName(configID), newValue.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
61
loader/src/myutils/ConfigInformation.h
Normal file
61
loader/src/myutils/ConfigInformation.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2018 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 _CONFIG_INFORMATION_H_
|
||||||
|
#define _CONFIG_INFORMATION_H_
|
||||||
|
|
||||||
|
#include <wups/config/WUPSConfig.h>
|
||||||
|
#include "settings/ConfigSettings.h"
|
||||||
|
#include <string>
|
||||||
|
#include <utils/logger.h>
|
||||||
|
|
||||||
|
class ConfigInformation {
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Creates a ConfigInformation object for a given WUPSConfig.
|
||||||
|
This also is responsible for persisting/loading the configurations to/from the SDCard.
|
||||||
|
The configuration will be loaded created/loaded at "[persistPath]/[persistFileName]"
|
||||||
|
**/
|
||||||
|
ConfigInformation(WUPSConfig * config, std::string persistPath, std::string persistFileName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Deletes the given WUPSConfig
|
||||||
|
Calls updateAndSaveSettings
|
||||||
|
Deletes the created ConfigSettings
|
||||||
|
**/
|
||||||
|
~ConfigInformation();
|
||||||
|
|
||||||
|
void updateAndSaveSettings();
|
||||||
|
|
||||||
|
WUPSConfig * getConfig() {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool createConfigSettings();
|
||||||
|
bool loadValuesFromSD();
|
||||||
|
bool updateConfigSettings();
|
||||||
|
|
||||||
|
WUPSConfig * config = NULL;
|
||||||
|
ConfigSettings * configSettings = NULL;
|
||||||
|
std::string persistPath;
|
||||||
|
std::string persistFileName;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
354
loader/src/myutils/ConfigUtils.cpp
Normal file
354
loader/src/myutils/ConfigUtils.cpp
Normal file
@ -0,0 +1,354 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2018 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 <map>
|
||||||
|
#include <wups/config/WUPSConfig.h>
|
||||||
|
#include <dynamic_libs/vpad_functions.h>
|
||||||
|
#include <utils/logger.h>
|
||||||
|
|
||||||
|
#include "common/common.h"
|
||||||
|
#include "common/retain_vars.h"
|
||||||
|
|
||||||
|
#include "overlay_helper.h"
|
||||||
|
#include "ScreenUtils.h"
|
||||||
|
#include "ConfigUtils.h"
|
||||||
|
#include <language/gettext.h>
|
||||||
|
|
||||||
|
#include "ConfigInformation.h"
|
||||||
|
|
||||||
|
void ConfigUtils::configMenuOpenedCallback(wups_overlay_options_type_t screen, void * args) {
|
||||||
|
// We close the configuration menu with the home button, but this would also
|
||||||
|
// trigger the home menu.
|
||||||
|
// To avoid this (and restore the GX2 buffers properly) we disable the home menu button
|
||||||
|
// as long we're in the configuration menu.
|
||||||
|
OSEnableHomeButtonMenu(false);
|
||||||
|
|
||||||
|
std::vector<WUPSConfig*> * configList = (std::vector<WUPSConfig*> *) args;
|
||||||
|
|
||||||
|
if(configList == NULL) {
|
||||||
|
DEBUG_FUNCTION_LINE("configList was NULL.\n");
|
||||||
|
// Re-enable home button. TODO: Only enable when it was enabled before.
|
||||||
|
OSEnableHomeButtonMenu(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t i = 0;
|
||||||
|
int32_t x = 0;
|
||||||
|
int32_t screen_y_pos = 0;
|
||||||
|
int32_t visible_rows_start = 2;
|
||||||
|
int32_t visible_rows_end = 16;
|
||||||
|
int32_t visible_rows_range = visible_rows_end - visible_rows_start;
|
||||||
|
|
||||||
|
WUPSConfig* curConfig = NULL;
|
||||||
|
|
||||||
|
VPADData vpad_data;
|
||||||
|
int32_t error;
|
||||||
|
|
||||||
|
int32_t maxSelect = 0;
|
||||||
|
int32_t curSelect = 0;
|
||||||
|
|
||||||
|
int32_t curScreenOffset = 0;
|
||||||
|
bool firstRun = true;
|
||||||
|
while(true) {
|
||||||
|
VPADRead(0, &vpad_data, 1, &error);
|
||||||
|
if(vpad_data.btns_d == VPAD_BUTTON_HOME) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t newSelect = curSelect;
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if(curConfig == NULL) {
|
||||||
|
maxSelect = configList->size();
|
||||||
|
if(maxSelect > 0) {
|
||||||
|
maxSelect--;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool selected = false;
|
||||||
|
|
||||||
|
if(vpad_data.btns_r & VPAD_BUTTON_DOWN) {
|
||||||
|
newSelect++;
|
||||||
|
}
|
||||||
|
if(vpad_data.btns_r & VPAD_BUTTON_UP) {
|
||||||
|
newSelect--;
|
||||||
|
}
|
||||||
|
if(vpad_data.btns_r & VPAD_BUTTON_A) {
|
||||||
|
selected = true;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newSelect < 0) {
|
||||||
|
newSelect = maxSelect;
|
||||||
|
} else if(newSelect > maxSelect) {
|
||||||
|
newSelect = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newSelect != curSelect) {
|
||||||
|
curSelect = newSelect;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if(!firstRun) {
|
||||||
|
if(!changed) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
firstRun = false;
|
||||||
|
|
||||||
|
ScreenUtils::OSScreenClear(screen);
|
||||||
|
screen_y_pos = 0;
|
||||||
|
ScreenUtils::printTextOnScreen(screen, 0, visible_rows_end + 1, gettext("Press HOME to return to the running application."));
|
||||||
|
ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++,gettext("Configurable running plugins:"));
|
||||||
|
ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++,"==========================");
|
||||||
|
|
||||||
|
if(configList->size() == 0) {
|
||||||
|
ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++,gettext("No configurable running plugins found."));
|
||||||
|
ScreenUtils::flipBuffers(screen);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t index = 0;
|
||||||
|
for (auto & curConfig_ : *configList) {
|
||||||
|
if(index == curSelect) {
|
||||||
|
ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++,"> %s",curConfig_->getName().c_str());
|
||||||
|
if(selected) {
|
||||||
|
curConfig = curConfig_;
|
||||||
|
curSelect = 0;
|
||||||
|
curScreenOffset = 0;
|
||||||
|
firstRun = true;
|
||||||
|
maxSelect = 0;
|
||||||
|
for (auto & curCat : curConfig_->getCategories()) {
|
||||||
|
maxSelect += curCat->getItems().size();
|
||||||
|
}
|
||||||
|
if(maxSelect > 0) {
|
||||||
|
maxSelect--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++," %s",curConfig_->getName().c_str());
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
ScreenUtils::flipBuffers(screen);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
WUPSConfigButtons pressedButtons = WUPS_CONFIG_BUTTON_NONE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
if(vpad_data.btns_r & VPAD_BUTTON_DOWN) {
|
||||||
|
pressedButtons |= WUPS_CONFIG_BUTTON_DOWN;
|
||||||
|
}
|
||||||
|
if(vpad_data.btns_r & VPAD_BUTTON_UP) {
|
||||||
|
pressedButtons |= WUPS_CONFIG_BUTTON_UP;
|
||||||
|
}*/
|
||||||
|
if(vpad_data.btns_d & VPAD_BUTTON_A) {
|
||||||
|
pressedButtons |= WUPS_CONFIG_BUTTON_A;
|
||||||
|
}
|
||||||
|
if(vpad_data.btns_d & VPAD_BUTTON_B) {
|
||||||
|
pressedButtons |= WUPS_CONFIG_BUTTON_B;
|
||||||
|
}
|
||||||
|
if(vpad_data.btns_d & VPAD_BUTTON_LEFT) {
|
||||||
|
pressedButtons |= WUPS_CONFIG_BUTTON_LEFT;
|
||||||
|
}
|
||||||
|
if(vpad_data.btns_d & VPAD_BUTTON_RIGHT) {
|
||||||
|
pressedButtons |= WUPS_CONFIG_BUTTON_RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(vpad_data.btns_r & VPAD_BUTTON_DOWN) {
|
||||||
|
newSelect++;
|
||||||
|
}
|
||||||
|
if(vpad_data.btns_r & VPAD_BUTTON_UP) {
|
||||||
|
newSelect--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(vpad_data.btns_d & VPAD_BUTTON_B) {
|
||||||
|
curConfig = NULL;
|
||||||
|
curSelect = 0;
|
||||||
|
curScreenOffset = 0;
|
||||||
|
firstRun = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(newSelect < 0) {
|
||||||
|
newSelect = maxSelect;
|
||||||
|
} else if(newSelect > maxSelect) {
|
||||||
|
newSelect = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newSelect != curSelect) {
|
||||||
|
curSelect = newSelect;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
if(pressedButtons != WUPS_CONFIG_BUTTON_NONE) {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t cur_visible_rows = 0;
|
||||||
|
if(!firstRun) {
|
||||||
|
if(!changed) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
firstRun = false;
|
||||||
|
|
||||||
|
ScreenUtils::OSScreenClear(screen);
|
||||||
|
|
||||||
|
int32_t inSelect = 0;
|
||||||
|
|
||||||
|
bool ignore = false;
|
||||||
|
for (auto & curCat : curConfig->getCategories()) {
|
||||||
|
cur_visible_rows += 2;
|
||||||
|
for (auto & curItem : curCat->getItems()) {
|
||||||
|
cur_visible_rows++;
|
||||||
|
if(!ignore && curSelect == inSelect) {
|
||||||
|
if(curSelect == 0) {
|
||||||
|
curScreenOffset = 0;
|
||||||
|
}else if(cur_visible_rows + curScreenOffset >= visible_rows_range) {
|
||||||
|
curScreenOffset -= (cur_visible_rows + curScreenOffset) - visible_rows_range;
|
||||||
|
}else if(cur_visible_rows + curScreenOffset < visible_rows_range/2 && cur_visible_rows >= visible_rows_range/2) {
|
||||||
|
curScreenOffset -= (cur_visible_rows + curScreenOffset) - visible_rows_range/2;
|
||||||
|
}
|
||||||
|
ignore = true;
|
||||||
|
}
|
||||||
|
inSelect++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenUtils::printTextOnScreen(screen, 0, 0, "Configuration for %s:", curConfig->getName().c_str());
|
||||||
|
|
||||||
|
int32_t arrow_x_offset = 60;
|
||||||
|
if(curScreenOffset < 0) {
|
||||||
|
ScreenUtils::printTextOnScreen(screen, arrow_x_offset, visible_rows_start + 1, " ^");
|
||||||
|
ScreenUtils::printTextOnScreen(screen, arrow_x_offset, visible_rows_start + 2, " |");
|
||||||
|
}
|
||||||
|
if(curScreenOffset + cur_visible_rows > visible_rows_range) {
|
||||||
|
ScreenUtils::printTextOnScreen(screen, arrow_x_offset, visible_rows_end - 2, " | ");
|
||||||
|
ScreenUtils::printTextOnScreen(screen, arrow_x_offset, visible_rows_end - 1, " v");
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenUtils::printTextOnScreen(screen, 0, visible_rows_end + 1, gettext("B = plugin overview, HOME = back to running application."));
|
||||||
|
|
||||||
|
screen_y_pos = curScreenOffset + visible_rows_start;
|
||||||
|
|
||||||
|
inSelect = 0;
|
||||||
|
|
||||||
|
for (auto & curCat : curConfig->getCategories()) {
|
||||||
|
if((screen_y_pos + 2) >= visible_rows_end) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if((screen_y_pos - visible_rows_start) < -1) {
|
||||||
|
screen_y_pos += 2;
|
||||||
|
} else if((screen_y_pos - visible_rows_start) < 0) {
|
||||||
|
screen_y_pos++;
|
||||||
|
ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++,"==========================");
|
||||||
|
} else {
|
||||||
|
ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++,"%s",curCat->getName().c_str());
|
||||||
|
ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++,"==========================");
|
||||||
|
}
|
||||||
|
for (auto & curItem : curCat->getItems()) {
|
||||||
|
if(screen_y_pos >= visible_rows_end) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(curSelect == inSelect) {
|
||||||
|
if(pressedButtons != WUPS_CONFIG_BUTTON_NONE) {
|
||||||
|
curItem->onButtonPressed(pressedButtons);
|
||||||
|
}
|
||||||
|
ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++,"> %-40s %s\n",curItem->getDisplayName().c_str(),curItem->getCurrentValueSelectedDisplay().c_str());
|
||||||
|
} else if((screen_y_pos - visible_rows_start) >= 0) {
|
||||||
|
ScreenUtils::printTextOnScreen(screen, x, screen_y_pos++," %-40s %s\n",curItem->getDisplayName().c_str(),curItem->getCurrentValueDisplay().c_str());
|
||||||
|
} else {
|
||||||
|
screen_y_pos++;
|
||||||
|
}
|
||||||
|
inSelect++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenUtils::flipBuffers(screen);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
// Re-enable home button. TODO: Only enable when it was enabled before.
|
||||||
|
// Currently we can be sure it was enabled, because it's an requirement to enter the configuration menu.
|
||||||
|
// This might change in the future.
|
||||||
|
OSEnableHomeButtonMenu(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigUtils::openConfigMenu(std::vector<WUPSConfig*> configs) {
|
||||||
|
overlay_helper(WUPS_OVERLAY_DRC_AND_TV_WITH_DRC_PRIO, configMenuOpenedCallback, (void*) &configs);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ConfigInformation *> ConfigUtils::getConfigInformation() {
|
||||||
|
std::vector<ConfigInformation *> configs;
|
||||||
|
for(int32_t plugin_index=0; plugin_index<gbl_replacement_data.number_used_plugins; plugin_index++) {
|
||||||
|
replacement_data_plugin_t * plugin_data = &gbl_replacement_data.plugin_data[plugin_index];
|
||||||
|
if(plugin_data == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for(int32_t j=0; j<plugin_data->number_used_hooks; j++) {
|
||||||
|
replacement_data_hook_t * hook_data = &plugin_data->hooks[j];
|
||||||
|
if(hook_data->type == WUPS_LOADER_HOOK_GET_CONFIG) {
|
||||||
|
if(hook_data->func_pointer == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
void * func_ptr = hook_data->func_pointer;
|
||||||
|
WUPSConfig * cur_config = ((WUPSConfig* (*)(void))((uint32_t*)func_ptr) )();
|
||||||
|
DCFlushRange(cur_config, sizeof(WUPSConfig));
|
||||||
|
if(cur_config != NULL) {
|
||||||
|
std::string fullPath(plugin_data->path);
|
||||||
|
std::string path = fullPath.substr(0, fullPath.find_last_of("/"));
|
||||||
|
size_t filenamePos = fullPath.find_last_of("/")+1;
|
||||||
|
std::string filename = fullPath.substr(filenamePos, fullPath.find_last_of(".") - filenamePos);
|
||||||
|
ConfigInformation * configInfo = new ConfigInformation(cur_config, path, filename.append(PLUGIN_CONFIG_FILE_EXT));
|
||||||
|
configs.push_back(configInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigUtils::deleteConfigInformation(std::vector<ConfigInformation *> configs) {
|
||||||
|
for (auto & curConfig : configs) {
|
||||||
|
delete curConfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigUtils::loadConfigFromSD() {
|
||||||
|
deleteConfigInformation(getConfigInformation());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigUtils::openConfigMenu() {
|
||||||
|
std::vector<ConfigInformation *> configInfos = getConfigInformation();
|
||||||
|
|
||||||
|
std::vector<WUPSConfig *> configs;
|
||||||
|
|
||||||
|
for (auto & curConfig : configInfos) {
|
||||||
|
configs.push_back(curConfig->getConfig());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto & curConfig : configs) {
|
||||||
|
DCFlushRange(curConfig, sizeof(WUPSConfig));
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigUtils::openConfigMenu(configs);
|
||||||
|
|
||||||
|
for (auto & curConfig : configs) {
|
||||||
|
DCFlushRange(curConfig, sizeof(WUPSConfig));
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteConfigInformation(configInfos);
|
||||||
|
}
|
81
loader/src/myutils/ConfigUtils.h
Normal file
81
loader/src/myutils/ConfigUtils.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2018 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 __CONFIG_UTILS_H_
|
||||||
|
#define __CONFIG_UTILS_H_
|
||||||
|
|
||||||
|
#include <wups.h>
|
||||||
|
#include <wups/config/WUPSConfig.h>
|
||||||
|
#include "ConfigInformation.h"
|
||||||
|
|
||||||
|
class ConfigUtils {
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Loads the configuration files of all loaded plugins from the SDCard
|
||||||
|
and triggers the "loadValue" if they differ the default value.
|
||||||
|
**/
|
||||||
|
static void loadConfigFromSD();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Opens the configuration menu where plugins can be configured.
|
||||||
|
Plugins need to implement the WUPS_GET_CONFIG() hook to show up in the menu.
|
||||||
|
The menu will be rendered on the TV and DRC screen, with optimization for the DRC.
|
||||||
|
If the menu is low, the menu may be only rendered to the DRC.
|
||||||
|
**/
|
||||||
|
static void openConfigMenu();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ConfigUtils() {}
|
||||||
|
~ConfigUtils() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Opens the configuration menu for a list of WUPSConfig.
|
||||||
|
If a configuration menu context could be created successfully, "configMenuOpenedCallback"
|
||||||
|
will be called, with the configs as an argument.
|
||||||
|
**/
|
||||||
|
static void openConfigMenu(std::vector<WUPSConfig*> configs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
The callback that renders the configuration menu.
|
||||||
|
The args parameter expects a "std::vector<WUPSConfig*> *".
|
||||||
|
Depending on the screen
|
||||||
|
**/
|
||||||
|
static void configMenuOpenedCallback(wups_overlay_options_type_t screen, void * args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Gets the ConfigInformation for all loaded plugin that have implemented
|
||||||
|
the WUPS_GET_CONFIG() hook.
|
||||||
|
|
||||||
|
This triggers creating ConfigInformation objects.
|
||||||
|
ConfigInformation objects load the corresponding configuration file for a plugin
|
||||||
|
from the sd card. It also calls the "loadValue" function if a loaded value differs from the
|
||||||
|
default value. This behaviour may change in the future.
|
||||||
|
See the ConfigInformation class for more information.
|
||||||
|
**/
|
||||||
|
static std::vector<ConfigInformation *> getConfigInformation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Delete a list of ConfigInformation.
|
||||||
|
The destructor of "ConfigInformation" causes the configuration files for the plugin
|
||||||
|
to be written to the sd card (if the value have changed). This behaviour may change
|
||||||
|
in the future. See the ConfigInformation class for more information.
|
||||||
|
**/
|
||||||
|
static void deleteConfigInformation(std::vector<ConfigInformation *> configs);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
69
loader/src/myutils/ScreenUtils.cpp
Normal file
69
loader/src/myutils/ScreenUtils.cpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2018 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 <utils/logger.h>
|
||||||
|
#include <wups.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include "dynamic_libs/os_functions.h"
|
||||||
|
#include "ScreenUtils.h"
|
||||||
|
|
||||||
|
void ScreenUtils::printTextOnScreen(wups_overlay_options_type_t screen, int x,int y, const char * msg, ...) {
|
||||||
|
if(screen == WUPS_OVERLAY_NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * tmp = NULL;
|
||||||
|
|
||||||
|
va_list va;
|
||||||
|
va_start(va, msg);
|
||||||
|
if((vasprintf(&tmp, msg, va) >= 0) && tmp) {
|
||||||
|
if(screen != WUPS_OVERLAY_DRC_ONLY) { // Draw TV if it's not DRC exclusive.
|
||||||
|
OSScreenPutFontEx(0, x, y, tmp);
|
||||||
|
}
|
||||||
|
if(screen != WUPS_OVERLAY_TV_ONLY) { // Draw DRC if it's not TV exclusive.
|
||||||
|
OSScreenPutFontEx(1, x, y, tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
va_end(va);
|
||||||
|
|
||||||
|
if(tmp) {
|
||||||
|
free(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenUtils::OSScreenClear(wups_overlay_options_type_t screen) {
|
||||||
|
if(screen == WUPS_OVERLAY_NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(screen != WUPS_OVERLAY_DRC_ONLY) { // Clear TV if it's not DRC exclusive.
|
||||||
|
OSScreenClearBufferEx(0, 0);
|
||||||
|
}
|
||||||
|
if(screen != WUPS_OVERLAY_TV_ONLY) { // Clear DRC if it's not TV exclusive.
|
||||||
|
OSScreenClearBufferEx(1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScreenUtils::flipBuffers(wups_overlay_options_type_t screen) {
|
||||||
|
if(screen == WUPS_OVERLAY_NONE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(screen != WUPS_OVERLAY_DRC_ONLY) { // Flip TV buffer if it's not DRC exclusive.
|
||||||
|
OSScreenFlipBuffersEx(0);
|
||||||
|
}
|
||||||
|
if(screen != WUPS_OVERLAY_TV_ONLY) { // Flip DRC buffer if it's not TV exclusive.
|
||||||
|
OSScreenFlipBuffersEx(1);
|
||||||
|
}
|
||||||
|
}
|
50
loader/src/myutils/ScreenUtils.h
Normal file
50
loader/src/myutils/ScreenUtils.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2018 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 __SCREEN_UTILS_H_
|
||||||
|
#define __SCREEN_UTILS_H_
|
||||||
|
|
||||||
|
class ScreenUtils {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Clears the screen for the given screens
|
||||||
|
\param screen defines on which screens should be printed
|
||||||
|
\param x defines the x position (character position) where the text should be printed
|
||||||
|
\param y defines on which line the text should be printed
|
||||||
|
\param msg C string that contains the text to be printed.
|
||||||
|
It can optionally contain embedded format specifiers that are replaced by the values specified in subsequent additional arguments and formatted as requested.
|
||||||
|
See printf for more information
|
||||||
|
\param ... Depending on the format string, the function may expect a sequence of additional arguments, each containing a value to be used to replace a format specifier in the format string
|
||||||
|
**/
|
||||||
|
static void printTextOnScreen(wups_overlay_options_type_t screen, int x,int y, const char * msg, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Clears the screen for the given screens
|
||||||
|
\param screen defines which screens should be cleared
|
||||||
|
**/
|
||||||
|
static void OSScreenClear(wups_overlay_options_type_t screen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Flips the buffer for the given screens
|
||||||
|
\param screen defines which screens should be flipped.
|
||||||
|
**/
|
||||||
|
static void flipBuffers(wups_overlay_options_type_t screen);
|
||||||
|
private:
|
||||||
|
ScreenUtils() {}
|
||||||
|
~ScreenUtils() {}
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif
|
@ -4,6 +4,7 @@
|
|||||||
#include "common/retain_vars.h"
|
#include "common/retain_vars.h"
|
||||||
#include "hooks_patcher.h"
|
#include "hooks_patcher.h"
|
||||||
#include "myutils/overlay_helper.h"
|
#include "myutils/overlay_helper.h"
|
||||||
|
#include "myutils/ConfigUtils.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "mymemory/memory_mapping.h"
|
#include "mymemory/memory_mapping.h"
|
||||||
@ -61,6 +62,48 @@ DECL(void, GX2WaitForVsync, void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t vpadPressCooldown = 0xFF;
|
uint8_t vpadPressCooldown = 0xFF;
|
||||||
|
|
||||||
|
uint8_t angleX_counter = 0;
|
||||||
|
float angleX_delta = 0.0f;
|
||||||
|
float angleX_last = 0.0f;
|
||||||
|
uint8_t angleX_frameCounter = 0;
|
||||||
|
|
||||||
|
bool checkMagic(VPADData *buffer) {
|
||||||
|
// buffer->angle stores the rotations per axis since the app started.
|
||||||
|
// Each full rotation add/subtracts 1.0f (depending on the direction).
|
||||||
|
|
||||||
|
// Check for rotation every only 5 frames.
|
||||||
|
angleX_frameCounter++;
|
||||||
|
if(angleX_frameCounter >= 5) {
|
||||||
|
// Get how much the gamepad rotated within the last 5 frames.
|
||||||
|
float diff_angle = -(buffer->angle.x - angleX_last);
|
||||||
|
// We want the gamepad to make (on average) at least 0.16% (1/6) of a full rotation per 5 frames (for 6 times in a row).
|
||||||
|
float target_diff = (0.16f);
|
||||||
|
// Calculate if rotated enough in this step (including the delta from the last step).
|
||||||
|
float total_diff = (diff_angle + angleX_delta) - target_diff;
|
||||||
|
if(total_diff > 0.0f) {
|
||||||
|
// The rotation in this step was enough.
|
||||||
|
angleX_counter++;
|
||||||
|
// When the gamepad rotated ~0.16% for 6 times in a row we made a full rotation!
|
||||||
|
if(angleX_counter > 5) {
|
||||||
|
ConfigUtils::openConfigMenu();
|
||||||
|
// reset stuff.
|
||||||
|
angleX_counter = 0;
|
||||||
|
angleX_delta = 0.0f;
|
||||||
|
} else {
|
||||||
|
// Save difference as it will be added on the next check.
|
||||||
|
angleX_delta = total_diff;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// reset counter if it stopped rotating.
|
||||||
|
angleX_counter = 0;
|
||||||
|
}
|
||||||
|
angleX_frameCounter = 0;
|
||||||
|
angleX_last = buffer->angle.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
DECL(int32_t, VPADRead, int32_t chan, VPADData *buffer, uint32_t buffer_size, int32_t *error) {
|
DECL(int32_t, VPADRead, int32_t chan, VPADData *buffer, uint32_t buffer_size, int32_t *error) {
|
||||||
int32_t result = real_VPADRead(chan, buffer, buffer_size, error);
|
int32_t result = real_VPADRead(chan, buffer, buffer_size, error);
|
||||||
|
|
||||||
@ -72,6 +115,14 @@ DECL(int32_t, VPADRead, int32_t chan, VPADData *buffer, uint32_t buffer_size, in
|
|||||||
}
|
}
|
||||||
vpadPressCooldown = 0x3C;
|
vpadPressCooldown = 0x3C;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(result > 0 && (buffer[0].btns_h == (VPAD_BUTTON_L | VPAD_BUTTON_DOWN | VPAD_BUTTON_MINUS)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) {
|
||||||
|
ConfigUtils::openConfigMenu();
|
||||||
|
vpadPressCooldown = 0x3C;
|
||||||
|
} else if(result > 0 && OSIsHomeButtonMenuEnabled()) {
|
||||||
|
checkMagic(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
if(vpadPressCooldown > 0) {
|
if(vpadPressCooldown > 0) {
|
||||||
vpadPressCooldown--;
|
vpadPressCooldown--;
|
||||||
}
|
}
|
||||||
|
262
loader/src/settings/ConfigSettings.cpp
Normal file
262
loader/src/settings/ConfigSettings.cpp
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
* Modified by Maschell, 2018 for WiiU plugin system loader
|
||||||
|
*
|
||||||
|
* 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "common/common.h"
|
||||||
|
#include "ConfigSettings.h"
|
||||||
|
#include <fs/CFile.hpp>
|
||||||
|
#include <fs/FSUtils.h>
|
||||||
|
#include <utils/StringTools.h>
|
||||||
|
#include <utils/logger.h>
|
||||||
|
#include <language/gettext.h>
|
||||||
|
|
||||||
|
#define VERSION_LINE "# WiiUPluginSystem - plugin settings file v"
|
||||||
|
#define VALID_VERSION 1
|
||||||
|
|
||||||
|
ConfigSettings::ConfigSettings(std::string configPath, std::string filename, std::map<int32_t, std::string> defaultValues, std::map<int32_t, std::string> settingsNames) {
|
||||||
|
bChanged = false;
|
||||||
|
memset(&nullValue, 0, sizeof(nullValue));
|
||||||
|
nullValue.strValue = new std::string();
|
||||||
|
|
||||||
|
this->configPath = configPath;
|
||||||
|
this->fileName = filename;
|
||||||
|
this->defaultValues = defaultValues;
|
||||||
|
this->settingsNames = settingsNames;
|
||||||
|
|
||||||
|
this->Load();
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigSettings::~ConfigSettings() {
|
||||||
|
for(uint32_t i = 0; i < settingsValues.size(); i++) {
|
||||||
|
if(settingsValues[i].dataType == TypeString)
|
||||||
|
delete settingsValues[i].strValue;
|
||||||
|
}
|
||||||
|
delete nullValue.strValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigSettings::SetDefault() {
|
||||||
|
for(uint32_t i = 0; i < settingsValues.size(); i++) {
|
||||||
|
if(settingsValues[i].dataType == TypeString) {
|
||||||
|
delete settingsValues[i].strValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto & kv : settingsNames) {
|
||||||
|
settingsNames[kv.first] = kv.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto & kv : defaultValues) {
|
||||||
|
SettingValue value;
|
||||||
|
value.dataType = TypeString;
|
||||||
|
value.strValue = new std::string(kv.second);
|
||||||
|
settingsValues[kv.first] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigSettings::Load() {
|
||||||
|
//! Reset default path variables to the right device
|
||||||
|
SetDefault();
|
||||||
|
|
||||||
|
std::string filepath = configPath + "/";
|
||||||
|
filepath += fileName;
|
||||||
|
|
||||||
|
DEBUG_FUNCTION_LINE("Loading Configuration from %s\n",filepath.c_str());
|
||||||
|
|
||||||
|
CFile file(filepath, CFile::ReadOnly);
|
||||||
|
if (!file.isOpen()) {
|
||||||
|
DEBUG_FUNCTION_LINE("Failed to open file\n");
|
||||||
|
bChanged = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string strBuffer;
|
||||||
|
strBuffer.resize(file.size());
|
||||||
|
file.read((uint8_t *) &strBuffer[0], strBuffer.size());
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
//! remove all windows crap signs
|
||||||
|
size_t position;
|
||||||
|
while(1 && !strBuffer.empty()) {
|
||||||
|
position = strBuffer.find('\r');
|
||||||
|
if(position == std::string::npos)
|
||||||
|
break;
|
||||||
|
|
||||||
|
strBuffer.erase(position, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> lines = StringTools::stringSplit(strBuffer, "\n");
|
||||||
|
|
||||||
|
if(lines.empty() || !ValidVersion(lines[0])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < lines.size(); ++i) {
|
||||||
|
std::vector<std::string> valueSplit = StringTools::stringSplit(lines[i], "=");
|
||||||
|
if(valueSplit.size() != 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
while((valueSplit[0].size() > 0) && valueSplit[0][0] == ' ') {
|
||||||
|
valueSplit[0].erase(0, 1);
|
||||||
|
}
|
||||||
|
while((valueSplit[1].size() > 0) && valueSplit[1][ valueSplit[1].size() - 1 ] == ' ') {
|
||||||
|
valueSplit[1].resize(valueSplit[1].size() - 1);
|
||||||
|
}
|
||||||
|
for(uint32_t n = 0; n < settingsNames.size(); n++) {
|
||||||
|
if(settingsNames.empty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(valueSplit[0] == settingsNames[n]) {
|
||||||
|
switch(settingsValues[n].dataType) {
|
||||||
|
case TypeBool:
|
||||||
|
settingsValues[n].bValue = atoi(valueSplit[1].c_str());
|
||||||
|
break;
|
||||||
|
case TypeS8:
|
||||||
|
settingsValues[n].cValue = atoi(valueSplit[1].c_str());
|
||||||
|
break;
|
||||||
|
case TypeU8:
|
||||||
|
settingsValues[n].ucValue = atoi(valueSplit[1].c_str());
|
||||||
|
break;
|
||||||
|
case TypeS16:
|
||||||
|
settingsValues[n].sValue = atoi(valueSplit[1].c_str());
|
||||||
|
break;
|
||||||
|
case TypeU16:
|
||||||
|
settingsValues[n].usValue = atoi(valueSplit[1].c_str());
|
||||||
|
break;
|
||||||
|
case TypeS32:
|
||||||
|
settingsValues[n].iValue = atoi(valueSplit[1].c_str());
|
||||||
|
break;
|
||||||
|
case TypeU32:
|
||||||
|
settingsValues[n].uiValue = strtoul(valueSplit[1].c_str(), 0, 10);
|
||||||
|
break;
|
||||||
|
case TypeF32:
|
||||||
|
settingsValues[n].fValue = atof(valueSplit[1].c_str());
|
||||||
|
break;
|
||||||
|
case TypeString:
|
||||||
|
if(settingsValues[n].strValue == NULL)
|
||||||
|
settingsValues[n].strValue = new std::string();
|
||||||
|
|
||||||
|
*settingsValues[n].strValue = valueSplit[1];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigSettings::ValidVersion(const std::string & versionString) {
|
||||||
|
int32_t version = 0;
|
||||||
|
|
||||||
|
if(versionString.find(VERSION_LINE) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
version = atoi(versionString.c_str() + strlen(VERSION_LINE));
|
||||||
|
|
||||||
|
return version == VALID_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigSettings::Reset() {
|
||||||
|
this->SetDefault();
|
||||||
|
bChanged = true;
|
||||||
|
|
||||||
|
if (this->Save()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ConfigSettings::getIdByName(std::string configID) {
|
||||||
|
for (auto & kv : settingsNames) {
|
||||||
|
if(configID.compare(kv.second) == 0) {
|
||||||
|
return kv.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigSettings::Save() {
|
||||||
|
if(!bChanged) {
|
||||||
|
DEBUG_FUNCTION_LINE("Nothing has changed, we can skip\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FSUtils::CreateSubfolder(configPath.c_str());
|
||||||
|
|
||||||
|
std::string filepath = configPath + "/";
|
||||||
|
filepath += fileName;
|
||||||
|
|
||||||
|
s32 res = open(filepath.c_str(), O_CREAT | O_TRUNC | O_WRONLY);
|
||||||
|
close(res);
|
||||||
|
|
||||||
|
CFile file(filepath, CFile::WriteOnly);
|
||||||
|
if (!file.isOpen()) {
|
||||||
|
DEBUG_FUNCTION_LINE("failed to open %s\n",filepath.c_str());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
file.fwrite("%s%i\n", VERSION_LINE, VALID_VERSION);
|
||||||
|
|
||||||
|
for(uint32_t i = 0; i < settingsValues.size(); i++) {
|
||||||
|
switch(settingsValues[i].dataType) {
|
||||||
|
case TypeBool:
|
||||||
|
file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].bValue);
|
||||||
|
break;
|
||||||
|
case TypeS8:
|
||||||
|
file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].cValue);
|
||||||
|
break;
|
||||||
|
case TypeU8:
|
||||||
|
file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].ucValue);
|
||||||
|
break;
|
||||||
|
case TypeS16:
|
||||||
|
file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].sValue);
|
||||||
|
break;
|
||||||
|
case TypeU16:
|
||||||
|
file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].usValue);
|
||||||
|
break;
|
||||||
|
case TypeS32:
|
||||||
|
file.fwrite("%s=%i\n", settingsNames[i], settingsValues[i].iValue);
|
||||||
|
break;
|
||||||
|
case TypeU32:
|
||||||
|
file.fwrite("%s=%u\n", settingsNames[i], settingsValues[i].uiValue);
|
||||||
|
break;
|
||||||
|
case TypeF32:
|
||||||
|
file.fwrite("%s=%f\n", settingsNames[i], settingsValues[i].fValue);
|
||||||
|
break;
|
||||||
|
case TypeString:
|
||||||
|
if(settingsValues[i].strValue != NULL)
|
||||||
|
file.fwrite("%s=%s\n", settingsNames[i].c_str(), settingsValues[i].strValue->c_str());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
bChanged = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
240
loader/src/settings/ConfigSettings.h
Normal file
240
loader/src/settings/ConfigSettings.h
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2015 Dimok
|
||||||
|
*
|
||||||
|
* Modified by Maschell, 2018 for WiiU plugin system loader
|
||||||
|
*
|
||||||
|
* 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 _CONFIG_SETTINGS_H_
|
||||||
|
#define _CONFIG_SETTINGS_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dynamic_libs/os_types.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
class ConfigSettings {
|
||||||
|
public:
|
||||||
|
//!Constructor
|
||||||
|
ConfigSettings(std::string configPath, std::string filename, std::map<int32_t, std::string> defaultValues, std::map<int32_t, std::string> settingsNames);
|
||||||
|
//!Destructor
|
||||||
|
~ConfigSettings();
|
||||||
|
|
||||||
|
//!Set Default Settings
|
||||||
|
void SetDefault();
|
||||||
|
//!Load Settings
|
||||||
|
bool Load();
|
||||||
|
//!Save Settings
|
||||||
|
bool Save();
|
||||||
|
//!Reset Settings
|
||||||
|
bool Reset();
|
||||||
|
|
||||||
|
enum DataTypes {
|
||||||
|
TypeNone,
|
||||||
|
TypeBool,
|
||||||
|
TypeS8,
|
||||||
|
TypeU8,
|
||||||
|
TypeS16,
|
||||||
|
TypeU16,
|
||||||
|
TypeS32,
|
||||||
|
TypeU32,
|
||||||
|
TypeF32,
|
||||||
|
TypeString
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t & getDataType(int32_t idx) {
|
||||||
|
if(isValidId(idx)) {
|
||||||
|
return settingsValues[idx].dataType;
|
||||||
|
}
|
||||||
|
return nullValue.dataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool & getValueAsBool(int32_t idx) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeBool) {
|
||||||
|
return settingsValues[idx].bValue;
|
||||||
|
}
|
||||||
|
return nullValue.bValue;
|
||||||
|
}
|
||||||
|
const int8_t & getValueAsS8(int32_t idx) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeS8) {
|
||||||
|
return settingsValues[idx].cValue;
|
||||||
|
}
|
||||||
|
return nullValue.cValue;
|
||||||
|
}
|
||||||
|
const uint8_t & getValueAsU8(int32_t idx) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeU8) {
|
||||||
|
return settingsValues[idx].ucValue;
|
||||||
|
}
|
||||||
|
return nullValue.ucValue;
|
||||||
|
}
|
||||||
|
const int16_t & getValueAsS16(int32_t idx) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeS16) {
|
||||||
|
return settingsValues[idx].sValue;
|
||||||
|
}
|
||||||
|
return nullValue.sValue;
|
||||||
|
}
|
||||||
|
const uint16_t & getValueAsU16(int32_t idx) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeU16) {
|
||||||
|
return settingsValues[idx].usValue;
|
||||||
|
}
|
||||||
|
return nullValue.usValue;
|
||||||
|
}
|
||||||
|
const int32_t & getValueAsS32(int32_t idx) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeS32) {
|
||||||
|
return settingsValues[idx].iValue;
|
||||||
|
}
|
||||||
|
return nullValue.iValue;
|
||||||
|
}
|
||||||
|
const uint32_t & getValueAsU32(int32_t idx) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeU32) {
|
||||||
|
return settingsValues[idx].uiValue;
|
||||||
|
}
|
||||||
|
return nullValue.uiValue;
|
||||||
|
}
|
||||||
|
const float & getValueAsF32(int32_t idx) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeF32) {
|
||||||
|
return settingsValues[idx].fValue;
|
||||||
|
}
|
||||||
|
return nullValue.fValue;
|
||||||
|
}
|
||||||
|
const std::string & getValueAsString(int32_t idx) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeString && settingsValues[idx].strValue) {
|
||||||
|
return *(settingsValues[idx].strValue);
|
||||||
|
}
|
||||||
|
return *(nullValue.strValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValueAsBool(int32_t idx, const bool & val) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeBool) {
|
||||||
|
if(settingsValues[idx].bValue != val) {
|
||||||
|
settingsValues[idx].bValue = val;
|
||||||
|
bChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValueAsS8(int32_t idx, const int8_t & val) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeS8) {
|
||||||
|
if(settingsValues[idx].cValue != val) {
|
||||||
|
settingsValues[idx].cValue = val;
|
||||||
|
bChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValueAsU8(int32_t idx, const uint8_t & val) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeU8) {
|
||||||
|
if(settingsValues[idx].ucValue != val) {
|
||||||
|
settingsValues[idx].ucValue = val;
|
||||||
|
bChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValueAsS16(int32_t idx, const int16_t & val) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeS16) {
|
||||||
|
if(settingsValues[idx].sValue != val) {
|
||||||
|
settingsValues[idx].sValue = val;
|
||||||
|
bChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValueAsU16(int32_t idx, const uint16_t & val) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeU16) {
|
||||||
|
if(settingsValues[idx].usValue != val) {
|
||||||
|
settingsValues[idx].usValue = val;
|
||||||
|
bChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValueAsS32(int32_t idx, const int32_t & val) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeS32) {
|
||||||
|
if(settingsValues[idx].iValue != val) {
|
||||||
|
settingsValues[idx].iValue = val;
|
||||||
|
bChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValueAsU32(int32_t idx, const uint32_t & val) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeU32) {
|
||||||
|
if(settingsValues[idx].uiValue != val) {
|
||||||
|
settingsValues[idx].uiValue = val;
|
||||||
|
bChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValueAsF32(int32_t idx, const float & val) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeF32) {
|
||||||
|
if(settingsValues[idx].fValue != val) {
|
||||||
|
settingsValues[idx].fValue = val;
|
||||||
|
bChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValueAsString(int32_t idx, const std::string & val) {
|
||||||
|
if(isValidId(idx) && settingsValues[idx].dataType == TypeString && settingsValues[idx].strValue) {
|
||||||
|
if(val.compare(*(settingsValues[idx].strValue)) != 0) { // Only update if the value changed.
|
||||||
|
*(settingsValues[idx].strValue) = val;
|
||||||
|
bChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t getIdByName(std::string configID);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool ValidVersion(const std::string & versionString);
|
||||||
|
|
||||||
|
bool isValidId(int32_t idx) {
|
||||||
|
return (settingsValues.count(idx) > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t dataType;
|
||||||
|
|
||||||
|
union {
|
||||||
|
bool bValue;
|
||||||
|
int8_t cValue;
|
||||||
|
uint8_t ucValue;
|
||||||
|
int16_t sValue;
|
||||||
|
uint16_t usValue;
|
||||||
|
int32_t iValue;
|
||||||
|
uint32_t uiValue;
|
||||||
|
float fValue;
|
||||||
|
std::string *strValue;
|
||||||
|
};
|
||||||
|
} SettingValue;
|
||||||
|
|
||||||
|
SettingValue nullValue;
|
||||||
|
|
||||||
|
std::string configPath;
|
||||||
|
std::string fileName;
|
||||||
|
|
||||||
|
std::map<int32_t, SettingValue> settingsValues;
|
||||||
|
|
||||||
|
std::map<int32_t, std::string> defaultValues;
|
||||||
|
std::map<int32_t, std::string> settingsNames;
|
||||||
|
|
||||||
|
|
||||||
|
bool bChanged;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
30
wups_include/wups/config.h
Normal file
30
wups_include/wups/config.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2018 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 WUPS_CONFIG_HOOKS_DEF_H_
|
||||||
|
#define WUPS_CONFIG_HOOKS_DEF_H_
|
||||||
|
|
||||||
|
#include "hooks.h"
|
||||||
|
#include "config/WUPSConfig.h"
|
||||||
|
|
||||||
|
#define WUPS_GET_CONFIG() \
|
||||||
|
WUPSConfig* get_config();\
|
||||||
|
WUPS_HOOK_EX(WUPS_LOADER_HOOK_GET_CONFIG,get_config); \
|
||||||
|
WUPSConfig* get_config()
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* WUPS_CONFIG_HOOKS_DEF_H_ */
|
87
wups_include/wups/config/WUPSConfig.h
Normal file
87
wups_include/wups/config/WUPSConfig.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2018 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 _WUPS_CONFIG_H_
|
||||||
|
#define _WUPS_CONFIG_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <wups/config/WUPSConfigCategory.h>
|
||||||
|
|
||||||
|
class WUPSConfig {
|
||||||
|
public:
|
||||||
|
WUPSConfig(std::string name) {
|
||||||
|
this->name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
~WUPSConfig() {
|
||||||
|
for (auto & element : categories) {
|
||||||
|
delete element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\return Returns the name of this WUPSConfig
|
||||||
|
**/
|
||||||
|
std::string getName(){
|
||||||
|
return this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Creates a new WUPSCategory add its to this WUPSConfig.
|
||||||
|
The category will be added to the end of the list.
|
||||||
|
This class holds responsibility for deleting the created instance.
|
||||||
|
|
||||||
|
\param categoryName: The name of the category that will be created.
|
||||||
|
|
||||||
|
\return On success, the created and inserted category will be returned.
|
||||||
|
**/
|
||||||
|
WUPSConfigCategory * addCategory(std::string categoryName){
|
||||||
|
WUPSConfigCategory * curCat = new WUPSConfigCategory(categoryName);
|
||||||
|
categories.push_back(curCat);
|
||||||
|
return curCat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Adds a given WUPSConfigCategory to this WUPSConfig.
|
||||||
|
The category will be added to the end of the list.
|
||||||
|
This class holds responsibility for deleting the created instance.
|
||||||
|
|
||||||
|
\param category: The category that will be added to this config.
|
||||||
|
|
||||||
|
\return On success, the inserted category will be returned.
|
||||||
|
On error NULL will be returned. In this case the caller still has the responsibility
|
||||||
|
for deleting the WUPSConfigCategory instance.
|
||||||
|
**/
|
||||||
|
WUPSConfigCategory * addCategory(WUPSConfigCategory * category){
|
||||||
|
categories.push_back(category);
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\return Returns a vector with all categories.
|
||||||
|
**/
|
||||||
|
std::vector<WUPSConfigCategory *> getCategories(){
|
||||||
|
return this->categories;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string name;
|
||||||
|
std::vector<WUPSConfigCategory *> categories;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
72
wups_include/wups/config/WUPSConfigCategory.h
Normal file
72
wups_include/wups/config/WUPSConfigCategory.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2018 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 _WUPS_CONFIG_CATEGORY_H_
|
||||||
|
#define _WUPS_CONFIG_CATEGORY_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <wups/config/WUPSConfigItem.h>
|
||||||
|
|
||||||
|
class WUPSConfigCategory {
|
||||||
|
public:
|
||||||
|
WUPSConfigCategory(std::string name) {
|
||||||
|
this->name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
~WUPSConfigCategory() {
|
||||||
|
for (auto & element : items) {
|
||||||
|
delete element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\return Returns the name of this WUPSConfigCategory
|
||||||
|
**/
|
||||||
|
std::string getName(){
|
||||||
|
return this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\brief Adds a given WUPSConfigItem to this WUPSConfigCategory.
|
||||||
|
The item will be added to the end of the list.
|
||||||
|
This class holds responsibility for deleting the created instance.
|
||||||
|
|
||||||
|
\param item: The item that will be added to this config.
|
||||||
|
|
||||||
|
\return On success, the inserted item will be returned.
|
||||||
|
On error NULL will be returned. In this case the caller still has the responsibility
|
||||||
|
for deleting the WUPSConfigItem instance.
|
||||||
|
**/
|
||||||
|
WUPSConfigItem * addItem(WUPSConfigItem * item){
|
||||||
|
items.push_back(item);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\return Returns a vector with all items.
|
||||||
|
**/
|
||||||
|
std::vector<WUPSConfigItem *> getItems(){
|
||||||
|
return this->items;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string name;
|
||||||
|
std::vector<WUPSConfigItem *> items;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
131
wups_include/wups/config/WUPSConfigItem.h
Normal file
131
wups_include/wups/config/WUPSConfigItem.h
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Copyright (C) 2018 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 _WUPS_CONFIG_ITEM_H_
|
||||||
|
#define _WUPS_CONFIG_ITEM_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define WUPS_CONFIG_BUTTON_NONE 0
|
||||||
|
#define WUPS_CONFIG_BUTTON_LEFT (1<<0)
|
||||||
|
#define WUPS_CONFIG_BUTTON_RIGHT (1<<1)
|
||||||
|
#define WUPS_CONFIG_BUTTON_UP (1<<2)
|
||||||
|
#define WUPS_CONFIG_BUTTON_DOWN (1<<3)
|
||||||
|
#define WUPS_CONFIG_BUTTON_A (1<<4)
|
||||||
|
#define WUPS_CONFIG_BUTTON_B (1<<5)
|
||||||
|
#define WUPS_CONFIG_BUTTON_ZL (1<<6)
|
||||||
|
#define WUPS_CONFIG_BUTTON_ZR (1<<7)
|
||||||
|
typedef int32_t WUPSConfigButtons;
|
||||||
|
|
||||||
|
class WUPSConfigItem {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
Sets the display name of this WUPSConfigItem
|
||||||
|
This is the value which will be shown in the configuration menu.
|
||||||
|
**/
|
||||||
|
virtual void setDisplayName(std::string displayName) {
|
||||||
|
this->displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\return Returns the display name of this WUPSConfigItem
|
||||||
|
**/
|
||||||
|
virtual std::string getDisplayName() {
|
||||||
|
return this->displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Sets the config ID name of this WUPSConfigItem.
|
||||||
|
This config ID is used to persist the configuration values and needs
|
||||||
|
to be unique in the context of this WUPSConfig.
|
||||||
|
Items in different categories are NOT allowed to have the config ID.
|
||||||
|
**/
|
||||||
|
virtual void setConfigID(std::string configID) {
|
||||||
|
this->configID = configID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
\return Returns the configID of this WUPSConfigItem.
|
||||||
|
**/
|
||||||
|
virtual std::string getConfigID() {
|
||||||
|
return this->configID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns a string that displays the current value.
|
||||||
|
This string is shown next to the display name when the cursor is NOT on this item
|
||||||
|
**/
|
||||||
|
virtual std::string getCurrentValueDisplay() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns a string that displays the current value when selected.
|
||||||
|
This string is shown next to the display name when the cursor IS on this item
|
||||||
|
**/
|
||||||
|
virtual std::string getCurrentValueSelectedDisplay() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Is called when the cursor enters or leaves the item.
|
||||||
|
When the cursor enters the item, "isSelected" will be true.
|
||||||
|
When the cursor leaves the item, "isSelected" will be false.
|
||||||
|
**/
|
||||||
|
virtual void onSelected(bool isSelected) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Is called when a button is pressed while the cursor on this item.
|
||||||
|
See the WUPSConfigButtons enum for possible values.
|
||||||
|
**/
|
||||||
|
virtual void onButtonPressed(WUPSConfigButtons buttons) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
When the cursor is on this item, the configuration menu asks this item
|
||||||
|
if it's allowed to leave it.
|
||||||
|
If it returns true, the item can be leaved.
|
||||||
|
It it returns false, leaves is not allowed.
|
||||||
|
**/
|
||||||
|
virtual bool isMovementAllowed() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns a string that represents the value of this item.
|
||||||
|
**/
|
||||||
|
virtual std::string persistValue() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Loads a value for a given string that contains the persisted value.
|
||||||
|
\param persistedValue A valued that the result of the persistValue function
|
||||||
|
**/
|
||||||
|
virtual void loadValue(std::string persistedValue) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Restores the default value
|
||||||
|
**/
|
||||||
|
virtual void restoreDefault() = 0;
|
||||||
|
|
||||||
|
WUPSConfigItem(std::string configID, std::string displayName){
|
||||||
|
this->configID = configID;
|
||||||
|
this->displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~WUPSConfigItem(){
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
std::string displayName;
|
||||||
|
|
||||||
|
std::string configID;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -45,6 +45,7 @@ typedef enum wups_loader_hook_type_t {
|
|||||||
WUPS_LOADER_HOOK_APP_STATUS_CHANGED, /* Called when the app status changes (foreground, background, closing) */
|
WUPS_LOADER_HOOK_APP_STATUS_CHANGED, /* Called when the app status changes (foreground, background, closing) */
|
||||||
|
|
||||||
WUPS_LOADER_HOOK_INIT_KERNEL, /* Only for internal usage */
|
WUPS_LOADER_HOOK_INIT_KERNEL, /* Only for internal usage */
|
||||||
|
WUPS_LOADER_HOOK_GET_CONFIG, /* Called when the config-menu will be loaded */
|
||||||
} wups_loader_hook_type_t;
|
} wups_loader_hook_type_t;
|
||||||
|
|
||||||
typedef struct wups_loader_hook_t {
|
typedef struct wups_loader_hook_t {
|
||||||
@ -85,7 +86,7 @@ typedef struct wups_loader_app_started_args_t {
|
|||||||
void init_kernel(wups_loader_init_kernel_args_t args){ \
|
void init_kernel(wups_loader_init_kernel_args_t args){ \
|
||||||
WUPS_InitKernel(args);\
|
WUPS_InitKernel(args);\
|
||||||
}
|
}
|
||||||
|
|
||||||
#define INITIALIZE_PLUGIN() \
|
#define INITIALIZE_PLUGIN() \
|
||||||
void init_plugin(void);\
|
void init_plugin(void);\
|
||||||
WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_PLUGIN,init_plugin); \
|
WUPS_HOOK_EX(WUPS_LOADER_HOOK_INIT_PLUGIN,init_plugin); \
|
||||||
|
Loading…
Reference in New Issue
Block a user