Itsa me, quake3io!
0
code/win32/background.bmp
Normal file → Executable file
Before Width: | Height: | Size: 193 KiB After Width: | Height: | Size: 193 KiB |
0
code/win32/clear.bmp
Normal file → Executable file
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
102
code/win32/glw_win.h
Normal file → Executable file
|
@ -1,51 +1,51 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code 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.
|
||||
|
||||
Quake III Arena source code 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 Foobar; 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
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code 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.
|
||||
|
||||
Quake III Arena source code 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 Foobar; 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
|
||||
|
|
0
code/win32/icon2.ico
Normal file → Executable file
Before Width: | Height: | Size: 766 B After Width: | Height: | Size: 766 B |
0
code/win32/mod-sdk-setup/GameSource.VCT
Normal file → Executable file
0
code/win32/mod-sdk-setup/QIIIA Game Source License.doc
Normal file → Executable file
0
code/win32/mod-sdk-setup/bin/lcc.exe
Normal file → Executable file
0
code/win32/mod-sdk-setup/bin/q3asm.exe
Normal file → Executable file
0
code/win32/mod-sdk-setup/bin/q3cpp.exe
Normal file → Executable file
0
code/win32/mod-sdk-setup/bin/q3rcc.exe
Normal file → Executable file
0
code/win32/qe3.ico
Normal file → Executable file
Before Width: | Height: | Size: 766 B After Width: | Height: | Size: 766 B |
88
code/win32/resource.h
Normal file → Executable file
|
@ -1,44 +1,44 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code 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.
|
||||
|
||||
Quake III Arena source code 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 Foobar; 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
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code 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.
|
||||
|
||||
Quake III Arena source code 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 Foobar; 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
|
||||
|
|
428
code/win32/win_gamma.c
Normal file → Executable file
|
@ -1,214 +1,214 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code 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.
|
||||
|
||||
Quake III Arena source code 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 Foobar; 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 puts 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 W2K 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 W2K 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code 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.
|
||||
|
||||
Quake III Arena source code 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 Foobar; 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 puts 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 W2K 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 W2K 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
3316
code/win32/win_glimp.c
Normal file → Executable file
2298
code/win32/win_input.c
Normal file → Executable file
190
code/win32/win_local.h
Normal file → Executable file
|
@ -1,95 +1,95 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code 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.
|
||||
|
||||
Quake III Arena source code 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 Foobar; 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>
|
||||
|
||||
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 ();
|
||||
|
||||
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;
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code 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.
|
||||
|
||||
Quake III Arena source code 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 Foobar; 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>
|
||||
|
||||
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 ();
|
||||
|
||||
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;
|
||||
|
|
2506
code/win32/win_main.c
Normal file → Executable file
2062
code/win32/win_net.c
Normal file → Executable file
8748
code/win32/win_qgl.c
Normal file → Executable file
612
code/win32/win_shared.c
Normal file → Executable file
|
@ -1,306 +1,306 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code 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.
|
||||
|
||||
Quake III Arena source code 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 Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../game/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>
|
||||
|
||||
/*
|
||||
================
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_SnapVector
|
||||
================
|
||||
*/
|
||||
long fastftol( float f ) {
|
||||
static int tmp;
|
||||
__asm fld f
|
||||
__asm fistp tmp
|
||||
__asm mov eax, tmp
|
||||
}
|
||||
|
||||
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;
|
||||
/*
|
||||
*v = fastftol(*v);
|
||||
v++;
|
||||
*v = fastftol(*v);
|
||||
v++;
|
||||
*v = fastftol(*v);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
**
|
||||
** Disable all optimizations temporarily so this code works correctly!
|
||||
**
|
||||
*/
|
||||
#pragma optimize( "", off )
|
||||
|
||||
/*
|
||||
** --------------------------------------------------------------------------------
|
||||
**
|
||||
** PROCESSOR STUFF
|
||||
**
|
||||
** --------------------------------------------------------------------------------
|
||||
*/
|
||||
static void CPUID( int func, unsigned regs[4] )
|
||||
{
|
||||
unsigned regEAX, regEBX, regECX, regEDX;
|
||||
|
||||
#ifndef __VECTORC
|
||||
__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;
|
||||
#else
|
||||
regs[0] = 0;
|
||||
regs[1] = 0;
|
||||
regs[2] = 0;
|
||||
regs[3] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** Re-enable optimizations back to what they were
|
||||
**
|
||||
*/
|
||||
#pragma optimize( "", on )
|
||||
|
||||
//============================================
|
||||
|
||||
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) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *Sys_DefaultInstallPath(void)
|
||||
{
|
||||
return Sys_Cwd();
|
||||
}
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code 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.
|
||||
|
||||
Quake III Arena source code 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 Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "../game/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>
|
||||
|
||||
/*
|
||||
================
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_SnapVector
|
||||
================
|
||||
*/
|
||||
long fastftol( float f ) {
|
||||
static int tmp;
|
||||
__asm fld f
|
||||
__asm fistp tmp
|
||||
__asm mov eax, tmp
|
||||
}
|
||||
|
||||
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;
|
||||
/*
|
||||
*v = fastftol(*v);
|
||||
v++;
|
||||
*v = fastftol(*v);
|
||||
v++;
|
||||
*v = fastftol(*v);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
**
|
||||
** Disable all optimizations temporarily so this code works correctly!
|
||||
**
|
||||
*/
|
||||
#pragma optimize( "", off )
|
||||
|
||||
/*
|
||||
** --------------------------------------------------------------------------------
|
||||
**
|
||||
** PROCESSOR STUFF
|
||||
**
|
||||
** --------------------------------------------------------------------------------
|
||||
*/
|
||||
static void CPUID( int func, unsigned regs[4] )
|
||||
{
|
||||
unsigned regEAX, regEBX, regECX, regEDX;
|
||||
|
||||
#ifndef __VECTORC
|
||||
__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;
|
||||
#else
|
||||
regs[0] = 0;
|
||||
regs[1] = 0;
|
||||
regs[2] = 0;
|
||||
regs[3] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** Re-enable optimizations back to what they were
|
||||
**
|
||||
*/
|
||||
#pragma optimize( "", on )
|
||||
|
||||
//============================================
|
||||
|
||||
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) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *Sys_DefaultInstallPath(void)
|
||||
{
|
||||
return Sys_Cwd();
|
||||
}
|
||||
|
||||
|
|
776
code/win32/win_snd.c
Normal file → Executable file
|
@ -1,388 +1,388 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code 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.
|
||||
|
||||
Quake III Arena source code 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 Foobar; 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) \
|
||||
EXTERN_C 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, &pbuf, &locksize,
|
||||
&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 ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code 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.
|
||||
|
||||
Quake III Arena source code 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 Foobar; 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) \
|
||||
EXTERN_C 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, &pbuf, &locksize,
|
||||
&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 ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
1192
code/win32/win_syscon.c
Normal file → Executable file
912
code/win32/win_wndproc.c
Normal file → Executable file
|
@ -1,456 +1,456 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code 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.
|
||||
|
||||
Quake III Arena source code 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 Foobar; 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_SCREENSAVERRUNNING, 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_SCREENSAVERRUNNING, 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 );
|
||||
}
|
||||
|
||||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code 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.
|
||||
|
||||
Quake III Arena source code 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 Foobar; 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_SCREENSAVERRUNNING, 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_SCREENSAVERRUNNING, 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 );
|
||||
}
|
||||
|
||||
|
|
142
code/win32/winquake.rc
Normal file → Executable file
|
@ -1,71 +1,71 @@
|
|||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "winres.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 "qe3.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_STRING1 "Quake3"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "winres.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 "qe3.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_STRING1 "Quake3"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|