-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathKeyBuffer.cpp
182 lines (145 loc) · 3.67 KB
/
KeyBuffer.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
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
#include "DosVisor.h"
DWORD dwGlobal_StopKeyBuffer = 0;
HANDLE hGlobal_KeyBufferThread = NULL;
BYTE bGlobal_KeyState[MAX_VIRTUAL_KEY_COUNT];
BYTE bGlobal_KeyBuffer[MAX_KEY_BUFFER_LENGTH];
DWORD dwGlobal_CurrKeyBufferCount = 0;
CRITICAL_SECTION Global_KeyBufferCriticalSection;
DWORD GetKeyInfo(BYTE bVirtualKey, WORD *pwScanCode, BYTE *pbAscii)
{
WORD wScanCode = 0;
BYTE bAscii = 0;
// get scan-code/ascii values from virtual key code
wScanCode = (WORD)MapVirtualKey(bVirtualKey, 0);
bAscii = (BYTE)MapVirtualKey(bVirtualKey, 2);
*pwScanCode = wScanCode;
*pbAscii = bAscii;
return 0;
}
DWORD AddToKeyBuffer(BYTE bVirtualKey)
{
// (this function is called by KeyBufferThread - already locked)
if(dwGlobal_CurrKeyBufferCount >= MAX_KEY_BUFFER_LENGTH)
{
// key buffer is full
return 1;
}
// add key to buffer
bGlobal_KeyBuffer[dwGlobal_CurrKeyBufferCount] = bVirtualKey;
dwGlobal_CurrKeyBufferCount++;
return 0;
}
DWORD CheckKeyWaiting(DWORD dwRemoveFromKeyBuffer, BYTE *pbVirtualKey)
{
DWORD dwKeyWaiting = 0;
BYTE bVirtualKey = 0;
EnterCriticalSection(&Global_KeyBufferCriticalSection);
// check if there any keys in the buffer
if(dwGlobal_CurrKeyBufferCount != 0)
{
dwKeyWaiting = 1;
bVirtualKey = bGlobal_KeyBuffer[0];
if(dwRemoveFromKeyBuffer != 0)
{
// remove from key buffer
dwGlobal_CurrKeyBufferCount--;
memmove(&bGlobal_KeyBuffer[0], &bGlobal_KeyBuffer[1], dwGlobal_CurrKeyBufferCount);
}
}
LeaveCriticalSection(&Global_KeyBufferCriticalSection);
if(dwKeyWaiting == 0)
{
// no key waiting
return 1;
}
if(pbVirtualKey != NULL)
{
// store key
*pbVirtualKey = bVirtualKey;
}
return 0;
}
DWORD WaitForKeyPress(DWORD dwRemoveFromKeyBuffer, BYTE *pbVirtualKey)
{
// wait until the key buffer is not empty
for(;;)
{
if(CheckKeyWaiting(dwRemoveFromKeyBuffer, pbVirtualKey) == 0)
{
break;
}
Sleep(1);
}
return 0;
}
DWORD WINAPI KeyBufferThread(LPVOID lpArg)
{
// check for keys
for(;;)
{
if(dwGlobal_StopKeyBuffer != 0)
{
break;
}
EnterCriticalSection(&Global_KeyBufferCriticalSection);
// check all keys
for(DWORD i = 0; i < MAX_VIRTUAL_KEY_COUNT; i++)
{
if(i == VK_LBUTTON || i == VK_RBUTTON || i == VK_MBUTTON)
{
// ignore mouse buttons
continue;
}
// check if key is currently down
if(((GetAsyncKeyState(i) >> 15) & 1) == 1)
{
if(bGlobal_KeyState[i] == 0)
{
// new key press
bGlobal_KeyState[i] = 1;
// check if the DOS terminal is in focus
if(GetConsoleWindow() == GetForegroundWindow())
{
// add to key buffer
AddToKeyBuffer((BYTE)i);
}
}
}
else
{
if(bGlobal_KeyState[i] != 0)
{
// key up
bGlobal_KeyState[i] = 0;
}
}
}
LeaveCriticalSection(&Global_KeyBufferCriticalSection);
// wait 10ms
Sleep(10);
}
return 0;
}
DWORD InitialiseKeyBuffer()
{
// initialise keybuffer
memset(bGlobal_KeyState, 0, sizeof(bGlobal_KeyState));
memset(bGlobal_KeyBuffer, 0, sizeof(bGlobal_KeyBuffer));
dwGlobal_CurrKeyBufferCount = 0;
InitializeCriticalSection(&Global_KeyBufferCriticalSection);
hGlobal_KeyBufferThread = CreateThread(NULL, 0, KeyBufferThread, NULL, 0, NULL);
if(hGlobal_KeyBufferThread == NULL)
{
DeleteCriticalSection(&Global_KeyBufferCriticalSection);
return 1;
}
return 0;
}
DWORD CloseKeyBuffer()
{
dwGlobal_StopKeyBuffer = 1;
WaitForSingleObject(hGlobal_KeyBufferThread, INFINITE);
CloseHandle(hGlobal_KeyBufferThread);
DeleteCriticalSection(&Global_KeyBufferCriticalSection);
return 0;
}