diff --git a/source/src/main.cpp b/source/src/main.cpp index 4e6c6f60..db987688 100644 --- a/source/src/main.cpp +++ b/source/src/main.cpp @@ -554,14 +554,75 @@ void keyrepeat(bool on) SDL_DEFAULT_REPEAT_INTERVAL); } +vector events; + +void pushevent(const SDL_Event &e) +{ + events.add(e); +} + +static void resetmousemotion() +{ +#ifndef WIN32 + if(!(screen->flags&SDL_FULLSCREEN)) + { + SDL_WarpMouse(screen->w / 2, screen->h / 2); + } +#endif +} + +static inline bool skipmousemotion(SDL_Event &event) +{ + if(event.type != SDL_MOUSEMOTION) return true; +#ifndef WIN32 + if(!(screen->flags&SDL_FULLSCREEN)) + { + #ifdef __APPLE__ + if(event.motion.y == 0) return true; // let mac users drag windows via the title bar + #endif + if(event.motion.x == screen->w / 2 && event.motion.y == screen->h / 2) return true; // ignore any motion events generated SDL_WarpMouse + } +#endif + return false; +} + +static void checkmousemotion(int &dx, int &dy) +{ + loopv(events) + { + SDL_Event &event = events[i]; + if(skipmousemotion(event)) + { + if(i > 0) events.remove(0, i); + return; + } + dx += event.motion.xrel; + dy += event.motion.yrel; + } + events.setsizenodelete(0); + SDL_Event event; + while(SDL_PollEvent(&event)) + { + if(skipmousemotion(event)) + { + events.add(event); + return; + } + dx += event.motion.xrel; + dy += event.motion.yrel; + } +} + static int ignoremouse = 5; void checkinput() { SDL_Event event; int lasttype = 0, lastbut = 0; - while(SDL_PollEvent(&event)) + while(events.length() || SDL_PollEvent(&event)) { + if(events.length()) event = events.remove(0); + switch(event.type) { case SDL_QUIT: @@ -589,20 +650,13 @@ void checkinput() case SDL_MOUSEMOTION: if(ignoremouse) { ignoremouse--; break; } - if(grabinput) + if(grabinput && !skipmousemotion(event)) { - #ifndef WIN32 - if(!(screen->flags&SDL_FULLSCREEN)) - { - #ifdef __APPLE__ - if(event.motion.y == 0) break; //let mac users drag windows via the title bar - #endif - if(event.motion.x == screen->w / 2 && event.motion.y == screen->h / 2) break; - SDL_WarpMouse(screen->w / 2, screen->h / 2); - } - #endif - mousemove(event.motion.xrel, event.motion.yrel); - } + int dx = event.motion.xrel, dy = event.motion.yrel; + checkmousemotion(dx, dy); + resetmousemotion(); + mousemove(dx, dy); + } break; case SDL_MOUSEBUTTONDOWN: diff --git a/source/src/physics.cpp b/source/src/physics.cpp index f89a3b85..98d79e46 100644 --- a/source/src/physics.cpp +++ b/source/src/physics.cpp @@ -741,16 +741,27 @@ void fixcamerarange(physent *cam) } FVARP(sensitivity, 1e-3f, 3.0f, 1000.0f); +FVARP(sensitivityscale, 1e-3f, 1, 1000); VARP(invmouse, 0, 0, 1); +FVARP(mouseaccel, 0, 0, 1000); +FVARP(mouseaccelmax, 0, 0, 1000); +FVARP(mouseaccelrate, 0, 5, 10000); void mousemove(int dx, int dy) { if(intermission) return; if(player1->isspectating() && player1->spectatemode==SM_FOLLOW1ST) return; - const float SENSF = 33.0f; // try match quake sens - camera1->yaw += (dx/SENSF)*sensitivity; - camera1->pitch -= (dy/SENSF)*sensitivity*(invmouse ? -1 : 1); + float cursens = sensitivity/(33.0f*sensitivityscale); // try match quake sens + if(mouseaccel && mouseaccelrate && curtime && (dx || dy)) + { + float dist = (dx*dx + dy*dy)/mouseaccelrate, + accel = 1 + pow(dist/curtime, mouseaccel)/dist; + if(mouseaccelmax) accel = min(accel, mouseaccelmax); + cursens *= accel; + } + camera1->yaw += dx*cursens; + camera1->pitch -= dy*cursens*(invmouse ? -1 : 1); fixcamerarange(); if(camera1!=player1 && player1->spectatemode!=SM_DEATHCAM) {