├── .gitignore ├── Makefile ├── UNLICENSE ├── README.md ├── demo ├── rand.c └── game.c ├── rlhk_rand.h ├── rlhk_algo.h └── rlhk_tui.h /.gitignore: -------------------------------------------------------------------------------- 1 | demo/game 2 | demo/game.exe 3 | demo/rand 4 | demo/rand.exe 5 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .POSIX: 2 | CC = cc 3 | CFLAGS = -ansi -pedantic -Os -Wall -Wextra -Wno-unused-function -g3 4 | LDLIBS = -lm 5 | SUFFIX = 6 | 7 | .SUFFIXES: .c $(SUFFIX) 8 | 9 | all: demo/game$(SUFFIX) demo/rand$(SUFFIX) 10 | 11 | demo/game$(SUFFIX): demo/game.c rlhk_tui.h rlhk_rand.h rlhk_algo.h 12 | demo/rand$(SUFFIX): demo/rand.c rlhk_tui.h rlhk_rand.h 13 | 14 | .c$(SUFFIX): 15 | $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS) 16 | 17 | clean: 18 | rm -f demo/game$(SUFFIX) demo/rand$(SUFFIX) 19 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Roguelike Header Kit (RLHK) 2 | 3 | The Roguelike Header Kit is a collection of public domain, portable, 4 | efficient, C header libraries for creating roguelikes. If your goal is 5 | a terminal / console roguelike, then you won't need any additional 6 | libraries — no ncurses, libtcod, etc — and since these are header 7 | libraries it's trivial to integrate without any linking headaches. 8 | 9 | ## Supported platforms 10 | 11 | * POSIX (ANSI terminal with UTF-8 encoding) 12 | * Win32 console 13 | * MS-DOS (DJGPP, requires [DPMI server][dpmi], e.g. cwsdpmi.exe) 14 | 15 | Assuming the proper compilers are available, try out the demo on 16 | different platforms: 17 | 18 | make CC=x86_64-linux-gnu-gcc 19 | make CC=x86_64-w64-mingw32-gcc SUFFIX=.exe 20 | make CC=i586-pc-msdosdjgpp-gcc SUFFIX=.exe 21 | 22 | The demo can also be built using Visual Studio's cl.exe, though not 23 | with this Makefile. 24 | 25 | ## Design Philosophy 26 | 27 | RLHK is designed for single-threaded roguelikes that completely blocks 28 | on user input. While this isn't *strictly* required, should you want to 29 | use multiple threads be mindful that RLHK functions are neither 30 | thread-safe nor re-entrant. 31 | 32 | For maximum portability, RLHK is written in strict ANSI C89 except for 33 | some isolated bits of platform-specific code. RLHK also uses none of 34 | the `stdio.h` functions, meaning your program won't have to link with 35 | these formatted output functions in a static build. 36 | 37 | RLHK functions do not make dynamic allocations. Either static storage 38 | is used, or a work buffer must be passed to the function, such as the 39 | case for `rlhk_algo_shortest()`. 40 | 41 | RLHK, being a header library, is designed to be embedded within your 42 | program. This reflected through its API, such as not using function 43 | pointers for callbacks. Its functions are intended to inline naturally 44 | with your program's own functions. For example, a modern optimizing 45 | compiler will inline parts of your `rlhk_algo_map_call()` directly 46 | into the library's functions, eliminating many of those function 47 | calls. Think of it like poor-man's templates but with cleaner 48 | semantics and faster compilation. 49 | 50 | ## Character Set 51 | 52 | Any ASCII character can be used directly as-is. For fancier 53 | characters, `rlhk_tui.h` provides a fully portable character set that 54 | work on the more limited Windows console and MS-DOS. It's essentially 55 | just [code page 437][cp437]. Each character is available in the host 56 | system's encoding via the macros named `RLHK_TUI_`. 57 | 58 | 59 | [dpmi]: http://www.delorie.com/djgpp/v2faq/faq4_4.html 60 | [cp437]: https://en.wikipedia.org/wiki/Code_page_437 61 | -------------------------------------------------------------------------------- /demo/rand.c: -------------------------------------------------------------------------------- 1 | #define RLHK_API static 2 | #define RLHK_IMPLEMENTATION 3 | #include "../rlhk_tui.h" 4 | #include "../rlhk_rand.h" 5 | 6 | #include 7 | #include 8 | 9 | #define MIN(a, b) ((b) < (a) ? (b) : (a)) 10 | #define MAX(a, b) ((b) > (a) ? (b) : (a)) 11 | #define WHITE RLHK_TUI_FR | RLHK_TUI_FG | RLHK_TUI_FB | RLHK_TUI_FH 12 | #define GREEN RLHK_TUI_FG | RLHK_TUI_FH 13 | 14 | enum func { 15 | FUNC_NORM 16 | }; 17 | 18 | static void 19 | bin_fill(unsigned long *bins, 20 | int nbins, 21 | long n, 22 | unsigned long *rng, 23 | enum func func) 24 | { 25 | int i, j; 26 | 27 | for (i = 0; i < n; i++) { 28 | switch (func) { 29 | case FUNC_NORM: { 30 | double s[2]; 31 | rlhk_rand_norm(rng, s + 0, s + 1); 32 | for (j = 0; j < 2; j++) { 33 | int v = s[j] * nbins / 6.0 + nbins / 2.0 + 0.5; 34 | if (v >= 0 && v < nbins) 35 | bins[v]++; 36 | } 37 | } break; 38 | } 39 | } 40 | } 41 | 42 | static void 43 | bin_draw(unsigned long *bins, int width, int height) 44 | { 45 | int x, y; 46 | unsigned long bin_max = 0; 47 | 48 | for (x = 0; x < width; x++) 49 | if (bins[x] > bin_max) 50 | bin_max = bins[x]; 51 | 52 | for (x = 0; x < width; x++) { 53 | int s = height * bins[x] / (double)bin_max; 54 | for (y = 0; y < height; y++) { 55 | unsigned c = ' '; 56 | if (y <= s - 4) 57 | c = RLHK_TUI_FULL_BLOCK; 58 | else if (y <= s - 3) 59 | c = RLHK_TUI_DARK_SHADE; 60 | else if (y <= s - 2) 61 | c = RLHK_TUI_MEDIUM_SHADE; 62 | else if (y <= s - 1) 63 | c = RLHK_TUI_LIGHT_SHADE; 64 | rlhk_tui_putc(x, height - y - 1, c, WHITE); 65 | } 66 | } 67 | rlhk_tui_flush(); 68 | } 69 | 70 | static void 71 | print(int width, const char *s) 72 | { 73 | int len = strlen(s); 74 | int x; 75 | for (x = 0; s[x]; x++) 76 | rlhk_tui_putc(width - len + x, 0, s[x], GREEN); 77 | } 78 | 79 | int 80 | main(void) 81 | { 82 | int width = 0; 83 | int height = 0; 84 | unsigned long rng[1]; 85 | unsigned long bins[RLHK_TUI_MAX_WIDTH]; 86 | int i; 87 | 88 | if (!rlhk_tui_size(&width, &height)) 89 | abort(); 90 | width = MIN(width, RLHK_TUI_MAX_WIDTH); 91 | height = MIN(height, RLHK_TUI_MAX_HEIGHT); 92 | rlhk_tui_init(width, height); 93 | rlhk_rand_entropy(rng, 4); 94 | 95 | memset(bins, 0, sizeof(bins)); 96 | for (i = 0; i < 10000; i++) { 97 | bin_fill(bins, width, 100, rng, FUNC_NORM); 98 | bin_draw(bins, width, height); 99 | } 100 | print(width, "Press any key ..."); 101 | rlhk_tui_flush(); 102 | rlhk_tui_getch(); 103 | 104 | rlhk_tui_release(); 105 | 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /rlhk_rand.h: -------------------------------------------------------------------------------- 1 | #ifndef RLHK_RAND_H 2 | #define RLHK_RAND_H 3 | 4 | #ifndef RLHK_RAND_API 5 | # ifdef RLHK_API 6 | # define RLHK_RAND_API RLHK_API 7 | # else 8 | # define RLHK_RAND_API 9 | # endif 10 | #endif 11 | 12 | /** 13 | * Fill a buffer with true entropy from the operating system. 14 | * 15 | * This shouldn't be used directly to generate numbers, but rather to 16 | * seed a PRNG. 17 | * 18 | * Returns 1 on success, 0 on failure (leaving buf untouched). 19 | */ 20 | RLHK_RAND_API 21 | int rlhk_rand_entropy(void *buf, unsigned len); 22 | 23 | /** 24 | * Generate a uniform 32-bit integer from a 32-bit state. 25 | */ 26 | RLHK_RAND_API 27 | unsigned long rlhk_rand_32(unsigned long *); 28 | 29 | /* Implementation */ 30 | #if defined(RLHK_IMPLEMENTATION) || defined(RLHK_RAND_IMPLEMENTATION) 31 | #include 32 | 33 | /* System entropy. */ 34 | #if (defined(__unix__) || defined(__APPLE__)) && !defined(__DJGPP__) 35 | #include 36 | #include 37 | 38 | RLHK_RAND_API 39 | int 40 | rlhk_rand_entropy(void *buf, unsigned len) 41 | { 42 | int fd = open("/dev/urandom", O_RDONLY); 43 | int success = 0; 44 | if (fd != -1) { 45 | success = read(fd, buf, len) == len; 46 | close(fd); 47 | } 48 | return success; 49 | } 50 | 51 | #elif defined(_WIN32) 52 | #include 53 | 54 | RLHK_RAND_API 55 | int 56 | rlhk_rand_entropy(void *buf, unsigned len) 57 | { 58 | HCRYPTPROV h = 0; 59 | DWORD type = PROV_RSA_FULL; 60 | DWORD flags = CRYPT_VERIFYCONTEXT | CRYPT_SILENT; 61 | int success = 62 | CryptAcquireContext(&h, 0, 0, type, flags) && 63 | CryptGenRandom(h, len, buf); 64 | if (h) 65 | CryptReleaseContext(h, 0); 66 | return success; 67 | } 68 | #elif defined(__MSDOS__) 69 | #include 70 | 71 | RLHK_RAND_API 72 | int 73 | rlhk_rand_entropy(void *buf, unsigned len) 74 | { 75 | /* Best option is the clock. */ 76 | unsigned long t = time(0); 77 | char *e = (char *)buf + len; 78 | char *p = buf; 79 | while (p != e) { 80 | unsigned long v = rlhk_rand_32(&t); 81 | int z = e - p > 4 ? 4 : e - p; 82 | memcpy(p, &v, z); 83 | p += z; 84 | } 85 | return 1; 86 | } 87 | 88 | #endif /* __MSDOS__ */ 89 | 90 | RLHK_RAND_API 91 | unsigned long 92 | rlhk_rand_32(unsigned long *state) 93 | { 94 | unsigned long x = *state; 95 | x ^= x << 13; 96 | x ^= (x & 0xffffffffUL) >> 17; 97 | x ^= x << 5; 98 | return (*state = x) & 0xffffffffUL; 99 | } 100 | 101 | RLHK_RAND_API 102 | double 103 | rlhk_rand_uniform(unsigned long *s) 104 | { 105 | return rlhk_rand_32(s) / (double)0xffffffffUL; 106 | } 107 | 108 | RLHK_RAND_API 109 | void 110 | rlhk_rand_norm(unsigned long *s, double *n0, double *n1) 111 | { 112 | double x0, x1, w; 113 | do { 114 | x0 = 2 * rlhk_rand_uniform(s) - 1; 115 | x1 = 2 * rlhk_rand_uniform(s) - 1; 116 | w = x0 * x0 + x1 * x1; 117 | } while (w >= 1); 118 | w = sqrt((-2.0 * log(w)) / w); 119 | *n0 = x0 * w; 120 | *n1 = x1 * w; 121 | } 122 | 123 | #endif /* RLHK_RAND_IMPLEMENTATION */ 124 | #endif /* RLHK_RAND_H */ 125 | -------------------------------------------------------------------------------- /demo/game.c: -------------------------------------------------------------------------------- 1 | typedef int rlhk_algo_map; 2 | 3 | #define RLHK_API 4 | #define RLHK_IMPLEMENTATION 5 | #include "../rlhk_tui.h" 6 | #include "../rlhk_rand.h" 7 | #include "../rlhk_algo.h" 8 | 9 | #include 10 | #include 11 | 12 | static int width; 13 | static int height; 14 | static int fov_radius = 12; 15 | 16 | #define TILE_EMPTY_C RLHK_TUI_FULL_STOP 17 | #define TILE_EMPTY_A (RLHK_TUI_FR | RLHK_TUI_FG | RLHK_TUI_FB) 18 | #define TILE_DIRT_C RLHK_TUI_MEDIUM_SHADE 19 | #define TILE_DIRT_A (RLHK_TUI_FR | RLHK_TUI_FG | RLHK_TUI_FB) 20 | #define TILE_WALL_C RLHK_TUI_FULL_BLOCK 21 | #define TILE_WALL_A (RLHK_TUI_FR | RLHK_TUI_FG | RLHK_TUI_FB) 22 | #define TILE_PLAYER_C RLHK_TUI_COMMERCIAL_AT 23 | #define TILE_PLAYER_A (RLHK_TUI_FR | RLHK_TUI_FB | RLHK_TUI_FH) 24 | 25 | static char game_map[2][RLHK_TUI_MAX_HEIGHT][RLHK_TUI_MAX_WIDTH]; 26 | static char map_marked[RLHK_TUI_MAX_HEIGHT][RLHK_TUI_MAX_WIDTH]; 27 | static char map_visible[RLHK_TUI_MAX_HEIGHT][RLHK_TUI_MAX_WIDTH]; 28 | static char map_route[RLHK_TUI_MAX_HEIGHT][RLHK_TUI_MAX_WIDTH]; 29 | static long map_distance[RLHK_TUI_MAX_HEIGHT][RLHK_TUI_MAX_WIDTH]; 30 | static long map_heuristic[RLHK_TUI_MAX_HEIGHT][RLHK_TUI_MAX_WIDTH]; 31 | 32 | #define IN_MAP(x, y) \ 33 | (x >= 0 && y >= 0 && x < width && y < height) 34 | 35 | #define IN_BOUNDS(x, y) \ 36 | (x > 0 && y > 0 && \ 37 | x < width - 1 && y < height - 1) 38 | 39 | #define ON_BORDER(x, y) \ 40 | (!x || !y || x == width - 1 || y == height - 1) 41 | 42 | static void 43 | map_generate(void) 44 | { 45 | unsigned long rng[1]; 46 | int x, y, i; 47 | 48 | if (!rlhk_rand_entropy(rng, 4)) 49 | abort(); 50 | 51 | memset(game_map, 1, sizeof(game_map)); 52 | for (i = 0; i < width * height / 4; i++) { 53 | double nx, ny; 54 | int x, y; 55 | rlhk_rand_norm(rng, &nx, &ny); 56 | x = nx * width / 6 + width / 2; 57 | y = ny * height / 6 + height / 2; 58 | if (IN_BOUNDS(x, y)) 59 | game_map[1][y][x] = 0; 60 | } 61 | 62 | for (i = 1; i < 3; i++) { 63 | for (y = 1; y < height - 1; y++) { 64 | for (x = 1; x < width - 1; x++) { 65 | int sum = 66 | game_map[i % 2][y - 1][x + 1] + 67 | game_map[i % 2][y - 1][x + 0] + 68 | game_map[i % 2][y - 1][x - 1] + 69 | game_map[i % 2][y + 0][x + 1] + 70 | game_map[i % 2][y + 0][x - 1] + 71 | game_map[i % 2][y + 1][x + 1] + 72 | game_map[i % 2][y + 1][x + 0] + 73 | game_map[i % 2][y + 1][x - 1]; 74 | game_map[(i + 1) % 2][y][x] = sum > 6; 75 | } 76 | } 77 | } 78 | } 79 | 80 | static int draw_dijkstra; 81 | 82 | static void 83 | map_draw(int px, int py) 84 | { 85 | int x, y; 86 | for (y = 0; y < height; y++) 87 | for (x = 0; x < width; x++) { 88 | unsigned visible = map_visible[y][x] ? RLHK_TUI_FH : 0; 89 | if (ON_BORDER(x, y)) 90 | rlhk_tui_putc(x, y, TILE_WALL_C, TILE_WALL_A | visible); 91 | else if (game_map[0][y][x]) 92 | rlhk_tui_putc(x, y, TILE_DIRT_C, TILE_DIRT_A | visible); 93 | else { 94 | unsigned mark = map_marked[y][x] ? RLHK_TUI_BR : 0; 95 | unsigned c = visible ? TILE_EMPTY_C : ' '; 96 | mark |= visible; 97 | if (!draw_dijkstra) { 98 | rlhk_tui_putc(x, y, c, TILE_EMPTY_A | mark); 99 | } else { 100 | unsigned a = TILE_EMPTY_A; 101 | long dist = map_distance[y][x]; 102 | if (dist != -1) { 103 | c = dist % 10 + '0'; 104 | a = RLHK_TUI_FR | RLHK_TUI_FG | RLHK_TUI_FB; 105 | } 106 | rlhk_tui_putc(x, y, c, a | mark); 107 | } 108 | } 109 | } 110 | rlhk_tui_putc(px, py, TILE_PLAYER_C, TILE_PLAYER_A); 111 | if (!rlhk_tui_flush()) 112 | abort(); 113 | } 114 | 115 | RLHK_ALGO_API 116 | long 117 | rlhk_algo_map_call(rlhk_algo_map map, 118 | enum rlhk_algo_map_method method, 119 | int x, int y, long data) 120 | { 121 | size_t i; 122 | long *p; 123 | (void)map; 124 | if (!IN_MAP(x, y)) 125 | abort(); 126 | switch (method) { 127 | case RLHK_ALGO_MAP_GET_PASSABLE: 128 | return game_map[0][y][x] == 0; 129 | case RLHK_ALGO_MAP_CLEAR_DISTANCE: 130 | p = &map_distance[0][0]; 131 | for (i = 0; i < sizeof(map_distance) / sizeof(long); i++) 132 | p[i] = -1; 133 | return data; 134 | case RLHK_ALGO_MAP_SET_DISTANCE: 135 | return (map_distance[y][x] = data); 136 | case RLHK_ALGO_MAP_GET_DISTANCE: 137 | return map_distance[y][x]; 138 | case RLHK_ALGO_MAP_SET_HEURISTIC: 139 | return (map_heuristic[y][x] = data); 140 | case RLHK_ALGO_MAP_GET_HEURISTIC: 141 | return map_heuristic[y][x]; 142 | case RLHK_ALGO_MAP_SET_GRADIENT: 143 | return (map_route[y][x] = data); 144 | case RLHK_ALGO_MAP_MARK_SHORTEST: 145 | map_marked[y][x] = 1; 146 | return map_route[y][x]; 147 | case RLHK_ALGO_MAP_MARK_VISIBLE: 148 | map_visible[y][x] = 1; 149 | return game_map[0][y][x] == 0; 150 | } 151 | abort(); 152 | } 153 | 154 | static void 155 | find_path(int x0, int y0, int x1, int y1) 156 | { 157 | static short buf[1024]; 158 | memset(map_marked, 0, sizeof(map_marked)); 159 | rlhk_algo_shortest(0, x0, y0, x1, y1, buf, sizeof(buf)); 160 | } 161 | 162 | int 163 | main(void) 164 | { 165 | int x, y; 166 | int running = 1; 167 | 168 | if (!rlhk_tui_size(&width, &height)) 169 | abort(); 170 | if (width > RLHK_TUI_MAX_WIDTH) 171 | width = RLHK_TUI_MAX_WIDTH; 172 | if (height > RLHK_TUI_MAX_HEIGHT) 173 | height = RLHK_TUI_MAX_HEIGHT; 174 | x = width / 2; 175 | y = height / 2; 176 | 177 | if (!rlhk_tui_init(width, height)) 178 | abort(); 179 | map_generate(); 180 | 181 | do { 182 | int k; 183 | int dx = 0; 184 | int dy = 0; 185 | 186 | { 187 | short buf[256]; 188 | long i = rlhk_algo_buf_push(buf, sizeof(buf), 0, x, y); 189 | rlhk_algo_dijkstra(0, buf, sizeof(buf), i); 190 | memset(map_visible, 0, sizeof(map_visible)); 191 | rlhk_algo_fov(0, x, y, fov_radius); 192 | } 193 | 194 | map_draw(x, y); 195 | if ((k = rlhk_tui_getch()) == -1) 196 | abort(); 197 | switch (k) { 198 | case RLHK_TUI_VK_L: 199 | case 'h': 200 | dx = -1; dy = 0; 201 | break; 202 | case RLHK_TUI_VK_R: 203 | case 'l': 204 | dx = 1; dy = 0; 205 | break; 206 | case RLHK_TUI_VK_U: 207 | case 'k': 208 | dx = 0; dy = -1; 209 | break; 210 | case RLHK_TUI_VK_D: 211 | case 'j': 212 | dx = 0; dy = 1; 213 | break; 214 | case RLHK_TUI_VK_UL: 215 | case 'y': 216 | dx = -1; dy = -1; 217 | break; 218 | case RLHK_TUI_VK_DL: 219 | case 'b': 220 | dx = -1; dy = 1; 221 | break; 222 | case RLHK_TUI_VK_UR: 223 | case 'u': 224 | dx = 1; dy = -1; 225 | break; 226 | case RLHK_TUI_VK_DR: 227 | case 'n': 228 | dx = 1; dy = 1; 229 | break; 230 | case ' ': 231 | find_path(x, y, width / 2, height / 2); 232 | break; 233 | case '+': 234 | fov_radius++; 235 | break; 236 | case '-': 237 | fov_radius--; 238 | break; 239 | case 'x': 240 | draw_dijkstra = !draw_dijkstra; 241 | break; 242 | case RLHK_TUI_VK_SIGINT: 243 | case 'q': 244 | running = 0; 245 | break; 246 | } 247 | if (!game_map[0][y + dy][x + dx]) { 248 | x += dx; 249 | y += dy; 250 | } 251 | } while (running); 252 | 253 | if (!rlhk_tui_release()) 254 | abort(); 255 | return 0; 256 | } 257 | -------------------------------------------------------------------------------- /rlhk_algo.h: -------------------------------------------------------------------------------- 1 | /* Roguelike Header Kit : Algorithms 2 | * 3 | * This is free and unencumbered software released into the public domain. 4 | * 5 | * Provides a portable set of general roguelike algorithms, largely 6 | * for 2D grid-based maps. In order to use this header you must 7 | * typedef rlhk_algo_map and implement rlhk_algo_map_call(). 8 | * 9 | * For all functions involving gradients or directions, the 8 possible 10 | * directions are represented using the integers 0 through 7. Counting 11 | * up, the directions are clockwise with "0" at twelve o'clock (north) 12 | * and "4" at six o'clock (south). Use the RLHK_ALGO_DX() and 13 | * RLHK_ALGO_DY() to decode the integers 0 through 7 into direction 14 | * deltas for each axis (-1, 0, +1). 15 | * 16 | * Map coordinates are always expected to fit in 16-bit integers 17 | * Negative coordinates are allowed. Path lengths are always expected 18 | * to fit in 32-bit integers. To save on memory, you may not actually 19 | * want to use "long" (possibly 64 bits) in your map representation 20 | * and instead try to specifically use a 32-bit integer. 21 | * 22 | * Functions: 23 | * - rlhk_algo_shortest 24 | * - rlhk_algo_dijkstra 25 | */ 26 | #ifndef RLHK_ALGO_H 27 | #define RLHK_ALGO_H 28 | 29 | #ifndef RLHK_ALGO_API 30 | # ifdef RLHK_API 31 | # define RLHK_ALGO_API RLHK_API 32 | # else 33 | # define RLHK_ALGO_API 34 | # endif 35 | #endif 36 | 37 | #define RLHK_ALGO_DX(i) ((int)((0x0489a621UL >> (4 * (i) + 0)) & 3) - 1) 38 | #define RLHK_ALGO_DY(i) ((int)((0x0489a621UL >> (4 * (i) + 2)) & 3) - 1) 39 | 40 | enum rlhk_algo_map_method { 41 | /** 42 | * Asks if the tile at (x, y) is passable coming from the 43 | * direction indicated via "data". Return non-zero for true, 0 for 44 | * false. 45 | * 46 | * To get strict 4-directional NSEW movement, return 0 for any 47 | * diagonal "data" direction. For bishop movement, return 0 for 48 | * any NSEW movement. 49 | */ 50 | RLHK_ALGO_MAP_GET_PASSABLE, 51 | 52 | /** 53 | * Set every tile's 32-bit distance value to -1. The return value 54 | * is ignored. 55 | */ 56 | RLHK_ALGO_MAP_CLEAR_DISTANCE, 57 | 58 | /** 59 | * Set a 32-bit distance value for (x, y). The return value is 60 | * ignored. 61 | */ 62 | RLHK_ALGO_MAP_SET_DISTANCE, 63 | 64 | /** 65 | * Return the previously-set 32-bit distance value at (x, y). The 66 | * "data" parameter is unused. 67 | */ 68 | RLHK_ALGO_MAP_GET_DISTANCE, 69 | 70 | /** 71 | * Set a 32-bit heuristic score for (x, y). The return value is 72 | * ignored. 73 | */ 74 | RLHK_ALGO_MAP_SET_HEURISTIC, 75 | 76 | /** 77 | * Return the previously-set 32-bit heuristic value at (x, y). The 78 | * "data" parameter is unused. 79 | */ 80 | RLHK_ALGO_MAP_GET_HEURISTIC, 81 | 82 | /** 83 | * Set an unsigned 3-bit directional value (0-7) at (x, y). A 84 | * special direction of "-1" is sometimes used to indicate a lack 85 | * of direction / gradient. You are not expected to return this -1 86 | * later and may either discard/ignore it or use the information 87 | * as you wish. 88 | * 89 | * The return value is ignored. 90 | */ 91 | RLHK_ALGO_MAP_SET_GRADIENT, 92 | 93 | /** 94 | * Indicates that a tile lies along a shortest path. You *must* 95 | * return the previous RLHK_ALGO_MAP_SET_GRADIENT data value, 96 | * unless that value was -1 in which case the return value is 97 | * ignored. The "data" value is the 32-bit distance from the goal 98 | * (x1, y1). 99 | */ 100 | RLHK_ALGO_MAP_MARK_SHORTEST, 101 | 102 | /** 103 | * Indicates that the tile at (x, y) is visible. The return value 104 | * must indicate if this tile is transparent: non-zero for true, 0 105 | * for false. 106 | * 107 | * The "data" parameter is unused. 108 | */ 109 | RLHK_ALGO_MAP_MARK_VISIBLE 110 | }; 111 | 112 | /** 113 | * Generic map interface provided to RLHK. 114 | * 115 | * It is *your* job to implement this function. You must implement 116 | * each of the methods above that may be used the map functions you 117 | * call. Your map representation will provide some of the per-tile 118 | * storage needed by the functions below. 119 | * 120 | * You must also typedef "rlhk_algo_map" to your own map type 121 | * (typically as a pointer type) before including this header. 122 | */ 123 | RLHK_ALGO_API 124 | long rlhk_algo_map_call(rlhk_algo_map map, 125 | enum rlhk_algo_map_method method, 126 | int x, int y, long data); 127 | 128 | /** 129 | * Find a shortest route between two points using A*. 130 | * 131 | * Ultimately the RLHK_ALGO_MAP_SET_RESULT method will be called for 132 | * each tile on the shortest route, starting from (x1, y1) and ending 133 | * at (x0, y1). 134 | * 135 | * You must provide some workspace memory (buf) and its size in bytes 136 | * (buflen) to be used as a priority queue. The memory need not be 137 | * initialized. A buflen of "sizeof(short) * numtiles * 2" will always 138 | * be sufficient (one pair of shorts per map tile). 139 | * 140 | * To perform a small search with early bailout, just provide a small 141 | * work buffer and allow the function to (safely) run out of memory. 142 | * 143 | * If successful, it returns the length of the path. On failure it 144 | * returns -1 if no path could be found or -2 if it ran out of 145 | * workspace before finding a solution. 146 | * 147 | * Methods used: 148 | * - RLHK_ALGO_MAP_GET_PASSABLE 149 | * - RLHK_ALGO_MAP_CLEAR_DISTANCE 150 | * - RLHK_ALGO_MAP_SET_DISTANCE 151 | * - RLHK_ALGO_MAP_GET_DISTANCE 152 | * - RLHK_ALGO_MAP_SET_HEURISTIC 153 | * - RLHK_ALGO_MAP_GET_HEURISTIC 154 | * - RLHK_ALGO_MAP_SET_GRADIENT 155 | * - RLHK_ALGO_MAP_MARK_SHORTEST 156 | */ 157 | RLHK_ALGO_API 158 | long rlhk_algo_shortest(rlhk_algo_map map, int x0, int y0, int x1, int y1, 159 | short *buf, long buflen); 160 | 161 | /** 162 | * Add an (x, y) coordinate to the buffer (buf). 163 | * 164 | * The buffer (buf) need not be initialized, but the index (i) must be 165 | * 0 on the first call to this function. The buffer size (buflen) is 166 | * in bytes. 167 | * 168 | * Returns the new value for i, or -1 if the buffer is full. 169 | */ 170 | RLHK_ALGO_API 171 | long rlhk_algo_buf_push(short *buf, long buflen, long i, int x, int y); 172 | 173 | /** 174 | * Create a Dijkstra map: a map-wide per-tile distance from a set of 175 | * tiles. 176 | * 177 | * Basically this is a breadth-first flood-fill of distance and 178 | * gradient. Results are delivered via RLHK_ALGO_MAP_SET_DISTANCE. 179 | * 180 | * Use rlhk_algo_buf_push() to add the points of interest to the 181 | * buffer (buf) before calling this function. The contents of the 182 | * buffer will be destroyed by this function. 183 | * 184 | * To get an early bailout and only fill the local area to the points 185 | * of interest, provide only a small buffer and let this function 186 | * (safely) run out of memory. 187 | * 188 | * Returns 1 on success or 0 if it ran out of buffer memory. 189 | * 190 | * Methods used: 191 | * RLHK_ALGO_MAP_GET_PASSABLE 192 | * RLHK_ALGO_MAP_SET_DISTANCE 193 | * RLHK_ALGO_MAP_GET_DISTANCE 194 | */ 195 | RLHK_ALGO_API 196 | int rlhk_algo_dijkstra(rlhk_algo_map map, short *buf, long buflen, long i); 197 | 198 | /** 199 | * Compute the field-of-view from a given tile. 200 | * 201 | * This uses a brute force raycast, which has a lot of overlap and is 202 | * relatively more expensive. But it's simple and doesn't require a 203 | * work buffer. 204 | * 205 | * Methods used: 206 | * RLHK_ALGO_MAP_MARK_VISIBLE 207 | */ 208 | RLHK_ALGO_API 209 | void rlhk_algo_fov(rlhk_algo_map map, int x, int y, int radius); 210 | 211 | /* Implementation */ 212 | #if defined(RLHK_IMPLEMENTATION) || defined(RLHK_ALGO_IMPLEMENTATION) 213 | #include 214 | #include 215 | 216 | #define RLHK_ALGO_CALL(m, method, x, y, d) \ 217 | rlhk_algo_map_call((m), RLHK_ALGO_MAP_##method, (x), (y), (d)) 218 | 219 | struct rlhk_algo_heap { 220 | short *coords; 221 | long count; 222 | long size; 223 | }; 224 | 225 | static void 226 | rlhk_algo_heap_swap(struct rlhk_algo_heap *heap, long a, long b) 227 | { 228 | short ax = heap->coords[a * 2 + 0]; 229 | short ay = heap->coords[a * 2 + 1]; 230 | heap->coords[a * 2 + 0] = heap->coords[b * 2 + 0]; 231 | heap->coords[a * 2 + 1] = heap->coords[b * 2 + 1]; 232 | heap->coords[b * 2 + 0] = ax; 233 | heap->coords[b * 2 + 1] = ay; 234 | } 235 | 236 | static int 237 | rlhk_algo_heap_push(struct rlhk_algo_heap *heap, 238 | rlhk_algo_map map, int x, int y) 239 | { 240 | long f, n; 241 | if (heap->count == heap->size) 242 | return 0; 243 | 244 | n = heap->count++; 245 | heap->coords[n * 2 + 0] = x; 246 | heap->coords[n * 2 + 1] = y; 247 | f = RLHK_ALGO_CALL(map, GET_HEURISTIC, x, y, 0); 248 | while (n > 0) { 249 | long p = (n - 1) / 2; 250 | int px = heap->coords[p * 2 + 0]; 251 | int py = heap->coords[p * 2 + 1]; 252 | long pf = RLHK_ALGO_CALL(map, GET_HEURISTIC, px, py, 0); 253 | if (f < pf) { 254 | rlhk_algo_heap_swap(heap, n, p); 255 | n = p; 256 | } else { 257 | break; 258 | } 259 | } 260 | return 1; 261 | } 262 | 263 | static void 264 | rlhk_algo_heap_pop(struct rlhk_algo_heap *heap, rlhk_algo_map map) 265 | { 266 | long n = 0; 267 | long d = --heap->count; 268 | int x = heap->coords[0] = heap->coords[d * 2 + 0]; 269 | int y = heap->coords[1] = heap->coords[d * 2 + 1]; 270 | long f = RLHK_ALGO_CALL(map, GET_HEURISTIC, x, y, 0); 271 | while (n < heap->count) { 272 | long an, af, bn, bf; 273 | an = 2 * n + 1; 274 | if (an < heap->count) { 275 | int ax = heap->coords[an * 2 + 0]; 276 | int ay = heap->coords[an * 2 + 1]; 277 | af = RLHK_ALGO_CALL(map, GET_HEURISTIC, ax, ay, 0); 278 | } else { 279 | af = LONG_MAX; 280 | } 281 | bn = 2 * n + 2; 282 | if (bn < heap->count) { 283 | int bx = heap->coords[bn * 2 + 0]; 284 | int by = heap->coords[bn * 2 + 1]; 285 | bf = RLHK_ALGO_CALL(map, GET_HEURISTIC, bx, by, 0); 286 | } else { 287 | bf = LONG_MAX; 288 | } 289 | if (af < f && af <= bf) { 290 | rlhk_algo_heap_swap(heap, n, an); 291 | n = an; 292 | } else if (bf < f && bf < af) { 293 | rlhk_algo_heap_swap(heap, n, bn); 294 | n = bn; 295 | } else { 296 | break; 297 | } 298 | } 299 | } 300 | 301 | #define RLHK_ALGO_MAX(a, b) ((b) > (a) ? (b) : (a)) 302 | 303 | RLHK_ALGO_API 304 | long 305 | rlhk_algo_shortest(rlhk_algo_map m, int x0, int y0, int x1, int y1, 306 | short *buf, long buflen) 307 | { 308 | struct rlhk_algo_heap heap[1]; 309 | long length = -1; 310 | int origin_heuristic = RLHK_ALGO_MAX(abs(x0 - x1), abs(y0 - y1)); 311 | 312 | heap->coords = buf; 313 | heap->count = 0; 314 | heap->size = buflen / (sizeof(heap->coords[0]) * 2); 315 | 316 | RLHK_ALGO_CALL(m, CLEAR_DISTANCE, 0, 0, 0); 317 | RLHK_ALGO_CALL(m, SET_DISTANCE, x0, y0, 0); 318 | RLHK_ALGO_CALL(m, SET_HEURISTIC, x0, y0, origin_heuristic); 319 | RLHK_ALGO_CALL(m, SET_GRADIENT, x0, y0, -1); 320 | rlhk_algo_heap_push(heap, m, x0, y0); 321 | 322 | while (heap->count) { 323 | int d; 324 | int x = heap->coords[0]; 325 | int y = heap->coords[1]; 326 | long g, tg; 327 | if (x == x1 && y == y1) { 328 | length = 0; 329 | break; 330 | } 331 | rlhk_algo_heap_pop(heap, m); 332 | g = RLHK_ALGO_CALL(m, GET_DISTANCE, x, y, 0); 333 | for (d = 0; d < 8; d++) { 334 | long tentative = g + 1; 335 | int tx = x + RLHK_ALGO_DX(d); 336 | int ty = y + RLHK_ALGO_DY(d); 337 | int passable = 338 | RLHK_ALGO_CALL(m, GET_PASSABLE, tx, ty, (d + 4) % 8); 339 | if (!passable) 340 | continue; 341 | tg = RLHK_ALGO_CALL(m, GET_DISTANCE, tx, ty, 0); 342 | if (tg == -1 || tentative < tg) { 343 | int h = RLHK_ALGO_MAX(abs(tx - x1), abs(ty - y1)); 344 | RLHK_ALGO_CALL(m, SET_GRADIENT, tx, ty, (d + 4) % 8); 345 | RLHK_ALGO_CALL(m, SET_DISTANCE, tx, ty, tentative); 346 | RLHK_ALGO_CALL(m, SET_HEURISTIC, tx, ty, tentative + h); 347 | if (!rlhk_algo_heap_push(heap, m, tx, ty)) 348 | return -2; /* out of memory */ 349 | } 350 | } 351 | } 352 | 353 | /* Reconstruct shortest route. */ 354 | if (length == 0) { 355 | int x = x1; 356 | int y = y1; 357 | int d; 358 | while (x != x0 || y != y0) { 359 | d = RLHK_ALGO_CALL(m, MARK_SHORTEST, x, y, length); 360 | x += RLHK_ALGO_DX(d); 361 | y += RLHK_ALGO_DY(d); 362 | length++; 363 | } 364 | RLHK_ALGO_CALL(m, MARK_SHORTEST, x, y, length); 365 | } 366 | 367 | return length; 368 | } 369 | 370 | RLHK_ALGO_API 371 | long 372 | rlhk_algo_buf_push(short *buf, long buflen, long i, int x, int y) 373 | { 374 | long size = buflen / (sizeof(*buf) * 2); 375 | if (i == size) { 376 | return -1; 377 | } else { 378 | buf[i * 2 + 0] = x; 379 | buf[i * 2 + 1] = y; 380 | return i + 1; 381 | } 382 | } 383 | 384 | RLHK_ALGO_API 385 | int rlhk_algo_dijkstra(rlhk_algo_map m, short *buf, long buflen, long head) 386 | { 387 | long size = buflen / (sizeof(*buf) * 2); 388 | long tail = 0; 389 | long i; 390 | 391 | /* Initialize distances. */ 392 | RLHK_ALGO_CALL(m, CLEAR_DISTANCE, 0, 0, 0); 393 | for (i = 0; i < head; i++) { 394 | int x = buf[i * 2 + 0]; 395 | int y = buf[i * 2 + 1]; 396 | RLHK_ALGO_CALL(m, SET_DISTANCE, x, y, 0); 397 | } 398 | 399 | /* Breadth-first search. */ 400 | while (tail != head) { 401 | int d; 402 | int x = buf[tail * 2 + 0]; 403 | int y = buf[tail * 2 + 1]; 404 | long v = RLHK_ALGO_CALL(m, GET_DISTANCE, x, y, 0); 405 | tail = (tail + 1) % size; 406 | for (d = 0; d < 8; d++) { 407 | int cx = x + RLHK_ALGO_DX(d); 408 | int cy = y + RLHK_ALGO_DY(d); 409 | int p = RLHK_ALGO_CALL(m, GET_PASSABLE, cx, cy, (d + 4) % 8); 410 | if (p) { 411 | long cv = RLHK_ALGO_CALL(m, GET_DISTANCE, cx, cy, 0); 412 | if (cv == -1) { 413 | long next = (head + 1) % size; 414 | RLHK_ALGO_CALL(m, SET_DISTANCE, cx, cy, v + 1); 415 | if (next == tail) 416 | return 0; /* out of memory */ 417 | buf[head * 2 + 0] = cx; 418 | buf[head * 2 + 1] = cy; 419 | head = next; 420 | 421 | } 422 | } 423 | } 424 | } 425 | return 1; 426 | } 427 | 428 | static void 429 | rlhk_algo_raycast(rlhk_algo_map map, int x0, int y0, int x1, int y1, int r) 430 | { 431 | int dx = abs(x1 - x0); 432 | int dy = abs(y1 - y0); 433 | int sx = x1 < x0 ? -1 : 1; 434 | int sy = y1 < y0 ? -1 : 1; 435 | int r2 = r * r; 436 | 437 | if (dx > dy) { 438 | int d = 2 * dy - dx; 439 | int x, y = y0; 440 | for (x = x0; x != x1; x += sx) { 441 | int dist2 = (x - x0) * (x - x0) + (y - y0) * (y - y0); 442 | if (!RLHK_ALGO_CALL(map, MARK_VISIBLE, x, y, 0) || dist2 > r2) 443 | return; 444 | if (d > 0) { 445 | y += sy; 446 | d -= 2 * dx; 447 | } 448 | d += 2 * dy; 449 | } 450 | } else { 451 | int d = 2 * dx - dy; 452 | int y, x = x0; 453 | for (y = y0; y != y1; y += sy) { 454 | int dist2 = (x - x0) * (x - x0) + (y - y0) * (y - y0); 455 | if (!RLHK_ALGO_CALL(map, MARK_VISIBLE, x, y, 0) || dist2 > r2) 456 | return; 457 | if (d > 0) { 458 | x += sx; 459 | d -= 2 * dy; 460 | } 461 | d += 2 * dx; 462 | } 463 | } 464 | RLHK_ALGO_CALL(map, MARK_VISIBLE, x1, y1, 0); 465 | } 466 | 467 | RLHK_ALGO_API 468 | void 469 | rlhk_algo_fov(rlhk_algo_map map, int x0, int y0, int r) 470 | { 471 | int x = r + 16; 472 | int y = 0; 473 | int e = 0; 474 | while (x >= y) { 475 | rlhk_algo_raycast(map, x0, y0, x0 + x, y0 + y, r); 476 | rlhk_algo_raycast(map, x0, y0, x0 + y, y0 + x, r); 477 | rlhk_algo_raycast(map, x0, y0, x0 - y, y0 + x, r); 478 | rlhk_algo_raycast(map, x0, y0, x0 - x, y0 + y, r); 479 | rlhk_algo_raycast(map, x0, y0, x0 - x, y0 - y, r); 480 | rlhk_algo_raycast(map, x0, y0, x0 - y, y0 - x, r); 481 | rlhk_algo_raycast(map, x0, y0, x0 + y, y0 - x, r); 482 | rlhk_algo_raycast(map, x0, y0, x0 + x, y0 - y, r); 483 | if (e <= 0) { 484 | y++; 485 | e += 2 * y + 1; 486 | } 487 | if (e > 0) { 488 | x--; 489 | e -= 2 * x + 1; 490 | } 491 | } 492 | } 493 | 494 | #endif /* RLHK_ALGO_IMPLEMENTATION */ 495 | #endif /* RLHK_ALGO_H */ 496 | -------------------------------------------------------------------------------- /rlhk_tui.h: -------------------------------------------------------------------------------- 1 | /* Roguelike Header Kit : Text User Interface 2 | * 3 | * This is free and unencumbered software released into the public domain. 4 | * 5 | * Provides portable (POSIX and Win32) functions for efficiently 6 | * rendering 16 colors of text to a terminal / console. No third-party 7 | * libraries, such as ncurses, are required. The maximum display size 8 | * is determined by the compile-time values RLHK_TUI_MAX_WIDTH and 9 | * RLHK_TUI_MAX_HEIGHT. You may define to your own before including 10 | * this module. 11 | * 12 | * For POSIX systems, the terminal is assumed to support ANSI escapes 13 | * and UTF-8 encoding. 14 | * 15 | * This library does not require nor use stdio.h. This may be useful 16 | * in some circumstances, such as builds with a static libc. 17 | * 18 | * To get the implementation, define RLHK_TUI_IMPLEMENTATION before 19 | * including this file. You may define your own RLHK_TUI_API to 20 | * control the linkage and/or visibility of the API. 21 | * 22 | * Functions: 23 | * - rlhk_tui_init 24 | * - rlhk_tui_release 25 | * - rlhk_tui_putc 26 | * - rlhk_tui_flush 27 | * - rlhk_tui_getch 28 | * - rlhk_tui_title 29 | * - rlhk_tui_size 30 | */ 31 | #ifndef RLHK_TUI_H 32 | #define RLHK_TUI_H 33 | 34 | #ifndef RLHK_TUI_API 35 | # ifdef RLHK_API 36 | # define RLHK_TUI_API RLHK_API 37 | # else 38 | # define RLHK_TUI_API 39 | # endif 40 | #endif 41 | 42 | #ifndef RLHK_TUI_MAX_WIDTH 43 | # define RLHK_TUI_MAX_WIDTH 80 44 | #endif 45 | 46 | #ifndef RLHK_TUI_MAX_HEIGHT 47 | # define RLHK_TUI_MAX_HEIGHT 25 48 | #endif 49 | 50 | /** 51 | * Must be called before most TUI functions. 52 | * 53 | * Both rlhk_tui_title() and rlhk_tui_size() may be called without an 54 | * initialized display. 55 | * 56 | * To properly restore the terminal/console state, you must call 57 | * rlhk_tui_release() before exiting the process. This function may be 58 | * called again after rlhk_tui_release(). 59 | * 60 | * The maximum width and height are determined by RLHK_TUI_MAX_WIDTH 61 | * and RLHK_TUI_MAX_HEIGHT. On Windows, the width cannot be greater 62 | * than 80. 63 | * 64 | * Returns 1 on success, 0 on failure. Call rlhk_tui_release() 65 | * regardless of this result. 66 | */ 67 | RLHK_TUI_API 68 | int rlhk_tui_init(int width, int height); 69 | 70 | /** 71 | * Reverse of rlhk_tui_init(), restoring the terminal / console. 72 | * 73 | * Returns 1 on success, 0 on failure. 74 | */ 75 | RLHK_TUI_API 76 | int rlhk_tui_release(void); 77 | 78 | #define RLHK_TUI_FR (1u << 0) /* foreground red */ 79 | #define RLHK_TUI_FG (1u << 1) /* foreground green */ 80 | #define RLHK_TUI_FB (1u << 2) /* foreground blue */ 81 | #define RLHK_TUI_FH (1u << 3) /* foreground highlight */ 82 | #define RLHK_TUI_BR (1u << 4) /* background red */ 83 | #define RLHK_TUI_BG (1u << 5) /* background green */ 84 | #define RLHK_TUI_BB (1u << 6) /* background blue */ 85 | #define RLHK_TUI_BH (1u << 7) /* background highlight */ 86 | 87 | /** 88 | * Put a 16-bit character at x, y with specific fore/background color. 89 | * 90 | * The limiting factor is the Win32 console, which can only display a 91 | * small subset of the BMP. Choose your characters wisely. 92 | * 93 | * An attribute is an 8-bit value composed of ORing the defined values 94 | * above. There are 16 available colors each for foreground and 95 | * background. The specific channel values (i.e. shades) are 96 | * determined by the terminal / console configuration. 97 | * 98 | * Characters are not immediately visible on the display. Instead they 99 | * are written to a background buffer, which is written to the display 100 | * with rlhk_tui_flush(). 101 | */ 102 | RLHK_TUI_API 103 | void rlhk_tui_putc(int x, int y, unsigned c, unsigned attr); 104 | 105 | /** 106 | * Flush all changes to the display. 107 | * 108 | * Calls to rlhk_tui_putc() are not visible until this call. You 109 | * probably want to call this function before rlhk_tui_getch(). 110 | * 111 | * Returns 1 on success, 0 on failure. 112 | */ 113 | RLHK_TUI_API 114 | int rlhk_tui_flush(void); 115 | 116 | #define RLHK_TUI_VK_U 321 /* up */ 117 | #define RLHK_TUI_VK_D 322 /* down */ 118 | #define RLHK_TUI_VK_L 324 /* left */ 119 | #define RLHK_TUI_VK_R 323 /* right */ 120 | #define RLHK_TUI_VK_UL 305 /* up-left */ 121 | #define RLHK_TUI_VK_DL 308 /* down-left */ 122 | #define RLHK_TUI_VK_UR 309 /* up-right */ 123 | #define RLHK_TUI_VK_DR 310 /* down-right */ 124 | #define RLHK_TUI_VK_SIGINT 3 /* ctrl-c */ 125 | 126 | /** 127 | * Blocks and returns a key press from the user. 128 | * 129 | * Limited to ASCII characters, but some special inputs, such as 130 | * directional arrow keys, have the above definitions. 131 | * 132 | * Returns -1 on error. 133 | */ 134 | RLHK_TUI_API 135 | int rlhk_tui_getch(void); 136 | 137 | /** 138 | * Sets the terminal / console window title. 139 | * 140 | * Returns 1 on success, 0 on failure. 141 | */ 142 | RLHK_TUI_API 143 | int rlhk_tui_title(const char *); 144 | 145 | /** 146 | * Gets the current terminal / console size. 147 | * 148 | * Useful for checking the size of the display in order to dynamically 149 | * scale the display, abort with an error for being too small, or to 150 | * wait until the screen is resized. 151 | * 152 | * Returns 1 on success, 0 on failure. 153 | */ 154 | RLHK_TUI_API 155 | int rlhk_tui_size(int *width, int *height); 156 | 157 | #if (defined(__unix__) || defined(__APPLE__)) && !defined(__DJGPP__) 158 | #define RLHK_TUI_WHITE_SMILING_FACE 0xba98e2U 159 | #define RLHK_TUI_BLACK_SMILING_FACE 0xbb98e2U 160 | #define RLHK_TUI_BLACK_HEART_SUIT 0xa599e2U 161 | #define RLHK_TUI_BLACK_DIAMOND_SUIT 0xa699e2U 162 | #define RLHK_TUI_BLACK_CLUB_SUIT 0xa399e2U 163 | #define RLHK_TUI_BLACK_SPADE_SUIT 0xa099e2U 164 | #define RLHK_TUI_BULLET 0xa280e2U 165 | #define RLHK_TUI_INVERSE_BULLET 0x9897e2U 166 | #define RLHK_TUI_WHITE_CIRCLE 0x8b97e2U 167 | #define RLHK_TUI_INVERSE_WHITE_CIRCLE 0x9997e2U 168 | #define RLHK_TUI_MALE_SIGN 0x8299e2U 169 | #define RLHK_TUI_FEMALE_SIGN 0x8099e2U 170 | #define RLHK_TUI_EIGHTH_NOTE 0xaa99e2U 171 | #define RLHK_TUI_BEAMED_EIGHTH_NOTES 0xab99e2U 172 | #define RLHK_TUI_WHITE_SUN_WITH_RAYS 0xbc98e2U 173 | #define RLHK_TUI_BLACK_RIGHT_POINTING_POINTER 0xba96e2U 174 | #define RLHK_TUI_BLACK_LEFT_POINTING_POINTER 0x8497e2U 175 | #define RLHK_TUI_UP_DOWN_ARROW 0x9586e2U 176 | #define RLHK_TUI_DOUBLE_EXCLAMATION_MARK 0xbc80e2U 177 | #define RLHK_TUI_PILCROW_SIGN 0x00b6c2U 178 | #define RLHK_TUI_SECTION_SIGN 0x00a7c2U 179 | #define RLHK_TUI_BLACK_RECTANGLE 0xac96e2U 180 | #define RLHK_TUI_UP_DOWN_ARROW_WITH_BASE 0xa886e2U 181 | #define RLHK_TUI_UPWARDS_ARROW 0x9186e2U 182 | #define RLHK_TUI_DOWNWARDS_ARROW 0x9386e2U 183 | #define RLHK_TUI_RIGHTWARDS_ARROW 0x9286e2U 184 | #define RLHK_TUI_LEFTWARDS_ARROW 0x9086e2U 185 | #define RLHK_TUI_RIGHT_ANGLE 0x9f88e2U 186 | #define RLHK_TUI_LEFT_RIGHT_ARROW 0x9486e2U 187 | #define RLHK_TUI_BLACK_UP_POINTING_TRIANGLE 0xb296e2U 188 | #define RLHK_TUI_BLACK_DOWN_POINTING_TRIANGLE 0xbc96e2U 189 | #define RLHK_TUI_SPACE 0x000020U 190 | #define RLHK_TUI_EXCLAMATION_MARK 0x000021U 191 | #define RLHK_TUI_QUOTATION_MARK 0x000022U 192 | #define RLHK_TUI_NUMBER_SIGN 0x000023U 193 | #define RLHK_TUI_DOLLAR_SIGN 0x000024U 194 | #define RLHK_TUI_PERCENT_SIGN 0x000025U 195 | #define RLHK_TUI_AMPERSAND 0x000026U 196 | #define RLHK_TUI_APOSTROPHE 0x000027U 197 | #define RLHK_TUI_LEFT_PARENTHESIS 0x000028U 198 | #define RLHK_TUI_RIGHT_PARENTHESIS 0x000029U 199 | #define RLHK_TUI_ASTERISK 0x00002aU 200 | #define RLHK_TUI_PLUS_SIGN 0x00002bU 201 | #define RLHK_TUI_COMMA 0x00002cU 202 | #define RLHK_TUI_HYPHEN_MINUS 0x00002dU 203 | #define RLHK_TUI_FULL_STOP 0x00002eU 204 | #define RLHK_TUI_SOLIDUS 0x00002fU 205 | #define RLHK_TUI_DIGIT_ZERO 0x000030U 206 | #define RLHK_TUI_DIGIT_ONE 0x000031U 207 | #define RLHK_TUI_DIGIT_TWO 0x000032U 208 | #define RLHK_TUI_DIGIT_THREE 0x000033U 209 | #define RLHK_TUI_DIGIT_FOUR 0x000034U 210 | #define RLHK_TUI_DIGIT_FIVE 0x000035U 211 | #define RLHK_TUI_DIGIT_SIX 0x000036U 212 | #define RLHK_TUI_DIGIT_SEVEN 0x000037U 213 | #define RLHK_TUI_DIGIT_EIGHT 0x000038U 214 | #define RLHK_TUI_DIGIT_NINE 0x000039U 215 | #define RLHK_TUI_COLON 0x00003aU 216 | #define RLHK_TUI_SEMICOLON 0x00003bU 217 | #define RLHK_TUI_LESS_THAN_SIGN 0x00003cU 218 | #define RLHK_TUI_EQUALS_SIGN 0x00003dU 219 | #define RLHK_TUI_GREATER_THAN_SIGN 0x00003eU 220 | #define RLHK_TUI_QUESTION_MARK 0x00003fU 221 | #define RLHK_TUI_COMMERCIAL_AT 0x000040U 222 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_A 0x000041U 223 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_B 0x000042U 224 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_C 0x000043U 225 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_D 0x000044U 226 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_E 0x000045U 227 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_F 0x000046U 228 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_G 0x000047U 229 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_H 0x000048U 230 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_I 0x000049U 231 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_J 0x00004aU 232 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_K 0x00004bU 233 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_L 0x00004cU 234 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_M 0x00004dU 235 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_N 0x00004eU 236 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_O 0x00004fU 237 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_P 0x000050U 238 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_Q 0x000051U 239 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_R 0x000052U 240 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_S 0x000053U 241 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_T 0x000054U 242 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_U 0x000055U 243 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_V 0x000056U 244 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_W 0x000057U 245 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_X 0x000058U 246 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_Y 0x000059U 247 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_Z 0x00005aU 248 | #define RLHK_TUI_LEFT_SQUARE_BRACKET 0x00005bU 249 | #define RLHK_TUI_REVERSE_SOLIDUS 0x00005cU 250 | #define RLHK_TUI_RIGHT_SQUARE_BRACKET 0x00005dU 251 | #define RLHK_TUI_CIRCUMFLEX_ACCENT 0x00005eU 252 | #define RLHK_TUI_LOW_LINE 0x00005fU 253 | #define RLHK_TUI_GRAVE_ACCENT 0x000060U 254 | #define RLHK_TUI_LATIN_SMALL_LETTER_A 0x000061U 255 | #define RLHK_TUI_LATIN_SMALL_LETTER_B 0x000062U 256 | #define RLHK_TUI_LATIN_SMALL_LETTER_C 0x000063U 257 | #define RLHK_TUI_LATIN_SMALL_LETTER_D 0x000064U 258 | #define RLHK_TUI_LATIN_SMALL_LETTER_E 0x000065U 259 | #define RLHK_TUI_LATIN_SMALL_LETTER_F 0x000066U 260 | #define RLHK_TUI_LATIN_SMALL_LETTER_G 0x000067U 261 | #define RLHK_TUI_LATIN_SMALL_LETTER_H 0x000068U 262 | #define RLHK_TUI_LATIN_SMALL_LETTER_I 0x000069U 263 | #define RLHK_TUI_LATIN_SMALL_LETTER_J 0x00006aU 264 | #define RLHK_TUI_LATIN_SMALL_LETTER_K 0x00006bU 265 | #define RLHK_TUI_LATIN_SMALL_LETTER_L 0x00006cU 266 | #define RLHK_TUI_LATIN_SMALL_LETTER_M 0x00006dU 267 | #define RLHK_TUI_LATIN_SMALL_LETTER_N 0x00006eU 268 | #define RLHK_TUI_LATIN_SMALL_LETTER_O 0x00006fU 269 | #define RLHK_TUI_LATIN_SMALL_LETTER_P 0x000070U 270 | #define RLHK_TUI_LATIN_SMALL_LETTER_Q 0x000071U 271 | #define RLHK_TUI_LATIN_SMALL_LETTER_R 0x000072U 272 | #define RLHK_TUI_LATIN_SMALL_LETTER_S 0x000073U 273 | #define RLHK_TUI_LATIN_SMALL_LETTER_T 0x000074U 274 | #define RLHK_TUI_LATIN_SMALL_LETTER_U 0x000075U 275 | #define RLHK_TUI_LATIN_SMALL_LETTER_V 0x000076U 276 | #define RLHK_TUI_LATIN_SMALL_LETTER_W 0x000077U 277 | #define RLHK_TUI_LATIN_SMALL_LETTER_X 0x000078U 278 | #define RLHK_TUI_LATIN_SMALL_LETTER_Y 0x000079U 279 | #define RLHK_TUI_LATIN_SMALL_LETTER_Z 0x00007aU 280 | #define RLHK_TUI_LEFT_CURLY_BRACKET 0x00007bU 281 | #define RLHK_TUI_VERTICAL_LINE 0x00007cU 282 | #define RLHK_TUI_RIGHT_CURLY_BRACKET 0x00007dU 283 | #define RLHK_TUI_TILDE 0x00007eU 284 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_C_WITH_CEDILLA 0x0087c3U 285 | #define RLHK_TUI_LATIN_SMALL_LETTER_U_WITH_DIAERESIS 0x00bcc3U 286 | #define RLHK_TUI_LATIN_SMALL_LETTER_E_WITH_ACUTE 0x00a9c3U 287 | #define RLHK_TUI_LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX 0x00a2c3U 288 | #define RLHK_TUI_LATIN_SMALL_LETTER_A_WITH_DIAERESIS 0x00a4c3U 289 | #define RLHK_TUI_LATIN_SMALL_LETTER_A_WITH_GRAVE 0x00a0c3U 290 | #define RLHK_TUI_LATIN_SMALL_LETTER_A_WITH_RING_ABOVE 0x00a5c3U 291 | #define RLHK_TUI_LATIN_SMALL_LETTER_C_WITH_CEDILLA 0x00a7c3U 292 | #define RLHK_TUI_LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX 0x00aac3U 293 | #define RLHK_TUI_LATIN_SMALL_LETTER_E_WITH_DIAERESIS 0x00abc3U 294 | #define RLHK_TUI_LATIN_SMALL_LETTER_E_WITH_GRAVE 0x00a8c3U 295 | #define RLHK_TUI_LATIN_SMALL_LETTER_I_WITH_DIAERESIS 0x00afc3U 296 | #define RLHK_TUI_LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX 0x00aec3U 297 | #define RLHK_TUI_LATIN_SMALL_LETTER_I_WITH_GRAVE 0x00acc3U 298 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS 0x0084c3U 299 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE 0x0085c3U 300 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_E_WITH_ACUTE 0x0089c3U 301 | #define RLHK_TUI_LATIN_SMALL_LIGATURE_AE 0x00a6c3U 302 | #define RLHK_TUI_LATIN_CAPITAL_LIGATURE_AE 0x0086c3U 303 | #define RLHK_TUI_LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX 0x00b4c3U 304 | #define RLHK_TUI_LATIN_SMALL_LETTER_O_WITH_DIAERESIS 0x00b6c3U 305 | #define RLHK_TUI_LATIN_SMALL_LETTER_O_WITH_GRAVE 0x00b2c3U 306 | #define RLHK_TUI_LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX 0x00bbc3U 307 | #define RLHK_TUI_LATIN_SMALL_LETTER_U_WITH_GRAVE 0x00b9c3U 308 | #define RLHK_TUI_LATIN_SMALL_LETTER_Y_WITH_DIAERESIS 0x00bfc3U 309 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS 0x0096c3U 310 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS 0x009cc3U 311 | #define RLHK_TUI_CENT_SIGN 0x00a2c2U 312 | #define RLHK_TUI_POUND_SIGN 0x00a3c2U 313 | #define RLHK_TUI_YEN_SIGN 0x00a5c2U 314 | #define RLHK_TUI_PESETA_SIGN 0xa782e2U 315 | #define RLHK_TUI_LATIN_SMALL_LETTER_F_WITH_HOOK 0x0092c6U 316 | #define RLHK_TUI_LATIN_SMALL_LETTER_A_WITH_ACUTE 0x00a1c3U 317 | #define RLHK_TUI_LATIN_SMALL_LETTER_I_WITH_ACUTE 0x00adc3U 318 | #define RLHK_TUI_LATIN_SMALL_LETTER_O_WITH_ACUTE 0x00b3c3U 319 | #define RLHK_TUI_LATIN_SMALL_LETTER_U_WITH_ACUTE 0x00bac3U 320 | #define RLHK_TUI_LATIN_SMALL_LETTER_N_WITH_TILDE 0x00b1c3U 321 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_N_WITH_TILDE 0x0091c3U 322 | #define RLHK_TUI_FEMININE_ORDINAL_INDICATOR 0x00aac2U 323 | #define RLHK_TUI_MASCULINE_ORDINAL_INDICATOR 0x00bac2U 324 | #define RLHK_TUI_INVERTED_QUESTION_MARK 0x00bfc2U 325 | #define RLHK_TUI_REVERSED_NOT_SIGN 0x908ce2U 326 | #define RLHK_TUI_NOT_SIGN 0x00acc2U 327 | #define RLHK_TUI_VULGAR_FRACTION_ONE_HALF 0x00bdc2U 328 | #define RLHK_TUI_VULGAR_FRACTION_ONE_QUARTER 0x00bcc2U 329 | #define RLHK_TUI_INVERTED_EXCLAMATION_MARK 0x00a1c2U 330 | #define RLHK_TUI_LEFT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK 0x00abc2U 331 | #define RLHK_TUI_RIGHT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK 0x00bbc2U 332 | #define RLHK_TUI_LIGHT_SHADE 0x9196e2U 333 | #define RLHK_TUI_MEDIUM_SHADE 0x9296e2U 334 | #define RLHK_TUI_DARK_SHADE 0x9396e2U 335 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_VERTICAL 0x8294e2U 336 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_VERTICAL_AND_LEFT 0xa494e2U 337 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_SINGLE_AND_LEFT_DOUBLE 0xa195e2U 338 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_DOUBLE_AND_LEFT_SINGLE 0xa295e2U 339 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_DOUBLE_AND_LEFT_SINGLE 0x9695e2U 340 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_SINGLE_AND_LEFT_DOUBLE 0x9595e2U 341 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_VERTICAL_AND_LEFT 0xa395e2U 342 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_VERTICAL 0x9195e2U 343 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_DOWN_AND_LEFT 0x9795e2U 344 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_UP_AND_LEFT 0x9d95e2U 345 | #define RLHK_TUI_BOX_DRAWINGS_UP_DOUBLE_AND_LEFT_SINGLE 0x9c95e2U 346 | #define RLHK_TUI_BOX_DRAWINGS_UP_SINGLE_AND_LEFT_DOUBLE 0x9b95e2U 347 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT 0x9094e2U 348 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT 0x9494e2U 349 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_UP_AND_HORIZONTAL 0xb494e2U 350 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_DOWN_AND_HORIZONTAL 0xac94e2U 351 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_VERTICAL_AND_RIGHT 0x9c94e2U 352 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_HORIZONTAL 0x8094e2U 353 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_VERTICAL_AND_HORIZONTAL 0xbc94e2U 354 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_SINGLE_AND_RIGHT_DOUBLE 0x9e95e2U 355 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_DOUBLE_AND_RIGHT_SINGLE 0x9f95e2U 356 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_UP_AND_RIGHT 0x9a95e2U 357 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_DOWN_AND_RIGHT 0x9495e2U 358 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_UP_AND_HORIZONTAL 0xa995e2U 359 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_DOWN_AND_HORIZONTAL 0xa695e2U 360 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_VERTICAL_AND_RIGHT 0xa095e2U 361 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_HORIZONTAL 0x9095e2U 362 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_VERTICAL_AND_HORIZONTAL 0xac95e2U 363 | #define RLHK_TUI_BOX_DRAWINGS_UP_SINGLE_AND_HORIZONTAL_DOUBLE 0xa795e2U 364 | #define RLHK_TUI_BOX_DRAWINGS_UP_DOUBLE_AND_HORIZONTAL_SINGLE 0xa895e2U 365 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_SINGLE_AND_HORIZONTAL_DOUBLE 0xa495e2U 366 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_DOUBLE_AND_HORIZONTAL_SINGLE 0xa595e2U 367 | #define RLHK_TUI_BOX_DRAWINGS_UP_DOUBLE_AND_RIGHT_SINGLE 0x9995e2U 368 | #define RLHK_TUI_BOX_DRAWINGS_UP_SINGLE_AND_RIGHT_DOUBLE 0x9895e2U 369 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_SINGLE_AND_RIGHT_DOUBLE 0x9295e2U 370 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_DOUBLE_AND_RIGHT_SINGLE 0x9395e2U 371 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_DOUBLE_AND_HORIZONTAL_SINGLE 0xab95e2U 372 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_SINGLE_AND_HORIZONTAL_DOUBLE 0xaa95e2U 373 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_UP_AND_LEFT 0x9894e2U 374 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT 0x8c94e2U 375 | #define RLHK_TUI_FULL_BLOCK 0x8896e2U 376 | #define RLHK_TUI_LOWER_HALF_BLOCK 0x8496e2U 377 | #define RLHK_TUI_LEFT_HALF_BLOCK 0x8c96e2U 378 | #define RLHK_TUI_RIGHT_HALF_BLOCK 0x9096e2U 379 | #define RLHK_TUI_UPPER_HALF_BLOCK 0x8096e2U 380 | #define RLHK_TUI_GREEK_SMALL_LETTER_ALPHA 0x00b1ceU 381 | #define RLHK_TUI_LATIN_SMALL_LETTER_SHARP_S 0x009fc3U 382 | #define RLHK_TUI_GREEK_CAPITAL_LETTER_GAMMA 0x0093ceU 383 | #define RLHK_TUI_GREEK_SMALL_LETTER_PI 0x0080cfU 384 | #define RLHK_TUI_GREEK_CAPITAL_LETTER_SIGMA 0x00a3ceU 385 | #define RLHK_TUI_GREEK_SMALL_LETTER_SIGMA 0x0083cfU 386 | #define RLHK_TUI_MICRO_SIGN 0x00b5c2U 387 | #define RLHK_TUI_GREEK_SMALL_LETTER_TAU 0x0084cfU 388 | #define RLHK_TUI_GREEK_CAPITAL_LETTER_PHI 0x00a6ceU 389 | #define RLHK_TUI_GREEK_CAPITAL_LETTER_THETA 0x0098ceU 390 | #define RLHK_TUI_GREEK_CAPITAL_LETTER_OMEGA 0x00a9ceU 391 | #define RLHK_TUI_GREEK_SMALL_LETTER_DELTA 0x00b4ceU 392 | #define RLHK_TUI_INFINITY 0x9e88e2U 393 | #define RLHK_TUI_GREEK_SMALL_LETTER_PHI 0x0086cfU 394 | #define RLHK_TUI_GREEK_SMALL_LETTER_EPSILON 0x00b5ceU 395 | #define RLHK_TUI_INTERSECTION 0xa988e2U 396 | #define RLHK_TUI_IDENTICAL_TO 0xa189e2U 397 | #define RLHK_TUI_PLUS_MINUS_SIGN 0x00b1c2U 398 | #define RLHK_TUI_GREATER_THAN_OR_EQUAL_TO 0xa589e2U 399 | #define RLHK_TUI_LESS_THAN_OR_EQUAL_TO 0xa489e2U 400 | #define RLHK_TUI_TOP_HALF_INTEGRAL 0xa08ce2U 401 | #define RLHK_TUI_BOTTOM_HALF_INTEGRAL 0xa18ce2U 402 | #define RLHK_TUI_DIVISION_SIGN 0x00b7c3U 403 | #define RLHK_TUI_ALMOST_EQUAL_TO 0x8889e2U 404 | #define RLHK_TUI_DEGREE_SIGN 0x00b0c2U 405 | #define RLHK_TUI_BULLET_OPERATOR 0x9988e2U 406 | #define RLHK_TUI_MIDDLE_DOT 0x00b7c2U 407 | #define RLHK_TUI_SQUARE_ROOT 0x9a88e2U 408 | #define RLHK_TUI_SUPERSCRIPT_LATIN_SMALL_LETTER_N 0xbf81e2U 409 | #define RLHK_TUI_SUPERSCRIPT_TWO 0x00b2c2U 410 | #define RLHK_TUI_BLACK_SQUARE 0xa096e2U 411 | #elif defined(_WIN32) 412 | #define RLHK_TUI_WHITE_SMILING_FACE 0x263A 413 | #define RLHK_TUI_BLACK_SMILING_FACE 0x263B 414 | #define RLHK_TUI_BLACK_HEART_SUIT 0x2665 415 | #define RLHK_TUI_BLACK_DIAMOND_SUIT 0x2666 416 | #define RLHK_TUI_BLACK_CLUB_SUIT 0x2663 417 | #define RLHK_TUI_BLACK_SPADE_SUIT 0x2660 418 | #define RLHK_TUI_BULLET 0x2022 419 | #define RLHK_TUI_INVERSE_BULLET 0x25D8 420 | #define RLHK_TUI_WHITE_CIRCLE 0x25CB 421 | #define RLHK_TUI_INVERSE_WHITE_CIRCLE 0x25D9 422 | #define RLHK_TUI_MALE_SIGN 0x2642 423 | #define RLHK_TUI_FEMALE_SIGN 0x2640 424 | #define RLHK_TUI_EIGHTH_NOTE 0x266A 425 | #define RLHK_TUI_BEAMED_EIGHTH_NOTES 0x266B 426 | #define RLHK_TUI_WHITE_SUN_WITH_RAYS 0x263C 427 | #define RLHK_TUI_BLACK_RIGHT_POINTING_POINTER 0x25BA 428 | #define RLHK_TUI_BLACK_LEFT_POINTING_POINTER 0x25C4 429 | #define RLHK_TUI_UP_DOWN_ARROW 0x2195 430 | #define RLHK_TUI_DOUBLE_EXCLAMATION_MARK 0x203C 431 | #define RLHK_TUI_PILCROW_SIGN 0x00B6 432 | #define RLHK_TUI_SECTION_SIGN 0x00A7 433 | #define RLHK_TUI_BLACK_RECTANGLE 0x25AC 434 | #define RLHK_TUI_UP_DOWN_ARROW_WITH_BASE 0x21A8 435 | #define RLHK_TUI_UPWARDS_ARROW 0x2191 436 | #define RLHK_TUI_DOWNWARDS_ARROW 0x2193 437 | #define RLHK_TUI_RIGHTWARDS_ARROW 0x2192 438 | #define RLHK_TUI_LEFTWARDS_ARROW 0x2190 439 | #define RLHK_TUI_RIGHT_ANGLE 0x221F 440 | #define RLHK_TUI_LEFT_RIGHT_ARROW 0x2194 441 | #define RLHK_TUI_BLACK_UP_POINTING_TRIANGLE 0x25B2 442 | #define RLHK_TUI_BLACK_DOWN_POINTING_TRIANGLE 0x25BC 443 | #define RLHK_TUI_SPACE 0x0020 444 | #define RLHK_TUI_EXCLAMATION_MARK 0x0021 445 | #define RLHK_TUI_QUOTATION_MARK 0x0022 446 | #define RLHK_TUI_NUMBER_SIGN 0x0023 447 | #define RLHK_TUI_DOLLAR_SIGN 0x0024 448 | #define RLHK_TUI_PERCENT_SIGN 0x0025 449 | #define RLHK_TUI_AMPERSAND 0x0026 450 | #define RLHK_TUI_APOSTROPHE 0x0027 451 | #define RLHK_TUI_LEFT_PARENTHESIS 0x0028 452 | #define RLHK_TUI_RIGHT_PARENTHESIS 0x0029 453 | #define RLHK_TUI_ASTERISK 0x002a 454 | #define RLHK_TUI_PLUS_SIGN 0x002b 455 | #define RLHK_TUI_COMMA 0x002c 456 | #define RLHK_TUI_HYPHEN_MINUS 0x002d 457 | #define RLHK_TUI_FULL_STOP 0x002e 458 | #define RLHK_TUI_SOLIDUS 0x002f 459 | #define RLHK_TUI_DIGIT_ZERO 0x0030 460 | #define RLHK_TUI_DIGIT_ONE 0x0031 461 | #define RLHK_TUI_DIGIT_TWO 0x0032 462 | #define RLHK_TUI_DIGIT_THREE 0x0033 463 | #define RLHK_TUI_DIGIT_FOUR 0x0034 464 | #define RLHK_TUI_DIGIT_FIVE 0x0035 465 | #define RLHK_TUI_DIGIT_SIX 0x0036 466 | #define RLHK_TUI_DIGIT_SEVEN 0x0037 467 | #define RLHK_TUI_DIGIT_EIGHT 0x0038 468 | #define RLHK_TUI_DIGIT_NINE 0x0039 469 | #define RLHK_TUI_COLON 0x003a 470 | #define RLHK_TUI_SEMICOLON 0x003b 471 | #define RLHK_TUI_LESS_THAN_SIGN 0x003c 472 | #define RLHK_TUI_EQUALS_SIGN 0x003d 473 | #define RLHK_TUI_GREATER_THAN_SIGN 0x003e 474 | #define RLHK_TUI_QUESTION_MARK 0x003f 475 | #define RLHK_TUI_COMMERCIAL_AT 0x0040 476 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_A 0x0041 477 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_B 0x0042 478 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_C 0x0043 479 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_D 0x0044 480 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_E 0x0045 481 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_F 0x0046 482 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_G 0x0047 483 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_H 0x0048 484 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_I 0x0049 485 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_J 0x004a 486 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_K 0x004b 487 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_L 0x004c 488 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_M 0x004d 489 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_N 0x004e 490 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_O 0x004f 491 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_P 0x0050 492 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_Q 0x0051 493 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_R 0x0052 494 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_S 0x0053 495 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_T 0x0054 496 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_U 0x0055 497 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_V 0x0056 498 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_W 0x0057 499 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_X 0x0058 500 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_Y 0x0059 501 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_Z 0x005a 502 | #define RLHK_TUI_LEFT_SQUARE_BRACKET 0x005b 503 | #define RLHK_TUI_REVERSE_SOLIDUS 0x005c 504 | #define RLHK_TUI_RIGHT_SQUARE_BRACKET 0x005d 505 | #define RLHK_TUI_CIRCUMFLEX_ACCENT 0x005e 506 | #define RLHK_TUI_LOW_LINE 0x005f 507 | #define RLHK_TUI_GRAVE_ACCENT 0x0060 508 | #define RLHK_TUI_LATIN_SMALL_LETTER_A 0x0061 509 | #define RLHK_TUI_LATIN_SMALL_LETTER_B 0x0062 510 | #define RLHK_TUI_LATIN_SMALL_LETTER_C 0x0063 511 | #define RLHK_TUI_LATIN_SMALL_LETTER_D 0x0064 512 | #define RLHK_TUI_LATIN_SMALL_LETTER_E 0x0065 513 | #define RLHK_TUI_LATIN_SMALL_LETTER_F 0x0066 514 | #define RLHK_TUI_LATIN_SMALL_LETTER_G 0x0067 515 | #define RLHK_TUI_LATIN_SMALL_LETTER_H 0x0068 516 | #define RLHK_TUI_LATIN_SMALL_LETTER_I 0x0069 517 | #define RLHK_TUI_LATIN_SMALL_LETTER_J 0x006a 518 | #define RLHK_TUI_LATIN_SMALL_LETTER_K 0x006b 519 | #define RLHK_TUI_LATIN_SMALL_LETTER_L 0x006c 520 | #define RLHK_TUI_LATIN_SMALL_LETTER_M 0x006d 521 | #define RLHK_TUI_LATIN_SMALL_LETTER_N 0x006e 522 | #define RLHK_TUI_LATIN_SMALL_LETTER_O 0x006f 523 | #define RLHK_TUI_LATIN_SMALL_LETTER_P 0x0070 524 | #define RLHK_TUI_LATIN_SMALL_LETTER_Q 0x0071 525 | #define RLHK_TUI_LATIN_SMALL_LETTER_R 0x0072 526 | #define RLHK_TUI_LATIN_SMALL_LETTER_S 0x0073 527 | #define RLHK_TUI_LATIN_SMALL_LETTER_T 0x0074 528 | #define RLHK_TUI_LATIN_SMALL_LETTER_U 0x0075 529 | #define RLHK_TUI_LATIN_SMALL_LETTER_V 0x0076 530 | #define RLHK_TUI_LATIN_SMALL_LETTER_W 0x0077 531 | #define RLHK_TUI_LATIN_SMALL_LETTER_X 0x0078 532 | #define RLHK_TUI_LATIN_SMALL_LETTER_Y 0x0079 533 | #define RLHK_TUI_LATIN_SMALL_LETTER_Z 0x007a 534 | #define RLHK_TUI_LEFT_CURLY_BRACKET 0x007b 535 | #define RLHK_TUI_VERTICAL_LINE 0x007c 536 | #define RLHK_TUI_RIGHT_CURLY_BRACKET 0x007d 537 | #define RLHK_TUI_TILDE 0x007e 538 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_C_WITH_CEDILLA 0x00c7 539 | #define RLHK_TUI_LATIN_SMALL_LETTER_U_WITH_DIAERESIS 0x00fc 540 | #define RLHK_TUI_LATIN_SMALL_LETTER_E_WITH_ACUTE 0x00e9 541 | #define RLHK_TUI_LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX 0x00e2 542 | #define RLHK_TUI_LATIN_SMALL_LETTER_A_WITH_DIAERESIS 0x00e4 543 | #define RLHK_TUI_LATIN_SMALL_LETTER_A_WITH_GRAVE 0x00e0 544 | #define RLHK_TUI_LATIN_SMALL_LETTER_A_WITH_RING_ABOVE 0x00e5 545 | #define RLHK_TUI_LATIN_SMALL_LETTER_C_WITH_CEDILLA 0x00e7 546 | #define RLHK_TUI_LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX 0x00ea 547 | #define RLHK_TUI_LATIN_SMALL_LETTER_E_WITH_DIAERESIS 0x00eb 548 | #define RLHK_TUI_LATIN_SMALL_LETTER_E_WITH_GRAVE 0x00e8 549 | #define RLHK_TUI_LATIN_SMALL_LETTER_I_WITH_DIAERESIS 0x00ef 550 | #define RLHK_TUI_LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX 0x00ee 551 | #define RLHK_TUI_LATIN_SMALL_LETTER_I_WITH_GRAVE 0x00ec 552 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS 0x00c4 553 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE 0x00c5 554 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_E_WITH_ACUTE 0x00c9 555 | #define RLHK_TUI_LATIN_SMALL_LIGATURE_AE 0x00e6 556 | #define RLHK_TUI_LATIN_CAPITAL_LIGATURE_AE 0x00c6 557 | #define RLHK_TUI_LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX 0x00f4 558 | #define RLHK_TUI_LATIN_SMALL_LETTER_O_WITH_DIAERESIS 0x00f6 559 | #define RLHK_TUI_LATIN_SMALL_LETTER_O_WITH_GRAVE 0x00f2 560 | #define RLHK_TUI_LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX 0x00fb 561 | #define RLHK_TUI_LATIN_SMALL_LETTER_U_WITH_GRAVE 0x00f9 562 | #define RLHK_TUI_LATIN_SMALL_LETTER_Y_WITH_DIAERESIS 0x00ff 563 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS 0x00d6 564 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS 0x00dc 565 | #define RLHK_TUI_CENT_SIGN 0x00a2 566 | #define RLHK_TUI_POUND_SIGN 0x00a3 567 | #define RLHK_TUI_YEN_SIGN 0x00a5 568 | #define RLHK_TUI_PESETA_SIGN 0x20a7 569 | #define RLHK_TUI_LATIN_SMALL_LETTER_F_WITH_HOOK 0x0192 570 | #define RLHK_TUI_LATIN_SMALL_LETTER_A_WITH_ACUTE 0x00e1 571 | #define RLHK_TUI_LATIN_SMALL_LETTER_I_WITH_ACUTE 0x00ed 572 | #define RLHK_TUI_LATIN_SMALL_LETTER_O_WITH_ACUTE 0x00f3 573 | #define RLHK_TUI_LATIN_SMALL_LETTER_U_WITH_ACUTE 0x00fa 574 | #define RLHK_TUI_LATIN_SMALL_LETTER_N_WITH_TILDE 0x00f1 575 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_N_WITH_TILDE 0x00d1 576 | #define RLHK_TUI_FEMININE_ORDINAL_INDICATOR 0x00aa 577 | #define RLHK_TUI_MASCULINE_ORDINAL_INDICATOR 0x00ba 578 | #define RLHK_TUI_INVERTED_QUESTION_MARK 0x00bf 579 | #define RLHK_TUI_REVERSED_NOT_SIGN 0x2310 580 | #define RLHK_TUI_NOT_SIGN 0x00ac 581 | #define RLHK_TUI_VULGAR_FRACTION_ONE_HALF 0x00bd 582 | #define RLHK_TUI_VULGAR_FRACTION_ONE_QUARTER 0x00bc 583 | #define RLHK_TUI_INVERTED_EXCLAMATION_MARK 0x00a1 584 | #define RLHK_TUI_LEFT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK 0x00ab 585 | #define RLHK_TUI_RIGHT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK 0x00bb 586 | #define RLHK_TUI_LIGHT_SHADE 0x2591 587 | #define RLHK_TUI_MEDIUM_SHADE 0x2592 588 | #define RLHK_TUI_DARK_SHADE 0x2593 589 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_VERTICAL 0x2502 590 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_VERTICAL_AND_LEFT 0x2524 591 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_SINGLE_AND_LEFT_DOUBLE 0x2561 592 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_DOUBLE_AND_LEFT_SINGLE 0x2562 593 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_DOUBLE_AND_LEFT_SINGLE 0x2556 594 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_SINGLE_AND_LEFT_DOUBLE 0x2555 595 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_VERTICAL_AND_LEFT 0x2563 596 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_VERTICAL 0x2551 597 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_DOWN_AND_LEFT 0x2557 598 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_UP_AND_LEFT 0x255d 599 | #define RLHK_TUI_BOX_DRAWINGS_UP_DOUBLE_AND_LEFT_SINGLE 0x255c 600 | #define RLHK_TUI_BOX_DRAWINGS_UP_SINGLE_AND_LEFT_DOUBLE 0x255b 601 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT 0x2510 602 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT 0x2514 603 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_UP_AND_HORIZONTAL 0x2534 604 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_DOWN_AND_HORIZONTAL 0x252c 605 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_VERTICAL_AND_RIGHT 0x251c 606 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_HORIZONTAL 0x2500 607 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_VERTICAL_AND_HORIZONTAL 0x253c 608 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_SINGLE_AND_RIGHT_DOUBLE 0x255e 609 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_DOUBLE_AND_RIGHT_SINGLE 0x255f 610 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_UP_AND_RIGHT 0x255a 611 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_DOWN_AND_RIGHT 0x2554 612 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_UP_AND_HORIZONTAL 0x2569 613 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_DOWN_AND_HORIZONTAL 0x2566 614 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_VERTICAL_AND_RIGHT 0x2560 615 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_HORIZONTAL 0x2550 616 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_VERTICAL_AND_HORIZONTAL 0x256c 617 | #define RLHK_TUI_BOX_DRAWINGS_UP_SINGLE_AND_HORIZONTAL_DOUBLE 0x2567 618 | #define RLHK_TUI_BOX_DRAWINGS_UP_DOUBLE_AND_HORIZONTAL_SINGLE 0x2568 619 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_SINGLE_AND_HORIZONTAL_DOUBLE 0x2564 620 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_DOUBLE_AND_HORIZONTAL_SINGLE 0x2565 621 | #define RLHK_TUI_BOX_DRAWINGS_UP_DOUBLE_AND_RIGHT_SINGLE 0x2559 622 | #define RLHK_TUI_BOX_DRAWINGS_UP_SINGLE_AND_RIGHT_DOUBLE 0x2558 623 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_SINGLE_AND_RIGHT_DOUBLE 0x2552 624 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_DOUBLE_AND_RIGHT_SINGLE 0x2553 625 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_DOUBLE_AND_HORIZONTAL_SINGLE 0x256b 626 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_SINGLE_AND_HORIZONTAL_DOUBLE 0x256a 627 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_UP_AND_LEFT 0x2518 628 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT 0x250c 629 | #define RLHK_TUI_FULL_BLOCK 0x2588 630 | #define RLHK_TUI_LOWER_HALF_BLOCK 0x2584 631 | #define RLHK_TUI_LEFT_HALF_BLOCK 0x258c 632 | #define RLHK_TUI_RIGHT_HALF_BLOCK 0x2590 633 | #define RLHK_TUI_UPPER_HALF_BLOCK 0x2580 634 | #define RLHK_TUI_GREEK_SMALL_LETTER_ALPHA 0x03b1 635 | #define RLHK_TUI_LATIN_SMALL_LETTER_SHARP_S 0x00df 636 | #define RLHK_TUI_GREEK_CAPITAL_LETTER_GAMMA 0x0393 637 | #define RLHK_TUI_GREEK_SMALL_LETTER_PI 0x03c0 638 | #define RLHK_TUI_GREEK_CAPITAL_LETTER_SIGMA 0x03a3 639 | #define RLHK_TUI_GREEK_SMALL_LETTER_SIGMA 0x03c3 640 | #define RLHK_TUI_MICRO_SIGN 0x00b5 641 | #define RLHK_TUI_GREEK_SMALL_LETTER_TAU 0x03c4 642 | #define RLHK_TUI_GREEK_CAPITAL_LETTER_PHI 0x03a6 643 | #define RLHK_TUI_GREEK_CAPITAL_LETTER_THETA 0x0398 644 | #define RLHK_TUI_GREEK_CAPITAL_LETTER_OMEGA 0x03a9 645 | #define RLHK_TUI_GREEK_SMALL_LETTER_DELTA 0x03b4 646 | #define RLHK_TUI_INFINITY 0x221e 647 | #define RLHK_TUI_GREEK_SMALL_LETTER_PHI 0x03c6 648 | #define RLHK_TUI_GREEK_SMALL_LETTER_EPSILON 0x03b5 649 | #define RLHK_TUI_INTERSECTION 0x2229 650 | #define RLHK_TUI_IDENTICAL_TO 0x2261 651 | #define RLHK_TUI_PLUS_MINUS_SIGN 0x00b1 652 | #define RLHK_TUI_GREATER_THAN_OR_EQUAL_TO 0x2265 653 | #define RLHK_TUI_LESS_THAN_OR_EQUAL_TO 0x2264 654 | #define RLHK_TUI_TOP_HALF_INTEGRAL 0x2320 655 | #define RLHK_TUI_BOTTOM_HALF_INTEGRAL 0x2321 656 | #define RLHK_TUI_DIVISION_SIGN 0x00f7 657 | #define RLHK_TUI_ALMOST_EQUAL_TO 0x2248 658 | #define RLHK_TUI_DEGREE_SIGN 0x00b0 659 | #define RLHK_TUI_BULLET_OPERATOR 0x2219 660 | #define RLHK_TUI_MIDDLE_DOT 0x00b7 661 | #define RLHK_TUI_SQUARE_ROOT 0x221a 662 | #define RLHK_TUI_SUPERSCRIPT_LATIN_SMALL_LETTER_N 0x207f 663 | #define RLHK_TUI_SUPERSCRIPT_TWO 0x00b2 664 | #define RLHK_TUI_BLACK_SQUARE 0x25a0 665 | #elif defined(__MSDOS__) 666 | #define RLHK_TUI_WHITE_SMILING_FACE 0x01 667 | #define RLHK_TUI_BLACK_SMILING_FACE 0x02 668 | #define RLHK_TUI_BLACK_HEART_SUIT 0x03 669 | #define RLHK_TUI_BLACK_DIAMOND_SUIT 0x04 670 | #define RLHK_TUI_BLACK_CLUB_SUIT 0x05 671 | #define RLHK_TUI_BLACK_SPADE_SUIT 0x06 672 | #define RLHK_TUI_BULLET 0x07 673 | #define RLHK_TUI_INVERSE_BULLET 0x08 674 | #define RLHK_TUI_WHITE_CIRCLE 0x09 675 | #define RLHK_TUI_INVERSE_WHITE_CIRCLE 0x0a 676 | #define RLHK_TUI_MALE_SIGN 0x0b 677 | #define RLHK_TUI_FEMALE_SIGN 0x0c 678 | #define RLHK_TUI_EIGHTH_NOTE 0x0d 679 | #define RLHK_TUI_BEAMED_EIGHTH_NOTES 0x0e 680 | #define RLHK_TUI_WHITE_SUN_WITH_RAYS 0x0f 681 | #define RLHK_TUI_BLACK_RIGHT_POINTING_POINTER 0x10 682 | #define RLHK_TUI_BLACK_LEFT_POINTING_POINTER 0x11 683 | #define RLHK_TUI_UP_DOWN_ARROW 0x12 684 | #define RLHK_TUI_DOUBLE_EXCLAMATION_MARK 0x13 685 | #define RLHK_TUI_PILCROW_SIGN 0x14 686 | #define RLHK_TUI_SECTION_SIGN 0x15 687 | #define RLHK_TUI_BLACK_RECTANGLE 0x16 688 | #define RLHK_TUI_UP_DOWN_ARROW_WITH_BASE 0x17 689 | #define RLHK_TUI_UPWARDS_ARROW 0x18 690 | #define RLHK_TUI_DOWNWARDS_ARROW 0x19 691 | #define RLHK_TUI_RIGHTWARDS_ARROW 0x1a 692 | #define RLHK_TUI_LEFTWARDS_ARROW 0x1b 693 | #define RLHK_TUI_RIGHT_ANGLE 0x1c 694 | #define RLHK_TUI_LEFT_RIGHT_ARROW 0x1d 695 | #define RLHK_TUI_BLACK_UP_POINTING_TRIANGLE 0x1e 696 | #define RLHK_TUI_BLACK_DOWN_POINTING_TRIANGLE 0x1f 697 | #define RLHK_TUI_SPACE 0x20 698 | #define RLHK_TUI_EXCLAMATION_MARK 0x21 699 | #define RLHK_TUI_QUOTATION_MARK 0x22 700 | #define RLHK_TUI_NUMBER_SIGN 0x23 701 | #define RLHK_TUI_DOLLAR_SIGN 0x24 702 | #define RLHK_TUI_PERCENT_SIGN 0x25 703 | #define RLHK_TUI_AMPERSAND 0x26 704 | #define RLHK_TUI_APOSTROPHE 0x27 705 | #define RLHK_TUI_LEFT_PARENTHESIS 0x28 706 | #define RLHK_TUI_RIGHT_PARENTHESIS 0x29 707 | #define RLHK_TUI_ASTERISK 0x2a 708 | #define RLHK_TUI_PLUS_SIGN 0x2b 709 | #define RLHK_TUI_COMMA 0x2c 710 | #define RLHK_TUI_HYPHEN_MINUS 0x2d 711 | #define RLHK_TUI_FULL_STOP 0x2e 712 | #define RLHK_TUI_SOLIDUS 0x2f 713 | #define RLHK_TUI_DIGIT_ZERO 0x30 714 | #define RLHK_TUI_DIGIT_ONE 0x31 715 | #define RLHK_TUI_DIGIT_TWO 0x32 716 | #define RLHK_TUI_DIGIT_THREE 0x33 717 | #define RLHK_TUI_DIGIT_FOUR 0x34 718 | #define RLHK_TUI_DIGIT_FIVE 0x35 719 | #define RLHK_TUI_DIGIT_SIX 0x36 720 | #define RLHK_TUI_DIGIT_SEVEN 0x37 721 | #define RLHK_TUI_DIGIT_EIGHT 0x38 722 | #define RLHK_TUI_DIGIT_NINE 0x39 723 | #define RLHK_TUI_COLON 0x3a 724 | #define RLHK_TUI_SEMICOLON 0x3b 725 | #define RLHK_TUI_LESS_THAN_SIGN 0x3c 726 | #define RLHK_TUI_EQUALS_SIGN 0x3d 727 | #define RLHK_TUI_GREATER_THAN_SIGN 0x3e 728 | #define RLHK_TUI_QUESTION_MARK 0x3f 729 | #define RLHK_TUI_COMMERCIAL_AT 0x40 730 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_A 0x41 731 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_B 0x42 732 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_C 0x43 733 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_D 0x44 734 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_E 0x45 735 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_F 0x46 736 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_G 0x47 737 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_H 0x48 738 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_I 0x49 739 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_J 0x4a 740 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_K 0x4b 741 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_L 0x4c 742 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_M 0x4d 743 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_N 0x4e 744 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_O 0x4f 745 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_P 0x50 746 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_Q 0x51 747 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_R 0x52 748 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_S 0x53 749 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_T 0x54 750 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_U 0x55 751 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_V 0x56 752 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_W 0x57 753 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_X 0x58 754 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_Y 0x59 755 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_Z 0x5a 756 | #define RLHK_TUI_LEFT_SQUARE_BRACKET 0x5b 757 | #define RLHK_TUI_REVERSE_SOLIDUS 0x5c 758 | #define RLHK_TUI_RIGHT_SQUARE_BRACKET 0x5d 759 | #define RLHK_TUI_CIRCUMFLEX_ACCENT 0x5e 760 | #define RLHK_TUI_LOW_LINE 0x5f 761 | #define RLHK_TUI_GRAVE_ACCENT 0x60 762 | #define RLHK_TUI_LATIN_SMALL_LETTER_A 0x61 763 | #define RLHK_TUI_LATIN_SMALL_LETTER_B 0x62 764 | #define RLHK_TUI_LATIN_SMALL_LETTER_C 0x63 765 | #define RLHK_TUI_LATIN_SMALL_LETTER_D 0x64 766 | #define RLHK_TUI_LATIN_SMALL_LETTER_E 0x65 767 | #define RLHK_TUI_LATIN_SMALL_LETTER_F 0x66 768 | #define RLHK_TUI_LATIN_SMALL_LETTER_G 0x67 769 | #define RLHK_TUI_LATIN_SMALL_LETTER_H 0x68 770 | #define RLHK_TUI_LATIN_SMALL_LETTER_I 0x69 771 | #define RLHK_TUI_LATIN_SMALL_LETTER_J 0x6a 772 | #define RLHK_TUI_LATIN_SMALL_LETTER_K 0x6b 773 | #define RLHK_TUI_LATIN_SMALL_LETTER_L 0x6c 774 | #define RLHK_TUI_LATIN_SMALL_LETTER_M 0x6d 775 | #define RLHK_TUI_LATIN_SMALL_LETTER_N 0x6e 776 | #define RLHK_TUI_LATIN_SMALL_LETTER_O 0x6f 777 | #define RLHK_TUI_LATIN_SMALL_LETTER_P 0x70 778 | #define RLHK_TUI_LATIN_SMALL_LETTER_Q 0x71 779 | #define RLHK_TUI_LATIN_SMALL_LETTER_R 0x72 780 | #define RLHK_TUI_LATIN_SMALL_LETTER_S 0x73 781 | #define RLHK_TUI_LATIN_SMALL_LETTER_T 0x74 782 | #define RLHK_TUI_LATIN_SMALL_LETTER_U 0x75 783 | #define RLHK_TUI_LATIN_SMALL_LETTER_V 0x76 784 | #define RLHK_TUI_LATIN_SMALL_LETTER_W 0x77 785 | #define RLHK_TUI_LATIN_SMALL_LETTER_X 0x78 786 | #define RLHK_TUI_LATIN_SMALL_LETTER_Y 0x79 787 | #define RLHK_TUI_LATIN_SMALL_LETTER_Z 0x7a 788 | #define RLHK_TUI_LEFT_CURLY_BRACKET 0x7b 789 | #define RLHK_TUI_VERTICAL_LINE 0x7c 790 | #define RLHK_TUI_RIGHT_CURLY_BRACKET 0x7d 791 | #define RLHK_TUI_TILDE 0x7e 792 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_C_WITH_CEDILLA 0x80 793 | #define RLHK_TUI_LATIN_SMALL_LETTER_U_WITH_DIAERESIS 0x81 794 | #define RLHK_TUI_LATIN_SMALL_LETTER_E_WITH_ACUTE 0x82 795 | #define RLHK_TUI_LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX 0x83 796 | #define RLHK_TUI_LATIN_SMALL_LETTER_A_WITH_DIAERESIS 0x84 797 | #define RLHK_TUI_LATIN_SMALL_LETTER_A_WITH_GRAVE 0x85 798 | #define RLHK_TUI_LATIN_SMALL_LETTER_A_WITH_RING_ABOVE 0x86 799 | #define RLHK_TUI_LATIN_SMALL_LETTER_C_WITH_CEDILLA 0x87 800 | #define RLHK_TUI_LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX 0x88 801 | #define RLHK_TUI_LATIN_SMALL_LETTER_E_WITH_DIAERESIS 0x89 802 | #define RLHK_TUI_LATIN_SMALL_LETTER_E_WITH_GRAVE 0x8a 803 | #define RLHK_TUI_LATIN_SMALL_LETTER_I_WITH_DIAERESIS 0x8b 804 | #define RLHK_TUI_LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX 0x8c 805 | #define RLHK_TUI_LATIN_SMALL_LETTER_I_WITH_GRAVE 0x8d 806 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS 0x8e 807 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE 0x8f 808 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_E_WITH_ACUTE 0x90 809 | #define RLHK_TUI_LATIN_SMALL_LIGATURE_AE 0x91 810 | #define RLHK_TUI_LATIN_CAPITAL_LIGATURE_AE 0x92 811 | #define RLHK_TUI_LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX 0x93 812 | #define RLHK_TUI_LATIN_SMALL_LETTER_O_WITH_DIAERESIS 0x94 813 | #define RLHK_TUI_LATIN_SMALL_LETTER_O_WITH_GRAVE 0x95 814 | #define RLHK_TUI_LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX 0x96 815 | #define RLHK_TUI_LATIN_SMALL_LETTER_U_WITH_GRAVE 0x97 816 | #define RLHK_TUI_LATIN_SMALL_LETTER_Y_WITH_DIAERESIS 0x98 817 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS 0x99 818 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS 0x9a 819 | #define RLHK_TUI_CENT_SIGN 0x9b 820 | #define RLHK_TUI_POUND_SIGN 0x9c 821 | #define RLHK_TUI_YEN_SIGN 0x9d 822 | #define RLHK_TUI_PESETA_SIGN 0x9e 823 | #define RLHK_TUI_LATIN_SMALL_LETTER_F_WITH_HOOK 0x9f 824 | #define RLHK_TUI_LATIN_SMALL_LETTER_A_WITH_ACUTE 0xa0 825 | #define RLHK_TUI_LATIN_SMALL_LETTER_I_WITH_ACUTE 0xa1 826 | #define RLHK_TUI_LATIN_SMALL_LETTER_O_WITH_ACUTE 0xa2 827 | #define RLHK_TUI_LATIN_SMALL_LETTER_U_WITH_ACUTE 0xa3 828 | #define RLHK_TUI_LATIN_SMALL_LETTER_N_WITH_TILDE 0xa4 829 | #define RLHK_TUI_LATIN_CAPITAL_LETTER_N_WITH_TILDE 0xa5 830 | #define RLHK_TUI_FEMININE_ORDINAL_INDICATOR 0xa6 831 | #define RLHK_TUI_MASCULINE_ORDINAL_INDICATOR 0xa7 832 | #define RLHK_TUI_INVERTED_QUESTION_MARK 0xa8 833 | #define RLHK_TUI_REVERSED_NOT_SIGN 0xa9 834 | #define RLHK_TUI_NOT_SIGN 0xaa 835 | #define RLHK_TUI_VULGAR_FRACTION_ONE_HALF 0xab 836 | #define RLHK_TUI_VULGAR_FRACTION_ONE_QUARTER 0xac 837 | #define RLHK_TUI_INVERTED_EXCLAMATION_MARK 0xad 838 | #define RLHK_TUI_LEFT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK 0xae 839 | #define RLHK_TUI_RIGHT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK 0xaf 840 | #define RLHK_TUI_LIGHT_SHADE 0xb0 841 | #define RLHK_TUI_MEDIUM_SHADE 0xb1 842 | #define RLHK_TUI_DARK_SHADE 0xb2 843 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_VERTICAL 0xb3 844 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_VERTICAL_AND_LEFT 0xb4 845 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_SINGLE_AND_LEFT_DOUBLE 0xb5 846 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_DOUBLE_AND_LEFT_SINGLE 0xb6 847 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_DOUBLE_AND_LEFT_SINGLE 0xb7 848 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_SINGLE_AND_LEFT_DOUBLE 0xb8 849 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_VERTICAL_AND_LEFT 0xb9 850 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_VERTICAL 0xba 851 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_DOWN_AND_LEFT 0xbb 852 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_UP_AND_LEFT 0xbc 853 | #define RLHK_TUI_BOX_DRAWINGS_UP_DOUBLE_AND_LEFT_SINGLE 0xbd 854 | #define RLHK_TUI_BOX_DRAWINGS_UP_SINGLE_AND_LEFT_DOUBLE 0xbe 855 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_DOWN_AND_LEFT 0xbf 856 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_UP_AND_RIGHT 0xc0 857 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_UP_AND_HORIZONTAL 0xc1 858 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_DOWN_AND_HORIZONTAL 0xc2 859 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_VERTICAL_AND_RIGHT 0xc3 860 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_HORIZONTAL 0xc4 861 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_VERTICAL_AND_HORIZONTAL 0xc5 862 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_SINGLE_AND_RIGHT_DOUBLE 0xc6 863 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_DOUBLE_AND_RIGHT_SINGLE 0xc7 864 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_UP_AND_RIGHT 0xc8 865 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_DOWN_AND_RIGHT 0xc9 866 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_UP_AND_HORIZONTAL 0xca 867 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_DOWN_AND_HORIZONTAL 0xcb 868 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_VERTICAL_AND_RIGHT 0xcc 869 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_HORIZONTAL 0xcd 870 | #define RLHK_TUI_BOX_DRAWINGS_DOUBLE_VERTICAL_AND_HORIZONTAL 0xce 871 | #define RLHK_TUI_BOX_DRAWINGS_UP_SINGLE_AND_HORIZONTAL_DOUBLE 0xcf 872 | #define RLHK_TUI_BOX_DRAWINGS_UP_DOUBLE_AND_HORIZONTAL_SINGLE 0xd0 873 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_SINGLE_AND_HORIZONTAL_DOUBLE 0xd1 874 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_DOUBLE_AND_HORIZONTAL_SINGLE 0xd2 875 | #define RLHK_TUI_BOX_DRAWINGS_UP_DOUBLE_AND_RIGHT_SINGLE 0xd3 876 | #define RLHK_TUI_BOX_DRAWINGS_UP_SINGLE_AND_RIGHT_DOUBLE 0xd4 877 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_SINGLE_AND_RIGHT_DOUBLE 0xd5 878 | #define RLHK_TUI_BOX_DRAWINGS_DOWN_DOUBLE_AND_RIGHT_SINGLE 0xd6 879 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_DOUBLE_AND_HORIZONTAL_SINGLE 0xd7 880 | #define RLHK_TUI_BOX_DRAWINGS_VERTICAL_SINGLE_AND_HORIZONTAL_DOUBLE 0xd8 881 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_UP_AND_LEFT 0xd9 882 | #define RLHK_TUI_BOX_DRAWINGS_LIGHT_DOWN_AND_RIGHT 0xda 883 | #define RLHK_TUI_FULL_BLOCK 0xdb 884 | #define RLHK_TUI_LOWER_HALF_BLOCK 0xdc 885 | #define RLHK_TUI_LEFT_HALF_BLOCK 0xdd 886 | #define RLHK_TUI_RIGHT_HALF_BLOCK 0xde 887 | #define RLHK_TUI_UPPER_HALF_BLOCK 0xdf 888 | #define RLHK_TUI_GREEK_SMALL_LETTER_ALPHA 0xe0 889 | #define RLHK_TUI_LATIN_SMALL_LETTER_SHARP_S 0xe1 890 | #define RLHK_TUI_GREEK_CAPITAL_LETTER_GAMMA 0xe2 891 | #define RLHK_TUI_GREEK_SMALL_LETTER_PI 0xe3 892 | #define RLHK_TUI_GREEK_CAPITAL_LETTER_SIGMA 0xe4 893 | #define RLHK_TUI_GREEK_SMALL_LETTER_SIGMA 0xe5 894 | #define RLHK_TUI_MICRO_SIGN 0xe6 895 | #define RLHK_TUI_GREEK_SMALL_LETTER_TAU 0xe7 896 | #define RLHK_TUI_GREEK_CAPITAL_LETTER_PHI 0xe8 897 | #define RLHK_TUI_GREEK_CAPITAL_LETTER_THETA 0xe9 898 | #define RLHK_TUI_GREEK_CAPITAL_LETTER_OMEGA 0xea 899 | #define RLHK_TUI_GREEK_SMALL_LETTER_DELTA 0xeb 900 | #define RLHK_TUI_INFINITY 0xec 901 | #define RLHK_TUI_GREEK_SMALL_LETTER_PHI 0xed 902 | #define RLHK_TUI_GREEK_SMALL_LETTER_EPSILON 0xee 903 | #define RLHK_TUI_INTERSECTION 0xef 904 | #define RLHK_TUI_IDENTICAL_TO 0xf0 905 | #define RLHK_TUI_PLUS_MINUS_SIGN 0xf1 906 | #define RLHK_TUI_GREATER_THAN_OR_EQUAL_TO 0xf2 907 | #define RLHK_TUI_LESS_THAN_OR_EQUAL_TO 0xf3 908 | #define RLHK_TUI_TOP_HALF_INTEGRAL 0xf4 909 | #define RLHK_TUI_BOTTOM_HALF_INTEGRAL 0xf5 910 | #define RLHK_TUI_DIVISION_SIGN 0xf6 911 | #define RLHK_TUI_ALMOST_EQUAL_TO 0xf7 912 | #define RLHK_TUI_DEGREE_SIGN 0xf8 913 | #define RLHK_TUI_BULLET_OPERATOR 0xf9 914 | #define RLHK_TUI_MIDDLE_DOT 0xfa 915 | #define RLHK_TUI_SQUARE_ROOT 0xfb 916 | #define RLHK_TUI_SUPERSCRIPT_LATIN_SMALL_LETTER_N 0xfc 917 | #define RLHK_TUI_SUPERSCRIPT_TWO 0xfd 918 | #define RLHK_TUI_BLACK_SQUARE 0xfe 919 | #endif /* __MSDOS__ */ 920 | 921 | /* Implementation */ 922 | #if defined(RLHK_IMPLEMENTATION) || defined(RLHK_TUI_IMPLEMENTATION) 923 | 924 | static int rlhk_tui_width; 925 | static int rlhk_tui_height; 926 | 927 | #if (defined(__unix__) || defined(__APPLE__)) && !defined(__DJGPP__) 928 | /* Here we're free to assume an int is 32-bits. */ 929 | #include 930 | #include 931 | #include 932 | #include 933 | #include 934 | 935 | struct termios rlhk_tui_termios_orig; 936 | 937 | /* The last written display. */ 938 | static unsigned rlhk_tui_oldc[RLHK_TUI_MAX_HEIGHT][RLHK_TUI_MAX_WIDTH]; 939 | static unsigned char rlhk_tui_olda[RLHK_TUI_MAX_HEIGHT][RLHK_TUI_MAX_WIDTH]; 940 | 941 | /* Characters to be written on the next flush. */ 942 | static unsigned rlhk_tui_bufc[RLHK_TUI_MAX_HEIGHT][RLHK_TUI_MAX_WIDTH]; 943 | static unsigned char rlhk_tui_bufa[RLHK_TUI_MAX_HEIGHT][RLHK_TUI_MAX_WIDTH]; 944 | 945 | static unsigned char * 946 | rlhk_tui_itoa(unsigned char *p, int v) 947 | { 948 | int len = !v; 949 | int i; 950 | for (i = v; i; i /= 10) 951 | len++; 952 | for (i = len - 1; i >= 0; i--, v /= 10) 953 | p[i] = v % 10 + '0'; 954 | return p + len; 955 | } 956 | 957 | RLHK_TUI_API 958 | int 959 | rlhk_tui_init(int width, int height) 960 | { 961 | struct termios raw; 962 | char init[] = { 963 | "\x1b[2J" /* Clear the screen. */ 964 | "\x1b[?25l" /* Hide the cursor. */ 965 | }; 966 | rlhk_tui_width = width; 967 | rlhk_tui_height = height; 968 | if (tcgetattr(STDIN_FILENO, &rlhk_tui_termios_orig) == -1) 969 | return 0; 970 | memcpy(&raw, &rlhk_tui_termios_orig, sizeof(raw)); 971 | raw.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); 972 | raw.c_oflag &= ~OPOST; 973 | raw.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); 974 | raw.c_cflag &= ~(CSIZE|PARENB); 975 | raw.c_cflag |= CS8; 976 | if (tcsetattr(STDIN_FILENO, TCSANOW, &raw) == -1) 977 | return 0; 978 | return write(STDIN_FILENO, init, sizeof(init) - 1) == sizeof(init) - 1; 979 | } 980 | 981 | RLHK_TUI_API 982 | int 983 | rlhk_tui_release(void) 984 | { 985 | char finish[24] = 986 | "\x1b[?25h" /* Restore cursor visibility. */ 987 | "\x1b["; /* Move cursor just outside drawing region. */ 988 | ssize_t finishz = sizeof(finish) - 1; 989 | unsigned char *f = (unsigned char *)finish + strlen(finish); 990 | char *p = (char *)rlhk_tui_itoa(f, rlhk_tui_height); 991 | strcpy(p, ";0H" "\x1b[0m\n"); /* Disable color/style. */ 992 | tcsetattr(STDIN_FILENO, TCSANOW, &rlhk_tui_termios_orig); 993 | memset(rlhk_tui_oldc, 0, sizeof(rlhk_tui_oldc)); 994 | return write(STDIN_FILENO, finish, finishz) == finishz; 995 | } 996 | 997 | RLHK_TUI_API 998 | void 999 | rlhk_tui_putc(int x, int y, unsigned c, unsigned attr) 1000 | { 1001 | rlhk_tui_bufc[y][x] = c; 1002 | rlhk_tui_bufa[y][x] = attr; 1003 | } 1004 | 1005 | RLHK_TUI_API 1006 | int 1007 | rlhk_tui_flush(void) 1008 | { 1009 | int x, y; 1010 | /* Estimated worst-case buffer. */ 1011 | static unsigned char buf[RLHK_TUI_MAX_HEIGHT * RLHK_TUI_MAX_WIDTH * 1012 | (5 + 11 + 3)]; 1013 | unsigned char *p = buf; 1014 | unsigned last_a = -1u; 1015 | int cx = -1; 1016 | int cy = -1; 1017 | for (y = 0; y < rlhk_tui_height; y++) { 1018 | for (x = 0; x < rlhk_tui_width; x++) { 1019 | unsigned *oc = &rlhk_tui_oldc[y][x]; 1020 | unsigned char *oa = &rlhk_tui_olda[y][x]; 1021 | unsigned c = rlhk_tui_bufc[y][x]; 1022 | unsigned a = rlhk_tui_bufa[y][x]; 1023 | if (*oc != c || *oa != a) { 1024 | /* Move to location. */ 1025 | if (x != cx || y != cy) { 1026 | *p++ = 0x1b; 1027 | *p++ = '['; 1028 | p = rlhk_tui_itoa(p, y + 1); 1029 | *p++ = ';'; 1030 | p = rlhk_tui_itoa(p, x + 1); 1031 | *p++ = 'H'; 1032 | last_a = -1u; 1033 | } 1034 | /* Apply colors. */ 1035 | if (a != last_a) { 1036 | int fg = ((a >> 0) & 0x07) + (a & 0x08 ? 90 : 30); 1037 | int bg = ((a >> 4) & 0x07) + (a & 0x80 ? 100 : 40); 1038 | *p++ = 0x1b; 1039 | *p++ = '['; 1040 | p = rlhk_tui_itoa(p, fg); 1041 | *p++ = ';'; 1042 | p = rlhk_tui_itoa(p, bg); 1043 | *p++ = 'm'; 1044 | last_a = a; 1045 | } 1046 | cx = x + 1; 1047 | cy = y; 1048 | *oc = c; 1049 | *oa = a; 1050 | do { 1051 | *p++ = c; 1052 | c >>= 8; 1053 | } while (c); 1054 | } 1055 | } 1056 | } 1057 | return write(STDOUT_FILENO, buf, p - buf) == p - buf; 1058 | } 1059 | 1060 | RLHK_TUI_API 1061 | int 1062 | rlhk_tui_getch(void) 1063 | { 1064 | int r; 1065 | unsigned char c; 1066 | if ((r = read(STDIN_FILENO, &c, 1)) != 1) { 1067 | return -1; 1068 | } else if (c == '\x1b') { 1069 | unsigned char code[2]; 1070 | if (read(STDIN_FILENO, code, 2) != 2) 1071 | return -1; 1072 | return code[1] + 256; 1073 | } else { 1074 | return c; 1075 | } 1076 | } 1077 | 1078 | RLHK_TUI_API 1079 | int 1080 | rlhk_tui_title(const char *title) 1081 | { 1082 | char a = '\a'; 1083 | ssize_t len = strlen(title); 1084 | if (write(STDIN_FILENO, "\x1b]2;", 4) != 4) 1085 | return 0; 1086 | if (write(STDIN_FILENO, title, len) != len) 1087 | return 0; 1088 | if (write(STDIN_FILENO, &a, 1) != 1) 1089 | return 0; 1090 | return 1; 1091 | } 1092 | 1093 | RLHK_TUI_API 1094 | int 1095 | rlhk_tui_size(int *width, int *height) 1096 | { 1097 | struct winsize w; 1098 | if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) != -1) { 1099 | *width = w.ws_col; 1100 | *height = w.ws_row; 1101 | return 1; 1102 | } else { 1103 | return 0; 1104 | } 1105 | } 1106 | 1107 | #elif defined(_WIN32) 1108 | #include 1109 | #include 1110 | 1111 | static CHAR_INFO rlhk_tui_buf[RLHK_TUI_MAX_HEIGHT * RLHK_TUI_MAX_WIDTH]; 1112 | static HANDLE rlhk_tui_out; 1113 | static HANDLE rlhk_tui_in; 1114 | static DWORD rlhk_tui_mode_orig; 1115 | 1116 | RLHK_TUI_API 1117 | int 1118 | rlhk_tui_init(int width, int height) 1119 | { 1120 | CONSOLE_CURSOR_INFO info = {100, FALSE}; 1121 | SMALL_RECT window = {0, 0, 0, 0}; 1122 | COORD size; 1123 | DWORD mode; 1124 | rlhk_tui_width = width; 1125 | rlhk_tui_height = height; 1126 | rlhk_tui_out = GetStdHandle(STD_OUTPUT_HANDLE); 1127 | rlhk_tui_in = GetStdHandle(STD_INPUT_HANDLE); 1128 | 1129 | /* Adjust console input and cursor. */ 1130 | SetConsoleCursorInfo(rlhk_tui_out, &info); 1131 | GetConsoleMode(rlhk_tui_in, &rlhk_tui_mode_orig); 1132 | mode = rlhk_tui_mode_orig & ~ENABLE_PROCESSED_INPUT; 1133 | SetConsoleMode(rlhk_tui_in, mode); 1134 | 1135 | /* Adjust window size. */ 1136 | window.Bottom = height - 1; 1137 | window.Right = width - 1; 1138 | if (!SetConsoleWindowInfo(rlhk_tui_out, TRUE, &window)) 1139 | return 0; 1140 | 1141 | /* Adjust buffer size. */ 1142 | size.X = width; 1143 | size.Y = height; 1144 | if (!SetConsoleScreenBufferSize(rlhk_tui_out, size)) 1145 | return 0; 1146 | 1147 | return 1; 1148 | } 1149 | 1150 | RLHK_TUI_API 1151 | int 1152 | rlhk_tui_release(void) 1153 | { 1154 | CONSOLE_CURSOR_INFO info = {100, TRUE}; 1155 | COORD coord = {0, 0}; 1156 | coord.Y = rlhk_tui_height - 1; 1157 | return 1158 | SetConsoleCursorInfo(rlhk_tui_out, &info) && 1159 | SetConsoleCursorPosition(rlhk_tui_out, coord) && 1160 | SetConsoleMode(rlhk_tui_in, rlhk_tui_mode_orig); 1161 | } 1162 | 1163 | RLHK_TUI_API 1164 | void 1165 | rlhk_tui_putc(int x, int y, unsigned c, unsigned attr) 1166 | { 1167 | rlhk_tui_buf[y * rlhk_tui_width + x].Char.UnicodeChar = c; 1168 | rlhk_tui_buf[y * rlhk_tui_width + x].Attributes = 1169 | (attr & 0xaa) | ((attr >> 2) & 0x11) | ((attr << 2) & 0x44); 1170 | } 1171 | 1172 | RLHK_TUI_API 1173 | int 1174 | rlhk_tui_flush(void) 1175 | { 1176 | COORD origin = {0, 0}; 1177 | SMALL_RECT area = {0, 0, 0, 0}; 1178 | COORD size; 1179 | void *buf = rlhk_tui_buf; 1180 | area.Right = rlhk_tui_width; 1181 | area.Bottom = rlhk_tui_height; 1182 | size.X = rlhk_tui_width; 1183 | size.Y = rlhk_tui_height; 1184 | return !!WriteConsoleOutputW(rlhk_tui_out, buf, size, origin, &area); 1185 | } 1186 | 1187 | RLHK_TUI_API 1188 | int 1189 | rlhk_tui_getch(void) 1190 | { 1191 | /* getch() cannot fail, so this function cannot fail. */ 1192 | int result = getch(); 1193 | if (result != 0xE0 && result != 0x00) { 1194 | return result; 1195 | } else { 1196 | result = getch(); 1197 | switch (result) { 1198 | case 72: 1199 | return RLHK_TUI_VK_U; 1200 | case 80: 1201 | return RLHK_TUI_VK_D; 1202 | case 75: 1203 | return RLHK_TUI_VK_L; 1204 | case 77: 1205 | return RLHK_TUI_VK_R; 1206 | case 71: 1207 | return RLHK_TUI_VK_UL; 1208 | case 73: 1209 | return RLHK_TUI_VK_UR; 1210 | case 79: 1211 | return RLHK_TUI_VK_DL; 1212 | case 81: 1213 | return RLHK_TUI_VK_DR; 1214 | default: 1215 | return result + 256; 1216 | } 1217 | } 1218 | } 1219 | 1220 | RLHK_TUI_API 1221 | int 1222 | rlhk_tui_title(const char *title) 1223 | { 1224 | return !!SetConsoleTitle(title); 1225 | } 1226 | 1227 | RLHK_TUI_API 1228 | int 1229 | rlhk_tui_size(int *width, int *height) 1230 | { 1231 | CONSOLE_SCREEN_BUFFER_INFO csbi; 1232 | if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) 1233 | return 0; 1234 | *width = csbi.srWindow.Right - csbi.srWindow.Left + 1; 1235 | *height = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; 1236 | return 1; 1237 | } 1238 | 1239 | #elif defined(__DJGPP__) 1240 | #ifdef __STRICT_ANSI__ 1241 | # undef __STRICT_ANSI__ /* Disable DJGPP annoyance. */ 1242 | #endif 1243 | #include 1244 | #include 1245 | #include 1246 | 1247 | static unsigned short rlhk_tui_buf[25][80]; 1248 | 1249 | RLHK_TUI_API 1250 | int 1251 | rlhk_tui_init(int width, int height) 1252 | { 1253 | rlhk_tui_width = width; 1254 | rlhk_tui_height = height; 1255 | return width <= 80 && height <= 25; 1256 | } 1257 | 1258 | RLHK_TUI_API 1259 | int 1260 | rlhk_tui_release(void) 1261 | { 1262 | memset(rlhk_tui_buf, 0, sizeof(rlhk_tui_buf)); 1263 | return 1; 1264 | } 1265 | 1266 | RLHK_TUI_API 1267 | void 1268 | rlhk_tui_putc(int x, int y, unsigned c, unsigned attr) 1269 | { 1270 | unsigned a = (attr & 0x2a) | ((attr >> 2) & 0x11) | ((attr << 2) & 0x44); 1271 | rlhk_tui_buf[y][x] = c | (a << 8); 1272 | } 1273 | 1274 | RLHK_TUI_API 1275 | int 1276 | rlhk_tui_flush(void) 1277 | { 1278 | char *screen = (char *)0xb8000 + __djgpp_conventional_base; 1279 | if (!__djgpp_nearptr_enable()) 1280 | return 0; 1281 | memcpy(screen, rlhk_tui_buf, sizeof(rlhk_tui_buf)); 1282 | __djgpp_nearptr_disable(); 1283 | return 1; 1284 | } 1285 | 1286 | RLHK_TUI_API 1287 | int 1288 | rlhk_tui_getch(void) 1289 | { 1290 | /* getch() cannot fail, so this function cannot fail. */ 1291 | int result = getch(); 1292 | if (result != 0xE0 && result != 0x00) { 1293 | return result; 1294 | } else { 1295 | result = getch(); 1296 | switch (result) { 1297 | case 72: 1298 | return RLHK_TUI_VK_U; 1299 | case 80: 1300 | return RLHK_TUI_VK_D; 1301 | case 75: 1302 | return RLHK_TUI_VK_L; 1303 | case 77: 1304 | return RLHK_TUI_VK_R; 1305 | case 71: 1306 | return RLHK_TUI_VK_UL; 1307 | case 73: 1308 | return RLHK_TUI_VK_UR; 1309 | case 79: 1310 | return RLHK_TUI_VK_DL; 1311 | case 81: 1312 | return RLHK_TUI_VK_DR; 1313 | default: 1314 | return result + 256; 1315 | } 1316 | } 1317 | } 1318 | 1319 | RLHK_TUI_API 1320 | int 1321 | rlhk_tui_title(const char *s) 1322 | { 1323 | return !!s; 1324 | } 1325 | 1326 | RLHK_TUI_API 1327 | int 1328 | rlhk_tui_size(int *width, int *height) 1329 | { 1330 | *width = 80; 1331 | *height = 25; 1332 | return 1; 1333 | } 1334 | 1335 | #endif /* __MSDOS__ */ 1336 | #endif /* RLHK_TUI_IMPLEMENTATION */ 1337 | #endif /* RLHK_TUI_H */ 1338 | --------------------------------------------------------------------------------