2004-08-23 00:15:46 +00:00
/*
Copyright ( C ) 1996 - 1997 Id Software , Inc .
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
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 this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
// sys_win.h
# include "quakedef.h"
# include "winquake.h"
# include "resource.h"
# include "errno.h"
# include "fcntl.h"
# include <limits.h>
# include <conio.h>
# include <io.h>
# include <direct.h>
# ifdef NODIRECTX
# define DDActive 0
# endif
2004-12-13 00:44:05 +00:00
static HINSTANCE game_library ;
/*
= = = = = = = = = = = = = = = = =
Sys_UnloadGame
= = = = = = = = = = = = = = = = =
*/
void Sys_UnloadGame ( void )
{
if ( ! FreeLibrary ( game_library ) )
Sys_Error ( " FreeLibrary failed for game library " ) ;
game_library = NULL ;
}
/*
= = = = = = = = = = = = = = = = =
Sys_GetGameAPI
Loads the game dll
= = = = = = = = = = = = = = = = =
*/
void * Sys_GetGameAPI ( void * parms )
{
2005-03-18 06:14:07 +00:00
void * ( VARGS * GetGameAPI ) ( void * ) ;
2004-12-13 00:44:05 +00:00
char name [ MAX_OSPATH ] ;
char * path ;
char cwd [ MAX_OSPATH ] ;
# if defined _M_IX86
const char * gamename = " gamex86.dll " ;
# ifdef NDEBUG
const char * debugdir = " release " ;
# else
const char * debugdir = " debug " ;
# endif
# elif defined _M_ALPHA
const char * gamename = " gameaxp.dll " ;
# ifdef NDEBUG
const char * debugdir = " releaseaxp " ;
# else
const char * debugdir = " debugaxp " ;
# endif
# endif
if ( game_library )
Sys_Error ( " Sys_GetGameAPI without Sys_UnloadingGame " ) ;
// check the current debug directory first for development purposes
# ifdef _WIN32
GetCurrentDirectory ( sizeof ( cwd ) , cwd ) ;
# else
_getcwd ( cwd , sizeof ( cwd ) ) ;
# endif
_snprintf ( name , sizeof ( name ) , " %s/%s/%s " , cwd , debugdir , gamename ) ;
game_library = LoadLibrary ( name ) ;
if ( game_library )
{
Con_DPrintf ( " LoadLibrary (%s) \n " , name ) ;
}
else
{
# ifdef DEBUG
// check the current directory for other development purposes
_snprintf ( name , sizeof ( name ) , " %s/%s " , cwd , gamename ) ;
game_library = LoadLibrary ( name ) ;
if ( game_library )
{
Con_DPrintf ( " LoadLibrary (%s) \n " , name ) ;
}
else
# endif
{
// now run through the search paths
path = NULL ;
while ( 1 )
{
path = COM_NextPath ( path ) ;
if ( ! path )
return NULL ; // couldn't find one anywhere
_snprintf ( name , sizeof ( name ) , " %s/%s " , path , gamename ) ;
game_library = LoadLibrary ( name ) ;
if ( game_library )
{
Con_DPrintf ( " LoadLibrary (%s) \n " , name ) ;
break ;
}
}
}
}
GetGameAPI = ( void * ) GetProcAddress ( game_library , " GetGameAPI " ) ;
if ( ! GetGameAPI )
{
Sys_UnloadGame ( ) ;
return NULL ;
}
return GetGameAPI ( parms ) ;
}
2004-08-23 00:15:46 +00:00
# define MINIMUM_WIN_MEMORY 0x0800000
2005-03-23 22:14:08 +00:00
# define MAXIMUM_WIN_MEMORY 0x4000000
2004-08-23 00:15:46 +00:00
# define PAUSE_SLEEP 50 // sleep time on pause or minimization
# define NOT_FOCUS_SLEEP 20 // sleep time when not focus
int starttime ;
qboolean ActiveApp , Minimized ;
qboolean WinNT ;
HWND hwnd_dialog ; // startup dialog box
static HANDLE hinput , houtput ;
HANDLE qwclsemaphore ;
static HANDLE tevent ;
void Sys_InitFloatTime ( void ) ;
void VARGS MaskExceptions ( void ) ;
void Sys_PopFPCW ( void ) ;
void Sys_PushFPCW_SetHigh ( void ) ;
void VARGS Sys_DebugLog ( char * file , char * fmt , . . . )
{
2004-12-13 00:44:05 +00:00
FILE * fd ;
va_list argptr ;
static char data [ 1024 ] ;
2004-08-23 00:15:46 +00:00
2004-12-13 00:44:05 +00:00
va_start ( argptr , fmt ) ;
_vsnprintf ( data , sizeof ( data ) - 1 , fmt , argptr ) ;
va_end ( argptr ) ;
2004-10-19 16:10:14 +00:00
# if defined(CRAZYDEBUGGING) && CRAZYDEBUGGING > 1
{
static int sock ;
if ( ! sock )
{
struct sockaddr_in sa ;
netadr_t na ;
int _true = true ;
int listip ;
listip = COM_CheckParm ( " -debugip " ) ;
NET_StringToAdr ( listip ? com_argv [ listip + 1 ] : " 127.0.0.1 " , & na ) ;
NetadrToSockadr ( & na , ( struct sockaddr_qstorage * ) & sa ) ;
sa . sin_port = htons ( 10000 ) ;
sock = socket ( AF_INET , SOCK_STREAM , IPPROTO_TCP ) ;
if ( - 1 = = connect ( sock , ( struct sockaddr * ) & sa , sizeof ( sa ) ) )
Sys_Error ( " Couldn't send debug log lines \n " ) ;
setsockopt ( sock , IPPROTO_TCP , TCP_NODELAY , ( char * ) & _true , sizeof ( _true ) ) ;
}
send ( sock , data , strlen ( data ) , 0 ) ;
}
# endif
2005-01-13 16:29:20 +00:00
fd = fopen ( file , " ab " ) ;
2005-05-08 06:02:03 +00:00
if ( fd )
{
fprintf ( fd , " %s " , data ) ;
fclose ( fd ) ;
}
2004-08-23 00:15:46 +00:00
} ;
int * debug ;
2004-09-04 17:45:10 +00:00
# if (_WIN32_WINNT < 0x0400)
# define LLKHF_ALTDOWN 0x00000020
# define LLKHF_UP 0x00000080
# define WH_KEYBOARD_LL 13
typedef struct {
DWORD vkCode ;
DWORD scanCode ;
DWORD flags ;
DWORD time ;
DWORD dwExtraInfo ;
} KBDLLHOOKSTRUCT ;
# elif defined(MINGW)
# define LLKHF_UP 0x00000080
# endif
HHOOK llkeyboardhook ;
cvar_t sys_disableWinKeys = { " sys_disableWinKeys " , " 0 " } ;
2004-10-07 13:04:30 +00:00
cvar_t sys_disableTaskSwitch = { " sys_disableTaskSwitch " , " 0 " , NULL , CVAR_NOTFROMSERVER } ; // please don't encourage people to use this...
2004-09-04 17:45:10 +00:00
LRESULT CALLBACK LowLevelKeyboardProc ( INT nCode , WPARAM wParam , LPARAM lParam )
{
KBDLLHOOKSTRUCT * pkbhs = ( KBDLLHOOKSTRUCT * ) lParam ;
if ( ActiveApp )
switch ( nCode )
{
case HC_ACTION :
{
//Trap the Left Windowskey
if ( pkbhs - > vkCode = = VK_LWIN )
{
Key_Event ( K_LWIN , ! ( pkbhs - > flags & LLKHF_UP ) ) ;
return 1 ;
}
//Trap the Right Windowskey
if ( pkbhs - > vkCode = = VK_RWIN )
{
Key_Event ( K_RWIN , ! ( pkbhs - > flags & LLKHF_UP ) ) ;
return 1 ;
}
//Trap the Application Key (what a pointless key)
if ( pkbhs - > vkCode = = VK_APPS )
{
Key_Event ( K_APP , ! ( pkbhs - > flags & LLKHF_UP ) ) ;
return 1 ;
}
// Disable CTRL+ESC
2004-10-03 10:19:58 +00:00
//this works, but we've got to give some way to tab out...
2004-10-07 13:04:30 +00:00
if ( sys_disableTaskSwitch . value )
{
if ( pkbhs - > vkCode = = VK_ESCAPE & & GetAsyncKeyState ( VK_CONTROL ) > > ( ( sizeof ( SHORT ) * 8 ) - 1 ) )
return 1 ;
2004-09-04 17:45:10 +00:00
// Disable ATL+TAB
2004-10-07 13:04:30 +00:00
if ( pkbhs - > vkCode = = VK_TAB & & pkbhs - > flags & LLKHF_ALTDOWN )
return 1 ;
2004-09-04 17:45:10 +00:00
// Disable ALT+ESC
2004-10-07 13:04:30 +00:00
if ( pkbhs - > vkCode = = VK_ESCAPE & & pkbhs - > flags & LLKHF_ALTDOWN )
return 1 ;
}
2004-09-04 17:45:10 +00:00
break ;
}
default :
break ;
}
return CallNextHookEx ( llkeyboardhook , nCode , wParam , lParam ) ;
}
void SetHookState ( qboolean state )
{
if ( ! state = = ! llkeyboardhook ) //not so types are comparable
return ;
if ( llkeyboardhook )
{
UnhookWindowsHookEx ( llkeyboardhook ) ;
llkeyboardhook = NULL ;
}
if ( state )
llkeyboardhook = SetWindowsHookEx ( WH_KEYBOARD_LL , LowLevelKeyboardProc , GetModuleHandle ( NULL ) , 0 ) ;
}
2004-08-23 00:15:46 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
FILE IO
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = =
Sys_filelength
= = = = = = = = = = = = = = = =
*/
int Sys_filelength ( FILE * f )
{
int pos ;
int end ;
pos = ftell ( f ) ;
fseek ( f , 0 , SEEK_END ) ;
end = ftell ( f ) ;
fseek ( f , pos , SEEK_SET ) ;
return end ;
}
int Sys_FileTime ( char * path )
{
FILE * f ;
int t = 0 , retval ;
if ( qrenderer )
t = VID_ForceUnlockedAndReturnState ( ) ;
f = fopen ( path , " rb " ) ;
if ( f )
{
fclose ( f ) ;
retval = 1 ;
}
else
{
retval = - 1 ;
}
if ( qrenderer )
VID_ForceLockState ( t ) ;
return retval ;
}
void Sys_mkdir ( char * path )
{
_mkdir ( path ) ;
}
qboolean Sys_remove ( char * path )
{
remove ( path ) ;
return true ;
}
int Sys_EnumerateFiles ( char * gpath , char * match , int ( * func ) ( char * , int , void * ) , void * parm )
{
HANDLE r ;
WIN32_FIND_DATA fd ;
char apath [ MAX_OSPATH ] ;
char file [ MAX_OSPATH ] ;
char * s ;
int go ;
2004-12-05 11:40:15 +00:00
if ( ! gpath )
return 0 ;
// strcpy(apath, match);
sprintf ( apath , " %s/%s " , gpath , match ) ;
for ( s = apath + strlen ( apath ) - 1 ; s > apath ; s - - )
2004-08-23 00:15:46 +00:00
{
if ( * s = = ' / ' )
break ;
}
2004-12-05 11:40:15 +00:00
* s = ' \0 ' ;
2004-08-23 00:15:46 +00:00
2004-12-05 11:40:15 +00:00
//this is what we ask windows for.
sprintf ( file , " %s/*.* " , apath ) ;
//we need to make apath contain the path in match but not gpath
strcpy ( apath , match ) ;
match = s + 1 ;
for ( s = apath + strlen ( apath ) - 1 ; s > apath ; s - - )
{
if ( * s = = ' / ' )
break ;
}
* s = ' \0 ' ;
if ( s ! = apath )
strcat ( apath , " / " ) ;
2004-08-23 00:15:46 +00:00
r = FindFirstFile ( file , & fd ) ;
if ( r = = ( HANDLE ) - 1 )
return 1 ;
go = true ;
do
{
2004-12-05 11:40:15 +00:00
if ( * fd . cFileName = = ' . ' ) ; //don't ever find files with a name starting with '.'
2005-05-30 12:30:41 +00:00
else if ( fd . dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) //is a directory
2004-08-23 00:15:46 +00:00
{
2004-12-05 11:40:15 +00:00
if ( wildcmp ( match , fd . cFileName ) )
{
2005-05-30 12:30:41 +00:00
sprintf ( file , " %s%s/ " , apath , fd . cFileName ) ;
2004-12-05 11:40:15 +00:00
go = func ( file , fd . nFileSizeLow , parm ) ;
}
2004-08-23 00:15:46 +00:00
}
else
{
2004-12-05 11:40:15 +00:00
if ( wildcmp ( match , fd . cFileName ) )
{
2005-05-30 12:30:41 +00:00
sprintf ( file , " %s%s " , apath , fd . cFileName ) ;
2004-12-05 11:40:15 +00:00
go = func ( file , fd . nFileSizeLow , parm ) ;
}
2004-08-23 00:15:46 +00:00
}
}
while ( FindNextFile ( r , & fd ) & & go ) ;
FindClose ( r ) ;
return go ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
SYSTEM IO
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = =
Sys_MakeCodeWriteable
= = = = = = = = = = = = = = = =
*/
void Sys_MakeCodeWriteable ( unsigned long startaddr , unsigned long length )
{
DWORD flOldProtect ;
//@@@ copy on write or just read-write?
if ( ! VirtualProtect ( ( LPVOID ) startaddr , length , PAGE_READWRITE , & flOldProtect ) )
Sys_Error ( " Protection change failed \n " ) ;
}
/*
= = = = = = = = = = = = = = = =
Sys_Init
= = = = = = = = = = = = = = = =
*/
void Sys_Init ( void )
{
// LARGE_INTEGER PerformanceFreq;
// unsigned int lowpart, highpart;
OSVERSIONINFO vinfo ;
2004-12-25 02:06:27 +00:00
2004-08-23 00:15:46 +00:00
# ifndef SERVERONLY
# ifndef CLIENTONLY
2004-12-25 02:06:27 +00:00
if ( ! isDedicated & & ! COM_CheckParm ( " -nomutex " ) )
# else
if ( ! COM_CheckParm ( " -nomutex " ) ) //we need to create a mutex to allow gamespy to realise that we're running, but it might not be desired as it prevents other clients from running too.
2004-08-23 00:15:46 +00:00
# endif
{
// allocate a named semaphore on the client so the
// front end can tell if it is alive
2005-07-28 15:22:15 +00:00
// mutex will fail if semephore already exists
2004-08-23 00:15:46 +00:00
qwclsemaphore = CreateMutex (
NULL , // Security attributes
0 , // owner
" qwcl " ) ; // Semaphore name
// if (!qwclsemaphore)
// Sys_Error ("QWCL is already running on this system");
CloseHandle ( qwclsemaphore ) ;
qwclsemaphore = CreateSemaphore (
NULL , // Security attributes
0 , // Initial count
1 , // Maximum count
" qwcl " ) ; // Semaphore name
}
# endif
2004-12-25 02:06:27 +00:00
2004-08-23 00:15:46 +00:00
MaskExceptions ( ) ;
Sys_SetFPCW ( ) ;
#if 0
if ( ! QueryPerformanceFrequency ( & PerformanceFreq ) )
Sys_Error ( " No hardware timer available " ) ;
// get 32 out of the 64 time bits such that we have around
// 1 microsecond resolution
lowpart = ( unsigned int ) PerformanceFreq . LowPart ;
highpart = ( unsigned int ) PerformanceFreq . HighPart ;
lowshift = 0 ;
while ( highpart | | ( lowpart > 2000000.0 ) )
{
lowshift + + ;
lowpart > > = 1 ;
lowpart | = ( highpart & 1 ) < < 31 ;
highpart > > = 1 ;
}
pfreq = 1.0 / ( double ) lowpart ;
Sys_InitFloatTime ( ) ;
# endif
// make sure the timer is high precision, otherwise
// NT gets 18ms resolution
timeBeginPeriod ( 1 ) ;
vinfo . dwOSVersionInfoSize = sizeof ( vinfo ) ;
if ( ! GetVersionEx ( & vinfo ) )
Sys_Error ( " Couldn't get OS info " ) ;
if ( ( vinfo . dwMajorVersion < 4 ) | |
( vinfo . dwPlatformId = = VER_PLATFORM_WIN32s ) )
{
Sys_Error ( " QuakeWorld requires at least Win95 or NT 4.0 " ) ;
}
if ( vinfo . dwPlatformId = = VER_PLATFORM_WIN32_NT )
WinNT = true ;
else
WinNT = false ;
}
void VARGS Sys_Error ( const char * error , . . . )
{
va_list argptr ;
char text [ 1024 ] ;
//, text2[1024];
// DWORD dummy;
va_start ( argptr , error ) ;
_vsnprintf ( text , sizeof ( text ) - 1 , error , argptr ) ;
va_end ( argptr ) ;
2004-09-04 17:45:10 +00:00
SetHookState ( false ) ;
2004-08-23 00:15:46 +00:00
Host_Shutdown ( ) ;
MessageBox ( NULL , text , " Error " , 0 ) ;
# ifndef SERVERONLY
CloseHandle ( qwclsemaphore ) ;
# endif
2004-09-04 17:45:10 +00:00
SetHookState ( false ) ;
2004-08-23 00:15:46 +00:00
exit ( 1 ) ;
}
void VARGS Sys_Printf ( char * fmt , . . . )
{
va_list argptr ;
char text [ 1024 ] ;
DWORD dummy ;
if ( ! houtput )
return ;
va_start ( argptr , fmt ) ;
_vsnprintf ( text , sizeof ( text ) - 1 , fmt , argptr ) ;
va_end ( argptr ) ;
WriteFile ( houtput , text , strlen ( text ) , & dummy , NULL ) ;
}
void Sys_Quit ( void )
{
if ( VID_ForceUnlockedAndReturnState )
VID_ForceUnlockedAndReturnState ( ) ;
2004-09-04 17:45:10 +00:00
SetHookState ( false ) ;
2004-08-23 00:15:46 +00:00
Host_Shutdown ( ) ;
# ifndef SERVERONLY
if ( tevent )
CloseHandle ( tevent ) ;
if ( qwclsemaphore )
CloseHandle ( qwclsemaphore ) ;
# endif
/* Yeah, right, just wishful thinking.
# ifdef _DEBUG
if ( Z_Allocated ( ) )
MessageBox ( 0 , " Some memory was left allocated " , " Mem was left " , 0 ) ;
# endif
*/
2004-09-04 17:45:10 +00:00
SetHookState ( false ) ;
2004-08-23 00:15:46 +00:00
exit ( 0 ) ;
}
#if 0
/*
= = = = = = = = = = = = = = = =
Sys_DoubleTime
= = = = = = = = = = = = = = = =
*/
double Sys_DoubleTime ( void )
{
static int sametimecount ;
static unsigned int oldtime ;
static int first = 1 ;
LARGE_INTEGER PerformanceCount ;
unsigned int temp , t2 ;
double time ;
Sys_PushFPCW_SetHigh ( ) ;
QueryPerformanceCounter ( & PerformanceCount ) ;
temp = ( ( unsigned int ) PerformanceCount . LowPart > > lowshift ) |
( ( unsigned int ) PerformanceCount . HighPart < < ( 32 - lowshift ) ) ;
if ( first )
{
oldtime = temp ;
first = 0 ;
}
else
{
// check for turnover or backward time
if ( ( temp < = oldtime ) & & ( ( oldtime - temp ) < 0x10000000 ) )
{
oldtime = temp ; // so we can't get stuck
}
else
{
t2 = temp - oldtime ;
time = ( double ) t2 * pfreq ;
oldtime = temp ;
curtime + = time ;
if ( curtime = = lastcurtime )
{
sametimecount + + ;
if ( sametimecount > 100000 )
{
curtime + = 1.0 ;
sametimecount = 0 ;
}
}
else
{
sametimecount = 0 ;
}
lastcurtime = curtime ;
}
}
Sys_PopFPCW ( ) ;
return curtime ;
}
/*
= = = = = = = = = = = = = = = =
Sys_InitFloatTime
= = = = = = = = = = = = = = = =
*/
void Sys_InitFloatTime ( void )
{
int j ;
Sys_DoubleTime ( ) ;
j = COM_CheckParm ( " -starttime " ) ;
if ( j )
{
curtime = ( double ) ( Q_atof ( com_argv [ j + 1 ] ) ) ;
}
else
{
curtime = 0.0 ;
}
lastcurtime = curtime ;
}
# endif
2005-08-07 18:08:13 +00:00
unsigned int Sys_Milliseconds ( void )
2004-08-23 00:15:46 +00:00
{
static DWORD starttime ;
static qboolean first = true ;
DWORD now ;
// double t;
now = timeGetTime ( ) ;
if ( first ) {
first = false ;
starttime = now ;
return 0.0 ;
}
2005-08-07 18:08:13 +00:00
/*
2004-08-23 00:15:46 +00:00
if ( now < starttime ) // wrapped?
{
double r ;
2005-08-07 18:08:13 +00:00
r = ( now ) + ( LONG_MAX - starttime ) ;
2004-08-23 00:15:46 +00:00
starttime = now ;
return r ;
}
if ( now - starttime = = 0 )
return 0.0 ;
2005-08-07 18:08:13 +00:00
*/
return ( now - starttime ) ;
}
2004-08-23 00:15:46 +00:00
2005-08-07 18:08:13 +00:00
double Sys_DoubleTime ( void )
{
return Sys_Milliseconds ( ) / 1000.f ;
2004-08-23 00:15:46 +00:00
}
/////////////////////////////////////////
//the system console stuff
char * Sys_ConsoleInput ( void )
{
static char text [ 256 ] ;
static int len ;
INPUT_RECORD recs [ 1024 ] ;
// int count;
int i ;
int ch ;
DWORD numevents , numread , dummy = 0 ;
HANDLE th ;
char * clipText , * textCopied ;
2005-05-08 06:02:03 +00:00
if ( ! hinput )
2005-05-17 02:36:54 +00:00
return NULL ;
2005-05-08 06:02:03 +00:00
2004-08-23 00:15:46 +00:00
for ( ; ; )
{
if ( ! GetNumberOfConsoleInputEvents ( hinput , & numevents ) )
Sys_Error ( " Error getting # of console events " ) ;
if ( numevents < = 0 )
break ;
if ( ! ReadConsoleInput ( hinput , recs , 1 , & numread ) )
Sys_Error ( " Error reading console input " ) ;
if ( numread ! = 1 )
Sys_Error ( " Couldn't read console input " ) ;
if ( recs [ 0 ] . EventType = = KEY_EVENT )
{
if ( recs [ 0 ] . Event . KeyEvent . bKeyDown )
{
ch = recs [ 0 ] . Event . KeyEvent . uChar . AsciiChar ;
switch ( ch )
{
case ' \r ' :
WriteFile ( houtput , " \r \n " , 2 , & dummy , NULL ) ;
if ( len )
{
text [ len ] = 0 ;
len = 0 ;
return text ;
}
break ;
case ' \b ' :
if ( len )
{
len - - ;
WriteFile ( houtput , " \b \b " , 3 , & dummy , NULL ) ;
}
break ;
default :
if ( ( ( ch = = ' V ' | | ch = = ' v ' ) & & ( recs [ 0 ] . Event . KeyEvent . dwControlKeyState &
( LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED ) ) ) | | ( ( recs [ 0 ] . Event . KeyEvent . dwControlKeyState
& SHIFT_PRESSED ) & & ( recs [ 0 ] . Event . KeyEvent . wVirtualKeyCode
= = VK_INSERT ) ) ) {
if ( OpenClipboard ( NULL ) ) {
th = GetClipboardData ( CF_TEXT ) ;
if ( th ) {
clipText = GlobalLock ( th ) ;
if ( clipText ) {
textCopied = BZ_Malloc ( GlobalSize ( th ) + 1 ) ;
strcpy ( textCopied , clipText ) ;
/* Substitutes a NULL for every token */ strtok ( textCopied , " \n \r \b " ) ;
i = strlen ( textCopied ) ;
if ( i + len > = 256 )
i = 256 - len ;
if ( i > 0 ) {
textCopied [ i ] = 0 ;
text [ len ] = 0 ;
strcat ( text , textCopied ) ;
len + = dummy ;
WriteFile ( houtput , textCopied , i , & dummy , NULL ) ;
}
BZ_Free ( textCopied ) ;
}
GlobalUnlock ( th ) ;
}
CloseClipboard ( ) ;
}
} else if ( ch > = ' ' )
{
WriteFile ( houtput , & ch , 1 , & dummy , NULL ) ;
text [ len ] = ch ;
len = ( len + 1 ) & 0xff ;
}
break ;
}
}
}
}
return NULL ;
}
BOOL WINAPI HandlerRoutine ( DWORD dwCtrlType )
{
switch ( dwCtrlType )
{
case CTRL_C_EVENT :
case CTRL_BREAK_EVENT :
case CTRL_CLOSE_EVENT :
case CTRL_LOGOFF_EVENT :
case CTRL_SHUTDOWN_EVENT :
Cbuf_AddText ( " quit \n " , RESTRICT_LOCAL ) ;
return true ;
}
return false ;
}
qboolean Sys_InitTerminal ( void )
{
if ( ! AllocConsole ( ) )
return false ;
SetConsoleCtrlHandler ( HandlerRoutine , TRUE ) ;
2005-11-14 01:32:21 +00:00
SetConsoleTitle ( FULLENGINENAME , " dedicated server " ) ;
2004-08-23 00:15:46 +00:00
hinput = GetStdHandle ( STD_INPUT_HANDLE ) ;
houtput = GetStdHandle ( STD_OUTPUT_HANDLE ) ;
return true ;
}
void Sys_CloseTerminal ( void )
{
FreeConsole ( ) ;
2005-05-08 06:02:03 +00:00
hinput = NULL ;
houtput = NULL ;
2004-08-23 00:15:46 +00:00
}
//
////////////////////////////
void Sys_Sleep ( void )
{
}
void Sys_SendKeyEvents ( void )
{
MSG msg ;
2005-05-08 06:02:03 +00:00
if ( isDedicated )
2004-08-23 00:15:46 +00:00
{
2004-11-29 01:21:00 +00:00
# ifndef CLIENTONLY
2004-08-23 00:15:46 +00:00
SV_GetConsoleCommands ( ) ;
2004-11-29 01:21:00 +00:00
# endif
2004-08-23 00:15:46 +00:00
return ;
}
while ( PeekMessage ( & msg , NULL , 0 , 0 , PM_NOREMOVE ) )
{
// we always update if there are any event, even if we're paused
scr_skipupdate = 0 ;
if ( ! GetMessage ( & msg , NULL , 0 , 0 ) )
break ;
// Sys_Quit ();
TranslateMessage ( & msg ) ;
DispatchMessage ( & msg ) ;
}
}
void Sys_ServerActivity ( void )
{
FlashWindow ( mainwindow , true ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
WINDOWS CRAP
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = = = = = = =
WinMain
= = = = = = = = = = = = = = = = = =
*/
void SleepUntilInput ( int time )
{
MsgWaitForMultipleObjects ( 1 , & tevent , FALSE , time , QS_ALLINPUT ) ;
}
/*
= = = = = = = = = = = = = = = = = =
WinMain
= = = = = = = = = = = = = = = = = =
*/
HINSTANCE global_hInstance ;
int global_nCmdShow ;
char * argv [ MAX_NUM_ARGVS ] ;
static char exename [ 256 ] ;
HWND hwnd_dialog ;
# ifndef CLIENTONLY
qboolean isDedicated = false ;
# endif
2005-10-01 03:09:17 +00:00
/*
2005-09-13 07:10:18 +00:00
# ifdef _MSC_VER
2005-09-08 22:52:46 +00:00
# include <signal.h>
2005-09-13 07:10:18 +00:00
void VARGS Signal_Error_Handler ( int i )
2005-09-08 22:52:46 +00:00
{
int * basepointer ;
__asm { mov basepointer , ebp } ;
2005-10-01 03:09:17 +00:00
Sys_Error ( " Received signal, offset was 0x%8x " , basepointer [ 73 ] ) ;
2005-09-08 22:52:46 +00:00
}
2005-09-13 07:10:18 +00:00
# endif
2005-10-01 03:09:17 +00:00
*/
2005-09-08 22:52:46 +00:00
2004-08-23 00:15:46 +00:00
int WINAPI WinMain ( HINSTANCE hInstance , HINSTANCE hPrevInstance , LPSTR lpCmdLine , int nCmdShow )
{
// MSG msg;
quakeparms_t parms ;
double time , oldtime , newtime ;
MEMORYSTATUS lpBuffer ;
static char cwd [ 1024 ] ;
int t ;
RECT rect ;
2004-12-25 02:06:27 +00:00
/* previous instances do not exist in Win32 */
2004-08-23 00:15:46 +00:00
if ( hPrevInstance )
2005-09-08 22:52:46 +00:00
return 0 ;
2005-10-01 03:09:17 +00:00
/*
2005-09-13 07:10:18 +00:00
# ifndef _DEBUG
# ifdef _MSC_VER
2005-09-08 22:52:46 +00:00
signal ( SIGFPE , Signal_Error_Handler ) ;
signal ( SIGILL , Signal_Error_Handler ) ;
signal ( SIGSEGV , Signal_Error_Handler ) ;
2005-09-13 07:10:18 +00:00
# endif
# endif
2005-10-01 03:09:17 +00:00
*/
2004-08-23 00:15:46 +00:00
global_hInstance = hInstance ;
global_nCmdShow = nCmdShow ;
lpBuffer . dwLength = sizeof ( MEMORYSTATUS ) ;
GlobalMemoryStatus ( & lpBuffer ) ;
GetModuleFileName ( NULL , cwd , sizeof ( cwd ) - 1 ) ;
strcpy ( exename , COM_SkipPath ( cwd ) ) ;
parms . argc = 1 ;
argv [ 0 ] = exename ;
while ( * lpCmdLine & & ( parms . argc < MAX_NUM_ARGVS ) )
{
while ( * lpCmdLine & & ( ( * lpCmdLine < = 32 ) | | ( * lpCmdLine > 126 ) ) )
lpCmdLine + + ;
if ( * lpCmdLine )
{
argv [ parms . argc ] = lpCmdLine ;
parms . argc + + ;
while ( * lpCmdLine & & ( ( * lpCmdLine > 32 ) & & ( * lpCmdLine < = 126 ) ) )
lpCmdLine + + ;
if ( * lpCmdLine )
{
* lpCmdLine = 0 ;
lpCmdLine + + ;
}
}
}
parms . argv = argv ;
COM_InitArgv ( parms . argc , parms . argv ) ;
TL_InitLanguages ( ) ;
//tprints are now allowed
if ( ! GetCurrentDirectory ( sizeof ( cwd ) , cwd ) )
Sys_Error ( " Couldn't determine current directory " ) ;
if ( cwd [ Q_strlen ( cwd ) - 1 ] = = ' / ' | | cwd [ Q_strlen ( cwd ) - 1 ] = = ' \\ ' )
cwd [ Q_strlen ( cwd ) - 1 ] = 0 ;
parms . basedir = cwd ;
parms . argc = com_argc ;
parms . argv = com_argv ;
# ifndef CLIENTONLY
if ( COM_CheckParm ( " -dedicated " ) )
{
isDedicated = true ;
hwnd_dialog = NULL ;
if ( ! Sys_InitTerminal ( ) )
Sys_Error ( " Couldn't allocate dedicated server console " ) ;
}
else
# endif
hwnd_dialog = CreateDialog ( hInstance , MAKEINTRESOURCE ( IDD_DIALOG1 ) , NULL , NULL ) ;
if ( hwnd_dialog )
{
if ( GetWindowRect ( hwnd_dialog , & rect ) )
{
if ( rect . left > ( rect . top * 2 ) )
{
SetWindowPos ( hwnd_dialog , 0 ,
( rect . left / 2 ) - ( ( rect . right - rect . left ) / 2 ) ,
rect . top , 0 , 0 ,
SWP_NOZORDER | SWP_NOSIZE ) ;
}
}
ShowWindow ( hwnd_dialog , SW_SHOWDEFAULT ) ;
UpdateWindow ( hwnd_dialog ) ;
SetForegroundWindow ( hwnd_dialog ) ;
}
// take the greater of all the available memory or half the total memory,
// but at least 8 Mb and no more than 16 Mb, unless they explicitly
// request otherwise
parms . memsize = lpBuffer . dwAvailPhys ;
if ( parms . memsize < MINIMUM_WIN_MEMORY )
parms . memsize = MINIMUM_WIN_MEMORY ;
if ( parms . memsize < ( lpBuffer . dwTotalPhys > > 1 ) )
parms . memsize = lpBuffer . dwTotalPhys > > 1 ;
2005-03-23 22:14:08 +00:00
if ( parms . memsize > MAXIMUM_WIN_MEMORY )
parms . memsize = MAXIMUM_WIN_MEMORY ;
2004-08-23 00:15:46 +00:00
if ( COM_CheckParm ( " -heapsize " ) )
{
t = COM_CheckParm ( " -heapsize " ) + 1 ;
if ( t < com_argc )
parms . memsize = Q_atoi ( com_argv [ t ] ) * 1024 ;
}
else if ( COM_CheckParm ( " -mem " ) )
{
t = COM_CheckParm ( " -mem " ) + 1 ;
if ( t < com_argc )
2004-12-15 17:45:59 +00:00
parms . memsize = Q_atoi ( com_argv [ t ] ) * 1024 * 1024 ;
2004-08-23 00:15:46 +00:00
}
parms . membase = VirtualAlloc ( NULL , parms . memsize , MEM_RESERVE , PAGE_NOACCESS ) ;
// parms.membase = malloc (parms.memsize);
if ( ! parms . membase )
Sys_Error ( " Not enough memory free; check disk space \n " ) ;
# ifndef CLIENTONLY
if ( isDedicated ) //compleate denial to switch to anything else - many of the client structures are not initialized.
{
SV_Init ( & parms ) ;
2005-08-07 18:08:13 +00:00
SV_Frame ( ) ;
2004-08-23 00:15:46 +00:00
while ( 1 )
{
if ( ! isDedicated )
Sys_Error ( " Dedicated was cleared " ) ;
2005-08-07 18:08:13 +00:00
NET_Sleep ( 100 , false ) ;
SV_Frame ( ) ;
2004-08-23 00:15:46 +00:00
}
return TRUE ;
}
# endif
tevent = CreateEvent ( NULL , FALSE , FALSE , NULL ) ;
if ( ! tevent )
Sys_Error ( " Couldn't create event " ) ;
Sys_Init ( ) ;
Sys_Printf ( " Host_Init \n " ) ;
Host_Init ( & parms ) ;
2004-10-07 13:04:30 +00:00
Cvar_Register ( & sys_disableWinKeys , " System vars " ) ;
Cvar_Register ( & sys_disableTaskSwitch , " System vars " ) ;
2004-09-04 17:45:10 +00:00
2004-08-23 00:15:46 +00:00
oldtime = Sys_DoubleTime ( ) ;
//client console should now be initialized.
/* main window message loop */
while ( 1 )
{
2004-11-29 01:21:00 +00:00
# ifndef CLIENTONLY
2004-08-23 00:15:46 +00:00
if ( isDedicated )
{
2005-06-14 04:52:10 +00:00
NET_Sleep ( 50 , false ) ;
2004-08-23 00:15:46 +00:00
// find time passed since last cycle
newtime = Sys_DoubleTime ( ) ;
time = newtime - oldtime ;
oldtime = newtime ;
2005-08-07 18:08:13 +00:00
SV_Frame ( ) ;
2004-08-23 00:15:46 +00:00
}
else
2004-11-29 01:21:00 +00:00
# endif
2004-08-23 00:15:46 +00:00
{
// yield the CPU for a little while when paused, minimized, or not the focus
if ( ( ( cl . paused & & ( ! ActiveApp & & ! DDActive ) ) | | Minimized | | block_drawing ) & & ! media_filmtype )
{
SleepUntilInput ( PAUSE_SLEEP ) ;
scr_skipupdate = 1 ; // no point in bothering to draw
}
else if ( ! ActiveApp & & ! DDActive & & ! media_filmtype )
{
SleepUntilInput ( NOT_FOCUS_SLEEP ) ;
}
newtime = Sys_DoubleTime ( ) ;
time = newtime - oldtime ;
Host_Frame ( time ) ;
oldtime = newtime ;
2004-09-04 17:45:10 +00:00
SetHookState ( sys_disableWinKeys . value ) ;
2005-04-16 16:21:27 +00:00
// Sleep(0);
2004-08-23 00:15:46 +00:00
}
}
/* return success of application */
return TRUE ;
}
# ifdef NOASM //these couldn't be found... (it is a masm thing, right?)
void Sys_HighFPPrecision ( void )
{
}
void Sys_LowFPPrecision ( void )
{
}
void Sys_SetFPCW ( void )
{
}
void MaskExceptions ( void )
{
}
# endif