diff --git a/src/engine/client.h b/src/engine/client.h
index 2f0adad7e..c2b7b1ada 100644
--- a/src/engine/client.h
+++ b/src/engine/client.h
@@ -110,6 +110,12 @@ public:
virtual void AutoStatScreenshot_Start() = 0;
virtual void ServerBrowserUpdate() = 0;
+ // gfx
+ virtual void SwitchWindowScreen(int Index) = 0;
+ virtual void ToggleFullscreen() = 0;
+ virtual void ToggleWindowBordered() = 0;
+ virtual void ToggleWindowVSync() = 0;
+
// networking
virtual void EnterGame() = 0;
diff --git a/src/engine/client/backend_sdl.cpp b/src/engine/client/backend_sdl.cpp
index bb3277b5d..09a7b4411 100644
--- a/src/engine/client/backend_sdl.cpp
+++ b/src/engine/client/backend_sdl.cpp
@@ -7,6 +7,7 @@
#endif
#include
+#include
#include
#include "SDL.h"
#include "SDL_syswm.h"
@@ -447,17 +448,17 @@ void CCommandProcessorFragment_SDL::Cmd_Shutdown(const SCommand_Shutdown *pComma
void CCommandProcessorFragment_SDL::Cmd_Swap(const CCommandBuffer::SCommand_Swap *pCommand)
{
- // TODO: Currently breaks some text fields
- //int Width, Height;
- //SDL_GetWindowSize(m_pWindow, &Width, &Height);
- //glViewport(((float)Width-(float)g_Config.m_GfxScreenWidth)/2, ((float)Height-(float)g_Config.m_GfxScreenHeight)/2, (float)g_Config.m_GfxScreenWidth, (float)g_Config.m_GfxScreenHeight);
-
SDL_GL_SwapWindow(m_pWindow);
if(pCommand->m_Finish)
glFinish();
}
+void CCommandProcessorFragment_SDL::Cmd_VSync(const CCommandBuffer::SCommand_VSync *pCommand)
+{
+ *pCommand->m_pRetOk = SDL_GL_SetSwapInterval(pCommand->m_VSync) == 0;
+}
+
void CCommandProcessorFragment_SDL::Cmd_VideoModes(const CCommandBuffer::SCommand_VideoModes *pCommand)
{
SDL_DisplayMode mode;
@@ -503,6 +504,7 @@ bool CCommandProcessorFragment_SDL::RunCommand(const CCommandBuffer::SCommand *p
switch(pBaseCommand->m_Cmd)
{
case CCommandBuffer::CMD_SWAP: Cmd_Swap(static_cast(pBaseCommand)); break;
+ case CCommandBuffer::CMD_VSYNC: Cmd_VSync(static_cast(pBaseCommand)); break;
case CCommandBuffer::CMD_VIDEOMODES: Cmd_VideoModes(static_cast(pBaseCommand)); break;
case CMD_INIT: Cmd_Init(static_cast(pBaseCommand)); break;
case CMD_SHUTDOWN: Cmd_Shutdown(static_cast(pBaseCommand)); break;
@@ -538,7 +540,7 @@ void CCommandProcessor_SDL_OpenGL::RunBuffer(CCommandBuffer *pBuffer)
// ------------ CGraphicsBackend_SDL_OpenGL
-int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int Screen, int *pWidth, int *pHeight, int FsaaSamples, int Flags, int *pDesktopWidth, int *pDesktopHeight)
+int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Screen, int *pWidth, int *pHeight, int FsaaSamples, int Flags, int *pDesktopWidth, int *pDesktopHeight)
{
if(!SDL_WasInit(SDL_INIT_VIDEO))
{
@@ -554,46 +556,58 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int Screen, int *pWidth
#endif
}
- SDL_Rect ScreenBounds;
- if(SDL_GetDisplayBounds(Screen, &ScreenBounds) < 0)
+ // set screen
+ SDL_Rect ScreenPos;
+ m_NumScreens = SDL_GetNumVideoDisplays();
+ if(m_NumScreens > 0)
{
- dbg_msg("gfx", "unable to get current screen bounds: %s", SDL_GetError());
+ clamp(*Screen, 0, m_NumScreens-1);
+ if(SDL_GetDisplayBounds(*Screen, &ScreenPos) != 0)
+ {
+ dbg_msg("gfx", "unable to retrieve screen information: %s", SDL_GetError());
+ return -1;
+ }
+
+ }
+ else
+ {
+ dbg_msg("gfx", "unable to retrieve number of screens: %s", SDL_GetError());
return -1;
}
- // use current resolution as default
+ // store desktop resolution for settings reset button
+ SDL_DisplayMode DisplayMode;
+ if(SDL_GetDesktopDisplayMode(*Screen, &DisplayMode))
+ {
+ dbg_msg("gfx", "unable to get desktop resolution: %s", SDL_GetError());
+ return -1;
+ }
+ *pDesktopWidth = DisplayMode.w;
+ *pDesktopHeight = DisplayMode.h;
+
+ // use desktop resolution as default resolution
#ifndef __ANDROID__
if(*pWidth == 0 || *pHeight == 0)
#endif
{
- *pWidth = ScreenBounds.w;
- *pHeight = ScreenBounds.h;
+ *pWidth = *pDesktopWidth;
+ *pHeight = *pDesktopHeight;
}
-
- *pDesktopWidth = ScreenBounds.w;
- *pDesktopHeight = ScreenBounds.h;
-
- dbg_assert(!(Flags&IGraphicsBackend::INITFLAG_BORDERLESS)
- || !(Flags&IGraphicsBackend::INITFLAG_FULLSCREEN),
- "only one of borderless and fullscreen may be activated at the same time");
-
// set flags
int SdlFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN;
if(Flags&IGraphicsBackend::INITFLAG_RESIZABLE)
SdlFlags |= SDL_WINDOW_RESIZABLE;
-
if(Flags&IGraphicsBackend::INITFLAG_BORDERLESS)
SdlFlags |= SDL_WINDOW_BORDERLESS;
-
if(Flags&IGraphicsBackend::INITFLAG_FULLSCREEN)
- {
- #if defined(CONF_FAMILY_WINDOWS) || defined(CONF_PLATFORM_MACOSX)
- SdlFlags |= SDL_WINDOW_FULLSCREEN;
- #else
- SdlFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
- #endif
- }
+#if defined(CONF_PLATFORM_MACOSX) // Todo SDL: remove this when fixed (game freezes when losing focus in fullscreen)
+ SdlFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP; // always use "fake" fullscreen
+ *pWidth = *pDesktopWidth;
+ *pHeight = *pDesktopHeight;
+#else
+ SdlFlags |= SDL_WINDOW_FULLSCREEN;
+#endif
// set gl attributes
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
@@ -610,8 +624,8 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int Screen, int *pWidth
m_pWindow = SDL_CreateWindow(
pName,
- SDL_WINDOWPOS_UNDEFINED_DISPLAY(0),
- SDL_WINDOWPOS_UNDEFINED_DISPLAY(0),
+ SDL_WINDOWPOS_CENTERED_DISPLAY(g_Config.m_GfxScreen),
+ SDL_WINDOWPOS_CENTERED_DISPLAY(g_Config.m_GfxScreen),
*pWidth,
*pHeight,
SdlFlags);
@@ -627,14 +641,16 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int Screen, int *pWidth
m_GLContext = SDL_GL_CreateContext(m_pWindow);
- SDL_ShowWindow(m_pWindow);
-
if(m_GLContext == NULL)
{
dbg_msg("gfx", "unable to create OpenGL context: %s", SDL_GetError());
return -1;
}
+ SDL_ShowWindow(m_pWindow);
+
+ SetWindowScreen(g_Config.m_GfxScreen);
+
SDL_GL_SetSwapInterval(Flags&IGraphicsBackend::INITFLAG_VSYNC ? 1 : 0);
SDL_GL_MakeCurrent(NULL, NULL);
@@ -697,7 +713,38 @@ void CGraphicsBackend_SDL_OpenGL::Maximize()
bool CGraphicsBackend_SDL_OpenGL::Fullscreen(bool State)
{
+#if defined(CONF_PLATFORM_MACOSX) // Todo SDL: remove this when fixed (game freezes when losing focus in fullscreen)
+ return SDL_SetWindowFullscreen(m_pWindow, State ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0) == 0;
+#else
return SDL_SetWindowFullscreen(m_pWindow, State ? SDL_WINDOW_FULLSCREEN : 0) == 0;
+#endif
+}
+
+void CGraphicsBackend_SDL_OpenGL::SetWindowBordered(bool State)
+{
+ SDL_SetWindowBordered(m_pWindow, SDL_bool(State));
+}
+
+bool CGraphicsBackend_SDL_OpenGL::SetWindowScreen(int Index)
+{
+ if(Index >= 0 && Index < m_NumScreens)
+ {
+ SDL_Rect ScreenPos;
+ if(SDL_GetDisplayBounds(Index, &ScreenPos) == 0)
+ {
+ SDL_SetWindowPosition(m_pWindow,
+ SDL_WINDOWPOS_CENTERED_DISPLAY(Index),
+ SDL_WINDOWPOS_CENTERED_DISPLAY(Index));
+ return true;
+ }
+ }
+
+ return false;
+}
+
+int CGraphicsBackend_SDL_OpenGL::GetWindowScreen()
+{
+ return SDL_GetWindowDisplayIndex(m_pWindow);
}
int CGraphicsBackend_SDL_OpenGL::WindowActive()
diff --git a/src/engine/client/backend_sdl.h b/src/engine/client/backend_sdl.h
index 796ecc188..02721f1c1 100644
--- a/src/engine/client/backend_sdl.h
+++ b/src/engine/client/backend_sdl.h
@@ -156,6 +156,7 @@ private:
void Cmd_Init(const SCommand_Init *pCommand);
void Cmd_Shutdown(const SCommand_Shutdown *pCommand);
void Cmd_Swap(const CCommandBuffer::SCommand_Swap *pCommand);
+ void Cmd_VSync(const CCommandBuffer::SCommand_VSync *pCommand);
void Cmd_VideoModes(const CCommandBuffer::SCommand_VideoModes *pCommand);
public:
CCommandProcessorFragment_SDL();
@@ -180,15 +181,21 @@ class CGraphicsBackend_SDL_OpenGL : public CGraphicsBackend_Threaded
SDL_GLContext m_GLContext;
ICommandProcessor *m_pProcessor;
volatile int m_TextureMemoryUsage;
+ int m_NumScreens;
public:
- virtual int Init(const char *pName, int Screen, int *pWidth, int *pHeight, int FsaaSamples, int Flags, int *pDesktopWidth, int *pDesktopHeight);
+ virtual int Init(const char *pName, int *Screen, int *pWidth, int *pHeight, int FsaaSamples, int Flags, int *pDesktopWidth, int *pDesktopHeight);
virtual int Shutdown();
virtual int MemoryUsage() const;
+ virtual int GetNumScreens() const { return m_NumScreens; }
+
virtual void Minimize();
virtual void Maximize();
virtual bool Fullscreen(bool State);
+ virtual void SetWindowBordered(bool State); // on=true/off=false
+ virtual bool SetWindowScreen(int Index);
+ virtual int GetWindowScreen();
virtual int WindowActive();
virtual int WindowOpen();
virtual void SetWindowGrab(bool Grab);
diff --git a/src/engine/client/client.cpp b/src/engine/client/client.cpp
index 6438d7fa5..fda41ec9b 100644
--- a/src/engine/client/client.cpp
+++ b/src/engine/client/client.cpp
@@ -2649,8 +2649,6 @@ void CClient::Run()
// never start with the editor
g_Config.m_ClEditor = 0;
- Input()->MouseModeRelative();
-
// process pending commands
m_pConsole->StoreCommands(false);
@@ -3189,6 +3187,89 @@ void CClient::ConchainServerBrowserUpdate(IConsole::IResult *pResult, void *pUse
((CClient *)pUserData)->ServerBrowserUpdate();
}
+void CClient::SwitchWindowScreen(int Index)
+{
+ // Todo SDL: remove this when fixed (changing screen when in fullscreen is bugged)
+ if(g_Config.m_GfxFullscreen)
+ {
+ ToggleFullscreen();
+ if(Graphics()->SetWindowScreen(Index))
+ g_Config.m_GfxScreen = Index;
+ ToggleFullscreen();
+ }
+ else
+ {
+ if(Graphics()->SetWindowScreen(Index))
+ g_Config.m_GfxScreen = Index;
+ }
+}
+
+void CClient::ConchainWindowScreen(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
+{
+ CClient *pSelf = (CClient *)pUserData;
+ if(pSelf->Graphics() && pResult->NumArguments())
+ {
+ if(g_Config.m_GfxScreen != pResult->GetInteger(0))
+ pSelf->SwitchWindowScreen(pResult->GetInteger(0));
+ }
+ else
+ pfnCallback(pResult, pCallbackUserData);
+}
+
+void CClient::ToggleFullscreen()
+{
+ if(Graphics()->Fullscreen(g_Config.m_GfxFullscreen^1))
+ g_Config.m_GfxFullscreen ^= 1;
+}
+
+void CClient::ConchainFullscreen(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
+{
+ CClient *pSelf = (CClient *)pUserData;
+ if(pSelf->Graphics() && pResult->NumArguments())
+ {
+ if(g_Config.m_GfxFullscreen != pResult->GetInteger(0))
+ pSelf->ToggleFullscreen();
+ }
+ else
+ pfnCallback(pResult, pCallbackUserData);
+}
+
+void CClient::ToggleWindowBordered()
+{
+ g_Config.m_GfxBorderless ^= 1;
+ Graphics()->SetWindowBordered(!g_Config.m_GfxBorderless);
+}
+
+void CClient::ConchainWindowBordered(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
+{
+ CClient *pSelf = (CClient *)pUserData;
+ if(pSelf->Graphics() && pResult->NumArguments())
+ {
+ if(!g_Config.m_GfxFullscreen && (g_Config.m_GfxBorderless != pResult->GetInteger(0)))
+ pSelf->ToggleWindowBordered();
+ }
+ else
+ pfnCallback(pResult, pCallbackUserData);
+}
+
+void CClient::ToggleWindowVSync()
+{
+ if(Graphics()->SetVSync(g_Config.m_GfxVsync^1))
+ g_Config.m_GfxVsync ^= 1;
+}
+
+void CClient::ConchainWindowVSync(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
+{
+ CClient *pSelf = (CClient *)pUserData;
+ if(pSelf->Graphics() && pResult->NumArguments())
+ {
+ if(g_Config.m_GfxVsync != pResult->GetInteger(0))
+ pSelf->ToggleWindowVSync();
+ }
+ else
+ pfnCallback(pResult, pCallbackUserData);
+}
+
void CClient::RegisterCommands()
{
m_pConsole = Kernel()->RequestInterface();
@@ -3231,6 +3312,11 @@ void CClient::RegisterCommands()
m_pConsole->Chain("br_filter_gametype", ConchainServerBrowserUpdate, this);
m_pConsole->Chain("br_filter_serveraddress", ConchainServerBrowserUpdate, this);
+ m_pConsole->Chain("gfx_screen", ConchainWindowScreen, this);
+ m_pConsole->Chain("gfx_fullscreen", ConchainFullscreen, this);
+ m_pConsole->Chain("gfx_borderless", ConchainWindowBordered, this);
+ m_pConsole->Chain("gfx_vsync", ConchainWindowVSync, this);
+
// DDRace
diff --git a/src/engine/client/client.h b/src/engine/client/client.h
index 1b78c12f2..4708ba469 100644
--- a/src/engine/client/client.h
+++ b/src/engine/client/client.h
@@ -333,6 +333,10 @@ public:
static void Con_StopRecord(IConsole::IResult *pResult, void *pUserData);
static void Con_AddDemoMarker(IConsole::IResult *pResult, void *pUserData);
static void ConchainServerBrowserUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
+ static void ConchainFullscreen(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
+ static void ConchainWindowBordered(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
+ static void ConchainWindowScreen(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
+ static void ConchainWindowVSync(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void Con_DemoSlice(IConsole::IResult *pResult, void *pUserData);
static void Con_DemoSliceBegin(IConsole::IResult *pResult, void *pUserData);
@@ -354,6 +358,12 @@ public:
void ServerBrowserUpdate();
+ // gfx
+ void SwitchWindowScreen(int Index);
+ void ToggleFullscreen();
+ void ToggleWindowBordered();
+ void ToggleWindowVSync();
+
// DDRace
virtual const char* GetCurrentMap();
diff --git a/src/engine/client/graphics_threaded.cpp b/src/engine/client/graphics_threaded.cpp
index 245277166..fa7cde496 100644
--- a/src/engine/client/graphics_threaded.cpp
+++ b/src/engine/client/graphics_threaded.cpp
@@ -782,18 +782,13 @@ void CGraphics_Threaded::QuadsText(float x, float y, float Size, const char *pTe
int CGraphics_Threaded::IssueInit()
{
int Flags = 0;
- if(g_Config.m_GfxBorderless && g_Config.m_GfxFullscreen)
- {
- dbg_msg("gfx", "both borderless and fullscreen activated, disabling borderless");
- g_Config.m_GfxBorderless = 0;
- }
if(g_Config.m_GfxBorderless) Flags |= IGraphicsBackend::INITFLAG_BORDERLESS;
- else if(g_Config.m_GfxFullscreen) Flags |= IGraphicsBackend::INITFLAG_FULLSCREEN;
+ if(g_Config.m_GfxFullscreen) Flags |= IGraphicsBackend::INITFLAG_FULLSCREEN;
if(g_Config.m_GfxVsync) Flags |= IGraphicsBackend::INITFLAG_VSYNC;
if(g_Config.m_DbgResizable) Flags |= IGraphicsBackend::INITFLAG_RESIZABLE;
- return m_pBackend->Init("DDNet Client", g_Config.m_GfxScreen, &g_Config.m_GfxScreenWidth, &g_Config.m_GfxScreenHeight, g_Config.m_GfxFsaaSamples, Flags, &m_DesktopScreenWidth, &m_DesktopScreenHeight);
+ return m_pBackend->Init("DDNet Client", &g_Config.m_GfxScreen, &g_Config.m_GfxScreenWidth, &g_Config.m_GfxScreenHeight, g_Config.m_GfxFsaaSamples, Flags, &m_DesktopScreenWidth, &m_DesktopScreenHeight);
}
int CGraphics_Threaded::InitWindow()
@@ -884,6 +879,11 @@ void CGraphics_Threaded::Shutdown()
delete m_apCommandBuffers[i];
}
+int CGraphics_Threaded::GetNumScreens() const
+{
+ return m_pBackend->GetNumScreens();
+}
+
void CGraphics_Threaded::Minimize()
{
m_pBackend->Minimize();
@@ -900,6 +900,21 @@ bool CGraphics_Threaded::Fullscreen(bool State)
return m_pBackend->Fullscreen(State);
}
+void CGraphics_Threaded::SetWindowBordered(bool State)
+{
+ m_pBackend->SetWindowBordered(State);
+}
+
+bool CGraphics_Threaded::SetWindowScreen(int Index)
+{
+ return m_pBackend->SetWindowScreen(Index);
+}
+
+int CGraphics_Threaded::GetWindowScreen()
+{
+ return m_pBackend->GetWindowScreen();
+}
+
int CGraphics_Threaded::WindowActive()
{
return m_pBackend->WindowActive();
@@ -954,6 +969,21 @@ void CGraphics_Threaded::Swap()
KickCommandBuffer();
}
+bool CGraphics_Threaded::SetVSync(bool State)
+{
+ // add vsnc command
+ bool RetOk = 0;
+ CCommandBuffer::SCommand_VSync Cmd;
+ Cmd.m_VSync = State ? 1 : 0;
+ Cmd.m_pRetOk = &RetOk;
+ m_pCommandBuffer->AddCommand(Cmd);
+
+ // kick the command buffer
+ KickCommandBuffer();
+ WaitForIdle();
+ return RetOk;
+}
+
// syncronization
void CGraphics_Threaded::InsertSignal(semaphore *pSemaphore)
{
@@ -988,10 +1018,11 @@ int CGraphics_Threaded::GetVideoModes(CVideoMode *pModes, int MaxModes, int Scre
mem_zero(&Image, sizeof(Image));
int NumModes = 0;
- CCommandBuffer::SCommand_VideoModes Cmd(Screen);
+ CCommandBuffer::SCommand_VideoModes Cmd;
Cmd.m_pModes = pModes;
Cmd.m_MaxModes = MaxModes;
Cmd.m_pNumModes = &NumModes;
+ Cmd.m_Screen = Screen;
m_pCommandBuffer->AddCommand(Cmd);
// kick the buffer and wait for the result and return it
diff --git a/src/engine/client/graphics_threaded.h b/src/engine/client/graphics_threaded.h
index 5c94e92b1..a4cf47879 100644
--- a/src/engine/client/graphics_threaded.h
+++ b/src/engine/client/graphics_threaded.h
@@ -82,6 +82,7 @@ public:
CMD_SWAP,
// misc
+ CMD_VSYNC,
CMD_SCREENSHOT,
CMD_VIDEOMODES,
@@ -191,7 +192,7 @@ public:
struct SCommand_VideoModes : public SCommand
{
- SCommand_VideoModes(int screen) : SCommand(CMD_VIDEOMODES), m_Screen(screen) {}
+ SCommand_VideoModes() : SCommand(CMD_VIDEOMODES) {}
CVideoMode *m_pModes; // processor will fill this in
int m_MaxModes; // maximum of modes the processor can write to the m_pModes
@@ -206,6 +207,14 @@ public:
int m_Finish;
};
+ struct SCommand_VSync : public SCommand
+ {
+ SCommand_VSync() : SCommand(CMD_VSYNC) {}
+
+ int m_VSync;
+ bool *m_pRetOk;
+ };
+
struct SCommand_Texture_Create : public SCommand
{
SCommand_Texture_Create() : SCommand(CMD_TEXTURE_CREATE) {}
@@ -304,14 +313,19 @@ public:
virtual ~IGraphicsBackend() {}
- virtual int Init(const char *pName, int Screen, int *pWidth, int *pHeight, int FsaaSamples, int Flags, int *pDesktopWidth, int *pDesktopHeight) = 0;
+ virtual int Init(const char *pName, int *Screen, int *pWidth, int *pHeight, int FsaaSamples, int Flags, int *pDesktopWidth, int *pDesktopHeight) = 0;
virtual int Shutdown() = 0;
virtual int MemoryUsage() const = 0;
+ virtual int GetNumScreens() const = 0;
+
virtual void Minimize() = 0;
virtual void Maximize() = 0;
virtual bool Fullscreen(bool State) = 0;
+ virtual void SetWindowBordered(bool State) = 0;
+ virtual bool SetWindowScreen(int Index) = 0;
+ virtual int GetWindowScreen() = 0;
virtual int WindowActive() = 0;
virtual int WindowOpen() = 0;
virtual void SetWindowGrab(bool Grab) = 0;
@@ -426,9 +440,13 @@ public:
virtual void QuadsDrawFreeform(const CFreeformItem *pArray, int Num);
virtual void QuadsText(float x, float y, float Size, const char *pText);
+ virtual int GetNumScreens() const;
virtual void Minimize();
virtual void Maximize();
virtual bool Fullscreen(bool State);
+ virtual void SetWindowBordered(bool State);
+ virtual bool SetWindowScreen(int Index);
+ virtual int GetWindowScreen();
virtual int WindowActive();
virtual int WindowOpen();
@@ -442,6 +460,7 @@ public:
virtual void TakeScreenshot(const char *pFilename);
virtual void TakeCustomScreenshot(const char *pFilename);
virtual void Swap();
+ virtual bool SetVSync(bool State);
virtual int GetVideoModes(CVideoMode *pModes, int MaxModes, int Screen);
diff --git a/src/engine/client/input.cpp b/src/engine/client/input.cpp
index d6b73fa83..0f5bfcb48 100644
--- a/src/engine/client/input.cpp
+++ b/src/engine/client/input.cpp
@@ -227,6 +227,16 @@ int CInput::Update()
Action = IInput::FLAG_RELEASE;
break;
+#if defined(CONF_PLATFORM_MACOSX) // Todo: remove this when fixed in SDL
+ case SDL_WINDOWEVENT:
+ if(Event.window.event == SDL_WINDOWEVENT_MAXIMIZED)
+ {
+ MouseModeAbsolute();
+ MouseModeRelative();
+ }
+ break;
+#endif
+
// other messages
case SDL_QUIT:
return 1;
diff --git a/src/engine/graphics.h b/src/engine/graphics.h
index 085f56f86..016919409 100644
--- a/src/engine/graphics.h
+++ b/src/engine/graphics.h
@@ -67,6 +67,10 @@ public:
float ScreenAspect() const { return (float)ScreenWidth()/(float)ScreenHeight(); }
virtual bool Fullscreen(bool State) = 0;
+ virtual void SetWindowBordered(bool State) = 0;
+ virtual bool SetWindowScreen(int Index) = 0;
+ virtual bool SetVSync(bool State) = 0;
+ virtual int GetWindowScreen() = 0;
virtual void Clear(float r, float g, float b) = 0;
@@ -141,6 +145,7 @@ public:
virtual int GetVideoModes(CVideoMode *pModes, int MaxModes, int Screen) = 0;
virtual void Swap() = 0;
+ virtual int GetNumScreens() const = 0;
// syncronization
virtual void InsertSignal(class semaphore *pSemaphore) = 0;
diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp
index 1defaa477..9eaf52151 100644
--- a/src/game/client/components/menus_settings.cpp
+++ b/src/game/client/components/menus_settings.cpp
@@ -801,7 +801,6 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView)
static int s_GfxScreenWidth = g_Config.m_GfxScreenWidth;
static int s_GfxScreenHeight = g_Config.m_GfxScreenHeight;
static int s_GfxColorDepth = g_Config.m_GfxColorDepth;
- static int s_GfxBorderless = g_Config.m_GfxBorderless;
static int s_GfxVsync = g_Config.m_GfxVsync;
static int s_GfxFsaaSamples = g_Config.m_GfxFsaaSamples;
static int s_GfxTextureQuality = g_Config.m_GfxTextureQuality;
@@ -858,41 +857,50 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView)
MainView.HSplitTop(20.0f, &Button, &MainView);
if(DoButton_CheckBox(&g_Config.m_GfxBorderless, Localize("Borderless window"), g_Config.m_GfxBorderless, &Button))
{
- g_Config.m_GfxBorderless ^= 1;
- if(g_Config.m_GfxBorderless && g_Config.m_GfxFullscreen)
- g_Config.m_GfxFullscreen = 0;
- CheckSettings = true;
+ Client()->ToggleWindowBordered();
}
MainView.HSplitTop(20.0f, &Button, &MainView);
if(DoButton_CheckBox(&g_Config.m_GfxFullscreen, Localize("Fullscreen"), g_Config.m_GfxFullscreen, &Button))
{
- if(Graphics()->Fullscreen(g_Config.m_GfxFullscreen^1))
- { g_Config.m_GfxFullscreen ^= 1;
- if(g_Config.m_GfxFullscreen && g_Config.m_GfxBorderless)
- g_Config.m_GfxBorderless = 0;
- }
+ Client()->ToggleFullscreen();
}
MainView.HSplitTop(20.0f, &Button, &MainView);
if(DoButton_CheckBox(&g_Config.m_GfxVsync, Localize("V-Sync"), g_Config.m_GfxVsync, &Button))
{
- g_Config.m_GfxVsync ^= 1;
- CheckSettings = true;
+ Client()->ToggleWindowVSync();
+ }
+
+ if(Graphics()->GetNumScreens() > 1)
+ {
+ int NumScreens = Graphics()->GetNumScreens();
+ MainView.HSplitTop(20.0f, &Button, &MainView);
+ int Screen_MouseButton = DoButton_CheckBox_Number(&g_Config.m_GfxScreen, Localize("Screen"), g_Config.m_GfxScreen, &Button);
+ if(Screen_MouseButton == 1) //inc
+ {
+ Client()->SwitchWindowScreen((g_Config.m_GfxScreen+1)%NumScreens);
+ s_NumNodes = Graphics()->GetVideoModes(s_aModes, MAX_RESOLUTIONS, g_Config.m_GfxScreen);
+ }
+ else if(Screen_MouseButton == 2) //dec
+ {
+ Client()->SwitchWindowScreen((g_Config.m_GfxScreen-1+NumScreens)%NumScreens);
+ s_NumNodes = Graphics()->GetVideoModes(s_aModes, MAX_RESOLUTIONS, g_Config.m_GfxScreen);
+ }
}
MainView.HSplitTop(20.0f, &Button, &MainView);
int GfxFsaaSamples_MouseButton = DoButton_CheckBox_Number(&g_Config.m_GfxFsaaSamples, Localize("FSAA samples"), g_Config.m_GfxFsaaSamples, &Button);
- if( GfxFsaaSamples_MouseButton == 1) //inc
+ if(GfxFsaaSamples_MouseButton == 1) //inc
{
g_Config.m_GfxFsaaSamples = (g_Config.m_GfxFsaaSamples+1)%17;
CheckSettings = true;
}
else if(GfxFsaaSamples_MouseButton == 2) //dec
- {
- g_Config.m_GfxFsaaSamples = (g_Config.m_GfxFsaaSamples-1 +17)%17;
- CheckSettings = true;
- }
+ {
+ g_Config.m_GfxFsaaSamples = (g_Config.m_GfxFsaaSamples-1 +17)%17;
+ CheckSettings = true;
+ }
MainView.HSplitTop(20.0f, &Button, &MainView);
if(DoButton_CheckBox(&g_Config.m_GfxTextureQuality, Localize("Quality Textures"), g_Config.m_GfxTextureQuality, &Button))
@@ -918,7 +926,6 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView)
if(s_GfxScreenWidth == g_Config.m_GfxScreenWidth &&
s_GfxScreenHeight == g_Config.m_GfxScreenHeight &&
s_GfxColorDepth == g_Config.m_GfxColorDepth &&
- s_GfxBorderless == g_Config.m_GfxBorderless &&
s_GfxVsync == g_Config.m_GfxVsync &&
s_GfxFsaaSamples == g_Config.m_GfxFsaaSamples &&
s_GfxTextureQuality == g_Config.m_GfxTextureQuality &&