]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - vid_shared.c
Removed the gray-out behavior on the gamma settings in the color control menu when...
[xonotic/darkplaces.git] / vid_shared.c
index 873d43285c39bf3cca2bb5c64e7f0a2f3dd5274a..843707b48f7b9ba2f9ea03cd7ca4b62fdad2d620 100644 (file)
@@ -1,6 +1,9 @@
 
 #include "quakedef.h"
+#ifdef CONFIG_CD
 #include "cdaudio.h"
+#endif
+#include "image.h"
 
 #ifdef SUPPORTD3D
 #include <d3d9.h>
@@ -71,10 +74,6 @@ int vid_xinputindex = -1;
 // global video state
 viddef_t vid;
 
-// LordHavoc: these are only set in wgl
-qboolean isG200 = false; // LordHavoc: the Matrox G200 can't do per pixel alpha, and it uses a D3D driver for GL... ugh...
-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.
-
 // AK FIXME -> input_dest
 qboolean in_client_mouse = true;
 
@@ -138,7 +137,7 @@ cvar_t joy_x360_sensitivityroll = {0, "joy_x360_sensitivityroll", "1", "movement
 
 // cvars for DPSOFTRAST
 cvar_t vid_soft = {CVAR_SAVE, "vid_soft", "0", "enables use of the DarkPlaces Software Rasterizer rather than OpenGL or Direct3D"};
-cvar_t vid_soft_threads = {CVAR_SAVE, "vid_soft_threads", "2", "the number of threads the DarkPlaces Software Rasterizer should use"}; 
+cvar_t vid_soft_threads = {CVAR_SAVE, "vid_soft_threads", "8", "the number of threads the DarkPlaces Software Rasterizer should use"}; 
 cvar_t vid_soft_interlace = {CVAR_SAVE, "vid_soft_interlace", "1", "whether the DarkPlaces Software Rasterizer should interlace the screen bands occupied by each thread"};
 
 // we don't know until we try it!
@@ -167,6 +166,12 @@ cvar_t vid_samples = {CVAR_SAVE, "vid_samples", "1", "how many anti-aliasing sam
 cvar_t vid_refreshrate = {CVAR_SAVE, "vid_refreshrate", "60", "refresh rate to use, in hz (higher values flicker less, if supported by your monitor)"};
 cvar_t vid_userefreshrate = {CVAR_SAVE, "vid_userefreshrate", "0", "set this to 1 to make vid_refreshrate used, or to 0 to let the engine choose a sane default"};
 cvar_t vid_stereobuffer = {CVAR_SAVE, "vid_stereobuffer", "0", "enables 'quad-buffered' stereo rendering for stereo shutterglasses, HMD (head mounted display) devices, or polarized stereo LCDs, if supported by your drivers"};
+// the density cvars are completely optional, set and use when something needs to have a density-independent size.
+// TODO: set them when changing resolution, setting them from the commandline will be independent from the resolution - use only if you have a native fixed resolution.
+// values for the Samsung Galaxy SIII, Snapdragon version: 2.000000 density, 304.799988 xdpi, 303.850464 ydpi
+cvar_t vid_touchscreen_density = {0, "vid_touchscreen_density", "2.0", "Standard quantized screen density multiplier (see Android documentation for DisplayMetrics), similar values are given on iPhoneOS"};
+cvar_t vid_touchscreen_xdpi = {0, "vid_touchscreen_xdpi", "300", "Horizontal DPI of the screen (only valid on Android currently)"};
+cvar_t vid_touchscreen_ydpi = {0, "vid_touchscreen_ydpi", "300", "Vertical DPI of the screen (only valid on Android currently)"};
 
 cvar_t vid_vsync = {CVAR_SAVE, "vid_vsync", "0", "sync to vertical blank, prevents 'tearing' (seeing part of one frame and part of another on the screen at the same time), automatically disabled when doing timedemo benchmarks"};
 cvar_t vid_mouse = {CVAR_SAVE, "vid_mouse", "1", "whether to use the mouse in windowed mode (fullscreen always does)"};
@@ -177,10 +182,14 @@ cvar_t vid_gl13 = {0, "vid_gl13", "1", "enables faster rendering using OpenGL 1.
 cvar_t vid_gl20 = {0, "vid_gl20", "1", "enables faster rendering using OpenGL 2.0 features (such as GL_ARB_fragment_shader extension)"};
 cvar_t gl_finish = {0, "gl_finish", "0", "make the cpu wait for the graphics processor at the end of each rendered frame (can help with strange input or video lag problems on some machines)"};
 cvar_t vid_sRGB = {CVAR_SAVE, "vid_sRGB", "0", "if hardware is capable, modify rendering to be gamma corrected for the sRGB color standard (computer monitors, TVs), recommended"};
+cvar_t vid_sRGB_fallback = {CVAR_SAVE, "vid_sRGB_fallback", "0", "do an approximate sRGB fallback if not properly supported by hardware (2: also use the fallback if framebuffer is 8bit, 3: always use the fallback even if sRGB is supported)"};
 
 cvar_t vid_touchscreen = {0, "vid_touchscreen", "0", "Use touchscreen-style input (no mouse grab, track mouse motion only while button is down, screen areas for mimicing joystick axes and buttons"};
+cvar_t vid_touchscreen_showkeyboard = {0, "vid_touchscreen_showkeyboard", "0", "shows the platform's screen keyboard for text entry, can be set by csqc or menu qc if it wants to receive text input, does nothing if the platform has no screen keyboard"};
+cvar_t vid_touchscreen_supportshowkeyboard = {CVAR_READONLY, "vid_touchscreen_supportshowkeyboard", "0", "indicates if the platform supports a virtual keyboard"};
 cvar_t vid_stick_mouse = {CVAR_SAVE, "vid_stick_mouse", "0", "have the mouse stuck in the center of the screen" };
 cvar_t vid_resizable = {CVAR_SAVE, "vid_resizable", "0", "0: window not resizable, 1: resizable, 2: window can be resized but the framebuffer isn't adjusted" };
+cvar_t vid_desktopfullscreen = {CVAR_SAVE, "vid_desktopfullscreen", "0", "force desktop resolution for fullscreen; also use some OS dependent tricks for better fullscreen integration"};
 
 cvar_t v_gamma = {CVAR_SAVE, "v_gamma", "1", "inverse gamma correction value, a brightness effect that does not affect white or black, and tends to make the image grey and dull"};
 cvar_t v_contrast = {CVAR_SAVE, "v_contrast", "1", "brightness of white (values above 1 give a brighter image with increased color saturation, unlike v_gamma)"};
@@ -198,6 +207,7 @@ cvar_t v_color_white_g = {CVAR_SAVE, "v_color_white_g", "1", "desired color of w
 cvar_t v_color_white_b = {CVAR_SAVE, "v_color_white_b", "1", "desired color of white"};
 cvar_t v_hwgamma = {CVAR_SAVE, "v_hwgamma", "0", "enables use of hardware gamma correction ramps if available (note: does not work very well on Windows2000 and above), values are 0 = off, 1 = attempt to use hardware gamma, 2 = use hardware gamma whether it works or not"};
 cvar_t v_glslgamma = {CVAR_SAVE, "v_glslgamma", "1", "enables use of GLSL to apply gamma correction ramps if available (note: overrides v_hwgamma)"};
+cvar_t v_glslgamma_2d = {CVAR_SAVE, "v_glslgamma_2d", "0", "applies GLSL gamma to 2d pictures (HUD, fonts)"};
 cvar_t v_psycho = {0, "v_psycho", "0", "easter egg"};
 
 // brand of graphics chip
@@ -216,6 +226,7 @@ const char *gl_platformextensions;
 // name of driver library (opengl32.dll, libGL.so.1, or whatever)
 char gl_driver[256];
 
+#ifndef USE_GLES2
 // GL_ARB_multitexture
 void (GLAPIENTRY *qglMultiTexCoord1f) (GLenum, GLfloat);
 void (GLAPIENTRY *qglMultiTexCoord2f) (GLenum, GLfloat, GLfloat);
@@ -257,6 +268,7 @@ void (GLAPIENTRY *qglClearDepth)(GLclampd depth);
 void (GLAPIENTRY *qglDepthFunc)(GLenum func);
 void (GLAPIENTRY *qglDepthMask)(GLboolean flag);
 void (GLAPIENTRY *qglDepthRange)(GLclampd near_val, GLclampd far_val);
+void (GLAPIENTRY *qglDepthRangef)(GLclampf near_val, GLclampf far_val);
 void (GLAPIENTRY *qglColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
 
 void (GLAPIENTRY *qglDrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
@@ -464,24 +476,27 @@ GLboolean (GLAPIENTRY *qglUnmapBufferARB) (GLenum target);
 void (GLAPIENTRY *qglBufferDataARB) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
 void (GLAPIENTRY *qglBufferSubDataARB) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
 
-//GL_EXT_framebuffer_object
-GLboolean (GLAPIENTRY *qglIsRenderbufferEXT)(GLuint renderbuffer);
-void (GLAPIENTRY *qglBindRenderbufferEXT)(GLenum target, GLuint renderbuffer);
-void (GLAPIENTRY *qglDeleteRenderbuffersEXT)(GLsizei n, const GLuint *renderbuffers);
-void (GLAPIENTRY *qglGenRenderbuffersEXT)(GLsizei n, GLuint *renderbuffers);
-void (GLAPIENTRY *qglRenderbufferStorageEXT)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
-void (GLAPIENTRY *qglGetRenderbufferParameterivEXT)(GLenum target, GLenum pname, GLint *params);
-GLboolean (GLAPIENTRY *qglIsFramebufferEXT)(GLuint framebuffer);
-void (GLAPIENTRY *qglBindFramebufferEXT)(GLenum target, GLuint framebuffer);
-void (GLAPIENTRY *qglDeleteFramebuffersEXT)(GLsizei n, const GLuint *framebuffers);
-void (GLAPIENTRY *qglGenFramebuffersEXT)(GLsizei n, GLuint *framebuffers);
-GLenum (GLAPIENTRY *qglCheckFramebufferStatusEXT)(GLenum target);
-//void (GLAPIENTRY *qglFramebufferTexture1DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
-void (GLAPIENTRY *qglFramebufferTexture2DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
-void (GLAPIENTRY *qglFramebufferTexture3DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
-void (GLAPIENTRY *qglFramebufferRenderbufferEXT)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
-void (GLAPIENTRY *qglGetFramebufferAttachmentParameterivEXT)(GLenum target, GLenum attachment, GLenum pname, GLint *params);
-void (GLAPIENTRY *qglGenerateMipmapEXT)(GLenum target);
+//GL_ARB_framebuffer_object
+GLboolean (GLAPIENTRY *qglIsRenderbuffer)(GLuint renderbuffer);
+GLvoid (GLAPIENTRY *qglBindRenderbuffer)(GLenum target, GLuint renderbuffer);
+GLvoid (GLAPIENTRY *qglDeleteRenderbuffers)(GLsizei n, const GLuint *renderbuffers);
+GLvoid (GLAPIENTRY *qglGenRenderbuffers)(GLsizei n, GLuint *renderbuffers);
+GLvoid (GLAPIENTRY *qglRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+GLvoid (GLAPIENTRY *qglRenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GLvoid (GLAPIENTRY *qglGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint *params);
+GLboolean (GLAPIENTRY *qglIsFramebuffer)(GLuint framebuffer);
+GLvoid (GLAPIENTRY *qglBindFramebuffer)(GLenum target, GLuint framebuffer);
+GLvoid (GLAPIENTRY *qglDeleteFramebuffers)(GLsizei n, const GLuint *framebuffers);
+GLvoid (GLAPIENTRY *qglGenFramebuffers)(GLsizei n, GLuint *framebuffers);
+GLenum (GLAPIENTRY *qglCheckFramebufferStatus)(GLenum target);
+GLvoid (GLAPIENTRY *qglFramebufferTexture1D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLvoid (GLAPIENTRY *qglFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+GLvoid (GLAPIENTRY *qglFramebufferTexture3D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer);
+GLvoid (GLAPIENTRY *qglFramebufferTextureLayer)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GLvoid (GLAPIENTRY *qglFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+GLvoid (GLAPIENTRY *qglGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint *params);
+GLvoid (GLAPIENTRY *qglBlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GLvoid (GLAPIENTRY *qglGenerateMipmap)(GLenum target);
 
 void (GLAPIENTRY *qglDrawBuffersARB)(GLsizei n, const GLenum *bufs);
 
@@ -504,6 +519,20 @@ void (GLAPIENTRY *qglGetQueryObjectuivARB)(GLuint qid, GLenum pname, GLuint *par
 
 void (GLAPIENTRY *qglSampleCoverageARB)(GLclampf value, GLboolean invert);
 
+void (GLAPIENTRY *qglGetUniformIndices)(GLuint program, GLsizei uniformCount, const GLchar** uniformNames, GLuint* uniformIndices);
+void (GLAPIENTRY *qglGetActiveUniformsiv)(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
+void (GLAPIENTRY *qglGetActiveUniformName)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformName);
+GLuint (GLAPIENTRY *qglGetUniformBlockIndex)(GLuint program, const GLchar* uniformBlockName);
+void (GLAPIENTRY *qglGetActiveUniformBlockiv)(GLuint program, GLuint uniformBlockIndex, GLenum pname,  GLint* params);
+void (GLAPIENTRY *qglGetActiveUniformBlockName)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
+void (GLAPIENTRY *qglBindBufferRange)(GLenum target, GLuint index, GLuint buffer, GLintptrARB offset, GLsizeiptrARB size);
+void (GLAPIENTRY *qglBindBufferBase)(GLenum target, GLuint index, GLuint buffer);
+void (GLAPIENTRY *qglGetIntegeri_v)(GLenum target, GLuint index, GLint* data);
+void (GLAPIENTRY *qglUniformBlockBinding)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+
+void (GLAPIENTRY *qglBlendFuncSeparate)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif
+
 #if _MSC_VER >= 1400
 #define sscanf sscanf_s
 #endif
@@ -583,6 +612,7 @@ qboolean GL_CheckExtension(const char *minglver_or_ext, const dllfunction_t *fun
        return true;
 }
 
+#ifndef USE_GLES2
 static dllfunction_t opengl110funcs[] =
 {
        {"glClearColor", (void **) &qglClearColor},
@@ -859,25 +889,65 @@ static dllfunction_t vbofuncs[] =
        {NULL, NULL}
 };
 
-static dllfunction_t fbofuncs[] =
+static dllfunction_t ubofuncs[] =
+{
+       {"glGetUniformIndices"        , (void **) &qglGetUniformIndices},
+       {"glGetActiveUniformsiv"      , (void **) &qglGetActiveUniformsiv},
+       {"glGetActiveUniformName"     , (void **) &qglGetActiveUniformName},
+       {"glGetUniformBlockIndex"     , (void **) &qglGetUniformBlockIndex},
+       {"glGetActiveUniformBlockiv"  , (void **) &qglGetActiveUniformBlockiv},
+       {"glGetActiveUniformBlockName", (void **) &qglGetActiveUniformBlockName},
+       {"glBindBufferRange"          , (void **) &qglBindBufferRange},
+       {"glBindBufferBase"           , (void **) &qglBindBufferBase},
+       {"glGetIntegeri_v"            , (void **) &qglGetIntegeri_v},
+       {"glUniformBlockBinding"      , (void **) &qglUniformBlockBinding},
+       {NULL, NULL}
+};
+
+static dllfunction_t arbfbofuncs[] =
 {
-       {"glIsRenderbufferEXT"                      , (void **) &qglIsRenderbufferEXT},
-       {"glBindRenderbufferEXT"                    , (void **) &qglBindRenderbufferEXT},
-       {"glDeleteRenderbuffersEXT"                 , (void **) &qglDeleteRenderbuffersEXT},
-       {"glGenRenderbuffersEXT"                    , (void **) &qglGenRenderbuffersEXT},
-       {"glRenderbufferStorageEXT"                 , (void **) &qglRenderbufferStorageEXT},
-       {"glGetRenderbufferParameterivEXT"          , (void **) &qglGetRenderbufferParameterivEXT},
-       {"glIsFramebufferEXT"                       , (void **) &qglIsFramebufferEXT},
-       {"glBindFramebufferEXT"                     , (void **) &qglBindFramebufferEXT},
-       {"glDeleteFramebuffersEXT"                  , (void **) &qglDeleteFramebuffersEXT},
-       {"glGenFramebuffersEXT"                     , (void **) &qglGenFramebuffersEXT},
-       {"glCheckFramebufferStatusEXT"              , (void **) &qglCheckFramebufferStatusEXT},
-//     {"glFramebufferTexture1DEXT"                , (void **) &qglFramebufferTexture1DEXT},
-       {"glFramebufferTexture2DEXT"                , (void **) &qglFramebufferTexture2DEXT},
-       {"glFramebufferTexture3DEXT"                , (void **) &qglFramebufferTexture3DEXT},
-       {"glFramebufferRenderbufferEXT"             , (void **) &qglFramebufferRenderbufferEXT},
-       {"glGetFramebufferAttachmentParameterivEXT" , (void **) &qglGetFramebufferAttachmentParameterivEXT},
-       {"glGenerateMipmapEXT"                      , (void **) &qglGenerateMipmapEXT},
+       {"glIsRenderbuffer"                      , (void **) &qglIsRenderbuffer},
+       {"glBindRenderbuffer"                    , (void **) &qglBindRenderbuffer},
+       {"glDeleteRenderbuffers"                 , (void **) &qglDeleteRenderbuffers},
+       {"glGenRenderbuffers"                    , (void **) &qglGenRenderbuffers},
+       {"glRenderbufferStorage"                 , (void **) &qglRenderbufferStorage},
+       {"glRenderbufferStorageMultisample"      , (void **) &qglRenderbufferStorageMultisample}, // not in GL_EXT_framebuffer_object
+       {"glGetRenderbufferParameteriv"          , (void **) &qglGetRenderbufferParameteriv},
+       {"glIsFramebuffer"                       , (void **) &qglIsFramebuffer},
+       {"glBindFramebuffer"                     , (void **) &qglBindFramebuffer},
+       {"glDeleteFramebuffers"                  , (void **) &qglDeleteFramebuffers},
+       {"glGenFramebuffers"                     , (void **) &qglGenFramebuffers},
+       {"glCheckFramebufferStatus"              , (void **) &qglCheckFramebufferStatus},
+       {"glFramebufferTexture1D"                , (void **) &qglFramebufferTexture1D},
+       {"glFramebufferTexture2D"                , (void **) &qglFramebufferTexture2D},
+       {"glFramebufferTexture3D"                , (void **) &qglFramebufferTexture3D},
+       {"glFramebufferTextureLayer"             , (void **) &qglFramebufferTextureLayer}, // not in GL_EXT_framebuffer_object
+       {"glFramebufferRenderbuffer"             , (void **) &qglFramebufferRenderbuffer},
+       {"glGetFramebufferAttachmentParameteriv" , (void **) &qglGetFramebufferAttachmentParameteriv},
+       {"glBlitFramebuffer"                     , (void **) &qglBlitFramebuffer}, // not in GL_EXT_framebuffer_object
+       {"glGenerateMipmap"                      , (void **) &qglGenerateMipmap},
+       {NULL, NULL}
+};
+
+static dllfunction_t extfbofuncs[] =
+{
+       {"glIsRenderbufferEXT"                      , (void **) &qglIsRenderbuffer},
+       {"glBindRenderbufferEXT"                    , (void **) &qglBindRenderbuffer},
+       {"glDeleteRenderbuffersEXT"                 , (void **) &qglDeleteRenderbuffers},
+       {"glGenRenderbuffersEXT"                    , (void **) &qglGenRenderbuffers},
+       {"glRenderbufferStorageEXT"                 , (void **) &qglRenderbufferStorage},
+       {"glGetRenderbufferParameterivEXT"          , (void **) &qglGetRenderbufferParameteriv},
+       {"glIsFramebufferEXT"                       , (void **) &qglIsFramebuffer},
+       {"glBindFramebufferEXT"                     , (void **) &qglBindFramebuffer},
+       {"glDeleteFramebuffersEXT"                  , (void **) &qglDeleteFramebuffers},
+       {"glGenFramebuffersEXT"                     , (void **) &qglGenFramebuffers},
+       {"glCheckFramebufferStatusEXT"              , (void **) &qglCheckFramebufferStatus},
+       {"glFramebufferTexture1DEXT"                , (void **) &qglFramebufferTexture1D},
+       {"glFramebufferTexture2DEXT"                , (void **) &qglFramebufferTexture2D},
+       {"glFramebufferTexture3DEXT"                , (void **) &qglFramebufferTexture3D},
+       {"glFramebufferRenderbufferEXT"             , (void **) &qglFramebufferRenderbuffer},
+       {"glGetFramebufferAttachmentParameterivEXT" , (void **) &qglGetFramebufferAttachmentParameteriv},
+       {"glGenerateMipmapEXT"                      , (void **) &qglGenerateMipmap},
        {NULL, NULL}
 };
 
@@ -918,6 +988,14 @@ static dllfunction_t multisamplefuncs[] =
        {NULL, NULL}
 };
 
+static dllfunction_t blendfuncseparatefuncs[] =
+{
+       {"glBlendFuncSeparateEXT", (void **) &qglBlendFuncSeparate},
+       {NULL, NULL}
+};
+
+#endif
+
 void VID_ClearExtensions(void)
 {
        // VorteX: reset extensions info cvar, it got filled by GL_CheckExtension
@@ -939,6 +1017,7 @@ void VID_ClearExtensions(void)
        vid.max_anisotropy = 1;
        vid.maxdrawbuffers = 1;
 
+#ifndef USE_GLES2
        // this is a complete list of all functions that are directly checked in the renderer
        qglDrawRangeElements = NULL;
        qglDrawBuffer = NULL;
@@ -946,10 +1025,12 @@ void VID_ClearExtensions(void)
        qglFlush = NULL;
        qglActiveTexture = NULL;
        qglGetCompressedTexImageARB = NULL;
-       qglFramebufferTexture2DEXT = NULL;
+       qglFramebufferTexture2D = NULL;
        qglDrawBuffersARB = NULL;
+#endif
 }
 
+#ifndef USE_GLES2
 void VID_CheckExtensions(void)
 {
        if (!GL_CheckExtension("glbase", opengl110funcs, NULL, false))
@@ -962,18 +1043,18 @@ void VID_CheckExtensions(void)
 
        if (vid.support.gl20shaders)
        {
-               // this one is purely optional, needed for GLSL 1.3 support (#version 130), so we don't even check the return value of GL_CheckExtension
-               vid.support.gl20shaders130 = GL_CheckExtension("glshaders130", glsl130funcs, "-noglsl130", true);
-               if(vid.support.gl20shaders130)
-               {
-                       char *s = (char *) qglGetString(GL_SHADING_LANGUAGE_VERSION);
-                       if(!s || atof(s) < 1.30 - 0.00001)
-                               vid.support.gl20shaders130 = 0;
-               }
-               if(vid.support.gl20shaders130)
-                       Con_DPrintf("Using GLSL 1.30\n");
-               else
-                       Con_DPrintf("Using GLSL 1.00\n");
+               char *s;
+               // detect what GLSL version is available, to enable features like r_glsl_skeletal and higher quality reliefmapping
+               vid.support.glshaderversion = 100;
+               s = (char *) qglGetString(GL_SHADING_LANGUAGE_VERSION);
+               if (s)
+                       vid.support.glshaderversion = (int)(atof(s) * 100.0f + 0.5f);
+               if (vid.support.glshaderversion < 100)
+                       vid.support.glshaderversion = 100;
+               Con_DPrintf("Detected GLSL #version %i\n", vid.support.glshaderversion);
+               // get the glBindFragDataLocation function
+               if (vid.support.glshaderversion >= 130)
+                       vid.support.gl20shaders130 = GL_CheckExtension("glshaders130", glsl130funcs, "-noglsl130", true);
        }
 
        // GL drivers generally prefer GL_BGRA
@@ -984,6 +1065,7 @@ void VID_CheckExtensions(void)
        vid.support.arb_draw_buffers = GL_CheckExtension("GL_ARB_draw_buffers", drawbuffersfuncs, "-nodrawbuffers", false);
        vid.support.arb_multitexture = GL_CheckExtension("GL_ARB_multitexture", multitexturefuncs, "-nomtex", false);
        vid.support.arb_occlusion_query = GL_CheckExtension("GL_ARB_occlusion_query", occlusionqueryfuncs, "-noocclusionquery", false);
+       vid.support.arb_query_buffer_object = GL_CheckExtension("GL_ARB_query_buffer_object", NULL, "-noquerybuffer", true);
        vid.support.arb_shadow = GL_CheckExtension("GL_ARB_shadow", NULL, "-noshadow", false);
        vid.support.arb_texture_compression = GL_CheckExtension("GL_ARB_texture_compression", texturecompressionfuncs, "-notexturecompression", false);
        vid.support.arb_texture_cube_map = GL_CheckExtension("GL_ARB_texture_cube_map", NULL, "-nocubemap", false);
@@ -994,17 +1076,28 @@ void VID_CheckExtensions(void)
        vid.support.arb_texture_non_power_of_two = GL_CheckExtension("GL_ARB_texture_non_power_of_two", NULL, "-notexturenonpoweroftwo", false);
 #endif
        vid.support.arb_vertex_buffer_object = GL_CheckExtension("GL_ARB_vertex_buffer_object", vbofuncs, "-novbo", false);
+       vid.support.arb_uniform_buffer_object = GL_CheckExtension("GL_ARB_uniform_buffer_object", ubofuncs, "-noubo", false);
        vid.support.ati_separate_stencil = GL_CheckExtension("separatestencil", gl2separatestencilfuncs, "-noseparatestencil", true) || GL_CheckExtension("GL_ATI_separate_stencil", atiseparatestencilfuncs, "-noseparatestencil", false);
        vid.support.ext_blend_minmax = GL_CheckExtension("GL_EXT_blend_minmax", blendequationfuncs, "-noblendminmax", false);
        vid.support.ext_blend_subtract = GL_CheckExtension("GL_EXT_blend_subtract", blendequationfuncs, "-noblendsubtract", false);
+       vid.support.ext_blend_func_separate = GL_CheckExtension("GL_EXT_blend_func_separate", blendfuncseparatefuncs, "-noblendfuncseparate", false);
        vid.support.ext_draw_range_elements = GL_CheckExtension("drawrangeelements", drawrangeelementsfuncs, "-nodrawrangeelements", true) || GL_CheckExtension("GL_EXT_draw_range_elements", drawrangeelementsextfuncs, "-nodrawrangeelements", false);
-       vid.support.ext_framebuffer_object = GL_CheckExtension("GL_EXT_framebuffer_object", fbofuncs, "-nofbo", false);
+       vid.support.arb_framebuffer_object = GL_CheckExtension("GL_ARB_framebuffer_object", arbfbofuncs, "-nofbo", false);
+       if (vid.support.arb_framebuffer_object)
+               vid.support.ext_framebuffer_object = true;
+       else
+               vid.support.ext_framebuffer_object = GL_CheckExtension("GL_EXT_framebuffer_object", extfbofuncs, "-nofbo", false);
+
+       vid.support.ext_packed_depth_stencil = GL_CheckExtension("GL_EXT_packed_depth_stencil", NULL, "-nopackeddepthstencil", false);
        vid.support.ext_stencil_two_side = GL_CheckExtension("GL_EXT_stencil_two_side", stenciltwosidefuncs, "-nostenciltwoside", false);
        vid.support.ext_texture_3d = GL_CheckExtension("GL_EXT_texture3D", texture3dextfuncs, "-notexture3d", false);
        vid.support.ext_texture_compression_s3tc = GL_CheckExtension("GL_EXT_texture_compression_s3tc", NULL, "-nos3tc", false);
        vid.support.ext_texture_edge_clamp = GL_CheckExtension("GL_EXT_texture_edge_clamp", NULL, "-noedgeclamp", false) || GL_CheckExtension("GL_SGIS_texture_edge_clamp", NULL, "-noedgeclamp", false);
        vid.support.ext_texture_filter_anisotropic = GL_CheckExtension("GL_EXT_texture_filter_anisotropic", NULL, "-noanisotropy", false);
        vid.support.ext_texture_srgb = GL_CheckExtension("GL_EXT_texture_sRGB", NULL, "-nosrgb", false);
+       vid.support.arb_texture_float = GL_CheckExtension("GL_ARB_texture_float", NULL, "-notexturefloat", false);
+       vid.support.arb_half_float_pixel = GL_CheckExtension("GL_ARB_half_float_pixel", NULL, "-nohalffloatpixel", false);
+       vid.support.arb_half_float_vertex = GL_CheckExtension("GL_ARB_half_float_vertex", NULL, "-nohalffloatvertex", false);
        vid.support.arb_multisample = GL_CheckExtension("GL_ARB_multisample", multisamplefuncs, "-nomultisample", false);
        vid.allowalphatocoverage = false;
 
@@ -1021,6 +1114,7 @@ void VID_CheckExtensions(void)
 // COMMANDLINEOPTION: GL: -nofbo disables GL_EXT_framebuffer_object (which accelerates rendering), only used if GL_ARB_fragment_shader is also available
 // COMMANDLINEOPTION: GL: -nomtex disables GL_ARB_multitexture (required for faster map rendering)
 // COMMANDLINEOPTION: GL: -noocclusionquery disables GL_ARB_occlusion_query (which allows coronas to fade according to visibility, and potentially used for rendering optimizations)
+// COMMANDLINEOPTION: GL: -noquerybuffer disables GL_ARB_query_buffer_object (which allows corona fading without synchronous rendering)
 // COMMANDLINEOPTION: GL: -nos3tc disables GL_EXT_texture_compression_s3tc (which allows use of .dds texture caching)
 // COMMANDLINEOPTION: GL: -noseparatestencil disables use of OpenGL2.0 glStencilOpSeparate and GL_ATI_separate_stencil extensions (which accelerate shadow rendering)
 // COMMANDLINEOPTION: GL: -noshadow disables use of GL_ARB_shadow (required for hardware shadowmap filtering)
@@ -1055,7 +1149,7 @@ void VID_CheckExtensions(void)
        if (vid.support.ext_texture_filter_anisotropic)
                qglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, (GLint*)&vid.max_anisotropy);
        if (vid.support.arb_texture_cube_map)
-               qglGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB, (GLint*)&vid.maxtexturesize_cubemap);
+               qglGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_cubemap);
        if (vid.support.ext_texture_3d)
                qglGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, (GLint*)&vid.maxtexturesize_3d);
 
@@ -1068,10 +1162,10 @@ void VID_CheckExtensions(void)
 
        vid.texunits = vid.teximageunits = vid.texarrayunits = 1;
        if (vid.support.arb_multitexture)
-               qglGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint*)&vid.texunits);
+               qglGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&vid.texunits);
        if (vid_gl20.integer && vid.support.gl20shaders)
        {
-               qglGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint*)&vid.texunits);
+               qglGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&vid.texunits);
                qglGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (int *)&vid.teximageunits);CHECKGLERROR
                qglGetIntegerv(GL_MAX_TEXTURE_COORDS, (int *)&vid.texarrayunits);CHECKGLERROR
                vid.texunits = bound(4, vid.texunits, MAX_TEXTUREUNITS);
@@ -1083,13 +1177,12 @@ void VID_CheckExtensions(void)
                vid.sRGBcapable3D = true;
                vid.useinterleavedarrays = false;
                Con_Printf("vid.support.arb_multisample %i\n", vid.support.arb_multisample);
-               Con_Printf("vid.mode.samples %i\n", vid.mode.samples);
                Con_Printf("vid.support.gl20shaders %i\n", vid.support.gl20shaders);
-               vid.allowalphatocoverage = vid.support.arb_multisample && vid_samples.integer > 1 && vid.support.gl20shaders;
+               vid.allowalphatocoverage = true; // but see below, it may get turned to false again if GL_SAMPLES_ARB is <= 1
        }
        else if (vid.support.arb_texture_env_combine && vid.texunits >= 2 && vid_gl13.integer)
        {
-               qglGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint*)&vid.texunits);
+               qglGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint*)&vid.texunits);
                vid.texunits = bound(1, vid.texunits, MAX_TEXTUREUNITS);
                vid.teximageunits = vid.texunits;
                vid.texarrayunits = vid.texunits;
@@ -1110,9 +1203,23 @@ void VID_CheckExtensions(void)
                vid.sRGBcapable3D = false;
                vid.useinterleavedarrays = false;
        }
+
        // enable multisample antialiasing if possible
-       if (vid_samples.integer > 1 && vid.support.arb_multisample)
-               qglEnable(GL_MULTISAMPLE_ARB);
+       if(vid.support.arb_multisample)
+       {
+               int samples = 0;
+               qglGetIntegerv(GL_SAMPLES_ARB, &samples);
+               vid.samples = samples;
+               if (samples > 1)
+                       qglEnable(GL_MULTISAMPLE_ARB);
+               else
+                       vid.allowalphatocoverage = false;
+       }
+       else
+       {
+               vid.allowalphatocoverage = false;
+               vid.samples = 1;
+       }
 
        // VorteX: set other info (maybe place them in VID_InitMode?)
        Cvar_SetQuick(&gl_info_vendor, gl_vendor);
@@ -1121,15 +1228,16 @@ void VID_CheckExtensions(void)
        Cvar_SetQuick(&gl_info_platform, gl_platform ? gl_platform : "");
        Cvar_SetQuick(&gl_info_driver, gl_driver);
 }
+#endif
 
-float VID_JoyState_GetAxis(const vid_joystate_t *joystate, int axis, float sensitivity, float deadzone)
+float VID_JoyState_GetAxis(const vid_joystate_t *joystate, int axis, float fsensitivity, float deadzone)
 {
        float value;
        value = (axis >= 0 && axis < MAXJOYAXIS) ? joystate->axis[axis] : 0.0f;
        value = value > deadzone ? (value - deadzone) : (value < -deadzone ? (value + deadzone) : 0.0f);
        value *= deadzone > 0 ? (1.0f / (1.0f - deadzone)) : 1.0f;
        value = bound(-1, value, 1);
-       return value * sensitivity;
+       return value * fsensitivity;
 }
 
 qboolean VID_JoyBlockEmulatedKeys(int keycode)
@@ -1214,7 +1322,7 @@ void VID_Shared_BuildJoyState_Finish(vid_joystate_t *joystate)
        joystate->button[35] = r < 0.0f;
 }
 
-void VID_KeyEventForButton(qboolean oldbutton, qboolean newbutton, int key, double *timer)
+static void VID_KeyEventForButton(qboolean oldbutton, qboolean newbutton, int key, double *timer)
 {
        if (oldbutton)
        {
@@ -1359,7 +1467,7 @@ int VID_Shared_SetJoystick(int index)
 }
 
 
-void Force_CenterView_f (void)
+static void Force_CenterView_f (void)
 {
        cl.viewangles[PITCH] = 0;
 }
@@ -1368,22 +1476,43 @@ static int gamma_forcenextframe = false;
 static float cachegamma, cachebrightness, cachecontrast, cacheblack[3], cachegrey[3], cachewhite[3], cachecontrastboost;
 static int cachecolorenable, cachehwgamma;
 
+void VID_ApplyGammaToColor(const float *rgb, float *out)
+{
+       int i;
+       if (cachecolorenable)
+       {
+               for (i = 0; i < 3; i++)
+                       out[i] = pow(cachecontrastboost * rgb[i] / ((cachecontrastboost - 1) * rgb[i] + 1), 1.0 / invpow(0.5, 1 - cachegrey[i])) * cachewhite[i] + cacheblack[i];
+       }
+       else
+       {
+               for (i = 0; i < 3; i++)
+                       out[i] = pow(cachecontrastboost * rgb[i] / ((cachecontrastboost - 1) * rgb[i] + 1), 1.0 / cachegamma) * cachecontrast + cachebrightness;
+       }
+}
+
 unsigned int vid_gammatables_serial = 0; // so other subsystems can poll if gamma parameters have changed
 qboolean vid_gammatables_trivial = true;
 void VID_BuildGammaTables(unsigned short *ramps, int rampsize)
 {
-       float srgbmul = (vid.sRGB2D || vid.sRGB3D) ? 2.2f : 1.0f;
        if (cachecolorenable)
        {
-               BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[0]) * srgbmul, cachewhite[0], cacheblack[0], cachecontrastboost, ramps, rampsize);
-               BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[1]) * srgbmul, cachewhite[1], cacheblack[1], cachecontrastboost, ramps + rampsize, rampsize);
-               BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[2]) * srgbmul, cachewhite[2], cacheblack[2], cachecontrastboost, ramps + rampsize*2, rampsize);
+               BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[0]), cachewhite[0], cacheblack[0], cachecontrastboost, ramps, rampsize);
+               BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[1]), cachewhite[1], cacheblack[1], cachecontrastboost, ramps + rampsize, rampsize);
+               BuildGammaTable16(1.0f, invpow(0.5, 1 - cachegrey[2]), cachewhite[2], cacheblack[2], cachecontrastboost, ramps + rampsize*2, rampsize);
        }
        else
        {
-               BuildGammaTable16(1.0f, cachegamma * srgbmul, cachecontrast, cachebrightness, cachecontrastboost, ramps, rampsize);
-               BuildGammaTable16(1.0f, cachegamma * srgbmul, cachecontrast, cachebrightness, cachecontrastboost, ramps + rampsize, rampsize);
-               BuildGammaTable16(1.0f, cachegamma * srgbmul, cachecontrast, cachebrightness, cachecontrastboost, ramps + rampsize*2, rampsize);
+               BuildGammaTable16(1.0f, cachegamma, cachecontrast, cachebrightness, cachecontrastboost, ramps, rampsize);
+               BuildGammaTable16(1.0f, cachegamma, cachecontrast, cachebrightness, cachecontrastboost, ramps + rampsize, rampsize);
+               BuildGammaTable16(1.0f, cachegamma, cachecontrast, cachebrightness, cachecontrastboost, ramps + rampsize*2, rampsize);
+       }
+
+       if(vid.sRGB2D || vid.sRGB3D)
+       {
+               int i;
+               for(i = 0; i < 3*rampsize; ++i)
+                       ramps[i] = (int)floor(bound(0.0f, Image_sRGBFloatFromLinearFloat(ramps[i] / 65535.0f), 1.0f) * 65535.0f + 0.5f);
        }
 
        // LordHavoc: this code came from Ben Winslow and Zinx Verituse, I have
@@ -1458,8 +1587,8 @@ void VID_UpdateGamma(qboolean force, int rampsize)
                wantgamma = 0;
 #define BOUNDCVAR(cvar, m1, m2) c = &(cvar);f = bound(m1, c->value, m2);if (c->value != f) Cvar_SetValueQuick(c, f);
        BOUNDCVAR(v_gamma, 0.1, 5);
-       BOUNDCVAR(v_contrast, 1, 5);
-       BOUNDCVAR(v_brightness, 0, 0.8);
+       BOUNDCVAR(v_contrast, 0.2, 5);
+       BOUNDCVAR(v_brightness, -v_contrast.value * 0.8, 0.8);
        //BOUNDCVAR(v_contrastboost, 0.0625, 16);
        BOUNDCVAR(v_color_black_r, 0, 0.8);
        BOUNDCVAR(v_color_black_g, 0, 0.8);
@@ -1639,6 +1768,7 @@ void VID_Shared_Init(void)
 
        Cvar_RegisterVariable(&v_hwgamma);
        Cvar_RegisterVariable(&v_glslgamma);
+       Cvar_RegisterVariable(&v_glslgamma_2d);
 
        Cvar_RegisterVariable(&v_psycho);
 
@@ -1650,18 +1780,25 @@ void VID_Shared_Init(void)
        Cvar_RegisterVariable(&vid_refreshrate);
        Cvar_RegisterVariable(&vid_userefreshrate);
        Cvar_RegisterVariable(&vid_stereobuffer);
+       Cvar_RegisterVariable(&vid_touchscreen_density);
+       Cvar_RegisterVariable(&vid_touchscreen_xdpi);
+       Cvar_RegisterVariable(&vid_touchscreen_ydpi);
        Cvar_RegisterVariable(&vid_vsync);
        Cvar_RegisterVariable(&vid_mouse);
        Cvar_RegisterVariable(&vid_grabkeyboard);
        Cvar_RegisterVariable(&vid_touchscreen);
+       Cvar_RegisterVariable(&vid_touchscreen_showkeyboard);
+       Cvar_RegisterVariable(&vid_touchscreen_supportshowkeyboard);
        Cvar_RegisterVariable(&vid_stick_mouse);
        Cvar_RegisterVariable(&vid_resizable);
+       Cvar_RegisterVariable(&vid_desktopfullscreen);
        Cvar_RegisterVariable(&vid_minwidth);
        Cvar_RegisterVariable(&vid_minheight);
        Cvar_RegisterVariable(&vid_gl13);
        Cvar_RegisterVariable(&vid_gl20);
        Cvar_RegisterVariable(&gl_finish);
        Cvar_RegisterVariable(&vid_sRGB);
+       Cvar_RegisterVariable(&vid_sRGB_fallback);
 
        Cvar_RegisterVariable(&joy_active);
 #ifdef WIN32
@@ -1717,9 +1854,10 @@ void VID_Shared_Init(void)
        Cmd_AddCommand("vid_restart", VID_Restart_f, "restarts video system (closes and reopens the window, restarts renderer)");
 }
 
-int VID_Mode(int fullscreen, int width, int height, int bpp, float refreshrate, int stereobuffer, int samples)
+static int VID_Mode(int fullscreen, int width, int height, int bpp, float refreshrate, int stereobuffer, int samples)
 {
        viddef_mode_t mode;
+       char vabuf[1024];
 
        memset(&mode, 0, sizeof(mode));
        mode.fullscreen = fullscreen != 0;
@@ -1732,6 +1870,8 @@ int VID_Mode(int fullscreen, int width, int height, int bpp, float refreshrate,
        mode.samples = samples;
        cl_ignoremousemoves = 2;
        VID_ClearExtensions();
+
+       vid.samples = vid.mode.samples;
        if (VID_InitMode(&mode))
        {
                // accept the (possibly modified) mode
@@ -1743,12 +1883,40 @@ int VID_Mode(int fullscreen, int width, int height, int bpp, float refreshrate,
                vid.refreshrate    = vid.mode.refreshrate;
                vid.userefreshrate = vid.mode.userefreshrate;
                vid.stereobuffer   = vid.mode.stereobuffer;
-               vid.samples        = vid.mode.samples;
                vid.stencil        = vid.mode.bitsperpixel > 16;
                vid.sRGB2D         = vid_sRGB.integer >= 1 && vid.sRGBcapable2D;
                vid.sRGB3D         = vid_sRGB.integer >= 1 && vid.sRGBcapable3D;
 
-               Con_Printf("Video Mode: %s %dx%dx%dx%.2fhz%s%s\n", mode.fullscreen ? "fullscreen" : "window", mode.width, mode.height, mode.bitsperpixel, mode.refreshrate, mode.stereobuffer ? " stereo" : "", mode.samples > 1 ? va(" (%ix AA)", mode.samples) : "");
+               switch(vid.renderpath)
+               {
+               case RENDERPATH_GL11:
+               case RENDERPATH_GL13:
+               case RENDERPATH_GL20:
+#ifdef GL_STEREO
+                       {
+                               GLboolean stereo;
+                               qglGetBooleanv(GL_STEREO, &stereo);
+                               vid.stereobuffer = stereo != 0;
+                       }
+#endif
+                       break;
+               default:
+                       vid.stereobuffer = false;
+                       break;
+               }
+
+               if(
+                       (vid_sRGB_fallback.integer >= 3) // force fallback
+                       ||
+                       (vid_sRGB_fallback.integer >= 2 && // fallback if framebuffer is 8bit
+                               !(r_viewfbo.integer >= 2 && vid.support.ext_framebuffer_object && vid.support.arb_texture_non_power_of_two && vid.samples < 2))
+               )
+                       vid.sRGB2D = vid.sRGB3D = false;
+
+               if(vid.samples != vid.mode.samples)
+                       Con_Printf("NOTE: requested %dx AA, got %dx AA\n", vid.mode.samples, vid.samples);
+
+               Con_Printf("Video Mode: %s %dx%dx%dx%.2fhz%s%s\n", mode.fullscreen ? "fullscreen" : "window", mode.width, mode.height, mode.bitsperpixel, mode.refreshrate, mode.stereobuffer ? " stereo" : "", mode.samples > 1 ? va(vabuf, sizeof(vabuf), " (%ix AA)", mode.samples) : "");
 
                Cvar_SetValueQuick(&vid_fullscreen, vid.mode.fullscreen);
                Cvar_SetValueQuick(&vid_width, vid.mode.width);
@@ -1757,7 +1925,13 @@ int VID_Mode(int fullscreen, int width, int height, int bpp, float refreshrate,
                Cvar_SetValueQuick(&vid_samples, vid.mode.samples);
                if(vid_userefreshrate.integer)
                        Cvar_SetValueQuick(&vid_refreshrate, vid.mode.refreshrate);
-               Cvar_SetValueQuick(&vid_stereobuffer, vid.mode.stereobuffer);
+               Cvar_SetValueQuick(&vid_stereobuffer, vid.stereobuffer ? 1 : 0);
+
+               if (vid_touchscreen.integer)
+               {
+                       in_windowmouse_x = vid_width.value / 2.f;
+                       in_windowmouse_y = vid_height.value / 2.f;
+               }
 
                return true;
        }
@@ -1782,19 +1956,21 @@ extern qboolean vid_opened;
 
 void VID_Restart_f(void)
 {
+       char vabuf[1024];
+       char vabuf2[1024];
        // don't crash if video hasn't started yet
        if (vid_commandlinecheck)
                return;
 
        if (!vid_opened)
        {
-               SCR_BeginLoadingPlaque();
+               SCR_BeginLoadingPlaque(false);
                return;
        }
 
        Con_Printf("VID_Restart: changing from %s %dx%dx%dbpp%s%s, to %s %dx%dx%dbpp%s%s.\n",
-               vid.mode.fullscreen ? "fullscreen" : "window", vid.mode.width, vid.mode.height, vid.mode.bitsperpixel, vid.mode.fullscreen && vid.mode.userefreshrate ? va("x%.2fhz", vid.mode.refreshrate) : "", vid.mode.samples > 1 ? va(" (%ix AA)", vid.mode.samples) : "",
-               vid_fullscreen.integer ? "fullscreen" : "window", vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, vid_fullscreen.integer && vid_userefreshrate.integer ? va("x%.2fhz", vid_refreshrate.value) : "", vid_samples.integer > 1 ? va(" (%ix AA)", vid_samples.integer) : "");
+               vid.mode.fullscreen ? "fullscreen" : "window", vid.mode.width, vid.mode.height, vid.mode.bitsperpixel, vid.mode.fullscreen && vid.mode.userefreshrate ? va(vabuf, sizeof(vabuf), "x%.2fhz", vid.mode.refreshrate) : "", vid.mode.samples > 1 ? va(vabuf2, sizeof(vabuf2), " (%ix AA)", vid.mode.samples) : "",
+               vid_fullscreen.integer ? "fullscreen" : "window", vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, vid_fullscreen.integer && vid_userefreshrate.integer ? va(vabuf, sizeof(vabuf), "x%.2fhz", vid_refreshrate.value) : "", vid_samples.integer > 1 ? va(vabuf2, sizeof(vabuf2), " (%ix AA)", vid_samples.integer) : "");
        VID_CloseSystems();
        VID_Shutdown();
        if (!VID_Mode(vid_fullscreen.integer, vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, vid_refreshrate.value, vid_stereobuffer.integer, vid_samples.integer))
@@ -1850,6 +2026,15 @@ void VID_Start(void)
 // COMMANDLINEOPTION: Video: -bpp <bits> performs +vid_bitsperpixel <bits> (example -bpp 32 or -bpp 16)
                if ((i = COM_CheckParm("-bpp")) != 0)
                        Cvar_SetQuick(&vid_bitsperpixel, com_argv[i+1]);
+// COMMANDLINEOPTION: Video: -density <multiplier> performs +vid_touchscreen_density <multiplier> (example -density 1 or -density 1.5)
+               if ((i = COM_CheckParm("-density")) != 0)
+                       Cvar_SetQuick(&vid_touchscreen_density, com_argv[i+1]);
+// COMMANDLINEOPTION: Video: -xdpi <dpi> performs +vid_touchscreen_xdpi <dpi> (example -xdpi 160 or -xdpi 320)
+               if ((i = COM_CheckParm("-touchscreen_xdpi")) != 0)
+                       Cvar_SetQuick(&vid_touchscreen_xdpi, com_argv[i+1]);
+// COMMANDLINEOPTION: Video: -ydpi <dpi> performs +vid_touchscreen_ydpi <dpi> (example -ydpi 160 or -ydpi 320)
+               if ((i = COM_CheckParm("-touchscreen_ydpi")) != 0)
+                       Cvar_SetQuick(&vid_touchscreen_ydpi, com_argv[i+1]);
        }
 
        success = VID_Mode(vid_fullscreen.integer, vid_width.integer, vid_height.integer, vid_bitsperpixel.integer, vid_refreshrate.value, vid_stereobuffer.integer, vid_samples.integer);
@@ -1873,7 +2058,7 @@ void VID_Stop(void)
        VID_Shutdown();
 }
 
-int VID_SortModes_Compare(const void *a_, const void *b_)
+static int VID_SortModes_Compare(const void *a_, const void *b_)
 {
        vid_mode_t *a = (vid_mode_t *) a_;
        vid_mode_t *b = (vid_mode_t *) b_;
@@ -1957,6 +2142,7 @@ void VID_Soft_SharedSetup(void)
        vid.support.arb_depth_texture = true;
        vid.support.arb_draw_buffers = true;
        vid.support.arb_occlusion_query = true;
+       vid.support.arb_query_buffer_object = false;
        vid.support.arb_shadow = true;
        //vid.support.arb_texture_compression = true;
        vid.support.arb_texture_cube_map = true;
@@ -1965,6 +2151,7 @@ void VID_Soft_SharedSetup(void)
        vid.support.ext_blend_subtract = true;
        vid.support.ext_draw_range_elements = true;
        vid.support.ext_framebuffer_object = true;
+
        vid.support.ext_texture_3d = true;
        //vid.support.ext_texture_compression_s3tc = true;
        vid.support.ext_texture_filter_anisotropic = true;
@@ -1996,7 +2183,11 @@ void VID_Soft_SharedSetup(void)
        Cvar_SetQuick(&gl_info_driver, gl_driver);
 
        // LordHavoc: report supported extensions
+#ifdef CONFIG_MENU
        Con_DPrintf("\nQuakeC extensions for server and client: %s\nQuakeC extensions for menu: %s\n", vm_sv_extensions, vm_m_extensions );
+#else
+       Con_DPrintf("\nQuakeC extensions for server and client: %s\n", vm_sv_extensions );
+#endif
 
        // clear to black (loading plaque will be seen over this)
        GL_Clear(GL_COLOR_BUFFER_BIT, NULL, 1.0f, 128);