the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 260 lines 6.3 kB view raw
1#include "stdafx.h" 2 3#ifdef _WINDOWS64 4 5#include "KeyboardMouseInput.h" 6 7KeyboardMouseInput KMInput; 8 9KeyboardMouseInput::KeyboardMouseInput() 10 : m_mouseDeltaXAccum(0.0f) 11 , m_mouseDeltaYAccum(0.0f) 12 , m_scrollDeltaAccum(0) 13 , m_captured(false) 14 , m_hWnd(NULL) 15 , m_initialized(false) 16 , m_mouseX(0) 17 , m_mouseY(0) 18{ 19 memset(m_keyState, 0, sizeof(m_keyState)); 20 memset(m_keyStatePrev, 0, sizeof(m_keyStatePrev)); 21 memset(m_mouseButtons, 0, sizeof(m_mouseButtons)); 22 memset(m_mouseButtonsPrev, 0, sizeof(m_mouseButtonsPrev)); 23 memset(m_keyPressedAccum, 0, sizeof(m_keyPressedAccum)); 24 memset(m_mousePressedAccum, 0, sizeof(m_mousePressedAccum)); 25 memset(m_mouseReleasedAccum, 0, sizeof(m_mouseReleasedAccum)); 26} 27 28KeyboardMouseInput::~KeyboardMouseInput() 29{ 30 if (m_captured) 31 { 32 SetCapture(false); 33 } 34} 35 36void KeyboardMouseInput::Init(HWND hWnd) 37{ 38 m_hWnd = hWnd; 39 m_initialized = true; 40 41 // Register for raw mouse input 42 RAWINPUTDEVICE rid; 43 rid.usUsagePage = HID_USAGE_PAGE_GENERIC; 44 rid.usUsage = HID_USAGE_GENERIC_MOUSE; 45 rid.dwFlags = 0; 46 rid.hwndTarget = hWnd; 47 RegisterRawInputDevices(&rid, 1, sizeof(rid)); 48} 49 50void KeyboardMouseInput::Tick() 51{ 52 // Keep cursor pinned to center while captured 53 if (m_captured) 54 CenterCursor(); 55} 56 57void KeyboardMouseInput::EndFrame() 58{ 59 // Advance previous state for next frame's edge detection. 60 // Must be called AFTER all per-frame consumers have read IsKeyPressed/Released etc. 61 memcpy(m_keyStatePrev, m_keyState, sizeof(m_keyState)); 62 memcpy(m_mouseButtonsPrev, m_mouseButtons, sizeof(m_mouseButtons)); 63} 64 65void KeyboardMouseInput::OnKeyDown(WPARAM vk) 66{ 67 if (vk < 256) 68 { 69 if (!m_keyState[vk]) m_keyPressedAccum[vk] = true; 70 m_keyState[vk] = true; 71 } 72} 73 74void KeyboardMouseInput::OnKeyUp(WPARAM vk) 75{ 76 if (vk < 256) 77 { 78 m_keyState[vk] = false; 79 } 80} 81 82void KeyboardMouseInput::OnRawMouseInput(LPARAM lParam) 83{ 84 if (!m_captured) return; 85 86 UINT dwSize = 0; 87 GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)); 88 89 BYTE* lpb = (BYTE*)alloca(dwSize); 90 if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize) 91 return; 92 93 RAWINPUT* raw = (RAWINPUT*)lpb; 94 if (raw->header.dwType == RIM_TYPEMOUSE) 95 { 96 if (raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE) 97 { 98 m_mouseDeltaXAccum += (float)raw->data.mouse.lLastX; 99 m_mouseDeltaYAccum += (float)raw->data.mouse.lLastY; 100 } 101 } 102} 103 104void KeyboardMouseInput::OnMouseButton(int button, bool down) 105{ 106 if (button >= 0 && button < 3) 107 { 108 if (down && !m_mouseButtons[button]) m_mousePressedAccum[button] = true; 109 if (!down && m_mouseButtons[button]) m_mouseReleasedAccum[button] = true; 110 m_mouseButtons[button] = down; 111 } 112} 113 114void KeyboardMouseInput::OnMouseWheel(int delta) 115{ 116 m_scrollDeltaAccum += delta; 117} 118 119void KeyboardMouseInput::OnMouseMove(int x, int y) 120{ 121 m_mouseX = x; 122 m_mouseY = y; 123} 124 125int KeyboardMouseInput::GetMouseX() const { return m_mouseX; } 126int KeyboardMouseInput::GetMouseY() const { return m_mouseY; } 127HWND KeyboardMouseInput::GetHWnd() const { return m_hWnd; } 128 129void KeyboardMouseInput::ClearAllState() 130{ 131 memset(m_keyState, 0, sizeof(m_keyState)); 132 memset(m_mouseButtons, 0, sizeof(m_mouseButtons)); 133 memset(m_keyPressedAccum, 0, sizeof(m_keyPressedAccum)); 134 memset(m_mousePressedAccum, 0, sizeof(m_mousePressedAccum)); 135 memset(m_mouseReleasedAccum, 0, sizeof(m_mouseReleasedAccum)); 136 m_mouseDeltaXAccum = 0.0f; 137 m_mouseDeltaYAccum = 0.0f; 138 m_scrollDeltaAccum = 0; 139} 140 141// Per-frame key queries 142bool KeyboardMouseInput::IsKeyDown(int vk) const 143{ 144 if (vk < 0 || vk >= 256) return false; 145 return m_keyState[vk]; 146} 147 148bool KeyboardMouseInput::IsKeyPressed(int vk) const 149{ 150 if (vk < 0 || vk >= 256) return false; 151 return m_keyState[vk] && !m_keyStatePrev[vk]; 152} 153 154bool KeyboardMouseInput::IsKeyReleased(int vk) const 155{ 156 if (vk < 0 || vk >= 256) return false; 157 return !m_keyState[vk] && m_keyStatePrev[vk]; 158} 159 160// Per-frame mouse button queries 161bool KeyboardMouseInput::IsMouseDown(int btn) const 162{ 163 if (btn < 0 || btn >= 3) return false; 164 return m_mouseButtons[btn]; 165} 166 167bool KeyboardMouseInput::IsMousePressed(int btn) const 168{ 169 if (btn < 0 || btn >= 3) return false; 170 return m_mouseButtons[btn] && !m_mouseButtonsPrev[btn]; 171} 172 173bool KeyboardMouseInput::IsMouseReleased(int btn) const 174{ 175 if (btn < 0 || btn >= 3) return false; 176 return !m_mouseButtons[btn] && m_mouseButtonsPrev[btn]; 177} 178 179// Game-tick consume methods 180bool KeyboardMouseInput::ConsumeKeyPress(int vk) 181{ 182 if (vk < 0 || vk >= 256) return false; 183 bool pressed = m_keyPressedAccum[vk]; 184 m_keyPressedAccum[vk] = false; 185 return pressed; 186} 187 188bool KeyboardMouseInput::ConsumeMousePress(int btn) 189{ 190 if (btn < 0 || btn >= 3) return false; 191 bool pressed = m_mousePressedAccum[btn]; 192 m_mousePressedAccum[btn] = false; 193 return pressed; 194} 195 196bool KeyboardMouseInput::ConsumeMouseRelease(int btn) 197{ 198 if (btn < 0 || btn >= 3) return false; 199 bool released = m_mouseReleasedAccum[btn]; 200 m_mouseReleasedAccum[btn] = false; 201 return released; 202} 203 204void KeyboardMouseInput::ConsumeMouseDelta(float &dx, float &dy) 205{ 206 dx = m_mouseDeltaXAccum; 207 dy = m_mouseDeltaYAccum; 208 m_mouseDeltaXAccum = 0.0f; 209 m_mouseDeltaYAccum = 0.0f; 210} 211 212int KeyboardMouseInput::ConsumeScrollDelta() 213{ 214 int delta = m_scrollDeltaAccum; 215 m_scrollDeltaAccum = 0; 216 return delta; 217} 218 219// Mouse capture 220void KeyboardMouseInput::SetCapture(bool capture) 221{ 222 if (capture == m_captured) return; 223 m_captured = capture; 224 225 if (capture) 226 { 227 ShowCursor(FALSE); 228 RECT rect; 229 GetClientRect(m_hWnd, &rect); 230 POINT topLeft = { rect.left, rect.top }; 231 POINT bottomRight = { rect.right, rect.bottom }; 232 ClientToScreen(m_hWnd, &topLeft); 233 ClientToScreen(m_hWnd, &bottomRight); 234 RECT screenRect = { topLeft.x, topLeft.y, bottomRight.x, bottomRight.y }; 235 ClipCursor(&screenRect); 236 CenterCursor(); 237 238 // Flush accumulated deltas so the snap-to-center doesn't cause a jump 239 m_mouseDeltaXAccum = 0.0f; 240 m_mouseDeltaYAccum = 0.0f; 241 } 242 else 243 { 244 ShowCursor(TRUE); 245 ClipCursor(NULL); 246 } 247} 248 249bool KeyboardMouseInput::IsCaptured() const { return m_captured; } 250 251void KeyboardMouseInput::CenterCursor() 252{ 253 RECT rect; 254 GetClientRect(m_hWnd, &rect); 255 POINT center = { (rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2 }; 256 ClientToScreen(m_hWnd, &center); 257 SetCursorPos(center.x, center.y); 258} 259 260#endif // _WINDOWS64