VID_Init now takes mode settings (fullscreen, width, height)
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 11 Sep 2002 15:05:44 +0000 (15:05 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 11 Sep 2002 15:05:44 +0000 (15:05 +0000)
commandline options like -window and -width are now parsed by vid_shared code
vid_width, vid_height, and vid_bitsperpixel cvars added, vid_mode removed
VID_CompareMode added, for simpler mode matching (returns a double, smaller value is better match)
GL_OpenLibrary takes a library name to load
GL_OpenLibrary, GL_CloseLibrary, and GL_GetProcAddress have been moved to platform specific vid_ files (wgl and glx)
gl_platform added (example values: "WGL", "GLX")
gl_platformextensions added (containing any extensions reported by platform specific strings)
gl_checkextension renamed to GL_CheckExtension for consistency
glXQueryExtensionsString and glXGetProcAddressARB support
looks up GLX_SGI_video_sync extension
removed halfscreen hack from vid_wgl (the code that tried to identify dual monitor configurations and use only one of them)

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2363 d7cf8633-e32d-0410-b094-e92efae38249

glquake.h
host.c
vid.h
vid_glx.c
vid_shared.c
vid_wgl.c

index d945bc9..bf362ed 100644 (file)
--- a/glquake.h
+++ b/glquake.h
@@ -37,20 +37,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 //#include <GL/gl.h>
 
-extern qboolean isG200;
-extern qboolean isRagePro;
-
 //====================================================
 
-extern const char *gl_vendor;
-extern const char *gl_renderer;
-extern const char *gl_version;
-extern const char *gl_extensions;
-
-void GL_OpenLibrary(void);
-void GL_CloseLibrary(void);
-void *GL_GetProcAddress(char *name);
-
 // wgl uses APIENTRY
 #ifndef APIENTRY
 #define APIENTRY
diff --git a/host.c b/host.c
index 305fe58..cc7102a 100644 (file)
--- a/host.c
+++ b/host.c
@@ -869,7 +869,7 @@ void Host_Init (void)
 #ifndef _WIN32 // on non win32, mouse comes before video for security reasons
                IN_Init ();
 #endif
-               VID_Init ();
+               VID_Init (vid_fullscreen.integer, vid_width.integer, vid_height.integer);
 
                Render_Init();
                S_Init ();
diff --git a/vid.h b/vid.h
index 2ab4443..265d6e0 100644 (file)
--- a/vid.h
+++ b/vid.h
@@ -42,9 +42,57 @@ extern void (*vid_menukeyfn)(int key);
 extern int vid_hidden;
 extern int vid_activewindow;
 
-extern cvar_t vid_mode;
-extern cvar_t vid_mouse;
 extern cvar_t vid_fullscreen;
+extern cvar_t vid_width;
+extern cvar_t vid_height;
+extern cvar_t vid_bitsperpixel;
+extern cvar_t vid_mouse;
+
+// brand of graphics chip
+extern const char *gl_vendor;
+// graphics chip model and other information
+extern const char *gl_renderer;
+// begins with 1.0.0, 1.1.0, 1.2.0, 1.2.1, 1.3.0, 1.3.1, or 1.4.0
+extern const char *gl_version;
+// extensions list, space separated
+extern const char *gl_extensions;
+// WGL, GLX, or AGL
+extern const char *gl_platform;
+// another extensions list, containing platform-specific extensions that are
+// not in the main list
+extern const char *gl_platformextensions;
+// name of driver library (opengl32.dll, libGL.so.1, or whatever)
+extern char gl_driver[256];
+
+// compatibility hacks
+extern qboolean isG200;
+extern qboolean isRagePro;
+
+// LordHavoc: GLX_SGI_video_sync and WGL_EXT_swap_control
+extern int gl_videosyncavailable;
+
+typedef struct
+{
+       const char *name;
+       void **funcvariable;
+}
+gl_extensionfunctionlist_t;
+
+typedef struct
+{
+       const char *name;
+       const gl_extensionfunctionlist_t *funcs;
+       int *enablevariable;
+       const char *disableparm;
+}
+gl_extensioninfo_t;
+
+int GL_OpenLibrary(const char *name);
+void GL_CloseLibrary(void);
+void *GL_GetProcAddress(const char *name);
+int GL_CheckExtension(const char *name, const gl_extensionfunctionlist_t *funcs, const char *disableparm, int silent);
+
+double VID_CompareMode(int width1, int height1, int bpp1, int width2, int height2, int bpp2);
 
 void VID_InitCvars(void);
 
@@ -52,7 +100,7 @@ void GL_Init (void);
 
 void VID_CheckExtensions(void);
 
-void VID_Init (void);
+void VID_Init (int fullscreen, int width, int height);
 // Called at startup
 
 void VID_Shutdown (void);
index 1021ff3..de6c7c4 100644 (file)
--- a/vid_glx.c
+++ b/vid_glx.c
@@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 //#include <stdio.h>
 #include <signal.h>
 
-//#include <dlfcn.h>
+#include <dlfcn.h>
 
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
@@ -40,12 +40,33 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "quakedef.h"
 
+//GLX prototypes
 XVisualInfo *(GLAPIENTRY *qglXChooseVisual)(Display *dpy, int screen, int *attribList);
 GLXContext (GLAPIENTRY *qglXCreateContext)(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct);
 void (GLAPIENTRY *qglXDestroyContext)(Display *dpy, GLXContext ctx);
 Bool (GLAPIENTRY *qglXMakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx);
 void (GLAPIENTRY *qglXSwapBuffers)(Display *dpy, GLXDrawable drawable);
+const char *(GLAPIENTRY *qglXQueryExtensionsString)(Display *dpy, int screen);
 
+//GLX_ARB_get_proc_address
+void *(GLAPIENTRY *qglXGetProcAddressARB)(const GLubyte *procName);
+
+static gl_extensionfunctionlist_t getprocaddressfuncs[] =
+{
+       {"glXGetProcAddressARB", (void **) &qglXGetProcAddressARB},
+       {NULL, NULL}
+};
+
+//GLX_SGI_video_sync
+GLint (GLAPIENTRY *qglXGetVideoSyncSGI)(GLuint *count);
+GLint (GLAPIENTRY *qglXWaitVideoSyncSGI)(int divisor, int remainder, unsigned int *count);
+
+static gl_extensionfunctionlist_t videosyncfuncs[] =
+{
+       {"glXGetVideoSyncSGI", (void **) &qglXGetVideoSyncSGI},
+       {"glXWaitVideoSyncSGI", (void **) &qglXWaitVideoSyncSGI},
+       {NULL, NULL}
+};
 
 static Display *vidx11_display = NULL;
 static int scrnum;
@@ -613,7 +634,7 @@ int VID_SetGamma(float prescale, float gamma, float scale, float base)
 #endif
 }
 
-void VID_Init(void)
+void VID_Init(int fullscreen, int width, int height)
 {
        int i;
 // LordHavoc: FIXME: finish this code, we need to allocate colors before we can store them
@@ -640,49 +661,18 @@ void VID_Init(void)
                GLX_DEPTH_SIZE, 1,
                None
        };
-       int width = 640, height = 480;
        XSetWindowAttributes attr;
        unsigned long mask;
        Window root;
        XVisualInfo *visinfo;
-       qboolean fullscreen = true;
        int MajorVersion, MinorVersion;
 
-       GL_OpenLibrary();
+       if (!GL_OpenLibrary("libGL.so.1"))
+               Sys_Error("Unable to load GL driver\n");
 
        Cvar_RegisterVariable (&vid_dga);
        Cvar_RegisterVariable (&vid_dga_mouseaccel);
 
-// interpret command-line params
-
-// set vid parameters
-       if ((i = COM_CheckParm("-window")) != 0)
-               fullscreen = false;
-
-       if ((i = COM_CheckParm("-width")) != 0)
-               width = atoi(com_argv[i+1]);
-
-       if ((i = COM_CheckParm("-height")) != 0)
-               height = atoi(com_argv[i+1]);
-
-       if ((i = COM_CheckParm("-conwidth")) != 0)
-               vid.conwidth = atoi(com_argv[i+1]);
-       else
-               vid.conwidth = 640;
-
-       vid.conwidth &= 0xfff8; // make it a multiple of eight
-
-       if (vid.conwidth < 320)
-               vid.conwidth = 320;
-
-       // pick a conheight that matches with correct aspect
-       vid.conheight = vid.conwidth*3 / 4;
-
-       if ((i = COM_CheckParm("-conheight")) != 0)
-               vid.conheight = atoi(com_argv[i+1]);
-       if (vid.conheight < 200)
-               vid.conheight = 200;
-
        if (!(vidx11_display = XOpenDisplay(NULL)))
        {
                fprintf(stderr, "Error couldn't open the X display\n");
@@ -705,8 +695,9 @@ void VID_Init(void)
        if ((qglXChooseVisual = GL_GetProcAddress("glXChooseVisual")) == NULL
         || (qglXCreateContext = GL_GetProcAddress("glXCreateContext")) == NULL
         || (qglXMakeCurrent = GL_GetProcAddress("glXMakeCurrent")) == NULL
-        || (qglXSwapBuffers = GL_GetProcAddress("glXSwapBuffers")) == NULL)
-               Sys_Error("glX functions not found in libGL.so.1\n");
+        || (qglXSwapBuffers = GL_GetProcAddress("glXSwapBuffers")) == NULL
+        || (qglXQueryExtensionsString = GL_GetProcAddress("glXQueryExtensionsString")) == NULL)
+               Sys_Error("glX functions not found in %s\n", gl_driver);
 
        visinfo = NULL;
 // LordHavoc: FIXME: finish this code, we need to allocate colors before we can store them
@@ -818,10 +809,18 @@ void VID_Init(void)
        scr_width = width;
        scr_height = height;
 
-       if (vid.conheight > height)
-               vid.conheight = height;
-       if (vid.conwidth > width)
-               vid.conwidth = width;
+       if ((qglGetString = GL_GetProcAddress("glGetString")) == NULL)
+               Sys_Error("glGetString not found in %s", gl_driver);
+
+       gl_renderer = qglGetString(GL_RENDERER);
+       gl_vendor = qglGetString(GL_VENDOR);
+       gl_version = qglGetString(GL_VERSION);
+       gl_extensions = qglGetString(GL_EXTENSIONS);
+       gl_platform = "GLX";
+       gl_platformextensions = qglXQueryExtensionsString(vidx11_display, scrnum);
+
+       GL_CheckExtension("GLX_ARB_get_proc_address", getprocaddressfuncs, "-nogetprocaddress", false);
+       gl_videosyncavailable = GL_CheckExtension("GLX_SGI_video_sync", videosyncfuncs, "-novideosync", false);
 
        InitSig(); // trap evil signals
 
@@ -839,7 +838,7 @@ void Sys_SendKeyEvents(void)
 
 void IN_Init(void)
 {
-       if (COM_CheckParm ("-nomouse"))
+       if (COM_CheckParm ("-nomouse") || COM_CheckParm("-safe"))
                mouse_avail = false;
 }
 
@@ -864,3 +863,39 @@ void IN_Move (usercmd_t *cmd)
        mouse_y = 0;
 }
 
+static void *prjobj = NULL;
+
+int GL_OpenLibrary(const char *name)
+{
+       Con_Printf("Loading GL driver %s\n", name);
+       GL_CloseLibrary();
+       if (!(prjobj = dlopen(name, RTLD_LAZY)))
+       {
+               Con_Printf("Unable to open symbol list for %s\n", name);
+               return false;
+       }
+       strcpy(gl_driver, name);
+       return true;
+}
+
+void GL_CloseLibrary(void)
+{
+       if (prjobj)
+               dlclose(prjobj);
+       prjobj = NULL;
+       gl_driver[0] = 0;
+       qglXGetProcAddressARB = NULL;
+       gl_extensions = "";
+       gl_platform = "";
+       gl_platformextensions = "";
+}
+
+void *GL_GetProcAddress(const char *name)
+{
+       void *p = NULL;
+       if (qglXGetProcAddressARB != NULL)
+               p = (void *) qglXGetProcAddressARB(name);
+       if (p == NULL)
+               p = (void *) dlsym(prjobj, name);
+       return p;
+}
index 8ae15b8..a35bb1e 100644 (file)
@@ -11,6 +11,8 @@ int gl_textureunits;
 int gl_combine_extension = false;
 // LordHavoc: GL_EXT_compiled_vertex_array support
 int gl_supportslockarrays = false;
+// LordHavoc: GLX_SGI_video_sync and WGL_EXT_swap_control
+int gl_videosyncavailable = false;
 
 // LordHavoc: if window is hidden, don't update screen
 int vid_hidden = false;
@@ -18,9 +20,12 @@ int vid_hidden = false;
 // let go of the mouse, turn off sound, and restore system gamma ramps...
 int vid_activewindow = true;
 
-cvar_t vid_mode = {0, "vid_mode", "0"};
-cvar_t vid_mouse = {CVAR_SAVE, "vid_mouse", "1"};
 cvar_t vid_fullscreen = {0, "vid_fullscreen", "1"};
+cvar_t vid_width = {0, "vid_width", "640"};
+cvar_t vid_height = {0, "vid_height", "480"};
+cvar_t vid_bitsperpixel = {0, "vid_bitsperpixel", "15"};
+
+cvar_t vid_mouse = {CVAR_SAVE, "vid_mouse", "1"};
 cvar_t gl_combine = {0, "gl_combine", "1"};
 
 cvar_t in_pitch_min = {0, "in_pitch_min", "-90"};
@@ -28,10 +33,21 @@ cvar_t in_pitch_max = {0, "in_pitch_max", "90"};
 
 cvar_t m_filter = {CVAR_SAVE, "m_filter","0"};
 
+// brand of graphics chip
 const char *gl_vendor;
+// graphics chip model and other information
 const char *gl_renderer;
+// begins with 1.0.0, 1.1.0, 1.2.0, 1.2.1, 1.3.0, 1.3.1, or 1.4.0
 const char *gl_version;
+// extensions list, space separated
 const char *gl_extensions;
+// WGL, GLX, or AGL
+const char *gl_platform;
+// another extensions list, containing platform-specific extensions that are
+// not in the main list
+const char *gl_platformextensions;
+// name of driver library (opengl32.dll, libGL.so.1, or whatever)
+char gl_driver[256];
 
 // GL_ARB_multitexture
 void (GLAPIENTRY *qglMultiTexCoord2f) (GLenum, GLfloat, GLfloat);
@@ -132,59 +148,46 @@ void (GLAPIENTRY *qglDrawRangeElementsEXT)(GLenum mode, GLuint start, GLuint end
 
 //void (GLAPIENTRY *qglColorTableEXT)(int, int, int, int, int, const void *);
 
-#if WIN32
-int (WINAPI *qwglChoosePixelFormat)(HDC, CONST PIXELFORMATDESCRIPTOR *);
-int (WINAPI *qwglDescribePixelFormat)(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR);
-//int (WINAPI *qwglGetPixelFormat)(HDC);
-BOOL (WINAPI *qwglSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *);
-BOOL (WINAPI *qwglSwapBuffers)(HDC);
-HGLRC (WINAPI *qwglCreateContext)(HDC);
-BOOL (WINAPI *qwglDeleteContext)(HGLRC);
-PROC (WINAPI *qwglGetProcAddress)(LPCSTR);
-BOOL (WINAPI *qwglMakeCurrent)(HDC, HGLRC);
-//BOOL (WINAPI *qwglSwapIntervalEXT)(int interval);
-#endif
-
-
-typedef struct
+int GL_CheckExtension(const char *name, const gl_extensionfunctionlist_t *funcs, const char *disableparm, int silent)
 {
-       char *name;
-       void **funcvariable;
-}
-gl_extensionfunctionlist_t;
+       int failed = false;
+       const gl_extensionfunctionlist_t *func;
 
-typedef struct
-{
-       char *name;
-       gl_extensionfunctionlist_t *funcs;
-       int *enablevariable;
-       char *disableparm;
-}
-gl_extensioninfo_t;
+       Con_Printf("checking for %s...  ", name);
 
-#if WIN32
-static gl_extensionfunctionlist_t wglfuncs[] =
-{
-       {"wglChoosePixelFormat", (void **) &qwglChoosePixelFormat},
-       {"wglDescribePixelFormat", (void **) &qwglDescribePixelFormat},
-//     {"wglGetPixelFormat", (void **) &qwglGetPixelFormat},
-       {"wglSetPixelFormat", (void **) &qwglSetPixelFormat},
-       {"wglSwapBuffers", (void **) &qwglSwapBuffers},
-       {"wglCreateContext", (void **) &qwglCreateContext},
-       {"wglDeleteContext", (void **) &qwglDeleteContext},
-       {"wglGetProcAddress", (void **) &qwglGetProcAddress},
-       {"wglMakeCurrent", (void **) &qwglMakeCurrent},
-       {NULL, NULL}
-};
+       for (func = funcs;func && func->name;func++)
+               *func->funcvariable = NULL;
 
-/*
-static gl_extensionfunctionlist_t wglswapintervalfuncs[] =
-{
-       {"wglSwapIntervalEXT", (void **) &qwglSwapIntervalEXT},
-       {NULL, NULL}
-};
-*/
-#endif
+       if (disableparm && COM_CheckParm(disableparm))
+       {
+               Con_Printf("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("missing function \"%s\" - broken driver!\n", func->name);
+                               failed = true;
+                       }
+               }
+               // delay the return so it prints all missing functions
+               if (failed)
+                       return false;
+               Con_Printf("enabled\n");
+               return true;
+       }
+       else
+       {
+               Con_Printf("not detected\n");
+               return false;
+       }
+}
 
 static gl_extensionfunctionlist_t opengl110funcs[] =
 {
@@ -284,140 +287,31 @@ static gl_extensionfunctionlist_t compiledvertexarrayfuncs[] =
        {NULL, NULL}
 };
 
-#ifndef WIN32
-#include <dlfcn.h>
-#endif
-
-#ifdef WIN32
-static HINSTANCE gldll;
-#else
-static void *prjobj = NULL;
-#endif
-
-void GL_OpenLibrary(void)
-{
-#ifdef WIN32
-       if (gldll)
-               FreeLibrary(gldll);
-       if (!(gldll = LoadLibrary("opengl32.dll")))
-               Sys_Error("Unable to LoadLibrary opengl32.dll\n");
-#else
-       if (prjobj)
-               dlclose(prjobj);
-       if (!(prjobj = dlopen("libGL.so.1", RTLD_LAZY)))
-               Sys_Error("Unable to open symbol list for libGL.so.1\n");
-#endif
-}
-
-void GL_CloseLibrary(void)
-{
-#ifdef WIN32
-       FreeLibrary(gldll);
-       gldll = 0;
-#else
-       if (prjobj)
-               dlclose(prjobj);
-       prjobj = NULL;
-#endif
-}
-
-void *GL_GetProcAddress(char *name)
-{
-       void *p = NULL;
-#ifdef WIN32
-       if (qwglGetProcAddress != NULL)
-               p = (void *) qwglGetProcAddress(name);
-       if (p == NULL)
-               p = (void *) GetProcAddress(gldll, name);
-#else
-       p = (void *) dlsym(prjobj, name);
-#endif
-       return p;
-}
-
-static int gl_checkextension(char *name, gl_extensionfunctionlist_t *funcs, char *disableparm, int silent)
-{
-       int failed = false;
-       gl_extensionfunctionlist_t *func;
-
-       Con_Printf("checking for %s...  ", name);
-
-       for (func = funcs;func && func->name;func++)
-               *func->funcvariable = NULL;
-
-       if (disableparm && COM_CheckParm(disableparm))
-       {
-               Con_Printf("disabled by commandline\n");
-               return false;
-       }
-
-       if (strncmp(name, "GL_", 3) || strstr(gl_extensions, name))
-       {
-               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("missing function \"%s\" - broken driver!\n", func->name);
-                               failed = true;
-                       }
-               }
-               // delay the return so it prints all missing functions
-               if (failed)
-                       return false;
-               Con_Printf("enabled\n");
-               return true;
-       }
-       else
-       {
-               Con_Printf("not detected\n");
-               return false;
-       }
-}
-
 void VID_CheckExtensions(void)
 {
-       gl_vendor = NULL;
-       gl_renderer = NULL;
-       gl_version = NULL;
-       gl_extensions = NULL;
-
-       Con_Printf("Opening OpenGL library to retrieve functions\n");
-
        gl_combine_extension = false;
        gl_supportslockarrays = false;
        gl_textureunits = 1;
 
-#if WIN32
-       if (!gl_checkextension("wgl", wglfuncs, NULL, false))
-               Sys_Error("wgl functions not found\n");
-       //gl_checkextension("wglSwapIntervalEXT", wglswapintervalfuncs, NULL, false);
-#endif
-
-       if (!gl_checkextension("OpenGL 1.1.0", opengl110funcs, NULL, false))
+       if (!GL_CheckExtension("OpenGL 1.1.0", opengl110funcs, NULL, false))
                Sys_Error("OpenGL 1.1.0 functions not found\n");
 
-       gl_vendor = qglGetString (GL_VENDOR);
-       gl_renderer = qglGetString (GL_RENDERER);
-       gl_version = qglGetString (GL_VERSION);
-       gl_extensions = qglGetString (GL_EXTENSIONS);
-
        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_Printf("Checking OpenGL extensions...\n");
 
-       if (!gl_checkextension("glDrawRangeElements", drawrangeelementsfuncs, "-nodrawrangeelements", true))
-               gl_checkextension("GL_EXT_draw_range_elements", drawrangeelementsextfuncs, "-nodrawrangeelements", false);
+       if (!GL_CheckExtension("glDrawRangeElements", drawrangeelementsfuncs, "-nodrawrangeelements", true))
+               GL_CheckExtension("GL_EXT_draw_range_elements", drawrangeelementsextfuncs, "-nodrawrangeelements", false);
 
-       if (gl_checkextension("GL_ARB_multitexture", multitexturefuncs, "-nomtex", false))
+       if (GL_CheckExtension("GL_ARB_multitexture", multitexturefuncs, "-nomtex", false))
        {
                qglGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_textureunits);
                if (gl_textureunits > 1)
-                       gl_combine_extension = gl_checkextension("GL_ARB_texture_env_combine", NULL, "-nocombine", false) || gl_checkextension("GL_EXT_texture_env_combine", NULL, "-nocombine", false);
+                       gl_combine_extension = GL_CheckExtension("GL_ARB_texture_env_combine", NULL, "-nocombine", false) || GL_CheckExtension("GL_EXT_texture_env_combine", NULL, "-nocombine", false);
                else
                {
                        Con_Printf("GL_ARB_multitexture with less than 2 units? - BROKEN DRIVER!\n");
@@ -425,13 +319,22 @@ void VID_CheckExtensions(void)
                }
        }
 
-       gl_supportslockarrays = gl_checkextension("GL_EXT_compiled_vertex_array", compiledvertexarrayfuncs, "-nocva", false);
+       gl_supportslockarrays = GL_CheckExtension("GL_EXT_compiled_vertex_array", compiledvertexarrayfuncs, "-nocva", 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;
 }
 
+double VID_CompareMode(int width1, int height1, int bpp1, int width2, int height2, int bpp2)
+{
+       double dw, dh, db;
+       dw = ((width2 - width1) / 2048) * 16;
+       dh = ((height2 - height1) / 1536) * 4;
+       db = (bpp2 - bpp1) / 32;
+       return dw * dw + dh * dh + db * db;
+}
+
 void Force_CenterView_f (void)
 {
        cl.viewangles[PITCH] = 0;
@@ -494,13 +397,29 @@ void IN_Mouse(usercmd_t *cmd, float mx, float my)
 
 void VID_InitCvars(void)
 {
-       Cvar_RegisterVariable(&vid_mode);
-       Cvar_RegisterVariable(&vid_mouse);
+       int i;
+
        Cvar_RegisterVariable(&vid_fullscreen);
+       Cvar_RegisterVariable(&vid_width);
+       Cvar_RegisterVariable(&vid_height);
+       Cvar_RegisterVariable(&vid_bitsperpixel);
+       Cvar_RegisterVariable(&vid_mouse);
        Cvar_RegisterVariable(&gl_combine);
        Cvar_RegisterVariable(&in_pitch_min);
        Cvar_RegisterVariable(&in_pitch_max);
        Cvar_RegisterVariable(&m_filter);
        Cmd_AddCommand("force_centerview", Force_CenterView_f);
+
+// interpret command-line parameters
+       if ((i = COM_CheckParm("-window")) != 0)
+               Cvar_SetValueQuick(&vid_fullscreen, false);
+       if ((i = COM_CheckParm("-fullscreen")) != 0)
+               Cvar_SetValueQuick(&vid_fullscreen, true);
+       if ((i = COM_CheckParm("-width")) != 0)
+               Cvar_SetQuick(&vid_width, com_argv[i+1]);
+       if ((i = COM_CheckParm("-height")) != 0)
+               Cvar_SetQuick(&vid_height, com_argv[i+1]);
+       if ((i = COM_CheckParm("-bpp")) != 0)
+               Cvar_SetQuick(&vid_bitsperpixel, com_argv[i+1]);
 }
 
index 578b94a..f5e2b38 100644 (file)
--- a/vid_wgl.c
+++ b/vid_wgl.c
@@ -24,6 +24,44 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "resource.h"
 #include <commctrl.h>
 
+int (WINAPI *qwglChoosePixelFormat)(HDC, CONST PIXELFORMATDESCRIPTOR *);
+int (WINAPI *qwglDescribePixelFormat)(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR);
+//int (WINAPI *qwglGetPixelFormat)(HDC);
+BOOL (WINAPI *qwglSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *);
+BOOL (WINAPI *qwglSwapBuffers)(HDC);
+HGLRC (WINAPI *qwglCreateContext)(HDC);
+BOOL (WINAPI *qwglDeleteContext)(HGLRC);
+PROC (WINAPI *qwglGetProcAddress)(LPCSTR);
+BOOL (WINAPI *qwglMakeCurrent)(HDC, HGLRC);
+BOOL (WINAPI *qwglSwapIntervalEXT)(int interval);
+const char *(WINAPI *wglGetExtensionsStringARB)(HDC hdc);
+
+static gl_extensionfunctionlist_t getextensionsstringfuncs[] =
+{
+       {"wglGetExtensionsString", (void **) &qwglGetExtensionsString},
+       {NULL, NULL}
+};
+
+static gl_extensionfunctionlist_t wglfuncs[] =
+{
+       {"wglChoosePixelFormat", (void **) &qwglChoosePixelFormat},
+       {"wglDescribePixelFormat", (void **) &qwglDescribePixelFormat},
+//     {"wglGetPixelFormat", (void **) &qwglGetPixelFormat},
+       {"wglSetPixelFormat", (void **) &qwglSetPixelFormat},
+       {"wglSwapBuffers", (void **) &qwglSwapBuffers},
+       {"wglCreateContext", (void **) &qwglCreateContext},
+       {"wglDeleteContext", (void **) &qwglDeleteContext},
+       {"wglGetProcAddress", (void **) &qwglGetProcAddress},
+       {"wglMakeCurrent", (void **) &qwglMakeCurrent},
+       {NULL, NULL}
+};
+
+static gl_extensionfunctionlist_t wglswapintervalfuncs[] =
+{
+       {"wglSwapIntervalEXT", (void **) &qwglSwapIntervalEXT},
+       {NULL, NULL}
+};
+
 #define MAX_MODE_LIST  30
 #define VID_ROW_SIZE   3
 #define MAXWIDTH               10000
@@ -41,7 +79,6 @@ typedef struct {
        int                     dib;
        int                     fullscreen;
        int                     bpp;
-       int                     halfscreen;
        char            modedesc[17];
 } vmode_t;
 
@@ -162,11 +199,6 @@ qboolean VID_SetWindowedMode (int modenum)
 
        modestate = MS_WINDOWED;
 
-       if (vid.conheight > modelist[modenum].height)
-               vid.conheight = modelist[modenum].height;
-       if (vid.conwidth > modelist[modenum].width)
-               vid.conwidth = modelist[modenum].width;
-
        SendMessage (mainwindow, WM_SETICON, (WPARAM)true, (LPARAM)hIcon);
        SendMessage (mainwindow, WM_SETICON, (WPARAM)false, (LPARAM)hIcon);
 
@@ -183,7 +215,7 @@ qboolean VID_SetFullDIBMode (int modenum)
        {
                gdevmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
                gdevmode.dmBitsPerPel = modelist[modenum].bpp;
-               gdevmode.dmPelsWidth = modelist[modenum].width << modelist[modenum].halfscreen;
+               gdevmode.dmPelsWidth = modelist[modenum].width;
                gdevmode.dmPelsHeight = modelist[modenum].height;
                gdevmode.dmSize = sizeof (gdevmode);
 
@@ -220,11 +252,6 @@ qboolean VID_SetFullDIBMode (int modenum)
        ShowWindow (mainwindow, SW_SHOWDEFAULT);
        UpdateWindow (mainwindow);
 
-       if (vid.conheight > modelist[modenum].height)
-               vid.conheight = modelist[modenum].height;
-       if (vid.conwidth > modelist[modenum].width)
-               vid.conwidth = modelist[modenum].width;
-
 // needed because we're not getting WM_MOVE messages fullscreen on NT
        window_x = 0;
        window_y = 0;
@@ -388,10 +415,10 @@ void VID_Shutdown (void)
        if (vid_initialized)
        {
                vid_canalttab = false;
-               hRC = wglGetCurrentContext();
-               hDC = wglGetCurrentDC();
+               hRC = qwglGetCurrentContext();
+               hDC = qwglGetCurrentDC();
 
-               wglMakeCurrent(NULL, NULL);
+               qwglMakeCurrent(NULL, NULL);
 
                // LordHavoc: free textures before closing (may help NVIDIA)
                for (i = 0;i < 8192;i++)
@@ -399,7 +426,7 @@ void VID_Shutdown (void)
                qglDeleteTextures(8192, temp);
 
                if (hRC)
-                       wglDeleteContext(hRC);
+                       qwglDeleteContext(hRC);
 
                // close the library before we get rid of the window
                GL_CloseLibrary();
@@ -864,7 +891,7 @@ void VID_DescribeModes_f (void)
        leavecurrentmode = t;
 }
 
-void VID_AddMode(int type, int width, int height, int modenum, int halfscreen, int dib, int fullscreen, int bpp)
+void VID_AddMode(int type, int width, int height, int modenum, int dib, int fullscreen, int bpp)
 {
        int i;
        if (nummodes >= MAX_MODE_LIST)
@@ -873,7 +900,6 @@ void VID_AddMode(int type, int width, int height, int modenum, int halfscreen, i
        modelist[nummodes].width = width;
        modelist[nummodes].height = height;
        modelist[nummodes].modenum = modenum;
-       modelist[nummodes].halfscreen = halfscreen;
        modelist[nummodes].dib = dib;
        modelist[nummodes].fullscreen = fullscreen;
        modelist[nummodes].bpp = bpp;
@@ -925,7 +951,7 @@ void VID_InitDIB (HINSTANCE hInstance)
        if (h < 240)
                h = 240;
 
-       VID_AddMode(MS_WINDOWED, w, h, 0, 0, 1, 0, 0);
+       VID_AddMode(MS_WINDOWED, w, h, 0, 1, 0, 0);
 }
 
 
@@ -1054,203 +1080,6 @@ void VID_RestoreSystemGamma(void)
        ReleaseDC (NULL, hdc);
 }
 
-/*
-===================
-VID_Init
-===================
-*/
-void VID_Init (void)
-{
-       int i;
-       int basenummodes, width, height = 0, bpp, findbpp, done;
-       HDC hdc;
-       DEVMODE devmode;
-
-       GL_OpenLibrary();
-
-       memset(&devmode, 0, sizeof(devmode));
-
-       Cmd_AddCommand ("vid_nummodes", VID_NumModes_f);
-       Cmd_AddCommand ("vid_describecurrentmode", VID_DescribeCurrentMode_f);
-       Cmd_AddCommand ("vid_describemode", VID_DescribeMode_f);
-       Cmd_AddCommand ("vid_describemodes", VID_DescribeModes_f);
-
-       VID_GetSystemGamma();
-
-       hIcon = LoadIcon (global_hInstance, MAKEINTRESOURCE (IDI_ICON2));
-
-       InitCommonControls();
-
-       VID_InitDIB (global_hInstance);
-       basenummodes = nummodes = 1;
-
-       VID_InitFullDIB (global_hInstance);
-
-       if (COM_CheckParm("-window"))
-       {
-               hdc = GetDC (NULL);
-
-               if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)
-                       Sys_Error ("Can't run in non-RGB mode");
-
-               ReleaseDC (NULL, hdc);
-
-               windowed = true;
-
-               vid_default = MODE_WINDOWED;
-       }
-       else
-       {
-               if (nummodes == 1)
-                       Sys_Error ("No RGB fullscreen modes available");
-
-               windowed = false;
-
-               if (COM_CheckParm("-mode"))
-                       vid_default = atoi(com_argv[COM_CheckParm("-mode")+1]);
-               else
-               {
-                       if (COM_CheckParm("-current"))
-                       {
-                               modelist[MODE_FULLSCREEN_DEFAULT].width = GetSystemMetrics (SM_CXSCREEN);
-                               modelist[MODE_FULLSCREEN_DEFAULT].height = GetSystemMetrics (SM_CYSCREEN);
-                               vid_default = MODE_FULLSCREEN_DEFAULT;
-                               leavecurrentmode = 1;
-                       }
-                       else
-                       {
-                               if (COM_CheckParm("-width"))
-                                       width = atoi(com_argv[COM_CheckParm("-width")+1]);
-                               else
-                                       width = 640;
-
-                               if (COM_CheckParm("-bpp"))
-                               {
-                                       bpp = atoi(com_argv[COM_CheckParm("-bpp")+1]);
-                                       findbpp = 0;
-                               }
-                               else
-                               {
-                                       bpp = 15;
-                                       findbpp = 1;
-                               }
-
-                               if (COM_CheckParm("-height"))
-                                       height = atoi(com_argv[COM_CheckParm("-height")+1]);
-
-                       // if they want to force it, add the specified mode to the list
-                               if (COM_CheckParm("-force") && (nummodes < MAX_MODE_LIST))
-                                       VID_AddMode(MS_FULLDIB, width, height, 0, 0, 1, 1, bpp);
-
-                               done = 0;
-
-                               do
-                               {
-                                       if (COM_CheckParm("-height"))
-                                       {
-                                               height = atoi(com_argv[COM_CheckParm("-height")+1]);
-
-                                               for (i=1, vid_default=0 ; i<nummodes ; i++)
-                                               {
-                                                       if ((modelist[i].width == width) && (modelist[i].height == height) && (modelist[i].bpp == bpp))
-                                                       {
-                                                               vid_default = i;
-                                                               done = 1;
-                                                               break;
-                                                       }
-                                               }
-                                       }
-                                       else
-                                       {
-                                               for (i=1, vid_default=0 ; i<nummodes ; i++)
-                                               {
-                                                       if ((modelist[i].width == width) && (modelist[i].bpp == bpp))
-                                                       {
-                                                               vid_default = i;
-                                                               done = 1;
-                                                               break;
-                                                       }
-                                               }
-                                       }
-
-                                       if (!done)
-                                       {
-                                               if (findbpp)
-                                               {
-                                                       switch (bpp)
-                                                       {
-                                                       case 15: bpp = 16;break;
-                                                       case 16: bpp = 32;break;
-                                                       case 32: bpp = 24;break;
-                                                       case 24: done = 1;break;
-                                                       }
-                                               }
-                                               else
-                                                       done = 1;
-                                       }
-                               }
-                               while (!done);
-
-                               if (!vid_default)
-                                       Sys_Error ("Specified video mode not available");
-                       }
-               }
-       }
-
-       vid_initialized = true;
-
-       if ((i = COM_CheckParm("-conwidth")) != 0)
-               vid.conwidth = atoi(com_argv[i+1]);
-       else
-               vid.conwidth = 640;
-
-       vid.conwidth &= 0xfff8; // make it a multiple of eight
-
-       if (vid.conwidth < 320)
-               vid.conwidth = 320;
-
-       // pick a conheight that matches with correct aspect
-       vid.conheight = vid.conwidth*3 / 4;
-
-       if ((i = COM_CheckParm("-conheight")) != 0)
-               vid.conheight = atoi(com_argv[i+1]);
-       if (vid.conheight < 200)
-               vid.conheight = 200;
-
-       VID_SetMode (vid_default);
-
-       maindc = GetDC(mainwindow);
-       bSetupPixelFormat(maindc);
-
-       baseRC = wglCreateContext( maindc );
-       if (!baseRC)
-               Sys_Error ("Could not initialize GL (wglCreateContext failed).\n\nMake sure you are in 65536 color mode, and try running -window.");
-       if (!wglMakeCurrent( maindc, baseRC ))
-               Sys_Error ("wglMakeCurrent failed");
-
-       GL_Init ();
-
-       // LordHavoc: special differences for ATI (broken 8bit color when also using 32bit? weird!)
-       if (strncasecmp(gl_vendor,"ATI",3)==0)
-       {
-               if (strncasecmp(gl_renderer,"Rage Pro",8)==0)
-                       isRagePro = true;
-       }
-       if (strncasecmp(gl_renderer,"Matrox G200 Direct3D",20)==0) // a D3D driver for GL? sigh...
-               isG200 = true;
-
-       vid_realmode = vid_modenum;
-
-       vid_menudrawfn = VID_MenuDraw;
-       vid_menukeyfn = VID_MenuKey;
-
-       strcpy (badmode.modedesc, "Bad mode");
-       vid_canalttab = true;
-
-       vid_hidden = false;
-}
-
-
 //========================================================
 // Video menu stuff
 //========================================================
@@ -1362,3 +1191,159 @@ void VID_MenuKey (int key)
        }
 }
 
+static HINSTANCE gldll;
+
+int GL_OpenLibrary(const char *name)
+{
+       Con_Printf("Loading GL driver %s\n", name);
+       GL_CloseLibrary();
+       if (!(gldll = LoadLibrary(name)))
+       {
+               Con_Printf("Unable to LoadLibrary %s\n", name);
+               return false;
+       }
+       strcpy(gl_driver, name);
+       return true;
+}
+
+void GL_CloseLibrary(void)
+{
+       FreeLibrary(gldll);
+       gldll = 0;
+       gl_driver[0] = 0;
+       qwglGetProcAddress = NULL;
+       gl_extensions = "";
+       gl_platform = "";
+       gl_platformextensions = "";
+}
+
+void *GL_GetProcAddress(const char *name)
+{
+       void *p = NULL;
+       if (qwglGetProcAddress != NULL)
+               p = (void *) qwglGetProcAddress(name);
+       if (p == NULL)
+               p = (void *) GetProcAddress(gldll, name);
+       return p;
+}
+/*
+===================
+VID_Init
+===================
+*/
+void VID_Init (int fullscreen, int width, int height)
+{
+       int i;
+       int basenummodes, bpp, findbpp, done;
+       HDC hdc;
+       DEVMODE devmode;
+
+       if (!GL_OpenLibrary("opengl32.dll"))
+               Sys_Error("Unable to load GL driver\n");
+
+       memset(&devmode, 0, sizeof(devmode));
+
+       Cmd_AddCommand ("vid_nummodes", VID_NumModes_f);
+       Cmd_AddCommand ("vid_describecurrentmode", VID_DescribeCurrentMode_f);
+       Cmd_AddCommand ("vid_describemode", VID_DescribeMode_f);
+       Cmd_AddCommand ("vid_describemodes", VID_DescribeModes_f);
+
+       VID_GetSystemGamma();
+
+       hIcon = LoadIcon (global_hInstance, MAKEINTRESOURCE (IDI_ICON2));
+
+       InitCommonControls();
+
+       VID_InitDIB (global_hInstance);
+       basenummodes = nummodes = 1;
+
+       VID_InitFullDIB (global_hInstance);
+
+       if (!fullscreen)
+       {
+               hdc = GetDC (NULL);
+
+               if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE)
+                       Sys_Error ("Can't run in non-RGB mode");
+
+               ReleaseDC (NULL, hdc);
+
+               windowed = true;
+
+               vid_default = MODE_WINDOWED;
+       }
+       else
+       {
+               if (nummodes == 1)
+                       Sys_Error ("No RGB fullscreen modes available");
+
+               windowed = false;
+
+               done = 0;
+
+               bestmode = -1;
+               bestrating = 1000000000;
+               for (i = 0;i < nummodes;i++)
+               {
+                       rating = VID_CompareMode(fullscreen, width, height, bpp, modelist[i].fullscreen, modelist[i].width, modelist[i].height, modelist[i].bpp);
+                       if (bestrating > rating)
+                       {
+                               bestrating = rating;
+                               bestmode = i;
+                       }
+               }
+
+               if (bestmode < 0)
+                       Sys_Error ("Specified video mode not available");
+       }
+
+       vid_initialized = true;
+
+       VID_SetMode (vid_default);
+
+       maindc = GetDC(mainwindow);
+       bSetupPixelFormat(maindc);
+
+       if (!gl_checkextension("wgl", wglfuncs, NULL, false))
+               Sys_Error("wgl functions not found\n");
+
+       baseRC = qwglCreateContext( maindc );
+       if (!baseRC)
+               Sys_Error ("Could not initialize GL (wglCreateContext failed).\n\nMake sure you are in 65536 color mode, and try running -window.");
+       if (!qwglMakeCurrent( maindc, baseRC ))
+               Sys_Error ("wglMakeCurrent failed");
+
+       gl_renderer = qglGetString(GL_RENDERER);
+       gl_vendor = qglGetString(GL_VENDOR);
+       gl_version = qglGetString(GL_VERSION);
+       gl_extensions = qglGetString(GL_EXTENSIONS);
+       gl_platformname = "WGL";
+       gl_platformextensions = "";
+
+       if (gl_checkextension("WGL_ARB_extensions_string", extensionsstringfuncs, NULL, false))
+               gl_platformextensions = qwglGetExtensionsStringARB(maindc);
+
+       gl_videosyncavailable = gl_checkextension("WGL_EXT_swap_control", wglswapintervalfuncs, NULL, false);
+
+       GL_Init ();
+
+       // LordHavoc: special differences for ATI (broken 8bit color when also using 32bit? weird!)
+       if (strncasecmp(gl_vendor,"ATI",3)==0)
+       {
+               if (strncasecmp(gl_renderer,"Rage Pro",8)==0)
+                       isRagePro = true;
+       }
+       if (strncasecmp(gl_renderer,"Matrox G200 Direct3D",20)==0) // a D3D driver for GL? sigh...
+               isG200 = true;
+
+       vid_realmode = vid_modenum;
+
+       vid_menudrawfn = VID_MenuDraw;
+       vid_menukeyfn = VID_MenuKey;
+
+       strcpy (badmode.modedesc, "Bad mode");
+       vid_canalttab = true;
+
+       vid_hidden = false;
+}
+