feat: improve mouse input handling

This commit is contained in:
daoge_cmd
2026-03-02 00:04:54 +08:00
parent e16600a3e6
commit 47e00f7b62
10 changed files with 284 additions and 12 deletions

View File

@@ -13,6 +13,8 @@ KeyboardMouseInput::KeyboardMouseInput()
, m_captured(false)
, m_hWnd(NULL)
, m_initialized(false)
, m_mouseX(0)
, m_mouseY(0)
{
memset(m_keyState, 0, sizeof(m_keyState));
memset(m_keyStatePrev, 0, sizeof(m_keyStatePrev));
@@ -20,6 +22,7 @@ KeyboardMouseInput::KeyboardMouseInput()
memset(m_mouseButtonsPrev, 0, sizeof(m_mouseButtonsPrev));
memset(m_keyPressedAccum, 0, sizeof(m_keyPressedAccum));
memset(m_mousePressedAccum, 0, sizeof(m_mousePressedAccum));
memset(m_mouseReleasedAccum, 0, sizeof(m_mouseReleasedAccum));
}
KeyboardMouseInput::~KeyboardMouseInput()
@@ -103,6 +106,7 @@ void KeyboardMouseInput::OnMouseButton(int button, bool down)
if (button >= 0 && button < 3)
{
if (down && !m_mouseButtons[button]) m_mousePressedAccum[button] = true;
if (!down && m_mouseButtons[button]) m_mouseReleasedAccum[button] = true;
m_mouseButtons[button] = down;
}
}
@@ -112,12 +116,23 @@ void KeyboardMouseInput::OnMouseWheel(int delta)
m_scrollDeltaAccum += delta;
}
void KeyboardMouseInput::OnMouseMove(int x, int y)
{
m_mouseX = x;
m_mouseY = y;
}
int KeyboardMouseInput::GetMouseX() const { return m_mouseX; }
int KeyboardMouseInput::GetMouseY() const { return m_mouseY; }
HWND KeyboardMouseInput::GetHWnd() const { return m_hWnd; }
void KeyboardMouseInput::ClearAllState()
{
memset(m_keyState, 0, sizeof(m_keyState));
memset(m_mouseButtons, 0, sizeof(m_mouseButtons));
memset(m_keyPressedAccum, 0, sizeof(m_keyPressedAccum));
memset(m_mousePressedAccum, 0, sizeof(m_mousePressedAccum));
memset(m_mouseReleasedAccum, 0, sizeof(m_mouseReleasedAccum));
m_mouseDeltaXAccum = 0.0f;
m_mouseDeltaYAccum = 0.0f;
m_scrollDeltaAccum = 0;
@@ -178,6 +193,14 @@ bool KeyboardMouseInput::ConsumeMousePress(int btn)
return pressed;
}
bool KeyboardMouseInput::ConsumeMouseRelease(int btn)
{
if (btn < 0 || btn >= 3) return false;
bool released = m_mouseReleasedAccum[btn];
m_mouseReleasedAccum[btn] = false;
return released;
}
void KeyboardMouseInput::ConsumeMouseDelta(float &dx, float &dy)
{
dx = m_mouseDeltaXAccum;

View File

@@ -42,9 +42,16 @@ public:
// Use these from code that runs at game tick rate (20Hz).
bool ConsumeKeyPress(int vk);
bool ConsumeMousePress(int btn);
bool ConsumeMouseRelease(int btn);
void ConsumeMouseDelta(float &dx, float &dy);
int ConsumeScrollDelta();
// Absolute cursor position (client-area coordinates, for GUI when not captured)
void OnMouseMove(int x, int y);
int GetMouseX() const;
int GetMouseY() const;
HWND GetHWnd() const;
// Mouse capture for FPS look
void SetCapture(bool capture);
bool IsCaptured() const;
@@ -61,6 +68,7 @@ private:
// Sticky press accumulators (persist until consumed by game tick)
bool m_keyPressedAccum[256];
bool m_mousePressedAccum[3];
bool m_mouseReleasedAccum[3];
// Mouse delta accumulators (persist until consumed by game tick)
float m_mouseDeltaXAccum;
@@ -72,6 +80,10 @@ private:
bool m_captured;
HWND m_hWnd;
bool m_initialized;
// Absolute cursor position in client coordinates
int m_mouseX;
int m_mouseY;
};
extern KeyboardMouseInput KMInput;

View File

@@ -395,6 +395,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_MOUSEWHEEL:
KMInput.OnMouseWheel(GET_WHEEL_DELTA_WPARAM(wParam));
break;
case WM_MOUSEMOVE:
KMInput.OnMouseMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
break;
case WM_ACTIVATE:
if (LOWORD(wParam) == WA_INACTIVE)
KMInput.SetCapture(false);
@@ -404,6 +407,15 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
KMInput.ClearAllState();
break;
case WM_SETCURSOR:
// Hide the OS cursor when an Iggy/Flash menu is displayed (it has its own Flash cursor)
if (LOWORD(lParam) == HTCLIENT && !KMInput.IsCaptured() && ui.GetMenuDisplayed(0))
{
SetCursor(NULL);
return TRUE;
}
return DefWindowProc(hWnd, message, wParam, lParam);
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
@@ -1184,7 +1196,7 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
// Update mouse capture: capture when in-game and no menu is open
{
static bool altToggleSuppressCapture = false;
bool shouldCapture = app.GetGameStarted() && !ui.GetMenuDisplayed(0);
bool shouldCapture = app.GetGameStarted() && !ui.GetMenuDisplayed(0) && pMinecraft->screen == NULL;
// Left Alt key toggles capture on/off for debugging
if (KMInput.IsKeyPressed(VK_MENU))
{