newlines fixed

This commit is contained in:
Zachary Slater 2005-08-26 17:39:27 +00:00
parent 7830940da6
commit 59cce31e75
1121 changed files with 717537 additions and 717537 deletions

View 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

View 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

View 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 );
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View 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;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View 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();
}

View 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 ();
}
}

File diff suppressed because it is too large Load diff

View 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 );
}

View 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
/////////////////////////////////////////////////////////////////////////////