diff options
| author | Paweł Redman <pawel.redman@gmail.com> | 2017-03-22 17:56:34 +0100 | 
|---|---|---|
| committer | Paweł Redman <pawel.redman@gmail.com> | 2017-03-22 17:56:34 +0100 | 
| commit | 6a777afc079c2a8d3af3ecd2145fe8dd50567a39 (patch) | |
| tree | 520f4489cebf8564ef6cb27064ceea45cbc005b3 /src/win32 | |
Diffstat (limited to 'src/win32')
| -rw-r--r-- | src/win32/glw_win.h | 52 | ||||
| -rw-r--r-- | src/win32/resource.h | 45 | ||||
| -rw-r--r-- | src/win32/win_gamma.c | 215 | ||||
| -rw-r--r-- | src/win32/win_glimp.c | 1609 | ||||
| -rw-r--r-- | src/win32/win_input.c | 1150 | ||||
| -rw-r--r-- | src/win32/win_local.h | 97 | ||||
| -rw-r--r-- | src/win32/win_main.c | 1265 | ||||
| -rw-r--r-- | src/win32/win_net.c | 1032 | ||||
| -rw-r--r-- | src/win32/win_qgl.c | 4387 | ||||
| -rw-r--r-- | src/win32/win_resource.rc | 71 | ||||
| -rw-r--r-- | src/win32/win_shared.c | 351 | ||||
| -rw-r--r-- | src/win32/win_snd.c | 389 | ||||
| -rw-r--r-- | src/win32/win_syscon.c | 597 | ||||
| -rw-r--r-- | src/win32/win_wndproc.c | 457 | 
14 files changed, 11717 insertions, 0 deletions
diff --git a/src/win32/glw_win.h b/src/win32/glw_win.h new file mode 100644 index 0000000..cd2407e --- /dev/null +++ b/src/win32/glw_win.h @@ -0,0 +1,52 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2006 Tim Angus + +This file is part of Tremulous. + +Tremulous 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. + +Tremulous is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Tremulous; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA +=========================================================================== +*/ +#ifndef _WIN32 +#  error You should not be including this file on this platform +#endif + +#ifndef __GLW_WIN_H__ +#define __GLW_WIN_H__ + +typedef struct +{ +	WNDPROC		wndproc; + +	HDC     hDC;			// handle to device context +	HGLRC   hGLRC;			// handle to GL rendering context + +	HINSTANCE hinstOpenGL;	// HINSTANCE for the OpenGL library + +	qboolean allowdisplaydepthchange; +	qboolean pixelFormatSet; + +	int		 desktopBitsPixel; +	int		 desktopWidth, desktopHeight; + +	qboolean	cdsFullscreen; + +	FILE *log_fp; +} glwstate_t; + +extern glwstate_t glw_state; + +#endif diff --git a/src/win32/resource.h b/src/win32/resource.h new file mode 100644 index 0000000..b1c79bc --- /dev/null +++ b/src/win32/resource.h @@ -0,0 +1,45 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2006 Tim Angus + +This file is part of Tremulous. + +Tremulous 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. + +Tremulous is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Tremulous; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA +=========================================================================== +*/ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by winquake.rc +// +#define IDS_STRING1                     1 +#define IDI_ICON1                       1 +#define IDB_BITMAP1                     1 +#define IDB_BITMAP2                     128 +#define IDC_CURSOR1                     129 +#define IDC_CURSOR2                     130 +#define IDC_CURSOR3                     131 + +// Next default values for new objects +//  +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC                     1 +#define _APS_NEXT_RESOURCE_VALUE        132 +#define _APS_NEXT_COMMAND_VALUE         40001 +#define _APS_NEXT_CONTROL_VALUE         1005 +#define _APS_NEXT_SYMED_VALUE           101 +#endif +#endif diff --git a/src/win32/win_gamma.c b/src/win32/win_gamma.c new file mode 100644 index 0000000..1832260 --- /dev/null +++ b/src/win32/win_gamma.c @@ -0,0 +1,215 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2006 Tim Angus + +This file is part of Tremulous. + +Tremulous 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. + +Tremulous is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Tremulous; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA +=========================================================================== +*/ +/* +** WIN_GAMMA.C +*/ +#include <assert.h> +#include "../renderer/tr_local.h" +#include "../qcommon/qcommon.h" +#include "glw_win.h" +#include "win_local.h" + +static unsigned short s_oldHardwareGamma[3][256]; + +/* +** WG_CheckHardwareGamma +** +** Determines if the underlying hardware supports the Win32 gamma correction API. +*/ +void WG_CheckHardwareGamma( void ) +{ +	HDC			hDC; + +	glConfig.deviceSupportsGamma = qfalse; + +	if ( qwglSetDeviceGammaRamp3DFX ) +	{ +		glConfig.deviceSupportsGamma = qtrue; + +		hDC = GetDC( GetDesktopWindow() ); +		glConfig.deviceSupportsGamma = qwglGetDeviceGammaRamp3DFX( hDC, s_oldHardwareGamma ); +		ReleaseDC( GetDesktopWindow(), hDC ); + +		return; +	} + +	// non-3Dfx standalone drivers don't support gamma changes, period +	if ( glConfig.driverType == GLDRV_STANDALONE ) +	{ +		return; +	} + +	if ( !r_ignorehwgamma->integer ) +	{ +		hDC = GetDC( GetDesktopWindow() ); +		glConfig.deviceSupportsGamma = GetDeviceGammaRamp( hDC, s_oldHardwareGamma ); +		ReleaseDC( GetDesktopWindow(), hDC ); + +		if ( glConfig.deviceSupportsGamma ) +		{ +			// +			// do a sanity check on the gamma values +			// +			if ( ( HIBYTE( s_oldHardwareGamma[0][255] ) <= HIBYTE( s_oldHardwareGamma[0][0] ) ) || +				 ( HIBYTE( s_oldHardwareGamma[1][255] ) <= HIBYTE( s_oldHardwareGamma[1][0] ) ) || +				 ( HIBYTE( s_oldHardwareGamma[2][255] ) <= HIBYTE( s_oldHardwareGamma[2][0] ) ) ) +			{ +				glConfig.deviceSupportsGamma = qfalse; +				ri.Printf( PRINT_WARNING, "WARNING: device has broken gamma support, generated gamma.dat\n" ); +			} + +			// +			// make sure that we didn't have a prior crash in the game, and if so we need to +			// restore the gamma values to at least a linear value +			// +			if ( ( HIBYTE( s_oldHardwareGamma[0][181] ) == 255 ) ) +			{ +				int g; + +				ri.Printf( PRINT_WARNING, "WARNING: suspicious gamma tables, using linear ramp for restoration\n" ); + +				for ( g = 0; g < 255; g++ ) +				{ +					s_oldHardwareGamma[0][g] = g << 8; +					s_oldHardwareGamma[1][g] = g << 8; +					s_oldHardwareGamma[2][g] = g << 8; +				} +			} +		} +	} +} + +/* +void mapGammaMax( void ) { +	int		i, j; +	unsigned short table[3][256]; + +	// try to figure out what win2k will let us get away with setting +	for ( i = 0 ; i < 256 ; i++ ) { +		if ( i >= 128 ) { +			table[0][i] = table[1][i] = table[2][i] = 0xffff; +		} else { +			table[0][i] = table[1][i] = table[2][i] = i<<9; +		} +	} + +	for ( i = 0 ; i < 128 ; i++ ) { +		for ( j = i*2 ; j < 255 ; j++ ) { +			table[0][i] = table[1][i] = table[2][i] = j<<8; +			if ( !SetDeviceGammaRamp( glw_state.hDC, table ) ) { +				break; +			} +		} +		table[0][i] = table[1][i] = table[2][i] = i<<9; +		Com_Printf( "index %i max: %i\n", i, j-1 ); +	} +} +*/ + +/* +** GLimp_SetGamma +** +** This routine should only be called if glConfig.deviceSupportsGamma is TRUE +*/ +void GLimp_SetGamma( unsigned char red[256], unsigned char green[256], unsigned char blue[256] ) { +	unsigned short table[3][256]; +	int		i, j; +	int		ret; +	OSVERSIONINFO	vinfo; + +	if ( !glConfig.deviceSupportsGamma || r_ignorehwgamma->integer || !glw_state.hDC ) { +		return; +	} + +//mapGammaMax(); + +	for ( i = 0; i < 256; i++ ) { +		table[0][i] = ( ( ( unsigned short ) red[i] ) << 8 ) | red[i]; +		table[1][i] = ( ( ( unsigned short ) green[i] ) << 8 ) | green[i]; +		table[2][i] = ( ( ( unsigned short ) blue[i] ) << 8 ) | blue[i]; +	} + +	// Win2K and newer put this odd restriction on gamma ramps... +	vinfo.dwOSVersionInfoSize = sizeof(vinfo); +	GetVersionEx( &vinfo ); +	if ( vinfo.dwMajorVersion >= 5 && vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) { +		Com_DPrintf( "performing gamma clamp.\n" ); +		for ( j = 0 ; j < 3 ; j++ ) { +			for ( i = 0 ; i < 128 ; i++ ) { +				if ( table[j][i] > ( (128+i) << 8 ) ) { +					table[j][i] = (128+i) << 8; +				} +			} +			if ( table[j][127] > 254<<8 ) { +				table[j][127] = 254<<8; +			} +		} +	} else { +		Com_DPrintf( "skipping gamma clamp.\n" ); +	} + +	// enforce constantly increasing +	for ( j = 0 ; j < 3 ; j++ ) { +		for ( i = 1 ; i < 256 ; i++ ) { +			if ( table[j][i] < table[j][i-1] ) { +				table[j][i] = table[j][i-1]; +			} +		} +	} + + +	if ( qwglSetDeviceGammaRamp3DFX ) +	{ +		qwglSetDeviceGammaRamp3DFX( glw_state.hDC, table ); +	} +	else +	{ +		ret = SetDeviceGammaRamp( glw_state.hDC, table ); +		if ( !ret ) { +			Com_Printf( "SetDeviceGammaRamp failed.\n" ); +		} +	} +} + +/* +** WG_RestoreGamma +*/ +void WG_RestoreGamma( void ) +{ +	if ( glConfig.deviceSupportsGamma ) +	{ +		if ( qwglSetDeviceGammaRamp3DFX ) +		{ +			qwglSetDeviceGammaRamp3DFX( glw_state.hDC, s_oldHardwareGamma ); +		} +		else +		{ +			HDC hDC; +			 +			hDC = GetDC( GetDesktopWindow() ); +			SetDeviceGammaRamp( hDC, s_oldHardwareGamma ); +			ReleaseDC( GetDesktopWindow(), hDC ); +		} +	} +} + diff --git a/src/win32/win_glimp.c b/src/win32/win_glimp.c new file mode 100644 index 0000000..ef8651d --- /dev/null +++ b/src/win32/win_glimp.c @@ -0,0 +1,1609 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2006 Tim Angus + +This file is part of Tremulous. + +Tremulous 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. + +Tremulous is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Tremulous; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA +=========================================================================== +*/ +/* +** WIN_GLIMP.C +** +** This file contains ALL Win32 specific stuff having to do with the +** OpenGL refresh.  When a port is being made the following functions +** must be implemented by the port: +** +** GLimp_EndFrame +** GLimp_Init +** GLimp_LogComment +** GLimp_Shutdown +** +** Note that the GLW_xxx functions are Windows specific GL-subsystem +** related functions that are relevant ONLY to win_glimp.c +*/ +#include <assert.h> +#include "../renderer/tr_local.h" +#include "../qcommon/qcommon.h" +#include "resource.h" +#include "glw_win.h" +#include "win_local.h" + +extern void WG_CheckHardwareGamma( void ); +extern void WG_RestoreGamma( void ); + +typedef enum { +	RSERR_OK, + +	RSERR_INVALID_FULLSCREEN, +	RSERR_INVALID_MODE, + +	RSERR_UNKNOWN +} rserr_t; + +#define TRY_PFD_SUCCESS		0 +#define TRY_PFD_FAIL_SOFT	1 +#define TRY_PFD_FAIL_HARD	2 + +static void		GLW_InitExtensions( void ); +static rserr_t	GLW_SetMode( const char *drivername,  +							 int mode,  +							 int colorbits,  +							 qboolean cdsFullscreen ); + +static qboolean s_classRegistered = qfalse; + +// +// function declaration +// +void	 QGL_EnableLogging( qboolean enable ); +qboolean QGL_Init( const char *dllname ); +void     QGL_Shutdown( void ); + +// +// variable declarations +// +glwstate_t glw_state; + +cvar_t	*r_allowSoftwareGL;		// don't abort out if the pixelformat claims software +cvar_t	*r_maskMinidriver;		// allow a different dll name to be treated as if it were opengl32.dll + + + +/* +** GLW_StartDriverAndSetMode +*/ +static qboolean GLW_StartDriverAndSetMode( const char *drivername,  +										   int mode,  +										   int colorbits, +										   qboolean cdsFullscreen ) +{ +	rserr_t err; + +	err = GLW_SetMode( drivername, r_mode->integer, colorbits, cdsFullscreen ); + +	switch ( err ) +	{ +	case RSERR_INVALID_FULLSCREEN: +		ri.Printf( PRINT_ALL, "...WARNING: fullscreen unavailable in this mode\n" ); +		return qfalse; +	case RSERR_INVALID_MODE: +		ri.Printf( PRINT_ALL, "...WARNING: could not set the given mode (%d)\n", mode ); +		return qfalse; +	default: +		break; +	} +	return qtrue; +} + +/* +** ChoosePFD +** +** Helper function that replaces ChoosePixelFormat. +*/ +#define MAX_PFDS 256 + +static int GLW_ChoosePFD( HDC hDC, PIXELFORMATDESCRIPTOR *pPFD ) +{ +	PIXELFORMATDESCRIPTOR pfds[MAX_PFDS+1]; +	int maxPFD = 0; +	int i; +	int bestMatch = 0; + +	ri.Printf( PRINT_ALL, "...GLW_ChoosePFD( %d, %d, %d )\n", ( int ) pPFD->cColorBits, ( int ) pPFD->cDepthBits, ( int ) pPFD->cStencilBits ); + +	// count number of PFDs +	if ( glConfig.driverType > GLDRV_ICD ) +	{ +		maxPFD = qwglDescribePixelFormat( hDC, 1, sizeof( PIXELFORMATDESCRIPTOR ), &pfds[0] ); +	} +	else +	{ +		maxPFD = DescribePixelFormat( hDC, 1, sizeof( PIXELFORMATDESCRIPTOR ), &pfds[0] ); +	} +	if ( maxPFD > MAX_PFDS ) +	{ +		ri.Printf( PRINT_WARNING, "...numPFDs > MAX_PFDS (%d > %d)\n", maxPFD, MAX_PFDS ); +		maxPFD = MAX_PFDS; +	} + +	ri.Printf( PRINT_ALL, "...%d PFDs found\n", maxPFD - 1 ); + +	// grab information +	for ( i = 1; i <= maxPFD; i++ ) +	{ +		if ( glConfig.driverType > GLDRV_ICD ) +		{ +			qwglDescribePixelFormat( hDC, i, sizeof( PIXELFORMATDESCRIPTOR ), &pfds[i] ); +		} +		else +		{ +			DescribePixelFormat( hDC, i, sizeof( PIXELFORMATDESCRIPTOR ), &pfds[i] ); +		} +	} + +	// look for a best match +	for ( i = 1; i <= maxPFD; i++ ) +	{ +		// +		// make sure this has hardware acceleration +		// +		if ( ( pfds[i].dwFlags & PFD_GENERIC_FORMAT ) != 0 )  +		{ +			if ( !r_allowSoftwareGL->integer ) +			{ +				if ( r_verbose->integer ) +				{ +					ri.Printf( PRINT_ALL, "...PFD %d rejected, software acceleration\n", i ); +				} +				continue; +			} +		} + +		// verify pixel type +		if ( pfds[i].iPixelType != PFD_TYPE_RGBA ) +		{ +			if ( r_verbose->integer ) +			{ +				ri.Printf( PRINT_ALL, "...PFD %d rejected, not RGBA\n", i ); +			} +			continue; +		} + +		// verify proper flags +		if ( ( ( pfds[i].dwFlags & pPFD->dwFlags ) & pPFD->dwFlags ) != pPFD->dwFlags )  +		{ +			if ( r_verbose->integer ) +			{ +				ri.Printf( PRINT_ALL, "...PFD %d rejected, improper flags (%x instead of %x)\n", i, pfds[i].dwFlags, pPFD->dwFlags ); +			} +			continue; +		} + +		// verify enough bits +		if ( pfds[i].cDepthBits < 15 ) +		{ +			continue; +		} +		if ( ( pfds[i].cStencilBits < 4 ) && ( pPFD->cStencilBits > 0 ) ) +		{ +			continue; +		} + +		// +		// selection criteria (in order of priority): +		//  +		//  PFD_STEREO +		//  colorBits +		//  depthBits +		//  stencilBits +		// +		if ( bestMatch ) +		{ +			// check stereo +			if ( ( pfds[i].dwFlags & PFD_STEREO ) && ( !( pfds[bestMatch].dwFlags & PFD_STEREO ) ) && ( pPFD->dwFlags & PFD_STEREO ) ) +			{ +				bestMatch = i; +				continue; +			} +			 +			if ( !( pfds[i].dwFlags & PFD_STEREO ) && ( pfds[bestMatch].dwFlags & PFD_STEREO ) && ( pPFD->dwFlags & PFD_STEREO ) ) +			{ +				bestMatch = i; +				continue; +			} + +			// check color +			if ( pfds[bestMatch].cColorBits != pPFD->cColorBits ) +			{ +				// prefer perfect match +				if ( pfds[i].cColorBits == pPFD->cColorBits ) +				{ +					bestMatch = i; +					continue; +				} +				// otherwise if this PFD has more bits than our best, use it +				else if ( pfds[i].cColorBits > pfds[bestMatch].cColorBits ) +				{ +					bestMatch = i; +					continue; +				} +			} + +			// check depth +			if ( pfds[bestMatch].cDepthBits != pPFD->cDepthBits ) +			{ +				// prefer perfect match +				if ( pfds[i].cDepthBits == pPFD->cDepthBits ) +				{ +					bestMatch = i; +					continue; +				} +				// otherwise if this PFD has more bits than our best, use it +				else if ( pfds[i].cDepthBits > pfds[bestMatch].cDepthBits ) +				{ +					bestMatch = i; +					continue; +				} +			} + +			// check stencil +			if ( pfds[bestMatch].cStencilBits != pPFD->cStencilBits ) +			{ +				// prefer perfect match +				if ( pfds[i].cStencilBits == pPFD->cStencilBits ) +				{ +					bestMatch = i; +					continue; +				} +				// otherwise if this PFD has more bits than our best, use it +				else if ( ( pfds[i].cStencilBits > pfds[bestMatch].cStencilBits ) &&  +					 ( pPFD->cStencilBits > 0 ) ) +				{ +					bestMatch = i; +					continue; +				} +			} +		} +		else +		{ +			bestMatch = i; +		} +	} +	 +	if ( !bestMatch ) +		return 0; + +	if ( ( pfds[bestMatch].dwFlags & PFD_GENERIC_FORMAT ) != 0 ) +	{ +		if ( !r_allowSoftwareGL->integer ) +		{ +			ri.Printf( PRINT_ALL, "...no hardware acceleration found\n" ); +			return 0; +		} +		else +		{ +			ri.Printf( PRINT_ALL, "...using software emulation\n" ); +		} +	} +	else if ( pfds[bestMatch].dwFlags & PFD_GENERIC_ACCELERATED ) +	{ +		ri.Printf( PRINT_ALL, "...MCD acceleration found\n" ); +	} +	else +	{ +		ri.Printf( PRINT_ALL, "...hardware acceleration found\n" ); +	} + +	*pPFD = pfds[bestMatch]; + +	return bestMatch; +} + +/* +** void GLW_CreatePFD +** +** Helper function zeros out then fills in a PFD +*/ +static void GLW_CreatePFD( PIXELFORMATDESCRIPTOR *pPFD, int colorbits, int depthbits, int stencilbits, qboolean stereo ) +{ +    PIXELFORMATDESCRIPTOR src =  +	{ +		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 +		24,								// 24-bit z-buffer	 +		8,								// 8-bit stencil buffer +		0,								// no auxiliary buffer +		PFD_MAIN_PLANE,					// main layer +		0,								// reserved +		0, 0, 0							// layer masks ignored +    }; + +	src.cColorBits = colorbits; +	src.cDepthBits = depthbits; +	src.cStencilBits = stencilbits; + +	if ( stereo ) +	{ +		ri.Printf( PRINT_ALL, "...attempting to use stereo\n" ); +		src.dwFlags |= PFD_STEREO; +		glConfig.stereoEnabled = qtrue; +	} +	else +	{ +		glConfig.stereoEnabled = qfalse; +	} + +	*pPFD = src; +} + +/* +** GLW_MakeContext +*/ +static int GLW_MakeContext( PIXELFORMATDESCRIPTOR *pPFD ) +{ +	int pixelformat; + +	// +	// don't putz around with pixelformat if it's already set (e.g. this is a soft +	// reset of the graphics system) +	// +	if ( !glw_state.pixelFormatSet ) +	{ +		// +		// choose, set, and describe our desired pixel format.  If we're +		// using a minidriver then we need to bypass the GDI functions, +		// otherwise use the GDI functions. +		// +		if ( ( pixelformat = GLW_ChoosePFD( glw_state.hDC, pPFD ) ) == 0 ) +		{ +			ri.Printf( PRINT_ALL, "...GLW_ChoosePFD failed\n"); +			return TRY_PFD_FAIL_SOFT; +		} +		ri.Printf( PRINT_ALL, "...PIXELFORMAT %d selected\n", pixelformat ); + +		if ( glConfig.driverType > GLDRV_ICD ) +		{ +			qwglDescribePixelFormat( glw_state.hDC, pixelformat, sizeof( *pPFD ), pPFD ); +			if ( qwglSetPixelFormat( glw_state.hDC, pixelformat, pPFD ) == FALSE ) +			{ +				ri.Printf ( PRINT_ALL, "...qwglSetPixelFormat failed\n"); +				return TRY_PFD_FAIL_SOFT; +			} +		} +		else +		{ +			DescribePixelFormat( glw_state.hDC, pixelformat, sizeof( *pPFD ), pPFD ); + +			if ( SetPixelFormat( glw_state.hDC, pixelformat, pPFD ) == FALSE ) +			{ +				ri.Printf (PRINT_ALL, "...SetPixelFormat failed\n", glw_state.hDC ); +				return TRY_PFD_FAIL_SOFT; +			} +		} + +		glw_state.pixelFormatSet = qtrue; +	} + +	// +	// startup the OpenGL subsystem by creating a context and making it current +	// +	if ( !glw_state.hGLRC ) +	{ +		ri.Printf( PRINT_ALL, "...creating GL context: " ); +		if ( ( glw_state.hGLRC = qwglCreateContext( glw_state.hDC ) ) == 0 ) +		{ +			ri.Printf (PRINT_ALL, "failed\n"); + +			return TRY_PFD_FAIL_HARD; +		} +		ri.Printf( PRINT_ALL, "succeeded\n" ); + +		ri.Printf( PRINT_ALL, "...making context current: " ); +		if ( !qwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) ) +		{ +			qwglDeleteContext( glw_state.hGLRC ); +			glw_state.hGLRC = NULL; +			ri.Printf (PRINT_ALL, "failed\n"); +			return TRY_PFD_FAIL_HARD; +		} +		ri.Printf( PRINT_ALL, "succeeded\n" ); +	} + +	return TRY_PFD_SUCCESS; +} + + +/* +** GLW_InitDriver +** +** - get a DC if one doesn't exist +** - create an HGLRC if one doesn't exist +*/ +static qboolean GLW_InitDriver( const char *drivername, int colorbits ) +{ +	int		tpfd; +	int		depthbits, stencilbits; +	static PIXELFORMATDESCRIPTOR pfd;		// save between frames since 'tr' gets cleared + +	ri.Printf( PRINT_ALL, "Initializing OpenGL driver\n" ); + +	// +	// get a DC for our window if we don't already have one allocated +	// +	if ( glw_state.hDC == NULL ) +	{ +		ri.Printf( PRINT_ALL, "...getting DC: " ); + +		if ( ( glw_state.hDC = GetDC( g_wv.hWnd ) ) == NULL ) +		{ +			ri.Printf( PRINT_ALL, "failed\n" ); +			return qfalse; +		} +		ri.Printf( PRINT_ALL, "succeeded\n" ); +	} + +	if ( colorbits == 0 ) +	{ +		colorbits = glw_state.desktopBitsPixel; +	} + +	// +	// implicitly assume Z-buffer depth == desktop color depth +	// +	if ( r_depthbits->integer == 0 ) { +		if ( colorbits > 16 ) { +			depthbits = 24; +		} else { +			depthbits = 16; +		} +	} else { +		depthbits = r_depthbits->integer; +	} + +	// +	// do not allow stencil if Z-buffer depth likely won't contain it +	// +	stencilbits = r_stencilbits->integer; +	if ( depthbits < 24 ) +	{ +		stencilbits = 0; +	} + +	// +	// make two attempts to set the PIXELFORMAT +	// + +	// +	// first attempt: r_colorbits, depthbits, and r_stencilbits +	// +	if ( !glw_state.pixelFormatSet ) +	{ +		GLW_CreatePFD( &pfd, colorbits, depthbits, stencilbits, r_stereo->integer ); +		if ( ( tpfd = GLW_MakeContext( &pfd ) ) != TRY_PFD_SUCCESS ) +		{ +			if ( tpfd == TRY_PFD_FAIL_HARD ) +			{ +				ri.Printf( PRINT_WARNING, "...failed hard\n" ); +				return qfalse; +			} + +			// +			// punt if we've already tried the desktop bit depth and no stencil bits +			// +			if ( ( r_colorbits->integer == glw_state.desktopBitsPixel ) && +				 ( stencilbits == 0 ) ) +			{ +				ReleaseDC( g_wv.hWnd, glw_state.hDC ); +				glw_state.hDC = NULL; + +				ri.Printf( PRINT_ALL, "...failed to find an appropriate PIXELFORMAT\n" ); + +				return qfalse; +			} + +			// +			// second attempt: desktop's color bits and no stencil +			// +			if ( colorbits > glw_state.desktopBitsPixel ) +			{ +				colorbits = glw_state.desktopBitsPixel; +			} +			GLW_CreatePFD( &pfd, colorbits, depthbits, 0, r_stereo->integer ); +			if ( GLW_MakeContext( &pfd ) != TRY_PFD_SUCCESS ) +			{ +				if ( glw_state.hDC ) +				{ +					ReleaseDC( g_wv.hWnd, glw_state.hDC ); +					glw_state.hDC = NULL; +				} + +				ri.Printf( PRINT_ALL, "...failed to find an appropriate PIXELFORMAT\n" ); + +				return qfalse; +			} +		} + +		/* +		** report if stereo is desired but unavailable +		*/ +		if ( !( pfd.dwFlags & PFD_STEREO ) && ( r_stereo->integer != 0 ) )  +		{ +			ri.Printf( PRINT_ALL, "...failed to select stereo pixel format\n" ); +			glConfig.stereoEnabled = qfalse; +		} +	} + +	/* +	** store PFD specifics  +	*/ +	glConfig.colorBits = ( int ) pfd.cColorBits; +	glConfig.depthBits = ( int ) pfd.cDepthBits; +	glConfig.stencilBits = ( int ) pfd.cStencilBits; + +	return qtrue; +} + +/* +** GLW_CreateWindow +** +** Responsible for creating the Win32 window and initializing the OpenGL driver. +*/ +#define	WINDOW_STYLE	(WS_OVERLAPPED|WS_BORDER|WS_CAPTION|WS_VISIBLE) +static qboolean GLW_CreateWindow( const char *drivername, int width, int height, int colorbits, qboolean cdsFullscreen ) +{ +	RECT			r; +	cvar_t			*vid_xpos, *vid_ypos; +	int				stylebits; +	int				x, y, w, h; +	int				exstyle; + +	// +	// register the window class if necessary +	// +	if ( !s_classRegistered ) +	{ +		WNDCLASS wc; + +		memset( &wc, 0, sizeof( wc ) ); + +		wc.style         = 0; +		wc.lpfnWndProc   = (WNDPROC) glw_state.wndproc; +		wc.cbClsExtra    = 0; +		wc.cbWndExtra    = 0; +		wc.hInstance     = g_wv.hInstance; +		wc.hIcon         = LoadIcon( g_wv.hInstance, MAKEINTRESOURCE(IDI_ICON1)); +		wc.hCursor       = LoadCursor (NULL,IDC_ARROW); +		wc.hbrBackground = (void *)COLOR_GRAYTEXT; +		wc.lpszMenuName  = 0; +		wc.lpszClassName = CLIENT_WINDOW_TITLE; + +		if ( !RegisterClass( &wc ) ) +		{ +			ri.Error( ERR_FATAL, "GLW_CreateWindow: could not register window class" ); +		} +		s_classRegistered = qtrue; +		ri.Printf( PRINT_ALL, "...registered window class\n" ); +	} + +	// +	// create the HWND if one does not already exist +	// +	if ( !g_wv.hWnd ) +	{ +		// +		// compute width and height +		// +		r.left = 0; +		r.top = 0; +		r.right  = width; +		r.bottom = height; + +		if ( cdsFullscreen || !Q_stricmp( _3DFX_DRIVER_NAME, drivername ) ) +		{ +			exstyle = WS_EX_TOPMOST; +			stylebits = WS_POPUP|WS_VISIBLE|WS_SYSMENU; +		} +		else +		{ +			exstyle = 0; +			stylebits = WINDOW_STYLE|WS_SYSMENU; +			AdjustWindowRect (&r, stylebits, FALSE); +		} + +		w = r.right - r.left; +		h = r.bottom - r.top; + +		if ( cdsFullscreen || !Q_stricmp( _3DFX_DRIVER_NAME, drivername ) ) +		{ +			x = 0; +			y = 0; +		} +		else +		{ +			vid_xpos = ri.Cvar_Get ("vid_xpos", "", 0); +			vid_ypos = ri.Cvar_Get ("vid_ypos", "", 0); +			x = vid_xpos->integer; +			y = vid_ypos->integer; + +			// adjust window coordinates if necessary  +			// so that the window is completely on screen +			if ( x < 0 ) +				x = 0; +			if ( y < 0 ) +				y = 0; + +			if ( w < glw_state.desktopWidth && +				 h < glw_state.desktopHeight ) +			{ +				if ( x + w > glw_state.desktopWidth ) +					x = ( glw_state.desktopWidth - w ); +				if ( y + h > glw_state.desktopHeight ) +					y = ( glw_state.desktopHeight - h ); +			} +		} + +		g_wv.hWnd = CreateWindowEx ( +			 exstyle,  +			 CLIENT_WINDOW_TITLE, +			 CLIENT_WINDOW_TITLE, +			 stylebits, +			 x, y, w, h, +			 NULL, +			 NULL, +			 g_wv.hInstance, +			 NULL); + +		if ( !g_wv.hWnd ) +		{ +			ri.Error (ERR_FATAL, "GLW_CreateWindow() - Couldn't create window"); +		} +	 +		ShowWindow( g_wv.hWnd, SW_SHOW ); +		UpdateWindow( g_wv.hWnd ); +		ri.Printf( PRINT_ALL, "...created window@%d,%d (%dx%d)\n", x, y, w, h ); +	} +	else +	{ +		ri.Printf( PRINT_ALL, "...window already present, CreateWindowEx skipped\n" ); +	} + +	if ( !GLW_InitDriver( drivername, colorbits ) ) +	{ +		ShowWindow( g_wv.hWnd, SW_HIDE ); +		DestroyWindow( g_wv.hWnd ); +		g_wv.hWnd = NULL; + +		return qfalse; +	} + +	SetForegroundWindow( g_wv.hWnd ); +	SetFocus( g_wv.hWnd ); + +	return qtrue; +} + +static void PrintCDSError( int value ) +{ +	switch ( value ) +	{ +	case DISP_CHANGE_RESTART: +		ri.Printf( PRINT_ALL, "restart required\n" ); +		break; +	case DISP_CHANGE_BADPARAM: +		ri.Printf( PRINT_ALL, "bad param\n" ); +		break; +	case DISP_CHANGE_BADFLAGS: +		ri.Printf( PRINT_ALL, "bad flags\n" ); +		break; +	case DISP_CHANGE_FAILED: +		ri.Printf( PRINT_ALL, "DISP_CHANGE_FAILED\n" ); +		break; +	case DISP_CHANGE_BADMODE: +		ri.Printf( PRINT_ALL, "bad mode\n" ); +		break; +	case DISP_CHANGE_NOTUPDATED: +		ri.Printf( PRINT_ALL, "not updated\n" ); +		break; +	default: +		ri.Printf( PRINT_ALL, "unknown error %d\n", value ); +		break; +	} +} + +/* +** GLW_SetMode +*/ +static rserr_t GLW_SetMode( const char *drivername,  +						    int mode,  +							int colorbits,  +							qboolean cdsFullscreen ) +{ +	HDC hDC; +	const char *win_fs[] = { "W", "FS" }; +	int		cdsRet; +	DEVMODE dm; +		 +	// +	// print out informational messages +	// +	ri.Printf( PRINT_ALL, "...setting mode %d:", mode ); +	if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) ) +	{ +		ri.Printf( PRINT_ALL, " invalid mode\n" ); +		return RSERR_INVALID_MODE; +	} +	ri.Printf( PRINT_ALL, " %d %d %s\n", glConfig.vidWidth, glConfig.vidHeight, win_fs[cdsFullscreen] ); + +	// +	// check our desktop attributes +	// +	hDC = GetDC( GetDesktopWindow() ); +	glw_state.desktopBitsPixel = GetDeviceCaps( hDC, BITSPIXEL ); +	glw_state.desktopWidth = GetDeviceCaps( hDC, HORZRES ); +	glw_state.desktopHeight = GetDeviceCaps( hDC, VERTRES ); +	ReleaseDC( GetDesktopWindow(), hDC ); + +	// +	// verify desktop bit depth +	// +	if ( glConfig.driverType != GLDRV_VOODOO ) +	{ +		if ( glw_state.desktopBitsPixel < 15 || glw_state.desktopBitsPixel == 24 ) +		{ +			if ( colorbits == 0 || ( !cdsFullscreen && colorbits >= 15 ) ) +			{ +				if ( MessageBox( NULL, +							"It is highly unlikely that a correct\n" +							"windowed display can be initialized with\n" +							"the current desktop display depth.  Select\n" +							"'OK' to try anyway.  Press 'Cancel' if you\n" +							"have a 3Dfx Voodoo, Voodoo-2, or Voodoo Rush\n" +							"3D accelerator installed, or if you otherwise\n" +							"wish to quit.", +							"Low Desktop Color Depth", +							MB_OKCANCEL | MB_ICONEXCLAMATION ) != IDOK ) +				{ +					return RSERR_INVALID_MODE; +				} +			} +		} +	} + +	// do a CDS if needed +	if ( cdsFullscreen ) +	{ +		memset( &dm, 0, sizeof( dm ) ); +		 +		dm.dmSize = sizeof( dm ); +		 +		dm.dmPelsWidth  = glConfig.vidWidth; +		dm.dmPelsHeight = glConfig.vidHeight; +		dm.dmFields     = DM_PELSWIDTH | DM_PELSHEIGHT; + +		if ( r_displayRefresh->integer != 0 ) +		{ +			dm.dmDisplayFrequency = r_displayRefresh->integer; +			dm.dmFields |= DM_DISPLAYFREQUENCY; +		} +		 +		// try to change color depth if possible +		if ( colorbits != 0 ) +		{ +			if ( glw_state.allowdisplaydepthchange ) +			{ +				dm.dmBitsPerPel = colorbits; +				dm.dmFields |= DM_BITSPERPEL; +				ri.Printf( PRINT_ALL, "...using colorsbits of %d\n", colorbits ); +			} +			else +			{ +				ri.Printf( PRINT_ALL, "WARNING:...changing depth not supported on Win95 < pre-OSR 2.x\n" ); +			} +		} +		else +		{ +			ri.Printf( PRINT_ALL, "...using desktop display depth of %d\n", glw_state.desktopBitsPixel ); +		} + +		// +		// if we're already in fullscreen then just create the window +		// +		if ( glw_state.cdsFullscreen ) +		{ +			ri.Printf( PRINT_ALL, "...already fullscreen, avoiding redundant CDS\n" ); + +			if ( !GLW_CreateWindow ( drivername, glConfig.vidWidth, glConfig.vidHeight, colorbits, qtrue ) ) +			{ +				ri.Printf( PRINT_ALL, "...restoring display settings\n" ); +				ChangeDisplaySettings( 0, 0 ); +				return RSERR_INVALID_MODE; +			} +		} +		// +		// need to call CDS +		// +		else +		{ +			ri.Printf( PRINT_ALL, "...calling CDS: " ); +			 +			// try setting the exact mode requested, because some drivers don't report +			// the low res modes in EnumDisplaySettings, but still work +			if ( ( cdsRet = ChangeDisplaySettings( &dm, CDS_FULLSCREEN ) ) == DISP_CHANGE_SUCCESSFUL ) +			{ +				ri.Printf( PRINT_ALL, "ok\n" ); + +				if ( !GLW_CreateWindow ( drivername, glConfig.vidWidth, glConfig.vidHeight, colorbits, qtrue) ) +				{ +					ri.Printf( PRINT_ALL, "...restoring display settings\n" ); +					ChangeDisplaySettings( 0, 0 ); +					return RSERR_INVALID_MODE; +				} +				 +				glw_state.cdsFullscreen = qtrue; +			} +			else +			{ +				// +				// the exact mode failed, so scan EnumDisplaySettings for the next largest mode +				// +				DEVMODE		devmode; +				int			modeNum; + +				ri.Printf( PRINT_ALL, "failed, " ); +				 +				PrintCDSError( cdsRet ); +			 +				ri.Printf( PRINT_ALL, "...trying next higher resolution:" ); +				 +				// we could do a better matching job here... +				for ( modeNum = 0 ; ; modeNum++ ) { +					if ( !EnumDisplaySettings( NULL, modeNum, &devmode ) ) { +						modeNum = -1; +						break; +					} +					if ( devmode.dmPelsWidth >= glConfig.vidWidth +						&& devmode.dmPelsHeight >= glConfig.vidHeight +						&& devmode.dmBitsPerPel >= 15 ) { +						break; +					} +				} + +				if ( modeNum != -1 && ( cdsRet = ChangeDisplaySettings( &devmode, CDS_FULLSCREEN ) ) == DISP_CHANGE_SUCCESSFUL ) +				{ +					ri.Printf( PRINT_ALL, " ok\n" ); +					if ( !GLW_CreateWindow( drivername, glConfig.vidWidth, glConfig.vidHeight, colorbits, qtrue) ) +					{ +						ri.Printf( PRINT_ALL, "...restoring display settings\n" ); +						ChangeDisplaySettings( 0, 0 ); +						return RSERR_INVALID_MODE; +					} +					 +					glw_state.cdsFullscreen = qtrue; +				} +				else +				{ +					ri.Printf( PRINT_ALL, " failed, " ); +					 +					PrintCDSError( cdsRet ); +					 +					ri.Printf( PRINT_ALL, "...restoring display settings\n" ); +					ChangeDisplaySettings( 0, 0 ); +					 +					glw_state.cdsFullscreen = qfalse; +					glConfig.isFullscreen = qfalse; +					if ( !GLW_CreateWindow( drivername, glConfig.vidWidth, glConfig.vidHeight, colorbits, qfalse) ) +					{ +						return RSERR_INVALID_MODE; +					} +					return RSERR_INVALID_FULLSCREEN; +				} +			} +		} +	} +	else +	{ +		if ( glw_state.cdsFullscreen ) +		{ +			ChangeDisplaySettings( 0, 0 ); +		} + +		glw_state.cdsFullscreen = qfalse; +		if ( !GLW_CreateWindow( drivername, glConfig.vidWidth, glConfig.vidHeight, colorbits, qfalse ) ) +		{ +			return RSERR_INVALID_MODE; +		} +	} + +	// +	// success, now check display frequency, although this won't be valid on Voodoo(2) +	// +	memset( &dm, 0, sizeof( dm ) ); +	dm.dmSize = sizeof( dm ); +	if ( EnumDisplaySettings( NULL, ENUM_CURRENT_SETTINGS, &dm ) ) +	{ +		glConfig.displayFrequency = dm.dmDisplayFrequency; +	} + +	// NOTE: this is overridden later on standalone 3Dfx drivers +	glConfig.isFullscreen = cdsFullscreen; + +	return RSERR_OK; +} + +/* +** GLW_InitExtensions +*/ +static void GLW_InitExtensions( void ) +{ +	if ( !r_allowExtensions->integer ) +	{ +		ri.Printf( PRINT_ALL, "*** IGNORING OPENGL EXTENSIONS ***\n" ); +		return; +	} + +	ri.Printf( PRINT_ALL, "Initializing OpenGL extensions\n" ); + +	// GL_S3_s3tc +	glConfig.textureCompression = TC_NONE; +	if ( strstr( glConfig.extensions_string, "GL_S3_s3tc" ) ) +	{ +		if ( r_ext_compressed_textures->integer ) +		{ +			glConfig.textureCompression = TC_S3TC; +			ri.Printf( PRINT_ALL, "...using GL_S3_s3tc\n" ); +		} +		else +		{ +			glConfig.textureCompression = TC_NONE; +			ri.Printf( PRINT_ALL, "...ignoring GL_S3_s3tc\n" ); +		} +	} +	else +	{ +		ri.Printf( PRINT_ALL, "...GL_S3_s3tc not found\n" ); +	} + +	// GL_EXT_texture_env_add +	glConfig.textureEnvAddAvailable = qfalse; +	if ( strstr( glConfig.extensions_string, "EXT_texture_env_add" ) ) +	{ +		if ( r_ext_texture_env_add->integer ) +		{ +			glConfig.textureEnvAddAvailable = qtrue; +			ri.Printf( PRINT_ALL, "...using GL_EXT_texture_env_add\n" ); +		} +		else +		{ +			glConfig.textureEnvAddAvailable = qfalse; +			ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_env_add\n" ); +		} +	} +	else +	{ +		ri.Printf( PRINT_ALL, "...GL_EXT_texture_env_add not found\n" ); +	} + +	// WGL_EXT_swap_control +	qwglSwapIntervalEXT = ( BOOL (WINAPI *)(int)) qwglGetProcAddress( "wglSwapIntervalEXT" ); +	if ( qwglSwapIntervalEXT ) +	{ +		ri.Printf( PRINT_ALL, "...using WGL_EXT_swap_control\n" ); +		r_swapInterval->modified = qtrue;	// force a set next frame +	} +	else +	{ +		ri.Printf( PRINT_ALL, "...WGL_EXT_swap_control not found\n" ); +	} + +	// GL_ARB_multitexture +	qglMultiTexCoord2fARB = NULL; +	qglActiveTextureARB = NULL; +	qglClientActiveTextureARB = NULL; +	if ( strstr( glConfig.extensions_string, "GL_ARB_multitexture" )  ) +	{ +		if ( r_ext_multitexture->integer ) +		{ +			qglMultiTexCoord2fARB = ( PFNGLMULTITEXCOORD2FARBPROC ) qwglGetProcAddress( "glMultiTexCoord2fARB" ); +			qglActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC ) qwglGetProcAddress( "glActiveTextureARB" ); +			qglClientActiveTextureARB = ( PFNGLCLIENTACTIVETEXTUREARBPROC ) qwglGetProcAddress( "glClientActiveTextureARB" ); + +			if ( qglActiveTextureARB ) +			{ +				qglGetIntegerv( GL_MAX_ACTIVE_TEXTURES_ARB, &glConfig.maxActiveTextures ); + +				if ( glConfig.maxActiveTextures > 1 ) +				{ +					ri.Printf( PRINT_ALL, "...using GL_ARB_multitexture\n" ); +				} +				else +				{ +					qglMultiTexCoord2fARB = NULL; +					qglActiveTextureARB = NULL; +					qglClientActiveTextureARB = NULL; +					ri.Printf( PRINT_ALL, "...not using GL_ARB_multitexture, < 2 texture units\n" ); +				} +			} +		} +		else +		{ +			ri.Printf( PRINT_ALL, "...ignoring GL_ARB_multitexture\n" ); +		} +	} +	else +	{ +		ri.Printf( PRINT_ALL, "...GL_ARB_multitexture not found\n" ); +	} + +	// GL_EXT_compiled_vertex_array +	qglLockArraysEXT = NULL; +	qglUnlockArraysEXT = NULL; +	if ( strstr( glConfig.extensions_string, "GL_EXT_compiled_vertex_array" ) && ( glConfig.hardwareType != GLHW_RIVA128 ) ) +	{ +		if ( r_ext_compiled_vertex_array->integer ) +		{ +			ri.Printf( PRINT_ALL, "...using GL_EXT_compiled_vertex_array\n" ); +			qglLockArraysEXT = ( void ( APIENTRY * )( int, int ) ) qwglGetProcAddress( "glLockArraysEXT" ); +			qglUnlockArraysEXT = ( void ( APIENTRY * )( void ) ) qwglGetProcAddress( "glUnlockArraysEXT" ); +			if (!qglLockArraysEXT || !qglUnlockArraysEXT) { +				ri.Error (ERR_FATAL, "bad getprocaddress"); +			} +		} +		else +		{ +			ri.Printf( PRINT_ALL, "...ignoring GL_EXT_compiled_vertex_array\n" ); +		} +	} +	else +	{ +		ri.Printf( PRINT_ALL, "...GL_EXT_compiled_vertex_array not found\n" ); +	} + +	// WGL_3DFX_gamma_control +	qwglGetDeviceGammaRamp3DFX = NULL; +	qwglSetDeviceGammaRamp3DFX = NULL; + +	if ( strstr( glConfig.extensions_string, "WGL_3DFX_gamma_control" ) ) +	{ +		if ( !r_ignorehwgamma->integer && r_ext_gamma_control->integer ) +		{ +			qwglGetDeviceGammaRamp3DFX = ( BOOL ( WINAPI * )( HDC, LPVOID ) ) qwglGetProcAddress( "wglGetDeviceGammaRamp3DFX" ); +			qwglSetDeviceGammaRamp3DFX = ( BOOL ( WINAPI * )( HDC, LPVOID ) ) qwglGetProcAddress( "wglSetDeviceGammaRamp3DFX" ); + +			if ( qwglGetDeviceGammaRamp3DFX && qwglSetDeviceGammaRamp3DFX ) +			{ +				ri.Printf( PRINT_ALL, "...using WGL_3DFX_gamma_control\n" ); +			} +			else +			{ +				qwglGetDeviceGammaRamp3DFX = NULL; +				qwglSetDeviceGammaRamp3DFX = NULL; +			} +		} +		else +		{ +			ri.Printf( PRINT_ALL, "...ignoring WGL_3DFX_gamma_control\n" ); +		} +	} +	else +	{ +		ri.Printf( PRINT_ALL, "...WGL_3DFX_gamma_control not found\n" ); +	} + +	glConfig.textureFilterAnisotropic = qfalse; +	if ( strstr( glConfig.extensions_string, "GL_EXT_texture_filter_anisotropic" ) ) +	{ +		if ( r_ext_texture_filter_anisotropic->integer ) { +			qglGetIntegerv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.maxAnisotropy ); +			if ( glConfig.maxAnisotropy <= 0 ) { +				ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not properly supported!\n" ); +				glConfig.maxAnisotropy = 0; +			} +			else +			{ +				ri.Printf( PRINT_ALL, "...using GL_EXT_texture_filter_anisotropic (max: %i)\n", glConfig.maxAnisotropy ); +				glConfig.textureFilterAnisotropic = qtrue; +			} +		} +		else +		{ +			ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_filter_anisotropic\n" ); +		} +	} +	else +	{ +		ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not found\n" ); +	} +} + +/* +** GLW_CheckOSVersion +*/ +static qboolean GLW_CheckOSVersion( void ) +{ +#define OSR2_BUILD_NUMBER 1111 + +	OSVERSIONINFO	vinfo; + +	vinfo.dwOSVersionInfoSize = sizeof(vinfo); + +	glw_state.allowdisplaydepthchange = qfalse; + +	if ( GetVersionEx( &vinfo) ) +	{ +		if ( vinfo.dwMajorVersion > 4 ) +		{ +			glw_state.allowdisplaydepthchange = qtrue; +		} +		else if ( vinfo.dwMajorVersion == 4 ) +		{ +			if ( vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT ) +			{ +				glw_state.allowdisplaydepthchange = qtrue; +			} +			else if ( vinfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) +			{ +				if ( LOWORD( vinfo.dwBuildNumber ) >= OSR2_BUILD_NUMBER ) +				{ +					glw_state.allowdisplaydepthchange = qtrue; +				} +			} +		} +	} +	else +	{ +		ri.Printf( PRINT_ALL, "GLW_CheckOSVersion() - GetVersionEx failed\n" ); +		return qfalse; +	} + +	return qtrue; +} + +/* +** GLW_LoadOpenGL +** +** GLimp_win.c internal function that attempts to load and use  +** a specific OpenGL DLL. +*/ +static qboolean GLW_LoadOpenGL( const char *drivername ) +{ +	char buffer[1024]; +	qboolean cdsFullscreen; + +	Q_strncpyz( buffer, drivername, sizeof(buffer) ); +	Q_strlwr(buffer); + +	// +	// determine if we're on a standalone driver +	// +	if ( strstr( buffer, "opengl32" ) != 0 || r_maskMinidriver->integer ) +	{ +		glConfig.driverType = GLDRV_ICD; +	} +	else +	{ +		glConfig.driverType = GLDRV_STANDALONE; + +		ri.Printf( PRINT_ALL, "...assuming '%s' is a standalone driver\n", drivername ); + +		if ( strstr( buffer, _3DFX_DRIVER_NAME ) ) +		{ +			glConfig.driverType = GLDRV_VOODOO; +		} +	} + +	// disable the 3Dfx splash screen +	_putenv("FX_GLIDE_NO_SPLASH=0"); + +	// +	// load the driver and bind our function pointers to it +	//  +	if ( QGL_Init( buffer ) )  +	{ +		cdsFullscreen = r_fullscreen->integer; + +		// create the window and set up the context +		if ( !GLW_StartDriverAndSetMode( drivername, r_mode->integer, r_colorbits->integer, cdsFullscreen ) ) +		{ +			// if we're on a 24/32-bit desktop and we're going fullscreen on an ICD, +			// try it again but with a 16-bit desktop +			if ( glConfig.driverType == GLDRV_ICD ) +			{ +				if ( r_colorbits->integer != 16 || +					 cdsFullscreen != qtrue || +					 r_mode->integer != 3 ) +				{ +					if ( !GLW_StartDriverAndSetMode( drivername, 3, 16, qtrue ) ) +					{ +						goto fail; +					} +				} +			} +			else +			{ +				goto fail; +			} +		} + +		if ( glConfig.driverType == GLDRV_VOODOO ) +		{ +			glConfig.isFullscreen = qtrue; +		} + +		return qtrue; +	} +fail: + +	QGL_Shutdown(); + +	return qfalse; +} + +/* +** GLimp_EndFrame +*/ +void GLimp_EndFrame (void) +{ +	// +	// swapinterval stuff +	// +	if ( r_swapInterval->modified ) { +		r_swapInterval->modified = qfalse; + +		if ( !glConfig.stereoEnabled ) {	// why? +			if ( qwglSwapIntervalEXT ) { +				qwglSwapIntervalEXT( r_swapInterval->integer ); +			} +		} +	} + + +	// don't flip if drawing to front buffer +	if ( Q_stricmp( r_drawBuffer->string, "GL_FRONT" ) != 0 ) +	{ +		if ( glConfig.driverType > GLDRV_ICD ) +		{ +			if ( !qwglSwapBuffers( glw_state.hDC ) ) +			{ +				ri.Error( ERR_FATAL, "GLimp_EndFrame() - SwapBuffers() failed!\n" ); +			} +		} +		else +		{ +			SwapBuffers( glw_state.hDC ); +		} +	} + +	// check logging +	QGL_EnableLogging( r_logFile->integer ); +} + +static void GLW_StartOpenGL( void ) +{ +	qboolean attemptedOpenGL32 = qfalse; +	qboolean attempted3Dfx = qfalse; + +	// +	// load and initialize the specific OpenGL driver +	// +	if ( !GLW_LoadOpenGL( r_glDriver->string ) ) +	{ +		if ( !Q_stricmp( r_glDriver->string, OPENGL_DRIVER_NAME ) ) +		{ +			attemptedOpenGL32 = qtrue; +		} +		else if ( !Q_stricmp( r_glDriver->string, _3DFX_DRIVER_NAME ) ) +		{ +			attempted3Dfx = qtrue; +		} + +		if ( !attempted3Dfx ) +		{ +			attempted3Dfx = qtrue; +			if ( GLW_LoadOpenGL( _3DFX_DRIVER_NAME ) ) +			{ +				ri.Cvar_Set( "r_glDriver", _3DFX_DRIVER_NAME ); +				r_glDriver->modified = qfalse; +			} +			else +			{ +				if ( !attemptedOpenGL32 ) +				{ +					if ( !GLW_LoadOpenGL( OPENGL_DRIVER_NAME ) ) +					{ +						ri.Error( ERR_FATAL, "GLW_StartOpenGL() - could not load OpenGL subsystem\n" ); +					} +					ri.Cvar_Set( "r_glDriver", OPENGL_DRIVER_NAME ); +					r_glDriver->modified = qfalse; +				} +				else +				{ +					ri.Error( ERR_FATAL, "GLW_StartOpenGL() - could not load OpenGL subsystem\n" ); +				} +			} +		} +		else if ( !attemptedOpenGL32 ) +		{ +			attemptedOpenGL32 = qtrue; +			if ( GLW_LoadOpenGL( OPENGL_DRIVER_NAME ) ) +			{ +				ri.Cvar_Set( "r_glDriver", OPENGL_DRIVER_NAME ); +				r_glDriver->modified = qfalse; +			} +			else +			{ +				ri.Error( ERR_FATAL, "GLW_StartOpenGL() - could not load OpenGL subsystem\n" ); +			} +		} +	} +} + +/* +** GLimp_Init +** +** This is the platform specific OpenGL initialization function.  It +** is responsible for loading OpenGL, initializing it, setting +** extensions, creating a window of the appropriate size, doing +** fullscreen manipulations, etc.  Its overall responsibility is +** to make sure that a functional OpenGL subsystem is operating +** when it returns to the ref. +*/ +void GLimp_Init( void ) +{ +	cvar_t	*cv; + +	ri.Printf( PRINT_ALL, "Initializing OpenGL subsystem\n" ); + +	// +	// check OS version to see if we can do fullscreen display changes +	// +	if ( !GLW_CheckOSVersion() ) +	{ +		ri.Error( ERR_FATAL, "GLimp_Init() - incorrect operating system\n" ); +	} + +	// save off hInstance and wndproc +	cv = ri.Cvar_Get( "win_hinstance", "", 0 ); +	sscanf( cv->string, "%i", (int *)&g_wv.hInstance ); + +	cv = ri.Cvar_Get( "win_wndproc", "", 0 ); +	sscanf( cv->string, "%i", (int *)&glw_state.wndproc ); + +	r_allowSoftwareGL = ri.Cvar_Get( "r_allowSoftwareGL", "0", CVAR_LATCH ); +	r_maskMinidriver = ri.Cvar_Get( "r_maskMinidriver", "0", CVAR_LATCH ); + +	// load appropriate DLL and initialize subsystem +	GLW_StartOpenGL(); + +	// get our config strings +	Q_strncpyz( glConfig.vendor_string, qglGetString (GL_VENDOR), sizeof( glConfig.vendor_string ) ); +	Q_strncpyz( glConfig.renderer_string, qglGetString (GL_RENDERER), sizeof( glConfig.renderer_string ) ); +	Q_strncpyz( glConfig.version_string, qglGetString (GL_VERSION), sizeof( glConfig.version_string ) ); +	Q_strncpyz( glConfig.extensions_string, qglGetString (GL_EXTENSIONS), sizeof( glConfig.extensions_string ) ); + +  GL_ResolveHardwareType( ); + +	ri.Cvar_Set( "r_lastValidRenderer", glConfig.renderer_string ); + +	GLW_InitExtensions(); +	WG_CheckHardwareGamma(); +} + +/* +** GLimp_Shutdown +** +** This routine does all OS specific shutdown procedures for the OpenGL +** subsystem. +*/ +void GLimp_Shutdown( void ) +{ +//	const char *strings[] = { "soft", "hard" }; +	const char *success[] = { "failed", "success" }; +	int retVal; + +	// FIXME: Brian, we need better fallbacks from partially initialized failures +	if ( !qwglMakeCurrent ) { +		return; +	} + +	ri.Printf( PRINT_ALL, "Shutting down OpenGL subsystem\n" ); + +	// restore gamma.  We do this first because 3Dfx's extension needs a valid OGL subsystem +	WG_RestoreGamma(); + +	// set current context to NULL +	if ( qwglMakeCurrent ) +	{ +		retVal = qwglMakeCurrent( NULL, NULL ) != 0; + +		ri.Printf( PRINT_ALL, "...wglMakeCurrent( NULL, NULL ): %s\n", success[retVal] ); +	} + +	// delete HGLRC +	if ( glw_state.hGLRC ) +	{ +		retVal = qwglDeleteContext( glw_state.hGLRC ) != 0; +		ri.Printf( PRINT_ALL, "...deleting GL context: %s\n", success[retVal] ); +		glw_state.hGLRC = NULL; +	} + +	// release DC +	if ( glw_state.hDC ) +	{ +		retVal = ReleaseDC( g_wv.hWnd, glw_state.hDC ) != 0; +		ri.Printf( PRINT_ALL, "...releasing DC: %s\n", success[retVal] ); +		glw_state.hDC   = NULL; +	} + +	// destroy window +	if ( g_wv.hWnd ) +	{ +		ri.Printf( PRINT_ALL, "...destroying window\n" ); +		ShowWindow( g_wv.hWnd, SW_HIDE ); +		DestroyWindow( g_wv.hWnd ); +		g_wv.hWnd = NULL; +		glw_state.pixelFormatSet = qfalse; +	} + +	// close the r_logFile +	if ( glw_state.log_fp ) +	{ +		fclose( glw_state.log_fp ); +		glw_state.log_fp = 0; +	} + +	// reset display settings +	if ( glw_state.cdsFullscreen ) +	{ +		ri.Printf( PRINT_ALL, "...resetting display\n" ); +		ChangeDisplaySettings( 0, 0 ); +		glw_state.cdsFullscreen = qfalse; +	} + +	// shutdown QGL subsystem +	QGL_Shutdown(); + +	memset( &glConfig, 0, sizeof( glConfig ) ); +	memset( &glState, 0, sizeof( glState ) ); +} + +/* +** GLimp_LogComment +*/ +void GLimp_LogComment( char *comment )  +{ +	if ( glw_state.log_fp ) { +		fprintf( glw_state.log_fp, "%s", comment ); +	} +} + + +/* +=========================================================== + +SMP acceleration + +=========================================================== +*/ + +HANDLE	renderCommandsEvent; +HANDLE	renderCompletedEvent; +HANDLE	renderActiveEvent; + +void (*glimpRenderThread)( void ); + +void GLimp_RenderThreadWrapper( void ) { +	glimpRenderThread(); + +	// unbind the context before we die +	qwglMakeCurrent( glw_state.hDC, NULL ); +} + +/* +======================= +GLimp_SpawnRenderThread +======================= +*/ +HANDLE	renderThreadHandle; +int		renderThreadId; +qboolean GLimp_SpawnRenderThread( void (*function)( void ) ) { + +	renderCommandsEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); +	renderCompletedEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); +	renderActiveEvent = CreateEvent( NULL, TRUE, FALSE, NULL ); + +	glimpRenderThread = function; + +	renderThreadHandle = CreateThread( +	   NULL,	// LPSECURITY_ATTRIBUTES lpsa, +	   0,		// DWORD cbStack, +	   (LPTHREAD_START_ROUTINE)GLimp_RenderThreadWrapper,	// LPTHREAD_START_ROUTINE lpStartAddr, +	   0,			// LPVOID lpvThreadParm, +	   0,			//   DWORD fdwCreate, +	   (long *)&renderThreadId ); + +	if ( !renderThreadHandle ) { +		return qfalse; +	} + +	return qtrue; +} + +static	void	*smpData; +static	int		wglErrors; + +void *GLimp_RendererSleep( void ) { +	void	*data; + +	if ( !qwglMakeCurrent( glw_state.hDC, NULL ) ) { +		wglErrors++; +	} + +	// after this, the front end can exit GLimp_FrontEndSleep +	SetEvent( renderCompletedEvent ); + +	WaitForSingleObject( renderCommandsEvent, INFINITE ); + +	ResetEvent( renderActiveEvent ); + +	if ( !qwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) ) { +		wglErrors++; +	} + +	ResetEvent( renderCompletedEvent ); +	ResetEvent( renderCommandsEvent ); + +	data = smpData; + +	// after this, the main thread can exit GLimp_WakeRenderer +	SetEvent( renderActiveEvent ); + +	return data; +} + + +void GLimp_FrontEndSleep( void ) { +	WaitForSingleObject( renderCompletedEvent, INFINITE ); + +	if ( !qwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) ) { +		wglErrors++; +	} +} + + +void GLimp_WakeRenderer( void *data ) { +	smpData = data; + +	if ( !qwglMakeCurrent( glw_state.hDC, NULL ) ) { +		wglErrors++; +	} + +	// after this, the renderer can continue through GLimp_RendererSleep +	SetEvent( renderCommandsEvent ); + +	WaitForSingleObject( renderActiveEvent, INFINITE ); +} + diff --git a/src/win32/win_input.c b/src/win32/win_input.c new file mode 100644 index 0000000..e725386 --- /dev/null +++ b/src/win32/win_input.c @@ -0,0 +1,1150 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2006 Tim Angus + +This file is part of Tremulous. + +Tremulous 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. + +Tremulous is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Tremulous; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA +=========================================================================== +*/ +// win_input.c -- win32 mouse and joystick code +// 02/21/97 JCB Added extended DirectInput code to support external controllers. + +#include "../client/client.h" +#include "win_local.h" + + +typedef struct { +	int			oldButtonState; + +	qboolean	mouseActive; +	qboolean	mouseInitialized; +  qboolean  mouseStartupDelayed; // delay mouse init to try DI again when we have a window +} WinMouseVars_t; + +static WinMouseVars_t s_wmv; + +static int	window_center_x, window_center_y; + +// +// MIDI definitions +// +static void IN_StartupMIDI( void ); +static void IN_ShutdownMIDI( void ); + +#define MAX_MIDIIN_DEVICES	8 + +typedef struct { +	int			numDevices; +	MIDIINCAPS	caps[MAX_MIDIIN_DEVICES]; + +	HMIDIIN		hMidiIn; +} MidiInfo_t; + +static MidiInfo_t s_midiInfo; + +// +// Joystick definitions +// +#define	JOY_MAX_AXES		6				// X, Y, Z, R, U, V + +typedef struct { +	qboolean	avail; +	int			id;			// joystick number +	JOYCAPS		jc; + +	int			oldbuttonstate; +	int			oldpovstate; + +	JOYINFOEX	ji; +} joystickInfo_t; + +static	joystickInfo_t	joy; + + + +cvar_t	*in_midi; +cvar_t	*in_midiport; +cvar_t	*in_midichannel; +cvar_t	*in_mididevice; + +cvar_t	*in_mouse; +cvar_t  *in_logitechbug; +cvar_t	*in_joystick; +cvar_t	*in_joyBallScale; +cvar_t	*in_debugJoystick; +cvar_t	*joy_threshold; + +qboolean	in_appactive; + +// forward-referenced functions +void IN_StartupJoystick (void); +void IN_JoyMove(void); + +static void MidiInfo_f( void ); + +/* +============================================================ + +WIN32 MOUSE CONTROL + +============================================================ +*/ + +/* +================ +IN_InitWin32Mouse +================ +*/ +void IN_InitWin32Mouse( void )  +{ +} + +/* +================ +IN_ShutdownWin32Mouse +================ +*/ +void IN_ShutdownWin32Mouse( void ) { +} + +/* +================ +IN_ActivateWin32Mouse +================ +*/ +void IN_ActivateWin32Mouse( void ) { +	int			width, height; +	RECT		window_rect; + +	width = GetSystemMetrics (SM_CXSCREEN); +	height = GetSystemMetrics (SM_CYSCREEN); + +	GetWindowRect ( g_wv.hWnd, &window_rect); +	if (window_rect.left < 0) +		window_rect.left = 0; +	if (window_rect.top < 0) +		window_rect.top = 0; +	if (window_rect.right >= width) +		window_rect.right = width-1; +	if (window_rect.bottom >= height-1) +		window_rect.bottom = height-1; +	window_center_x = (window_rect.right + window_rect.left)/2; +	window_center_y = (window_rect.top + window_rect.bottom)/2; + +	SetCursorPos (window_center_x, window_center_y); + +	SetCapture ( g_wv.hWnd ); +	ClipCursor (&window_rect); +	while (ShowCursor (FALSE) >= 0) +		; +} + +/* +================ +IN_DeactivateWin32Mouse +================ +*/ +void IN_DeactivateWin32Mouse( void )  +{ +	ClipCursor (NULL); +	ReleaseCapture (); +	while (ShowCursor (TRUE) < 0) +		; +} + +/* +================ +IN_Win32Mouse +================ +*/ +void IN_Win32Mouse( int *mx, int *my ) { +	POINT		current_pos; + +	// find mouse movement +	GetCursorPos (¤t_pos); + +	// force the mouse to the center, so there's room to move +	SetCursorPos (window_center_x, window_center_y); + +	*mx = current_pos.x - window_center_x; +	*my = current_pos.y - window_center_y; +} + + +/* +============================================================ + +DIRECT INPUT MOUSE CONTROL + +============================================================ +*/ + +#undef DEFINE_GUID + +#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ +        const GUID name \ +                = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } } + +DEFINE_GUID(GUID_SysMouse,   0x6F1D2B60,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(GUID_XAxis,   0xA36D02E0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(GUID_YAxis,   0xA36D02E1,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); +DEFINE_GUID(GUID_ZAxis,   0xA36D02E2,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00); + + +#define DINPUT_BUFFERSIZE           16 +#define iDirectInputCreate(a,b,c,d)	pDirectInputCreate(a,b,c,d) + +HRESULT (WINAPI *pDirectInputCreate)(HINSTANCE hinst, DWORD dwVersion, +	LPDIRECTINPUT * lplpDirectInput, LPUNKNOWN punkOuter); + +static HINSTANCE hInstDI; + +typedef struct MYDATA { +	LONG  lX;                   // X axis goes here +	LONG  lY;                   // Y axis goes here +	LONG  lZ;                   // Z axis goes here +	BYTE  bButtonA;             // One button goes here +	BYTE  bButtonB;             // Another button goes here +	BYTE  bButtonC;             // Another button goes here +	BYTE  bButtonD;             // Another button goes here +} MYDATA; + +static DIOBJECTDATAFORMAT rgodf[] = { +  { &GUID_XAxis,    FIELD_OFFSET(MYDATA, lX),       DIDFT_AXIS | DIDFT_ANYINSTANCE,   0,}, +  { &GUID_YAxis,    FIELD_OFFSET(MYDATA, lY),       DIDFT_AXIS | DIDFT_ANYINSTANCE,   0,}, +  { &GUID_ZAxis,    FIELD_OFFSET(MYDATA, lZ),       0x80000000 | DIDFT_AXIS | DIDFT_ANYINSTANCE,   0,}, +  { 0,              FIELD_OFFSET(MYDATA, bButtonA), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, +  { 0,              FIELD_OFFSET(MYDATA, bButtonB), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, +  { 0,              FIELD_OFFSET(MYDATA, bButtonC), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, +  { 0,              FIELD_OFFSET(MYDATA, bButtonD), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, +}; + +#define NUM_OBJECTS (sizeof(rgodf) / sizeof(rgodf[0])) + +// NOTE TTimo: would be easier using c_dfDIMouse or c_dfDIMouse2  +static DIDATAFORMAT	df = { +	sizeof(DIDATAFORMAT),       // this structure +	sizeof(DIOBJECTDATAFORMAT), // size of object data format +	DIDF_RELAXIS,               // absolute axis coordinates +	sizeof(MYDATA),             // device data size +	NUM_OBJECTS,                // number of objects +	rgodf,                      // and here they are +}; + +static LPDIRECTINPUT		g_pdi; +static LPDIRECTINPUTDEVICE	g_pMouse; + +void IN_DIMouse( int *mx, int *my ); + +/* +======================== +IN_InitDIMouse +======================== +*/ +qboolean IN_InitDIMouse( void ) { +    HRESULT		hr; +	int			x, y; +	DIPROPDWORD	dipdw = { +		{ +			sizeof(DIPROPDWORD),        // diph.dwSize +			sizeof(DIPROPHEADER),       // diph.dwHeaderSize +			0,                          // diph.dwObj +			DIPH_DEVICE,                // diph.dwHow +		}, +		DINPUT_BUFFERSIZE,              // dwData +	}; + +	Com_Printf( "Initializing DirectInput...\n"); + +	if (!hInstDI) { +		hInstDI = LoadLibrary("dinput.dll"); +		 +		if (hInstDI == NULL) { +			Com_Printf ("Couldn't load dinput.dll\n"); +			return qfalse; +		} +	} + +	if (!pDirectInputCreate) { +		pDirectInputCreate = (HRESULT (WINAPI *)(HINSTANCE, DWORD, LPDIRECTINPUT *, LPUNKNOWN)) +			GetProcAddress(hInstDI,"DirectInputCreateA"); + +		if (!pDirectInputCreate) { +			Com_Printf ("Couldn't get DI proc addr\n"); +			return qfalse; +		} +	} + +	// register with DirectInput and get an IDirectInput to play with. +	hr = iDirectInputCreate( g_wv.hInstance, DIRECTINPUT_VERSION, &g_pdi, NULL); + +	if (FAILED(hr)) { +		Com_Printf ("iDirectInputCreate failed\n"); +		return qfalse; +	} + +	// obtain an interface to the system mouse device. +	hr = IDirectInput_CreateDevice(g_pdi, &GUID_SysMouse, &g_pMouse, NULL); + +	if (FAILED(hr)) { +		Com_Printf ("Couldn't open DI mouse device\n"); +		return qfalse; +	} + +	// set the data format to "mouse format". +	hr = IDirectInputDevice_SetDataFormat(g_pMouse, &df); + +	if (FAILED(hr)) 	{ +		Com_Printf ("Couldn't set DI mouse format\n"); +		return qfalse; +	} + +	// set the cooperativity level. +	hr = IDirectInputDevice_SetCooperativeLevel(g_pMouse, g_wv.hWnd, +			DISCL_EXCLUSIVE | DISCL_FOREGROUND); + +	// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=50 +	if (FAILED(hr)) { +		Com_Printf ("Couldn't set DI coop level\n"); +		return qfalse; +	} + + +	// set the buffer size to DINPUT_BUFFERSIZE elements. +	// the buffer size is a DWORD property associated with the device +	hr = IDirectInputDevice_SetProperty(g_pMouse, DIPROP_BUFFERSIZE, &dipdw.diph); + +	if (FAILED(hr)) { +		Com_Printf ("Couldn't set DI buffersize\n"); +		return qfalse; +	} + +	// clear any pending samples +	IN_DIMouse( &x, &y ); +	IN_DIMouse( &x, &y ); + +	Com_Printf( "DirectInput initialized.\n"); +	return qtrue; +} + +/* +========================== +IN_ShutdownDIMouse +========================== +*/ +void IN_ShutdownDIMouse( void ) { +    if (g_pMouse) { +		IDirectInputDevice_Release(g_pMouse); +		g_pMouse = NULL; +	} + +    if (g_pdi) { +		IDirectInput_Release(g_pdi); +		g_pdi = NULL; +	} +} + +/* +========================== +IN_ActivateDIMouse +========================== +*/ +void IN_ActivateDIMouse( void ) { +	HRESULT		hr; + +	if (!g_pMouse) { +		return; +	} + +	// we may fail to reacquire if the window has been recreated +	hr = IDirectInputDevice_Acquire( g_pMouse ); +	if (FAILED(hr)) { +		if ( !IN_InitDIMouse() ) { +			Com_Printf ("Falling back to Win32 mouse support...\n"); +			Cvar_Set( "in_mouse", "-1" ); +		} +	} +} + +/* +========================== +IN_DeactivateDIMouse +========================== +*/ +void IN_DeactivateDIMouse( void ) { +	if (!g_pMouse) { +		return; +	} +	IDirectInputDevice_Unacquire( g_pMouse ); +} + + +/* +=================== +IN_DIMouse +=================== +*/ +void IN_DIMouse( int *mx, int *my ) { +	DIDEVICEOBJECTDATA	od; +	DIMOUSESTATE		state; +	DWORD				dwElements; +	HRESULT				hr; +  int value; + +	if ( !g_pMouse ) { +		return; +	} + +	// fetch new events +	for (;;) +	{ +		dwElements = 1; + +		hr = IDirectInputDevice_GetDeviceData(g_pMouse, +				sizeof(DIDEVICEOBJECTDATA), &od, &dwElements, 0); +		if ((hr == DIERR_INPUTLOST) || (hr == DIERR_NOTACQUIRED)) { +			IDirectInputDevice_Acquire(g_pMouse); +			return; +		} + +		/* Unable to read data or no data available */ +		if ( FAILED(hr) ) { +			break; +		} + +		if ( dwElements == 0 ) { +			break; +		} + +		switch (od.dwOfs) { +		case DIMOFS_BUTTON0: +			if (od.dwData & 0x80) +				Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MOUSE1, qtrue, 0, NULL ); +			else +				Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MOUSE1, qfalse, 0, NULL ); +			break; + +		case DIMOFS_BUTTON1: +			if (od.dwData & 0x80) +				Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MOUSE2, qtrue, 0, NULL ); +			else +				Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MOUSE2, qfalse, 0, NULL ); +			break; +			 +		case DIMOFS_BUTTON2: +			if (od.dwData & 0x80) +				Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MOUSE3, qtrue, 0, NULL ); +			else +				Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MOUSE3, qfalse, 0, NULL ); +			break; + +		case DIMOFS_BUTTON3: +			if (od.dwData & 0x80) +				Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MOUSE4, qtrue, 0, NULL ); +			else +				Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MOUSE4, qfalse, 0, NULL ); +			break;       +    // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=50 +		case DIMOFS_Z: +			value = od.dwData; +			if (value == 0) { + +			} else if (value < 0) { +				Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL ); +				Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL ); +			} else { +				Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MWHEELUP, qtrue, 0, NULL ); +				Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MWHEELUP, qfalse, 0, NULL ); +			} +			break; +		} +	} + +	// read the raw delta counter and ignore +	// the individual sample time / values +	hr = IDirectInputDevice_GetDeviceState(g_pMouse, +			sizeof(DIDEVICEOBJECTDATA), &state); +	if ( FAILED(hr) ) { +		*mx = *my = 0; +		return; +	} +	*mx = state.lX; +	*my = state.lY; +} + +/* +============================================================ + +  MOUSE CONTROL + +============================================================ +*/ + +/* +=========== +IN_ActivateMouse + +Called when the window gains focus or changes in some way +=========== +*/ +void IN_ActivateMouse( void )  +{ +	if (!s_wmv.mouseInitialized ) { +		return; +	} +	if ( !in_mouse->integer )  +	{ +		s_wmv.mouseActive = qfalse; +		return; +	} +	if ( s_wmv.mouseActive )  +	{ +		return; +	} + +	s_wmv.mouseActive = qtrue; + +	if ( in_mouse->integer != -1 ) { +		IN_ActivateDIMouse(); +	} +	IN_ActivateWin32Mouse(); +} + + +/* +=========== +IN_DeactivateMouse + +Called when the window loses focus +=========== +*/ +void IN_DeactivateMouse( void ) { +	if (!s_wmv.mouseInitialized ) { +		return; +	} +	if (!s_wmv.mouseActive ) { +		return; +	} +	s_wmv.mouseActive = qfalse; + +	IN_DeactivateDIMouse(); +	IN_DeactivateWin32Mouse(); +} + + + +/* +=========== +IN_StartupMouse +=========== +*/ +void IN_StartupMouse( void )  +{ +	s_wmv.mouseInitialized = qfalse; +  s_wmv.mouseStartupDelayed = qfalse; + +	if ( in_mouse->integer == 0 ) { +		Com_Printf ("Mouse control not active.\n"); +		return; +	} + +	// nt4.0 direct input is screwed up +	if ( ( g_wv.osversion.dwPlatformId == VER_PLATFORM_WIN32_NT ) && +		 ( g_wv.osversion.dwMajorVersion == 4 ) ) +	{ +		Com_Printf ("Disallowing DirectInput on NT 4.0\n"); +		Cvar_Set( "in_mouse", "-1" ); +	} + +	if ( in_mouse->integer == -1 ) { +		Com_Printf ("Skipping check for DirectInput\n"); +	} else { +    if (!g_wv.hWnd) +    { +      Com_Printf ("No window for DirectInput mouse init, delaying\n"); +      s_wmv.mouseStartupDelayed = qtrue; +      return; +    } +		if ( IN_InitDIMouse() ) { +	    s_wmv.mouseInitialized = qtrue; +			return; +		} +		Com_Printf ("Falling back to Win32 mouse support...\n"); +	} +	s_wmv.mouseInitialized = qtrue; +	IN_InitWin32Mouse(); +} + +/* +=========== +IN_MouseEvent +=========== +*/ +void IN_MouseEvent (int mstate) +{ +	int		i; + +	if ( !s_wmv.mouseInitialized ) +		return; + +// perform button actions +	for  (i = 0 ; i < 3 ; i++ ) +	{ +		if ( (mstate & (1<<i)) && +			!(s_wmv.oldButtonState & (1<<i)) ) +		{ +			Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MOUSE1 + i, qtrue, 0, NULL ); +		} + +		if ( !(mstate & (1<<i)) && +			(s_wmv.oldButtonState & (1<<i)) ) +		{ +			Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MOUSE1 + i, qfalse, 0, NULL ); +		} +	}	 + +	s_wmv.oldButtonState = mstate; +} + + +/* +=========== +IN_MouseMove +=========== +*/ +void IN_MouseMove ( void ) { +	int		mx, my; + +	if ( g_pMouse ) { +		IN_DIMouse( &mx, &my ); +	} else { +		IN_Win32Mouse( &mx, &my ); +	} + +	if ( !mx && !my ) { +		return; +	} + +	Sys_QueEvent( 0, SE_MOUSE, mx, my, 0, NULL ); +} + + +/* +========================================================================= + +========================================================================= +*/ + +/* +=========== +IN_Startup +=========== +*/ +void IN_Startup( void ) { +	Com_Printf ("\n------- Input Initialization -------\n"); +	IN_StartupMouse (); +	IN_StartupJoystick (); +	IN_StartupMIDI(); +	Com_Printf ("------------------------------------\n"); + +	in_mouse->modified = qfalse; +	in_joystick->modified = qfalse; +} + +/* +=========== +IN_Shutdown +=========== +*/ +void IN_Shutdown( void ) { +	IN_DeactivateMouse(); +	IN_ShutdownDIMouse(); +	IN_ShutdownMIDI(); +	Cmd_RemoveCommand("midiinfo" ); +} + + +/* +=========== +IN_Init +=========== +*/ +void IN_Init( void ) { +	// MIDI input controler variables +	in_midi					= Cvar_Get ("in_midi",					"0",		CVAR_ARCHIVE); +	in_midiport				= Cvar_Get ("in_midiport",				"1",		CVAR_ARCHIVE); +	in_midichannel			= Cvar_Get ("in_midichannel",			"1",		CVAR_ARCHIVE); +	in_mididevice			= Cvar_Get ("in_mididevice",			"0",		CVAR_ARCHIVE); + +	Cmd_AddCommand( "midiinfo", MidiInfo_f ); + +	// mouse variables +  in_mouse				= Cvar_Get ("in_mouse",					"1",		CVAR_ARCHIVE|CVAR_LATCH); +	in_logitechbug  = Cvar_Get ("in_logitechbug", "0", CVAR_ARCHIVE); + +	// joystick variables +	in_joystick				= Cvar_Get ("in_joystick",				"0",		CVAR_ARCHIVE|CVAR_LATCH); +	in_joyBallScale			= Cvar_Get ("in_joyBallScale",			"0.02",		CVAR_ARCHIVE); +	in_debugJoystick		= Cvar_Get ("in_debugjoystick",			"0",		CVAR_TEMP); + +	joy_threshold			= Cvar_Get ("joy_threshold",			"0.15",		CVAR_ARCHIVE); + +	IN_Startup(); +} + + +/* +=========== +IN_Activate + +Called when the main window gains or loses focus. +The window may have been destroyed and recreated +between a deactivate and an activate. +=========== +*/ +void IN_Activate (qboolean active) { +	in_appactive = active; + +	if ( !active ) +	{ +		IN_DeactivateMouse(); +	} +} + + +/* +================== +IN_Frame + +Called every frame, even if not generating commands +================== +*/ +void IN_Frame (void) { +	// post joystick events +	IN_JoyMove(); + +	if ( !s_wmv.mouseInitialized ) { +    if (s_wmv.mouseStartupDelayed && g_wv.hWnd) +		{ +			Com_Printf("Proceeding with delayed mouse init\n"); +      IN_StartupMouse(); +			s_wmv.mouseStartupDelayed = qfalse; +		} +		return; +	} + +	if ( cls.keyCatchers & KEYCATCH_CONSOLE ) { +		// temporarily deactivate if not in the game and +		// running on the desktop +		// voodoo always counts as full screen +		if (Cvar_VariableValue ("r_fullscreen") == 0 +			&& strcmp( Cvar_VariableString("r_glDriver"), _3DFX_DRIVER_NAME) )	{ +			IN_DeactivateMouse (); +			return; +		} +	} + +	if ( !in_appactive ) { +		IN_DeactivateMouse (); +		return; +	} + +	IN_ActivateMouse(); + +	// post events to the system que +	IN_MouseMove(); + +} + + +/* +=================== +IN_ClearStates +=================== +*/ +void IN_ClearStates (void)  +{ +	s_wmv.oldButtonState = 0; +} + + +/* +========================================================================= + +JOYSTICK + +========================================================================= +*/ + +/*  +===============  +IN_StartupJoystick  +===============  +*/   +void IN_StartupJoystick (void) {  +	int			numdevs; +	MMRESULT	mmr; + +	// assume no joystick +	joy.avail = qfalse;  + +	if (! in_joystick->integer ) { +		Com_Printf ("Joystick is not active.\n"); +		return; +	} + +	// verify joystick driver is present +	if ((numdevs = joyGetNumDevs ()) == 0) +	{ +		Com_Printf ("joystick not found -- driver not present\n"); +		return; +	} + +	// cycle through the joystick ids for the first valid one +	mmr = 0; +	for (joy.id=0 ; joy.id<numdevs ; joy.id++) +	{ +		Com_Memset (&joy.ji, 0, sizeof(joy.ji)); +		joy.ji.dwSize = sizeof(joy.ji); +		joy.ji.dwFlags = JOY_RETURNCENTERED; + +		if ((mmr = joyGetPosEx (joy.id, &joy.ji)) == JOYERR_NOERROR) +			break; +	}  + +	// abort startup if we didn't find a valid joystick +	if (mmr != JOYERR_NOERROR) +	{ +		Com_Printf ("joystick not found -- no valid joysticks (%x)\n", mmr); +		return; +	} + +	// get the capabilities of the selected joystick +	// abort startup if command fails +	Com_Memset (&joy.jc, 0, sizeof(joy.jc)); +	if ((mmr = joyGetDevCaps (joy.id, &joy.jc, sizeof(joy.jc))) != JOYERR_NOERROR) +	{ +		Com_Printf ("joystick not found -- invalid joystick capabilities (%x)\n", mmr);  +		return; +	} + +	Com_Printf( "Joystick found.\n" ); +	Com_Printf( "Pname: %s\n", joy.jc.szPname ); +	Com_Printf( "OemVxD: %s\n", joy.jc.szOEMVxD ); +	Com_Printf( "RegKey: %s\n", joy.jc.szRegKey ); + +	Com_Printf( "Numbuttons: %i / %i\n", joy.jc.wNumButtons, joy.jc.wMaxButtons ); +	Com_Printf( "Axis: %i / %i\n", joy.jc.wNumAxes, joy.jc.wMaxAxes ); +	Com_Printf( "Caps: 0x%x\n", joy.jc.wCaps ); +	if ( joy.jc.wCaps & JOYCAPS_HASPOV ) { +		Com_Printf( "HASPOV\n" ); +	} else { +		Com_Printf( "no POV\n" ); +	} + +	// old button and POV states default to no buttons pressed +	joy.oldbuttonstate = 0; +	joy.oldpovstate = 0; + +	// mark the joystick as available +	joy.avail = qtrue;  +} + +/* +=========== +JoyToF +=========== +*/ +float JoyToF( int value ) { +	float	fValue; + +	// move centerpoint to zero +	value -= 32768; + +	// convert range from -32768..32767 to -1..1  +	fValue = (float)value / 32768.0; + +	if ( fValue < -1 ) { +		fValue = -1; +	} +	if ( fValue > 1 ) { +		fValue = 1; +	} +	return fValue; +} + +int JoyToI( int value ) { +	// move centerpoint to zero +	value -= 32768; + +	return value; +} + +int	joyDirectionKeys[16] = { +	K_LEFTARROW, K_RIGHTARROW, +	K_UPARROW, K_DOWNARROW, +	K_JOY16, K_JOY17, +	K_JOY18, K_JOY19, +	K_JOY20, K_JOY21, +	K_JOY22, K_JOY23, + +	K_JOY24, K_JOY25, +	K_JOY26, K_JOY27 +}; + +/* +=========== +IN_JoyMove +=========== +*/ +void IN_JoyMove( void ) { +	float	fAxisValue; +	int		i; +	DWORD	buttonstate, povstate; +	int		x, y; + +	// verify joystick is available and that the user wants to use it +	if ( !joy.avail ) { +		return;  +	} + +	// collect the joystick data, if possible +	Com_Memset (&joy.ji, 0, sizeof(joy.ji)); +	joy.ji.dwSize = sizeof(joy.ji); +	joy.ji.dwFlags = JOY_RETURNALL; + +	if ( joyGetPosEx (joy.id, &joy.ji) != JOYERR_NOERROR ) { +		// read error occurred +		// turning off the joystick seems too harsh for 1 read error, +		// but what should be done? +		// Com_Printf ("IN_ReadJoystick: no response\n"); +		// joy.avail = false; +		return; +	} + +	if ( in_debugJoystick->integer ) { +		Com_Printf( "%8x %5i %5.2f %5.2f %5.2f %5.2f %6i %6i\n",  +			JoyToI( joy.ji.dwButtons ), +			JoyToI( joy.ji.dwPOV ), +			JoyToF( joy.ji.dwXpos ), JoyToF( joy.ji.dwYpos ), +			JoyToF( joy.ji.dwZpos ), JoyToF( joy.ji.dwRpos ), +			JoyToI( joy.ji.dwUpos ), JoyToI( joy.ji.dwVpos ) ); +	} + +	// loop through the joystick buttons +	// key a joystick event or auxillary event for higher number buttons for each state change +	buttonstate = joy.ji.dwButtons; +	for ( i=0 ; i < joy.jc.wNumButtons ; i++ ) { +		if ( (buttonstate & (1<<i)) && !(joy.oldbuttonstate & (1<<i)) ) { +			Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_JOY1 + i, qtrue, 0, NULL ); +		} +		if ( !(buttonstate & (1<<i)) && (joy.oldbuttonstate & (1<<i)) ) { +			Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_JOY1 + i, qfalse, 0, NULL ); +		} +	} +	joy.oldbuttonstate = buttonstate; + +	povstate = 0; + +	// convert main joystick motion into 6 direction button bits +	for (i = 0; i < joy.jc.wNumAxes && i < 4 ; i++) { +		// get the floating point zero-centered, potentially-inverted data for the current axis +		fAxisValue = JoyToF( (&joy.ji.dwXpos)[i] ); + +		if ( fAxisValue < -joy_threshold->value ) { +			povstate |= (1<<(i*2)); +		} else if ( fAxisValue > joy_threshold->value ) { +			povstate |= (1<<(i*2+1)); +		} +	} + +	// convert POV information from a direction into 4 button bits +	if ( joy.jc.wCaps & JOYCAPS_HASPOV ) { +		if ( joy.ji.dwPOV != JOY_POVCENTERED ) { +			if (joy.ji.dwPOV == JOY_POVFORWARD) +				povstate |= 1<<12; +			if (joy.ji.dwPOV == JOY_POVBACKWARD) +				povstate |= 1<<13; +			if (joy.ji.dwPOV == JOY_POVRIGHT) +				povstate |= 1<<14; +			if (joy.ji.dwPOV == JOY_POVLEFT) +				povstate |= 1<<15; +		} +	} + +	// determine which bits have changed and key an auxillary event for each change +	for (i=0 ; i < 16 ; i++) { +		if ( (povstate & (1<<i)) && !(joy.oldpovstate & (1<<i)) ) { +			Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, joyDirectionKeys[i], qtrue, 0, NULL ); +		} + +		if ( !(povstate & (1<<i)) && (joy.oldpovstate & (1<<i)) ) { +			Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, joyDirectionKeys[i], qfalse, 0, NULL ); +		} +	} +	joy.oldpovstate = povstate; + +	// if there is a trackball like interface, simulate mouse moves +	if ( joy.jc.wNumAxes >= 6 ) { +		x = JoyToI( joy.ji.dwUpos ) * in_joyBallScale->value; +		y = JoyToI( joy.ji.dwVpos ) * in_joyBallScale->value; +		if ( x || y ) { +			Sys_QueEvent( g_wv.sysMsgTime, SE_MOUSE, x, y, 0, NULL ); +		} +	} +} + +/* +========================================================================= + +MIDI + +========================================================================= +*/ + +static void MIDI_NoteOff( int note ) +{ +	int qkey; + +	qkey = note - 60 + K_AUX1; + +	if ( qkey > 255 || qkey < K_AUX1 ) +		return; + +	Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, qkey, qfalse, 0, NULL ); +} + +static void MIDI_NoteOn( int note, int velocity ) +{ +	int qkey; + +	if ( velocity == 0 ) +		MIDI_NoteOff( note ); + +	qkey = note - 60 + K_AUX1; + +	if ( qkey > 255 || qkey < K_AUX1 ) +		return; + +	Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, qkey, qtrue, 0, NULL ); +} + +static void CALLBACK MidiInProc( HMIDIIN hMidiIn, UINT uMsg, DWORD dwInstance,  +								 DWORD dwParam1, DWORD dwParam2 ) +{ +	int message; + +	switch ( uMsg ) +	{ +	case MIM_OPEN: +		break; +	case MIM_CLOSE: +		break; +	case MIM_DATA: +		message = dwParam1 & 0xff; + +		// note on +		if ( ( message & 0xf0 ) == 0x90 ) +		{ +			if ( ( ( message & 0x0f ) + 1 ) == in_midichannel->integer ) +				MIDI_NoteOn( ( dwParam1 & 0xff00 ) >> 8, ( dwParam1 & 0xff0000 ) >> 16 ); +		} +		else if ( ( message & 0xf0 ) == 0x80 ) +		{ +			if ( ( ( message & 0x0f ) + 1 ) == in_midichannel->integer ) +				MIDI_NoteOff( ( dwParam1 & 0xff00 ) >> 8 ); +		} +		break; +	case MIM_LONGDATA: +		break; +	case MIM_ERROR: +		break; +	case MIM_LONGERROR: +		break; +	} + +//	Sys_QueEvent( sys_msg_time, SE_KEY, wMsg, qtrue, 0, NULL ); +} + +static void MidiInfo_f( void ) +{ +	int i; + +	const char *enableStrings[] = { "disabled", "enabled" }; + +	Com_Printf( "\nMIDI control:       %s\n", enableStrings[in_midi->integer != 0] ); +	Com_Printf( "port:               %d\n", in_midiport->integer ); +	Com_Printf( "channel:            %d\n", in_midichannel->integer ); +	Com_Printf( "current device:     %d\n", in_mididevice->integer ); +	Com_Printf( "number of devices:  %d\n", s_midiInfo.numDevices ); +	for ( i = 0; i < s_midiInfo.numDevices; i++ ) +	{ +		if ( i == Cvar_VariableValue( "in_mididevice" ) ) +			Com_Printf( "***" ); +		else +			Com_Printf( "..." ); +		Com_Printf(    "device %2d:       %s\n", i, s_midiInfo.caps[i].szPname ); +		Com_Printf( "...manufacturer ID: 0x%hx\n", s_midiInfo.caps[i].wMid ); +		Com_Printf( "...product ID:      0x%hx\n", s_midiInfo.caps[i].wPid ); + +		Com_Printf( "\n" ); +	} +} + +static void IN_StartupMIDI( void ) +{ +	int i; + +	if ( !Cvar_VariableValue( "in_midi" ) ) +		return; + +	// +	// enumerate MIDI IN devices +	// +	s_midiInfo.numDevices = midiInGetNumDevs(); + +	for ( i = 0; i < s_midiInfo.numDevices; i++ ) +	{ +		midiInGetDevCaps( i, &s_midiInfo.caps[i], sizeof( s_midiInfo.caps[i] ) ); +	} + +	// +	// open the MIDI IN port +	// +	if ( midiInOpen( &s_midiInfo.hMidiIn,  +		             in_mididevice->integer, +					 ( unsigned long ) MidiInProc, +					 ( unsigned long ) NULL, +					 CALLBACK_FUNCTION ) != MMSYSERR_NOERROR ) +	{ +		Com_Printf( "WARNING: could not open MIDI device %d: '%s'\n", +								in_mididevice->integer , s_midiInfo.caps[( int ) in_mididevice->value].szPname ); +		return; +	} + +	midiInStart( s_midiInfo.hMidiIn ); +} + +static void IN_ShutdownMIDI( void ) +{ +	if ( s_midiInfo.hMidiIn ) +	{ +		midiInClose( s_midiInfo.hMidiIn ); +	} +	Com_Memset( &s_midiInfo, 0, sizeof( s_midiInfo ) ); +} + diff --git a/src/win32/win_local.h b/src/win32/win_local.h new file mode 100644 index 0000000..9d59973 --- /dev/null +++ b/src/win32/win_local.h @@ -0,0 +1,97 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2006 Tim Angus + +This file is part of Tremulous. + +Tremulous 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. + +Tremulous is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Tremulous; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA +=========================================================================== +*/ +// win_local.h: Win32-specific Quake3 header file + +#if defined (_MSC_VER) && (_MSC_VER >= 1200) +#pragma warning(disable : 4201) +#pragma warning( push ) +#endif +#include <windows.h> +#if defined (_MSC_VER) && (_MSC_VER >= 1200) +#pragma warning( pop ) +#endif + +#define	DIRECTSOUND_VERSION	0x0300 +#define	DIRECTINPUT_VERSION	0x0300 + +#include <dinput.h> +#include <dsound.h> +#include <winsock.h> +#include <wsipx.h> +#include <shlobj.h> + +void	IN_MouseEvent (int mstate); + +void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr ); + +void	Sys_CreateConsole( void ); +void	Sys_DestroyConsole( void ); + +char	*Sys_ConsoleInput (void); + +qboolean	Sys_GetPacket ( netadr_t *net_from, msg_t *net_message ); + +// Input subsystem + +void	IN_Init (void); +void	IN_Shutdown (void); +void	IN_JoystickCommands (void); + +void	IN_Move (usercmd_t *cmd); +// add additional non keyboard / non mouse movement on top of the keyboard move cmd + +void	IN_DeactivateWin32Mouse( void); + +void	IN_Activate (qboolean active); +void	IN_Frame (void); + +// window procedure +LONG WINAPI MainWndProc ( +    HWND    hWnd, +    UINT    uMsg, +    WPARAM  wParam, +    LPARAM  lParam); + +void Conbuf_AppendText( const char *msg ); + +void SNDDMA_Activate( void ); +int  SNDDMA_InitDS (void); + +typedef struct +{ +	 +	HINSTANCE		reflib_library;		// Handle to refresh DLL  +	qboolean		reflib_active; + +	HWND			hWnd; +	HINSTANCE		hInstance; +	qboolean		activeApp; +	qboolean		isMinimized; +	OSVERSIONINFO	osversion; + +	// when we get a windows message, we store the time off so keyboard processing +	// can know the exact time of an event +	unsigned		sysMsgTime; +} WinVars_t; + +extern WinVars_t	g_wv; diff --git a/src/win32/win_main.c b/src/win32/win_main.c new file mode 100644 index 0000000..8b390af --- /dev/null +++ b/src/win32/win_main.c @@ -0,0 +1,1265 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2006 Tim Angus + +This file is part of Tremulous. + +Tremulous 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. + +Tremulous is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Tremulous; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA +=========================================================================== +*/ +// win_main.c + +#include "../client/client.h" +#include "../qcommon/qcommon.h" +#include "win_local.h" +#include "resource.h" +#include <errno.h> +#include <float.h> +#include <fcntl.h> +#include <stdio.h> +#include <direct.h> +#include <io.h> +#include <conio.h> + +#define	CD_BASEDIR	"quake3" +#define	CD_EXE		"quake3.exe" +#define	CD_BASEDIR_LINUX	"bin\\x86\\glibc-2.1" +#define	CD_EXE_LINUX "quake3" +#define MEM_THRESHOLD 96*1024*1024 + +static char		sys_cmdline[MAX_STRING_CHARS]; + +// define this to use alternate spanking method +// I found out that the regular way doesn't work on my box for some reason +// see the associated spank.sh script +#define ALT_SPANK +#ifdef ALT_SPANK +#include <stdio.h> +#include <sys/stat.h> + +int fh = 0; + +void Spk_Open(char *name) +{ +  fh = open( name, O_TRUNC | O_CREAT | O_WRONLY, S_IREAD | S_IWRITE ); +}; + +void Spk_Close(void) +{ +  if (!fh) +    return; + +  close( fh ); +  fh = 0; +} + +void Spk_Printf (const char *text, ...) +{ +  va_list argptr; +  char buf[32768]; + +  if (!fh) +    return; + +  va_start (argptr,text); +  vsprintf (buf, text, argptr); +  write(fh, buf, strlen(buf)); +  _commit(fh); +  va_end (argptr); + +}; +#endif + +/* +================== +Sys_LowPhysicalMemory() +================== +*/ + +qboolean Sys_LowPhysicalMemory() { +	MEMORYSTATUS stat; +  GlobalMemoryStatus (&stat); +	return (stat.dwTotalPhys <= MEM_THRESHOLD) ? qtrue : qfalse; +} + +/* +================== +Sys_BeginProfiling +================== +*/ +void Sys_BeginProfiling( void ) { +	// this is just used on the mac build +} + +/* +============= +Sys_Error + +Show the early console as an error dialog +============= +*/ +void QDECL Sys_Error( const char *error, ... ) { +	va_list		argptr; +	char		text[4096]; +    MSG        msg; + +	va_start (argptr, error); +	vsprintf (text, error, argptr); +	va_end (argptr); + +	Conbuf_AppendText( text ); +	Conbuf_AppendText( "\n" ); + +	Sys_SetErrorText( text ); +	Sys_ShowConsole( 1, qtrue ); + +	timeEndPeriod( 1 ); + +	IN_Shutdown(); + +	// wait for the user to quit +	while ( 1 ) { +		if (!GetMessage (&msg, NULL, 0, 0)) +			Com_Quit_f (); +		TranslateMessage (&msg); +      	DispatchMessage (&msg); +	} + +	Sys_DestroyConsole(); + +	exit (1); +} + +/* +============== +Sys_Quit +============== +*/ +void Sys_Quit( void ) { +	timeEndPeriod( 1 ); +	IN_Shutdown(); +	Sys_DestroyConsole(); + +	exit (0); +} + +/* +============== +Sys_Print +============== +*/ +void Sys_Print( const char *msg ) { +	Conbuf_AppendText( msg ); +} + + +/* +============== +Sys_Mkdir +============== +*/ +void Sys_Mkdir( const char *path ) { +	_mkdir (path); +} + +/* +============== +Sys_Cwd +============== +*/ +char *Sys_Cwd( void ) { +	static char cwd[MAX_OSPATH]; + +	_getcwd( cwd, sizeof( cwd ) - 1 ); +	cwd[MAX_OSPATH-1] = 0; + +	return cwd; +} + +/* +============== +Sys_DefaultCDPath +============== +*/ +char *Sys_DefaultCDPath( void ) { +	return ""; +} + +/* +============== +Sys_DefaultBasePath +============== +*/ +char *Sys_DefaultBasePath( void ) { +	return Sys_Cwd(); +} + +/* +============================================================== + +DIRECTORY SCANNING + +============================================================== +*/ + +#define	MAX_FOUND_FILES	0x1000 + +void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, char **list, int *numfiles ) { +	char		search[MAX_OSPATH], newsubdirs[MAX_OSPATH]; +	char		filename[MAX_OSPATH]; +	int			findhandle; +	struct _finddata_t findinfo; + +	if ( *numfiles >= MAX_FOUND_FILES - 1 ) { +		return; +	} + +	if (strlen(subdirs)) { +		Com_sprintf( search, sizeof(search), "%s\\%s\\*", basedir, subdirs ); +	} +	else { +		Com_sprintf( search, sizeof(search), "%s\\*", basedir ); +	} + +	findhandle = _findfirst (search, &findinfo); +	if (findhandle == -1) { +		return; +	} + +	do { +		if (findinfo.attrib & _A_SUBDIR) { +			if (Q_stricmp(findinfo.name, ".") && Q_stricmp(findinfo.name, "..")) { +				if (strlen(subdirs)) { +					Com_sprintf( newsubdirs, sizeof(newsubdirs), "%s\\%s", subdirs, findinfo.name); +				} +				else { +					Com_sprintf( newsubdirs, sizeof(newsubdirs), "%s", findinfo.name); +				} +				Sys_ListFilteredFiles( basedir, newsubdirs, filter, list, numfiles ); +			} +		} +		if ( *numfiles >= MAX_FOUND_FILES - 1 ) { +			break; +		} +		Com_sprintf( filename, sizeof(filename), "%s\\%s", subdirs, findinfo.name ); +		if (!Com_FilterPath( filter, filename, qfalse )) +			continue; +		list[ *numfiles ] = CopyString( filename ); +		(*numfiles)++; +	} while ( _findnext (findhandle, &findinfo) != -1 ); + +	_findclose (findhandle); +} + +static qboolean strgtr(const char *s0, const char *s1) { +	int l0, l1, i; + +	l0 = strlen(s0); +	l1 = strlen(s1); + +	if (l1<l0) { +		l0 = l1; +	} + +	for(i=0;i<l0;i++) { +		if (s1[i] > s0[i]) { +			return qtrue; +		} +		if (s1[i] < s0[i]) { +			return qfalse; +		} +	} +	return qfalse; +} + +char **Sys_ListFiles( const char *directory, const char *extension, char *filter, int *numfiles, qboolean wantsubs ) { +	char		search[MAX_OSPATH]; +	int			nfiles; +	char		**listCopy; +	char		*list[MAX_FOUND_FILES]; +	struct _finddata_t findinfo; +	int			findhandle; +	int			flag; +	int			i; + +	if (filter) { + +		nfiles = 0; +		Sys_ListFilteredFiles( directory, "", filter, list, &nfiles ); + +		list[ nfiles ] = 0; +		*numfiles = nfiles; + +		if (!nfiles) +			return NULL; + +		listCopy = Z_Malloc( ( nfiles + 1 ) * sizeof( *listCopy ) ); +		for ( i = 0 ; i < nfiles ; i++ ) { +			listCopy[i] = list[i]; +		} +		listCopy[i] = NULL; + +		return listCopy; +	} + +	if ( !extension) { +		extension = ""; +	} + +	// passing a slash as extension will find directories +	if ( extension[0] == '/' && extension[1] == 0 ) { +		extension = ""; +		flag = 0; +	} else { +		flag = _A_SUBDIR; +	} + +	Com_sprintf( search, sizeof(search), "%s\\*%s", directory, extension ); + +	// search +	nfiles = 0; + +	findhandle = _findfirst (search, &findinfo); +	if (findhandle == -1) { +		*numfiles = 0; +		return NULL; +	} + +	do { +		if ( (!wantsubs && flag ^ ( findinfo.attrib & _A_SUBDIR )) || (wantsubs && findinfo.attrib & _A_SUBDIR) ) { +			if ( nfiles == MAX_FOUND_FILES - 1 ) { +				break; +			} +			list[ nfiles ] = CopyString( findinfo.name ); +			nfiles++; +		} +	} while ( _findnext (findhandle, &findinfo) != -1 ); + +	list[ nfiles ] = 0; + +	_findclose (findhandle); + +	// return a copy of the list +	*numfiles = nfiles; + +	if ( !nfiles ) { +		return NULL; +	} + +	listCopy = Z_Malloc( ( nfiles + 1 ) * sizeof( *listCopy ) ); +	for ( i = 0 ; i < nfiles ; i++ ) { +		listCopy[i] = list[i]; +	} +	listCopy[i] = NULL; + +	do { +		flag = 0; +		for(i=1; i<nfiles; i++) { +			if (strgtr(listCopy[i-1], listCopy[i])) { +				char *temp = listCopy[i]; +				listCopy[i] = listCopy[i-1]; +				listCopy[i-1] = temp; +				flag = 1; +			} +		} +	} while(flag); + +	return listCopy; +} + +void	Sys_FreeFileList( char **list ) { +	int		i; + +	if ( !list ) { +		return; +	} + +	for ( i = 0 ; list[i] ; i++ ) { +		Z_Free( list[i] ); +	} + +	Z_Free( list ); +} + +//======================================================== + + +/* +================ +Sys_ScanForCD + +Search all the drives to see if there is a valid CD to grab +the cddir from +================ +*/ +qboolean Sys_ScanForCD( void ) { +	static char	cddir[MAX_OSPATH]; +	char		drive[4]; +	FILE		*f; +	char		test[MAX_OSPATH]; +#if 0 +	// don't override a cdpath on the command line +	if ( strstr( sys_cmdline, "cdpath" ) ) { +		return; +	} +#endif + +	drive[0] = 'c'; +	drive[1] = ':'; +	drive[2] = '\\'; +	drive[3] = 0; + +	// scan the drives +	for ( drive[0] = 'c' ; drive[0] <= 'z' ; drive[0]++ ) { +		if ( GetDriveType (drive) != DRIVE_CDROM ) { +			continue; +		} + +		sprintf (cddir, "%s%s", drive, CD_BASEDIR); +		sprintf (test, "%s\\%s", cddir, CD_EXE); +		f = fopen( test, "r" ); +		if ( f ) { +			fclose (f); +			return qtrue; +    } else { +      sprintf(cddir, "%s%s", drive, CD_BASEDIR_LINUX); +      sprintf(test, "%s\\%s", cddir, CD_EXE_LINUX); +  		f = fopen( test, "r" ); +	  	if ( f ) { +		  	fclose (f); +			  return qtrue; +      } +    } +	} + +	return qfalse; +} + +/* +================ +Sys_CheckCD + +Return true if the proper CD is in the drive +================ +*/ +qboolean	Sys_CheckCD( void ) { +  // FIXME: mission pack +  return qtrue; +	//return Sys_ScanForCD(); +} + + +/* +================ +Sys_GetClipboardData + +================ +*/ +char *Sys_GetClipboardData( void ) { +	char *data = NULL; +	char *cliptext; + +	if ( OpenClipboard( NULL ) != 0 ) { +		HANDLE hClipboardData; + +		if ( ( hClipboardData = GetClipboardData( CF_TEXT ) ) != 0 ) { +			if ( ( cliptext = GlobalLock( hClipboardData ) ) != 0 ) { +				data = Z_Malloc( GlobalSize( hClipboardData ) + 1 ); +				Q_strncpyz( data, cliptext, GlobalSize( hClipboardData ) ); +				GlobalUnlock( hClipboardData ); +				 +				strtok( data, "\n\r\b" ); +			} +		} +		CloseClipboard(); +	} +	return data; +} + + +/* +======================================================================== + +LOAD/UNLOAD DLL + +======================================================================== +*/ + +/* +================= +Sys_UnloadDll + +================= +*/ +void Sys_UnloadDll( void *dllHandle ) { +	if ( !dllHandle ) { +		return; +	} +	if ( !FreeLibrary( dllHandle ) ) { +		Com_Error (ERR_FATAL, "Sys_UnloadDll FreeLibrary failed"); +	} +} + +/* +================= +Sys_LoadDll + +Used to load a development dll instead of a virtual machine + +TTimo: added some verbosity in debug +================= +*/ +extern char		*FS_BuildOSPath( const char *base, const char *game, const char *qpath ); + +// fqpath param added 7/20/02 by T.Ray - Sys_LoadDll is only called in vm.c at this time +// fqpath will be empty if dll not loaded, otherwise will hold fully qualified path of dll module loaded +// fqpath buffersize must be at least MAX_QPATH+1 bytes long +void * QDECL Sys_LoadDll( const char *name, char *fqpath , intptr_t (QDECL **entryPoint)(intptr_t, ...), +				  intptr_t (QDECL *systemcalls)(intptr_t, ...) ) { +	HINSTANCE	libHandle; +	void	(QDECL *dllEntry)( intptr_t (QDECL *syscallptr)(intptr_t, ...) ); +	char	*basepath; +	char	*cdpath; +	char	*gamedir; +	char	*fn; +#ifdef NDEBUG +	static int	lastWarning = 0; +	int		timestamp; +  int   ret; +#endif +	char	filename[MAX_QPATH]; + +	*fqpath = 0 ;		// added 7/20/02 by T.Ray + +	Com_sprintf( filename, sizeof( filename ), "%sx86.dll", name ); + +#ifdef NDEBUG +	timestamp = Sys_Milliseconds(); +	if( ((timestamp - lastWarning) > (5 * 60000)) && !Cvar_VariableIntegerValue( "dedicated" ) +		&& !Cvar_VariableIntegerValue( "com_blindlyLoadDLLs" ) ) { +		if (FS_FileExists(filename)) { +			lastWarning = timestamp; +			ret = MessageBoxEx( NULL, "You are about to load a .DLL executable that\n" +				  "has not been verified for use with Tremulous.\n" +				  "This type of file can compromise the security of\n" +				  "your computer.\n\n" +				  "Select 'OK' if you choose to load it anyway.", +				  "Security Warning", MB_OKCANCEL | MB_ICONEXCLAMATION | MB_DEFBUTTON2 | MB_TOPMOST | MB_SETFOREGROUND, +				  MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ) ); +			if( ret != IDOK ) { +				return NULL; +			} +		} +	} +#endif + +#ifndef NDEBUG +	libHandle = LoadLibrary( filename ); +  if (libHandle) +    Com_Printf("LoadLibrary '%s' ok\n", filename); +  else +    Com_Printf("LoadLibrary '%s' failed\n", filename); +	if ( !libHandle ) { +#endif +	basepath = Cvar_VariableString( "fs_basepath" ); +	cdpath = Cvar_VariableString( "fs_cdpath" ); +	gamedir = Cvar_VariableString( "fs_game" ); + +	fn = FS_BuildOSPath( basepath, gamedir, filename ); +	libHandle = LoadLibrary( fn ); +#ifndef NDEBUG +  if (libHandle) +    Com_Printf("LoadLibrary '%s' ok\n", fn); +  else +    Com_Printf("LoadLibrary '%s' failed\n", fn); +#endif + +	if ( !libHandle ) { +		if( cdpath[0] ) { +			fn = FS_BuildOSPath( cdpath, gamedir, filename ); +			libHandle = LoadLibrary( fn ); +#ifndef NDEBUG +      if (libHandle) +        Com_Printf("LoadLibrary '%s' ok\n", fn); +      else +        Com_Printf("LoadLibrary '%s' failed\n", fn); +#endif +		} + +		if ( !libHandle ) { +			return NULL; +		} +	} +#ifndef NDEBUG +	} +#endif + +	dllEntry = ( void (QDECL *)(intptr_t (QDECL *)( intptr_t, ... ) ) )GetProcAddress( libHandle, "dllEntry" );  +	*entryPoint = (intptr_t (QDECL *)(intptr_t,...))GetProcAddress( libHandle, "vmMain" ); +	if ( !*entryPoint || !dllEntry ) { +		FreeLibrary( libHandle ); +		return NULL; +	} +	dllEntry( systemcalls ); + +	if ( libHandle ) Q_strncpyz ( fqpath , filename , MAX_QPATH ) ;		// added 7/20/02 by T.Ray +	return libHandle; +} + + +/* +======================================================================== + +BACKGROUND FILE STREAMING + +======================================================================== +*/ + +#if 1 + +void Sys_InitStreamThread( void ) { +} + +void Sys_ShutdownStreamThread( void ) { +} + +void Sys_BeginStreamedFile( fileHandle_t f, int readAhead ) { +} + +void Sys_EndStreamedFile( fileHandle_t f ) { +} + +int Sys_StreamedRead( void *buffer, int size, int count, fileHandle_t f ) { +   return FS_Read( buffer, size * count, f ); +} + +void Sys_StreamSeek( fileHandle_t f, int offset, int origin ) { +   FS_Seek( f, offset, origin ); +} + + +#else + +typedef struct { +	fileHandle_t	file; +	byte	*buffer; +	qboolean	eof; +	qboolean	active; +	int		bufferSize; +	int		streamPosition;	// next byte to be returned by Sys_StreamRead +	int		threadPosition;	// next byte to be read from file +} streamsIO_t; + +typedef struct { +	HANDLE				threadHandle; +	int					threadId; +	CRITICAL_SECTION	crit; +	streamsIO_t			sIO[MAX_FILE_HANDLES]; +} streamState_t; + +streamState_t	stream; + +/* +=============== +Sys_StreamThread + +A thread will be sitting in this loop forever +================ +*/ +void Sys_StreamThread( void ) { +	int		buffer; +	int		count; +	int		readCount; +	int		bufferPoint; +	int		r, i; + +	while (1) { +		Sleep( 10 ); +//		EnterCriticalSection (&stream.crit); + +		for (i=1;i<MAX_FILE_HANDLES;i++) { +			// if there is any space left in the buffer, fill it up +			if ( stream.sIO[i].active  && !stream.sIO[i].eof ) { +				count = stream.sIO[i].bufferSize - (stream.sIO[i].threadPosition - stream.sIO[i].streamPosition); +				if ( !count ) { +					continue; +				} + +				bufferPoint = stream.sIO[i].threadPosition % stream.sIO[i].bufferSize; +				buffer = stream.sIO[i].bufferSize - bufferPoint; +				readCount = buffer < count ? buffer : count; + +				r = FS_Read( stream.sIO[i].buffer + bufferPoint, readCount, stream.sIO[i].file ); +				stream.sIO[i].threadPosition += r; + +				if ( r != readCount ) { +					stream.sIO[i].eof = qtrue; +				} +			} +		} +//		LeaveCriticalSection (&stream.crit); +	} +} + +/* +=============== +Sys_InitStreamThread + +================ +*/ +void Sys_InitStreamThread( void ) { +	int i; + +	InitializeCriticalSection ( &stream.crit ); + +	// don't leave the critical section until there is a +	// valid file to stream, which will cause the StreamThread +	// to sleep without any overhead +//	EnterCriticalSection( &stream.crit ); + +	stream.threadHandle = CreateThread( +	   NULL,	// LPSECURITY_ATTRIBUTES lpsa, +	   0,		// DWORD cbStack, +	   (LPTHREAD_START_ROUTINE)Sys_StreamThread,	// LPTHREAD_START_ROUTINE lpStartAddr, +	   0,			// LPVOID lpvThreadParm, +	   0,			//   DWORD fdwCreate, +	   &stream.threadId); +	for(i=0;i<MAX_FILE_HANDLES;i++) { +		stream.sIO[i].active = qfalse; +	} +} + +/* +=============== +Sys_ShutdownStreamThread + +================ +*/ +void Sys_ShutdownStreamThread( void ) { +} + + +/* +=============== +Sys_BeginStreamedFile + +================ +*/ +void Sys_BeginStreamedFile( fileHandle_t f, int readAhead ) { +	if ( stream.sIO[f].file ) { +		Sys_EndStreamedFile( stream.sIO[f].file ); +	} + +	stream.sIO[f].file = f; +	stream.sIO[f].buffer = Z_Malloc( readAhead ); +	stream.sIO[f].bufferSize = readAhead; +	stream.sIO[f].streamPosition = 0; +	stream.sIO[f].threadPosition = 0; +	stream.sIO[f].eof = qfalse; +	stream.sIO[f].active = qtrue; + +	// let the thread start running +//	LeaveCriticalSection( &stream.crit ); +} + +/* +=============== +Sys_EndStreamedFile + +================ +*/ +void Sys_EndStreamedFile( fileHandle_t f ) { +	if ( f != stream.sIO[f].file ) { +		Com_Error( ERR_FATAL, "Sys_EndStreamedFile: wrong file"); +	} +	// don't leave critical section until another stream is started +	EnterCriticalSection( &stream.crit ); + +	stream.sIO[f].file = 0; +	stream.sIO[f].active = qfalse; + +	Z_Free( stream.sIO[f].buffer ); + +	LeaveCriticalSection( &stream.crit ); +} + + +/* +=============== +Sys_StreamedRead + +================ +*/ +int Sys_StreamedRead( void *buffer, int size, int count, fileHandle_t f ) { +	int		available; +	int		remaining; +	int		sleepCount; +	int		copy; +	int		bufferCount; +	int		bufferPoint; +	byte	*dest; + +	if (stream.sIO[f].active == qfalse) { +		Com_Error( ERR_FATAL, "Streamed read with non-streaming file" ); +	} + +	dest = (byte *)buffer; +	remaining = size * count; + +	if ( remaining <= 0 ) { +		Com_Error( ERR_FATAL, "Streamed read with non-positive size" ); +	} + +	sleepCount = 0; +	while ( remaining > 0 ) { +		available = stream.sIO[f].threadPosition - stream.sIO[f].streamPosition; +		if ( !available ) { +			if ( stream.sIO[f].eof ) { +				break; +			} +			if ( sleepCount == 1 ) { +				Com_DPrintf( "Sys_StreamedRead: waiting\n" ); +			} +			if ( ++sleepCount > 100 ) { +				Com_Error( ERR_FATAL, "Sys_StreamedRead: thread has died"); +			} +			Sleep( 10 ); +			continue; +		} + +		EnterCriticalSection( &stream.crit ); + +		bufferPoint = stream.sIO[f].streamPosition % stream.sIO[f].bufferSize; +		bufferCount = stream.sIO[f].bufferSize - bufferPoint; + +		copy = available < bufferCount ? available : bufferCount; +		if ( copy > remaining ) { +			copy = remaining; +		} +		memcpy( dest, stream.sIO[f].buffer + bufferPoint, copy ); +		stream.sIO[f].streamPosition += copy; +		dest += copy; +		remaining -= copy; + +		LeaveCriticalSection( &stream.crit ); +	} + +	return (count * size - remaining) / size; +} + +/* +=============== +Sys_StreamSeek + +================ +*/ +void Sys_StreamSeek( fileHandle_t f, int offset, int origin ) { + +	// halt the thread +	EnterCriticalSection( &stream.crit ); + +	// clear to that point +	FS_Seek( f, offset, origin ); +	stream.sIO[f].streamPosition = 0; +	stream.sIO[f].threadPosition = 0; +	stream.sIO[f].eof = qfalse; + +	// let the thread start running at the new position +	LeaveCriticalSection( &stream.crit ); +} + +#endif + +/* +======================================================================== + +EVENT LOOP + +======================================================================== +*/ + +#define	MAX_QUED_EVENTS		256 +#define	MASK_QUED_EVENTS	( MAX_QUED_EVENTS - 1 ) + +sysEvent_t	eventQue[MAX_QUED_EVENTS]; +int			eventHead, eventTail; +byte		sys_packetReceived[MAX_MSGLEN]; + +/* +================ +Sys_QueEvent + +A time of 0 will get the current time +Ptr should either be null, or point to a block of data that can +be freed by the game later. +================ +*/ +void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr ) { +	sysEvent_t	*ev; + +	ev = &eventQue[ eventHead & MASK_QUED_EVENTS ]; +	if ( eventHead - eventTail >= MAX_QUED_EVENTS ) { +		Com_Printf("Sys_QueEvent: overflow\n"); +		// we are discarding an event, but don't leak memory +		if ( ev->evPtr ) { +			Z_Free( ev->evPtr ); +		} +		eventTail++; +	} + +	eventHead++; + +	if ( time == 0 ) { +		time = Sys_Milliseconds(); +	} + +	ev->evTime = time; +	ev->evType = type; +	ev->evValue = value; +	ev->evValue2 = value2; +	ev->evPtrLength = ptrLength; +	ev->evPtr = ptr; +} + +/* +================ +Sys_GetEvent + +================ +*/ +sysEvent_t Sys_GetEvent( void ) { +    MSG			msg; +	sysEvent_t	ev; +	char		*s; +	msg_t		netmsg; +	netadr_t	adr; + +	// return if we have data +	if ( eventHead > eventTail ) { +		eventTail++; +		return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ]; +	} + +	// pump the message loop +	while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) { +		if ( !GetMessage (&msg, NULL, 0, 0) ) { +			Com_Quit_f(); +		} + +		// save the msg time, because wndprocs don't have access to the timestamp +		g_wv.sysMsgTime = msg.time; + +		TranslateMessage (&msg); +      	DispatchMessage (&msg); +	} + +	// check for console commands +	s = Sys_ConsoleInput(); +	if ( s ) { +		char	*b; +		int		len; + +		len = strlen( s ) + 1; +		b = Z_Malloc( len ); +		Q_strncpyz( b, s, len-1 ); +		Sys_QueEvent( 0, SE_CONSOLE, 0, 0, len, b ); +	} + +	// check for network packets +	MSG_Init( &netmsg, sys_packetReceived, sizeof( sys_packetReceived ) ); +	if ( Sys_GetPacket ( &adr, &netmsg ) ) { +		netadr_t		*buf; +		int				len; + +		// copy out to a seperate buffer for qeueing +		// the readcount stepahead is for SOCKS support +		len = sizeof( netadr_t ) + netmsg.cursize - netmsg.readcount; +		buf = Z_Malloc( len ); +		*buf = adr; +		memcpy( buf+1, &netmsg.data[netmsg.readcount], netmsg.cursize - netmsg.readcount ); +		Sys_QueEvent( 0, SE_PACKET, 0, 0, len, buf ); +	} + +	// return if we have data +	if ( eventHead > eventTail ) { +		eventTail++; +		return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ]; +	} + +	// create an empty event to return + +	memset( &ev, 0, sizeof( ev ) ); +	ev.evTime = timeGetTime(); + +	return ev; +} + +//================================================================ + +/* +================= +Sys_In_Restart_f + +Restart the input subsystem +================= +*/ +void Sys_In_Restart_f( void ) { +	IN_Shutdown(); +	IN_Init(); +} + + +/* +================= +Sys_Net_Restart_f + +Restart the network subsystem +================= +*/ +void Sys_Net_Restart_f( void ) { +	NET_Restart(); +} + + +/* +================ +Sys_Init + +Called after the common systems (cvars, files, etc) +are initialized +================ +*/ +#define OSR2_BUILD_NUMBER 1111 +#define WIN98_BUILD_NUMBER 1998 + +void Sys_Init( void ) { +	int cpuid; + +	// make sure the timer is high precision, otherwise +	// NT gets 18ms resolution +	timeBeginPeriod( 1 ); + +	Cmd_AddCommand ("in_restart", Sys_In_Restart_f); +	Cmd_AddCommand ("net_restart", Sys_Net_Restart_f); + +	g_wv.osversion.dwOSVersionInfoSize = sizeof( g_wv.osversion ); + +	if (!GetVersionEx (&g_wv.osversion)) +		Sys_Error ("Couldn't get OS info"); + +	if (g_wv.osversion.dwMajorVersion < 4) +		Sys_Error ("Tremulous requires Windows version 4 or greater"); +	if (g_wv.osversion.dwPlatformId == VER_PLATFORM_WIN32s) +		Sys_Error ("Tremulous doesn't run on Win32s"); + +	if ( g_wv.osversion.dwPlatformId == VER_PLATFORM_WIN32_NT ) +	{ +		Cvar_Set( "arch", "winnt" ); +	} +	else if ( g_wv.osversion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ) +	{ +		if ( LOWORD( g_wv.osversion.dwBuildNumber ) >= WIN98_BUILD_NUMBER ) +		{ +			Cvar_Set( "arch", "win98" ); +		} +		else if ( LOWORD( g_wv.osversion.dwBuildNumber ) >= OSR2_BUILD_NUMBER ) +		{ +			Cvar_Set( "arch", "win95 osr2.x" ); +		} +		else +		{ +			Cvar_Set( "arch", "win95" ); +		} +	} +	else +	{ +		Cvar_Set( "arch", "unknown Windows variant" ); +	} + +	// save out a couple things in rom cvars for the renderer to access +	Cvar_Get( "win_hinstance", va("%i", (int)g_wv.hInstance), CVAR_ROM ); +	Cvar_Get( "win_wndproc", va("%i", (int)MainWndProc), CVAR_ROM ); + +	// +	// figure out our CPU +	// +	Cvar_Get( "sys_cpustring", "detect", 0 ); +	if ( !Q_stricmp( Cvar_VariableString( "sys_cpustring"), "detect" ) ) +	{ +		Com_Printf( "...detecting CPU, found " ); + +#ifndef __MINGW32__ +		cpuid = Sys_GetProcessorId(); +#else // See comments in win_shared.c +		cpuid = CPUID_GENERIC; +#endif + +		switch ( cpuid ) +		{ +		case CPUID_GENERIC: +			Cvar_Set( "sys_cpustring", "generic" ); +			break; +		case CPUID_INTEL_UNSUPPORTED: +			Cvar_Set( "sys_cpustring", "x86 (pre-Pentium)" ); +			break; +		case CPUID_INTEL_PENTIUM: +			Cvar_Set( "sys_cpustring", "x86 (P5/PPro, non-MMX)" ); +			break; +		case CPUID_INTEL_MMX: +			Cvar_Set( "sys_cpustring", "x86 (P5/Pentium2, MMX)" ); +			break; +		case CPUID_INTEL_KATMAI: +			Cvar_Set( "sys_cpustring", "Intel Pentium III" ); +			break; +		case CPUID_AMD_3DNOW: +			Cvar_Set( "sys_cpustring", "AMD w/ 3DNow!" ); +			break; +		case CPUID_AXP: +			Cvar_Set( "sys_cpustring", "Alpha AXP" ); +			break; +		default: +			Com_Error( ERR_FATAL, "Unknown cpu type %d\n", cpuid ); +			break; +		} +	} +	else +	{ +		Com_Printf( "...forcing CPU type to " ); +		if ( !Q_stricmp( Cvar_VariableString( "sys_cpustring" ), "generic" ) ) +		{ +			cpuid = CPUID_GENERIC; +		} +		else if ( !Q_stricmp( Cvar_VariableString( "sys_cpustring" ), "x87" ) ) +		{ +			cpuid = CPUID_INTEL_PENTIUM; +		} +		else if ( !Q_stricmp( Cvar_VariableString( "sys_cpustring" ), "mmx" ) ) +		{ +			cpuid = CPUID_INTEL_MMX; +		} +		else if ( !Q_stricmp( Cvar_VariableString( "sys_cpustring" ), "3dnow" ) ) +		{ +			cpuid = CPUID_AMD_3DNOW; +		} +		else if ( !Q_stricmp( Cvar_VariableString( "sys_cpustring" ), "PentiumIII" ) ) +		{ +			cpuid = CPUID_INTEL_KATMAI; +		} +		else if ( !Q_stricmp( Cvar_VariableString( "sys_cpustring" ), "axp" ) ) +		{ +			cpuid = CPUID_AXP; +		} +		else +		{ +			Com_Printf( "WARNING: unknown sys_cpustring '%s'\n", Cvar_VariableString( "sys_cpustring" ) ); +			cpuid = CPUID_GENERIC; +		} +	} +	Cvar_SetValue( "sys_cpuid", cpuid ); +	Com_Printf( "%s\n", Cvar_VariableString( "sys_cpustring" ) ); + +	Cvar_Set( "username", Sys_GetCurrentUser() ); + +	IN_Init();		// FIXME: not in dedicated? +} + + +qboolean Sys_DetectAltivec( void ) +{ +    return qfalse;  // never altivec on Windows...at least for now.  :) +} + + + +//======================================================================= + +int	totalMsec, countMsec; + +/* +================== +WinMain + +================== +*/ +int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { +	char		cwd[MAX_OSPATH]; +	int			startTime, endTime; + +    // should never get a previous instance in Win32 +    if ( hPrevInstance ) { +        return 0; +	} + +	g_wv.hInstance = hInstance; +	Q_strncpyz( sys_cmdline, lpCmdLine, sizeof( sys_cmdline ) ); + +	// done before Com/Sys_Init since we need this for error output +	Sys_CreateConsole(); + +	// no abort/retry/fail errors +	SetErrorMode( SEM_FAILCRITICALERRORS ); + +	// get the initial time base +	Sys_Milliseconds(); +#if 0 +	// if we find the CD, add a +set cddir xxx command line +	Sys_ScanForCD(); +#endif + +	Sys_InitStreamThread(); + +	Com_Init( sys_cmdline ); +	NET_Init(); + +	_getcwd (cwd, sizeof(cwd)); +	Com_Printf("Working directory: %s\n", cwd); + +	// hide the early console since we've reached the point where we +	// have a working graphics subsystems +	if ( !com_dedicated->integer && !com_viewlog->integer ) { +		Sys_ShowConsole( 0, qfalse ); +	} + +    // main game loop +	while( 1 ) { +		// if not running as a game client, sleep a bit +		if ( g_wv.isMinimized || ( com_dedicated && com_dedicated->integer ) ) { +			Sleep( 5 ); +		} + +		// set low precision every frame, because some system calls +		// reset it arbitrarily +//		_controlfp( _PC_24, _MCW_PC ); +//    _controlfp( -1, _MCW_EM  ); // no exceptions, even if some crappy +                                // syscall turns them back on! + +		startTime = Sys_Milliseconds(); + +		// make sure mouse and joystick are only called once a frame +		IN_Frame(); + +		// run the game +		Com_Frame(); + +		endTime = Sys_Milliseconds(); +		totalMsec += endTime - startTime; +		countMsec++; +	} + +	// never gets here +} + + diff --git a/src/win32/win_net.c b/src/win32/win_net.c new file mode 100644 index 0000000..3f430fc --- /dev/null +++ b/src/win32/win_net.c @@ -0,0 +1,1032 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2006 Tim Angus + +This file is part of Tremulous. + +Tremulous 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. + +Tremulous is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Tremulous; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA +=========================================================================== +*/ +// net_wins.c + +#include "../qcommon/q_shared.h" +#include "../qcommon/qcommon.h" +#include "win_local.h" + +static WSADATA	winsockdata; +static qboolean	winsockInitialized = qfalse; +static qboolean usingSocks = qfalse; +static qboolean networkingEnabled = qfalse; + +static cvar_t	*net_noudp; +static cvar_t	*net_noipx; + +static cvar_t	*net_socksEnabled; +static cvar_t	*net_socksServer; +static cvar_t	*net_socksPort; +static cvar_t	*net_socksUsername; +static cvar_t	*net_socksPassword; +static struct sockaddr	socksRelayAddr; + +static SOCKET	ip_socket; +static SOCKET	socks_socket; +static SOCKET	ipx_socket; + +#define	MAX_IPS		16 +static	int		numIP; +static	byte	localIP[MAX_IPS][4]; + +//============================================================================= + + +/* +==================== +NET_ErrorString +==================== +*/ +char *NET_ErrorString( void ) { +	int		code; + +	code = WSAGetLastError(); +	switch( code ) { +	case WSAEINTR: return "WSAEINTR"; +	case WSAEBADF: return "WSAEBADF"; +	case WSAEACCES: return "WSAEACCES"; +	case WSAEDISCON: return "WSAEDISCON"; +	case WSAEFAULT: return "WSAEFAULT"; +	case WSAEINVAL: return "WSAEINVAL"; +	case WSAEMFILE: return "WSAEMFILE"; +	case WSAEWOULDBLOCK: return "WSAEWOULDBLOCK"; +	case WSAEINPROGRESS: return "WSAEINPROGRESS"; +	case WSAEALREADY: return "WSAEALREADY"; +	case WSAENOTSOCK: return "WSAENOTSOCK"; +	case WSAEDESTADDRREQ: return "WSAEDESTADDRREQ"; +	case WSAEMSGSIZE: return "WSAEMSGSIZE"; +	case WSAEPROTOTYPE: return "WSAEPROTOTYPE"; +	case WSAENOPROTOOPT: return "WSAENOPROTOOPT"; +	case WSAEPROTONOSUPPORT: return "WSAEPROTONOSUPPORT"; +	case WSAESOCKTNOSUPPORT: return "WSAESOCKTNOSUPPORT"; +	case WSAEOPNOTSUPP: return "WSAEOPNOTSUPP"; +	case WSAEPFNOSUPPORT: return "WSAEPFNOSUPPORT"; +	case WSAEAFNOSUPPORT: return "WSAEAFNOSUPPORT"; +	case WSAEADDRINUSE: return "WSAEADDRINUSE"; +	case WSAEADDRNOTAVAIL: return "WSAEADDRNOTAVAIL"; +	case WSAENETDOWN: return "WSAENETDOWN"; +	case WSAENETUNREACH: return "WSAENETUNREACH"; +	case WSAENETRESET: return "WSAENETRESET"; +	case WSAECONNABORTED: return "WSWSAECONNABORTEDAEINTR"; +	case WSAECONNRESET: return "WSAECONNRESET"; +	case WSAENOBUFS: return "WSAENOBUFS"; +	case WSAEISCONN: return "WSAEISCONN"; +	case WSAENOTCONN: return "WSAENOTCONN"; +	case WSAESHUTDOWN: return "WSAESHUTDOWN"; +	case WSAETOOMANYREFS: return "WSAETOOMANYREFS"; +	case WSAETIMEDOUT: return "WSAETIMEDOUT"; +	case WSAECONNREFUSED: return "WSAECONNREFUSED"; +	case WSAELOOP: return "WSAELOOP"; +	case WSAENAMETOOLONG: return "WSAENAMETOOLONG"; +	case WSAEHOSTDOWN: return "WSAEHOSTDOWN"; +	case WSASYSNOTREADY: return "WSASYSNOTREADY"; +	case WSAVERNOTSUPPORTED: return "WSAVERNOTSUPPORTED"; +	case WSANOTINITIALISED: return "WSANOTINITIALISED"; +	case WSAHOST_NOT_FOUND: return "WSAHOST_NOT_FOUND"; +	case WSATRY_AGAIN: return "WSATRY_AGAIN"; +	case WSANO_RECOVERY: return "WSANO_RECOVERY"; +	case WSANO_DATA: return "WSANO_DATA"; +	default: return "NO ERROR"; +	} +} + +void NetadrToSockadr( netadr_t *a, struct sockaddr *s ) { +	memset( s, 0, sizeof(*s) ); + +	if( a->type == NA_BROADCAST ) { +		((struct sockaddr_in *)s)->sin_family = AF_INET; +		((struct sockaddr_in *)s)->sin_port = a->port; +		((struct sockaddr_in *)s)->sin_addr.s_addr = INADDR_BROADCAST; +	} +	else if( a->type == NA_IP ) { +		((struct sockaddr_in *)s)->sin_family = AF_INET; +		((struct sockaddr_in *)s)->sin_addr.s_addr = *(int *)&a->ip; +		((struct sockaddr_in *)s)->sin_port = a->port; +	} +	else if( a->type == NA_IPX ) { +		((struct sockaddr_ipx *)s)->sa_family = AF_IPX; +		memcpy( ((struct sockaddr_ipx *)s)->sa_netnum, &a->ipx[0], 4 ); +		memcpy( ((struct sockaddr_ipx *)s)->sa_nodenum, &a->ipx[4], 6 ); +		((struct sockaddr_ipx *)s)->sa_socket = a->port; +	} +	else if( a->type == NA_BROADCAST_IPX ) { +		((struct sockaddr_ipx *)s)->sa_family = AF_IPX; +		memset( ((struct sockaddr_ipx *)s)->sa_netnum, 0, 4 ); +		memset( ((struct sockaddr_ipx *)s)->sa_nodenum, 0xff, 6 ); +		((struct sockaddr_ipx *)s)->sa_socket = a->port; +	} +} + + +void SockadrToNetadr( struct sockaddr *s, netadr_t *a ) { +	if (s->sa_family == AF_INET) { +		a->type = NA_IP; +		*(int *)&a->ip = ((struct sockaddr_in *)s)->sin_addr.s_addr; +		a->port = ((struct sockaddr_in *)s)->sin_port; +	} +	else if( s->sa_family == AF_IPX ) { +		a->type = NA_IPX; +		memcpy( &a->ipx[0], ((struct sockaddr_ipx *)s)->sa_netnum, 4 ); +		memcpy( &a->ipx[4], ((struct sockaddr_ipx *)s)->sa_nodenum, 6 ); +		a->port = ((struct sockaddr_ipx *)s)->sa_socket; +	} +} + + +/* +============= +Sys_StringToAdr + +idnewt +192.246.40.70 +12121212.121212121212 +============= +*/ +#define DO(src,dest)	\ +	copy[0] = s[src];	\ +	copy[1] = s[src + 1];	\ +	sscanf (copy, "%x", &val);	\ +	((struct sockaddr_ipx *)sadr)->dest = val + +qboolean Sys_StringToSockaddr( const char *s, struct sockaddr *sadr ) { +	struct hostent	*h; +	int		val; +	char	copy[MAX_STRING_CHARS]; +	 +	memset( sadr, 0, sizeof( *sadr ) ); + +	// check for an IPX address +	if( ( strlen( s ) == 21 ) && ( s[8] == '.' ) ) { +		((struct sockaddr_ipx *)sadr)->sa_family = AF_IPX; +		((struct sockaddr_ipx *)sadr)->sa_socket = 0; +		copy[2] = 0; +		DO(0, sa_netnum[0]); +		DO(2, sa_netnum[1]); +		DO(4, sa_netnum[2]); +		DO(6, sa_netnum[3]); +		DO(9, sa_nodenum[0]); +		DO(11, sa_nodenum[1]); +		DO(13, sa_nodenum[2]); +		DO(15, sa_nodenum[3]); +		DO(17, sa_nodenum[4]); +		DO(19, sa_nodenum[5]); +	} +	else { +		((struct sockaddr_in *)sadr)->sin_family = AF_INET; +		((struct sockaddr_in *)sadr)->sin_port = 0; + +		if( s[0] >= '0' && s[0] <= '9' ) { +			*(int *)&((struct sockaddr_in *)sadr)->sin_addr = inet_addr(s); +		} else { +			if( ( h = gethostbyname( s ) ) == 0 ) { +				return 0; +			} +			*(int *)&((struct sockaddr_in *)sadr)->sin_addr = *(int *)h->h_addr_list[0]; +		} +	} +	 +	return qtrue; +} + +#undef DO + +/* +============= +Sys_StringToAdr + +idnewt +192.246.40.70 +============= +*/ +qboolean Sys_StringToAdr( const char *s, netadr_t *a ) { +	struct sockaddr sadr; +	 +	if ( !Sys_StringToSockaddr( s, &sadr ) ) { +		return qfalse; +	} +	 +	SockadrToNetadr( &sadr, a ); +	return qtrue; +} + +//============================================================================= + +/* +================== +Sys_GetPacket + +Never called by the game logic, just the system event queing +================== +*/ +int	recvfromCount; + +qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ) { +	int 	ret; +	struct sockaddr from; +	int		fromlen; +	int		net_socket; +	int		protocol; +	int		err; + +	for( protocol = 0 ; protocol < 2 ; protocol++ )	{ +		if( protocol == 0 ) { +			net_socket = ip_socket; +		} +		else { +			net_socket = ipx_socket; +		} + +		if( !net_socket ) { +			continue; +		} + +		fromlen = sizeof(from); +		recvfromCount++;		// performance check +		ret = recvfrom( net_socket, net_message->data, net_message->maxsize, 0, (struct sockaddr *)&from, &fromlen ); +		if (ret == SOCKET_ERROR) +		{ +			err = WSAGetLastError(); + +			if( err == WSAEWOULDBLOCK || err == WSAECONNRESET ) { +				continue; +			} +			Com_Printf( "NET_GetPacket: %s\n", NET_ErrorString() ); +			continue; +		} + +		if ( net_socket == ip_socket ) { +			memset( ((struct sockaddr_in *)&from)->sin_zero, 0, 8 ); +		} + +		if ( usingSocks && net_socket == ip_socket && memcmp( &from, &socksRelayAddr, fromlen ) == 0 ) { +			if ( ret < 10 || net_message->data[0] != 0 || net_message->data[1] != 0 || net_message->data[2] != 0 || net_message->data[3] != 1 ) { +				continue; +			} +			net_from->type = NA_IP; +			net_from->ip[0] = net_message->data[4]; +			net_from->ip[1] = net_message->data[5]; +			net_from->ip[2] = net_message->data[6]; +			net_from->ip[3] = net_message->data[7]; +			net_from->port = *(short *)&net_message->data[8]; +			net_message->readcount = 10; +		} +		else { +			SockadrToNetadr( &from, net_from ); +			net_message->readcount = 0; +		} + +		if( ret == net_message->maxsize ) { +			Com_Printf( "Oversize packet from %s\n", NET_AdrToString (*net_from) ); +			continue; +		} + +		net_message->cursize = ret; +		return qtrue; +	} + +	return qfalse; +} + +//============================================================================= + +static char socksBuf[4096]; + +/* +================== +Sys_SendPacket +================== +*/ +void Sys_SendPacket( int length, const void *data, netadr_t to ) { +	int				ret; +	struct sockaddr	addr; +	SOCKET			net_socket; + +	if( to.type == NA_BROADCAST ) { +		net_socket = ip_socket; +	} +	else if( to.type == NA_IP ) { +		net_socket = ip_socket; +	} +	else if( to.type == NA_IPX ) { +		net_socket = ipx_socket; +	} +	else if( to.type == NA_BROADCAST_IPX ) { +		net_socket = ipx_socket; +	} +	else { +		Com_Error( ERR_FATAL, "Sys_SendPacket: bad address type" ); +		return; +	} + +	if( !net_socket ) { +		return; +	} + +	NetadrToSockadr( &to, &addr ); + +	if( usingSocks && to.type == NA_IP ) { +		socksBuf[0] = 0;	// reserved +		socksBuf[1] = 0; +		socksBuf[2] = 0;	// fragment (not fragmented) +		socksBuf[3] = 1;	// address type: IPV4 +		*(int *)&socksBuf[4] = ((struct sockaddr_in *)&addr)->sin_addr.s_addr; +		*(short *)&socksBuf[8] = ((struct sockaddr_in *)&addr)->sin_port; +		memcpy( &socksBuf[10], data, length ); +		ret = sendto( net_socket, socksBuf, length+10, 0, &socksRelayAddr, sizeof(socksRelayAddr) ); +	} +	else { +		ret = sendto( net_socket, data, length, 0, &addr, sizeof(addr) ); +	} +	if( ret == SOCKET_ERROR ) { +		int err = WSAGetLastError(); + +		// wouldblock is silent +		if( err == WSAEWOULDBLOCK ) { +			return; +		} + +		// some PPP links do not allow broadcasts and return an error +		if( ( err == WSAEADDRNOTAVAIL ) && ( ( to.type == NA_BROADCAST ) || ( to.type == NA_BROADCAST_IPX ) ) ) { +			return; +		} + +		Com_Printf( "NET_SendPacket: %s\n", NET_ErrorString() ); +	} +} + + +//============================================================================= + +/* +================== +Sys_IsLANAddress + +LAN clients will have their rate var ignored +================== +*/ +qboolean Sys_IsLANAddress( netadr_t adr ) { +	int		i; + +	if( adr.type == NA_LOOPBACK ) { +		return qtrue; +	} + +	if( adr.type == NA_IPX ) { +		return qtrue; +	} + +	if( adr.type != NA_IP ) { +		return qfalse; +	} + +	// choose which comparison to use based on the class of the address being tested +	// any local adresses of a different class than the address being tested will fail based on the first byte + +	if( adr.ip[0] == 127 && adr.ip[1] == 0 && adr.ip[2] == 0 && adr.ip[3] == 1 ) { +		return qtrue; +	} + +	// Class A +	if( (adr.ip[0] & 0x80) == 0x00 ) { +		for ( i = 0 ; i < numIP ; i++ ) { +			if( adr.ip[0] == localIP[i][0] ) { +				return qtrue; +			} +		} +		// the RFC1918 class a block will pass the above test +		return qfalse; +	} + +	// Class B +	if( (adr.ip[0] & 0xc0) == 0x80 ) { +		for ( i = 0 ; i < numIP ; i++ ) { +			if( adr.ip[0] == localIP[i][0] && adr.ip[1] == localIP[i][1] ) { +				return qtrue; +			} +			// also check against the RFC1918 class b blocks +			if( adr.ip[0] == 172 && localIP[i][0] == 172 && (adr.ip[1] & 0xf0) == 16 && (localIP[i][1] & 0xf0) == 16 ) { +				return qtrue; +			} +		} +		return qfalse; +	} + +	// Class C +	for ( i = 0 ; i < numIP ; i++ ) { +		if( adr.ip[0] == localIP[i][0] && adr.ip[1] == localIP[i][1] && adr.ip[2] == localIP[i][2] ) { +			return qtrue; +		} +		// also check against the RFC1918 class c blocks +		if( adr.ip[0] == 192 && localIP[i][0] == 192 && adr.ip[1] == 168 && localIP[i][1] == 168 ) { +			return qtrue; +		} +	} +	return qfalse; +} + +/* +================== +Sys_ShowIP +================== +*/ +void Sys_ShowIP(void) { +	int i; + +	for (i = 0; i < numIP; i++) { +		Com_Printf( "IP: %i.%i.%i.%i\n", localIP[i][0], localIP[i][1], localIP[i][2], localIP[i][3] ); +	} +} + + +//============================================================================= + + +/* +==================== +NET_IPSocket +==================== +*/ +int NET_IPSocket( char *net_interface, int port ) { +	SOCKET				newsocket; +	struct sockaddr_in	address; +	qboolean			_true = qtrue; +	int					i = 1; +	int					err; + +	if( net_interface ) { +		Com_Printf( "Opening IP socket: %s:%i\n", net_interface, port ); +	} +	else { +		Com_Printf( "Opening IP socket: localhost:%i\n", port ); +	} + +	if( ( newsocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == INVALID_SOCKET ) { +		err = WSAGetLastError(); +		if( err != WSAEAFNOSUPPORT ) { +			Com_Printf( "WARNING: UDP_OpenSocket: socket: %s\n", NET_ErrorString() ); +		} +		return 0; +	} + +	// make it non-blocking +	if( ioctlsocket( newsocket, FIONBIO, (u_long *)&_true ) == SOCKET_ERROR ) { +		Com_Printf( "WARNING: UDP_OpenSocket: ioctl FIONBIO: %s\n", NET_ErrorString() ); +		return 0; +	} + +	// make it broadcast capable +	if( setsockopt( newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i) ) == SOCKET_ERROR ) { +		Com_Printf( "WARNING: UDP_OpenSocket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString() ); +		return 0; +	} + +	if( !net_interface || !net_interface[0] || !Q_stricmp(net_interface, "localhost") ) { +		address.sin_addr.s_addr = INADDR_ANY; +	} +	else { +		Sys_StringToSockaddr( net_interface, (struct sockaddr *)&address ); +	} + +	if( port == PORT_ANY ) { +		address.sin_port = 0; +	} +	else { +		address.sin_port = htons( (short)port ); +	} + +	address.sin_family = AF_INET; + +	if( bind( newsocket, (void *)&address, sizeof(address) ) == SOCKET_ERROR ) { +		Com_Printf( "WARNING: UDP_OpenSocket: bind: %s\n", NET_ErrorString() ); +		closesocket( newsocket ); +		return 0; +	} + +	return newsocket; +} + + +/* +==================== +NET_OpenSocks +==================== +*/ +void NET_OpenSocks( int port ) { +	struct sockaddr_in	address; +	int					err; +	struct hostent		*h; +	int					len; +	qboolean			rfc1929; +	unsigned char		buf[64]; + +	usingSocks = qfalse; + +	Com_Printf( "Opening connection to SOCKS server.\n" ); + +	if ( ( socks_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ) == INVALID_SOCKET ) { +		err = WSAGetLastError(); +		Com_Printf( "WARNING: NET_OpenSocks: socket: %s\n", NET_ErrorString() ); +		return; +	} + +	h = gethostbyname( net_socksServer->string ); +	if ( h == NULL ) { +		err = WSAGetLastError(); +		Com_Printf( "WARNING: NET_OpenSocks: gethostbyname: %s\n", NET_ErrorString() ); +		return; +	} +	if ( h->h_addrtype != AF_INET ) { +		Com_Printf( "WARNING: NET_OpenSocks: gethostbyname: address type was not AF_INET\n" ); +		return; +	} +	address.sin_family = AF_INET; +	address.sin_addr.s_addr = *(int *)h->h_addr_list[0]; +	address.sin_port = htons( (short)net_socksPort->integer ); + +	if ( connect( socks_socket, (struct sockaddr *)&address, sizeof( address ) ) == SOCKET_ERROR ) { +		err = WSAGetLastError(); +		Com_Printf( "NET_OpenSocks: connect: %s\n", NET_ErrorString() ); +		return; +	} + +	// send socks authentication handshake +	if ( *net_socksUsername->string || *net_socksPassword->string ) { +		rfc1929 = qtrue; +	} +	else { +		rfc1929 = qfalse; +	} + +	buf[0] = 5;		// SOCKS version +	// method count +	if ( rfc1929 ) { +		buf[1] = 2; +		len = 4; +	} +	else { +		buf[1] = 1; +		len = 3; +	} +	buf[2] = 0;		// method #1 - method id #00: no authentication +	if ( rfc1929 ) { +		buf[2] = 2;		// method #2 - method id #02: username/password +	} +	if ( send( socks_socket, buf, len, 0 ) == SOCKET_ERROR ) { +		err = WSAGetLastError(); +		Com_Printf( "NET_OpenSocks: send: %s\n", NET_ErrorString() ); +		return; +	} + +	// get the response +	len = recv( socks_socket, buf, 64, 0 ); +	if ( len == SOCKET_ERROR ) { +		err = WSAGetLastError(); +		Com_Printf( "NET_OpenSocks: recv: %s\n", NET_ErrorString() ); +		return; +	} +	if ( len != 2 || buf[0] != 5 ) { +		Com_Printf( "NET_OpenSocks: bad response\n" ); +		return; +	} +	switch( buf[1] ) { +	case 0:	// no authentication +		break; +	case 2: // username/password authentication +		break; +	default: +		Com_Printf( "NET_OpenSocks: request denied\n" ); +		return; +	} + +	// do username/password authentication if needed +	if ( buf[1] == 2 ) { +		int		ulen; +		int		plen; + +		// build the request +		ulen = strlen( net_socksUsername->string ); +		plen = strlen( net_socksPassword->string ); + +		buf[0] = 1;		// username/password authentication version +		buf[1] = ulen; +		if ( ulen ) { +			memcpy( &buf[2], net_socksUsername->string, ulen ); +		} +		buf[2 + ulen] = plen; +		if ( plen ) { +			memcpy( &buf[3 + ulen], net_socksPassword->string, plen ); +		} + +		// send it +		if ( send( socks_socket, buf, 3 + ulen + plen, 0 ) == SOCKET_ERROR ) { +			err = WSAGetLastError(); +			Com_Printf( "NET_OpenSocks: send: %s\n", NET_ErrorString() ); +			return; +		} + +		// get the response +		len = recv( socks_socket, buf, 64, 0 ); +		if ( len == SOCKET_ERROR ) { +			err = WSAGetLastError(); +			Com_Printf( "NET_OpenSocks: recv: %s\n", NET_ErrorString() ); +			return; +		} +		if ( len != 2 || buf[0] != 1 ) { +			Com_Printf( "NET_OpenSocks: bad response\n" ); +			return; +		} +		if ( buf[1] != 0 ) { +			Com_Printf( "NET_OpenSocks: authentication failed\n" ); +			return; +		} +	} + +	// send the UDP associate request +	buf[0] = 5;		// SOCKS version +	buf[1] = 3;		// command: UDP associate +	buf[2] = 0;		// reserved +	buf[3] = 1;		// address type: IPV4 +	*(int *)&buf[4] = INADDR_ANY; +	*(short *)&buf[8] = htons( (short)port );		// port +	if ( send( socks_socket, buf, 10, 0 ) == SOCKET_ERROR ) { +		err = WSAGetLastError(); +		Com_Printf( "NET_OpenSocks: send: %s\n", NET_ErrorString() ); +		return; +	} + +	// get the response +	len = recv( socks_socket, buf, 64, 0 ); +	if( len == SOCKET_ERROR ) { +		err = WSAGetLastError(); +		Com_Printf( "NET_OpenSocks: recv: %s\n", NET_ErrorString() ); +		return; +	} +	if( len < 2 || buf[0] != 5 ) { +		Com_Printf( "NET_OpenSocks: bad response\n" ); +		return; +	} +	// check completion code +	if( buf[1] != 0 ) { +		Com_Printf( "NET_OpenSocks: request denied: %i\n", buf[1] ); +		return; +	} +	if( buf[3] != 1 ) { +		Com_Printf( "NET_OpenSocks: relay address is not IPV4: %i\n", buf[3] ); +		return; +	} +	((struct sockaddr_in *)&socksRelayAddr)->sin_family = AF_INET; +	((struct sockaddr_in *)&socksRelayAddr)->sin_addr.s_addr = *(int *)&buf[4]; +	((struct sockaddr_in *)&socksRelayAddr)->sin_port = *(short *)&buf[8]; +	memset( ((struct sockaddr_in *)&socksRelayAddr)->sin_zero, 0, 8 ); + +	usingSocks = qtrue; +} + + +/* +===================== +NET_GetLocalAddress +===================== +*/ +void NET_GetLocalAddress( void ) { +	char				hostname[256]; +	struct hostent		*hostInfo; +	int					error; +	char				*p; +	int					ip; +	int					n; + +	if( gethostname( hostname, 256 ) == SOCKET_ERROR ) { +		error = WSAGetLastError(); +		return; +	} + +	hostInfo = gethostbyname( hostname ); +	if( !hostInfo ) { +		error = WSAGetLastError(); +		return; +	} + +	Com_Printf( "Hostname: %s\n", hostInfo->h_name ); +	n = 0; +	while( ( p = hostInfo->h_aliases[n++] ) != NULL ) { +		Com_Printf( "Alias: %s\n", p ); +	} + +	if ( hostInfo->h_addrtype != AF_INET ) { +		return; +	} + +	numIP = 0; +	while( ( p = hostInfo->h_addr_list[numIP] ) != NULL && numIP < MAX_IPS ) { +		ip = ntohl( *(int *)p ); +		localIP[ numIP ][0] = p[0]; +		localIP[ numIP ][1] = p[1]; +		localIP[ numIP ][2] = p[2]; +		localIP[ numIP ][3] = p[3]; +		Com_Printf( "IP: %i.%i.%i.%i\n", ( ip >> 24 ) & 0xff, ( ip >> 16 ) & 0xff, ( ip >> 8 ) & 0xff, ip & 0xff ); +		numIP++; +	} +} + +/* +==================== +NET_OpenIP +==================== +*/ +void NET_OpenIP( void ) { +	cvar_t	*ip; +	int		port; +	int		i; + +	ip = Cvar_Get( "net_ip", "localhost", CVAR_LATCH ); +	port = Cvar_Get( "net_port", va( "%i", PORT_SERVER ), CVAR_LATCH )->integer; + +	// automatically scan for a valid port, so multiple +	// dedicated servers can be started without requiring +	// a different net_port for each one +	for( i = 0 ; i < 10 ; i++ ) { +		ip_socket = NET_IPSocket( ip->string, port + i ); +		if ( ip_socket ) { +			Cvar_SetValue( "net_port", port + i ); +			if ( net_socksEnabled->integer ) { +				NET_OpenSocks( port + i ); +			} +			NET_GetLocalAddress(); +			return; +		} +	} +	Com_Printf( "WARNING: Couldn't allocate IP port\n"); +} + + +/* +==================== +NET_IPXSocket +==================== +*/ +int NET_IPXSocket( int port ) { +	SOCKET				newsocket; +	struct sockaddr_ipx	address; +	int					_true = 1; +	int					err; + +	if( ( newsocket = socket( AF_IPX, SOCK_DGRAM, NSPROTO_IPX ) ) == INVALID_SOCKET ) { +		err = WSAGetLastError(); +		if (err != WSAEAFNOSUPPORT) { +			Com_Printf( "WARNING: IPX_Socket: socket: %s\n", NET_ErrorString() ); +		} +		return 0; +	} + +	// make it non-blocking +	if( ioctlsocket( newsocket, FIONBIO, (u_long *)&_true ) == SOCKET_ERROR ) { +		Com_Printf( "WARNING: IPX_Socket: ioctl FIONBIO: %s\n", NET_ErrorString() ); +		return 0; +	} + +	// make it broadcast capable +	if( setsockopt( newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&_true, sizeof( _true ) ) == SOCKET_ERROR ) { +		Com_Printf( "WARNING: IPX_Socket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString() ); +		return 0; +	} + +	address.sa_family = AF_IPX; +	memset( address.sa_netnum, 0, 4 ); +	memset( address.sa_nodenum, 0, 6 ); +	if( port == PORT_ANY ) { +		address.sa_socket = 0; +	} +	else { +		address.sa_socket = htons( (short)port ); +	} + +	if( bind( newsocket, (void *)&address, sizeof(address) ) == SOCKET_ERROR ) { +		Com_Printf( "WARNING: IPX_Socket: bind: %s\n", NET_ErrorString() ); +		closesocket( newsocket ); +		return 0; +	} + +	return newsocket; +} + + +/* +==================== +NET_OpenIPX +==================== +*/ +void NET_OpenIPX( void ) { +	int		port; + +	port = Cvar_Get( "net_port", va( "%i", PORT_SERVER ), CVAR_LATCH )->integer; +	ipx_socket = NET_IPXSocket( port ); +} + + + +//=================================================================== + + +/* +==================== +NET_GetCvars +==================== +*/ +static qboolean NET_GetCvars( void ) { +	qboolean	modified; + +	modified = qfalse; + +	if( net_noudp && net_noudp->modified ) { +		modified = qtrue; +	} +	net_noudp = Cvar_Get( "net_noudp", "0", CVAR_LATCH | CVAR_ARCHIVE ); + +	if( net_noipx && net_noipx->modified ) { +		modified = qtrue; +	} +	net_noipx = Cvar_Get( "net_noipx", "0", CVAR_LATCH | CVAR_ARCHIVE ); + + +	if( net_socksEnabled && net_socksEnabled->modified ) { +		modified = qtrue; +	} +	net_socksEnabled = Cvar_Get( "net_socksEnabled", "0", CVAR_LATCH | CVAR_ARCHIVE ); + +	if( net_socksServer && net_socksServer->modified ) { +		modified = qtrue; +	} +	net_socksServer = Cvar_Get( "net_socksServer", "", CVAR_LATCH | CVAR_ARCHIVE ); + +	if( net_socksPort && net_socksPort->modified ) { +		modified = qtrue; +	} +	net_socksPort = Cvar_Get( "net_socksPort", "1080", CVAR_LATCH | CVAR_ARCHIVE ); + +	if( net_socksUsername && net_socksUsername->modified ) { +		modified = qtrue; +	} +	net_socksUsername = Cvar_Get( "net_socksUsername", "", CVAR_LATCH | CVAR_ARCHIVE ); + +	if( net_socksPassword && net_socksPassword->modified ) { +		modified = qtrue; +	} +	net_socksPassword = Cvar_Get( "net_socksPassword", "", CVAR_LATCH | CVAR_ARCHIVE ); + + +	return modified; +} + + +/* +==================== +NET_Config +==================== +*/ +void NET_Config( qboolean enableNetworking ) { +	qboolean	modified; +	qboolean	stop; +	qboolean	start; + +	// get any latched changes to cvars +	modified = NET_GetCvars(); + +	if( net_noudp->integer && net_noipx->integer ) { +		enableNetworking = qfalse; +	} + +	// if enable state is the same and no cvars were modified, we have nothing to do +	if( enableNetworking == networkingEnabled && !modified ) { +		return; +	} + +	if( enableNetworking == networkingEnabled ) { +		if( enableNetworking ) { +			stop = qtrue; +			start = qtrue; +		} +		else { +			stop = qfalse; +			start = qfalse; +		} +	} +	else { +		if( enableNetworking ) { +			stop = qfalse; +			start = qtrue; +		} +		else { +			stop = qtrue; +			start = qfalse; +		} +		networkingEnabled = enableNetworking; +	} + +	if( stop ) { +		if ( ip_socket && ip_socket != INVALID_SOCKET ) { +			closesocket( ip_socket ); +			ip_socket = 0; +		} + +		if ( socks_socket && socks_socket != INVALID_SOCKET ) { +			closesocket( socks_socket ); +			socks_socket = 0; +		} + +		if ( ipx_socket && ipx_socket != INVALID_SOCKET ) { +			closesocket( ipx_socket ); +			ipx_socket = 0; +		} +	} + +	if( start ) { +		if (! net_noudp->integer ) { +			NET_OpenIP(); +		} +		if (! net_noipx->integer ) { +			NET_OpenIPX(); +		} +	} +} + + +/* +==================== +NET_Init +==================== +*/ +void NET_Init( void ) { +	int		r; + +	r = WSAStartup( MAKEWORD( 1, 1 ), &winsockdata ); +	if( r ) { +		Com_Printf( "WARNING: Winsock initialization failed, returned %d\n", r ); +		return; +	} + +	winsockInitialized = qtrue; +	Com_Printf( "Winsock Initialized\n" ); + +	// this is really just to get the cvars registered +	NET_GetCvars(); + +	//FIXME testing! +	NET_Config( qtrue ); +} + + +/* +==================== +NET_Shutdown +==================== +*/ +void NET_Shutdown( void ) { +	if ( !winsockInitialized ) { +		return; +	} +	NET_Config( qfalse ); +	WSACleanup(); +	winsockInitialized = qfalse; +} + + +/* +==================== +NET_Sleep + +sleeps msec or until net socket is ready +==================== +*/ +void NET_Sleep( int msec ) { +} + + +/* +==================== +NET_Restart_f +==================== +*/ +void NET_Restart( void ) { +	NET_Config( networkingEnabled ); +} diff --git a/src/win32/win_qgl.c b/src/win32/win_qgl.c new file mode 100644 index 0000000..40c6cd2 --- /dev/null +++ b/src/win32/win_qgl.c @@ -0,0 +1,4387 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2006 Tim Angus + +This file is part of Tremulous. + +Tremulous 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. + +Tremulous is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Tremulous; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA +=========================================================================== +*/ +/* +** QGL_WIN.C +** +** This file implements the operating system binding of GL to QGL function +** pointers.  When doing a port of Quake3 you must implement the following +** two functions: +** +** QGL_Init() - loads libraries, assigns function pointers, etc. +** QGL_Shutdown() - unloads libraries, NULLs function pointers +*/ +#include <float.h> +#include "../renderer/tr_local.h" +#include "glw_win.h" + +void QGL_EnableLogging( qboolean enable ); + +int ( WINAPI * qwglSwapIntervalEXT)( int interval ); +BOOL  ( WINAPI * qwglGetDeviceGammaRamp3DFX)( HDC, LPVOID ); +BOOL  ( WINAPI * qwglSetDeviceGammaRamp3DFX)( HDC, LPVOID ); + +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); + +BOOL  ( WINAPI * qwglCopyContext)(HGLRC, HGLRC, UINT); +HGLRC ( WINAPI * qwglCreateContext)(HDC); +HGLRC ( WINAPI * qwglCreateLayerContext)(HDC, int); +BOOL  ( WINAPI * qwglDeleteContext)(HGLRC); +HGLRC ( WINAPI * qwglGetCurrentContext)(VOID); +HDC   ( WINAPI * qwglGetCurrentDC)(VOID); +PROC  ( WINAPI * qwglGetProcAddress)(LPCSTR); +BOOL  ( WINAPI * qwglMakeCurrent)(HDC, HGLRC); +BOOL  ( WINAPI * qwglShareLists)(HGLRC, HGLRC); +BOOL  ( WINAPI * qwglUseFontBitmaps)(HDC, DWORD, DWORD, DWORD); + +BOOL  ( WINAPI * qwglUseFontOutlines)(HDC, DWORD, DWORD, DWORD, FLOAT, +                                           FLOAT, int, LPGLYPHMETRICSFLOAT); + +BOOL ( WINAPI * qwglDescribeLayerPlane)(HDC, int, int, UINT, +                                            LPLAYERPLANEDESCRIPTOR); +int  ( WINAPI * qwglSetLayerPaletteEntries)(HDC, int, int, int, +                                                CONST COLORREF *); +int  ( WINAPI * qwglGetLayerPaletteEntries)(HDC, int, int, int, +                                                COLORREF *); +BOOL ( WINAPI * qwglRealizeLayerPalette)(HDC, int, BOOL); +BOOL ( WINAPI * qwglSwapLayerBuffers)(HDC, UINT); + +void ( APIENTRY * qglAccum )(GLenum op, GLfloat value); +void ( APIENTRY * qglAlphaFunc )(GLenum func, GLclampf ref); +GLboolean ( APIENTRY * qglAreTexturesResident )(GLsizei n, const GLuint *textures, GLboolean *residences); +void ( APIENTRY * qglArrayElement )(GLint i); +void ( APIENTRY * qglBegin )(GLenum mode); +void ( APIENTRY * qglBindTexture )(GLenum target, GLuint texture); +void ( APIENTRY * qglBitmap )(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); +void ( APIENTRY * qglBlendFunc )(GLenum sfactor, GLenum dfactor); +void ( APIENTRY * qglCallList )(GLuint list); +void ( APIENTRY * qglCallLists )(GLsizei n, GLenum type, const GLvoid *lists); +void ( APIENTRY * qglClear )(GLbitfield mask); +void ( APIENTRY * qglClearAccum )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +void ( APIENTRY * qglClearColor )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +void ( APIENTRY * qglClearDepth )(GLclampd depth); +void ( APIENTRY * qglClearIndex )(GLfloat c); +void ( APIENTRY * qglClearStencil )(GLint s); +void ( APIENTRY * qglClipPlane )(GLenum plane, const GLdouble *equation); +void ( APIENTRY * qglColor3b )(GLbyte red, GLbyte green, GLbyte blue); +void ( APIENTRY * qglColor3bv )(const GLbyte *v); +void ( APIENTRY * qglColor3d )(GLdouble red, GLdouble green, GLdouble blue); +void ( APIENTRY * qglColor3dv )(const GLdouble *v); +void ( APIENTRY * qglColor3f )(GLfloat red, GLfloat green, GLfloat blue); +void ( APIENTRY * qglColor3fv )(const GLfloat *v); +void ( APIENTRY * qglColor3i )(GLint red, GLint green, GLint blue); +void ( APIENTRY * qglColor3iv )(const GLint *v); +void ( APIENTRY * qglColor3s )(GLshort red, GLshort green, GLshort blue); +void ( APIENTRY * qglColor3sv )(const GLshort *v); +void ( APIENTRY * qglColor3ub )(GLubyte red, GLubyte green, GLubyte blue); +void ( APIENTRY * qglColor3ubv )(const GLubyte *v); +void ( APIENTRY * qglColor3ui )(GLuint red, GLuint green, GLuint blue); +void ( APIENTRY * qglColor3uiv )(const GLuint *v); +void ( APIENTRY * qglColor3us )(GLushort red, GLushort green, GLushort blue); +void ( APIENTRY * qglColor3usv )(const GLushort *v); +void ( APIENTRY * qglColor4b )(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +void ( APIENTRY * qglColor4bv )(const GLbyte *v); +void ( APIENTRY * qglColor4d )(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +void ( APIENTRY * qglColor4dv )(const GLdouble *v); +void ( APIENTRY * qglColor4f )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +void ( APIENTRY * qglColor4fv )(const GLfloat *v); +void ( APIENTRY * qglColor4i )(GLint red, GLint green, GLint blue, GLint alpha); +void ( APIENTRY * qglColor4iv )(const GLint *v); +void ( APIENTRY * qglColor4s )(GLshort red, GLshort green, GLshort blue, GLshort alpha); +void ( APIENTRY * qglColor4sv )(const GLshort *v); +void ( APIENTRY * qglColor4ub )(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +void ( APIENTRY * qglColor4ubv )(const GLubyte *v); +void ( APIENTRY * qglColor4ui )(GLuint red, GLuint green, GLuint blue, GLuint alpha); +void ( APIENTRY * qglColor4uiv )(const GLuint *v); +void ( APIENTRY * qglColor4us )(GLushort red, GLushort green, GLushort blue, GLushort alpha); +void ( APIENTRY * qglColor4usv )(const GLushort *v); +void ( APIENTRY * qglColorMask )(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +void ( APIENTRY * qglColorMaterial )(GLenum face, GLenum mode); +void ( APIENTRY * qglColorPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +void ( APIENTRY * qglCopyPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +void ( APIENTRY * qglCopyTexImage1D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); +void ( APIENTRY * qglCopyTexImage2D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +void ( APIENTRY * qglCopyTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +void ( APIENTRY * qglCopyTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +void ( APIENTRY * qglCullFace )(GLenum mode); +void ( APIENTRY * qglDeleteLists )(GLuint list, GLsizei range); +void ( APIENTRY * qglDeleteTextures )(GLsizei n, const GLuint *textures); +void ( APIENTRY * qglDepthFunc )(GLenum func); +void ( APIENTRY * qglDepthMask )(GLboolean flag); +void ( APIENTRY * qglDepthRange )(GLclampd zNear, GLclampd zFar); +void ( APIENTRY * qglDisable )(GLenum cap); +void ( APIENTRY * qglDisableClientState )(GLenum array); +void ( APIENTRY * qglDrawArrays )(GLenum mode, GLint first, GLsizei count); +void ( APIENTRY * qglDrawBuffer )(GLenum mode); +void ( APIENTRY * qglDrawElements )(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); +void ( APIENTRY * qglDrawPixels )(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +void ( APIENTRY * qglEdgeFlag )(GLboolean flag); +void ( APIENTRY * qglEdgeFlagPointer )(GLsizei stride, const GLvoid *pointer); +void ( APIENTRY * qglEdgeFlagv )(const GLboolean *flag); +void ( APIENTRY * qglEnable )(GLenum cap); +void ( APIENTRY * qglEnableClientState )(GLenum array); +void ( APIENTRY * qglEnd )(void); +void ( APIENTRY * qglEndList )(void); +void ( APIENTRY * qglEvalCoord1d )(GLdouble u); +void ( APIENTRY * qglEvalCoord1dv )(const GLdouble *u); +void ( APIENTRY * qglEvalCoord1f )(GLfloat u); +void ( APIENTRY * qglEvalCoord1fv )(const GLfloat *u); +void ( APIENTRY * qglEvalCoord2d )(GLdouble u, GLdouble v); +void ( APIENTRY * qglEvalCoord2dv )(const GLdouble *u); +void ( APIENTRY * qglEvalCoord2f )(GLfloat u, GLfloat v); +void ( APIENTRY * qglEvalCoord2fv )(const GLfloat *u); +void ( APIENTRY * qglEvalMesh1 )(GLenum mode, GLint i1, GLint i2); +void ( APIENTRY * qglEvalMesh2 )(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +void ( APIENTRY * qglEvalPoint1 )(GLint i); +void ( APIENTRY * qglEvalPoint2 )(GLint i, GLint j); +void ( APIENTRY * qglFeedbackBuffer )(GLsizei size, GLenum type, GLfloat *buffer); +void ( APIENTRY * qglFinish )(void); +void ( APIENTRY * qglFlush )(void); +void ( APIENTRY * qglFogf )(GLenum pname, GLfloat param); +void ( APIENTRY * qglFogfv )(GLenum pname, const GLfloat *params); +void ( APIENTRY * qglFogi )(GLenum pname, GLint param); +void ( APIENTRY * qglFogiv )(GLenum pname, const GLint *params); +void ( APIENTRY * qglFrontFace )(GLenum mode); +void ( APIENTRY * qglFrustum )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLuint ( APIENTRY * qglGenLists )(GLsizei range); +void ( APIENTRY * qglGenTextures )(GLsizei n, GLuint *textures); +void ( APIENTRY * qglGetBooleanv )(GLenum pname, GLboolean *params); +void ( APIENTRY * qglGetClipPlane )(GLenum plane, GLdouble *equation); +void ( APIENTRY * qglGetDoublev )(GLenum pname, GLdouble *params); +GLenum ( APIENTRY * qglGetError )(void); +void ( APIENTRY * qglGetFloatv )(GLenum pname, GLfloat *params); +void ( APIENTRY * qglGetIntegerv )(GLenum pname, GLint *params); +void ( APIENTRY * qglGetLightfv )(GLenum light, GLenum pname, GLfloat *params); +void ( APIENTRY * qglGetLightiv )(GLenum light, GLenum pname, GLint *params); +void ( APIENTRY * qglGetMapdv )(GLenum target, GLenum query, GLdouble *v); +void ( APIENTRY * qglGetMapfv )(GLenum target, GLenum query, GLfloat *v); +void ( APIENTRY * qglGetMapiv )(GLenum target, GLenum query, GLint *v); +void ( APIENTRY * qglGetMaterialfv )(GLenum face, GLenum pname, GLfloat *params); +void ( APIENTRY * qglGetMaterialiv )(GLenum face, GLenum pname, GLint *params); +void ( APIENTRY * qglGetPixelMapfv )(GLenum map, GLfloat *values); +void ( APIENTRY * qglGetPixelMapuiv )(GLenum map, GLuint *values); +void ( APIENTRY * qglGetPixelMapusv )(GLenum map, GLushort *values); +void ( APIENTRY * qglGetPointerv )(GLenum pname, GLvoid* *params); +void ( APIENTRY * qglGetPolygonStipple )(GLubyte *mask); +const GLubyte * ( APIENTRY * qglGetString )(GLenum name); +void ( APIENTRY * qglGetTexEnvfv )(GLenum target, GLenum pname, GLfloat *params); +void ( APIENTRY * qglGetTexEnviv )(GLenum target, GLenum pname, GLint *params); +void ( APIENTRY * qglGetTexGendv )(GLenum coord, GLenum pname, GLdouble *params); +void ( APIENTRY * qglGetTexGenfv )(GLenum coord, GLenum pname, GLfloat *params); +void ( APIENTRY * qglGetTexGeniv )(GLenum coord, GLenum pname, GLint *params); +void ( APIENTRY * qglGetTexImage )(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); +void ( APIENTRY * qglGetTexLevelParameterfv )(GLenum target, GLint level, GLenum pname, GLfloat *params); +void ( APIENTRY * qglGetTexLevelParameteriv )(GLenum target, GLint level, GLenum pname, GLint *params); +void ( APIENTRY * qglGetTexParameterfv )(GLenum target, GLenum pname, GLfloat *params); +void ( APIENTRY * qglGetTexParameteriv )(GLenum target, GLenum pname, GLint *params); +void ( APIENTRY * qglHint )(GLenum target, GLenum mode); +void ( APIENTRY * qglIndexMask )(GLuint mask); +void ( APIENTRY * qglIndexPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); +void ( APIENTRY * qglIndexd )(GLdouble c); +void ( APIENTRY * qglIndexdv )(const GLdouble *c); +void ( APIENTRY * qglIndexf )(GLfloat c); +void ( APIENTRY * qglIndexfv )(const GLfloat *c); +void ( APIENTRY * qglIndexi )(GLint c); +void ( APIENTRY * qglIndexiv )(const GLint *c); +void ( APIENTRY * qglIndexs )(GLshort c); +void ( APIENTRY * qglIndexsv )(const GLshort *c); +void ( APIENTRY * qglIndexub )(GLubyte c); +void ( APIENTRY * qglIndexubv )(const GLubyte *c); +void ( APIENTRY * qglInitNames )(void); +void ( APIENTRY * qglInterleavedArrays )(GLenum format, GLsizei stride, const GLvoid *pointer); +GLboolean ( APIENTRY * qglIsEnabled )(GLenum cap); +GLboolean ( APIENTRY * qglIsList )(GLuint list); +GLboolean ( APIENTRY * qglIsTexture )(GLuint texture); +void ( APIENTRY * qglLightModelf )(GLenum pname, GLfloat param); +void ( APIENTRY * qglLightModelfv )(GLenum pname, const GLfloat *params); +void ( APIENTRY * qglLightModeli )(GLenum pname, GLint param); +void ( APIENTRY * qglLightModeliv )(GLenum pname, const GLint *params); +void ( APIENTRY * qglLightf )(GLenum light, GLenum pname, GLfloat param); +void ( APIENTRY * qglLightfv )(GLenum light, GLenum pname, const GLfloat *params); +void ( APIENTRY * qglLighti )(GLenum light, GLenum pname, GLint param); +void ( APIENTRY * qglLightiv )(GLenum light, GLenum pname, const GLint *params); +void ( APIENTRY * qglLineStipple )(GLint factor, GLushort pattern); +void ( APIENTRY * qglLineWidth )(GLfloat width); +void ( APIENTRY * qglListBase )(GLuint base); +void ( APIENTRY * qglLoadIdentity )(void); +void ( APIENTRY * qglLoadMatrixd )(const GLdouble *m); +void ( APIENTRY * qglLoadMatrixf )(const GLfloat *m); +void ( APIENTRY * qglLoadName )(GLuint name); +void ( APIENTRY * qglLogicOp )(GLenum opcode); +void ( APIENTRY * qglMap1d )(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +void ( APIENTRY * qglMap1f )(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +void ( APIENTRY * qglMap2d )(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +void ( APIENTRY * qglMap2f )(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +void ( APIENTRY * qglMapGrid1d )(GLint un, GLdouble u1, GLdouble u2); +void ( APIENTRY * qglMapGrid1f )(GLint un, GLfloat u1, GLfloat u2); +void ( APIENTRY * qglMapGrid2d )(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +void ( APIENTRY * qglMapGrid2f )(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +void ( APIENTRY * qglMaterialf )(GLenum face, GLenum pname, GLfloat param); +void ( APIENTRY * qglMaterialfv )(GLenum face, GLenum pname, const GLfloat *params); +void ( APIENTRY * qglMateriali )(GLenum face, GLenum pname, GLint param); +void ( APIENTRY * qglMaterialiv )(GLenum face, GLenum pname, const GLint *params); +void ( APIENTRY * qglMatrixMode )(GLenum mode); +void ( APIENTRY * qglMultMatrixd )(const GLdouble *m); +void ( APIENTRY * qglMultMatrixf )(const GLfloat *m); +void ( APIENTRY * qglNewList )(GLuint list, GLenum mode); +void ( APIENTRY * qglNormal3b )(GLbyte nx, GLbyte ny, GLbyte nz); +void ( APIENTRY * qglNormal3bv )(const GLbyte *v); +void ( APIENTRY * qglNormal3d )(GLdouble nx, GLdouble ny, GLdouble nz); +void ( APIENTRY * qglNormal3dv )(const GLdouble *v); +void ( APIENTRY * qglNormal3f )(GLfloat nx, GLfloat ny, GLfloat nz); +void ( APIENTRY * qglNormal3fv )(const GLfloat *v); +void ( APIENTRY * qglNormal3i )(GLint nx, GLint ny, GLint nz); +void ( APIENTRY * qglNormal3iv )(const GLint *v); +void ( APIENTRY * qglNormal3s )(GLshort nx, GLshort ny, GLshort nz); +void ( APIENTRY * qglNormal3sv )(const GLshort *v); +void ( APIENTRY * qglNormalPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); +void ( APIENTRY * qglOrtho )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +void ( APIENTRY * qglPassThrough )(GLfloat token); +void ( APIENTRY * qglPixelMapfv )(GLenum map, GLsizei mapsize, const GLfloat *values); +void ( APIENTRY * qglPixelMapuiv )(GLenum map, GLsizei mapsize, const GLuint *values); +void ( APIENTRY * qglPixelMapusv )(GLenum map, GLsizei mapsize, const GLushort *values); +void ( APIENTRY * qglPixelStoref )(GLenum pname, GLfloat param); +void ( APIENTRY * qglPixelStorei )(GLenum pname, GLint param); +void ( APIENTRY * qglPixelTransferf )(GLenum pname, GLfloat param); +void ( APIENTRY * qglPixelTransferi )(GLenum pname, GLint param); +void ( APIENTRY * qglPixelZoom )(GLfloat xfactor, GLfloat yfactor); +void ( APIENTRY * qglPointSize )(GLfloat size); +void ( APIENTRY * qglPolygonMode )(GLenum face, GLenum mode); +void ( APIENTRY * qglPolygonOffset )(GLfloat factor, GLfloat units); +void ( APIENTRY * qglPolygonStipple )(const GLubyte *mask); +void ( APIENTRY * qglPopAttrib )(void); +void ( APIENTRY * qglPopClientAttrib )(void); +void ( APIENTRY * qglPopMatrix )(void); +void ( APIENTRY * qglPopName )(void); +void ( APIENTRY * qglPrioritizeTextures )(GLsizei n, const GLuint *textures, const GLclampf *priorities); +void ( APIENTRY * qglPushAttrib )(GLbitfield mask); +void ( APIENTRY * qglPushClientAttrib )(GLbitfield mask); +void ( APIENTRY * qglPushMatrix )(void); +void ( APIENTRY * qglPushName )(GLuint name); +void ( APIENTRY * qglRasterPos2d )(GLdouble x, GLdouble y); +void ( APIENTRY * qglRasterPos2dv )(const GLdouble *v); +void ( APIENTRY * qglRasterPos2f )(GLfloat x, GLfloat y); +void ( APIENTRY * qglRasterPos2fv )(const GLfloat *v); +void ( APIENTRY * qglRasterPos2i )(GLint x, GLint y); +void ( APIENTRY * qglRasterPos2iv )(const GLint *v); +void ( APIENTRY * qglRasterPos2s )(GLshort x, GLshort y); +void ( APIENTRY * qglRasterPos2sv )(const GLshort *v); +void ( APIENTRY * qglRasterPos3d )(GLdouble x, GLdouble y, GLdouble z); +void ( APIENTRY * qglRasterPos3dv )(const GLdouble *v); +void ( APIENTRY * qglRasterPos3f )(GLfloat x, GLfloat y, GLfloat z); +void ( APIENTRY * qglRasterPos3fv )(const GLfloat *v); +void ( APIENTRY * qglRasterPos3i )(GLint x, GLint y, GLint z); +void ( APIENTRY * qglRasterPos3iv )(const GLint *v); +void ( APIENTRY * qglRasterPos3s )(GLshort x, GLshort y, GLshort z); +void ( APIENTRY * qglRasterPos3sv )(const GLshort *v); +void ( APIENTRY * qglRasterPos4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +void ( APIENTRY * qglRasterPos4dv )(const GLdouble *v); +void ( APIENTRY * qglRasterPos4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +void ( APIENTRY * qglRasterPos4fv )(const GLfloat *v); +void ( APIENTRY * qglRasterPos4i )(GLint x, GLint y, GLint z, GLint w); +void ( APIENTRY * qglRasterPos4iv )(const GLint *v); +void ( APIENTRY * qglRasterPos4s )(GLshort x, GLshort y, GLshort z, GLshort w); +void ( APIENTRY * qglRasterPos4sv )(const GLshort *v); +void ( APIENTRY * qglReadBuffer )(GLenum mode); +void ( APIENTRY * qglReadPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); +void ( APIENTRY * qglRectd )(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +void ( APIENTRY * qglRectdv )(const GLdouble *v1, const GLdouble *v2); +void ( APIENTRY * qglRectf )(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +void ( APIENTRY * qglRectfv )(const GLfloat *v1, const GLfloat *v2); +void ( APIENTRY * qglRecti )(GLint x1, GLint y1, GLint x2, GLint y2); +void ( APIENTRY * qglRectiv )(const GLint *v1, const GLint *v2); +void ( APIENTRY * qglRects )(GLshort x1, GLshort y1, GLshort x2, GLshort y2); +void ( APIENTRY * qglRectsv )(const GLshort *v1, const GLshort *v2); +GLint ( APIENTRY * qglRenderMode )(GLenum mode); +void ( APIENTRY * qglRotated )(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +void ( APIENTRY * qglRotatef )(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +void ( APIENTRY * qglScaled )(GLdouble x, GLdouble y, GLdouble z); +void ( APIENTRY * qglScalef )(GLfloat x, GLfloat y, GLfloat z); +void ( APIENTRY * qglScissor )(GLint x, GLint y, GLsizei width, GLsizei height); +void ( APIENTRY * qglSelectBuffer )(GLsizei size, GLuint *buffer); +void ( APIENTRY * qglShadeModel )(GLenum mode); +void ( APIENTRY * qglStencilFunc )(GLenum func, GLint ref, GLuint mask); +void ( APIENTRY * qglStencilMask )(GLuint mask); +void ( APIENTRY * qglStencilOp )(GLenum fail, GLenum zfail, GLenum zpass); +void ( APIENTRY * qglTexCoord1d )(GLdouble s); +void ( APIENTRY * qglTexCoord1dv )(const GLdouble *v); +void ( APIENTRY * qglTexCoord1f )(GLfloat s); +void ( APIENTRY * qglTexCoord1fv )(const GLfloat *v); +void ( APIENTRY * qglTexCoord1i )(GLint s); +void ( APIENTRY * qglTexCoord1iv )(const GLint *v); +void ( APIENTRY * qglTexCoord1s )(GLshort s); +void ( APIENTRY * qglTexCoord1sv )(const GLshort *v); +void ( APIENTRY * qglTexCoord2d )(GLdouble s, GLdouble t); +void ( APIENTRY * qglTexCoord2dv )(const GLdouble *v); +void ( APIENTRY * qglTexCoord2f )(GLfloat s, GLfloat t); +void ( APIENTRY * qglTexCoord2fv )(const GLfloat *v); +void ( APIENTRY * qglTexCoord2i )(GLint s, GLint t); +void ( APIENTRY * qglTexCoord2iv )(const GLint *v); +void ( APIENTRY * qglTexCoord2s )(GLshort s, GLshort t); +void ( APIENTRY * qglTexCoord2sv )(const GLshort *v); +void ( APIENTRY * qglTexCoord3d )(GLdouble s, GLdouble t, GLdouble r); +void ( APIENTRY * qglTexCoord3dv )(const GLdouble *v); +void ( APIENTRY * qglTexCoord3f )(GLfloat s, GLfloat t, GLfloat r); +void ( APIENTRY * qglTexCoord3fv )(const GLfloat *v); +void ( APIENTRY * qglTexCoord3i )(GLint s, GLint t, GLint r); +void ( APIENTRY * qglTexCoord3iv )(const GLint *v); +void ( APIENTRY * qglTexCoord3s )(GLshort s, GLshort t, GLshort r); +void ( APIENTRY * qglTexCoord3sv )(const GLshort *v); +void ( APIENTRY * qglTexCoord4d )(GLdouble s, GLdouble t, GLdouble r, GLdouble q); +void ( APIENTRY * qglTexCoord4dv )(const GLdouble *v); +void ( APIENTRY * qglTexCoord4f )(GLfloat s, GLfloat t, GLfloat r, GLfloat q); +void ( APIENTRY * qglTexCoord4fv )(const GLfloat *v); +void ( APIENTRY * qglTexCoord4i )(GLint s, GLint t, GLint r, GLint q); +void ( APIENTRY * qglTexCoord4iv )(const GLint *v); +void ( APIENTRY * qglTexCoord4s )(GLshort s, GLshort t, GLshort r, GLshort q); +void ( APIENTRY * qglTexCoord4sv )(const GLshort *v); +void ( APIENTRY * qglTexCoordPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +void ( APIENTRY * qglTexEnvf )(GLenum target, GLenum pname, GLfloat param); +void ( APIENTRY * qglTexEnvfv )(GLenum target, GLenum pname, const GLfloat *params); +void ( APIENTRY * qglTexEnvi )(GLenum target, GLenum pname, GLint param); +void ( APIENTRY * qglTexEnviv )(GLenum target, GLenum pname, const GLint *params); +void ( APIENTRY * qglTexGend )(GLenum coord, GLenum pname, GLdouble param); +void ( APIENTRY * qglTexGendv )(GLenum coord, GLenum pname, const GLdouble *params); +void ( APIENTRY * qglTexGenf )(GLenum coord, GLenum pname, GLfloat param); +void ( APIENTRY * qglTexGenfv )(GLenum coord, GLenum pname, const GLfloat *params); +void ( APIENTRY * qglTexGeni )(GLenum coord, GLenum pname, GLint param); +void ( APIENTRY * qglTexGeniv )(GLenum coord, GLenum pname, const GLint *params); +void ( APIENTRY * qglTexImage1D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +void ( APIENTRY * qglTexImage2D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +void ( APIENTRY * qglTexParameterf )(GLenum target, GLenum pname, GLfloat param); +void ( APIENTRY * qglTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params); +void ( APIENTRY * qglTexParameteri )(GLenum target, GLenum pname, GLint param); +void ( APIENTRY * qglTexParameteriv )(GLenum target, GLenum pname, const GLint *params); +void ( APIENTRY * qglTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +void ( APIENTRY * qglTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +void ( APIENTRY * qglTranslated )(GLdouble x, GLdouble y, GLdouble z); +void ( APIENTRY * qglTranslatef )(GLfloat x, GLfloat y, GLfloat z); +void ( APIENTRY * qglVertex2d )(GLdouble x, GLdouble y); +void ( APIENTRY * qglVertex2dv )(const GLdouble *v); +void ( APIENTRY * qglVertex2f )(GLfloat x, GLfloat y); +void ( APIENTRY * qglVertex2fv )(const GLfloat *v); +void ( APIENTRY * qglVertex2i )(GLint x, GLint y); +void ( APIENTRY * qglVertex2iv )(const GLint *v); +void ( APIENTRY * qglVertex2s )(GLshort x, GLshort y); +void ( APIENTRY * qglVertex2sv )(const GLshort *v); +void ( APIENTRY * qglVertex3d )(GLdouble x, GLdouble y, GLdouble z); +void ( APIENTRY * qglVertex3dv )(const GLdouble *v); +void ( APIENTRY * qglVertex3f )(GLfloat x, GLfloat y, GLfloat z); +void ( APIENTRY * qglVertex3fv )(const GLfloat *v); +void ( APIENTRY * qglVertex3i )(GLint x, GLint y, GLint z); +void ( APIENTRY * qglVertex3iv )(const GLint *v); +void ( APIENTRY * qglVertex3s )(GLshort x, GLshort y, GLshort z); +void ( APIENTRY * qglVertex3sv )(const GLshort *v); +void ( APIENTRY * qglVertex4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +void ( APIENTRY * qglVertex4dv )(const GLdouble *v); +void ( APIENTRY * qglVertex4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +void ( APIENTRY * qglVertex4fv )(const GLfloat *v); +void ( APIENTRY * qglVertex4i )(GLint x, GLint y, GLint z, GLint w); +void ( APIENTRY * qglVertex4iv )(const GLint *v); +void ( APIENTRY * qglVertex4s )(GLshort x, GLshort y, GLshort z, GLshort w); +void ( APIENTRY * qglVertex4sv )(const GLshort *v); +void ( APIENTRY * qglVertexPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +void ( APIENTRY * qglViewport )(GLint x, GLint y, GLsizei width, GLsizei height); + +void ( APIENTRY * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t ); +void ( APIENTRY * qglActiveTextureARB )( GLenum texture ); +void ( APIENTRY * qglClientActiveTextureARB )( GLenum texture ); + +void ( APIENTRY * qglLockArraysEXT)( GLint, GLint); +void ( APIENTRY * qglUnlockArraysEXT) ( void ); + + +static void ( APIENTRY * dllAccum )(GLenum op, GLfloat value); +static void ( APIENTRY * dllAlphaFunc )(GLenum func, GLclampf ref); +GLboolean ( APIENTRY * dllAreTexturesResident )(GLsizei n, const GLuint *textures, GLboolean *residences); +static void ( APIENTRY * dllArrayElement )(GLint i); +static void ( APIENTRY * dllBegin )(GLenum mode); +static void ( APIENTRY * dllBindTexture )(GLenum target, GLuint texture); +static void ( APIENTRY * dllBitmap )(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); +static void ( APIENTRY * dllBlendFunc )(GLenum sfactor, GLenum dfactor); +static void ( APIENTRY * dllCallList )(GLuint list); +static void ( APIENTRY * dllCallLists )(GLsizei n, GLenum type, const GLvoid *lists); +static void ( APIENTRY * dllClear )(GLbitfield mask); +static void ( APIENTRY * dllClearAccum )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +static void ( APIENTRY * dllClearColor )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +static void ( APIENTRY * dllClearDepth )(GLclampd depth); +static void ( APIENTRY * dllClearIndex )(GLfloat c); +static void ( APIENTRY * dllClearStencil )(GLint s); +static void ( APIENTRY * dllClipPlane )(GLenum plane, const GLdouble *equation); +static void ( APIENTRY * dllColor3b )(GLbyte red, GLbyte green, GLbyte blue); +static void ( APIENTRY * dllColor3bv )(const GLbyte *v); +static void ( APIENTRY * dllColor3d )(GLdouble red, GLdouble green, GLdouble blue); +static void ( APIENTRY * dllColor3dv )(const GLdouble *v); +static void ( APIENTRY * dllColor3f )(GLfloat red, GLfloat green, GLfloat blue); +static void ( APIENTRY * dllColor3fv )(const GLfloat *v); +static void ( APIENTRY * dllColor3i )(GLint red, GLint green, GLint blue); +static void ( APIENTRY * dllColor3iv )(const GLint *v); +static void ( APIENTRY * dllColor3s )(GLshort red, GLshort green, GLshort blue); +static void ( APIENTRY * dllColor3sv )(const GLshort *v); +static void ( APIENTRY * dllColor3ub )(GLubyte red, GLubyte green, GLubyte blue); +static void ( APIENTRY * dllColor3ubv )(const GLubyte *v); +static void ( APIENTRY * dllColor3ui )(GLuint red, GLuint green, GLuint blue); +static void ( APIENTRY * dllColor3uiv )(const GLuint *v); +static void ( APIENTRY * dllColor3us )(GLushort red, GLushort green, GLushort blue); +static void ( APIENTRY * dllColor3usv )(const GLushort *v); +static void ( APIENTRY * dllColor4b )(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); +static void ( APIENTRY * dllColor4bv )(const GLbyte *v); +static void ( APIENTRY * dllColor4d )(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); +static void ( APIENTRY * dllColor4dv )(const GLdouble *v); +static void ( APIENTRY * dllColor4f )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); +static void ( APIENTRY * dllColor4fv )(const GLfloat *v); +static void ( APIENTRY * dllColor4i )(GLint red, GLint green, GLint blue, GLint alpha); +static void ( APIENTRY * dllColor4iv )(const GLint *v); +static void ( APIENTRY * dllColor4s )(GLshort red, GLshort green, GLshort blue, GLshort alpha); +static void ( APIENTRY * dllColor4sv )(const GLshort *v); +static void ( APIENTRY * dllColor4ub )(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); +static void ( APIENTRY * dllColor4ubv )(const GLubyte *v); +static void ( APIENTRY * dllColor4ui )(GLuint red, GLuint green, GLuint blue, GLuint alpha); +static void ( APIENTRY * dllColor4uiv )(const GLuint *v); +static void ( APIENTRY * dllColor4us )(GLushort red, GLushort green, GLushort blue, GLushort alpha); +static void ( APIENTRY * dllColor4usv )(const GLushort *v); +static void ( APIENTRY * dllColorMask )(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +static void ( APIENTRY * dllColorMaterial )(GLenum face, GLenum mode); +static void ( APIENTRY * dllColorPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +static void ( APIENTRY * dllCopyPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); +static void ( APIENTRY * dllCopyTexImage1D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); +static void ( APIENTRY * dllCopyTexImage2D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +static void ( APIENTRY * dllCopyTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); +static void ( APIENTRY * dllCopyTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +static void ( APIENTRY * dllCullFace )(GLenum mode); +static void ( APIENTRY * dllDeleteLists )(GLuint list, GLsizei range); +static void ( APIENTRY * dllDeleteTextures )(GLsizei n, const GLuint *textures); +static void ( APIENTRY * dllDepthFunc )(GLenum func); +static void ( APIENTRY * dllDepthMask )(GLboolean flag); +static void ( APIENTRY * dllDepthRange )(GLclampd zNear, GLclampd zFar); +static void ( APIENTRY * dllDisable )(GLenum cap); +static void ( APIENTRY * dllDisableClientState )(GLenum array); +static void ( APIENTRY * dllDrawArrays )(GLenum mode, GLint first, GLsizei count); +static void ( APIENTRY * dllDrawBuffer )(GLenum mode); +static void ( APIENTRY * dllDrawElements )(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); +static void ( APIENTRY * dllDrawPixels )(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +static void ( APIENTRY * dllEdgeFlag )(GLboolean flag); +static void ( APIENTRY * dllEdgeFlagPointer )(GLsizei stride, const GLvoid *pointer); +static void ( APIENTRY * dllEdgeFlagv )(const GLboolean *flag); +static void ( APIENTRY * dllEnable )(GLenum cap); +static void ( APIENTRY * dllEnableClientState )(GLenum array); +static void ( APIENTRY * dllEnd )(void); +static void ( APIENTRY * dllEndList )(void); +static void ( APIENTRY * dllEvalCoord1d )(GLdouble u); +static void ( APIENTRY * dllEvalCoord1dv )(const GLdouble *u); +static void ( APIENTRY * dllEvalCoord1f )(GLfloat u); +static void ( APIENTRY * dllEvalCoord1fv )(const GLfloat *u); +static void ( APIENTRY * dllEvalCoord2d )(GLdouble u, GLdouble v); +static void ( APIENTRY * dllEvalCoord2dv )(const GLdouble *u); +static void ( APIENTRY * dllEvalCoord2f )(GLfloat u, GLfloat v); +static void ( APIENTRY * dllEvalCoord2fv )(const GLfloat *u); +static void ( APIENTRY * dllEvalMesh1 )(GLenum mode, GLint i1, GLint i2); +static void ( APIENTRY * dllEvalMesh2 )(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); +static void ( APIENTRY * dllEvalPoint1 )(GLint i); +static void ( APIENTRY * dllEvalPoint2 )(GLint i, GLint j); +static void ( APIENTRY * dllFeedbackBuffer )(GLsizei size, GLenum type, GLfloat *buffer); +static void ( APIENTRY * dllFinish )(void); +static void ( APIENTRY * dllFlush )(void); +static void ( APIENTRY * dllFogf )(GLenum pname, GLfloat param); +static void ( APIENTRY * dllFogfv )(GLenum pname, const GLfloat *params); +static void ( APIENTRY * dllFogi )(GLenum pname, GLint param); +static void ( APIENTRY * dllFogiv )(GLenum pname, const GLint *params); +static void ( APIENTRY * dllFrontFace )(GLenum mode); +static void ( APIENTRY * dllFrustum )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +GLuint ( APIENTRY * dllGenLists )(GLsizei range); +static void ( APIENTRY * dllGenTextures )(GLsizei n, GLuint *textures); +static void ( APIENTRY * dllGetBooleanv )(GLenum pname, GLboolean *params); +static void ( APIENTRY * dllGetClipPlane )(GLenum plane, GLdouble *equation); +static void ( APIENTRY * dllGetDoublev )(GLenum pname, GLdouble *params); +GLenum ( APIENTRY * dllGetError )(void); +static void ( APIENTRY * dllGetFloatv )(GLenum pname, GLfloat *params); +static void ( APIENTRY * dllGetIntegerv )(GLenum pname, GLint *params); +static void ( APIENTRY * dllGetLightfv )(GLenum light, GLenum pname, GLfloat *params); +static void ( APIENTRY * dllGetLightiv )(GLenum light, GLenum pname, GLint *params); +static void ( APIENTRY * dllGetMapdv )(GLenum target, GLenum query, GLdouble *v); +static void ( APIENTRY * dllGetMapfv )(GLenum target, GLenum query, GLfloat *v); +static void ( APIENTRY * dllGetMapiv )(GLenum target, GLenum query, GLint *v); +static void ( APIENTRY * dllGetMaterialfv )(GLenum face, GLenum pname, GLfloat *params); +static void ( APIENTRY * dllGetMaterialiv )(GLenum face, GLenum pname, GLint *params); +static void ( APIENTRY * dllGetPixelMapfv )(GLenum map, GLfloat *values); +static void ( APIENTRY * dllGetPixelMapuiv )(GLenum map, GLuint *values); +static void ( APIENTRY * dllGetPixelMapusv )(GLenum map, GLushort *values); +static void ( APIENTRY * dllGetPointerv )(GLenum pname, GLvoid* *params); +static void ( APIENTRY * dllGetPolygonStipple )(GLubyte *mask); +const GLubyte * ( APIENTRY * dllGetString )(GLenum name); +static void ( APIENTRY * dllGetTexEnvfv )(GLenum target, GLenum pname, GLfloat *params); +static void ( APIENTRY * dllGetTexEnviv )(GLenum target, GLenum pname, GLint *params); +static void ( APIENTRY * dllGetTexGendv )(GLenum coord, GLenum pname, GLdouble *params); +static void ( APIENTRY * dllGetTexGenfv )(GLenum coord, GLenum pname, GLfloat *params); +static void ( APIENTRY * dllGetTexGeniv )(GLenum coord, GLenum pname, GLint *params); +static void ( APIENTRY * dllGetTexImage )(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); +static void ( APIENTRY * dllGetTexLevelParameterfv )(GLenum target, GLint level, GLenum pname, GLfloat *params); +static void ( APIENTRY * dllGetTexLevelParameteriv )(GLenum target, GLint level, GLenum pname, GLint *params); +static void ( APIENTRY * dllGetTexParameterfv )(GLenum target, GLenum pname, GLfloat *params); +static void ( APIENTRY * dllGetTexParameteriv )(GLenum target, GLenum pname, GLint *params); +static void ( APIENTRY * dllHint )(GLenum target, GLenum mode); +static void ( APIENTRY * dllIndexMask )(GLuint mask); +static void ( APIENTRY * dllIndexPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); +static void ( APIENTRY * dllIndexd )(GLdouble c); +static void ( APIENTRY * dllIndexdv )(const GLdouble *c); +static void ( APIENTRY * dllIndexf )(GLfloat c); +static void ( APIENTRY * dllIndexfv )(const GLfloat *c); +static void ( APIENTRY * dllIndexi )(GLint c); +static void ( APIENTRY * dllIndexiv )(const GLint *c); +static void ( APIENTRY * dllIndexs )(GLshort c); +static void ( APIENTRY * dllIndexsv )(const GLshort *c); +static void ( APIENTRY * dllIndexub )(GLubyte c); +static void ( APIENTRY * dllIndexubv )(const GLubyte *c); +static void ( APIENTRY * dllInitNames )(void); +static void ( APIENTRY * dllInterleavedArrays )(GLenum format, GLsizei stride, const GLvoid *pointer); +GLboolean ( APIENTRY * dllIsEnabled )(GLenum cap); +GLboolean ( APIENTRY * dllIsList )(GLuint list); +GLboolean ( APIENTRY * dllIsTexture )(GLuint texture); +static void ( APIENTRY * dllLightModelf )(GLenum pname, GLfloat param); +static void ( APIENTRY * dllLightModelfv )(GLenum pname, const GLfloat *params); +static void ( APIENTRY * dllLightModeli )(GLenum pname, GLint param); +static void ( APIENTRY * dllLightModeliv )(GLenum pname, const GLint *params); +static void ( APIENTRY * dllLightf )(GLenum light, GLenum pname, GLfloat param); +static void ( APIENTRY * dllLightfv )(GLenum light, GLenum pname, const GLfloat *params); +static void ( APIENTRY * dllLighti )(GLenum light, GLenum pname, GLint param); +static void ( APIENTRY * dllLightiv )(GLenum light, GLenum pname, const GLint *params); +static void ( APIENTRY * dllLineStipple )(GLint factor, GLushort pattern); +static void ( APIENTRY * dllLineWidth )(GLfloat width); +static void ( APIENTRY * dllListBase )(GLuint base); +static void ( APIENTRY * dllLoadIdentity )(void); +static void ( APIENTRY * dllLoadMatrixd )(const GLdouble *m); +static void ( APIENTRY * dllLoadMatrixf )(const GLfloat *m); +static void ( APIENTRY * dllLoadName )(GLuint name); +static void ( APIENTRY * dllLogicOp )(GLenum opcode); +static void ( APIENTRY * dllMap1d )(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); +static void ( APIENTRY * dllMap1f )(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); +static void ( APIENTRY * dllMap2d )(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); +static void ( APIENTRY * dllMap2f )(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); +static void ( APIENTRY * dllMapGrid1d )(GLint un, GLdouble u1, GLdouble u2); +static void ( APIENTRY * dllMapGrid1f )(GLint un, GLfloat u1, GLfloat u2); +static void ( APIENTRY * dllMapGrid2d )(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); +static void ( APIENTRY * dllMapGrid2f )(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); +static void ( APIENTRY * dllMaterialf )(GLenum face, GLenum pname, GLfloat param); +static void ( APIENTRY * dllMaterialfv )(GLenum face, GLenum pname, const GLfloat *params); +static void ( APIENTRY * dllMateriali )(GLenum face, GLenum pname, GLint param); +static void ( APIENTRY * dllMaterialiv )(GLenum face, GLenum pname, const GLint *params); +static void ( APIENTRY * dllMatrixMode )(GLenum mode); +static void ( APIENTRY * dllMultMatrixd )(const GLdouble *m); +static void ( APIENTRY * dllMultMatrixf )(const GLfloat *m); +static void ( APIENTRY * dllNewList )(GLuint list, GLenum mode); +static void ( APIENTRY * dllNormal3b )(GLbyte nx, GLbyte ny, GLbyte nz); +static void ( APIENTRY * dllNormal3bv )(const GLbyte *v); +static void ( APIENTRY * dllNormal3d )(GLdouble nx, GLdouble ny, GLdouble nz); +static void ( APIENTRY * dllNormal3dv )(const GLdouble *v); +static void ( APIENTRY * dllNormal3f )(GLfloat nx, GLfloat ny, GLfloat nz); +static void ( APIENTRY * dllNormal3fv )(const GLfloat *v); +static void ( APIENTRY * dllNormal3i )(GLint nx, GLint ny, GLint nz); +static void ( APIENTRY * dllNormal3iv )(const GLint *v); +static void ( APIENTRY * dllNormal3s )(GLshort nx, GLshort ny, GLshort nz); +static void ( APIENTRY * dllNormal3sv )(const GLshort *v); +static void ( APIENTRY * dllNormalPointer )(GLenum type, GLsizei stride, const GLvoid *pointer); +static void ( APIENTRY * dllOrtho )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); +static void ( APIENTRY * dllPassThrough )(GLfloat token); +static void ( APIENTRY * dllPixelMapfv )(GLenum map, GLsizei mapsize, const GLfloat *values); +static void ( APIENTRY * dllPixelMapuiv )(GLenum map, GLsizei mapsize, const GLuint *values); +static void ( APIENTRY * dllPixelMapusv )(GLenum map, GLsizei mapsize, const GLushort *values); +static void ( APIENTRY * dllPixelStoref )(GLenum pname, GLfloat param); +static void ( APIENTRY * dllPixelStorei )(GLenum pname, GLint param); +static void ( APIENTRY * dllPixelTransferf )(GLenum pname, GLfloat param); +static void ( APIENTRY * dllPixelTransferi )(GLenum pname, GLint param); +static void ( APIENTRY * dllPixelZoom )(GLfloat xfactor, GLfloat yfactor); +static void ( APIENTRY * dllPointSize )(GLfloat size); +static void ( APIENTRY * dllPolygonMode )(GLenum face, GLenum mode); +static void ( APIENTRY * dllPolygonOffset )(GLfloat factor, GLfloat units); +static void ( APIENTRY * dllPolygonStipple )(const GLubyte *mask); +static void ( APIENTRY * dllPopAttrib )(void); +static void ( APIENTRY * dllPopClientAttrib )(void); +static void ( APIENTRY * dllPopMatrix )(void); +static void ( APIENTRY * dllPopName )(void); +static void ( APIENTRY * dllPrioritizeTextures )(GLsizei n, const GLuint *textures, const GLclampf *priorities); +static void ( APIENTRY * dllPushAttrib )(GLbitfield mask); +static void ( APIENTRY * dllPushClientAttrib )(GLbitfield mask); +static void ( APIENTRY * dllPushMatrix )(void); +static void ( APIENTRY * dllPushName )(GLuint name); +static void ( APIENTRY * dllRasterPos2d )(GLdouble x, GLdouble y); +static void ( APIENTRY * dllRasterPos2dv )(const GLdouble *v); +static void ( APIENTRY * dllRasterPos2f )(GLfloat x, GLfloat y); +static void ( APIENTRY * dllRasterPos2fv )(const GLfloat *v); +static void ( APIENTRY * dllRasterPos2i )(GLint x, GLint y); +static void ( APIENTRY * dllRasterPos2iv )(const GLint *v); +static void ( APIENTRY * dllRasterPos2s )(GLshort x, GLshort y); +static void ( APIENTRY * dllRasterPos2sv )(const GLshort *v); +static void ( APIENTRY * dllRasterPos3d )(GLdouble x, GLdouble y, GLdouble z); +static void ( APIENTRY * dllRasterPos3dv )(const GLdouble *v); +static void ( APIENTRY * dllRasterPos3f )(GLfloat x, GLfloat y, GLfloat z); +static void ( APIENTRY * dllRasterPos3fv )(const GLfloat *v); +static void ( APIENTRY * dllRasterPos3i )(GLint x, GLint y, GLint z); +static void ( APIENTRY * dllRasterPos3iv )(const GLint *v); +static void ( APIENTRY * dllRasterPos3s )(GLshort x, GLshort y, GLshort z); +static void ( APIENTRY * dllRasterPos3sv )(const GLshort *v); +static void ( APIENTRY * dllRasterPos4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +static void ( APIENTRY * dllRasterPos4dv )(const GLdouble *v); +static void ( APIENTRY * dllRasterPos4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +static void ( APIENTRY * dllRasterPos4fv )(const GLfloat *v); +static void ( APIENTRY * dllRasterPos4i )(GLint x, GLint y, GLint z, GLint w); +static void ( APIENTRY * dllRasterPos4iv )(const GLint *v); +static void ( APIENTRY * dllRasterPos4s )(GLshort x, GLshort y, GLshort z, GLshort w); +static void ( APIENTRY * dllRasterPos4sv )(const GLshort *v); +static void ( APIENTRY * dllReadBuffer )(GLenum mode); +static void ( APIENTRY * dllReadPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); +static void ( APIENTRY * dllRectd )(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); +static void ( APIENTRY * dllRectdv )(const GLdouble *v1, const GLdouble *v2); +static void ( APIENTRY * dllRectf )(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); +static void ( APIENTRY * dllRectfv )(const GLfloat *v1, const GLfloat *v2); +static void ( APIENTRY * dllRecti )(GLint x1, GLint y1, GLint x2, GLint y2); +static void ( APIENTRY * dllRectiv )(const GLint *v1, const GLint *v2); +static void ( APIENTRY * dllRects )(GLshort x1, GLshort y1, GLshort x2, GLshort y2); +static void ( APIENTRY * dllRectsv )(const GLshort *v1, const GLshort *v2); +GLint ( APIENTRY * dllRenderMode )(GLenum mode); +static void ( APIENTRY * dllRotated )(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); +static void ( APIENTRY * dllRotatef )(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); +static void ( APIENTRY * dllScaled )(GLdouble x, GLdouble y, GLdouble z); +static void ( APIENTRY * dllScalef )(GLfloat x, GLfloat y, GLfloat z); +static void ( APIENTRY * dllScissor )(GLint x, GLint y, GLsizei width, GLsizei height); +static void ( APIENTRY * dllSelectBuffer )(GLsizei size, GLuint *buffer); +static void ( APIENTRY * dllShadeModel )(GLenum mode); +static void ( APIENTRY * dllStencilFunc )(GLenum func, GLint ref, GLuint mask); +static void ( APIENTRY * dllStencilMask )(GLuint mask); +static void ( APIENTRY * dllStencilOp )(GLenum fail, GLenum zfail, GLenum zpass); +static void ( APIENTRY * dllTexCoord1d )(GLdouble s); +static void ( APIENTRY * dllTexCoord1dv )(const GLdouble *v); +static void ( APIENTRY * dllTexCoord1f )(GLfloat s); +static void ( APIENTRY * dllTexCoord1fv )(const GLfloat *v); +static void ( APIENTRY * dllTexCoord1i )(GLint s); +static void ( APIENTRY * dllTexCoord1iv )(const GLint *v); +static void ( APIENTRY * dllTexCoord1s )(GLshort s); +static void ( APIENTRY * dllTexCoord1sv )(const GLshort *v); +static void ( APIENTRY * dllTexCoord2d )(GLdouble s, GLdouble t); +static void ( APIENTRY * dllTexCoord2dv )(const GLdouble *v); +static void ( APIENTRY * dllTexCoord2f )(GLfloat s, GLfloat t); +static void ( APIENTRY * dllTexCoord2fv )(const GLfloat *v); +static void ( APIENTRY * dllTexCoord2i )(GLint s, GLint t); +static void ( APIENTRY * dllTexCoord2iv )(const GLint *v); +static void ( APIENTRY * dllTexCoord2s )(GLshort s, GLshort t); +static void ( APIENTRY * dllTexCoord2sv )(const GLshort *v); +static void ( APIENTRY * dllTexCoord3d )(GLdouble s, GLdouble t, GLdouble r); +static void ( APIENTRY * dllTexCoord3dv )(const GLdouble *v); +static void ( APIENTRY * dllTexCoord3f )(GLfloat s, GLfloat t, GLfloat r); +static void ( APIENTRY * dllTexCoord3fv )(const GLfloat *v); +static void ( APIENTRY * dllTexCoord3i )(GLint s, GLint t, GLint r); +static void ( APIENTRY * dllTexCoord3iv )(const GLint *v); +static void ( APIENTRY * dllTexCoord3s )(GLshort s, GLshort t, GLshort r); +static void ( APIENTRY * dllTexCoord3sv )(const GLshort *v); +static void ( APIENTRY * dllTexCoord4d )(GLdouble s, GLdouble t, GLdouble r, GLdouble q); +static void ( APIENTRY * dllTexCoord4dv )(const GLdouble *v); +static void ( APIENTRY * dllTexCoord4f )(GLfloat s, GLfloat t, GLfloat r, GLfloat q); +static void ( APIENTRY * dllTexCoord4fv )(const GLfloat *v); +static void ( APIENTRY * dllTexCoord4i )(GLint s, GLint t, GLint r, GLint q); +static void ( APIENTRY * dllTexCoord4iv )(const GLint *v); +static void ( APIENTRY * dllTexCoord4s )(GLshort s, GLshort t, GLshort r, GLshort q); +static void ( APIENTRY * dllTexCoord4sv )(const GLshort *v); +static void ( APIENTRY * dllTexCoordPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +static void ( APIENTRY * dllTexEnvf )(GLenum target, GLenum pname, GLfloat param); +static void ( APIENTRY * dllTexEnvfv )(GLenum target, GLenum pname, const GLfloat *params); +static void ( APIENTRY * dllTexEnvi )(GLenum target, GLenum pname, GLint param); +static void ( APIENTRY * dllTexEnviv )(GLenum target, GLenum pname, const GLint *params); +static void ( APIENTRY * dllTexGend )(GLenum coord, GLenum pname, GLdouble param); +static void ( APIENTRY * dllTexGendv )(GLenum coord, GLenum pname, const GLdouble *params); +static void ( APIENTRY * dllTexGenf )(GLenum coord, GLenum pname, GLfloat param); +static void ( APIENTRY * dllTexGenfv )(GLenum coord, GLenum pname, const GLfloat *params); +static void ( APIENTRY * dllTexGeni )(GLenum coord, GLenum pname, GLint param); +static void ( APIENTRY * dllTexGeniv )(GLenum coord, GLenum pname, const GLint *params); +static void ( APIENTRY * dllTexImage1D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +static void ( APIENTRY * dllTexImage2D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +static void ( APIENTRY * dllTexParameterf )(GLenum target, GLenum pname, GLfloat param); +static void ( APIENTRY * dllTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params); +static void ( APIENTRY * dllTexParameteri )(GLenum target, GLenum pname, GLint param); +static void ( APIENTRY * dllTexParameteriv )(GLenum target, GLenum pname, const GLint *params); +static void ( APIENTRY * dllTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); +static void ( APIENTRY * dllTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +static void ( APIENTRY * dllTranslated )(GLdouble x, GLdouble y, GLdouble z); +static void ( APIENTRY * dllTranslatef )(GLfloat x, GLfloat y, GLfloat z); +static void ( APIENTRY * dllVertex2d )(GLdouble x, GLdouble y); +static void ( APIENTRY * dllVertex2dv )(const GLdouble *v); +static void ( APIENTRY * dllVertex2f )(GLfloat x, GLfloat y); +static void ( APIENTRY * dllVertex2fv )(const GLfloat *v); +static void ( APIENTRY * dllVertex2i )(GLint x, GLint y); +static void ( APIENTRY * dllVertex2iv )(const GLint *v); +static void ( APIENTRY * dllVertex2s )(GLshort x, GLshort y); +static void ( APIENTRY * dllVertex2sv )(const GLshort *v); +static void ( APIENTRY * dllVertex3d )(GLdouble x, GLdouble y, GLdouble z); +static void ( APIENTRY * dllVertex3dv )(const GLdouble *v); +static void ( APIENTRY * dllVertex3f )(GLfloat x, GLfloat y, GLfloat z); +static void ( APIENTRY * dllVertex3fv )(const GLfloat *v); +static void ( APIENTRY * dllVertex3i )(GLint x, GLint y, GLint z); +static void ( APIENTRY * dllVertex3iv )(const GLint *v); +static void ( APIENTRY * dllVertex3s )(GLshort x, GLshort y, GLshort z); +static void ( APIENTRY * dllVertex3sv )(const GLshort *v); +static void ( APIENTRY * dllVertex4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w); +static void ( APIENTRY * dllVertex4dv )(const GLdouble *v); +static void ( APIENTRY * dllVertex4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w); +static void ( APIENTRY * dllVertex4fv )(const GLfloat *v); +static void ( APIENTRY * dllVertex4i )(GLint x, GLint y, GLint z, GLint w); +static void ( APIENTRY * dllVertex4iv )(const GLint *v); +static void ( APIENTRY * dllVertex4s )(GLshort x, GLshort y, GLshort z, GLshort w); +static void ( APIENTRY * dllVertex4sv )(const GLshort *v); +static void ( APIENTRY * dllVertexPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); +static void ( APIENTRY * dllViewport )(GLint x, GLint y, GLsizei width, GLsizei height); + +static const char * BooleanToString( GLboolean b ) +{ +	if ( b == GL_FALSE ) +		return "GL_FALSE"; +	else if ( b == GL_TRUE ) +		return "GL_TRUE"; +	else +		return "OUT OF RANGE FOR BOOLEAN"; +} + +static const char * FuncToString( GLenum f ) +{ +	switch ( f ) +	{ +	case GL_ALWAYS: +		return "GL_ALWAYS"; +	case GL_NEVER: +		return "GL_NEVER"; +	case GL_LEQUAL: +		return "GL_LEQUAL"; +	case GL_LESS: +		return "GL_LESS"; +	case GL_EQUAL: +		return "GL_EQUAL"; +	case GL_GREATER: +		return "GL_GREATER"; +	case GL_GEQUAL: +		return "GL_GEQUAL"; +	case GL_NOTEQUAL: +		return "GL_NOTEQUAL"; +	default: +		return "!!! UNKNOWN !!!"; +	} +} + +static const char * PrimToString( GLenum mode ) +{ +	static char prim[1024]; + +	if ( mode == GL_TRIANGLES ) +		strcpy( prim, "GL_TRIANGLES" ); +	else if ( mode == GL_TRIANGLE_STRIP ) +		strcpy( prim, "GL_TRIANGLE_STRIP" ); +	else if ( mode == GL_TRIANGLE_FAN ) +		strcpy( prim, "GL_TRIANGLE_FAN" ); +	else if ( mode == GL_QUADS ) +		strcpy( prim, "GL_QUADS" ); +	else if ( mode == GL_QUAD_STRIP ) +		strcpy( prim, "GL_QUAD_STRIP" ); +	else if ( mode == GL_POLYGON ) +		strcpy( prim, "GL_POLYGON" ); +	else if ( mode == GL_POINTS ) +		strcpy( prim, "GL_POINTS" ); +	else if ( mode == GL_LINES ) +		strcpy( prim, "GL_LINES" ); +	else if ( mode == GL_LINE_STRIP ) +		strcpy( prim, "GL_LINE_STRIP" ); +	else if ( mode == GL_LINE_LOOP ) +		strcpy( prim, "GL_LINE_LOOP" ); +	else +		sprintf( prim, "0x%x", mode ); + +	return prim; +} + +static const char * CapToString( GLenum cap ) +{ +	static char buffer[1024]; + +	switch ( cap ) +	{ +	case GL_TEXTURE_2D: +		return "GL_TEXTURE_2D"; +	case GL_BLEND: +		return "GL_BLEND"; +	case GL_DEPTH_TEST: +		return "GL_DEPTH_TEST"; +	case GL_CULL_FACE: +		return "GL_CULL_FACE"; +	case GL_CLIP_PLANE0: +		return "GL_CLIP_PLANE0"; +	case GL_COLOR_ARRAY: +		return "GL_COLOR_ARRAY"; +	case GL_TEXTURE_COORD_ARRAY: +		return "GL_TEXTURE_COORD_ARRAY"; +	case GL_VERTEX_ARRAY: +		return "GL_VERTEX_ARRAY"; +	case GL_ALPHA_TEST: +		return "GL_ALPHA_TEST"; +	case GL_STENCIL_TEST: +		return "GL_STENCIL_TEST"; +	default: +		sprintf( buffer, "0x%x", cap ); +	} + +	return buffer; +} + +static const char * TypeToString( GLenum t ) +{ +	switch ( t ) +	{ +	case GL_BYTE: +		return "GL_BYTE"; +	case GL_UNSIGNED_BYTE: +		return "GL_UNSIGNED_BYTE"; +	case GL_SHORT: +		return "GL_SHORT"; +	case GL_UNSIGNED_SHORT: +		return "GL_UNSIGNED_SHORT"; +	case GL_INT: +		return "GL_INT"; +	case GL_UNSIGNED_INT: +		return "GL_UNSIGNED_INT"; +	case GL_FLOAT: +		return "GL_FLOAT"; +	case GL_DOUBLE: +		return "GL_DOUBLE"; +	default: +		return "!!! UNKNOWN !!!"; +	} +} + +static void APIENTRY logAccum(GLenum op, GLfloat value) +{ +	fprintf( glw_state.log_fp, "glAccum\n" ); +	dllAccum( op, value ); +} + +static void APIENTRY logAlphaFunc(GLenum func, GLclampf ref) +{ +	fprintf( glw_state.log_fp, "glAlphaFunc( 0x%x, %f )\n", func, ref ); +	dllAlphaFunc( func, ref ); +} + +static GLboolean APIENTRY logAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences) +{ +	fprintf( glw_state.log_fp, "glAreTexturesResident\n" ); +	return dllAreTexturesResident( n, textures, residences ); +} + +static void APIENTRY logArrayElement(GLint i) +{ +	fprintf( glw_state.log_fp, "glArrayElement\n" ); +	dllArrayElement( i ); +} + +static void APIENTRY logBegin(GLenum mode) +{ +	fprintf( glw_state.log_fp, "glBegin( %s )\n", PrimToString( mode )); +	dllBegin( mode ); +} + +static void APIENTRY logBindTexture(GLenum target, GLuint texture) +{ +	fprintf( glw_state.log_fp, "glBindTexture( 0x%x, %u )\n", target, texture ); +	dllBindTexture( target, texture ); +} + +static void APIENTRY logBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap) +{ +	fprintf( glw_state.log_fp, "glBitmap\n" ); +	dllBitmap( width, height, xorig, yorig, xmove, ymove, bitmap ); +} + +static void BlendToName( char *n, GLenum f ) +{ +	switch ( f ) +	{ +	case GL_ONE: +		strcpy( n, "GL_ONE" ); +		break; +	case GL_ZERO: +		strcpy( n, "GL_ZERO" ); +		break; +	case GL_SRC_ALPHA: +		strcpy( n, "GL_SRC_ALPHA" ); +		break; +	case GL_ONE_MINUS_SRC_ALPHA: +		strcpy( n, "GL_ONE_MINUS_SRC_ALPHA" ); +		break; +	case GL_DST_COLOR: +		strcpy( n, "GL_DST_COLOR" ); +		break; +	case GL_ONE_MINUS_DST_COLOR: +		strcpy( n, "GL_ONE_MINUS_DST_COLOR" ); +		break; +	case GL_DST_ALPHA: +		strcpy( n, "GL_DST_ALPHA" ); +		break; +	default: +		sprintf( n, "0x%x", f ); +	} +} +static void APIENTRY logBlendFunc(GLenum sfactor, GLenum dfactor) +{ +	char sf[128], df[128]; + +	BlendToName( sf, sfactor ); +	BlendToName( df, dfactor ); + +	fprintf( glw_state.log_fp, "glBlendFunc( %s, %s )\n", sf, df ); +	dllBlendFunc( sfactor, dfactor ); +} + +static void APIENTRY logCallList(GLuint list) +{ +	fprintf( glw_state.log_fp, "glCallList( %u )\n", list ); +	dllCallList( list ); +} + +static void APIENTRY logCallLists(GLsizei n, GLenum type, const void *lists) +{ +	fprintf( glw_state.log_fp, "glCallLists\n" ); +	dllCallLists( n, type, lists ); +} + +static void APIENTRY logClear(GLbitfield mask) +{ +	fprintf( glw_state.log_fp, "glClear( 0x%x = ", mask ); + +	if ( mask & GL_COLOR_BUFFER_BIT ) +		fprintf( glw_state.log_fp, "GL_COLOR_BUFFER_BIT " ); +	if ( mask & GL_DEPTH_BUFFER_BIT ) +		fprintf( glw_state.log_fp, "GL_DEPTH_BUFFER_BIT " ); +	if ( mask & GL_STENCIL_BUFFER_BIT ) +		fprintf( glw_state.log_fp, "GL_STENCIL_BUFFER_BIT " ); +	if ( mask & GL_ACCUM_BUFFER_BIT ) +		fprintf( glw_state.log_fp, "GL_ACCUM_BUFFER_BIT " ); + +	fprintf( glw_state.log_fp, ")\n" ); +	dllClear( mask ); +} + +static void APIENTRY logClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ +	fprintf( glw_state.log_fp, "glClearAccum\n" ); +	dllClearAccum( red, green, blue, alpha ); +} + +static void APIENTRY logClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +{ +	fprintf( glw_state.log_fp, "glClearColor\n" ); +	dllClearColor( red, green, blue, alpha ); +} + +static void APIENTRY logClearDepth(GLclampd depth) +{ +	fprintf( glw_state.log_fp, "glClearDepth( %f )\n", ( float ) depth ); +	dllClearDepth( depth ); +} + +static void APIENTRY logClearIndex(GLfloat c) +{ +	fprintf( glw_state.log_fp, "glClearIndex\n" ); +	dllClearIndex( c ); +} + +static void APIENTRY logClearStencil(GLint s) +{ +	fprintf( glw_state.log_fp, "glClearStencil( %d )\n", s ); +	dllClearStencil( s ); +} + +static void APIENTRY logClipPlane(GLenum plane, const GLdouble *equation) +{ +	fprintf( glw_state.log_fp, "glClipPlane\n" ); +	dllClipPlane( plane, equation ); +} + +static void APIENTRY logColor3b(GLbyte red, GLbyte green, GLbyte blue) +{ +	fprintf( glw_state.log_fp, "glColor3b\n" ); +	dllColor3b( red, green, blue ); +} + +static void APIENTRY logColor3bv(const GLbyte *v) +{ +	fprintf( glw_state.log_fp, "glColor3bv\n" ); +	dllColor3bv( v ); +} + +static void APIENTRY logColor3d(GLdouble red, GLdouble green, GLdouble blue) +{ +	fprintf( glw_state.log_fp, "glColor3d\n" ); +	dllColor3d( red, green, blue ); +} + +static void APIENTRY logColor3dv(const GLdouble *v) +{ +	fprintf( glw_state.log_fp, "glColor3dv\n" ); +	dllColor3dv( v ); +} + +static void APIENTRY logColor3f(GLfloat red, GLfloat green, GLfloat blue) +{ +	fprintf( glw_state.log_fp, "glColor3f\n" ); +	dllColor3f( red, green, blue ); +} + +static void APIENTRY logColor3fv(const GLfloat *v) +{ +	fprintf( glw_state.log_fp, "glColor3fv\n" ); +	dllColor3fv( v ); +} + +static void APIENTRY logColor3i(GLint red, GLint green, GLint blue) +{ +	fprintf( glw_state.log_fp, "glColor3i\n" ); +	dllColor3i( red, green, blue ); +} + +static void APIENTRY logColor3iv(const GLint *v) +{ +	fprintf( glw_state.log_fp, "glColor3iv\n" ); +	dllColor3iv( v ); +} + +static void APIENTRY logColor3s(GLshort red, GLshort green, GLshort blue) +{ +	fprintf( glw_state.log_fp, "glColor3s\n" ); +	dllColor3s( red, green, blue ); +} + +static void APIENTRY logColor3sv(const GLshort *v) +{ +	fprintf( glw_state.log_fp, "glColor3sv\n" ); +	dllColor3sv( v ); +} + +static void APIENTRY logColor3ub(GLubyte red, GLubyte green, GLubyte blue) +{ +	fprintf( glw_state.log_fp, "glColor3ub\n" ); +	dllColor3ub( red, green, blue ); +} + +static void APIENTRY logColor3ubv(const GLubyte *v) +{ +	fprintf( glw_state.log_fp, "glColor3ubv\n" ); +	dllColor3ubv( v ); +} + +#define SIG( x ) fprintf( glw_state.log_fp, x "\n" ) + +static void APIENTRY logColor3ui(GLuint red, GLuint green, GLuint blue) +{ +	SIG( "glColor3ui" ); +	dllColor3ui( red, green, blue ); +} + +static void APIENTRY logColor3uiv(const GLuint *v) +{ +	SIG( "glColor3uiv" ); +	dllColor3uiv( v ); +} + +static void APIENTRY logColor3us(GLushort red, GLushort green, GLushort blue) +{ +	SIG( "glColor3us" ); +	dllColor3us( red, green, blue ); +} + +static void APIENTRY logColor3usv(const GLushort *v) +{ +	SIG( "glColor3usv" ); +	dllColor3usv( v ); +} + +static void APIENTRY logColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) +{ +	SIG( "glColor4b" ); +	dllColor4b( red, green, blue, alpha ); +} + +static void APIENTRY logColor4bv(const GLbyte *v) +{ +	SIG( "glColor4bv" ); +	dllColor4bv( v ); +} + +static void APIENTRY logColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha) +{ +	SIG( "glColor4d" ); +	dllColor4d( red, green, blue, alpha ); +} +static void APIENTRY logColor4dv(const GLdouble *v) +{ +	SIG( "glColor4dv" ); +	dllColor4dv( v ); +} +static void APIENTRY logColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +{ +	fprintf( glw_state.log_fp, "glColor4f( %f,%f,%f,%f )\n", red, green, blue, alpha ); +	dllColor4f( red, green, blue, alpha ); +} +static void APIENTRY logColor4fv(const GLfloat *v) +{ +	fprintf( glw_state.log_fp, "glColor4fv( %f,%f,%f,%f )\n", v[0], v[1], v[2], v[3] ); +	dllColor4fv( v ); +} +static void APIENTRY logColor4i(GLint red, GLint green, GLint blue, GLint alpha) +{ +	SIG( "glColor4i" ); +	dllColor4i( red, green, blue, alpha ); +} +static void APIENTRY logColor4iv(const GLint *v) +{ +	SIG( "glColor4iv" ); +	dllColor4iv( v ); +} +static void APIENTRY logColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha) +{ +	SIG( "glColor4s" ); +	dllColor4s( red, green, blue, alpha ); +} +static void APIENTRY logColor4sv(const GLshort *v) +{ +	SIG( "glColor4sv" ); +	dllColor4sv( v ); +} +static void APIENTRY logColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) +{ +	SIG( "glColor4b" ); +	dllColor4b( red, green, blue, alpha ); +} +static void APIENTRY logColor4ubv(const GLubyte *v) +{ +	SIG( "glColor4ubv" ); +	dllColor4ubv( v ); +} +static void APIENTRY logColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha) +{ +	SIG( "glColor4ui" ); +	dllColor4ui( red, green, blue, alpha ); +} +static void APIENTRY logColor4uiv(const GLuint *v) +{ +	SIG( "glColor4uiv" ); +	dllColor4uiv( v ); +} +static void APIENTRY logColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha) +{ +	SIG( "glColor4us" ); +	dllColor4us( red, green, blue, alpha ); +} +static void APIENTRY logColor4usv(const GLushort *v) +{ +	SIG( "glColor4usv" ); +	dllColor4usv( v ); +} +static void APIENTRY logColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +{ +	SIG( "glColorMask" ); +	dllColorMask( red, green, blue, alpha ); +} +static void APIENTRY logColorMaterial(GLenum face, GLenum mode) +{ +	SIG( "glColorMaterial" ); +	dllColorMaterial( face, mode ); +} + +static void APIENTRY logColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) +{ +	fprintf( glw_state.log_fp, "glColorPointer( %d, %s, %d, MEM )\n", size, TypeToString( type ), stride ); +	dllColorPointer( size, type, stride, pointer ); +} + +static void APIENTRY logCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) +{ +	SIG( "glCopyPixels" ); +	dllCopyPixels( x, y, width, height, type ); +} + +static void APIENTRY logCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border) +{ +	SIG( "glCopyTexImage1D" ); +	dllCopyTexImage1D( target, level, internalFormat, x, y, width, border ); +} + +static void APIENTRY logCopyTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +{ +	SIG( "glCopyTexImage2D" ); +	dllCopyTexImage2D( target, level, internalFormat, x, y, width, height, border ); +} + +static void APIENTRY logCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) +{ +	SIG( "glCopyTexSubImage1D" ); +	dllCopyTexSubImage1D( target, level, xoffset, x, y, width ); +} + +static void APIENTRY logCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +{ +	SIG( "glCopyTexSubImage2D" ); +	dllCopyTexSubImage2D( target, level, xoffset, yoffset, x, y, width, height ); +} + +static void APIENTRY logCullFace(GLenum mode) +{ +	fprintf( glw_state.log_fp, "glCullFace( %s )\n", ( mode == GL_FRONT ) ? "GL_FRONT" : "GL_BACK" ); +	dllCullFace( mode ); +} + +static void APIENTRY logDeleteLists(GLuint list, GLsizei range) +{ +	SIG( "glDeleteLists" ); +	dllDeleteLists( list, range ); +} + +static void APIENTRY logDeleteTextures(GLsizei n, const GLuint *textures) +{ +	SIG( "glDeleteTextures" ); +	dllDeleteTextures( n, textures ); +} + +static void APIENTRY logDepthFunc(GLenum func) +{ +	fprintf( glw_state.log_fp, "glDepthFunc( %s )\n", FuncToString( func ) ); +	dllDepthFunc( func ); +} + +static void APIENTRY logDepthMask(GLboolean flag) +{ +	fprintf( glw_state.log_fp, "glDepthMask( %s )\n", BooleanToString( flag ) ); +	dllDepthMask( flag ); +} + +static void APIENTRY logDepthRange(GLclampd zNear, GLclampd zFar) +{ +	fprintf( glw_state.log_fp, "glDepthRange( %f, %f )\n", ( float ) zNear, ( float ) zFar ); +	dllDepthRange( zNear, zFar ); +} + +static void APIENTRY logDisable(GLenum cap) +{ +	fprintf( glw_state.log_fp, "glDisable( %s )\n", CapToString( cap ) ); +	dllDisable( cap ); +} + +static void APIENTRY logDisableClientState(GLenum array) +{ +	fprintf( glw_state.log_fp, "glDisableClientState( %s )\n", CapToString( array ) ); +	dllDisableClientState( array ); +} + +static void APIENTRY logDrawArrays(GLenum mode, GLint first, GLsizei count) +{ +	SIG( "glDrawArrays" ); +	dllDrawArrays( mode, first, count ); +} + +static void APIENTRY logDrawBuffer(GLenum mode) +{ +	SIG( "glDrawBuffer" ); +	dllDrawBuffer( mode ); +} + +static void APIENTRY logDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) +{ +	fprintf( glw_state.log_fp, "glDrawElements( %s, %d, %s, MEM )\n", PrimToString( mode ), count, TypeToString( type ) ); +	dllDrawElements( mode, count, type, indices ); +} + +static void APIENTRY logDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) +{ +	SIG( "glDrawPixels" ); +	dllDrawPixels( width, height, format, type, pixels ); +} + +static void APIENTRY logEdgeFlag(GLboolean flag) +{ +	SIG( "glEdgeFlag" ); +	dllEdgeFlag( flag ); +} + +static void APIENTRY logEdgeFlagPointer(GLsizei stride, const void *pointer) +{ +	SIG( "glEdgeFlagPointer" ); +	dllEdgeFlagPointer( stride, pointer ); +} + +static void APIENTRY logEdgeFlagv(const GLboolean *flag) +{ +	SIG( "glEdgeFlagv" ); +	dllEdgeFlagv( flag ); +} + +static void APIENTRY logEnable(GLenum cap) +{ +	fprintf( glw_state.log_fp, "glEnable( %s )\n", CapToString( cap ) ); +	dllEnable( cap ); +} + +static void APIENTRY logEnableClientState(GLenum array) +{ +	fprintf( glw_state.log_fp, "glEnableClientState( %s )\n", CapToString( array ) ); +	dllEnableClientState( array ); +} + +static void APIENTRY logEnd(void) +{ +	SIG( "glEnd" ); +	dllEnd(); +} + +static void APIENTRY logEndList(void) +{ +	SIG( "glEndList" ); +	dllEndList(); +} + +static void APIENTRY logEvalCoord1d(GLdouble u) +{ +	SIG( "glEvalCoord1d" ); +	dllEvalCoord1d( u ); +} + +static void APIENTRY logEvalCoord1dv(const GLdouble *u) +{ +	SIG( "glEvalCoord1dv" ); +	dllEvalCoord1dv( u ); +} + +static void APIENTRY logEvalCoord1f(GLfloat u) +{ +	SIG( "glEvalCoord1f" ); +	dllEvalCoord1f( u ); +} + +static void APIENTRY logEvalCoord1fv(const GLfloat *u) +{ +	SIG( "glEvalCoord1fv" ); +	dllEvalCoord1fv( u ); +} +static void APIENTRY logEvalCoord2d(GLdouble u, GLdouble v) +{ +	SIG( "glEvalCoord2d" ); +	dllEvalCoord2d( u, v ); +} +static void APIENTRY logEvalCoord2dv(const GLdouble *u) +{ +	SIG( "glEvalCoord2dv" ); +	dllEvalCoord2dv( u ); +} +static void APIENTRY logEvalCoord2f(GLfloat u, GLfloat v) +{ +	SIG( "glEvalCoord2f" ); +	dllEvalCoord2f( u, v ); +} +static void APIENTRY logEvalCoord2fv(const GLfloat *u) +{ +	SIG( "glEvalCoord2fv" ); +	dllEvalCoord2fv( u ); +} + +static void APIENTRY logEvalMesh1(GLenum mode, GLint i1, GLint i2) +{ +	SIG( "glEvalMesh1" ); +	dllEvalMesh1( mode, i1, i2 ); +} +static void APIENTRY logEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) +{ +	SIG( "glEvalMesh2" ); +	dllEvalMesh2( mode, i1, i2, j1, j2 ); +} +static void APIENTRY logEvalPoint1(GLint i) +{ +	SIG( "glEvalPoint1" ); +	dllEvalPoint1( i ); +} +static void APIENTRY logEvalPoint2(GLint i, GLint j) +{ +	SIG( "glEvalPoint2" ); +	dllEvalPoint2( i, j ); +} + +static void APIENTRY logFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer) +{ +	SIG( "glFeedbackBuffer" ); +	dllFeedbackBuffer( size, type, buffer ); +} + +static void APIENTRY logFinish(void) +{ +	SIG( "glFinish" ); +	dllFinish(); +} + +static void APIENTRY logFlush(void) +{ +	SIG( "glFlush" ); +	dllFlush(); +} + +static void APIENTRY logFogf(GLenum pname, GLfloat param) +{ +	SIG( "glFogf" ); +	dllFogf( pname, param ); +} + +static void APIENTRY logFogfv(GLenum pname, const GLfloat *params) +{ +	SIG( "glFogfv" ); +	dllFogfv( pname, params ); +} + +static void APIENTRY logFogi(GLenum pname, GLint param) +{ +	SIG( "glFogi" ); +	dllFogi( pname, param ); +} + +static void APIENTRY logFogiv(GLenum pname, const GLint *params) +{ +	SIG( "glFogiv" ); +	dllFogiv( pname, params ); +} + +static void APIENTRY logFrontFace(GLenum mode) +{ +	SIG( "glFrontFace" ); +	dllFrontFace( mode ); +} + +static void APIENTRY logFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) +{ +	SIG( "glFrustum" ); +	dllFrustum( left, right, bottom, top, zNear, zFar ); +} + +static GLuint APIENTRY logGenLists(GLsizei range) +{ +	SIG( "glGenLists" ); +	return dllGenLists( range ); +} + +static void APIENTRY logGenTextures(GLsizei n, GLuint *textures) +{ +	SIG( "glGenTextures" ); +	dllGenTextures( n, textures ); +} + +static void APIENTRY logGetBooleanv(GLenum pname, GLboolean *params) +{ +	SIG( "glGetBooleanv" ); +	dllGetBooleanv( pname, params ); +} + +static void APIENTRY logGetClipPlane(GLenum plane, GLdouble *equation) +{ +	SIG( "glGetClipPlane" ); +	dllGetClipPlane( plane, equation ); +} + +static void APIENTRY logGetDoublev(GLenum pname, GLdouble *params) +{ +	SIG( "glGetDoublev" ); +	dllGetDoublev( pname, params ); +} + +static GLenum APIENTRY logGetError(void) +{ +	SIG( "glGetError" ); +	return dllGetError(); +} + +static void APIENTRY logGetFloatv(GLenum pname, GLfloat *params) +{ +	SIG( "glGetFloatv" ); +	dllGetFloatv( pname, params ); +} + +static void APIENTRY logGetIntegerv(GLenum pname, GLint *params) +{ +	SIG( "glGetIntegerv" ); +	dllGetIntegerv( pname, params ); +} + +static void APIENTRY logGetLightfv(GLenum light, GLenum pname, GLfloat *params) +{ +	SIG( "glGetLightfv" ); +	dllGetLightfv( light, pname, params ); +} + +static void APIENTRY logGetLightiv(GLenum light, GLenum pname, GLint *params) +{ +	SIG( "glGetLightiv" ); +	dllGetLightiv( light, pname, params ); +} + +static void APIENTRY logGetMapdv(GLenum target, GLenum query, GLdouble *v) +{ +	SIG( "glGetMapdv" ); +	dllGetMapdv( target, query, v ); +} + +static void APIENTRY logGetMapfv(GLenum target, GLenum query, GLfloat *v) +{ +	SIG( "glGetMapfv" ); +	dllGetMapfv( target, query, v ); +} + +static void APIENTRY logGetMapiv(GLenum target, GLenum query, GLint *v) +{ +	SIG( "glGetMapiv" ); +	dllGetMapiv( target, query, v ); +} + +static void APIENTRY logGetMaterialfv(GLenum face, GLenum pname, GLfloat *params) +{ +	SIG( "glGetMaterialfv" ); +	dllGetMaterialfv( face, pname, params ); +} + +static void APIENTRY logGetMaterialiv(GLenum face, GLenum pname, GLint *params) +{ +	SIG( "glGetMaterialiv" ); +	dllGetMaterialiv( face, pname, params ); +} + +static void APIENTRY logGetPixelMapfv(GLenum map, GLfloat *values) +{ +	SIG( "glGetPixelMapfv" ); +	dllGetPixelMapfv( map, values ); +} + +static void APIENTRY logGetPixelMapuiv(GLenum map, GLuint *values) +{ +	SIG( "glGetPixelMapuiv" ); +	dllGetPixelMapuiv( map, values ); +} + +static void APIENTRY logGetPixelMapusv(GLenum map, GLushort *values) +{ +	SIG( "glGetPixelMapusv" ); +	dllGetPixelMapusv( map, values ); +} + +static void APIENTRY logGetPointerv(GLenum pname, GLvoid* *params) +{ +	SIG( "glGetPointerv" ); +	dllGetPointerv( pname, params ); +} + +static void APIENTRY logGetPolygonStipple(GLubyte *mask) +{ +	SIG( "glGetPolygonStipple" ); +	dllGetPolygonStipple( mask ); +} + +static const GLubyte * APIENTRY logGetString(GLenum name) +{ +	SIG( "glGetString" ); +	return dllGetString( name ); +} + +static void APIENTRY logGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params) +{ +	SIG( "glGetTexEnvfv" ); +	dllGetTexEnvfv( target, pname, params ); +} + +static void APIENTRY logGetTexEnviv(GLenum target, GLenum pname, GLint *params) +{ +	SIG( "glGetTexEnviv" ); +	dllGetTexEnviv( target, pname, params ); +} + +static void APIENTRY logGetTexGendv(GLenum coord, GLenum pname, GLdouble *params) +{ +	SIG( "glGetTexGendv" ); +	dllGetTexGendv( coord, pname, params ); +} + +static void APIENTRY logGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params) +{ +	SIG( "glGetTexGenfv" ); +	dllGetTexGenfv( coord, pname, params ); +} + +static void APIENTRY logGetTexGeniv(GLenum coord, GLenum pname, GLint *params) +{ +	SIG( "glGetTexGeniv" ); +	dllGetTexGeniv( coord, pname, params ); +} + +static void APIENTRY logGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void *pixels) +{ +	SIG( "glGetTexImage" ); +	dllGetTexImage( target, level, format, type, pixels ); +} +static void APIENTRY logGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params ) +{ +	SIG( "glGetTexLevelParameterfv" ); +	dllGetTexLevelParameterfv( target, level, pname, params ); +} + +static void APIENTRY logGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) +{ +	SIG( "glGetTexLevelParameteriv" ); +	dllGetTexLevelParameteriv( target, level, pname, params ); +} + +static void APIENTRY logGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) +{ +	SIG( "glGetTexParameterfv" ); +	dllGetTexParameterfv( target, pname, params ); +} + +static void APIENTRY logGetTexParameteriv(GLenum target, GLenum pname, GLint *params) +{ +	SIG( "glGetTexParameteriv" ); +	dllGetTexParameteriv( target, pname, params ); +} + +static void APIENTRY logHint(GLenum target, GLenum mode) +{ +	fprintf( glw_state.log_fp, "glHint( 0x%x, 0x%x )\n", target, mode ); +	dllHint( target, mode ); +} + +static void APIENTRY logIndexMask(GLuint mask) +{ +	SIG( "glIndexMask" ); +	dllIndexMask( mask ); +} + +static void APIENTRY logIndexPointer(GLenum type, GLsizei stride, const void *pointer) +{ +	SIG( "glIndexPointer" ); +	dllIndexPointer( type, stride, pointer ); +} + +static void APIENTRY logIndexd(GLdouble c) +{ +	SIG( "glIndexd" ); +	dllIndexd( c ); +} + +static void APIENTRY logIndexdv(const GLdouble *c) +{ +	SIG( "glIndexdv" ); +	dllIndexdv( c ); +} + +static void APIENTRY logIndexf(GLfloat c) +{ +	SIG( "glIndexf" ); +	dllIndexf( c ); +} + +static void APIENTRY logIndexfv(const GLfloat *c) +{ +	SIG( "glIndexfv" ); +	dllIndexfv( c ); +} + +static void APIENTRY logIndexi(GLint c) +{ +	SIG( "glIndexi" ); +	dllIndexi( c ); +} + +static void APIENTRY logIndexiv(const GLint *c) +{ +	SIG( "glIndexiv" ); +	dllIndexiv( c ); +} + +static void APIENTRY logIndexs(GLshort c) +{ +	SIG( "glIndexs" ); +	dllIndexs( c ); +} + +static void APIENTRY logIndexsv(const GLshort *c) +{ +	SIG( "glIndexsv" ); +	dllIndexsv( c ); +} + +static void APIENTRY logIndexub(GLubyte c) +{ +	SIG( "glIndexub" ); +	dllIndexub( c ); +} + +static void APIENTRY logIndexubv(const GLubyte *c) +{ +	SIG( "glIndexubv" ); +	dllIndexubv( c ); +} + +static void APIENTRY logInitNames(void) +{ +	SIG( "glInitNames" ); +	dllInitNames(); +} + +static void APIENTRY logInterleavedArrays(GLenum format, GLsizei stride, const void *pointer) +{ +	SIG( "glInterleavedArrays" ); +	dllInterleavedArrays( format, stride, pointer ); +} + +static GLboolean APIENTRY logIsEnabled(GLenum cap) +{ +	SIG( "glIsEnabled" ); +	return dllIsEnabled( cap ); +} +static GLboolean APIENTRY logIsList(GLuint list) +{ +	SIG( "glIsList" ); +	return dllIsList( list ); +} +static GLboolean APIENTRY logIsTexture(GLuint texture) +{ +	SIG( "glIsTexture" ); +	return dllIsTexture( texture ); +} + +static void APIENTRY logLightModelf(GLenum pname, GLfloat param) +{ +	SIG( "glLightModelf" ); +	dllLightModelf( pname, param ); +} + +static void APIENTRY logLightModelfv(GLenum pname, const GLfloat *params) +{ +	SIG( "glLightModelfv" ); +	dllLightModelfv( pname, params ); +} + +static void APIENTRY logLightModeli(GLenum pname, GLint param) +{ +	SIG( "glLightModeli" ); +	dllLightModeli( pname, param ); + +} + +static void APIENTRY logLightModeliv(GLenum pname, const GLint *params) +{ +	SIG( "glLightModeliv" ); +	dllLightModeliv( pname, params ); +} + +static void APIENTRY logLightf(GLenum light, GLenum pname, GLfloat param) +{ +	SIG( "glLightf" ); +	dllLightf( light, pname, param ); +} + +static void APIENTRY logLightfv(GLenum light, GLenum pname, const GLfloat *params) +{ +	SIG( "glLightfv" ); +	dllLightfv( light, pname, params ); +} + +static void APIENTRY logLighti(GLenum light, GLenum pname, GLint param) +{ +	SIG( "glLighti" ); +	dllLighti( light, pname, param ); +} + +static void APIENTRY logLightiv(GLenum light, GLenum pname, const GLint *params) +{ +	SIG( "glLightiv" ); +	dllLightiv( light, pname, params ); +} + +static void APIENTRY logLineStipple(GLint factor, GLushort pattern) +{ +	SIG( "glLineStipple" ); +	dllLineStipple( factor, pattern ); +} + +static void APIENTRY logLineWidth(GLfloat width) +{ +	SIG( "glLineWidth" ); +	dllLineWidth( width ); +} + +static void APIENTRY logListBase(GLuint base) +{ +	SIG( "glListBase" ); +	dllListBase( base ); +} + +static void APIENTRY logLoadIdentity(void) +{ +	SIG( "glLoadIdentity" ); +	dllLoadIdentity(); +} + +static void APIENTRY logLoadMatrixd(const GLdouble *m) +{ +	SIG( "glLoadMatrixd" ); +	dllLoadMatrixd( m ); +} + +static void APIENTRY logLoadMatrixf(const GLfloat *m) +{ +	SIG( "glLoadMatrixf" ); +	dllLoadMatrixf( m ); +} + +static void APIENTRY logLoadName(GLuint name) +{ +	SIG( "glLoadName" ); +	dllLoadName( name ); +} + +static void APIENTRY logLogicOp(GLenum opcode) +{ +	SIG( "glLogicOp" ); +	dllLogicOp( opcode ); +} + +static void APIENTRY logMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points) +{ +	SIG( "glMap1d" ); +	dllMap1d( target, u1, u2, stride, order, points ); +} + +static void APIENTRY logMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points) +{ +	SIG( "glMap1f" ); +	dllMap1f( target, u1, u2, stride, order, points ); +} + +static void APIENTRY logMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points) +{ +	SIG( "glMap2d" ); +	dllMap2d( target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points ); +} + +static void APIENTRY logMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points) +{ +	SIG( "glMap2f" ); +	dllMap2f( target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points ); +} + +static void APIENTRY logMapGrid1d(GLint un, GLdouble u1, GLdouble u2) +{ +	SIG( "glMapGrid1d" ); +	dllMapGrid1d( un, u1, u2 ); +} + +static void APIENTRY logMapGrid1f(GLint un, GLfloat u1, GLfloat u2) +{ +	SIG( "glMapGrid1f" ); +	dllMapGrid1f( un, u1, u2 ); +} + +static void APIENTRY logMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2) +{ +	SIG( "glMapGrid2d" ); +	dllMapGrid2d( un, u1, u2, vn, v1, v2 ); +} +static void APIENTRY logMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2) +{ +	SIG( "glMapGrid2f" ); +	dllMapGrid2f( un, u1, u2, vn, v1, v2 ); +} +static void APIENTRY logMaterialf(GLenum face, GLenum pname, GLfloat param) +{ +	SIG( "glMaterialf" ); +	dllMaterialf( face, pname, param ); +} +static void APIENTRY logMaterialfv(GLenum face, GLenum pname, const GLfloat *params) +{ +	SIG( "glMaterialfv" ); +	dllMaterialfv( face, pname, params ); +} + +static void APIENTRY logMateriali(GLenum face, GLenum pname, GLint param) +{ +	SIG( "glMateriali" ); +	dllMateriali( face, pname, param ); +} + +static void APIENTRY logMaterialiv(GLenum face, GLenum pname, const GLint *params) +{ +	SIG( "glMaterialiv" ); +	dllMaterialiv( face, pname, params ); +} + +static void APIENTRY logMatrixMode(GLenum mode) +{ +	SIG( "glMatrixMode" ); +	dllMatrixMode( mode ); +} + +static void APIENTRY logMultMatrixd(const GLdouble *m) +{ +	SIG( "glMultMatrixd" ); +	dllMultMatrixd( m ); +} + +static void APIENTRY logMultMatrixf(const GLfloat *m) +{ +	SIG( "glMultMatrixf" ); +	dllMultMatrixf( m ); +} + +static void APIENTRY logNewList(GLuint list, GLenum mode) +{ +	SIG( "glNewList" ); +	dllNewList( list, mode ); +} + +static void APIENTRY logNormal3b(GLbyte nx, GLbyte ny, GLbyte nz) +{ +	SIG ("glNormal3b" ); +	dllNormal3b( nx, ny, nz ); +} + +static void APIENTRY logNormal3bv(const GLbyte *v) +{ +	SIG( "glNormal3bv" ); +	dllNormal3bv( v ); +} + +static void APIENTRY logNormal3d(GLdouble nx, GLdouble ny, GLdouble nz) +{ +	SIG( "glNormal3d" ); +	dllNormal3d( nx, ny, nz ); +} + +static void APIENTRY logNormal3dv(const GLdouble *v) +{ +	SIG( "glNormal3dv" ); +	dllNormal3dv( v ); +} + +static void APIENTRY logNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) +{ +	SIG( "glNormal3f" ); +	dllNormal3f( nx, ny, nz ); +} + +static void APIENTRY logNormal3fv(const GLfloat *v) +{ +	SIG( "glNormal3fv" ); +	dllNormal3fv( v ); +} +static void APIENTRY logNormal3i(GLint nx, GLint ny, GLint nz) +{ +	SIG( "glNormal3i" ); +	dllNormal3i( nx, ny, nz ); +} +static void APIENTRY logNormal3iv(const GLint *v) +{ +	SIG( "glNormal3iv" ); +	dllNormal3iv( v ); +} +static void APIENTRY logNormal3s(GLshort nx, GLshort ny, GLshort nz) +{ +	SIG( "glNormal3s" ); +	dllNormal3s( nx, ny, nz ); +} +static void APIENTRY logNormal3sv(const GLshort *v) +{ +	SIG( "glNormal3sv" ); +	dllNormal3sv( v ); +} +static void APIENTRY logNormalPointer(GLenum type, GLsizei stride, const void *pointer) +{ +	SIG( "glNormalPointer" ); +	dllNormalPointer( type, stride, pointer ); +} +static void APIENTRY logOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) +{ +	SIG( "glOrtho" ); +	dllOrtho( left, right, bottom, top, zNear, zFar ); +} + +static void APIENTRY logPassThrough(GLfloat token) +{ +	SIG( "glPassThrough" ); +	dllPassThrough( token ); +} + +static void APIENTRY logPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values) +{ +	SIG( "glPixelMapfv" ); +	dllPixelMapfv( map, mapsize, values ); +} + +static void APIENTRY logPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values) +{ +	SIG( "glPixelMapuiv" ); +	dllPixelMapuiv( map, mapsize, values ); +} + +static void APIENTRY logPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values) +{ +	SIG( "glPixelMapusv" ); +	dllPixelMapusv( map, mapsize, values ); +} +static void APIENTRY logPixelStoref(GLenum pname, GLfloat param) +{ +	SIG( "glPixelStoref" ); +	dllPixelStoref( pname, param ); +} +static void APIENTRY logPixelStorei(GLenum pname, GLint param) +{ +	SIG( "glPixelStorei" ); +	dllPixelStorei( pname, param ); +} +static void APIENTRY logPixelTransferf(GLenum pname, GLfloat param) +{ +	SIG( "glPixelTransferf" ); +	dllPixelTransferf( pname, param ); +} + +static void APIENTRY logPixelTransferi(GLenum pname, GLint param) +{ +	SIG( "glPixelTransferi" ); +	dllPixelTransferi( pname, param ); +} + +static void APIENTRY logPixelZoom(GLfloat xfactor, GLfloat yfactor) +{ +	SIG( "glPixelZoom" ); +	dllPixelZoom( xfactor, yfactor ); +} + +static void APIENTRY logPointSize(GLfloat size) +{ +	SIG( "glPointSize" ); +	dllPointSize( size ); +} + +static void APIENTRY logPolygonMode(GLenum face, GLenum mode) +{ +	fprintf( glw_state.log_fp, "glPolygonMode( 0x%x, 0x%x )\n", face, mode ); +	dllPolygonMode( face, mode ); +} + +static void APIENTRY logPolygonOffset(GLfloat factor, GLfloat units) +{ +	SIG( "glPolygonOffset" ); +	dllPolygonOffset( factor, units ); +} +static void APIENTRY logPolygonStipple(const GLubyte *mask ) +{ +	SIG( "glPolygonStipple" ); +	dllPolygonStipple( mask ); +} +static void APIENTRY logPopAttrib(void) +{ +	SIG( "glPopAttrib" ); +	dllPopAttrib(); +} + +static void APIENTRY logPopClientAttrib(void) +{ +	SIG( "glPopClientAttrib" ); +	dllPopClientAttrib(); +} + +static void APIENTRY logPopMatrix(void) +{ +	SIG( "glPopMatrix" ); +	dllPopMatrix(); +} + +static void APIENTRY logPopName(void) +{ +	SIG( "glPopName" ); +	dllPopName(); +} + +static void APIENTRY logPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities) +{ +	SIG( "glPrioritizeTextures" ); +	dllPrioritizeTextures( n, textures, priorities ); +} + +static void APIENTRY logPushAttrib(GLbitfield mask) +{ +	SIG( "glPushAttrib" ); +	dllPushAttrib( mask ); +} + +static void APIENTRY logPushClientAttrib(GLbitfield mask) +{ +	SIG( "glPushClientAttrib" ); +	dllPushClientAttrib( mask ); +} + +static void APIENTRY logPushMatrix(void) +{ +	SIG( "glPushMatrix" ); +	dllPushMatrix(); +} + +static void APIENTRY logPushName(GLuint name) +{ +	SIG( "glPushName" ); +	dllPushName( name ); +} + +static void APIENTRY logRasterPos2d(GLdouble x, GLdouble y) +{ +	SIG ("glRasterPot2d" ); +	dllRasterPos2d( x, y ); +} + +static void APIENTRY logRasterPos2dv(const GLdouble *v) +{ +	SIG( "glRasterPos2dv" ); +	dllRasterPos2dv( v ); +} + +static void APIENTRY logRasterPos2f(GLfloat x, GLfloat y) +{ +	SIG( "glRasterPos2f" ); +	dllRasterPos2f( x, y ); +} +static void APIENTRY logRasterPos2fv(const GLfloat *v) +{ +	SIG( "glRasterPos2dv" ); +	dllRasterPos2fv( v ); +} +static void APIENTRY logRasterPos2i(GLint x, GLint y) +{ +	SIG( "glRasterPos2if" ); +	dllRasterPos2i( x, y ); +} +static void APIENTRY logRasterPos2iv(const GLint *v) +{ +	SIG( "glRasterPos2iv" ); +	dllRasterPos2iv( v ); +} +static void APIENTRY logRasterPos2s(GLshort x, GLshort y) +{ +	SIG( "glRasterPos2s" ); +	dllRasterPos2s( x, y ); +} +static void APIENTRY logRasterPos2sv(const GLshort *v) +{ +	SIG( "glRasterPos2sv" ); +	dllRasterPos2sv( v ); +} +static void APIENTRY logRasterPos3d(GLdouble x, GLdouble y, GLdouble z) +{ +	SIG( "glRasterPos3d" ); +	dllRasterPos3d( x, y, z ); +} +static void APIENTRY logRasterPos3dv(const GLdouble *v) +{ +	SIG( "glRasterPos3dv" ); +	dllRasterPos3dv( v ); +} +static void APIENTRY logRasterPos3f(GLfloat x, GLfloat y, GLfloat z) +{ +	SIG( "glRasterPos3f" ); +	dllRasterPos3f( x, y, z ); +} +static void APIENTRY logRasterPos3fv(const GLfloat *v) +{ +	SIG( "glRasterPos3fv" ); +	dllRasterPos3fv( v ); +} +static void APIENTRY logRasterPos3i(GLint x, GLint y, GLint z) +{ +	SIG( "glRasterPos3i" ); +	dllRasterPos3i( x, y, z ); +} +static void APIENTRY logRasterPos3iv(const GLint *v) +{ +	SIG( "glRasterPos3iv" ); +	dllRasterPos3iv( v ); +} +static void APIENTRY logRasterPos3s(GLshort x, GLshort y, GLshort z) +{ +	SIG( "glRasterPos3s" ); +	dllRasterPos3s( x, y, z ); +} +static void APIENTRY logRasterPos3sv(const GLshort *v) +{ +	SIG( "glRasterPos3sv" ); +	dllRasterPos3sv( v ); +} +static void APIENTRY logRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) +{ +	SIG( "glRasterPos4d" ); +	dllRasterPos4d( x, y, z, w ); +} +static void APIENTRY logRasterPos4dv(const GLdouble *v) +{ +	SIG( "glRasterPos4dv" ); +	dllRasterPos4dv( v ); +} +static void APIENTRY logRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ +	SIG( "glRasterPos4f" ); +	dllRasterPos4f( x, y, z, w ); +} +static void APIENTRY logRasterPos4fv(const GLfloat *v) +{ +	SIG( "glRasterPos4fv" ); +	dllRasterPos4fv( v ); +} +static void APIENTRY logRasterPos4i(GLint x, GLint y, GLint z, GLint w) +{ +	SIG( "glRasterPos4i" ); +	dllRasterPos4i( x, y, z, w ); +} +static void APIENTRY logRasterPos4iv(const GLint *v) +{ +	SIG( "glRasterPos4iv" ); +	dllRasterPos4iv( v ); +} +static void APIENTRY logRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w) +{ +	SIG( "glRasterPos4s" ); +	dllRasterPos4s( x, y, z, w ); +} +static void APIENTRY logRasterPos4sv(const GLshort *v) +{ +	SIG( "glRasterPos4sv" ); +	dllRasterPos4sv( v ); +} +static void APIENTRY logReadBuffer(GLenum mode) +{ +	SIG( "glReadBuffer" ); +	dllReadBuffer( mode ); +} +static void APIENTRY logReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels) +{ +	SIG( "glReadPixels" ); +	dllReadPixels( x, y, width, height, format, type, pixels ); +} + +static void APIENTRY logRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) +{ +	SIG( "glRectd" ); +	dllRectd( x1, y1, x2, y2 ); +} + +static void APIENTRY logRectdv(const GLdouble *v1, const GLdouble *v2) +{ +	SIG( "glRectdv" ); +	dllRectdv( v1, v2 ); +} + +static void APIENTRY logRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) +{ +	SIG( "glRectf" ); +	dllRectf( x1, y1, x2, y2 ); +} + +static void APIENTRY logRectfv(const GLfloat *v1, const GLfloat *v2) +{ +	SIG( "glRectfv" ); +	dllRectfv( v1, v2 ); +} +static void APIENTRY logRecti(GLint x1, GLint y1, GLint x2, GLint y2) +{ +	SIG( "glRecti" ); +	dllRecti( x1, y1, x2, y2 ); +} +static void APIENTRY logRectiv(const GLint *v1, const GLint *v2) +{ +	SIG( "glRectiv" ); +	dllRectiv( v1, v2 ); +} +static void APIENTRY logRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2) +{ +	SIG( "glRects" ); +	dllRects( x1, y1, x2, y2 ); +} +static void APIENTRY logRectsv(const GLshort *v1, const GLshort *v2) +{ +	SIG( "glRectsv" ); +	dllRectsv( v1, v2 ); +} +static GLint APIENTRY logRenderMode(GLenum mode) +{ +	SIG( "glRenderMode" ); +	return dllRenderMode( mode ); +} +static void APIENTRY logRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) +{ +	SIG( "glRotated" ); +	dllRotated( angle, x, y, z ); +} + +static void APIENTRY logRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) +{ +	SIG( "glRotatef" ); +	dllRotatef( angle, x, y, z ); +} + +static void APIENTRY logScaled(GLdouble x, GLdouble y, GLdouble z) +{ +	SIG( "glScaled" ); +	dllScaled( x, y, z ); +} + +static void APIENTRY logScalef(GLfloat x, GLfloat y, GLfloat z) +{ +	SIG( "glScalef" ); +	dllScalef( x, y, z ); +} + +static void APIENTRY logScissor(GLint x, GLint y, GLsizei width, GLsizei height) +{ +	fprintf( glw_state.log_fp, "glScissor( %d, %d, %d, %d )\n", x, y, width, height ); +	dllScissor( x, y, width, height ); +} + +static void APIENTRY logSelectBuffer(GLsizei size, GLuint *buffer) +{ +	SIG( "glSelectBuffer" ); +	dllSelectBuffer( size, buffer ); +} + +static void APIENTRY logShadeModel(GLenum mode) +{ +	SIG( "glShadeModel" ); +	dllShadeModel( mode ); +} + +static void APIENTRY logStencilFunc(GLenum func, GLint ref, GLuint mask) +{ +	SIG( "glStencilFunc" ); +	dllStencilFunc( func, ref, mask ); +} + +static void APIENTRY logStencilMask(GLuint mask) +{ +	SIG( "glStencilMask" ); +	dllStencilMask( mask ); +} + +static void APIENTRY logStencilOp(GLenum fail, GLenum zfail, GLenum zpass) +{ +	SIG( "glStencilOp" ); +	dllStencilOp( fail, zfail, zpass ); +} + +static void APIENTRY logTexCoord1d(GLdouble s) +{ +	SIG( "glTexCoord1d" ); +	dllTexCoord1d( s ); +} + +static void APIENTRY logTexCoord1dv(const GLdouble *v) +{ +	SIG( "glTexCoord1dv" ); +	dllTexCoord1dv( v ); +} + +static void APIENTRY logTexCoord1f(GLfloat s) +{ +	SIG( "glTexCoord1f" ); +	dllTexCoord1f( s ); +} +static void APIENTRY logTexCoord1fv(const GLfloat *v) +{ +	SIG( "glTexCoord1fv" ); +	dllTexCoord1fv( v ); +} +static void APIENTRY logTexCoord1i(GLint s) +{ +	SIG( "glTexCoord1i" ); +	dllTexCoord1i( s ); +} +static void APIENTRY logTexCoord1iv(const GLint *v) +{ +	SIG( "glTexCoord1iv" ); +	dllTexCoord1iv( v ); +} +static void APIENTRY logTexCoord1s(GLshort s) +{ +	SIG( "glTexCoord1s" ); +	dllTexCoord1s( s ); +} +static void APIENTRY logTexCoord1sv(const GLshort *v) +{ +	SIG( "glTexCoord1sv" ); +	dllTexCoord1sv( v ); +} +static void APIENTRY logTexCoord2d(GLdouble s, GLdouble t) +{ +	SIG( "glTexCoord2d" ); +	dllTexCoord2d( s, t ); +} + +static void APIENTRY logTexCoord2dv(const GLdouble *v) +{ +	SIG( "glTexCoord2dv" ); +	dllTexCoord2dv( v ); +} +static void APIENTRY logTexCoord2f(GLfloat s, GLfloat t) +{ +	SIG( "glTexCoord2f" ); +	dllTexCoord2f( s, t ); +} +static void APIENTRY logTexCoord2fv(const GLfloat *v) +{ +	SIG( "glTexCoord2fv" ); +	dllTexCoord2fv( v ); +} +static void APIENTRY logTexCoord2i(GLint s, GLint t) +{ +	SIG( "glTexCoord2i" ); +	dllTexCoord2i( s, t ); +} +static void APIENTRY logTexCoord2iv(const GLint *v) +{ +	SIG( "glTexCoord2iv" ); +	dllTexCoord2iv( v ); +} +static void APIENTRY logTexCoord2s(GLshort s, GLshort t) +{ +	SIG( "glTexCoord2s" ); +	dllTexCoord2s( s, t ); +} +static void APIENTRY logTexCoord2sv(const GLshort *v) +{ +	SIG( "glTexCoord2sv" ); +	dllTexCoord2sv( v ); +} +static void APIENTRY logTexCoord3d(GLdouble s, GLdouble t, GLdouble r) +{ +	SIG( "glTexCoord3d" ); +	dllTexCoord3d( s, t, r ); +} +static void APIENTRY logTexCoord3dv(const GLdouble *v) +{ +	SIG( "glTexCoord3dv" ); +	dllTexCoord3dv( v ); +} +static void APIENTRY logTexCoord3f(GLfloat s, GLfloat t, GLfloat r) +{ +	SIG( "glTexCoord3f" ); +	dllTexCoord3f( s, t, r ); +} +static void APIENTRY logTexCoord3fv(const GLfloat *v) +{ +	SIG( "glTexCoord3fv" ); +	dllTexCoord3fv( v ); +} +static void APIENTRY logTexCoord3i(GLint s, GLint t, GLint r) +{ +	SIG( "glTexCoord3i" ); +	dllTexCoord3i( s, t, r ); +} +static void APIENTRY logTexCoord3iv(const GLint *v) +{ +	SIG( "glTexCoord3iv" ); +	dllTexCoord3iv( v ); +} +static void APIENTRY logTexCoord3s(GLshort s, GLshort t, GLshort r) +{ +	SIG( "glTexCoord3s" ); +	dllTexCoord3s( s, t, r ); +} +static void APIENTRY logTexCoord3sv(const GLshort *v) +{ +	SIG( "glTexCoord3sv" ); +	dllTexCoord3sv( v ); +} +static void APIENTRY logTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q) +{ +	SIG( "glTexCoord4d" ); +	dllTexCoord4d( s, t, r, q ); +} +static void APIENTRY logTexCoord4dv(const GLdouble *v) +{ +	SIG( "glTexCoord4dv" ); +	dllTexCoord4dv( v ); +} +static void APIENTRY logTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) +{ +	SIG( "glTexCoord4f" ); +	dllTexCoord4f( s, t, r, q ); +} +static void APIENTRY logTexCoord4fv(const GLfloat *v) +{ +	SIG( "glTexCoord4fv" ); +	dllTexCoord4fv( v ); +} +static void APIENTRY logTexCoord4i(GLint s, GLint t, GLint r, GLint q) +{ +	SIG( "glTexCoord4i" ); +	dllTexCoord4i( s, t, r, q ); +} +static void APIENTRY logTexCoord4iv(const GLint *v) +{ +	SIG( "glTexCoord4iv" ); +	dllTexCoord4iv( v ); +} +static void APIENTRY logTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q) +{ +	SIG( "glTexCoord4s" ); +	dllTexCoord4s( s, t, r, q ); +} +static void APIENTRY logTexCoord4sv(const GLshort *v) +{ +	SIG( "glTexCoord4sv" ); +	dllTexCoord4sv( v ); +} +static void APIENTRY logTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) +{ +	fprintf( glw_state.log_fp, "glTexCoordPointer( %d, %s, %d, MEM )\n", size, TypeToString( type ), stride ); +	dllTexCoordPointer( size, type, stride, pointer ); +} + +static void APIENTRY logTexEnvf(GLenum target, GLenum pname, GLfloat param) +{ +	fprintf( glw_state.log_fp, "glTexEnvf( 0x%x, 0x%x, %f )\n", target, pname, param ); +	dllTexEnvf( target, pname, param ); +} + +static void APIENTRY logTexEnvfv(GLenum target, GLenum pname, const GLfloat *params) +{ +	SIG( "glTexEnvfv" ); +	dllTexEnvfv( target, pname, params ); +} + +static void APIENTRY logTexEnvi(GLenum target, GLenum pname, GLint param) +{ +	fprintf( glw_state.log_fp, "glTexEnvi( 0x%x, 0x%x, 0x%x )\n", target, pname, param ); +	dllTexEnvi( target, pname, param ); +} +static void APIENTRY logTexEnviv(GLenum target, GLenum pname, const GLint *params) +{ +	SIG( "glTexEnviv" ); +	dllTexEnviv( target, pname, params ); +} + +static void APIENTRY logTexGend(GLenum coord, GLenum pname, GLdouble param) +{ +	SIG( "glTexGend" ); +	dllTexGend( coord, pname, param ); +} + +static void APIENTRY logTexGendv(GLenum coord, GLenum pname, const GLdouble *params) +{ +	SIG( "glTexGendv" ); +	dllTexGendv( coord, pname, params ); +} + +static void APIENTRY logTexGenf(GLenum coord, GLenum pname, GLfloat param) +{ +	SIG( "glTexGenf" ); +	dllTexGenf( coord, pname, param ); +} +static void APIENTRY logTexGenfv(GLenum coord, GLenum pname, const GLfloat *params) +{ +	SIG( "glTexGenfv" ); +	dllTexGenfv( coord, pname, params ); +} +static void APIENTRY logTexGeni(GLenum coord, GLenum pname, GLint param) +{ +	SIG( "glTexGeni" ); +	dllTexGeni( coord, pname, param ); +} +static void APIENTRY logTexGeniv(GLenum coord, GLenum pname, const GLint *params) +{ +	SIG( "glTexGeniv" ); +	dllTexGeniv( coord, pname, params ); +} +static void APIENTRY logTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels) +{ +	SIG( "glTexImage1D" ); +	dllTexImage1D( target, level, internalformat, width, border, format, type, pixels ); +} +static void APIENTRY logTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) +{ +	SIG( "glTexImage2D" ); +	dllTexImage2D( target, level, internalformat, width, height, border, format, type, pixels ); +} + +static void APIENTRY logTexParameterf(GLenum target, GLenum pname, GLfloat param) +{ +	fprintf( glw_state.log_fp, "glTexParameterf( 0x%x, 0x%x, %f )\n", target, pname, param ); +	dllTexParameterf( target, pname, param ); +} + +static void APIENTRY logTexParameterfv(GLenum target, GLenum pname, const GLfloat *params) +{ +	SIG( "glTexParameterfv" ); +	dllTexParameterfv( target, pname, params ); +} +static void APIENTRY logTexParameteri(GLenum target, GLenum pname, GLint param) +{ +	fprintf( glw_state.log_fp, "glTexParameteri( 0x%x, 0x%x, 0x%x )\n", target, pname, param ); +	dllTexParameteri( target, pname, param ); +} +static void APIENTRY logTexParameteriv(GLenum target, GLenum pname, const GLint *params) +{ +	SIG( "glTexParameteriv" ); +	dllTexParameteriv( target, pname, params ); +} +static void APIENTRY logTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels) +{ +	SIG( "glTexSubImage1D" ); +	dllTexSubImage1D( target, level, xoffset, width, format, type, pixels ); +} +static void APIENTRY logTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) +{ +	SIG( "glTexSubImage2D" ); +	dllTexSubImage2D( target, level, xoffset, yoffset, width, height, format, type, pixels ); +} +static void APIENTRY logTranslated(GLdouble x, GLdouble y, GLdouble z) +{ +	SIG( "glTranslated" ); +	dllTranslated( x, y, z ); +} + +static void APIENTRY logTranslatef(GLfloat x, GLfloat y, GLfloat z) +{ +	SIG( "glTranslatef" ); +	dllTranslatef( x, y, z ); +} + +static void APIENTRY logVertex2d(GLdouble x, GLdouble y) +{ +	SIG( "glVertex2d" ); +	dllVertex2d( x, y ); +} + +static void APIENTRY logVertex2dv(const GLdouble *v) +{ +	SIG( "glVertex2dv" ); +	dllVertex2dv( v ); +} +static void APIENTRY logVertex2f(GLfloat x, GLfloat y) +{ +	SIG( "glVertex2f" ); +	dllVertex2f( x, y ); +} +static void APIENTRY logVertex2fv(const GLfloat *v) +{ +	SIG( "glVertex2fv" ); +	dllVertex2fv( v ); +} +static void APIENTRY logVertex2i(GLint x, GLint y) +{ +	SIG( "glVertex2i" ); +	dllVertex2i( x, y ); +} +static void APIENTRY logVertex2iv(const GLint *v) +{ +	SIG( "glVertex2iv" ); +	dllVertex2iv( v ); +} +static void APIENTRY logVertex2s(GLshort x, GLshort y) +{ +	SIG( "glVertex2s" ); +	dllVertex2s( x, y ); +} +static void APIENTRY logVertex2sv(const GLshort *v) +{ +	SIG( "glVertex2sv" ); +	dllVertex2sv( v ); +} +static void APIENTRY logVertex3d(GLdouble x, GLdouble y, GLdouble z) +{ +	SIG( "glVertex3d" ); +	dllVertex3d( x, y, z ); +} +static void APIENTRY logVertex3dv(const GLdouble *v) +{ +	SIG( "glVertex3dv" ); +	dllVertex3dv( v ); +} +static void APIENTRY logVertex3f(GLfloat x, GLfloat y, GLfloat z) +{ +	SIG( "glVertex3f" ); +	dllVertex3f( x, y, z ); +} +static void APIENTRY logVertex3fv(const GLfloat *v) +{ +	SIG( "glVertex3fv" ); +	dllVertex3fv( v ); +} +static void APIENTRY logVertex3i(GLint x, GLint y, GLint z) +{ +	SIG( "glVertex3i" ); +	dllVertex3i( x, y, z ); +} +static void APIENTRY logVertex3iv(const GLint *v) +{ +	SIG( "glVertex3iv" ); +	dllVertex3iv( v ); +} +static void APIENTRY logVertex3s(GLshort x, GLshort y, GLshort z) +{ +	SIG( "glVertex3s" ); +	dllVertex3s( x, y, z ); +} +static void APIENTRY logVertex3sv(const GLshort *v) +{ +	SIG( "glVertex3sv" ); +	dllVertex3sv( v ); +} +static void APIENTRY logVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) +{ +	SIG( "glVertex4d" ); +	dllVertex4d( x, y, z, w ); +} +static void APIENTRY logVertex4dv(const GLdouble *v) +{ +	SIG( "glVertex4dv" ); +	dllVertex4dv( v ); +} +static void APIENTRY logVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ +	SIG( "glVertex4f" ); +	dllVertex4f( x, y, z, w ); +} +static void APIENTRY logVertex4fv(const GLfloat *v) +{ +	SIG( "glVertex4fv" ); +	dllVertex4fv( v ); +} +static void APIENTRY logVertex4i(GLint x, GLint y, GLint z, GLint w) +{ +	SIG( "glVertex4i" ); +	dllVertex4i( x, y, z, w ); +} +static void APIENTRY logVertex4iv(const GLint *v) +{ +	SIG( "glVertex4iv" ); +	dllVertex4iv( v ); +} +static void APIENTRY logVertex4s(GLshort x, GLshort y, GLshort z, GLshort w) +{ +	SIG( "glVertex4s" ); +	dllVertex4s( x, y, z, w ); +} +static void APIENTRY logVertex4sv(const GLshort *v) +{ +	SIG( "glVertex4sv" ); +	dllVertex4sv( v ); +} +static void APIENTRY logVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer) +{ +	fprintf( glw_state.log_fp, "glVertexPointer( %d, %s, %d, MEM )\n", size, TypeToString( type ), stride ); +	dllVertexPointer( size, type, stride, pointer ); +} +static void APIENTRY logViewport(GLint x, GLint y, GLsizei width, GLsizei height) +{ +	fprintf( glw_state.log_fp, "glViewport( %d, %d, %d, %d )\n", x, y, width, height ); +	dllViewport( x, y, width, height ); +} + +/* +** QGL_Shutdown +** +** Unloads the specified DLL then nulls out all the proc pointers.  This +** is only called during a hard shutdown of the OGL subsystem (e.g. vid_restart). +*/ +void QGL_Shutdown( void ) +{ +	ri.Printf( PRINT_ALL, "...shutting down QGL\n" ); + +	if ( glw_state.hinstOpenGL ) +	{ +		ri.Printf( PRINT_ALL, "...unloading OpenGL DLL\n" ); +		FreeLibrary( glw_state.hinstOpenGL ); +	} + +	glw_state.hinstOpenGL = NULL; + +	qglAccum                     = NULL; +	qglAlphaFunc                 = NULL; +	qglAreTexturesResident       = NULL; +	qglArrayElement              = NULL; +	qglBegin                     = NULL; +	qglBindTexture               = NULL; +	qglBitmap                    = NULL; +	qglBlendFunc                 = NULL; +	qglCallList                  = NULL; +	qglCallLists                 = NULL; +	qglClear                     = NULL; +	qglClearAccum                = NULL; +	qglClearColor                = NULL; +	qglClearDepth                = NULL; +	qglClearIndex                = NULL; +	qglClearStencil              = NULL; +	qglClipPlane                 = NULL; +	qglColor3b                   = NULL; +	qglColor3bv                  = NULL; +	qglColor3d                   = NULL; +	qglColor3dv                  = NULL; +	qglColor3f                   = NULL; +	qglColor3fv                  = NULL; +	qglColor3i                   = NULL; +	qglColor3iv                  = NULL; +	qglColor3s                   = NULL; +	qglColor3sv                  = NULL; +	qglColor3ub                  = NULL; +	qglColor3ubv                 = NULL; +	qglColor3ui                  = NULL; +	qglColor3uiv                 = NULL; +	qglColor3us                  = NULL; +	qglColor3usv                 = NULL; +	qglColor4b                   = NULL; +	qglColor4bv                  = NULL; +	qglColor4d                   = NULL; +	qglColor4dv                  = NULL; +	qglColor4f                   = NULL; +	qglColor4fv                  = NULL; +	qglColor4i                   = NULL; +	qglColor4iv                  = NULL; +	qglColor4s                   = NULL; +	qglColor4sv                  = NULL; +	qglColor4ub                  = NULL; +	qglColor4ubv                 = NULL; +	qglColor4ui                  = NULL; +	qglColor4uiv                 = NULL; +	qglColor4us                  = NULL; +	qglColor4usv                 = NULL; +	qglColorMask                 = NULL; +	qglColorMaterial             = NULL; +	qglColorPointer              = NULL; +	qglCopyPixels                = NULL; +	qglCopyTexImage1D            = NULL; +	qglCopyTexImage2D            = NULL; +	qglCopyTexSubImage1D         = NULL; +	qglCopyTexSubImage2D         = NULL; +	qglCullFace                  = NULL; +	qglDeleteLists               = NULL; +	qglDeleteTextures            = NULL; +	qglDepthFunc                 = NULL; +	qglDepthMask                 = NULL; +	qglDepthRange                = NULL; +	qglDisable                   = NULL; +	qglDisableClientState        = NULL; +	qglDrawArrays                = NULL; +	qglDrawBuffer                = NULL; +	qglDrawElements              = NULL; +	qglDrawPixels                = NULL; +	qglEdgeFlag                  = NULL; +	qglEdgeFlagPointer           = NULL; +	qglEdgeFlagv                 = NULL; +	qglEnable                    = NULL; +	qglEnableClientState         = NULL; +	qglEnd                       = NULL; +	qglEndList                   = NULL; +	qglEvalCoord1d               = NULL; +	qglEvalCoord1dv              = NULL; +	qglEvalCoord1f               = NULL; +	qglEvalCoord1fv              = NULL; +	qglEvalCoord2d               = NULL; +	qglEvalCoord2dv              = NULL; +	qglEvalCoord2f               = NULL; +	qglEvalCoord2fv              = NULL; +	qglEvalMesh1                 = NULL; +	qglEvalMesh2                 = NULL; +	qglEvalPoint1                = NULL; +	qglEvalPoint2                = NULL; +	qglFeedbackBuffer            = NULL; +	qglFinish                    = NULL; +	qglFlush                     = NULL; +	qglFogf                      = NULL; +	qglFogfv                     = NULL; +	qglFogi                      = NULL; +	qglFogiv                     = NULL; +	qglFrontFace                 = NULL; +	qglFrustum                   = NULL; +	qglGenLists                  = NULL; +	qglGenTextures               = NULL; +	qglGetBooleanv               = NULL; +	qglGetClipPlane              = NULL; +	qglGetDoublev                = NULL; +	qglGetError                  = NULL; +	qglGetFloatv                 = NULL; +	qglGetIntegerv               = NULL; +	qglGetLightfv                = NULL; +	qglGetLightiv                = NULL; +	qglGetMapdv                  = NULL; +	qglGetMapfv                  = NULL; +	qglGetMapiv                  = NULL; +	qglGetMaterialfv             = NULL; +	qglGetMaterialiv             = NULL; +	qglGetPixelMapfv             = NULL; +	qglGetPixelMapuiv            = NULL; +	qglGetPixelMapusv            = NULL; +	qglGetPointerv               = NULL; +	qglGetPolygonStipple         = NULL; +	qglGetString                 = NULL; +	qglGetTexEnvfv               = NULL; +	qglGetTexEnviv               = NULL; +	qglGetTexGendv               = NULL; +	qglGetTexGenfv               = NULL; +	qglGetTexGeniv               = NULL; +	qglGetTexImage               = NULL; +	qglGetTexLevelParameterfv    = NULL; +	qglGetTexLevelParameteriv    = NULL; +	qglGetTexParameterfv         = NULL; +	qglGetTexParameteriv         = NULL; +	qglHint                      = NULL; +	qglIndexMask                 = NULL; +	qglIndexPointer              = NULL; +	qglIndexd                    = NULL; +	qglIndexdv                   = NULL; +	qglIndexf                    = NULL; +	qglIndexfv                   = NULL; +	qglIndexi                    = NULL; +	qglIndexiv                   = NULL; +	qglIndexs                    = NULL; +	qglIndexsv                   = NULL; +	qglIndexub                   = NULL; +	qglIndexubv                  = NULL; +	qglInitNames                 = NULL; +	qglInterleavedArrays         = NULL; +	qglIsEnabled                 = NULL; +	qglIsList                    = NULL; +	qglIsTexture                 = NULL; +	qglLightModelf               = NULL; +	qglLightModelfv              = NULL; +	qglLightModeli               = NULL; +	qglLightModeliv              = NULL; +	qglLightf                    = NULL; +	qglLightfv                   = NULL; +	qglLighti                    = NULL; +	qglLightiv                   = NULL; +	qglLineStipple               = NULL; +	qglLineWidth                 = NULL; +	qglListBase                  = NULL; +	qglLoadIdentity              = NULL; +	qglLoadMatrixd               = NULL; +	qglLoadMatrixf               = NULL; +	qglLoadName                  = NULL; +	qglLogicOp                   = NULL; +	qglMap1d                     = NULL; +	qglMap1f                     = NULL; +	qglMap2d                     = NULL; +	qglMap2f                     = NULL; +	qglMapGrid1d                 = NULL; +	qglMapGrid1f                 = NULL; +	qglMapGrid2d                 = NULL; +	qglMapGrid2f                 = NULL; +	qglMaterialf                 = NULL; +	qglMaterialfv                = NULL; +	qglMateriali                 = NULL; +	qglMaterialiv                = NULL; +	qglMatrixMode                = NULL; +	qglMultMatrixd               = NULL; +	qglMultMatrixf               = NULL; +	qglNewList                   = NULL; +	qglNormal3b                  = NULL; +	qglNormal3bv                 = NULL; +	qglNormal3d                  = NULL; +	qglNormal3dv                 = NULL; +	qglNormal3f                  = NULL; +	qglNormal3fv                 = NULL; +	qglNormal3i                  = NULL; +	qglNormal3iv                 = NULL; +	qglNormal3s                  = NULL; +	qglNormal3sv                 = NULL; +	qglNormalPointer             = NULL; +	qglOrtho                     = NULL; +	qglPassThrough               = NULL; +	qglPixelMapfv                = NULL; +	qglPixelMapuiv               = NULL; +	qglPixelMapusv               = NULL; +	qglPixelStoref               = NULL; +	qglPixelStorei               = NULL; +	qglPixelTransferf            = NULL; +	qglPixelTransferi            = NULL; +	qglPixelZoom                 = NULL; +	qglPointSize                 = NULL; +	qglPolygonMode               = NULL; +	qglPolygonOffset             = NULL; +	qglPolygonStipple            = NULL; +	qglPopAttrib                 = NULL; +	qglPopClientAttrib           = NULL; +	qglPopMatrix                 = NULL; +	qglPopName                   = NULL; +	qglPrioritizeTextures        = NULL; +	qglPushAttrib                = NULL; +	qglPushClientAttrib          = NULL; +	qglPushMatrix                = NULL; +	qglPushName                  = NULL; +	qglRasterPos2d               = NULL; +	qglRasterPos2dv              = NULL; +	qglRasterPos2f               = NULL; +	qglRasterPos2fv              = NULL; +	qglRasterPos2i               = NULL; +	qglRasterPos2iv              = NULL; +	qglRasterPos2s               = NULL; +	qglRasterPos2sv              = NULL; +	qglRasterPos3d               = NULL; +	qglRasterPos3dv              = NULL; +	qglRasterPos3f               = NULL; +	qglRasterPos3fv              = NULL; +	qglRasterPos3i               = NULL; +	qglRasterPos3iv              = NULL; +	qglRasterPos3s               = NULL; +	qglRasterPos3sv              = NULL; +	qglRasterPos4d               = NULL; +	qglRasterPos4dv              = NULL; +	qglRasterPos4f               = NULL; +	qglRasterPos4fv              = NULL; +	qglRasterPos4i               = NULL; +	qglRasterPos4iv              = NULL; +	qglRasterPos4s               = NULL; +	qglRasterPos4sv              = NULL; +	qglReadBuffer                = NULL; +	qglReadPixels                = NULL; +	qglRectd                     = NULL; +	qglRectdv                    = NULL; +	qglRectf                     = NULL; +	qglRectfv                    = NULL; +	qglRecti                     = NULL; +	qglRectiv                    = NULL; +	qglRects                     = NULL; +	qglRectsv                    = NULL; +	qglRenderMode                = NULL; +	qglRotated                   = NULL; +	qglRotatef                   = NULL; +	qglScaled                    = NULL; +	qglScalef                    = NULL; +	qglScissor                   = NULL; +	qglSelectBuffer              = NULL; +	qglShadeModel                = NULL; +	qglStencilFunc               = NULL; +	qglStencilMask               = NULL; +	qglStencilOp                 = NULL; +	qglTexCoord1d                = NULL; +	qglTexCoord1dv               = NULL; +	qglTexCoord1f                = NULL; +	qglTexCoord1fv               = NULL; +	qglTexCoord1i                = NULL; +	qglTexCoord1iv               = NULL; +	qglTexCoord1s                = NULL; +	qglTexCoord1sv               = NULL; +	qglTexCoord2d                = NULL; +	qglTexCoord2dv               = NULL; +	qglTexCoord2f                = NULL; +	qglTexCoord2fv               = NULL; +	qglTexCoord2i                = NULL; +	qglTexCoord2iv               = NULL; +	qglTexCoord2s                = NULL; +	qglTexCoord2sv               = NULL; +	qglTexCoord3d                = NULL; +	qglTexCoord3dv               = NULL; +	qglTexCoord3f                = NULL; +	qglTexCoord3fv               = NULL; +	qglTexCoord3i                = NULL; +	qglTexCoord3iv               = NULL; +	qglTexCoord3s                = NULL; +	qglTexCoord3sv               = NULL; +	qglTexCoord4d                = NULL; +	qglTexCoord4dv               = NULL; +	qglTexCoord4f                = NULL; +	qglTexCoord4fv               = NULL; +	qglTexCoord4i                = NULL; +	qglTexCoord4iv               = NULL; +	qglTexCoord4s                = NULL; +	qglTexCoord4sv               = NULL; +	qglTexCoordPointer           = NULL; +	qglTexEnvf                   = NULL; +	qglTexEnvfv                  = NULL; +	qglTexEnvi                   = NULL; +	qglTexEnviv                  = NULL; +	qglTexGend                   = NULL; +	qglTexGendv                  = NULL; +	qglTexGenf                   = NULL; +	qglTexGenfv                  = NULL; +	qglTexGeni                   = NULL; +	qglTexGeniv                  = NULL; +	qglTexImage1D                = NULL; +	qglTexImage2D                = NULL; +	qglTexParameterf             = NULL; +	qglTexParameterfv            = NULL; +	qglTexParameteri             = NULL; +	qglTexParameteriv            = NULL; +	qglTexSubImage1D             = NULL; +	qglTexSubImage2D             = NULL; +	qglTranslated                = NULL; +	qglTranslatef                = NULL; +	qglVertex2d                  = NULL; +	qglVertex2dv                 = NULL; +	qglVertex2f                  = NULL; +	qglVertex2fv                 = NULL; +	qglVertex2i                  = NULL; +	qglVertex2iv                 = NULL; +	qglVertex2s                  = NULL; +	qglVertex2sv                 = NULL; +	qglVertex3d                  = NULL; +	qglVertex3dv                 = NULL; +	qglVertex3f                  = NULL; +	qglVertex3fv                 = NULL; +	qglVertex3i                  = NULL; +	qglVertex3iv                 = NULL; +	qglVertex3s                  = NULL; +	qglVertex3sv                 = NULL; +	qglVertex4d                  = NULL; +	qglVertex4dv                 = NULL; +	qglVertex4f                  = NULL; +	qglVertex4fv                 = NULL; +	qglVertex4i                  = NULL; +	qglVertex4iv                 = NULL; +	qglVertex4s                  = NULL; +	qglVertex4sv                 = NULL; +	qglVertexPointer             = NULL; +	qglViewport                  = NULL; + +	qwglCopyContext              = NULL; +	qwglCreateContext            = NULL; +	qwglCreateLayerContext       = NULL; +	qwglDeleteContext            = NULL; +	qwglDescribeLayerPlane       = NULL; +	qwglGetCurrentContext        = NULL; +	qwglGetCurrentDC             = NULL; +	qwglGetLayerPaletteEntries   = NULL; +	qwglGetProcAddress           = NULL; +	qwglMakeCurrent              = NULL; +	qwglRealizeLayerPalette      = NULL; +	qwglSetLayerPaletteEntries   = NULL; +	qwglShareLists               = NULL; +	qwglSwapLayerBuffers         = NULL; +	qwglUseFontBitmaps           = NULL; +	qwglUseFontOutlines          = NULL; + +	qwglChoosePixelFormat        = NULL; +	qwglDescribePixelFormat      = NULL; +	qwglGetPixelFormat           = NULL; +	qwglSetPixelFormat           = NULL; +	qwglSwapBuffers              = NULL; +} + +#define GR_NUM_BOARDS 0x0f + +static qboolean GlideIsValid( void ) +{ +	HMODULE hGlide; +//	int numBoards; +//	void (__stdcall *grGet)(unsigned int, unsigned int, int*); + +    if ( ( hGlide = LoadLibrary("Glide3X") ) != 0 )  +	{ +		// FIXME: 3Dfx needs to fix this shit +		return qtrue; + +#if 0 +        grGet = (void *)GetProcAddress( hGlide, "_grGet@12"); + +		if ( grGet ) +		{ +	        grGet( GR_NUM_BOARDS, sizeof(int), &numBoards); +		} +		else +		{ +			// if we've reached this point, something is seriously wrong +			ri.Printf( PRINT_WARNING, "WARNING: could not find grGet in GLIDE3X.DLL\n" ); +			numBoards = 0; +		} + +		FreeLibrary( hGlide ); +		hGlide = NULL; + +		if ( numBoards > 0 ) +		{ +			return qtrue; +		} + +		ri.Printf( PRINT_WARNING, "WARNING: invalid Glide installation!\n" ); +#endif +    } + +	return qfalse; +}  + +#ifdef _MSC_VER +#	pragma warning (disable : 4113 4133 4047 ) +#	define GPA( a ) GetProcAddress( glw_state.hinstOpenGL, a ) +#else +#	define GPA( a ) (void *)GetProcAddress( glw_state.hinstOpenGL, a ) +#endif + +/* +** QGL_Init +** +** This is responsible for binding our qgl function pointers to  +** the appropriate GL stuff.  In Windows this means doing a  +** LoadLibrary and a bunch of calls to GetProcAddress.  On other +** operating systems we need to do the right thing, whatever that +** might be. +*/ +qboolean QGL_Init( const char *dllname ) +{ +	char systemDir[1024]; +	char libName[1024]; + +	GetSystemDirectory( systemDir, sizeof( systemDir ) ); + +	assert( glw_state.hinstOpenGL == 0 ); + +	ri.Printf( PRINT_ALL, "...initializing QGL\n" ); + +	// NOTE: this assumes that 'dllname' is lower case (and it should be)! +	if ( strstr( dllname, _3DFX_DRIVER_NAME ) ) +	{ +		if ( !GlideIsValid() ) +		{ +			ri.Printf( PRINT_ALL, "...WARNING: missing Glide installation, assuming no 3Dfx available\n" ); +			return qfalse; +		} +	} + +	if ( dllname[0] != '!' ) +	{ +		Com_sprintf( libName, sizeof( libName ), "%s\\%s", systemDir, dllname ); +	} +	else +	{ +		Q_strncpyz( libName, dllname, sizeof( libName ) ); +	} + +	ri.Printf( PRINT_ALL, "...calling LoadLibrary( '%s.dll' ): ", libName ); + +	if ( ( glw_state.hinstOpenGL = LoadLibrary( dllname ) ) == 0 ) +	{ +		ri.Printf( PRINT_ALL, "failed\n" ); +		return qfalse; +	} +	ri.Printf( PRINT_ALL, "succeeded\n" ); + +	qglAccum                     = dllAccum = GPA( "glAccum" ); +	qglAlphaFunc                 = dllAlphaFunc = GPA( "glAlphaFunc" ); +	qglAreTexturesResident       = dllAreTexturesResident = GPA( "glAreTexturesResident" ); +	qglArrayElement              = dllArrayElement = GPA( "glArrayElement" ); +	qglBegin                     = dllBegin = GPA( "glBegin" ); +	qglBindTexture               = dllBindTexture = GPA( "glBindTexture" ); +	qglBitmap                    = dllBitmap = GPA( "glBitmap" ); +	qglBlendFunc                 = dllBlendFunc = GPA( "glBlendFunc" ); +	qglCallList                  = dllCallList = GPA( "glCallList" ); +	qglCallLists                 = dllCallLists = GPA( "glCallLists" ); +	qglClear                     = dllClear = GPA( "glClear" ); +	qglClearAccum                = dllClearAccum = GPA( "glClearAccum" ); +	qglClearColor                = dllClearColor = GPA( "glClearColor" ); +	qglClearDepth                = dllClearDepth = GPA( "glClearDepth" ); +	qglClearIndex                = dllClearIndex = GPA( "glClearIndex" ); +	qglClearStencil              = dllClearStencil = GPA( "glClearStencil" ); +	qglClipPlane                 = dllClipPlane = GPA( "glClipPlane" ); +	qglColor3b                   = dllColor3b = GPA( "glColor3b" ); +	qglColor3bv                  = dllColor3bv = GPA( "glColor3bv" ); +	qglColor3d                   = dllColor3d = GPA( "glColor3d" ); +	qglColor3dv                  = dllColor3dv = GPA( "glColor3dv" ); +	qglColor3f                   = dllColor3f = GPA( "glColor3f" ); +	qglColor3fv                  = dllColor3fv = GPA( "glColor3fv" ); +	qglColor3i                   = dllColor3i = GPA( "glColor3i" ); +	qglColor3iv                  = dllColor3iv = GPA( "glColor3iv" ); +	qglColor3s                   = dllColor3s = GPA( "glColor3s" ); +	qglColor3sv                  = dllColor3sv = GPA( "glColor3sv" ); +	qglColor3ub                  = dllColor3ub = GPA( "glColor3ub" ); +	qglColor3ubv                 = dllColor3ubv = GPA( "glColor3ubv" ); +	qglColor3ui                  = dllColor3ui = GPA( "glColor3ui" ); +	qglColor3uiv                 = dllColor3uiv = GPA( "glColor3uiv" ); +	qglColor3us                  = dllColor3us = GPA( "glColor3us" ); +	qglColor3usv                 = dllColor3usv = GPA( "glColor3usv" ); +	qglColor4b                   = dllColor4b = GPA( "glColor4b" ); +	qglColor4bv                  = dllColor4bv = GPA( "glColor4bv" ); +	qglColor4d                   = dllColor4d = GPA( "glColor4d" ); +	qglColor4dv                  = dllColor4dv = GPA( "glColor4dv" ); +	qglColor4f                   = dllColor4f = GPA( "glColor4f" ); +	qglColor4fv                  = dllColor4fv = GPA( "glColor4fv" ); +	qglColor4i                   = dllColor4i = GPA( "glColor4i" ); +	qglColor4iv                  = dllColor4iv = GPA( "glColor4iv" ); +	qglColor4s                   = dllColor4s = GPA( "glColor4s" ); +	qglColor4sv                  = dllColor4sv = GPA( "glColor4sv" ); +	qglColor4ub                  = dllColor4ub = GPA( "glColor4ub" ); +	qglColor4ubv                 = dllColor4ubv = GPA( "glColor4ubv" ); +	qglColor4ui                  = dllColor4ui = GPA( "glColor4ui" ); +	qglColor4uiv                 = dllColor4uiv = GPA( "glColor4uiv" ); +	qglColor4us                  = dllColor4us = GPA( "glColor4us" ); +	qglColor4usv                 = dllColor4usv = GPA( "glColor4usv" ); +	qglColorMask                 = dllColorMask = GPA( "glColorMask" ); +	qglColorMaterial             = dllColorMaterial = GPA( "glColorMaterial" ); +	qglColorPointer              = dllColorPointer = GPA( "glColorPointer" ); +	qglCopyPixels                = dllCopyPixels = GPA( "glCopyPixels" ); +	qglCopyTexImage1D            = dllCopyTexImage1D = GPA( "glCopyTexImage1D" ); +	qglCopyTexImage2D            = dllCopyTexImage2D = GPA( "glCopyTexImage2D" ); +	qglCopyTexSubImage1D         = dllCopyTexSubImage1D = GPA( "glCopyTexSubImage1D" ); +	qglCopyTexSubImage2D         = dllCopyTexSubImage2D = GPA( "glCopyTexSubImage2D" ); +	qglCullFace                  = dllCullFace = GPA( "glCullFace" ); +	qglDeleteLists               = dllDeleteLists = GPA( "glDeleteLists" ); +	qglDeleteTextures            = dllDeleteTextures = GPA( "glDeleteTextures" ); +	qglDepthFunc                 = dllDepthFunc = GPA( "glDepthFunc" ); +	qglDepthMask                 = dllDepthMask = GPA( "glDepthMask" ); +	qglDepthRange                = dllDepthRange = GPA( "glDepthRange" ); +	qglDisable                   = dllDisable = GPA( "glDisable" ); +	qglDisableClientState        = dllDisableClientState = GPA( "glDisableClientState" ); +	qglDrawArrays                = dllDrawArrays = GPA( "glDrawArrays" ); +	qglDrawBuffer                = dllDrawBuffer = GPA( "glDrawBuffer" ); +	qglDrawElements              = dllDrawElements = GPA( "glDrawElements" ); +	qglDrawPixels                = dllDrawPixels = GPA( "glDrawPixels" ); +	qglEdgeFlag                  = dllEdgeFlag = GPA( "glEdgeFlag" ); +	qglEdgeFlagPointer           = dllEdgeFlagPointer = GPA( "glEdgeFlagPointer" ); +	qglEdgeFlagv                 = dllEdgeFlagv = GPA( "glEdgeFlagv" ); +	qglEnable                    = 	dllEnable                    = GPA( "glEnable" ); +	qglEnableClientState         = 	dllEnableClientState         = GPA( "glEnableClientState" ); +	qglEnd                       = 	dllEnd                       = GPA( "glEnd" ); +	qglEndList                   = 	dllEndList                   = GPA( "glEndList" ); +	qglEvalCoord1d				 = 	dllEvalCoord1d				 = GPA( "glEvalCoord1d" ); +	qglEvalCoord1dv              = 	dllEvalCoord1dv              = GPA( "glEvalCoord1dv" ); +	qglEvalCoord1f               = 	dllEvalCoord1f               = GPA( "glEvalCoord1f" ); +	qglEvalCoord1fv              = 	dllEvalCoord1fv              = GPA( "glEvalCoord1fv" ); +	qglEvalCoord2d               = 	dllEvalCoord2d               = GPA( "glEvalCoord2d" ); +	qglEvalCoord2dv              = 	dllEvalCoord2dv              = GPA( "glEvalCoord2dv" ); +	qglEvalCoord2f               = 	dllEvalCoord2f               = GPA( "glEvalCoord2f" ); +	qglEvalCoord2fv              = 	dllEvalCoord2fv              = GPA( "glEvalCoord2fv" ); +	qglEvalMesh1                 = 	dllEvalMesh1                 = GPA( "glEvalMesh1" ); +	qglEvalMesh2                 = 	dllEvalMesh2                 = GPA( "glEvalMesh2" ); +	qglEvalPoint1                = 	dllEvalPoint1                = GPA( "glEvalPoint1" ); +	qglEvalPoint2                = 	dllEvalPoint2                = GPA( "glEvalPoint2" ); +	qglFeedbackBuffer            = 	dllFeedbackBuffer            = GPA( "glFeedbackBuffer" ); +	qglFinish                    = 	dllFinish                    = GPA( "glFinish" ); +	qglFlush                     = 	dllFlush                     = GPA( "glFlush" ); +	qglFogf                      = 	dllFogf                      = GPA( "glFogf" ); +	qglFogfv                     = 	dllFogfv                     = GPA( "glFogfv" ); +	qglFogi                      = 	dllFogi                      = GPA( "glFogi" ); +	qglFogiv                     = 	dllFogiv                     = GPA( "glFogiv" ); +	qglFrontFace                 = 	dllFrontFace                 = GPA( "glFrontFace" ); +	qglFrustum                   = 	dllFrustum                   = GPA( "glFrustum" ); +	qglGenLists                  = 	dllGenLists                  = ( GLuint (__stdcall * )(int) ) GPA( "glGenLists" ); +	qglGenTextures               = 	dllGenTextures               = GPA( "glGenTextures" ); +	qglGetBooleanv               = 	dllGetBooleanv               = GPA( "glGetBooleanv" ); +	qglGetClipPlane              = 	dllGetClipPlane              = GPA( "glGetClipPlane" ); +	qglGetDoublev                = 	dllGetDoublev                = GPA( "glGetDoublev" ); +	qglGetError                  = 	dllGetError                  = ( GLenum (__stdcall * )(void) ) GPA( "glGetError" ); +	qglGetFloatv                 = 	dllGetFloatv                 = GPA( "glGetFloatv" ); +	qglGetIntegerv               = 	dllGetIntegerv               = GPA( "glGetIntegerv" ); +	qglGetLightfv                = 	dllGetLightfv                = GPA( "glGetLightfv" ); +	qglGetLightiv                = 	dllGetLightiv                = GPA( "glGetLightiv" ); +	qglGetMapdv                  = 	dllGetMapdv                  = GPA( "glGetMapdv" ); +	qglGetMapfv                  = 	dllGetMapfv                  = GPA( "glGetMapfv" ); +	qglGetMapiv                  = 	dllGetMapiv                  = GPA( "glGetMapiv" ); +	qglGetMaterialfv             = 	dllGetMaterialfv             = GPA( "glGetMaterialfv" ); +	qglGetMaterialiv             = 	dllGetMaterialiv             = GPA( "glGetMaterialiv" ); +	qglGetPixelMapfv             = 	dllGetPixelMapfv             = GPA( "glGetPixelMapfv" ); +	qglGetPixelMapuiv            = 	dllGetPixelMapuiv            = GPA( "glGetPixelMapuiv" ); +	qglGetPixelMapusv            = 	dllGetPixelMapusv            = GPA( "glGetPixelMapusv" ); +	qglGetPointerv               = 	dllGetPointerv               = GPA( "glGetPointerv" ); +	qglGetPolygonStipple         = 	dllGetPolygonStipple         = GPA( "glGetPolygonStipple" ); +	qglGetString                 = 	dllGetString                 = GPA( "glGetString" ); +	qglGetTexEnvfv               = 	dllGetTexEnvfv               = GPA( "glGetTexEnvfv" ); +	qglGetTexEnviv               = 	dllGetTexEnviv               = GPA( "glGetTexEnviv" ); +	qglGetTexGendv               = 	dllGetTexGendv               = GPA( "glGetTexGendv" ); +	qglGetTexGenfv               = 	dllGetTexGenfv               = GPA( "glGetTexGenfv" ); +	qglGetTexGeniv               = 	dllGetTexGeniv               = GPA( "glGetTexGeniv" ); +	qglGetTexImage               = 	dllGetTexImage               = GPA( "glGetTexImage" ); +	qglGetTexParameterfv         = 	dllGetTexParameterfv         = GPA( "glGetTexParameterfv" ); +	qglGetTexParameteriv         = 	dllGetTexParameteriv         = GPA( "glGetTexParameteriv" ); +	qglHint                      = 	dllHint                      = GPA( "glHint" ); +	qglIndexMask                 = 	dllIndexMask                 = GPA( "glIndexMask" ); +	qglIndexPointer              = 	dllIndexPointer              = GPA( "glIndexPointer" ); +	qglIndexd                    = 	dllIndexd                    = GPA( "glIndexd" ); +	qglIndexdv                   = 	dllIndexdv                   = GPA( "glIndexdv" ); +	qglIndexf                    = 	dllIndexf                    = GPA( "glIndexf" ); +	qglIndexfv                   = 	dllIndexfv                   = GPA( "glIndexfv" ); +	qglIndexi                    = 	dllIndexi                    = GPA( "glIndexi" ); +	qglIndexiv                   = 	dllIndexiv                   = GPA( "glIndexiv" ); +	qglIndexs                    = 	dllIndexs                    = GPA( "glIndexs" ); +	qglIndexsv                   = 	dllIndexsv                   = GPA( "glIndexsv" ); +	qglIndexub                   = 	dllIndexub                   = GPA( "glIndexub" ); +	qglIndexubv                  = 	dllIndexubv                  = GPA( "glIndexubv" ); +	qglInitNames                 = 	dllInitNames                 = GPA( "glInitNames" ); +	qglInterleavedArrays         = 	dllInterleavedArrays         = GPA( "glInterleavedArrays" ); +	qglIsEnabled                 = 	dllIsEnabled                 = GPA( "glIsEnabled" ); +	qglIsList                    = 	dllIsList                    = GPA( "glIsList" ); +	qglIsTexture                 = 	dllIsTexture                 = GPA( "glIsTexture" ); +	qglLightModelf               = 	dllLightModelf               = GPA( "glLightModelf" ); +	qglLightModelfv              = 	dllLightModelfv              = GPA( "glLightModelfv" ); +	qglLightModeli               = 	dllLightModeli               = GPA( "glLightModeli" ); +	qglLightModeliv              = 	dllLightModeliv              = GPA( "glLightModeliv" ); +	qglLightf                    = 	dllLightf                    = GPA( "glLightf" ); +	qglLightfv                   = 	dllLightfv                   = GPA( "glLightfv" ); +	qglLighti                    = 	dllLighti                    = GPA( "glLighti" ); +	qglLightiv                   = 	dllLightiv                   = GPA( "glLightiv" ); +	qglLineStipple               = 	dllLineStipple               = GPA( "glLineStipple" ); +	qglLineWidth                 = 	dllLineWidth                 = GPA( "glLineWidth" ); +	qglListBase                  = 	dllListBase                  = GPA( "glListBase" ); +	qglLoadIdentity              = 	dllLoadIdentity              = GPA( "glLoadIdentity" ); +	qglLoadMatrixd               = 	dllLoadMatrixd               = GPA( "glLoadMatrixd" ); +	qglLoadMatrixf               = 	dllLoadMatrixf               = GPA( "glLoadMatrixf" ); +	qglLoadName                  = 	dllLoadName                  = GPA( "glLoadName" ); +	qglLogicOp                   = 	dllLogicOp                   = GPA( "glLogicOp" ); +	qglMap1d                     = 	dllMap1d                     = GPA( "glMap1d" ); +	qglMap1f                     = 	dllMap1f                     = GPA( "glMap1f" ); +	qglMap2d                     = 	dllMap2d                     = GPA( "glMap2d" ); +	qglMap2f                     = 	dllMap2f                     = GPA( "glMap2f" ); +	qglMapGrid1d                 = 	dllMapGrid1d                 = GPA( "glMapGrid1d" ); +	qglMapGrid1f                 = 	dllMapGrid1f                 = GPA( "glMapGrid1f" ); +	qglMapGrid2d                 = 	dllMapGrid2d                 = GPA( "glMapGrid2d" ); +	qglMapGrid2f                 = 	dllMapGrid2f                 = GPA( "glMapGrid2f" ); +	qglMaterialf                 = 	dllMaterialf                 = GPA( "glMaterialf" ); +	qglMaterialfv                = 	dllMaterialfv                = GPA( "glMaterialfv" ); +	qglMateriali                 = 	dllMateriali                 = GPA( "glMateriali" ); +	qglMaterialiv                = 	dllMaterialiv                = GPA( "glMaterialiv" ); +	qglMatrixMode                = 	dllMatrixMode                = GPA( "glMatrixMode" ); +	qglMultMatrixd               = 	dllMultMatrixd               = GPA( "glMultMatrixd" ); +	qglMultMatrixf               = 	dllMultMatrixf               = GPA( "glMultMatrixf" ); +	qglNewList                   = 	dllNewList                   = GPA( "glNewList" ); +	qglNormal3b                  = 	dllNormal3b                  = GPA( "glNormal3b" ); +	qglNormal3bv                 = 	dllNormal3bv                 = GPA( "glNormal3bv" ); +	qglNormal3d                  = 	dllNormal3d                  = GPA( "glNormal3d" ); +	qglNormal3dv                 = 	dllNormal3dv                 = GPA( "glNormal3dv" ); +	qglNormal3f                  = 	dllNormal3f                  = GPA( "glNormal3f" ); +	qglNormal3fv                 = 	dllNormal3fv                 = GPA( "glNormal3fv" ); +	qglNormal3i                  = 	dllNormal3i                  = GPA( "glNormal3i" ); +	qglNormal3iv                 = 	dllNormal3iv                 = GPA( "glNormal3iv" ); +	qglNormal3s                  = 	dllNormal3s                  = GPA( "glNormal3s" ); +	qglNormal3sv                 = 	dllNormal3sv                 = GPA( "glNormal3sv" ); +	qglNormalPointer             = 	dllNormalPointer             = GPA( "glNormalPointer" ); +	qglOrtho                     = 	dllOrtho                     = GPA( "glOrtho" ); +	qglPassThrough               = 	dllPassThrough               = GPA( "glPassThrough" ); +	qglPixelMapfv                = 	dllPixelMapfv                = GPA( "glPixelMapfv" ); +	qglPixelMapuiv               = 	dllPixelMapuiv               = GPA( "glPixelMapuiv" ); +	qglPixelMapusv               = 	dllPixelMapusv               = GPA( "glPixelMapusv" ); +	qglPixelStoref               = 	dllPixelStoref               = GPA( "glPixelStoref" ); +	qglPixelStorei               = 	dllPixelStorei               = GPA( "glPixelStorei" ); +	qglPixelTransferf            = 	dllPixelTransferf            = GPA( "glPixelTransferf" ); +	qglPixelTransferi            = 	dllPixelTransferi            = GPA( "glPixelTransferi" ); +	qglPixelZoom                 = 	dllPixelZoom                 = GPA( "glPixelZoom" ); +	qglPointSize                 = 	dllPointSize                 = GPA( "glPointSize" ); +	qglPolygonMode               = 	dllPolygonMode               = GPA( "glPolygonMode" ); +	qglPolygonOffset             = 	dllPolygonOffset             = GPA( "glPolygonOffset" ); +	qglPolygonStipple            = 	dllPolygonStipple            = GPA( "glPolygonStipple" ); +	qglPopAttrib                 = 	dllPopAttrib                 = GPA( "glPopAttrib" ); +	qglPopClientAttrib           = 	dllPopClientAttrib           = GPA( "glPopClientAttrib" ); +	qglPopMatrix                 = 	dllPopMatrix                 = GPA( "glPopMatrix" ); +	qglPopName                   = 	dllPopName                   = GPA( "glPopName" ); +	qglPrioritizeTextures        = 	dllPrioritizeTextures        = GPA( "glPrioritizeTextures" ); +	qglPushAttrib                = 	dllPushAttrib                = GPA( "glPushAttrib" ); +	qglPushClientAttrib          = 	dllPushClientAttrib          = GPA( "glPushClientAttrib" ); +	qglPushMatrix                = 	dllPushMatrix                = GPA( "glPushMatrix" ); +	qglPushName                  = 	dllPushName                  = GPA( "glPushName" ); +	qglRasterPos2d               = 	dllRasterPos2d               = GPA( "glRasterPos2d" ); +	qglRasterPos2dv              = 	dllRasterPos2dv              = GPA( "glRasterPos2dv" ); +	qglRasterPos2f               = 	dllRasterPos2f               = GPA( "glRasterPos2f" ); +	qglRasterPos2fv              = 	dllRasterPos2fv              = GPA( "glRasterPos2fv" ); +	qglRasterPos2i               = 	dllRasterPos2i               = GPA( "glRasterPos2i" ); +	qglRasterPos2iv              = 	dllRasterPos2iv              = GPA( "glRasterPos2iv" ); +	qglRasterPos2s               = 	dllRasterPos2s               = GPA( "glRasterPos2s" ); +	qglRasterPos2sv              = 	dllRasterPos2sv              = GPA( "glRasterPos2sv" ); +	qglRasterPos3d               = 	dllRasterPos3d               = GPA( "glRasterPos3d" ); +	qglRasterPos3dv              = 	dllRasterPos3dv              = GPA( "glRasterPos3dv" ); +	qglRasterPos3f               = 	dllRasterPos3f               = GPA( "glRasterPos3f" ); +	qglRasterPos3fv              = 	dllRasterPos3fv              = GPA( "glRasterPos3fv" ); +	qglRasterPos3i               = 	dllRasterPos3i               = GPA( "glRasterPos3i" ); +	qglRasterPos3iv              = 	dllRasterPos3iv              = GPA( "glRasterPos3iv" ); +	qglRasterPos3s               = 	dllRasterPos3s               = GPA( "glRasterPos3s" ); +	qglRasterPos3sv              = 	dllRasterPos3sv              = GPA( "glRasterPos3sv" ); +	qglRasterPos4d               = 	dllRasterPos4d               = GPA( "glRasterPos4d" ); +	qglRasterPos4dv              = 	dllRasterPos4dv              = GPA( "glRasterPos4dv" ); +	qglRasterPos4f               = 	dllRasterPos4f               = GPA( "glRasterPos4f" ); +	qglRasterPos4fv              = 	dllRasterPos4fv              = GPA( "glRasterPos4fv" ); +	qglRasterPos4i               = 	dllRasterPos4i               = GPA( "glRasterPos4i" ); +	qglRasterPos4iv              = 	dllRasterPos4iv              = GPA( "glRasterPos4iv" ); +	qglRasterPos4s               = 	dllRasterPos4s               = GPA( "glRasterPos4s" ); +	qglRasterPos4sv              = 	dllRasterPos4sv              = GPA( "glRasterPos4sv" ); +	qglReadBuffer                = 	dllReadBuffer                = GPA( "glReadBuffer" ); +	qglReadPixels                = 	dllReadPixels                = GPA( "glReadPixels" ); +	qglRectd                     = 	dllRectd                     = GPA( "glRectd" ); +	qglRectdv                    = 	dllRectdv                    = GPA( "glRectdv" ); +	qglRectf                     = 	dllRectf                     = GPA( "glRectf" ); +	qglRectfv                    = 	dllRectfv                    = GPA( "glRectfv" ); +	qglRecti                     = 	dllRecti                     = GPA( "glRecti" ); +	qglRectiv                    = 	dllRectiv                    = GPA( "glRectiv" ); +	qglRects                     = 	dllRects                     = GPA( "glRects" ); +	qglRectsv                    = 	dllRectsv                    = GPA( "glRectsv" ); +	qglRenderMode                = 	dllRenderMode                = GPA( "glRenderMode" ); +	qglRotated                   = 	dllRotated                   = GPA( "glRotated" ); +	qglRotatef                   = 	dllRotatef                   = GPA( "glRotatef" ); +	qglScaled                    = 	dllScaled                    = GPA( "glScaled" ); +	qglScalef                    = 	dllScalef                    = GPA( "glScalef" ); +	qglScissor                   = 	dllScissor                   = GPA( "glScissor" ); +	qglSelectBuffer              = 	dllSelectBuffer              = GPA( "glSelectBuffer" ); +	qglShadeModel                = 	dllShadeModel                = GPA( "glShadeModel" ); +	qglStencilFunc               = 	dllStencilFunc               = GPA( "glStencilFunc" ); +	qglStencilMask               = 	dllStencilMask               = GPA( "glStencilMask" ); +	qglStencilOp                 = 	dllStencilOp                 = GPA( "glStencilOp" ); +	qglTexCoord1d                = 	dllTexCoord1d                = GPA( "glTexCoord1d" ); +	qglTexCoord1dv               = 	dllTexCoord1dv               = GPA( "glTexCoord1dv" ); +	qglTexCoord1f                = 	dllTexCoord1f                = GPA( "glTexCoord1f" ); +	qglTexCoord1fv               = 	dllTexCoord1fv               = GPA( "glTexCoord1fv" ); +	qglTexCoord1i                = 	dllTexCoord1i                = GPA( "glTexCoord1i" ); +	qglTexCoord1iv               = 	dllTexCoord1iv               = GPA( "glTexCoord1iv" ); +	qglTexCoord1s                = 	dllTexCoord1s                = GPA( "glTexCoord1s" ); +	qglTexCoord1sv               = 	dllTexCoord1sv               = GPA( "glTexCoord1sv" ); +	qglTexCoord2d                = 	dllTexCoord2d                = GPA( "glTexCoord2d" ); +	qglTexCoord2dv               = 	dllTexCoord2dv               = GPA( "glTexCoord2dv" ); +	qglTexCoord2f                = 	dllTexCoord2f                = GPA( "glTexCoord2f" ); +	qglTexCoord2fv               = 	dllTexCoord2fv               = GPA( "glTexCoord2fv" ); +	qglTexCoord2i                = 	dllTexCoord2i                = GPA( "glTexCoord2i" ); +	qglTexCoord2iv               = 	dllTexCoord2iv               = GPA( "glTexCoord2iv" ); +	qglTexCoord2s                = 	dllTexCoord2s                = GPA( "glTexCoord2s" ); +	qglTexCoord2sv               = 	dllTexCoord2sv               = GPA( "glTexCoord2sv" ); +	qglTexCoord3d                = 	dllTexCoord3d                = GPA( "glTexCoord3d" ); +	qglTexCoord3dv               = 	dllTexCoord3dv               = GPA( "glTexCoord3dv" ); +	qglTexCoord3f                = 	dllTexCoord3f                = GPA( "glTexCoord3f" ); +	qglTexCoord3fv               = 	dllTexCoord3fv               = GPA( "glTexCoord3fv" ); +	qglTexCoord3i                = 	dllTexCoord3i                = GPA( "glTexCoord3i" ); +	qglTexCoord3iv               = 	dllTexCoord3iv               = GPA( "glTexCoord3iv" ); +	qglTexCoord3s                = 	dllTexCoord3s                = GPA( "glTexCoord3s" ); +	qglTexCoord3sv               = 	dllTexCoord3sv               = GPA( "glTexCoord3sv" ); +	qglTexCoord4d                = 	dllTexCoord4d                = GPA( "glTexCoord4d" ); +	qglTexCoord4dv               = 	dllTexCoord4dv               = GPA( "glTexCoord4dv" ); +	qglTexCoord4f                = 	dllTexCoord4f                = GPA( "glTexCoord4f" ); +	qglTexCoord4fv               = 	dllTexCoord4fv               = GPA( "glTexCoord4fv" ); +	qglTexCoord4i                = 	dllTexCoord4i                = GPA( "glTexCoord4i" ); +	qglTexCoord4iv               = 	dllTexCoord4iv               = GPA( "glTexCoord4iv" ); +	qglTexCoord4s                = 	dllTexCoord4s                = GPA( "glTexCoord4s" ); +	qglTexCoord4sv               = 	dllTexCoord4sv               = GPA( "glTexCoord4sv" ); +	qglTexCoordPointer           = 	dllTexCoordPointer           = GPA( "glTexCoordPointer" ); +	qglTexEnvf                   = 	dllTexEnvf                   = GPA( "glTexEnvf" ); +	qglTexEnvfv                  = 	dllTexEnvfv                  = GPA( "glTexEnvfv" ); +	qglTexEnvi                   = 	dllTexEnvi                   = GPA( "glTexEnvi" ); +	qglTexEnviv                  = 	dllTexEnviv                  = GPA( "glTexEnviv" ); +	qglTexGend                   = 	dllTexGend                   = GPA( "glTexGend" ); +	qglTexGendv                  = 	dllTexGendv                  = GPA( "glTexGendv" ); +	qglTexGenf                   = 	dllTexGenf                   = GPA( "glTexGenf" ); +	qglTexGenfv                  = 	dllTexGenfv                  = GPA( "glTexGenfv" ); +	qglTexGeni                   = 	dllTexGeni                   = GPA( "glTexGeni" ); +	qglTexGeniv                  = 	dllTexGeniv                  = GPA( "glTexGeniv" ); +	qglTexImage1D                = 	dllTexImage1D                = GPA( "glTexImage1D" ); +	qglTexImage2D                = 	dllTexImage2D                = GPA( "glTexImage2D" ); +	qglTexParameterf             = 	dllTexParameterf             = GPA( "glTexParameterf" ); +	qglTexParameterfv            = 	dllTexParameterfv            = GPA( "glTexParameterfv" ); +	qglTexParameteri             = 	dllTexParameteri             = GPA( "glTexParameteri" ); +	qglTexParameteriv            = 	dllTexParameteriv            = GPA( "glTexParameteriv" ); +	qglTexSubImage1D             = 	dllTexSubImage1D             = GPA( "glTexSubImage1D" ); +	qglTexSubImage2D             = 	dllTexSubImage2D             = GPA( "glTexSubImage2D" ); +	qglTranslated                = 	dllTranslated                = GPA( "glTranslated" ); +	qglTranslatef                = 	dllTranslatef                = GPA( "glTranslatef" ); +	qglVertex2d                  = 	dllVertex2d                  = GPA( "glVertex2d" ); +	qglVertex2dv                 = 	dllVertex2dv                 = GPA( "glVertex2dv" ); +	qglVertex2f                  = 	dllVertex2f                  = GPA( "glVertex2f" ); +	qglVertex2fv                 = 	dllVertex2fv                 = GPA( "glVertex2fv" ); +	qglVertex2i                  = 	dllVertex2i                  = GPA( "glVertex2i" ); +	qglVertex2iv                 = 	dllVertex2iv                 = GPA( "glVertex2iv" ); +	qglVertex2s                  = 	dllVertex2s                  = GPA( "glVertex2s" ); +	qglVertex2sv                 = 	dllVertex2sv                 = GPA( "glVertex2sv" ); +	qglVertex3d                  = 	dllVertex3d                  = GPA( "glVertex3d" ); +	qglVertex3dv                 = 	dllVertex3dv                 = GPA( "glVertex3dv" ); +	qglVertex3f                  = 	dllVertex3f                  = GPA( "glVertex3f" ); +	qglVertex3fv                 = 	dllVertex3fv                 = GPA( "glVertex3fv" ); +	qglVertex3i                  = 	dllVertex3i                  = GPA( "glVertex3i" ); +	qglVertex3iv                 = 	dllVertex3iv                 = GPA( "glVertex3iv" ); +	qglVertex3s                  = 	dllVertex3s                  = GPA( "glVertex3s" ); +	qglVertex3sv                 = 	dllVertex3sv                 = GPA( "glVertex3sv" ); +	qglVertex4d                  = 	dllVertex4d                  = GPA( "glVertex4d" ); +	qglVertex4dv                 = 	dllVertex4dv                 = GPA( "glVertex4dv" ); +	qglVertex4f                  = 	dllVertex4f                  = GPA( "glVertex4f" ); +	qglVertex4fv                 = 	dllVertex4fv                 = GPA( "glVertex4fv" ); +	qglVertex4i                  = 	dllVertex4i                  = GPA( "glVertex4i" ); +	qglVertex4iv                 = 	dllVertex4iv                 = GPA( "glVertex4iv" ); +	qglVertex4s                  = 	dllVertex4s                  = GPA( "glVertex4s" ); +	qglVertex4sv                 = 	dllVertex4sv                 = GPA( "glVertex4sv" ); +	qglVertexPointer             = 	dllVertexPointer             = GPA( "glVertexPointer" ); +	qglViewport                  = 	dllViewport                  = GPA( "glViewport" ); + +	qwglCopyContext              = GPA( "wglCopyContext" ); +	qwglCreateContext            = GPA( "wglCreateContext" ); +	qwglCreateLayerContext       = GPA( "wglCreateLayerContext" ); +	qwglDeleteContext            = GPA( "wglDeleteContext" ); +	qwglDescribeLayerPlane       = GPA( "wglDescribeLayerPlane" ); +	qwglGetCurrentContext        = GPA( "wglGetCurrentContext" ); +	qwglGetCurrentDC             = GPA( "wglGetCurrentDC" ); +	qwglGetLayerPaletteEntries   = GPA( "wglGetLayerPaletteEntries" ); +	qwglGetProcAddress           = GPA( "wglGetProcAddress" ); +	qwglMakeCurrent              = GPA( "wglMakeCurrent" ); +	qwglRealizeLayerPalette      = GPA( "wglRealizeLayerPalette" ); +	qwglSetLayerPaletteEntries   = GPA( "wglSetLayerPaletteEntries" ); +	qwglShareLists               = GPA( "wglShareLists" ); +	qwglSwapLayerBuffers         = GPA( "wglSwapLayerBuffers" ); +	qwglUseFontBitmaps           = GPA( "wglUseFontBitmapsA" ); +	qwglUseFontOutlines          = GPA( "wglUseFontOutlinesA" ); + +	qwglChoosePixelFormat        = GPA( "wglChoosePixelFormat" ); +	qwglDescribePixelFormat      = GPA( "wglDescribePixelFormat" ); +	qwglGetPixelFormat           = GPA( "wglGetPixelFormat" ); +	qwglSetPixelFormat           = GPA( "wglSetPixelFormat" ); +	qwglSwapBuffers              = GPA( "wglSwapBuffers" ); + +	qwglSwapIntervalEXT = 0; +	qglActiveTextureARB = 0; +	qglClientActiveTextureARB = 0; +	qglMultiTexCoord2fARB = 0; +	qglLockArraysEXT = 0; +	qglUnlockArraysEXT = 0; +	qwglGetDeviceGammaRamp3DFX = NULL; +	qwglSetDeviceGammaRamp3DFX = NULL; + +	// check logging +	QGL_EnableLogging( r_logFile->integer ); + +	return qtrue; +} + +void QGL_EnableLogging( qboolean enable ) +{ +	static qboolean isEnabled; + +	// return if we're already active +	if ( isEnabled && enable ) { +		// decrement log counter and stop if it has reached 0 +		ri.Cvar_Set( "r_logFile", va("%d", r_logFile->integer - 1 ) ); +		if ( r_logFile->integer ) { +			return; +		} +		enable = qfalse; +	} + +	// return if we're already disabled +	if ( !enable && !isEnabled ) +		return; + +	isEnabled = enable; + +	if ( enable ) +	{ +		if ( !glw_state.log_fp ) +		{ +			struct tm *newtime; +			time_t aclock; +			char buffer[1024]; +			cvar_t	*basedir; + +			time( &aclock ); +			newtime = localtime( &aclock ); + +			asctime( newtime ); + +			basedir = ri.Cvar_Get( "fs_basepath", "", 0 ); +			Com_sprintf( buffer, sizeof(buffer), "%s/gl.log", basedir->string );  +			glw_state.log_fp = fopen( buffer, "wt" ); + +			fprintf( glw_state.log_fp, "%s\n", asctime( newtime ) ); +		} + +		qglAccum                     = logAccum; +		qglAlphaFunc                 = logAlphaFunc; +		qglAreTexturesResident       = logAreTexturesResident; +		qglArrayElement              = logArrayElement; +		qglBegin                     = logBegin; +		qglBindTexture               = logBindTexture; +		qglBitmap                    = logBitmap; +		qglBlendFunc                 = logBlendFunc; +		qglCallList                  = logCallList; +		qglCallLists                 = logCallLists; +		qglClear                     = logClear; +		qglClearAccum                = logClearAccum; +		qglClearColor                = logClearColor; +		qglClearDepth                = logClearDepth; +		qglClearIndex                = logClearIndex; +		qglClearStencil              = logClearStencil; +		qglClipPlane                 = logClipPlane; +		qglColor3b                   = logColor3b; +		qglColor3bv                  = logColor3bv; +		qglColor3d                   = logColor3d; +		qglColor3dv                  = logColor3dv; +		qglColor3f                   = logColor3f; +		qglColor3fv                  = logColor3fv; +		qglColor3i                   = logColor3i; +		qglColor3iv                  = logColor3iv; +		qglColor3s                   = logColor3s; +		qglColor3sv                  = logColor3sv; +		qglColor3ub                  = logColor3ub; +		qglColor3ubv                 = logColor3ubv; +		qglColor3ui                  = logColor3ui; +		qglColor3uiv                 = logColor3uiv; +		qglColor3us                  = logColor3us; +		qglColor3usv                 = logColor3usv; +		qglColor4b                   = logColor4b; +		qglColor4bv                  = logColor4bv; +		qglColor4d                   = logColor4d; +		qglColor4dv                  = logColor4dv; +		qglColor4f                   = logColor4f; +		qglColor4fv                  = logColor4fv; +		qglColor4i                   = logColor4i; +		qglColor4iv                  = logColor4iv; +		qglColor4s                   = logColor4s; +		qglColor4sv                  = logColor4sv; +		qglColor4ub                  = logColor4ub; +		qglColor4ubv                 = logColor4ubv; +		qglColor4ui                  = logColor4ui; +		qglColor4uiv                 = logColor4uiv; +		qglColor4us                  = logColor4us; +		qglColor4usv                 = logColor4usv; +		qglColorMask                 = logColorMask; +		qglColorMaterial             = logColorMaterial; +		qglColorPointer              = logColorPointer; +		qglCopyPixels                = logCopyPixels; +		qglCopyTexImage1D            = logCopyTexImage1D; +		qglCopyTexImage2D            = logCopyTexImage2D; +		qglCopyTexSubImage1D         = logCopyTexSubImage1D; +		qglCopyTexSubImage2D         = logCopyTexSubImage2D; +		qglCullFace                  = logCullFace; +		qglDeleteLists               = logDeleteLists ; +		qglDeleteTextures            = logDeleteTextures ; +		qglDepthFunc                 = logDepthFunc ; +		qglDepthMask                 = logDepthMask ; +		qglDepthRange                = logDepthRange ; +		qglDisable                   = logDisable ; +		qglDisableClientState        = logDisableClientState ; +		qglDrawArrays                = logDrawArrays ; +		qglDrawBuffer                = logDrawBuffer ; +		qglDrawElements              = logDrawElements ; +		qglDrawPixels                = logDrawPixels ; +		qglEdgeFlag                  = logEdgeFlag ; +		qglEdgeFlagPointer           = logEdgeFlagPointer ; +		qglEdgeFlagv                 = logEdgeFlagv ; +		qglEnable                    = 	logEnable                    ; +		qglEnableClientState         = 	logEnableClientState         ; +		qglEnd                       = 	logEnd                       ; +		qglEndList                   = 	logEndList                   ; +		qglEvalCoord1d				 = 	logEvalCoord1d				 ; +		qglEvalCoord1dv              = 	logEvalCoord1dv              ; +		qglEvalCoord1f               = 	logEvalCoord1f               ; +		qglEvalCoord1fv              = 	logEvalCoord1fv              ; +		qglEvalCoord2d               = 	logEvalCoord2d               ; +		qglEvalCoord2dv              = 	logEvalCoord2dv              ; +		qglEvalCoord2f               = 	logEvalCoord2f               ; +		qglEvalCoord2fv              = 	logEvalCoord2fv              ; +		qglEvalMesh1                 = 	logEvalMesh1                 ; +		qglEvalMesh2                 = 	logEvalMesh2                 ; +		qglEvalPoint1                = 	logEvalPoint1                ; +		qglEvalPoint2                = 	logEvalPoint2                ; +		qglFeedbackBuffer            = 	logFeedbackBuffer            ; +		qglFinish                    = 	logFinish                    ; +		qglFlush                     = 	logFlush                     ; +		qglFogf                      = 	logFogf                      ; +		qglFogfv                     = 	logFogfv                     ; +		qglFogi                      = 	logFogi                      ; +		qglFogiv                     = 	logFogiv                     ; +		qglFrontFace                 = 	logFrontFace                 ; +		qglFrustum                   = 	logFrustum                   ; +		qglGenLists                  = 	logGenLists                  ; +		qglGenTextures               = 	logGenTextures               ; +		qglGetBooleanv               = 	logGetBooleanv               ; +		qglGetClipPlane              = 	logGetClipPlane              ; +		qglGetDoublev                = 	logGetDoublev                ; +		qglGetError                  = 	logGetError                  ; +		qglGetFloatv                 = 	logGetFloatv                 ; +		qglGetIntegerv               = 	logGetIntegerv               ; +		qglGetLightfv                = 	logGetLightfv                ; +		qglGetLightiv                = 	logGetLightiv                ; +		qglGetMapdv                  = 	logGetMapdv                  ; +		qglGetMapfv                  = 	logGetMapfv                  ; +		qglGetMapiv                  = 	logGetMapiv                  ; +		qglGetMaterialfv             = 	logGetMaterialfv             ; +		qglGetMaterialiv             = 	logGetMaterialiv             ; +		qglGetPixelMapfv             = 	logGetPixelMapfv             ; +		qglGetPixelMapuiv            = 	logGetPixelMapuiv            ; +		qglGetPixelMapusv            = 	logGetPixelMapusv            ; +		qglGetPointerv               = 	logGetPointerv               ; +		qglGetPolygonStipple         = 	logGetPolygonStipple         ; +		qglGetString                 = 	logGetString                 ; +		qglGetTexEnvfv               = 	logGetTexEnvfv               ; +		qglGetTexEnviv               = 	logGetTexEnviv               ; +		qglGetTexGendv               = 	logGetTexGendv               ; +		qglGetTexGenfv               = 	logGetTexGenfv               ; +		qglGetTexGeniv               = 	logGetTexGeniv               ; +		qglGetTexImage               = 	logGetTexImage               ; +		qglGetTexLevelParameterfv    = 	logGetTexLevelParameterfv    ; +		qglGetTexLevelParameteriv    = 	logGetTexLevelParameteriv    ; +		qglGetTexParameterfv         = 	logGetTexParameterfv         ; +		qglGetTexParameteriv         = 	logGetTexParameteriv         ; +		qglHint                      = 	logHint                      ; +		qglIndexMask                 = 	logIndexMask                 ; +		qglIndexPointer              = 	logIndexPointer              ; +		qglIndexd                    = 	logIndexd                    ; +		qglIndexdv                   = 	logIndexdv                   ; +		qglIndexf                    = 	logIndexf                    ; +		qglIndexfv                   = 	logIndexfv                   ; +		qglIndexi                    = 	logIndexi                    ; +		qglIndexiv                   = 	logIndexiv                   ; +		qglIndexs                    = 	logIndexs                    ; +		qglIndexsv                   = 	logIndexsv                   ; +		qglIndexub                   = 	logIndexub                   ; +		qglIndexubv                  = 	logIndexubv                  ; +		qglInitNames                 = 	logInitNames                 ; +		qglInterleavedArrays         = 	logInterleavedArrays         ; +		qglIsEnabled                 = 	logIsEnabled                 ; +		qglIsList                    = 	logIsList                    ; +		qglIsTexture                 = 	logIsTexture                 ; +		qglLightModelf               = 	logLightModelf               ; +		qglLightModelfv              = 	logLightModelfv              ; +		qglLightModeli               = 	logLightModeli               ; +		qglLightModeliv              = 	logLightModeliv              ; +		qglLightf                    = 	logLightf                    ; +		qglLightfv                   = 	logLightfv                   ; +		qglLighti                    = 	logLighti                    ; +		qglLightiv                   = 	logLightiv                   ; +		qglLineStipple               = 	logLineStipple               ; +		qglLineWidth                 = 	logLineWidth                 ; +		qglListBase                  = 	logListBase                  ; +		qglLoadIdentity              = 	logLoadIdentity              ; +		qglLoadMatrixd               = 	logLoadMatrixd               ; +		qglLoadMatrixf               = 	logLoadMatrixf               ; +		qglLoadName                  = 	logLoadName                  ; +		qglLogicOp                   = 	logLogicOp                   ; +		qglMap1d                     = 	logMap1d                     ; +		qglMap1f                     = 	logMap1f                     ; +		qglMap2d                     = 	logMap2d                     ; +		qglMap2f                     = 	logMap2f                     ; +		qglMapGrid1d                 = 	logMapGrid1d                 ; +		qglMapGrid1f                 = 	logMapGrid1f                 ; +		qglMapGrid2d                 = 	logMapGrid2d                 ; +		qglMapGrid2f                 = 	logMapGrid2f                 ; +		qglMaterialf                 = 	logMaterialf                 ; +		qglMaterialfv                = 	logMaterialfv                ; +		qglMateriali                 = 	logMateriali                 ; +		qglMaterialiv                = 	logMaterialiv                ; +		qglMatrixMode                = 	logMatrixMode                ; +		qglMultMatrixd               = 	logMultMatrixd               ; +		qglMultMatrixf               = 	logMultMatrixf               ; +		qglNewList                   = 	logNewList                   ; +		qglNormal3b                  = 	logNormal3b                  ; +		qglNormal3bv                 = 	logNormal3bv                 ; +		qglNormal3d                  = 	logNormal3d                  ; +		qglNormal3dv                 = 	logNormal3dv                 ; +		qglNormal3f                  = 	logNormal3f                  ; +		qglNormal3fv                 = 	logNormal3fv                 ; +		qglNormal3i                  = 	logNormal3i                  ; +		qglNormal3iv                 = 	logNormal3iv                 ; +		qglNormal3s                  = 	logNormal3s                  ; +		qglNormal3sv                 = 	logNormal3sv                 ; +		qglNormalPointer             = 	logNormalPointer             ; +		qglOrtho                     = 	logOrtho                     ; +		qglPassThrough               = 	logPassThrough               ; +		qglPixelMapfv                = 	logPixelMapfv                ; +		qglPixelMapuiv               = 	logPixelMapuiv               ; +		qglPixelMapusv               = 	logPixelMapusv               ; +		qglPixelStoref               = 	logPixelStoref               ; +		qglPixelStorei               = 	logPixelStorei               ; +		qglPixelTransferf            = 	logPixelTransferf            ; +		qglPixelTransferi            = 	logPixelTransferi            ; +		qglPixelZoom                 = 	logPixelZoom                 ; +		qglPointSize                 = 	logPointSize                 ; +		qglPolygonMode               = 	logPolygonMode               ; +		qglPolygonOffset             = 	logPolygonOffset             ; +		qglPolygonStipple            = 	logPolygonStipple            ; +		qglPopAttrib                 = 	logPopAttrib                 ; +		qglPopClientAttrib           = 	logPopClientAttrib           ; +		qglPopMatrix                 = 	logPopMatrix                 ; +		qglPopName                   = 	logPopName                   ; +		qglPrioritizeTextures        = 	logPrioritizeTextures        ; +		qglPushAttrib                = 	logPushAttrib                ; +		qglPushClientAttrib          = 	logPushClientAttrib          ; +		qglPushMatrix                = 	logPushMatrix                ; +		qglPushName                  = 	logPushName                  ; +		qglRasterPos2d               = 	logRasterPos2d               ; +		qglRasterPos2dv              = 	logRasterPos2dv              ; +		qglRasterPos2f               = 	logRasterPos2f               ; +		qglRasterPos2fv              = 	logRasterPos2fv              ; +		qglRasterPos2i               = 	logRasterPos2i               ; +		qglRasterPos2iv              = 	logRasterPos2iv              ; +		qglRasterPos2s               = 	logRasterPos2s               ; +		qglRasterPos2sv              = 	logRasterPos2sv              ; +		qglRasterPos3d               = 	logRasterPos3d               ; +		qglRasterPos3dv              = 	logRasterPos3dv              ; +		qglRasterPos3f               = 	logRasterPos3f               ; +		qglRasterPos3fv              = 	logRasterPos3fv              ; +		qglRasterPos3i               = 	logRasterPos3i               ; +		qglRasterPos3iv              = 	logRasterPos3iv              ; +		qglRasterPos3s               = 	logRasterPos3s               ; +		qglRasterPos3sv              = 	logRasterPos3sv              ; +		qglRasterPos4d               = 	logRasterPos4d               ; +		qglRasterPos4dv              = 	logRasterPos4dv              ; +		qglRasterPos4f               = 	logRasterPos4f               ; +		qglRasterPos4fv              = 	logRasterPos4fv              ; +		qglRasterPos4i               = 	logRasterPos4i               ; +		qglRasterPos4iv              = 	logRasterPos4iv              ; +		qglRasterPos4s               = 	logRasterPos4s               ; +		qglRasterPos4sv              = 	logRasterPos4sv              ; +		qglReadBuffer                = 	logReadBuffer                ; +		qglReadPixels                = 	logReadPixels                ; +		qglRectd                     = 	logRectd                     ; +		qglRectdv                    = 	logRectdv                    ; +		qglRectf                     = 	logRectf                     ; +		qglRectfv                    = 	logRectfv                    ; +		qglRecti                     = 	logRecti                     ; +		qglRectiv                    = 	logRectiv                    ; +		qglRects                     = 	logRects                     ; +		qglRectsv                    = 	logRectsv                    ; +		qglRenderMode                = 	logRenderMode                ; +		qglRotated                   = 	logRotated                   ; +		qglRotatef                   = 	logRotatef                   ; +		qglScaled                    = 	logScaled                    ; +		qglScalef                    = 	logScalef                    ; +		qglScissor                   = 	logScissor                   ; +		qglSelectBuffer              = 	logSelectBuffer              ; +		qglShadeModel                = 	logShadeModel                ; +		qglStencilFunc               = 	logStencilFunc               ; +		qglStencilMask               = 	logStencilMask               ; +		qglStencilOp                 = 	logStencilOp                 ; +		qglTexCoord1d                = 	logTexCoord1d                ; +		qglTexCoord1dv               = 	logTexCoord1dv               ; +		qglTexCoord1f                = 	logTexCoord1f                ; +		qglTexCoord1fv               = 	logTexCoord1fv               ; +		qglTexCoord1i                = 	logTexCoord1i                ; +		qglTexCoord1iv               = 	logTexCoord1iv               ; +		qglTexCoord1s                = 	logTexCoord1s                ; +		qglTexCoord1sv               = 	logTexCoord1sv               ; +		qglTexCoord2d                = 	logTexCoord2d                ; +		qglTexCoord2dv               = 	logTexCoord2dv               ; +		qglTexCoord2f                = 	logTexCoord2f                ; +		qglTexCoord2fv               = 	logTexCoord2fv               ; +		qglTexCoord2i                = 	logTexCoord2i                ; +		qglTexCoord2iv               = 	logTexCoord2iv               ; +		qglTexCoord2s                = 	logTexCoord2s                ; +		qglTexCoord2sv               = 	logTexCoord2sv               ; +		qglTexCoord3d                = 	logTexCoord3d                ; +		qglTexCoord3dv               = 	logTexCoord3dv               ; +		qglTexCoord3f                = 	logTexCoord3f                ; +		qglTexCoord3fv               = 	logTexCoord3fv               ; +		qglTexCoord3i                = 	logTexCoord3i                ; +		qglTexCoord3iv               = 	logTexCoord3iv               ; +		qglTexCoord3s                = 	logTexCoord3s                ; +		qglTexCoord3sv               = 	logTexCoord3sv               ; +		qglTexCoord4d                = 	logTexCoord4d                ; +		qglTexCoord4dv               = 	logTexCoord4dv               ; +		qglTexCoord4f                = 	logTexCoord4f                ; +		qglTexCoord4fv               = 	logTexCoord4fv               ; +		qglTexCoord4i                = 	logTexCoord4i                ; +		qglTexCoord4iv               = 	logTexCoord4iv               ; +		qglTexCoord4s                = 	logTexCoord4s                ; +		qglTexCoord4sv               = 	logTexCoord4sv               ; +		qglTexCoordPointer           = 	logTexCoordPointer           ; +		qglTexEnvf                   = 	logTexEnvf                   ; +		qglTexEnvfv                  = 	logTexEnvfv                  ; +		qglTexEnvi                   = 	logTexEnvi                   ; +		qglTexEnviv                  = 	logTexEnviv                  ; +		qglTexGend                   = 	logTexGend                   ; +		qglTexGendv                  = 	logTexGendv                  ; +		qglTexGenf                   = 	logTexGenf                   ; +		qglTexGenfv                  = 	logTexGenfv                  ; +		qglTexGeni                   = 	logTexGeni                   ; +		qglTexGeniv                  = 	logTexGeniv                  ; +		qglTexImage1D                = 	logTexImage1D                ; +		qglTexImage2D                = 	logTexImage2D                ; +		qglTexParameterf             = 	logTexParameterf             ; +		qglTexParameterfv            = 	logTexParameterfv            ; +		qglTexParameteri             = 	logTexParameteri             ; +		qglTexParameteriv            = 	logTexParameteriv            ; +		qglTexSubImage1D             = 	logTexSubImage1D             ; +		qglTexSubImage2D             = 	logTexSubImage2D             ; +		qglTranslated                = 	logTranslated                ; +		qglTranslatef                = 	logTranslatef                ; +		qglVertex2d                  = 	logVertex2d                  ; +		qglVertex2dv                 = 	logVertex2dv                 ; +		qglVertex2f                  = 	logVertex2f                  ; +		qglVertex2fv                 = 	logVertex2fv                 ; +		qglVertex2i                  = 	logVertex2i                  ; +		qglVertex2iv                 = 	logVertex2iv                 ; +		qglVertex2s                  = 	logVertex2s                  ; +		qglVertex2sv                 = 	logVertex2sv                 ; +		qglVertex3d                  = 	logVertex3d                  ; +		qglVertex3dv                 = 	logVertex3dv                 ; +		qglVertex3f                  = 	logVertex3f                  ; +		qglVertex3fv                 = 	logVertex3fv                 ; +		qglVertex3i                  = 	logVertex3i                  ; +		qglVertex3iv                 = 	logVertex3iv                 ; +		qglVertex3s                  = 	logVertex3s                  ; +		qglVertex3sv                 = 	logVertex3sv                 ; +		qglVertex4d                  = 	logVertex4d                  ; +		qglVertex4dv                 = 	logVertex4dv                 ; +		qglVertex4f                  = 	logVertex4f                  ; +		qglVertex4fv                 = 	logVertex4fv                 ; +		qglVertex4i                  = 	logVertex4i                  ; +		qglVertex4iv                 = 	logVertex4iv                 ; +		qglVertex4s                  = 	logVertex4s                  ; +		qglVertex4sv                 = 	logVertex4sv                 ; +		qglVertexPointer             = 	logVertexPointer             ; +		qglViewport                  = 	logViewport                  ; +	} +	else +	{ +		if ( glw_state.log_fp )	{ +			fprintf( glw_state.log_fp, "*** CLOSING LOG ***\n" ); +			fclose( glw_state.log_fp ); +			glw_state.log_fp = NULL; +		} +		qglAccum                     = dllAccum; +		qglAlphaFunc                 = dllAlphaFunc; +		qglAreTexturesResident       = dllAreTexturesResident; +		qglArrayElement              = dllArrayElement; +		qglBegin                     = dllBegin; +		qglBindTexture               = dllBindTexture; +		qglBitmap                    = dllBitmap; +		qglBlendFunc                 = dllBlendFunc; +		qglCallList                  = dllCallList; +		qglCallLists                 = dllCallLists; +		qglClear                     = dllClear; +		qglClearAccum                = dllClearAccum; +		qglClearColor                = dllClearColor; +		qglClearDepth                = dllClearDepth; +		qglClearIndex                = dllClearIndex; +		qglClearStencil              = dllClearStencil; +		qglClipPlane                 = dllClipPlane; +		qglColor3b                   = dllColor3b; +		qglColor3bv                  = dllColor3bv; +		qglColor3d                   = dllColor3d; +		qglColor3dv                  = dllColor3dv; +		qglColor3f                   = dllColor3f; +		qglColor3fv                  = dllColor3fv; +		qglColor3i                   = dllColor3i; +		qglColor3iv                  = dllColor3iv; +		qglColor3s                   = dllColor3s; +		qglColor3sv                  = dllColor3sv; +		qglColor3ub                  = dllColor3ub; +		qglColor3ubv                 = dllColor3ubv; +		qglColor3ui                  = dllColor3ui; +		qglColor3uiv                 = dllColor3uiv; +		qglColor3us                  = dllColor3us; +		qglColor3usv                 = dllColor3usv; +		qglColor4b                   = dllColor4b; +		qglColor4bv                  = dllColor4bv; +		qglColor4d                   = dllColor4d; +		qglColor4dv                  = dllColor4dv; +		qglColor4f                   = dllColor4f; +		qglColor4fv                  = dllColor4fv; +		qglColor4i                   = dllColor4i; +		qglColor4iv                  = dllColor4iv; +		qglColor4s                   = dllColor4s; +		qglColor4sv                  = dllColor4sv; +		qglColor4ub                  = dllColor4ub; +		qglColor4ubv                 = dllColor4ubv; +		qglColor4ui                  = dllColor4ui; +		qglColor4uiv                 = dllColor4uiv; +		qglColor4us                  = dllColor4us; +		qglColor4usv                 = dllColor4usv; +		qglColorMask                 = dllColorMask; +		qglColorMaterial             = dllColorMaterial; +		qglColorPointer              = dllColorPointer; +		qglCopyPixels                = dllCopyPixels; +		qglCopyTexImage1D            = dllCopyTexImage1D; +		qglCopyTexImage2D            = dllCopyTexImage2D; +		qglCopyTexSubImage1D         = dllCopyTexSubImage1D; +		qglCopyTexSubImage2D         = dllCopyTexSubImage2D; +		qglCullFace                  = dllCullFace; +		qglDeleteLists               = dllDeleteLists ; +		qglDeleteTextures            = dllDeleteTextures ; +		qglDepthFunc                 = dllDepthFunc ; +		qglDepthMask                 = dllDepthMask ; +		qglDepthRange                = dllDepthRange ; +		qglDisable                   = dllDisable ; +		qglDisableClientState        = dllDisableClientState ; +		qglDrawArrays                = dllDrawArrays ; +		qglDrawBuffer                = dllDrawBuffer ; +		qglDrawElements              = dllDrawElements ; +		qglDrawPixels                = dllDrawPixels ; +		qglEdgeFlag                  = dllEdgeFlag ; +		qglEdgeFlagPointer           = dllEdgeFlagPointer ; +		qglEdgeFlagv                 = dllEdgeFlagv ; +		qglEnable                    = 	dllEnable                    ; +		qglEnableClientState         = 	dllEnableClientState         ; +		qglEnd                       = 	dllEnd                       ; +		qglEndList                   = 	dllEndList                   ; +		qglEvalCoord1d				 = 	dllEvalCoord1d				 ; +		qglEvalCoord1dv              = 	dllEvalCoord1dv              ; +		qglEvalCoord1f               = 	dllEvalCoord1f               ; +		qglEvalCoord1fv              = 	dllEvalCoord1fv              ; +		qglEvalCoord2d               = 	dllEvalCoord2d               ; +		qglEvalCoord2dv              = 	dllEvalCoord2dv              ; +		qglEvalCoord2f               = 	dllEvalCoord2f               ; +		qglEvalCoord2fv              = 	dllEvalCoord2fv              ; +		qglEvalMesh1                 = 	dllEvalMesh1                 ; +		qglEvalMesh2                 = 	dllEvalMesh2                 ; +		qglEvalPoint1                = 	dllEvalPoint1                ; +		qglEvalPoint2                = 	dllEvalPoint2                ; +		qglFeedbackBuffer            = 	dllFeedbackBuffer            ; +		qglFinish                    = 	dllFinish                    ; +		qglFlush                     = 	dllFlush                     ; +		qglFogf                      = 	dllFogf                      ; +		qglFogfv                     = 	dllFogfv                     ; +		qglFogi                      = 	dllFogi                      ; +		qglFogiv                     = 	dllFogiv                     ; +		qglFrontFace                 = 	dllFrontFace                 ; +		qglFrustum                   = 	dllFrustum                   ; +		qglGenLists                  = 	dllGenLists                  ; +		qglGenTextures               = 	dllGenTextures               ; +		qglGetBooleanv               = 	dllGetBooleanv               ; +		qglGetClipPlane              = 	dllGetClipPlane              ; +		qglGetDoublev                = 	dllGetDoublev                ; +		qglGetError                  = 	dllGetError                  ; +		qglGetFloatv                 = 	dllGetFloatv                 ; +		qglGetIntegerv               = 	dllGetIntegerv               ; +		qglGetLightfv                = 	dllGetLightfv                ; +		qglGetLightiv                = 	dllGetLightiv                ; +		qglGetMapdv                  = 	dllGetMapdv                  ; +		qglGetMapfv                  = 	dllGetMapfv                  ; +		qglGetMapiv                  = 	dllGetMapiv                  ; +		qglGetMaterialfv             = 	dllGetMaterialfv             ; +		qglGetMaterialiv             = 	dllGetMaterialiv             ; +		qglGetPixelMapfv             = 	dllGetPixelMapfv             ; +		qglGetPixelMapuiv            = 	dllGetPixelMapuiv            ; +		qglGetPixelMapusv            = 	dllGetPixelMapusv            ; +		qglGetPointerv               = 	dllGetPointerv               ; +		qglGetPolygonStipple         = 	dllGetPolygonStipple         ; +		qglGetString                 = 	dllGetString                 ; +		qglGetTexEnvfv               = 	dllGetTexEnvfv               ; +		qglGetTexEnviv               = 	dllGetTexEnviv               ; +		qglGetTexGendv               = 	dllGetTexGendv               ; +		qglGetTexGenfv               = 	dllGetTexGenfv               ; +		qglGetTexGeniv               = 	dllGetTexGeniv               ; +		qglGetTexImage               = 	dllGetTexImage               ; +		qglGetTexLevelParameterfv    = 	dllGetTexLevelParameterfv    ; +		qglGetTexLevelParameteriv    = 	dllGetTexLevelParameteriv    ; +		qglGetTexParameterfv         = 	dllGetTexParameterfv         ; +		qglGetTexParameteriv         = 	dllGetTexParameteriv         ; +		qglHint                      = 	dllHint                      ; +		qglIndexMask                 = 	dllIndexMask                 ; +		qglIndexPointer              = 	dllIndexPointer              ; +		qglIndexd                    = 	dllIndexd                    ; +		qglIndexdv                   = 	dllIndexdv                   ; +		qglIndexf                    = 	dllIndexf                    ; +		qglIndexfv                   = 	dllIndexfv                   ; +		qglIndexi                    = 	dllIndexi                    ; +		qglIndexiv                   = 	dllIndexiv                   ; +		qglIndexs                    = 	dllIndexs                    ; +		qglIndexsv                   = 	dllIndexsv                   ; +		qglIndexub                   = 	dllIndexub                   ; +		qglIndexubv                  = 	dllIndexubv                  ; +		qglInitNames                 = 	dllInitNames                 ; +		qglInterleavedArrays         = 	dllInterleavedArrays         ; +		qglIsEnabled                 = 	dllIsEnabled                 ; +		qglIsList                    = 	dllIsList                    ; +		qglIsTexture                 = 	dllIsTexture                 ; +		qglLightModelf               = 	dllLightModelf               ; +		qglLightModelfv              = 	dllLightModelfv              ; +		qglLightModeli               = 	dllLightModeli               ; +		qglLightModeliv              = 	dllLightModeliv              ; +		qglLightf                    = 	dllLightf                    ; +		qglLightfv                   = 	dllLightfv                   ; +		qglLighti                    = 	dllLighti                    ; +		qglLightiv                   = 	dllLightiv                   ; +		qglLineStipple               = 	dllLineStipple               ; +		qglLineWidth                 = 	dllLineWidth                 ; +		qglListBase                  = 	dllListBase                  ; +		qglLoadIdentity              = 	dllLoadIdentity              ; +		qglLoadMatrixd               = 	dllLoadMatrixd               ; +		qglLoadMatrixf               = 	dllLoadMatrixf               ; +		qglLoadName                  = 	dllLoadName                  ; +		qglLogicOp                   = 	dllLogicOp                   ; +		qglMap1d                     = 	dllMap1d                     ; +		qglMap1f                     = 	dllMap1f                     ; +		qglMap2d                     = 	dllMap2d                     ; +		qglMap2f                     = 	dllMap2f                     ; +		qglMapGrid1d                 = 	dllMapGrid1d                 ; +		qglMapGrid1f                 = 	dllMapGrid1f                 ; +		qglMapGrid2d                 = 	dllMapGrid2d                 ; +		qglMapGrid2f                 = 	dllMapGrid2f                 ; +		qglMaterialf                 = 	dllMaterialf                 ; +		qglMaterialfv                = 	dllMaterialfv                ; +		qglMateriali                 = 	dllMateriali                 ; +		qglMaterialiv                = 	dllMaterialiv                ; +		qglMatrixMode                = 	dllMatrixMode                ; +		qglMultMatrixd               = 	dllMultMatrixd               ; +		qglMultMatrixf               = 	dllMultMatrixf               ; +		qglNewList                   = 	dllNewList                   ; +		qglNormal3b                  = 	dllNormal3b                  ; +		qglNormal3bv                 = 	dllNormal3bv                 ; +		qglNormal3d                  = 	dllNormal3d                  ; +		qglNormal3dv                 = 	dllNormal3dv                 ; +		qglNormal3f                  = 	dllNormal3f                  ; +		qglNormal3fv                 = 	dllNormal3fv                 ; +		qglNormal3i                  = 	dllNormal3i                  ; +		qglNormal3iv                 = 	dllNormal3iv                 ; +		qglNormal3s                  = 	dllNormal3s                  ; +		qglNormal3sv                 = 	dllNormal3sv                 ; +		qglNormalPointer             = 	dllNormalPointer             ; +		qglOrtho                     = 	dllOrtho                     ; +		qglPassThrough               = 	dllPassThrough               ; +		qglPixelMapfv                = 	dllPixelMapfv                ; +		qglPixelMapuiv               = 	dllPixelMapuiv               ; +		qglPixelMapusv               = 	dllPixelMapusv               ; +		qglPixelStoref               = 	dllPixelStoref               ; +		qglPixelStorei               = 	dllPixelStorei               ; +		qglPixelTransferf            = 	dllPixelTransferf            ; +		qglPixelTransferi            = 	dllPixelTransferi            ; +		qglPixelZoom                 = 	dllPixelZoom                 ; +		qglPointSize                 = 	dllPointSize                 ; +		qglPolygonMode               = 	dllPolygonMode               ; +		qglPolygonOffset             = 	dllPolygonOffset             ; +		qglPolygonStipple            = 	dllPolygonStipple            ; +		qglPopAttrib                 = 	dllPopAttrib                 ; +		qglPopClientAttrib           = 	dllPopClientAttrib           ; +		qglPopMatrix                 = 	dllPopMatrix                 ; +		qglPopName                   = 	dllPopName                   ; +		qglPrioritizeTextures        = 	dllPrioritizeTextures        ; +		qglPushAttrib                = 	dllPushAttrib                ; +		qglPushClientAttrib          = 	dllPushClientAttrib          ; +		qglPushMatrix                = 	dllPushMatrix                ; +		qglPushName                  = 	dllPushName                  ; +		qglRasterPos2d               = 	dllRasterPos2d               ; +		qglRasterPos2dv              = 	dllRasterPos2dv              ; +		qglRasterPos2f               = 	dllRasterPos2f               ; +		qglRasterPos2fv              = 	dllRasterPos2fv              ; +		qglRasterPos2i               = 	dllRasterPos2i               ; +		qglRasterPos2iv              = 	dllRasterPos2iv              ; +		qglRasterPos2s               = 	dllRasterPos2s               ; +		qglRasterPos2sv              = 	dllRasterPos2sv              ; +		qglRasterPos3d               = 	dllRasterPos3d               ; +		qglRasterPos3dv              = 	dllRasterPos3dv              ; +		qglRasterPos3f               = 	dllRasterPos3f               ; +		qglRasterPos3fv              = 	dllRasterPos3fv              ; +		qglRasterPos3i               = 	dllRasterPos3i               ; +		qglRasterPos3iv              = 	dllRasterPos3iv              ; +		qglRasterPos3s               = 	dllRasterPos3s               ; +		qglRasterPos3sv              = 	dllRasterPos3sv              ; +		qglRasterPos4d               = 	dllRasterPos4d               ; +		qglRasterPos4dv              = 	dllRasterPos4dv              ; +		qglRasterPos4f               = 	dllRasterPos4f               ; +		qglRasterPos4fv              = 	dllRasterPos4fv              ; +		qglRasterPos4i               = 	dllRasterPos4i               ; +		qglRasterPos4iv              = 	dllRasterPos4iv              ; +		qglRasterPos4s               = 	dllRasterPos4s               ; +		qglRasterPos4sv              = 	dllRasterPos4sv              ; +		qglReadBuffer                = 	dllReadBuffer                ; +		qglReadPixels                = 	dllReadPixels                ; +		qglRectd                     = 	dllRectd                     ; +		qglRectdv                    = 	dllRectdv                    ; +		qglRectf                     = 	dllRectf                     ; +		qglRectfv                    = 	dllRectfv                    ; +		qglRecti                     = 	dllRecti                     ; +		qglRectiv                    = 	dllRectiv                    ; +		qglRects                     = 	dllRects                     ; +		qglRectsv                    = 	dllRectsv                    ; +		qglRenderMode                = 	dllRenderMode                ; +		qglRotated                   = 	dllRotated                   ; +		qglRotatef                   = 	dllRotatef                   ; +		qglScaled                    = 	dllScaled                    ; +		qglScalef                    = 	dllScalef                    ; +		qglScissor                   = 	dllScissor                   ; +		qglSelectBuffer              = 	dllSelectBuffer              ; +		qglShadeModel                = 	dllShadeModel                ; +		qglStencilFunc               = 	dllStencilFunc               ; +		qglStencilMask               = 	dllStencilMask               ; +		qglStencilOp                 = 	dllStencilOp                 ; +		qglTexCoord1d                = 	dllTexCoord1d                ; +		qglTexCoord1dv               = 	dllTexCoord1dv               ; +		qglTexCoord1f                = 	dllTexCoord1f                ; +		qglTexCoord1fv               = 	dllTexCoord1fv               ; +		qglTexCoord1i                = 	dllTexCoord1i                ; +		qglTexCoord1iv               = 	dllTexCoord1iv               ; +		qglTexCoord1s                = 	dllTexCoord1s                ; +		qglTexCoord1sv               = 	dllTexCoord1sv               ; +		qglTexCoord2d                = 	dllTexCoord2d                ; +		qglTexCoord2dv               = 	dllTexCoord2dv               ; +		qglTexCoord2f                = 	dllTexCoord2f                ; +		qglTexCoord2fv               = 	dllTexCoord2fv               ; +		qglTexCoord2i                = 	dllTexCoord2i                ; +		qglTexCoord2iv               = 	dllTexCoord2iv               ; +		qglTexCoord2s                = 	dllTexCoord2s                ; +		qglTexCoord2sv               = 	dllTexCoord2sv               ; +		qglTexCoord3d                = 	dllTexCoord3d                ; +		qglTexCoord3dv               = 	dllTexCoord3dv               ; +		qglTexCoord3f                = 	dllTexCoord3f                ; +		qglTexCoord3fv               = 	dllTexCoord3fv               ; +		qglTexCoord3i                = 	dllTexCoord3i                ; +		qglTexCoord3iv               = 	dllTexCoord3iv               ; +		qglTexCoord3s                = 	dllTexCoord3s                ; +		qglTexCoord3sv               = 	dllTexCoord3sv               ; +		qglTexCoord4d                = 	dllTexCoord4d                ; +		qglTexCoord4dv               = 	dllTexCoord4dv               ; +		qglTexCoord4f                = 	dllTexCoord4f                ; +		qglTexCoord4fv               = 	dllTexCoord4fv               ; +		qglTexCoord4i                = 	dllTexCoord4i                ; +		qglTexCoord4iv               = 	dllTexCoord4iv               ; +		qglTexCoord4s                = 	dllTexCoord4s                ; +		qglTexCoord4sv               = 	dllTexCoord4sv               ; +		qglTexCoordPointer           = 	dllTexCoordPointer           ; +		qglTexEnvf                   = 	dllTexEnvf                   ; +		qglTexEnvfv                  = 	dllTexEnvfv                  ; +		qglTexEnvi                   = 	dllTexEnvi                   ; +		qglTexEnviv                  = 	dllTexEnviv                  ; +		qglTexGend                   = 	dllTexGend                   ; +		qglTexGendv                  = 	dllTexGendv                  ; +		qglTexGenf                   = 	dllTexGenf                   ; +		qglTexGenfv                  = 	dllTexGenfv                  ; +		qglTexGeni                   = 	dllTexGeni                   ; +		qglTexGeniv                  = 	dllTexGeniv                  ; +		qglTexImage1D                = 	dllTexImage1D                ; +		qglTexImage2D                = 	dllTexImage2D                ; +		qglTexParameterf             = 	dllTexParameterf             ; +		qglTexParameterfv            = 	dllTexParameterfv            ; +		qglTexParameteri             = 	dllTexParameteri             ; +		qglTexParameteriv            = 	dllTexParameteriv            ; +		qglTexSubImage1D             = 	dllTexSubImage1D             ; +		qglTexSubImage2D             = 	dllTexSubImage2D             ; +		qglTranslated                = 	dllTranslated                ; +		qglTranslatef                = 	dllTranslatef                ; +		qglVertex2d                  = 	dllVertex2d                  ; +		qglVertex2dv                 = 	dllVertex2dv                 ; +		qglVertex2f                  = 	dllVertex2f                  ; +		qglVertex2fv                 = 	dllVertex2fv                 ; +		qglVertex2i                  = 	dllVertex2i                  ; +		qglVertex2iv                 = 	dllVertex2iv                 ; +		qglVertex2s                  = 	dllVertex2s                  ; +		qglVertex2sv                 = 	dllVertex2sv                 ; +		qglVertex3d                  = 	dllVertex3d                  ; +		qglVertex3dv                 = 	dllVertex3dv                 ; +		qglVertex3f                  = 	dllVertex3f                  ; +		qglVertex3fv                 = 	dllVertex3fv                 ; +		qglVertex3i                  = 	dllVertex3i                  ; +		qglVertex3iv                 = 	dllVertex3iv                 ; +		qglVertex3s                  = 	dllVertex3s                  ; +		qglVertex3sv                 = 	dllVertex3sv                 ; +		qglVertex4d                  = 	dllVertex4d                  ; +		qglVertex4dv                 = 	dllVertex4dv                 ; +		qglVertex4f                  = 	dllVertex4f                  ; +		qglVertex4fv                 = 	dllVertex4fv                 ; +		qglVertex4i                  = 	dllVertex4i                  ; +		qglVertex4iv                 = 	dllVertex4iv                 ; +		qglVertex4s                  = 	dllVertex4s                  ; +		qglVertex4sv                 = 	dllVertex4sv                 ; +		qglVertexPointer             = 	dllVertexPointer             ; +		qglViewport                  = 	dllViewport                  ; +	} +} + +#ifdef _MSC_VER +#pragma warning (default : 4113 4133 4047 ) +#endif + + + diff --git a/src/win32/win_resource.rc b/src/win32/win_resource.rc new file mode 100644 index 0000000..2782b32 --- /dev/null +++ b/src/win32/win_resource.rc @@ -0,0 +1,71 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include <winresrc.h> + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE  +BEGIN +    "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE  +BEGIN +    "#include ""winres.h""\r\n" +    "\0" +END + +3 TEXTINCLUDE DISCARDABLE  +BEGIN +    "\0" +END + +#endif    // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1               ICON    DISCARDABLE     "misc/tremulous.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE  +BEGIN +    IDS_STRING1             "Tremulous" +END + +#endif    // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + diff --git a/src/win32/win_shared.c b/src/win32/win_shared.c new file mode 100644 index 0000000..457a8d5 --- /dev/null +++ b/src/win32/win_shared.c @@ -0,0 +1,351 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2006 Tim Angus + +This file is part of Tremulous. + +Tremulous 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. + +Tremulous is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Tremulous; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA +=========================================================================== +*/ + +#include "../qcommon/q_shared.h" +#include "../qcommon/qcommon.h" +#include "win_local.h" +#include <lmerr.h> +#include <lmcons.h> +#include <lmwksta.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <direct.h> +#include <io.h> +#include <conio.h> +#include <wincrypt.h> + +/* +================ +Sys_Milliseconds +================ +*/ +int			sys_timeBase; +int Sys_Milliseconds (void) +{ +	int			sys_curtime; +	static qboolean	initialized = qfalse; + +	if (!initialized) { +		sys_timeBase = timeGetTime(); +		initialized = qtrue; +	} +	sys_curtime = timeGetTime() - sys_timeBase; + +	return sys_curtime; +} + +#ifndef __GNUC__ //see snapvectora.s +/* +================ +Sys_SnapVector +================ +*/ +void Sys_SnapVector( float *v ) +{ +	int i; +	float f; + +	f = *v; +	__asm	fld		f; +	__asm	fistp	i; +	*v = i; +	v++; +	f = *v; +	__asm	fld		f; +	__asm	fistp	i; +	*v = i; +	v++; +	f = *v; +	__asm	fld		f; +	__asm	fistp	i; +	*v = i; +} +#endif + +qboolean Sys_RandomBytes( byte *string, int len ) +{ +	HCRYPTPROV  prov; + +	if( !CryptAcquireContext( &prov, NULL, NULL, +		PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) )  { + +		return qfalse; +	} + +	if( !CryptGenRandom( prov, len, (BYTE *)string ) )  { +		CryptReleaseContext( prov, 0 ); +		return qfalse; +	} +	CryptReleaseContext( prov, 0 ); +	return qtrue; +} + + +/* +** +** Disable all optimizations temporarily so this code works correctly! +** +*/ +#ifdef _MSC_VER +#pragma optimize( "", off ) +#endif + +// If you fancy porting this stuff to AT&T then feel free... :) +// It's not actually used functionally though, so it may be a waste of effort +#ifndef __MINGW32__ +/* +** -------------------------------------------------------------------------------- +** +** PROCESSOR STUFF +** +** -------------------------------------------------------------------------------- +*/ +static void CPUID( int func, unsigned regs[4] ) +{ +	unsigned regEAX, regEBX, regECX, regEDX; + +	__asm mov eax, func +	__asm __emit 00fh +	__asm __emit 0a2h +	__asm mov regEAX, eax +	__asm mov regEBX, ebx +	__asm mov regECX, ecx +	__asm mov regEDX, edx + +	regs[0] = regEAX; +	regs[1] = regEBX; +	regs[2] = regECX; +	regs[3] = regEDX; +} + +static int IsPentium( void ) +{ +	__asm  +	{ +		pushfd						// save eflags +		pop		eax +		test	eax, 0x00200000		// check ID bit +		jz		set21				// bit 21 is not set, so jump to set_21 +		and		eax, 0xffdfffff		// clear bit 21 +		push	eax					// save new value in register +		popfd						// store new value in flags +		pushfd +		pop		eax +		test	eax, 0x00200000		// check ID bit +		jz		good +		jmp		err					// cpuid not supported +set21: +		or		eax, 0x00200000		// set ID bit +		push	eax					// store new value +		popfd						// store new value in EFLAGS +		pushfd +		pop		eax +		test	eax, 0x00200000		// if bit 21 is on +		jnz		good +		jmp		err +	} + +err: +	return qfalse; +good: +	return qtrue; +} + +static int Is3DNOW( void ) +{ +	unsigned regs[4]; +	char pstring[16]; +	char processorString[13]; + +	// get name of processor +	CPUID( 0, ( unsigned int * ) pstring ); +	processorString[0] = pstring[4]; +	processorString[1] = pstring[5]; +	processorString[2] = pstring[6]; +	processorString[3] = pstring[7]; +	processorString[4] = pstring[12]; +	processorString[5] = pstring[13]; +	processorString[6] = pstring[14]; +	processorString[7] = pstring[15]; +	processorString[8] = pstring[8]; +	processorString[9] = pstring[9]; +	processorString[10] = pstring[10]; +	processorString[11] = pstring[11]; +	processorString[12] = 0; + +//  REMOVED because you can have 3DNow! on non-AMD systems +//	if ( strcmp( processorString, "AuthenticAMD" ) ) +//		return qfalse; + +	// check AMD-specific functions +	CPUID( 0x80000000, regs ); +	if ( regs[0] < 0x80000000 ) +		return qfalse; + +	// bit 31 of EDX denotes 3DNOW! support +	CPUID( 0x80000001, regs ); +	if ( regs[3] & ( 1 << 31 ) ) +		return qtrue; + +	return qfalse; +} + +static int IsKNI( void ) +{ +	unsigned regs[4]; + +	// get CPU feature bits +	CPUID( 1, regs ); + +	// bit 25 of EDX denotes KNI existence +	if ( regs[3] & ( 1 << 25 ) ) +		return qtrue; + +	return qfalse; +} + +static int IsMMX( void ) +{ +	unsigned regs[4]; + +	// get CPU feature bits +	CPUID( 1, regs ); + +	// bit 23 of EDX denotes MMX existence +	if ( regs[3] & ( 1 << 23 ) ) +		return qtrue; +	return qfalse; +} + +int Sys_GetProcessorId( void ) +{ +#if defined _M_ALPHA +	return CPUID_AXP; +#elif !defined _M_IX86 +	return CPUID_GENERIC; +#else + +	// verify we're at least a Pentium or 486 w/ CPUID support +	if ( !IsPentium() ) +		return CPUID_INTEL_UNSUPPORTED; + +	// check for MMX +	if ( !IsMMX() ) +	{ +		// Pentium or PPro +		return CPUID_INTEL_PENTIUM; +	} + +	// see if we're an AMD 3DNOW! processor +	if ( Is3DNOW() ) +	{ +		return CPUID_AMD_3DNOW; +	} + +	// see if we're an Intel Katmai +	if ( IsKNI() ) +	{ +		return CPUID_INTEL_KATMAI; +	} + +	// by default we're functionally a vanilla Pentium/MMX or P2/MMX +	return CPUID_INTEL_MMX; + +#endif +} +#endif + +/* +** +** Re-enable optimizations back to what they were +** +*/ +#ifdef _MSC_VER +#pragma optimize( "", on ) +#endif + +//============================================ + +char *Sys_GetCurrentUser( void ) +{ +	static char s_userName[1024]; +	unsigned long size = sizeof( s_userName ); + + +	if ( !GetUserName( s_userName, &size ) ) +		strcpy( s_userName, "player" ); + +	if ( !s_userName[0] ) +	{ +		strcpy( s_userName, "player" ); +	} + +	return s_userName; +} + +char	*Sys_DefaultHomePath(void) { +	TCHAR szPath[MAX_PATH]; +	static char path[MAX_OSPATH]; +	FARPROC qSHGetFolderPath; +	HMODULE shfolder = LoadLibrary("shfolder.dll"); +	 +	if(shfolder == NULL) { +		Com_Printf("Unable to load SHFolder.dll\n"); +		return NULL; +	} + +	qSHGetFolderPath = GetProcAddress(shfolder, "SHGetFolderPathA"); +	if(qSHGetFolderPath == NULL) +	{ +		Com_Printf("Unable to find SHGetFolderPath in SHFolder.dll\n"); +		FreeLibrary(shfolder); +		return NULL; +	} + +	if( !SUCCEEDED( qSHGetFolderPath( NULL, CSIDL_APPDATA, +		NULL, 0, szPath ) ) ) +	{ +		Com_Printf("Unable to detect CSIDL_APPDATA\n"); +		FreeLibrary(shfolder); +		return NULL; +	} +	Q_strncpyz( path, szPath, sizeof(path) ); +	Q_strcat( path, sizeof(path), "\\Tremulous" ); +	FreeLibrary(shfolder); +	if( !CreateDirectory( path, NULL ) ) +	{ +		if( GetLastError() != ERROR_ALREADY_EXISTS ) +		{ +			Com_Printf("Unable to create directory \"%s\"\n", path); +			return NULL; +		} +	} +	return path; +} + +char *Sys_DefaultInstallPath(void) +{ +	return Sys_Cwd(); +} + diff --git a/src/win32/win_snd.c b/src/win32/win_snd.c new file mode 100644 index 0000000..184c032 --- /dev/null +++ b/src/win32/win_snd.c @@ -0,0 +1,389 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2006 Tim Angus + +This file is part of Tremulous. + +Tremulous 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. + +Tremulous is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Tremulous; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA +=========================================================================== +*/ +#include <float.h> + +#include "../client/snd_local.h" +#include "win_local.h" + +HRESULT (WINAPI *pDirectSoundCreate)(GUID FAR *lpGUID, LPDIRECTSOUND FAR *lplpDS, IUnknown FAR *pUnkOuter); +#define iDirectSoundCreate(a,b,c)	pDirectSoundCreate(a,b,c) + +#define SECONDARY_BUFFER_SIZE	0x10000 + + +static qboolean	dsound_init; +static int		sample16; +static DWORD	gSndBufSize; +static DWORD	locksize; +static LPDIRECTSOUND pDS; +static LPDIRECTSOUNDBUFFER pDSBuf, pDSPBuf; +static HINSTANCE hInstDS; + + +static const char *DSoundError( int error ) { +	switch ( error ) { +	case DSERR_BUFFERLOST: +		return "DSERR_BUFFERLOST"; +	case DSERR_INVALIDCALL: +		return "DSERR_INVALIDCALLS"; +	case DSERR_INVALIDPARAM: +		return "DSERR_INVALIDPARAM"; +	case DSERR_PRIOLEVELNEEDED: +		return "DSERR_PRIOLEVELNEEDED"; +	} + +	return "unknown"; +} + +/* +================== +SNDDMA_Shutdown +================== +*/ +void SNDDMA_Shutdown( void ) { +	Com_DPrintf( "Shutting down sound system\n" ); + +	if ( pDS ) { +		Com_DPrintf( "Destroying DS buffers\n" ); +		if ( pDS ) +		{ +			Com_DPrintf( "...setting NORMAL coop level\n" ); +			pDS->lpVtbl->SetCooperativeLevel( pDS, g_wv.hWnd, DSSCL_PRIORITY ); +		} + +		if ( pDSBuf ) +		{ +			Com_DPrintf( "...stopping and releasing sound buffer\n" ); +			pDSBuf->lpVtbl->Stop( pDSBuf ); +			pDSBuf->lpVtbl->Release( pDSBuf ); +		} + +		// only release primary buffer if it's not also the mixing buffer we just released +		if ( pDSPBuf && ( pDSBuf != pDSPBuf ) ) +		{ +			Com_DPrintf( "...releasing primary buffer\n" ); +			pDSPBuf->lpVtbl->Release( pDSPBuf ); +		} +		pDSBuf = NULL; +		pDSPBuf = NULL; + +		dma.buffer = NULL; + +		Com_DPrintf( "...releasing DS object\n" ); +		pDS->lpVtbl->Release( pDS ); +	} + +	if ( hInstDS ) { +		Com_DPrintf( "...freeing DSOUND.DLL\n" ); +		FreeLibrary( hInstDS ); +		hInstDS = NULL; +	} + +	pDS = NULL; +	pDSBuf = NULL; +	pDSPBuf = NULL; +	dsound_init = qfalse; +	memset ((void *)&dma, 0, sizeof (dma)); +	CoUninitialize( ); +} + +/* +================== +SNDDMA_Init + +Initialize direct sound +Returns false if failed +================== +*/ +qboolean SNDDMA_Init(void) { + +	memset ((void *)&dma, 0, sizeof (dma)); +	dsound_init = 0; + +	CoInitialize(NULL); + +	if ( !SNDDMA_InitDS () ) { +		return qfalse; +	} + +	dsound_init = qtrue; + +	Com_DPrintf("Completed successfully\n" ); + +    return qtrue; +} + +#undef DEFINE_GUID + +#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ +        const GUID name \ +                = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } } + +// DirectSound Component GUID {47D4D946-62E8-11CF-93BC-444553540000} +DEFINE_GUID(CLSID_DirectSound, 0x47d4d946, 0x62e8, 0x11cf, 0x93, 0xbc, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0); + +// DirectSound 8.0 Component GUID {3901CC3F-84B5-4FA4-BA35-AA8172B8A09B} +DEFINE_GUID(CLSID_DirectSound8, 0x3901cc3f, 0x84b5, 0x4fa4, 0xba, 0x35, 0xaa, 0x81, 0x72, 0xb8, 0xa0, 0x9b); + +DEFINE_GUID(IID_IDirectSound8, 0xC50A7E93, 0xF395, 0x4834, 0x9E, 0xF6, 0x7F, 0xA9, 0x9D, 0xE5, 0x09, 0x66); +DEFINE_GUID(IID_IDirectSound, 0x279AFA83, 0x4981, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60); + + +int SNDDMA_InitDS () +{ +	HRESULT			hresult; +	DSBUFFERDESC	dsbuf; +	DSBCAPS			dsbcaps; +	WAVEFORMATEX	format; +	int				use8; + +	Com_Printf( "Initializing DirectSound\n"); + +	use8 = 1; +    // Create IDirectSound using the primary sound device +    if( FAILED( hresult = CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound8, (void **)&pDS))) { +		use8 = 0; +	    if( FAILED( hresult = CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void **)&pDS))) { +			Com_Printf ("failed\n"); +			SNDDMA_Shutdown (); +			return qfalse; +		} +	} + +	hresult = pDS->lpVtbl->Initialize( pDS, NULL); + +	Com_DPrintf( "ok\n" ); + +	Com_DPrintf("...setting DSSCL_PRIORITY coop level: " ); + +	if ( DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, g_wv.hWnd, DSSCL_PRIORITY ) )	{ +		Com_Printf ("failed\n"); +		SNDDMA_Shutdown (); +		return qfalse; +	} +	Com_DPrintf("ok\n" ); + + +	// create the secondary buffer we'll actually work with +	dma.channels = 2; +	dma.samplebits = 16; + +//	if (s_khz->integer == 44) +//		dma.speed = 44100; +//	else if (s_khz->integer == 22) +//		dma.speed = 22050; +//	else +//		dma.speed = 11025; + +	dma.speed = 22050; +	memset (&format, 0, sizeof(format)); +	format.wFormatTag = WAVE_FORMAT_PCM; +    format.nChannels = dma.channels; +    format.wBitsPerSample = dma.samplebits; +    format.nSamplesPerSec = dma.speed; +    format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8; +    format.cbSize = 0; +    format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign;  + +	memset (&dsbuf, 0, sizeof(dsbuf)); +	dsbuf.dwSize = sizeof(DSBUFFERDESC); + +	// Micah: take advantage of 2D hardware.if available. +	dsbuf.dwFlags = DSBCAPS_LOCHARDWARE; +	if (use8) { +		dsbuf.dwFlags |= DSBCAPS_GETCURRENTPOSITION2; +	} +	dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE; +	dsbuf.lpwfxFormat = &format; +	 +	memset(&dsbcaps, 0, sizeof(dsbcaps)); +	dsbcaps.dwSize = sizeof(dsbcaps); +	 +	Com_DPrintf( "...creating secondary buffer: " ); +	if (DS_OK == pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL)) { +		Com_Printf( "locked hardware.  ok\n" ); +	} +	else { +		// Couldn't get hardware, fallback to software. +		dsbuf.dwFlags = DSBCAPS_LOCSOFTWARE; +		if (use8) { +			dsbuf.dwFlags |= DSBCAPS_GETCURRENTPOSITION2; +		} +		if (DS_OK != pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL)) { +			Com_Printf( "failed\n" ); +			SNDDMA_Shutdown (); +			return qfalse; +		} +		Com_DPrintf( "forced to software.  ok\n" ); +	} +		 +	// Make sure mixer is active +	if ( DS_OK != pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING) ) { +		Com_Printf ("*** Looped sound play failed ***\n"); +		SNDDMA_Shutdown (); +		return qfalse; +	} + +	// get the returned buffer size +	if ( DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps) ) { +		Com_Printf ("*** GetCaps failed ***\n"); +		SNDDMA_Shutdown (); +		return qfalse; +	} +	 +	gSndBufSize = dsbcaps.dwBufferBytes; + +	dma.channels = format.nChannels; +	dma.samplebits = format.wBitsPerSample; +	dma.speed = format.nSamplesPerSec; +	dma.samples = gSndBufSize/(dma.samplebits/8); +	dma.submission_chunk = 1; +	dma.buffer = NULL;			// must be locked first + +	sample16 = (dma.samplebits/8) - 1; + +	SNDDMA_BeginPainting (); +	if (dma.buffer) +		memset(dma.buffer, 0, dma.samples * dma.samplebits/8); +	SNDDMA_Submit (); +	return 1; +} +/* +============== +SNDDMA_GetDMAPos + +return the current sample position (in mono samples read) +inside the recirculating dma buffer, so the mixing code will know +how many sample are required to fill it up. +=============== +*/ +int SNDDMA_GetDMAPos( void ) { +	MMTIME	mmtime; +	int		s; +	DWORD	dwWrite; + +	if ( !dsound_init ) { +		return 0; +	} + +	mmtime.wType = TIME_SAMPLES; +	pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &mmtime.u.sample, &dwWrite); + +	s = mmtime.u.sample; + +	s >>= sample16; + +	s &= (dma.samples-1); + +	return s; +} + +/* +============== +SNDDMA_BeginPainting + +Makes sure dma.buffer is valid +=============== +*/ +void SNDDMA_BeginPainting( void ) { +	int		reps; +	DWORD	dwSize2; +	DWORD	*pbuf, *pbuf2; +	HRESULT	hresult; +	DWORD	dwStatus; + +	if ( !pDSBuf ) { +		return; +	} + +	// if the buffer was lost or stopped, restore it and/or restart it +	if ( pDSBuf->lpVtbl->GetStatus (pDSBuf, &dwStatus) != DS_OK ) { +		Com_Printf ("Couldn't get sound buffer status\n"); +	} +	 +	if (dwStatus & DSBSTATUS_BUFFERLOST) +		pDSBuf->lpVtbl->Restore (pDSBuf); +	 +	if (!(dwStatus & DSBSTATUS_PLAYING)) +		pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); + +	// lock the dsound buffer + +	reps = 0; +	dma.buffer = NULL; + +	while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, (LPVOID)&pbuf, &locksize,  +								   (LPVOID)&pbuf2, &dwSize2, 0)) != DS_OK) +	{ +		if (hresult != DSERR_BUFFERLOST) +		{ +			Com_Printf( "SNDDMA_BeginPainting: Lock failed with error '%s'\n", DSoundError( hresult ) ); +			S_Shutdown (); +			return; +		} +		else +		{ +			pDSBuf->lpVtbl->Restore( pDSBuf ); +		} + +		if (++reps > 2) +			return; +	} +	dma.buffer = (unsigned char *)pbuf; +} + +/* +============== +SNDDMA_Submit + +Send sound to device if buffer isn't really the dma buffer +Also unlocks the dsound buffer +=============== +*/ +void SNDDMA_Submit( void ) { +    // unlock the dsound buffer +	if ( pDSBuf ) { +		pDSBuf->lpVtbl->Unlock(pDSBuf, dma.buffer, locksize, NULL, 0); +	} +} + + +/* +================= +SNDDMA_Activate + +When we change windows we need to do this +================= +*/ +void SNDDMA_Activate( void ) { +	if ( !pDS ) { +		return; +	} + +	if ( DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, g_wv.hWnd, DSSCL_PRIORITY ) )	{ +		Com_Printf ("sound SetCooperativeLevel failed\n"); +		SNDDMA_Shutdown (); +	} +} + + diff --git a/src/win32/win_syscon.c b/src/win32/win_syscon.c new file mode 100644 index 0000000..7fa21a4 --- /dev/null +++ b/src/win32/win_syscon.c @@ -0,0 +1,597 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2006 Tim Angus + +This file is part of Tremulous. + +Tremulous 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. + +Tremulous is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Tremulous; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA +=========================================================================== +*/ +// win_syscon.h +#include "../client/client.h" +#include "win_local.h" +#include "resource.h" +#include <errno.h> +#include <float.h> +#include <fcntl.h> +#include <stdio.h> +#include <direct.h> +#include <io.h> +#include <conio.h> + +#define COPY_ID			1 +#define QUIT_ID			2 +#define CLEAR_ID		3 + +#define ERRORBOX_ID		10 +#define ERRORTEXT_ID	11 + +#define EDIT_ID			100 +#define INPUT_ID		101 + +typedef struct +{ +	HWND		hWnd; +	HWND		hwndBuffer; + +	HWND		hwndButtonClear; +	HWND		hwndButtonCopy; +	HWND		hwndButtonQuit; + +	HWND		hwndErrorBox; +	HWND		hwndErrorText; + +	HBITMAP		hbmLogo; +	HBITMAP		hbmClearBitmap; + +	HBRUSH		hbrEditBackground; +	HBRUSH		hbrErrorBackground; + +	HFONT		hfBufferFont; +	HFONT		hfButtonFont; + +	HWND		hwndInputLine; + +	char		errorString[80]; + +	char		consoleText[512], returnedText[512]; +	int			visLevel; +	qboolean	quitOnClose; +	int			windowWidth, windowHeight; +	 +	WNDPROC		SysInputLineWndProc; + +} WinConData; + +static WinConData s_wcd; + +static LONG WINAPI ConWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ +	char *cmdString; +	static qboolean s_timePolarity; + +	switch (uMsg) +	{ +	case WM_ACTIVATE: +		if ( LOWORD( wParam ) != WA_INACTIVE ) +		{ +			SetFocus( s_wcd.hwndInputLine ); +		} + +		if ( com_viewlog && ( com_dedicated && !com_dedicated->integer ) ) +		{ +			// if the viewlog is open, check to see if it's being minimized +			if ( com_viewlog->integer == 1 ) +			{ +				if ( HIWORD( wParam ) )		// minimized flag +				{ +					Cvar_Set( "viewlog", "2" ); +				} +			} +			else if ( com_viewlog->integer == 2 ) +			{ +				if ( !HIWORD( wParam ) )		// minimized flag +				{ +					Cvar_Set( "viewlog", "1" ); +				} +			} +		} +		break; + +	case WM_CLOSE: +		if ( ( com_dedicated && com_dedicated->integer ) ) +		{ +			cmdString = CopyString( "quit" ); +			Sys_QueEvent( 0, SE_CONSOLE, 0, 0, strlen( cmdString ) + 1, cmdString ); +		} +		else if ( s_wcd.quitOnClose ) +		{ +			PostQuitMessage( 0 ); +		} +		else +		{ +			Sys_ShowConsole( 0, qfalse ); +			Cvar_Set( "viewlog", "0" ); +		} +		return 0; +	case WM_CTLCOLORSTATIC: +		if ( ( HWND ) lParam == s_wcd.hwndBuffer ) +		{ +			SetBkColor( ( HDC ) wParam, RGB( 0x00, 0x00, 0xB0 ) ); +			SetTextColor( ( HDC ) wParam, RGB( 0xff, 0xff, 0x00 ) ); + +#if 0	// this draws a background in the edit box, but there are issues with this +			if ( ( hdcScaled = CreateCompatibleDC( ( HDC ) wParam ) ) != 0 ) +			{ +				if ( SelectObject( ( HDC ) hdcScaled, s_wcd.hbmLogo ) ) +				{ +					StretchBlt( ( HDC ) wParam, 0, 0, 512, 384,  +							hdcScaled, 0, 0, 512, 384, +							SRCCOPY ); +				} +				DeleteDC( hdcScaled ); +			} +#endif +			return ( long ) s_wcd.hbrEditBackground; +		} +		else if ( ( HWND ) lParam == s_wcd.hwndErrorBox ) +		{ +			if ( s_timePolarity & 1 ) +			{ +				SetBkColor( ( HDC ) wParam, RGB( 0x80, 0x80, 0x80 ) ); +				SetTextColor( ( HDC ) wParam, RGB( 0xff, 0x0, 0x00 ) ); +			} +			else +			{ +				SetBkColor( ( HDC ) wParam, RGB( 0x80, 0x80, 0x80 ) ); +				SetTextColor( ( HDC ) wParam, RGB( 0x00, 0x0, 0x00 ) ); +			} +			return ( long ) s_wcd.hbrErrorBackground; +		} +		break; + +	case WM_COMMAND: +		if ( wParam == COPY_ID ) +		{ +			SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 ); +			SendMessage( s_wcd.hwndBuffer, WM_COPY, 0, 0 ); +		} +		else if ( wParam == QUIT_ID ) +		{ +			if ( s_wcd.quitOnClose ) +			{ +				PostQuitMessage( 0 ); +			} +			else +			{ +				cmdString = CopyString( "quit" ); +				Sys_QueEvent( 0, SE_CONSOLE, 0, 0, strlen( cmdString ) + 1, cmdString ); +			} +		} +		else if ( wParam == CLEAR_ID ) +		{ +			SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 ); +			SendMessage( s_wcd.hwndBuffer, EM_REPLACESEL, FALSE, ( LPARAM ) "" ); +			UpdateWindow( s_wcd.hwndBuffer ); +		} +		break; +	case WM_CREATE: +//		s_wcd.hbmLogo = LoadBitmap( g_wv.hInstance, MAKEINTRESOURCE( IDB_BITMAP1 ) ); +//		s_wcd.hbmClearBitmap = LoadBitmap( g_wv.hInstance, MAKEINTRESOURCE( IDB_BITMAP2 ) ); +		s_wcd.hbrEditBackground = CreateSolidBrush( RGB( 0x00, 0x00, 0xB0 ) ); +		s_wcd.hbrErrorBackground = CreateSolidBrush( RGB( 0x80, 0x80, 0x80 ) ); +		SetTimer( hWnd, 1, 1000, NULL ); +		break; +	case WM_ERASEBKGND: +#if 0 +	HDC hdcScaled; +	HGDIOBJ oldObject; + +#if 1	// a single, large image +		hdcScaled = CreateCompatibleDC( ( HDC ) wParam ); +		assert( hdcScaled != 0 ); + +		if ( hdcScaled ) +		{ +			oldObject = SelectObject( ( HDC ) hdcScaled, s_wcd.hbmLogo ); +			assert( oldObject != 0 ); +			if ( oldObject ) +			{ +				StretchBlt( ( HDC ) wParam, 0, 0, s_wcd.windowWidth, s_wcd.windowHeight,  +						hdcScaled, 0, 0, 512, 384, +						SRCCOPY ); +			} +			DeleteDC( hdcScaled ); +			hdcScaled = 0; +		} +#else	// a repeating brush +		{ +			HBRUSH hbrClearBrush; +			RECT r; + +			GetWindowRect( hWnd, &r ); + +			r.bottom = r.bottom - r.top + 1; +			r.right = r.right - r.left + 1; +			r.top = 0; +			r.left = 0; + +			hbrClearBrush = CreatePatternBrush( s_wcd.hbmClearBitmap ); + +			assert( hbrClearBrush != 0 ); + +			if ( hbrClearBrush ) +			{ +				FillRect( ( HDC ) wParam, &r, hbrClearBrush ); +				DeleteObject( hbrClearBrush ); +			} +		} +#endif +		return 1; +#endif +	    return DefWindowProc( hWnd, uMsg, wParam, lParam ); +	case WM_TIMER: +		if ( wParam == 1 ) +		{ +			s_timePolarity = !s_timePolarity; +			if ( s_wcd.hwndErrorBox ) +			{ +				InvalidateRect( s_wcd.hwndErrorBox, NULL, FALSE ); +			} +		} +		break; +    } + +    return DefWindowProc( hWnd, uMsg, wParam, lParam ); +} + +LONG WINAPI InputLineWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ +	char inputBuffer[1024]; + +	switch ( uMsg ) +	{ +	case WM_KILLFOCUS: +		if ( ( HWND ) wParam == s_wcd.hWnd || +			 ( HWND ) wParam == s_wcd.hwndErrorBox ) +		{ +			SetFocus( hWnd ); +			return 0; +		} +		break; + +	case WM_CHAR: +		if ( wParam == 13 ) +		{ +			GetWindowText( s_wcd.hwndInputLine, inputBuffer, sizeof( inputBuffer ) ); +			strncat( s_wcd.consoleText, inputBuffer, sizeof( s_wcd.consoleText ) - strlen( s_wcd.consoleText ) - 5 ); +			strcat( s_wcd.consoleText, "\n" ); +			SetWindowText( s_wcd.hwndInputLine, "" ); + +			Sys_Print( va( "]%s\n", inputBuffer ) ); + +			return 0; +		} +	} + +	return CallWindowProc( s_wcd.SysInputLineWndProc, hWnd, uMsg, wParam, lParam ); +} + +/* +** Sys_CreateConsole +*/ +void Sys_CreateConsole( void ) +{ +	HDC hDC; +	WNDCLASS wc; +	RECT rect; +	const char *DEDCLASS = "Tremulous WinConsole"; +	int nHeight; +	int swidth, sheight; +	int DEDSTYLE = WS_POPUPWINDOW | WS_CAPTION | WS_MINIMIZEBOX; + +	memset( &wc, 0, sizeof( wc ) ); + +	wc.style         = 0; +	wc.lpfnWndProc   = (WNDPROC) ConWndProc; +	wc.cbClsExtra    = 0; +	wc.cbWndExtra    = 0; +	wc.hInstance     = g_wv.hInstance; +	wc.hIcon         = LoadIcon( g_wv.hInstance, MAKEINTRESOURCE(IDI_ICON1)); +	wc.hCursor       = LoadCursor (NULL,IDC_ARROW); +	wc.hbrBackground = (void *)COLOR_WINDOW; +	wc.lpszMenuName  = 0; +	wc.lpszClassName = DEDCLASS; + +	if ( !RegisterClass (&wc) ) +		return; + +	rect.left = 0; +	rect.right = 540; +	rect.top = 0; +	rect.bottom = 450; +	AdjustWindowRect( &rect, DEDSTYLE, FALSE ); + +	hDC = GetDC( GetDesktopWindow() ); +	swidth = GetDeviceCaps( hDC, HORZRES ); +	sheight = GetDeviceCaps( hDC, VERTRES ); +	ReleaseDC( GetDesktopWindow(), hDC ); + +	s_wcd.windowWidth = rect.right - rect.left + 1; +	s_wcd.windowHeight = rect.bottom - rect.top + 1; + +	s_wcd.hWnd = CreateWindowEx( 0, +							   DEDCLASS, +							   CONSOLE_WINDOW_TITLE, +							   DEDSTYLE, +							   ( swidth - 600 ) / 2, ( sheight - 450 ) / 2 , rect.right - rect.left + 1, rect.bottom - rect.top + 1, +							   NULL, +							   NULL, +							   g_wv.hInstance, +							   NULL ); + +	if ( s_wcd.hWnd == NULL ) +	{ +		return; +	} + +	// +	// create fonts +	// +	hDC = GetDC( s_wcd.hWnd ); +	nHeight = -MulDiv( 8, GetDeviceCaps( hDC, LOGPIXELSY), 72); + +	s_wcd.hfBufferFont = CreateFont( nHeight, +									  0, +									  0, +									  0, +									  FW_LIGHT, +									  0, +									  0, +									  0, +									  DEFAULT_CHARSET, +									  OUT_DEFAULT_PRECIS, +									  CLIP_DEFAULT_PRECIS, +									  DEFAULT_QUALITY, +									  FF_MODERN | FIXED_PITCH, +									  "Courier New" ); + +	ReleaseDC( s_wcd.hWnd, hDC ); + +	// +	// create the input line +	// +	s_wcd.hwndInputLine = CreateWindow( "edit", NULL, WS_CHILD | WS_VISIBLE | WS_BORDER |  +												ES_LEFT | ES_AUTOHSCROLL, +												6, 400, 528, 20, +												s_wcd.hWnd,  +												( HMENU ) INPUT_ID,	// child window ID +												g_wv.hInstance, NULL ); + +	// +	// create the buttons +	// +	s_wcd.hwndButtonCopy = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, +												5, 425, 72, 24, +												s_wcd.hWnd,  +												( HMENU ) COPY_ID,	// child window ID +												g_wv.hInstance, NULL ); +	SendMessage( s_wcd.hwndButtonCopy, WM_SETTEXT, 0, ( LPARAM ) "copy" ); + +	s_wcd.hwndButtonClear = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, +												82, 425, 72, 24, +												s_wcd.hWnd,  +												( HMENU ) CLEAR_ID,	// child window ID +												g_wv.hInstance, NULL ); +	SendMessage( s_wcd.hwndButtonClear, WM_SETTEXT, 0, ( LPARAM ) "clear" ); + +	s_wcd.hwndButtonQuit = CreateWindow( "button", NULL, BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, +												462, 425, 72, 24, +												s_wcd.hWnd,  +												( HMENU ) QUIT_ID,	// child window ID +												g_wv.hInstance, NULL ); +	SendMessage( s_wcd.hwndButtonQuit, WM_SETTEXT, 0, ( LPARAM ) "quit" ); + + +	// +	// create the scrollbuffer +	// +	s_wcd.hwndBuffer = CreateWindow( "edit", NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_BORDER |  +												ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY, +												6, 40, 526, 354, +												s_wcd.hWnd,  +												( HMENU ) EDIT_ID,	// child window ID +												g_wv.hInstance, NULL ); +	SendMessage( s_wcd.hwndBuffer, WM_SETFONT, ( WPARAM ) s_wcd.hfBufferFont, 0 ); + +	s_wcd.SysInputLineWndProc = ( WNDPROC ) SetWindowLong( s_wcd.hwndInputLine, GWL_WNDPROC, ( long ) InputLineWndProc ); +	SendMessage( s_wcd.hwndInputLine, WM_SETFONT, ( WPARAM ) s_wcd.hfBufferFont, 0 ); + +	ShowWindow( s_wcd.hWnd, SW_SHOWDEFAULT); +	UpdateWindow( s_wcd.hWnd ); +	SetForegroundWindow( s_wcd.hWnd ); +	SetFocus( s_wcd.hwndInputLine ); + +	s_wcd.visLevel = 1; +} + +/* +** Sys_DestroyConsole +*/ +void Sys_DestroyConsole( void ) { +	if ( s_wcd.hWnd ) { +		ShowWindow( s_wcd.hWnd, SW_HIDE ); +		CloseWindow( s_wcd.hWnd ); +		DestroyWindow( s_wcd.hWnd ); +		s_wcd.hWnd = 0; +	} +} + +/* +** Sys_ShowConsole +*/ +void Sys_ShowConsole( int visLevel, qboolean quitOnClose ) +{ +	s_wcd.quitOnClose = quitOnClose; + +	if ( visLevel == s_wcd.visLevel ) +	{ +		return; +	} + +	s_wcd.visLevel = visLevel; + +	if ( !s_wcd.hWnd ) +		return; + +	switch ( visLevel ) +	{ +	case 0: +		ShowWindow( s_wcd.hWnd, SW_HIDE ); +		break; +	case 1: +		ShowWindow( s_wcd.hWnd, SW_SHOWNORMAL ); +		SendMessage( s_wcd.hwndBuffer, EM_LINESCROLL, 0, 0xffff ); +		break; +	case 2: +		ShowWindow( s_wcd.hWnd, SW_MINIMIZE ); +		break; +	default: +		Sys_Error( "Invalid visLevel %d sent to Sys_ShowConsole\n", visLevel ); +		break; +	} +} + +/* +** Sys_ConsoleInput +*/ +char *Sys_ConsoleInput( void ) +{ +	if ( s_wcd.consoleText[0] == 0 ) +	{ +		return NULL; +	} +		 +	strcpy( s_wcd.returnedText, s_wcd.consoleText ); +	s_wcd.consoleText[0] = 0; +	 +	return s_wcd.returnedText; +} + +/* +** Conbuf_AppendText +*/ +void Conbuf_AppendText( const char *pMsg ) +{ +#define CONSOLE_BUFFER_SIZE		16384 + +	char buffer[CONSOLE_BUFFER_SIZE*2]; +	char *b = buffer; +	const char *msg; +	int bufLen; +	int i = 0; +	static unsigned long s_totalChars; + +	// +	// if the message is REALLY long, use just the last portion of it +	// +	if ( strlen( pMsg ) > CONSOLE_BUFFER_SIZE - 1 ) +	{ +		msg = pMsg + strlen( pMsg ) - CONSOLE_BUFFER_SIZE + 1; +	} +	else +	{ +		msg = pMsg; +	} + +	// +	// copy into an intermediate buffer +	// +	while ( msg[i] && ( ( b - buffer ) < sizeof( buffer ) - 1 ) ) +	{ +		if ( msg[i] == '\n' && msg[i+1] == '\r' ) +		{ +			b[0] = '\r'; +			b[1] = '\n'; +			b += 2; +			i++; +		} +		else if ( msg[i] == '\r' ) +		{ +			b[0] = '\r'; +			b[1] = '\n'; +			b += 2; +		} +		else if ( msg[i] == '\n' ) +		{ +			b[0] = '\r'; +			b[1] = '\n'; +			b += 2; +		} +		else if ( Q_IsColorString( &msg[i] ) ) +		{ +			i++; +		} +		else +		{ +			*b= msg[i]; +			b++; +		} +		i++; +	} +	*b = 0; +	bufLen = b - buffer; + +	s_totalChars += bufLen; + +	// +	// replace selection instead of appending if we're overflowing +	// +	if ( s_totalChars > 0x7fff ) +	{ +		SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 ); +		s_totalChars = bufLen; +	} + +	// +	// put this text into the windows console +	// +	SendMessage( s_wcd.hwndBuffer, EM_LINESCROLL, 0, 0xffff ); +	SendMessage( s_wcd.hwndBuffer, EM_SCROLLCARET, 0, 0 ); +	SendMessage( s_wcd.hwndBuffer, EM_REPLACESEL, 0, (LPARAM) buffer ); +} + +/* +** Sys_SetErrorText +*/ +void Sys_SetErrorText( const char *buf ) +{ +	Q_strncpyz( s_wcd.errorString, buf, sizeof( s_wcd.errorString ) ); + +	if ( !s_wcd.hwndErrorBox ) +	{ +		s_wcd.hwndErrorBox = CreateWindow( "static", NULL, WS_CHILD | WS_VISIBLE | SS_SUNKEN, +													6, 5, 526, 30, +													s_wcd.hWnd,  +													( HMENU ) ERRORBOX_ID,	// child window ID +													g_wv.hInstance, NULL ); +		SendMessage( s_wcd.hwndErrorBox, WM_SETFONT, ( WPARAM ) s_wcd.hfBufferFont, 0 ); +		SetWindowText( s_wcd.hwndErrorBox, s_wcd.errorString ); + +		DestroyWindow( s_wcd.hwndInputLine ); +		s_wcd.hwndInputLine = NULL; +	} +} diff --git a/src/win32/win_wndproc.c b/src/win32/win_wndproc.c new file mode 100644 index 0000000..334d97a --- /dev/null +++ b/src/win32/win_wndproc.c @@ -0,0 +1,457 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2006 Tim Angus + +This file is part of Tremulous. + +Tremulous 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. + +Tremulous is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Tremulous; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA +=========================================================================== +*/ + +#include "../client/client.h" +#include "win_local.h" + +WinVars_t	g_wv; + +#ifndef WM_MOUSEWHEEL +#define WM_MOUSEWHEEL (WM_MOUSELAST+1)  // message that will be supported by the OS  +#endif + +static UINT MSH_MOUSEWHEEL; + +// Console variables that we need to access from this module +cvar_t		*vid_xpos;			// X coordinate of window position +cvar_t		*vid_ypos;			// Y coordinate of window position +cvar_t		*r_fullscreen; + +#define VID_NUM_MODES ( sizeof( vid_modes ) / sizeof( vid_modes[0] ) ) + +LONG WINAPI MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + +static qboolean s_alttab_disabled; + +static void WIN_DisableAltTab( void ) +{ +	if ( s_alttab_disabled ) +		return; + +	if ( !Q_stricmp( Cvar_VariableString( "arch" ), "winnt" ) ) +	{ +		RegisterHotKey( 0, 0, MOD_ALT, VK_TAB ); +	} +	else +	{ +		BOOL old; + +		SystemParametersInfo( SPI_SETSCREENSAVERRUNNING, 1, &old, 0 ); +	} +	s_alttab_disabled = qtrue; +} + +static void WIN_EnableAltTab( void ) +{ +	if ( s_alttab_disabled ) +	{ +		if ( !Q_stricmp( Cvar_VariableString( "arch" ), "winnt" ) ) +		{ +			UnregisterHotKey( 0, 0 ); +		} +		else +		{ +			BOOL old; + +			SystemParametersInfo( SPI_SETSCREENSAVERRUNNING, 0, &old, 0 ); +		} + +		s_alttab_disabled = qfalse; +	} +} + +/* +================== +VID_AppActivate +================== +*/ +static void VID_AppActivate(BOOL fActive, BOOL minimize) +{ +	g_wv.isMinimized = minimize; + +	Com_DPrintf("VID_AppActivate: %i\n", fActive ); + +	Key_ClearStates();	// FIXME!!! + +	// we don't want to act like we're active if we're minimized +	if (fActive && !g_wv.isMinimized ) +	{ +		g_wv.activeApp = qtrue; +	} +	else +	{ +		g_wv.activeApp = qfalse; +	} + +	// minimize/restore mouse-capture on demand +	if (!g_wv.activeApp ) +	{ +		IN_Activate (qfalse); +	} +	else +	{ +		IN_Activate (qtrue); +	} +} + +//========================================================================== + +static byte s_scantokey[128] =  +					{  +//  0           1       2       3       4       5       6       7  +//  8           9       A       B       C       D       E       F  +	0  ,    27,     '1',    '2',    '3',    '4',    '5',    '6',  +	'7',    '8',    '9',    '0',    '-',    '=',    K_BACKSPACE, 9, // 0  +	'q',    'w',    'e',    'r',    't',    'y',    'u',    'i',  +	'o',    'p',    '[',    ']',    13 ,    K_CTRL,'a',  's',      // 1  +	'd',    'f',    'g',    'h',    'j',    'k',    'l',    ';',  +	'\'' ,    '`',    K_SHIFT,'\\',  'z',    'x',    'c',    'v',      // 2  +	'b',    'n',    'm',    ',',    '.',    '/',    K_SHIFT,'*',  +	K_ALT,' ',   K_CAPSLOCK  ,    K_F1, K_F2, K_F3, K_F4, K_F5,   // 3  +	K_F6, K_F7, K_F8, K_F9, K_F10,  K_PAUSE,    0  , K_HOME,  +	K_UPARROW,K_PGUP,K_KP_MINUS,K_LEFTARROW,K_KP_5,K_RIGHTARROW, K_KP_PLUS,K_END, //4  +	K_DOWNARROW,K_PGDN,K_INS,K_DEL,0,0,             0,              K_F11,  +	K_F12,0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0,        // 5 +	0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0,  +	0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0,        // 6  +	0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0,  +	0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0  ,    0         // 7  +};  + +/* +======= +MapKey + +Map from windows to quake keynums +======= +*/ +static int MapKey (int key) +{ +	int result; +	int modified; +	qboolean is_extended; + +//	Com_Printf( "0x%x\n", key); + +	modified = ( key >> 16 ) & 255; + +	if ( modified > 127 ) +		return 0; + +	if ( key & ( 1 << 24 ) ) +	{ +		is_extended = qtrue; +	} +	else +	{ +		is_extended = qfalse; +	} + +	result = s_scantokey[modified]; + +	if ( !is_extended ) +	{ +		switch ( result ) +		{ +		case K_HOME: +			return K_KP_HOME; +		case K_UPARROW: +			return K_KP_UPARROW; +		case K_PGUP: +			return K_KP_PGUP; +		case K_LEFTARROW: +			return K_KP_LEFTARROW; +		case K_RIGHTARROW: +			return K_KP_RIGHTARROW; +		case K_END: +			return K_KP_END; +		case K_DOWNARROW: +			return K_KP_DOWNARROW; +		case K_PGDN: +			return K_KP_PGDN; +		case K_INS: +			return K_KP_INS; +		case K_DEL: +			return K_KP_DEL; +		default: +			return result; +		} +	} +	else +	{ +		switch ( result ) +		{ +		case K_PAUSE: +			return K_KP_NUMLOCK; +		case 0x0D: +			return K_KP_ENTER; +		case 0x2F: +			return K_KP_SLASH; +		case 0xAF: +			return K_KP_PLUS; +		} +		return result; +	} +} + + +/* +==================== +MainWndProc + +main window procedure +==================== +*/ +extern cvar_t *in_mouse; +extern cvar_t *in_logitechbug; +LONG WINAPI MainWndProc ( +    HWND    hWnd, +    UINT    uMsg, +    WPARAM  wParam, +    LPARAM  lParam) +{ +	static qboolean flip = qtrue; +	int zDelta, i; + +	// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/mouseinput/aboutmouseinput.asp +	// Windows 95, Windows NT 3.51 - uses MSH_MOUSEWHEEL +	// only relevant for non-DI input +	// +	// NOTE: not sure how reliable this is anymore, might trigger double wheel events +	if (in_mouse->integer != 1) +	{ +		if ( uMsg == MSH_MOUSEWHEEL ) +		{ +			if ( ( ( int ) wParam ) > 0 ) +			{ +				Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELUP, qtrue, 0, NULL ); +				Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELUP, qfalse, 0, NULL ); +			} +			else +			{ +				Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL ); +				Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL ); +			} +			return DefWindowProc (hWnd, uMsg, wParam, lParam); +		} +	} + +	switch (uMsg) +	{ +	case WM_MOUSEWHEEL: +		// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/mouseinput/aboutmouseinput.asp +		// Windows 98/Me, Windows NT 4.0 and later - uses WM_MOUSEWHEEL +		// only relevant for non-DI input and when console is toggled in window mode +		//   if console is toggled in window mode (KEYCATCH_CONSOLE) then mouse is released and DI doesn't see any mouse wheel +		if (in_mouse->integer != 1 || (!r_fullscreen->integer && (cls.keyCatchers & KEYCATCH_CONSOLE))) +		{ +			// 120 increments, might be 240 and multiples if wheel goes too fast +			// NOTE Logitech: logitech drivers are screwed and send the message twice? +			//   could add a cvar to interpret the message as successive press/release events +			zDelta = ( short ) HIWORD( wParam ) / 120; +			if ( zDelta > 0 ) +			{ +				for(i=0; i<zDelta; i++) +				{ +					if (!in_logitechbug->integer) +					{ +						Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELUP, qtrue, 0, NULL ); +						Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELUP, qfalse, 0, NULL ); +					} +					else +					{ +						Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELUP, flip, 0, NULL ); +						flip = !flip; +					} +				} +			} +			else +			{ +				for(i=0; i<-zDelta; i++) +				{ +					if (!in_logitechbug->integer) +					{ +						Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL ); +						Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL ); +					} +					else +					{ +						Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MWHEELDOWN, flip, 0, NULL ); +						flip = !flip; +					} +				} +			} +			// when an application processes the WM_MOUSEWHEEL message, it must return zero +			return 0; +		} +		break; + +	case WM_CREATE: + +		g_wv.hWnd = hWnd; + +		vid_xpos = Cvar_Get ("vid_xpos", "3", CVAR_ARCHIVE); +		vid_ypos = Cvar_Get ("vid_ypos", "22", CVAR_ARCHIVE); +		r_fullscreen = Cvar_Get ("r_fullscreen", "1", CVAR_ARCHIVE | CVAR_LATCH ); + +		MSH_MOUSEWHEEL = RegisterWindowMessage("MSWHEEL_ROLLMSG");  +		if ( r_fullscreen->integer ) +		{ +			WIN_DisableAltTab(); +		} +		else +		{ +			WIN_EnableAltTab(); +		} + +		break; +#if 0 +	case WM_DISPLAYCHANGE: +		Com_DPrintf( "WM_DISPLAYCHANGE\n" ); +		// we need to force a vid_restart if the user has changed +		// their desktop resolution while the game is running, +		// but don't do anything if the message is a result of +		// our own calling of ChangeDisplaySettings +		if ( com_insideVidInit ) { +			break;		// we did this on purpose +		} +		// something else forced a mode change, so restart all our gl stuff +		Cbuf_AddText( "vid_restart\n" ); +		break; +#endif +	case WM_DESTROY: +		// let sound and input know about this? +		g_wv.hWnd = NULL; +		if ( r_fullscreen->integer ) +		{ +			WIN_EnableAltTab(); +		} +		break; + +	case WM_CLOSE: +		Cbuf_ExecuteText( EXEC_APPEND, "quit" ); +		break; + +	case WM_ACTIVATE: +		{ +			int	fActive, fMinimized; + +			fActive = LOWORD(wParam); +			fMinimized = (BOOL) HIWORD(wParam); + +			VID_AppActivate( fActive != WA_INACTIVE, fMinimized); +			SNDDMA_Activate(); +		} +		break; + +	case WM_MOVE: +		{ +			int		xPos, yPos; +			RECT r; +			int		style; + +			if (!r_fullscreen->integer ) +			{ +				xPos = (short) LOWORD(lParam);    // horizontal position  +				yPos = (short) HIWORD(lParam);    // vertical position  + +				r.left   = 0; +				r.top    = 0; +				r.right  = 1; +				r.bottom = 1; + +				style = GetWindowLong( hWnd, GWL_STYLE ); +				AdjustWindowRect( &r, style, FALSE ); + +				Cvar_SetValue( "vid_xpos", xPos + r.left); +				Cvar_SetValue( "vid_ypos", yPos + r.top); +				vid_xpos->modified = qfalse; +				vid_ypos->modified = qfalse; +				if ( g_wv.activeApp ) +				{ +					IN_Activate (qtrue); +				} +			} +		} +		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: +		{ +			int	temp; + +			temp = 0; + +			if (wParam & MK_LBUTTON) +				temp |= 1; + +			if (wParam & MK_RBUTTON) +				temp |= 2; + +			if (wParam & MK_MBUTTON) +				temp |= 4; + +			IN_MouseEvent (temp); +		} +		break; + +	case WM_SYSCOMMAND: +		if ( wParam == SC_SCREENSAVE ) +			return 0; +		break; + +	case WM_SYSKEYDOWN: +		if ( wParam == 13 ) +		{ +			if ( r_fullscreen ) +			{ +				Cvar_SetValue( "r_fullscreen", !r_fullscreen->integer ); +				Cbuf_AddText( "vid_restart\n" ); +			} +			return 0; +		} +		// fall through +	case WM_KEYDOWN: +		Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, MapKey( lParam ), qtrue, 0, NULL ); +		break; + +	case WM_SYSKEYUP: +	case WM_KEYUP: +		Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, MapKey( lParam ), qfalse, 0, NULL ); +		break; + +	case WM_CHAR: +		Sys_QueEvent( g_wv.sysMsgTime, SE_CHAR, wParam, 0, 0, NULL ); +		break; +   } + +    return DefWindowProc( hWnd, uMsg, wParam, lParam ); +} +  | 
