Quake II RTX doxygen  1.0 dev
refresh.c
Go to the documentation of this file.
1 /*
2 Copyright (C) 1997-2001 Id Software, Inc.
3 Copyright (C) 2019, NVIDIA CORPORATION. All rights reserved.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 
20 // Main windowed and fullscreen graphics interface module. This module
21 // is used for both the software and OpenGL rendering versions of the
22 // Quake refresh engine.
23 
24 
25 #include "client.h"
26 #include "refresh/images.h"
27 #include "refresh/models.h"
28 
29 // Console variables that we need to access from this module
30 cvar_t *vid_rtx;
31 cvar_t *vid_geometry;
32 cvar_t *vid_modelist;
35 cvar_t *vid_display;
37 
38 #define MODE_GEOMETRY 1
39 #define MODE_FULLSCREEN 2
40 #define MODE_MODELIST 4
41 
42 static int mode_changed;
43 
44 /*
45 ==========================================================================
46 
47 HELPER FUNCTIONS
48 
49 ==========================================================================
50 */
51 
52 // 640x480 800x600 1024x768
53 // 640x480@75
54 // 640x480@75:32
55 // 640x480:32@75
56 qboolean VID_GetFullscreen(vrect_t *rc, int *freq_p, int *depth_p)
57 {
58  unsigned long w, h, freq, depth;
59  char *s;
60  int mode;
61 
62  // fill in default parameters
63  rc->x = 0;
64  rc->y = 0;
65  rc->width = 640;
66  rc->height = 480;
67 
68  if (freq_p)
69  *freq_p = 0;
70  if (depth_p)
71  *depth_p = 0;
72 
74  return qfalse;
75 
76  s = vid_modelist->string;
77  while (Q_isspace(*s))
78  s++;
79  if (!*s)
80  return qfalse;
81 
82  mode = 1;
83  while (1) {
84  if (!strncmp(s, "desktop", 7)) {
85  s += 7;
86  if (*s && !Q_isspace(*s)) {
87  Com_DPrintf("Mode %d is malformed\n", mode);
88  return qfalse;
89  }
90  w = h = freq = depth = 0;
91  } else {
92  w = strtoul(s, &s, 10);
93  if (*s != 'x' && *s != 'X') {
94  Com_DPrintf("Mode %d is malformed\n", mode);
95  return qfalse;
96  }
97  h = strtoul(s + 1, &s, 10);
98  freq = depth = 0;
99  if (*s == '@') {
100  freq = strtoul(s + 1, &s, 10);
101  if (*s == ':') {
102  depth = strtoul(s + 1, &s, 10);
103  }
104  } else if (*s == ':') {
105  depth = strtoul(s + 1, &s, 10);
106  if (*s == '@') {
107  freq = strtoul(s + 1, &s, 10);
108  }
109  }
110  }
111  if (mode == vid_fullscreen->integer) {
112  break;
113  }
114  while (Q_isspace(*s))
115  s++;
116  if (!*s) {
117  Com_DPrintf("Mode %d not found\n", vid_fullscreen->integer);
118  return qfalse;
119  }
120  mode++;
121  }
122 
123  // sanity check
124  if (w < 64 || w > 8192 || h < 64 || h > 8192 || freq > 1000 || depth > 32) {
125  Com_DPrintf("Mode %lux%lu@%lu:%lu doesn't look sane\n", w, h, freq, depth);
126  return qfalse;
127  }
128 
129  rc->width = w;
130  rc->height = h;
131 
132  if (freq_p)
133  *freq_p = freq;
134  if (depth_p)
135  *depth_p = depth;
136 
137  return qtrue;
138 }
139 
140 // 640x480
141 // 640x480+0
142 // 640x480+0+0
143 // 640x480-100-100
144 qboolean VID_GetGeometry(vrect_t *rc)
145 {
146  unsigned long w, h;
147  long x, y;
148  char *s;
149 
150  // fill in default parameters
151  rc->x = 100;
152  rc->y = 100;
153  rc->width = 1280;
154  rc->height = 720;
155 
156  if (!vid_geometry)
157  return qfalse;
158 
159  s = vid_geometry->string;
160  if (!*s)
161  return qfalse;
162 
163  w = strtoul(s, &s, 10);
164  if (*s != 'x' && *s != 'X') {
165  Com_DPrintf("Geometry string is malformed\n");
166  return qfalse;
167  }
168  h = strtoul(s + 1, &s, 10);
169  x = rc->x;
170  y = rc->y;
171  if (*s == '+' || *s == '-') {
172  x = strtol(s, &s, 10);
173  if (*s == '+' || *s == '-') {
174  y = strtol(s, &s, 10);
175  }
176  }
177 
178  // sanity check
179  if (w < 64 || w > 8192 || h < 64 || h > 8192) {
180  Com_DPrintf("Geometry %lux%lu doesn't look sane\n", w, h);
181  return qfalse;
182  }
183 
184  rc->x = x;
185  rc->y = y;
186  rc->width = w;
187  rc->height = h;
188 
189  return qtrue;
190 }
191 
192 void VID_SetGeometry(vrect_t *rc)
193 {
194  char buffer[MAX_QPATH];
195 
196  if (!vid_geometry)
197  return;
198 
199  Q_snprintf(buffer, sizeof(buffer), "%dx%d%+d%+d",
200  rc->width, rc->height, rc->x, rc->y);
201  Cvar_SetByVar(vid_geometry, buffer, FROM_CODE);
202 }
203 
205 {
207  return;
208 
209  if (!vid_fullscreen->integer) {
210  if (!_vid_fullscreen->integer) {
211  Cvar_Set("_vid_fullscreen", "1");
212  }
213  Cbuf_AddText(&cmd_buffer, "set vid_fullscreen $_vid_fullscreen\n");
214  } else {
215  Cbuf_AddText(&cmd_buffer, "set vid_fullscreen 0\n");
216  }
217 }
218 
219 /*
220 ==========================================================================
221 
222 LOADING / SHUTDOWN
223 
224 ==========================================================================
225 */
226 
227 /*
228 ============
229 CL_RunResfresh
230 ============
231 */
232 void CL_RunRefresh(void)
233 {
234  if (!cls.ref_initialized) {
235  return;
236  }
237 
238  VID_PumpEvents();
239 
240  if (mode_changed) {
242  VID_SetMode();
243  if (vid_fullscreen->integer) {
244  Cvar_Set("_vid_fullscreen", vid_fullscreen->string);
245  }
246  } else {
247  if (vid_fullscreen->integer) {
248  if (mode_changed & MODE_MODELIST) {
249  VID_SetMode();
250  }
251  } else {
252  if (mode_changed & MODE_GEOMETRY) {
253  VID_SetMode();
254  }
255  }
256  }
257  mode_changed = 0;
258  }
259 
260  if (cvar_modified & CVAR_REFRESH) {
261  CL_RestartRefresh(qtrue);
262  cvar_modified &= ~CVAR_REFRESH;
263  } else if (cvar_modified & CVAR_FILES) {
264  CL_RestartRefresh(qfalse);
265  cvar_modified &= ~CVAR_FILES;
266  }
267 }
268 
269 static void vid_geometry_changed(cvar_t *self)
270 {
272 }
273 
274 static void vid_fullscreen_changed(cvar_t *self)
275 {
277 }
278 
279 static void vid_modelist_changed(cvar_t *self)
280 {
282 }
283 
284 /*
285 ============
286 CL_InitRefresh
287 ============
288 */
289 void CL_InitRefresh(void)
290 {
291  char *modelist;
292 
293  if (cls.ref_initialized) {
294  return;
295  }
296 
297  vid_display = Cvar_Get("vid_display", "0", CVAR_ARCHIVE | CVAR_REFRESH);
298  vid_displaylist = Cvar_Get("vid_displaylist", "\"<unknown>\" 0", CVAR_ROM);
299 
300  Com_SetLastError(NULL);
301 
302  modelist = VID_GetDefaultModeList();
303  if (!modelist) {
304  Com_Error(ERR_FATAL, "Couldn't initialize refresh: %s", Com_GetLastError());
305  }
306 
307  // Create the video variables so we know how to start the graphics drivers
308 
309  vid_rtx = Cvar_Get("vid_rtx",
310 #if REF_VKPT
311  "1",
312 #else
313  "0",
314 #endif
315  CVAR_REFRESH | CVAR_ARCHIVE);
316 
317  vid_fullscreen = Cvar_Get("vid_fullscreen", "0", CVAR_ARCHIVE);
318  _vid_fullscreen = Cvar_Get("_vid_fullscreen", "1", CVAR_ARCHIVE);
319  vid_modelist = Cvar_Get("vid_modelist", modelist, 0);
320  vid_geometry = Cvar_Get("vid_geometry", VID_GEOMETRY, CVAR_ARCHIVE);
321 
322  Z_Free(modelist);
323 
324  if (vid_fullscreen->integer) {
325  Cvar_Set("_vid_fullscreen", vid_fullscreen->string);
326  } else if (!_vid_fullscreen->integer) {
327  Cvar_Set("_vid_fullscreen", "1");
328  }
329 
330  Com_SetLastError(NULL);
331 
332 #if REF_GL && REF_VKPT
333  if (vid_rtx->integer)
335  else
337 #elif REF_GL
339 #elif REF_VKPT
341 #else
342 #error "REF_GL and REF_VKPT are both disabled, at least one has to be enableds"
343 #endif
344 
345  if (!R_Init(qtrue)) {
346  Com_Error(ERR_FATAL, "Couldn't initialize refresh: %s", Com_GetLastError());
347  }
348 
349  cls.ref_initialized = qtrue;
350 
354 
355  mode_changed = 0;
356 
357  FX_Init();
358 
359  // Initialize the rest of graphics subsystems
360  V_Init();
361  SCR_Init();
362  UI_Init();
363 
366 
367  cvar_modified &= ~(CVAR_FILES | CVAR_REFRESH);
368 }
369 
370 /*
371 ============
372 CL_ShutdownRefresh
373 ============
374 */
376 {
377  if (!cls.ref_initialized) {
378  return;
379  }
380 
381  // Shutdown the rest of graphics subsystems
382  V_Shutdown();
383  SCR_Shutdown();
384  UI_Shutdown();
385 
386  vid_geometry->changed = NULL;
387  vid_fullscreen->changed = NULL;
388  vid_modelist->changed = NULL;
389 
390  R_Shutdown(qtrue);
391 
392  cls.ref_initialized = qfalse;
393 
394  // no longer active
395  cls.active = ACT_MINIMIZED;
396 
397  Z_LeakTest(TAG_RENDERER);
398 }
399 
400 
401 refcfg_t r_config;
402 
403 qboolean(*R_Init)(qboolean total) = NULL;
404 void(*R_Shutdown)(qboolean total) = NULL;
405 void(*R_BeginRegistration)(const char *map) = NULL;
406 void(*R_SetSky)(const char *name, float rotate, vec3_t axis) = NULL;
408 void(*R_RenderFrame)(refdef_t *fd) = NULL;
409 void(*R_LightPoint)(vec3_t origin, vec3_t light) = NULL;
411 void(*R_SetAlpha)(float clpha) = NULL;
412 void(*R_SetAlphaScale)(float alpha) = NULL;
413 void(*R_SetColor)(uint32_t color) = NULL;
414 void(*R_SetClipRect)(const clipRect_t *clip) = NULL;
415 void(*R_SetScale)(float scale) = NULL;
416 void(*R_DrawChar)(int x, int y, int flags, int ch, qhandle_t font) = NULL;
417 int(*R_DrawString)(int x, int y, int flags, size_t maxChars,
418  const char *string, qhandle_t font) = NULL;
419 void(*R_DrawPic)(int x, int y, qhandle_t pic) = NULL;
420 void(*R_DrawStretchPic)(int x, int y, int w, int h, qhandle_t pic) = NULL;
421 void(*R_TileClear)(int x, int y, int w, int h, qhandle_t pic) = NULL;
422 void(*R_DrawFill8)(int x, int y, int w, int h, int c) = NULL;
423 void(*R_DrawFill32)(int x, int y, int w, int h, uint32_t color) = NULL;
425 void(*R_EndFrame)(void) = NULL;
426 void(*R_ModeChanged)(int width, int height, int flags, int rowbytes, void *pixels) = NULL;
427 void(*R_AddDecal)(decal_t *d) = NULL;
428 qboolean(*R_InterceptKey)(unsigned key, qboolean down) = NULL;
429 
430 void(*IMG_Unload)(image_t *image) = NULL;
431 void(*IMG_Load)(image_t *image, byte *pic) = NULL;
432 byte* (*IMG_ReadPixels)(int *width, int *height, int *rowbytes) = NULL;
433 
434 qerror_t(*MOD_LoadMD2)(model_t *model, const void *rawdata, size_t length) = NULL;
435 #if USE_MD3
436 qerror_t(*MOD_LoadMD3)(model_t *model, const void *rawdata, size_t length) = NULL;
437 #endif
438 void(*MOD_Reference)(model_t *model) = NULL;
439 
440 float R_ClampScale(cvar_t *var)
441 {
442  if (!var)
443  return 1.0f;
444 
445  if (var->value)
446  return 1.0f / Cvar_ClampValue(var, 1.0f, 10.0f);
447 
448  if (r_config.width * r_config.height >= 2560 * 1440)
449  return 0.25f;
450 
451  if (r_config.width * r_config.height >= 1280 * 720)
452  return 0.5f;
453 
454  return 1.0f;
455 }
R_TileClear
void(* R_TileClear)(int x, int y, int w, int h, qhandle_t pic)
Definition: refresh.c:421
edict_s::s
entity_state_t s
Definition: g_local.h:954
MOD_Reference
void(* MOD_Reference)(model_t *model)
Definition: refresh.c:438
R_EndRegistration
void(* R_EndRegistration)(void)
Definition: refresh.c:407
VID_SetGeometry
void VID_SetGeometry(vrect_t *rc)
Definition: refresh.c:192
Cvar_Set
cvar_t * Cvar_Set(const char *var_name, const char *value)
Definition: cvar.c:466
R_SetColor
void(* R_SetColor)(uint32_t color)
Definition: refresh.c:413
R_InterceptKey
qboolean(* R_InterceptKey)(unsigned key, qboolean down)
Definition: refresh.c:428
edict_s::model
char * model
Definition: g_local.h:988
cvar_modified
int cvar_modified
Definition: cvar.c:32
FX_Init
void FX_Init(void)
Definition: effects.c:838
vid_modelist
cvar_t * vid_modelist
Definition: refresh.c:32
R_SetSky
void(* R_SetSky)(const char *name, float rotate, vec3_t axis)
Definition: refresh.c:406
height
static int height
Definition: physical_sky.c:39
R_SetAlpha
void(* R_SetAlpha)(float clpha)
Definition: refresh.c:411
Q_snprintf
size_t Q_snprintf(char *dest, size_t size, const char *fmt,...)
Definition: shared.c:846
image_t
struct image_s image_t
Definition: material.h:27
SCR_Shutdown
void SCR_Shutdown(void)
Definition: screen.c:1413
VID_SetMode
void VID_SetMode(void)
Definition: client.c:960
IMG_Load
void(* IMG_Load)(image_t *image, byte *pic)
Definition: refresh.c:431
VID_GetGeometry
qboolean VID_GetGeometry(vrect_t *rc)
Definition: refresh.c:144
Cvar_Get
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags)
Definition: cvar.c:257
Z_LeakTest
void Z_LeakTest(memtag_t tag)
Definition: zone.c:120
edict_s::map
char * map
Definition: g_local.h:1049
R_ClearColor
void(* R_ClearColor)(void)
Definition: refresh.c:410
R_LightPoint
void(* R_LightPoint)(vec3_t origin, vec3_t light)
Definition: refresh.c:409
VID_GetDefaultModeList
char * VID_GetDefaultModeList(void)
Definition: client.c:198
R_Init
qboolean(* R_Init)(qboolean total)
Definition: refresh.c:403
UI_Init
void UI_Init(void)
Definition: ui.c:627
client_static_s::ref_initialized
qboolean ref_initialized
Definition: client.h:380
R_DrawFill8
void(* R_DrawFill8)(int x, int y, int w, int h, int c)
Definition: refresh.c:422
R_ClampScale
float R_ClampScale(cvar_t *var)
Definition: refresh.c:440
client_static_s::active
active_t active
Definition: client.h:378
R_BeginFrame
void(* R_BeginFrame)(void)
Definition: refresh.c:424
MODE_GEOMETRY
#define MODE_GEOMETRY
Definition: refresh.c:38
_vid_fullscreen
cvar_t * _vid_fullscreen
Definition: refresh.c:34
R_RegisterFunctionsRTX
void R_RegisterFunctionsRTX()
Definition: main.c:3503
R_AddDecal
void(* R_AddDecal)(decal_t *d)
Definition: refresh.c:427
VID_PumpEvents
void VID_PumpEvents(void)
Definition: client.c:971
V_Shutdown
void V_Shutdown(void)
Definition: view.c:560
R_SetAlphaScale
void(* R_SetAlphaScale)(float alpha)
Definition: refresh.c:412
width
static int width
Definition: physical_sky.c:38
MODE_MODELIST
#define MODE_MODELIST
Definition: refresh.c:40
cmd_buffer
cmdbuf_t cmd_buffer
Definition: cmd.c:49
VID_GetFullscreen
qboolean VID_GetFullscreen(vrect_t *rc, int *freq_p, int *depth_p)
Definition: refresh.c:56
Com_Error
void Com_Error(error_type_t type, const char *fmt,...)
Definition: g_main.c:258
MOD_LoadMD2
qerror_t(* MOD_LoadMD2)(model_t *model, const void *rawdata, size_t length)
Definition: refresh.c:434
SCR_RegisterMedia
void SCR_RegisterMedia(void)
Definition: screen.c:1297
Cvar_ClampValue
float Cvar_ClampValue(cvar_t *var, float min, float max)
Definition: cvar.c:571
Cbuf_AddText
void Cbuf_AddText(cmdbuf_t *buf, const char *text)
Definition: cmd.c:95
Z_Free
void Z_Free(void *ptr)
Definition: zone.c:147
R_DrawPic
void(* R_DrawPic)(int x, int y, qhandle_t pic)
Definition: refresh.c:419
vid_display
cvar_t * vid_display
Definition: refresh.c:35
origin
static vec3_t origin
Definition: mesh.c:27
R_DrawString
int(* R_DrawString)(int x, int y, int flags, size_t maxChars, const char *string, qhandle_t font)
Definition: refresh.c:417
void
void(APIENTRY *qwglDrawBuffer)(GLenum mode)
Cvar_SetByVar
void Cvar_SetByVar(cvar_t *var, const char *value, from_t from)
Definition: cvar.c:345
CL_RunRefresh
void CL_RunRefresh(void)
Definition: refresh.c:232
Com_GetLastError
char * Com_GetLastError(void)
Definition: common.c:391
R_DrawFill32
void(* R_DrawFill32)(int x, int y, int w, int h, uint32_t color)
Definition: refresh.c:423
UI_Shutdown
void UI_Shutdown(void)
Definition: ui.c:674
IMG_Unload
void(* IMG_Unload)(image_t *image)
Definition: refresh.c:430
cls
client_static_t cls
Definition: main.c:98
VID_ToggleFullscreen
void VID_ToggleFullscreen(void)
Definition: refresh.c:204
c
statCounters_t c
Definition: main.c:30
R_Shutdown
void(* R_Shutdown)(qboolean total)
Definition: refresh.c:404
V_Init
void V_Init(void)
Definition: view.c:533
CL_InitRefresh
void CL_InitRefresh(void)
Definition: refresh.c:289
SCR_Init
void SCR_Init(void)
Definition: screen.c:1348
edict_s::flags
int flags
Definition: g_local.h:986
R_RenderFrame
void(* R_RenderFrame)(refdef_t *fd)
Definition: refresh.c:408
vid_geometry
cvar_t * vid_geometry
Definition: refresh.c:31
Com_SetLastError
void Com_SetLastError(const char *msg)
Definition: common.c:382
R_BeginRegistration
void(* R_BeginRegistration)(const char *map)
Definition: refresh.c:405
R_SetClipRect
void(* R_SetClipRect)(const clipRect_t *clip)
Definition: refresh.c:414
CL_ShutdownRefresh
void CL_ShutdownRefresh(void)
Definition: refresh.c:375
R_DrawStretchPic
void(* R_DrawStretchPic)(int x, int y, int w, int h, qhandle_t pic)
Definition: refresh.c:420
client.h
R_SetScale
void(* R_SetScale)(float scale)
Definition: refresh.c:415
R_EndFrame
void(* R_EndFrame)(void)
Definition: refresh.c:425
R_DrawChar
void(* R_DrawChar)(int x, int y, int flags, int ch, qhandle_t font)
Definition: refresh.c:416
color
static vec4_t color
Definition: mesh.c:33
vid_modelist_changed
static void vid_modelist_changed(cvar_t *self)
Definition: refresh.c:279
vid_geometry_changed
static void vid_geometry_changed(cvar_t *self)
Definition: refresh.c:269
MODE_FULLSCREEN
#define MODE_FULLSCREEN
Definition: refresh.c:39
vid_rtx
cvar_t * vid_rtx
Definition: refresh.c:30
vid_fullscreen
cvar_t * vid_fullscreen
Definition: refresh.c:33
CL_RestartRefresh
void CL_RestartRefresh(qboolean total)
Definition: main.c:2483
int
CONST PIXELFORMATDESCRIPTOR int
Definition: wgl.c:26
R_ModeChanged
void(* R_ModeChanged)(int width, int height, int flags, int rowbytes, void *pixels)
Definition: refresh.c:426
Con_RegisterMedia
void Con_RegisterMedia(void)
Definition: console.c:628
R_RegisterFunctionsGL
void R_RegisterFunctionsGL()
Definition: main.c:1147
mode_changed
static int mode_changed
Definition: refresh.c:42
r_config
refcfg_t r_config
Definition: refresh.c:401
vid_displaylist
cvar_t * vid_displaylist
Definition: refresh.c:36
vid_fullscreen_changed
static void vid_fullscreen_changed(cvar_t *self)
Definition: refresh.c:274