Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1 | pmbaty | 1 | /* |
| 2 | * This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>. |
||
| 3 | * It is copyright by its individual contributors, as recorded in the |
||
| 4 | * project's Git history. See COPYING.txt at the top level for license |
||
| 5 | * terms and a link to the Git history. |
||
| 6 | */ |
||
| 7 | /* |
||
| 8 | * |
||
| 9 | * SDL keyboard input support |
||
| 10 | * |
||
| 11 | * |
||
| 12 | */ |
||
| 13 | |||
| 14 | #include <algorithm> |
||
| 15 | #include <stdio.h> |
||
| 16 | #include <stdlib.h> |
||
| 17 | |||
| 18 | #include <SDL.h> |
||
| 19 | #include <SDL_version.h> |
||
| 20 | #if SDL_MAJOR_VERSION == 2 |
||
| 21 | #include <SDL_keycode.h> |
||
| 22 | #endif |
||
| 23 | |||
| 24 | #include "event.h" |
||
| 25 | #include "dxxerror.h" |
||
| 26 | #include "key.h" |
||
| 27 | #include "timer.h" |
||
| 28 | #include "window.h" |
||
| 29 | #include "console.h" |
||
| 30 | #include "args.h" |
||
| 31 | |||
| 32 | #include "dxxsconf.h" |
||
| 33 | #include "dsx-ns.h" |
||
| 34 | #include "compiler-range_for.h" |
||
| 35 | #include <array> |
||
| 36 | |||
| 37 | namespace dcx { |
||
| 38 | |||
| 39 | //-------- Variable accessed by outside functions --------- |
||
| 40 | static bool keyd_repeat; // 1 = use repeats, 0 no repeats |
||
| 41 | pressed_keys keyd_pressed; |
||
| 42 | fix64 keyd_time_when_last_pressed; |
||
| 43 | std::array<unsigned char, KEY_BUFFER_SIZE> unicode_frame_buffer; |
||
| 44 | |||
| 45 | const std::array<key_props, 256> key_properties = {{ |
||
| 46 | { "", 255, SDLK_UNKNOWN }, // 0 |
||
| 47 | { "ESC", 255, SDLK_ESCAPE }, |
||
| 48 | { "1", '1', SDLK_1 }, |
||
| 49 | { "2", '2', SDLK_2 }, |
||
| 50 | { "3", '3', SDLK_3 }, |
||
| 51 | { "4", '4', SDLK_4 }, |
||
| 52 | { "5", '5', SDLK_5 }, |
||
| 53 | { "6", '6', SDLK_6 }, |
||
| 54 | { "7", '7', SDLK_7 }, |
||
| 55 | { "8", '8', SDLK_8 }, |
||
| 56 | { "9", '9', SDLK_9 }, // 10 |
||
| 57 | { "0", '0', SDLK_0 }, |
||
| 58 | { "-", '-', SDLK_MINUS }, |
||
| 59 | { "=", '=', SDLK_EQUALS }, |
||
| 60 | { "BSPC", 255, SDLK_BACKSPACE }, |
||
| 61 | { "TAB", 255, SDLK_TAB }, |
||
| 62 | { "Q", 'q', SDLK_q }, |
||
| 63 | { "W", 'w', SDLK_w }, |
||
| 64 | { "E", 'e', SDLK_e }, |
||
| 65 | { "R", 'r', SDLK_r }, |
||
| 66 | { "T", 't', SDLK_t }, // 20 |
||
| 67 | { "Y", 'y', SDLK_y }, |
||
| 68 | { "U", 'u', SDLK_u }, |
||
| 69 | { "I", 'i', SDLK_i }, |
||
| 70 | { "O", 'o', SDLK_o }, |
||
| 71 | { "P", 'p', SDLK_p }, |
||
| 72 | { "[", '[', SDLK_LEFTBRACKET }, |
||
| 73 | { "]", ']', SDLK_RIGHTBRACKET }, |
||
| 74 | { "ENTER", 255, SDLK_RETURN }, |
||
| 75 | { "LCTRL", 255, SDLK_LCTRL }, |
||
| 76 | { "A", 'a', SDLK_a }, // 30 |
||
| 77 | { "S", 's', SDLK_s }, |
||
| 78 | { "D", 'd', SDLK_d }, |
||
| 79 | { "F", 'f', SDLK_f }, |
||
| 80 | { "G", 'g', SDLK_g }, |
||
| 81 | { "H", 'h', SDLK_h }, |
||
| 82 | { "J", 'j', SDLK_j }, |
||
| 83 | { "K", 'k', SDLK_k }, |
||
| 84 | { "L", 'l', SDLK_l }, |
||
| 85 | { ";", ';', SDLK_SEMICOLON }, |
||
| 86 | { "'", '\'', SDLK_QUOTE }, // 40 |
||
| 87 | { "`", '`', SDLK_BACKQUOTE }, |
||
| 88 | { "LSHFT", 255, SDLK_LSHIFT }, |
||
| 89 | { "\\", '\\', SDLK_BACKSLASH }, |
||
| 90 | { "Z", 'z', SDLK_z }, |
||
| 91 | { "X", 'x', SDLK_x }, |
||
| 92 | { "C", 'c', SDLK_c }, |
||
| 93 | { "V", 'v', SDLK_v }, |
||
| 94 | { "B", 'b', SDLK_b }, |
||
| 95 | { "N", 'n', SDLK_n }, |
||
| 96 | { "M", 'm', SDLK_m }, // 50 |
||
| 97 | { ",", ',', SDLK_COMMA }, |
||
| 98 | { ".", '.', SDLK_PERIOD }, |
||
| 99 | { "/", '/', SDLK_SLASH }, |
||
| 100 | { "RSHFT", 255, SDLK_RSHIFT }, |
||
| 101 | { "PAD*", '*', SDLK_KP_MULTIPLY }, |
||
| 102 | { "LALT", 255, SDLK_LALT }, |
||
| 103 | { "SPC", ' ', SDLK_SPACE }, |
||
| 104 | { "CPSLK", 255, SDLK_CAPSLOCK }, |
||
| 105 | { "F1", 255, SDLK_F1 }, |
||
| 106 | { "F2", 255, SDLK_F2 }, // 60 |
||
| 107 | { "F3", 255, SDLK_F3 }, |
||
| 108 | { "F4", 255, SDLK_F4 }, |
||
| 109 | { "F5", 255, SDLK_F5 }, |
||
| 110 | { "F6", 255, SDLK_F6 }, |
||
| 111 | { "F7", 255, SDLK_F7 }, |
||
| 112 | { "F8", 255, SDLK_F8 }, |
||
| 113 | { "F9", 255, SDLK_F9 }, |
||
| 114 | { "F10", 255, SDLK_F10 }, |
||
| 115 | #if SDL_MAJOR_VERSION == 1 |
||
| 116 | #define SDLK_NUMLOCKCLEAR SDLK_NUMLOCK |
||
| 117 | #define SDLK_SCROLLLOCK SDLK_SCROLLOCK |
||
| 118 | #define SDLK_KP_0 SDLK_KP0 |
||
| 119 | #define SDLK_KP_1 SDLK_KP1 |
||
| 120 | #define SDLK_KP_2 SDLK_KP2 |
||
| 121 | #define SDLK_KP_3 SDLK_KP3 |
||
| 122 | #define SDLK_KP_4 SDLK_KP4 |
||
| 123 | #define SDLK_KP_5 SDLK_KP5 |
||
| 124 | #define SDLK_KP_6 SDLK_KP6 |
||
| 125 | #define SDLK_KP_7 SDLK_KP7 |
||
| 126 | #define SDLK_KP_8 SDLK_KP8 |
||
| 127 | #define SDLK_KP_9 SDLK_KP9 |
||
| 128 | #endif |
||
| 129 | { "NMLCK", 255, SDLK_NUMLOCKCLEAR }, |
||
| 130 | { "SCLK", 255, SDLK_SCROLLLOCK }, // 70 |
||
| 131 | { "PAD7", 255, SDLK_KP_7 }, |
||
| 132 | { "PAD8", 255, SDLK_KP_8 }, |
||
| 133 | { "PAD9", 255, SDLK_KP_9 }, |
||
| 134 | { "PAD-", 255, SDLK_KP_MINUS }, |
||
| 135 | { "PAD4", 255, SDLK_KP_4 }, |
||
| 136 | { "PAD5", 255, SDLK_KP_5 }, |
||
| 137 | { "PAD6", 255, SDLK_KP_6 }, |
||
| 138 | { "PAD+", 255, SDLK_KP_PLUS }, |
||
| 139 | { "PAD1", 255, SDLK_KP_1 }, |
||
| 140 | { "PAD2", 255, SDLK_KP_2 }, // 80 |
||
| 141 | { "PAD3", 255, SDLK_KP_3 }, |
||
| 142 | { "PAD0", 255, SDLK_KP_0 }, |
||
| 143 | { "PAD.", 255, SDLK_KP_PERIOD }, |
||
| 144 | { "", 255, SDLK_UNKNOWN }, |
||
| 145 | { "", 255, SDLK_UNKNOWN }, |
||
| 146 | { "", 255, SDLK_UNKNOWN }, |
||
| 147 | { "F11", 255, SDLK_F11 }, |
||
| 148 | { "F12", 255, SDLK_F12 }, |
||
| 149 | { "", 255, SDLK_UNKNOWN }, |
||
| 150 | { "", 255, SDLK_UNKNOWN }, // 90 |
||
| 151 | { "", 255, SDLK_UNKNOWN }, |
||
| 152 | { "", 255, SDLK_UNKNOWN }, |
||
| 153 | { "", 255, SDLK_UNKNOWN }, |
||
| 154 | { "", 255, SDLK_UNKNOWN }, |
||
| 155 | { "", 255, SDLK_UNKNOWN }, |
||
| 156 | { "", 255, SDLK_UNKNOWN }, |
||
| 157 | { "PAUSE", 255, SDLK_PAUSE }, |
||
| 158 | #if SDL_MAJOR_VERSION == 2 |
||
| 159 | #define SDLK_WORLD_0 SDLK_UNKNOWN |
||
| 160 | #define SDLK_WORLD_1 SDLK_UNKNOWN |
||
| 161 | #define SDLK_WORLD_2 SDLK_UNKNOWN |
||
| 162 | #define SDLK_WORLD_3 SDLK_UNKNOWN |
||
| 163 | #define SDLK_WORLD_4 SDLK_UNKNOWN |
||
| 164 | #define SDLK_WORLD_5 SDLK_UNKNOWN |
||
| 165 | #define SDLK_WORLD_6 SDLK_UNKNOWN |
||
| 166 | #define SDLK_WORLD_7 SDLK_UNKNOWN |
||
| 167 | #define SDLK_WORLD_8 SDLK_UNKNOWN |
||
| 168 | #define SDLK_WORLD_9 SDLK_UNKNOWN |
||
| 169 | #define SDLK_WORLD_10 SDLK_UNKNOWN |
||
| 170 | #define SDLK_WORLD_11 SDLK_UNKNOWN |
||
| 171 | #define SDLK_WORLD_12 SDLK_UNKNOWN |
||
| 172 | #define SDLK_WORLD_13 SDLK_UNKNOWN |
||
| 173 | #define SDLK_WORLD_14 SDLK_UNKNOWN |
||
| 174 | #define SDLK_WORLD_15 SDLK_UNKNOWN |
||
| 175 | #define SDLK_WORLD_16 SDLK_UNKNOWN |
||
| 176 | #define SDLK_WORLD_17 SDLK_UNKNOWN |
||
| 177 | #define SDLK_WORLD_18 SDLK_UNKNOWN |
||
| 178 | #define SDLK_WORLD_19 SDLK_UNKNOWN |
||
| 179 | #define SDLK_WORLD_20 SDLK_UNKNOWN |
||
| 180 | #define SDLK_WORLD_21 SDLK_UNKNOWN |
||
| 181 | #define SDLK_WORLD_22 SDLK_UNKNOWN |
||
| 182 | #define SDLK_WORLD_23 SDLK_UNKNOWN |
||
| 183 | #define SDLK_WORLD_24 SDLK_UNKNOWN |
||
| 184 | #define SDLK_WORLD_25 SDLK_UNKNOWN |
||
| 185 | #define SDLK_WORLD_26 SDLK_UNKNOWN |
||
| 186 | #define SDLK_WORLD_27 SDLK_UNKNOWN |
||
| 187 | #define SDLK_WORLD_28 SDLK_UNKNOWN |
||
| 188 | #define SDLK_WORLD_29 SDLK_UNKNOWN |
||
| 189 | #define SDLK_WORLD_30 SDLK_UNKNOWN |
||
| 190 | #define SDLK_WORLD_31 SDLK_UNKNOWN |
||
| 191 | #define SDLK_WORLD_32 SDLK_UNKNOWN |
||
| 192 | #define SDLK_WORLD_33 SDLK_UNKNOWN |
||
| 193 | #define SDLK_WORLD_34 SDLK_UNKNOWN |
||
| 194 | #define SDLK_WORLD_35 SDLK_UNKNOWN |
||
| 195 | #define SDLK_WORLD_36 SDLK_UNKNOWN |
||
| 196 | #define SDLK_WORLD_37 SDLK_UNKNOWN |
||
| 197 | #define SDLK_WORLD_38 SDLK_UNKNOWN |
||
| 198 | #define SDLK_WORLD_39 SDLK_UNKNOWN |
||
| 199 | #define SDLK_WORLD_40 SDLK_UNKNOWN |
||
| 200 | #define SDLK_WORLD_41 SDLK_UNKNOWN |
||
| 201 | #define SDLK_WORLD_42 SDLK_UNKNOWN |
||
| 202 | #define SDLK_WORLD_43 SDLK_UNKNOWN |
||
| 203 | #define SDLK_WORLD_44 SDLK_UNKNOWN |
||
| 204 | #define SDLK_WORLD_45 SDLK_UNKNOWN |
||
| 205 | #define SDLK_WORLD_46 SDLK_UNKNOWN |
||
| 206 | #define SDLK_WORLD_47 SDLK_UNKNOWN |
||
| 207 | #define SDLK_WORLD_48 SDLK_UNKNOWN |
||
| 208 | #define SDLK_WORLD_49 SDLK_UNKNOWN |
||
| 209 | #define SDLK_WORLD_50 SDLK_UNKNOWN |
||
| 210 | #define SDLK_WORLD_51 SDLK_UNKNOWN |
||
| 211 | #endif |
||
| 212 | { "W0", 255, SDLK_WORLD_0 }, |
||
| 213 | { "W1", 255, SDLK_WORLD_1 }, |
||
| 214 | { "W2", 255, SDLK_WORLD_2 }, // 100 |
||
| 215 | { "W3", 255, SDLK_WORLD_3 }, |
||
| 216 | { "W4", 255, SDLK_WORLD_4 }, |
||
| 217 | { "W5", 255, SDLK_WORLD_5 }, |
||
| 218 | { "W6", 255, SDLK_WORLD_6 }, |
||
| 219 | { "W7", 255, SDLK_WORLD_7 }, |
||
| 220 | { "W8", 255, SDLK_WORLD_8 }, |
||
| 221 | { "W9", 255, SDLK_WORLD_9 }, |
||
| 222 | { "W10", 255, SDLK_WORLD_10 }, |
||
| 223 | { "W11", 255, SDLK_WORLD_11 }, |
||
| 224 | { "W12", 255, SDLK_WORLD_12 }, // 110 |
||
| 225 | { "W13", 255, SDLK_WORLD_13 }, |
||
| 226 | { "W14", 255, SDLK_WORLD_14 }, |
||
| 227 | { "W15", 255, SDLK_WORLD_15 }, |
||
| 228 | { "W16", 255, SDLK_WORLD_16 }, |
||
| 229 | { "W17", 255, SDLK_WORLD_17 }, |
||
| 230 | { "W18", 255, SDLK_WORLD_18 }, |
||
| 231 | { "W19", 255, SDLK_WORLD_19 }, |
||
| 232 | { "W20", 255, SDLK_WORLD_20 }, |
||
| 233 | { "W21", 255, SDLK_WORLD_21 }, |
||
| 234 | { "W22", 255, SDLK_WORLD_22 }, // 120 |
||
| 235 | { "W23", 255, SDLK_WORLD_23 }, |
||
| 236 | { "W24", 255, SDLK_WORLD_24 }, |
||
| 237 | { "W25", 255, SDLK_WORLD_25 }, |
||
| 238 | { "W26", 255, SDLK_WORLD_26 }, |
||
| 239 | { "W27", 255, SDLK_WORLD_27 }, |
||
| 240 | { "W28", 255, SDLK_WORLD_28 }, |
||
| 241 | { "W29", 255, SDLK_WORLD_29 }, |
||
| 242 | { "W30", 255, SDLK_WORLD_30 }, |
||
| 243 | { "W31", 255, SDLK_WORLD_31 }, |
||
| 244 | { "W32", 255, SDLK_WORLD_32 }, // 130 |
||
| 245 | { "W33", 255, SDLK_WORLD_33 }, |
||
| 246 | { "W34", 255, SDLK_WORLD_34 }, |
||
| 247 | { "W35", 255, SDLK_WORLD_35 }, |
||
| 248 | { "W36", 255, SDLK_WORLD_36 }, |
||
| 249 | { "W37", 255, SDLK_WORLD_37 }, |
||
| 250 | { "W38", 255, SDLK_WORLD_38 }, |
||
| 251 | { "W39", 255, SDLK_WORLD_39 }, |
||
| 252 | { "W40", 255, SDLK_WORLD_40 }, |
||
| 253 | { "W41", 255, SDLK_WORLD_41 }, |
||
| 254 | { "W42", 255, SDLK_WORLD_42 }, // 140 |
||
| 255 | { "W43", 255, SDLK_WORLD_43 }, |
||
| 256 | { "W44", 255, SDLK_WORLD_44 }, |
||
| 257 | { "W45", 255, SDLK_WORLD_45 }, |
||
| 258 | { "W46", 255, SDLK_WORLD_46 }, |
||
| 259 | { "W47", 255, SDLK_WORLD_47 }, |
||
| 260 | { "W48", 255, SDLK_WORLD_48 }, |
||
| 261 | { "W49", 255, SDLK_WORLD_49 }, |
||
| 262 | { "W50", 255, SDLK_WORLD_50 }, |
||
| 263 | { "W51", 255, SDLK_WORLD_51 }, |
||
| 264 | { "", 255, SDLK_UNKNOWN }, // 150 |
||
| 265 | { "", 255, SDLK_UNKNOWN }, |
||
| 266 | { "", 255, SDLK_UNKNOWN }, |
||
| 267 | { "", 255, SDLK_UNKNOWN }, |
||
| 268 | { "", 255, SDLK_UNKNOWN }, |
||
| 269 | { "", 255, SDLK_UNKNOWN }, |
||
| 270 | { "PAD", 255, SDLK_KP_ENTER }, |
||
| 271 | { "RCTRL", 255, SDLK_RCTRL }, |
||
| 272 | #if SDL_MAJOR_VERSION == 2 |
||
| 273 | #define SDLK_LMETA SDLK_UNKNOWN |
||
| 274 | #define SDLK_RMETA SDLK_UNKNOWN |
||
| 275 | #endif |
||
| 276 | { "LCMD", 255, SDLK_LMETA }, |
||
| 277 | { "RCMD", 255, SDLK_RMETA }, |
||
| 278 | { "", 255, SDLK_UNKNOWN }, // 160 |
||
| 279 | { "", 255, SDLK_UNKNOWN }, |
||
| 280 | { "", 255, SDLK_UNKNOWN }, |
||
| 281 | { "", 255, SDLK_UNKNOWN }, |
||
| 282 | { "", 255, SDLK_UNKNOWN }, |
||
| 283 | { "", 255, SDLK_UNKNOWN }, |
||
| 284 | { "", 255, SDLK_UNKNOWN }, |
||
| 285 | { "", 255, SDLK_UNKNOWN }, |
||
| 286 | { "", 255, SDLK_UNKNOWN }, |
||
| 287 | { "", 255, SDLK_UNKNOWN }, |
||
| 288 | { "", 255, SDLK_UNKNOWN }, // 170 |
||
| 289 | { "", 255, SDLK_UNKNOWN }, |
||
| 290 | { "", 255, SDLK_UNKNOWN }, |
||
| 291 | { "", 255, SDLK_UNKNOWN }, |
||
| 292 | { "", 255, SDLK_UNKNOWN }, |
||
| 293 | { "", 255, SDLK_UNKNOWN }, |
||
| 294 | { "", 255, SDLK_UNKNOWN }, |
||
| 295 | { "", 255, SDLK_UNKNOWN }, |
||
| 296 | { "", 255, SDLK_UNKNOWN }, |
||
| 297 | { "", 255, SDLK_UNKNOWN }, |
||
| 298 | { "", 255, SDLK_UNKNOWN }, // 180 |
||
| 299 | { "PAD/", 255, SDLK_KP_DIVIDE }, |
||
| 300 | { "", 255, SDLK_UNKNOWN }, |
||
| 301 | #if SDL_MAJOR_VERSION == 1 |
||
| 302 | #define SDLK_PRINTSCREEN SDLK_PRINT |
||
| 303 | #endif |
||
| 304 | { "PRSCR", 255, SDLK_PRINTSCREEN }, |
||
| 305 | { "RALT", 255, SDLK_RALT }, |
||
| 306 | { "", 255, SDLK_UNKNOWN }, |
||
| 307 | { "", 255, SDLK_UNKNOWN }, |
||
| 308 | { "", 255, SDLK_UNKNOWN }, |
||
| 309 | { "", 255, SDLK_UNKNOWN }, |
||
| 310 | { "", 255, SDLK_UNKNOWN }, |
||
| 311 | { "", 255, SDLK_UNKNOWN }, // 190 |
||
| 312 | { "", 255, SDLK_UNKNOWN }, |
||
| 313 | { "", 255, SDLK_UNKNOWN }, |
||
| 314 | { "", 255, SDLK_UNKNOWN }, |
||
| 315 | { "", 255, SDLK_UNKNOWN }, |
||
| 316 | { "", 255, SDLK_UNKNOWN }, |
||
| 317 | { "", 255, SDLK_UNKNOWN }, |
||
| 318 | { "", 255, SDLK_UNKNOWN }, |
||
| 319 | { "", 255, SDLK_UNKNOWN }, |
||
| 320 | { "HOME", 255, SDLK_HOME }, |
||
| 321 | { "UP", 255, SDLK_UP }, // 200 |
||
| 322 | { "PGUP", 255, SDLK_PAGEUP }, |
||
| 323 | { "", 255, SDLK_UNKNOWN }, |
||
| 324 | { "LEFT", 255, SDLK_LEFT }, |
||
| 325 | { "", 255, SDLK_UNKNOWN }, |
||
| 326 | { "RIGHT", 255, SDLK_RIGHT }, |
||
| 327 | { "", 255, SDLK_UNKNOWN }, |
||
| 328 | { "END", 255, SDLK_END }, |
||
| 329 | { "DOWN", 255, SDLK_DOWN }, |
||
| 330 | { "PGDN", 255, SDLK_PAGEDOWN }, |
||
| 331 | { "INS", 255, SDLK_INSERT }, // 210 |
||
| 332 | { "DEL", 255, SDLK_DELETE }, |
||
| 333 | #if SDL_MAJOR_VERSION == 1 |
||
| 334 | { "W52", 255, SDLK_WORLD_52 }, |
||
| 335 | { "W53", 255, SDLK_WORLD_53 }, |
||
| 336 | { "W54", 255, SDLK_WORLD_54 }, |
||
| 337 | { "W55", 255, SDLK_WORLD_55 }, |
||
| 338 | { "W56", 255, SDLK_WORLD_56 }, |
||
| 339 | { "W57", 255, SDLK_WORLD_57 }, |
||
| 340 | { "W58", 255, SDLK_WORLD_58 }, |
||
| 341 | { "W59", 255, SDLK_WORLD_59 }, |
||
| 342 | { "W60", 255, SDLK_WORLD_60 }, // 220 |
||
| 343 | { "W61", 255, SDLK_WORLD_61 }, |
||
| 344 | { "W62", 255, SDLK_WORLD_62 }, |
||
| 345 | { "W63", 255, SDLK_WORLD_63 }, |
||
| 346 | { "W64", 255, SDLK_WORLD_64 }, |
||
| 347 | { "W65", 255, SDLK_WORLD_65 }, |
||
| 348 | { "W66", 255, SDLK_WORLD_66 }, |
||
| 349 | { "W67", 255, SDLK_WORLD_67 }, |
||
| 350 | { "W68", 255, SDLK_WORLD_68 }, |
||
| 351 | { "W69", 255, SDLK_WORLD_69 }, |
||
| 352 | { "W70", 255, SDLK_WORLD_70 }, // 230 |
||
| 353 | { "W71", 255, SDLK_WORLD_71 }, |
||
| 354 | { "W72", 255, SDLK_WORLD_72 }, |
||
| 355 | { "W73", 255, SDLK_WORLD_73 }, |
||
| 356 | { "W74", 255, SDLK_WORLD_74 }, |
||
| 357 | { "W75", 255, SDLK_WORLD_75 }, |
||
| 358 | { "W76", 255, SDLK_WORLD_76 }, |
||
| 359 | { "W77", 255, SDLK_WORLD_77 }, |
||
| 360 | { "W78", 255, SDLK_WORLD_78 }, |
||
| 361 | { "W79", 255, SDLK_WORLD_79 }, |
||
| 362 | { "W80", 255, SDLK_WORLD_80 }, // 240 |
||
| 363 | { "W81", 255, SDLK_WORLD_81 }, |
||
| 364 | { "W82", 255, SDLK_WORLD_82 }, |
||
| 365 | { "W83", 255, SDLK_WORLD_83 }, |
||
| 366 | { "W84", 255, SDLK_WORLD_84 }, |
||
| 367 | { "W85", 255, SDLK_WORLD_85 }, |
||
| 368 | { "W86", 255, SDLK_WORLD_86 }, |
||
| 369 | { "W87", 255, SDLK_WORLD_87 }, |
||
| 370 | { "W88", 255, SDLK_WORLD_88 }, |
||
| 371 | { "W89", 255, SDLK_WORLD_89 }, |
||
| 372 | { "W90", 255, SDLK_WORLD_90 }, // 250 |
||
| 373 | { "W91", 255, SDLK_WORLD_91 }, |
||
| 374 | { "W92", 255, SDLK_WORLD_92 }, |
||
| 375 | { "W93", 255, SDLK_WORLD_93 }, |
||
| 376 | { "W94", 255, SDLK_WORLD_94 }, |
||
| 377 | { "W95", 255, SDLK_WORLD_95 }, // 255 |
||
| 378 | #endif |
||
| 379 | }}; |
||
| 380 | |||
| 381 | namespace { |
||
| 382 | |||
| 383 | struct d_event_keycommand : d_event |
||
| 384 | { |
||
| 385 | const unsigned keycode; |
||
| 386 | constexpr d_event_keycommand(const event_type t, const unsigned k) : |
||
| 387 | d_event(t), keycode(k) |
||
| 388 | { |
||
| 389 | } |
||
| 390 | }; |
||
| 391 | |||
| 392 | } |
||
| 393 | |||
| 394 | static int key_ismodlck(int keycode) |
||
| 395 | { |
||
| 396 | switch (keycode) |
||
| 397 | { |
||
| 398 | case KEY_LSHIFT: |
||
| 399 | case KEY_RSHIFT: |
||
| 400 | case KEY_LALT: |
||
| 401 | case KEY_RALT: |
||
| 402 | case KEY_LCTRL: |
||
| 403 | case KEY_RCTRL: |
||
| 404 | case KEY_LMETA: |
||
| 405 | case KEY_RMETA: |
||
| 406 | return KEY_ISMOD; |
||
| 407 | case KEY_NUMLOCK: |
||
| 408 | case KEY_SCROLLOCK: |
||
| 409 | case KEY_CAPSLOCK: |
||
| 410 | return KEY_ISLCK; |
||
| 411 | default: |
||
| 412 | return 0; |
||
| 413 | } |
||
| 414 | } |
||
| 415 | |||
| 416 | unsigned char key_ascii() |
||
| 417 | { |
||
| 418 | using std::move; |
||
| 419 | using std::next; |
||
| 420 | static std::array<unsigned char, KEY_BUFFER_SIZE> unibuffer; |
||
| 421 | auto src = begin(unicode_frame_buffer); |
||
| 422 | auto dst = next(begin(unibuffer), strlen(reinterpret_cast<const char *>(&unibuffer[0]))); |
||
| 423 | |||
| 424 | // move temporal chars from unicode_frame_buffer to empty space behind last unibuffer char (if any) |
||
| 425 | for (; dst != end(unibuffer); ++dst) |
||
| 426 | if (*src != '\0') |
||
| 427 | { |
||
| 428 | *dst = *src; |
||
| 429 | *src = '\0'; |
||
| 430 | ++src; |
||
| 431 | } |
||
| 432 | |||
| 433 | // unibuffer is not empty. store first char, remove it, shift all chars one step left and then print our char |
||
| 434 | if (unibuffer[0] != '\0') |
||
| 435 | { |
||
| 436 | unsigned char retval = unibuffer[0]; |
||
| 437 | *move(next(unibuffer.begin()), unibuffer.end(), unibuffer.begin()) = 0; |
||
| 438 | return retval; |
||
| 439 | } |
||
| 440 | else |
||
| 441 | return 255; |
||
| 442 | } |
||
| 443 | |||
| 444 | void pressed_keys::update(const std::size_t keycode, const uint8_t down) |
||
| 445 | { |
||
| 446 | constexpr unsigned all_modifiers_combined = KEY_SHIFTED | KEY_ALTED | KEY_CTRLED | KEY_DEBUGGED | KEY_METAED; |
||
| 447 | constexpr unsigned all_modifiers_shifted = all_modifiers_combined >> modifier_shift; |
||
| 448 | static_assert(all_modifiers_combined == all_modifiers_shifted << modifier_shift, "shift error"); |
||
| 449 | static_assert(all_modifiers_shifted == static_cast<uint8_t>(all_modifiers_shifted), "truncation error"); |
||
| 450 | uint8_t mask; |
||
| 451 | keyd_pressed.update_pressed(keycode, down); |
||
| 452 | switch (keycode) |
||
| 453 | { |
||
| 454 | case KEY_LSHIFT: |
||
| 455 | case KEY_RSHIFT: |
||
| 456 | mask = KEY_SHIFTED >> modifier_shift; |
||
| 457 | break; |
||
| 458 | case KEY_LALT: |
||
| 459 | case KEY_RALT: |
||
| 460 | mask = KEY_ALTED >> modifier_shift; |
||
| 461 | break; |
||
| 462 | case KEY_LCTRL: |
||
| 463 | case KEY_RCTRL: |
||
| 464 | mask = KEY_CTRLED >> modifier_shift; |
||
| 465 | break; |
||
| 466 | case KEY_DELETE: |
||
| 467 | mask = KEY_DEBUGGED >> modifier_shift; |
||
| 468 | break; |
||
| 469 | case KEY_LMETA: |
||
| 470 | case KEY_RMETA: |
||
| 471 | mask = KEY_METAED >> modifier_shift; |
||
| 472 | break; |
||
| 473 | default: |
||
| 474 | return; |
||
| 475 | } |
||
| 476 | if (down) |
||
| 477 | modifier_cache |= mask; |
||
| 478 | else |
||
| 479 | modifier_cache &= ~mask; |
||
| 480 | } |
||
| 481 | |||
| 482 | window_event_result key_handler(const SDL_KeyboardEvent *const kevent) |
||
| 483 | { |
||
| 484 | // Read SDLK symbol and state |
||
| 485 | const auto event_keysym = kevent->keysym.sym; |
||
| 486 | if (event_keysym == SDLK_UNKNOWN) |
||
| 487 | return window_event_result::ignored; |
||
| 488 | const auto key_state = (kevent->state != SDL_RELEASED); |
||
| 489 | |||
| 490 | // fill the unicode frame-related unicode buffer |
||
| 491 | if (key_state) |
||
| 492 | { |
||
| 493 | #if SDL_MAJOR_VERSION == 1 |
||
| 494 | const auto sym = kevent->keysym.unicode; |
||
| 495 | #elif SDL_MAJOR_VERSION == 2 |
||
| 496 | const auto sym = kevent->keysym.sym; |
||
| 497 | #endif |
||
| 498 | if (sym > 31 && sym < 255) |
||
| 499 | { |
||
| 500 | range_for (auto &i, unicode_frame_buffer) |
||
| 501 | if (i == '\0') |
||
| 502 | { |
||
| 503 | i = sym; |
||
| 504 | break; |
||
| 505 | } |
||
| 506 | } |
||
| 507 | } |
||
| 508 | |||
| 509 | //===================================================== |
||
| 510 | auto re = key_properties.rend(); |
||
| 511 | auto fi = std::find_if(key_properties.rbegin(), re, [event_keysym](const key_props &k) { return k.sym == event_keysym; }); |
||
| 512 | if (fi == re) |
||
| 513 | return window_event_result::ignored; |
||
| 514 | unsigned keycode = std::distance(key_properties.begin(), std::next(fi).base()); |
||
| 515 | if (keycode == 0) |
||
| 516 | return window_event_result::ignored; |
||
| 517 | |||
| 518 | /* |
||
| 519 | * process the key if: |
||
| 520 | * - it's a valid key AND |
||
| 521 | * - if the keystate has changed OR |
||
| 522 | * - key state same as last one and game accepts key repeats but keep out mod/lock keys |
||
| 523 | */ |
||
| 524 | if (key_state != keyd_pressed[keycode] || (keyd_repeat && !key_ismodlck(keycode))) |
||
| 525 | { |
||
| 526 | // now update the key props |
||
| 527 | keyd_pressed.update(keycode, key_state); |
||
| 528 | const auto raw_keycode = keycode; |
||
| 529 | keycode |= keyd_pressed.get_modifiers(); |
||
| 530 | |||
| 531 | // We allowed the key to be added to the queue for now, |
||
| 532 | // because there are still input loops without associated windows |
||
| 533 | const d_event_keycommand event{key_state ? EVENT_KEY_COMMAND : EVENT_KEY_RELEASE, keycode}; |
||
| 534 | con_printf(CON_DEBUG, "Sending event %s: %s %s %s %s %s %s", |
||
| 535 | (key_state) ? "EVENT_KEY_COMMAND": "EVENT_KEY_RELEASE", |
||
| 536 | (keycode & KEY_METAED) ? "META" : "", |
||
| 537 | (keycode & KEY_DEBUGGED) ? "DEBUG" : "", |
||
| 538 | (keycode & KEY_CTRLED) ? "CTRL" : "", |
||
| 539 | (keycode & KEY_ALTED) ? "ALT" : "", |
||
| 540 | (keycode & KEY_SHIFTED) ? "SHIFT" : "", |
||
| 541 | key_properties[raw_keycode].key_text |
||
| 542 | ); |
||
| 543 | return event_send(event); |
||
| 544 | } |
||
| 545 | return window_event_result::ignored; |
||
| 546 | } |
||
| 547 | |||
| 548 | void key_init() |
||
| 549 | { |
||
| 550 | #if SDL_MAJOR_VERSION == 1 |
||
| 551 | SDL_EnableUNICODE(1); |
||
| 552 | #endif |
||
| 553 | key_toggle_repeat(1); |
||
| 554 | |||
| 555 | keyd_time_when_last_pressed = timer_query(); |
||
| 556 | // Clear the keyboard array |
||
| 557 | key_flush(); |
||
| 558 | } |
||
| 559 | |||
| 560 | static void restore_sticky_key(const uint8_t *keystate, const unsigned i) |
||
| 561 | { |
||
| 562 | #if SDL_MAJOR_VERSION == 1 |
||
| 563 | const auto ki = key_properties[i].sym; |
||
| 564 | #elif SDL_MAJOR_VERSION == 2 |
||
| 565 | const auto ki = i; |
||
| 566 | #endif |
||
| 567 | const auto v = keystate[ki]; // do not flush status of sticky keys |
||
| 568 | keyd_pressed.update_pressed(i, v); |
||
| 569 | } |
||
| 570 | |||
| 571 | void key_flush() |
||
| 572 | { |
||
| 573 | //Clear the unicode buffer |
||
| 574 | unicode_frame_buffer = {}; |
||
| 575 | keyd_pressed = {}; |
||
| 576 | if (unlikely(CGameArg.CtlNoStickyKeys)) |
||
| 577 | return; |
||
| 578 | #if SDL_MAJOR_VERSION == 1 |
||
| 579 | const auto &keystate = SDL_GetKeyState(nullptr); |
||
| 580 | #define DXX_SDL_STICKY_KEYS {KEY_CAPSLOCK, KEY_NUMLOCK, KEY_SCROLLOCK} |
||
| 581 | #elif SDL_MAJOR_VERSION == 2 |
||
| 582 | const auto &keystate = SDL_GetKeyboardState(nullptr); |
||
| 583 | #define DXX_SDL_STICKY_KEYS {SDL_SCANCODE_CAPSLOCK, SDL_SCANCODE_SCROLLLOCK, SDL_SCANCODE_NUMLOCKCLEAR} |
||
| 584 | #endif |
||
| 585 | range_for (const auto key, DXX_SDL_STICKY_KEYS) |
||
| 586 | #undef DXX_SDL_STICKY_KEYS |
||
| 587 | restore_sticky_key(keystate, key); |
||
| 588 | } |
||
| 589 | |||
| 590 | void event_keycommand_send(unsigned key) { |
||
| 591 | const d_event_keycommand event{EVENT_KEY_COMMAND, key}; |
||
| 592 | event_send(event); |
||
| 593 | } |
||
| 594 | |||
| 595 | int event_key_get(const d_event &event) |
||
| 596 | { |
||
| 597 | auto &e = static_cast<const d_event_keycommand &>(event); |
||
| 598 | Assert(e.type == EVENT_KEY_COMMAND || e.type == EVENT_KEY_RELEASE); |
||
| 599 | return e.keycode; |
||
| 600 | } |
||
| 601 | |||
| 602 | // same as above but without mod states |
||
| 603 | int event_key_get_raw(const d_event &event) |
||
| 604 | { |
||
| 605 | return event_key_get(event) & ~(KEY_SHIFTED | KEY_ALTED | KEY_CTRLED | KEY_DEBUGGED | KEY_METAED); |
||
| 606 | } |
||
| 607 | |||
| 608 | void key_toggle_repeat1() |
||
| 609 | { |
||
| 610 | #if SDL_MAJOR_VERSION == 1 |
||
| 611 | if (SDL_EnableKeyRepeat(KEY_REPEAT_DELAY, KEY_REPEAT_INTERVAL) == 0) |
||
| 612 | #endif |
||
| 613 | keyd_repeat = 1; |
||
| 614 | key_flush(); |
||
| 615 | } |
||
| 616 | |||
| 617 | void key_toggle_repeat0() |
||
| 618 | { |
||
| 619 | #if SDL_MAJOR_VERSION == 1 |
||
| 620 | SDL_EnableKeyRepeat(0, 0); |
||
| 621 | #endif |
||
| 622 | keyd_repeat = 0; |
||
| 623 | key_flush(); |
||
| 624 | } |
||
| 625 | |||
| 626 | } |