1 /* 2 ******************************************************************************************* 3 * Dgame (a D game framework) - Copyright (c) Randy Schütt 4 * 5 * This software is provided 'as-is', without any express or implied warranty. 6 * In no event will the authors be held liable for any damages arising from 7 * the use of this software. 8 * 9 * Permission is granted to anyone to use this software for any purpose, 10 * including commercial applications, and to alter it and redistribute it 11 * freely, subject to the following restrictions: 12 * 13 * 1. The origin of this software must not be misrepresented; you must not claim 14 * that you wrote the original software. If you use this software in a product, 15 * an acknowledgment in the product documentation would be appreciated but is 16 * not required. 17 * 18 * 2. Altered source versions must be plainly marked as such, and must not be 19 * misrepresented as being the original software. 20 * 21 * 3. This notice may not be removed or altered from any source distribution. 22 ******************************************************************************************* 23 */ 24 module Dgame.System.Keyboard; 25 26 private { 27 import derelict.sdl2.types; 28 import derelict.sdl2.functions; 29 30 import Dgame.Math.Rect; 31 } 32 33 /** 34 * Represent the Keyboard 35 */ 36 final abstract class Keyboard { 37 private: 38 static ubyte* _Keys; 39 40 public: 41 static this() { 42 _Keys = SDL_GetKeyboardState(null); 43 } 44 45 /** 46 * Returns the pointer to the Keyboard state. 47 * With that you can check if some key is pressed without using a event queue. 48 * A value of 1 means that the key is pressed and a value of 0 means that it is not. 49 * The pointer will be valid for the whole lifetime of the application and should not be freed by the caller. 50 * 51 * Note: This function gives you the current state after all events have been processed, 52 * so if a key or button has been pressed and released before you process events, 53 * then the pressed state will never show up in the update calls. 54 * Note: This function doesn't take into account whether shift has been pressed or not. 55 * 56 * Examples: 57 * --- 58 * ubyte* keyStates = Keyboard.getState(); 59 * if (keyStates[Keyboard.ScanCode.Escape]) 60 * writeln("escape is pressed."); 61 * --- 62 */ 63 static ubyte* getState() in { 64 assert(_Keys !is null, "You have to call Keyboard.update first."); 65 } body { 66 return _Keys; 67 } 68 69 /** 70 * Use this function to start accepting Unicode text input events 71 */ 72 static void startTextInput() { 73 SDL_StartTextInput(); 74 } 75 76 /** 77 * Use this function to stop receiving any text input events. 78 */ 79 static void stopTextInput() { 80 SDL_StopTextInput(); 81 } 82 83 /** 84 * Use this function to set the rectangle used to type Unicode text inputs. 85 */ 86 static void setTextInputRect(ref ShortRect rect) { 87 SDL_Rect input = void; 88 rect.transferTo(&input); 89 90 SDL_SetTextInputRect(&input); 91 } 92 93 /** 94 * Rvalue version 95 */ 96 static void setTextInputRect(ShortRect rect) { 97 Keyboard.setTextInputRect(rect); 98 } 99 100 /** 101 * Returns if the given Keyboard.Code is pressed. 102 * 103 * Examples: 104 * --- 105 * if (Keyboard.isPressed(Keyboard.Code.Escape)) 106 * writeln("escape is pressed."); 107 * --- 108 */ 109 static bool isPressed(Code code) { 110 int scancode = SDL_GetScancodeFromKey(code); 111 112 return _Keys[scancode] == 1; 113 } 114 115 /** 116 * Returns if the given Keyboard.ScanCode is pressed. 117 * 118 * Examples: 119 * --- 120 * if (Keyboard.isPressed(Keyboard.ScanCode.Escape)) 121 * writeln("escape is pressed."); 122 * --- 123 */ 124 static bool isPressed(ScanCode scancode) { 125 return _Keys[scancode] == 1; 126 } 127 128 /** 129 * Returns the current Keyboard modifier. 130 * 131 * See: Mod enum 132 */ 133 static Mod getModifier() { 134 return cast(Mod) SDL_GetModState(); 135 } 136 137 /** 138 * Set the current Keyboard modifier. 139 * 140 * See: Mod enum 141 */ 142 static void setModifier(Mod mod) { 143 SDL_SetModState(mod); 144 } 145 146 /** 147 * Returns if screen keyboard is supported. 148 */ 149 static bool hasScreenSupport() { 150 return SDL_HasScreenKeyboardSupport() == SDL_TRUE; 151 } 152 153 /** 154 * Supported Keyboard States 155 */ 156 enum State { 157 Pressed = SDL_PRESSED, /** Key is pressed. */ 158 Released = SDL_RELEASED /** Key is released. */ 159 } 160 161 /** 162 * All supported Keyboard modifiers. 163 */ 164 enum Mod { 165 None = KMOD_NONE, /** 0 (no modifier is applicable) */ 166 LShift = KMOD_LSHIFT, /** the left Shift key is down */ 167 RShift = KMOD_RSHIFT, /** the right Shift key is down */ 168 LCtrl = KMOD_LCTRL, /** the left Ctrl (Control) key is down */ 169 RCtrl = KMOD_RCTRL, /** the right Ctrl (Control) key is down */ 170 LAlt = KMOD_LALT, /** the left Alt key is down */ 171 RAlt = KMOD_RALT, /** the right Alt key is down */ 172 LGui = KMOD_LGUI, /** the left GUI key (often the Windows key) is down */ 173 RGui = KMOD_RGUI, /** the right GUI key (often the Windows key) is down */ 174 Num = KMOD_NUM, /** the Num Lock key (may be located on an extended keypad) is down */ 175 Caps = KMOD_CAPS, /** the Caps Lock key is down */ 176 Mode = KMOD_MODE, /** the AltGr key is down */ 177 178 Ctrl = KMOD_CTRL, /** (Mod.LCtrl|Mod.RCtrl) */ 179 Shift = KMOD_SHIFT, /** (Mod.LShift|Mod.RShift) */ 180 Alt = KMOD_ALT, /** (Mod.LAlt|Mod.RAlt) */ 181 Gui = KMOD_GUI, /** (Mod.LGui|Mod.RGui) */ 182 } 183 184 /** 185 * Supported Keyboard Codes. 186 * This are all possible keys. 187 */ 188 enum Code { 189 Unknown = SDLK_UNKNOWN, /** */ 190 191 Return = SDLK_RETURN, /** */ 192 Escape = SDLK_ESCAPE, /** */ 193 Backspace = SDLK_BACKSPACE, /** */ 194 Tab = SDLK_TAB, /** */ 195 Space = SDLK_SPACE, /** */ 196 Exclaim = SDLK_EXCLAIM, /** */ 197 Quotedbl = SDLK_QUOTEDBL, /** */ 198 Hash = SDLK_HASH, /** */ 199 Percent = SDLK_PERCENT, /** */ 200 Dollar = SDLK_DOLLAR, /** */ 201 Ampersand = SDLK_AMPERSAND, /** */ 202 Quote = SDLK_QUOTE, /** */ 203 Leftparen = SDLK_LEFTPAREN, /** */ 204 Rightparen = SDLK_RIGHTPAREN, /** */ 205 Asterisk = SDLK_ASTERISK, /** */ 206 Plus = SDLK_PLUS, /** */ 207 Comma = SDLK_COMMA, /** */ 208 Minus = SDLK_MINUS, /** */ 209 Period = SDLK_PERIOD, /** */ 210 Slash = SDLK_SLASH, /** */ 211 212 Esc = Escape, /** Shortcut */ 213 214 Num0 = SDLK_0, /** */ 215 Num1 = SDLK_1, /** */ 216 Num2 = SDLK_2, /** */ 217 Num3 = SDLK_3, /** */ 218 Num4 = SDLK_4, /** */ 219 Num5 = SDLK_5, /** */ 220 Num6 = SDLK_6, /** */ 221 Num7 = SDLK_7, /** */ 222 Num8 = SDLK_8, /** */ 223 Num9 = SDLK_9, /** */ 224 225 Colon = SDLK_COLON, /** */ 226 Semicolon = SDLK_SEMICOLON, /** */ 227 Less = SDLK_LESS, /** */ 228 Equals = SDLK_EQUALS, /** */ 229 Greater = SDLK_GREATER, /** */ 230 Question = SDLK_QUESTION, /** */ 231 At = SDLK_AT, /** */ 232 233 Leftbracket = SDLK_LEFTBRACKET, /** */ 234 Backslash = SDLK_BACKSLASH, /** */ 235 Rightbracket = SDLK_RIGHTBRACKET, /** */ 236 Caret = SDLK_CARET, /** */ 237 Underscore = SDLK_UNDERSCORE, /** */ 238 Backquote = SDLK_BACKQUOTE, /** */ 239 240 A = SDLK_a, /** */ 241 B = SDLK_b, /** */ 242 C = SDLK_c, /** */ 243 D = SDLK_d, /** */ 244 E = SDLK_e, /** */ 245 F = SDLK_f, /** */ 246 G = SDLK_g, /** */ 247 H = SDLK_h, /** */ 248 I = SDLK_i, /** */ 249 J = SDLK_j, /** */ 250 K = SDLK_k, /** */ 251 L = SDLK_l, /** */ 252 M = SDLK_m, /** */ 253 N = SDLK_n, /** */ 254 O = SDLK_o, /** */ 255 P = SDLK_p, /** */ 256 Q = SDLK_q, /** */ 257 R = SDLK_r, /** */ 258 S = SDLK_s, /** */ 259 T = SDLK_t, /** */ 260 U = SDLK_u, /** */ 261 V = SDLK_v, /** */ 262 W = SDLK_w, /** */ 263 X = SDLK_x, /** */ 264 Y = SDLK_y, /** */ 265 Z = SDLK_z, /** */ 266 267 Capslock = SDLK_CAPSLOCK, /** */ 268 269 F1 = SDLK_F1, /** */ 270 F2 = SDLK_F2, /** */ 271 F3 = SDLK_F3, /** */ 272 F4 = SDLK_F4, /** */ 273 F5 = SDLK_F5, /** */ 274 F6 = SDLK_F6, /** */ 275 F7 = SDLK_F7, /** */ 276 F8 = SDLK_F8, /** */ 277 F9 = SDLK_F9, /** */ 278 F10 = SDLK_F10, /** */ 279 F11 = SDLK_F11, /** */ 280 F12 = SDLK_F12, /** */ 281 282 Printscreen = SDLK_PRINTSCREEN, /** */ 283 Scrolllock = SDLK_SCROLLLOCK, /** */ 284 Pause = SDLK_PAUSE, /** */ 285 Insert = SDLK_INSERT, /** */ 286 Home = SDLK_HOME, /** */ 287 PageUp = SDLK_PAGEUP, /** */ 288 Delete = SDLK_DELETE, /** */ 289 End = SDLK_END, /** */ 290 PageDown = SDLK_PAGEDOWN, /** */ 291 Right = SDLK_RIGHT, /** */ 292 Left = SDLK_LEFT, /** */ 293 Down = SDLK_DOWN, /** */ 294 Up = SDLK_UP, /** */ 295 296 NumLockClear = SDLK_NUMLOCKCLEAR, /** */ 297 KP_Divide = SDLK_KP_DIVIDE, /** */ 298 KP_Multiply = SDLK_KP_MULTIPLY, /** */ 299 KP_Minus = SDLK_KP_MINUS, /** */ 300 KP_Plus = SDLK_KP_PLUS, /** */ 301 KP_Enter = SDLK_KP_ENTER, /** */ 302 KP_1 = SDLK_KP_1, /** */ 303 KP_2 = SDLK_KP_2, /** */ 304 KP_3 = SDLK_KP_3, /** */ 305 KP_4 = SDLK_KP_4, /** */ 306 KP_5 = SDLK_KP_5, /** */ 307 KP_6 = SDLK_KP_6, /** */ 308 KP_7 = SDLK_KP_7, /** */ 309 KP_8 = SDLK_KP_8, /** */ 310 KP_9 = SDLK_KP_9, /** */ 311 KP_0 = SDLK_KP_0, /** */ 312 313 F13 = SDLK_F13, /** */ 314 F14 = SDLK_F14, /** */ 315 F15 = SDLK_F15, /** */ 316 F16 = SDLK_F16, /** */ 317 F17 = SDLK_F17, /** */ 318 F18 = SDLK_F18, /** */ 319 F19 = SDLK_F19, /** */ 320 F20 = SDLK_F20, /** */ 321 F21 = SDLK_F21, /** */ 322 F22 = SDLK_F22, /** */ 323 F23 = SDLK_F23, /** */ 324 F24 = SDLK_F24, /** */ 325 326 LCtrl = SDLK_LCTRL, /** */ 327 LShift = SDLK_LSHIFT, /** */ 328 LAlt = SDLK_LALT, /** */ 329 LGui = SDLK_LGUI, /** */ 330 RCtrl = SDLK_RCTRL, /** */ 331 RShift = SDLK_RSHIFT, /** */ 332 RAlt = SDLK_RALT, /** */ 333 RGui = SDLK_RGUI /** */ 334 } 335 336 /** 337 * Supported Keyboard ScanCodes. 338 * This are all possible keys. 339 */ 340 enum ScanCode { 341 Unknown = SDL_SCANCODE_UNKNOWN, /** */ 342 343 Return = SDL_SCANCODE_RETURN, /** */ 344 Escape = SDL_SCANCODE_ESCAPE, /** */ 345 Backspace = SDL_SCANCODE_BACKSPACE, /** */ 346 Tab = SDL_SCANCODE_TAB, /** */ 347 Space = SDL_SCANCODE_SPACE, /** */ 348 Comma = SDL_SCANCODE_COMMA, /** */ 349 Minus = SDL_SCANCODE_MINUS, /** */ 350 Period = SDL_SCANCODE_PERIOD, /** */ 351 Slash = SDL_SCANCODE_SLASH, /** */ 352 353 Esc = Escape, /** Shortcut */ 354 355 Num0 = SDL_SCANCODE_0, /** */ 356 Num1 = SDL_SCANCODE_1, /** */ 357 Num2 = SDL_SCANCODE_2, /** */ 358 Num3 = SDL_SCANCODE_3, /** */ 359 Num4 = SDL_SCANCODE_4, /** */ 360 Num5 = SDL_SCANCODE_5, /** */ 361 Num6 = SDL_SCANCODE_6, /** */ 362 Num7 = SDL_SCANCODE_7, /** */ 363 Num8 = SDL_SCANCODE_8, /** */ 364 Num9 = SDL_SCANCODE_9, /** */ 365 366 Semicolon = SDL_SCANCODE_SEMICOLON, /** */ 367 Equals = SDL_SCANCODE_EQUALS, /** */ 368 369 Leftbracket = SDL_SCANCODE_LEFTBRACKET, /** */ 370 Backslash = SDL_SCANCODE_BACKSLASH, /** */ 371 Rightbracket = SDL_SCANCODE_RIGHTBRACKET, /** */ 372 373 A = SDL_SCANCODE_A, /** */ 374 B = SDL_SCANCODE_B, /** */ 375 C = SDL_SCANCODE_C, /** */ 376 D = SDL_SCANCODE_D, /** */ 377 E = SDL_SCANCODE_E, /** */ 378 F = SDL_SCANCODE_F, /** */ 379 G = SDL_SCANCODE_G, /** */ 380 H = SDL_SCANCODE_H, /** */ 381 I = SDL_SCANCODE_I, /** */ 382 J = SDL_SCANCODE_J, /** */ 383 K = SDL_SCANCODE_K, /** */ 384 L = SDL_SCANCODE_L, /** */ 385 M = SDL_SCANCODE_M, /** */ 386 N = SDL_SCANCODE_N, /** */ 387 O = SDL_SCANCODE_O, /** */ 388 P = SDL_SCANCODE_P, /** */ 389 Q = SDL_SCANCODE_Q, /** */ 390 R = SDL_SCANCODE_R, /** */ 391 S = SDL_SCANCODE_S, /** */ 392 T = SDL_SCANCODE_T, /** */ 393 U = SDL_SCANCODE_U, /** */ 394 V = SDL_SCANCODE_V, /** */ 395 W = SDL_SCANCODE_W, /** */ 396 X = SDL_SCANCODE_X, /** */ 397 Y = SDL_SCANCODE_Y, /** */ 398 Z = SDL_SCANCODE_Z, /** */ 399 400 Capslock = SDL_SCANCODE_CAPSLOCK, /** */ 401 402 F1 = SDL_SCANCODE_F1, /** */ 403 F2 = SDL_SCANCODE_F2, /** */ 404 F3 = SDL_SCANCODE_F3, /** */ 405 F4 = SDL_SCANCODE_F4, /** */ 406 F5 = SDL_SCANCODE_F5, /** */ 407 F6 = SDL_SCANCODE_F6, /** */ 408 F7 = SDL_SCANCODE_F7, /** */ 409 F8 = SDL_SCANCODE_F8, /** */ 410 F9 = SDL_SCANCODE_F9, /** */ 411 F10 = SDL_SCANCODE_F10, /** */ 412 F11 = SDL_SCANCODE_F11, /** */ 413 F12 = SDL_SCANCODE_F12, /** */ 414 415 Printscreen = SDL_SCANCODE_PRINTSCREEN, /** */ 416 Scrolllock = SDL_SCANCODE_SCROLLLOCK, /** */ 417 Pause = SDL_SCANCODE_PAUSE, /** */ 418 Insert = SDL_SCANCODE_INSERT, /** */ 419 Home = SDL_SCANCODE_HOME, /** */ 420 PageUp = SDL_SCANCODE_PAGEUP, /** */ 421 Delete = SDL_SCANCODE_DELETE, /** */ 422 End = SDL_SCANCODE_END, /** */ 423 PageDown = SDL_SCANCODE_PAGEDOWN, /** */ 424 Right = SDL_SCANCODE_RIGHT, /** */ 425 Left = SDL_SCANCODE_LEFT, /** */ 426 Down = SDL_SCANCODE_DOWN, /** */ 427 Up = SDL_SCANCODE_UP, /** */ 428 429 NumLockClear = SDL_SCANCODE_NUMLOCKCLEAR, /** */ 430 KP_Divide = SDL_SCANCODE_KP_DIVIDE, /** */ 431 KP_Multiply = SDL_SCANCODE_KP_MULTIPLY, /** */ 432 KP_Minus = SDL_SCANCODE_KP_MINUS, /** */ 433 KP_Plus = SDL_SCANCODE_KP_PLUS, /** */ 434 KP_Enter = SDL_SCANCODE_KP_ENTER, /** */ 435 KP_1 = SDL_SCANCODE_KP_1, /** */ 436 KP_2 = SDL_SCANCODE_KP_2, /** */ 437 KP_3 = SDL_SCANCODE_KP_3, /** */ 438 KP_4 = SDL_SCANCODE_KP_4, /** */ 439 KP_5 = SDL_SCANCODE_KP_5, /** */ 440 KP_6 = SDL_SCANCODE_KP_6, /** */ 441 KP_7 = SDL_SCANCODE_KP_7, /** */ 442 KP_8 = SDL_SCANCODE_KP_8, /** */ 443 KP_9 = SDL_SCANCODE_KP_9, /** */ 444 KP_0 = SDL_SCANCODE_KP_0, /** */ 445 446 F13 = SDL_SCANCODE_F13, /** */ 447 F14 = SDL_SCANCODE_F14, /** */ 448 F15 = SDL_SCANCODE_F15, /** */ 449 F16 = SDL_SCANCODE_F16, /** */ 450 F17 = SDL_SCANCODE_F17, /** */ 451 F18 = SDL_SCANCODE_F18, /** */ 452 F19 = SDL_SCANCODE_F19, /** */ 453 F20 = SDL_SCANCODE_F20, /** */ 454 F21 = SDL_SCANCODE_F21, /** */ 455 F22 = SDL_SCANCODE_F22, /** */ 456 F23 = SDL_SCANCODE_F23, /** */ 457 F24 = SDL_SCANCODE_F24, /** */ 458 459 LCtrl = SDL_SCANCODE_LCTRL, /** */ 460 LShift = SDL_SCANCODE_LSHIFT, /** */ 461 LAlt = SDL_SCANCODE_LALT, /** */ 462 LGui = SDL_SCANCODE_LGUI, /** */ 463 RCtrl = SDL_SCANCODE_RCTRL, /** */ 464 RShift = SDL_SCANCODE_RSHIFT, /** */ 465 RAlt = SDL_SCANCODE_RALT, /** */ 466 RGui = SDL_SCANCODE_RGUI /** */ 467 } 468 }