-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInput.cpp
More file actions
210 lines (156 loc) · 5.24 KB
/
Input.cpp
File metadata and controls
210 lines (156 loc) · 5.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
//
// Created by shawn on 5/16/2025.
//
#include "Input.h"
#include <unordered_map>
#include <iostream>
#include <bits/algorithmfwd.h>
#include "App.h"
std::unordered_map<SDL_Keycode, bool> isDown;
std::unordered_map<SDL_Keycode, bool> isUp;
std::unordered_map<SDL_Keycode, bool> holding;
std::unordered_map<Uint8, MouseState> mouseState;
std::unordered_map<Uint8, MouseState> lastMouseState;
DWORD Input::currentPID = 0;
HWND Input::windowHandle = nullptr;
void Input::onKeyDown(const SDL_Keycode pressed) {
if(const auto iterVal = isDown.find(pressed); iterVal == isDown.end()) {
//add the key here as it does not exist
isDown[pressed] = true;
isUp[pressed] = false; //add this because how could something be up if it has not been pressed?
return;
}
isDown[pressed] = true;
isUp[pressed] = false;
}
void Input::onKeyUp(const SDL_Keycode released) {
if(const auto iterVal = isUp.find(released); iterVal == isUp.end()) {
isUp[released] = true;
return;
}
isUp[released] = true;
holding[released] = false;
isDown[released] = false;
}
void Input::onKeyHeld(const SDL_Keycode pressing) {
isDown[pressing] = false;
holding[pressing] = true;
}
bool Input::isKeyDown(SDL_Keycode key) {
const auto find = isDown.find(key);
return find != isDown.end() && isDown[key];
}
bool Input::isKeyUp(const SDL_Keycode key) {
const auto find = isUp.find(key);
return find == isUp.end() || isUp[key];
}
bool Input::isKeyHeld(const SDL_Keycode key) {
return isKeyDown(key) || holding.contains(key) && holding[key];
}
void Input::doKeyCheck(const SDL_Event& event) {
//check if isDown contains the keycode
const SDL_Keycode key = event.key.keysym.sym;
//if isDown does not contain we shall add it
//or
//if the current key is not down and it is also not being held
if(!isDown.contains(key) || (!isDown[key] && !holding[key])) {
onKeyDown(key);
}
else { //item was down in the previous poll
onKeyHeld(key);
}
}
void Input::updateMouseInputState(const Uint8 &key, const bool& down) {
mouseState[key] = down ? Down : Up;
}
MouseState Input::getMouseInputState(const MouseButton &mouseButton) {
Uint8 key;
switch (mouseButton) {
case Left:
key = SDL_BUTTON_LEFT;
break;
case Right:
key = SDL_BUTTON_RIGHT;
break;;
default:
throw std::runtime_error("Invalid choice");
}
if(!mouseState.contains(key)) {
return Up; //assume it has never been pressed or anything
}
MouseState state = mouseState[key];
if(lastMouseState[key] == Down && state == Down) {
mouseState[key] = Held;
state = Held;
}
lastMouseState[key] = state;
return state;
}
//For internal use, updates the input states.
void Input::pollInput() {
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
exit(0);
break;
case SDL_KEYDOWN:
doKeyCheck(event);
break;
case SDL_KEYUP:
onKeyUp(event.key.keysym.sym);
break;
case SDL_MOUSEBUTTONDOWN:
updateMouseInputState(event.button.button, true);
break;
case SDL_MOUSEBUTTONUP:
updateMouseInputState(event.button.button, false);
default:
break;
}
}
}
long Input::clampLong( const long& val, const long& min, const long& max) {
if(val < min)
return min;
return val > max ? max : val;
}
Vector2 Input::getMousePosition() {
if(!windowHasFocus()) {
return Vector2{ 0, 0 };
}
Vector2 finalPosition;
const auto dimensions = App::getInstance()->getSettings()->windowDimensions;
POINT cursorPoint;
if(GetCursorPos(&cursorPoint)) {
if(ScreenToClient(windowHandle, &cursorPoint)) {
finalPosition.x = clampLong(cursorPoint.x, 0, dimensions.x);
finalPosition.y = clampLong(cursorPoint.y, 0, dimensions.y);
}
}
return finalPosition;
}
//SOURCE: https://stackoverflow.com/questions/11711417/get-hwnd-by-process-id-c
BOOL CALLBACK Input::EnumWindowsProcMy(HWND hwnd, LPARAM lParam) {
DWORD lpdwProcessId;
GetWindowThreadProcessId(hwnd,&lpdwProcessId);
if(lpdwProcessId==lParam)
{
windowHandle = hwnd;
return FALSE;
}
return TRUE;
}
bool Input::windowHasFocus() {
currentPID = GetCurrentProcessId(); //retrieve the current process id
EnumWindows(EnumWindowsProcMy, currentPID);
return GetForegroundWindow() == windowHandle;
}
double Input::getMovement(const Direction &direction) {
//check if any up/right keys are being held per direction
const bool leftSideAr = direction == Vertical ? isKeyHeld(SDLK_w) || isKeyHeld(SDLK_UP) : isKeyHeld(SDLK_d) || isKeyHeld(SDLK_RIGHT);
//check if any down/left keys are being held per direction
const bool rightSideAr = direction == Vertical ? isKeyHeld(SDLK_s) || isKeyHeld(SDLK_DOWN) : isKeyHeld(SDLK_a) || isKeyHeld(SDLK_LEFT);
//(up/right) - (down/left)
return static_cast<int>(leftSideAr) - static_cast<int>(rightSideAr);
}