mirror of
https://github.com/cathery/sys-con.git
synced 2024-11-05 08:26:32 +00:00
Reimplement config loading behavior
This commit is contained in:
parent
1771b42ade
commit
9de5e87c4f
322
source/Sysmodule/source/config_handler.cpp
Normal file
322
source/Sysmodule/source/config_handler.cpp
Normal file
@ -0,0 +1,322 @@
|
||||
#include "switch.h"
|
||||
#include "config_handler.h"
|
||||
#include "Controllers.h"
|
||||
#include "ControllerConfig.h"
|
||||
#include "log.h"
|
||||
#include "ini.h"
|
||||
#include <cstring>
|
||||
#include <stratosphere.hpp>
|
||||
#include "usb_module.h"
|
||||
|
||||
namespace syscon::config
|
||||
{
|
||||
namespace
|
||||
{
|
||||
ControllerConfig tempConfig;
|
||||
GlobalConfig tempGlobalConfig;
|
||||
RGBAColor tempColor;
|
||||
char firmwarePath[100];
|
||||
|
||||
UTimer filecheckTimer;
|
||||
Waiter filecheckTimerWaiter = waiterForUTimer(&filecheckTimer);
|
||||
|
||||
void ConfigChangedCheckThreadFunc(void *arg);
|
||||
|
||||
ams::os::StaticThread<0x2'000> g_config_changed_check_thread(&ConfigChangedCheckThreadFunc, nullptr, 0x3F);
|
||||
|
||||
bool is_config_changed_check_thread_running = false;
|
||||
|
||||
constexpr const char *keyNames[NUM_CONTROLLERBUTTONS]
|
||||
{
|
||||
"FACE_UP",
|
||||
"FACE_RIGHT",
|
||||
"FACE_DOWN",
|
||||
"FACE_LEFT",
|
||||
"LSTICK_CLICK",
|
||||
"RSTICK_CLICK",
|
||||
"LEFT_BUMPER",
|
||||
"RIGHT_BUMPER",
|
||||
"LEFT_TRIGGER",
|
||||
"RIGHT_TRIGGER",
|
||||
"BACK",
|
||||
"START",
|
||||
"DPAD_UP",
|
||||
"DPAD_RIGHT",
|
||||
"DPAD_DOWN",
|
||||
"DPAD_LEFT",
|
||||
"SYNC",
|
||||
"GUIDE",
|
||||
"TOUCHPAD",
|
||||
};
|
||||
|
||||
ControllerButton StringToKey(const char *text)
|
||||
{
|
||||
for (int i = 0; i != NUM_CONTROLLERBUTTONS; ++i)
|
||||
{
|
||||
if (strcmp(keyNames[i], text) == 0)
|
||||
{
|
||||
return static_cast<ControllerButton>(i);
|
||||
}
|
||||
}
|
||||
return NOT_SET;
|
||||
}
|
||||
|
||||
RGBAColor DecodeColorValue(const char *value)
|
||||
{
|
||||
RGBAColor color{255};
|
||||
uint8_t counter = 0;
|
||||
int charIndex = 0;
|
||||
while (value[charIndex] != '\0')
|
||||
{
|
||||
if (charIndex == 0)
|
||||
color.values[counter++] = atoi(value + charIndex++);
|
||||
if (value[charIndex++] == ',')
|
||||
{
|
||||
color.values[counter++] = atoi(value + charIndex);
|
||||
if (counter == 4)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
int ParseConfigLine(void *dummy, const char *section, const char *name, const char *value)
|
||||
{
|
||||
if (strcmp(section, "global") == 0)
|
||||
{
|
||||
if (strcmp(name, "use_dualshock_2nd_generation") == 0)
|
||||
{
|
||||
tempGlobalConfig.dualshock4_productID = (strcmp(value, "true") ? PRODUCT_DUALSHOCK4_1X : PRODUCT_DUALSHOCK4_2X);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strncmp(name, "key_", 4) == 0)
|
||||
{
|
||||
ControllerButton button = StringToKey(name + 4);
|
||||
ControllerButton buttonValue = StringToKey(value);
|
||||
tempConfig.buttons[button] = buttonValue;
|
||||
tempConfig.buttons[buttonValue] = button;
|
||||
return 1;
|
||||
}
|
||||
else if (strcmp(name, "left_stick_deadzone") == 0)
|
||||
{
|
||||
tempConfig.leftStickDeadzonePercent = atoi(value);
|
||||
return 1;
|
||||
}
|
||||
else if (strcmp(name, "right_stick_deadzone") == 0)
|
||||
{
|
||||
tempConfig.rightStickDeadzonePercent = atoi(value);
|
||||
return 1;
|
||||
}
|
||||
else if (strcmp(name, "left_stick_rotation") == 0)
|
||||
{
|
||||
tempConfig.leftStickRotationDegrees = atoi(value);
|
||||
return 1;
|
||||
}
|
||||
else if (strcmp(name, "right_stick_rotation") == 0)
|
||||
{
|
||||
tempConfig.rightStickRotationDegrees = atoi(value);
|
||||
return 1;
|
||||
}
|
||||
else if (strcmp(name, "trigger_deadzone") == 0)
|
||||
{
|
||||
tempConfig.triggerDeadzonePercent = atoi(value);
|
||||
return 1;
|
||||
}
|
||||
else if (strcmp(name, "swap_dpad_and_lstick") == 0)
|
||||
{
|
||||
tempConfig.swapDPADandLSTICK = (strcmp(value, "true") ? false : true);
|
||||
return 1;
|
||||
}
|
||||
else if (strcmp(name, "firmware_path") == 0)
|
||||
{
|
||||
strcpy(firmwarePath, value);
|
||||
return 1;
|
||||
}
|
||||
else if (strncmp(name, "color_", 6) == 0)
|
||||
{
|
||||
if (strcmp(name + 6, "body") == 0)
|
||||
{
|
||||
tempConfig.bodyColor = DecodeColorValue(value);
|
||||
return 1;
|
||||
}
|
||||
else if (strcmp(name + 6, "buttons") == 0)
|
||||
{
|
||||
tempConfig.buttonsColor = DecodeColorValue(value);
|
||||
return 1;
|
||||
}
|
||||
else if (strcmp(name + 6, "leftGrip") == 0)
|
||||
{
|
||||
tempConfig.leftGripColor = DecodeColorValue(value);
|
||||
return 1;
|
||||
}
|
||||
else if (strcmp(name + 6, "rightGrip") == 0)
|
||||
{
|
||||
tempConfig.rightGripColor = DecodeColorValue(value);
|
||||
return 1;
|
||||
}
|
||||
else if (strcmp(name + 6, "led") == 0)
|
||||
{
|
||||
tempColor = DecodeColorValue(value);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Result ReadFromConfig(const char *path)
|
||||
{
|
||||
tempConfig = ControllerConfig{};
|
||||
for (int i = 0; i != NUM_CONTROLLERBUTTONS; ++i)
|
||||
{
|
||||
tempConfig.buttons[i] = NOT_SET;
|
||||
}
|
||||
return ini_parse(path, ParseConfigLine, NULL);
|
||||
}
|
||||
|
||||
|
||||
void ConfigChangedCheckThreadFunc(void *arg)
|
||||
{
|
||||
while (is_config_changed_check_thread_running)
|
||||
{
|
||||
if (R_SUCCEEDED(waitSingle(filecheckTimerWaiter, 0)))
|
||||
{
|
||||
if (config::CheckForFileChanges())
|
||||
{
|
||||
WriteToLog("File check succeeded! Loading configs...");
|
||||
config::LoadAllConfigs();
|
||||
usb::ReloadDualshock4Event();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LoadGlobalConfig(const GlobalConfig &config)
|
||||
{
|
||||
config::globalConfig = config;
|
||||
}
|
||||
|
||||
void LoadAllConfigs()
|
||||
{
|
||||
if (R_SUCCEEDED(ReadFromConfig(GLOBALCONFIG)))
|
||||
{
|
||||
LoadGlobalConfig(tempGlobalConfig);
|
||||
}
|
||||
else
|
||||
WriteToLog("Failed to read from global config!");
|
||||
|
||||
if (R_SUCCEEDED(ReadFromConfig(XBOXCONFIG)))
|
||||
{
|
||||
XboxController::LoadConfig(&tempConfig);
|
||||
}
|
||||
else
|
||||
WriteToLog("Failed to read from xbox orig config!");
|
||||
|
||||
if (R_SUCCEEDED(ReadFromConfig(XBOXONECONFIG)))
|
||||
XboxOneController::LoadConfig(&tempConfig);
|
||||
else
|
||||
WriteToLog("Failed to read from xbox one config!");
|
||||
|
||||
if (R_SUCCEEDED(ReadFromConfig(XBOX360CONFIG)))
|
||||
{
|
||||
Xbox360Controller::LoadConfig(&tempConfig);
|
||||
Xbox360WirelessController::LoadConfig(&tempConfig);
|
||||
}
|
||||
else
|
||||
WriteToLog("Failed to read from xbox 360 config!");
|
||||
|
||||
if (R_SUCCEEDED(ReadFromConfig(DUALSHOCK3CONFIG)))
|
||||
Dualshock3Controller::LoadConfig(&tempConfig);
|
||||
else
|
||||
WriteToLog("Failed to read from dualshock 3 config!");
|
||||
|
||||
if (R_SUCCEEDED(ReadFromConfig(DUALSHOCK4CONFIG)))
|
||||
Dualshock4Controller::LoadConfig(&tempConfig, tempColor);
|
||||
else
|
||||
WriteToLog("Failed to read from dualshock 4 config!");
|
||||
}
|
||||
bool CheckForFileChanges()
|
||||
{
|
||||
static u64 globalConfigLastModified;
|
||||
static u64 xboxConfigLastModified;
|
||||
static u64 xbox360ConfigLastModified;
|
||||
static u64 xboxOneConfigLastModified;
|
||||
static u64 dualshock3ConfigLastModified;
|
||||
static u64 dualshock4ConfigLastModified;
|
||||
|
||||
// Maybe this should be called only once when initializing?
|
||||
// I left it here in case this would cause issues when ejecting the SD card
|
||||
FsFileSystem *fs = fsdevGetDeviceFileSystem("sdmc");
|
||||
|
||||
if (fs == nullptr)
|
||||
return false;
|
||||
|
||||
bool filesChanged = false;
|
||||
FsTimeStampRaw timestamp;
|
||||
|
||||
if (R_SUCCEEDED(fsFsGetFileTimeStampRaw(fs, GLOBALCONFIG, ×tamp)))
|
||||
if (globalConfigLastModified != timestamp.modified)
|
||||
{
|
||||
globalConfigLastModified = timestamp.modified;
|
||||
filesChanged = true;
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(fsFsGetFileTimeStampRaw(fs, XBOXCONFIG, ×tamp)))
|
||||
if (xboxConfigLastModified != timestamp.modified)
|
||||
{
|
||||
xboxConfigLastModified = timestamp.modified;
|
||||
filesChanged = true;
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(fsFsGetFileTimeStampRaw(fs, XBOX360CONFIG, ×tamp)))
|
||||
if (xbox360ConfigLastModified != timestamp.modified)
|
||||
{
|
||||
xbox360ConfigLastModified = timestamp.modified;
|
||||
filesChanged = true;
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(fsFsGetFileTimeStampRaw(fs, XBOXONECONFIG, ×tamp)))
|
||||
if (xboxOneConfigLastModified != timestamp.modified)
|
||||
{
|
||||
xboxOneConfigLastModified = timestamp.modified;
|
||||
filesChanged = true;
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(fsFsGetFileTimeStampRaw(fs, DUALSHOCK3CONFIG, ×tamp)))
|
||||
if (dualshock3ConfigLastModified != timestamp.modified)
|
||||
{
|
||||
dualshock3ConfigLastModified = timestamp.modified;
|
||||
filesChanged = true;
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(fsFsGetFileTimeStampRaw(fs, DUALSHOCK4CONFIG, ×tamp)))
|
||||
if (dualshock4ConfigLastModified != timestamp.modified)
|
||||
{
|
||||
dualshock4ConfigLastModified = timestamp.modified;
|
||||
filesChanged = true;
|
||||
}
|
||||
return filesChanged;
|
||||
}
|
||||
|
||||
Result Initialize()
|
||||
{
|
||||
config::LoadAllConfigs();
|
||||
utimerCreate(&filecheckTimer, 1e+9L, TimerType_Repeating);
|
||||
utimerStart(&filecheckTimer);
|
||||
is_config_changed_check_thread_running = true;
|
||||
return g_config_changed_check_thread.Start().GetValue();
|
||||
}
|
||||
|
||||
void Exit()
|
||||
{
|
||||
is_config_changed_check_thread_running = true;
|
||||
utimerStop(&filecheckTimer);
|
||||
g_config_changed_check_thread.CancelSynchronization();
|
||||
g_config_changed_check_thread.Join();
|
||||
}
|
||||
}
|
31
source/Sysmodule/source/config_handler.h
Normal file
31
source/Sysmodule/source/config_handler.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include "ControllerTypes.h"
|
||||
|
||||
#define CONFIG_PATH "/config/sys-con/"
|
||||
|
||||
#define GLOBALCONFIG CONFIG_PATH "config_global.ini"
|
||||
#define XBOXCONFIG CONFIG_PATH "config_xboxorig.ini"
|
||||
#define XBOX360CONFIG CONFIG_PATH "config_xbox360.ini"
|
||||
#define XBOXONECONFIG CONFIG_PATH "config_xboxone.ini"
|
||||
#define DUALSHOCK3CONFIG CONFIG_PATH "config_dualshock3.ini"
|
||||
#define DUALSHOCK4CONFIG CONFIG_PATH "config_dualshock4.ini"
|
||||
|
||||
namespace syscon::config
|
||||
{
|
||||
struct GlobalConfig
|
||||
{
|
||||
uint16_t dualshock4_productID;
|
||||
};
|
||||
|
||||
inline GlobalConfig globalConfig
|
||||
{
|
||||
.dualshock4_productID = PRODUCT_DUALSHOCK4_1X,
|
||||
};
|
||||
|
||||
void LoadGlobalConfig(const GlobalConfig &config);
|
||||
void LoadAllConfigs();
|
||||
bool CheckForFileChanges();
|
||||
|
||||
Result Initialize();
|
||||
void Exit();
|
||||
};
|
@ -1,11 +1,10 @@
|
||||
#include "switch.h"
|
||||
#include "log.h"
|
||||
#include "mainLoop.h"
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
#include "usb_module.h"
|
||||
#include "controller_handler.h"
|
||||
#include "configFile.h"
|
||||
#include "config_handler.h"
|
||||
|
||||
#define APP_VERSION "0.6.0"
|
||||
|
||||
@ -78,11 +77,10 @@ using namespace syscon;
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
WriteToLog("\n\nNew sysmodule session started on version " APP_VERSION);
|
||||
config::Initialize();
|
||||
handler::Initialize();
|
||||
usb::Initialize();
|
||||
|
||||
LoadAllConfigs();
|
||||
|
||||
while (true)
|
||||
{
|
||||
svcSleepThread(1e+8L);
|
||||
@ -90,4 +88,5 @@ int main(int argc, char *argv[])
|
||||
|
||||
usb::Exit();
|
||||
handler::Exit();
|
||||
config::Exit();
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "switch.h"
|
||||
#include "usb_module.h"
|
||||
#include "controller_handler.h"
|
||||
#include "config_handler.h"
|
||||
|
||||
|
||||
#include "SwitchUSBDevice.h"
|
||||
@ -22,7 +23,7 @@ namespace syscon::usb
|
||||
void UsbInterfaceChangeThreadFunc(void *arg);
|
||||
|
||||
ams::os::StaticThread<0x2'000> g_usb_event_thread(&UsbEventThreadFunc, nullptr, 0x20);
|
||||
ams::os::StaticThread<0x2'000> g_usb_interface_change_thread(&UsbInterfaceChangeThreadFunc, nullptr, 0x20);
|
||||
ams::os::StaticThread<0x2'000> g_usb_interface_change_thread(&UsbInterfaceChangeThreadFunc, nullptr, 0x21);
|
||||
|
||||
bool is_usb_event_thread_running = false;
|
||||
bool is_usb_interface_change_thread_running = false;
|
||||
@ -157,10 +158,10 @@ namespace syscon::usb
|
||||
|
||||
Result CreateDualshock4AvailableEvent()
|
||||
{
|
||||
constexpr UsbHsInterfaceFilter filter {
|
||||
const UsbHsInterfaceFilter filter{
|
||||
.Flags = UsbHsInterfaceFilterFlags_idVendor | UsbHsInterfaceFilterFlags_idProduct,
|
||||
.idVendor = VENDOR_SONY,
|
||||
.idProduct = PRODUCT_DUALSHOCK4_2X,
|
||||
.idProduct = config::globalConfig.dualshock4_productID,
|
||||
};
|
||||
return usbHsCreateInterfaceAvailableEvent(&g_usbDualshock4Event, true, Dualshock4EventIndex, &filter);
|
||||
}
|
||||
@ -210,4 +211,10 @@ namespace syscon::usb
|
||||
|
||||
handler::Reset();
|
||||
}
|
||||
|
||||
Result ReloadDualshock4Event()
|
||||
{
|
||||
usbHsDestroyInterfaceAvailableEvent(&g_usbDualshock4Event, Dualshock4EventIndex);
|
||||
return CreateDualshock4AvailableEvent();
|
||||
}
|
||||
}
|
@ -8,4 +8,6 @@ namespace syscon::usb {
|
||||
|
||||
Result Enable();
|
||||
void Disable();
|
||||
|
||||
Result ReloadDualshock4Event();
|
||||
}
|
Loading…
Reference in New Issue
Block a user