the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
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, ¢er);
257 SetCursorPos(center.x, center.y);
258}
259
260#endif // _WINDOWS64