-
Notifications
You must be signed in to change notification settings - Fork 0
/
Controls.h
201 lines (147 loc) · 5.37 KB
/
Controls.h
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
#pragma once
#include "utils/GetGameController.h"
// Mouse Functions
// For uniformity
#define GetMouseState SDL_GetMouseState
#define JOYSTICK_LEFTX SDL_CONTROLLER_AXIS_LEFTX
#define JOYSTICK_LEFTY SDL_CONTROLLER_AXIS_LEFTY
#define JOYSTICK_RIGHTX SDL_CONTROLLER_AXIS_RIGHTX
#define JOYSTICK_RIGHTY SDL_CONTROLLER_AXIS_RIGHTY
// minimum angle for axis to be considered "moved"
#define AXIS_MIN_MOVED 7000
// Maximum value for the axis
#define AXIS_MAX 32767
struct Map;
struct GlobalControls {
const Uint8 *keys_down = NULL;
SDL_GameController *controller = NULL;
bool action_one_before = false;
bool action_dev_before = false;
int old_mouse_x, old_mouse_y = 0;
void Init();
// CALL AFTER ALL OTHER UPDATE CALLS
void EndUpdate();
bool Left();
bool Right();
bool Up();
bool Down();
bool Action1();
bool Action2();
bool Action1Event();
bool Back();
bool MouseMoved();
bool ActionDev();
};
extern GlobalControls g_controls;
// Mouse
void GetMouseInGameWindowCoords(int *x, int *y);
v2i GetMouseInGameWindowCoords();
v2i GetMouseGameOverlayCoords();
bool CursorInGameWindow();
inline bool GetMouseDown(int i = 1) {
return SDL_GetMouseState(NULL, NULL) == SDL_BUTTON(i);
};
// Joystick
// Functions with same functionality, but the names makes it slightly clearer
// when running them.
inline bool IsLeft(s16 value) {
return value < -AXIS_MIN_MOVED;
};
inline bool IsRight(s16 value) {
return value > AXIS_MIN_MOVED;
};
inline bool IsUp(s16 value) {
return value < -AXIS_MIN_MOVED;
};
inline bool IsDown(s16 value) {
return value > AXIS_MIN_MOVED;
};
inline s16 ControllerAxis(SDL_GameControllerAxis button) {
return SDL_GameControllerGetAxis(g_controls.controller, button);
}
inline bool ControllerButton(SDL_GameControllerButton button) {
return SDL_GameControllerGetButton(g_controls.controller, button);
}
#ifdef ENGINE_IMPLEMENTATION
void GlobalControls::Init() {
keys_down = SDL_GetKeyboardState(NULL);
controller = GetGameController();
}
void GlobalControls::EndUpdate() {
action_one_before = Action1();
}
bool GlobalControls::Left() {
return keys_down[SDL_SCANCODE_LEFT] || keys_down[SDL_SCANCODE_A] ||
IsLeft(ControllerAxis(JOYSTICK_LEFTX));
}
bool GlobalControls::Right() {
return keys_down[SDL_SCANCODE_RIGHT] || keys_down[SDL_SCANCODE_D] ||
IsRight(ControllerAxis(JOYSTICK_LEFTX));
}
bool GlobalControls::Up() {
return keys_down[SDL_SCANCODE_UP] || keys_down[SDL_SCANCODE_W] ||
IsUp(ControllerAxis(JOYSTICK_LEFTY));
}
bool GlobalControls::Down() {
return keys_down[SDL_SCANCODE_DOWN] || keys_down[SDL_SCANCODE_S] ||
IsDown(ControllerAxis(JOYSTICK_LEFTY));
}
bool GlobalControls::Action1() {
return GetMouseDown(SDL_BUTTON_LEFT) || ControllerButton(SDL_CONTROLLER_BUTTON_X);
}
bool GlobalControls::Action2() {
return GetMouseDown(SDL_BUTTON_RIGHT) || ControllerButton(SDL_CONTROLLER_BUTTON_Y);
}
bool GlobalControls::Action1Event() {
// If we have the mouse down and it wasn't down before, then that's an event!
return Action1() && ! action_one_before;
}
bool GlobalControls::Back() {
return keys_down[SDL_SCANCODE_ESCAPE] || ControllerButton(SDL_CONTROLLER_BUTTON_START);
}
// we don't need to use g_graphics.high_dpi_scale here because we don't care about the
// actual values, we only care if they change, so this is still correct if we don't use
// the variable because a number change is a change whether or not the number is "accurate".
bool GlobalControls::MouseMoved() {
int new_x, new_y;
GetMouseState(&new_x, &new_y);
bool result = old_mouse_x != new_x || old_mouse_y != new_y;
old_mouse_x = new_x;
old_mouse_y = new_y;
return result;
}
bool GlobalControls::ActionDev() {
// To make sure the function doesn't constantly spam ActionDev is down.
// It acts more as a key down event.
bool action_dev_now = (keys_down[SDL_SCANCODE_LCTRL]) || (ControllerButton(SDL_CONTROLLER_BUTTON_BACK) && g_controls.Left());
bool result = action_dev_now && !action_dev_before;
action_dev_before = action_dev_now;
return result;
}
GlobalControls g_controls;
v2i GetMouseInGameWindowCoords() {
v2i return_coord = {-1, -1};
SDL_GetMouseState(& return_coord.x, & return_coord.y);
return_coord.x *= g_graphics.high_dpi_scale;
return_coord.y *= g_graphics.high_dpi_scale;
return_coord.x = (return_coord.x - g_graphics.gameplay_target_x) / g_graphics.scale;
return_coord.y = (return_coord.y - g_graphics.gameplay_target_y) / g_graphics.scale;
return return_coord;
}
v2i GetMouseGameOverlayCoords() {
v2i return_coord = {-1, -1};
SDL_GetMouseState(& return_coord.x, & return_coord.y);
return_coord.x *= g_graphics.high_dpi_scale;
return_coord.y *= g_graphics.high_dpi_scale;
return_coord.x = return_coord.x / g_graphics.scale;
return_coord.y = return_coord.y / g_graphics.scale;
return return_coord;
}
bool CursorInGameWindow() {
v2i coords;
SDL_GetMouseState(& coords.x, & coords.y);
coords.x *= g_graphics.high_dpi_scale;
coords.y *= g_graphics.high_dpi_scale;
return PointRect(coords.x, coords.y, g_graphics.gameplay_target_x, g_graphics.gameplay_target_y, g_graphics.gameplay_target_w * g_graphics.scale, g_graphics.gameplay_target_h * g_graphics.scale);
}
#endif