mirror of
https://github.com/WinDurango/WinDurango.git
synced 2025-12-30 23:49:46 -06:00
352 lines
13 KiB
C++
352 lines
13 KiB
C++
#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 <winrt/Windows.Foundation.Collections.h>
|
|
#include <winrt/Windows.Foundation.h>
|
|
#include <winrt/Windows.UI.Input.h>
|
|
#include <windowsx.h>
|
|
#include <Xinput.h>
|
|
#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<winrt::Windows::Xbox::Input::IGamepad> Gamepad::Gamepads()
|
|
{
|
|
if (staticGamepads == Foundation::Collections::IVector<winrt::Windows::Xbox::Input::IGamepad>(nullptr) || staticGamepads.Size() == 0) {
|
|
staticGamepads = winrt::single_threaded_vector<Input::IGamepad>();
|
|
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>(gamepad);
|
|
staticGamepads.Append(newGamepad);
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (staticGamepads.Size() == 0) {
|
|
wprintf(L"Gamepad || No Gamepads Found!\n");
|
|
IGamepad dummyGamepad = winrt::make<Gamepad>(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, winrt::Windows::UI::Core::PointerEventArgs>(
|
|
[&](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<winrt::Windows::Xbox::Input::GamepadAddedEventArgs> 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<winrt::Windows::Xbox::Input::GamepadRemovedEventArgs> 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<winrt::Windows::Xbox::Input::NavigationController, winrt::Windows::Xbox::Input::INavigationReadingChangedEventArgs> 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<WORD>(value.LeftMotorLevel * 65535);
|
|
vibration.wRightMotorSpeed = static_cast<WORD>(value.RightMotorLevel * 65535);
|
|
XInputSetState(m_id, &vibration);
|
|
}
|
|
|
|
winrt::Windows::Xbox::Input::IGamepadReading Gamepad::GetCurrentReading()
|
|
{
|
|
return winrt::make<implementation::GamepadReading>(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<winrt::Windows::Xbox::Input::Gamepad, winrt::Windows::Xbox::Input::IGamepadReadingChangedEventArgs> 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;
|
|
}
|
|
} |