From 19effdad2c77491d1bcf0052e0f4177a1bf6227a Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Wed, 2 Jan 2013 21:20:31 +0100 Subject: [PATCH 1/7] fix zlib include path in zip.h --- neo/libs/zlib/minizip/zip.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/neo/libs/zlib/minizip/zip.h b/neo/libs/zlib/minizip/zip.h index 477fe89b..925d0d96 100644 --- a/neo/libs/zlib/minizip/zip.h +++ b/neo/libs/zlib/minizip/zip.h @@ -47,7 +47,7 @@ extern "C" { //#define HAVE_BZIP2 #ifndef _ZLIB_H -#include "../../libs/zlib/zlib.h" +#include "../zlib.h" #endif #ifndef _ZLIBIOAPI_H From d6c32cd49bc76c3fb280568daf9b2be36f66ab72 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Thu, 3 Jan 2013 05:50:51 +0100 Subject: [PATCH 2/7] Support resizing windows + improve fullscreen for SDL2 By implementing GLimp_SetScreenParms() and enhancing the event handling --- neo/renderer/RenderSystem_init.cpp | 6 + neo/sys/sdl/sdl_events.cpp | 45 +++++++- neo/sys/sdl/sdl_glimp.cpp | 174 ++++++++++++++++++++++++++++- 3 files changed, 218 insertions(+), 7 deletions(-) diff --git a/neo/renderer/RenderSystem_init.cpp b/neo/renderer/RenderSystem_init.cpp index c10b83e1..66dfcefc 100644 --- a/neo/renderer/RenderSystem_init.cpp +++ b/neo/renderer/RenderSystem_init.cpp @@ -53,7 +53,13 @@ idCVar r_skipIntelWorkarounds( "r_skipIntelWorkarounds", "0", CVAR_RENDERER | CV idCVar r_multiSamples( "r_multiSamples", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "number of antialiasing samples" ); idCVar r_vidMode( "r_vidMode", "0", CVAR_ARCHIVE | CVAR_RENDERER | CVAR_INTEGER, "fullscreen video mode number" ); idCVar r_displayRefresh( "r_displayRefresh", "0", CVAR_RENDERER | CVAR_INTEGER | CVAR_NOCHEAT, "optional display refresh rate option for vid mode", 0.0f, 240.0f ); +#ifdef WIN32 idCVar r_fullscreen( "r_fullscreen", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "0 = windowed, 1 = full screen on monitor 1, 2 = full screen on monitor 2, etc" ); +#else +// DG: add mode -2 for SDL, also defaulting to windowed mode, as that causes less trouble on linux +idCVar r_fullscreen( "r_fullscreen", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "-2 = use current monitor, -1 = (reserved), 0 = windowed, 1 = full screen on monitor 1, 2 = full screen on monitor 2, etc" ); +// DG end +#endif idCVar r_customWidth( "r_customWidth", "1280", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "custom screen width. set r_vidMode to -1 to activate" ); idCVar r_customHeight( "r_customHeight", "720", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "custom screen height. set r_vidMode to -1 to activate" ); idCVar r_windowX( "r_windowX", "0", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "Non-fullscreen parameter" ); diff --git a/neo/sys/sdl/sdl_events.cpp b/neo/sys/sdl/sdl_events.cpp index 7fd4c890..b7988c6a 100644 --- a/neo/sys/sdl/sdl_events.cpp +++ b/neo/sys/sdl/sdl_events.cpp @@ -5,6 +5,7 @@ Doom 3 GPL Source Code Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. Copyright (C) 2012 dhewg (dhewm3) Copyright (C) 2012 Robert Beckebans +Copyright (C) 2013 Daniel Gibson This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code"). @@ -28,9 +29,10 @@ If you have questions concerning this license or the applicable additional terms =========================================================================== */ +#include "../../idlib/precompiled.h" + #include -#include "../../idlib/precompiled.h" #include "renderer/tr_local.h" #include "sdl_local.h" #include "../posix/posix_public.h" @@ -58,6 +60,13 @@ If you have questions concerning this license or the applicable additional terms // DG end #endif +// DG: those are needed for moving/resizing windows +extern idCVar r_windowX; +extern idCVar r_windowY; +extern idCVar r_windowWidth; +extern idCVar r_windowHeight; +// DG end + const char* kbdNames[] = { "english", "french", "german", "italian", "spanish", "turkish", "norwegian", NULL @@ -742,7 +751,28 @@ sysEvent_t Sys_GetEvent() GLimp_GrabInput( 0 ); break; - // TODO: SDL_WINDOWEVENT_RESIZED + // DG: handle resizing and moving of window + case SDL_WINDOWEVENT_RESIZED: + { + int w = ev.window.data1; + int h = ev.window.data2; + r_windowWidth.SetInteger( w ); + r_windowHeight.SetInteger( h ); + + glConfig.nativeScreenWidth = w; + glConfig.nativeScreenHeight = h; + break; + } + + case SDL_WINDOWEVENT_MOVED: + { + int x = ev.window.data1; + int y = ev.window.data2; + r_windowX.SetInteger( x ); + r_windowY.SetInteger( y ); + break; + } + // DG end } return res_none; @@ -777,7 +807,16 @@ sysEvent_t Sys_GetEvent() case SDL_KEYDOWN: if( ev.key.keysym.sym == SDLK_RETURN && ( ev.key.keysym.mod & KMOD_ALT ) > 0 ) { - cvarSystem->SetCVarBool( "r_fullscreen", !renderSystem->IsFullScreen() ); + // DG: go to fullscreen on current display, instead of always first display + int fullscreen = 0; + if( ! renderSystem->IsFullScreen() ) + { + // this will be handled as "fullscreen on current window" + // r_fullscreen 1 means "fullscreen on first window" in d3 bfg + fullscreen = -2; + } + cvarSystem->SetCVarInteger( "r_fullscreen", fullscreen ); + // DG end PushConsoleEvent( "vid_restart" ); return res_none; } diff --git a/neo/sys/sdl/sdl_glimp.cpp b/neo/sys/sdl/sdl_glimp.cpp index 556112c0..fc1022d2 100644 --- a/neo/sys/sdl/sdl_glimp.cpp +++ b/neo/sys/sdl/sdl_glimp.cpp @@ -5,6 +5,7 @@ Doom 3 GPL Source Code Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. Copyright (C) 2012 dhewg (dhewm3) Copyright (C) 2012 Robert Beckebans +Copyright (C) 2013 Daniel Gibson This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code"). @@ -89,7 +90,9 @@ bool GLimp_Init( glimpParms_t parms ) GLimp_PreInit(); // DG: make sure SDL is initialized - Uint32 flags = SDL_WINDOW_OPENGL; + // DG: make window resizable + Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; + // DG end if( parms.fullScreen ) flags |= SDL_WINDOW_FULLSCREEN; @@ -198,10 +201,34 @@ bool GLimp_Init( glimpParms_t parms ) } // RB end + // DG: set display num for fullscreen + int windowPos = SDL_WINDOWPOS_UNDEFINED; + if( parms.fullScreen > 0 ) + { + if( parms.fullScreen > SDL_GetNumVideoDisplays() ) + { + common->Warning( "Couldn't set display to num %i because we only have %i displays", + parms.fullScreen, SDL_GetNumVideoDisplays() ); + } + else + { + // -1 because SDL starts counting displays at 0, while parms.fullScreen starts at 1 + windowPos = SDL_WINDOWPOS_UNDEFINED_DISPLAY( ( parms.fullScreen - 1 ) ); + } + } + // TODO: if parms.fullScreen == -1 there should be a borderless window spanning multiple displays + /* + * NOTE that this implicitly handles parms.fullScreen == -2 (from r_fullscreen -2) meaning + * "do fullscreen, but I don't care on what monitor", at least on my box it's the monitor with + * the mouse cursor. + */ + + window = SDL_CreateWindow( GAME_NAME, - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, + windowPos, + windowPos, parms.width, parms.height, flags ); + // DG end context = SDL_GL_CreateContext( window ); if( !window ) @@ -273,6 +300,113 @@ bool GLimp_Init( glimpParms_t parms ) return true; } +/* +=================== + Helper functions for GLimp_SetScreenParms() +=================== +*/ + +#if SDL_VERSION_ATLEAST(2, 0, 0) +// SDL1 doesn't support multiple displays +// makes sure the window will be full-screened on the right display and returns the SDL display index +static int ScreenParmsHandleDisplayIndex( glimpParms_t parms ) +{ + int displayIdx; + if( parms.fullScreen > 0 ) + { + displayIdx = parms.fullScreen - 1; // first display for SDL is 0, in parms it's 1 + } + else // -2 == use current display + { + displayIdx = SDL_GetWindowDisplay( window ); + if( displayIdx < 0 ) // for some reason the display for the window couldn't be detected + displayIdx = 0; + } + + if( parms.fullScreen > SDL_GetNumVideoDisplays() ) + { + common->Warning( "Can't set fullscreen mode to display number %i, because SDL2 only knows about %i displays!", + parms.fullScreen, SDL_GetNumVideoDisplays() ); + return -1; + } + + if( parms.fullScreen != glConfig.isFullscreen ) + { + // we have to switch to another display + if( glConfig.isFullscreen ) + { + // if we're already in fullscreen mode but want to switch to another monitor + // we have to go to windowed mode first to move the window.. SDL-oddity. + SDL_SetWindowFullscreen( window, SDL_FALSE ); + } + // select display ; SDL_WINDOWPOS_UNDEFINED_DISPLAY() doesn't work. + int x = SDL_WINDOWPOS_CENTERED_DISPLAY( displayIdx ); + // move window to the center of selected display + SDL_SetWindowPosition( window, x, x ); + } + return displayIdx; +} +#endif // SDL_VERSION_ATLEAST(2, 0, 0) + +static bool SetScreenParmsFullscreen( glimpParms_t parms ) +{ +#if SDL_VERSION_ATLEAST(2, 0, 0) + SDL_DisplayMode m = {0}; + int displayIdx = ScreenParmsHandleDisplayIndex( parms ); + if( displayIdx < 0 ) + return false; + + // get current mode of display the window should be full-screened on + SDL_GetCurrentDisplayMode( displayIdx, &m ); + + // change settings in that display mode according to parms + // FIXME: check if refreshrate, width and height are supported? + // m.refresh_rate = parms.displayHz; + m.w = parms.width; + m.h = parms.height; + + // set that displaymode + if( SDL_SetWindowDisplayMode( window, &m ) < 0 ) + { + common->Warning( "Couldn't set window mode for fullscreen, reason: %s", SDL_GetError() ); + return false; + } + + // if we're currently not in fullscreen mode, we need to switch to fullscreen + if( !( SDL_GetWindowFlags( window ) & SDL_WINDOW_FULLSCREEN ) ) + { + if( SDL_SetWindowFullscreen( window, SDL_TRUE ) < 0 ) + { + common->Warning( "Couldn't switch to fullscreen mode, reason: %s!", SDL_GetError() ); + return false; + } + } +#else // ! SDL_VERSION_ATLEAST(2, 0, 0) => SDL1.2 + // TODO: SDL1.2 fullscreen handling +#endif // SDL_VERSION_ATLEAST(2, 0, 0) + return true; +} + +static bool SetScreenParmsWindowed( glimpParms_t parms ) +{ +#if SDL_VERSION_ATLEAST(2, 0, 0) + SDL_SetWindowSize( window, parms.width, parms.height ); + SDL_SetWindowPosition( window, parms.x, parms.y ); + + // if we're currently in fullscreen mode, we need to disable that + if( SDL_GetWindowFlags( window ) & SDL_WINDOW_FULLSCREEN ) + { + if( SDL_SetWindowFullscreen( window, SDL_FALSE ) < 0 ) + { + common->Warning( "Couldn't switch to windowed mode, reason: %s!", SDL_GetError() ); + return false; + } + } +#else // SDL 1.2 + // TODO: SDL1.2 windowed handling +#endif + return true; +} /* =================== @@ -281,7 +415,39 @@ GLimp_SetScreenParms */ bool GLimp_SetScreenParms( glimpParms_t parms ) { - common->DPrintf( "TODO: GLimp_SetScreenParms\n" ); +#if SDL_VERSION_ATLEAST(2, 0, 0) + if( parms.fullScreen > 0 || parms.fullScreen == -2 ) + { + if( !SetScreenParmsFullscreen( parms ) ) + return false; + } + else if( parms.fullScreen == 0 ) // windowed mode + { + if( !SetScreenParmsWindowed( parms ) ) + return false; + } + else + { + common->Warning( "GLimp_SetScreenParms: fullScreen -1 (borderless window for multiple displays) currently unsupported!" ); + return false; + } + + // Note: the following stuff would also work with SDL1.2 + SDL_GL_SetAttribute( SDL_GL_STEREO, parms.stereo ? 1 : 0 ); + + SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, parms.multiSamples ? 1 : 0 ); + SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, parms.multiSamples ); + + glConfig.isFullscreen = parms.fullScreen; + glConfig.isStereoPixelFormat = parms.stereo; + glConfig.nativeScreenWidth = parms.width; + glConfig.nativeScreenHeight = parms.height; + glConfig.displayFrequency = parms.displayHz; + glConfig.multisamples = parms.multiSamples; +#else // SDL 1.2 + common->Printf( "TODO: Implement GLimp_SetScreenParms() for SDL1.2\n" ); +#endif + return true; } From a1c1f1b6b20b5fe6eb9605c3cf1e9d30750f4bc9 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Thu, 3 Jan 2013 08:15:09 +0100 Subject: [PATCH 3/7] Support resizing windows for SDL1.2 By implementing GLimp_SetScreenParms() for SDL1.2 and enhancing the event handling --- neo/sys/sdl/sdl_events.cpp | 18 +++++++++++++++- neo/sys/sdl/sdl_glimp.cpp | 43 ++++++++++++++++++++++++++------------ 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/neo/sys/sdl/sdl_events.cpp b/neo/sys/sdl/sdl_events.cpp index b7988c6a..251830d8 100644 --- a/neo/sys/sdl/sdl_events.cpp +++ b/neo/sys/sdl/sdl_events.cpp @@ -802,8 +802,24 @@ sysEvent_t Sys_GetEvent() case SDL_VIDEOEXPOSE: return res_none; -#endif + // DG: handle resizing and moving of window + case SDL_VIDEORESIZE: + { + int w = ev.resize.w; + int h = ev.resize.h; + r_windowWidth.SetInteger( w ); + r_windowHeight.SetInteger( h ); + + glConfig.nativeScreenWidth = w; + glConfig.nativeScreenHeight = h; + // for some reason this needs a vid_restart in SDL1 but not SDL2 so GLimp_SetScreenParms() is called + PushConsoleEvent( "vid_restart" ); + return res_none; + } + // DG end +#endif + case SDL_KEYDOWN: if( ev.key.keysym.sym == SDLK_RETURN && ( ev.key.keysym.mod & KMOD_ALT ) > 0 ) { diff --git a/neo/sys/sdl/sdl_glimp.cpp b/neo/sys/sdl/sdl_glimp.cpp index fc1022d2..fee6c78f 100644 --- a/neo/sys/sdl/sdl_glimp.cpp +++ b/neo/sys/sdl/sdl_glimp.cpp @@ -55,6 +55,7 @@ static SDL_GLContext context = NULL; static SDL_Surface* window = NULL; #define SDL_WINDOW_OPENGL SDL_OPENGL #define SDL_WINDOW_FULLSCREEN SDL_FULLSCREEN +#define SDL_WINDOW_RESIZABLE SDL_RESIZABLE #endif bool QGL_Init( const char* dllname ); @@ -307,7 +308,7 @@ bool GLimp_Init( glimpParms_t parms ) */ #if SDL_VERSION_ATLEAST(2, 0, 0) -// SDL1 doesn't support multiple displays +// SDL1 doesn't support multiple displays, so the source is much shorter and doesn't need seperate functions // makes sure the window will be full-screened on the right display and returns the SDL display index static int ScreenParmsHandleDisplayIndex( glimpParms_t parms ) { @@ -346,11 +347,9 @@ static int ScreenParmsHandleDisplayIndex( glimpParms_t parms ) } return displayIdx; } -#endif // SDL_VERSION_ATLEAST(2, 0, 0) static bool SetScreenParmsFullscreen( glimpParms_t parms ) { -#if SDL_VERSION_ATLEAST(2, 0, 0) SDL_DisplayMode m = {0}; int displayIdx = ScreenParmsHandleDisplayIndex( parms ); if( displayIdx < 0 ) @@ -381,15 +380,11 @@ static bool SetScreenParmsFullscreen( glimpParms_t parms ) return false; } } -#else // ! SDL_VERSION_ATLEAST(2, 0, 0) => SDL1.2 - // TODO: SDL1.2 fullscreen handling -#endif // SDL_VERSION_ATLEAST(2, 0, 0) return true; } static bool SetScreenParmsWindowed( glimpParms_t parms ) { -#if SDL_VERSION_ATLEAST(2, 0, 0) SDL_SetWindowSize( window, parms.width, parms.height ); SDL_SetWindowPosition( window, parms.x, parms.y ); @@ -402,11 +397,9 @@ static bool SetScreenParmsWindowed( glimpParms_t parms ) return false; } } -#else // SDL 1.2 - // TODO: SDL1.2 windowed handling -#endif return true; } +#endif // SDL_VERSION_ATLEAST(2, 0, 0) /* =================== @@ -431,6 +424,33 @@ bool GLimp_SetScreenParms( glimpParms_t parms ) common->Warning( "GLimp_SetScreenParms: fullScreen -1 (borderless window for multiple displays) currently unsupported!" ); return false; } +#else // SDL 1.2 - so much shorter, but doesn't handle multiple displays + SDL_Surface* s = SDL_GetVideoSurface(); + if( s == NULL ) + { + common->Warning( "GLimp_SetScreenParms: Couldn't get video information, reason: %s", SDL_GetError() ); + return false; + } + + + int bitsperpixel = 24; + if( s->format ) + bitsperpixel = s->format->BitsPerPixel; + + Uint32 flags = s->flags; + + if( parms.fullScreen ) + flags |= SDL_FULLSCREEN; + else + flags &= ~SDL_FULLSCREEN; + + s = SDL_SetVideoMode( parms.width, parms.height, bitsperpixel, flags ); + if( s == NULL ) + { + common->Warning( "GLimp_SetScreenParms: Couldn't set video information, reason: %s", SDL_GetError() ); + return false; + } +#endif // SDL_VERSION_ATLEAST(2, 0, 0) // Note: the following stuff would also work with SDL1.2 SDL_GL_SetAttribute( SDL_GL_STEREO, parms.stereo ? 1 : 0 ); @@ -444,9 +464,6 @@ bool GLimp_SetScreenParms( glimpParms_t parms ) glConfig.nativeScreenHeight = parms.height; glConfig.displayFrequency = parms.displayHz; glConfig.multisamples = parms.multiSamples; -#else // SDL 1.2 - common->Printf( "TODO: Implement GLimp_SetScreenParms() for SDL1.2\n" ); -#endif return true; } From 732d8987d3ebaa72628f2383210ccb18bdc8b1ad Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Thu, 3 Jan 2013 09:28:52 +0100 Subject: [PATCH 4/7] support ctrl-g for (un)grabbing mouse Many Linux Games support that --- neo/sys/sdl/sdl_events.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/neo/sys/sdl/sdl_events.cpp b/neo/sys/sdl/sdl_events.cpp index 251830d8..dd0a4bbc 100644 --- a/neo/sys/sdl/sdl_events.cpp +++ b/neo/sys/sdl/sdl_events.cpp @@ -837,6 +837,16 @@ sysEvent_t Sys_GetEvent() return res_none; } + // DG: ctrl-g to un-grab mouse - yeah, left ctrl shoots, then just use right ctrl :) + if( ev.key.keysym.sym == SDLK_g && ( ev.key.keysym.mod & KMOD_CTRL ) > 0 ) + { + bool grab = cvarSystem->GetCVarBool( "in_nograb" ); + grab = !grab; + cvarSystem->SetCVarBool( "in_nograb", grab ); + return res_none; + } + // DG end + // fall through case SDL_KEYUP: { From a405b37f13907a06f1e7b96fa562ab860092c081 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Thu, 3 Jan 2013 12:39:16 +0100 Subject: [PATCH 5/7] Pause when window loses focus, introduce com_pause If the window loses focus com_pause is set to 1, when it regains focus it's set to 0. The behaviour on Win32 stayed the same (the implementation is less hacky though) and Linux now matchces that. --- neo/framework/Common.cpp | 4 ++++ neo/framework/common_frame.cpp | 22 +++++++++++++++++----- neo/sys/posix/posix_session_local.cpp | 5 ++--- neo/sys/sdl/sdl_events.cpp | 18 ++++++++++++------ neo/sys/win32/win_session_local.cpp | 4 +++- neo/sys/win32/win_wndproc.cpp | 4 ++++ 6 files changed, 42 insertions(+), 15 deletions(-) diff --git a/neo/framework/Common.cpp b/neo/framework/Common.cpp index 62bfabb4..21ab1960 100644 --- a/neo/framework/Common.cpp +++ b/neo/framework/Common.cpp @@ -86,6 +86,10 @@ idCVar preload_CommonAssets( "preload_CommonAssets", "1", CVAR_SYSTEM | CVAR_BOO idCVar net_inviteOnly( "net_inviteOnly", "1", CVAR_BOOL | CVAR_ARCHIVE, "whether or not the private server you create allows friends to join or invite only" ); +// DG: add cvar for pause +idCVar com_pause( "com_pause", "0", CVAR_BOOL | CVAR_SYSTEM , "set to 1 to pause game, to 0 to unpause again" ); +// DG end + extern idCVar g_demoMode; idCVar com_engineHz( "com_engineHz", "60", CVAR_FLOAT | CVAR_ARCHIVE, "Frames per second the engine runs at", 10.0f, 1024.0f ); diff --git a/neo/framework/common_frame.cpp b/neo/framework/common_frame.cpp index a1968f50..a63f0053 100644 --- a/neo/framework/common_frame.cpp +++ b/neo/framework/common_frame.cpp @@ -438,6 +438,8 @@ void idCommonLocal::ProcessGameReturn( const gameReturn_t& ret ) extern idCVar com_forceGenericSIMD; +extern idCVar com_pause; + /* ================= idCommonLocal::Frame @@ -485,13 +487,16 @@ void idCommonLocal::Frame() // if the console or another gui is down, we don't need to hold the mouse cursor bool chatting = false; + // DG: Add pause from com_pause cvar // RB begin #if defined(USE_DOOMCLASSIC) - if( console->Active() || Dialog().IsDialogActive() || session->IsSystemUIShowing() || ( game && game->InhibitControls() && !IsPlayingDoomClassic() ) ) + if( console->Active() || Dialog().IsDialogActive() || session->IsSystemUIShowing() + || ( game && game->InhibitControls() && !IsPlayingDoomClassic() ) ) #else - if( console->Active() || Dialog().IsDialogActive() || session->IsSystemUIShowing() || ( game && game->InhibitControls() ) ) + if( com_pause.GetInteger() || console->Active() || Dialog().IsDialogActive() || session->IsSystemUIShowing() + || ( game && game->InhibitControls() ) ) #endif - // RB end + // RB end, DG end { Sys_GrabMouseCursor( false ); usercmdGen->InhibitUsercmd( INHIBIT_SESSION, true ); @@ -505,9 +510,16 @@ void idCommonLocal::Frame() // RB begin #if defined(USE_DOOMCLASSIC) - const bool pauseGame = ( !mapSpawned || ( !IsMultiplayer() && ( Dialog().IsDialogPausing() || session->IsSystemUIShowing() || ( game && game->Shell_IsActive() ) ) ) ) && !IsPlayingDoomClassic(); + const bool pauseGame = ( !mapSpawned + || ( !IsMultiplayer() + && ( Dialog().IsDialogPausing() || session->IsSystemUIShowing() + || ( game && game->Shell_IsActive() ) || com_pause.GetInteger() ) ) ) + && !IsPlayingDoomClassic(); #else - const bool pauseGame = ( !mapSpawned || ( !IsMultiplayer() && ( Dialog().IsDialogPausing() || session->IsSystemUIShowing() || ( game && game->Shell_IsActive() ) ) ) ); + const bool pauseGame = ( !mapSpawned + || ( !IsMultiplayer() + && ( Dialog().IsDialogPausing() || session->IsSystemUIShowing() + || ( game && game->Shell_IsActive() ) || com_pause.GetInteger() ) ) ); #endif // RB end diff --git a/neo/sys/posix/posix_session_local.cpp b/neo/sys/posix/posix_session_local.cpp index 404f4670..cca9802e 100644 --- a/neo/sys/posix/posix_session_local.cpp +++ b/neo/sys/posix/posix_session_local.cpp @@ -456,10 +456,9 @@ idSessionLocalWin::IsSystemUIShowing */ bool idSessionLocalWin::IsSystemUIShowing() const { - // RB: TODO track SDL_ACTIVEENT + // DG: pausing here when window is out of focus like originally done on windows is hacky + // it's done with com_pause now. return isSysUIShowing; - - //return !win32.activeApp || isSysUIShowing; // If the user alt+tabs away, treat it the same as bringing up the steam overlay } /* diff --git a/neo/sys/sdl/sdl_events.cpp b/neo/sys/sdl/sdl_events.cpp index dd0a4bbc..e0e4ca21 100644 --- a/neo/sys/sdl/sdl_events.cpp +++ b/neo/sys/sdl/sdl_events.cpp @@ -741,14 +741,18 @@ sysEvent_t Sys_GetEvent() newmod |= KMOD_CAPS; SDL_SetModState( ( SDL_Keymod )newmod ); - // DG: disabling the cursor is now done once in GLimp_Init() because it should always be disabled - GLimp_GrabInput( GRAB_ENABLE | GRAB_REENABLE ); + + // DG: un-pause the game when focus is gained, that also re-grabs the input + // disabling the cursor is now done once in GLimp_Init() because it should always be disabled + cvarSystem->SetCVarBool( "com_pause", false ); // DG end break; } case SDL_WINDOWEVENT_FOCUS_LOST: - GLimp_GrabInput( 0 ); + // DG: pause the game when focus is lost, that also un-grabs the input + cvarSystem->SetCVarBool( "com_pause", true ); + // DG end break; // DG: handle resizing and moving of window @@ -779,11 +783,13 @@ sysEvent_t Sys_GetEvent() #else case SDL_ACTIVEEVENT: { - int flags = 0; + // DG: (un-)pause the game when focus is gained, that also (un-)grabs the input + bool pause = true; if( ev.active.gain ) { - flags = GRAB_ENABLE | GRAB_REENABLE | GRAB_HIDECURSOR; + + pause = false; // unset modifier, in case alt-tab was used to leave window and ALT is still set // as that can cause fullscreen-toggling when pressing enter... @@ -795,7 +801,7 @@ sysEvent_t Sys_GetEvent() SDL_SetModState( ( SDLMod )newmod ); } - GLimp_GrabInput( flags ); + cvarSystem->SetCVarBool( "com_pause", pause ); } return res_none; diff --git a/neo/sys/win32/win_session_local.cpp b/neo/sys/win32/win_session_local.cpp index 3b175eb7..b76b065b 100644 --- a/neo/sys/win32/win_session_local.cpp +++ b/neo/sys/win32/win_session_local.cpp @@ -456,7 +456,9 @@ idSessionLocalWin::IsSystemUIShowing */ bool idSessionLocalWin::IsSystemUIShowing() const { - return !win32.activeApp || isSysUIShowing; // If the user alt+tabs away, treat it the same as bringing up the steam overlay + // DG: wtf, !win32.activeApp doesn't belong here, this is totally confusing and hacky. + // pause (when losing focus or invoking explicitly) is now handled properly by com_pause + return isSysUIShowing; } /* diff --git a/neo/sys/win32/win_wndproc.cpp b/neo/sys/win32/win_wndproc.cpp index 680b467e..5eec81eb 100644 --- a/neo/sys/win32/win_wndproc.cpp +++ b/neo/sys/win32/win_wndproc.cpp @@ -288,6 +288,10 @@ LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) // start playing the game sound world soundSystem->SetMute( !win32.activeApp ); + // DG: set com_pause so game pauses when focus is lost + // and continues when focus is regained + cvarSystem->SetCVarBool( "com_pause", !win32.activeApp ); + // DG end // we do not actually grab or release the mouse here, // that will be done next time through the main loop From cf8d287a4e1ae97ce4ba4d01679beb6c4afff26a Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Fri, 4 Jan 2013 14:33:17 +0100 Subject: [PATCH 6/7] Fix Sys_ListFiles() on POSIX once again Turned out that as "extension" (which is really more like a pattern that matches the whole file) was even used with patterns like "*.*" so we do proper matching using fnmatch() now - which is even easier than the old way. Now deleting savegames on POSIX works. --- neo/sys/posix/posix_main.cpp | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/neo/sys/posix/posix_main.cpp b/neo/sys/posix/posix_main.cpp index ea460114..80ee0831 100644 --- a/neo/sys/posix/posix_main.cpp +++ b/neo/sys/posix/posix_main.cpp @@ -42,6 +42,7 @@ If you have questions concerning this license or the applicable additional terms #include #include #include +#include // RB begin #if defined(__ANDROID__) @@ -358,21 +359,23 @@ int Sys_ListFiles( const char* directory, const char* extension, idStrList& list list.Clear(); debug = cvarSystem->GetCVarBool( "fs_debug" ); - - // DG: handle "*" as special case that matches everything - // FIXME: handle * properly as a wildcase somewhere in the string? - if( !extension || ( extension[0] == '*' && extension[1] == '\0' ) ) - extension = ""; - // DG end + // DG: we use fnmatch for shell-style pattern matching + // so the pattern should at least contain "*" to match everything, + // the extension will be added behind that (if !dironly) + idStr pattern( "*" ); // passing a slash as extension will find directories if( extension[0] == '/' && extension[1] == 0 ) { - extension = ""; dironly = true; } + else + { + // so we have *, the same as in the windows code basically + pattern += extension; + } + // DG end - // search // NOTE: case sensitivity of directory path can screw us up here if( ( fdir = opendir( directory ) ) == NULL ) { @@ -399,8 +402,6 @@ int Sys_ListFiles( const char* directory, const char* extension, idStrList& list return 0; } - int extLen = idStr::Length( extension ); - while( readdir_r( fdir, entry, &d ) == 0 && d != NULL ) { // DG end @@ -410,14 +411,11 @@ int Sys_ListFiles( const char* directory, const char* extension, idStrList& list if( !dironly ) { // DG: the original code didn't work because d3 bfg abuses the extension - // to match whole filenames in the savegame-code, not just file extensions... - // the extension must be the last chars of the filename - // so start matching at startPos = strlen(d->d_name) - strlen(extension) - int startPos = idStr::Length( d->d_name ) - extLen; - // of course the extension can't match if it's longer than the filename, i.e. startPos < 0 - if( startPos < 0 || idStr::FindText( d->d_name, extension, true, startPos ) < 0 ) + // to match whole filenames and patterns in the savegame-code, not just file extensions... + // so just use fnmatch() which supports matching shell wildcard patterns ("*.foo" etc) + // if we should ever need case insensitivity, use FNM_CASEFOLD as third flag + if( fnmatch( pattern.c_str(), d->d_name, 0 ) != 0 ) continue; - // DG end } if( ( dironly && !( st.st_mode & S_IFDIR ) ) || From c58f0d47496989b61c464143ec610f24e5481bb3 Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Fri, 4 Jan 2013 17:01:40 +0100 Subject: [PATCH 7/7] Precompiled Headers for GCC+Clang --- neo/CMakeLists.txt | 68 ++++++++++++++++++++++++++++++++++++++-- neo/idlib/CMakeLists.txt | 43 ++++++++++++++++++++++--- 2 files changed, 104 insertions(+), 7 deletions(-) diff --git a/neo/CMakeLists.txt b/neo/CMakeLists.txt index ec09fdcc..fe61f08f 100644 --- a/neo/CMakeLists.txt +++ b/neo/CMakeLists.txt @@ -36,7 +36,7 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang") #endif() # the warnings are used for every profile anyway, so put them in a variable - set(my_warn_flags "-Wno-pragmas -fno-strict-aliasing -Wno-unused-variable -Wno-unused-but-set-variable -Wno-switch -Wno-unused-value") + set(my_warn_flags "-Wno-pragmas -Wno-unused-variable -Wno-unused-but-set-variable -Wno-switch -Wno-unused-value -Winvalid-pch") if(CMAKE_C_COMPILER_ID STREQUAL "Clang") # append clang-specific settings for warnings (the second one make sure clang doesn't complain @@ -1205,9 +1205,73 @@ else() list(REMOVE_DUPLICATES RBDOOM3_SOURCES) + set(RBDOOM3_PRECOMPILED_SOURCES ${RBDOOM3_SOURCES}) + list(REMOVE_ITEM RBDOOM3_PRECOMPILED_SOURCES ${TIMIDITY_SOURCES} ${JPEG_SOURCES} ${ZLIB_SOURCES}) + list(REMOVE_ITEM RBDOOM3_PRECOMPILED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/libs/zlib/minizip/ioapi.c) + list(REMOVE_ITEM RBDOOM3_PRECOMPILED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/renderer/DXT/DXTDecoder.cpp) + list(REMOVE_ITEM RBDOOM3_PRECOMPILED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/renderer/DXT/DXTEncoder.cpp) + list(REMOVE_ITEM RBDOOM3_PRECOMPILED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/renderer/DXT/DXTEncoder_SSE2.cpp) + list(REMOVE_ITEM RBDOOM3_PRECOMPILED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/renderer/jobs/dynamicshadowvolume/DynamicShadowVolume.cpp) + list(REMOVE_ITEM RBDOOM3_PRECOMPILED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/renderer/jobs/prelightshadowvolume/PreLightShadowVolume.cpp) + list(REMOVE_ITEM RBDOOM3_PRECOMPILED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/renderer/jobs/staticshadowvolume/StaticShadowVolume.cpp) + list(REMOVE_ITEM RBDOOM3_PRECOMPILED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/renderer/jobs/ShadowShared.cpp) + list(REMOVE_ITEM RBDOOM3_PRECOMPILED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/renderer/RenderLog.cpp) +# list(REMOVE_ITEM RBDOOM3_PRECOMPILED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../doomclassic/doom/i_sound_stub.cpp) + + foreach( src_file ${RBDOOM3_PRECOMPILED_SOURCES} ) + #message(STATUS "-include precompiled.h for ${src_file}") + set_source_files_properties( + ${src_file} + PROPERTIES + COMPILE_FLAGS "-include ${CMAKE_CURRENT_SOURCE_DIR}/idlib/precompiled.h" + ) + endforeach() + + # precompiled magic for GCC/clang, adapted from https://gist.github.com/573926 + STRING(TOUPPER "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" _flags_var_name) + SET(_compiler_FLAGS ${${_flags_var_name}}) + GET_DIRECTORY_PROPERTY(_directory_flags INCLUDE_DIRECTORIES) + FOREACH(item ${_directory_flags}) + LIST(APPEND _compiler_FLAGS " -I${item}") + ENDFOREACH(item) + + GET_DIRECTORY_PROPERTY(_directory_flags DEFINITIONS) + LIST(APPEND _compiler_FLAGS ${_directory_flags}) + SEPARATE_ARGUMENTS(_compiler_FLAGS) + + # we need to recreate the precompiled header for RBDoom3BFG + # (i.e. can't use the one created for idlib before) + # because some definitions (e.g. -D__IDLIB__ -D__DOOM_DLL__) differ + add_custom_target(precomp_header_rbdoom3bfg ALL + COMMAND ${CMAKE_CXX_COMPILER} ${_compiler_FLAGS} -x c++-header idlib/precompiled.h -o idlib/precompiled.h.gch + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Creating idlib/precompiled.h.gch for RBDoom3BFG" + ) + + if(WIN32) + set(remove_command "del") + else() + set(remove_command "rm") + endif() + # it's ugly enough that the precompiled header binary needs to be in the + # source directory (instead of the build directory), so let's at least + # delete it after build. + add_custom_target(rm_precomp_header ALL + COMMAND ${remove_command} "idlib/precompiled.h.gch" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "remove idlib/precompiled.h.gch" + ) + + # make sure this is run after creating idlib + add_dependencies(precomp_header_rbdoom3bfg idlib) + add_executable(RBDoom3BFG WIN32 ${RBDOOM3_SOURCES}) - add_dependencies(RBDoom3BFG idlib) + # make sure precompiled header is created before executable is compiled + add_dependencies(RBDoom3BFG precomp_header_rbdoom3bfg) + + # make sure precompiled header is deleted after executable is compiled + add_dependencies(rm_precomp_header RBDoom3BFG) if(MINGW) include_directories(libs/sdl2/include) diff --git a/neo/idlib/CMakeLists.txt b/neo/idlib/CMakeLists.txt index 31f521fb..23d24219 100644 --- a/neo/idlib/CMakeLists.txt +++ b/neo/idlib/CMakeLists.txt @@ -14,14 +14,14 @@ endif() # add_definitions(-DSTANDALONE) #endif() +set(ID_PRECOMPILED_SOURCES ${ID_SOURCES}) +list(REMOVE_ITEM ID_PRECOMPILED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/geometry/RenderMatrix.cpp) +list(REMOVE_ITEM ID_PRECOMPILED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/SoftwareCache.cpp) + if(MSVC) #set_target_properties(idlib PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h") - set(ID_PRECOMPILED_SOURCES ${ID_SOURCES}) - list(REMOVE_ITEM ID_PRECOMPILED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/geometry/RenderMatrix.cpp) - list(REMOVE_ITEM ID_PRECOMPILED_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/SoftwareCache.cpp) - foreach( src_file ${ID_PRECOMPILED_SOURCES} ) #message(STATUS "/Yuprecompiled.h for ${src_file}") set_source_files_properties( @@ -35,11 +35,44 @@ if(MSVC) PROPERTIES COMPILE_FLAGS "/Ycprecompiled.h" ) + + add_library(idlib ${ID_SOURCES} ${ID_INCLUDES}) else() + foreach( src_file ${ID_PRECOMPILED_SOURCES} ) + #message(STATUS "-include precompiled.h for ${src_file}") + set_source_files_properties( + ${src_file} + PROPERTIES + COMPILE_FLAGS "-include ${CMAKE_CURRENT_SOURCE_DIR}/precompiled.h" + ) + endforeach() + include_directories(.) + + # precompiled magic for GCC/clang, adapted from https://gist.github.com/573926 + STRING(TOUPPER "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" _flags_var_name) + SET(_compiler_FLAGS ${${_flags_var_name}}) + GET_DIRECTORY_PROPERTY(_directory_flags INCLUDE_DIRECTORIES) + FOREACH(item ${_directory_flags}) + LIST(APPEND _compiler_FLAGS " -I${item}") + ENDFOREACH(item) + + GET_DIRECTORY_PROPERTY(_directory_flags DEFINITIONS) + LIST(APPEND _compiler_FLAGS ${_directory_flags}) + + SEPARATE_ARGUMENTS(_compiler_FLAGS) + + add_custom_target(precomp_header_idlib ALL + COMMAND ${CMAKE_CXX_COMPILER} ${_compiler_FLAGS} -x c++-header precompiled.h -o precompiled.h.gch + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Creating idlib/precompiled.h.gch for idlib" + ) + + add_library(idlib ${ID_SOURCES} ${ID_INCLUDES}) + add_dependencies(idlib precomp_header_idlib) + endif() -add_library(idlib ${ID_SOURCES} ${ID_INCLUDES}) # if(MSVC) # # set_source_files_properties(precompiled.cpp