#include "pch.h" #include "Windows.h" #include "Windows.Xbox.Input.GamepadReading.h" #include "Windows.Xbox.Input.Gamepad.h" #include "Windows.Xbox.Input.Gamepad.g.cpp" #include #include #include #include #include #include "Windows.Xbox.System.User.h" #include "../WinDurangoConfig.h" namespace winrt::Windows::Xbox::Input::implementation { int Gamepad::currNeed = 0; bool Gamepad::isMC = false; winrt::Windows::Foundation::Collections::IVectorView Gamepad::Gamepads() { if (staticGamepads == Foundation::Collections::IVector(nullptr) || staticGamepads.Size() == 0) { staticGamepads = winrt::single_threaded_vector(); LOG_INFO_W(L"Gamepad || Gamepads Queried!\n"); for (DWORD gamepad = 0; gamepad < XUSER_MAX_COUNT; gamepad++) { XINPUT_CAPABILITIES capabilities; if (XInputGetCapabilities(gamepad, XINPUT_FLAG_GAMEPAD, &capabilities) == ERROR_SUCCESS) { wprintf(L"Gamepad || Gamepad %d Created!\n", gamepad); IGamepad newGamepad = winrt::make(gamepad); staticGamepads.Append(newGamepad); continue; } } } if (staticGamepads.Size() == 0) { wprintf(L"Gamepad || No Gamepads Found!\n"); IGamepad dummyGamepad = winrt::make(0); staticGamepads.Append(dummyGamepad); } HWND hwnd = GetFocus(); ShowCursor(FALSE); RECT rc; GetClientRect(hwnd, &rc); POINT tl = { rc.left, rc.top }; POINT br = { rc.right, rc.bottom }; MapWindowPoints(hwnd, nullptr, &tl, 1); MapWindowPoints(hwnd, nullptr, &br, 1); RECT screenRect = { tl.x, tl.y, br.x, br.y }; ClipCursor(&screenRect); ShowCursor(FALSE); if (isMC) { auto window = winrt::Windows::UI::Core::CoreWindow::GetForCurrentThread(); window.PointerWheelChanged( winrt::Windows::Foundation::TypedEventHandler( [&](winrt::Windows::UI::Core::CoreWindow const&, winrt::Windows::UI::Core::PointerEventArgs const& args) { auto delta = args.CurrentPoint().Properties().MouseWheelDelta(); int scrollUnits = delta / 120.0f; Gamepad::currNeed += scrollUnits; LOG_INFO_W((L"Wheel delta: " + std::to_wstring(scrollUnits) + L"\n").c_str()); } ) ); } return staticGamepads.GetView(); } winrt::event_token Gamepad::GamepadAdded(winrt::Windows::Foundation::EventHandler const& handler) { LOG_INFO_W(L"Gamepad || Gamepad Added!\n"); LOG_WARNING("Gamepad || GamepadAdded event is not implemented, returning empty token."); return {}; } void Gamepad::GamepadAdded(winrt::event_token const& token) noexcept { LOG_INFO_W(L"Gamepad || Gamepad Added!\n"); LOG_NOT_IMPLEMENTED(); throw hresult_not_implemented(); } winrt::event_token Gamepad::GamepadRemoved(winrt::Windows::Foundation::EventHandler const& handler) { LOG_INFO_W(L"Gamepad || Gamepad Removed!\n"); LOG_NOT_IMPLEMENTED(); return {}; } void Gamepad::GamepadRemoved(winrt::event_token const& token) noexcept { LOG_INFO_W(L"Gamepad || Gamepad Removed!\n"); LOG_NOT_IMPLEMENTED(); throw hresult_not_implemented(); } uint64_t Gamepad::Id() { LOG_INFO_W(L"Gamepad || Gamepad ID (%d) Queried!\n", m_id); return m_id; } hstring Gamepad::Type() { return L"Windows.Xbox.Input.Gamepad"; } winrt::Windows::Xbox::System::User Gamepad::User() { LOG_INFO_W(L"Gamepad || User Queried!\n"); return System::implementation::User::Users().GetAt(Id()); } winrt::Windows::Xbox::Input::INavigationReading Gamepad::GetNavigationReading() { LOG_NOT_IMPLEMENTED(); throw hresult_not_implemented(); } winrt::Windows::Xbox::Input::RawNavigationReading Gamepad::GetRawNavigationReading() { RawNavigationReading dummyNavigationReading = RawNavigationReading(); dummyNavigationReading.Timestamp = GetTickCount64(); dummyNavigationReading.Buttons |= NavigationButtons::Up; return dummyNavigationReading; } winrt::event_token Gamepad::NavigationReadingChanged(winrt::Windows::Foundation::TypedEventHandler const& handler) { LOG_NOT_IMPLEMENTED(); throw hresult_not_implemented(); } void Gamepad::NavigationReadingChanged(winrt::event_token const& token) noexcept { LOG_NOT_IMPLEMENTED(); throw hresult_not_implemented(); } void Gamepad::SetVibration(winrt::Windows::Xbox::Input::GamepadVibration const& value) { XINPUT_VIBRATION vibration; ZeroMemory(&vibration, sizeof(XINPUT_VIBRATION)); vibration.wLeftMotorSpeed = static_cast(value.LeftMotorLevel * 65535); vibration.wRightMotorSpeed = static_cast(value.RightMotorLevel * 65535); XInputSetState(m_id, &vibration); } winrt::Windows::Xbox::Input::IGamepadReading Gamepad::GetCurrentReading() { return winrt::make(GetRawCurrentReading()); } winrt::Windows::Xbox::Input::RawGamepadReading Gamepad::GetRawCurrentReading() { XINPUT_STATE xiState; ZeroMemory(&xiState, sizeof(XINPUT_STATE)); reading = {}; DWORD result = XInputGetState(m_id, &xiState); if (result == ERROR_SUCCESS) { // Debug logging - remove after testing if (xiState.Gamepad.wButtons != 0) { LOG_INFO_W(L"Gamepad || Controller %d - Button mask: 0x%04X\n", m_id, xiState.Gamepad.wButtons); } for (int i = 0; i < ARRAYSIZE(gamepadButtons); i++) { if (xiState.Gamepad.wButtons & gamepadButtons[ i ].first) { reading.Buttons |= gamepadButtons[ i ].second; // Debug: Log when Start button is detected if (gamepadButtons[ i ].first == XINPUT_GAMEPAD_START) { LOG_INFO_W(L"Gamepad || START BUTTON DETECTED!\n"); } } } reading.LeftTrigger = xiState.Gamepad.bLeftTrigger / 255.f; reading.RightTrigger = xiState.Gamepad.bRightTrigger / 255.f; reading.LeftThumbstickX = xiState.Gamepad.sThumbLX / 32768.f; reading.LeftThumbstickY = xiState.Gamepad.sThumbLY / 32768.f; reading.RightThumbstickX = xiState.Gamepad.sThumbRX / 32768.f; reading.RightThumbstickY = xiState.Gamepad.sThumbRY / 32768.f; } else { LOG_WARNING_W(L"Gamepad || XInputGetState failed for controller %d with error: %d\n", m_id, result); } float lx = 0.0f; float ly = 0.0f; for (int i = 0; i < ARRAYSIZE(keyboardButtons); i++) { if (GetAsyncKeyState(keyboardButtons[ i ].first)) { reading.Buttons |= keyboardButtons[ i ].second; if (keyboardButtons[i].first == 'V') { //menuOpened = true; } else if (keyboardButtons[i].first == 'X') { //menuOpened = false; } } if (GetAsyncKeyState(wdcfg.GetData().MovementThumbY) & 0x8000) { ly = 1.0f; } if (GetAsyncKeyState(wdcfg.GetData().MovementThumbXM) & 0x8000) { lx = -1.0f; } if (GetAsyncKeyState(wdcfg.GetData().MovementThumbYM) & 0x8000) { ly = -1.0f; } if (GetAsyncKeyState(wdcfg.GetData().MovementThumbX) & 0x8000) { lx = 1.0f; } } lx = std::clamp(lx, -1.0f, 1.0f); ly = std::clamp(ly, -1.0f, 1.0f); if (lx != 0.0f || ly != 0.0f) { if (wdcfg.GetData().MovementStick == "Left") { reading.LeftThumbstickX = lx; reading.LeftThumbstickY = ly; } else if (wdcfg.GetData().MovementStick == "Right") { reading.RightThumbstickX = lx; reading.RightThumbstickY = ly; } } if (menuOpened && wdcfg.GetData().game == WinDurangoConfigData::Game::Minecraft) { if (GetAsyncKeyState(wdcfg.GetData().RTrigger) & 0x8000) { reading.Buttons |= keyboardButtons[VK_SPACE].second; } if (GetAsyncKeyState(wdcfg.GetData().LTrigger) & 0x8000) { reading.Buttons |= keyboardButtons['V'].second; } } else { if (GetAsyncKeyState(wdcfg.GetData().RTrigger) & 0x8000) { reading.RightTrigger = 1.0f; } if (GetAsyncKeyState(wdcfg.GetData().LTrigger) & 0x8000) { reading.LeftTrigger = 1.0f; } } /* * Mouse Input */ POINT pos; GetCursorPos(&pos); if (firstFrame) { prev = pos; firstFrame = false; } int dx = pos.x - prev.x; int dy = pos.y - prev.y; deltasumX += dx; deltasumY += dy; prev = pos; int centerX = GetSystemMetrics(SM_CXSCREEN) / 2; int centerY = GetSystemMetrics(SM_CYSCREEN) / 2; SetCursorPos(centerX, centerY); prev.x = centerX; prev.y = centerY; auto sign = [](float v) { return (v > 0) - (v < 0); }; float x = -std::exp((-1.0f / 5.0f) * std::abs(deltasumX)) + 1.0f; float y = -std::exp((-1.0f / 5.0f) * std::abs(deltasumY)) + 1.0f; x *= sign(deltasumX); y *= -sign(deltasumY); if (x != 0 || y != 0) { if (menuOpened && wdcfg.GetData().game == WinDurangoConfigData::Game::Minecraft) { if (wdcfg.GetData().MouseStick == "Right") { reading.LeftThumbstickX = std::clamp(x, -1.0f, 1.0f); reading.LeftThumbstickY = std::clamp(y, -1.0f, 1.0f); } else if (wdcfg.GetData().MouseStick == "Left") { reading.RightThumbstickX = std::clamp(x, -1.0f, 1.0f); reading.RightThumbstickY = std::clamp(y, -1.0f, 1.0f); } } else { if (wdcfg.GetData().MouseStick == "Right") { reading.RightThumbstickX = std::clamp(x, -1.0f, 1.0f); reading.RightThumbstickY = std::clamp(y, -1.0f, 1.0f); } else if (wdcfg.GetData().MouseStick == "Left") { reading.LeftThumbstickX = std::clamp(x, -1.0f, 1.0f); reading.LeftThumbstickY = std::clamp(y, -1.0f, 1.0f); } } } deltasumX = 0.0f; deltasumY = 0.0f; if (currNeed != 0) { if (!isCtrl) { isCtrl = true; if (currNeed > 0) { reading.Buttons |= GamepadButtons::RightShoulder; } else if (currNeed < 0) { reading.Buttons |= GamepadButtons::LeftShoulder; } } else { isCtrl = false; if (currNeed > 0) { currNeed--; } else if (currNeed < 0) { currNeed++; } } } return reading; } winrt::event_token Gamepad::ReadingChanged(winrt::Windows::Foundation::TypedEventHandler const& handler) { LOG_NOT_IMPLEMENTED(); throw hresult_not_implemented(); } void Gamepad::ReadingChanged(winrt::event_token const& token) noexcept { LOG_NOT_IMPLEMENTED(); throw hresult_not_implemented(); } bool Gamepad::IsTrusted() { return true; } }