28
28
29
29
#if defined(_WIN32 ) || defined(WIN32 )
30
30
#define OS_WINDOWS
31
+ #define WIN32_LEAN_AND_MEAN
31
32
#include <windows.h>
32
33
#else
33
34
#include <sys/ioctl.h>
@@ -111,10 +112,30 @@ char *output_buffer;
111
112
size_t output_buffer_size ;
112
113
struct timespec ts_init ;
113
114
114
- char input_buffer [INPUT_BUFFER_LEN ];
115
+ unsigned char input_buffer [INPUT_BUFFER_LEN ];
115
116
uint16_t event_buffer [EVENT_BUFFER_LEN ];
116
117
uint16_t * event_buf_loc ;
117
118
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
+
118
139
void DG_Init ()
119
140
{
120
141
#ifdef OS_WINDOWS
@@ -128,9 +149,16 @@ void DG_Init()
128
149
const HANDLE hInputHandle = GetStdHandle (STD_INPUT_HANDLE );
129
150
WINDOWS_CALL (hInputHandle == INVALID_HANDLE_VALUE , "DG_Init: %s" );
130
151
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 );
132
153
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" );
133
159
#endif
160
+ atexit (& DG_AtExit );
161
+
134
162
/* Longest SGR code: \033[38;2;RRR;GGG;BBBm (length 19)
135
163
* Maximum 21 bytes per pixel: SGR + 2 x char
136
164
* 1 Newline character per line
@@ -220,11 +248,105 @@ uint32_t DG_GetTicksMs()
220
248
return (ts .tv_sec - ts_init .tv_sec ) * 1000 + (ts .tv_nsec - ts_init .tv_nsec ) / 1000000 ;
221
249
}
222
250
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 )
224
347
{
225
348
switch (* * buf ) {
226
349
case '\012' :
227
- (* buf )++ ;
228
350
return KEY_ENTER ;
229
351
case '\033' :
230
352
(* buf )++ ;
@@ -233,57 +355,109 @@ char convertToDoomKey(char **buf)
233
355
(* buf )++ ;
234
356
switch (* * buf ) {
235
357
case 'A' :
236
- (* buf )++ ;
237
358
return KEY_UPARROW ;
238
359
case 'B' :
239
- (* buf )++ ;
240
360
return KEY_DOWNARROW ;
241
361
case 'C' :
242
- (* buf )++ ;
243
362
return KEY_RIGHTARROW ;
244
363
case 'D' :
245
- (* buf )++ ;
246
364
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 ;
247
425
}
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 ;
248
440
default :
249
441
return KEY_ESCAPE ;
250
442
}
251
443
case ' ' :
252
- (* buf )++ ;
253
444
return KEY_FIRE ;
254
445
default :
255
- return tolower (* (( * buf ) ++ ) );
446
+ return tolower (* * buf );
256
447
}
448
+ return '\0' ;
257
449
}
450
+ #endif
258
451
259
452
void DG_ReadInput (void )
260
453
{
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 ];
263
455
264
456
memcpy (prev_input_buffer , input_buffer , INPUT_BUFFER_LEN );
265
- memset (raw_input_buffer , '\0' , INPUT_BUFFER_LEN );
266
457
memset (input_buffer , '\0' , INPUT_BUFFER_LEN );
267
458
memset (event_buffer , '\0' , 2u * EVENT_BUFFER_LEN );
268
459
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
287
461
const HANDLE hInputHandle = GetStdHandle (STD_INPUT_HANDLE );
288
462
WINDOWS_CALL (hInputHandle == INVALID_HANDLE_VALUE , "DG_ReadInput: %s" );
289
463
@@ -306,21 +480,46 @@ void DG_ReadInput(void)
306
480
DWORD i ;
307
481
for (i = 0 ; i < event_cnt ; i ++ ) {
308
482
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
+ }
312
489
}
313
490
}
314
491
}
315
492
316
493
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
+
318
515
/* create input buffer */
319
516
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 ) {
322
519
* input_buf_loc ++ = convertToDoomKey (& raw_input_buf_loc );
323
-
520
+ raw_input_buf_loc ++ ;
521
+ }
522
+ #endif
324
523
/* construct event array */
325
524
int i , j ;
326
525
for (i = 0 ; input_buffer [i ]; i ++ ) {
0 commit comments