mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Windows support for window resizing and fullscreen toggling.
Windows build fixes. This was SVN commit r7607.
This commit is contained in:
parent
0f611042b1
commit
a18aa24fe3
6 changed files with 130 additions and 29 deletions
|
|
@ -830,14 +830,15 @@ function setup_atlas_packages()
|
|||
"Misc"
|
||||
},{ -- extern_libs
|
||||
"boost",
|
||||
"comsuppw",
|
||||
"devil",
|
||||
--"ffmpeg", -- disabled for now because it causes too many build difficulties
|
||||
"libxml2",
|
||||
"sdl", -- key definitions
|
||||
"spidermonkey",
|
||||
"wxwidgets",
|
||||
"comsuppw",
|
||||
"zlib",
|
||||
"x11",
|
||||
"zlib",
|
||||
},{ -- extra_params
|
||||
pch = (not has_broken_pch),
|
||||
extra_links = atlas_extra_links,
|
||||
|
|
|
|||
|
|
@ -203,10 +203,11 @@ static inline void video_enter_game_mode()
|
|||
ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
|
||||
}
|
||||
|
||||
static inline void video_leave_game_mode()
|
||||
static inline void video_leave_game_mode(bool hide = true)
|
||||
{
|
||||
ChangeDisplaySettings(0, 0);
|
||||
ShowWindow(g_hWnd, SW_MINIMIZE);
|
||||
if(hide)
|
||||
ShowWindow(g_hWnd, SW_MINIMIZE);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -218,6 +219,27 @@ int SDL_GL_SetAttribute(SDL_GLattr attr, int value)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void compute_window_style_and_size(bool fullscreen, DWORD* windowStyle, int* w, int* h)
|
||||
{
|
||||
*windowStyle = fullscreen? WS_POPUP : WS_POPUPWINDOW|WS_CAPTION|WS_MINIMIZEBOX;
|
||||
*windowStyle |= WS_VISIBLE;
|
||||
*windowStyle |= WS_CLIPCHILDREN|WS_CLIPSIBLINGS; // MSDN SetPixelFormat says this is required
|
||||
|
||||
// support resizing of windows
|
||||
if(!fullscreen)
|
||||
*windowStyle |= WS_SIZEBOX|WS_MAXIMIZEBOX;
|
||||
|
||||
// Calculate the size of the outer window, so that the client area has
|
||||
// the desired dimensions.
|
||||
RECT r;
|
||||
r.left = r.top = 0;
|
||||
r.right = *w; r.bottom = *h;
|
||||
if (AdjustWindowRectEx(&r, *windowStyle, FALSE, 0))
|
||||
{
|
||||
*w = r.right - r.left;
|
||||
*h = r.bottom - r.top;
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK wndproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
|
@ -244,20 +266,8 @@ static HWND wsdl_CreateWindow(int w, int h)
|
|||
return 0;
|
||||
}
|
||||
|
||||
DWORD windowStyle = fullscreen? WS_POPUP : WS_POPUPWINDOW|WS_CAPTION|WS_MINIMIZEBOX;
|
||||
windowStyle |= WS_VISIBLE;
|
||||
windowStyle |= WS_CLIPCHILDREN|WS_CLIPSIBLINGS; // MSDN SetPixelFormat says this is required
|
||||
|
||||
// Calculate the size of the outer window, so that the client area has
|
||||
// the desired dimensions.
|
||||
RECT r;
|
||||
r.left = r.top = 0;
|
||||
r.right = w; r.bottom = h;
|
||||
if (AdjustWindowRectEx(&r, windowStyle, FALSE, 0))
|
||||
{
|
||||
w = r.right - r.left;
|
||||
h = r.bottom - r.top;
|
||||
}
|
||||
DWORD windowStyle;
|
||||
compute_window_style_and_size(fullscreen, &windowStyle, &w, &h);
|
||||
|
||||
// note: you can override the hardcoded window name via SDL_WM_SetCaption.
|
||||
return CreateWindowExW(WS_EX_APPWINDOW, (LPCWSTR)(uintptr_t)class_atom, L"wsdl", windowStyle, 0, 0, w, h, 0, 0, hInst, 0);
|
||||
|
|
@ -330,20 +340,51 @@ int SDL_SetVideoMode(int w, int h, int bpp, unsigned long flags)
|
|||
}
|
||||
// the (possibly changed) mode will be (re)set at next WM_ACTIVATE
|
||||
|
||||
g_hWnd = wsdl_CreateWindow(w, h);
|
||||
if(!wutil_IsValidHandle(g_hWnd))
|
||||
return 0;
|
||||
if(g_hWnd == (HWND)INVALID_HANDLE_VALUE)
|
||||
{
|
||||
g_hWnd = wsdl_CreateWindow(w, h);
|
||||
if(!wutil_IsValidHandle(g_hWnd))
|
||||
return 0;
|
||||
|
||||
g_hDC = GetDC(g_hWnd);
|
||||
g_hDC = GetDC(g_hWnd);
|
||||
|
||||
SetPixelFormat(g_hDC, bpp);
|
||||
SetPixelFormat(g_hDC, bpp);
|
||||
|
||||
hGLRC = wglCreateContext(g_hDC);
|
||||
if(!hGLRC)
|
||||
return 0;
|
||||
hGLRC = wglCreateContext(g_hDC);
|
||||
if(!hGLRC)
|
||||
return 0;
|
||||
|
||||
if(!wglMakeCurrent(g_hDC, hGLRC))
|
||||
return 0;
|
||||
if(!wglMakeCurrent(g_hDC, hGLRC))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// update the existing window
|
||||
|
||||
DWORD oldWindowStyle = GetWindowLongW(g_hWnd, GWL_STYLE);
|
||||
|
||||
DWORD windowStyle;
|
||||
compute_window_style_and_size(fullscreen, &windowStyle, &w, &h);
|
||||
|
||||
UINT flags = SWP_FRAMECHANGED|SWP_NOZORDER|SWP_NOACTIVATE;
|
||||
|
||||
if(!fullscreen)
|
||||
{
|
||||
// preserve the top-left corner if windowed
|
||||
flags |= SWP_NOMOVE;
|
||||
|
||||
// preserve maximisedness, else we'll mess up when the user attempts to maximise the window
|
||||
windowStyle |= (oldWindowStyle & WS_MAXIMIZE);
|
||||
}
|
||||
|
||||
WARN_IF_FALSE(SetWindowLongW(g_hWnd, GWL_STYLE, windowStyle));
|
||||
WARN_IF_FALSE(SetWindowPos(g_hWnd, 0, 0, 0, w, h, flags));
|
||||
|
||||
if(fullscreen)
|
||||
video_enter_game_mode();
|
||||
else
|
||||
video_leave_game_mode(false);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -956,6 +997,30 @@ int SDL_ShowCursor(int toggle)
|
|||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// resizing
|
||||
|
||||
static void queue_resize_event(int w, int h)
|
||||
{
|
||||
SDL_Event ev;
|
||||
ev.type = SDL_VIDEORESIZE;
|
||||
ev.resize.w = w;
|
||||
ev.resize.h = h;
|
||||
queue_event(ev);
|
||||
}
|
||||
|
||||
static LRESULT OnPosChanged(HWND hWnd, PWINDOWPOS pos)
|
||||
{
|
||||
RECT client_rect;
|
||||
WARN_IF_FALSE(GetClientRect(hWnd, &client_rect));
|
||||
|
||||
queue_resize_event(client_rect.right, client_rect.bottom);
|
||||
// top, left are documented to always be 0
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
static LRESULT OnDestroy(HWND hWnd)
|
||||
|
|
@ -1041,6 +1106,9 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
|||
case WM_MBUTTONUP:
|
||||
return OnMouseButton(hWnd, uMsg, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), (UINT)wParam);
|
||||
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
return OnPosChanged(hWnd, (PWINDOWPOS)lParam);
|
||||
|
||||
default:
|
||||
// can't call DefWindowProc here: some messages
|
||||
// are only conditionally 'grabbed' (e.g. NCHITTEST)
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ extern int SDL_GL_SetAttribute(SDL_GLattr attr, int value);
|
|||
// SDL_SetVideoMode() flags
|
||||
#define SDL_OPENGL 0
|
||||
#define SDL_FULLSCREEN 1
|
||||
#define SDL_RESIZABLE 2
|
||||
|
||||
extern int SDL_SetVideoMode(int w, int h, int bpp, unsigned long flags);
|
||||
|
||||
|
|
@ -211,6 +212,14 @@ typedef struct
|
|||
}
|
||||
SDL_ActiveEvent;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Uint8 type;
|
||||
int w;
|
||||
int h;
|
||||
}
|
||||
SDL_ResizeEvent;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Uint8 type;
|
||||
|
|
@ -228,6 +237,7 @@ enum SDL_Event_type
|
|||
SDL_MOUSEBUTTONUP,
|
||||
SDL_ACTIVEEVENT,
|
||||
SDL_QUIT,
|
||||
SDL_VIDEORESIZE,
|
||||
SDL_USEREVENT
|
||||
};
|
||||
|
||||
|
|
@ -238,6 +248,7 @@ typedef union
|
|||
SDL_MouseMotionEvent motion;
|
||||
SDL_MouseButtonEvent button;
|
||||
SDL_ActiveEvent active;
|
||||
SDL_ResizeEvent resize;
|
||||
SDL_UserEvent user;
|
||||
}
|
||||
SDL_Event;
|
||||
|
|
|
|||
|
|
@ -72,6 +72,13 @@ extern bool g_GameRestarted;
|
|||
|
||||
void kill_mainloop();
|
||||
|
||||
// to avoid redundant and/or recursive resizing, we save the new
|
||||
// size after VIDEORESIZE messages and only update the video mode
|
||||
// once per frame.
|
||||
// these values are the latest resize message, and reset to 0 once we've
|
||||
// updated the video mode
|
||||
static int g_ResizedW;
|
||||
static int g_ResizedH;
|
||||
|
||||
// main app message handler
|
||||
static InReaction MainInputHandler(const SDL_Event_* ev)
|
||||
|
|
@ -83,7 +90,8 @@ static InReaction MainInputHandler(const SDL_Event_* ev)
|
|||
break;
|
||||
|
||||
case SDL_VIDEORESIZE:
|
||||
g_VideoMode.ResizeWindow(ev->ev.resize.w, ev->ev.resize.h);
|
||||
g_ResizedW = ev->ev.resize.w;
|
||||
g_ResizedH = ev->ev.resize.h;
|
||||
break;
|
||||
|
||||
case SDL_HOTKEYDOWN:
|
||||
|
|
@ -266,6 +274,13 @@ static void Frame()
|
|||
PumpEvents();
|
||||
PROFILE_END("input");
|
||||
|
||||
// respond to pumped resize events
|
||||
if (g_ResizedW || g_ResizedH)
|
||||
{
|
||||
g_VideoMode.ResizeWindow(g_ResizedW, g_ResizedH);
|
||||
g_ResizedW = g_ResizedH = 0;
|
||||
}
|
||||
|
||||
PROFILE_START("network poll");
|
||||
if (g_NetServer)
|
||||
g_NetServer->Poll();
|
||||
|
|
|
|||
|
|
@ -159,6 +159,10 @@ bool CVideoMode::ResizeWindow(int w, int h)
|
|||
if (m_IsFullscreen)
|
||||
return true;
|
||||
|
||||
// Ignore if the size hasn't changed
|
||||
if (w == m_WindowedW && h == m_WindowedH)
|
||||
return true;
|
||||
|
||||
int bpp = GetBestBPP();
|
||||
|
||||
if (!SetVideoMode(w, h, bpp, false))
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "KeyMap.h"
|
||||
|
||||
#include "SDL/SDL_keysym.h"
|
||||
|
|
|
|||
Loading…
Reference in a new issue