diff --git a/exports.def b/exports.def index c3f8976..b0bf8c8 100644 --- a/exports.def +++ b/exports.def @@ -2,6 +2,7 @@ EXPORTS AddControllerChanged=?AddControllerChanged@WindowsGamingInput@@YAXP6AXW4EventType@1@W4ControllerType@1@V?$variant@_KV?$basic_string_view@_WU?$char_traits@_W@std@@@std@@@std@@@Z@Z RemoveControllerChanged=?RemoveControllerChanged@WindowsGamingInput@@YAXP6AXW4EventType@1@W4ControllerType@1@V?$variant@_KV?$basic_string_view@_WU?$char_traits@_W@std@@@std@@@std@@@Z@Z + Gamepad_IsInitialized=?IsInitialized@Gamepad@WindowsGamingInput@@YA_NXZ Gamepad_GetCount=?GetCount@Gamepad@WindowsGamingInput@@YA_KXZ Gamepad_IsConnected=?IsConnected@Gamepad@WindowsGamingInput@@YA_N_K@Z Gamepad_IsWireless=?IsWireless@Gamepad@WindowsGamingInput@@YA_N_KAEA_N@Z @@ -10,6 +11,7 @@ EXPORTS Gamepad_GetVibration=?GetVibration@Gamepad@WindowsGamingInput@@YA_N_KAEAUVibration@2@@Z Gamepad_SetVibration=?SetVibration@Gamepad@WindowsGamingInput@@YA_N_KAEBUVibration@2@@Z + RawGameController_IsInitialized=?IsInitialized@RawGameController@WindowsGamingInput@@YA_NXZ RawGameController_GetCount=?GetCount@RawGameController@WindowsGamingInput@@YA_KXZ RawGameController_GetControllers=?GetControllers@RawGameController@WindowsGamingInput@@YA_KPEAUDescription@RawController@2@_K@Z RawGameController_GetController=?GetController@RawGameController@WindowsGamingInput@@YA_NV?$basic_string_view@_WU?$char_traits@_W@std@@@std@@AEAUDescription@RawController@2@@Z diff --git a/include/WindowsGamingInput.h b/include/WindowsGamingInput.h index 09dcbf2..51e94b7 100644 --- a/include/WindowsGamingInput.h +++ b/include/WindowsGamingInput.h @@ -183,6 +183,7 @@ namespace WindowsGamingInput namespace Gamepad { + DLLEXPORT bool IsInitialized(); DLLEXPORT size_t GetCount(); DLLEXPORT bool IsConnected(size_t index); DLLEXPORT bool GetState(size_t index, GamepadState& state); @@ -206,6 +207,7 @@ namespace WindowsGamingInput size_t axis_count; }; // + DLLEXPORT bool IsInitialized(); DLLEXPORT size_t GetCount(); DLLEXPORT size_t GetControllers(Description* controllers, size_t count); DLLEXPORT bool GetController(std::wstring_view uid, Description& description); diff --git a/src/WindowsGamingInput.cpp b/src/WindowsGamingInput.cpp index 01dbee6..7fbbedd 100644 --- a/src/WindowsGamingInput.cpp +++ b/src/WindowsGamingInput.cpp @@ -71,7 +71,7 @@ void ScanGamepads() } } -EventRegistrationToken g_add_gamepad_token; +EventRegistrationToken g_add_gamepad_token{}; HRESULT OnGamepadAdded(IInspectable* sender, IGamepad* gamepad) { #ifdef _DEBUG @@ -120,7 +120,7 @@ HRESULT OnGamepadAdded(IInspectable* sender, IGamepad* gamepad) return S_OK; } -EventRegistrationToken g_remove_gamepad_token; +EventRegistrationToken g_remove_gamepad_token{}; HRESULT OnGamepadRemoved(IInspectable* sender, IGamepad* gamepad) { #ifdef _DEBUG @@ -226,7 +226,7 @@ void ScanRawGameControllers() } } -EventRegistrationToken g_add_rcontroller_token; +EventRegistrationToken g_add_rcontroller_token{}; HRESULT OnRawGameControllerAdded(IInspectable* sender, IRawGameController* controller) { @@ -264,7 +264,7 @@ HRESULT OnRawGameControllerAdded(IInspectable* sender, IRawGameController* contr return S_OK; } -EventRegistrationToken g_remove_rcontroller_token; +EventRegistrationToken g_remove_rcontroller_token{}; HRESULT OnRawGameControllerRemoved(IInspectable* sender, IRawGameController* controller) { @@ -311,48 +311,66 @@ BOOL WINAPI DllMain(HINSTANCE hinstance, DWORD reason, LPVOID reserved) { auto hr = RoGetActivationFactory(HStringReference(L"Windows.Gaming.Input.Gamepad").Get(), __uuidof(IGamepadStatics), (void**)&g_gamepad_statics); - assert(SUCCEEDED(hr)); + if (SUCCEEDED(hr) && g_gamepad_statics) + { - hr = g_gamepad_statics->add_GamepadAdded( - Callback<__FIEventHandler_1_Windows__CGaming__CInput__CGamepad>(OnGamepadAdded).Get(), - &g_add_gamepad_token); - assert(SUCCEEDED(hr)); + hr = g_gamepad_statics->add_GamepadAdded( + Callback<__FIEventHandler_1_Windows__CGaming__CInput__CGamepad>(OnGamepadAdded).Get(), + &g_add_gamepad_token); + assert(SUCCEEDED(hr)); - hr = g_gamepad_statics->add_GamepadRemoved( - Callback<__FIEventHandler_1_Windows__CGaming__CInput__CGamepad>(OnGamepadRemoved).Get(), - &g_remove_gamepad_token); - assert(SUCCEEDED(hr)); + hr = g_gamepad_statics->add_GamepadRemoved( + Callback<__FIEventHandler_1_Windows__CGaming__CInput__CGamepad>(OnGamepadRemoved).Get(), + &g_remove_gamepad_token); + assert(SUCCEEDED(hr)); #ifdef _DEBUG - std::cout << "Windows.Gaming.Input.Gamepad initialized" << std::endl; + std::cout << "Windows.Gaming.Input.Gamepad initialized" << std::endl; #endif + } + else + { +#ifdef _DEBUG + std::cout << "Windows.Gaming.Input.Gamepad init failed: 0x" << std::hex << (uintptr_t)hr << std::endl; +#endif + } } - - ScanGamepads(); + + if(g_gamepad_statics) + ScanGamepads(); if (!g_rcontroller_statics) { auto hr = RoGetActivationFactory(HStringReference(L"Windows.Gaming.Input.RawGameController").Get(), __uuidof(IRawGameControllerStatics), (void**)&g_rcontroller_statics); - assert(SUCCEEDED(hr)); + if (SUCCEEDED(hr) && g_rcontroller_statics) + { + hr = g_rcontroller_statics->add_RawGameControllerAdded( + Callback<__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController>(OnRawGameControllerAdded). + Get(), + &g_add_rcontroller_token); + assert(SUCCEEDED(hr)); - hr = g_rcontroller_statics->add_RawGameControllerAdded( - Callback<__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController>(OnRawGameControllerAdded). - Get(), - &g_add_rcontroller_token); - assert(SUCCEEDED(hr)); - - hr = g_rcontroller_statics->add_RawGameControllerRemoved( - Callback<__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController>( - OnRawGameControllerRemoved).Get(), - &g_remove_rcontroller_token); - assert(SUCCEEDED(hr)); + hr = g_rcontroller_statics->add_RawGameControllerRemoved( + Callback<__FIEventHandler_1_Windows__CGaming__CInput__CRawGameController>( + OnRawGameControllerRemoved).Get(), + &g_remove_rcontroller_token); + assert(SUCCEEDED(hr)); #ifdef _DEBUG - std::cout << "Windows.Gaming.Input.RawGameController initialized" << std::endl; + std::cout << "Windows.Gaming.Input.RawGameController initialized" << std::endl; #endif + } + else + { +#ifdef _DEBUG + std::cout << "Windows.Gaming.Input.RawGameController init failed: 0x" << std::hex << (uintptr_t)hr << std::endl; +#endif + } } - ScanRawGameControllers(); + + if(g_rcontroller_statics) + ScanRawGameControllers(); }).detach(); } else if (reason == DLL_PROCESS_DETACH) @@ -369,8 +387,11 @@ BOOL WINAPI DllMain(HINSTANCE hinstance, DWORD reason, LPVOID reserved) g_gamepads.clear(); if (g_gamepad_statics) { - g_gamepad_statics->remove_GamepadAdded(g_add_rcontroller_token); - g_gamepad_statics->remove_GamepadRemoved(g_remove_rcontroller_token); + if(g_add_gamepad_token.value) + g_gamepad_statics->remove_GamepadAdded(g_add_gamepad_token); + + if(g_remove_gamepad_token.value) + g_gamepad_statics->remove_GamepadRemoved(g_remove_gamepad_token); } } @@ -381,8 +402,11 @@ BOOL WINAPI DllMain(HINSTANCE hinstance, DWORD reason, LPVOID reserved) g_rcontrollers.clear(); if (g_rcontroller_statics) { - g_rcontroller_statics->remove_RawGameControllerAdded(g_add_rcontroller_token); - g_rcontroller_statics->remove_RawGameControllerRemoved(g_remove_rcontroller_token); + if(g_add_rcontroller_token.value) + g_rcontroller_statics->remove_RawGameControllerAdded(g_add_rcontroller_token); + + if(g_remove_rcontroller_token.value) + g_rcontroller_statics->remove_RawGameControllerRemoved(g_remove_rcontroller_token); } } } @@ -405,7 +429,7 @@ namespace WindowsGamingInput const auto rm = std::ranges::remove(g_callbacks, cb); g_callbacks.erase(rm.begin(), rm.end()); } - + bool GetBatteryInfo(ComPtr battery_info, BatteryStatus& status, double& battery) { ComPtr report; @@ -441,6 +465,11 @@ namespace WindowsGamingInput namespace Gamepad { + bool IsInitialized() + { + return g_gamepad_statics != nullptr; + } + size_t GetCount() { std::shared_lock lock(g_gamepad_mutex); @@ -544,6 +573,11 @@ namespace WindowsGamingInput namespace RawGameController { + bool IsInitialized() + { + return g_rcontroller_statics != nullptr; + } + size_t GetCount() { std::shared_lock lock(g_rcontroller_mutex);