diff --git a/Minecraft.Client/Minecraft.Client.vcxproj b/Minecraft.Client/Minecraft.Client.vcxproj
index 85d1718c..900d8c1f 100644
--- a/Minecraft.Client/Minecraft.Client.vcxproj
+++ b/Minecraft.Client/Minecraft.Client.vcxproj
@@ -28784,6 +28784,50 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CUtrue
true
+
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ false
+ false
+ false
+ false
+ false
+ false
+ false
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+ true
+
true
true
diff --git a/Minecraft.Client/Windows64/KBMInput.cpp b/Minecraft.Client/Windows64/KBMInput.cpp
new file mode 100644
index 00000000..daad5063
--- /dev/null
+++ b/Minecraft.Client/Windows64/KBMInput.cpp
@@ -0,0 +1,429 @@
+#include "stdafx.h"
+
+
+#include "KBMInput.h"
+#include
+
+KeyboardMouseInput g_KBMInput;
+
+extern HWND g_hWnd;
+
+// Forward declaration
+static void ClipCursorToWindow(HWND hWnd);
+
+static bool IsModifierKeyDown(const bool* keyState, int vkCode)
+{
+ switch (vkCode)
+ {
+ case VK_SHIFT:
+ return keyState[VK_LSHIFT] || keyState[VK_RSHIFT];
+ case VK_CONTROL:
+ return keyState[VK_LCONTROL] || keyState[VK_RCONTROL];
+ case VK_MENU:
+ return keyState[VK_LMENU] || keyState[VK_RMENU];
+ default:
+ return false;
+ }
+}
+
+void KeyboardMouseInput::Init()
+{
+ memset(m_keyDown, 0, sizeof(m_keyDown));
+ memset(m_keyDownPrev, 0, sizeof(m_keyDownPrev));
+ memset(m_keyPressedAccum, 0, sizeof(m_keyPressedAccum));
+ memset(m_keyReleasedAccum, 0, sizeof(m_keyReleasedAccum));
+ memset(m_keyPressed, 0, sizeof(m_keyPressed));
+ memset(m_keyReleased, 0, sizeof(m_keyReleased));
+ memset(m_mouseButtonDown, 0, sizeof(m_mouseButtonDown));
+ memset(m_mouseButtonDownPrev, 0, sizeof(m_mouseButtonDownPrev));
+ memset(m_mouseBtnPressedAccum, 0, sizeof(m_mouseBtnPressedAccum));
+ memset(m_mouseBtnReleasedAccum, 0, sizeof(m_mouseBtnReleasedAccum));
+ memset(m_mouseBtnPressed, 0, sizeof(m_mouseBtnPressed));
+ memset(m_mouseBtnReleased, 0, sizeof(m_mouseBtnReleased));
+ m_mouseX = 0;
+ m_mouseY = 0;
+ m_mouseDeltaX = 0;
+ m_mouseDeltaY = 0;
+ m_mouseDeltaAccumX = 0;
+ m_mouseDeltaAccumY = 0;
+ m_mouseWheelAccum = 0;
+ m_mouseWheelConsumed = false;
+ m_mouseGrabbed = false;
+ m_cursorHiddenForUI = false;
+ m_windowFocused = true;
+ m_hasInput = false;
+ m_kbmActive = true;
+ m_screenWantsCursorHidden = false;
+ m_charBufferHead = 0;
+ m_charBufferTail = 0;
+
+ RAWINPUTDEVICE rid;
+ rid.usUsagePage = 0x01; // HID_USAGE_PAGE_GENERIC
+ rid.usUsage = 0x02; // HID_USAGE_GENERIC_MOUSE
+ rid.dwFlags = 0;
+ rid.hwndTarget = g_hWnd;
+ RegisterRawInputDevices(&rid, 1, sizeof(rid));
+}
+
+void KeyboardMouseInput::ClearAllState()
+{
+ memset(m_keyDown, 0, sizeof(m_keyDown));
+ memset(m_keyDownPrev, 0, sizeof(m_keyDownPrev));
+ memset(m_keyPressedAccum, 0, sizeof(m_keyPressedAccum));
+ memset(m_keyReleasedAccum, 0, sizeof(m_keyReleasedAccum));
+ memset(m_keyPressed, 0, sizeof(m_keyPressed));
+ memset(m_keyReleased, 0, sizeof(m_keyReleased));
+ memset(m_mouseButtonDown, 0, sizeof(m_mouseButtonDown));
+ memset(m_mouseButtonDownPrev, 0, sizeof(m_mouseButtonDownPrev));
+ memset(m_mouseBtnPressedAccum, 0, sizeof(m_mouseBtnPressedAccum));
+ memset(m_mouseBtnReleasedAccum, 0, sizeof(m_mouseBtnReleasedAccum));
+ memset(m_mouseBtnPressed, 0, sizeof(m_mouseBtnPressed));
+ memset(m_mouseBtnReleased, 0, sizeof(m_mouseBtnReleased));
+ m_mouseDeltaX = 0;
+ m_mouseDeltaY = 0;
+ m_mouseDeltaAccumX = 0;
+ m_mouseDeltaAccumY = 0;
+ m_mouseWheelAccum = 0;
+ m_mouseWheelConsumed = false;
+}
+
+void KeyboardMouseInput::Tick()
+{
+ memcpy(m_keyDownPrev, m_keyDown, sizeof(m_keyDown));
+ memcpy(m_mouseButtonDownPrev, m_mouseButtonDown, sizeof(m_mouseButtonDown));
+
+ memcpy(m_keyPressed, m_keyPressedAccum, sizeof(m_keyPressedAccum));
+ memcpy(m_keyReleased, m_keyReleasedAccum, sizeof(m_keyReleasedAccum));
+ memset(m_keyPressedAccum, 0, sizeof(m_keyPressedAccum));
+ memset(m_keyReleasedAccum, 0, sizeof(m_keyReleasedAccum));
+
+ memcpy(m_mouseBtnPressed, m_mouseBtnPressedAccum, sizeof(m_mouseBtnPressedAccum));
+ memcpy(m_mouseBtnReleased, m_mouseBtnReleasedAccum, sizeof(m_mouseBtnReleasedAccum));
+ memset(m_mouseBtnPressedAccum, 0, sizeof(m_mouseBtnPressedAccum));
+ memset(m_mouseBtnReleasedAccum, 0, sizeof(m_mouseBtnReleasedAccum));
+
+ m_mouseDeltaX = m_mouseDeltaAccumX;
+ m_mouseDeltaY = m_mouseDeltaAccumY;
+ m_mouseDeltaAccumX = 0;
+ m_mouseDeltaAccumY = 0;
+ m_mouseWheelConsumed = false;
+
+ m_hasInput = (m_mouseDeltaX != 0 || m_mouseDeltaY != 0 || m_mouseWheelAccum != 0);
+ if (!m_hasInput)
+ {
+ for (int i = 0; i < MAX_KEYS; i++)
+ {
+ if (m_keyDown[i]) { m_hasInput = true; break; }
+ }
+ }
+ if (!m_hasInput)
+ {
+ for (int i = 0; i < MAX_MOUSE_BUTTONS; i++)
+ {
+ if (m_mouseButtonDown[i]) { m_hasInput = true; break; }
+ }
+ }
+
+ if ((m_mouseGrabbed || m_cursorHiddenForUI) && m_windowFocused && g_hWnd)
+ {
+ RECT rc;
+ GetClientRect(g_hWnd, &rc);
+ POINT center;
+ center.x = (rc.right - rc.left) / 2;
+ center.y = (rc.bottom - rc.top) / 2;
+ ClientToScreen(g_hWnd, ¢er);
+ SetCursorPos(center.x, center.y);
+ }
+}
+
+void KeyboardMouseInput::OnKeyDown(int vkCode)
+{
+ if (vkCode >= 0 && vkCode < MAX_KEYS)
+ {
+ if (!m_keyDown[vkCode])
+ m_keyPressedAccum[vkCode] = true;
+ m_keyDown[vkCode] = true;
+ }
+}
+
+void KeyboardMouseInput::OnKeyUp(int vkCode)
+{
+ if (vkCode >= 0 && vkCode < MAX_KEYS)
+ {
+ if (m_keyDown[vkCode])
+ m_keyReleasedAccum[vkCode] = true;
+ m_keyDown[vkCode] = false;
+ }
+}
+
+void KeyboardMouseInput::OnMouseButtonDown(int button)
+{
+ if (button >= 0 && button < MAX_MOUSE_BUTTONS)
+ {
+ if (!m_mouseButtonDown[button])
+ m_mouseBtnPressedAccum[button] = true;
+ m_mouseButtonDown[button] = true;
+ }
+}
+
+void KeyboardMouseInput::OnMouseButtonUp(int button)
+{
+ if (button >= 0 && button < MAX_MOUSE_BUTTONS)
+ {
+ if (m_mouseButtonDown[button])
+ m_mouseBtnReleasedAccum[button] = true;
+ m_mouseButtonDown[button] = false;
+ }
+}
+
+void KeyboardMouseInput::OnMouseMove(int x, int y)
+{
+ m_mouseX = x;
+ m_mouseY = y;
+}
+
+void KeyboardMouseInput::OnMouseWheel(int delta)
+{
+ // Normalize from raw Windows delta (multiples of WHEEL_DELTA=120) to discrete notch counts
+ m_mouseWheelAccum += delta / WHEEL_DELTA;
+}
+
+int KeyboardMouseInput::GetMouseWheel()
+{
+ int val = m_mouseWheelAccum;
+ if (val != 0)
+ m_mouseWheelConsumed = true;
+ m_mouseWheelAccum = 0;
+ return val;
+}
+
+void KeyboardMouseInput::OnRawMouseDelta(int dx, int dy)
+{
+ m_mouseDeltaAccumX += dx;
+ m_mouseDeltaAccumY += dy;
+}
+
+bool KeyboardMouseInput::IsKeyDown(int vkCode) const
+{
+ if (vkCode == VK_SHIFT || vkCode == VK_CONTROL || vkCode == VK_MENU)
+ return IsModifierKeyDown(m_keyDown, vkCode);
+
+ if (vkCode >= 0 && vkCode < MAX_KEYS)
+ return m_keyDown[vkCode];
+ return false;
+}
+
+bool KeyboardMouseInput::IsKeyPressed(int vkCode) const
+{
+ if (vkCode == VK_SHIFT || vkCode == VK_CONTROL || vkCode == VK_MENU)
+ return IsModifierKeyDown(m_keyPressed, vkCode);
+
+ if (vkCode >= 0 && vkCode < MAX_KEYS)
+ return m_keyPressed[vkCode];
+ return false;
+}
+
+bool KeyboardMouseInput::IsKeyReleased(int vkCode) const
+{
+ if (vkCode == VK_SHIFT || vkCode == VK_CONTROL || vkCode == VK_MENU)
+ return IsModifierKeyDown(m_keyReleased, vkCode);
+
+ if (vkCode >= 0 && vkCode < MAX_KEYS)
+ return m_keyReleased[vkCode];
+ return false;
+}
+
+int KeyboardMouseInput::GetPressedKey() const
+{
+ for (int i = 0; i < MAX_KEYS; ++i)
+ if (m_keyPressed[i]) return i;
+ return 0;
+}
+
+bool KeyboardMouseInput::IsMouseButtonDown(int button) const
+{
+ if (button >= 0 && button < MAX_MOUSE_BUTTONS)
+ return m_mouseButtonDown[button];
+ return false;
+}
+
+bool KeyboardMouseInput::IsMouseButtonPressed(int button) const
+{
+ if (button >= 0 && button < MAX_MOUSE_BUTTONS)
+ return m_mouseBtnPressed[button];
+ return false;
+}
+
+bool KeyboardMouseInput::IsMouseButtonReleased(int button) const
+{
+ if (button >= 0 && button < MAX_MOUSE_BUTTONS)
+ return m_mouseBtnReleased[button];
+ return false;
+}
+
+void KeyboardMouseInput::ConsumeMouseDelta(float &dx, float &dy)
+{
+ dx = static_cast(m_mouseDeltaAccumX);
+ dy = static_cast(m_mouseDeltaAccumY);
+ m_mouseDeltaAccumX = 0;
+ m_mouseDeltaAccumY = 0;
+}
+
+void KeyboardMouseInput::SetMouseGrabbed(bool grabbed)
+{
+ if (m_mouseGrabbed == grabbed)
+ return;
+
+ m_mouseGrabbed = grabbed;
+ if (grabbed && g_hWnd)
+ {
+ while (ShowCursor(FALSE) >= 0) {}
+ ClipCursorToWindow(g_hWnd);
+
+ RECT rc;
+ GetClientRect(g_hWnd, &rc);
+ POINT center;
+ center.x = (rc.right - rc.left) / 2;
+ center.y = (rc.bottom - rc.top) / 2;
+ ClientToScreen(g_hWnd, ¢er);
+ SetCursorPos(center.x, center.y);
+
+ m_mouseDeltaAccumX = 0;
+ m_mouseDeltaAccumY = 0;
+ }
+ else if (!grabbed && !m_cursorHiddenForUI && g_hWnd)
+ {
+ while (ShowCursor(TRUE) < 0) {}
+ ClipCursor(nullptr);
+ }
+}
+
+void KeyboardMouseInput::SetCursorHiddenForUI(bool hidden)
+{
+ if (m_cursorHiddenForUI == hidden)
+ return;
+
+ m_cursorHiddenForUI = hidden;
+ if (hidden && g_hWnd)
+ {
+ while (ShowCursor(FALSE) >= 0) {}
+ ClipCursorToWindow(g_hWnd);
+
+ RECT rc;
+ GetClientRect(g_hWnd, &rc);
+ POINT center;
+ center.x = (rc.right - rc.left) / 2;
+ center.y = (rc.bottom - rc.top) / 2;
+ ClientToScreen(g_hWnd, ¢er);
+ SetCursorPos(center.x, center.y);
+
+ m_mouseDeltaAccumX = 0;
+ m_mouseDeltaAccumY = 0;
+ }
+ else if (!hidden && !m_mouseGrabbed && g_hWnd)
+ {
+ while (ShowCursor(TRUE) < 0) {}
+ ClipCursor(nullptr);
+ }
+}
+
+static void ClipCursorToWindow(HWND hWnd)
+{
+ if (!hWnd) return;
+ RECT rc;
+ GetClientRect(hWnd, &rc);
+ POINT topLeft = { rc.left, rc.top };
+ POINT bottomRight = { rc.right, rc.bottom };
+ ClientToScreen(hWnd, &topLeft);
+ ClientToScreen(hWnd, &bottomRight);
+ RECT clipRect = { topLeft.x, topLeft.y, bottomRight.x, bottomRight.y };
+ ClipCursor(&clipRect);
+}
+
+void KeyboardMouseInput::SetWindowFocused(bool focused)
+{
+ m_windowFocused = focused;
+ if (focused)
+ {
+ if (m_mouseGrabbed || m_cursorHiddenForUI)
+ {
+ while (ShowCursor(FALSE) >= 0) {}
+ ClipCursorToWindow(g_hWnd);
+ }
+ else
+ {
+ while (ShowCursor(TRUE) < 0) {}
+ ClipCursor(nullptr);
+ }
+ }
+ else
+ {
+ while (ShowCursor(TRUE) < 0) {}
+ ClipCursor(nullptr);
+ }
+}
+
+float KeyboardMouseInput::GetMoveX() const
+{
+ float x = 0.0f;
+ if (m_keyDown[KEY_LEFT]) x += 1.0f;
+ if (m_keyDown[KEY_RIGHT]) x -= 1.0f;
+ return x;
+}
+
+float KeyboardMouseInput::GetMoveY() const
+{
+ float y = 0.0f;
+ if (m_keyDown[KEY_FORWARD]) y += 1.0f;
+ if (m_keyDown[KEY_BACKWARD]) y -= 1.0f;
+ return y;
+}
+
+float KeyboardMouseInput::GetLookX(float sensitivity) const
+{
+ return static_cast(m_mouseDeltaX) * sensitivity;
+}
+
+float KeyboardMouseInput::GetLookY(float sensitivity) const
+{
+ return static_cast(-m_mouseDeltaY) * sensitivity;
+}
+
+void KeyboardMouseInput::SetCursorIcon(LPCWSTR cursorName)
+{
+ HCURSOR hCursor = LoadCursorW(nullptr, cursorName);
+ if (hCursor)
+ {
+ SetCursor(hCursor);
+
+ if (g_hWnd)
+ {
+ SetClassLongPtrW(g_hWnd, GCLP_HCURSOR, (LONG_PTR)hCursor);
+ }
+ }
+}
+
+void KeyboardMouseInput::OnChar(wchar_t c)
+{
+ int next = (m_charBufferHead + 1) % CHAR_BUFFER_SIZE;
+ if (next != m_charBufferTail)
+ {
+ m_charBuffer[m_charBufferHead] = c;
+ m_charBufferHead = next;
+ }
+}
+
+bool KeyboardMouseInput::ConsumeChar(wchar_t &outChar)
+{
+ if (m_charBufferTail == m_charBufferHead)
+ return false;
+ outChar = m_charBuffer[m_charBufferTail];
+ m_charBufferTail = (m_charBufferTail + 1) % CHAR_BUFFER_SIZE;
+ return true;
+}
+
+void KeyboardMouseInput::ClearCharBuffer()
+{
+ m_charBufferHead = 0;
+ m_charBufferTail = 0;
+}
diff --git a/Minecraft.Client/Windows64/KBMInput.h b/Minecraft.Client/Windows64/KBMInput.h
new file mode 100644
index 00000000..ec8343d3
--- /dev/null
+++ b/Minecraft.Client/Windows64/KBMInput.h
@@ -0,0 +1,153 @@
+#pragma once
+
+#include
+
+class KeyboardMouseInput
+{
+public:
+ static const int MAX_KEYS = 256;
+
+ static const int MOUSE_LEFT = 0;
+ static const int MOUSE_RIGHT = 1;
+ static const int MOUSE_MIDDLE = 2;
+ static const int MAX_MOUSE_BUTTONS = 3;
+
+ static const int KEY_FORWARD = 'W';
+ static const int KEY_BACKWARD = 'S';
+ static const int KEY_LEFT = 'A';
+ static const int KEY_RIGHT = 'D';
+ static const int KEY_JUMP = VK_SPACE;
+ static const int KEY_SNEAK = VK_LSHIFT;
+ static const int KEY_SPRINT = VK_CONTROL;
+ static const int KEY_INVENTORY = 'E';
+ static const int KEY_DROP = 'Q';
+ static const int KEY_CRAFTING = 'C';
+ static const int KEY_CRAFTING_ALT = 'R';
+ static const int KEY_CHAT = 'T';
+ static const int KEY_CONFIRM = VK_RETURN;
+ static const int KEY_CANCEL = VK_ESCAPE;
+ static const int KEY_PAUSE = VK_ESCAPE;
+ static const int KEY_TOGGLE_HUD = VK_F1;
+ static const int KEY_DEBUG_INFO = VK_F3;
+ static const int KEY_DEBUG_MENU = VK_F4;
+ static const int KEY_CONTROL = VK_CONTROL;
+ static const int KEY_THIRD_PERSON = VK_F5;
+ static const int KEY_DEBUG_CONSOLE = VK_F6;
+ static const int KEY_HOST_SETTINGS = VK_TAB;
+ static const int KEY_FULLSCREEN = VK_F11;
+ static const int KEY_SCREENSHOT = VK_F2;
+
+ void Init();
+ void Tick();
+ void ClearAllState();
+
+ void OnKeyDown(int vkCode);
+ void OnKeyUp(int vkCode);
+ void OnMouseButtonDown(int button);
+ void OnMouseButtonUp(int button);
+ void OnMouseMove(int x, int y);
+ void OnMouseWheel(int delta);
+ void OnRawMouseDelta(int dx, int dy);
+
+ bool IsKeyDown(int vkCode) const;
+ bool IsKeyPressed(int vkCode) const;
+ bool IsKeyReleased(int vkCode) const;
+
+ int GetPressedKey() const;
+
+ bool IsMouseButtonDown(int button) const;
+ bool IsMouseButtonPressed(int button) const;
+ bool IsMouseButtonReleased(int button) const;
+
+ int GetMouseX() const { return m_mouseX; }
+ int GetMouseY() const { return m_mouseY; }
+
+ int GetMouseDeltaX() const { return m_mouseDeltaX; }
+ int GetMouseDeltaY() const { return m_mouseDeltaY; }
+
+ int GetMouseWheel();
+ int PeekMouseWheel() const { return m_mouseWheelAccum; }
+ void ConsumeMouseWheel() { if (m_mouseWheelAccum != 0) m_mouseWheelConsumed = true; m_mouseWheelAccum = 0; }
+ bool WasMouseWheelConsumed() const { return m_mouseWheelConsumed; }
+
+ // Per-frame delta consumption for low-latency mouse look.
+ // Reads and clears the raw accumulators (not the per-tick snapshot).
+ void ConsumeMouseDelta(float &dx, float &dy);
+
+ void SetMouseGrabbed(bool grabbed);
+ bool IsMouseGrabbed() const { return m_mouseGrabbed; }
+
+ void SetCursorHiddenForUI(bool hidden);
+ bool IsCursorHiddenForUI() const { return m_cursorHiddenForUI; }
+
+ void SetWindowFocused(bool focused);
+ bool IsWindowFocused() const { return m_windowFocused; }
+
+ bool HasAnyInput() const { return m_hasInput; }
+
+ void SetKBMActive(bool active) { m_kbmActive = active; }
+ bool IsKBMActive() const { return m_kbmActive; }
+
+ void SetScreenCursorHidden(bool hidden) { m_screenWantsCursorHidden = hidden; }
+ bool IsScreenCursorHidden() const { return m_screenWantsCursorHidden; }
+
+ // Text input: buffer characters typed while the native keyboard scene is open
+ void OnChar(wchar_t c);
+ bool ConsumeChar(wchar_t &outChar);
+ void ClearCharBuffer();
+
+ float GetMoveX() const;
+ float GetMoveY() const;
+
+ float GetLookX(float sensitivity) const;
+ float GetLookY(float sensitivity) const;
+
+ void SetCursorIcon(LPCWSTR cursorName);
+
+private:
+ bool m_keyDown[MAX_KEYS];
+ bool m_keyDownPrev[MAX_KEYS];
+
+ bool m_keyPressedAccum[MAX_KEYS];
+ bool m_keyReleasedAccum[MAX_KEYS];
+ bool m_keyPressed[MAX_KEYS];
+ bool m_keyReleased[MAX_KEYS];
+
+ bool m_mouseButtonDown[MAX_MOUSE_BUTTONS];
+ bool m_mouseButtonDownPrev[MAX_MOUSE_BUTTONS];
+
+ bool m_mouseBtnPressedAccum[MAX_MOUSE_BUTTONS];
+ bool m_mouseBtnReleasedAccum[MAX_MOUSE_BUTTONS];
+ bool m_mouseBtnPressed[MAX_MOUSE_BUTTONS];
+ bool m_mouseBtnReleased[MAX_MOUSE_BUTTONS];
+
+ int m_mouseX;
+ int m_mouseY;
+
+ int m_mouseDeltaX;
+ int m_mouseDeltaY;
+ int m_mouseDeltaAccumX;
+ int m_mouseDeltaAccumY;
+
+ int m_mouseWheelAccum;
+ bool m_mouseWheelConsumed;
+
+ bool m_mouseGrabbed;
+
+ bool m_cursorHiddenForUI;
+
+ bool m_windowFocused;
+
+ bool m_hasInput;
+
+ bool m_kbmActive;
+
+ bool m_screenWantsCursorHidden;
+
+ static const int CHAR_BUFFER_SIZE = 32;
+ wchar_t m_charBuffer[CHAR_BUFFER_SIZE];
+ int m_charBufferHead;
+ int m_charBufferTail;
+};
+
+extern KeyboardMouseInput g_KBMInput;
diff --git a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp
index 836f23e4..35f89393 100644
--- a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp
+++ b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp
@@ -20,6 +20,7 @@
#include "..\..\Minecraft.World\net.minecraft.world.level.tile.h"
#include "..\ClientConnection.h"
+#include "KBMInput.h"
#include "..\User.h"
#include "..\..\Minecraft.World\Socket.h"
#include "..\..\Minecraft.World\ThreadName.h"
@@ -842,6 +843,25 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
{
InputManager.Tick();
}
+
+ if (InputManager.IsPadConnected(0))
+ {
+ const bool controllerUsed = InputManager.ButtonPressed(0) ||
+ InputManager.GetJoypadStick_LX(0, false) != 0.0f ||
+ InputManager.GetJoypadStick_LY(0, false) != 0.0f ||
+ InputManager.GetJoypadStick_RX(0, false) != 0.0f ||
+ InputManager.GetJoypadStick_RY(0, false) != 0.0f;
+
+ if (controllerUsed) {
+ g_KBMInput.SetKBMActive(false);
+ //if (ui.FindScene(eUIScene_BookMenu) != nullptr) ui.FindScene(eUIScene_BookMenu)->KBMUpdate(false);
+ }
+ else if (g_KBMInput.HasAnyInput()) {
+ g_KBMInput.SetKBMActive(true);
+ //if (ui.FindScene(eUIScene_BookMenu) != nullptr) ui.FindScene(eUIScene_BookMenu)->KBMUpdate(true);
+ }
+ }
+
PIXEndNamedEvent();
/*PIXBeginNamedEvent(0,"Profile manager tick");
ProfileManager.Tick();