Skip to content

Commit 8f55c01

Browse files
committed
Release v0.2.0. Improve keyboard reading. Don't echo input.
1 parent 89bba1c commit 8f55c01

File tree

2 files changed

+239
-40
lines changed

2 files changed

+239
-40
lines changed

src/config.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
#define PACKAGE_NAME "Doom ASCII"
7474

7575
/* Define to the full name and version of this package. */
76-
#define PACKAGE_STRING "Doom ASCII 0.1.1"
76+
#define PACKAGE_STRING "Doom ASCII 0.2.0"
7777

7878
/* Define to the one symbol short name of this package. */
7979
#define PACKAGE_TARNAME "doom_ascii.tar"
@@ -91,7 +91,7 @@
9191
#define STDC_HEADERS 1
9292

9393
/* Version number of package */
94-
#define VERSION 0.1.1
94+
#define VERSION 0.2.0
9595

9696
/* Define to 1 if you want to compile the unmodified code */
9797
#undef ORIGCODE

src/doomgeneric_ascii.c

Lines changed: 237 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
#if defined(_WIN32) || defined(WIN32)
3030
#define OS_WINDOWS
31+
#define WIN32_LEAN_AND_MEAN
3132
#include <windows.h>
3233
#else
3334
#include <sys/ioctl.h>
@@ -111,10 +112,30 @@ char *output_buffer;
111112
size_t output_buffer_size;
112113
struct timespec ts_init;
113114

114-
char input_buffer[INPUT_BUFFER_LEN];
115+
unsigned char input_buffer[INPUT_BUFFER_LEN];
115116
uint16_t event_buffer[EVENT_BUFFER_LEN];
116117
uint16_t *event_buf_loc;
117118

119+
void DG_AtExit(void)
120+
{
121+
#ifdef OS_WINDOWS
122+
DWORD mode;
123+
const HANDLE hInputHandle = GetStdHandle(STD_INPUT_HANDLE);
124+
if (UNLIKELY(hInputHandle == INVALID_HANDLE_VALUE))
125+
return;
126+
if (UNLIKELY(!GetConsoleMode(hInputHandle, &mode)))
127+
return;
128+
mode |= ENABLE_ECHO_INPUT;
129+
SetConsoleMode(hInputHandle, mode);
130+
#else
131+
struct termios t;
132+
if (UNLIKELY(tcgetattr(STDIN_FILENO, &t)))
133+
return;
134+
t.c_lflag |= ECHO;
135+
tcsetattr(STDIN_FILENO, TCSANOW, &t);
136+
#endif
137+
}
138+
118139
void DG_Init()
119140
{
120141
#ifdef OS_WINDOWS
@@ -128,9 +149,16 @@ void DG_Init()
128149
const HANDLE hInputHandle = GetStdHandle(STD_INPUT_HANDLE);
129150
WINDOWS_CALL(hInputHandle == INVALID_HANDLE_VALUE, "DG_Init: %s");
130151
WINDOWS_CALL(!GetConsoleMode(hInputHandle, &mode), "DG_Init: %s");
131-
mode &= ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT | ENABLE_QUICK_EDIT_MODE);
152+
mode &= ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT | ENABLE_QUICK_EDIT_MODE | ENABLE_ECHO_INPUT);
132153
WINDOWS_CALL(!SetConsoleMode(hInputHandle, mode), "DG_Init: %s");
154+
#else
155+
struct termios t;
156+
CALL(tcgetattr(STDIN_FILENO, &t), "DG_Init: tcgetattr error %d");
157+
t.c_lflag &= ~(ECHO);
158+
CALL(tcsetattr(STDIN_FILENO, TCSANOW, &t), "DG_Init: tcsetattr error %d");
133159
#endif
160+
atexit(&DG_AtExit);
161+
134162
/* Longest SGR code: \033[38;2;RRR;GGG;BBBm (length 19)
135163
* Maximum 21 bytes per pixel: SGR + 2 x char
136164
* 1 Newline character per line
@@ -220,11 +248,105 @@ uint32_t DG_GetTicksMs()
220248
return (ts.tv_sec - ts_init.tv_sec) * 1000 + (ts.tv_nsec - ts_init.tv_nsec) / 1000000;
221249
}
222250

223-
char convertToDoomKey(char **buf)
251+
#ifdef OS_WINDOWS
252+
unsigned char convertToDoomKey(WORD wVirtualKeyCode, CHAR AsciiChar)
253+
{
254+
switch (wVirtualKeyCode) {
255+
case VK_RETURN:
256+
return KEY_ENTER;
257+
case VK_LEFT:
258+
return KEY_LEFTARROW;
259+
case VK_UP:
260+
return KEY_UPARROW;
261+
case VK_RIGHT:
262+
return KEY_RIGHTARROW;
263+
case VK_DOWN:
264+
return KEY_DOWNARROW;
265+
case VK_SPACE:
266+
return KEY_FIRE;
267+
case VK_TAB:
268+
return KEY_TAB;
269+
case VK_F1:
270+
return KEY_F1;
271+
case VK_F2:
272+
return KEY_F2;
273+
case VK_F3:
274+
return KEY_F3;
275+
case VK_F4:
276+
return KEY_F4;
277+
case VK_F5:
278+
return KEY_F5;
279+
case VK_F6:
280+
return KEY_F6;
281+
case VK_F7:
282+
return KEY_F7;
283+
case VK_F8:
284+
return KEY_F8;
285+
case VK_F9:
286+
return KEY_F9;
287+
case VK_F10:
288+
return KEY_F10;
289+
case VK_F11:
290+
return KEY_F11;
291+
case VK_F12:
292+
return KEY_F12;
293+
case VK_BACK:
294+
return KEY_BACKSPACE;
295+
case VK_PAUSE:
296+
return KEY_PAUSE;
297+
case VK_RSHIFT:
298+
return KEY_RSHIFT;
299+
case VK_RCONTROL:
300+
return KEY_RCTRL;
301+
case VK_CAPITAL:
302+
return KEY_CAPSLOCK;
303+
case VK_NUMLOCK:
304+
return KEY_NUMLOCK;
305+
case VK_SCROLL:
306+
return KEY_SCRLCK;
307+
case VK_SNAPSHOT:
308+
return KEY_PRTSCR;
309+
case VK_HOME:
310+
return KEY_HOME;
311+
case VK_END:
312+
return KEY_END;
313+
case VK_PRIOR:
314+
return KEY_PGUP;
315+
case VK_NEXT:
316+
return KEY_PGDN;
317+
case VK_INSERT:
318+
return KEY_INS;
319+
case VK_DELETE:
320+
return KEY_DEL;
321+
case VK_NUMPAD0:
322+
return KEYP_0;
323+
case VK_NUMPAD1:
324+
return KEYP_1;
325+
case VK_NUMPAD2:
326+
return KEYP_2;
327+
case VK_NUMPAD3:
328+
return KEYP_3;
329+
case VK_NUMPAD4:
330+
return KEYP_4;
331+
case VK_NUMPAD5:
332+
return KEYP_5;
333+
case VK_NUMPAD6:
334+
return KEYP_6;
335+
case VK_NUMPAD7:
336+
return KEYP_7;
337+
case VK_NUMPAD8:
338+
return KEYP_8;
339+
case VK_NUMPAD9:
340+
return KEYP_9;
341+
default:
342+
return tolower(AsciiChar);
343+
}
344+
}
345+
#else
346+
unsigned char convertToDoomKey(char **buf)
224347
{
225348
switch (**buf) {
226349
case '\012':
227-
(*buf)++;
228350
return KEY_ENTER;
229351
case '\033':
230352
(*buf)++;
@@ -233,57 +355,109 @@ char convertToDoomKey(char **buf)
233355
(*buf)++;
234356
switch (**buf) {
235357
case 'A':
236-
(*buf)++;
237358
return KEY_UPARROW;
238359
case 'B':
239-
(*buf)++;
240360
return KEY_DOWNARROW;
241361
case 'C':
242-
(*buf)++;
243362
return KEY_RIGHTARROW;
244363
case 'D':
245-
(*buf)++;
246364
return KEY_LEFTARROW;
365+
case 'H':
366+
return KEY_HOME;
367+
case 'F':
368+
return KEY_END;
369+
case '1':
370+
(*buf)++;
371+
switch (**buf) {
372+
case '5':
373+
if (*(++(*buf)) == '~')
374+
return KEY_F5;
375+
break;
376+
case '7':
377+
if (*(++(*buf)) == '~')
378+
return KEY_F6;
379+
break;
380+
case '8':
381+
if (*(++(*buf)) == '~')
382+
return KEY_F7;
383+
break;
384+
case '9':
385+
if (*(++(*buf)) == '~')
386+
return KEY_F8;
387+
break;
388+
}
389+
break;
390+
case '2':
391+
(*buf)++;
392+
switch (**buf) {
393+
case '0':
394+
if (*(++(*buf)) == '~')
395+
return KEY_F9;
396+
break;
397+
case '1':
398+
if (*(++(*buf)) == '~')
399+
return KEY_F10;
400+
break;
401+
case '3':
402+
if (*(++(*buf)) == '~')
403+
return KEY_F11;
404+
break;
405+
case '4':
406+
if (*(++(*buf)) == '~')
407+
return KEY_F12;
408+
break;
409+
case '~':
410+
return KEY_INS;
411+
}
412+
break;
413+
case '3':
414+
if (*(++(*buf)) == '~')
415+
return KEY_DEL;
416+
break;
417+
case '5':
418+
if (*(++(*buf)) == '~')
419+
return KEY_PGUP;
420+
break;
421+
case '6':
422+
if (*(++(*buf)) == '~')
423+
return KEY_PGDN;
424+
break;
247425
}
426+
break;
427+
case 'O':
428+
(*buf)++;
429+
switch (**buf) {
430+
case 'P':
431+
return KEY_F1;
432+
case 'Q':
433+
return KEY_F2;
434+
case 'R':
435+
return KEY_F3;
436+
case 'S':
437+
return KEY_F4;
438+
}
439+
break;
248440
default:
249441
return KEY_ESCAPE;
250442
}
251443
case ' ':
252-
(*buf)++;
253444
return KEY_FIRE;
254445
default:
255-
return tolower(*((*buf)++));
446+
return tolower(**buf);
256447
}
448+
return '\0';
257449
}
450+
#endif
258451

259452
void DG_ReadInput(void)
260453
{
261-
static char prev_input_buffer[INPUT_BUFFER_LEN];
262-
static char raw_input_buffer[INPUT_BUFFER_LEN];
454+
static unsigned char prev_input_buffer[INPUT_BUFFER_LEN];
263455

264456
memcpy(prev_input_buffer, input_buffer, INPUT_BUFFER_LEN);
265-
memset(raw_input_buffer, '\0', INPUT_BUFFER_LEN);
266457
memset(input_buffer, '\0', INPUT_BUFFER_LEN);
267458
memset(event_buffer, '\0', 2u * EVENT_BUFFER_LEN);
268459
event_buf_loc = event_buffer;
269-
#if defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
270-
struct termios oldt, newt;
271-
272-
/* Disable canonical mode */
273-
CALL(tcgetattr(STDIN_FILENO, &oldt), "DG_DrawFrame: tcgetattr error %d");
274-
newt = oldt;
275-
newt.c_lflag &= ~(ICANON);
276-
newt.c_cc[VMIN] = 0;
277-
newt.c_cc[VTIME] = 0;
278-
CALL(tcsetattr(STDIN_FILENO, TCSANOW, &newt), "DG_DrawFrame: tcsetattr error %d");
279-
280-
CALL(read(2, raw_input_buffer, INPUT_BUFFER_LEN - 1u) < 0, "DG_DrawFrame: read error %d");
281-
282-
CALL(tcsetattr(STDIN_FILENO, TCSANOW, &oldt), "DG_DrawFrame: tcsetattr error %d");
283-
284-
/* Flush input buffer to prevent read of previous unread input */
285-
CALL(tcflush(STDIN_FILENO, TCIFLUSH), "DG_DrawFrame: tcflush error %d");
286-
#else /* defined(OS_WINDOWS) */
460+
#ifdef OS_WINDOWS
287461
const HANDLE hInputHandle = GetStdHandle(STD_INPUT_HANDLE);
288462
WINDOWS_CALL(hInputHandle == INVALID_HANDLE_VALUE, "DG_ReadInput: %s");
289463

@@ -306,21 +480,46 @@ void DG_ReadInput(void)
306480
DWORD i;
307481
for (i = 0; i < event_cnt; i++) {
308482
if (input_records[i].Event.KeyEvent.bKeyDown && input_records[i].EventType == KEY_EVENT) {
309-
raw_input_buffer[input_count++] = input_records[i].Event.KeyEvent.uChar.AsciiChar;
310-
if (input_count == INPUT_BUFFER_LEN - 1u)
311-
break;
483+
unsigned char inp = convertToDoomKey(input_records[i].Event.KeyEvent.wVirtualKeyCode, input_records[i].Event.KeyEvent.uChar.AsciiChar);
484+
if (inp) {
485+
input_buffer[input_count++] = inp;
486+
if (input_count == INPUT_BUFFER_LEN - 1u)
487+
break;
488+
}
312489
}
313490
}
314491
}
315492

316493
WINDOWS_CALL(!SetConsoleMode(hInputHandle, old_mode), "DG_ReadInput: %s");
317-
#endif
494+
#else /* defined(OS_WINDOWS) */
495+
static char raw_input_buffer[INPUT_BUFFER_LEN];
496+
struct termios oldt, newt;
497+
498+
memset(raw_input_buffer, '\0', INPUT_BUFFER_LEN);
499+
500+
/* Disable canonical mode */
501+
CALL(tcgetattr(STDIN_FILENO, &oldt), "DG_DrawFrame: tcgetattr error %d");
502+
newt = oldt;
503+
newt.c_lflag &= ~(ICANON);
504+
newt.c_cc[VMIN] = 0;
505+
newt.c_cc[VTIME] = 0;
506+
CALL(tcsetattr(STDIN_FILENO, TCSANOW, &newt), "DG_DrawFrame: tcsetattr error %d");
507+
508+
CALL(read(2, raw_input_buffer, INPUT_BUFFER_LEN - 1u) < 0, "DG_DrawFrame: read error %d");
509+
510+
CALL(tcsetattr(STDIN_FILENO, TCSANOW, &oldt), "DG_DrawFrame: tcsetattr error %d");
511+
512+
/* Flush input buffer to prevent read of previous unread input */
513+
CALL(tcflush(STDIN_FILENO, TCIFLUSH), "DG_DrawFrame: tcflush error %d");
514+
318515
/* create input buffer */
319516
char *raw_input_buf_loc = raw_input_buffer;
320-
char *input_buf_loc = input_buffer;
321-
while (*raw_input_buf_loc)
517+
unsigned char *input_buf_loc = input_buffer;
518+
while (*raw_input_buf_loc) {
322519
*input_buf_loc++ = convertToDoomKey(&raw_input_buf_loc);
323-
520+
raw_input_buf_loc++;
521+
}
522+
#endif
324523
/* construct event array */
325524
int i, j;
326525
for (i = 0; input_buffer[i]; i++) {

0 commit comments

Comments
 (0)