Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Questions about the mouse sprite

This thread is locked; no one can reply to it. rss feed Print
Questions about the mouse sprite
biscuitz
Member #5,679
March 2005
avatar

In my code I have:

1BITMAP *cursor = load_bmp( "cursor.bmp", NULL );
2enable_hardware_cursor();
3show_mouse( screen );
4 
5while ( !done )
6 {
7 show_mouse( screen );
8 if ( last_mouse_x > 63 && mouse_x < 64)
9 {
10 set_mouse_sprite( NULL );
11 set_mouse_sprite_focus( 0, 0 );
12 }
13 else if ( last_mouse_x < 64 && mouse_x > 63)
14 {
15 set_mouse_sprite( cursor );
16 set_mouse_sprite_focus( 8, 8 );
17 }
18 }

1) It changes the mouse sprite but not the sprite focus. The sprite focus stays at ( 0, 0 ). I tried switching it around but it didn't work. Any suggestions?

2) When I my program starts up it doesn't show the mouse until I move the mouse. How do I fix this?

---Allegro Version 4.2.0 (beta4)
The hardest part is getting started.
WATCH TV! It's good for ya'
Wave your hand really fast in front of the monitor (It looks like when those Matrix agents dodge bullets)

Evert
Member #794
November 2000
avatar

Quote:

The sprite focus stays at ( 0, 0 ). I tried switching it around but it didn't work. Any suggestions?

Sounds like a bug.

Quote:

2) When I my program starts up it doesn't show the mouse until I move the mouse. How do I fix this?

You don't, but we should. This is a bug in Allegro, but I thought I'd fixed it a while back. Maybe it got reintroduced in some later patch because it had undesirable side-effects.

What system/Allegro version are you using? I'll try if I can reproduce and fix the problem here. I can probably use the exmouse example to do the testing, but if you have a small testcase programme I can compile and run, that might be helpful.

Oh, one suggestion: use load_bitmap() instead of load_bmp().

biscuitz
Member #5,679
March 2005
avatar

I'm using Allegro 4.2.0 (beta 3) on Windows XP. For a "testcase programme" I could give you the source code for my program that has the bug. You want that? (I'll also give the bitmaps also so you can see mostly what I'm seeing).

Quote:

Oh, one suggestion: use load_bitmap() instead of load_bmp().

Why use 'load_bitmap()' instead of 'load_bmp()'? Is there an advantage?

---Allegro Version 4.2.0 (beta4)
The hardest part is getting started.
WATCH TV! It's good for ya'
Wave your hand really fast in front of the monitor (It looks like when those Matrix agents dodge bullets)

Tobi Vollebregt
Member #1,031
March 2001

biscuitz said:

Why use 'load_bitmap()' instead of 'load_bmp()'? Is there an advantage?

load_bitmap can load all kinds of bitmaps Allegro can load natively (BMP/LBM/PCX/TGA) plus all formats registered to it (by addons for example).

load_bmp can only load .BMP files.

________________________________________
website || Zipfile reader @ Allegro Wiki || Download zipfile reader

Ceagon Xylas
Member #5,495
February 2005
avatar

Wow I never knew that. Any proformance matters? I use load_pcx() alot. You're saying I should use load_bitmap() for that too?

Maikol
Member #4,997
September 2004
avatar

Maybe I'm not a good C programmer but I can see in your code many bugs.

If it's true it doesn't change the focus because of an Allegro's bug, you can solve it like this:

Think this is the screen, where point P represents where mouse_x and mouse_y are; point X is where you would like mouse_x and mouse_y to be. Then you must add to Px and Py necessaries pixels.

+--------------------------------------+
|
| .[P]
| .[X]
|
|
+
...

Before writing the code I must advise you to control all your variables before using them. Obviously you won't see your mouse until you move it, because you haven't initialised it before entering the while loop.

You ought not to call show_mouse() if it isn't necessary.

This is the code I'd write:

1 ... ( whatever )
2 
3 BITMAP *cursor;
4 int done, my_mouse_x, my_mouse_y, add_x, add_y;
5 
6 cursor = load_bitmap( "cursor.bmp", NULL );
7 set_mouse_sprite( cursor );
8 show_mouse( screen );
9 
10 add_x = 0;
11 add_y = 0;
12 
13 while ( !done ) {
14 
15 my_mouse_x = mouse_x + add_x;
16 my_mouse_y = mouse_y + add_y;
17 
18 /* I don't know the meaning of last_mouse_x, so I don't move it */
19 if (( last_mouse_x > 63 ) && ( my_mouse_x < 64 )) {
20 set_mouse_sprite( NULL );
21 show_mouse( screen );
22 add_x = 0;
23 add_y = 0;
24 }
25 
26 /* No need to use 'else if' */
27 if (( last_mouse_x < 64 ) && ( my_mouse_y > 63 )) {
28 set_mouse_sprite( cursor );
29 show_mouse( screen );
30 add_x = 8;
31 add_y = 8;
32 }
33 }
34 destroy_bitmap( cursor );

El sabio no dice todo lo que piensa, pero siempre piensa todo lo que dice
Aristóteles

biscuitz
Member #5,679
March 2005
avatar

Victor, you missed the part about enabling a hardware cursor (which is probably why show_mouse() is needed). And 'last_mouse_x' records the mouse's last x position. I wouldn't use 'add_x' idea. I'm just using 1 mouse sprite now (I redesigned it so it'd look okay without sprite switching).

BTW My new code initializes the mouse sprite before the while loop and it still doesn't show the mouse.

---Allegro Version 4.2.0 (beta4)
The hardest part is getting started.
WATCH TV! It's good for ya'
Wave your hand really fast in front of the monitor (It looks like when those Matrix agents dodge bullets)

Evert
Member #794
November 2000
avatar

Quote:

If it's true it doesn't change the focus because of an Allegro's bug, you can solve it like this:

No, if it's a bug you report it or try to help fix it, not work around it. That said, I haven't had time to look into it yet.

That said, the extra show_mouse() within the loop is definitely redundant and will probably produce much poorer behavior than if it were removed. You also should only change the mouse sprite if you really want to change it, not at each iteration of the loop.
None of those bugs would cause the problem you're seeing though.

EDIT:
Can you try the following: open allegro/src/win/wddraw.c and find the function gfx_directx_show_mouse(). Add ShowCursor(TRUE) after SetCursor() so that the function now looks like

/* gfx_directx_show_mouse:
 *  Switch the Windows cursor to a hardware cursor
 */
int gfx_directx_show_mouse(struct BITMAP *bmp, int x, int y)
{
   if (hcursor) {
      _win_hcursor = hcursor;
      SetCursor(hcursor);
      ShowCursor(TRUE);
      return 0;
   }

   return -1;
}

and recompile Allegro.

For good measure and if this works, you should probably also change gfx_directx_hide_mouse() like so:

/* gfx_directx_hide_mouse:
 *  Hide the hardware cursor
 */
void gfx_directx_hide_mouse(void)
{
   _win_hcursor = NULL;
   SetCursor(NULL);
   ShowCursor(FALSE);
}

biscuitz
Member #5,679
March 2005
avatar

That didn't do anything. The mouse is still invisible at start of program and it still doesn't change the mouse sprite focus (not sure what the purpose of the hack was).

---Allegro Version 4.2.0 (beta4)
The hardest part is getting started.
WATCH TV! It's good for ya'
Wave your hand really fast in front of the monitor (It looks like when those Matrix agents dodge bullets)

Evert
Member #794
November 2000
avatar

Ah soryy, I forgot to comment about the mouse sprite focus.
The code is a little messy (well, that's putting it mildly) but it looks liek it actually should work. Try calling set_mouse_sprite_focus() before set_mouse_sprite() and see if that helps. You can also try explicitly hiding and redisplaying the mouse. Let me know if that works.

About displaying the mouse, the code I posted above was an attempt to tell Windows to display the pointer. Apparently, however, Windows is too stupid (excuse me) to draw the mouse pointer unless the mouse moves. The attached patch is a hack that fakes a move event to work around the problem. I've already tested and submitted it.

biscuitz
Member #5,679
March 2005
avatar

Okay that hack makes the mouse show up on start up. I tried switching around sprite mouse focus and it looks like they're both redundant (mouse sprite focus stays at default (1,1) rather than (0,0) or (8,8) ).

---Allegro Version 4.2.0 (beta4)
The hardest part is getting started.
WATCH TV! It's good for ya'
Wave your hand really fast in front of the monitor (It looks like when those Matrix agents dodge bullets)

ngiacomelli
Member #5,114
October 2004

I hope this isn't considered a 'thread hijack' (i'm not sure what is and is not considered a 'hijack'). But is there any performace gain out of setting a mouse pointer to an image you want and show_mouse-ing it to the buffer, rather than just doing a draw_sprite at mouse_x, mouse_y?

biscuitz
Member #5,679
March 2005
avatar

Okay please look at my code (way up top). Do you see 'enable_hardware_cursor();'? That lets the OS draw the cursor so it won't get clipped into the window (which I think looks ugly in a windowed program; in a full screen program it wouldn't matter). Also since the OS is drawing the mouse pointer it should be pretty fast (I think). Hopefully no one else will talk about blitting the mouse sprite to the buffer because I'd rather have a hardware cursor, which doesn't get clipped to the window (if you don't know what I'm talking about try moving your mouse out of the window of your program, it will stay stuck in there and that looks weird (to me)).

Don't know what you mean by 'thread hijack'. I've never heard of anyone "hijacking" a thread before.

---Allegro Version 4.2.0 (beta4)
The hardest part is getting started.
WATCH TV! It's good for ya'
Wave your hand really fast in front of the monitor (It looks like when those Matrix agents dodge bullets)

ngiacomelli
Member #5,114
October 2004

Quote:

Don't know what you mean by 'thread hijack'. I've never heard of anyone "hijacking" a thread before.

It's basically when someone takes a thread off the original topic... ahem :-X

Thanks for your reply :) (I'm using show_mouse, right now. I was just curious as to the other technique!)

Go to: