mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-02-17 01:21:12 +00:00
General cleanup of vid.c
* Reformat code and reorder functions. * Remove unnecessary stuff. * Move everything possible into headers. * Implement a clean fallback logic, gl3 -> gl1 -> soft.
This commit is contained in:
parent
9a53a681bb
commit
bef21c101e
4 changed files with 425 additions and 317 deletions
|
@ -41,8 +41,15 @@
|
||||||
#include "../../client/header/client.h"
|
#include "../../client/header/client.h"
|
||||||
#include "../../client/header/keyboard.h"
|
#include "../../client/header/keyboard.h"
|
||||||
|
|
||||||
|
// --------
|
||||||
|
|
||||||
|
// Screenshots
|
||||||
|
// -----------
|
||||||
|
|
||||||
#ifdef ZIP
|
#ifdef ZIP
|
||||||
// if we build with zip support, zlib is available and we can use that for better PNG compression
|
// If we build with zip support, zlib is available and
|
||||||
|
// we can use that for better PNG compression.
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
|
|
||||||
static unsigned char*
|
static unsigned char*
|
||||||
|
@ -50,23 +57,164 @@ compress_for_stbiw(unsigned char *data, int data_len, int *out_len, int quality)
|
||||||
{
|
{
|
||||||
uLongf bufSize = compressBound(data_len);
|
uLongf bufSize = compressBound(data_len);
|
||||||
unsigned char* buf = malloc(bufSize);
|
unsigned char* buf = malloc(bufSize);
|
||||||
if(buf == NULL) return NULL;
|
|
||||||
if(compress2(buf, &bufSize, data, data_len, quality) != Z_OK)
|
if (buf == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compress2(buf, &bufSize, data, data_len, quality) != Z_OK)
|
||||||
{
|
{
|
||||||
free(buf);
|
free(buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
*out_len = bufSize;
|
*out_len = bufSize;
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STBIW_ZLIB_COMPRESS compress_for_stbiw
|
#define STBIW_ZLIB_COMPRESS compress_for_stbiw
|
||||||
#endif // ZIP
|
#endif
|
||||||
|
|
||||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||||
#include "header/stb_image_write.h"
|
#include "header/stb_image_write.h"
|
||||||
|
|
||||||
qboolean VID_LoadRefresh(void);
|
/*
|
||||||
|
* Writes a screenshot. This function is called with raw image data of
|
||||||
|
* width*height pixels, each pixel has comp bytes. Must be 3 or 4, for
|
||||||
|
* RGB or RGBA. The pixels must be given row-wise, stating at the top
|
||||||
|
* left.
|
||||||
|
*/
|
||||||
|
void VID_WriteScreenshot(int width, int height, int comp, const void* data)
|
||||||
|
{
|
||||||
|
char picname[80];
|
||||||
|
char checkname[MAX_OSPATH];
|
||||||
|
int i, success = 0;
|
||||||
|
static const char* supportedFormats[] = { "tga", "bmp", "png", "jpg" };
|
||||||
|
static const int numFormats = sizeof(supportedFormats)/sizeof(supportedFormats[0]);
|
||||||
|
int format = 0; // 0=tga, 1=bmp, 2=png, 3=jpg
|
||||||
|
int quality = 85;
|
||||||
|
int argc = Cmd_Argc();
|
||||||
|
const char* gameDir = FS_Gamedir();
|
||||||
|
|
||||||
|
// FS_InitFilesystem() made sure the screenshots dir exists./
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
{
|
||||||
|
const char* maybeFormat = Cmd_Argv(1);
|
||||||
|
|
||||||
|
for (i = 0; i < numFormats; ++i)
|
||||||
|
{
|
||||||
|
if (Q_stricmp(maybeFormat, supportedFormats[i]) == 0)
|
||||||
|
{
|
||||||
|
format = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == numFormats)
|
||||||
|
{
|
||||||
|
Com_Printf("the (optional) second argument to 'screenshot' is the format, one of \"tga\", \"bmp\", \"png\", \"jpg\"\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc > 2)
|
||||||
|
{
|
||||||
|
const char* q = Cmd_Argv(2);
|
||||||
|
int qualityStrLen = strlen(q);
|
||||||
|
|
||||||
|
for (i = 0; i < qualityStrLen; ++i)
|
||||||
|
{
|
||||||
|
if (q[i] < '0' || q[i] > '9')
|
||||||
|
{
|
||||||
|
Com_Printf("The (optional!) third argument to 'screenshot' is jpg quality, a number between 1 and 100\n");
|
||||||
|
Com_Printf(" or png compression level, between 0 and 9!\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quality = atoi(q);
|
||||||
|
|
||||||
|
if (format == 2) // png
|
||||||
|
{
|
||||||
|
if (quality < 0)
|
||||||
|
{
|
||||||
|
quality = 0;
|
||||||
|
}
|
||||||
|
else if (quality > 9)
|
||||||
|
{
|
||||||
|
quality = 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(format == 3) // jpg
|
||||||
|
{
|
||||||
|
if (quality < 1)
|
||||||
|
{
|
||||||
|
quality = 1;
|
||||||
|
}
|
||||||
|
else if (quality > 100)
|
||||||
|
{
|
||||||
|
quality = 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find a file name to save it to */
|
||||||
|
for (i = 0; i <= 9999; i++)
|
||||||
|
{
|
||||||
|
FILE *f;
|
||||||
|
Com_sprintf(checkname, sizeof(checkname), "%s/scrnshot/q2_%04d.%s", gameDir, i, supportedFormats[format]);
|
||||||
|
f = Q_fopen(checkname, "rb");
|
||||||
|
|
||||||
|
if (!f)
|
||||||
|
{
|
||||||
|
Com_sprintf(picname, sizeof(picname), "q2_%04d.%s", i, supportedFormats[format]);
|
||||||
|
break; /* file doesn't exist */
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 10000)
|
||||||
|
{
|
||||||
|
Com_Printf("SCR_ScreenShot_f: Couldn't create a file\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (format) // 0=tga, 1=bmp, 2=png, 3=jpg
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
success = stbi_write_tga(checkname, width, height, comp, data);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
success = stbi_write_bmp(checkname, width, height, comp, data);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
stbi_write_png_compression_level = (quality < 10) ? quality : 7;
|
||||||
|
success = stbi_write_png(checkname, width, height, comp, data, 0);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
success = stbi_write_jpg(checkname, width, height, comp, data, quality);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(success)
|
||||||
|
{
|
||||||
|
Com_Printf("Wrote %s\n", picname);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Com_Printf("SCR_ScreenShot_f: Couldn't write %s\n", picname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------
|
||||||
|
|
||||||
|
// Video mode array
|
||||||
|
// ----------------
|
||||||
|
|
||||||
typedef struct vidmode_s
|
typedef struct vidmode_s
|
||||||
{
|
{
|
||||||
|
@ -75,7 +223,7 @@ typedef struct vidmode_s
|
||||||
int mode;
|
int mode;
|
||||||
} vidmode_t;
|
} vidmode_t;
|
||||||
|
|
||||||
/* This must be the same as in videomenu.c! */
|
// This must be the same as in videomenu.c!
|
||||||
vidmode_t vid_modes[] = {
|
vidmode_t vid_modes[] = {
|
||||||
{"Mode 0: 320x240", 320, 240, 0},
|
{"Mode 0: 320x240", 320, 240, 0},
|
||||||
{"Mode 1: 400x300", 400, 300, 1},
|
{"Mode 1: 400x300", 400, 300, 1},
|
||||||
|
@ -111,40 +259,28 @@ vidmode_t vid_modes[] = {
|
||||||
{"Mode 31: 5120x2880", 5120, 2880, 31},
|
{"Mode 31: 5120x2880", 5120, 2880, 31},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Console variables that we need to access from this module */
|
|
||||||
cvar_t *vid_gamma;
|
|
||||||
cvar_t *vid_fullscreen;
|
|
||||||
cvar_t *vid_renderer;
|
|
||||||
|
|
||||||
/* Global variables used internally by this module */
|
|
||||||
viddef_t viddef; /* global video state; used by other modules */
|
|
||||||
|
|
||||||
#define VID_NUM_MODES (sizeof(vid_modes) / sizeof(vid_modes[0]))
|
#define VID_NUM_MODES (sizeof(vid_modes) / sizeof(vid_modes[0]))
|
||||||
#define MAXPRINTMSG 4096
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Console command to re-start the video mode and refresh. We do this
|
* Callback function for the 'vid_listmodes' cmd.
|
||||||
* simply by setting the modified flag for the vid_fullscreen variable, which will
|
|
||||||
* cause the entire video mode and refreshto be reset on the next frame.
|
|
||||||
*/
|
*/
|
||||||
void
|
|
||||||
VID_Restart_f(void)
|
|
||||||
{
|
|
||||||
vid_fullscreen->modified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
VID_ListModes_f(void)
|
VID_ListModes_f(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
Com_Printf("Supported video modes (r_mode):\n");
|
Com_Printf("Supported video modes (r_mode):\n");
|
||||||
for(i=0; i<VID_NUM_MODES; ++i)
|
|
||||||
|
for (i = 0; i < VID_NUM_MODES; ++i)
|
||||||
{
|
{
|
||||||
Com_Printf(" %s\n", vid_modes[i].description);
|
Com_Printf(" %s\n", vid_modes[i].description);
|
||||||
}
|
}
|
||||||
Com_Printf(" Mode -1: r_customwidth x r_customheight\n");
|
Com_Printf(" Mode -1: r_customwidth x r_customheight\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns informations about the given mode.
|
||||||
|
*/
|
||||||
qboolean
|
qboolean
|
||||||
VID_GetModeInfo(int *width, int *height, int mode)
|
VID_GetModeInfo(int *width, int *height, int mode)
|
||||||
{
|
{
|
||||||
|
@ -159,6 +295,40 @@ VID_GetModeInfo(int *width, int *height, int mode)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --------
|
||||||
|
|
||||||
|
// Renderer load, restart and shutdown
|
||||||
|
// -----------------------------------
|
||||||
|
|
||||||
|
// Global console variables.
|
||||||
|
cvar_t *vid_gamma;
|
||||||
|
cvar_t *vid_fullscreen;
|
||||||
|
cvar_t *vid_renderer;
|
||||||
|
|
||||||
|
// Global video state, used throughout the client.
|
||||||
|
viddef_t viddef;
|
||||||
|
|
||||||
|
// Struct with the pointers exported by the renderer.
|
||||||
|
refexport_t re;
|
||||||
|
|
||||||
|
// Handle / pointer the the loaded renderer DLL.
|
||||||
|
void *reflib_handle = NULL;
|
||||||
|
|
||||||
|
// Is a renderer loaded and active?
|
||||||
|
qboolean ref_active = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: Not with vid_fullscreen...
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
VID_Restart_f(void)
|
||||||
|
{
|
||||||
|
vid_fullscreen->modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FIXME: This is only used by the softrenderer. Remove it.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
VID_NewWindow(int width, int height)
|
VID_NewWindow(int width, int height)
|
||||||
{
|
{
|
||||||
|
@ -167,266 +337,8 @@ VID_NewWindow(int width, int height)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function gets called once just before drawing each frame, and
|
* Shuts the renderer down and unloads it.
|
||||||
* it's sole purpose in life is to check to see if any of the video mode
|
|
||||||
* parameters have changed, and if they have to update the refresh
|
|
||||||
* and/or video mode to match.
|
|
||||||
*/
|
*/
|
||||||
void
|
|
||||||
VID_CheckChanges(void)
|
|
||||||
{
|
|
||||||
if (vid_fullscreen->modified)
|
|
||||||
{
|
|
||||||
S_StopAllSounds();
|
|
||||||
|
|
||||||
/* refresh has changed */
|
|
||||||
cl.refresh_prepped = false;
|
|
||||||
cl.cinematicpalette_active = false;
|
|
||||||
cls.disable_screen = true;
|
|
||||||
|
|
||||||
// Proceed to reboot the refresher
|
|
||||||
if(!VID_LoadRefresh())
|
|
||||||
{
|
|
||||||
if (strcmp(vid_renderer->string, "gl1") != 0)
|
|
||||||
{
|
|
||||||
Com_Printf("\n ... trying again with standard OpenGL1.x renderer ... \n\n");
|
|
||||||
Cvar_Set("vid_renderer", "gl1");
|
|
||||||
if (!VID_LoadRefresh())
|
|
||||||
{
|
|
||||||
Com_Error(ERR_FATAL, "Couldn't even load the gl1 fallback rendering backend!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Com_Error(ERR_FATAL, "Couldn't load a rendering backend!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cls.disable_screen = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern qboolean GLimp_Init(void);
|
|
||||||
|
|
||||||
void
|
|
||||||
VID_Init(void)
|
|
||||||
{
|
|
||||||
/* Create the video variables so we know how to start the graphics drivers */
|
|
||||||
vid_fullscreen = Cvar_Get("vid_fullscreen", "0", CVAR_ARCHIVE);
|
|
||||||
vid_gamma = Cvar_Get("vid_gamma", "1.2", CVAR_ARCHIVE);
|
|
||||||
vid_renderer = Cvar_Get("vid_renderer", "gl1", CVAR_ARCHIVE);
|
|
||||||
|
|
||||||
/* Add some console commands that we want to handle */
|
|
||||||
Cmd_AddCommand("vid_restart", VID_Restart_f);
|
|
||||||
Cmd_AddCommand("vid_listmodes", VID_ListModes_f);
|
|
||||||
|
|
||||||
/* Initialize the backend. */
|
|
||||||
if (!GLimp_Init())
|
|
||||||
{
|
|
||||||
Com_Error(ERR_FATAL, "Couldn't initialize the graphics subsystem!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Start the graphics mode and load refresh DLL */
|
|
||||||
VID_CheckChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
// called with image data of width*height pixel which comp bytes per pixel (must be 3 or 4 for RGB or RGBA)
|
|
||||||
// expects the pixels data to be row-wise, starting at top left
|
|
||||||
void VID_WriteScreenshot( int width, int height, int comp, const void* data )
|
|
||||||
{
|
|
||||||
char picname[80];
|
|
||||||
char checkname[MAX_OSPATH];
|
|
||||||
int i, success=0;
|
|
||||||
static const char* supportedFormats[] = { "tga", "bmp", "png", "jpg" };
|
|
||||||
static const int numFormats = sizeof(supportedFormats)/sizeof(supportedFormats[0]);
|
|
||||||
int format = 0; // 0=tga 1=bmp 2=png 3=jpg
|
|
||||||
int quality = 85;
|
|
||||||
int argc = Cmd_Argc();
|
|
||||||
const char* gameDir = FS_Gamedir();
|
|
||||||
|
|
||||||
/* FS_InitFilesystem() made sure the screenshots dir exists */
|
|
||||||
|
|
||||||
if(argc > 1)
|
|
||||||
{
|
|
||||||
const char* maybeFormat = Cmd_Argv(1);
|
|
||||||
|
|
||||||
for(i=0; i<numFormats; ++i)
|
|
||||||
{
|
|
||||||
if(Q_stricmp(maybeFormat, supportedFormats[i]) == 0)
|
|
||||||
{
|
|
||||||
format = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(i==numFormats)
|
|
||||||
{
|
|
||||||
Com_Printf("the (optional) second argument to 'screenshot' is the format, one of \"tga\", \"bmp\", \"png\", \"jpg\"\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(argc > 2)
|
|
||||||
{
|
|
||||||
const char* q = Cmd_Argv(2);
|
|
||||||
int qualityStrLen = strlen(q);
|
|
||||||
for(i=0; i<qualityStrLen; ++i)
|
|
||||||
{
|
|
||||||
if(q[i] < '0' || q[i] > '9')
|
|
||||||
{
|
|
||||||
Com_Printf("the (optional!) third argument to 'screenshot' is jpg quality, a number between 1 and 100\n");
|
|
||||||
Com_Printf(" or png compression level, between 0 and 9!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
quality = atoi(q);
|
|
||||||
if(format == 2) // png
|
|
||||||
{
|
|
||||||
if(quality < 0) quality = 0;
|
|
||||||
else if(quality > 9) quality = 9;
|
|
||||||
}
|
|
||||||
else if(format == 3) // jpg
|
|
||||||
{
|
|
||||||
if(quality < 1) quality = 1;
|
|
||||||
else if(quality > 100) quality = 100;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find a file name to save it to */
|
|
||||||
for (i = 0; i <= 9999; i++)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
Com_sprintf(checkname, sizeof(checkname), "%s/scrnshot/q2_%04d.%s", gameDir, i, supportedFormats[format]);
|
|
||||||
f = Q_fopen(checkname, "rb");
|
|
||||||
|
|
||||||
if (!f)
|
|
||||||
{
|
|
||||||
Com_sprintf(picname, sizeof(picname), "q2_%04d.%s", i, supportedFormats[format]);
|
|
||||||
break; /* file doesn't exist */
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == 10000)
|
|
||||||
{
|
|
||||||
Com_Printf("SCR_ScreenShot_f: Couldn't create a file\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(format) // 0=tga 1=bmp 2=png 3=jpg
|
|
||||||
{
|
|
||||||
case 0: success = stbi_write_tga(checkname, width, height, comp, data); break;
|
|
||||||
case 1: success = stbi_write_bmp(checkname, width, height, comp, data); break;
|
|
||||||
case 2:
|
|
||||||
stbi_write_png_compression_level = (quality < 10) ? quality : 7;
|
|
||||||
success = stbi_write_png(checkname, width, height, comp, data, 0);
|
|
||||||
break;
|
|
||||||
case 3: success = stbi_write_jpg(checkname, width, height, comp, data, quality); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(success)
|
|
||||||
{
|
|
||||||
Com_Printf("Wrote %s\n", picname);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Com_Printf("SCR_ScreenShot_f: Couldn't write %s\n", picname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Structure containing functions exported from refresh DLL
|
|
||||||
refexport_t re;
|
|
||||||
void *reflib_handle = NULL; // Handle to refresh DLL
|
|
||||||
qboolean ref_active = false; /* Is the refresher being used? */
|
|
||||||
|
|
||||||
void Key_MarkAllUp(void);
|
|
||||||
void VID_ShutdownRenderer(void);
|
|
||||||
|
|
||||||
extern qboolean GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight);
|
|
||||||
|
|
||||||
qboolean
|
|
||||||
VID_LoadRefresh(void)
|
|
||||||
{
|
|
||||||
refimport_t ri;
|
|
||||||
GetRefAPI_t GetRefAPI;
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
const char* lib_ext = "dylib";
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
const char* lib_ext = "dll";
|
|
||||||
#else
|
|
||||||
const char* lib_ext = "so";
|
|
||||||
#endif
|
|
||||||
char reflib_name[64] = {0};
|
|
||||||
char reflib_path[MAX_OSPATH] = {0};
|
|
||||||
|
|
||||||
// If the refresher is already active
|
|
||||||
// we'll shut it down
|
|
||||||
VID_ShutdownRenderer();
|
|
||||||
|
|
||||||
// Log it!
|
|
||||||
Com_Printf("----- refresher initialization -----\n");
|
|
||||||
|
|
||||||
snprintf(reflib_name, sizeof(reflib_name), "ref_%s.%s", vid_renderer->string, lib_ext);
|
|
||||||
snprintf(reflib_path, sizeof(reflib_path), "%s%s", Sys_GetBinaryDir(), reflib_name);
|
|
||||||
|
|
||||||
Com_Printf("LoadLibrary(%s)\n", reflib_name);
|
|
||||||
GetRefAPI = Sys_LoadLibrary(reflib_path, "GetRefAPI", &reflib_handle);
|
|
||||||
if(GetRefAPI == NULL)
|
|
||||||
{
|
|
||||||
Com_Error( ERR_FATAL, "Loading %s as renderer lib failed!", reflib_name );
|
|
||||||
Cvar_Set("vid_renderer", "gl1");
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ri.Cmd_AddCommand = Cmd_AddCommand;
|
|
||||||
ri.Cmd_RemoveCommand = Cmd_RemoveCommand;
|
|
||||||
ri.Cmd_Argc = Cmd_Argc;
|
|
||||||
ri.Cmd_Argv = Cmd_Argv;
|
|
||||||
ri.Cmd_ExecuteText = Cbuf_ExecuteText;
|
|
||||||
ri.Com_VPrintf = Com_VPrintf;
|
|
||||||
ri.Sys_Error = Com_Error;
|
|
||||||
ri.FS_LoadFile = FS_LoadFile;
|
|
||||||
ri.FS_FreeFile = FS_FreeFile;
|
|
||||||
ri.FS_Gamedir = FS_Gamedir;
|
|
||||||
ri.Cvar_Get = Cvar_Get;
|
|
||||||
ri.Cvar_Set = Cvar_Set;
|
|
||||||
ri.Cvar_SetValue = Cvar_SetValue;
|
|
||||||
ri.Vid_GetModeInfo = VID_GetModeInfo;
|
|
||||||
ri.Vid_MenuInit = VID_MenuInit;
|
|
||||||
ri.Vid_NewWindow = VID_NewWindow;
|
|
||||||
ri.Vid_WriteScreenshot = VID_WriteScreenshot;
|
|
||||||
|
|
||||||
ri.GLimp_InitGraphics = GLimp_InitGraphics;
|
|
||||||
|
|
||||||
re = GetRefAPI( ri );
|
|
||||||
|
|
||||||
// Declare the refresher as active
|
|
||||||
ref_active = true;
|
|
||||||
|
|
||||||
if (re.api_version != API_VERSION)
|
|
||||||
{
|
|
||||||
VID_ShutdownRenderer();
|
|
||||||
Com_Error (ERR_FATAL, "%s has incompatible api_version %d", reflib_name, re.api_version);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initiate the refresher
|
|
||||||
if (!re.Init())
|
|
||||||
{
|
|
||||||
VID_ShutdownRenderer(); // Isn't that just too bad? :(
|
|
||||||
Com_Printf("ERROR: Loading %s as rendering backend failed!\n", reflib_name);
|
|
||||||
Com_Printf("------------------------------------\n\n");
|
|
||||||
return false; // TODO: try again with default renderer?
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure that all key states are cleared */
|
|
||||||
Key_MarkAllUp();
|
|
||||||
|
|
||||||
Com_Printf("Successfully loaded %s as rendering backend\n", reflib_name);
|
|
||||||
Com_Printf("------------------------------------\n\n");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
VID_ShutdownRenderer(void)
|
VID_ShutdownRenderer(void)
|
||||||
{
|
{
|
||||||
|
@ -443,8 +355,189 @@ VID_ShutdownRenderer(void)
|
||||||
ref_active = false;
|
ref_active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void GLimp_Shutdown(void);
|
/*
|
||||||
|
* Loads and initializes a renderer.
|
||||||
|
*/
|
||||||
|
qboolean
|
||||||
|
VID_LoadRenderer(void)
|
||||||
|
{
|
||||||
|
refimport_t ri;
|
||||||
|
GetRefAPI_t GetRefAPI;
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
const char* lib_ext = "dylib";
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
const char* lib_ext = "dll";
|
||||||
|
#else
|
||||||
|
const char* lib_ext = "so";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char reflib_name[64] = {0};
|
||||||
|
char reflib_path[MAX_OSPATH] = {0};
|
||||||
|
|
||||||
|
// If the refresher is already active we need
|
||||||
|
// to shut it down before loading a new one
|
||||||
|
VID_ShutdownRenderer();
|
||||||
|
|
||||||
|
// Log what we're doing.
|
||||||
|
Com_Printf("----- refresher initialization -----\n");
|
||||||
|
|
||||||
|
snprintf(reflib_name, sizeof(reflib_name), "ref_%s.%s", vid_renderer->string, lib_ext);
|
||||||
|
snprintf(reflib_path, sizeof(reflib_path), "%s%s", Sys_GetBinaryDir(), reflib_name);
|
||||||
|
Com_Printf("LoadLibrary(%s)\n", reflib_name);
|
||||||
|
|
||||||
|
// Mkay, let's load the requested renderer.
|
||||||
|
GetRefAPI = Sys_LoadLibrary(reflib_path, "GetRefAPI", &reflib_handle);
|
||||||
|
|
||||||
|
// Okay, we couldn't load it. It's up to the
|
||||||
|
// caller to recover from this.
|
||||||
|
if (GetRefAPI == NULL)
|
||||||
|
{
|
||||||
|
Com_Printf("Loading %s as renderer lib failed!", reflib_path);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill in the struct exported to the renderer.
|
||||||
|
// FIXME: Do we really need all these?
|
||||||
|
ri.Cmd_AddCommand = Cmd_AddCommand;
|
||||||
|
ri.Cmd_Argc = Cmd_Argc;
|
||||||
|
ri.Cmd_Argv = Cmd_Argv;
|
||||||
|
ri.Cmd_ExecuteText = Cbuf_ExecuteText;
|
||||||
|
ri.Cmd_RemoveCommand = Cmd_RemoveCommand;
|
||||||
|
ri.Com_VPrintf = Com_VPrintf;
|
||||||
|
ri.Cvar_Get = Cvar_Get;
|
||||||
|
ri.Cvar_Set = Cvar_Set;
|
||||||
|
ri.Cvar_SetValue = Cvar_SetValue;
|
||||||
|
ri.FS_FreeFile = FS_FreeFile;
|
||||||
|
ri.FS_Gamedir = FS_Gamedir;
|
||||||
|
ri.FS_LoadFile = FS_LoadFile;
|
||||||
|
ri.GLimp_InitGraphics = GLimp_InitGraphics;
|
||||||
|
ri.Sys_Error = Com_Error;
|
||||||
|
ri.Vid_GetModeInfo = VID_GetModeInfo;
|
||||||
|
ri.Vid_MenuInit = VID_MenuInit;
|
||||||
|
ri.Vid_NewWindow = VID_NewWindow;
|
||||||
|
ri.Vid_WriteScreenshot = VID_WriteScreenshot;
|
||||||
|
|
||||||
|
// Exchange our export struct with the renderers import struct.
|
||||||
|
re = GetRefAPI(ri);
|
||||||
|
|
||||||
|
// Declare the refresher as active.
|
||||||
|
ref_active = true;
|
||||||
|
|
||||||
|
// Let's check if we've got a compatible renderer.
|
||||||
|
if (re.api_version != API_VERSION)
|
||||||
|
{
|
||||||
|
VID_ShutdownRenderer();
|
||||||
|
|
||||||
|
Com_Printf("%s has incompatible api_version %d!\n", reflib_name, re.api_version);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Everything seems okay, initialize it.
|
||||||
|
if (!re.Init())
|
||||||
|
{
|
||||||
|
VID_ShutdownRenderer();
|
||||||
|
|
||||||
|
Com_Printf("ERROR: Loading %s as rendering backend failed!\n", reflib_name);
|
||||||
|
Com_Printf("------------------------------------\n\n");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure that all key states are cleared */
|
||||||
|
Key_MarkAllUp();
|
||||||
|
|
||||||
|
Com_Printf("Successfully loaded %s as rendering backend\n", reflib_name);
|
||||||
|
Com_Printf("------------------------------------\n\n");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Checks if a renderer changes was requested and executes it.
|
||||||
|
* Inclusive fallback through all renderers. :)
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
VID_CheckChanges(void)
|
||||||
|
{
|
||||||
|
// FIXME: Not with vid_fullscreen
|
||||||
|
if (vid_fullscreen->modified)
|
||||||
|
{
|
||||||
|
// Stop sound, because the clients blocks while
|
||||||
|
// we're reloading the renderer. The sound system
|
||||||
|
// would screw up it's internal timings.
|
||||||
|
S_StopAllSounds();
|
||||||
|
|
||||||
|
// Reset the client side of the renderer state.
|
||||||
|
cl.refresh_prepped = false;
|
||||||
|
cl.cinematicpalette_active = false;
|
||||||
|
|
||||||
|
// More or less blocks the client.
|
||||||
|
cls.disable_screen = true;
|
||||||
|
|
||||||
|
// Mkay, let's try our luck.
|
||||||
|
while (!VID_LoadRenderer())
|
||||||
|
{
|
||||||
|
// We try: gl3 -> gl1 -> soft.
|
||||||
|
if (strcmp(vid_renderer->string, "gl3") == 0)
|
||||||
|
{
|
||||||
|
Com_Printf("Retrying with gl1...\n");
|
||||||
|
Cvar_Set("vid_renderer", "gl1");
|
||||||
|
}
|
||||||
|
else if (strcmp(vid_renderer->string, "gl1") == 0)
|
||||||
|
{
|
||||||
|
Com_Printf("Retrying with soft...\n");
|
||||||
|
Cvar_Set("vid_renderer", "soft");
|
||||||
|
}
|
||||||
|
else if (strcmp("vid_renderer", "soft") == 0)
|
||||||
|
{
|
||||||
|
// Sorry, no usable renderer found.
|
||||||
|
Com_Error(ERR_FATAL, "No usable renderer found!\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// User forced something stupid.
|
||||||
|
Com_Printf("Retrying with gl3...\n");
|
||||||
|
Cvar_Set("vid_renderer", "gl3");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unblock the client.
|
||||||
|
cls.disable_screen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initializes the video stuff.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
VID_Init(void)
|
||||||
|
{
|
||||||
|
// Console variables
|
||||||
|
vid_fullscreen = Cvar_Get("vid_gamma", "1.0", CVAR_ARCHIVE);
|
||||||
|
vid_fullscreen = Cvar_Get("vid_fullscreen", "0", CVAR_ARCHIVE);
|
||||||
|
vid_renderer = Cvar_Get("vid_renderer", "gl1", CVAR_ARCHIVE);
|
||||||
|
|
||||||
|
// Commands
|
||||||
|
Cmd_AddCommand("vid_restart", VID_Restart_f);
|
||||||
|
Cmd_AddCommand("vid_listmodes", VID_ListModes_f);
|
||||||
|
|
||||||
|
// Initializes the video backend. This is NOT the renderer
|
||||||
|
// itself, just the client side support stuff!
|
||||||
|
if (!GLimp_Init())
|
||||||
|
{
|
||||||
|
Com_Error(ERR_FATAL, "Couldn't initialize the graphics subsystem!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the renderer and get things going.
|
||||||
|
VID_CheckChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shuts the video stuff down.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
VID_Shutdown(void)
|
VID_Shutdown(void)
|
||||||
{
|
{
|
||||||
|
@ -452,12 +545,15 @@ VID_Shutdown(void)
|
||||||
GLimp_Shutdown();
|
GLimp_Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ======== wrappers for functions from refresh lib ========
|
// ----
|
||||||
|
|
||||||
|
// Wrappers for the functions provided by the renderer libs.
|
||||||
|
// =========================================================
|
||||||
|
|
||||||
void
|
void
|
||||||
R_BeginRegistration(char *map)
|
R_BeginRegistration(char *map)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
re.BeginRegistration(map);
|
re.BeginRegistration(map);
|
||||||
}
|
}
|
||||||
|
@ -466,27 +562,29 @@ R_BeginRegistration(char *map)
|
||||||
struct model_s*
|
struct model_s*
|
||||||
R_RegisterModel(char *name)
|
R_RegisterModel(char *name)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
return re.RegisterModel(name);
|
return re.RegisterModel(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct image_s*
|
struct image_s*
|
||||||
R_RegisterSkin(char *name)
|
R_RegisterSkin(char *name)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
return re.RegisterSkin(name);
|
return re.RegisterSkin(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
R_SetSky(char *name, float rotate, vec3_t axis)
|
R_SetSky(char *name, float rotate, vec3_t axis)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
re.SetSky(name, rotate, axis);
|
re.SetSky(name, rotate, axis);
|
||||||
}
|
}
|
||||||
|
@ -495,7 +593,7 @@ R_SetSky(char *name, float rotate, vec3_t axis)
|
||||||
void
|
void
|
||||||
R_EndRegistration(void)
|
R_EndRegistration(void)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
re.EndRegistration();
|
re.EndRegistration();
|
||||||
}
|
}
|
||||||
|
@ -504,7 +602,7 @@ R_EndRegistration(void)
|
||||||
void
|
void
|
||||||
R_RenderFrame(refdef_t *fd)
|
R_RenderFrame(refdef_t *fd)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
re.RenderFrame(fd);
|
re.RenderFrame(fd);
|
||||||
}
|
}
|
||||||
|
@ -513,10 +611,11 @@ R_RenderFrame(refdef_t *fd)
|
||||||
struct image_s*
|
struct image_s*
|
||||||
Draw_FindPic(char *name)
|
Draw_FindPic(char *name)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
return re.DrawFindPic(name);
|
return re.DrawFindPic(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,7 +623,7 @@ Draw_FindPic(char *name)
|
||||||
void
|
void
|
||||||
Draw_GetPicSize(int *w, int *h, char *name)
|
Draw_GetPicSize(int *w, int *h, char *name)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
re.DrawGetPicSize(w, h, name);
|
re.DrawGetPicSize(w, h, name);
|
||||||
}
|
}
|
||||||
|
@ -533,7 +632,7 @@ Draw_GetPicSize(int *w, int *h, char *name)
|
||||||
void
|
void
|
||||||
Draw_StretchPic(int x, int y, int w, int h, char *name)
|
Draw_StretchPic(int x, int y, int w, int h, char *name)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
re.DrawStretchPic(x, y, w, h, name);
|
re.DrawStretchPic(x, y, w, h, name);
|
||||||
}
|
}
|
||||||
|
@ -542,7 +641,7 @@ Draw_StretchPic(int x, int y, int w, int h, char *name)
|
||||||
void
|
void
|
||||||
Draw_PicScaled(int x, int y, char *pic, float factor)
|
Draw_PicScaled(int x, int y, char *pic, float factor)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
re.DrawPicScaled(x, y, pic, factor);
|
re.DrawPicScaled(x, y, pic, factor);
|
||||||
}
|
}
|
||||||
|
@ -551,7 +650,7 @@ Draw_PicScaled(int x, int y, char *pic, float factor)
|
||||||
void
|
void
|
||||||
Draw_CharScaled(int x, int y, int num, float scale)
|
Draw_CharScaled(int x, int y, int num, float scale)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
re.DrawCharScaled(x, y, num, scale);
|
re.DrawCharScaled(x, y, num, scale);
|
||||||
}
|
}
|
||||||
|
@ -560,7 +659,7 @@ Draw_CharScaled(int x, int y, int num, float scale)
|
||||||
void
|
void
|
||||||
Draw_TileClear(int x, int y, int w, int h, char *name)
|
Draw_TileClear(int x, int y, int w, int h, char *name)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
re.DrawTileClear(x, y, w, h, name);
|
re.DrawTileClear(x, y, w, h, name);
|
||||||
}
|
}
|
||||||
|
@ -569,7 +668,7 @@ Draw_TileClear(int x, int y, int w, int h, char *name)
|
||||||
void
|
void
|
||||||
Draw_Fill(int x, int y, int w, int h, int c)
|
Draw_Fill(int x, int y, int w, int h, int c)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
re.DrawFill(x, y, w, h, c);
|
re.DrawFill(x, y, w, h, c);
|
||||||
}
|
}
|
||||||
|
@ -578,7 +677,7 @@ Draw_Fill(int x, int y, int w, int h, int c)
|
||||||
void
|
void
|
||||||
Draw_FadeScreen(void)
|
Draw_FadeScreen(void)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
re.DrawFadeScreen();
|
re.DrawFadeScreen();
|
||||||
}
|
}
|
||||||
|
@ -587,7 +686,7 @@ Draw_FadeScreen(void)
|
||||||
void
|
void
|
||||||
Draw_StretchRaw(int x, int y, int w, int h, int cols, int rows, byte *data)
|
Draw_StretchRaw(int x, int y, int w, int h, int cols, int rows, byte *data)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
re.DrawStretchRaw(x, y, w, h, cols, rows, data);
|
re.DrawStretchRaw(x, y, w, h, cols, rows, data);
|
||||||
}
|
}
|
||||||
|
@ -596,7 +695,7 @@ Draw_StretchRaw(int x, int y, int w, int h, int cols, int rows, byte *data)
|
||||||
void
|
void
|
||||||
R_SetPalette(const unsigned char *palette)
|
R_SetPalette(const unsigned char *palette)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
re.SetPalette(palette);
|
re.SetPalette(palette);
|
||||||
}
|
}
|
||||||
|
@ -605,7 +704,7 @@ R_SetPalette(const unsigned char *palette)
|
||||||
void
|
void
|
||||||
R_BeginFrame(float camera_separation)
|
R_BeginFrame(float camera_separation)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
re.BeginFrame(camera_separation);
|
re.BeginFrame(camera_separation);
|
||||||
}
|
}
|
||||||
|
@ -623,9 +722,10 @@ R_EndFrame(void)
|
||||||
qboolean
|
qboolean
|
||||||
R_IsVSyncActive(void)
|
R_IsVSyncActive(void)
|
||||||
{
|
{
|
||||||
if(ref_active)
|
if (ref_active)
|
||||||
{
|
{
|
||||||
return re.IsVSyncActive();
|
return re.IsVSyncActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -355,9 +355,6 @@ IN_TranslateSDLtoQ2Key(unsigned int keysym)
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
extern void GLimp_GrabInput(qboolean grab);
|
|
||||||
extern int glimp_refreshRate;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Updates the input queue state. Called every
|
* Updates the input queue state. Called every
|
||||||
* frame by the client and does nearly all the
|
* frame by the client and does nearly all the
|
||||||
|
|
|
@ -246,8 +246,9 @@ GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight)
|
||||||
window = NULL;
|
window = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the window */
|
/* We need the window size for the menu, the HUD, etc. */
|
||||||
VID_NewWindow(width, height);
|
viddef.width = width;
|
||||||
|
viddef.height = height;
|
||||||
|
|
||||||
/* Let renderer prepare things (set OpenGL attributes) */
|
/* Let renderer prepare things (set OpenGL attributes) */
|
||||||
flags = re.PrepareForWindow();
|
flags = re.PrepareForWindow();
|
||||||
|
@ -292,8 +293,6 @@ GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight)
|
||||||
Cvar_SetValue("r_mode", 4);
|
Cvar_SetValue("r_mode", 4);
|
||||||
Cvar_SetValue("vid_fullscreen", 0);
|
Cvar_SetValue("vid_fullscreen", 0);
|
||||||
|
|
||||||
VID_NewWindow(width, height);
|
|
||||||
|
|
||||||
*pwidth = width = 640;
|
*pwidth = width = 640;
|
||||||
*pheight = height = 480;
|
*pheight = height = 480;
|
||||||
flags &= ~fs_flag;
|
flags &= ~fs_flag;
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
*
|
*
|
||||||
* =======================================================================
|
* =======================================================================
|
||||||
*
|
*
|
||||||
* ABI to the video oute driver
|
* API between client and renderer.
|
||||||
*
|
*
|
||||||
* =======================================================================
|
* =======================================================================
|
||||||
*/
|
*/
|
||||||
|
@ -27,17 +27,23 @@
|
||||||
#ifndef CL_VID_H
|
#ifndef CL_VID_H
|
||||||
#define CL_VID_H
|
#define CL_VID_H
|
||||||
|
|
||||||
|
#include "../../common/header/common.h"
|
||||||
|
|
||||||
|
// FIXME: Remove it, it's unused.
|
||||||
typedef struct vrect_s {
|
typedef struct vrect_s {
|
||||||
int x,y,width,height;
|
int x,y,width,height;
|
||||||
} vrect_t;
|
} vrect_t;
|
||||||
|
|
||||||
|
// Hold the video state.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int width, height; /* coordinates from main game */
|
int height;
|
||||||
|
int width;
|
||||||
} viddef_t;
|
} viddef_t;
|
||||||
|
|
||||||
extern viddef_t viddef; /* global video state */
|
// Global video state.
|
||||||
|
extern viddef_t viddef;
|
||||||
|
|
||||||
/* Video module initialisation, etc */
|
// Generic stuff.
|
||||||
void VID_Init(void);
|
void VID_Init(void);
|
||||||
void VID_Shutdown(void);
|
void VID_Shutdown(void);
|
||||||
void VID_CheckChanges(void);
|
void VID_CheckChanges(void);
|
||||||
|
@ -46,7 +52,13 @@ void VID_MenuInit(void);
|
||||||
void VID_MenuDraw(void);
|
void VID_MenuDraw(void);
|
||||||
const char *VID_MenuKey(int);
|
const char *VID_MenuKey(int);
|
||||||
|
|
||||||
void VID_NewWindow(int width, int height);
|
// Stuff provided by platform backend.
|
||||||
qboolean VID_GetModeInfo(int *width, int *height, int mode);
|
extern int glimp_refreshRate;
|
||||||
|
|
||||||
|
qboolean GLimp_Init(void);
|
||||||
|
void GLimp_Shutdown(void);
|
||||||
|
qboolean GLimp_InitGraphics(int fullscreen, int *pwidth, int *pheight);
|
||||||
|
void GLimp_GrabInput(qboolean grab);
|
||||||
|
int GLimp_GetRefreshRate(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue