Last active
October 22, 2019 04:58
-
-
Save kou1okada/1642394e874c6054a077 to your computer and use it in GitHub Desktop.
tty_getkey - Multiplatform simplified non-blocking keyboard input routine.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* msleep - sleep for microseconds | |
* Copyright 2014 (c) Koichi OKADA. All rights reserved. | |
* This file is distributed under the MIT license. | |
* http://www.opensource.org/licenses/mit-license.php | |
*/ | |
#ifndef MSLEEP_H | |
#define MSLEEP_H | |
#if defined(_WIN32) | |
#include <windows.h> | |
#define msleep Sleep | |
#define sleep(x) Sleep((x)*1000) | |
#elif defined(__unix__) | |
#include <unistd.h> | |
#define msleep(x) usleep((x)*1000) | |
#endif//defined(_WIN32),defined(__unix__) | |
#endif//USLEEP_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* tty_getkey - Multiplatform simplified non-blocking keyboard input routine. | |
* Copyright 2014 (c) Koichi OKADA. All rights reserved. | |
* This file is distributed under the MIT license. | |
* http://www.opensource.org/licenses/mit-license.php | |
*/ | |
// Reference: | |
// comp.lang.c FAQ list * Question 19.1 | |
// Q: How can I read a single character from the keyboard without waiting for the RETURN key? | |
// How can I stop characters from being echoed on the screen as they're typed? | |
// http://c-faq.com/osdep/cbreak.html | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdarg.h> | |
#include "tty_getkey.h" | |
// Reference: | |
// C/C++ tip: How to detect the operating system type using compiler predefined macros | |
// http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system | |
#if defined(_WIN32) | |
void tty_setxy(int x, int y) | |
{ | |
gotoxy(x + 1, y + 1); | |
} | |
int tty_getx(void) | |
{ | |
return wherex() - 1; | |
} | |
int tty_gety(void) | |
{ | |
return wherey() - 1; | |
} | |
int tty_getw(void) | |
{ | |
struct text_info info; | |
gettextinfo(&info); | |
return info.screenwidth; | |
} | |
int tty_geth(void) | |
{ | |
struct text_info info; | |
gettextinfo(&info); | |
return info.screenheight; | |
} | |
static char *initial_txt = NULL; | |
static int initial_x; | |
static int initial_y; | |
static int initial_w; | |
static int initial_h; | |
int tty_begin(void) | |
{ | |
textmode(C80X21); | |
initial_x = tty_getx(); | |
initial_y = tty_gety(); | |
initial_w = tty_getw(); | |
initial_h = tty_geth(); | |
initial_txt = malloc(initial_w * initial_h * 2); | |
gettext(1, 1, initial_w, initial_h, initial_txt); | |
clrscr(); | |
return 0; | |
} | |
int tty_end(void) | |
{ | |
puttext(1, 1, initial_w, initial_h, initial_txt); | |
free(initial_txt); | |
tty_setxy(initial_x, initial_y); | |
return 0; | |
} | |
int tty_getkey(void) | |
{ | |
int c = getch(); | |
if (c == 0) { | |
switch (c = getch()) { | |
case 0x3b: c = KEY_F1; break; | |
case 0x3c: c = KEY_F2; break; | |
case 0x3d: c = KEY_F3; break; | |
case 0x3e: c = KEY_F4; break; | |
case 0x3f: c = KEY_F5; break; | |
case 0x40: c = KEY_F6; break; | |
case 0x41: c = KEY_F7; break; | |
case 0x42: c = KEY_F8; break; | |
case 0x43: c = KEY_F9; break; | |
case 0x44: c = KEY_F10; break; | |
case 0x47: c = KEY_HOME; break; | |
case 0x48: c = KEY_UP; break; | |
case 0x49: c = KEY_PAGEUP; break; | |
case 0x4b: c = KEY_LEFT; break; | |
case 0x4d: c = KEY_RIGHT; break; | |
case 0x4f: c = KEY_END; break; | |
case 0x50: c = KEY_DOWN; break; | |
case 0x51: c = KEY_PAGEDOWN; break; | |
case 0x52: c = KEY_INSERT; break; | |
case 0x53: c = KEY_DELETE; break; | |
case 0x54: c = KEY_F13; break; | |
case 0x55: c = KEY_F14; break; | |
case 0x56: c = KEY_F15; break; | |
case 0x57: c = KEY_F16; break; | |
case 0x58: c = KEY_F17; break; | |
case 0x59: c = KEY_F18; break; | |
case 0x5a: c = KEY_F19; break; | |
case 0x5b: c = KEY_F20; break; | |
case 0x5c: c = KEY_F21; break; | |
case 0x5d: c = KEY_F22; break; | |
case 0x5e: c = KEY_F25; break; | |
case 0x5f: c = KEY_F26; break; | |
case 0x60: c = KEY_F27; break; | |
case 0x61: c = KEY_F28; break; | |
case 0x62: c = KEY_F29; break; | |
case 0x63: c = KEY_F30; break; | |
case 0x64: c = KEY_F31; break; | |
case 0x65: c = KEY_F32; break; | |
case 0x66: c = KEY_F33; break; | |
case 0x67: c = KEY_F34; break; | |
case 0x68: c = KEY_F37; break; | |
case 0x69: c = KEY_F38; break; | |
case 0x6a: c = KEY_F39; break; | |
case 0x6b: c = KEY_F40; break; | |
case 0x6c: c = KEY_F41; break; | |
case 0x6d: c = KEY_F42; break; | |
case 0x6e: c = KEY_F43; break; | |
case 0x6f: c = KEY_F44; break; | |
case 0x70: c = KEY_F45; break; | |
case 0x71: c = KEY_F46; break; | |
case 0x85: c = KEY_F11; break; | |
case 0x86: c = KEY_F12; break; | |
case 0x87: c = KEY_F23; break; | |
case 0x88: c = KEY_F24; break; | |
case 0x89: c = KEY_F35; break; | |
case 0x8a: c = KEY_F36; break; | |
case 0x8b: c = KEY_F47; break; | |
case 0x8c: c = KEY_F48; break; | |
} | |
} else { | |
switch (c) { | |
case 0x08: c = KEY_BACKSPACE; break; | |
case 0x0d: c = KEY_ENTER; break; | |
} | |
} | |
return c; | |
} | |
int tty_iskeyhit(void) | |
{ | |
return kbhit(); | |
} | |
#elif defined(__unix__) | |
void tty_setxy(int x, int y) | |
{ | |
move(y, x); | |
} | |
int tty_getx(void) | |
{ | |
int x, y; | |
getyx(stdscr, y, x); | |
return x; | |
} | |
int tty_gety(void) | |
{ | |
int x, y; | |
getyx(stdscr, y, x); | |
return y; | |
} | |
int tty_getw(void) | |
{ | |
int x, y; | |
getmaxyx(stdscr, y, x); | |
return x; | |
} | |
int tty_geth(void) | |
{ | |
int x, y; | |
getmaxyx(stdscr, y, x); | |
return y; | |
} | |
// Reference: | |
// How can I perform pre-main initialization in C/C++ with avr-gcc? | |
// http://stackoverflow.com/questions/949890/how-can-i-perform-pre-main-initialization-in-c-c-with-avr-gcc | |
int tty_begin(void) | |
{ | |
initscr(); | |
noecho(); | |
cbreak(); | |
keypad(stdscr, TRUE); | |
return 0; | |
} | |
int tty_end(void) | |
{ | |
echo(); | |
nocbreak(); | |
endwin(); | |
return 0; | |
} | |
int tty_getkey(void) | |
{ | |
int c = getch(); | |
switch (c) { | |
case 0x0a: c = KEY_ENTER; break; | |
} | |
return c; | |
} | |
int tty_iskeyhit(void) | |
{ | |
int c; | |
timeout(0); | |
c = tty_getkey(); | |
timeout(-1); | |
if (c != ERR) { | |
ungetch(c); | |
} | |
return c != ERR; | |
} | |
#else | |
#error "_WIN32 and __unix__ macro is undefined." | |
#endif//defined(_WIN32),defined(__unix__) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* tty_getkey - Multiplatform simplified non-blocking keyboard input routine. | |
* Copyright 2014 (c) Koichi OKADA. All rights reserved. | |
* This file is distributed under the MIT license. | |
* http://www.opensource.org/licenses/mit-license.php | |
*/ | |
#ifndef TTY_GETKEY_H | |
#define TTY_GETKEY_H | |
#if defined(_WIN32) | |
#include <conio.h> | |
#define KEY_DOWN 0x102 | |
#define KEY_UP 0x103 | |
#define KEY_LEFT 0x104 | |
#define KEY_RIGHT 0x105 | |
#define KEY_HOME 0x106 | |
#define KEY_BACKSPACE 0x107 | |
#define KEY_PPAGE 0x153 | |
#define KEY_NPAGE 0x152 | |
#define KEY_HOME 0x106 | |
#define KEY_END 0x168 | |
#define KEY_IC 0x14b | |
#define KEY_DC 0x14a | |
#define KEY_F1 0x109 | |
#define KEY_F2 0x10a | |
#define KEY_F3 0x10b | |
#define KEY_F4 0x10c | |
#define KEY_F5 0x10d | |
#define KEY_F6 0x10e | |
#define KEY_F7 0x10f | |
#define KEY_F8 0x110 | |
#define KEY_F9 0x111 | |
#define KEY_F10 0x112 | |
#define KEY_F11 0x113 | |
#define KEY_F12 0x114 | |
#define KEY_F13 0x115 | |
#define KEY_F14 0x116 | |
#define KEY_F15 0x117 | |
#define KEY_F16 0x118 | |
#define KEY_F17 0x119 | |
#define KEY_F18 0x11a | |
#define KEY_F19 0x11b | |
#define KEY_F20 0x11c | |
#define KEY_F21 0x11d | |
#define KEY_F22 0x11e | |
#define KEY_F23 0x11f | |
#define KEY_F24 0x120 | |
#define KEY_F25 0x121 | |
#define KEY_F26 0x122 | |
#define KEY_F27 0x123 | |
#define KEY_F28 0x124 | |
#define KEY_F29 0x125 | |
#define KEY_F30 0x126 | |
#define KEY_F31 0x127 | |
#define KEY_F32 0x128 | |
#define KEY_F33 0x129 | |
#define KEY_F34 0x12a | |
#define KEY_F35 0x12b | |
#define KEY_F36 0x12c | |
#define KEY_F37 0x12d | |
#define KEY_F38 0x12e | |
#define KEY_F39 0x12f | |
#define KEY_F40 0x130 | |
#define KEY_F41 0x131 | |
#define KEY_F42 0x132 | |
#define KEY_F43 0x133 | |
#define KEY_F44 0x134 | |
#define KEY_F45 0x135 | |
#define KEY_F46 0x136 | |
#define KEY_F47 0x137 | |
#define KEY_F48 0x138 | |
#define KEY_ENTER 0x157 | |
#define tty_printf cprintf | |
#elif defined(__unix__) | |
#include <ncurses/curses.h> | |
#define KEY_BS KEY_BACKSPACE | |
#define tty_printf printw | |
#endif//defined(_WIN32),defined(__unix__) | |
#define KEY_TAB 0x09 | |
#define KEY_ESC 0x1b | |
#define KEY_SPACE 0x20 | |
#define KEY_SP 0x20 | |
//#define KEY_ENTER 0x0a | |
#define KEY_BS KEY_BACKSPACE | |
#define KEY_PAGEUP KEY_PPAGE | |
#define KEY_PAGEDOWN KEY_NPAGE | |
#define KEY_DEL KEY_DC | |
#define KEY_DELETE KEY_DC | |
#define KEY_INS KEY_IC | |
#define KEY_INSERT KEY_IC | |
void tty_setxy(int x, int y); | |
int tty_getx(void); | |
int tty_gety(void); | |
int tty_getw(void); | |
int tty_geth(void); | |
//int tty_printf(char *format, ...); | |
int tty_begin(void); | |
int tty_end(void); | |
int tty_getkey(void); | |
int tty_iskeyhit(void); | |
#endif//TTY_GETKEY_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* tty_getkey_sample - sample program for tty_getkey | |
* Copyright 2014 (c) Koichi OKADA. All rights reserved. | |
* This file is distributed under the MIT license. | |
* http://www.opensource.org/licenses/mit-license.php | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include "tty_getkey.h" | |
#include "msleep.h" | |
int main() | |
{ | |
int c; | |
tty_begin(); | |
while(tty_iskeyhit() == 0) { | |
msleep(1); | |
} | |
c = tty_getkey(); | |
tty_printf("%#x key was hit.\n", c); | |
tty_printf("Hit ESC key to exit.\n"); | |
while(KEY_ESC != tty_getkey()) { | |
; | |
} | |
tty_end(); | |
return EXIT_SUCCESS; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* tty_getkey_sample - sample program for tty_getkey | |
* Copyright 2014 (c) Koichi OKADA. All rights reserved. | |
* This file is distributed under the MIT license. | |
* http://www.opensource.org/licenses/mit-license.php | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include "tty_getkey.h" | |
int main(int argc, char *argv[]) | |
{ | |
int c; | |
int x, y, w, h; | |
tty_begin(); | |
w = tty_getw(); | |
h = tty_geth(); | |
x = w / 2; | |
y = h / 2; | |
tty_setxy(x, y); | |
tty_printf("*"); | |
while (KEY_ESC != (c = tty_getkey())) { | |
switch (c) { | |
case KEY_UP: y--; break; | |
case KEY_DOWN: y++; break; | |
case KEY_RIGHT: x++; break; | |
case KEY_LEFT: x--; break; | |
} | |
x = x < 1 ? 1 : w - 2 < x ? w - 2 : x; | |
y = y < 1 ? 1 : h - 2 < y ? h - 2 : y; | |
tty_setxy(0,0); | |
tty_printf("(%2d,%2d) : %#06x", x, y, c); | |
tty_setxy(x, y); | |
tty_printf("*"); | |
} | |
tty_end(); | |
return EXIT_SUCCESS; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* tty_getkey_sample - sample program for tty_getkey | |
* Copyright 2014 (c) Koichi OKADA. All rights reserved. | |
* This file is distributed under the MIT license. | |
* http://www.opensource.org/licenses/mit-license.php | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include "tty_getkey.h" | |
#include "msleep.h" | |
#define frand() (rand() / (RAND_MAX + 1.0)) | |
int main() | |
{ | |
int c, d; | |
tty_begin(); | |
while(tty_iskeyhit() == 0) { | |
d = frand() * 6 + 1; | |
tty_setxy(0, 0); | |
tty_printf("%d", d); | |
msleep(1); | |
} | |
msleep(3000); | |
tty_end(); | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment