1 module mutils.events;
2 
3 import core.stdc..string : memset, strlen;
4 import mutils.time;
5 
6 Events gEvents;
7 
8 enum MouseButton {
9 	left = 0,
10 	right = 1,
11 	middle = 2,	
12 }
13 
14 enum Key {
15 	ctrl,
16 	alt,
17 	shift,
18 	F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,
19 	up,down,left,right,
20 	space,
21 	esc,
22 	backspace,
23 	delete_,
24 	return_,
25 	pageup,
26 	pagedown,
27 	home,
28 	end,
29 	insert,
30 }
31 /**
32  * Struct to store simple controller event states, like pressed, down, released.
33  * Supports keyboard and mouse.
34  * Additionaly this object calculates fps.
35  * */
36 struct Events{
37 
38 	bool[256] downKeys;
39 	bool[256] pressedKeys;
40 	bool[256] releasedKeys;
41 	bool[Key.max + 1] downKeysSpecial;
42 	bool[Key.max + 1] pressedKeysSpecial;
43 	bool[Key.max + 1] releasedKeysSpecial;
44 
45 	bool[MouseButton.max + 1] mouseDownKeys;
46 	bool[MouseButton.max + 1] mousePressedKeys;
47 	bool[MouseButton.max + 1] mouseReleasedKeys;
48 	int[2] _mousePos = [100,100];
49 	int[2] _mouseWheel;
50 
51 	char[] inputedText;
52 
53 	float dtf=0;
54 	float fps = 0;
55 	float minTime = 0;
56 	float maxTime = 0;
57 	long oldTime, newTime;
58 
59 	bool quit = false;
60 
61 	void initialzie(){
62 		reset();
63 	}
64 
65 	void reset(){
66 		newTime = oldTime = useconds();
67 		dtf = 0;
68 		fps = 0;
69 		minTime = 0;
70 		maxTime = 0;
71 	}
72 
73 	long getFrameTimeMsecs(){
74 		return cast(long)(1000f/fps);
75 	}
76 	
77 	void update() {
78 		__gshared static char[] defaultInputText=['\0', '\0', '\0', '\0'];
79 		_mouseWheel = [0, 0];
80 		inputedText=defaultInputText;
81 		memset(&pressedKeys, 0, 256);
82 		memset(&releasedKeys, 0, 256);
83 		memset(&mousePressedKeys, 0, MouseButton.max + 1);
84 		memset(&mouseReleasedKeys, 0, MouseButton.max + 1);
85 		memset(&pressedKeysSpecial, 0, Key.max + 1);
86 		memset(&releasedKeysSpecial, 0, Key.max + 1);
87 		fpsCounter();
88 	}
89 
90 	void fpsCounter() {
91 		static int frames;
92 		static float fpsTimer=0;
93 		static float miTime=0, maTime=0;
94 		long dt;
95 
96 		frames++;
97 		oldTime = newTime;
98 		newTime = useconds();
99 		dt = newTime - oldTime;
100 		dtf = cast(float) dt/ 1_000_000;
101 		fpsTimer += dtf;
102 		if (miTime > dtf)
103 			miTime = dtf;
104 		if (maTime < dtf)
105 			maTime = dtf;
106 		if (fpsTimer >= 1) {
107 			minTime = miTime;
108 			maxTime = maTime;
109 			maTime = miTime = dtf;
110 			fps = cast(float)frames / fpsTimer;
111 			fpsTimer -= 1;
112 			frames = 0;
113 		}
114 		
115 	}
116 	
117 	
118 	int[2] mousePos() {
119 		return _mousePos;
120 	}
121 	
122 	int[2] mouseWheel() {
123 		return _mouseWheel;
124 	}
125 	
126 	bool mouseButtonDown(MouseButton b) {
127 		if (mouseDownKeys[b]) {
128 			return true;
129 		}
130 		return false;
131 	}
132 	
133 	bool mouseButtonPressed(MouseButton b) {
134 		
135 		if (mousePressedKeys[b]) {
136 			return true;
137 		}
138 		return false;
139 	}
140 	
141 	bool mouseButtonReleased(MouseButton b) {
142 		if (mouseReleasedKeys[b]) {
143 			return true;
144 		}
145 		return false;
146 	}
147 	
148 	bool keyPressed(short k) {
149 		if (k < 256) {
150 			return pressedKeys[k];
151 		} else {
152 			return false;
153 		}
154 	}
155 	
156 	bool keyReleased(short k) {
157 		if (k < 256) {
158 			return releasedKeys[k];
159 		} else {
160 			return false;
161 		}
162 	}
163 	
164 	bool keyDown(short k) {
165 		if (k < 256) {
166 			return downKeys[k];
167 		} else {
168 			return false;
169 		}
170 	}
171 	
172 	bool keyPressed(Key k) {
173 		if (k < 256) {
174 			return pressedKeysSpecial[k];
175 		} else {
176 			return false;
177 		}
178 	}
179 	
180 	bool keyReleased(Key k) {
181 		if (k < 256) {
182 			return releasedKeysSpecial[k];
183 		} else {
184 			return false;
185 		}
186 	}
187 	
188 	bool keyDown(Key k) {
189 		if (k < 256) {
190 			return downKeysSpecial[k];
191 		} else {
192 			return false;
193 		}
194 	}
195 	///////////////////////////////////////
196 	//// Events check implementations /////
197 	///////////////////////////////////////
198 
199 	
200 	void fromSDLEvent(T)(ref T event){
201 		import derelict.sdl2.sdl;
202 		static assert( is(T==SDL_Event));
203 
204 		__gshared static char[SDL_TEXTINPUTEVENT_TEXT_SIZE] textStorage;
205 
206 		void specialKeysImpl(uint sym, bool up) {
207 			Key key;
208 			switch (sym) {
209 				//CONTROL ARROWS
210 				case SDLK_UP:key=Key.up;break;
211 				case SDLK_DOWN:key= Key.down;break;
212 				case SDLK_LEFT:key=Key.left;break;
213 				case SDLK_RIGHT:key=Key.right;break;
214 					//CONTROL KEYS
215 				case SDLK_ESCAPE:key=Key.esc;break;
216 				case SDLK_LCTRL:key= Key.ctrl;break;
217 				case SDLK_LSHIFT:key=Key.shift;break;
218 				case SDLK_LALT:key=Key.alt;break;
219 				case SDLK_SPACE:key=Key.space;break;
220 					//F_XX
221 				case SDLK_F1:key=Key.F1;break;
222 				case SDLK_F2:key=Key.F2;break;
223 				case SDLK_F3:key=Key.F3;break;
224 				case SDLK_F4:key=Key.F4;break;
225 				case SDLK_F5:key=Key.F5;break;
226 				case SDLK_F6:key=Key.F6;break;
227 				case SDLK_F7:key=Key.F7;break;
228 				case SDLK_F8:key=Key.F8;break;
229 				case SDLK_F9:key=Key.F9;break;
230 				case SDLK_F10:key=Key.F10;break;
231 				case SDLK_F11:key=Key.F11;break;
232 				case SDLK_F12:key=Key.F12;break;
233 					//OTHER
234 				case SDLK_BACKSPACE:key=Key.backspace;break;
235 				case SDLK_DELETE:key=Key.delete_;break;
236 				case SDLK_RETURN:key=Key.return_;break;
237 				case SDLK_PAGEUP:key=Key.pageup;break;
238 				case SDLK_PAGEDOWN:key=Key.pagedown;break;
239 				case SDLK_HOME:key=Key.home;break;
240 				case SDLK_END:key=Key.end;break;
241 				case SDLK_INSERT:key=Key.insert;break;
242 
243 				default:
244 					return;
245 			}
246 			if (!up) {
247 				downKeysSpecial[key] = true;
248 				pressedKeysSpecial[key] = true;
249 			} else {
250 				downKeysSpecial[key] = false;
251 				releasedKeysSpecial[key] = true;
252 			}
253 		}
254 
255 		
256 		switch (event.type) {
257 			case SDL_TEXTINPUT:
258 				textStorage=event.text.text;
259 				inputedText=textStorage[0..strlen(textStorage.ptr)];
260 				break;
261 			case SDL_KEYDOWN:
262 				auto sym=event.key.keysym.sym;
263 				specialKeysImpl(sym, false);
264 				int toUpper=(keyDown(Key.shift) && sym>='a' && sym <='z' )?'A'-'a':0;
265 				if (sym < 256) {
266 					downKeys[toUpper+sym] = true;
267 					pressedKeys[toUpper+sym] = true;
268 				}
269 				
270 				break;
271 			case SDL_KEYUP:
272 				auto sym=event.key.keysym.sym;
273 				specialKeysImpl(sym, true);
274 				int toUpper=(keyDown(Key.shift) && sym>='a' && sym <='z' )?'A'-'a':0;
275 				if (sym < 256) {
276 					downKeys[toUpper+sym] = false;
277 					releasedKeys[toUpper+sym] = true;
278 				}
279 				break;
280 			case SDL_MOUSEBUTTONDOWN:
281 				switch (event.button.button) {
282 					case SDL_BUTTON_LEFT:
283 						mouseDownKeys[MouseButton.left] = true;
284 						mousePressedKeys[MouseButton.left] = true;
285 						break;
286 					case SDL_BUTTON_RIGHT:
287 						mouseDownKeys[MouseButton.right] = true;
288 						mousePressedKeys[MouseButton.right] = true;
289 						break;
290 					case SDL_BUTTON_MIDDLE:
291 						mouseDownKeys[MouseButton.middle] = true;
292 						mousePressedKeys[MouseButton.middle] = true;
293 						break;
294 					default:
295 						break;
296 				}
297 				break;
298 			case SDL_MOUSEBUTTONUP:
299 				switch (event.button.button) {
300 					case SDL_BUTTON_LEFT:
301 						mouseDownKeys[MouseButton.left] = false;
302 						mouseReleasedKeys[MouseButton.left] = true;
303 						break;
304 					case SDL_BUTTON_RIGHT:
305 						mouseDownKeys[MouseButton.right] = false;
306 						mouseReleasedKeys[MouseButton.right] = true;
307 						break;
308 					case SDL_BUTTON_MIDDLE:
309 						mouseDownKeys[MouseButton.middle] = false;
310 						mouseReleasedKeys[MouseButton.middle] = true;
311 						break;
312 					default:
313 						break;
314 				}
315 				break;
316 			case SDL_MOUSEWHEEL:
317 				_mouseWheel[0] = event.wheel.x;
318 				_mouseWheel[1] = event.wheel.y;
319 				
320 				break;
321 			case SDL_QUIT:
322 				gEvents.quit = true;
323 				break;
324 			default:
325 				break;
326 		}
327 		
328 	}
329 
330 	
331 
332 	
333 
334 }
335