Sign in to follow this  
Cypherjb

Ingame GUI. DirectInput problem.

Recommended Posts

Hello, I'm currently working on a program that requires a D3D GUI inside a variety of games (similar to XFire). So far the rendering etc works fine, and so does input most of the time, but Unreal Tournament 3 is presenting some issues. It works just fine under windowed mode, but when in full-screen and in-game I can't get a cursor to show. Obviously the game hides it so its not in the way of the crosshair etc, but I can't get it to re-show (I'm attempting to show the regular windows cursor). How I've implemented it: I'm hooking DirectX, and when hFocusWindow is passed to CreateDevice I subclass it with my own window procedure. I also hook SetWindowLong and catch any attempts to overwrite my custom wndproc and keep myself at the 'top' of the chain. I also hook GetCursorPos and SetCursorPos so I can 'unlock' the mouse in games like CSS (because otherwise the game would continually be calling SetCursorPos to center the cursor on the screen and I wouldn't be able to interact with my GUI). Then finally, I hook SetCursor and catch calls to it that try to set the cursor to something other than the default windows cursor. If my GUI is up when this is attempted I 'block' the call. This all works fine in most of the games I've tried. UT3 is presenting the issue that although I can interact with my GUI just fine, I can't get any cursor to show up (which obviously makes interaction with my GUI a pain, you basically have to 'guess' where the mouse is at any point in time). Does anyone have any experience with DirectInput and maybe know what I would need to call or hook to display the cursor? (Typically I'm showing the cursor returned by LoadCursor(NULL, IDC_ARROW))) P.S. I've tried calling IDirect3DDevice9::ShowCursor and ::ShowCursor on every frame but that didn't seem to work.

Share this post


Link to post
Share on other sites
Why not just skip the windows API pains and draw the cursor by yourself? You said you can interact so you know its location. Just draw a sprite there with a cursor pic. You should be able to do that if you already have a GUI up and running.
Never liked the d3d9 cursor mess, much simpler to just get the pos and draw it yourself.

Share this post


Link to post
Share on other sites
Direct3D9 has integrated support for displaying an asynchronous hardware cursor. See IDirect3DDevice9::ShowCursor() and IDirect3DDevice9::SetCursorProperties().

I've used it with great success in my engine to get a usable cursor even when frame rates were abysmal (unlike some annoying games which render the cursor themselves, making it nearly impossible to use when the frame rate drops :D)

This is how I did it:
void Direct3D9VideoDevice::setCursor(const shared_ptr<Image> &spCursorImage) {
D3DCheck(
"Nuclex::Video::Direct3D9VideoDevice::setCursor()",
"IDirect3DDevice9::CreateOffscreenPlainSurface()",
m_spDirect3DDevice->CreateOffscreenPlainSurface(
spCursorImage->getSize().X, spCursorImage->getSize().Y,
D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_spCursor, NULL
)
);

{ D3DLOCKED_RECT LockedRect;
D3DCheck(
"Nuclex::Video::Direct3D9VideoDevice::setCursor()",
"IDirect3DSurface9::LockRect()",
m_spCursor->LockRect(&LockedRect, NULL, D3DLOCK_DISCARD)
);

{ Loki::ScopeGuard Unlock_Surface = Loki::MakeObjGuard(
*m_spCursor, &IDirect3DSurface9::UnlockRect
);

Surface::LockInfo LockedSurface;
LockedSurface.pMemory = LockedRect.pBits;
LockedSurface.eFormat = Surface::PF_ARGB_8_8_8_8;
LockedSurface.nPitch = LockedRect.Pitch;
LockedSurface.eMode = Surface::LM_OVERWRITEALL;
LockedSurface.Size = spCursorImage->getSize();

spCursorImage->blitTo(LockedSurface);
}
}

D3DCheck(
"Nuclex::Video::Direct3D9VideoDevice::setCursor()",
"IDirect3DDevice9::SetCursorProperties()",
m_spDirect3DDevice->SetCursorProperties(0, 0, m_spCursor)
);
}

Share this post


Link to post
Share on other sites
Quote:
Original post by darkelf2k5
Why not just skip the windows API pains and draw the cursor by yourself? You said you can interact so you know its location. Just draw a sprite there with a cursor pic. You should be able to do that if you already have a GUI up and running.
Never liked the d3d9 cursor mess, much simpler to just get the pos and draw it yourself.


Thanks, it's something I really wanted to avoid though. Its definitely something I'll do if I can't get the normal cursor to work though.

Quote:
Original post by Cygon
Direct3D9 has integrated support for displaying an asynchronous hardware cursor. See IDirect3DDevice9::ShowCursor() and IDirect3DDevice9::SetCursorProperties().

I've used it with great success in my engine to get a usable cursor even when frame rates were abysmal (unlike some annoying games which render the cursor themselves, making it nearly impossible to use when the frame rate drops :D)

This is how I did it:
*** Source Snippet Removed ***


Thanks, I'll give that a try.

Share this post


Link to post
Share on other sites
Quote:


Thanks, it's something I really wanted to avoid though. Its definitely something I'll do if I can't get the normal cursor to work though.



As a side note, DX10 and later does not have the cursor methods of DX9 so everything needs to be done by hand. If you plan of moving on in the near future, you might as well get used to it and roll your own. If not, just do whatever works. :)

Share this post


Link to post
Share on other sites
Quote:
Original post by darkelf2k5
Quote:


Thanks, it's something I really wanted to avoid though. Its definitely something I'll do if I can't get the normal cursor to work though.



As a side note, DX10 and later does not have the cursor methods of DX9 so everything needs to be done by hand. If you plan of moving on in the near future, you might as well get used to it and roll your own. If not, just do whatever works. :)


Ah crap. Thanks for the heads up. I do intend to move to DX10 once everything is stable on DX9.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this