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