From 264673d6fc8990ae11c5d44e1039e40b50659fe8 Mon Sep 17 00:00:00 2001 From: cathery Date: Wed, 6 Nov 2019 15:28:56 +0300 Subject: [PATCH] Reduce memory usage by using threadCreate instead of std::thread --- .gitignore | 5 +- .../include/Controllers/XboxOneController.h | 2 +- ControllerUSB/include/IController.h | 1 - .../Controllers/Dualshock3Controller.cpp | 2 +- .../source/Controllers/XboxOneController.cpp | 2 +- .../include/SwitchAbstractedPadHandler.h | 2 - SwitchUSB/include/SwitchControllerHandler.h | 1 - SwitchUSB/include/SwitchHDLHandler.h | 1 - SwitchUSB/include/SwitchUSBEndpoint.h | 4 +- .../include/SwitchVirtualGamepadHandler.h | 11 ++-- .../source/SwitchAbstractedPadHandler.cpp | 6 ++- SwitchUSB/source/SwitchHDLHandler.cpp | 47 +++++++++++----- SwitchUSB/source/SwitchUSBEndpoint.cpp | 13 +++-- SwitchUSB/source/SwitchUSBInterface.cpp | 2 +- .../source/SwitchVirtualGamepadHandler.cpp | 36 ++++++++----- source/main.cpp | 11 +--- source/mainLoop.cpp | 54 +++++++++---------- 17 files changed, 112 insertions(+), 88 deletions(-) diff --git a/.gitignore b/.gitignore index 3d5f570..8e136bf 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,7 @@ buildSysmodule/* *.nso .vscode *.code-workspace -*.flag \ No newline at end of file +*.flag +*.rar +*.xml +*.png \ No newline at end of file diff --git a/ControllerUSB/include/Controllers/XboxOneController.h b/ControllerUSB/include/Controllers/XboxOneController.h index d041dbb..ae3f80e 100644 --- a/ControllerUSB/include/Controllers/XboxOneController.h +++ b/ControllerUSB/include/Controllers/XboxOneController.h @@ -79,7 +79,7 @@ private: IUSBEndpoint *m_outPipe = nullptr; XboxOneButtonData m_buttonData; - bool m_GuidePressed; + bool m_GuidePressed{false}; int16_t kLeftThumbDeadzone = 2500; //7849; int16_t kRightThumbDeadzone = 3500; //8689; diff --git a/ControllerUSB/include/IController.h b/ControllerUSB/include/IController.h index 4419216..a101a08 100644 --- a/ControllerUSB/include/IController.h +++ b/ControllerUSB/include/IController.h @@ -2,7 +2,6 @@ #include "IUSBDevice.h" #include "ControllerTypes.h" #include -#include "Status.h" struct NormalizedButtonData { diff --git a/ControllerUSB/source/Controllers/Dualshock3Controller.cpp b/ControllerUSB/source/Controllers/Dualshock3Controller.cpp index 35a198d..6953417 100644 --- a/ControllerUSB/source/Controllers/Dualshock3Controller.cpp +++ b/ControllerUSB/source/Controllers/Dualshock3Controller.cpp @@ -83,7 +83,7 @@ void Dualshock3Controller::CloseInterfaces() Status Dualshock3Controller::GetInput() { - uint8_t input_bytes[64]; + uint8_t input_bytes[49]; Status rc = m_inPipe->Read(input_bytes, sizeof(input_bytes)); if (S_FAILED(rc)) diff --git a/ControllerUSB/source/Controllers/XboxOneController.cpp b/ControllerUSB/source/Controllers/XboxOneController.cpp index c8b4ace..7505236 100644 --- a/ControllerUSB/source/Controllers/XboxOneController.cpp +++ b/ControllerUSB/source/Controllers/XboxOneController.cpp @@ -88,7 +88,7 @@ void XboxOneController::CloseInterfaces() Status XboxOneController::GetInput() { - uint8_t input_bytes[64]; + uint8_t input_bytes[18]; Status rc = m_inPipe->Read(input_bytes, sizeof(input_bytes)); if (S_FAILED(rc)) diff --git a/SwitchUSB/include/SwitchAbstractedPadHandler.h b/SwitchUSB/include/SwitchAbstractedPadHandler.h index 97f1fcd..ea4e557 100644 --- a/SwitchUSB/include/SwitchAbstractedPadHandler.h +++ b/SwitchUSB/include/SwitchAbstractedPadHandler.h @@ -4,10 +4,8 @@ #include "IController.h" #include "SwitchControllerHandler.h" #include "SwitchVirtualGamepadHandler.h" -#include //Wrapper for AbstractedPad for switch versions [5.0.0 - 8.1.0] -//DOESN'T WORK PROPERLY. See inside SwitchAbstractedPadHandler::FillAbstractedState() class SwitchAbstractedPadHandler : public SwitchVirtualGamepadHandler { private: diff --git a/SwitchUSB/include/SwitchControllerHandler.h b/SwitchUSB/include/SwitchControllerHandler.h index 4bbe724..c3016b4 100644 --- a/SwitchUSB/include/SwitchControllerHandler.h +++ b/SwitchUSB/include/SwitchControllerHandler.h @@ -2,7 +2,6 @@ #include "switch.h" #include "IController.h" -#include class SwitchControllerHandler { diff --git a/SwitchUSB/include/SwitchHDLHandler.h b/SwitchUSB/include/SwitchHDLHandler.h index b6a5d2d..cbc8f04 100644 --- a/SwitchUSB/include/SwitchHDLHandler.h +++ b/SwitchUSB/include/SwitchHDLHandler.h @@ -4,7 +4,6 @@ #include "IController.h" #include "SwitchControllerHandler.h" #include "SwitchVirtualGamepadHandler.h" -#include //Wrapper for HDL functions for switch versions [7.0.0+] class SwitchHDLHandler : public SwitchVirtualGamepadHandler diff --git a/SwitchUSB/include/SwitchUSBEndpoint.h b/SwitchUSB/include/SwitchUSBEndpoint.h index 62a949c..d474fb2 100644 --- a/SwitchUSB/include/SwitchUSBEndpoint.h +++ b/SwitchUSB/include/SwitchUSBEndpoint.h @@ -7,8 +7,8 @@ class SwitchUSBEndpoint : public IUSBEndpoint { private: UsbHsClientEpSession m_epSession{}; - UsbHsClientIfSession m_ifSession; - usb_endpoint_descriptor m_descriptor; + UsbHsClientIfSession *m_ifSession; + usb_endpoint_descriptor *m_descriptor; void *m_buffer; diff --git a/SwitchUSB/include/SwitchVirtualGamepadHandler.h b/SwitchUSB/include/SwitchVirtualGamepadHandler.h index dfa9821..d29e5f2 100644 --- a/SwitchUSB/include/SwitchVirtualGamepadHandler.h +++ b/SwitchUSB/include/SwitchVirtualGamepadHandler.h @@ -2,7 +2,6 @@ #include "switch.h" #include "IController.h" #include "SwitchControllerHandler.h" -#include //This class is a base class for SwitchHDLHandler and SwitchAbstractedPaadHandler. class SwitchVirtualGamepadHandler @@ -12,10 +11,10 @@ protected: SwitchControllerHandler m_controllerHandler; bool m_keepInputThreadRunning; - std::thread m_inputThread; + Thread m_inputThread; bool m_keepOutputThreadRunning; - std::thread m_outputThread; + Thread m_outputThread; public: SwitchVirtualGamepadHandler(std::unique_ptr &&controller); @@ -33,12 +32,12 @@ public: virtual void Exit(); //Separately init the input-reading thread - void InitInputThread(); + Result InitInputThread(); //Separately close the input-reading thread void ExitInputThread(); //Separately init the rumble sending thread - void InitOutputThread(); + Result InitOutputThread(); //Separately close the rumble sending thread void ExitOutputThread(); @@ -48,6 +47,8 @@ public: virtual void UpdateOutput() = 0; //Get the raw controller handler pointer + inline bool *GetInputThreadBool() { return &m_keepInputThreadRunning; } + inline bool *GetOutputThreadBool() { return &m_keepOutputThreadRunning; } inline SwitchControllerHandler *GetControllerHandler() { return &m_controllerHandler; } inline IController *GetController() { return m_controllerHandler.GetController(); } inline u32 *GetVibrationHandle() { return &m_vibrationDeviceHandle; } diff --git a/SwitchUSB/source/SwitchAbstractedPadHandler.cpp b/SwitchUSB/source/SwitchAbstractedPadHandler.cpp index 2d26d0d..d31f2d2 100644 --- a/SwitchUSB/source/SwitchAbstractedPadHandler.cpp +++ b/SwitchUSB/source/SwitchAbstractedPadHandler.cpp @@ -1,7 +1,6 @@ #include "SwitchAbstractedPadHandler.h" #include #include -#include "../../source/log.h" SwitchAbstractedPadHandler::SwitchAbstractedPadHandler(std::unique_ptr &&controller) : SwitchVirtualGamepadHandler(std::move(controller)) @@ -52,7 +51,10 @@ Result SwitchAbstractedPadHandler::Initialize() WriteToLog("Failed to iniitalize vibration device with error ", rc2); */ - InitInputThread(); + rc = InitInputThread(); + if (R_FAILED(rc)) + return rc; + return rc; } diff --git a/SwitchUSB/source/SwitchHDLHandler.cpp b/SwitchUSB/source/SwitchHDLHandler.cpp index dbc29dc..ee928bb 100644 --- a/SwitchUSB/source/SwitchHDLHandler.cpp +++ b/SwitchUSB/source/SwitchHDLHandler.cpp @@ -1,6 +1,5 @@ #include "SwitchHDLHandler.h" #include -#include "../../source/log.h" SwitchHDLHandler::SwitchHDLHandler(std::unique_ptr &&controller) : SwitchVirtualGamepadHandler(std::move(controller)) @@ -50,7 +49,9 @@ Result SwitchHDLHandler::Initialize() WriteToLog("Failed to iniitalize vibration with error ", rc2); */ - InitInputThread(); + rc = InitInputThread(); + if (R_FAILED(rc)) + return rc; return rc; } @@ -75,8 +76,8 @@ Result SwitchHDLHandler::InitHdlState() // Set the controller colors. The grip colors are for Pro-Controller on [9.0.0+]. m_deviceInfo.singleColorBody = RGBA8_MAXALPHA(107, 107, 107); m_deviceInfo.singleColorButtons = RGBA8_MAXALPHA(0, 0, 0); - m_deviceInfo.colorLeftGrip = RGBA8_MAXALPHA(23, 125, 62); - m_deviceInfo.colorRightGrip = RGBA8_MAXALPHA(23, 125, 62); + m_deviceInfo.colorLeftGrip = RGBA8_MAXALPHA(70, 70, 70); + m_deviceInfo.colorRightGrip = RGBA8_MAXALPHA(70, 70, 70); m_hdlState.batteryCharge = 4; // Set battery charge to full. m_hdlState.joysticks[JOYSTICK_LEFT].dx = 0x1234; @@ -95,19 +96,39 @@ Result SwitchHDLHandler::ExitHdlState() Result SwitchHDLHandler::UpdateHdlState() { //Checks if the virtual device was erased, in which case re-attach the device - bool found_flag = false; - HiddbgHdlsStateList list; - hiddbgDumpHdlsStates(&list); - for (int i = 0; i != list.total_entries; ++i) + + if (R_SUCCEEDED(serviceDispatch(hiddbgGetServiceSession(), 327))) { - if (list.entries[i].HdlsHandle == m_hdlHandle) + bool found_flag = false; + + if (hosversionBefore(9, 0, 0)) { - found_flag = true; - break; + HiddbgHdlsStateListV7 *stateList = static_cast(hiddbgGetWorkBufferTransferMemoryAddress()->src_addr); + for (int i = 0; i != stateList->total_entries; ++i) + { + if (stateList->entries[i].HdlsHandle == m_hdlHandle) + { + found_flag = true; + break; + } + } } + else + { + HiddbgHdlsStateList *stateList = static_cast(hiddbgGetWorkBufferTransferMemoryAddress()->src_addr); + for (int i = 0; i != stateList->total_entries; ++i) + { + if (stateList->entries[i].HdlsHandle == m_hdlHandle) + { + found_flag = true; + break; + } + } + } + + if (!found_flag) + hiddbgAttachHdlsVirtualDevice(&m_hdlHandle, &m_deviceInfo); } - if (!found_flag) - hiddbgAttachHdlsVirtualDevice(&m_hdlHandle, &m_deviceInfo); return hiddbgSetHdlsState(m_hdlHandle, &m_hdlState); } diff --git a/SwitchUSB/source/SwitchUSBEndpoint.cpp b/SwitchUSB/source/SwitchUSBEndpoint.cpp index 6ca87e9..19482ae 100644 --- a/SwitchUSB/source/SwitchUSBEndpoint.cpp +++ b/SwitchUSB/source/SwitchUSBEndpoint.cpp @@ -1,13 +1,12 @@ #include "SwitchUSBEndpoint.h" #include -#include #include SwitchUSBEndpoint::SwitchUSBEndpoint(UsbHsClientIfSession &if_session, usb_endpoint_descriptor &desc) - : m_ifSession(if_session), - m_descriptor(desc) + : m_ifSession(&if_session), + m_descriptor(&desc) { - m_buffer = memalign(0x1000, 0x100); + m_buffer = memalign(0x1000, 64); } SwitchUSBEndpoint::~SwitchUSBEndpoint() @@ -18,7 +17,7 @@ SwitchUSBEndpoint::~SwitchUSBEndpoint() Result SwitchUSBEndpoint::Open() { - Result rc = usbHsIfOpenUsbEp(&m_ifSession, &m_epSession, 1, m_descriptor.wMaxPacketSize, &m_descriptor); + Result rc = usbHsIfOpenUsbEp(m_ifSession, &m_epSession, 1, m_descriptor->wMaxPacketSize, m_descriptor); if (R_FAILED(rc)) return 73011; return rc; @@ -69,10 +68,10 @@ Result SwitchUSBEndpoint::Read(void *outBuffer, size_t bufferSize) IUSBEndpoint::Direction SwitchUSBEndpoint::GetDirection() { - return ((m_descriptor.bEndpointAddress & USB_ENDPOINT_IN) ? USB_ENDPOINT_IN : USB_ENDPOINT_OUT); + return ((m_descriptor->bEndpointAddress & USB_ENDPOINT_IN) ? USB_ENDPOINT_IN : USB_ENDPOINT_OUT); } IUSBEndpoint::EndpointDescriptor *SwitchUSBEndpoint::GetDescriptor() { - return reinterpret_cast(&m_descriptor); + return reinterpret_cast(m_descriptor); } \ No newline at end of file diff --git a/SwitchUSB/source/SwitchUSBInterface.cpp b/SwitchUSB/source/SwitchUSBInterface.cpp index 942b92b..ec7b0ef 100644 --- a/SwitchUSB/source/SwitchUSBInterface.cpp +++ b/SwitchUSB/source/SwitchUSBInterface.cpp @@ -6,7 +6,7 @@ SwitchUSBInterface::SwitchUSBInterface(UsbHsInterface &interface) : m_interface(interface) { - m_controlTransferBuffer = memalign(0x1000, 0x100); + m_controlTransferBuffer = memalign(0x1000, 64); } SwitchUSBInterface::~SwitchUSBInterface() diff --git a/SwitchUSB/source/SwitchVirtualGamepadHandler.cpp b/SwitchUSB/source/SwitchVirtualGamepadHandler.cpp index da86125..5ae0711 100644 --- a/SwitchUSB/source/SwitchVirtualGamepadHandler.cpp +++ b/SwitchUSB/source/SwitchVirtualGamepadHandler.cpp @@ -18,46 +18,58 @@ void SwitchVirtualGamepadHandler::Exit() { } -void inputThreadLoop(bool *keepThreadRunning, SwitchVirtualGamepadHandler *handler) +void inputThreadLoop(void *handler) { svcSleepThread(1e+7L); + SwitchVirtualGamepadHandler *switchHandler = static_cast(handler); + bool *keepThreadRunning = switchHandler->GetInputThreadBool(); + while (*keepThreadRunning) { - handler->UpdateInput(); + switchHandler->UpdateInput(); } } -void outputThreadLoop(bool *keepThreadRunning, SwitchVirtualGamepadHandler *handler) +void outputThreadLoop(void *handler) { svcSleepThread(1e+7L); + SwitchVirtualGamepadHandler *switchHandler = static_cast(handler); + bool *keepThreadRunning = switchHandler->GetInputThreadBool(); + while (*keepThreadRunning) { - handler->UpdateOutput(); + switchHandler->UpdateOutput(); } } -void SwitchVirtualGamepadHandler::InitInputThread() +Result SwitchVirtualGamepadHandler::InitInputThread() { m_keepInputThreadRunning = true; - m_inputThread = std::thread(inputThreadLoop, &m_keepInputThreadRunning, this); + Result rc = threadCreate(&m_inputThread, inputThreadLoop, this, NULL, 0x400, 0x3B, -2); + if (R_FAILED(rc)) + return rc; + return threadStart(&m_inputThread); } void SwitchVirtualGamepadHandler::ExitInputThread() { m_keepInputThreadRunning = false; - if (m_inputThread.joinable()) - m_inputThread.join(); + threadWaitForExit(&m_inputThread); + threadClose(&m_inputThread); } -void SwitchVirtualGamepadHandler::InitOutputThread() +Result SwitchVirtualGamepadHandler::InitOutputThread() { m_keepOutputThreadRunning = true; - m_outputThread = std::thread(outputThreadLoop, &m_keepOutputThreadRunning, this); + Result rc = threadCreate(&m_outputThread, outputThreadLoop, this, NULL, 0x400, 0x3B, -2); + if (R_FAILED(rc)) + return rc; + return threadStart(&m_outputThread); } void SwitchVirtualGamepadHandler::ExitOutputThread() { m_keepOutputThreadRunning = false; - if (m_outputThread.joinable()) - m_outputThread.join(); + threadWaitForExit(&m_outputThread); + threadClose(&m_outputThread); } \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index be67cc0..6400871 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -16,7 +16,7 @@ extern "C" { // Adjust size as needed. -#define INNER_HEAP_SIZE 0x100000 +#define INNER_HEAP_SIZE 0x40000 #ifndef __APPLET__ u32 __nx_applet_type = AppletType_None; @@ -74,15 +74,6 @@ 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 ", ctx->error_desc); - } } int main(int argc, char *argv[]) diff --git a/source/mainLoop.cpp b/source/mainLoop.cpp index 808f145..6a6e4e5 100644 --- a/source/mainLoop.cpp +++ b/source/mainLoop.cpp @@ -16,38 +16,35 @@ struct VendorEvent Result mainLoop() { Result rc = 0; - UsbHsInterface interfaces[16]; - s32 total_entries; - std::vector vendors = GetVendors(); + bool useAbstractedPad = hosversionBetween(5, 7); //hidPermitVibration(false); //hidPermitVibration(true); - VendorEvent events[vendors.size()]; + VendorEvent events[2]; std::vector> controllerInterfaces; WriteToLog("\n\nNew sysmodule session started"); { - int i = 0; - for (auto &&vendor : vendors) - { - UsbHsInterfaceFilter filter; - filter.Flags = UsbHsInterfaceFilterFlags_idVendor; - filter.idVendor = vendor; - if (vendor == VENDOR_SONY) - { - filter.Flags |= UsbHsInterfaceFilterFlags_idProduct; - filter.idProduct = PRODUCT_DUALSHOCK3; - } - auto &&event = events[i] = {vendor, Event()}; + UsbHsInterfaceFilter filter; + filter.Flags = UsbHsInterfaceFilterFlags_idVendor; + filter.idVendor = VENDOR_MICROSOFT; + events[0] = {VENDOR_MICROSOFT, Event()}; + rc = usbHsCreateInterfaceAvailableEvent(&events[0].event, true, 0, &filter); + if (R_FAILED(rc)) + WriteToLog("Failed to open event for microsoft"); + else + WriteToLog("Successfully created event for microsoft"); - rc = usbHsCreateInterfaceAvailableEvent(&event.event, true, i, &filter); - if (R_FAILED(rc)) - WriteToLog("Failed to open event ", event.vendor); - else - WriteToLog("Successfully created event ", event.vendor); - ++i; - } + filter.Flags = UsbHsInterfaceFilterFlags_idVendor | UsbHsInterfaceFilterFlags_idProduct; + filter.idVendor = VENDOR_SONY; + filter.idProduct = PRODUCT_DUALSHOCK3; + events[1] = {VENDOR_SONY, Event()}; + rc = usbHsCreateInterfaceAvailableEvent(&events[1].event, true, 1, &filter); + if (R_FAILED(rc)) + WriteToLog("Failed to open event for sony dualshock 3"); + else + WriteToLog("Successfully created event for sony dualshock 3"); } controllerInterfaces.reserve(8); @@ -58,7 +55,7 @@ Result mainLoop() #ifdef __APPLET__ hidScanInput(); u64 kDown = hidKeysDown(CONTROLLER_P1_AUTO); - + /* if (kDown & KEY_Y) { for (int i = 0; i != 8; ++i) @@ -72,7 +69,6 @@ Result mainLoop() } } } - /* if (kDown & KEY_X) { @@ -117,14 +113,15 @@ Result mainLoop() WriteToLog("Succeeded event ", event.vendor); WriteToLog("Interfaces size: ", controllerInterfaces.size(), "; capacity: ", controllerInterfaces.capacity()); - auto &&products = GetVendorProducts(event.vendor); - for (auto &&product : products) + for (auto &&product : GetVendorProducts(event.vendor)) { if (controllerInterfaces.size() == 8) { WriteToLog("Reached controller limit! skipping initialization"); break; } + UsbHsInterface interfaces[4]; + s32 total_entries; UsbHsInterfaceFilter tempFilter; tempFilter.Flags = UsbHsInterfaceFilterFlags_idVendor | UsbHsInterfaceFilterFlags_idProduct; @@ -164,6 +161,9 @@ Result mainLoop() WriteToLog("Interface state was changed"); eventClear(usbHsGetInterfaceStateChangeEvent()); + UsbHsInterface interfaces[4]; + s32 total_entries; + rc = usbHsQueryAcquiredInterfaces(interfaces, sizeof(interfaces), &total_entries); if (R_SUCCEEDED(rc)) {