+ int failed = false;
+ const dllfunction_t *func;
+
+ Con_Printf("checking for %s... ", name);
+
+ for (func = funcs;func && func->name;func++)
+ *func->funcvariable = NULL;
+
+ if (disableparm && (COM_CheckParm(disableparm) || COM_CheckParm("-safe")))
+ {
+ Con_Print("disabled by commandline\n");
+ return false;
+ }
+
+ if (strstr(gl_extensions, name) || strstr(gl_platformextensions, name) || (strncmp(name, "GL_", 3) && strncmp(name, "WGL_", 4) && strncmp(name, "GLX_", 4) && strncmp(name, "AGL_", 4)))
+ {
+ for (func = funcs;func && func->name != NULL;func++)
+ {
+ // functions are cleared before all the extensions are evaluated
+ if (!(*func->funcvariable = (void *) GL_GetProcAddress(func->name)))
+ {
+ if (!silent)
+ Con_Printf("OpenGL extension \"%s\" is missing function \"%s\" - broken driver!\n", name, func->name);
+ failed = true;
+ }
+ }
+ // delay the return so it prints all missing functions
+ if (failed)
+ return false;
+ Con_Print("enabled\n");
+ return true;
+ }
+ else
+ {
+ Con_Print("not detected\n");
+ return false;
+ }
+}
+
+static dllfunction_t opengl110funcs[] =
+{
+ {"glClearColor", (void **) &qglClearColor},
+ {"glClear", (void **) &qglClear},
+ {"glAlphaFunc", (void **) &qglAlphaFunc},
+ {"glBlendFunc", (void **) &qglBlendFunc},
+ {"glCullFace", (void **) &qglCullFace},
+ {"glDrawBuffer", (void **) &qglDrawBuffer},
+ {"glReadBuffer", (void **) &qglReadBuffer},
+ {"glEnable", (void **) &qglEnable},
+ {"glDisable", (void **) &qglDisable},
+ {"glIsEnabled", (void **) &qglIsEnabled},
+ {"glEnableClientState", (void **) &qglEnableClientState},
+ {"glDisableClientState", (void **) &qglDisableClientState},
+ {"glGetBooleanv", (void **) &qglGetBooleanv},
+ {"glGetDoublev", (void **) &qglGetDoublev},
+ {"glGetFloatv", (void **) &qglGetFloatv},
+ {"glGetIntegerv", (void **) &qglGetIntegerv},
+ {"glGetError", (void **) &qglGetError},
+ {"glGetString", (void **) &qglGetString},
+ {"glFinish", (void **) &qglFinish},
+ {"glFlush", (void **) &qglFlush},
+ {"glClearDepth", (void **) &qglClearDepth},
+ {"glDepthFunc", (void **) &qglDepthFunc},
+ {"glDepthMask", (void **) &qglDepthMask},
+ {"glDepthRange", (void **) &qglDepthRange},
+ {"glDrawElements", (void **) &qglDrawElements},
+ {"glColorMask", (void **) &qglColorMask},
+ {"glVertexPointer", (void **) &qglVertexPointer},
+ {"glNormalPointer", (void **) &qglNormalPointer},
+ {"glColorPointer", (void **) &qglColorPointer},
+ {"glTexCoordPointer", (void **) &qglTexCoordPointer},
+ {"glArrayElement", (void **) &qglArrayElement},
+ {"glColor4f", (void **) &qglColor4f},
+ {"glTexCoord1f", (void **) &qglTexCoord1f},
+ {"glTexCoord2f", (void **) &qglTexCoord2f},
+ {"glTexCoord3f", (void **) &qglTexCoord3f},
+ {"glTexCoord4f", (void **) &qglTexCoord4f},
+ {"glVertex2f", (void **) &qglVertex2f},
+ {"glVertex3f", (void **) &qglVertex3f},
+ {"glBegin", (void **) &qglBegin},
+ {"glEnd", (void **) &qglEnd},
+ {"glMatrixMode", (void **) &qglMatrixMode},
+ {"glOrtho", (void **) &qglOrtho},
+ {"glFrustum", (void **) &qglFrustum},
+ {"glViewport", (void **) &qglViewport},
+ {"glPushMatrix", (void **) &qglPushMatrix},
+ {"glPopMatrix", (void **) &qglPopMatrix},
+ {"glLoadIdentity", (void **) &qglLoadIdentity},
+ {"glLoadMatrixd", (void **) &qglLoadMatrixd},
+ {"glLoadMatrixf", (void **) &qglLoadMatrixf},
+ {"glMultMatrixd", (void **) &qglMultMatrixd},
+ {"glMultMatrixf", (void **) &qglMultMatrixf},
+ {"glRotated", (void **) &qglRotated},
+ {"glRotatef", (void **) &qglRotatef},
+ {"glScaled", (void **) &qglScaled},
+ {"glScalef", (void **) &qglScalef},
+ {"glTranslated", (void **) &qglTranslated},
+ {"glTranslatef", (void **) &qglTranslatef},
+ {"glReadPixels", (void **) &qglReadPixels},
+ {"glStencilFunc", (void **) &qglStencilFunc},
+ {"glStencilMask", (void **) &qglStencilMask},
+ {"glStencilOp", (void **) &qglStencilOp},
+ {"glClearStencil", (void **) &qglClearStencil},
+ {"glTexEnvf", (void **) &qglTexEnvf},
+ {"glTexEnvfv", (void **) &qglTexEnvfv},
+ {"glTexEnvi", (void **) &qglTexEnvi},
+ {"glTexParameterf", (void **) &qglTexParameterf},
+ {"glTexParameterfv", (void **) &qglTexParameterfv},
+ {"glTexParameteri", (void **) &qglTexParameteri},
+ {"glPixelStoref", (void **) &qglPixelStoref},
+ {"glPixelStorei", (void **) &qglPixelStorei},
+ {"glGenTextures", (void **) &qglGenTextures},
+ {"glDeleteTextures", (void **) &qglDeleteTextures},
+ {"glBindTexture", (void **) &qglBindTexture},
+// {"glPrioritizeTextures", (void **) &qglPrioritizeTextures},
+// {"glAreTexturesResident", (void **) &qglAreTexturesResident},
+ {"glIsTexture", (void **) &qglIsTexture},
+ {"glTexImage1D", (void **) &qglTexImage1D},
+ {"glTexImage2D", (void **) &qglTexImage2D},
+ {"glTexSubImage1D", (void **) &qglTexSubImage1D},
+ {"glTexSubImage2D", (void **) &qglTexSubImage2D},
+ {"glCopyTexImage1D", (void **) &qglCopyTexImage1D},
+ {"glCopyTexImage2D", (void **) &qglCopyTexImage2D},
+ {"glCopyTexSubImage1D", (void **) &qglCopyTexSubImage1D},
+ {"glCopyTexSubImage2D", (void **) &qglCopyTexSubImage2D},
+ {"glScissor", (void **) &qglScissor},
+ {"glPolygonOffset", (void **) &qglPolygonOffset},
+ {NULL, NULL}
+};
+
+static dllfunction_t drawrangeelementsfuncs[] =
+{
+ {"glDrawRangeElements", (void **) &qglDrawRangeElements},
+ {NULL, NULL}
+};
+
+static dllfunction_t drawrangeelementsextfuncs[] =
+{
+ {"glDrawRangeElementsEXT", (void **) &qglDrawRangeElementsEXT},
+ {NULL, NULL}
+};
+
+static dllfunction_t multitexturefuncs[] =
+{
+ {"glMultiTexCoord1fARB", (void **) &qglMultiTexCoord1f},
+ {"glMultiTexCoord2fARB", (void **) &qglMultiTexCoord2f},
+ {"glMultiTexCoord3fARB", (void **) &qglMultiTexCoord3f},
+ {"glMultiTexCoord4fARB", (void **) &qglMultiTexCoord4f},
+ {"glActiveTextureARB", (void **) &qglActiveTexture},
+ {"glClientActiveTextureARB", (void **) &qglClientActiveTexture},
+ {NULL, NULL}
+};
+
+static dllfunction_t compiledvertexarrayfuncs[] =
+{
+ {"glLockArraysEXT", (void **) &qglLockArraysEXT},
+ {"glUnlockArraysEXT", (void **) &qglUnlockArraysEXT},
+ {NULL, NULL}
+};
+
+static dllfunction_t texture3dextfuncs[] =
+{
+ {"glTexImage3DEXT", (void **) &qglTexImage3D},
+ {"glTexSubImage3DEXT", (void **) &qglTexSubImage3D},
+ {"glCopyTexSubImage3DEXT", (void **) &qglCopyTexSubImage3D},
+ {NULL, NULL}
+};
+
+static dllfunction_t stenciltwosidefuncs[] =
+{
+ {"glActiveStencilFaceEXT", (void **) &qglActiveStencilFaceEXT},
+ {NULL, NULL}
+};
+
+static dllfunction_t shaderobjectsfuncs[] =
+{
+ {"glDeleteObjectARB", (void **) &qglDeleteObjectARB},
+ {"glGetHandleARB", (void **) &qglGetHandleARB},
+ {"glDetachObjectARB", (void **) &qglDetachObjectARB},
+ {"glCreateShaderObjectARB", (void **) &qglCreateShaderObjectARB},
+ {"glShaderSourceARB", (void **) &qglShaderSourceARB},
+ {"glCompileShaderARB", (void **) &qglCompileShaderARB},
+ {"glCreateProgramObjectARB", (void **) &qglCreateProgramObjectARB},
+ {"glAttachObjectARB", (void **) &qglAttachObjectARB},
+ {"glLinkProgramARB", (void **) &qglLinkProgramARB},
+ {"glUseProgramObjectARB", (void **) &qglUseProgramObjectARB},
+ {"glValidateProgramARB", (void **) &qglValidateProgramARB},
+ {"glUniform1fARB", (void **) &qglUniform1fARB},
+ {"glUniform2fARB", (void **) &qglUniform2fARB},
+ {"glUniform3fARB", (void **) &qglUniform3fARB},
+ {"glUniform4fARB", (void **) &qglUniform4fARB},
+ {"glUniform1iARB", (void **) &qglUniform1iARB},
+ {"glUniform2iARB", (void **) &qglUniform2iARB},
+ {"glUniform3iARB", (void **) &qglUniform3iARB},
+ {"glUniform4iARB", (void **) &qglUniform4iARB},
+ {"glUniform1fvARB", (void **) &qglUniform1fvARB},
+ {"glUniform2fvARB", (void **) &qglUniform2fvARB},
+ {"glUniform3fvARB", (void **) &qglUniform3fvARB},
+ {"glUniform4fvARB", (void **) &qglUniform4fvARB},
+ {"glUniform1ivARB", (void **) &qglUniform1ivARB},
+ {"glUniform2ivARB", (void **) &qglUniform2ivARB},
+ {"glUniform3ivARB", (void **) &qglUniform3ivARB},
+ {"glUniform4ivARB", (void **) &qglUniform4ivARB},
+ {"glUniformMatrix2fvARB", (void **) &qglUniformMatrix2fvARB},
+ {"glUniformMatrix3fvARB", (void **) &qglUniformMatrix3fvARB},
+ {"glUniformMatrix4fvARB", (void **) &qglUniformMatrix4fvARB},
+ {"glGetObjectParameterfvARB", (void **) &qglGetObjectParameterfvARB},
+ {"glGetObjectParameterivARB", (void **) &qglGetObjectParameterivARB},
+ {"glGetInfoLogARB", (void **) &qglGetInfoLogARB},
+ {"glGetAttachedObjectsARB", (void **) &qglGetAttachedObjectsARB},
+ {"glGetUniformLocationARB", (void **) &qglGetUniformLocationARB},
+ {"glGetActiveUniformARB", (void **) &qglGetActiveUniformARB},
+ {"glGetUniformfvARB", (void **) &qglGetUniformfvARB},
+ {"glGetUniformivARB", (void **) &qglGetUniformivARB},
+ {"glGetShaderSourceARB", (void **) &qglGetShaderSourceARB},
+ {NULL, NULL}
+};
+
+static dllfunction_t vertexshaderfuncs[] =
+{
+// {"glVertexAttrib1fARB", (void **) &qglVertexAttrib1fARB},
+// {"glVertexAttrib1sARB", (void **) &qglVertexAttrib1sARB},
+// {"glVertexAttrib1dARB", (void **) &qglVertexAttrib1dARB},
+// {"glVertexAttrib2fARB", (void **) &qglVertexAttrib2fARB},
+// {"glVertexAttrib2sARB", (void **) &qglVertexAttrib2sARB},
+// {"glVertexAttrib2dARB", (void **) &qglVertexAttrib2dARB},
+// {"glVertexAttrib3fARB", (void **) &qglVertexAttrib3fARB},
+// {"glVertexAttrib3sARB", (void **) &qglVertexAttrib3sARB},
+// {"glVertexAttrib3dARB", (void **) &qglVertexAttrib3dARB},
+// {"glVertexAttrib4fARB", (void **) &qglVertexAttrib4fARB},
+// {"glVertexAttrib4sARB", (void **) &qglVertexAttrib4sARB},
+// {"glVertexAttrib4dARB", (void **) &qglVertexAttrib4dARB},
+// {"glVertexAttrib4NubARB", (void **) &qglVertexAttrib4NubARB},
+// {"glVertexAttrib1fvARB", (void **) &qglVertexAttrib1fvARB},
+// {"glVertexAttrib1svARB", (void **) &qglVertexAttrib1svARB},
+// {"glVertexAttrib1dvARB", (void **) &qglVertexAttrib1dvARB},
+// {"glVertexAttrib2fvARB", (void **) &qglVertexAttrib1fvARB},
+// {"glVertexAttrib2svARB", (void **) &qglVertexAttrib1svARB},
+// {"glVertexAttrib2dvARB", (void **) &qglVertexAttrib1dvARB},
+// {"glVertexAttrib3fvARB", (void **) &qglVertexAttrib1fvARB},
+// {"glVertexAttrib3svARB", (void **) &qglVertexAttrib1svARB},
+// {"glVertexAttrib3dvARB", (void **) &qglVertexAttrib1dvARB},
+// {"glVertexAttrib4fvARB", (void **) &qglVertexAttrib1fvARB},
+// {"glVertexAttrib4svARB", (void **) &qglVertexAttrib1svARB},
+// {"glVertexAttrib4dvARB", (void **) &qglVertexAttrib1dvARB},
+// {"glVertexAttrib4ivARB", (void **) &qglVertexAttrib1ivARB},
+// {"glVertexAttrib4bvARB", (void **) &qglVertexAttrib1bvARB},
+// {"glVertexAttrib4ubvARB", (void **) &qglVertexAttrib1ubvARB},
+// {"glVertexAttrib4usvARB", (void **) &qglVertexAttrib1usvARB},
+// {"glVertexAttrib4uivARB", (void **) &qglVertexAttrib1uivARB},
+// {"glVertexAttrib4NbvARB", (void **) &qglVertexAttrib1NbvARB},
+// {"glVertexAttrib4NsvARB", (void **) &qglVertexAttrib1NsvARB},
+// {"glVertexAttrib4NivARB", (void **) &qglVertexAttrib1NivARB},
+// {"glVertexAttrib4NubvARB", (void **) &qglVertexAttrib1NubvARB},
+// {"glVertexAttrib4NusvARB", (void **) &qglVertexAttrib1NusvARB},
+// {"glVertexAttrib4NuivARB", (void **) &qglVertexAttrib1NuivARB},
+ {"glVertexAttribPointerARB", (void **) &qglVertexAttribPointerARB},
+ {"glEnableVertexAttribArrayARB", (void **) &qglEnableVertexAttribArrayARB},
+ {"glDisableVertexAttribArrayARB", (void **) &qglDisableVertexAttribArrayARB},
+ {"glBindAttribLocationARB", (void **) &qglBindAttribLocationARB},
+ {"glGetActiveAttribARB", (void **) &qglGetActiveAttribARB},
+ {"glGetAttribLocationARB", (void **) &qglGetAttribLocationARB},
+// {"glGetVertexAttribdvARB", (void **) &qglGetVertexAttribdvARB},
+// {"glGetVertexAttribfvARB", (void **) &qglGetVertexAttribfvARB},
+// {"glGetVertexAttribivARB", (void **) &qglGetVertexAttribivARB},
+// {"glGetVertexAttribPointervARB", (void **) &qglGetVertexAttribPointervARB},
+ {NULL, NULL}
+};
+
+
+void VID_CheckExtensions(void)
+{
+ gl_stencil = vid_bitsperpixel.integer == 32;
+
+ // reset all the gl extension variables here
+ // this should match the declarations
+ gl_textureunits = 1;
+ gl_combine_extension = false;
+ gl_supportslockarrays = false;
+ gl_texture3d = false;
+ gl_texturecubemap = false;
+ gl_dot3arb = false;
+ gl_support_clamptoedge = false;
+ gl_support_anisotropy = false;
+ gl_max_anisotropy = 1;
+ gl_textureshader = false;
+ gl_support_stenciltwoside = false;
+ gl_support_shader_objects = false;
+ gl_support_shading_language_100 = false;
+ gl_support_vertex_shader = false;
+ gl_support_fragment_shader = false;
+
+ if (!GL_CheckExtension("OpenGL 1.1.0", opengl110funcs, NULL, false))
+ Sys_Error("OpenGL 1.1.0 functions not found\n");
+
+ Con_Printf("GL_VENDOR: %s\n", gl_vendor);
+ Con_Printf("GL_RENDERER: %s\n", gl_renderer);
+ Con_Printf("GL_VERSION: %s\n", gl_version);
+ Con_Printf("GL_EXTENSIONS: %s\n", gl_extensions);
+ Con_Printf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions);
+
+ Con_Print("Checking OpenGL extensions...\n");
+
+// COMMANDLINEOPTION: GL: -nodrawrangeelements disables GL_EXT_draw_range_elements (renders faster)
+ if (!GL_CheckExtension("glDrawRangeElements", drawrangeelementsfuncs, "-nodrawrangeelements", true))
+ GL_CheckExtension("GL_EXT_draw_range_elements", drawrangeelementsextfuncs, "-nodrawrangeelements", false);
+
+// COMMANDLINEOPTION: GL: -nomtex disables GL_ARB_multitexture (required for faster map rendering)
+ if (GL_CheckExtension("GL_ARB_multitexture", multitexturefuncs, "-nomtex", false))
+ {
+ qglGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_textureunits);
+// COMMANDLINEOPTION: GL: -nocombine disables GL_ARB_texture_env_combine or GL_EXT_texture_env_combine (required for bumpmapping and faster map rendering)
+ gl_combine_extension = GL_CheckExtension("GL_ARB_texture_env_combine", NULL, "-nocombine", false) || GL_CheckExtension("GL_EXT_texture_env_combine", NULL, "-nocombine", false);
+// COMMANDLINEOPTION: GL: -nodot3 disables GL_ARB_texture_env_dot3 (required for bumpmapping)
+ if (gl_combine_extension)
+ gl_dot3arb = GL_CheckExtension("GL_ARB_texture_env_dot3", NULL, "-nodot3", false);
+ }
+
+// COMMANDLINEOPTION: GL: -notexture3d disables GL_EXT_texture3D (required for spherical lights, otherwise they render as a column)
+ gl_texture3d = GL_CheckExtension("GL_EXT_texture3D", texture3dextfuncs, "-notexture3d", false);
+// COMMANDLINEOPTION: GL: -nocubemap disables GL_ARB_texture_cube_map (required for bumpmapping)
+ gl_texturecubemap = GL_CheckExtension("GL_ARB_texture_cube_map", NULL, "-nocubemap", false);
+// COMMANDLINEOPTION: GL: -nocva disables GL_EXT_compiled_vertex_array (renders faster)
+ gl_supportslockarrays = GL_CheckExtension("GL_EXT_compiled_vertex_array", compiledvertexarrayfuncs, "-nocva", false);
+// COMMANDLINEOPTION: GL: -noedgeclamp disables GL_EXT_texture_edge_clamp or GL_SGIS_texture_edge_clamp (recommended, some cards do not support the other texture clamp method)
+ gl_support_clamptoedge = GL_CheckExtension("GL_EXT_texture_edge_clamp", NULL, "-noedgeclamp", false) || GL_CheckExtension("GL_SGIS_texture_edge_clamp", NULL, "-noedgeclamp", false);
+
+// COMMANDLINEOPTION: GL: -noanisotropy disables GL_EXT_texture_filter_anisotropic (allows higher quality texturing)
+ if ((gl_support_anisotropy = GL_CheckExtension("GL_EXT_texture_filter_anisotropic", NULL, "-noanisotropy", false)))
+ qglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max_anisotropy);
+
+// COMMANDLINEOPTION: GL: -notextureshader disables GL_NV_texture_shader (required for the Geforce3 water shader, NVIDIA only)
+ gl_textureshader = GL_CheckExtension("GL_NV_texture_shader", NULL, "-notextureshader", false);
+
+// COMMANDLINEOPTION: GL: -nostenciltwoside disables GL_EXT_stencil_two_side (accelerates shadow rendering)
+ gl_support_stenciltwoside = GL_CheckExtension("GL_EXT_stencil_two_side", stenciltwosidefuncs, "-nostenciltwoside", false);
+
+ // we don't care if it's an extension or not, they are identical functions, so keep it simple in the rendering code
+ if (qglDrawRangeElements == NULL)
+ qglDrawRangeElements = qglDrawRangeElementsEXT;
+
+// COMMANDLINEOPTION: GL: -noshaderobjects disables GL_ARB_shader_objects (required for vertex shader and fragment shader)
+// COMMANDLINEOPTION: GL: -noshadinglanguage100 disables GL_ARB_shading_language_100 (required for vertex shader and fragment shader)
+// COMMANDLINEOPTION: GL: -novertexshader disables GL_ARB_vertex_shader (currently unused, allows vertex shader effects)
+// COMMANDLINEOPTION: GL: -nofragmentshader disables GL_ARB_fragment_shader (currently unused, allows pixel shader effects)
+ if ((gl_support_shader_objects = GL_CheckExtension("GL_ARB_shader_objects", shaderobjectsfuncs, "-noshaderobjects", false)))
+ if ((gl_support_shading_language_100 = GL_CheckExtension("GL_ARB_shading_language_100", NULL, "-noshadinglanguage100", false)))
+ if ((gl_support_vertex_shader = GL_CheckExtension("GL_ARB_vertex_shader", vertexshaderfuncs, "-novertexshader", false)))
+ gl_support_fragment_shader = GL_CheckExtension("GL_ARB_fragment_shader", NULL, "-nofragmentshader", false);
+}
+
+qboolean vid_vertexarrays_are_var = false;
+void *VID_AllocVertexArrays(mempool_t *pool, int size, int fast, float readfrequency, float writefrequency, float priority)
+{
+ void *m;
+ vid_vertexarrays_are_var = false;
+ if (fast && qglAllocateMemoryNV)
+ {
+ CHECKGLERROR
+ m = qglAllocateMemoryNV(size, readfrequency, writefrequency, priority);
+ CHECKGLERROR
+ if (m)
+ {
+ vid_vertexarrays_are_var = true;
+ return m;
+ }
+ }
+ return Mem_Alloc(pool, size);
+}
+
+void VID_FreeVertexArrays(void *pointer)
+{
+ if (vid_vertexarrays_are_var)
+ {
+ CHECKGLERROR
+ qglFreeMemoryNV(pointer);
+ CHECKGLERROR
+ }
+ else
+ Mem_Free(pointer);
+ vid_vertexarrays_are_var = false;
+}
+
+void Force_CenterView_f (void)
+{
+ cl.viewangles[PITCH] = 0;
+}
+
+static float cachegamma, cachebrightness, cachecontrast, cacheblack[3], cachegrey[3], cachewhite[3];
+static int cachecolorenable, cachehwgamma;
+#define BOUNDCVAR(cvar, m1, m2) c = &(cvar);f = bound(m1, c->value, m2);if (c->value != f) Cvar_SetValueQuick(c, f);
+void VID_UpdateGamma(qboolean force)
+{
+ cvar_t *c;
+ float f;
+ static int forcenextframe = false;
+
+ // LordHavoc: don't mess with gamma tables if running dedicated
+ if (cls.state == ca_dedicated)
+ return;
+
+ if (!force
+ && !forcenextframe
+ && !v_psycho.integer
+ && vid_usinghwgamma == (vid_activewindow && v_hwgamma.integer)
+ && v_gamma.value == cachegamma
+ && v_contrast.value == cachecontrast
+ && v_brightness.value == cachebrightness
+ && cachecolorenable == v_color_enable.integer
+ && cacheblack[0] == v_color_black_r.value
+ && cacheblack[1] == v_color_black_g.value
+ && cacheblack[2] == v_color_black_b.value
+ && cachegrey[0] == v_color_grey_r.value
+ && cachegrey[1] == v_color_grey_g.value
+ && cachegrey[2] == v_color_grey_b.value
+ && cachewhite[0] == v_color_white_r.value
+ && cachewhite[1] == v_color_white_g.value
+ && cachewhite[2] == v_color_white_b.value)
+ return;
+
+ forcenextframe = false;
+
+ if (vid_activewindow && v_hwgamma.integer)
+ {
+ if (!vid_usinghwgamma)
+ {
+ vid_usinghwgamma = true;
+ Cvar_SetValueQuick(&vid_hardwaregammasupported, VID_GetGamma(vid_systemgammaramps));
+ }
+
+ BOUNDCVAR(v_gamma, 0.1, 5);cachegamma = v_gamma.value;
+ BOUNDCVAR(v_contrast, 1, 5);cachecontrast = v_contrast.value;
+ BOUNDCVAR(v_brightness, 0, 0.8);cachebrightness = v_brightness.value;
+ BOUNDCVAR(v_color_black_r, 0, 0.8);cacheblack[0] = v_color_black_r.value;
+ BOUNDCVAR(v_color_black_g, 0, 0.8);cacheblack[1] = v_color_black_g.value;
+ BOUNDCVAR(v_color_black_b, 0, 0.8);cacheblack[2] = v_color_black_b.value;
+ BOUNDCVAR(v_color_grey_r, 0, 0.95);cachegrey[0] = v_color_grey_r.value;
+ BOUNDCVAR(v_color_grey_g, 0, 0.95);cachegrey[1] = v_color_grey_g.value;
+ BOUNDCVAR(v_color_grey_b, 0, 0.95);cachegrey[2] = v_color_grey_b.value;
+ BOUNDCVAR(v_color_white_r, 1, 5);cachewhite[0] = v_color_white_r.value;
+ BOUNDCVAR(v_color_white_g, 1, 5);cachewhite[1] = v_color_white_g.value;
+ BOUNDCVAR(v_color_white_b, 1, 5);cachewhite[2] = v_color_white_b.value;
+ cachecolorenable = v_color_enable.integer;
+ cachehwgamma = v_hwgamma.integer;
+
+ if (cachecolorenable)
+ {
+ BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[0]), cachewhite[0], cacheblack[0], vid_gammaramps);
+ BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[1]), cachewhite[1], cacheblack[1], vid_gammaramps + 256);
+ BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[2]), cachewhite[2], cacheblack[2], vid_gammaramps + 512);
+ }
+ else
+ {
+ BuildGammaTable16(1.0f, cachegamma, cachecontrast, cachebrightness, vid_gammaramps);
+ BuildGammaTable16(1.0f, cachegamma, cachecontrast, cachebrightness, vid_gammaramps + 256);
+ BuildGammaTable16(1.0f, cachegamma, cachecontrast, cachebrightness, vid_gammaramps + 512);
+ }
+
+ // LordHavoc: this code came from Ben Winslow and Zinx Verituse, I have
+ // immensely butchered it to work with variable framerates and fit in with
+ // the rest of darkplaces.
+ if (v_psycho.integer)
+ {
+ int x, y;
+ float t;
+ static float n[3], nd[3], nt[3];
+ static int init = true;
+ unsigned short *ramp;
+ forcenextframe = true;
+ if (init)
+ {
+ init = false;
+ for (x = 0;x < 3;x++)
+ {
+ n[x] = lhrandom(0, 1);
+ nd[x] = (rand()&1)?-0.25:0.25;
+ nt[x] = lhrandom(1, 8.2);
+ }
+ }
+
+ for (x = 0;x < 3;x++)
+ {
+ nt[x] -= host_realframetime;
+ if (nt[x] < 0)
+ {
+ nd[x] = -nd[x];
+ nt[x] += lhrandom(1, 8.2);
+ }
+ n[x] += nd[x] * host_realframetime;
+ n[x] -= floor(n[x]);
+ }
+
+ for (x = 0, ramp = vid_gammaramps;x < 3;x++)
+ for (y = 0, t = n[x] - 0.75f;y < 256;y++, t += 0.75f * (2.0f / 256.0f))
+ *ramp++ = cos(t*(M_PI*2.0)) * 32767.0f + 32767.0f;
+ }
+
+ Cvar_SetValueQuick(&vid_hardwaregammasupported, VID_SetGamma(vid_gammaramps));
+ // if custom gamma ramps failed (Windows stupidity), restore to system gamma
+ if(!vid_hardwaregammasupported.integer)
+ VID_SetGamma(vid_systemgammaramps);
+ }
+ else
+ {
+ if (vid_usinghwgamma)
+ {
+ vid_usinghwgamma = false;
+ Cvar_SetValueQuick(&vid_hardwaregammasupported, VID_SetGamma(vid_systemgammaramps));
+ }
+ }
+}
+
+void VID_RestoreSystemGamma(void)
+{
+ if (vid_usinghwgamma)
+ {
+ vid_usinghwgamma = false;
+ VID_SetGamma(vid_systemgammaramps);
+ }
+}
+
+void VID_Shared_Init(void)
+{
+ Cvar_RegisterVariable(&vid_hardwaregammasupported);
+ Cvar_RegisterVariable(&v_gamma);
+ Cvar_RegisterVariable(&v_brightness);
+ Cvar_RegisterVariable(&v_contrast);
+
+ Cvar_RegisterVariable(&v_color_enable);
+ Cvar_RegisterVariable(&v_color_black_r);
+ Cvar_RegisterVariable(&v_color_black_g);
+ Cvar_RegisterVariable(&v_color_black_b);
+ Cvar_RegisterVariable(&v_color_grey_r);
+ Cvar_RegisterVariable(&v_color_grey_g);
+ Cvar_RegisterVariable(&v_color_grey_b);
+ Cvar_RegisterVariable(&v_color_white_r);
+ Cvar_RegisterVariable(&v_color_white_g);
+ Cvar_RegisterVariable(&v_color_white_b);
+
+ Cvar_RegisterVariable(&v_hwgamma);
+
+ Cvar_RegisterVariable(&v_psycho);
+