vertex arrays renamed to varray_ and exposed to rest of engine
[divverent/darkplaces.git] / vid_shared.c
1
2 #include "quakedef.h"
3
4 // LordHavoc: these are only set in wgl
5 qboolean isG200 = false; // LordHavoc: the Matrox G200 can't do per pixel alpha, and it uses a D3D driver for GL... ugh...
6 qboolean isRagePro = false; // LordHavoc: the ATI Rage Pro has limitations with per pixel alpha (the color scaler does not apply to per pixel alpha images...), although not as bad as a G200.
7
8 // LordHavoc: GL_ARB_multitexture support
9 int gl_textureunits;
10 // LordHavoc: GL_ARB_texture_env_combine or GL_EXT_texture_env_combine support
11 int gl_combine_extension = false;
12 // LordHavoc: GL_EXT_compiled_vertex_array support
13 int gl_supportslockarrays = false;
14
15 // LordHavoc: if window is hidden, don't update screen
16 int vid_hidden = false;
17 // LordHavoc: if window is not the active window, don't hog as much CPU time,
18 // let go of the mouse, turn off sound, and restore system gamma ramps...
19 int vid_activewindow = true;
20
21 cvar_t vid_mode = {0, "vid_mode", "0"};
22 cvar_t vid_mouse = {CVAR_SAVE, "vid_mouse", "1"};
23 cvar_t vid_fullscreen = {0, "vid_fullscreen", "1"};
24 cvar_t gl_combine = {0, "gl_combine", "1"};
25
26 cvar_t in_pitch_min = {0, "in_pitch_min", "-90"};
27 cvar_t in_pitch_max = {0, "in_pitch_max", "90"};
28
29 cvar_t m_filter = {CVAR_SAVE, "m_filter","0"};
30
31 const char *gl_vendor;
32 const char *gl_renderer;
33 const char *gl_version;
34 const char *gl_extensions;
35
36 // GL_ARB_multitexture
37 void (GLAPIENTRY *qglMultiTexCoord2f) (GLenum, GLfloat, GLfloat);
38 void (GLAPIENTRY *qglActiveTexture) (GLenum);
39 void (GLAPIENTRY *qglClientActiveTexture) (GLenum);
40
41 // GL_EXT_compiled_vertex_array
42 void (GLAPIENTRY *qglLockArraysEXT) (GLint first, GLint count);
43 void (GLAPIENTRY *qglUnlockArraysEXT) (void);
44
45
46 // general GL functions
47
48 void (GLAPIENTRY *qglClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
49
50 void (GLAPIENTRY *qglClear)(GLbitfield mask);
51
52 //void (GLAPIENTRY *qglAlphaFunc)(GLenum func, GLclampf ref);
53 void (GLAPIENTRY *qglBlendFunc)(GLenum sfactor, GLenum dfactor);
54 void (GLAPIENTRY *qglCullFace)(GLenum mode);
55
56 void (GLAPIENTRY *qglDrawBuffer)(GLenum mode);
57 void (GLAPIENTRY *qglReadBuffer)(GLenum mode);
58 void (GLAPIENTRY *qglEnable)(GLenum cap);
59 void (GLAPIENTRY *qglDisable)(GLenum cap);
60 //GLboolean GLAPIENTRY *qglIsEnabled)(GLenum cap);
61
62 void (GLAPIENTRY *qglEnableClientState)(GLenum cap);
63 void (GLAPIENTRY *qglDisableClientState)(GLenum cap);
64
65 //void (GLAPIENTRY *qglGetBooleanv)(GLenum pname, GLboolean *params);
66 //void (GLAPIENTRY *qglGetDoublev)(GLenum pname, GLdouble *params);
67 //void (GLAPIENTRY *qglGetFloatv)(GLenum pname, GLfloat *params);
68 void (GLAPIENTRY *qglGetIntegerv)(GLenum pname, GLint *params);
69
70 GLenum (GLAPIENTRY *qglGetError)(void);
71 const GLubyte* (GLAPIENTRY *qglGetString)(GLenum name);
72 void (GLAPIENTRY *qglFinish)(void);
73 void (GLAPIENTRY *qglFlush)(void);
74
75 void (GLAPIENTRY *qglClearDepth)(GLclampd depth);
76 void (GLAPIENTRY *qglDepthFunc)(GLenum func);
77 void (GLAPIENTRY *qglDepthMask)(GLboolean flag);
78 void (GLAPIENTRY *qglDepthRange)(GLclampd near_val, GLclampd far_val);
79
80 void (GLAPIENTRY *qglDrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
81 void (GLAPIENTRY *qglDrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
82 void (GLAPIENTRY *qglVertexPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
83 //void (GLAPIENTRY *qglNormalPointer)(GLenum type, GLsizei stride, const GLvoid *ptr);
84 void (GLAPIENTRY *qglColorPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
85 void (GLAPIENTRY *qglTexCoordPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
86 void (GLAPIENTRY *qglArrayElement)(GLint i);
87
88 void (GLAPIENTRY *qglColor4ub)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
89 void (GLAPIENTRY *qglTexCoord2f)(GLfloat s, GLfloat t);
90 void (GLAPIENTRY *qglVertex2f)(GLfloat x, GLfloat y);
91 void (GLAPIENTRY *qglVertex3f)(GLfloat x, GLfloat y, GLfloat z);
92 void (GLAPIENTRY *qglBegin)(GLenum mode);
93 void (GLAPIENTRY *qglEnd)(void);
94
95 void (GLAPIENTRY *qglMatrixMode)(GLenum mode);
96 void (GLAPIENTRY *qglOrtho)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val);
97 void (GLAPIENTRY *qglFrustum)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val);
98 void (GLAPIENTRY *qglViewport)(GLint x, GLint y, GLsizei width, GLsizei height);
99 //void (GLAPIENTRY *qglPushMatrix)(void);
100 //void (GLAPIENTRY *qglPopMatrix)(void);
101 void (GLAPIENTRY *qglLoadIdentity)(void);
102 //void (GLAPIENTRY *qglLoadMatrixd)(const GLdouble *m);
103 //void (GLAPIENTRY *qglLoadMatrixf)(const GLfloat *m);
104 //void (GLAPIENTRY *qglMultMatrixd)(const GLdouble *m);
105 //void (GLAPIENTRY *qglMultMatrixf)(const GLfloat *m);
106 //void (GLAPIENTRY *qglRotated)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
107 void (GLAPIENTRY *qglRotatef)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
108 //void (GLAPIENTRY *qglScaled)(GLdouble x, GLdouble y, GLdouble z);
109 //void (GLAPIENTRY *qglScalef)(GLfloat x, GLfloat y, GLfloat z);
110 //void (GLAPIENTRY *qglTranslated)(GLdouble x, GLdouble y, GLdouble z);
111 void (GLAPIENTRY *qglTranslatef)(GLfloat x, GLfloat y, GLfloat z);
112
113 void (GLAPIENTRY *qglReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
114
115 //void (GLAPIENTRY *qglStencilFunc)(GLenum func, GLint ref, GLuint mask);
116 //void (GLAPIENTRY *qglStencilMask)(GLuint mask);
117 //void (GLAPIENTRY *qglStencilOp)(GLenum fail, GLenum zfail, GLenum zpass);
118 //void (GLAPIENTRY *qglClearStencil)(GLint s);
119
120 //void (GLAPIENTRY *qglTexEnvf)(GLenum target, GLenum pname, GLfloat param);
121 void (GLAPIENTRY *qglTexEnvi)(GLenum target, GLenum pname, GLint param);
122
123 //void (GLAPIENTRY *qglTexParameterf)(GLenum target, GLenum pname, GLfloat param);
124 void (GLAPIENTRY *qglTexParameteri)(GLenum target, GLenum pname, GLint param);
125
126 void (GLAPIENTRY *qglBindTexture)(GLenum target, GLuint texture);
127 void (GLAPIENTRY *qglTexImage2D)(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
128 void (GLAPIENTRY *qglTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
129 void (GLAPIENTRY *qglDeleteTextures)(GLsizei n, const GLuint *textures);
130
131 void (GLAPIENTRY *qglDrawRangeElementsEXT)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
132
133 //void (GLAPIENTRY *qglColorTableEXT)(int, int, int, int, int, const void *);
134
135 #if WIN32
136 int (WINAPI *qwglChoosePixelFormat)(HDC, CONST PIXELFORMATDESCRIPTOR *);
137 int (WINAPI *qwglDescribePixelFormat)(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR);
138 //int (WINAPI *qwglGetPixelFormat)(HDC);
139 BOOL (WINAPI *qwglSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *);
140 BOOL (WINAPI *qwglSwapBuffers)(HDC);
141 HGLRC (WINAPI *qwglCreateContext)(HDC);
142 BOOL (WINAPI *qwglDeleteContext)(HGLRC);
143 PROC (WINAPI *qwglGetProcAddress)(LPCSTR);
144 BOOL (WINAPI *qwglMakeCurrent)(HDC, HGLRC);
145 //BOOL (WINAPI *qwglSwapIntervalEXT)(int interval);
146 #endif
147
148
149 typedef struct
150 {
151         char *name;
152         void **funcvariable;
153 }
154 gl_extensionfunctionlist_t;
155
156 typedef struct
157 {
158         char *name;
159         gl_extensionfunctionlist_t *funcs;
160         int *enablevariable;
161         char *disableparm;
162 }
163 gl_extensioninfo_t;
164
165 #if WIN32
166 static gl_extensionfunctionlist_t wglfuncs[] =
167 {
168         {"wglChoosePixelFormat", (void **) &qwglChoosePixelFormat},
169         {"wglDescribePixelFormat", (void **) &qwglDescribePixelFormat},
170 //      {"wglGetPixelFormat", (void **) &qwglGetPixelFormat},
171         {"wglSetPixelFormat", (void **) &qwglSetPixelFormat},
172         {"wglSwapBuffers", (void **) &qwglSwapBuffers},
173         {"wglCreateContext", (void **) &qwglCreateContext},
174         {"wglDeleteContext", (void **) &qwglDeleteContext},
175         {"wglGetProcAddress", (void **) &qwglGetProcAddress},
176         {"wglMakeCurrent", (void **) &qwglMakeCurrent},
177         {NULL, NULL}
178 };
179
180 /*
181 static gl_extensionfunctionlist_t wglswapintervalfuncs[] =
182 {
183         {"wglSwapIntervalEXT", (void **) &qwglSwapIntervalEXT},
184         {NULL, NULL}
185 };
186 */
187 #endif
188
189 static gl_extensionfunctionlist_t opengl110funcs[] =
190 {
191         {"glClearColor", (void **) &qglClearColor},
192         {"glClear", (void **) &qglClear},
193 //      {"glAlphaFunc", (void **) &qglAlphaFunc},
194         {"glBlendFunc", (void **) &qglBlendFunc},
195         {"glCullFace", (void **) &qglCullFace},
196         {"glDrawBuffer", (void **) &qglDrawBuffer},
197         {"glReadBuffer", (void **) &qglReadBuffer},
198         {"glEnable", (void **) &qglEnable},
199         {"glDisable", (void **) &qglDisable},
200 //      {"glIsEnabled", (void **) &qglIsEnabled},
201         {"glEnableClientState", (void **) &qglEnableClientState},
202         {"glDisableClientState", (void **) &qglDisableClientState},
203 //      {"glGetBooleanv", (void **) &qglGetBooleanv},
204 //      {"glGetDoublev", (void **) &qglGetDoublev},
205 //      {"glGetFloatv", (void **) &qglGetFloatv},
206         {"glGetIntegerv", (void **) &qglGetIntegerv},
207         {"glGetError", (void **) &qglGetError},
208         {"glGetString", (void **) &qglGetString},
209         {"glFinish", (void **) &qglFinish},
210         {"glFlush", (void **) &qglFlush},
211         {"glClearDepth", (void **) &qglClearDepth},
212         {"glDepthFunc", (void **) &qglDepthFunc},
213         {"glDepthMask", (void **) &qglDepthMask},
214         {"glDepthRange", (void **) &qglDepthRange},
215         {"glDrawElements", (void **) &qglDrawElements},
216         {"glVertexPointer", (void **) &qglVertexPointer},
217 //      {"glNormalPointer", (void **) &qglNormalPointer},
218         {"glColorPointer", (void **) &qglColorPointer},
219         {"glTexCoordPointer", (void **) &qglTexCoordPointer},
220         {"glArrayElement", (void **) &qglArrayElement},
221         {"glColor4ub", (void **) &qglColor4ub},
222         {"glTexCoord2f", (void **) &qglTexCoord2f},
223         {"glVertex2f", (void **) &qglVertex2f},
224         {"glVertex3f", (void **) &qglVertex3f},
225         {"glBegin", (void **) &qglBegin},
226         {"glEnd", (void **) &qglEnd},
227         {"glMatrixMode", (void **) &qglMatrixMode},
228         {"glOrtho", (void **) &qglOrtho},
229         {"glFrustum", (void **) &qglFrustum},
230         {"glViewport", (void **) &qglViewport},
231 //      {"glPushMatrix", (void **) &qglPushMatrix},
232 //      {"glPopMatrix", (void **) &qglPopMatrix},
233         {"glLoadIdentity", (void **) &qglLoadIdentity},
234 //      {"glLoadMatrixd", (void **) &qglLoadMatrixd},
235 //      {"glLoadMatrixf", (void **) &qglLoadMatrixf},
236 //      {"glMultMatrixd", (void **) &qglMultMatrixd},
237 //      {"glMultMatrixf", (void **) &qglMultMatrixf},
238 //      {"glRotated", (void **) &qglRotated},
239         {"glRotatef", (void **) &qglRotatef},
240 //      {"glScaled", (void **) &qglScaled},
241 //      {"glScalef", (void **) &qglScalef},
242 //      {"glTranslated", (void **) &qglTranslated},
243         {"glTranslatef", (void **) &qglTranslatef},
244         {"glReadPixels", (void **) &qglReadPixels},
245 //      {"glStencilFunc", (void **) &qglStencilFunc},
246 //      {"glStencilMask", (void **) &qglStencilMask},
247 //      {"glStencilOp", (void **) &qglStencilOp},
248 //      {"glClearStencil", (void **) &qglClearStencil},
249 //      {"glTexEnvf", (void **) &qglTexEnvf},
250         {"glTexEnvi", (void **) &qglTexEnvi},
251 //      {"glTexParameterf", (void **) &qglTexParameterf},
252         {"glTexParameteri", (void **) &qglTexParameteri},
253         {"glBindTexture", (void **) &qglBindTexture},
254         {"glTexImage2D", (void **) &qglTexImage2D},
255         {"glTexSubImage2D", (void **) &qglTexSubImage2D},
256         {"glDeleteTextures", (void **) &qglDeleteTextures},
257         {NULL, NULL}
258 };
259
260 static gl_extensionfunctionlist_t drawrangeelementsfuncs[] =
261 {
262         {"glDrawRangeElements", (void **) &qglDrawRangeElements},
263         {NULL, NULL}
264 };
265
266 static gl_extensionfunctionlist_t drawrangeelementsextfuncs[] =
267 {
268         {"glDrawRangeElementsEXT", (void **) &qglDrawRangeElementsEXT},
269         {NULL, NULL}
270 };
271
272 static gl_extensionfunctionlist_t multitexturefuncs[] =
273 {
274         {"glMultiTexCoord2fARB", (void **) &qglMultiTexCoord2f},
275         {"glActiveTextureARB", (void **) &qglActiveTexture},
276         {"glClientActiveTextureARB", (void **) &qglClientActiveTexture},
277         {NULL, NULL}
278 };
279
280 static gl_extensionfunctionlist_t compiledvertexarrayfuncs[] =
281 {
282         {"glLockArraysEXT", (void **) &qglLockArraysEXT},
283         {"glUnlockArraysEXT", (void **) &qglUnlockArraysEXT},
284         {NULL, NULL}
285 };
286
287 #ifndef WIN32
288 #include <dlfcn.h>
289 #endif
290
291 #ifdef WIN32
292 static HINSTANCE gldll;
293 #else
294 static void *prjobj = NULL;
295 #endif
296
297 void GL_OpenLibrary(void)
298 {
299 #ifdef WIN32
300         if (gldll)
301                 FreeLibrary(gldll);
302         if (!(gldll = LoadLibrary("opengl32.dll")))
303                 Sys_Error("Unable to LoadLibrary opengl32.dll\n");
304 #else
305         if (prjobj)
306                 dlclose(prjobj);
307         if (!(prjobj = dlopen("libGL.so.1", RTLD_LAZY)))
308                 Sys_Error("Unable to open symbol list for libGL.so.1\n");
309 #endif
310 }
311
312 void GL_CloseLibrary(void)
313 {
314 #ifdef WIN32
315         FreeLibrary(gldll);
316         gldll = 0;
317 #else
318         if (prjobj)
319                 dlclose(prjobj);
320         prjobj = NULL;
321 #endif
322 }
323
324 void *GL_GetProcAddress(char *name)
325 {
326         void *p = NULL;
327 #ifdef WIN32
328         if (qwglGetProcAddress != NULL)
329                 p = (void *) qwglGetProcAddress(name);
330         if (p == NULL)
331                 p = (void *) GetProcAddress(gldll, name);
332 #else
333         p = (void *) dlsym(prjobj, name);
334 #endif
335         return p;
336 }
337
338 static int gl_checkextension(char *name, gl_extensionfunctionlist_t *funcs, char *disableparm, int silent)
339 {
340         int failed = false;
341         gl_extensionfunctionlist_t *func;
342
343         Con_Printf("checking for %s...  ", name);
344
345         for (func = funcs;func && func->name;func++)
346                 *func->funcvariable = NULL;
347
348         if (disableparm && COM_CheckParm(disableparm))
349         {
350                 Con_Printf("disabled by commandline\n");
351                 return false;
352         }
353
354         if (strncmp(name, "GL_", 3) || strstr(gl_extensions, name))
355         {
356                 for (func = funcs;func && func->name != NULL;func++)
357                 {
358                         // functions are cleared before all the extensions are evaluated
359                         if (!(*func->funcvariable = (void *) GL_GetProcAddress(func->name)))
360                         {
361                                 if (!silent)
362                                         Con_Printf("missing function \"%s\" - broken driver!\n", func->name);
363                                 failed = true;
364                         }
365                 }
366                 // delay the return so it prints all missing functions
367                 if (failed)
368                         return false;
369                 Con_Printf("enabled\n");
370                 return true;
371         }
372         else
373         {
374                 Con_Printf("not detected\n");
375                 return false;
376         }
377 }
378
379 void VID_CheckExtensions(void)
380 {
381         gl_vendor = NULL;
382         gl_renderer = NULL;
383         gl_version = NULL;
384         gl_extensions = NULL;
385
386         Con_Printf("Opening OpenGL library to retrieve functions\n");
387
388         gl_combine_extension = false;
389         gl_supportslockarrays = false;
390         gl_textureunits = 1;
391
392 #if WIN32
393         if (!gl_checkextension("wgl", wglfuncs, NULL, false))
394                 Sys_Error("wgl functions not found\n");
395         //gl_checkextension("wglSwapIntervalEXT", wglswapintervalfuncs, NULL, false);
396 #endif
397
398         if (!gl_checkextension("OpenGL 1.1.0", opengl110funcs, NULL, false))
399                 Sys_Error("OpenGL 1.1.0 functions not found\n");
400
401         gl_vendor = qglGetString (GL_VENDOR);
402         gl_renderer = qglGetString (GL_RENDERER);
403         gl_version = qglGetString (GL_VERSION);
404         gl_extensions = qglGetString (GL_EXTENSIONS);
405
406         Con_Printf ("GL_VENDOR: %s\n", gl_vendor);
407         Con_Printf ("GL_RENDERER: %s\n", gl_renderer);
408         Con_Printf ("GL_VERSION: %s\n", gl_version);
409         Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions);
410
411         Con_Printf("Checking OpenGL extensions...\n");
412
413         if (!gl_checkextension("glDrawRangeElements", drawrangeelementsfuncs, "-nodrawrangeelements", true))
414                 gl_checkextension("GL_EXT_draw_range_elements", drawrangeelementsextfuncs, "-nodrawrangeelements", false);
415
416         if (gl_checkextension("GL_ARB_multitexture", multitexturefuncs, "-nomtex", false))
417         {
418                 qglGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_textureunits);
419                 if (gl_textureunits > 1)
420                         gl_combine_extension = gl_checkextension("GL_ARB_texture_env_combine", NULL, "-nocombine", false) || gl_checkextension("GL_EXT_texture_env_combine", NULL, "-nocombine", false);
421                 else
422                 {
423                         Con_Printf("GL_ARB_multitexture with less than 2 units? - BROKEN DRIVER!\n");
424                         gl_textureunits = 1; // for sanity sake, make sure it's not 0
425                 }
426         }
427
428         gl_supportslockarrays = gl_checkextension("GL_EXT_compiled_vertex_array", compiledvertexarrayfuncs, "-nocva", false);
429
430         // we don't care if it's an extension or not, they are identical functions, so keep it simple in the rendering code
431         if (qglDrawRangeElements == NULL)
432                 qglDrawRangeElements = qglDrawRangeElementsEXT;
433 }
434
435 void Force_CenterView_f (void)
436 {
437         cl.viewangles[PITCH] = 0;
438 }
439
440 void IN_PreMove(void)
441 {
442 }
443
444 void CL_AdjustAngles(void);
445 void IN_PostMove(void)
446 {
447         // clamp after the move as well to prevent messed up rendering angles
448         CL_AdjustAngles();
449 }
450
451 void IN_Mouse(usercmd_t *cmd, float mx, float my)
452 {
453         int mouselook = (in_mlook.state & 1) || freelook.integer;
454         float mouse_x, mouse_y;
455         static float old_mouse_x = 0, old_mouse_y = 0;
456
457         if (m_filter.integer)
458         {
459                 mouse_x = (mx + old_mouse_x) * 0.5;
460                 mouse_y = (my + old_mouse_y) * 0.5;
461         }
462         else
463         {
464                 mouse_x = mx;
465                 mouse_y = my;
466         }
467
468         old_mouse_x = mx;
469         old_mouse_y = my;
470
471         // LordHavoc: viewzoom affects mouse sensitivity for sniping
472         mouse_x *= sensitivity.value * cl.viewzoom;
473         mouse_y *= sensitivity.value * cl.viewzoom;
474
475         // Add mouse X/Y movement to cmd
476         if ((in_strafe.state & 1) || (lookstrafe.integer && mouselook))
477                 cmd->sidemove += m_side.value * mouse_x;
478         else
479                 cl.viewangles[YAW] -= m_yaw.value * mouse_x;
480
481         if (mouselook)
482                 V_StopPitchDrift();
483
484         if (mouselook && !(in_strafe.state & 1))
485                 cl.viewangles[PITCH] += m_pitch.value * mouse_y;
486         else
487         {
488                 if ((in_strafe.state & 1) && noclip_anglehack)
489                         cmd->upmove -= m_forward.value * mouse_y;
490                 else
491                         cmd->forwardmove -= m_forward.value * mouse_y;
492         }
493 }
494
495 void VID_InitCvars(void)
496 {
497         Cvar_RegisterVariable(&vid_mode);
498         Cvar_RegisterVariable(&vid_mouse);
499         Cvar_RegisterVariable(&vid_fullscreen);
500         Cvar_RegisterVariable(&gl_combine);
501         Cvar_RegisterVariable(&in_pitch_min);
502         Cvar_RegisterVariable(&in_pitch_max);
503         Cvar_RegisterVariable(&m_filter);
504         Cmd_AddCommand("force_centerview", Force_CenterView_f);
505 }
506