Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » mouse flicker problem

This thread is locked; no one can reply to it. rss feed Print
mouse flicker problem
Charles256
Member #8,370
February 2007

Whenever I run my program in windowed mode the mouse is fine but when I go full screen it flickers...
relevant code

allegro_init();
set_color_depth(32);
install_keyboard();
install_mouse();  
if (set_gfx_mode(GFX_AUTODETECT_WINDOWED,1024,768,0,0)!=0)
{
    set_gfx_mode(GFX_TEXT,0,0,0,0);
    allegro_message(allegro_error);
    exit(1);
}
show_mouse(screen);

and the screen rendering part.

vsync();
blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H);

I do rest as a way of slowing the game down, I tried to use the tick method but I couldn't even get that to compile so if you think that's the issue let me know and if you know of where a tutorial is off the top of your head let em know, if not, I'll google. :-D

Jakub Wasilewski
Member #3,653
June 2003
avatar

Read about those two functions:

You should "scare" the mouse prior to drawing to the screen, and unscare it after you're done using screen.

---------------------------
[ ChristmasHack! | My games ] :::: One CSS to style them all, One Javascript to script them, / One HTML to bring them all and in the browser bind them / In the Land of Fantasy where Standards mean something.

Charles256
Member #8,370
February 2007

That helped some, it went from being invisible (unless i moved it), to being visible for flickering like a mad man,ideas?

Jakub Wasilewski
Member #3,653
June 2003
avatar

Show all the code you have for the main loop (where drawing happens).

---------------------------
[ ChristmasHack! | My games ] :::: One CSS to style them all, One Javascript to script them, / One HTML to bring them all and in the browser bind them / In the Land of Fantasy where Standards mean something.

Charles256
Member #8,370
February 2007

1void setup()
2{
3 allegro_init();
4 set_color_depth(32);
5 install_keyboard();
6 install_mouse();
7 if (set_gfx_mode(GFX_AUTODETECT,1024,768,0,0)!=0)
8 {
9 set_gfx_mode(GFX_TEXT,0,0,0,0);
10 allegro_message(allegro_error);
11 exit(1);
12 }
13 show_mouse(screen);
14
15}
16 
17 
18int main(void)
19{
20 setup(); // sets up the screen
21 buffering game_screen; // creates an object where our screen will be held, handles
22 // double buffering for us.
23 select_character_menu character_menu(game_screen);
24 main_menu my_main_menu(game_screen); // we want to set up the main menu so we pass
25 // it a reference to game screen so it knows where to set up stuff. kind of important :-D
26 while(!game_over)
27 {
28 if(key[KEY_ESC])
29 {
30 int answer=alert("Really Quit?", NULL, NULL, "&Yes", "&No", 'y', 'n');
31 if (answer == 1)
32 {
33 game_over=true;
34 }
35 }
36 else if(game_state=="main_menu")
37 {
38 my_main_menu.render_menu();// puts the main menu onto the buffer
39 }
40 else if(game_state=="new_game")
41 {
42 character_menu.render_menu();
43 }
44 
45 scare_mouse();
46 game_screen.render(); // puts the buffer onto the viewable screen removing the flickering
47 unscare_mouse();
48 rest(30);
49
50 }
51 return 0;
52}
53END_OF_MAIN()

buffering code

1#include <allegro.h>
2#include <string>
3#include <vector>
4 
5using namespace std;
6#ifndef BUFFERING
7#define BUFFERING
8 
9// i know globals make me a bad person but this is a special circumstance
10// game over is something that will be used everywhere and in this one instance
11// i'm breaking the rule.
12bool game_over=false;
13string game_state="main_menu";
14class buffering
15{
16 private:
17 // we'l need a buffer and a vector to hold reference to location of bitmaps.
18 BITMAP * buffer;
19 vector<BITMAP *> bitmaps;
20 
21 public:
22 buffering()
23 {
24 // the buffer needs to be the entire screen
25 // so we use allegro defined variables to make it so.
26 buffer=create_bitmap(SCREEN_W,SCREEN_H);
27 }
28 void mark_bitmap_for_deletion(BITMAP *picture)
29 {
30 bitmaps.push_back(picture);
31 }
32 
33 // this is just a wrapper for load_bitmap so we can add their memory locations
34 // into a vector for automatic deletion later on.
35 void add_bitmap(BITMAP *picture,int x=0,int y=0)
36 {
37 draw_sprite(buffer,picture,x,y);
38 }
39 
40 // same thign as above
41 void add_stretched_bitmap(BITMAP * picture,int x=0, int y=0,int width=SCREEN_W, int height=SCREEN_H)
42 {
43 stretch_sprite(buffer,picture,x,y,width,height);
44 }
45 
46 // draw the buffer to the screen
47 void render()
48 {
49 vsync();
50 blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H);
51 }
52 
53 void add_text(char *text,int color, int x, int y)
54 {
55 textprintf_ex(buffer,font,x,y,color,1,text);
56 }
57 
58 //dynamically destroy all the bitmaps. good stuff. :-D
59 // beats the hell out of 20 million calls to destroy_bitmap
60 ~buffering()
61 {
62 for(int i=0;i<bitmaps.size();i++)
63 {
64 destroy_bitmap(bitmaps<i>);
65 }
66 bitmaps.empty();
67 }
68};
69 
70#endif

Tobias Dammers
Member #2,604
August 2002
avatar

In a fully double buffering system (read: anything other than dirty rectangles), I found the best solution for the mouse pointer is to just draw the mouse sprite manually by calling the following right before blitting / flipping:

...and not activate the built-in mouse pointer at all (call show_mouse(NULL) just to be sure). As long as the double buffering system works reasonably fast, you get smooth, flicker-free mouse movement without any buffering artifacts (the odd wrong-color rectangles you sometimes see under the mouse cursor in windows).

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Jakub Wasilewski
Member #3,653
June 2003
avatar

Think about the order of things.

scare_mouse()
// ...
vsync()
blit(...)
// ...
unscare_mouse()

So, you hide the mouse, and then execute vsync, which waits (potentially a long time) for a vertical refresh, and only then you show it again. This means the mouse stays hidden for the whole time of the wait.

Instead, reorder the calls so that the mouse is hidden for the shortest interval neccessary:

class buffering{
//...
  void render()
  {
    vsync();
    scare_mouse();
    blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H);
    unscare_mouse();
  };
};

That might help, but I'm not sure at that point - I haven't used Allegro's built-in mouse handling for a long while.

---------------------------
[ ChristmasHack! | My games ] :::: One CSS to style them all, One Javascript to script them, / One HTML to bring them all and in the browser bind them / In the Land of Fantasy where Standards mean something.

Tobias Dammers
Member #2,604
August 2002
avatar

And on a side note: What's with the bitmap vector in the buffering class?
From your comments, I take it you're trying to implement some sort of garbage collection scheme for the bitmaps you load on-the-fly...
I'd suggest you implement a resource handler and put that in a dedicated class. It can be as simple as loading an entire datafile and return the correct bitmap when asked to. More sophisticated approaches will allow for dynamic loading (load on demand), loading and unloading multiple datafiles, etc. But for now I'd say keep it at load_datafile at startup and unload_datafile when done.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Go to: