1 module polyplex.core.input.keyboard; 2 import bindbc.sdl; 3 import std.stdio; 4 import std.conv; 5 6 enum Keys { 7 Unknown, 8 A = SDL_SCANCODE_A, 9 B = SDL_SCANCODE_B, 10 C = SDL_SCANCODE_C, 11 D = SDL_SCANCODE_D, 12 E = SDL_SCANCODE_E, 13 F = SDL_SCANCODE_F, 14 G = SDL_SCANCODE_G, 15 H = SDL_SCANCODE_H, 16 I = SDL_SCANCODE_I, 17 J = SDL_SCANCODE_J, 18 K = SDL_SCANCODE_K, 19 L = SDL_SCANCODE_L, 20 M = SDL_SCANCODE_M, 21 N = SDL_SCANCODE_N, 22 O = SDL_SCANCODE_O, 23 P = SDL_SCANCODE_P, 24 Q = SDL_SCANCODE_Q, 25 R = SDL_SCANCODE_R, 26 S = SDL_SCANCODE_S, 27 T = SDL_SCANCODE_T, 28 U = SDL_SCANCODE_U, 29 V = SDL_SCANCODE_V, 30 W = SDL_SCANCODE_W, 31 X = SDL_SCANCODE_X, 32 Y = SDL_SCANCODE_Y, 33 Z = SDL_SCANCODE_Z, 34 One = SDL_SCANCODE_1, 35 Two = SDL_SCANCODE_2, 36 Three = SDL_SCANCODE_3, 37 Four = SDL_SCANCODE_4, 38 Five = SDL_SCANCODE_5, 39 Six = SDL_SCANCODE_6, 40 Seven = SDL_SCANCODE_7, 41 Eight = SDL_SCANCODE_8, 42 Nine = SDL_SCANCODE_9, 43 Zero = SDL_SCANCODE_0, 44 Return = SDL_SCANCODE_RETURN, 45 Escape = SDL_SCANCODE_ESCAPE, 46 Backspace = SDL_SCANCODE_BACKSPACE, 47 Tab = SDL_SCANCODE_TAB, 48 Space = SDL_SCANCODE_SPACE, 49 Minus = SDL_SCANCODE_MINUS, 50 Equals = SDL_SCANCODE_EQUALS, 51 LeftBracket = SDL_SCANCODE_LEFTBRACKET, 52 RightBracket = SDL_SCANCODE_RIGHTBRACKET, 53 Backslash = SDL_SCANCODE_BACKSLASH, 54 Nonuhash = SDL_SCANCODE_NONUSHASH, 55 Semicolon = SDL_SCANCODE_SEMICOLON, 56 Apostrophe = SDL_SCANCODE_APOSTROPHE, 57 Grave = SDL_SCANCODE_GRAVE, 58 Comma = SDL_SCANCODE_COMMA, 59 Period = SDL_SCANCODE_PERIOD, 60 Slash = SDL_SCANCODE_SLASH, 61 Capslock = SDL_SCANCODE_CAPSLOCK, 62 F1 = SDL_SCANCODE_F1, 63 F2 = SDL_SCANCODE_F2, 64 F3 = SDL_SCANCODE_F3, 65 F4 = SDL_SCANCODE_F4, 66 F5 = SDL_SCANCODE_F5, 67 F6 = SDL_SCANCODE_F6, 68 F7 = SDL_SCANCODE_F7, 69 F8 = SDL_SCANCODE_F8, 70 F9 = SDL_SCANCODE_F9, 71 F10 = SDL_SCANCODE_F10, 72 F11 = SDL_SCANCODE_F11, 73 F12 = SDL_SCANCODE_F12, 74 Execute = SDL_SCANCODE_EXECUTE, 75 Help = SDL_SCANCODE_HELP, 76 Menu = SDL_SCANCODE_MENU, 77 Select = SDL_SCANCODE_SELECT, 78 Stop = SDL_SCANCODE_STOP, 79 Again = SDL_SCANCODE_AGAIN, 80 Undo = SDL_SCANCODE_UNDO, 81 Cut = SDL_SCANCODE_CUT, 82 Copy = SDL_SCANCODE_COPY, 83 Paste = SDL_SCANCODE_PASTE, 84 Find = SDL_SCANCODE_FIND, 85 Mute = SDL_SCANCODE_MUTE, 86 VolumeUp = SDL_SCANCODE_VOLUMEUP, 87 VolumeDown = SDL_SCANCODE_VOLUMEDOWN, 88 KPComma = SDL_SCANCODE_KP_COMMA, 89 KPEqual = SDL_SCANCODE_KP_EQUALS, 90 International1, 91 International2, 92 International3, 93 International4, 94 International5, 95 International6, 96 International7, 97 International8, 98 International9, 99 Lang1, 100 Lang2, 101 Lang3, 102 Lang4, 103 Lang5, 104 Lang6, 105 Lang7, 106 Lang8, 107 Lang9, 108 AltErase = SDL_SCANCODE_ALTERASE, 109 Sysreq = SDL_SCANCODE_SYSREQ, 110 Cancel = SDL_SCANCODE_CANCEL, 111 Clear = SDL_SCANCODE_CLEAR, 112 Prior = SDL_SCANCODE_PRIOR, 113 Return2 = SDL_SCANCODE_RETURN2, 114 Seperator = SDL_SCANCODE_SEPARATOR, 115 Out = SDL_SCANCODE_OUT, 116 Oper = SDL_SCANCODE_OPER, 117 ClearAgain = SDL_SCANCODE_CLEARAGAIN, 118 LeftControl = SDL_SCANCODE_LCTRL, 119 LeftShift = SDL_SCANCODE_LSHIFT, 120 LeftAlt = SDL_SCANCODE_LALT, 121 LeftGUI = SDL_SCANCODE_LGUI, 122 RightControl = SDL_SCANCODE_RCTRL, 123 RightShift = SDL_SCANCODE_RSHIFT, 124 RightAlt = SDL_SCANCODE_RALT, 125 RightGUI = SDL_SCANCODE_RGUI, 126 Mode, 127 AudioNext, 128 AudioPrevious, 129 AudioStop, 130 AudioPlay, 131 AudioMute, 132 MediaSelect, 133 WWW, 134 Mail, 135 Calculator, 136 Computer, 137 ACSearch, 138 ACHome, 139 ACBack, 140 ACForward, 141 ACStop, 142 ACRefresh, 143 ACBookmarks, 144 BrightnessDown, 145 BrightnessUp, 146 DisplaySwitch, 147 KBDIlluminationToggle, 148 KBDIlluminationDown, 149 KBDIlluminationUp, 150 Eject, 151 Sleep, 152 App1, 153 App2, 154 Up = SDL_SCANCODE_UP, 155 Down = SDL_SCANCODE_DOWN, 156 Left = SDL_SCANCODE_LEFT, 157 Right = SDL_SCANCODE_RIGHT, 158 159 ScancodeCount = SDL_NUM_SCANCODES 160 } 161 162 enum KeyState { 163 Up, 164 Down 165 } 166 167 public class KeyboardState { 168 private ubyte[] key_states; 169 170 this() { 171 this.key_states = new ubyte[Keys.ScancodeCount]; 172 } 173 174 this(ubyte* key_states, int size) { 175 // SDL wants to override the values, so we manually copy them in to another array. 176 this.key_states = new ubyte[size]; 177 foreach(i; 0 .. size) { 178 this.key_states[i] = key_states[i]; 179 } 180 } 181 182 /** 183 Returns true if the specified key is down (pressed). 184 */ 185 public bool IsKeyDown(Keys key) { 186 if (key_states[key] == 1) return true; 187 return false; 188 } 189 190 /** 191 Returns true if all of the specified keys are down (pressed). 192 */ 193 public bool AreKeysDown(Keys[] kees) { 194 foreach(Keys k; kees) { 195 if (IsKeyUp(k)) return false; 196 } 197 return true; 198 } 199 200 /** 201 Returns true if the specified key is up (not pressed). 202 */ 203 public bool IsKeyUp(Keys key) { 204 return !IsKeyDown(key); 205 } 206 207 /** 208 Returns true if all of the specified keys are up (not pressed). 209 */ 210 public bool AreKeysUp(Keys[] kees) { 211 foreach(Keys k; kees) { 212 if (IsKeyDown(k)) return false; 213 } 214 return true; 215 } 216 } 217 218 public class Keyboard { 219 220 private static KeyboardState backupState; 221 222 /** 223 Returns the current state of the keyboard. 224 */ 225 public static KeyboardState GetState() { 226 int* elements = new int; 227 ubyte* arr = SDL_GetKeyboardState(elements); 228 229 // Make sure we do actually recieve any data. 230 if (elements is null) return backupState; 231 232 // If so, we update our backup state and return the new state 233 backupState = new KeyboardState(arr, *elements); 234 return backupState; 235 } 236 }