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