[A5] Mouse response is slow
adamk kromm

Hi

I'm working on a map editor thing, and keyboard input works great and is responsive, but the mouse input is quite delayed.

Here is the scenario: I have a screen and when I click it puts a white box where the user clicks. The problem being after I click the mouse, there is a ~1 second delay before the box shows up. If I click and drag the mouse, all the boxes show up, but again, there is a 1-3 second delay for all of them to show up. The weird thing is, if I click the mouse and rather than dragging the mouse i use the keyboard to "move" the drawing plane then everything is immediately.

so in short: mouse input slow, keyboard input perfect...

I'm using Allegro 5.0.7 md
with a core i7 quad core
8gb ram
nvidia gtx 660m fully updated.
I'm using opengl 3.0 though i doubt that makes any difference.

Any ideas on how to fix it?

thanks adam.

Peter Wang

I couldn't understand what you wrote.

Are you using event queues, and letting the events pile up? Moving the mouse generates a lot more events than you would get with a keyboard.

Timorg

Are you draining the message queue every time? If you are only taking one message out each time, the mouse moving could be causing a flood of messages that have to come through before it gets to processing the mouse click.

adamk kromm

You are both right.

I was only taking out one message at a time from the event queue, and thus it was backing up.

So speaking of having a backup in the event queue, is there a proper way to handle it? Or is it safe (and practical) to just take the first event off the queue and ignore the rest?

Thanks for the responses.
Adam.

J-Gamer

You don't want to miss an event, because then you're even worse off than with polling in A4. So you really have to parse every event in the queue before drawing a frame.

Arthur Kalliokoski

I have this in my code

#SelectExpand
1 int redraw = 0; 2 while (true) 3 { 4 al_wait_for_event(queue, &event); 5 { 6 switch (event.type) 7 { 8 case ALLEGRO_EVENT_DISPLAY_CLOSE: 9 goto done; 10 11 case ALLEGRO_EVENT_KEY_CHAR: 12 { 13 int i; 14 blah 15 blah 16 break; 17 } 18 19 case whatever: 20 blah 21 blah 22 break; 23 24 case ALLEGRO_EVENT_TIMER: 25 { 26 draw some stuff 27 al_flip_display(); 28 frames++; 29 redraw++; 30 } 31 32 } 33 while( (redraw > 0) && al_is_event_queue_empty(queue)) 34 { 35 redraw--; 36 } 37 } 38done:

J-Gamer

@Arthur: that way, you'll be drawing at each timer event, and that'll cause your program to lag behind if the drawing takes too long.

#SelectExpand
1while(!quit) { 2 al_wait_for_event(queue,&event); 3 switch(event.type) 4 { 5 case ALLEGRO_EVENT_DISPLAY_CLOSE: 6 quit = true; 7 break; 8 9 case ALLEGRO_EVENT_KEY_CHAR: 10 blah 11 blah 12 break; 13 14 case whatever: 15 blah 16 blah 17 break; 18 19 case ALLEGRO_EVENT_TIMER: 20 redraw = true; 21 break; 22 23 } 24 if(redraw && !al_is_event_queue_empty(queue)) { 25 //draw some stuff 26 al_flip_display(); 27 redraw = false; 28 } 29}

Arthur Kalliokoski

Yeah, my event-fu is weak. :-/

adamk kromm

Here is how I now have it, so that there is not mouse lag, (or any other that i can notice.)

I is set up so that it does logic updates 45x per second, and draws as fast as the computer will let it.

#SelectExpand
1bool running = true; 2 3const int FRAMES_PER_SECOND = 45; 4const double SKIP_FRAMES = 1.0 / FRAMES_PER_SECOND; 5const int MAX_FRAME_SKIP = 15; 6 7double nextFrame = al_get_time(); 8int frameSkip = 0; 9int fpsLogic, fpsDisplay; 10 11long long frames = 1; 12long long framesDisplay = 1; 13double startTime = al_get_time(); 14 15while(running) 16{ 17 frameSkip = 0; 18 19//loop as long as we havent skipped MAX_FRAME_SKIP frames, and we have extra time before the next 20//logic update is needed 21 while(frameSkip < MAX_FRAME_SKIP && al_get_time() > nextFrame) 22 { 23 //do input logic 24 ALLEGRO_EVENT ev; 25 while(al_peek_next_event(eventQueue, &ev)) 26 { 27 al_get_next_event(eventQueue, &ev); 28 if( ev.type == ALLEGRO_EVENT_KEY_DOWN || 29 ev.type == ALLEGRO_EVENT_KEY_UP || 30 ev.type == ALLEGRO_EVENT_MOUSE_AXES || 31 ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN || 32 ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP 33 ) 34 { 35 inputManager->ProcessEvent(ev); 36 } 37 } 38 39 running = HandleInput(); 40 Update(); 41 inputManager->Update(); 42 43 ++frames; 44 ++frameSkip; 45 nextFrame += SKIP_FRAMES; 46 } 47 48 float interp = (float)((al_get_time() + SKIP_FRAMES - nextFrame) / SKIP_FRAMES); 49 50 Render(); 51 ++framesDisplay; 52 53 //calculate frames per second 54 fpsLogic = (int)(frames / (al_get_time() - startTime)); 55 fpsDisplay = (int)(framesDisplay / (al_get_time() - startTime)); 56 57 std::stringstream ss; 58 ss<<"Maze Gaze - Map Editor | FPS (logic): "<<fpsLogic<<" (display): "<<fpsDisplay; 59 al_set_window_title(window, ss.str().c_str()); 60}

Thomas Fjellstrom

I is set up so that it does logic updates 45x per second, and draws as fast as the computer will let it.

What's the point of drawing if nothing has changed?

Matthew Leverton

Don't you ever write code like this?

int x = 1;
x = 1;
x = 1; // make sure x REALLY is 1

adamk kromm

In this case you are right; in the map editor I have no need to update the display any more than when something changes.

However in the game (where I copied this from) things are a little different. I originally had it update the logic at 25 or 30 times per second. So all movement and animations where only updated at 25-30fps. So if I were to update the display only 25-30 times per second there would be a noticeable jerkiness. Rather than objects smoothly moving across the screen they would appear to skip or jump across the screen.

So by not limiting the display rate, I can calculate an interpolation value (not used in the code I posted because there is no animation nor movement) and interpolate the rendering between the last update and the next expected update. This helps the animations and movements look a lot smoother.

Thomas Fjellstrom

Yeah, I don't have anything against updating at the refresh rate, but any more than that is pretty silly as the display won't show any of it. Interpolating between frames is a pretty good idea, can help smooth things out, even if it does sort of lie about where things are on screen.

Also updating as often as you can wastes power. People on a laptop will be unhappy with you. And people with loud GPUs will be as well.

adamk kromm

I guess when I said: "as fast as the computer will let it" I was not very clear. I do have vsync turned on, so it will only redraw the screen at the vsync rate.

Thomas Fjellstrom

Though turning vsync on is more of a hint. Graphics drivers let you disable it system wide or individually per app/game.

I guess though that then its the users fault.

adamk kromm

I guess when I said: "as fast as the computer will let it" I was not very clear. I do have vsync turned on, so it will only redraw the screen at the vsync rate.

Thomas Fjellstrom

I guess when I said: "as fast as the computer will let it" I was not very clear. I do have vsync turned on, so it will only redraw the screen at the vsync rate.

Did you mean to double post that?

adamk kromm

Woops sorry, having some internet problems here at the university.

Thread #611033. Printed from Allegro.cc