2004-08-22 22:29:09 +00:00
/*
Copyright ( C ) 1996 - 1997 Id Software , Inc .
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
2011-05-19 13:34:07 +00:00
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
2004-08-22 22:29:09 +00:00
See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
// gl_vidnt.c -- NT GL vid component
# include "quakedef.h"
2009-11-04 21:16:50 +00:00
# ifdef GLQUAKE
2004-08-22 22:29:09 +00:00
# include "glquake.h"
# include "winquake.h"
# include "resource.h"
# include <commctrl.h>
2009-04-01 22:03:56 +00:00
# ifndef SetWindowLongPtr //yes its a define, for unicode support
# define SetWindowLongPtr SetWindowLong
# endif
2004-08-22 22:29:09 +00:00
# ifndef CDS_FULLSCREEN
2006-02-06 01:06:17 +00:00
# define CDS_FULLSCREEN 4
2004-08-22 22:29:09 +00:00
# endif
# ifndef WM_XBUTTONDOWN
# define WM_XBUTTONDOWN 0x020B
# define WM_XBUTTONUP 0x020C
# endif
# ifndef MK_XBUTTON1
# define MK_XBUTTON1 0x0020
2009-01-18 01:47:48 +00:00
# endif
# ifndef MK_XBUTTON2
2004-08-22 22:29:09 +00:00
# define MK_XBUTTON2 0x0040
2009-01-18 01:47:48 +00:00
# endif
2005-06-18 22:30:57 +00:00
// copied from DarkPlaces in an attempt to grab more buttons
2009-01-18 01:47:48 +00:00
# ifndef MK_XBUTTON3
2005-06-18 22:30:57 +00:00
# define MK_XBUTTON3 0x0080
2009-01-18 01:47:48 +00:00
# endif
# ifndef MK_XBUTTON4
2005-06-18 22:30:57 +00:00
# define MK_XBUTTON4 0x0100
2009-01-18 01:47:48 +00:00
# endif
# ifndef MK_XBUTTON5
2005-06-18 22:30:57 +00:00
# define MK_XBUTTON5 0x0200
2009-01-18 01:47:48 +00:00
# endif
# ifndef MK_XBUTTON6
2005-06-18 22:30:57 +00:00
# define MK_XBUTTON6 0x0400
2009-01-18 01:47:48 +00:00
# endif
# ifndef MK_XBUTTON7
2005-06-18 22:30:57 +00:00
# define MK_XBUTTON7 0x0800
2009-01-18 01:47:48 +00:00
# endif
2004-08-22 22:29:09 +00:00
2005-06-29 21:20:34 +00:00
# ifndef WM_INPUT
# define WM_INPUT 255
# endif
2004-08-22 22:29:09 +00:00
2009-04-06 00:34:32 +00:00
# ifndef WS_EX_LAYERED
# define WS_EX_LAYERED 0x00080000
2009-04-06 01:01:31 +00:00
# endif
# ifndef LWA_ALPHA
2009-04-06 00:34:32 +00:00
# define LWA_ALPHA 0x00000002
# endif
2011-05-19 13:34:07 +00:00
typedef BOOL ( WINAPI * lpfnSetLayeredWindowAttributes ) ( HWND hwnd , COLORREF crKey , BYTE bAlpha , DWORD dwFlags ) ;
2009-04-06 00:34:32 +00:00
2006-04-02 09:11:37 +00:00
extern cvar_t vid_conwidth , vid_conautoscale ;
2004-08-22 22:29:09 +00:00
2009-04-01 22:03:56 +00:00
# define WINDOW_CLASS_NAME "FTEGLQuake"
2004-08-22 22:29:09 +00:00
# define MAX_MODE_LIST 128
# define VID_ROW_SIZE 3
# define WARP_WIDTH 320
# define WARP_HEIGHT 200
# define MAXWIDTH 10000
# define MAXHEIGHT 10000
# define BASEWIDTH 320
# define BASEHEIGHT 200
2009-04-06 00:34:32 +00:00
extern cvar_t vid_width ;
extern cvar_t vid_height ;
extern cvar_t vid_wndalpha ;
2004-08-22 22:29:09 +00:00
typedef enum { MS_WINDOWED , MS_FULLSCREEN , MS_FULLDIB , MS_UNINIT } modestate_t ;
BOOL bSetupPixelFormat ( HDC hDC ) ;
//qboolean VID_SetWindowedMode (int modenum);
//qboolean VID_SetFullDIBMode (int modenum);
qboolean VID_SetWindowedMode ( rendererstate_t * info ) ; //-1 on bpp or hz for default.
qboolean VID_SetFullDIBMode ( rendererstate_t * info ) ; //-1 on bpp or hz for default.
qboolean scr_skipupdate ;
static DEVMODE gdevmode ;
static qboolean vid_initialized = false ;
static qboolean leavecurrentmode = true ;
static qboolean vid_canalttab = false ;
static qboolean vid_wassuspended = false ;
extern qboolean mouseactive ; // from in_win.c
static HICON hIcon ;
extern qboolean vid_isfullscreen ;
2005-07-28 15:52:31 +00:00
unsigned short originalgammaramps [ 3 ] [ 256 ] ;
2004-09-20 23:25:38 +00:00
2009-07-16 22:06:59 +00:00
qboolean vid_initializing ;
2004-08-22 22:29:09 +00:00
qboolean VID_AttachGL ( rendererstate_t * info ) ;
int DIBWidth , DIBHeight ;
RECT WindowRect ;
DWORD WindowStyle , ExWindowStyle ;
HWND mainwindow , dibwindow ;
unsigned char vid_curpal [ 256 * 3 ] ;
HGLRC baseRC ;
HDC maindc ;
HWND WINAPI InitializeWindow ( HINSTANCE hInstance , int nCmdShow ) ;
viddef_t vid ; // global video state
//unsigned short d_8to16rgbtable[256];
//unsigned d_8to24rgbtable[256];
//unsigned short d_8to16bgrtable[256];
//unsigned d_8to24bgrtable[256];
modestate_t modestate = MS_UNINIT ;
LONG WINAPI GLMainWndProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam ) ;
2005-12-06 02:19:22 +00:00
qboolean GLAppActivate ( BOOL fActive , BOOL minimize ) ;
2004-08-22 22:29:09 +00:00
void ClearAllStates ( void ) ;
2009-04-06 00:34:32 +00:00
void VID_UpdateWindowStatus ( HWND hWnd ) ;
2004-08-22 22:29:09 +00:00
void GL_Init ( void * ( * getglfunction ) ( char * name ) ) ;
typedef void ( APIENTRY * lp3DFXFUNC ) ( int , int , int , int , int , const void * ) ;
2005-01-07 03:16:44 +00:00
lp3DFXFUNC qglColorTableEXT ;
2004-08-22 22:29:09 +00:00
qboolean is8bit = false ;
qboolean isPermedia = false ;
//====================================
// Note that 0 is MODE_WINDOWED
extern cvar_t vid_mode ;
// Note that 3 is MODE_FULLSCREEN_DEFAULT
extern cvar_t _vid_wait_override ;
extern cvar_t _windowed_mouse ;
2004-09-20 23:25:38 +00:00
extern cvar_t vid_hardwaregamma ;
2005-10-18 04:42:13 +00:00
extern cvar_t vid_desktopgamma ;
2004-11-18 17:55:04 +00:00
extern cvar_t gl_lateswap ;
2008-01-09 00:37:17 +00:00
extern cvar_t vid_preservegamma ;
2004-08-22 22:29:09 +00:00
2009-11-04 21:16:50 +00:00
extern cvar_t vid_gl_context_version ;
extern cvar_t vid_gl_context_debug ;
2011-01-04 02:56:16 +00:00
extern cvar_t vid_gl_context_es2 ;
2009-11-04 21:16:50 +00:00
extern cvar_t vid_gl_context_forwardcompatible ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
extern cvar_t vid_gl_context_compatibility ;
2009-11-04 21:16:50 +00:00
2004-08-22 22:29:09 +00:00
int window_center_x , window_center_y , window_x , window_y , window_width , window_height ;
RECT window_rect ;
HMODULE hInstGL = NULL ;
HMODULE hInstwgl = NULL ;
2011-10-27 16:16:29 +00:00
static qboolean usingminidriver ;
static char reqminidriver [ MAX_OSPATH ] ;
static char opengldllname [ MAX_OSPATH ] ;
2004-08-22 22:29:09 +00:00
//just GetProcAddress with a safty net.
void * getglfunc ( char * name )
{
FARPROC proc ;
proc = qwglGetProcAddress ? qwglGetProcAddress ( name ) : NULL ;
if ( ! proc )
{
proc = GetProcAddress ( hInstGL , name ) ;
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: getglfunc: gpa %s: success %i \n " , name , ! ! proc ) ) ;
2004-08-22 22:29:09 +00:00
return proc ;
}
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: getglfunc: glgpa %s: success %i \n " , name , ! ! proc ) ) ;
2004-08-22 22:29:09 +00:00
return proc ;
}
void * getwglfunc ( char * name )
{
FARPROC proc ;
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: getwglfunc: %s: getting \n " , name ) ) ;
2010-07-11 02:22:39 +00:00
2004-08-22 22:29:09 +00:00
proc = GetProcAddress ( hInstGL , name ) ;
if ( ! proc )
{
if ( ! hInstwgl )
2004-10-07 13:13:15 +00:00
{
TRACE ( ( " dbg: getwglfunc: explicitly loading opengl32.dll \n " , name ) ) ;
2004-08-22 22:29:09 +00:00
hInstwgl = LoadLibrary ( " opengl32.dll " ) ;
2004-10-07 13:13:15 +00:00
}
TRACE ( ( " dbg: getwglfunc: %s: wglgetting \n " , name ) ) ;
2004-08-22 22:29:09 +00:00
proc = GetProcAddress ( hInstwgl , name ) ;
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: getwglfunc: gpa %s: success %i \n " , name , ! ! proc ) ) ;
2004-08-22 22:29:09 +00:00
if ( ! proc )
Sys_Error ( " GL function %s was not found in %s \n Possibly you do not have a full enough gl implementation " , name , opengldllname ) ;
}
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: getwglfunc: glgpa %s: success %i \n " , name , ! ! proc ) ) ;
2004-08-22 22:29:09 +00:00
return proc ;
}
HGLRC ( WINAPI * qwglCreateContext ) ( HDC ) ;
BOOL ( WINAPI * qwglDeleteContext ) ( HGLRC ) ;
HGLRC ( WINAPI * qwglGetCurrentContext ) ( VOID ) ;
HDC ( WINAPI * qwglGetCurrentDC ) ( VOID ) ;
PROC ( WINAPI * qwglGetProcAddress ) ( LPCSTR ) ;
BOOL ( WINAPI * qwglMakeCurrent ) ( HDC , HGLRC ) ;
BOOL ( WINAPI * qSwapBuffers ) ( HDC ) ;
2011-10-27 16:16:29 +00:00
int ( WINAPI * qChoosePixelFormat ) ( HDC , CONST PIXELFORMATDESCRIPTOR * ) ;
BOOL ( WINAPI * qSetPixelFormat ) ( HDC , int , CONST PIXELFORMATDESCRIPTOR * ) ;
int ( WINAPI * qDescribePixelFormat ) ( HDC , int , UINT , LPPIXELFORMATDESCRIPTOR ) ;
2004-08-22 22:29:09 +00:00
BOOL ( WINAPI * qwglSwapIntervalEXT ) ( int ) ;
2006-02-11 02:05:15 +00:00
BOOL ( APIENTRY * qGetDeviceGammaRamp ) ( HDC hDC , GLvoid * ramp ) ;
BOOL ( APIENTRY * qSetDeviceGammaRamp ) ( HDC hDC , GLvoid * ramp ) ;
2004-08-22 22:29:09 +00:00
2006-03-15 20:11:37 +00:00
BOOL ( APIENTRY * qwglChoosePixelFormatARB ) ( HDC hdc , const int * piAttribIList , const FLOAT * pfAttribFList , UINT nMaxFormats , int * piFormats , UINT * nNumFormats ) ;
2009-11-04 21:16:50 +00:00
HGLRC ( APIENTRY * qwglCreateContextAttribsARB ) ( HDC hDC , HGLRC hShareContext , const int * attribList ) ;
# define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
# define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
# define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
# define WGL_CONTEXT_FLAGS_ARB 0x2094
2011-01-04 02:56:16 +00:00
# define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
# define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
# define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
2011-01-04 02:56:16 +00:00
# define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
# define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
# define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 /*WGL_CONTEXT_ES2_PROFILE_BIT_EXT*/
2009-11-04 21:16:50 +00:00
# define ERROR_INVALID_VERSION_ARB 0x2095
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
# define ERROR_INVALID_PROFILE_ARB 0x2096
2009-11-04 21:16:50 +00:00
2004-08-22 22:29:09 +00:00
qboolean GLInitialise ( char * renderer )
{
2011-06-16 02:03:57 +00:00
if ( ! hInstGL | | strcmp ( reqminidriver , renderer ) )
2005-04-26 16:04:12 +00:00
{
2011-10-27 16:16:29 +00:00
usingminidriver = false ;
2005-04-26 16:04:12 +00:00
if ( hInstGL )
2011-06-16 02:03:57 +00:00
FreeLibrary ( hInstGL ) ;
hInstGL = NULL ;
if ( hInstwgl )
FreeLibrary ( hInstwgl ) ;
hInstwgl = NULL ;
2011-05-19 13:34:07 +00:00
2011-06-16 02:03:57 +00:00
Q_strncpyz ( reqminidriver , renderer , sizeof ( reqminidriver ) ) ;
Q_strncpyz ( opengldllname , renderer , sizeof ( opengldllname ) ) ;
2005-04-26 16:04:12 +00:00
2011-06-16 02:03:57 +00:00
if ( * renderer )
{
Con_DPrintf ( " Loading renderer dll \" %s \" " , renderer ) ;
hInstGL = LoadLibrary ( opengldllname ) ;
if ( hInstGL )
2011-10-27 16:16:29 +00:00
{
usingminidriver = true ;
2011-06-16 02:03:57 +00:00
Con_DPrintf ( " Success \n " ) ;
2011-10-27 16:16:29 +00:00
}
2011-06-16 02:03:57 +00:00
else
Con_DPrintf ( " Failed \n " ) ;
}
2005-04-26 16:04:12 +00:00
else
2011-06-16 02:03:57 +00:00
hInstGL = NULL ;
if ( ! hInstGL )
{
unsigned int emode ;
strcpy ( opengldllname , " opengl32 " ) ;
Con_DPrintf ( " Loading renderer dll \" %s \" " , opengldllname ) ;
emode = SetErrorMode ( SEM_FAILCRITICALERRORS ) ; /*no annoying errors if they use glide*/
hInstGL = LoadLibrary ( opengldllname ) ;
SetErrorMode ( emode ) ;
if ( hInstGL )
Con_DPrintf ( " Success \n " ) ;
else
Con_DPrintf ( " Failed \n " ) ;
}
if ( ! hInstGL )
{
if ( * renderer )
Con_Printf ( " Couldn't load %s or %s \n " , renderer , opengldllname ) ;
else
Con_Printf ( " Couldn't load %s \n " , opengldllname ) ;
return false ;
}
2004-12-24 08:45:56 +00:00
}
2011-06-16 02:03:57 +00:00
else
2004-08-22 22:29:09 +00:00
{
2011-06-16 02:03:57 +00:00
Con_DPrintf ( " Reusing renderer dll %s \n " , opengldllname ) ;
2004-08-22 22:29:09 +00:00
}
2004-12-24 08:45:56 +00:00
Con_DPrintf ( " Loaded renderer dll %s \n " , opengldllname ) ;
2004-10-07 13:13:15 +00:00
2004-08-22 22:29:09 +00:00
// windows dependant
qwglCreateContext = ( void * ) getwglfunc ( " wglCreateContext " ) ;
qwglDeleteContext = ( void * ) getwglfunc ( " wglDeleteContext " ) ;
qwglGetCurrentContext = ( void * ) getwglfunc ( " wglGetCurrentContext " ) ;
qwglGetCurrentDC = ( void * ) getwglfunc ( " wglGetCurrentDC " ) ;
qwglGetProcAddress = ( void * ) getwglfunc ( " wglGetProcAddress " ) ;
qwglMakeCurrent = ( void * ) getwglfunc ( " wglMakeCurrent " ) ;
2011-10-27 16:16:29 +00:00
if ( usingminidriver )
{
qSwapBuffers = ( void * ) getglfunc ( " wglSwapBuffers " ) ;
qChoosePixelFormat = ( void * ) getglfunc ( " wglChoosePixelFormat " ) ;
qSetPixelFormat = ( void * ) getglfunc ( " wglSetPixelFormat " ) ;
qDescribePixelFormat = ( void * ) getglfunc ( " wglDescribePixelFormat " ) ;
}
else
{
qSwapBuffers = SwapBuffers ;
qChoosePixelFormat = ChoosePixelFormat ;
qSetPixelFormat = SetPixelFormat ;
qDescribePixelFormat = DescribePixelFormat ;
}
2004-08-22 22:29:09 +00:00
2006-02-11 02:05:15 +00:00
qGetDeviceGammaRamp = ( void * ) getglfunc ( " wglGetDeviceGammaRamp3DFX " ) ;
qSetDeviceGammaRamp = ( void * ) getglfunc ( " wglSetDeviceGammaRamp3DFX " ) ;
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: GLInitialise: got wgl funcs \n " ) ) ;
2004-08-22 22:29:09 +00:00
return true ;
}
2011-04-30 17:21:10 +00:00
/*doesn't consider parent offsets*/
2011-10-27 16:16:29 +00:00
RECT centerrect ( unsigned int parentleft , unsigned int parenttop , unsigned int parentwidth , unsigned int parentheight , unsigned int cwidth , unsigned int cheight )
2004-08-22 22:29:09 +00:00
{
2011-04-30 17:21:10 +00:00
RECT r ;
if ( ! vid_width . ival )
cwidth = parentwidth ;
if ( ! vid_height . ival )
cheight = parentwidth ;
if ( parentwidth < cwidth )
{
2011-10-27 16:16:29 +00:00
r . left = parentleft ;
r . right = r . left + parentwidth ;
2011-04-30 17:21:10 +00:00
}
else
{
2011-10-27 16:16:29 +00:00
r . left = parentleft + ( parentwidth - cwidth ) / 2 ;
2011-04-30 17:21:10 +00:00
r . right = r . left + cwidth ;
}
if ( parentheight < cheight )
{
2011-10-27 16:16:29 +00:00
r . top = parenttop ;
r . bottom = r . top + parentheight ;
2011-04-30 17:21:10 +00:00
}
else
{
2011-10-27 16:16:29 +00:00
r . top = parenttop + ( parentheight - cheight ) / 2 ;
2011-04-30 17:21:10 +00:00
r . bottom = r . top + cheight ;
}
return r ;
2004-08-22 22:29:09 +00:00
}
qboolean VID_SetWindowedMode ( rendererstate_t * info )
//qboolean VID_SetWindowedMode (int modenum)
{
int i ;
HDC hdc ;
2011-10-27 16:16:29 +00:00
int lastmodestate , wwidth , wheight , pleft , ptop , pwidth , pheight ;
2004-08-22 22:29:09 +00:00
RECT rect ;
hdc = GetDC ( NULL ) ;
if ( GetDeviceCaps ( hdc , RASTERCAPS ) & RC_PALETTE )
{
ReleaseDC ( NULL , hdc ) ;
Con_Printf ( " Can't run GL in non-RGB mode \n " ) ;
return false ;
}
ReleaseDC ( NULL , hdc ) ;
lastmodestate = modestate ;
WindowRect . top = WindowRect . left = 0 ;
WindowRect . right = info - > width ;
WindowRect . bottom = info - > height ;
2010-08-11 23:55:35 +00:00
# ifndef _SDL
2009-04-06 00:34:32 +00:00
if ( sys_parentwindow )
2009-04-01 22:03:56 +00:00
{
2009-04-06 00:34:32 +00:00
SetWindowLong ( sys_parentwindow , GWL_STYLE , GetWindowLong ( sys_parentwindow , GWL_STYLE ) | WS_OVERLAPPED ) ;
2009-04-01 22:03:56 +00:00
WindowStyle = WS_CHILDWINDOW | WS_OVERLAPPED ;
ExWindowStyle = 0 ;
2009-04-06 00:34:32 +00:00
2011-10-27 16:16:29 +00:00
pleft = sys_parentleft ;
ptop = sys_parenttop ;
2011-04-30 17:21:10 +00:00
pwidth = sys_parentwidth ;
pheight = sys_parentheight ;
2009-04-01 22:03:56 +00:00
}
else
2010-08-11 23:55:35 +00:00
# endif
2009-04-01 22:03:56 +00:00
{
WindowStyle = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU |
WS_MINIMIZEBOX ;
ExWindowStyle = 0 ;
2004-08-22 22:29:09 +00:00
2009-04-01 22:03:56 +00:00
WindowStyle | = WS_SIZEBOX | WS_MAXIMIZEBOX ;
2011-04-30 17:21:10 +00:00
2011-10-27 16:16:29 +00:00
pleft = 0 ;
ptop = 0 ;
2011-04-30 17:21:10 +00:00
pwidth = GetSystemMetrics ( SM_CXSCREEN ) ;
pheight = GetSystemMetrics ( SM_CYSCREEN ) ;
/*Assume dual monitors, and chop the width to try to put it on only one screen*/
if ( pwidth > = pheight * 2 )
pwidth / = 2 ;
2009-04-01 22:03:56 +00:00
}
2004-08-22 22:29:09 +00:00
2009-04-06 00:34:32 +00:00
DIBWidth = WindowRect . right - WindowRect . left ;
DIBHeight = WindowRect . bottom - WindowRect . top ;
2004-08-22 22:29:09 +00:00
rect = WindowRect ;
AdjustWindowRectEx ( & rect , WindowStyle , FALSE , 0 ) ;
wwidth = rect . right - rect . left ;
wheight = rect . bottom - rect . top ;
2011-10-27 16:16:29 +00:00
WindowRect = centerrect ( pleft , ptop , pwidth , pheight , wwidth , wheight ) ;
2011-04-30 17:21:10 +00:00
2004-08-22 22:29:09 +00:00
// Create the DIB window
dibwindow = CreateWindowEx (
ExWindowStyle ,
WINDOW_CLASS_NAME ,
2005-11-14 01:32:21 +00:00
FULLENGINENAME ,
2004-08-22 22:29:09 +00:00
WindowStyle ,
2011-04-30 17:21:10 +00:00
WindowRect . left , WindowRect . top ,
WindowRect . right - WindowRect . left ,
WindowRect . bottom - WindowRect . top ,
2009-04-06 00:34:32 +00:00
sys_parentwindow ,
2004-08-22 22:29:09 +00:00
NULL ,
global_hInstance ,
NULL ) ;
if ( ! dibwindow )
{
Con_Printf ( " Couldn't create DIB window " ) ;
return false ;
}
2009-04-06 00:34:32 +00:00
if ( ! sys_parentwindow )
2009-04-01 22:03:56 +00:00
{
2009-04-06 00:34:32 +00:00
# ifdef WS_EX_LAYERED
int av ;
av = 255 * vid_wndalpha . value ;
if ( av < 70 )
av = 70 ;
if ( av < 255 )
{
HMODULE hm = GetModuleHandle ( " user32.dll " ) ;
lpfnSetLayeredWindowAttributes pSetLayeredWindowAttributes ;
pSetLayeredWindowAttributes = ( void * ) GetProcAddress ( hm , " SetLayeredWindowAttributes " ) ;
if ( pSetLayeredWindowAttributes )
{
2011-05-19 13:34:07 +00:00
// Set WS_EX_LAYERED on this window
2009-04-06 00:34:32 +00:00
SetWindowLong ( dibwindow , GWL_EXSTYLE , GetWindowLong ( dibwindow , GWL_EXSTYLE ) | WS_EX_LAYERED ) ;
// Make this window 70% alpha
2009-07-25 11:05:06 +00:00
pSetLayeredWindowAttributes ( dibwindow , 0 , ( BYTE ) av , LWA_ALPHA ) ;
2009-04-06 00:34:32 +00:00
}
}
# endif
2009-04-01 22:03:56 +00:00
}
2011-04-30 17:21:10 +00:00
ShowWindow ( dibwindow , SW_SHOWDEFAULT ) ;
SetFocus ( dibwindow ) ;
2004-08-22 22:29:09 +00:00
2006-03-15 20:11:37 +00:00
// ShowWindow (dibwindow, SW_SHOWDEFAULT);
// UpdateWindow (dibwindow);
2004-08-22 22:29:09 +00:00
modestate = MS_WINDOWED ;
// because we have set the background brush for the window to NULL
// (to avoid flickering when re-sizing the window on the desktop),
// we clear the window to black when created, otherwise it will be
// empty while Quake starts up.
hdc = GetDC ( dibwindow ) ;
PatBlt ( hdc , 0 , 0 , WindowRect . right , WindowRect . bottom , BLACKNESS ) ;
ReleaseDC ( dibwindow , hdc ) ;
if ( ( i = COM_CheckParm ( " -conwidth " ) ) ! = 0 )
2010-07-11 02:22:39 +00:00
vid . width = Q_atoi ( com_argv [ i + 1 ] ) ;
2004-08-22 22:29:09 +00:00
else
{
2010-07-11 02:22:39 +00:00
vid . width = 640 ;
2004-08-22 22:29:09 +00:00
}
2010-07-11 02:22:39 +00:00
vid . width & = 0xfff8 ; // make it a multiple of eight
2004-08-22 22:29:09 +00:00
2010-07-11 02:22:39 +00:00
if ( vid . width < 320 )
vid . width = 320 ;
2004-08-22 22:29:09 +00:00
// pick a conheight that matches with correct aspect
2010-07-11 02:22:39 +00:00
vid . height = vid . width * 3 / 4 ;
2004-08-22 22:29:09 +00:00
if ( ( i = COM_CheckParm ( " -conheight " ) ) ! = 0 )
2010-07-11 02:22:39 +00:00
vid . height = Q_atoi ( com_argv [ i + 1 ] ) ;
if ( vid . height < 200 )
vid . height = 200 ;
2004-08-22 22:29:09 +00:00
2010-07-11 02:22:39 +00:00
if ( vid . height > info - > height )
vid . height = info - > height ;
if ( vid . width > info - > width )
vid . width = info - > width ;
2004-08-22 22:29:09 +00:00
vid . numpages = 2 ;
mainwindow = dibwindow ;
vid_isfullscreen = false ;
SendMessage ( mainwindow , WM_SETICON , ( WPARAM ) TRUE , ( LPARAM ) hIcon ) ;
SendMessage ( mainwindow , WM_SETICON , ( WPARAM ) FALSE , ( LPARAM ) hIcon ) ;
return true ;
}
2007-02-23 00:21:33 +00:00
void GLVID_SetCaption ( char * text )
{
SetWindowText ( mainwindow , text ) ;
}
2004-08-22 22:29:09 +00:00
qboolean VID_SetFullDIBMode ( rendererstate_t * info )
{
int i ;
HDC hdc ;
int lastmodestate , wwidth , wheight ;
RECT rect ;
2011-04-30 17:21:10 +00:00
if ( leavecurrentmode ) //don't do this with d3d - d3d should set it's own video mode.
2004-08-27 00:51:25 +00:00
{ //make windows change res.
2004-08-22 22:29:09 +00:00
gdevmode . dmFields = DM_PELSWIDTH | DM_PELSHEIGHT ;
if ( info - > bpp )
gdevmode . dmFields | = DM_BITSPERPEL ;
if ( info - > rate )
gdevmode . dmFields | = DM_DISPLAYFREQUENCY ;
gdevmode . dmBitsPerPel = info - > bpp ;
2006-04-14 01:55:12 +00:00
if ( info - > bpp & & ( gdevmode . dmBitsPerPel < 15 ) )
{
Con_Printf ( " Forcing at least 16bpp \n " ) ;
gdevmode . dmBitsPerPel = 16 ;
}
2004-08-22 22:29:09 +00:00
gdevmode . dmDisplayFrequency = info - > rate ;
gdevmode . dmPelsWidth = info - > width ;
gdevmode . dmPelsHeight = info - > height ;
gdevmode . dmSize = sizeof ( gdevmode ) ;
if ( ChangeDisplaySettings ( & gdevmode , CDS_FULLSCREEN ) ! = DISP_CHANGE_SUCCESSFUL )
{
2011-05-19 13:34:07 +00:00
Con_SafePrintf ( ( gdevmode . dmFields & DM_DISPLAYFREQUENCY ) ? " Windows rejected mode %i*%i*%i*%i \n " : " Windows rejected mode %i*%i*%i \n " , ( int ) gdevmode . dmPelsWidth , ( int ) gdevmode . dmPelsHeight , ( int ) gdevmode . dmBitsPerPel , ( int ) gdevmode . dmDisplayFrequency ) ;
2004-08-22 22:29:09 +00:00
return false ;
}
}
lastmodestate = modestate ;
modestate = MS_FULLDIB ;
WindowRect . top = WindowRect . left = 0 ;
WindowRect . right = info - > width ;
WindowRect . bottom = info - > height ;
DIBWidth = info - > width ;
DIBHeight = info - > height ;
WindowStyle = WS_POPUP ;
ExWindowStyle = 0 ;
rect = WindowRect ;
AdjustWindowRectEx ( & rect , WindowStyle , FALSE , 0 ) ;
wwidth = rect . right - rect . left ;
wheight = rect . bottom - rect . top ;
// Create the DIB window
dibwindow = CreateWindowEx (
ExWindowStyle ,
WINDOW_CLASS_NAME ,
2005-11-14 01:32:21 +00:00
FULLENGINENAME ,
2004-08-22 22:29:09 +00:00
WindowStyle ,
rect . left , rect . top ,
wwidth ,
wheight ,
NULL ,
NULL ,
global_hInstance ,
NULL ) ;
if ( ! dibwindow )
Sys_Error ( " Couldn't create DIB window " ) ;
ShowWindow ( dibwindow , SW_SHOWDEFAULT ) ;
UpdateWindow ( dibwindow ) ;
// Because we have set the background brush for the window to NULL
// (to avoid flickering when re-sizing the window on the desktop), we
// clear the window to black when created, otherwise it will be
// empty while Quake starts up.
hdc = GetDC ( dibwindow ) ;
PatBlt ( hdc , 0 , 0 , WindowRect . right , WindowRect . bottom , BLACKNESS ) ;
ReleaseDC ( dibwindow , hdc ) ;
if ( ( i = COM_CheckParm ( " -conwidth " ) ) ! = 0 )
2010-07-11 02:22:39 +00:00
vid . width = Q_atoi ( com_argv [ i + 1 ] ) ;
2004-08-22 22:29:09 +00:00
else
2010-07-11 02:22:39 +00:00
vid . width = 640 ;
2004-08-22 22:29:09 +00:00
2010-07-11 02:22:39 +00:00
vid . width & = 0xfff8 ; // make it a multiple of eight
2004-08-22 22:29:09 +00:00
2010-07-11 02:22:39 +00:00
if ( vid . width < 320 )
vid . width = 320 ;
2004-08-22 22:29:09 +00:00
// pick a conheight that matches with correct aspect
2010-07-11 02:22:39 +00:00
vid . height = vid . width * 3 / 4 ;
2004-08-22 22:29:09 +00:00
if ( ( i = COM_CheckParm ( " -conheight " ) ) ! = 0 )
2010-07-11 02:22:39 +00:00
vid . height = Q_atoi ( com_argv [ i + 1 ] ) ;
if ( vid . height < 200 )
vid . height = 200 ;
2004-08-22 22:29:09 +00:00
2010-07-11 02:22:39 +00:00
if ( vid . height > info - > height )
vid . height = info - > height ;
if ( vid . width > info - > width )
vid . width = info - > width ;
2004-08-22 22:29:09 +00:00
vid . numpages = 2 ;
// needed because we're not getting WM_MOVE messages fullscreen on NT
window_x = 0 ;
window_y = 0 ;
vid_isfullscreen = true ;
mainwindow = dibwindow ;
SendMessage ( mainwindow , WM_SETICON , ( WPARAM ) TRUE , ( LPARAM ) hIcon ) ;
SendMessage ( mainwindow , WM_SETICON , ( WPARAM ) FALSE , ( LPARAM ) hIcon ) ;
return true ;
}
2011-03-12 13:51:40 +00:00
extern qboolean gammaworks ;
2006-03-15 20:11:37 +00:00
static void ReleaseGL ( void ) ;
static qboolean CreateMainWindow ( rendererstate_t * info )
2004-08-22 22:29:09 +00:00
{
qboolean stat ;
if ( ! info - > fullscreen )
{
if ( _windowed_mouse . value & & ( key_dest = = key_game | | key_dest = = key_menu ) )
{
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: GLVID_SetMode: VID_SetWindowedMode \n " ) ) ;
2004-08-22 22:29:09 +00:00
stat = VID_SetWindowedMode ( info ) ;
}
else
{
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: GLVID_SetMode: VID_SetWindowedMode 2 \n " ) ) ;
2004-08-22 22:29:09 +00:00
stat = VID_SetWindowedMode ( info ) ;
}
}
else
{
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: GLVID_SetMode: VID_SetFullDIBMode \n " ) ) ;
2004-08-22 22:29:09 +00:00
stat = VID_SetFullDIBMode ( info ) ;
}
2009-04-01 22:03:56 +00:00
IN_UpdateGrabs ( info - > fullscreen , ActiveApp ) ;
2006-03-15 20:11:37 +00:00
return stat ;
}
BOOL CheckForcePixelFormat ( rendererstate_t * info ) ;
void VID_UnSetMode ( void ) ;
int GLVID_SetMode ( rendererstate_t * info , unsigned char * palette )
{
int temp ;
qboolean stat ;
2011-09-16 05:56:54 +00:00
# ifndef NPFTE
2006-03-15 20:11:37 +00:00
MSG msg ;
2009-04-01 22:03:56 +00:00
# endif
2006-03-15 20:11:37 +00:00
// HDC hdc;
TRACE ( ( " dbg: GLVID_SetMode \n " ) ) ;
// so Con_Printfs don't mess us up by forcing vid and snd updates
temp = scr_disabled_for_loading ;
scr_disabled_for_loading = true ;
CDAudio_Pause ( ) ;
// Set either the fullscreen or windowed mode
qwglChoosePixelFormatARB = NULL ;
2009-11-04 21:16:50 +00:00
qwglCreateContextAttribsARB = NULL ;
2006-03-15 20:11:37 +00:00
stat = CreateMainWindow ( info ) ;
if ( stat )
{
stat = VID_AttachGL ( info ) ;
if ( stat )
{
TRACE ( ( " dbg: GLVID_SetMode: attaching gl okay \n " ) ) ;
if ( CheckForcePixelFormat ( info ) )
{
HMODULE oldgl = hInstGL ;
hInstGL = NULL ; //don't close the gl library, just in case
VID_UnSetMode ( ) ;
hInstGL = oldgl ;
if ( CreateMainWindow ( info ) & & VID_AttachGL ( info ) )
{
//we have our multisample window
}
else
{
//multisample failed
//try the origional way
if ( ! CreateMainWindow ( info ) | | ! VID_AttachGL ( info ) )
{
Con_Printf ( " Failed to undo antialising. Giving up. \n " ) ;
return false ; //eek
}
}
}
}
else
{
TRACE ( ( " dbg: GLVID_SetMode: attaching gl failed \n " ) ) ;
return false ;
}
}
2004-08-22 22:29:09 +00:00
2004-10-07 13:13:15 +00:00
if ( ! stat )
{
TRACE ( ( " dbg: GLVID_SetMode: VID_Set... failed \n " ) ) ;
return false ;
}
2004-08-22 22:29:09 +00:00
window_width = DIBWidth ;
window_height = DIBHeight ;
2009-04-06 00:34:32 +00:00
VID_UpdateWindowStatus ( mainwindow ) ;
2004-08-22 22:29:09 +00:00
CDAudio_Resume ( ) ;
scr_disabled_for_loading = temp ;
// now we try to make sure we get the focus on the mode switch, because
// sometimes in some systems we don't. We grab the foreground, then
// finish setting up, pump all our messages, and sleep for a little while
// to let messages finish bouncing around the system, then we put
// ourselves at the top of the z order, then grab the foreground again,
// Who knows if it helps, but it probably doesn't hurt
SetForegroundWindow ( mainwindow ) ;
VID_SetPalette ( palette ) ;
2011-09-16 05:56:54 +00:00
# ifndef NPFTE
2010-03-14 14:35:56 +00:00
/*I don't like this, but if we */
2009-04-01 22:03:56 +00:00
while ( PeekMessage ( & msg , mainwindow , 0 , 0 , PM_REMOVE ) )
2004-08-22 22:29:09 +00:00
{
TranslateMessage ( & msg ) ;
DispatchMessage ( & msg ) ;
}
Sleep ( 100 ) ;
2010-03-14 14:35:56 +00:00
# endif
2004-08-22 22:29:09 +00:00
SetWindowPos ( mainwindow , HWND_TOP , 0 , 0 , 0 , 0 ,
SWP_DRAWFRAME | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW |
SWP_NOCOPYBITS ) ;
SetForegroundWindow ( mainwindow ) ;
// fix the leftover Alt from any Alt-Tab or the like that switched us away
ClearAllStates ( ) ;
GLVID_SetPalette ( palette ) ;
vid . recalc_refdef = 1 ;
2005-10-18 04:42:13 +00:00
if ( vid_desktopgamma . value )
{
HDC hDC = GetDC ( GetDesktopWindow ( ) ) ;
2006-02-11 02:05:15 +00:00
gammaworks = qGetDeviceGammaRamp ( hDC , originalgammaramps ) ;
2005-10-18 04:42:13 +00:00
ReleaseDC ( GetDesktopWindow ( ) , hDC ) ;
}
else
2006-02-11 02:05:15 +00:00
gammaworks = qGetDeviceGammaRamp ( maindc , originalgammaramps ) ;
2004-09-20 23:25:38 +00:00
2004-08-22 22:29:09 +00:00
return true ;
}
2006-03-15 20:11:37 +00:00
static void ReleaseGL ( void )
2004-08-22 22:29:09 +00:00
{
HGLRC hRC ;
HDC hDC = NULL ;
2006-03-15 20:11:37 +00:00
if ( qwglGetCurrentContext )
2004-08-22 22:29:09 +00:00
{
2006-03-15 20:11:37 +00:00
hRC = qwglGetCurrentContext ( ) ;
hDC = qwglGetCurrentDC ( ) ;
2004-08-22 22:29:09 +00:00
2006-03-15 20:11:37 +00:00
qwglMakeCurrent ( NULL , NULL ) ;
2004-08-22 22:29:09 +00:00
2006-03-15 20:11:37 +00:00
if ( hRC )
qwglDeleteContext ( hRC ) ;
}
qwglGetCurrentContext = NULL ;
2004-08-22 22:29:09 +00:00
2006-03-15 20:11:37 +00:00
if ( hDC & & dibwindow )
ReleaseDC ( dibwindow , hDC ) ;
}
void VID_UnSetMode ( void )
{
if ( mainwindow & & vid_initialized )
{
GLAppActivate ( false , false ) ;
2004-08-22 22:29:09 +00:00
2006-03-15 20:11:37 +00:00
vid_canalttab = false ;
ReleaseGL ( ) ;
2004-08-22 22:29:09 +00:00
if ( modestate = = MS_FULLDIB )
ChangeDisplaySettings ( NULL , 0 ) ;
if ( maindc & & dibwindow )
ReleaseDC ( dibwindow , maindc ) ;
}
if ( mainwindow )
{
dibwindow = NULL ;
2009-04-01 22:03:56 +00:00
// ShowWindow(mainwindow, SW_HIDE);
// SetWindowLongPtr(mainwindow, GWL_WNDPROC, DefWindowProc);
// PostMessage(mainwindow, WM_CLOSE, 0, 0);
2004-08-22 22:29:09 +00:00
DestroyWindow ( mainwindow ) ;
mainwindow = NULL ;
}
2011-06-16 02:03:57 +00:00
#if 0
//Logically this code should be active. However...
//1: vid_restarts are slightly slower if we don't reuse the old dll
//2: nvidia drivers crash if we shut it down+reload!
2004-08-22 22:29:09 +00:00
if ( hInstGL )
{
FreeLibrary ( hInstGL ) ;
2011-06-16 02:03:57 +00:00
hInstGL = NULL ;
2004-08-22 22:29:09 +00:00
}
2011-06-16 02:03:57 +00:00
if ( hInstwgl )
{
FreeLibrary ( hInstwgl ) ;
hInstwgl = NULL ;
}
* opengldllname = 0 ;
# endif
2004-08-22 22:29:09 +00:00
}
/*
= = = = = = = = = = = = = = = =
VID_UpdateWindowStatus
= = = = = = = = = = = = = = = =
*/
2009-04-06 00:34:32 +00:00
void VID_UpdateWindowStatus ( HWND hWnd )
2004-08-22 22:29:09 +00:00
{
2009-04-06 00:34:32 +00:00
POINT p ;
RECT nr ;
GetClientRect ( hWnd , & nr ) ;
//if its bad then we're probably minimised
if ( nr . right < = nr . left )
return ;
if ( nr . bottom < = nr . top )
return ;
WindowRect = nr ;
p . x = 0 ;
p . y = 0 ;
ClientToScreen ( hWnd , & p ) ;
window_x = p . x ;
window_y = p . y ;
window_width = WindowRect . right - WindowRect . left ;
window_height = WindowRect . bottom - WindowRect . top ;
2009-11-04 21:16:50 +00:00
vid . pixelwidth = window_width ;
vid . pixelheight = window_height ;
2004-08-22 22:29:09 +00:00
window_rect . left = window_x ;
window_rect . top = window_y ;
window_rect . right = window_x + window_width ;
window_rect . bottom = window_y + window_height ;
window_center_x = ( window_rect . left + window_rect . right ) / 2 ;
window_center_y = ( window_rect . top + window_rect . bottom ) / 2 ;
IN_UpdateClipCursor ( ) ;
}
//====================================
qboolean VID_AttachGL ( rendererstate_t * info )
{ //make sure we can get a valid renderer.
do
{
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: VID_AttachGL: GLInitialise \n " ) ) ;
2004-08-22 22:29:09 +00:00
if ( GLInitialise ( info - > glrenderer ) )
{
maindc = GetDC ( mainwindow ) ;
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: VID_AttachGL: bSetupPixelFormat \n " ) ) ;
2006-07-21 23:38:24 +00:00
if ( bSetupPixelFormat ( maindc ) )
break ;
2010-12-05 02:46:07 +00:00
ReleaseDC ( mainwindow , maindc ) ;
2004-08-22 22:29:09 +00:00
}
2005-06-04 04:20:20 +00:00
if ( ! * info - > glrenderer | | ! stricmp ( info - > glrenderer , " opengl32.dll " ) | | ! stricmp ( info - > glrenderer , " opengl32 " ) ) //go for windows system dir if we failed with the default. Should help to avoid the 3dfx problem.
2004-08-22 22:29:09 +00:00
{
char systemgl [ MAX_OSPATH + 1 ] ;
GetSystemDirectory ( systemgl , sizeof ( systemgl ) - 1 ) ;
strncat ( systemgl , " \\ " , sizeof ( systemgl ) - 1 ) ;
2005-06-04 04:20:20 +00:00
if ( * info - > glrenderer )
strncat ( systemgl , info - > glrenderer , sizeof ( systemgl ) - 1 ) ;
else
strncat ( systemgl , " opengl32.dll " , sizeof ( systemgl ) - 1 ) ;
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: VID_AttachGL: GLInitialise (system dir specific) \n " ) ) ;
2004-08-22 22:29:09 +00:00
if ( GLInitialise ( systemgl ) )
{
maindc = GetDC ( mainwindow ) ;
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: VID_AttachGL: bSetupPixelFormat \n " ) ) ;
2006-07-21 23:38:24 +00:00
if ( bSetupPixelFormat ( maindc ) )
break ;
2010-12-05 02:46:07 +00:00
ReleaseDC ( mainwindow , maindc ) ;
2004-08-22 22:29:09 +00:00
}
}
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: VID_AttachGL: failed to find a valid dll \n " ) ) ;
2004-08-22 22:29:09 +00:00
return false ;
} while ( 1 ) ;
2011-05-19 13:34:07 +00:00
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: VID_AttachGL: qwglCreateContext \n " ) ) ;
2004-08-22 22:29:09 +00:00
2010-12-05 02:46:07 +00:00
baseRC = qwglCreateContext ( maindc ) ;
2004-08-22 22:29:09 +00:00
if ( ! baseRC )
{
2007-09-23 15:28:06 +00:00
Con_SafePrintf ( CON_ERROR " Could not initialize GL (wglCreateContext failed). \n \n Make sure you in are 65535 color mode, and try running -window. \n " ) ; //green to make it show.
2004-08-22 22:29:09 +00:00
return false ;
}
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: VID_AttachGL: qwglMakeCurrent \n " ) ) ;
2010-12-05 02:46:07 +00:00
if ( ! qwglMakeCurrent ( maindc , baseRC ) )
2004-08-22 22:29:09 +00:00
{
2007-09-23 15:28:06 +00:00
Con_SafePrintf ( CON_ERROR " wglMakeCurrent failed \n " ) ; //green to make it show.
2004-08-22 22:29:09 +00:00
return false ;
}
2011-01-23 03:44:49 +00:00
2011-01-04 02:56:16 +00:00
if ( developer . ival )
{
2011-01-23 03:44:49 +00:00
char * ( WINAPI * wglGetExtensionsString ) ( HDC hdc ) = NULL ;
2011-01-04 02:56:16 +00:00
if ( ! wglGetExtensionsString )
wglGetExtensionsString = getglfunc ( " wglGetExtensionsString " ) ;
if ( ! wglGetExtensionsString )
wglGetExtensionsString = getglfunc ( " wglGetExtensionsStringARB " ) ;
if ( ! wglGetExtensionsString )
wglGetExtensionsString = getglfunc ( " wglGetExtensionsStringEXT " ) ;
if ( wglGetExtensionsString )
2011-01-23 03:44:49 +00:00
Con_SafePrintf ( " WGL extensions: %s \n " , wglGetExtensionsString ( maindc ) ) ;
2011-01-04 02:56:16 +00:00
}
2011-01-23 03:44:49 +00:00
2009-11-04 21:16:50 +00:00
qwglCreateContextAttribsARB = getglfunc ( " wglCreateContextAttribsARB " ) ;
# ifdef _DEBUG
//attempt to promote that to opengl3.
if ( qwglCreateContextAttribsARB )
{
HGLRC opengl3 ;
2010-09-05 10:42:23 +00:00
int attribs [ 9 ] ;
2009-11-04 21:16:50 +00:00
char * mv ;
int i = 0 ;
2011-01-23 03:44:49 +00:00
char * ver ;
ver = vid_gl_context_version . string ;
if ( ! * ver & & vid_gl_context_es2 . ival )
ver = " 2.0 " ;
2009-11-04 21:16:50 +00:00
2011-01-23 03:44:49 +00:00
mv = ver ;
2009-11-04 21:16:50 +00:00
while ( * mv )
{
if ( * mv + + = = ' . ' )
break ;
}
2011-01-23 03:44:49 +00:00
if ( * ver )
2009-11-04 21:16:50 +00:00
{
attribs [ i + + ] = WGL_CONTEXT_MAJOR_VERSION_ARB ;
2011-01-23 03:44:49 +00:00
attribs [ i + + ] = atoi ( ver ) ;
2009-11-04 21:16:50 +00:00
}
if ( * mv )
{
attribs [ i + + ] = WGL_CONTEXT_MINOR_VERSION_ARB ;
attribs [ i + + ] = atoi ( mv ) ;
}
//flags
attribs [ i + 1 ] = 0 ;
2010-09-05 10:42:23 +00:00
if ( vid_gl_context_debug . ival )
2009-11-04 21:16:50 +00:00
attribs [ i + 1 ] | = WGL_CONTEXT_DEBUG_BIT_ARB ;
2010-09-05 10:42:23 +00:00
if ( vid_gl_context_forwardcompatible . ival )
2009-11-04 21:16:50 +00:00
attribs [ i + 1 ] | = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB ;
if ( attribs [ i + 1 ] )
{
attribs [ i ] = WGL_CONTEXT_FLAGS_ARB ;
i + = 2 ;
}
2010-09-05 10:42:23 +00:00
/*only switch contexts if there's actually a point*/
2011-01-04 02:56:16 +00:00
if ( i | | ! vid_gl_context_compatibility . ival | | vid_gl_context_es2 . ival )
2009-11-04 21:16:50 +00:00
{
2010-09-05 10:42:23 +00:00
attribs [ i + 1 ] = 0 ;
2011-01-04 02:56:16 +00:00
if ( vid_gl_context_es2 . ival )
attribs [ i + 1 ] | = WGL_CONTEXT_ES2_PROFILE_BIT_EXT ;
else if ( vid_gl_context_compatibility . ival )
2010-09-05 10:42:23 +00:00
attribs [ i + 1 ] | = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB ;
else
attribs [ i + 1 ] | = WGL_CONTEXT_CORE_PROFILE_BIT_ARB ;
attribs [ i ] = WGL_CONTEXT_PROFILE_MASK_ARB ;
i + = 2 ;
2009-11-04 21:16:50 +00:00
2010-09-05 10:42:23 +00:00
attribs [ i ] = 0 ;
if ( ( opengl3 = qwglCreateContextAttribsARB ( maindc , NULL , attribs ) ) )
2009-11-04 21:16:50 +00:00
{
2011-05-20 04:10:46 +00:00
qwglMakeCurrent ( maindc , NULL ) ;
2010-09-05 10:42:23 +00:00
qwglDeleteContext ( baseRC ) ;
baseRC = opengl3 ;
if ( ! qwglMakeCurrent ( maindc , baseRC ) )
{
Con_SafePrintf ( CON_ERROR " wglMakeCurrent failed \n " ) ; //green to make it show.
return false ;
}
2009-11-04 21:16:50 +00:00
}
else
2010-09-05 10:42:23 +00:00
{
DWORD error = GetLastError ( ) ;
2011-01-23 03:44:49 +00:00
if ( error = = ( 0xc0070000 | ERROR_INVALID_VERSION_ARB ) )
2010-09-05 10:42:23 +00:00
Con_Printf ( " Unsupported OpenGL context version (%s). \n " , vid_gl_context_version . string ) ;
2011-01-23 03:44:49 +00:00
else if ( error = = ( 0xc0070000 | ERROR_INVALID_PROFILE_ARB ) )
Con_Printf ( " Unsupported OpenGL profile (%s). \n " , vid_gl_context_es2 . ival ? " gles " : ( vid_gl_context_compatibility . ival ? " compat " : " core " ) ) ;
2010-09-05 10:42:23 +00:00
else
Con_Printf ( " Unknown error creating an OpenGL (%s) Context. \n " , vid_gl_context_version . string ) ;
}
2009-11-04 21:16:50 +00:00
}
}
# endif
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: VID_AttachGL: GL_Init \n " ) ) ;
2004-08-22 22:29:09 +00:00
GL_Init ( getglfunc ) ;
2009-11-04 21:16:50 +00:00
2006-03-15 20:11:37 +00:00
qwglChoosePixelFormatARB = getglfunc ( " wglChoosePixelFormatARB " ) ;
2009-11-04 21:16:50 +00:00
2004-08-22 22:29:09 +00:00
qwglSwapIntervalEXT = getglfunc ( " wglSwapIntervalEXT " ) ;
2006-02-01 22:32:30 +00:00
if ( qwglSwapIntervalEXT & & * _vid_wait_override . string )
2004-10-07 13:13:15 +00:00
{
TRACE ( ( " dbg: VID_AttachGL: qwglSwapIntervalEXT \n " ) ) ;
2004-08-22 22:29:09 +00:00
qwglSwapIntervalEXT ( _vid_wait_override . value ) ;
2004-10-07 13:13:15 +00:00
}
TRACE ( ( " dbg: VID_AttachGL: qSwapBuffers \n " ) ) ;
2005-01-07 03:16:44 +00:00
qglClearColor ( 0 , 0 , 0 , 0 ) ;
qglClear ( GL_COLOR_BUFFER_BIT ) ;
2004-08-22 22:29:09 +00:00
qSwapBuffers ( maindc ) ;
2006-02-12 17:06:55 +00:00
if ( ! qGetDeviceGammaRamp ) qGetDeviceGammaRamp = ( void * ) GetDeviceGammaRamp ;
if ( ! qSetDeviceGammaRamp ) qSetDeviceGammaRamp = ( void * ) SetDeviceGammaRamp ;
2004-08-22 22:29:09 +00:00
return true ;
}
/*
= = = = = = = = = = = = = = = = =
GL_BeginRendering
= = = = = = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
void GL_BeginRendering ( void )
2004-08-22 22:29:09 +00:00
{
2009-11-04 21:16:50 +00:00
vid . pixelwidth = WindowRect . right - WindowRect . left ;
vid . pixelheight = WindowRect . bottom - WindowRect . top ;
2004-08-22 22:29:09 +00:00
// if (!wglMakeCurrent( maindc, baseRC ))
// Sys_Error ("wglMakeCurrent failed");
// glViewport (*x, *y, *width, *height);
}
2006-04-21 06:02:06 +00:00
void VID_Wait_Override_Callback ( struct cvar_s * var , char * oldvalue )
{
if ( qwglSwapIntervalEXT & & * _vid_wait_override . string )
qwglSwapIntervalEXT ( _vid_wait_override . value ) ;
}
2011-04-30 17:21:10 +00:00
void GLVID_Recenter_f ( void )
2009-04-06 00:34:32 +00:00
{
2011-05-19 13:34:07 +00:00
// 4 unused variables
//int nw = vid_width.value;
//int nh = vid_height.value;
//int nx = 0;
//int ny = 0;
2009-04-06 00:34:32 +00:00
if ( sys_parentwindow & & modestate = = MS_WINDOWED )
{
2011-10-27 16:16:29 +00:00
WindowRect = centerrect ( sys_parentleft , sys_parenttop , sys_parentwidth , sys_parentheight , vid_width . value , vid_height . value ) ;
2011-04-30 17:21:10 +00:00
MoveWindow ( mainwindow , WindowRect . left , WindowRect . top , WindowRect . right - WindowRect . left , WindowRect . bottom - WindowRect . top , FALSE ) ;
2009-04-06 00:34:32 +00:00
2011-04-30 17:21:10 +00:00
Cvar_ForceCallback ( & vid_conautoscale ) ;
Cvar_ForceCallback ( & vid_conwidth ) ;
VID_UpdateWindowStatus ( mainwindow ) ;
2009-04-06 00:34:32 +00:00
}
}
void VID_WndAlpha_Override_Callback ( struct cvar_s * var , char * oldvalue )
{
2009-04-06 01:01:31 +00:00
# ifdef WS_EX_LAYERED
2009-04-06 00:34:32 +00:00
if ( modestate = = MS_WINDOWED )
{
int av ;
HMODULE hm = GetModuleHandle ( " user32.dll " ) ;
lpfnSetLayeredWindowAttributes pSetLayeredWindowAttributes ;
pSetLayeredWindowAttributes = ( void * ) GetProcAddress ( hm , " SetLayeredWindowAttributes " ) ;
av = 255 * var - > value ;
if ( av < 70 )
av = 70 ;
if ( av > 255 )
av = 255 ;
if ( pSetLayeredWindowAttributes )
{
2011-05-19 13:34:07 +00:00
// Set WS_EX_LAYERED on this window
2009-04-06 00:34:32 +00:00
if ( av < 255 )
{
SetWindowLong ( mainwindow , GWL_EXSTYLE , GetWindowLong ( mainwindow , GWL_EXSTYLE ) | WS_EX_LAYERED ) ;
// Make this window 70% alpha
2009-07-25 11:05:06 +00:00
pSetLayeredWindowAttributes ( mainwindow , 0 , ( BYTE ) av , LWA_ALPHA ) ;
2009-04-06 00:34:32 +00:00
}
else
SetWindowLong ( mainwindow , GWL_EXSTYLE , GetWindowLong ( mainwindow , GWL_EXSTYLE ) & ~ WS_EX_LAYERED ) ;
}
}
# endif
}
2004-11-18 17:55:04 +00:00
qboolean screenflush ;
void GL_DoSwap ( void )
2004-08-22 22:29:09 +00:00
{
2004-11-18 17:55:04 +00:00
if ( ! screenflush )
return ;
screenflush = 0 ;
2009-07-17 22:15:37 +00:00
if ( ! scr_skipupdate )
2004-08-22 22:29:09 +00:00
qSwapBuffers ( maindc ) ;
// handle the mouse state when windowed if that's changed
2009-04-01 22:03:56 +00:00
IN_UpdateGrabs ( modestate ! = MS_WINDOWED , ActiveApp ) ;
2004-08-22 22:29:09 +00:00
}
2004-11-18 17:55:04 +00:00
void GL_EndRendering ( void )
{
screenflush = true ;
if ( ! gl_lateswap . value )
GL_DoSwap ( ) ;
}
2008-01-09 00:37:17 +00:00
void OblitterateOldGamma ( void )
{
int i ;
if ( vid_preservegamma . value )
return ;
for ( i = 0 ; i < 256 ; i + + )
{
originalgammaramps [ 0 ] [ i ] = ( i < < 8 ) + i ;
originalgammaramps [ 1 ] [ i ] = ( i < < 8 ) + i ;
originalgammaramps [ 2 ] [ i ] = ( i < < 8 ) + i ;
}
}
2004-08-22 22:29:09 +00:00
void GLVID_SetPalette ( unsigned char * palette )
{
qbyte * pal ;
unsigned r , g , b ;
unsigned v ;
unsigned short i ;
unsigned * table ;
extern qbyte gammatable [ 256 ] ;
2004-12-08 04:03:36 +00:00
//
// 8 8 8 encoding
//
if ( vid_hardwaregamma . value )
2004-08-22 22:29:09 +00:00
{
2004-12-08 04:03:36 +00:00
// don't built in the gamma table
pal = palette ;
table = d_8to24rgbtable ;
for ( i = 0 ; i < 256 ; i + + )
{
r = pal [ 0 ] ;
g = pal [ 1 ] ;
b = pal [ 2 ] ;
pal + = 3 ;
2011-05-19 13:34:07 +00:00
2004-12-08 04:03:36 +00:00
// v = (255<<24) + (r<<16) + (g<<8) + (b<<0);
// v = (255<<0) + (r<<8) + (g<<16) + (b<<24);
v = ( 255 < < 24 ) + ( r < < 0 ) + ( g < < 8 ) + ( b < < 16 ) ;
* table + + = v ;
}
d_8to24rgbtable [ 255 ] & = 0xffffff ; // 255 is transparent
}
else
{
//computer has no hardware gamma (poor suckers) increase table accordingly
pal = palette ;
table = d_8to24rgbtable ;
for ( i = 0 ; i < 256 ; i + + )
{
r = gammatable [ pal [ 0 ] ] ;
g = gammatable [ pal [ 1 ] ] ;
b = gammatable [ pal [ 2 ] ] ;
pal + = 3 ;
2011-05-19 13:34:07 +00:00
2004-12-08 04:03:36 +00:00
// v = (255<<24) + (r<<16) + (g<<8) + (b<<0);
// v = (255<<0) + (r<<8) + (g<<16) + (b<<24);
v = ( 255 < < 24 ) + ( r < < 0 ) + ( g < < 8 ) + ( b < < 16 ) ;
* table + + = v ;
}
d_8to24rgbtable [ 255 ] & = 0xffffff ; // 255 is transparent
2004-08-22 22:29:09 +00:00
}
}
void GLVID_ShiftPalette ( unsigned char * palette )
{
2004-09-20 23:25:38 +00:00
extern unsigned short ramps [ 3 ] [ 256 ] ;
2004-08-22 22:29:09 +00:00
2004-10-01 02:19:17 +00:00
if ( ActiveApp & & vid_hardwaregamma . value ) //this is needed because ATI drivers don't work properly (or when task-switched out).
2004-10-14 12:31:29 +00:00
{
if ( gammaworks )
{ //we have hardware gamma applied - if we're doing a BF, we don't want to reset to the default gamma (yuck)
2005-10-18 04:42:13 +00:00
if ( vid_desktopgamma . value )
{
HDC hDC = GetDC ( GetDesktopWindow ( ) ) ;
2006-02-27 00:42:25 +00:00
qSetDeviceGammaRamp ( hDC , ramps ) ;
2005-10-18 04:42:13 +00:00
ReleaseDC ( GetDesktopWindow ( ) , hDC ) ;
}
else
2006-02-11 02:05:15 +00:00
{
2006-02-27 00:42:25 +00:00
qSetDeviceGammaRamp ( maindc , ramps ) ;
2006-02-11 02:05:15 +00:00
}
2004-10-14 12:31:29 +00:00
return ;
}
}
2004-08-22 22:29:09 +00:00
}
2009-11-04 21:16:50 +00:00
void GLVID_Crashed ( void )
{
if ( qSetDeviceGammaRamp & & gammaworks )
{
OblitterateOldGamma ( ) ;
qSetDeviceGammaRamp ( maindc , originalgammaramps ) ;
}
}
2004-08-22 22:29:09 +00:00
void GLVID_Shutdown ( void )
{
2006-02-11 02:05:15 +00:00
if ( qSetDeviceGammaRamp )
2005-10-18 04:42:13 +00:00
{
2008-01-09 00:37:17 +00:00
OblitterateOldGamma ( ) ;
2006-02-11 02:05:15 +00:00
if ( vid_desktopgamma . value )
{
HDC hDC = GetDC ( GetDesktopWindow ( ) ) ;
qSetDeviceGammaRamp ( hDC , originalgammaramps ) ;
ReleaseDC ( GetDesktopWindow ( ) , hDC ) ;
}
else
{
qSetDeviceGammaRamp ( maindc , originalgammaramps ) ;
}
2005-10-18 04:42:13 +00:00
}
2006-02-11 02:05:15 +00:00
qSetDeviceGammaRamp = NULL ;
qGetDeviceGammaRamp = NULL ;
2005-10-18 04:42:13 +00:00
2004-10-14 12:31:29 +00:00
gammaworks = false ;
2004-09-20 23:25:38 +00:00
2004-08-22 22:29:09 +00:00
VID_UnSetMode ( ) ;
}
//==========================================================================
2006-03-15 20:11:37 +00:00
# define WGL_DRAW_TO_WINDOW_ARB 0x2001
# define WGL_SUPPORT_OPENGL_ARB 0x2010
# define WGL_ACCELERATION_ARB 0x2003
# define WGL_FULL_ACCELERATION_ARB 0x2027
# define WGL_COLOR_BITS_ARB 0x2014
# define WGL_ALPHA_BITS_ARB 0x201B
# define WGL_DEPTH_BITS_ARB 0x2022
# define WGL_STENCIL_BITS_ARB 0x2023
# define WGL_DOUBLE_BUFFER_ARB 0x2011
qboolean shouldforcepixelformat ;
int forcepixelformat ;
BOOL CheckForcePixelFormat ( rendererstate_t * info )
{
if ( qwglChoosePixelFormatARB & & info - > multisample )
{
HDC hDC ;
int valid ;
float fAttributes [ ] = { 0 , 0 } ;
UINT numFormats ;
int pixelformat ;
int iAttributes [ ] = { WGL_DRAW_TO_WINDOW_ARB , GL_TRUE ,
WGL_SUPPORT_OPENGL_ARB , GL_TRUE ,
WGL_ACCELERATION_ARB , WGL_FULL_ACCELERATION_ARB ,
WGL_COLOR_BITS_ARB , info - > bpp ,
WGL_ALPHA_BITS_ARB , 8 ,
WGL_DEPTH_BITS_ARB , 16 ,
WGL_STENCIL_BITS_ARB , 8 ,
WGL_DOUBLE_BUFFER_ARB , GL_TRUE ,
WGL_SAMPLE_BUFFERS_ARB , GL_TRUE ,
WGL_SAMPLES_ARB , info - > multisample , // Check For 4x Multisampling
0 , 0 } ;
TRACE ( ( " dbg: bSetupPixelFormat: attempting wglChoosePixelFormatARB (multisample 4) \n " ) ) ;
hDC = GetDC ( mainwindow ) ;
2006-03-15 20:48:48 +00:00
2006-03-15 20:11:37 +00:00
valid = qwglChoosePixelFormatARB ( hDC , iAttributes , fAttributes , 1 , & pixelformat , & numFormats ) ;
2006-03-15 20:48:48 +00:00
while ( ( ! valid | | numFormats < 1 ) & & iAttributes [ 19 ] > 1 )
2006-03-15 20:11:37 +00:00
{ //failed, switch wgl_samples to 2
2006-03-15 20:48:48 +00:00
iAttributes [ 19 ] / = 2 ;
TRACE ( ( " dbg: bSetupPixelFormat: attempting wglChoosePixelFormatARB (smaller multisample) \n " ) ) ;
2006-03-15 20:11:37 +00:00
valid = qwglChoosePixelFormatARB ( hDC , iAttributes , fAttributes , 1 , & pixelformat , & numFormats ) ;
}
2006-03-15 20:48:48 +00:00
2006-03-15 20:11:37 +00:00
ReleaseDC ( mainwindow , hDC ) ;
if ( valid & & numFormats > 0 )
{
shouldforcepixelformat = true ;
forcepixelformat = pixelformat ;
return true ;
}
}
return false ;
}
2004-08-22 22:29:09 +00:00
2006-07-21 23:38:24 +00:00
BYTE IntensityFromShifted ( unsigned int index , unsigned int shift , unsigned int bits )
{
unsigned int val ;
val = ( index > > shift ) & ( ( 1 < < bits ) - 1 ) ;
switch ( bits )
{
case 1 :
val = val ? 0xFF : 0 ;
break ;
case 2 :
val | = val < < 2 ;
val | = val < < 4 ;
break ;
case 3 :
val = val < < ( 8 - bits ) ;
val | = val > > 3 ;
break ;
case 4 :
case 5 :
case 6 :
case 7 :
val = val < < ( 8 - bits ) ;
val | = val > > bits ;
break ;
case 8 :
break ;
default :
return 0 ;
}
return val ;
}
void FixPaletteInDescriptor ( HDC hDC , PIXELFORMATDESCRIPTOR * pfd )
{
LOGPALETTE * ppal ;
HPALETTE hpal ;
int idx , clrs ;
if ( pfd - > dwFlags & PFD_NEED_PALETTE )
{
clrs = 1 < < pfd - > cColorBits ;
ppal = Z_Malloc ( sizeof ( LOGPALETTE ) + sizeof ( PALETTEENTRY ) * clrs ) ;
ppal - > palVersion = 0x300 ;
ppal - > palNumEntries = clrs ;
for ( idx = 0 ; idx < clrs ; idx + + )
{
ppal - > palPalEntry [ idx ] . peRed = IntensityFromShifted ( idx , pfd - > cRedShift , pfd - > cRedBits ) ;
ppal - > palPalEntry [ idx ] . peGreen = IntensityFromShifted ( idx , pfd - > cGreenShift , pfd - > cGreenBits ) ;
ppal - > palPalEntry [ idx ] . peBlue = IntensityFromShifted ( idx , pfd - > cBlueShift , pfd - > cBlueBits ) ;
ppal - > palPalEntry [ idx ] . peFlags = 0 ;
}
hpal = CreatePalette ( ppal ) ;
SelectPalette ( hDC , hpal , FALSE ) ;
RealizePalette ( hDC ) ;
Z_Free ( ppal ) ;
}
}
2004-08-22 22:29:09 +00:00
BOOL bSetupPixelFormat ( HDC hDC )
{
static PIXELFORMATDESCRIPTOR pfd = {
sizeof ( PIXELFORMATDESCRIPTOR ) , // size of this pfd
1 , // version number
PFD_DRAW_TO_WINDOW // support window
| PFD_SUPPORT_OPENGL // support OpenGL
| PFD_DOUBLEBUFFER , // double buffered
PFD_TYPE_RGBA , // RGBA type
24 , // 24-bit color depth
0 , 0 , 0 , 0 , 0 , 0 , // color bits ignored
0 , // no alpha buffer
0 , // shift bit ignored
0 , // no accumulation buffer
0 , 0 , 0 , 0 , // accum bits ignored
2009-11-04 21:16:50 +00:00
# ifndef RTLIGHTS
32 , // 32-bit z-buffer
0 , // 0 stencil, don't need it unless we're using rtlights
# else
24 , // 24-bit z-buffer
2004-08-22 22:29:09 +00:00
8 , // stencil buffer
2009-11-04 21:16:50 +00:00
# endif
2004-08-22 22:29:09 +00:00
0 , // no auxiliary buffer
PFD_MAIN_PLANE , // main layer
0 , // reserved
0 , 0 , 0 // layer masks ignored
} ;
int pixelformat ;
2006-03-15 20:11:37 +00:00
2004-10-07 13:13:15 +00:00
TRACE ( ( " dbg: bSetupPixelFormat: ChoosePixelFormat \n " ) ) ;
2004-08-22 22:29:09 +00:00
2006-03-15 20:11:37 +00:00
if ( shouldforcepixelformat & & qwglChoosePixelFormatARB ) //the extra && is paranoia
2004-10-07 13:13:15 +00:00
{
2006-03-15 20:11:37 +00:00
shouldforcepixelformat = false ;
pixelformat = forcepixelformat ;
}
else
{
2011-10-27 16:16:29 +00:00
if ( ( pixelformat = qChoosePixelFormat ( hDC , & pfd ) ) )
2004-08-22 22:29:09 +00:00
{
2006-03-15 20:11:37 +00:00
TRACE ( ( " dbg: ChoosePixelFormat 1: worked \n " ) ) ;
2006-07-21 23:38:24 +00:00
2011-10-27 16:16:29 +00:00
if ( qSetPixelFormat ( hDC , pixelformat , & pfd ) )
2006-03-15 20:11:37 +00:00
{
TRACE ( ( " dbg: bSetupPixelFormat: we can use the stencil buffer. woot \n " ) ) ;
2011-10-27 16:16:29 +00:00
qDescribePixelFormat ( hDC , pixelformat , sizeof ( pfd ) , & pfd ) ;
2006-07-21 23:38:24 +00:00
FixPaletteInDescriptor ( hDC , & pfd ) ;
2006-03-15 20:11:37 +00:00
gl_canstencil = pfd . cStencilBits ;
return TRUE ;
}
2004-08-22 22:29:09 +00:00
}
2006-03-15 20:11:37 +00:00
TRACE ( ( " dbg: ChoosePixelFormat 1: no stencil buffer for us \n " ) ) ;
2004-08-22 22:29:09 +00:00
2006-03-15 20:11:37 +00:00
pfd . cStencilBits = 0 ;
gl_canstencil = false ;
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
if ( ( pixelformat = qChoosePixelFormat ( hDC , & pfd ) ) = = 0 )
2006-03-15 20:11:37 +00:00
{
2011-05-19 13:34:07 +00:00
Con_Printf ( " bSetupPixelFormat: ChoosePixelFormat failed (%i) \n " , ( int ) GetLastError ( ) ) ;
2006-03-15 20:11:37 +00:00
return FALSE ;
}
}
2004-08-22 22:29:09 +00:00
2011-10-27 16:16:29 +00:00
if ( qSetPixelFormat ( hDC , pixelformat , & pfd ) = = FALSE )
2004-08-22 22:29:09 +00:00
{
2011-05-19 13:34:07 +00:00
Con_Printf ( " bSetupPixelFormat: SetPixelFormat failed (%i) \n " , ( int ) GetLastError ( ) ) ;
2004-08-22 22:29:09 +00:00
return FALSE ;
}
2006-07-21 23:38:24 +00:00
FixPaletteInDescriptor ( hDC , & pfd ) ;
2004-08-22 22:29:09 +00:00
return TRUE ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
MAIN WINDOW
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = =
ClearAllStates
= = = = = = = = = = = = = = = =
*/
void ClearAllStates ( void )
{
int i ;
2011-05-19 13:34:07 +00:00
2004-08-22 22:29:09 +00:00
// send an up event for each key, to make sure the server clears them all
for ( i = 0 ; i < 256 ; i + + )
{
2010-08-14 00:15:07 +00:00
Key_Event ( 0 , i , 0 , false ) ;
2004-08-22 22:29:09 +00:00
}
Key_ClearStates ( ) ;
IN_ClearStates ( ) ;
}
2005-12-06 02:19:22 +00:00
qboolean GLAppActivate ( BOOL fActive , BOOL minimize )
2004-08-22 22:29:09 +00:00
/****************************************************************************
*
* Function : AppActivate
* Parameters : fActive - True if app is activating
*
* Description : If the application is activating , then swap the system
* into SYSPAL_NOSTATIC mode so that our palettes will display
* correctly .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
{
static BOOL sound_active ;
2005-12-06 02:19:22 +00:00
if ( ActiveApp = = fActive & & Minimized = = minimize )
return false ; //so windows doesn't crash us over and over again.
2004-08-22 22:29:09 +00:00
ActiveApp = fActive ;
Minimized = minimize ;
// enable/disable sound on focus gain/loss
if ( ! ActiveApp & & sound_active )
{
S_BlockSound ( ) ;
sound_active = false ;
}
else if ( ActiveApp & & ! sound_active )
{
S_UnblockSound ( ) ;
sound_active = true ;
}
2009-04-01 22:03:56 +00:00
IN_UpdateGrabs ( modestate ! = MS_WINDOWED , ActiveApp ) ;
2004-08-22 22:29:09 +00:00
if ( fActive )
{
2005-08-26 22:56:51 +00:00
if ( modestate ! = MS_WINDOWED )
2004-08-22 22:29:09 +00:00
{
if ( vid_canalttab & & vid_wassuspended ) {
vid_wassuspended = false ;
ChangeDisplaySettings ( & gdevmode , CDS_FULLSCREEN ) ;
ShowWindow ( mainwindow , SW_SHOWNORMAL ) ;
// Fix for alt-tab bug in NVidia drivers
MoveWindow ( mainwindow , 0 , 0 , gdevmode . dmPelsWidth , gdevmode . dmPelsHeight , false ) ;
}
}
2004-10-01 02:19:17 +00:00
2006-05-06 05:50:33 +00:00
Cvar_ForceCallback ( & v_gamma ) ;
2004-08-22 22:29:09 +00:00
}
if ( ! fActive )
{
2005-08-26 22:56:51 +00:00
if ( modestate ! = MS_WINDOWED )
2004-08-22 22:29:09 +00:00
{
2011-05-19 13:34:07 +00:00
if ( vid_canalttab ) {
2004-08-22 22:29:09 +00:00
ChangeDisplaySettings ( NULL , 0 ) ;
vid_wassuspended = true ;
}
}
2004-10-01 02:19:17 +00:00
2006-05-06 05:50:33 +00:00
Cvar_ForceCallback ( & v_gamma ) ; //wham bam thanks.
2004-10-01 02:19:17 +00:00
2006-02-11 02:05:15 +00:00
if ( qSetDeviceGammaRamp )
2005-10-18 04:42:13 +00:00
{
2008-01-09 00:37:17 +00:00
OblitterateOldGamma ( ) ;
2006-02-11 02:05:15 +00:00
if ( vid_desktopgamma . value )
{
HDC hDC = GetDC ( GetDesktopWindow ( ) ) ;
2006-02-27 00:42:25 +00:00
qSetDeviceGammaRamp ( hDC , originalgammaramps ) ;
2006-02-11 02:05:15 +00:00
ReleaseDC ( GetDesktopWindow ( ) , hDC ) ;
}
else
{
2006-02-27 00:42:25 +00:00
qSetDeviceGammaRamp ( maindc , originalgammaramps ) ;
2006-02-11 02:05:15 +00:00
}
2005-10-18 04:42:13 +00:00
}
2004-08-22 22:29:09 +00:00
}
2005-11-26 21:13:45 +00:00
2005-12-06 02:19:22 +00:00
return true ;
2004-08-22 22:29:09 +00:00
}
/* main window procedure */
LONG WINAPI GLMainWndProc (
HWND hWnd ,
UINT uMsg ,
WPARAM wParam ,
LPARAM lParam )
{
LONG lRet = 1 ;
int fActive , fMinimized , temp ;
extern unsigned int uiWheelMessage ;
if ( uMsg = = uiWheelMessage )
uMsg = WM_MOUSEWHEEL ;
switch ( uMsg )
{
case WM_KILLFOCUS :
2009-04-01 22:03:56 +00:00
GLAppActivate ( FALSE , Minimized ) ;
2004-08-22 22:29:09 +00:00
if ( modestate = = MS_FULLDIB )
ShowWindow ( mainwindow , SW_SHOWMINNOACTIVE ) ;
2009-04-01 22:03:56 +00:00
ClearAllStates ( ) ;
break ;
case WM_SETFOCUS :
if ( ! GLAppActivate ( TRUE , Minimized ) )
break ;
ClearAllStates ( ) ;
2004-08-22 22:29:09 +00:00
break ;
case WM_CREATE :
break ;
case WM_MOVE :
2009-04-06 00:34:32 +00:00
VID_UpdateWindowStatus ( hWnd ) ;
2004-08-22 22:29:09 +00:00
break ;
case WM_KEYDOWN :
case WM_SYSKEYDOWN :
if ( ! vid_initializing )
2010-08-23 04:53:20 +00:00
IN_TranslateKeyEvent ( wParam , lParam , true , 0 ) ;
2009-07-05 18:45:53 +00:00
break ;
// case WM_UNICHAR:
case WM_DEADCHAR :
case WM_SYSDEADCHAR :
case WM_CHAR :
case WM_SYSCHAR :
// if (!vid_initializing)
// IN_TranslateKeyEvent(wParam, lParam, true);
2004-08-22 22:29:09 +00:00
break ;
2004-11-13 17:31:04 +00:00
2004-08-22 22:29:09 +00:00
case WM_KEYUP :
case WM_SYSKEYUP :
if ( ! vid_initializing )
2010-08-23 04:53:20 +00:00
IN_TranslateKeyEvent ( wParam , lParam , false , 0 ) ;
2004-08-22 22:29:09 +00:00
break ;
// this is complicated because Win32 seems to pack multiple mouse events into
// one update sometimes, so we always check all states and look for events
case WM_LBUTTONDOWN :
case WM_LBUTTONUP :
case WM_RBUTTONDOWN :
case WM_RBUTTONUP :
case WM_MBUTTONDOWN :
case WM_MBUTTONUP :
case WM_MOUSEMOVE :
case WM_XBUTTONDOWN :
case WM_XBUTTONUP :
temp = 0 ;
if ( wParam & MK_LBUTTON )
2009-04-01 22:03:56 +00:00
{
2004-08-22 22:29:09 +00:00
temp | = 1 ;
2011-09-16 05:56:54 +00:00
# ifdef NPFTE
2009-04-01 22:03:56 +00:00
SetFocus ( hWnd ) ;
# endif
}
2004-08-22 22:29:09 +00:00
if ( wParam & MK_RBUTTON )
temp | = 2 ;
if ( wParam & MK_MBUTTON )
temp | = 4 ;
if ( wParam & MK_XBUTTON1 )
temp | = 8 ;
if ( wParam & MK_XBUTTON2 )
temp | = 16 ;
2005-06-18 22:30:57 +00:00
if ( wParam & MK_XBUTTON3 )
temp | = 32 ;
if ( wParam & MK_XBUTTON4 )
temp | = 64 ;
if ( wParam & MK_XBUTTON5 )
temp | = 128 ;
if ( wParam & MK_XBUTTON6 )
temp | = 256 ;
if ( wParam & MK_XBUTTON7 )
temp | = 512 ;
2004-08-22 22:29:09 +00:00
if ( ! vid_initializing )
IN_MouseEvent ( temp ) ;
break ;
// JACK: This is the mouse wheel with the Intellimouse
// Its delta is either positive or neg, and we generate the proper
// Event.
2011-05-19 13:34:07 +00:00
case WM_MOUSEWHEEL :
2004-08-22 22:29:09 +00:00
if ( ! vid_initializing )
2004-09-13 04:16:52 +00:00
{
if ( ( short ) HIWORD ( wParam ) > 0 )
{
2010-08-14 00:15:07 +00:00
Key_Event ( 0 , K_MWHEELUP , 0 , true ) ;
Key_Event ( 0 , K_MWHEELUP , 0 , false ) ;
2004-09-13 04:16:52 +00:00
}
else
{
2010-08-14 00:15:07 +00:00
Key_Event ( 0 , K_MWHEELDOWN , 0 , true ) ;
Key_Event ( 0 , K_MWHEELDOWN , 0 , false ) ;
2004-08-22 22:29:09 +00:00
}
2004-09-13 04:16:52 +00:00
}
2004-08-22 22:29:09 +00:00
break ;
2005-06-29 21:20:34 +00:00
case WM_INPUT :
// raw input handling
2010-08-23 04:53:20 +00:00
if ( ! vid_initializing )
IN_RawInput_Read ( ( HANDLE ) lParam ) ;
2005-06-29 21:20:34 +00:00
break ;
2011-03-31 02:32:32 +00:00
case WM_GETMINMAXINFO :
{
RECT windowrect ;
RECT clientrect ;
MINMAXINFO * mmi = ( MINMAXINFO * ) lParam ;
GetWindowRect ( hWnd , & windowrect ) ;
GetClientRect ( hWnd , & clientrect ) ;
mmi - > ptMinTrackSize . x = 320 + ( ( windowrect . right - windowrect . left ) - ( clientrect . right - clientrect . left ) ) ;
mmi - > ptMinTrackSize . y = 200 + ( ( windowrect . bottom - windowrect . top ) - ( clientrect . bottom - clientrect . top ) ) ;
}
return 0 ;
2004-08-22 22:29:09 +00:00
case WM_SIZE :
if ( ! vid_initializing )
{
2006-04-15 06:57:13 +00:00
Cvar_ForceCallback ( & vid_conautoscale ) ;
Cvar_ForceCallback ( & vid_conwidth ) ;
2009-04-06 00:34:32 +00:00
VID_UpdateWindowStatus ( hWnd ) ;
2004-08-22 22:29:09 +00:00
}
break ;
case WM_CLOSE :
if ( ! vid_initializing )
if ( MessageBox ( mainwindow , " Are you sure you want to quit? " , " Confirm Exit " ,
MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION ) = = IDYES )
{
2011-10-27 16:16:29 +00:00
Cbuf_AddText ( " \n quit \n " , RESTRICT_LOCAL ) ;
2004-08-22 22:29:09 +00:00
}
break ;
case WM_ACTIVATE :
fActive = LOWORD ( wParam ) ;
fMinimized = ( BOOL ) HIWORD ( wParam ) ;
2005-12-06 02:19:22 +00:00
if ( ! GLAppActivate ( ! ( fActive = = WA_INACTIVE ) , fMinimized ) )
break ; //so, urm, tell me microsoft, what changed?
2004-08-22 22:29:09 +00:00
if ( modestate = = MS_FULLDIB )
ShowWindow ( mainwindow , SW_SHOWNORMAL ) ;
// fix the leftover Alt from any Alt-Tab or the like that switched us away
ClearAllStates ( ) ;
2011-10-27 16:16:29 +00:00
Cvar_ForceCallback ( & vid_conautoscale ) ;
2004-08-22 22:29:09 +00:00
break ;
case WM_DESTROY :
{
if ( dibwindow )
DestroyWindow ( dibwindow ) ;
}
break ;
case MM_MCINOTIFY :
lRet = CDAudio_MessageHandler ( hWnd , uMsg , wParam , lParam ) ;
break ;
2011-05-19 13:34:07 +00:00
2004-08-22 22:29:09 +00:00
default :
/* pass all unhandled messages to DefWindowProc */
lRet = DefWindowProc ( hWnd , uMsg , wParam , lParam ) ;
break ;
}
/* return 1 if handled message, 0 if not */
return lRet ;
}
2009-11-04 21:16:50 +00:00
qboolean GLVID_Is8bit ( void ) {
2004-08-22 22:29:09 +00:00
return is8bit ;
}
2011-05-19 13:34:07 +00:00
void VID_Init8bitPalette ( void )
2004-08-22 22:29:09 +00:00
{
2010-01-18 02:10:55 +00:00
# ifdef GL_USE8BITTEX
# ifdef GL_EXT_paletted_texture
# define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB
2004-08-22 22:29:09 +00:00
// Check for 8bit Extensions and initialize them.
int i ;
char thePalette [ 256 * 3 ] ;
char * oldPalette , * newPalette ;
2005-01-07 03:16:44 +00:00
qglColorTableEXT = ( void * ) qwglGetProcAddress ( " glColorTableEXT " ) ;
2010-07-11 02:22:39 +00:00
if ( ! qglColorTableEXT | | ! GL_CheckExtension ( " GL_EXT_shared_texture_palette " ) | | COM_CheckParm ( " -no8bit " ) )
2004-08-22 22:29:09 +00:00
return ;
Con_SafePrintf ( " 8-bit GL extensions enabled. \n " ) ;
2010-07-11 02:22:39 +00:00
qglEnable ( GL_SHARED_TEXTURE_PALETTE_EXT ) ;
2004-08-22 22:29:09 +00:00
oldPalette = ( char * ) d_8to24rgbtable ; //d_8to24table3dfx;
newPalette = thePalette ;
2009-11-04 21:16:50 +00:00
for ( i = 0 ; i < 256 ; i + + )
{
2004-08-22 22:29:09 +00:00
* newPalette + + = * oldPalette + + ;
* newPalette + + = * oldPalette + + ;
* newPalette + + = * oldPalette + + ;
oldPalette + + ;
}
2005-01-07 03:16:44 +00:00
qglColorTableEXT ( GL_SHARED_TEXTURE_PALETTE_EXT , GL_RGB , 256 , GL_RGB , GL_UNSIGNED_BYTE ,
2004-08-22 22:29:09 +00:00
( void * ) thePalette ) ;
is8bit = TRUE ;
2010-01-18 02:10:55 +00:00
# endif
# endif
2004-08-22 22:29:09 +00:00
}
void GLVID_DeInit ( void )
{
GLVID_Shutdown ( ) ;
2009-04-01 22:03:56 +00:00
ActiveApp = false ;
2004-08-22 22:29:09 +00:00
2006-04-21 06:02:06 +00:00
Cvar_Unhook ( & _vid_wait_override ) ;
2009-04-06 00:34:32 +00:00
Cvar_Unhook ( & vid_wndalpha ) ;
2011-04-30 17:21:10 +00:00
Cmd_RemoveCommand ( " vid_recenter " ) ;
2006-04-21 06:02:06 +00:00
2004-08-22 22:29:09 +00:00
UnregisterClass ( WINDOW_CLASS_NAME , global_hInstance ) ;
}
2011-04-30 17:21:10 +00:00
2004-08-22 22:29:09 +00:00
/*
= = = = = = = = = = = = = = = = = = =
VID_Init
= = = = = = = = = = = = = = = = = = =
*/
qboolean GLVID_Init ( rendererstate_t * info , unsigned char * palette )
{
// qbyte *ptmp;
DEVMODE devmode ;
WNDCLASS wc ;
memset ( & devmode , 0 , sizeof ( devmode ) ) ;
/* Register the frame class */
wc . style = 0 ;
wc . lpfnWndProc = ( WNDPROC ) GLMainWndProc ;
wc . cbClsExtra = 0 ;
wc . cbWndExtra = 0 ;
wc . hInstance = global_hInstance ;
wc . hIcon = 0 ;
wc . hCursor = LoadCursor ( NULL , IDC_ARROW ) ;
wc . hbrBackground = NULL ;
wc . lpszMenuName = 0 ;
wc . lpszClassName = WINDOW_CLASS_NAME ;
2009-04-01 22:03:56 +00:00
if ( ! RegisterClass ( & wc ) ) //this isn't really fatal, we'll let the CreateWindow fail instead.
MessageBox ( NULL , " RegisterClass failed " , " GAH " , 0 ) ;
2004-08-22 22:29:09 +00:00
2009-11-04 21:16:50 +00:00
hIcon = LoadIcon ( global_hInstance , MAKEINTRESOURCE ( IDI_ICON1 ) ) ;
2004-08-22 22:29:09 +00:00
vid_initialized = false ;
vid_initializing = true ;
VID_SetPalette ( palette ) ;
if ( ! GLVID_SetMode ( info , palette ) )
{
VID_UnSetMode ( ) ;
return false ;
}
// Check for 3DFX Extensions and initialize them.
VID_Init8bitPalette ( ) ;
vid_canalttab = true ;
S_Restart_f ( ) ;
2006-04-21 06:02:06 +00:00
Cvar_Hook ( & _vid_wait_override , VID_Wait_Override_Callback ) ;
2009-04-06 00:34:32 +00:00
Cvar_Hook ( & vid_wndalpha , VID_WndAlpha_Override_Callback ) ;
2006-04-21 06:02:06 +00:00
2011-04-30 17:21:10 +00:00
Cmd_AddRemCommand ( " vid_recenter " , GLVID_Recenter_f ) ;
2004-08-22 22:29:09 +00:00
vid_initialized = true ;
vid_initializing = false ;
return true ;
}
2004-12-15 19:53:30 +00:00
# endif