-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathKeyboardInput.cpp
155 lines (129 loc) · 3.52 KB
/
KeyboardInput.cpp
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
#include "KeyboardInput.h"
KeyboardInput::KeyboardInput()
{
}
KeyboardInput::KeyboardInput ( HANDLE bufferHandle ) : m_bufferHandle ( bufferHandle )
{
if ( m_bufferHandle == INVALID_HANDLE_VALUE )
{
return;
}
init ( );
}
KeyboardInput::~KeyboardInput ( )
{
if (m_ready)
{
// reset console mode
SetConsoleMode(m_bufferHandle, fdwSaveOldMode);
}
for ( auto & key : m_keyRegistrations )
{
delete key.second;
}
m_keyRegistrations.clear ( );
}
void KeyboardInput::tick ( const float deltaTime )
{
if ( !m_ready )
{
return;
}
for ( auto & key : m_keyRegistrations )
{
auto result = GetAsyncKeyState ( key.first );
if ( result & 0x8000 ) // check most significant bit
{
// key is down
if ( key.second->isPressed )
{
key.second->pressedDuration += deltaTime;
}
else
{
key.second->isPressed = true;
// if this is the first frame for this scene then don't process on pressed or wasPressedThisFrame.
key.second->pressedDuration = deltaTime > 0 ? 0 : 0.001f;
if ( key.second->onPressCallback != nullptr && deltaTime > 0 )
{
key.second->onPressCallback ( key.first, result );
}
}
}
else
{
// key is up
if ( key.second->isPressed )
{
key.second->isPressed = false;
}
}
}
}
bool KeyboardInput::registerKey ( WORD key )
{
if ( !m_ready )
{
return false;
}
if ( m_keyRegistrations.find ( key ) != m_keyRegistrations.end ( ) )
{
// this key has already been registered.
return true;
}
auto data = new keyEventStatus ( );
data->onPressCallback = nullptr;
m_keyRegistrations [ key ] = data;
return true;
}
bool KeyboardInput::registerOnKey ( WORD key, std::function<void ( WORD , short )> callback )
{
if ( !m_ready )
{
return false;
}
if ( m_keyRegistrations.find ( key ) != m_keyRegistrations.end ( ) )
{
// this key has already been registered.
delete m_keyRegistrations [ key ];
}
auto data = new keyEventStatus ( );
data->onPressCallback = callback;
m_keyRegistrations [ key ] = data;
return true;
}
bool KeyboardInput::wasPressedThisFrame ( WORD key )
{
auto const status = m_keyRegistrations [ key ];
return status->isPressed && status->pressedDuration == 0;
}
bool KeyboardInput::isPressed ( WORD key )
{
return m_keyRegistrations [ key ]->isPressed;
}
void KeyboardInput::resetKeyPresses ( )
{
for ( auto & key : m_keyRegistrations )
{
key.second->isPressed = false;
key.second->pressedDuration = 0;
}
}
void KeyboardInput::init ( )
{
// FC note to self this function probably should be moved outside of the keyboard input
// and into somewhere that handles the console setup specifically.
// Save the current input mode, to be restored on exit.
if ( !GetConsoleMode ( m_bufferHandle, &fdwSaveOldMode ) )
{
return;
}
// Enable the window and mouse input events.
// ENABLE_EXTENDED_FLAGS without ENABLE_QUICK_EDIT_MODE will disable quick edit mode.
DWORD fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS;
if ( !SetConsoleMode ( m_bufferHandle, fdwMode ) )
{
return;
}
m_ready = true;
}