Wintermute Engine Forum

Wintermute Engine => Technical forum => WME sources discussion => Topic started by: mRax on February 13, 2009, 04:05:08 PM

Title: Mouse position & maximilized window
Post by: mRax on February 13, 2009, 04:05:08 PM
There is a little interesting bug. When game is in window mode (not fullscreen) and game window is stretched like desktop wallpaper, mouse position is calculated wrong.

For example, there are desktop resolution 1280x800 and game window resolution 1280x1024. When game window is maximilized, then its lower part is inaccessible, because of windows mouse position isn't translated properly to stretched window position. The bottom of mouse position (x,800) translated surely into game as it is (x,800) instead of (x,1024).

Here is possible modification, bold font style is used to show changes. (Well, is it good idea to write about all that in `sources discussion`?  ???)

Quote from: bgame.cpp
void CBGame::GetMousePos(POINT* Pos)
{
   CBPlatform::GetCursorPos(Pos);
   CBPlatform::ScreenToClient(Game->m_Renderer->m_Window, Pos);

   Pos->x -= m_Renderer->m_DrawOffsetX;
   Pos->y -= m_Renderer->m_DrawOffsetY;

   //cursor position modification while window is maximized
   if(Game->m_Renderer->m_Windowed)
   {
      HWND hWnd = Game->m_Renderer->m_Window;
      WINDOWPLACEMENT wndpl;
      if(GetWindowPlacement(hWnd, &wndpl))
         if(wndpl.showCmd == SW_SHOWMAXIMIZED)
         {
            RECT hWnd_rect;
            GetClientRect(hWnd, &hWnd_rect);
            Pos->x *= Game->m_Renderer->m_RealWidth;
            Pos->x /= hWnd_rect.right;
            Pos->y *= Game->m_Renderer->m_RealHeight;
            Pos->y /= hWnd_rect.bottom;
         }
   }


   if(m_MouseLockRect.left != 0 && m_MouseLockRect.right != 0 && m_MouseLockRect.top != 0 && m_MouseLockRect.bottom != 0)
   {
      if(!CBPlatform::PtInRect(&m_MouseLockRect, *Pos))
      {
         Pos->x = max(m_MouseLockRect.left, Pos->x);
         Pos->y = max(m_MouseLockRect.top, Pos->y);

         Pos->x = min(m_MouseLockRect.right, Pos->x);
         Pos->y = min(m_MouseLockRect.bottom, Pos->y);

         POINT NewPos = *Pos;
         CBPlatform::ClientToScreen(Game->m_Renderer->m_Window, &NewPos);
         CBPlatform::SetCursorPos(NewPos.x, NewPos.y);
      }
   }
}

I'm sorry for my English, but guess you're understanding what I'm talking about...

P.S. That stretched window is a great way to make game for several screen resolutions. Meaning 1280x1024 window fits perfectly for all desktop resolutions (1280x1024, 1280x800, 1024x768, 800x600, e.t.c.) of 4:3 monitor. I'm talking about window mode, of course.
Title: Re: Mouse position & maximilized window
Post by: Mnemonic on February 13, 2009, 05:49:19 PM
Thanks, mRax. I didn't realize Windows would squish the window on maximize when it's larger than desktop resolution.
Title: Re: Mouse position & maximilized window
Post by: mRax on February 16, 2009, 10:23:15 AM
I didn't realize Windows would squish the window on maximize when it's larger than desktop resolution.

For me it was a surprise also :)

By the way there is one moment which disturbs me. Since I didn't use MouseLockRect, I haven't paid attention to NewPos object. Now I'm thinking, that NewPos must be recalculated "back" to original (something like that: NewPos.X = NewPox.X * hWnd_rect.right / Game->m_Renderer->m_RealWidth), when the window is squished. Other way mouse cursor can go somewhere wrong in each frame :-\ (to left top corner?) caused by SetCursorPos... Well, I'm not sure...
Title: Re: Mouse position & maximilized window
Post by: Mnemonic on February 16, 2009, 10:35:14 AM
The mouse lock rectangle is only used in full screen. The purpose is to lock the mouse on one monitor in multi-mon environments.