diff --git a/SwitchUSB/include/SwitchHDLHandler.h b/SwitchUSB/include/SwitchHDLHandler.h index 769344c..b6a5d2d 100644 --- a/SwitchUSB/include/SwitchHDLHandler.h +++ b/SwitchUSB/include/SwitchHDLHandler.h @@ -10,7 +10,6 @@ class SwitchHDLHandler : public SwitchVirtualGamepadHandler { private: - u32 m_vibrationDeviceHandle; u64 m_hdlHandle; HiddbgHdlsDeviceInfo m_deviceInfo; HiddbgHdlsState m_hdlState; @@ -37,6 +36,4 @@ public: void FillHdlState(const NormalizedButtonData &data); //Passes the HDL state to HID so that it could register the inputs Result UpdateHdlState(); - - inline u32 *GetVibrationHandle() { return &m_vibrationDeviceHandle; } }; \ No newline at end of file diff --git a/SwitchUSB/include/SwitchVirtualGamepadHandler.h b/SwitchUSB/include/SwitchVirtualGamepadHandler.h index 620720f..dfa9821 100644 --- a/SwitchUSB/include/SwitchVirtualGamepadHandler.h +++ b/SwitchUSB/include/SwitchVirtualGamepadHandler.h @@ -8,6 +8,7 @@ class SwitchVirtualGamepadHandler { protected: + u32 m_vibrationDeviceHandle; SwitchControllerHandler m_controllerHandler; bool m_keepInputThreadRunning; @@ -49,4 +50,5 @@ public: //Get the raw controller handler pointer inline SwitchControllerHandler *GetControllerHandler() { return &m_controllerHandler; } inline IController *GetController() { return m_controllerHandler.GetController(); } + inline u32 *GetVibrationHandle() { return &m_vibrationDeviceHandle; } }; \ No newline at end of file diff --git a/SwitchUSB/source/SwitchAbstractedPadHandler.cpp b/SwitchUSB/source/SwitchAbstractedPadHandler.cpp index ce0d64c..385e6c0 100644 --- a/SwitchUSB/source/SwitchAbstractedPadHandler.cpp +++ b/SwitchUSB/source/SwitchAbstractedPadHandler.cpp @@ -1,6 +1,7 @@ #include "SwitchAbstractedPadHandler.h" #include #include +#include "../../source/log.h" SwitchAbstractedPadHandler::SwitchAbstractedPadHandler(std::unique_ptr &&controller) : SwitchVirtualGamepadHandler(std::move(controller)) @@ -18,10 +19,37 @@ Result SwitchAbstractedPadHandler::Initialize() if (R_FAILED(rc)) return rc; + hidScanInput(); + HidControllerID lastOfflineID; + for (int i = 0; i != 8; ++i) + { + if (!hidIsControllerConnected(static_cast(i))) + { + lastOfflineID = static_cast(i); + break; + } + } + WriteToLog("Found last offline ID: ", lastOfflineID); + rc = InitAbstractedPadState(); if (R_FAILED(rc)) return rc; + svcSleepThread(1e+7L); + hidScanInput(); + + WriteToLog("Is last offline id connected? ", hidIsControllerConnected(lastOfflineID)); + WriteToLog("Last offline id type: ", hidGetControllerType(lastOfflineID)); + + Result rc2 = hidInitializeVibrationDevices(&m_vibrationDeviceHandle, 1, lastOfflineID, hidGetControllerType(lastOfflineID)); + if (R_SUCCEEDED(rc2)) + { + WriteToLog("Initializing vibration device with handle ", m_vibrationDeviceHandle); + InitOutputThread(); + } + else + WriteToLog("Failed to iniitalize vibration with error ", rc2); + InitInputThread(); return rc; } @@ -31,7 +59,7 @@ void SwitchAbstractedPadHandler::Exit() ExitAbstractedPadState(); m_controllerHandler.Exit(); ExitInputThread(); - //ExitRumbleThread(); + ExitOutputThread(); } //Used to give out unique ids to abstracted pads @@ -129,5 +157,13 @@ void SwitchAbstractedPadHandler::UpdateInput() void SwitchAbstractedPadHandler::UpdateOutput() { + Result rc; + HidVibrationValue value; + rc = hidGetActualVibrationValue(&m_vibrationDeviceHandle, &value); + if (R_FAILED(rc)) + return; + + rc = GetController()->SetRumble(static_cast(value.amp_high * 255.0f), static_cast(value.amp_low * 255.0f)); + svcSleepThread(1e+7L); } \ No newline at end of file diff --git a/SwitchUSB/source/SwitchHDLHandler.cpp b/SwitchUSB/source/SwitchHDLHandler.cpp index 0f4600b..9d8bd62 100644 --- a/SwitchUSB/source/SwitchHDLHandler.cpp +++ b/SwitchUSB/source/SwitchHDLHandler.cpp @@ -1,5 +1,6 @@ #include "SwitchHDLHandler.h" #include +#include "../../source/log.h" SwitchHDLHandler::SwitchHDLHandler(std::unique_ptr &&controller) : SwitchVirtualGamepadHandler(std::move(controller)) @@ -17,16 +18,39 @@ Result SwitchHDLHandler::Initialize() if (R_FAILED(rc)) return rc; + hidScanInput(); + HidControllerID lastOfflineID; + for (int i = 0; i != 8; ++i) + { + if (!hidIsControllerConnected(static_cast(i))) + { + lastOfflineID = static_cast(i); + break; + } + } + WriteToLog("Found last offline ID: ", lastOfflineID); + rc = InitHdlState(); if (R_FAILED(rc)) return rc; - if (R_SUCCEEDED(hidInitializeVibrationDevices(&m_vibrationDeviceHandle, 1, CONTROLLER_PLAYER_2, static_cast(TYPE_PROCONTROLLER | TYPE_SYSTEM_EXT)))) + svcSleepThread(1e+7L); + hidScanInput(); + + WriteToLog("Is last offline id connected? ", hidIsControllerConnected(lastOfflineID)); + WriteToLog("Last offline id type: ", hidGetControllerType(lastOfflineID)); + + Result rc2 = hidInitializeVibrationDevices(&m_vibrationDeviceHandle, 1, lastOfflineID, hidGetControllerType(lastOfflineID)); + if (R_SUCCEEDED(rc2)) { + WriteToLog("Initializing vibration device with handle ", m_vibrationDeviceHandle); InitOutputThread(); } + else + WriteToLog("Failed to iniitalize vibration with error ", rc2); InitInputThread(); + return rc; } @@ -45,7 +69,7 @@ Result SwitchHDLHandler::InitHdlState() m_hdlState = {0}; // Set the controller type to Pro-Controller, and set the npadInterfaceType. - m_deviceInfo.deviceType = HidDeviceType_FullKey3; + m_deviceInfo.deviceType = HidDeviceType_FullKey15; m_deviceInfo.npadInterfaceType = NpadInterfaceType_USB; // Set the controller colors. The grip colors are for Pro-Controller on [9.0.0+]. m_deviceInfo.singleColorBody = RGBA8_MAXALPHA(107, 107, 107); diff --git a/source/main.cpp b/source/main.cpp index 1ea082a..1856a6d 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -61,10 +61,19 @@ extern "C" rc = usbCommsInitialize(); if (R_FAILED(rc)) fatalThrow(rc); + +#ifndef __APPLET__ + rc = hidInitialize(); + if (R_FAILED(rc)) + fatalThrow(rc); +#endif } void __attribute__((weak)) userAppExit(void) { +#ifndef __APPLET__ + hidExit(); +#endif usbCommsExit(); usbHsExit(); hiddbgReleaseHdlsWorkBuffer(); diff --git a/source/mainLoop.cpp b/source/mainLoop.cpp index b70bcbc..49b92f0 100644 --- a/source/mainLoop.cpp +++ b/source/mainLoop.cpp @@ -20,6 +20,8 @@ Result mainLoop() s32 total_entries; std::vector vendors = GetVendors(); bool useAbstractedPad = hosversionBetween(5, 7); + hidPermitVibration(false); + hidPermitVibration(true); VendorEvent events[vendors.size()]; std::vector> controllerInterfaces; @@ -50,6 +52,45 @@ Result mainLoop() #ifdef __APPLET__ hidScanInput(); u64 kDown = hidKeysDown(CONTROLLER_P1_AUTO); + + if (kDown & KEY_Y) + { + for (int i = 0; i != 8; ++i) + { + bool isConnected = hidIsControllerConnected(static_cast(i)); + WriteToLog("Is controller ", i, " connected: ", isConnected); + if (isConnected) + { + HidControllerType type = hidGetControllerType(static_cast(i)); + WriteToLog("Controller ", i, " type: ", type); + } + } + } + + if (kDown & KEY_X) + { + WriteToLog("Sending rumble to all controllers\n"); + for (auto &&con : controllerInterfaces) + { + u32 *vibrationHandle = con->GetVibrationHandle(); + bool flag; + Result rc = hidIsVibrationDeviceMounted(vibrationHandle, &flag); + if (R_SUCCEEDED(rc)) + { + WriteToLog("Is vibration device mounted: ", flag); + HidVibrationValue value; + value.amp_high = 0.5f; + value.amp_low = 0.5f; + value.freq_high = 320.0f; + value.freq_low = 160.0f; + rc = hidSendVibrationValue(vibrationHandle, &value); + WriteToLog("SendVirationValue result: ", rc); + } + else + WriteToLog("failed to check for vibration device"); + } + } + if (kDown & KEY_B) break; #endif