Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » mouse flickering: old question, vague answer

Credits go to Evert for helping out!
This thread is locked; no one can reply to it. rss feed Print
mouse flickering: old question, vague answer
Ju-Han Soon
Member #6,738
December 2005

Hi all,
I'm using Dev-C++ and coding in C.

Like everyone else, I've got mouse icon flickering issues when i'm blitting my backbuffer to the screen every 50 ms. Its a simple game, so I don't really want to have a triple buffer going on here. I suppose DRS might work but that means I gotta blit every ms, which I'm trying to avoid now (trying to inhibit blitting backbuffer to screen every 50ms or so only). I'm working in a windowed mode game, and hardware mouse is enabled. The best I could get that removed flickering was this code:

scare_mouse();
show_mouse(buffer);
blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);
show_mouse(screen);
unscare_mouse();

It works, but since I'm only blitting every 50ms, i'm getting shadows left behind from the recent blitting.

Any thoughts on this? Or does everyone just go the distance and let the computer blit buffers to the screen like crazy?

thanks
=Han=

Billybob
Member #3,136
January 2003

Why not just use
scare_mouse();
blit
unscare_mouse();

and never call show_mouse (so it always draw to the screen)

?

ImLeftFooted
Member #3,935
October 2003
avatar

scare_mouse();
show_mouse(buffer);
blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);
show_mouse(screen);
unscare_mouse();

Hm, why would you call show_mouse on your buffer, and then again on the screen? thats going to come out very weird. Take Williams advice. And btw, using the hardware mouse means the OS handles the mouse drawing, not you.

Take out the line show_mouse(screen);

Evert
Member #794
November 2000
avatar

Quote:

show_mouse(buffer);

Never, ever, use show_mouse() on a memory backbuffer. It doesn't make sense.
Just call show_mouse(screen) once and use scare_mouse()/unscare_mouse() (they do nothing if you're using a hardware cursor, but that's ok).

Quote:

I'm working in a windowed mode game, and hardware mouse is enabled.

Not if you're doing something other than show_mouse(screen).

GullRaDriel
Member #3,861
September 2003
avatar

Just use your own mouse bitmap.
assuming BITMAP *mouspr is the picture of your pointer
blit it as:

blit( mouspr , buffer , 0 , 0 , mouse_x , mouse_y , mouspr -> w , mouspr -> h );

You could add some X and Y to center the mouspr on the mouse coordinate.

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Evert
Member #794
November 2000
avatar

Quote:

Just use your own mouse bitmap.

That is sometimes a good idea, but Allegro's mouse API is there for a reason, you know?
Also, if you can get the OS to draw the mouse cursor for you (which you normally can at least in windowed mode) that is absolutely the best way to do it.

GullRaDriel
Member #3,861
September 2003
avatar

Yeah. But the blit avoir flickering. All flickering. If there is still, it's vsync & | refresh rate faults. GfxDriver parameters can be culprites too.
And a simple call to a simple blit is one line less than too show_mouse call ;-)
(for the last i'm joking you know ;-p )

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Evert
Member #794
November 2000
avatar

Quote:

But the blit avoir flickering. All flickering.

So should using a hardware cursur. At least, I never see severe mouse cursor flickering when a window (any window) is updated.
The blit also limits the update rate of the on-screen cursor to your current framerate, which is in general not good for various reasons. The mouse cursor is logically part of the input system, not the display.

Ju-Han Soon
Member #6,738
December 2005

Well the reason I typed that convulted code (I chucked the double show_mouse in there coz a single wasnt helping).

Like i said earlier on, with my original show_mouse(screen) and only a

scare_mouse();
blit(buffer, screen, ...);
unscare_mouse();

to do any blitting, since I'm doing this every 50ms (interrupt timer), it seems to cause my mouse to flicker. Anyway at the moment I'm just doing a show_mouse(buffer) and doing a

while (something) {
show_mouse(NULL);
// game loop code in here
show_mouse(buffer);
blit(buffer, screen, ....);
}

Which means I'm just gonna do a massive amount of buffer->screen blitting in my game. Is that what people normally do to avoid flickering mouse icons?

Btw, I read in another post that show_mouse(NULL) disingages the hardware mousedrawing. Is that true?

And I don't intend to write my own code to check mouse_x and y to handle my own mouse icon because the API is there, and its messy to clear my screen or backbuffer to reblit the icon and the image behind it.

Evert
Member #794
November 2000
avatar

Quote:

to do any blitting, since I'm doing this every 50ms (interrupt timer), it seems to cause my mouse to flicker.

Are you sure the hardware mouse cursr is in use? Can you post a sample programme that reproduces the problem?
What happens if you remove the scare_mouse() and unscare_mouse() calls? (As said, they should do nothing for hardware cursors).

Quote:

Btw, I read in another post that show_mouse(NULL) disingages the hardware mousedrawing. Is that true?

It hides the mouse cursor, if that's what you mean.

Ju-Han Soon
Member #6,738
December 2005

I tried this with a 15x15 cursor and it wasn't visible. So i used what i'm using in my game: 75x75 cursor. And sure enough, flickering icon.

1#include <allegro.h>
2 BITMAP *buffer;
3
4void timer_routine () {
5 scare_mouse();
6 blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);
7 unscare_mouse();
8}
9 
10void main() {
11 allegro_init();
12 install_keyboard();
13 install_timer();
14 install_mouse();
15
16 set_color_depth(24);
17 set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
18
19 buffer = create_bitmap(screen->w, screen->h);
20 BITMAP *cursor = load_bitmap("cursor.bmp", NULL);
21
22 clear_to_color(buffer, makecol(200, 200, 255));
23 set_mouse_sprite(cursor);
24 set_mouse_sprite_focus(cursor->w/2, cursor->h/2);
25 show_mouse(screen);
26
27 install_int(timer_routine, 50);
28 while (!key[KEY_ESC]) {
29 }
30
31 remove_int(timer_routine);
32 destroy_bitmap(buffer);
33 destroy_bitmap(cursor);
34 allegro_exit();
35}
36END_OF_MAIN();

Evert
Member #794
November 2000
avatar

Quote:

So i used what i'm using in my game: 75x75 cursor.

When I tried last, Windows couldn't do more than 32x32 pixel cursors. In that case, Allegro is not using a hardware cursor (and gfx_capabilities should tell you so).

Ju-Han Soon
Member #6,738
December 2005

Ah... nowonder. So without hardware cursoring, I'm stuck with a flickering icon unless I do something else. Thanks! I've worked around it by show_mouse(buffer) and blitting buffer to screen every game loop. Not very resource-friendly I guess, but it works.

=Han=

Evert
Member #794
November 2000
avatar

Quote:

I've worked around it by show_mouse(buffer) and blitting buffer to screen every game loop.

Don't. I recommend against using show_mouse() on a memory bitmap. If that's what you want to do, then draw the mouse pointer manually with trans_blit().
Also, it's best to check if you can do a hardware cursor and only draw the mouse yourself if you cannot.

Ju-Han Soon
Member #6,738
December 2005

Why shouldn't I use show_mouse(buffer)? What is the badness of doing it on a memory bitmap? Sorry I think I read it somewhere but forgot where, and its not in the manual.

I guess the reason I don't want to draw my mouse on my buffer is that it will draw over something on my buffer that I don't want overwritten or it will take some re-coding to figure out how to redraw the thing behind it. maybe dirty rectangles. But I thought this show_mouse(buffer) thing seemed to solve all my problems. Thats why I would like to know what so bad about it.

Thanks
=Han=

Evert
Member #794
November 2000
avatar

Threading issues, and there are some things that don't actually work properly (but I need to look up the discussion on AD to tell you what exactly gets broken under what circumstances).
The end of the discussion was that it's pointless to do continuus asynchronous updates of the mouse cursor on a non-visible surface (which is quite true if you think about it) and that for that reason it doesn't make sense to do it. I think the idea was also to discourage doing this and drop active support in the 4.3 branch.
But I may be remembering more than was actually discussed at the time.

Ju-Han Soon
Member #6,738
December 2005

Ooo.. ok. That makes perfect sense. I'll keep that in mind and do a dirty rectangle then. Peace out.

Go to: