We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 1674

Summary: Mouse Wheel Events Dropped in Games using SDL
Product: SDL Reporter: Kamona <bugsquasher>
Component: videoAssignee: Sam Lantinga <slouken>
Status: RESOLVED INVALID QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2    
Version: 1.2.14   
Hardware: All   
OS: Linux   

Description Kamona 2012-12-29 07:28:49 UTC
In games which use sdl especially shooters, i cannot scroll the mouse wheel while moving the mouse anymore after changing to XUbuntu 12.04 (installed: libsdl in packet version 1.2.14-6.4ubuntu3).
i tracked this down so i have a test program which reproduces this error (see below). the main problem seems to be that sdl fires a mouse motion event when the program itself sets the position of the mouse with SDL_WarpMouse(). this should be no problem in general, but games need to checkout the mouse position via SDL_GetMouseState() very often and after checking replace the mouse into the middle of the screen. other events are checked less often and so the event queue is being overrun by mousemotion events and mouse wheel events are being dropped (i could not find out why other mouse events are not dropped, maybe games handle them also different).

test program:

#include <stdio.h>
#include "/usr/include/SDL/SDL.h"

int main() {
	SDL_Event event;
	SDL_Surface *screen;
	if(SDL_Init(SDL_INIT_VIDEO)<0) {
		printf("Could not init sdl:%d - %s\n",SDL_Init(SDL_INIT_VIDEO),SDL_GetError());
		return (1);
	}
	screen=SDL_SetVideoMode(600, 400, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
	SDL_WM_ToggleFullScreen(screen);
	SDL_WM_GrabInput(SDL_GRAB_ON);
	while(1) {
		int c;
		for(c=0; c<100; c++) {
			SDL_WarpMouse(300,200);
		}
		if(SDL_PollEvent(&event)) {
			if(event.type==SDL_KEYDOWN) {
				printf("Key Press!\n");
				break;
			} else if (event.type==SDL_MOUSEBUTTONDOWN) {
				if(event.button.button==SDL_BUTTON_WHEELUP) {
					printf("Wheelup!\n");
				} else if(event.button.button==SDL_BUTTON_WHEELDOWN) {
					printf("Wheeldown!\n");
				}
			} else if(event.type==SDL_MOUSEMOTION) {
				//printf("Mouse move!\n");
			}
		}
	}
	SDL_WM_ToggleFullScreen(screen);
	SDL_WM_GrabInput(SDL_GRAB_OFF);
	SDL_FreeSurface(screen);
	SDL_Quit();
}

i assume the behaviour of SDL_WarpMouse was changed because i did not have this error with the same games before. is this now intended behaviour like, are the games expected to also poll the mouse motion events they created by calling SDL_WarpMouse?

also, i tried to check wether the same error occurs in sdl1.3, but when running the program it is not able to init sdl because no video device is available. from the code, it seems to be the same behaviour.
Comment 1 Sam Lantinga 2012-12-31 14:05:58 UTC
When processing events you need to drain the queue to prevent messages from building up (switch your if (SDL_PollEvent()) to a while (SDL_PollEvent())).  I would also recommend using SDL relative mouse mode instead of warping the mouse, if you are doing it every frame.

Cheers!
Comment 2 Kamona 2013-01-06 08:29:08 UTC
(In reply to comment #1)
> When processing events you need to drain the queue to prevent messages from
> building up (switch your if (SDL_PollEvent()) to a while (SDL_PollEvent())).

Thats not the point. It is not me wanting to write this program, it is all games being written that way, with more calls to SDL_WarpMouse() after SDL_GetMouseState() than calls to SDL_PollEvent().

> I would also recommend using SDL relative mouse mode instead of warping the
> mouse, if you are doing it every frame.
> 
> Cheers!

So the answer is that the games (Sauerbraten, Red Eclipse, Urban Terror, Teeworlds etc.) should change their code.

Thanks for the fast reply!:)