Archived

This topic is now archived and is closed to further replies.

Moe

using a bitmap as a custom cursor

Recommended Posts

Intead of using a regular black and white cursor that I could compile, I decided to use a bitmap instead. What I am trying to do is get the mouse position every frame and blit the bitmap at the cursors position (via Direct Draw blt function). Something is funny. I just can''t get it to work. Here is the code (which is in the main message loop) to get the cursor''s position: case WM_MOUSEMOVE: { //do that neat cursor thingy here //extract mouse position int mouse_x = (int)LOWORD(lparam); int mouse_y = (int)HIWORD(lparam); RECT cursor; DDBLTFX ddbltfx; //set it so that the bitmap is displayed where the cursor should be cursor.top = mouse_y; cursor.left = mouse_x; cursor.bottom = mouse_y + 32; cursor.right = mouse_x + 32; lpddsprimary->Blt(&cursor, lpcursor, NULL, DDBLT_WAIT, &ddbltfx); } break; I can''t figure out what is wrong with it for the life of me. Anyone here have any ideas? Shrapnel Games

Share this post


Link to post
Share on other sites
Not quite sure why you''re passing a DDBLTFX structure to blt
when you aren''t setting any of the parameters in it....how about
passing NULL where you pass the DDBLTFX structure to blt that
might help a little bit.

lpddsprimary->Blt(&cursor, lpcursor, NULL, DDBLT_WAIT, NULL);

~S''Greth

Share this post


Link to post
Share on other sites
I see that you have not specified any source rect. But that is probably not the problem. Then the mouse coordinate is relative to the upper-left corner of the client area. You must change this if you are working in window mode.

//set it so that the bitmap is displayed where the cursor should be
cursor.top = g_rcMainWin.top + mouse_y;
cursor.left = g_rcMainWin.left + mouse_x;
cursor.bottom = cursor.top + 32;
cursor.right = cursor.left + 32;

Zeblar Nagrim, Lord of Chaos

Share this post


Link to post
Share on other sites
Your code looks fine. This is just a shot in the dark here. I think your problem may be one of different bit depths. Check the bit depth of your bitmap. Is it the same as your application''s current bit depth?

hope that helped,
skitzo_smurf

Share this post


Link to post
Share on other sites
bit depth shouldnt matter as all surfaces will be the same bitdepth, it maybe you dont have the bitmap loaded correctly in lpcursor

Im Always Bored
--Bordem
ICQ: 76947930

Share this post


Link to post
Share on other sites
sorry,
maybe that wasnt clear enough. I meant that he could be trying to load a 32 bit bitmap onto an 8 bit surface. In other words, I meant to check that the bitmap''s bit depth is the same as his surfaces'' bit depths. That could definitely cause a problem.

skitzo_smurf

Share this post


Link to post
Share on other sites
case WM_MOUSEMOVE:
{
// Store windowrect in global rect
// Do this in your WM_MOVE message,
// not here.
RECT g_rcMainWin;
GetWindowRect(hWnd, &rcClientRect);
CopyRect(&g_rcMainWin, &rcClientRect);

// Hide cursor if inside client rect
int hide;
while(1)
{
hide = ShowCursor(FALSE);
if(hide < 0)
break;
}

//do that neat cursor thingy here
//extract mouse position
int mouse_x = (int)LOWORD(lParam);
int mouse_y = (int)HIWORD(lParam);

// Show cursor on menu
if(mouse_y < 20)
{
while(1)
{
hide = ShowCursor(TRUE);
if(hide > 0)
break;
}
break;
}

RECT cursor;

//set it so that the bitmap is displayed where the cursor should be
cursor.top = g_rcMainWin.top + mouse_y;
cursor.left = g_rcMainWin.left + mouse_x;
cursor.bottom = cursor.top + 32;
cursor.right = cursor.left + 32;

static RECT srect = {0,0,32,32};
lpddsprimary->Blt(&cursor, lpcursor, &srect, 0, &ddbltfx);

}
break;

Zeblar Nagrim, Lord of Chaos

Edited by - Zeblar Nagrim on July 20, 2000 5:59:33 AM

Share this post


Link to post
Share on other sites
Okay, I kinda figured it out, but there still is a few problems. I am working with a fullscreen exclusive window, so I am not worry about the position within the window (and I don''t have any menus, or anything). I know now that I have properly loaded the bitmaps, since I can see them. Now here is the updated code:

case WM_MOUSEMOVE:
{
DDCOLORKEY key;

key.dwColorSpaceLowValue = (0,0,0);
key.dwColorSpaceHighValue = (0,0,0);
//not sure which surface to set it on, the back??
lpddsback->SetColorKey(DDCKEY_SRCBLT,&key);
lpddsprimary->SetColorKey(DDCKEY_SRCBLT, &key);

lpddsback->Blt(NULL,lpbackground,NULL,DDBLT_WAIT,NULL);

//do that neat cursor thingy here
//extract mouse position
int mouse_x = (int)LOWORD(lparam);
int mouse_y = (int)HIWORD(lparam);
int buttons = (int)wparam;

RECT dest;
dest.left = mouse_x;
dest.top = mouse_y;
dest.right = mouse_x+32;
dest.bottom = mouse_y+32;


lpddsback->Blt(&dest,lpcursor,NULL,DDBLT_WAIT | DDCKEY_SRCBLT,NULL);


} break;

The colorkey doesn''t seem to work. I want a source colorkey so that no black will appear around the cursor. I have also implimented a background bitmap, and page flipping. Now heres the new problems:

When I can''t see the cursor bitmap at all. I am not sure what it causing that. When I turn off (comment out) the colorkeying can see it but it flickers and there appears to be a ''shadow'' copy of the cursor bitmap. Anyone seen anything like that before? (I should try to post the source code and demo at my website). Anyone?

Shrapnel Games

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
key.dwColorSpaceLowValue = (0,0,0);
key.dwColorSpaceHighValue = (0,0,0);

doesn''t look right...
you need a word creating macro for the correct display mode.
And how did you get (0,0,0) to compile?

Share this post


Link to post
Share on other sites
I have not tried this yet (I''m implementing a mouse pointer in my prog tomorrow).

Try saving the location of your mouse pointer in a variable and doing the mouse draw code at the end of your main loop, just before you flip.

You may be drawing your mouse cursor behind your main objects, to test this out, comment out all calls from your main loop, but not the clear and flip calls.

Saving the position and then drawing when you know it will be displayed is far better then letting the event draw your cursor.

Share this post


Link to post
Share on other sites
I finally got it(mostly)! Saving the position of the mouse cursor in a global variable, then blitting it as the last thing in the main loop worked. But...
I still can''t seem to get that colorkeying to work. Whenever I add the flag into the blitting for the cursor, it dissapears entirely. I think the problem might be in setting the color key high and low values. I will have to look it up in one of my many books.

oh, and annonymous poster, it compiled fine. Quite surprising anything of mine compiles fine...

Shrapnel Games

Share this post


Link to post
Share on other sites
Here''s the code I use to set the colour key to blank:

    
DDBLTFX ddfx;

ZeroMemory( &ddfx, sizeof( ddfx ) );
ddfx.dwSize = sizeof( ddfx );
ddfx.ddckSrcColorkey.dwColorSpaceLowValue = 0;
ddfx.ddckSrcColorkey.dwColorSpaceHighValue = 0;

Engine->BBuffer->Blt( &rect2, lpDDSBalls, &rect, DDBLT_KEYSRCOVERRIDE | DDBLT_WAIT, &ddfx );


try that, i could not get the colour key to work on the surface itself, I had to inform the Blt() to use the DDBLTFX struct info.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster

ddckey.dwColorSpaceHighValue = 0;
ddckey.dwColorSpaceLowValue = 0;

hrVal = lpcursor->SetColorKey( DDCKEY_SRCBLT, &ddckey );
if( FAILED( hrVal ) )
// error



You want to set the color key on the cursor''s surface not the primary and back buffer surface. And I believe you only need to set it once, not every time the mouse moves.

hth

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
If you never set the colorkey of the cursor surface, and tried to blt with a src color key (using the cursor as the source) you should actully get an error during the blit (because there is no color key set) I believe and from what I can see you don''t check for any errors during the blit.

hth

Share this post


Link to post
Share on other sites