From 17b205d8d0549f9b93afaa858ad224204f6c61d0 Mon Sep 17 00:00:00 2001 From: cathery Date: Fri, 22 Nov 2019 00:40:42 +0300 Subject: [PATCH] Update code structure --- source/configFile.cpp | 2 +- source/main.cpp | 20 ++++- source/mainLoop.cpp | 204 +++++++++++++++++++----------------------- 3 files changed, 111 insertions(+), 115 deletions(-) diff --git a/source/configFile.cpp b/source/configFile.cpp index 35ea5df..47e5542 100644 --- a/source/configFile.cpp +++ b/source/configFile.cpp @@ -18,7 +18,7 @@ #define DUALSHOCK3CONFIG "config_dualshock3.ini" #define DUALSHOCK4CONFIG "config_dualshock4.ini" -std::array keyNames{ +constexpr std::array keyNames{ "FACE_UP", "FACE_RIGHT", "FACE_DOWN", diff --git a/source/main.cpp b/source/main.cpp index c2830b4..27f5f6d 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -2,10 +2,13 @@ #include "log.h" #include "mainLoop.h" +//CHANGELOG +// Fixed an issue where unplugging one controller would unplug others + //ISSUES: -// when exiting the applet, only one of the controllers is reset -// Rumble is currently missing on all controllers -// Kosmos Toolbox doesn't allow this sysmodule to be turned on after turning it off, probably due to heap memory not being freed up +// Kosmos Toolbox doesn't free up the memory associated with the sysmodule due to hiddbgAttachHdlsWorkBuffer() memory not being freed up +// After plugging and unplugging a controller for a while, sysmodule stops working +// DS3 controller seems to send random inputs //TODO: // Shrink unneessary heap memory/stack size used for the sysmodule @@ -14,7 +17,7 @@ extern "C" { // Adjust size as needed. -#define INNER_HEAP_SIZE 0x40000 +#define INNER_HEAP_SIZE 0x40'000 #ifndef __APPLET__ u32 __nx_applet_type = AppletType_None; @@ -75,6 +78,15 @@ extern "C" hiddbgReleaseHdlsWorkBuffer(); hiddbgExit(); } + + alignas(16) u8 __nx_exception_stack[0x1000]; + u64 __nx_exception_stack_size = sizeof(__nx_exception_stack); + __attribute__((weak)) u32 __nx_exception_ignoredebug = 1; + + void __libnx_exception_handler(ThreadExceptionDump *ctx) + { + WriteToLog("Sysmodule crashed with error 0x", std::hex, ctx->error_desc); + } } int main(int argc, char *argv[]) diff --git a/source/mainLoop.cpp b/source/mainLoop.cpp index 1e1c111..910676a 100644 --- a/source/mainLoop.cpp +++ b/source/mainLoop.cpp @@ -9,13 +9,84 @@ #include "SwitchAbstractedPadHandler.h" #include "configFile.h" -#define APP_VERSION "0.5.0" +#define APP_VERSION "0.5.1" -struct VendorEvent +static const bool useAbstractedPad = hosversionBetween(5, 7); +std::vector> controllerInterfaces; + +static GlobalConfig _globalConfig{}; + +void LoadGlobalConfig(const GlobalConfig *config) { - uint16_t vendor; - Event event; -}; + _globalConfig = *config; +} + +Result CallInitHandler(std::unique_ptr &controllerPtr) +{ + if (controllerPtr) + { + std::unique_ptr switchHandler; + if (useAbstractedPad) + switchHandler = std::make_unique(std::move(controllerPtr)); + else + switchHandler = std::make_unique(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 ", rc); + return rc; + } + } + return 1; +} + +Result CreateDualshck3AvailableEvent(Event &out) +{ + UsbHsInterfaceFilter filter; + filter.Flags = UsbHsInterfaceFilterFlags_idVendor | UsbHsInterfaceFilterFlags_idProduct; + filter.idVendor = VENDOR_SONY; + filter.idProduct = PRODUCT_DUALSHOCK3; + Result rc = usbHsCreateInterfaceAvailableEvent(&out, true, 0, &filter); + if (R_FAILED(rc)) + WriteToLog("Failed to open event for Dualshock 3"); + else + WriteToLog("Successfully created event for Dualshock 3"); + return rc; +} + +Result CreateDualshock4AvailableEvent(Event &out) +{ + UsbHsInterfaceFilter filter; + filter.Flags = UsbHsInterfaceFilterFlags_idVendor | UsbHsInterfaceFilterFlags_idProduct; + filter.idVendor = VENDOR_SONY; + filter.idProduct = _globalConfig.dualshock4_productID; + Result rc = usbHsCreateInterfaceAvailableEvent(&out, true, 1, &filter); + if (R_FAILED(rc)) + WriteToLog("Failed to open event for Dualshock 4 0x", std::hex, _globalConfig.dualshock4_productID); + else + WriteToLog("Successfully created event for Dualshock 4 0x", std::hex, _globalConfig.dualshock4_productID); + return rc; +} + +Result CreateAllAvailableEvent(Event &out) +{ + UsbHsInterfaceFilter filter; + filter.Flags = UsbHsInterfaceFilterFlags_bcdDevice_Min; + filter.bcdDevice_Min = 0; + Result rc = usbHsCreateInterfaceAvailableEvent(&out, true, 2, &filter); + if (R_FAILED(rc)) + WriteToLog("Failed to open catch-all event"); + else + WriteToLog("Successfully created catch-all event"); + return rc; +} Result QueryInterfaces(UsbHsInterface *interfaces, size_t interfaces_size, s32 *total_entries, u8 infclass, u8 infsubclass, u8 infprotocol) { @@ -44,109 +115,28 @@ Result QueryVendorProduct(UsbHsInterface *interfaces, size_t interfaces_size, s3 return 1; } -std::unique_ptr devicePtr; -std::unique_ptr controllerPtr; -bool useAbstractedPad = hosversionBetween(5, 7); -std::vector> controllerInterfaces; - -static GlobalConfig _globalConfig{}; - -void LoadGlobalConfig(const GlobalConfig *config) -{ - _globalConfig = *config; -} - -Result CreateDualshock4AvailableEvent(Event &event) -{ - UsbHsInterfaceFilter filter; - filter.Flags = UsbHsInterfaceFilterFlags_idVendor | UsbHsInterfaceFilterFlags_idProduct; - filter.idVendor = VENDOR_SONY; - filter.idProduct = _globalConfig.dualshock4_productID; - Result rc = usbHsCreateInterfaceAvailableEvent(&event, true, 2, &filter); - if (R_FAILED(rc)) - WriteToLog("Failed to open event for Dualshock 4 0x", std::hex, _globalConfig.dualshock4_productID); - else - WriteToLog("Successfully created event for Dualshock 4 0x", std::hex, _globalConfig.dualshock4_productID); - return rc; -} - -Result CallInitHandler() -{ - if (controllerPtr) - { - Result rc; - std::unique_ptr switchHandler; - if (useAbstractedPad) - switchHandler = std::make_unique(std::move(controllerPtr)); - else - switchHandler = std::make_unique(std::move(controllerPtr)); - - 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 ", rc); - return rc; - } - } - return 1; -} - Result mainLoop() { WriteToLog("\n\nNew sysmodule session started on version " APP_VERSION); Result rc = 0; - Event catchAllEvent; - Event ds3Event; - Event ds4Event; + std::unique_ptr controllerPtr; UTimer filecheckTimer; Waiter filecheckTimerWaiter = waiterForUTimer(&filecheckTimer); utimerCreate(&filecheckTimer, 1e+9L, TimerType_Repeating); utimerStart(&filecheckTimer); + CheckForFileChanges(); LoadAllConfigs(); - { - UsbHsInterfaceFilter filter; - //filter.Flags = UsbHsInterfaceFilterFlags_bInterfaceClass | UsbHsInterfaceFilterFlags_bcdDevice_Min; - //filter.bInterfaceClass = USB_CLASS_HID; - //filter.bcdDevice_Min = 0; - filter.Flags = UsbHsInterfaceFilterFlags_idVendor | UsbHsInterfaceFilterFlags_idProduct; - filter.idVendor = VENDOR_SONY; - filter.idProduct = PRODUCT_DUALSHOCK3; - rc = usbHsCreateInterfaceAvailableEvent(&ds3Event, true, 0, &filter); - if (R_FAILED(rc)) - WriteToLog("Failed to open event for Dualshock 3"); - else - WriteToLog("Successfully created event for Dualshock 3"); + Event catchAllEvent; + Event ds3Event; + Event ds4Event; - filter.Flags = UsbHsInterfaceFilterFlags_bcdDevice_Min; - filter.bcdDevice_Min = 0; - rc = usbHsCreateInterfaceAvailableEvent(&catchAllEvent, true, 1, &filter); - if (R_FAILED(rc)) - WriteToLog("Failed to open catch-all event"); - else - WriteToLog("Successfully created catch-all event"); - /* - filter.Flags = UsbHsInterfaceFilterFlags_idVendor | UsbHsInterfaceFilterFlags_idProduct; - filter.idVendor = VENDOR_SONY; - filter.idProduct = PRODUCT_DUALSHOCK4_2X; - rc = usbHsCreateInterfaceAvailableEvent(&ds4Event, true, 2, &filter); - if (R_FAILED(rc)) - WriteToLog("Failed to open event for Dualshock 4 2x"); - else - WriteToLog("Successfully created event for Dualshock 4 2x"); - */ - - CreateDualshock4AvailableEvent(ds4Event); - } + CreateDualshck3AvailableEvent(ds3Event); + CreateAllAvailableEvent(catchAllEvent); + CreateDualshock4AvailableEvent(ds4Event); controllerInterfaces.reserve(10); @@ -193,37 +183,32 @@ Result mainLoop() if (R_SUCCEEDED(QueryInterfaces(interfaces, sizeof(interfaces), &total_entries, USB_CLASS_VENDOR_SPEC, 93, 1))) { WriteToLog("Registering Xbox 360 controller"); - devicePtr = std::make_unique(interfaces, total_entries); - controllerPtr = std::make_unique(std::move(devicePtr)); + controllerPtr = std::make_unique(std::make_unique(interfaces, total_entries)); } else if (R_SUCCEEDED(QueryInterfaces(interfaces, sizeof(interfaces), &total_entries, USB_CLASS_VENDOR_SPEC, 93, 129))) { WriteToLog("Registering Xbox 360 Wireless adapter"); for (int i = 0; i != total_entries; ++i) { - devicePtr = std::make_unique(interfaces + i, 1); - controllerPtr = std::make_unique(std::move(devicePtr)); - CallInitHandler(); + controllerPtr = std::make_unique(std::make_unique(interfaces + i, 1)); + CallInitHandler(controllerPtr); } } else if (R_SUCCEEDED(QueryInterfaces(interfaces, sizeof(interfaces), &total_entries, 0x58, 0x42, 0x00))) { WriteToLog("Registering Xbox One controller"); - devicePtr = std::make_unique(interfaces, total_entries); - controllerPtr = std::make_unique(std::move(devicePtr)); + controllerPtr = std::make_unique(std::make_unique(interfaces, total_entries)); } else if (R_SUCCEEDED(QueryInterfaces(interfaces, sizeof(interfaces), &total_entries, USB_CLASS_VENDOR_SPEC, 71, 208))) { WriteToLog("Registering Xbox One controller"); - devicePtr = std::make_unique(interfaces, total_entries); - controllerPtr = std::make_unique(std::move(devicePtr)); + controllerPtr = std::make_unique(std::make_unique(interfaces, total_entries)); } /* else if (R_SUCCEEDED(QueryInterfaces(interfaces, sizeof(interfaces), &total_entries, USB_CLASS_VENDOR_SPEC, 255, 255))) { WriteToLog("Registering Xbox One adapter"); - devicePtr = std::make_unique(interfaces, total_entries); - controllerPtr = std::make_unique(std::move(devicePtr)); + controllerPtr = std::make_unique(std::make_unique(interfaces, total_entries)); } */ } @@ -238,8 +223,7 @@ Result mainLoop() if (R_SUCCEEDED(QueryInterfaces(interfaces, sizeof(interfaces), &total_entries, USB_CLASS_HID, 0, 0))) { WriteToLog("Registering DS3 controller"); - devicePtr = std::make_unique(interfaces, total_entries); - controllerPtr = std::make_unique(std::move(devicePtr)); + controllerPtr = std::make_unique(std::make_unique(interfaces, total_entries)); } } rc = eventWait(&ds4Event, 0); @@ -252,11 +236,10 @@ Result mainLoop() if (R_SUCCEEDED(QueryInterfaces(interfaces, sizeof(interfaces), &total_entries, USB_CLASS_HID, 0, 0))) { WriteToLog("Registering DS4 controller"); - devicePtr = std::make_unique(interfaces, total_entries); - controllerPtr = std::make_unique(std::move(devicePtr)); + controllerPtr = std::make_unique(std::make_unique(interfaces, total_entries)); } } - CallInitHandler(); + CallInitHandler(controllerPtr); //On interface change event, check if any devices were removed, and erase them from memory appropriately rc = eventWait(usbHsGetInterfaceStateChangeEvent(), 0); @@ -299,6 +282,7 @@ Result mainLoop() } } + //Checks every 1 second for any changes in config files, then reloads them rc = waitSingle(filecheckTimerWaiter, 0); if (R_SUCCEEDED(rc)) {