-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathInputState.cpp
More file actions
239 lines (205 loc) · 7.05 KB
/
Copy pathInputState.cpp
File metadata and controls
239 lines (205 loc) · 7.05 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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#include "InputState.h"
#include <iostream>
#include <cassert>
#include <cstring>
#include <algorithm>
#include <SDL2/SDL.h>
#include "GamepadState.h"
#include "LogInput.h"
InputState& InputState::GetInstance() {
static InputState inputState;
return inputState;
}
void InputState::Initialize() {
if ( SDL_InitSubSystem( SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER ) != 0 ) {
LogInput( "Failed to initialize SDL input subsystem", "SDL", LogSeverity::ERROR_MSG );
assert( false );
}
m_Gamepads.resize( INPUT_MAX_NR_OF_GAMEPADS );
std::fill( m_Gamepads.begin(), m_Gamepads.end(), nullptr );
}
void InputState::Deinitialize() {
SDL_QuitSubSystem( SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER );
if ( m_Callbacks.size() > 0 ) {
rStringStream ss;
for ( auto& callback : m_Callbacks ) {
ss << static_cast<int>( callback.Handle ) << ", ";
}
LogInput( "Input state was destructed while still having callbacks registered to it. Callback values: " + ss.str(), "InputState", LogSeverity::WARNING_MSG );
}
if ( m_KeyboardState ) {
pDelete( m_KeyboardState );
m_KeyboardState = nullptr;
}
for ( auto& gamepad : m_Gamepads ) {
if ( gamepad ) {
pDelete( gamepad );
}
}
}
void InputState::Update() {
SDL_PumpEvents();
if ( m_KeyboardStateTracking ) {
int size;
const Uint8* keyboardState = SDL_GetKeyboardState( &size );
if ( m_KeyboardState == nullptr ) {
m_KeyboardState = pNewArray( Uint8, size );
}
memcpy( m_KeyboardState, keyboardState, size );
}
m_MouseState.ButtonState = SDL_GetMouseState( &m_MouseState.PositionX, &m_MouseState.PositionY );
m_MouseInsideWindow = SDL_GetMouseFocus() != nullptr;
int mouseMoveX, mouseMoveY;
SDL_GetRelativeMouseState( &mouseMoveX, &mouseMoveY );
m_MouseMoveAccumulationX += mouseMoveX;
m_MouseMoveAccumulationY += mouseMoveY;
for ( auto gamepad : m_Gamepads ) {
if ( gamepad ) {
gamepad->Update();
}
}
}
void InputState::HandleEvent( const SDL_Event &event ) {
// Process event for this class
switch ( event.type ) {
case SDL_MOUSEWHEEL: {
m_MouseScrollAccumulationX += event.wheel.x;
m_MouseScrollAccumulationY += event.wheel.y;
} break;
case SDL_CONTROLLERDEVICEADDED: {
SDL_GameController* controller = nullptr;
// Open controller so we can use it
controller = SDL_GameControllerOpen( event.cdevice.which );
if ( controller ) {
m_Gamepads.at( event.cdevice.which ) = pNew( GamepadState, controller );
LogInput( pString( SDL_GameControllerName( controller ) ) + " " + rToString( event.cdevice.which ) + " added",
"GamepadState", LogSeverity::INFO_MSG );
} else {
LogInput( "Could not open gamecontroller " + rToString( event.cdevice.which ) + ": " + SDL_GetError(), "GamepadState",
LogSeverity::ERROR_MSG );
}
} break;
case SDL_CONTROLLERDEVICEREMOVED: {
GamepadState* gp = m_Gamepads.at( event.cdevice.which );
if ( gp != nullptr ) {
LogInput( gp->GetName() + " " + std::to_string( event.cdevice.which ) + " removed", "GamepadState", LogSeverity::INFO_MSG );
m_Gamepads.at( event.cdevice.which ) = nullptr;
pDelete( gp );
}
} break;
}
// Relay event to callbacks
switch ( event.type ) {
case SDL_MOUSEWHEEL: { }
case SDL_KEYUP:
case SDL_KEYDOWN:
case SDL_MOUSEMOTION:
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
case SDL_CONTROLLERAXISMOTION:
case SDL_CONTROLLERBUTTONUP:
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERDEVICEADDED:
case SDL_CONTROLLERDEVICEREMOVED:
case SDL_CONTROLLERDEVICEREMAPPED:
case SDL_FINGERDOWN:
case SDL_FINGERUP:
case SDL_FINGERMOTION: // If you know what i mean ;)
case SDL_TEXTEDITING:
case SDL_TEXTINPUT: {
for ( auto& callback : m_Callbacks ) {
// Will return true if it wants to consume the event
if ( callback.Function( event ) ) {
break;
}
}
} break;
}
}
InputEventCallbackHandle InputState::RegisterEventInterest( InputEventCallbackFunction callbackFunction, int priority ) {
InputEventCallbackHandle handle = static_cast<InputEventCallbackHandle>( m_NextHandle++ );
m_Callbacks.push_back( CallbackEntry { priority, handle, callbackFunction } );
std::sort( m_Callbacks.begin(), m_Callbacks.end(), [] ( const CallbackEntry& lhs, const CallbackEntry& rhs ) {
return lhs.Priority < rhs.Priority;
} );
return handle;
}
void InputState::UnregisterEventInterest( InputEventCallbackHandle callbackHandle ) {
pVector<CallbackEntry>::iterator it;
for ( it = m_Callbacks.begin(); it != m_Callbacks.end(); ++it ) {
if ( it->Handle == callbackHandle ) {
break;
}
}
if ( it == m_Callbacks.end() ) {
LogInput( "Tried to unregister invalid input event callback handle: " + rToString( static_cast<int>( callbackHandle ) ), "InputState", LogSeverity::WARNING_MSG );
} else {
m_Callbacks.erase( it );
}
}
const MouseState& InputState::GetMouseState() const {
return m_MouseState;
}
int InputState::GetMouseDeltaX( int previousValue ) const {
return m_MouseMoveAccumulationX - previousValue;
}
int InputState::GetMouseDeltaY( int previousValue ) const {
return m_MouseMoveAccumulationY - previousValue;
}
int InputState::GetMouseDeltaAccumulationX() const {
return m_MouseMoveAccumulationX;
}
int InputState::GetMouseDeltaAccumulationY() const {
return m_MouseMoveAccumulationY;
}
int InputState::GetMouseScrollDeltaX( int previousValue ) const {
return m_MouseScrollAccumulationX - previousValue;
}
int InputState::GetMouseScrollDeltaY( int previousValue ) const {
return m_MouseScrollAccumulationY - previousValue;
}
int InputState::GetMouseScrollAccumulationX() const {
return m_MouseScrollAccumulationX;
}
int InputState::GetMouseScrollAccumulationY() const {
return m_MouseScrollAccumulationY;
}
bool InputState::IsMouseButtonDown( MOUSE_BUTTON mouseButton ) const {
return ( m_MouseState.ButtonState & SDL_BUTTON( mouseButton ) ) != 0;
}
bool InputState::IsMouseButtonUp( MOUSE_BUTTON mouseButton ) const {
return !( m_MouseState.ButtonState & SDL_BUTTON( mouseButton ) );
}
void InputState::SetMouseButtonState( MOUSE_BUTTON mouseButton, INPUT_STATE state ) {
// Set the corresponding bit
m_MouseState.ButtonState ^= ( -state ^ m_MouseState.ButtonState ) & ( 1 << mouseButton );
}
bool InputState::IsKeyDown( SDL_Scancode scanCode ) const {
return m_KeyboardState[scanCode] && m_KeyboardStateTracking;
}
bool InputState::IsKeyUp( SDL_Scancode scanCode ) const {
return !m_KeyboardState[scanCode] && m_KeyboardStateTracking;
}
void InputState::ActivateKeyboardStateTracking() {
m_KeyboardStateTracking = true;
}
void InputState::DeactivateKeyboardStateTracking() {
m_KeyboardStateTracking = false;
}
bool InputState::IsKeyboardStateTrackingActivated() const {
return m_KeyboardStateTracking;
}
void InputState::SetKeyState( SDL_Scancode scanCode, INPUT_STATE state ) {
if ( state != INPUT_STATE_IGNORE ) {
m_KeyboardState[scanCode] = static_cast<int>( state );
}
}
const GamepadState* InputState::GetGamepadState( unsigned int gamepadIndex ) const {
if ( gamepadIndex >= m_Gamepads.size() ) {
return nullptr;
}
return m_Gamepads.at( gamepadIndex );
}
size_t InputState::GetNrOfGamepads() const {
return m_Gamepads.size();
}