diff --git a/src/client/vid/header/ref.h b/src/client/vid/header/ref.h index 094fa613..888351c6 100644 --- a/src/client/vid/header/ref.h +++ b/src/client/vid/header/ref.h @@ -116,6 +116,14 @@ typedef struct { particle_t *particles; } refdef_t; +// Renderer restart type. +typedef enum { + RESTART_UNDEF, + RESTART_NO, + RESTART_FULL, + RESTART_PARTIAL +} ref_restart_t; + // FIXME: bump API_VERSION? #define API_VERSION 5 #define EXPORT @@ -233,6 +241,8 @@ typedef struct qboolean (IMPORT *GLimp_InitGraphics)(int fullscreen, int *pwidth, int *pheight); qboolean (IMPORT *GLimp_GetDesktopMode)(int *pwidth, int *pheight); + + void (IMPORT *Vid_RequestRestart)(ref_restart_t rs); } refimport_t; // this is the only function actually exported at the linker level diff --git a/src/client/vid/vid.c b/src/client/vid/vid.c index e6da7d5b..2106fcd9 100644 --- a/src/client/vid/vid.c +++ b/src/client/vid/vid.c @@ -300,13 +300,30 @@ void *reflib_handle = NULL; // Is a renderer loaded and active? qboolean ref_active = false; +// Renderer restart type requested. +ref_restart_t restart_state = RESTART_UNDEF; + +/* + * Called by the renderer to request a restart. + */ +void +VID_RequestRestart(ref_restart_t rs) +{ + restart_state = rs; +} + /* * Restarts the renderer. */ void VID_Restart_f(void) { - vid_fullscreen->modified = true; + if (restart_state == RESTART_UNDEF) + { + vid_fullscreen->modified = true; + } else { + restart_state = RESTART_FULL; + } } /* @@ -392,6 +409,8 @@ VID_LoadRenderer(void) ri.Vid_GetModeInfo = VID_GetModeInfo; ri.Vid_MenuInit = VID_MenuInit; ri.Vid_WriteScreenshot = VID_WriteScreenshot; + ri.Vid_WriteScreenshot = VID_WriteScreenshot; + ri.Vid_RequestRestart = VID_RequestRestart; // Exchange our export struct with the renderers import struct. re = GetRefAPI(ri); @@ -436,11 +455,25 @@ VID_LoadRenderer(void) void VID_CheckChanges(void) { - // FIXME: Not with vid_fullscreen, should be a dedicated variable. - // Sounds easy but this vid_fullscreen hack is really messy and - // interacts with several critical places in both the client and - // the renderers... - if (vid_fullscreen->modified) + // Hack around renderers that still abuse vid_fullscreen + // to communicate restart requests to the client. + ref_restart_t rs; + + if (restart_state == RESTART_UNDEF) + { + if (vid_fullscreen->modified) + { + rs = RESTART_FULL; + vid_fullscreen->modified = false; + } else { + rs = RESTART_NO; + } + } else { + rs = restart_state; + restart_state = RESTART_NO; + } + + if (rs == RESTART_FULL) { // Stop sound, because the clients blocks while // we're reloading the renderer. The sound system @@ -486,16 +519,12 @@ VID_CheckChanges(void) } } - // Ignore possible changes in vid_renderer above. - vid_renderer->modified = false; - // Unblock the client. cls.disable_screen = false; } - if (vid_renderer->modified) + if (rs == RESTART_PARTIAL) { - vid_renderer->modified = false; cl.refresh_prepped = false; } }