Jump to content
  • Advertisement
Sign in to follow this  
Jamoflaw

Mouse input

This topic is 3029 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have been using Direct Input to recieve mouse input (no jeers please) I have just started migration to the Windows input method as MS now says you should.



This video is of my engine currently. The mouse input is fine unless the window is resized from default in which case it is miles out.

My mouse up[date method basically:


GetCursorPos(&position);
ScreenToClient(this->window, &position);



Am I missing anything here? I assumed the ScreenToClient message would have handled the transition to a maximised window without trouble :(

James

Share this post


Link to post
Share on other sites
Advertisement
You're not resizing your backbuffer when you resize the window, so the client coordinates aren't the same as backbuffer coordinates any more.

You'll need to Reset() your device, passing in a new backbuffer width and height to match the new client area size.

Share this post


Link to post
Share on other sites
Ah, I suppose my internal renderer coords are out of sync with the screen coords when they arent mapped to the desktop 1:1.

Always something simple! I would rather it that the user could keep the same BB res with a different window size, similar to how World of Warcraft handles mouse input. Would I have to adjust the returned cursor point using the current window size?

Share this post


Link to post
Share on other sites
Quote:
I assumed the ScreenToClient message would have handled the transition to a maximised window without trouble

It does. You'll have to post the code that converts and uses the mouse position.

EDIT: As per normal, Evil Steve's probably got it.

Share this post


Link to post
Share on other sites
Jsut updating the code to resize the bb

Whcih window message is good to put this code in? WM_SIZE and SIZING are called quite a lot during window resize :S

Share this post


Link to post
Share on other sites
Quote:
Original post by Jamoflaw
Jsut updating the code to resize the bb

Whcih window message is good to put this code in? WM_SIZE and SIZING are called quite a lot during window resize :S
I'd resize the backbuffer in WM_SIZE, and update the projection matrix in WM_SIZING. That way, it'll have the correct aspect ratio when you're dragging the window around, and will update when you let go of the corner of the window (Which is when you should get WM_SIZE).

You can also speed the Reset() up somewhat by creating a custom swap chain (And setting the default swap chain to 1x1 in your present params). That way you just need to reset the swap chain instead of the entire device (Which would mean reloading all default pool resources, and re-uploading managed resources).

Share this post


Link to post
Share on other sites
Quote:
Original post by Jamoflaw
Jsut updating the code to resize the bb

Whcih window message is good to put this code in? WM_SIZE and SIZING are called quite a lot during window resize :S


WM_SIZE is fired by the windows api when a window size is changed, WM_SIZING is fired when the user changes the size of a window. You want it in WM_SIZE to make sure it reacts to all scenarios to prevent bugs. Don't worry about calling it too much - the windows api itself causes a lot of overhead because of resizing, the frame rate is going to be horrible during a resize regardless. Or you could program something to disable rendering until the user has finished resizing (if WM_SIZING is being called), so the bb is only resized once.

Share this post


Link to post
Share on other sites
Two different scenarios:

1. user drags the window to a new size
2. user clicks the maximize button

When the user drags the window frame, you'll get a lot of WM_SIZE messages. You need to decide if you want the window to be updated continually when that happens.

If you want continuous updating, either put the code in WM_SIZE or call a function to do the updating in the WM_SIZE case. EDIT: See Evil Steve's comment above.

Normally I stop updating during the drag scenario. I turn off updating on WM_ENTERSIZEMOVE and resume updating when WM_EXITSIZEMOVE is passed. FYI: WM_ENTER/EXITSIZEMOVE aren't passed when the window is maximized, only during drag moves.

Something like:

case WM_ENTERSIZEMOVE:
inSizeMove = true;
break;
case WM_EXITSIZEMOVE:
inSizeMove = false;
break;
case WM_SIZE:
if( !inSizeMove )
{
// call a routine here to reset the device
// or set a flag such as "resetNeeded = true"
// to be processed the next time through your run loop
}
break;



Share this post


Link to post
Share on other sites
Bah! I'm no idea where I am going here! These window messages are a pain!!

I have a method which combines the device reset and a display mode change if necessary. I think I am resetting the window to an incorrect mode as the cursor is about the distance of the title bar away from where i expect it to be

:(

This was easier when I had the cursor in exclusive mode :p


void GEngine::ChangeScreenResolution(int width, int height, int colorDepth, bool fullscreen)
{
if(this->GENDEBUG)
this->Console_AddLine("Changing Screen Resolution");

this->SetScreenWidth(width);
this->SetScreenHeight(height);
this->SetColorDepth(colorDepth);
this->SetFullscreen(fullscreen);

this->d3dpp.BackBufferHeight = height;
this->d3dpp.BackBufferWidth = width;
this->d3dpp.Windowed = !fullscreen;

if (fullscreen)
{
if(this->GENDEBUG)
this->Console_AddLine("Switching to fullscreen...");

this->OnLostDevice();
this->GetDevice()->Reset(&this->d3dpp);
this->OnResetDevice();

SetWindowLongPtr(this->GetWindowHandle(), GWL_STYLE, WS_POPUP);

RECT R = {0,0,width,height};

AdjustWindowRectEx(&R, WS_POPUP, false, WS_EX_APPWINDOW);



ShowCursor(false);

SetWindowPos(this->GetWindowHandle(), HWND_TOP, 0,0, width, height, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED );

}
else
{
if(this->GENDEBUG)
this->Console_AddLine("Switching to windowed mode...");

this->OnLostDevice();
this->GetDevice()->Reset(&this->d3dpp);
this->OnResetDevice();

RECT R = {0,0,width,height};

AdjustWindowRectEx(&R, WS_OVERLAPPEDWINDOW, false, WS_EX_APPWINDOW | WS_EX_WINDOWEDGE);

ShowCursor(true);


SetWindowPos(this->GetWindowHandle(), HWND_TOP, 0, 0, R.right, R.bottom, SWP_FRAMECHANGED | SWP_NOZORDER | SWP_SHOWWINDOW );
}

if(this->GENDEBUG)
this->Console_AddLine("COMPLETE");
}


Share this post


Link to post
Share on other sites
Quote:
Original post by Jamoflaw
I have a method which combines the device reset and a display mode change if necessary. I think I am resetting the window to an incorrect mode as the cursor is about the distance of the title bar away from where i expect it to be
You need to call AdjustWindowRect() to get the size to pass to SetWindowPos(). The size you pass to SetWindowPos() includes the title bar and borders (I.e. it's the window rect, not the client area rect). AdjustWindowRect will give the window size based on the desired client area size.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!