mirror of
https://github.com/cathery/sys-con.git
synced 2024-09-28 22:40:47 +00:00
Remove old code
This commit is contained in:
parent
3dfa505ca8
commit
c91bcd9e26
@ -1,56 +0,0 @@
|
|||||||
#include "SwitchThread.h"
|
|
||||||
#include "switch.h"
|
|
||||||
|
|
||||||
void SwitchThread::ThreadLoop(void *argument)
|
|
||||||
{
|
|
||||||
svcSleepThread(1e+7L);
|
|
||||||
while (static_cast<SwitchThread *>(argument)->m_isRunning)
|
|
||||||
{
|
|
||||||
static_cast<SwitchThread *>(argument)->m_function(static_cast<SwitchThread *>(argument)->m_argument);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SwitchThread::SwitchThread(ThreadFunc function, void *argument, size_t stackSize, int prio)
|
|
||||||
{
|
|
||||||
if (R_SUCCEEDED(Initialize(stackSize, prio)))
|
|
||||||
{
|
|
||||||
Start(function, argument);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Result SwitchThread::Initialize(size_t stackSize, int prio)
|
|
||||||
{
|
|
||||||
Result rc = threadCreate(&m_thread, &SwitchThread::ThreadLoop, this, NULL, stackSize, prio, -2);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
SwitchThread::~SwitchThread()
|
|
||||||
{
|
|
||||||
Exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result SwitchThread::Start(ThreadFunc function, void *argument)
|
|
||||||
{
|
|
||||||
if (!m_isRunning)
|
|
||||||
{
|
|
||||||
m_isRunning = true;
|
|
||||||
m_function = function;
|
|
||||||
m_argument = argument;
|
|
||||||
return threadStart(&m_thread);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result SwitchThread::Exit()
|
|
||||||
{
|
|
||||||
if (m_isRunning)
|
|
||||||
{
|
|
||||||
m_isRunning = false;
|
|
||||||
svcCancelSynchronization(m_thread.handle);
|
|
||||||
threadWaitForExit(&m_thread);
|
|
||||||
return threadClose(&m_thread);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "switch.h"
|
|
||||||
|
|
||||||
//Wrapper for switch thread implementation. Passed function will be called indefinitely until the thread closes.
|
|
||||||
class SwitchThread
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Thread m_thread;
|
|
||||||
bool m_isRunning = false;
|
|
||||||
ThreadFunc m_function;
|
|
||||||
void *m_argument;
|
|
||||||
|
|
||||||
static void ThreadLoop(void *argument);
|
|
||||||
|
|
||||||
public:
|
|
||||||
SwitchThread(){};
|
|
||||||
|
|
||||||
//Constructs the class by creating and starting the thread.
|
|
||||||
//function - the function you want to be called
|
|
||||||
//argument - the argument passed to that function
|
|
||||||
//stackSize - the stack size of the created thread
|
|
||||||
//prio - thread priority, 0x00 - highest, 0x3F - lowest. Switch uses 0x2C
|
|
||||||
SwitchThread(ThreadFunc function, void *argument, size_t stackSize, int prio);
|
|
||||||
|
|
||||||
//SwitchThread isn't copy-movable, because the memory address of its variables is important
|
|
||||||
SwitchThread &operator=(const SwitchThread &other) = delete;
|
|
||||||
SwitchThread &operator=(const SwitchThread &&other) = delete;
|
|
||||||
//Closes the thread upon exiting
|
|
||||||
~SwitchThread();
|
|
||||||
|
|
||||||
//Creates the thread.
|
|
||||||
//function - the function you want to be called
|
|
||||||
//argument - the argument passed to that function
|
|
||||||
//stackSize - the stack size of the created thread
|
|
||||||
//prio - thread priority, 0x00 - highest, 0x3F - lowest. Switch uses 0x2C
|
|
||||||
Result Initialize(size_t stackSize, int prio);
|
|
||||||
|
|
||||||
//Starts the thread. The given function will be called with the given argument in a loop until the thread is closed.
|
|
||||||
Result Start(ThreadFunc function, void *argument);
|
|
||||||
|
|
||||||
//Closes the thread.
|
|
||||||
//This will block the caller indefinitely until the thread is returned!
|
|
||||||
Result Exit();
|
|
||||||
|
|
||||||
bool inline IsRunning() { return m_isRunning; }
|
|
||||||
};
|
|
@ -1,270 +0,0 @@
|
|||||||
#include "mainLoop.h"
|
|
||||||
#include "configFile.h"
|
|
||||||
#include "Controllers.h"
|
|
||||||
#include "ControllerConfig.h"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <array>
|
|
||||||
#include "ini.h"
|
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
#define GLOBALCONFIG "config_global.ini"
|
|
||||||
|
|
||||||
#define XBOXCONFIG "config_xboxorig.ini"
|
|
||||||
#define XBOX360CONFIG "config_xbox360.ini"
|
|
||||||
#define XBOXONECONFIG "config_xboxone.ini"
|
|
||||||
#define DUALSHOCK3CONFIG "config_dualshock3.ini"
|
|
||||||
#define DUALSHOCK4CONFIG "config_dualshock4.ini"
|
|
||||||
|
|
||||||
constexpr std::array<const char *, NUM_CONTROLLERBUTTONS> keyNames{
|
|
||||||
"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",
|
|
||||||
};
|
|
||||||
|
|
||||||
static 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ControllerConfig temp_config;
|
|
||||||
static GlobalConfig global_config;
|
|
||||||
static RGBAColor temp_color;
|
|
||||||
static char firmwarePath[100];
|
|
||||||
|
|
||||||
static 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)
|
|
||||||
{
|
|
||||||
global_config.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);
|
|
||||||
temp_config.buttons[button] = buttonValue;
|
|
||||||
temp_config.buttons[buttonValue] = button;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (strcmp(name, "left_stick_deadzone") == 0)
|
|
||||||
{
|
|
||||||
temp_config.leftStickDeadzonePercent = atoi(value);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (strcmp(name, "right_stick_deadzone") == 0)
|
|
||||||
{
|
|
||||||
temp_config.rightStickDeadzonePercent = atoi(value);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (strcmp(name, "left_stick_rotation") == 0)
|
|
||||||
{
|
|
||||||
temp_config.leftStickRotationDegrees = atoi(value);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (strcmp(name, "right_stick_rotation") == 0)
|
|
||||||
{
|
|
||||||
temp_config.rightStickRotationDegrees = atoi(value);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (strcmp(name, "trigger_deadzone") == 0)
|
|
||||||
{
|
|
||||||
temp_config.triggerDeadzonePercent = atoi(value);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (strcmp(name, "swap_dpad_and_lstick") == 0)
|
|
||||||
{
|
|
||||||
temp_config.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)
|
|
||||||
{
|
|
||||||
temp_config.bodyColor = _DecodeColorValue(value);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (strcmp(name + 6, "buttons") == 0)
|
|
||||||
{
|
|
||||||
temp_config.buttonsColor = _DecodeColorValue(value);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (strcmp(name + 6, "leftGrip") == 0)
|
|
||||||
{
|
|
||||||
temp_config.leftGripColor = _DecodeColorValue(value);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (strcmp(name + 6, "rightGrip") == 0)
|
|
||||||
{
|
|
||||||
temp_config.rightGripColor = _DecodeColorValue(value);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (strcmp(name + 6, "led") == 0)
|
|
||||||
{
|
|
||||||
temp_color = _DecodeColorValue(value);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Result _ReadFromConfig(const char *path)
|
|
||||||
{
|
|
||||||
temp_config = ControllerConfig{};
|
|
||||||
for (int i = 0; i != NUM_CONTROLLERBUTTONS; ++i)
|
|
||||||
{
|
|
||||||
temp_config.buttons[i] = NOT_SET;
|
|
||||||
}
|
|
||||||
return ini_parse(path, _ParseConfigLine, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadAllConfigs()
|
|
||||||
{
|
|
||||||
if (R_SUCCEEDED(_ReadFromConfig(CONFIG_PATH GLOBALCONFIG)))
|
|
||||||
{
|
|
||||||
LoadGlobalConfig(&global_config);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
WriteToLog("Failed to read from global config!");
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(_ReadFromConfig(CONFIG_PATH XBOXCONFIG)))
|
|
||||||
{
|
|
||||||
XboxController::LoadConfig(&temp_config);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
WriteToLog("Failed to read from xbox orig config!");
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(_ReadFromConfig(CONFIG_PATH XBOXONECONFIG)))
|
|
||||||
XboxOneController::LoadConfig(&temp_config);
|
|
||||||
else
|
|
||||||
WriteToLog("Failed to read from xbox one config!");
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(_ReadFromConfig(CONFIG_PATH XBOX360CONFIG)))
|
|
||||||
{
|
|
||||||
Xbox360Controller::LoadConfig(&temp_config);
|
|
||||||
Xbox360WirelessController::LoadConfig(&temp_config);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
WriteToLog("Failed to read from xbox 360 config!");
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(_ReadFromConfig(CONFIG_PATH DUALSHOCK3CONFIG)))
|
|
||||||
Dualshock3Controller::LoadConfig(&temp_config);
|
|
||||||
else
|
|
||||||
WriteToLog("Failed to read from dualshock 3 config!");
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(_ReadFromConfig(CONFIG_PATH DUALSHOCK4CONFIG)))
|
|
||||||
Dualshock4Controller::LoadConfig(&temp_config, temp_color);
|
|
||||||
else
|
|
||||||
WriteToLog("Failed to read from dualshock 4 config!");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CheckForFileChanges()
|
|
||||||
{
|
|
||||||
bool filesChanged = false;
|
|
||||||
|
|
||||||
static time_t globalConfigLastModified;
|
|
||||||
static time_t xboxConfigLastModified;
|
|
||||||
static time_t xbox360ConfigLastModified;
|
|
||||||
static time_t xboxOneConfigLastModified;
|
|
||||||
static time_t dualshock3ConfigLastModified;
|
|
||||||
static time_t dualshock4ConfigLastModified;
|
|
||||||
struct stat result;
|
|
||||||
|
|
||||||
if (stat(CONFIG_PATH GLOBALCONFIG, &result) == 0)
|
|
||||||
if (globalConfigLastModified != result.st_mtime)
|
|
||||||
{
|
|
||||||
globalConfigLastModified = result.st_mtime;
|
|
||||||
filesChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stat(CONFIG_PATH XBOXCONFIG, &result) == 0)
|
|
||||||
if (xboxConfigLastModified != result.st_mtime)
|
|
||||||
{
|
|
||||||
xboxConfigLastModified = result.st_mtime;
|
|
||||||
filesChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stat(CONFIG_PATH XBOX360CONFIG, &result) == 0)
|
|
||||||
if (xbox360ConfigLastModified != result.st_mtime)
|
|
||||||
{
|
|
||||||
xbox360ConfigLastModified = result.st_mtime;
|
|
||||||
filesChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stat(CONFIG_PATH XBOXONECONFIG, &result) == 0)
|
|
||||||
if (xboxOneConfigLastModified != result.st_mtime)
|
|
||||||
{
|
|
||||||
xboxOneConfigLastModified = result.st_mtime;
|
|
||||||
filesChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stat(CONFIG_PATH DUALSHOCK3CONFIG, &result) == 0)
|
|
||||||
if (dualshock3ConfigLastModified != result.st_mtime)
|
|
||||||
{
|
|
||||||
dualshock3ConfigLastModified = result.st_mtime;
|
|
||||||
filesChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stat(CONFIG_PATH DUALSHOCK4CONFIG, &result) == 0)
|
|
||||||
if (dualshock4ConfigLastModified != result.st_mtime)
|
|
||||||
{
|
|
||||||
dualshock4ConfigLastModified = result.st_mtime;
|
|
||||||
filesChanged = true;
|
|
||||||
}
|
|
||||||
return filesChanged;
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#define CONFIG_PATH "/config/sys-con/"
|
|
||||||
|
|
||||||
void LoadAllConfigs();
|
|
||||||
|
|
||||||
bool CheckForFileChanges();
|
|
@ -1,6 +1,6 @@
|
|||||||
#include "switch.h"
|
#include "switch.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "configFile.h"
|
#include "config_handler.h"
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
static ams::os::Mutex printMutex;
|
static ams::os::Mutex printMutex;
|
||||||
|
@ -1,387 +0,0 @@
|
|||||||
#include <switch.h>
|
|
||||||
#include "mainLoop.h"
|
|
||||||
#include <variant>
|
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
#include "SwitchUSBDevice.h"
|
|
||||||
#include "ControllerHelpers.h"
|
|
||||||
#include "SwitchHDLHandler.h"
|
|
||||||
#include "SwitchAbstractedPadHandler.h"
|
|
||||||
#include "configFile.h"
|
|
||||||
#include "SwitchThread.h"
|
|
||||||
|
|
||||||
#define APP_VERSION "0.5.3"
|
|
||||||
|
|
||||||
#define DS3EVENT_INDEX 0
|
|
||||||
#define DS4EVENT_INDEX 1
|
|
||||||
#define ALLEVENT_INDEX 2
|
|
||||||
|
|
||||||
#ifdef __APPLET__
|
|
||||||
#define APPLET_STACKSIZE 0x1'000
|
|
||||||
#else
|
|
||||||
#define APPLET_STACKSIZE 0x0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const bool useAbstractedPad = hosversionBetween(5, 7);
|
|
||||||
std::vector<std::unique_ptr<SwitchVirtualGamepadHandler>> controllerInterfaces;
|
|
||||||
std::unique_ptr<IController> controllerPtr;
|
|
||||||
UsbHsInterface interfaces[16];
|
|
||||||
s32 total_entries;
|
|
||||||
UsbHsInterfaceFilter g_filter;
|
|
||||||
|
|
||||||
static GlobalConfig _globalConfig{};
|
|
||||||
|
|
||||||
void LoadGlobalConfig(const GlobalConfig *config)
|
|
||||||
{
|
|
||||||
_globalConfig = *config;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result CallInitHandler(std::unique_ptr<IController> &controllerPtr)
|
|
||||||
{
|
|
||||||
if (controllerPtr)
|
|
||||||
{
|
|
||||||
std::unique_ptr<SwitchVirtualGamepadHandler> switchHandler;
|
|
||||||
if (useAbstractedPad)
|
|
||||||
switchHandler = std::make_unique<SwitchAbstractedPadHandler>(std::move(controllerPtr));
|
|
||||||
else
|
|
||||||
switchHandler = std::make_unique<SwitchHDLHandler>(std::move(controllerPtr));
|
|
||||||
|
|
||||||
Result rc = switchHandler->Initialize();
|
|
||||||
if (R_SUCCEEDED(rc))
|
|
||||||
{
|
|
||||||
controllerInterfaces.push_back(std::move(switchHandler));
|
|
||||||
WriteToLog("Interface created successfully");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteToLog("Error creating interface with error 0x%x", rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result CreateDualshck3AvailableEvent(Event &out)
|
|
||||||
{
|
|
||||||
g_filter = {};
|
|
||||||
g_filter.Flags = UsbHsInterfaceFilterFlags_idVendor | UsbHsInterfaceFilterFlags_idProduct;
|
|
||||||
g_filter.idVendor = VENDOR_SONY;
|
|
||||||
g_filter.idProduct = PRODUCT_DUALSHOCK3;
|
|
||||||
Result rc = usbHsCreateInterfaceAvailableEvent(&out, true, DS3EVENT_INDEX, &g_filter);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result CreateDualshock4AvailableEvent(Event &out)
|
|
||||||
{
|
|
||||||
g_filter = {};
|
|
||||||
g_filter.Flags = UsbHsInterfaceFilterFlags_idVendor | UsbHsInterfaceFilterFlags_idProduct;
|
|
||||||
g_filter.idVendor = VENDOR_SONY;
|
|
||||||
g_filter.idProduct = _globalConfig.dualshock4_productID;
|
|
||||||
Result rc = usbHsCreateInterfaceAvailableEvent(&out, true, DS4EVENT_INDEX, &g_filter);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result CreateAllAvailableEvent(Event &out)
|
|
||||||
{
|
|
||||||
g_filter = {};
|
|
||||||
g_filter.Flags = UsbHsInterfaceFilterFlags_bcdDevice_Min;
|
|
||||||
g_filter.bcdDevice_Min = 0;
|
|
||||||
Result rc = usbHsCreateInterfaceAvailableEvent(&out, true, ALLEVENT_INDEX, &g_filter);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result QueryInterfaces(UsbHsInterface *interfaces, size_t interfaces_size, s32 *total_entries, u8 infclass, u8 infsubclass, u8 infprotocol)
|
|
||||||
{
|
|
||||||
g_filter = {};
|
|
||||||
g_filter.Flags = UsbHsInterfaceFilterFlags_bInterfaceClass | UsbHsInterfaceFilterFlags_bInterfaceSubClass | UsbHsInterfaceFilterFlags_bInterfaceProtocol;
|
|
||||||
g_filter.bInterfaceClass = infclass;
|
|
||||||
g_filter.bInterfaceSubClass = infsubclass;
|
|
||||||
g_filter.bInterfaceProtocol = infprotocol;
|
|
||||||
Result rc = usbHsQueryAvailableInterfaces(&g_filter, interfaces, interfaces_size, total_entries);
|
|
||||||
if (R_SUCCEEDED(rc) && *total_entries != 0)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result QueryVendorProduct(UsbHsInterface *interfaces, size_t interfaces_size, s32 *total_entries, uint16_t vendor_id, uint16_t product_id)
|
|
||||||
{
|
|
||||||
g_filter = {};
|
|
||||||
g_filter.Flags = UsbHsInterfaceFilterFlags_idVendor | UsbHsInterfaceFilterFlags_idProduct;
|
|
||||||
g_filter.idVendor = vendor_id;
|
|
||||||
g_filter.idProduct = product_id;
|
|
||||||
Result rc = usbHsQueryAvailableInterfaces(&g_filter, interfaces, interfaces_size, total_entries);
|
|
||||||
if (R_SUCCEEDED(rc) && *total_entries != 0)
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Event catchAllEvent;
|
|
||||||
Event ds3Event;
|
|
||||||
Event ds4Event;
|
|
||||||
|
|
||||||
Result inline OpenEvents()
|
|
||||||
{
|
|
||||||
Result rc = CreateAllAvailableEvent(catchAllEvent);
|
|
||||||
if (R_FAILED(rc))
|
|
||||||
return 3;
|
|
||||||
rc = CreateDualshck3AvailableEvent(ds3Event);
|
|
||||||
if (R_FAILED(rc))
|
|
||||||
return 1;
|
|
||||||
rc = CreateDualshock4AvailableEvent(ds4Event);
|
|
||||||
if (R_FAILED(rc))
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void inline CloseEvents()
|
|
||||||
{
|
|
||||||
usbHsDestroyInterfaceAvailableEvent(&ds3Event, DS3EVENT_INDEX);
|
|
||||||
usbHsDestroyInterfaceAvailableEvent(&ds4Event, DS4EVENT_INDEX);
|
|
||||||
usbHsDestroyInterfaceAvailableEvent(&catchAllEvent, ALLEVENT_INDEX);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PSCLoopBuffer
|
|
||||||
{
|
|
||||||
PscPmModule &pscModule;
|
|
||||||
bool &shouldSleep;
|
|
||||||
};
|
|
||||||
|
|
||||||
void pscLoop(void *buffer)
|
|
||||||
{
|
|
||||||
PscPmState pscState;
|
|
||||||
u32 out_flags;
|
|
||||||
|
|
||||||
Result rc = waitSingle(waiterForEvent(&static_cast<PSCLoopBuffer *>(buffer)->pscModule.event), U64_MAX);
|
|
||||||
if (R_SUCCEEDED(rc))
|
|
||||||
{
|
|
||||||
rc = pscPmModuleGetRequest(&static_cast<PSCLoopBuffer *>(buffer)->pscModule, &pscState, &out_flags);
|
|
||||||
if (R_SUCCEEDED(rc))
|
|
||||||
{
|
|
||||||
switch (pscState)
|
|
||||||
{
|
|
||||||
case PscPmState_ReadyAwaken:
|
|
||||||
OpenEvents();
|
|
||||||
static_cast<PSCLoopBuffer *>(buffer)->shouldSleep = false;
|
|
||||||
break;
|
|
||||||
case PscPmState_ReadySleep:
|
|
||||||
case PscPmState_ReadyShutdown:
|
|
||||||
CloseEvents();
|
|
||||||
static_cast<PSCLoopBuffer *>(buffer)->shouldSleep = true;
|
|
||||||
//controllerInterfaces.clear();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pscPmModuleAcknowledge(&static_cast<PSCLoopBuffer *>(buffer)->pscModule, pscState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckForInterfaces()
|
|
||||||
{
|
|
||||||
if (controllerInterfaces.size() >= 10)
|
|
||||||
WriteToLog("But the controllers table reached its max size!");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
if (R_SUCCEEDED(QueryInterfaces(interfaces, sizeof(interfaces), &total_entries, USB_CLASS_VENDOR_SPEC, 93, 1)))
|
|
||||||
{
|
|
||||||
controllerPtr = std::make_unique<Xbox360Controller>(std::make_unique<SwitchUSBDevice>(interfaces, total_entries));
|
|
||||||
WriteToLog("Registered Xbox 360 controller");
|
|
||||||
}
|
|
||||||
else if (R_SUCCEEDED(QueryInterfaces(interfaces, sizeof(interfaces), &total_entries, USB_CLASS_VENDOR_SPEC, 93, 129)))
|
|
||||||
{
|
|
||||||
for (int i = 0; i != total_entries; ++i)
|
|
||||||
{
|
|
||||||
controllerPtr = std::make_unique<Xbox360WirelessController>(std::make_unique<SwitchUSBDevice>(interfaces + i, 1));
|
|
||||||
CallInitHandler(controllerPtr);
|
|
||||||
}
|
|
||||||
WriteToLog("Registered Xbox 360 Wireless adapter");
|
|
||||||
}
|
|
||||||
else if (R_SUCCEEDED(QueryInterfaces(interfaces, sizeof(interfaces), &total_entries, 0x58, 0x42, 0x00)))
|
|
||||||
{
|
|
||||||
controllerPtr = std::make_unique<XboxController>(std::make_unique<SwitchUSBDevice>(interfaces, total_entries));
|
|
||||||
WriteToLog("Registered Xbox controller");
|
|
||||||
}
|
|
||||||
else if (R_SUCCEEDED(QueryInterfaces(interfaces, sizeof(interfaces), &total_entries, USB_CLASS_VENDOR_SPEC, 71, 208)))
|
|
||||||
{
|
|
||||||
controllerPtr = std::make_unique<XboxOneController>(std::make_unique<SwitchUSBDevice>(interfaces, total_entries));
|
|
||||||
WriteToLog("Registered Xbox One controller");
|
|
||||||
}
|
|
||||||
else if (R_SUCCEEDED(QueryVendorProduct(interfaces, sizeof(interfaces), &total_entries, VENDOR_SONY, PRODUCT_DUALSHOCK3)))
|
|
||||||
{
|
|
||||||
controllerPtr = std::make_unique<Dualshock3Controller>(std::make_unique<SwitchUSBDevice>(interfaces, total_entries));
|
|
||||||
WriteToLog("Registered DS3 controller");
|
|
||||||
}
|
|
||||||
else if (R_SUCCEEDED(QueryVendorProduct(interfaces, sizeof(interfaces), &total_entries, VENDOR_SONY, _globalConfig.dualshock4_productID)))
|
|
||||||
{
|
|
||||||
controllerPtr = std::make_unique<Dualshock4Controller>(std::make_unique<SwitchUSBDevice>(interfaces, total_entries));
|
|
||||||
WriteToLog("Registered DS4 controller");
|
|
||||||
}
|
|
||||||
CallInitHandler(controllerPtr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void eventLoop(void *buffer)
|
|
||||||
{
|
|
||||||
if (R_SUCCEEDED(eventWait(static_cast<Event *>(buffer), U64_MAX)))
|
|
||||||
{
|
|
||||||
CheckForInterfaces();
|
|
||||||
WriteToLog("Catch-all event went off");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Result errorLoop()
|
|
||||||
{
|
|
||||||
#ifdef __APPLET__
|
|
||||||
WriteToLog("Press B to exit...");
|
|
||||||
while (appletMainLoop())
|
|
||||||
{
|
|
||||||
hidScanInput();
|
|
||||||
|
|
||||||
if (hidKeysDown(CONTROLLER_P1_AUTO) & KEY_B)
|
|
||||||
break;
|
|
||||||
LockedUpdateConsole();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result mainLoop()
|
|
||||||
{
|
|
||||||
WriteToLog("\n\nNew sysmodule session started on version " APP_VERSION);
|
|
||||||
Result rc = 0;
|
|
||||||
|
|
||||||
UTimer filecheckTimer;
|
|
||||||
Waiter filecheckTimerWaiter = waiterForUTimer(&filecheckTimer);
|
|
||||||
utimerCreate(&filecheckTimer, 1e+9L, TimerType_Repeating);
|
|
||||||
utimerStart(&filecheckTimer);
|
|
||||||
|
|
||||||
PscPmModule pscModule;
|
|
||||||
const uint16_t dependencies[] = {PscPmModuleId_Usb};
|
|
||||||
|
|
||||||
rc = pscmGetPmModule(&pscModule, static_cast<PscPmModuleId>(126), dependencies, sizeof(dependencies) / sizeof(uint16_t), true);
|
|
||||||
WriteToLog("Get module result: 0x%x", rc);
|
|
||||||
if (R_FAILED(rc))
|
|
||||||
return errorLoop();
|
|
||||||
|
|
||||||
bool shouldSleep = false;
|
|
||||||
PSCLoopBuffer loopBuffer{pscModule, shouldSleep};
|
|
||||||
|
|
||||||
SwitchThread pscThread = SwitchThread(pscLoop, &loopBuffer, 0x300, 0x3B);
|
|
||||||
WriteToLog("Is psc thread running: %i", pscThread.IsRunning());
|
|
||||||
|
|
||||||
CheckForFileChanges();
|
|
||||||
LoadAllConfigs();
|
|
||||||
|
|
||||||
rc = OpenEvents();
|
|
||||||
if (R_FAILED(rc))
|
|
||||||
{
|
|
||||||
WriteToLog("Failed to open events: 0x%x", rc);
|
|
||||||
return errorLoop();
|
|
||||||
}
|
|
||||||
controllerInterfaces.reserve(10);
|
|
||||||
|
|
||||||
constexpr size_t eventThreadStack = 0x1'500 + APPLET_STACKSIZE;
|
|
||||||
SwitchThread eventThread(&eventLoop, &catchAllEvent, eventThreadStack, 0x20);
|
|
||||||
WriteToLog("Is event thread running: %i", eventThread.IsRunning());
|
|
||||||
|
|
||||||
while (appletMainLoop())
|
|
||||||
{
|
|
||||||
if (!shouldSleep)
|
|
||||||
{
|
|
||||||
|
|
||||||
#ifdef __APPLET__
|
|
||||||
hidScanInput();
|
|
||||||
u64 kDown = hidKeysDown(CONTROLLER_P1_AUTO);
|
|
||||||
|
|
||||||
for (int i = 0; i != 8; ++i)
|
|
||||||
{
|
|
||||||
u64 kHeld = hidKeysDown(static_cast<HidControllerID>(i));
|
|
||||||
if (kHeld != 0)
|
|
||||||
WriteToLog("Player %i: %lu", i + 1, kHeld);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kDown & KEY_B)
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
//On interface change event, check if any devices were removed, and erase them from memory appropriately
|
|
||||||
rc = eventWait(usbHsGetInterfaceStateChangeEvent(), 0);
|
|
||||||
if (R_SUCCEEDED(rc))
|
|
||||||
{
|
|
||||||
WriteToLog("Interface state was changed");
|
|
||||||
eventClear(usbHsGetInterfaceStateChangeEvent());
|
|
||||||
rc = usbHsQueryAcquiredInterfaces(interfaces, sizeof(interfaces), &total_entries);
|
|
||||||
if (R_SUCCEEDED(rc))
|
|
||||||
{
|
|
||||||
for (auto it = controllerInterfaces.begin(); it != controllerInterfaces.end(); ++it)
|
|
||||||
{
|
|
||||||
bool found_flag = false;
|
|
||||||
|
|
||||||
for (auto &&ptr : (*it)->GetController()->GetDevice()->GetInterfaces())
|
|
||||||
{
|
|
||||||
//We check if a device was removed by comparing the controller's interfaces and the currently acquired interfaces
|
|
||||||
//If we didn't find a single matching interface ID, we consider a controller removed
|
|
||||||
for (int i = 0; i != total_entries; ++i)
|
|
||||||
{
|
|
||||||
if (interfaces[i].inf.ID == static_cast<SwitchUSBInterface *>(ptr.get())->GetID())
|
|
||||||
{
|
|
||||||
found_flag = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found_flag)
|
|
||||||
{
|
|
||||||
WriteToLog("Erasing controller! %i", (*it)->GetController()->GetType());
|
|
||||||
controllerInterfaces.erase(it--);
|
|
||||||
WriteToLog("Controller erased!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Checks every 1 second for any changes in config files, then reloads them
|
|
||||||
rc = waitSingle(filecheckTimerWaiter, 0);
|
|
||||||
if (R_SUCCEEDED(rc))
|
|
||||||
{
|
|
||||||
if (CheckForFileChanges())
|
|
||||||
{
|
|
||||||
WriteToLog("File check succeeded! Loading configs...");
|
|
||||||
LoadAllConfigs();
|
|
||||||
usbHsDestroyInterfaceAvailableEvent(&ds4Event, DS4EVENT_INDEX);
|
|
||||||
CreateDualshock4AvailableEvent(ds4Event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (controllerInterfaces.size() != 0)
|
|
||||||
{
|
|
||||||
WriteToLog("Clearing interfaces before going to sleep");
|
|
||||||
controllerInterfaces.clear();
|
|
||||||
}
|
|
||||||
#ifdef __APPLET__
|
|
||||||
LockedUpdateConsole();
|
|
||||||
#else
|
|
||||||
svcSleepThread(1e+7L);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteToLog("Closing PSC module");
|
|
||||||
pscPmModuleFinalize(&pscModule);
|
|
||||||
pscPmModuleClose(&pscModule);
|
|
||||||
eventClose(&pscModule.event);
|
|
||||||
pscThread.Exit();
|
|
||||||
|
|
||||||
WriteToLog("Destroying events");
|
|
||||||
CloseEvents();
|
|
||||||
eventThread.Exit();
|
|
||||||
|
|
||||||
WriteToLog("Clearing interfaces");
|
|
||||||
controllerInterfaces.clear();
|
|
||||||
return rc;
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "switch/result.h"
|
|
||||||
|
|
||||||
struct GlobalConfig
|
|
||||||
{
|
|
||||||
uint16_t dualshock4_productID;
|
|
||||||
};
|
|
||||||
|
|
||||||
Result mainLoop();
|
|
||||||
|
|
||||||
void LoadGlobalConfig(const GlobalConfig *config);
|
|
Loading…
Reference in New Issue
Block a user