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 }