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 &&