summaryrefslogtreecommitdiff
path: root/src/qcommon
diff options
context:
space:
mode:
Diffstat (limited to 'src/qcommon')
-rw-r--r--src/qcommon/cm_trace.c17
-rw-r--r--src/qcommon/common.c253
-rw-r--r--src/qcommon/cvar.c26
-rw-r--r--src/qcommon/files.c595
-rw-r--r--src/qcommon/net_chan.c19
-rw-r--r--src/qcommon/net_ip.c1076
-rw-r--r--src/qcommon/q_math.c9
-rw-r--r--src/qcommon/q_platform.h2
-rw-r--r--src/qcommon/q_shared.c56
-rw-r--r--src/qcommon/q_shared.h27
-rw-r--r--src/qcommon/qcommon.h107
-rw-r--r--src/qcommon/vm.c17
-rw-r--r--src/qcommon/vm_interpreted.c2
-rw-r--r--src/qcommon/vm_local.h1
-rw-r--r--src/qcommon/vm_x86.c14
-rw-r--r--src/qcommon/vm_x86_64.c2
16 files changed, 1635 insertions, 588 deletions
diff --git a/src/qcommon/cm_trace.c b/src/qcommon/cm_trace.c
index c40e1013..bd8d4bd5 100644
--- a/src/qcommon/cm_trace.c
+++ b/src/qcommon/cm_trace.c
@@ -42,7 +42,7 @@ BASIC MATH
RotatePoint
================
*/
-void RotatePoint(vec3_t point, /*const*/ vec3_t matrix[3]) { // bk: FIXME
+void RotatePoint(vec3_t point, /*const*/ vec3_t matrix[3]) { // FIXME
vec3_t tvec;
VectorCopy(point, tvec);
@@ -56,7 +56,7 @@ void RotatePoint(vec3_t point, /*const*/ vec3_t matrix[3]) { // bk: FIXME
TransposeMatrix
================
*/
-void TransposeMatrix(/*const*/ vec3_t matrix[3], vec3_t transpose[3]) { // bk: FIXME
+void TransposeMatrix(/*const*/ vec3_t matrix[3], vec3_t transpose[3]) { // FIXME
int i, j;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
@@ -1269,17 +1269,6 @@ void CM_TraceThroughTree( traceWork_t *tw, int num, float p1f, float p2f, vec3_t
if ( tw->isPoint ) {
offset = 0;
} else {
-#if 0 // bk010201 - DEAD
- // an axial brush right behind a slanted bsp plane
- // will poke through when expanded, so adjust
- // by sqrt(3)
- offset = fabs(tw->extents[0]*plane->normal[0]) +
- fabs(tw->extents[1]*plane->normal[1]) +
- fabs(tw->extents[2]*plane->normal[2]);
-
- offset *= 2;
- offset = tw->maxOffset;
-#endif
// this is silly
offset = 2048;
}
@@ -1479,7 +1468,7 @@ void CM_Trace( trace_t *results, const vec3_t start,
//
if (start[0] == end[0] && start[1] == end[1] && start[2] == end[2]) {
if ( model ) {
-#ifdef ALWAYS_BBOX_VS_BBOX // bk010201 - FIXME - compile time flag?
+#ifdef ALWAYS_BBOX_VS_BBOX // FIXME - compile time flag?
if ( model == BOX_MODEL_HANDLE || model == CAPSULE_MODEL_HANDLE) {
tw.type = TT_AABB;
CM_TestInLeaf( &tw, &cmod->leaf );
diff --git a/src/qcommon/common.c b/src/qcommon/common.c
index be4eafd1..083a7d18 100644
--- a/src/qcommon/common.c
+++ b/src/qcommon/common.c
@@ -57,7 +57,6 @@ static fileHandle_t logfile;
fileHandle_t com_journalFile; // events are written here
fileHandle_t com_journalDataFile; // config files are written here
-cvar_t *com_viewlog;
cvar_t *com_speeds;
cvar_t *com_developer;
cvar_t *com_dedicated;
@@ -80,9 +79,9 @@ cvar_t *sv_paused;
cvar_t *cl_packetdelay;
cvar_t *sv_packetdelay;
cvar_t *com_cameraMode;
-#if defined(_WIN32) && defined(_DEBUG)
-cvar_t *com_noErrorInterrupt;
-#endif
+cvar_t *com_ansiColor;
+cvar_t *com_unfocused;
+cvar_t *com_minimized;
// com_speeds times
int time_game;
@@ -161,10 +160,9 @@ void QDECL Com_Printf( const char *fmt, ... ) {
return;
}
- // echo to console if we're not a dedicated server
- if ( com_dedicated && !com_dedicated->integer ) {
- CL_ConsolePrint( msg );
- }
+#ifndef DEDICATED
+ CL_ConsolePrint( msg );
+#endif
// echo to dedicated console and early console
Sys_Print( msg );
@@ -246,17 +244,6 @@ void QDECL Com_Error( int code, const char *fmt, ... ) {
static int errorCount;
int currentTime;
-#if defined(_WIN32) && defined(_DEBUG)
- if ( code != ERR_DISCONNECT && code != ERR_NEED_CD ) {
- if (!com_noErrorInterrupt->integer) {
- __asm {
- int 0x03
- }
- }
- }
-#endif
- Cvar_Set("com_errorCode", va("%i", code));
-
// when we are running automated scripts, make sure we
// know if anything failed
if ( com_buildScript && com_buildScript->integer ) {
@@ -1127,7 +1114,6 @@ typedef struct memstatic_s {
byte mem[2];
} memstatic_t;
-// bk001204 - initializer brackets
memstatic_t emptystring =
{ {(sizeof(memblock_t)+2 + 3) & ~3, TAG_STATIC, NULL, NULL, ZONEID}, {'\0', '\0'} };
memstatic_t numberstring[] = {
@@ -1386,7 +1372,6 @@ Com_InitZoneMemory
*/
void Com_InitSmallZoneMemory( void ) {
s_smallZoneTotal = 512 * 1024;
- // bk001205 - was malloc
smallzone = calloc( s_smallZoneTotal, 1 );
if ( !smallzone ) {
Com_Error( ERR_FATAL, "Small zone data failed to allocate %1.1f megs", (float)s_smallZoneTotal / (1024*1024) );
@@ -1412,7 +1397,6 @@ void Com_InitZoneMemory( void ) {
s_zoneTotal = cv->integer * 1024 * 1024;
}
- // bk001205 - was malloc
mainzone = calloc( s_zoneTotal, 1 );
if ( !mainzone ) {
Com_Error( ERR_FATAL, "Zone data failed to allocate %i megs", s_zoneTotal / (1024*1024) );
@@ -1537,8 +1521,6 @@ void Com_InitHunkMemory( void ) {
s_hunkTotal = cv->integer * 1024 * 1024;
}
-
- // bk001205 - was malloc
s_hunkData = calloc( s_hunkTotal + 31, 1 );
if ( !s_hunkData ) {
Com_Error( ERR_FATAL, "Hunk data failed to allocate %i megs", s_hunkTotal / (1024*1024) );
@@ -1902,14 +1884,9 @@ journaled file
===================================================================
*/
-// bk001129 - here we go again: upped from 64
-// FIXME TTimo blunt upping from 256 to 1024
-// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=5
#define MAX_PUSHED_EVENTS 1024
-// bk001129 - init, also static
static int com_pushedEventsHead = 0;
static int com_pushedEventsTail = 0;
-// bk001129 - static
static sysEvent_t com_pushedEvents[MAX_PUSHED_EVENTS];
/*
@@ -1943,6 +1920,125 @@ void Com_InitJournaling( void ) {
}
/*
+========================================================================
+
+EVENT LOOP
+
+========================================================================
+*/
+
+#define MAX_QUEUED_EVENTS 256
+#define MASK_QUEUED_EVENTS ( MAX_QUEUED_EVENTS - 1 )
+
+static sysEvent_t eventQueue[ MAX_QUEUED_EVENTS ];
+static int eventHead = 0;
+static int eventTail = 0;
+static byte sys_packetReceived[ MAX_MSGLEN ];
+
+/*
+================
+Com_QueueEvent
+
+A time of 0 will get the current time
+Ptr should either be null, or point to a block of data that can
+be freed by the game later.
+================
+*/
+void Com_QueueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr )
+{
+ sysEvent_t *ev;
+
+ ev = &eventQueue[ eventHead & MASK_QUEUED_EVENTS ];
+
+ if ( eventHead - eventTail >= MAX_QUEUED_EVENTS )
+ {
+ Com_Printf("Com_QueueEvent: overflow\n");
+ // we are discarding an event, but don't leak memory
+ if ( ev->evPtr )
+ {
+ Z_Free( ev->evPtr );
+ }
+ eventTail++;
+ }
+
+ eventHead++;
+
+ if ( time == 0 )
+ {
+ time = Sys_Milliseconds();
+ }
+
+ ev->evTime = time;
+ ev->evType = type;
+ ev->evValue = value;
+ ev->evValue2 = value2;
+ ev->evPtrLength = ptrLength;
+ ev->evPtr = ptr;
+}
+
+/*
+================
+Com_GetSystemEvent
+
+================
+*/
+sysEvent_t Com_GetSystemEvent( void )
+{
+ sysEvent_t ev;
+ char *s;
+ msg_t netmsg;
+ netadr_t adr;
+
+ // return if we have data
+ if ( eventHead > eventTail )
+ {
+ eventTail++;
+ return eventQueue[ ( eventTail - 1 ) & MASK_QUEUED_EVENTS ];
+ }
+
+ // check for console commands
+ s = Sys_ConsoleInput();
+ if ( s )
+ {
+ char *b;
+ int len;
+
+ len = strlen( s ) + 1;
+ b = Z_Malloc( len );
+ strcpy( b, s );
+ Com_QueueEvent( 0, SE_CONSOLE, 0, 0, len, b );
+ }
+
+ // check for network packets
+ MSG_Init( &netmsg, sys_packetReceived, sizeof( sys_packetReceived ) );
+ if ( Sys_GetPacket ( &adr, &netmsg ) )
+ {
+ netadr_t *buf;
+ int len;
+
+ // copy out to a seperate buffer for qeueing
+ len = sizeof( netadr_t ) + netmsg.cursize;
+ buf = Z_Malloc( len );
+ *buf = adr;
+ memcpy( buf+1, netmsg.data, netmsg.cursize );
+ Com_QueueEvent( 0, SE_PACKET, 0, 0, len, buf );
+ }
+
+ // return if we have data
+ if ( eventHead > eventTail )
+ {
+ eventTail++;
+ return eventQueue[ ( eventTail - 1 ) & MASK_QUEUED_EVENTS ];
+ }
+
+ // create an empty event to return
+ memset( &ev, 0, sizeof( ev ) );
+ ev.evTime = Sys_Milliseconds();
+
+ return ev;
+}
+
+/*
=================
Com_GetRealEvent
=================
@@ -1965,7 +2061,7 @@ sysEvent_t Com_GetRealEvent( void ) {
}
}
} else {
- ev = Sys_GetEvent();
+ ev = Com_GetSystemEvent();
// write the journal value out if needed
if ( com_journal->integer == 1 ) {
@@ -1991,7 +2087,6 @@ sysEvent_t Com_GetRealEvent( void ) {
Com_InitPushEvent
=================
*/
-// bk001129 - added
void Com_InitPushEvent( void ) {
// clear the static buffer array
// this requires SE_NONE to be accepted as a valid but NOP event
@@ -2010,7 +2105,7 @@ Com_PushEvent
*/
void Com_PushEvent( sysEvent_t *event ) {
sysEvent_t *ev;
- static int printedWarning = 0; // bk001129 - init, bk001204 - explicit int
+ static int printedWarning = 0;
ev = &com_pushedEvents[ com_pushedEventsHead & (MAX_PUSHED_EVENTS-1) ];
@@ -2111,7 +2206,6 @@ int Com_EventLoop( void ) {
switch ( ev.evType ) {
default:
- // bk001129 - was ev.evTime
Com_Error( ERR_FATAL, "Com_EventLoop: bad event type %i", ev.evType );
break;
case SE_NONE:
@@ -2260,7 +2354,7 @@ static void Com_DetectAltivec(void)
static qboolean altivec = qfalse;
static qboolean detected = qfalse;
if (!detected) {
- altivec = Sys_DetectAltivec();
+ altivec = ( Sys_GetProcessorFeatures( ) & CF_ALTIVEC );
detected = qtrue;
}
@@ -2279,13 +2373,17 @@ Com_Init
void Com_Init( char *commandLine ) {
char *s;
- Com_Printf( "%s %s %s\n", SVN_VERSION, PLATFORM_STRING, __DATE__ );
+ Com_Printf( "%s %s %s\n", Q3_VERSION, PLATFORM_STRING, __DATE__ );
if ( setjmp (abortframe) ) {
Sys_Error ("Error during initialization");
}
- // bk001129 - do this before anything else decides to push events
+ // Clear queues
+ Com_Memset( &eventQueue[ 0 ], 0, MAX_QUEUED_EVENTS * sizeof( sysEvent_t ) );
+ Com_Memset( &sys_packetReceived[ 0 ], 0, MAX_MSGLEN * sizeof( byte ) );
+
+ // do this before anything else decides to push events
Com_InitPushEvent();
Com_InitSmallZoneMemory();
@@ -2355,7 +2453,6 @@ void Com_Init( char *commandLine ) {
com_fixedtime = Cvar_Get ("fixedtime", "0", CVAR_CHEAT);
com_showtrace = Cvar_Get ("com_showtrace", "0", CVAR_CHEAT);
com_dropsim = Cvar_Get ("com_dropsim", "0", CVAR_CHEAT);
- com_viewlog = Cvar_Get( "viewlog", "0", CVAR_CHEAT );
com_speeds = Cvar_Get ("com_speeds", "0", 0);
com_timedemo = Cvar_Get ("timedemo", "0", CVAR_CHEAT);
com_cameraMode = Cvar_Get ("com_cameraMode", "0", CVAR_CHEAT);
@@ -2367,16 +2464,10 @@ void Com_Init( char *commandLine ) {
com_sv_running = Cvar_Get ("sv_running", "0", CVAR_ROM);
com_cl_running = Cvar_Get ("cl_running", "0", CVAR_ROM);
com_buildScript = Cvar_Get( "com_buildScript", "0", 0 );
+ com_ansiColor = Cvar_Get( "com_ansiColor", "0", CVAR_ARCHIVE );
-#if defined(_WIN32) && defined(_DEBUG)
- com_noErrorInterrupt = Cvar_Get( "com_noErrorInterrupt", "0", 0 );
-#endif
-
- if ( com_dedicated->integer ) {
- if ( !com_viewlog->integer ) {
- Cvar_Set( "viewlog", "1" );
- }
- }
+ com_unfocused = Cvar_Get( "com_unfocused", "0", CVAR_ROM );
+ com_minimized = Cvar_Get( "com_minimized", "0", CVAR_ROM );
if ( com_developer && com_developer->integer ) {
Cmd_AddCommand ("error", Com_Error_f);
@@ -2396,10 +2487,9 @@ void Com_Init( char *commandLine ) {
SV_Init();
com_dedicated->modified = qfalse;
- if ( !com_dedicated->integer ) {
- CL_Init();
- Sys_ShowConsole( com_viewlog->integer, qfalse );
- }
+#ifndef DEDICATED
+ CL_Init();
+#endif
// set com_frameTime so that if a map is started on the
// command line it will still be able to count on com_frameTime
@@ -2417,7 +2507,7 @@ void Com_Init( char *commandLine ) {
// start in full screen ui mode
Cvar_Set("r_uiFullScreen", "1");
- CL_StartHunkUsers();
+ CL_StartHunkUsers( qfalse );
// make sure single player is off by default
Cvar_Set("ui_singlePlayerActive", "0");
@@ -2426,9 +2516,9 @@ void Com_Init( char *commandLine ) {
// always set the cvar, but only print the info if it makes sense.
Com_DetectAltivec();
- #if idppc
+#if idppc
Com_Printf ("Altivec support is %s\n", com_altivec->integer ? "enabled" : "disabled");
- #endif
+#endif
Com_Printf ("--- Common Initialization Complete ---\n");
}
@@ -2571,8 +2661,6 @@ void Com_Frame( void ) {
return; // an ERR_DROP was thrown
}
- // bk001204 - init to zero.
- // also: might be clobbered by `longjmp' or `vfork'
timeBeforeFirstEvents =0;
timeBeforeServer =0;
timeBeforeEvents =0;
@@ -2586,14 +2674,6 @@ void Com_Frame( void ) {
// write config file if anything changed
Com_WriteConfiguration();
- // if "viewlog" has been modified, show or hide the log console
- if ( com_viewlog->modified ) {
- if ( !com_dedicated->value ) {
- Sys_ShowConsole( com_viewlog->integer, qfalse );
- }
- com_viewlog->modified = qfalse;
- }
-
//
// main event loop
//
@@ -2646,42 +2726,39 @@ void Com_Frame( void ) {
Cvar_Get( "dedicated", "0", 0 );
com_dedicated->modified = qfalse;
if ( !com_dedicated->integer ) {
- CL_Init();
- Sys_ShowConsole( com_viewlog->integer, qfalse );
- } else {
- CL_Shutdown();
- Sys_ShowConsole( 1, qtrue );
+ SV_Shutdown( "dedicated set to 0" );
+ CL_FlushMemory();
}
}
+#ifndef DEDICATED
//
// client system
//
- if ( !com_dedicated->integer ) {
- //
- // run event loop a second time to get server to client packets
- // without a frame of latency
- //
- if ( com_speeds->integer ) {
- timeBeforeEvents = Sys_Milliseconds ();
- }
- Com_EventLoop();
- Cbuf_Execute ();
+ //
+ // run event loop a second time to get server to client packets
+ // without a frame of latency
+ //
+ if ( com_speeds->integer ) {
+ timeBeforeEvents = Sys_Milliseconds ();
+ }
+ Com_EventLoop();
+ Cbuf_Execute ();
- //
- // client side
- //
- if ( com_speeds->integer ) {
- timeBeforeClient = Sys_Milliseconds ();
- }
+ //
+ // client side
+ //
+ if ( com_speeds->integer ) {
+ timeBeforeClient = Sys_Milliseconds ();
+ }
- CL_Frame( msec );
+ CL_Frame( msec );
- if ( com_speeds->integer ) {
- timeAfter = Sys_Milliseconds ();
- }
+ if ( com_speeds->integer ) {
+ timeAfter = Sys_Milliseconds ();
}
+#endif
//
// report timing information
diff --git a/src/qcommon/cvar.c b/src/qcommon/cvar.c
index 91d3dfbe..d39f134e 100644
--- a/src/qcommon/cvar.c
+++ b/src/qcommon/cvar.c
@@ -512,8 +512,20 @@ qboolean Cvar_Command( void ) {
if ( Cmd_Argc() == 1 ) {
Com_TruncateLongString( string, v->string );
Com_TruncateLongString( resetString, v->resetString );
- Com_Printf ("\"%s\" is:\"%s" S_COLOR_WHITE "\" default:\"%s" S_COLOR_WHITE "\"\n",
- v->name, string, resetString );
+ Com_Printf ("\"%s\" is:\"%s" S_COLOR_WHITE "\"",
+ v->name, string );
+
+ if ( !( v->flags & CVAR_ROM ) ) {
+ if ( !Q_stricmp( string, resetString ) ) {
+ Com_Printf (", the default" );
+ } else {
+ Com_Printf (" default:\"%s" S_COLOR_WHITE "\"",
+ resetString );
+ }
+ }
+
+ Com_Printf ("\n");
+
if ( v->latchedString ) {
Com_TruncateLongString( latchedString, v->latchedString );
Com_Printf( "latched: \"%s\"\n", latchedString );
@@ -893,8 +905,8 @@ updates an interpreted modules' version of a cvar
=====================
*/
void Cvar_Update( vmCvar_t *vmCvar ) {
- cvar_t *cv = NULL; // bk001129
- assert(vmCvar); // bk
+ cvar_t *cv = NULL;
+ assert(vmCvar);
if ( (unsigned)vmCvar->handle >= cvar_numIndexes ) {
Com_Error( ERR_DROP, "Cvar_Update: handle out of range" );
@@ -909,16 +921,10 @@ void Cvar_Update( vmCvar_t *vmCvar ) {
return; // variable might have been cleared by a cvar_restart
}
vmCvar->modificationCount = cv->modificationCount;
- // bk001129 - mismatches.
if ( strlen(cv->string)+1 > MAX_CVAR_VALUE_STRING )
Com_Error( ERR_DROP, "Cvar_Update: src %s length %zd exceeds MAX_CVAR_VALUE_STRING",
cv->string,
strlen(cv->string));
- // bk001212 - Q_strncpyz guarantees zero padding and dest[MAX_CVAR_VALUE_STRING-1]==0
- // bk001129 - paranoia. Never trust the destination string.
- // bk001129 - beware, sizeof(char*) is always 4 (for cv->string).
- // sizeof(vmCvar->string) always MAX_CVAR_VALUE_STRING
- //Q_strncpyz( vmCvar->string, cv->string, sizeof( vmCvar->string ) ); // id
Q_strncpyz( vmCvar->string, cv->string, MAX_CVAR_VALUE_STRING );
vmCvar->value = cv->value;
diff --git a/src/qcommon/files.c b/src/qcommon/files.c
index c1f6fb2d..536434c4 100644
--- a/src/qcommon/files.c
+++ b/src/qcommon/files.c
@@ -52,15 +52,6 @@ command line to allow code debugging in a different directory. Basepath cannot
be modified at all after startup. Any files that are created (demos, screenshots,
etc) will be created reletive to the base path, so base path should usually be writable.
-The "cd path" is the path to an alternate hierarchy that will be searched if a file
-is not located in the base path. A user can do a partial install that copies some
-data to a base path created on their hard drive and leave the rest on the cd. Files
-are never writen to the cd path. It defaults to a value set by the installer, like
-"e:\quake3", but it can be overridden with "+set fs_cdpath g:\quake3".
-
-If a user runs the game directly from a CD, the base path would be on the CD. This
-should still function correctly, but all file writes will fail (harmlessly).
-
The "home path" is the path used for all write access. On win32 systems we have "base path"
== "home path", but on *nix systems the base installation is usually readonly, and
"home path" points to ~/.q3a or similar
@@ -94,21 +85,6 @@ trying to restrict demo / oem versions of the game with code changes. Demo / oe
should be exactly the same executables as release versions, but with different data that
automatically restricts where game media can come from to prevent add-ons from working.
-After the paths are initialized, quake will look for the product.txt file. If not
-found and verified, the game will run in restricted mode. In restricted mode, only
-files contained in demoq3/pak0.pk3 will be available for loading, and only if the zip header is
-verified to not have been modified. A single exception is made for autogen.cfg. Files
-can still be written out in restricted mode, so screenshots and demos are allowed.
-Restricted mode can be tested by setting "+set fs_restrict 1" on the command line, even
-if there is a valid product.txt under the basepath or cdpath.
-
-If not running in restricted mode, and a file is not found in any local filesystem,
-an attempt will be made to download it and save it under the base path.
-
-If the "fs_copyfiles" cvar is set to 1, then every time a file is sourced from the cd
-path, it will be copied over to the base path. This is a development aid to help build
-test releases and to copy working sets over slow network links.
-
File search order: when FS_FOpenFileRead gets called it will go through the fs_searchpaths
structure and stop on the first successful hit. fs_searchpaths is built with successive
calls to FS_AddGameDirectory
@@ -261,10 +237,7 @@ static cvar_t *fs_debug;
static cvar_t *fs_homepath;
static cvar_t *fs_basepath;
static cvar_t *fs_basegame;
-static cvar_t *fs_cdpath;
-static cvar_t *fs_copyfiles;
static cvar_t *fs_gamedirvar;
-static cvar_t *fs_restrict;
static searchpath_t *fs_searchpaths;
static int fs_readCount; // total bytes read
static int fs_loadCount; // total files read
@@ -363,7 +336,7 @@ int FS_LoadStack( void )
{
return fs_loadStack;
}
-
+
/*
================
return a hash value for the filename
@@ -677,8 +650,9 @@ fileHandle_t FS_SV_FOpenFileWrite( const char *filename ) {
/*
===========
FS_SV_FOpenFileRead
-search for a file somewhere below the home path, base path or cd path
-we search in that order, matching FS_SV_FOpenFileRead order
+
+Search for a file somewhere below the home path then base path
+in that order
===========
*/
int FS_SV_FOpenFileRead( const char *filename, fileHandle_t *fp ) {
@@ -697,7 +671,7 @@ int FS_SV_FOpenFileRead( const char *filename, fileHandle_t *fp ) {
// don't let sound stutter
S_ClearSoundBuffer();
- // search homepath
+ // search homepath
ospath = FS_BuildOSPath( fs_homepath->string, filename, "" );
// remove trailing slash
ospath[strlen(ospath)-1] = '\0';
@@ -708,48 +682,30 @@ int FS_SV_FOpenFileRead( const char *filename, fileHandle_t *fp ) {
fsh[f].handleFiles.file.o = fopen( ospath, "rb" );
fsh[f].handleSync = qfalse;
- if (!fsh[f].handleFiles.file.o)
- {
- // NOTE TTimo on non *nix systems, fs_homepath == fs_basepath, might want to avoid
- if (Q_stricmp(fs_homepath->string,fs_basepath->string))
- {
- // search basepath
- ospath = FS_BuildOSPath( fs_basepath->string, filename, "" );
- ospath[strlen(ospath)-1] = '\0';
-
- if ( fs_debug->integer )
- {
- Com_Printf( "FS_SV_FOpenFileRead (fs_basepath): %s\n", ospath );
- }
-
- fsh[f].handleFiles.file.o = fopen( ospath, "rb" );
- fsh[f].handleSync = qfalse;
-
- if ( !fsh[f].handleFiles.file.o )
- {
- f = 0;
- }
- }
- }
+ if (!fsh[f].handleFiles.file.o)
+ {
+ // If fs_homepath == fs_basepath, don't bother
+ if (Q_stricmp(fs_homepath->string,fs_basepath->string))
+ {
+ // search basepath
+ ospath = FS_BuildOSPath( fs_basepath->string, filename, "" );
+ ospath[strlen(ospath)-1] = '\0';
+
+ if ( fs_debug->integer )
+ {
+ Com_Printf( "FS_SV_FOpenFileRead (fs_basepath): %s\n", ospath );
+ }
+
+ fsh[f].handleFiles.file.o = fopen( ospath, "rb" );
+ fsh[f].handleSync = qfalse;
+ }
+
+ if ( !fsh[f].handleFiles.file.o )
+ {
+ f = 0;
+ }
+ }
- if (!fsh[f].handleFiles.file.o) {
- // search cd path
- ospath = FS_BuildOSPath( fs_cdpath->string, filename, "" );
- ospath[strlen(ospath)-1] = '\0';
-
- if (fs_debug->integer)
- {
- Com_Printf( "FS_SV_FOpenFileRead (fs_cdpath) : %s\n", ospath );
- }
-
- fsh[f].handleFiles.file.o = fopen( ospath, "rb" );
- fsh[f].handleSync = qfalse;
-
- if( !fsh[f].handleFiles.file.o ) {
- f = 0;
- }
- }
-
*fp = f;
if (f) {
return FS_filelength(f);
@@ -837,9 +793,6 @@ void FS_FCloseFile( fileHandle_t f ) {
Com_Error( ERR_FATAL, "Filesystem call made without initialization\n" );
}
- if (fsh[f].streamed) {
- Sys_EndStreamedFile(f);
- }
if (fsh[f].zipFile == qtrue) {
unzCloseCurrentFile( fsh[f].handleFiles.file.z );
if ( fsh[f].handleFiles.unique ) {
@@ -1101,7 +1054,7 @@ int FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean uniqueF
}
}
- if (!(pak->referenced & FS_QAGAME_REF) && strstr(filename, "game.qvm")) {
+ if (!(pak->referenced & FS_QAGAME_REF) && strstr(filename, "qagame.qvm")) {
pak->referenced |= FS_QAGAME_REF;
}
if (!(pak->referenced & FS_CGAME_REF) && strstr(filename, "cgame.qvm")) {
@@ -1149,12 +1102,12 @@ int FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean uniqueF
// if we are running restricted, the only files we
// will allow to come from the directory are .cfg files
l = strlen( filename );
- // FIXME TTimo I'm not sure about the fs_numServerPaks test
- // if you are using FS_ReadFile to find out if a file exists,
- // this test can make the search fail although the file is in the directory
- // I had the problem on https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=8
- // turned out I used FS_FileExists instead
- if ( fs_restrict->integer || fs_numServerPaks ) {
+ // FIXME TTimo I'm not sure about the fs_numServerPaks test
+ // if you are using FS_ReadFile to find out if a file exists,
+ // this test can make the search fail although the file is in the directory
+ // I had the problem on https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=8
+ // turned out I used FS_FileExists instead
+ if ( fs_numServerPaks ) {
if ( Q_stricmp( filename + l - 4, ".cfg" ) // for config files
&& Q_stricmp( filename + l - 5, ".menu" ) // menu files
@@ -1180,7 +1133,7 @@ int FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean uniqueF
&& Q_stricmp( filename + l - 4, ".dat" ) ) { // for journal files
fs_fakeChkSum = random();
}
-
+
Q_strncpyz( fsh[*file].name, filename, sizeof( fsh[*file].name ) );
fsh[*file].zipFile = qfalse;
if ( fs_debug->integer ) {
@@ -1188,20 +1141,10 @@ int FS_FOpenFileRead( const char *filename, fileHandle_t *file, qboolean uniqueF
dir->path, dir->gamedir );
}
- // if we are getting it from the cdpath, optionally copy it
- // to the basepath
- if ( fs_copyfiles->integer && !Q_stricmp( dir->path, fs_cdpath->string ) ) {
- char *copypath;
-
- copypath = FS_BuildOSPath( fs_basepath->string, dir->gamedir, filename );
- FS_CopyFile( netpath, copypath );
- }
-
return FS_filelength (*file);
}
}
- Com_DPrintf ("Can't find %s\n", filename);
#ifdef FS_MISSING
if (missingFiles) {
fprintf(missingFiles, "%s\n", filename);
@@ -1230,7 +1173,7 @@ int FS_Read2( void *buffer, int len, fileHandle_t f ) {
if (fsh[f].streamed) {
int r;
fsh[f].streamed = qfalse;
- r = Sys_StreamedRead( buffer, len, 1, f);
+ r = FS_Read( buffer, len, f );
fsh[f].streamed = qtrue;
return r;
} else {
@@ -1366,7 +1309,7 @@ int FS_Seek( fileHandle_t f, long offset, int origin ) {
if (fsh[f].streamed) {
fsh[f].streamed = qfalse;
- Sys_StreamSeek( f, offset, origin );
+ FS_Seek( f, offset, origin );
fsh[f].streamed = qtrue;
}
@@ -1941,7 +1884,7 @@ char **FS_ListFilteredFiles( const char *path, const char *extension, char *filt
char *name;
// don't scan directories for files if we are pure or restricted
- if ( fs_restrict->integer || fs_numServerPaks ) {
+ if ( fs_numServerPaks ) {
continue;
} else {
netpath = FS_BuildOSPath( search->dir->path, search->dir->gamedir, path );
@@ -2055,58 +1998,51 @@ FIXME TTimo those two should move to common.c next to Sys_ListFiles
*/
static unsigned int Sys_CountFileList(char **list)
{
- int i = 0;
+ int i = 0;
- if (list)
- {
- while (*list)
- {
- list++;
- i++;
- }
- }
- return i;
+ if (list)
+ {
+ while (*list)
+ {
+ list++;
+ i++;
+ }
+ }
+ return i;
}
-static char** Sys_ConcatenateFileLists( char **list0, char **list1, char **list2 )
+static char** Sys_ConcatenateFileLists( char **list0, char **list1 )
{
- int totalLength = 0;
- char** cat = NULL, **dst, **src;
-
- totalLength += Sys_CountFileList(list0);
- totalLength += Sys_CountFileList(list1);
- totalLength += Sys_CountFileList(list2);
-
- /* Create new list. */
- dst = cat = Z_Malloc( ( totalLength + 1 ) * sizeof( char* ) );
-
- /* Copy over lists. */
- if (list0)
- {
- for (src = list0; *src; src++, dst++)
- *dst = *src;
- }
- if (list1)
- {
- for (src = list1; *src; src++, dst++)
- *dst = *src;
- }
- if (list2)
- {
- for (src = list2; *src; src++, dst++)
- *dst = *src;
- }
-
- // Terminate the list
- *dst = NULL;
-
- // Free our old lists.
- // NOTE: not freeing their content, it's been merged in dst and still being used
- if (list0) Z_Free( list0 );
- if (list1) Z_Free( list1 );
- if (list2) Z_Free( list2 );
-
- return cat;
+ int totalLength = 0;
+ char** cat = NULL, **dst, **src;
+
+ totalLength += Sys_CountFileList(list0);
+ totalLength += Sys_CountFileList(list1);
+
+ /* Create new list. */
+ dst = cat = Z_Malloc( ( totalLength + 1 ) * sizeof( char* ) );
+
+ /* Copy over lists. */
+ if (list0)
+ {
+ for (src = list0; *src; src++, dst++)
+ *dst = *src;
+ }
+ if (list1)
+ {
+ for (src = list1; *src; src++, dst++)
+ *dst = *src;
+ }
+
+ // Terminate the list
+ *dst = NULL;
+
+ // Free our old lists.
+ // NOTE: not freeing their content, it's been merged in dst and still being used
+ if (list0) Z_Free( list0 );
+ if (list1) Z_Free( list1 );
+
+ return cat;
}
/*
@@ -2119,116 +2055,106 @@ The directories are searched in base path, cd path and home path
================
*/
int FS_GetModList( char *listbuf, int bufsize ) {
- int nMods, i, j, nTotal, nLen, nPaks, nPotential, nDescLen;
- char **pFiles = NULL;
- char **pPaks = NULL;
- char *name, *path;
- char descPath[MAX_OSPATH];
- fileHandle_t descHandle;
-
- int dummy;
- char **pFiles0 = NULL;
- char **pFiles1 = NULL;
- char **pFiles2 = NULL;
- qboolean bDrop = qfalse;
-
- *listbuf = 0;
- nMods = nPotential = nTotal = 0;
-
- pFiles0 = Sys_ListFiles( fs_homepath->string, NULL, NULL, &dummy, qtrue );
- pFiles1 = Sys_ListFiles( fs_basepath->string, NULL, NULL, &dummy, qtrue );
- pFiles2 = Sys_ListFiles( fs_cdpath->string, NULL, NULL, &dummy, qtrue );
- // we searched for mods in the three paths
- // it is likely that we have duplicate names now, which we will cleanup below
- pFiles = Sys_ConcatenateFileLists( pFiles0, pFiles1, pFiles2 );
- nPotential = Sys_CountFileList(pFiles);
-
- for ( i = 0 ; i < nPotential ; i++ ) {
- name = pFiles[i];
- // NOTE: cleaner would involve more changes
- // ignore duplicate mod directories
- if (i!=0) {
- bDrop = qfalse;
- for(j=0; j<i; j++)
- {
- if (Q_stricmp(pFiles[j],name)==0) {
- // this one can be dropped
- bDrop = qtrue;
- break;
- }
- }
- }
- if (bDrop) {
- continue;
- }
- // we drop BASEGAME "." and ".."
- if (Q_stricmp(name, BASEGAME) && Q_stricmpn(name, ".", 1)) {
- // now we need to find some .pk3 files to validate the mod
- // NOTE TTimo: (actually I'm not sure why .. what if it's a mod under developement with no .pk3?)
- // we didn't keep the information when we merged the directory names, as to what OS Path it was found under
- // so it could be in base path, cd path or home path
- // we will try each three of them here (yes, it's a bit messy)
- path = FS_BuildOSPath( fs_basepath->string, name, "" );
- nPaks = 0;
- pPaks = Sys_ListFiles(path, ".pk3", NULL, &nPaks, qfalse);
- Sys_FreeFileList( pPaks ); // we only use Sys_ListFiles to check wether .pk3 files are present
-
- /* Try on cd path */
- if( nPaks <= 0 ) {
- path = FS_BuildOSPath( fs_cdpath->string, name, "" );
- nPaks = 0;
- pPaks = Sys_ListFiles( path, ".pk3", NULL, &nPaks, qfalse );
- Sys_FreeFileList( pPaks );
- }
-
- /* try on home path */
- if ( nPaks <= 0 )
- {
- path = FS_BuildOSPath( fs_homepath->string, name, "" );
- nPaks = 0;
- pPaks = Sys_ListFiles( path, ".pk3", NULL, &nPaks, qfalse );
- Sys_FreeFileList( pPaks );
- }
-
- if (nPaks > 0) {
- nLen = strlen(name) + 1;
- // nLen is the length of the mod path
- // we need to see if there is a description available
- descPath[0] = '\0';
- strcpy(descPath, name);
- strcat(descPath, "/description.txt");
- nDescLen = FS_SV_FOpenFileRead( descPath, &descHandle );
- if ( nDescLen > 0 && descHandle) {
- FILE *file;
- file = FS_FileForHandle(descHandle);
- Com_Memset( descPath, 0, sizeof( descPath ) );
- nDescLen = fread(descPath, 1, 48, file);
- if (nDescLen >= 0) {
- descPath[nDescLen] = '\0';
- }
- FS_FCloseFile(descHandle);
- } else {
- strcpy(descPath, name);
- }
- nDescLen = strlen(descPath) + 1;
-
- if (nTotal + nLen + 1 + nDescLen + 1 < bufsize) {
- strcpy(listbuf, name);
- listbuf += nLen;
- strcpy(listbuf, descPath);
- listbuf += nDescLen;
- nTotal += nLen + nDescLen;
- nMods++;
- }
- else {
- break;
- }
- }
- }
- }
- Sys_FreeFileList( pFiles );
-
- return nMods;
+ int nMods, i, j, nTotal, nLen, nPaks, nPotential, nDescLen;
+ char **pFiles = NULL;
+ char **pPaks = NULL;
+ char *name, *path;
+ char descPath[MAX_OSPATH];
+ fileHandle_t descHandle;
+
+ int dummy;
+ char **pFiles0 = NULL;
+ char **pFiles1 = NULL;
+ qboolean bDrop = qfalse;
+
+ *listbuf = 0;
+ nMods = nPotential = nTotal = 0;
+
+ pFiles0 = Sys_ListFiles( fs_homepath->string, NULL, NULL, &dummy, qtrue );
+ pFiles1 = Sys_ListFiles( fs_basepath->string, NULL, NULL, &dummy, qtrue );
+ // we searched for mods in the three paths
+ // it is likely that we have duplicate names now, which we will cleanup below
+ pFiles = Sys_ConcatenateFileLists( pFiles0, pFiles1 );
+ nPotential = Sys_CountFileList(pFiles);
+
+ for ( i = 0 ; i < nPotential ; i++ ) {
+ name = pFiles[i];
+ // NOTE: cleaner would involve more changes
+ // ignore duplicate mod directories
+ if (i!=0) {
+ bDrop = qfalse;
+ for(j=0; j<i; j++)
+ {
+ if (Q_stricmp(pFiles[j],name)==0) {
+ // this one can be dropped
+ bDrop = qtrue;
+ break;
+ }
+ }
+ }
+ if (bDrop) {
+ continue;
+ }
+ // we drop "baseq3" "." and ".."
+ if (Q_stricmp(name, BASEGAME) && Q_stricmpn(name, ".", 1)) {
+ // now we need to find some .pk3 files to validate the mod
+ // NOTE TTimo: (actually I'm not sure why .. what if it's a mod under developement with no .pk3?)
+ // we didn't keep the information when we merged the directory names, as to what OS Path it was found under
+ // so it could be in base path, cd path or home path
+ // we will try each three of them here (yes, it's a bit messy)
+ path = FS_BuildOSPath( fs_basepath->string, name, "" );
+ nPaks = 0;
+ pPaks = Sys_ListFiles(path, ".pk3", NULL, &nPaks, qfalse);
+ Sys_FreeFileList( pPaks ); // we only use Sys_ListFiles to check wether .pk3 files are present
+
+ /* try on home path */
+ if ( nPaks <= 0 )
+ {
+ path = FS_BuildOSPath( fs_homepath->string, name, "" );
+ nPaks = 0;
+ pPaks = Sys_ListFiles( path, ".pk3", NULL, &nPaks, qfalse );
+ Sys_FreeFileList( pPaks );
+ }
+
+ if (nPaks > 0) {
+ nLen = strlen(name) + 1;
+ // nLen is the length of the mod path
+ // we need to see if there is a description available
+ descPath[0] = '\0';
+ strcpy(descPath, name);
+ strcat(descPath, "/description.txt");
+ nDescLen = FS_SV_FOpenFileRead( descPath, &descHandle );
+ if ( nDescLen > 0 && descHandle) {
+ FILE *file;
+ file = FS_FileForHandle(descHandle);
+ Com_Memset( descPath, 0, sizeof( descPath ) );
+ nDescLen = fread(descPath, 1, 48, file);
+ if (nDescLen >= 0) {
+ descPath[nDescLen] = '\0';
+ }
+ FS_FCloseFile(descHandle);
+ } else {
+ strcpy(descPath, name);
+ }
+ nDescLen = strlen(descPath) + 1;
+
+ if (nTotal + nLen + 1 + nDescLen + 1 < bufsize) {
+ strcpy(listbuf, name);
+ listbuf += nLen;
+ strcpy(listbuf, descPath);
+ listbuf += nDescLen;
+ nTotal += nLen + nDescLen;
+ nMods++;
+ }
+ else {
+ break;
+ }
+ }
+ }
+ }
+ Sys_FreeFileList( pFiles );
+
+ return nMods;
}
@@ -2295,7 +2221,7 @@ Ignore case and seprator char distinctions
*/
int FS_PathCmp( const char *s1, const char *s2 ) {
int c1, c2;
-
+
do {
c1 = *s1++;
c2 = *s2++;
@@ -2424,9 +2350,6 @@ void FS_Path_f( void ) {
/*
============
FS_TouchFile_f
-
-The only purpose of this function is to allow game script files to copy
-arbitrary files furing an "fs_copyfiles 1" run.
============
*/
void FS_TouchFile_f( void ) {
@@ -2472,8 +2395,7 @@ static void FS_AddGameDirectory( const char *path, const char *dir ) {
int numfiles;
char **pakfiles;
- // this fixes the case where fs_basepath is the same as fs_cdpath
- // which happens on full installs
+ // Unique
for ( sp = fs_searchpaths ; sp ; sp = sp->next ) {
if ( sp->dir && !Q_stricmp(sp->dir->path, path) && !Q_stricmp(sp->dir->gamedir, dir)) {
return; // we've already got this one
@@ -2604,10 +2526,10 @@ qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ) {
// Make sure the server cannot make us write to non-quake3 directories.
if(FS_CheckDirTraversal(fs_serverReferencedPakNames[i]))
- {
+ {
Com_Printf("WARNING: Invalid download name %s\n", fs_serverReferencedPakNames[i]);
- continue;
- }
+ continue;
+ }
for ( sp = fs_searchpaths ; sp ; sp = sp->next ) {
if ( sp->pack && sp->pack->checksum == fs_serverReferencedPaks[i] ) {
@@ -2619,54 +2541,55 @@ qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ) {
if ( !havepak && fs_serverReferencedPakNames[i] && *fs_serverReferencedPakNames[i] ) {
// Don't got it
- if (dlstring)
- {
- // We need this to make sure we won't hit the end of the buffer or the server could
- // overwrite non-pk3 files on clients by writing so much crap into neededpaks that
- // Q_strcat cuts off the .pk3 extension.
-
- origpos += strlen(origpos);
-
- // Remote name
- Q_strcat( neededpaks, len, "@");
- Q_strcat( neededpaks, len, fs_serverReferencedPakNames[i] );
- Q_strcat( neededpaks, len, ".pk3" );
-
- // Local name
- Q_strcat( neededpaks, len, "@");
- // Do we have one with the same name?
- if ( FS_SV_FileExists( va( "%s.pk3", fs_serverReferencedPakNames[i] ) ) )
- {
- char st[MAX_ZPATH];
- // We already have one called this, we need to download it to another name
- // Make something up with the checksum in it
- Com_sprintf( st, sizeof( st ), "%s.%08x.pk3", fs_serverReferencedPakNames[i], fs_serverReferencedPaks[i] );
- Q_strcat( neededpaks, len, st );
- } else
- {
- Q_strcat( neededpaks, len, fs_serverReferencedPakNames[i] );
- Q_strcat( neededpaks, len, ".pk3" );
- }
-
- // Find out whether it might have overflowed the buffer and don't add this file to the
- // list if that is the case.
- if(strlen(origpos) + (origpos - neededpaks) >= len - 1)
- {
- *origpos = '\0';
- break;
- }
- }
- else
- {
- Q_strcat( neededpaks, len, fs_serverReferencedPakNames[i] );
- Q_strcat( neededpaks, len, ".pk3" );
- // Do we have one with the same name?
- if ( FS_SV_FileExists( va( "%s.pk3", fs_serverReferencedPakNames[i] ) ) )
- {
- Q_strcat( neededpaks, len, " (local file exists with wrong checksum)");
- }
- Q_strcat( neededpaks, len, "\n");
- }
+ if (dlstring)
+ {
+ // We need this to make sure we won't hit the end of the buffer or the server could
+ // overwrite non-pk3 files on clients by writing so much crap into neededpaks that
+ // Q_strcat cuts off the .pk3 extension.
+
+ origpos += strlen(origpos);
+
+ // Remote name
+ Q_strcat( neededpaks, len, "@");
+ Q_strcat( neededpaks, len, fs_serverReferencedPakNames[i] );
+ Q_strcat( neededpaks, len, ".pk3" );
+
+ // Local name
+ Q_strcat( neededpaks, len, "@");
+ // Do we have one with the same name?
+ if ( FS_SV_FileExists( va( "%s.pk3", fs_serverReferencedPakNames[i] ) ) )
+ {
+ char st[MAX_ZPATH];
+ // We already have one called this, we need to download it to another name
+ // Make something up with the checksum in it
+ Com_sprintf( st, sizeof( st ), "%s.%08x.pk3", fs_serverReferencedPakNames[i], fs_serverReferencedPaks[i] );
+ Q_strcat( neededpaks, len, st );
+ }
+ else
+ {
+ Q_strcat( neededpaks, len, fs_serverReferencedPakNames[i] );
+ Q_strcat( neededpaks, len, ".pk3" );
+ }
+
+ // Find out whether it might have overflowed the buffer and don't add this file to the
+ // list if that is the case.
+ if(strlen(origpos) + (origpos - neededpaks) >= len - 1)
+ {
+ *origpos = '\0';
+ break;
+ }
+ }
+ else
+ {
+ Q_strcat( neededpaks, len, fs_serverReferencedPakNames[i] );
+ Q_strcat( neededpaks, len, ".pk3" );
+ // Do we have one with the same name?
+ if ( FS_SV_FileExists( va( "%s.pk3", fs_serverReferencedPakNames[i] ) ) )
+ {
+ Q_strcat( neededpaks, len, " (local file exists with wrong checksum)");
+ }
+ Q_strcat( neededpaks, len, "\n");
+ }
}
}
@@ -2737,14 +2660,14 @@ static void FS_ReorderPurePaks( void )
int i;
searchpath_t **p_insert_index, // for linked list reordering
**p_previous; // when doing the scan
-
+
// only relevant when connected to pure server
if ( !fs_numServerPaks )
return;
-
+
fs_reordered = qfalse;
-
- p_insert_index = &fs_searchpaths; // we insert in order at the beginning of the list
+
+ p_insert_index = &fs_searchpaths; // we insert in order at the beginning of the list
for ( i = 0 ; i < fs_numServerPaks ; i++ ) {
p_previous = p_insert_index; // track the pointer-to-current-item
for (s = *p_insert_index; s; s = s->next) {
@@ -2759,7 +2682,7 @@ static void FS_ReorderPurePaks( void )
p_insert_index = &s->next;
break; // iterate to next server pack
}
- p_previous = &s->next;
+ p_previous = &s->next;
}
}
}
@@ -2769,42 +2692,34 @@ static void FS_ReorderPurePaks( void )
FS_Startup
================
*/
-static void FS_Startup( const char *gameName ) {
- const char *homePath;
+static void FS_Startup( const char *gameName )
+{
+ const char *homePath;
Com_Printf( "----- FS_Startup -----\n" );
fs_debug = Cvar_Get( "fs_debug", "0", 0 );
- fs_copyfiles = Cvar_Get( "fs_copyfiles", "0", CVAR_INIT );
- fs_cdpath = Cvar_Get ("fs_cdpath", Sys_DefaultCDPath(), CVAR_INIT );
fs_basepath = Cvar_Get ("fs_basepath", Sys_DefaultInstallPath(), CVAR_INIT );
fs_basegame = Cvar_Get ("fs_basegame", "", CVAR_INIT );
- homePath = Sys_DefaultHomePath();
- if (!homePath || !homePath[0]) {
+ homePath = Sys_DefaultHomePath();
+ if (!homePath || !homePath[0]) {
homePath = fs_basepath->string;
}
fs_homepath = Cvar_Get ("fs_homepath", homePath, CVAR_INIT );
fs_gamedirvar = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO );
- fs_restrict = Cvar_Get ("fs_restrict", "", CVAR_INIT );
// add search path elements in reverse priority order
- if (fs_cdpath->string[0]) {
- FS_AddGameDirectory( fs_cdpath->string, gameName );
- }
if (fs_basepath->string[0]) {
FS_AddGameDirectory( fs_basepath->string, gameName );
}
- // fs_homepath is somewhat particular to *nix systems, only add if relevant
- // NOTE: same filtering below for mods and basegame
- if (fs_basepath->string[0] && Q_stricmp(fs_homepath->string,fs_basepath->string)) {
+ // fs_homepath is somewhat particular to *nix systems, only add if relevant
+ // NOTE: same filtering below for mods and basegame
+ if (fs_homepath->string[0] && Q_stricmp(fs_homepath->string,fs_basepath->string)) {
FS_AddGameDirectory ( fs_homepath->string, gameName );
}
-
+
// check for additional base game so mods can be based upon other mods
if ( fs_basegame->string[0] && !Q_stricmp( gameName, BASEGAME ) && Q_stricmp( fs_basegame->string, gameName ) ) {
- if (fs_cdpath->string[0]) {
- FS_AddGameDirectory(fs_cdpath->string, fs_basegame->string);
- }
if (fs_basepath->string[0]) {
FS_AddGameDirectory(fs_basepath->string, fs_basegame->string);
}
@@ -2815,9 +2730,6 @@ static void FS_Startup( const char *gameName ) {
// check for additional game folder for mods
if ( fs_gamedirvar->string[0] && !Q_stricmp( gameName, BASEGAME ) && Q_stricmp( fs_gamedirvar->string, gameName ) ) {
- if (fs_cdpath->string[0]) {
- FS_AddGameDirectory(fs_cdpath->string, fs_gamedirvar->string);
- }
if (fs_basepath->string[0]) {
FS_AddGameDirectory(fs_basepath->string, fs_gamedirvar->string);
}
@@ -2835,7 +2747,7 @@ static void FS_Startup( const char *gameName ) {
// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=506
// reorder the pure pk3 files according to server order
FS_ReorderPurePaks();
-
+
// print the current search paths
FS_Path_f();
@@ -3214,12 +3126,9 @@ void FS_InitFilesystem( void ) {
// we have to specially handle this, because normal command
// line variable sets don't happen until after the filesystem
// has already been initialized
- Com_StartupVariable( "fs_cdpath" );
Com_StartupVariable( "fs_basepath" );
Com_StartupVariable( "fs_homepath" );
Com_StartupVariable( "fs_game" );
- Com_StartupVariable( "fs_copyfiles" );
- Com_StartupVariable( "fs_restrict" );
// try to start up normally
FS_Startup( BASEGAME );
@@ -3229,13 +3138,10 @@ void FS_InitFilesystem( void ) {
// graphics screen when the font fails to load
if ( FS_ReadFile( "default.cfg", NULL ) <= 0 ) {
Com_Error( ERR_FATAL, "Couldn't load default.cfg" );
- // bk001208 - SafeMode see below, FIXME?
}
Q_strncpyz(lastValidBase, fs_basepath->string, sizeof(lastValidBase));
Q_strncpyz(lastValidGame, fs_gamedirvar->string, sizeof(lastValidGame));
-
- // bk001208 - SafeMode see below, FIXME?
}
@@ -3270,7 +3176,6 @@ void FS_Restart( int checksumFeed ) {
Cvar_Set("fs_gamedirvar", lastValidGame);
lastValidBase[0] = '\0';
lastValidGame[0] = '\0';
- Cvar_Set( "fs_restrict", "0" );
FS_Restart(checksumFeed);
Com_Error( ERR_DROP, "Invalid game folder\n" );
return;
@@ -3278,7 +3183,6 @@ void FS_Restart( int checksumFeed ) {
Com_Error( ERR_FATAL, "Couldn't load default.cfg" );
}
- // bk010116 - new check before safeMode
if ( Q_stricmp(fs_gamedirvar->string, lastValidGame) ) {
// skip the autogen.cfg if "safe" is on the command line
if ( !Com_SafeMode() ) {
@@ -3358,7 +3262,6 @@ int FS_FOpenFileByMode( const char *qpath, fileHandle_t *f, fsMode_t mode ) {
fsh[*f].streamed = qfalse;
if (mode == FS_READ) {
- Sys_BeginStreamedFile( *f, 0x4000 );
fsh[*f].streamed = qtrue;
}
}
diff --git a/src/qcommon/net_chan.c b/src/qcommon/net_chan.c
index 869d87a3..aba3b96d 100644
--- a/src/qcommon/net_chan.c
+++ b/src/qcommon/net_chan.c
@@ -483,14 +483,6 @@ qboolean NET_CompareBaseAdr (netadr_t a, netadr_t b)
return qfalse;
}
- if (a.type == NA_IPX)
- {
- if ((memcmp(a.ipx, b.ipx, 10) == 0))
- return qtrue;
- return qfalse;
- }
-
-
Com_Printf ("NET_CompareBaseAdr: bad address type\n");
return qfalse;
}
@@ -504,10 +496,6 @@ const char *NET_AdrToString (netadr_t a)
} else if (a.type == NA_IP) {
Com_sprintf (s, sizeof(s), "%i.%i.%i.%i:%hu",
a.ip[0], a.ip[1], a.ip[2], a.ip[3], BigShort(a.port));
- } else {
- Com_sprintf (s, sizeof(s), "%02x%02x%02x%02x.%02x%02x%02x%02x%02x%02x:%hu",
- a.ipx[0], a.ipx[1], a.ipx[2], a.ipx[3], a.ipx[4], a.ipx[5], a.ipx[6], a.ipx[7], a.ipx[8], a.ipx[9],
- BigShort(a.port));
}
return s;
@@ -529,13 +517,6 @@ qboolean NET_CompareAdr (netadr_t a, netadr_t b)
return qfalse;
}
- if (a.type == NA_IPX)
- {
- if ((memcmp(a.ipx, b.ipx, 10) == 0) && a.port == b.port)
- return qtrue;
- return qfalse;
- }
-
Com_Printf ("NET_CompareAdr: bad address type\n");
return qfalse;
}
diff --git a/src/qcommon/net_ip.c b/src/qcommon/net_ip.c
new file mode 100644
index 00000000..dadfbd3b
--- /dev/null
+++ b/src/qcommon/net_ip.c
@@ -0,0 +1,1076 @@
+/*
+===========================================================================
+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 Quake III Arena source code; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+===========================================================================
+*/
+
+#include "../qcommon/q_shared.h"
+#include "../qcommon/qcommon.h"
+
+#ifdef _WIN32
+#include <winsock.h>
+
+typedef int socklen_t;
+#define EAGAIN WSAEWOULDBLOCK
+#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#define ECONNRESET WSAECONNRESET
+#define socketError WSAGetLastError( )
+
+static WSADATA winsockdata;
+static qboolean winsockInitialized = qfalse;
+
+#else
+
+#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
+ // needed for socklen_t on OSX 10.2
+# define _BSD_SOCKLEN_T_
+#endif
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifdef MACOS_X
+#include <sys/sockio.h>
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/if_dl.h> // for 'struct sockaddr_dl'
+#endif
+
+#ifdef __sun
+#include <sys/filio.h>
+#endif
+
+typedef int SOCKET;
+#define INVALID_SOCKET -1
+#define SOCKET_ERROR -1
+#define closesocket close
+#define ioctlsocket ioctl
+#define socketError errno
+
+#endif
+
+static qboolean usingSocks = qfalse;
+static qboolean networkingEnabled = qfalse;
+
+static cvar_t *net_noudp;
+
+static cvar_t *net_socksEnabled;
+static cvar_t *net_socksServer;
+static cvar_t *net_socksPort;
+static cvar_t *net_socksUsername;
+static cvar_t *net_socksPassword;
+static struct sockaddr socksRelayAddr;
+
+static SOCKET ip_socket;
+static SOCKET socks_socket;
+
+#define MAX_IPS 16
+static int numIP;
+static byte localIP[MAX_IPS][4];
+
+//=============================================================================
+
+
+/*
+====================
+NET_ErrorString
+====================
+*/
+char *NET_ErrorString( void ) {
+#ifdef _WIN32
+ //FIXME: replace with FormatMessage?
+ switch( socketError ) {
+ case WSAEINTR: return "WSAEINTR";
+ case WSAEBADF: return "WSAEBADF";
+ case WSAEACCES: return "WSAEACCES";
+ case WSAEDISCON: return "WSAEDISCON";
+ case WSAEFAULT: return "WSAEFAULT";
+ case WSAEINVAL: return "WSAEINVAL";
+ case WSAEMFILE: return "WSAEMFILE";
+ case WSAEWOULDBLOCK: return "WSAEWOULDBLOCK";
+ case WSAEINPROGRESS: return "WSAEINPROGRESS";
+ case WSAEALREADY: return "WSAEALREADY";
+ case WSAENOTSOCK: return "WSAENOTSOCK";
+ case WSAEDESTADDRREQ: return "WSAEDESTADDRREQ";
+ case WSAEMSGSIZE: return "WSAEMSGSIZE";
+ case WSAEPROTOTYPE: return "WSAEPROTOTYPE";
+ case WSAENOPROTOOPT: return "WSAENOPROTOOPT";
+ case WSAEPROTONOSUPPORT: return "WSAEPROTONOSUPPORT";
+ case WSAESOCKTNOSUPPORT: return "WSAESOCKTNOSUPPORT";
+ case WSAEOPNOTSUPP: return "WSAEOPNOTSUPP";
+ case WSAEPFNOSUPPORT: return "WSAEPFNOSUPPORT";
+ case WSAEAFNOSUPPORT: return "WSAEAFNOSUPPORT";
+ case WSAEADDRINUSE: return "WSAEADDRINUSE";
+ case WSAEADDRNOTAVAIL: return "WSAEADDRNOTAVAIL";
+ case WSAENETDOWN: return "WSAENETDOWN";
+ case WSAENETUNREACH: return "WSAENETUNREACH";
+ case WSAENETRESET: return "WSAENETRESET";
+ case WSAECONNABORTED: return "WSWSAECONNABORTEDAEINTR";
+ case WSAECONNRESET: return "WSAECONNRESET";
+ case WSAENOBUFS: return "WSAENOBUFS";
+ case WSAEISCONN: return "WSAEISCONN";
+ case WSAENOTCONN: return "WSAENOTCONN";
+ case WSAESHUTDOWN: return "WSAESHUTDOWN";
+ case WSAETOOMANYREFS: return "WSAETOOMANYREFS";
+ case WSAETIMEDOUT: return "WSAETIMEDOUT";
+ case WSAECONNREFUSED: return "WSAECONNREFUSED";
+ case WSAELOOP: return "WSAELOOP";
+ case WSAENAMETOOLONG: return "WSAENAMETOOLONG";
+ case WSAEHOSTDOWN: return "WSAEHOSTDOWN";
+ case WSASYSNOTREADY: return "WSASYSNOTREADY";
+ case WSAVERNOTSUPPORTED: return "WSAVERNOTSUPPORTED";
+ case WSANOTINITIALISED: return "WSANOTINITIALISED";
+ case WSAHOST_NOT_FOUND: return "WSAHOST_NOT_FOUND";
+ case WSATRY_AGAIN: return "WSATRY_AGAIN";
+ case WSANO_RECOVERY: return "WSANO_RECOVERY";
+ case WSANO_DATA: return "WSANO_DATA";
+ default: return "NO ERROR";
+ }
+#else
+ return strerror (errno);
+#endif
+}
+
+static void NetadrToSockadr( netadr_t *a, struct sockaddr *s ) {
+ memset( s, 0, sizeof(*s) );
+
+ if( a->type == NA_BROADCAST ) {
+ ((struct sockaddr_in *)s)->sin_family = AF_INET;
+ ((struct sockaddr_in *)s)->sin_port = a->port;
+ ((struct sockaddr_in *)s)->sin_addr.s_addr = INADDR_BROADCAST;
+ }
+ else if( a->type == NA_IP ) {
+ ((struct sockaddr_in *)s)->sin_family = AF_INET;
+ ((struct sockaddr_in *)s)->sin_addr.s_addr = *(int *)&a->ip;
+ ((struct sockaddr_in *)s)->sin_port = a->port;
+ }
+}
+
+
+static void SockadrToNetadr( struct sockaddr *s, netadr_t *a ) {
+ if (s->sa_family == AF_INET) {
+ a->type = NA_IP;
+ *(int *)&a->ip = ((struct sockaddr_in *)s)->sin_addr.s_addr;
+ a->port = ((struct sockaddr_in *)s)->sin_port;
+ }
+}
+
+
+/*
+=============
+Sys_StringToSockaddr
+=============
+*/
+static qboolean Sys_StringToSockaddr( const char *s, struct sockaddr *sadr ) {
+ struct hostent *h;
+
+ memset( sadr, 0, sizeof( *sadr ) );
+
+ ((struct sockaddr_in *)sadr)->sin_family = AF_INET;
+ ((struct sockaddr_in *)sadr)->sin_port = 0;
+
+ if( s[0] >= '0' && s[0] <= '9' ) {
+ *(int *)&((struct sockaddr_in *)sadr)->sin_addr = inet_addr(s);
+ } else {
+ if( ( h = gethostbyname( s ) ) == 0 ) {
+ return 0;
+ }
+ *(int *)&((struct sockaddr_in *)sadr)->sin_addr = *(int *)h->h_addr_list[0];
+ }
+
+ return qtrue;
+}
+
+/*
+=============
+Sys_StringToAdr
+=============
+*/
+qboolean Sys_StringToAdr( const char *s, netadr_t *a ) {
+ struct sockaddr sadr;
+
+ if ( !Sys_StringToSockaddr( s, &sadr ) ) {
+ return qfalse;
+ }
+
+ SockadrToNetadr( &sadr, a );
+ return qtrue;
+}
+
+//=============================================================================
+
+/*
+==================
+Sys_GetPacket
+
+Never called by the game logic, just the system event queing
+==================
+*/
+#ifdef _DEBUG
+int recvfromCount;
+#endif
+
+qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ) {
+ int ret;
+ struct sockaddr from;
+ socklen_t fromlen;
+ int err;
+
+ if( !ip_socket ) {
+ return qfalse;
+ }
+
+ fromlen = sizeof(from);
+#ifdef _DEBUG
+ recvfromCount++; // performance check
+#endif
+ ret = recvfrom( ip_socket, net_message->data, net_message->maxsize, 0, (struct sockaddr *)&from, &fromlen );
+ if (ret == SOCKET_ERROR)
+ {
+ err = socketError;
+
+ if( err == EAGAIN || err == ECONNRESET ) {
+ return qfalse;
+ }
+ Com_Printf( "NET_GetPacket: %s\n", NET_ErrorString() );
+ return qfalse;
+ }
+
+ memset( ((struct sockaddr_in *)&from)->sin_zero, 0, 8 );
+
+ if ( usingSocks && memcmp( &from, &socksRelayAddr, fromlen ) == 0 ) {
+ if ( ret < 10 || net_message->data[0] != 0 || net_message->data[1] != 0 || net_message->data[2] != 0 || net_message->data[3] != 1 ) {
+ return qfalse;
+ }
+ net_from->type = NA_IP;
+ net_from->ip[0] = net_message->data[4];
+ net_from->ip[1] = net_message->data[5];
+ net_from->ip[2] = net_message->data[6];
+ net_from->ip[3] = net_message->data[7];
+ net_from->port = *(short *)&net_message->data[8];
+ net_message->readcount = 10;
+ }
+ else {
+ SockadrToNetadr( &from, net_from );
+ net_message->readcount = 0;
+ }
+
+ if( ret == net_message->maxsize ) {
+ Com_Printf( "Oversize packet from %s\n", NET_AdrToString (*net_from) );
+ return qfalse;
+ }
+
+ net_message->cursize = ret;
+ return qtrue;
+}
+
+//=============================================================================
+
+static char socksBuf[4096];
+
+/*
+==================
+Sys_SendPacket
+==================
+*/
+void Sys_SendPacket( int length, const void *data, netadr_t to ) {
+ int ret;
+ struct sockaddr addr;
+
+ if( to.type != NA_BROADCAST && to.type != NA_IP ) {
+ Com_Error( ERR_FATAL, "Sys_SendPacket: bad address type" );
+ return;
+ }
+
+ if( !ip_socket ) {
+ return;
+ }
+
+ NetadrToSockadr( &to, &addr );
+
+ if( usingSocks && to.type == NA_IP ) {
+ socksBuf[0] = 0; // reserved
+ socksBuf[1] = 0;
+ socksBuf[2] = 0; // fragment (not fragmented)
+ socksBuf[3] = 1; // address type: IPV4
+ *(int *)&socksBuf[4] = ((struct sockaddr_in *)&addr)->sin_addr.s_addr;
+ *(short *)&socksBuf[8] = ((struct sockaddr_in *)&addr)->sin_port;
+ memcpy( &socksBuf[10], data, length );
+ ret = sendto( ip_socket, socksBuf, length+10, 0, &socksRelayAddr, sizeof(socksRelayAddr) );
+ }
+ else {
+ ret = sendto( ip_socket, data, length, 0, &addr, sizeof(addr) );
+ }
+ if( ret == SOCKET_ERROR ) {
+ int err = socketError;
+
+ // wouldblock is silent
+ if( err == EAGAIN ) {
+ return;
+ }
+
+ // some PPP links do not allow broadcasts and return an error
+ if( ( err == EADDRNOTAVAIL ) && ( ( to.type == NA_BROADCAST ) ) ) {
+ return;
+ }
+
+ Com_Printf( "NET_SendPacket: %s\n", NET_ErrorString() );
+ }
+}
+
+
+//=============================================================================
+
+/*
+==================
+Sys_IsLANAddress
+
+LAN clients will have their rate var ignored
+==================
+*/
+qboolean Sys_IsLANAddress( netadr_t adr ) {
+ int i;
+
+ if( adr.type == NA_LOOPBACK ) {
+ return qtrue;
+ }
+
+ if( adr.type != NA_IP ) {
+ return qfalse;
+ }
+
+ // RFC1918:
+ // 10.0.0.0 - 10.255.255.255 (10/8 prefix)
+ // 172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
+ // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
+ if(adr.ip[0] == 10)
+ return qtrue;
+ if(adr.ip[0] == 172 && (adr.ip[1]&0xf0) == 16)
+ return qtrue;
+ if(adr.ip[0] == 192 && adr.ip[1] == 168)
+ return qtrue;
+
+ // choose which comparison to use based on the class of the address being tested
+ // any local adresses of a different class than the address being tested will fail based on the first byte
+ // FIXME tma 28/08/07 Try and make this work for arbitrary subnet masks somehow
+
+ if( adr.ip[0] == 127 && adr.ip[1] == 0 && adr.ip[2] == 0 && adr.ip[3] == 1 ) {
+ return qtrue;
+ }
+
+ // Class A
+ if( (adr.ip[0] & 0x80) == 0x00 ) {
+ for ( i = 0 ; i < numIP ; i++ ) {
+ if( adr.ip[0] == localIP[i][0] ) {
+ return qtrue;
+ }
+ }
+
+ return qfalse;
+ }
+
+ // Class B
+ if( (adr.ip[0] & 0xc0) == 0x80 ) {
+ for ( i = 0 ; i < numIP ; i++ ) {
+ if( adr.ip[0] == localIP[i][0] && adr.ip[1] == localIP[i][1] ) {
+ return qtrue;
+ }
+ }
+ return qfalse;
+ }
+
+ // Class C
+ for ( i = 0 ; i < numIP ; i++ ) {
+ if( adr.ip[0] == localIP[i][0] && adr.ip[1] == localIP[i][1] && adr.ip[2] == localIP[i][2] ) {
+ return qtrue;
+ }
+ }
+ return qfalse;
+}
+
+/*
+==================
+Sys_ShowIP
+==================
+*/
+void Sys_ShowIP(void) {
+ int i;
+
+ for (i = 0; i < numIP; i++) {
+ Com_Printf( "IP: %i.%i.%i.%i\n", localIP[i][0], localIP[i][1], localIP[i][2], localIP[i][3] );
+ }
+}
+
+
+//=============================================================================
+
+
+/*
+====================
+NET_IPSocket
+====================
+*/
+int NET_IPSocket( char *net_interface, int port ) {
+ SOCKET newsocket;
+ struct sockaddr_in address;
+ qboolean _true = qtrue;
+ int i = 1;
+ int err;
+
+ if( net_interface ) {
+ Com_Printf( "Opening IP socket: %s:%i\n", net_interface, port );
+ }
+ else {
+ Com_Printf( "Opening IP socket: localhost:%i\n", port );
+ }
+
+ if( ( newsocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == INVALID_SOCKET ) {
+ err = socketError;
+ if( err != EAFNOSUPPORT ) {
+ Com_Printf( "WARNING: UDP_OpenSocket: socket: %s\n", NET_ErrorString() );
+ }
+ return 0;
+ }
+
+ // make it non-blocking
+ if( ioctlsocket( newsocket, FIONBIO, (u_long *)&_true ) == SOCKET_ERROR ) {
+ Com_Printf( "WARNING: UDP_OpenSocket: ioctl FIONBIO: %s\n", NET_ErrorString() );
+ return 0;
+ }
+
+ // make it broadcast capable
+ if( setsockopt( newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i) ) == SOCKET_ERROR ) {
+ Com_Printf( "WARNING: UDP_OpenSocket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString() );
+ return 0;
+ }
+
+ if( !net_interface || !net_interface[0] || !Q_stricmp(net_interface, "localhost") ) {
+ address.sin_addr.s_addr = INADDR_ANY;
+ }
+ else {
+ Sys_StringToSockaddr( net_interface, (struct sockaddr *)&address );
+ }
+
+ if( port == PORT_ANY ) {
+ address.sin_port = 0;
+ }
+ else {
+ address.sin_port = htons( (short)port );
+ }
+
+ address.sin_family = AF_INET;
+
+ if( bind( newsocket, (void *)&address, sizeof(address) ) == SOCKET_ERROR ) {
+ Com_Printf( "WARNING: UDP_OpenSocket: bind: %s\n", NET_ErrorString() );
+ closesocket( newsocket );
+ return 0;
+ }
+
+ return newsocket;
+}
+
+
+/*
+====================
+NET_OpenSocks
+====================
+*/
+void NET_OpenSocks( int port ) {
+ struct sockaddr_in address;
+ int err;
+ struct hostent *h;
+ int len;
+ qboolean rfc1929;
+ unsigned char buf[64];
+
+ usingSocks = qfalse;
+
+ Com_Printf( "Opening connection to SOCKS server.\n" );
+
+ if ( ( socks_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ) == INVALID_SOCKET ) {
+ err = socketError;
+ Com_Printf( "WARNING: NET_OpenSocks: socket: %s\n", NET_ErrorString() );
+ return;
+ }
+
+ h = gethostbyname( net_socksServer->string );
+ if ( h == NULL ) {
+ err = socketError;
+ Com_Printf( "WARNING: NET_OpenSocks: gethostbyname: %s\n", NET_ErrorString() );
+ return;
+ }
+ if ( h->h_addrtype != AF_INET ) {
+ Com_Printf( "WARNING: NET_OpenSocks: gethostbyname: address type was not AF_INET\n" );
+ return;
+ }
+ address.sin_family = AF_INET;
+ address.sin_addr.s_addr = *(int *)h->h_addr_list[0];
+ address.sin_port = htons( (short)net_socksPort->integer );
+
+ if ( connect( socks_socket, (struct sockaddr *)&address, sizeof( address ) ) == SOCKET_ERROR ) {
+ err = socketError;
+ Com_Printf( "NET_OpenSocks: connect: %s\n", NET_ErrorString() );
+ return;
+ }
+
+ // send socks authentication handshake
+ if ( *net_socksUsername->string || *net_socksPassword->string ) {
+ rfc1929 = qtrue;
+ }
+ else {
+ rfc1929 = qfalse;
+ }
+
+ buf[0] = 5; // SOCKS version
+ // method count
+ if ( rfc1929 ) {
+ buf[1] = 2;
+ len = 4;
+ }
+ else {
+ buf[1] = 1;
+ len = 3;
+ }
+ buf[2] = 0; // method #1 - method id #00: no authentication
+ if ( rfc1929 ) {
+ buf[2] = 2; // method #2 - method id #02: username/password
+ }
+ if ( send( socks_socket, buf, len, 0 ) == SOCKET_ERROR ) {
+ err = socketError;
+ Com_Printf( "NET_OpenSocks: send: %s\n", NET_ErrorString() );
+ return;
+ }
+
+ // get the response
+ len = recv( socks_socket, buf, 64, 0 );
+ if ( len == SOCKET_ERROR ) {
+ err = socketError;
+ Com_Printf( "NET_OpenSocks: recv: %s\n", NET_ErrorString() );
+ return;
+ }
+ if ( len != 2 || buf[0] != 5 ) {
+ Com_Printf( "NET_OpenSocks: bad response\n" );
+ return;
+ }
+ switch( buf[1] ) {
+ case 0: // no authentication
+ break;
+ case 2: // username/password authentication
+ break;
+ default:
+ Com_Printf( "NET_OpenSocks: request denied\n" );
+ return;
+ }
+
+ // do username/password authentication if needed
+ if ( buf[1] == 2 ) {
+ int ulen;
+ int plen;
+
+ // build the request
+ ulen = strlen( net_socksUsername->string );
+ plen = strlen( net_socksPassword->string );
+
+ buf[0] = 1; // username/password authentication version
+ buf[1] = ulen;
+ if ( ulen ) {
+ memcpy( &buf[2], net_socksUsername->string, ulen );
+ }
+ buf[2 + ulen] = plen;
+ if ( plen ) {
+ memcpy( &buf[3 + ulen], net_socksPassword->string, plen );
+ }
+
+ // send it
+ if ( send( socks_socket, buf, 3 + ulen + plen, 0 ) == SOCKET_ERROR ) {
+ err = socketError;
+ Com_Printf( "NET_OpenSocks: send: %s\n", NET_ErrorString() );
+ return;
+ }
+
+ // get the response
+ len = recv( socks_socket, buf, 64, 0 );
+ if ( len == SOCKET_ERROR ) {
+ err = socketError;
+ Com_Printf( "NET_OpenSocks: recv: %s\n", NET_ErrorString() );
+ return;
+ }
+ if ( len != 2 || buf[0] != 1 ) {
+ Com_Printf( "NET_OpenSocks: bad response\n" );
+ return;
+ }
+ if ( buf[1] != 0 ) {
+ Com_Printf( "NET_OpenSocks: authentication failed\n" );
+ return;
+ }
+ }
+
+ // send the UDP associate request
+ buf[0] = 5; // SOCKS version
+ buf[1] = 3; // command: UDP associate
+ buf[2] = 0; // reserved
+ buf[3] = 1; // address type: IPV4
+ *(int *)&buf[4] = INADDR_ANY;
+ *(short *)&buf[8] = htons( (short)port ); // port
+ if ( send( socks_socket, buf, 10, 0 ) == SOCKET_ERROR ) {
+ err = socketError;
+ Com_Printf( "NET_OpenSocks: send: %s\n", NET_ErrorString() );
+ return;
+ }
+
+ // get the response
+ len = recv( socks_socket, buf, 64, 0 );
+ if( len == SOCKET_ERROR ) {
+ err = socketError;
+ Com_Printf( "NET_OpenSocks: recv: %s\n", NET_ErrorString() );
+ return;
+ }
+ if( len < 2 || buf[0] != 5 ) {
+ Com_Printf( "NET_OpenSocks: bad response\n" );
+ return;
+ }
+ // check completion code
+ if( buf[1] != 0 ) {
+ Com_Printf( "NET_OpenSocks: request denied: %i\n", buf[1] );
+ return;
+ }
+ if( buf[3] != 1 ) {
+ Com_Printf( "NET_OpenSocks: relay address is not IPV4: %i\n", buf[3] );
+ return;
+ }
+ ((struct sockaddr_in *)&socksRelayAddr)->sin_family = AF_INET;
+ ((struct sockaddr_in *)&socksRelayAddr)->sin_addr.s_addr = *(int *)&buf[4];
+ ((struct sockaddr_in *)&socksRelayAddr)->sin_port = *(short *)&buf[8];
+ memset( ((struct sockaddr_in *)&socksRelayAddr)->sin_zero, 0, 8 );
+
+ usingSocks = qtrue;
+}
+
+
+/*
+=====================
+NET_GetLocalAddress
+=====================
+*/
+#ifdef MACOS_X
+// Don't do a forward mapping from the hostname of the machine to the IP.
+// The reason is that we might have obtained an IP address from DHCP and
+// there might not be any name registered for the machine. On Mac OS X,
+// the machine name defaults to 'localhost' and NetInfo has 127.0.0.1
+// listed for this name. Instead, we want to get a list of all the IP
+// network interfaces on the machine. This code adapted from
+// OmniNetworking.
+
+#ifdef _SIZEOF_ADDR_IFREQ
+ // tjw: OSX 10.4 does not have sa_len
+ #define IFR_NEXT(ifr) \
+ ((struct ifreq *) ((char *) ifr + _SIZEOF_ADDR_IFREQ(*ifr)))
+#else
+ // tjw: assume that once upon a time some version did have sa_len
+ #define IFR_NEXT(ifr) \
+ ((struct ifreq *) ((char *) (ifr) + sizeof(*(ifr)) + \
+ MAX(0, (int) (ifr)->ifr_addr.sa_len - (int) sizeof((ifr)->ifr_addr))))
+#endif
+
+void NET_GetLocalAddress( void ) {
+ struct ifreq requestBuffer[MAX_IPS], *linkInterface, *inetInterface;
+ struct ifconf ifc;
+ struct ifreq ifr;
+ struct sockaddr_dl *sdl;
+ int interfaceSocket;
+ int family;
+
+ // Set this early so we can just return if there is an error
+ numIP = 0;
+
+ ifc.ifc_len = sizeof(requestBuffer);
+ ifc.ifc_buf = (caddr_t)requestBuffer;
+
+ // Since we get at this info via an ioctl, we need a temporary little socket.
+ // This will only get AF_INET interfaces, but we probably don't care about
+ // anything else. If we do end up caring later, we should add a
+ // ONAddressFamily and at a -interfaces method to it.
+ family = AF_INET;
+ if ((interfaceSocket = socket(family, SOCK_DGRAM, 0)) < 0) {
+ Com_Printf("NET_GetLocalAddress: Unable to create temporary socket, errno = %d\n", errno);
+ return;
+ }
+
+ if (ioctl(interfaceSocket, SIOCGIFCONF, &ifc) != 0) {
+ Com_Printf("NET_GetLocalAddress: Unable to get list of network interfaces, errno = %d\n", errno);
+ return;
+ }
+
+ linkInterface = (struct ifreq *) ifc.ifc_buf;
+ while ((char *) linkInterface < &ifc.ifc_buf[ifc.ifc_len]) {
+ unsigned int nameLength;
+
+ // The ioctl returns both the entries having the address (AF_INET)
+ // and the link layer entries (AF_LINK). The AF_LINK entry has the
+ // link layer address which contains the interface type. This is the
+ // only way I can see to get this information. We cannot assume that
+ // we will get bot an AF_LINK and AF_INET entry since the interface
+ // may not be configured. For example, if you have a 10Mb port on
+ // the motherboard and a 100Mb card, you may not configure the
+ // motherboard port.
+
+ // For each AF_LINK entry...
+ if (linkInterface->ifr_addr.sa_family == AF_LINK) {
+ // if there is a matching AF_INET entry
+ inetInterface = (struct ifreq *) ifc.ifc_buf;
+ while ((char *) inetInterface < &ifc.ifc_buf[ifc.ifc_len]) {
+ if (inetInterface->ifr_addr.sa_family == AF_INET &&
+ !strncmp(inetInterface->ifr_name, linkInterface->ifr_name,
+ sizeof(linkInterface->ifr_name))) {
+
+ for (nameLength = 0; nameLength < IFNAMSIZ; nameLength++)
+ if (!linkInterface->ifr_name[nameLength])
+ break;
+
+ sdl = (struct sockaddr_dl *)&linkInterface->ifr_addr;
+ // Skip loopback interfaces
+ if (sdl->sdl_type != IFT_LOOP) {
+ // Get the local interface address
+ strncpy(ifr.ifr_name, inetInterface->ifr_name, sizeof(ifr.ifr_name));
+ if (ioctl(interfaceSocket, OSIOCGIFADDR, (caddr_t)&ifr) < 0) {
+ Com_Printf("NET_GetLocalAddress: Unable to get local address "
+ "for interface '%s', errno = %d\n", inetInterface->ifr_name, errno);
+ } else {
+ struct sockaddr_in *sin;
+ int ip;
+
+ sin = (struct sockaddr_in *)&ifr.ifr_addr;
+
+ ip = ntohl(sin->sin_addr.s_addr);
+ localIP[ numIP ][0] = (ip >> 24) & 0xff;
+ localIP[ numIP ][1] = (ip >> 16) & 0xff;
+ localIP[ numIP ][2] = (ip >> 8) & 0xff;
+ localIP[ numIP ][3] = (ip >> 0) & 0xff;
+ Com_Printf( "IP: %i.%i.%i.%i (%s)\n",
+ localIP[ numIP ][0], localIP[ numIP ][1],
+ localIP[ numIP ][2], localIP[ numIP ][3],
+ inetInterface->ifr_name);
+ numIP++;
+ }
+ }
+
+ // We will assume that there is only one AF_INET entry per AF_LINK entry.
+ // What happens when we have an interface that has multiple IP addresses, or
+ // can that even happen?
+ // break;
+ }
+ inetInterface = IFR_NEXT(inetInterface);
+ }
+ }
+ linkInterface = IFR_NEXT(linkInterface);
+ }
+
+ close(interfaceSocket);
+}
+#else
+void NET_GetLocalAddress( void ) {
+ char hostname[256];
+ struct hostent *hostInfo;
+ int error;
+ char *p;
+ int ip;
+ int n;
+
+ if( gethostname( hostname, 256 ) == SOCKET_ERROR ) {
+ error = socketError;
+ return;
+ }
+
+ hostInfo = gethostbyname( hostname );
+ if( !hostInfo ) {
+ error = socketError;
+ return;
+ }
+
+ Com_Printf( "Hostname: %s\n", hostInfo->h_name );
+ n = 0;
+ while( ( p = hostInfo->h_aliases[n++] ) != NULL ) {
+ Com_Printf( "Alias: %s\n", p );
+ }
+
+ if ( hostInfo->h_addrtype != AF_INET ) {
+ return;
+ }
+
+ numIP = 0;
+ while( ( p = hostInfo->h_addr_list[numIP] ) != NULL && numIP < MAX_IPS ) {
+ ip = ntohl( *(int *)p );
+ localIP[ numIP ][0] = p[0];
+ localIP[ numIP ][1] = p[1];
+ localIP[ numIP ][2] = p[2];
+ localIP[ numIP ][3] = p[3];
+ Com_Printf( "IP: %i.%i.%i.%i\n", ( ip >> 24 ) & 0xff, ( ip >> 16 ) & 0xff, ( ip >> 8 ) & 0xff, ip & 0xff );
+ numIP++;
+ }
+}
+#endif
+
+/*
+====================
+NET_OpenIP
+====================
+*/
+void NET_OpenIP( void ) {
+ cvar_t *ip;
+ int port;
+ int i;
+
+ ip = Cvar_Get( "net_ip", "localhost", CVAR_LATCH );
+ port = Cvar_Get( "net_port", va( "%i", PORT_SERVER ), CVAR_LATCH )->integer;
+
+ // automatically scan for a valid port, so multiple
+ // dedicated servers can be started without requiring
+ // a different net_port for each one
+ for( i = 0 ; i < 10 ; i++ ) {
+ ip_socket = NET_IPSocket( ip->string, port + i );
+ if ( ip_socket ) {
+ Cvar_SetValue( "net_port", port + i );
+ if ( net_socksEnabled->integer ) {
+ NET_OpenSocks( port + i );
+ }
+ NET_GetLocalAddress();
+ return;
+ }
+ }
+ Com_Printf( "WARNING: Couldn't allocate IP port\n");
+}
+
+
+//===================================================================
+
+
+/*
+====================
+NET_GetCvars
+====================
+*/
+static qboolean NET_GetCvars( void ) {
+ qboolean modified;
+
+ modified = qfalse;
+
+ if( net_noudp && net_noudp->modified ) {
+ modified = qtrue;
+ }
+ net_noudp = Cvar_Get( "net_noudp", "0", CVAR_LATCH | CVAR_ARCHIVE );
+
+
+ if( net_socksEnabled && net_socksEnabled->modified ) {
+ modified = qtrue;
+ }
+ net_socksEnabled = Cvar_Get( "net_socksEnabled", "0", CVAR_LATCH | CVAR_ARCHIVE );
+
+ if( net_socksServer && net_socksServer->modified ) {
+ modified = qtrue;
+ }
+ net_socksServer = Cvar_Get( "net_socksServer", "", CVAR_LATCH | CVAR_ARCHIVE );
+
+ if( net_socksPort && net_socksPort->modified ) {
+ modified = qtrue;
+ }
+ net_socksPort = Cvar_Get( "net_socksPort", "1080", CVAR_LATCH | CVAR_ARCHIVE );
+
+ if( net_socksUsername && net_socksUsername->modified ) {
+ modified = qtrue;
+ }
+ net_socksUsername = Cvar_Get( "net_socksUsername", "", CVAR_LATCH | CVAR_ARCHIVE );
+
+ if( net_socksPassword && net_socksPassword->modified ) {
+ modified = qtrue;
+ }
+ net_socksPassword = Cvar_Get( "net_socksPassword", "", CVAR_LATCH | CVAR_ARCHIVE );
+
+
+ return modified;
+}
+
+
+/*
+====================
+NET_Config
+====================
+*/
+void NET_Config( qboolean enableNetworking ) {
+ qboolean modified;
+ qboolean stop;
+ qboolean start;
+
+ // get any latched changes to cvars
+ modified = NET_GetCvars();
+
+ if( net_noudp->integer ) {
+ enableNetworking = qfalse;
+ }
+
+ // if enable state is the same and no cvars were modified, we have nothing to do
+ if( enableNetworking == networkingEnabled && !modified ) {
+ return;
+ }
+
+ if( enableNetworking == networkingEnabled ) {
+ if( enableNetworking ) {
+ stop = qtrue;
+ start = qtrue;
+ }
+ else {
+ stop = qfalse;
+ start = qfalse;
+ }
+ }
+ else {
+ if( enableNetworking ) {
+ stop = qfalse;
+ start = qtrue;
+ }
+ else {
+ stop = qtrue;
+ start = qfalse;
+ }
+ networkingEnabled = enableNetworking;
+ }
+
+ if( stop ) {
+ if ( ip_socket && ip_socket != INVALID_SOCKET ) {
+ closesocket( ip_socket );
+ ip_socket = 0;
+ }
+
+ if ( socks_socket && socks_socket != INVALID_SOCKET ) {
+ closesocket( socks_socket );
+ socks_socket = 0;
+ }
+ }
+
+ if( start ) {
+ if (! net_noudp->integer ) {
+ NET_OpenIP();
+ }
+ }
+}
+
+
+/*
+====================
+NET_Init
+====================
+*/
+void NET_Init( void ) {
+#ifdef _WIN32
+ int r;
+
+ r = WSAStartup( MAKEWORD( 1, 1 ), &winsockdata );
+ if( r ) {
+ Com_Printf( "WARNING: Winsock initialization failed, returned %d\n", r );
+ return;
+ }
+
+ winsockInitialized = qtrue;
+ Com_Printf( "Winsock Initialized\n" );
+#endif
+
+ // this is really just to get the cvars registered
+ NET_GetCvars();
+
+ NET_Config( qtrue );
+}
+
+
+/*
+====================
+NET_Shutdown
+====================
+*/
+void NET_Shutdown( void ) {
+ if ( !networkingEnabled ) {
+ return;
+ }
+
+ NET_Config( qfalse );
+
+#ifdef _WIN32
+ WSACleanup();
+ winsockInitialized = qfalse;
+#endif
+}
+
+
+/*
+====================
+NET_Sleep
+
+Sleeps msec or until something happens on the network or stdin
+====================
+*/
+void NET_Sleep( int msec ) {
+ struct timeval timeout;
+ fd_set fdset;
+ int highestfd = 0;
+
+ if (!com_dedicated->integer)
+ return; // we're not a server, just run full speed
+
+ FD_ZERO(&fdset);
+
+ FD_SET(fileno(stdin), &fdset);
+ highestfd = fileno(stdin) + 1;
+
+ if(ip_socket)
+ {
+ FD_SET(ip_socket, &fdset); // network socket
+ if(ip_socket >= highestfd)
+ highestfd = ip_socket + 1;
+ }
+
+ if(highestfd)
+ {
+ if(msec >= 0)
+ {
+ timeout.tv_sec = msec/1000;
+ timeout.tv_usec = (msec%1000)*1000;
+ select(highestfd, &fdset, NULL, NULL, &timeout);
+ }
+ else
+ {
+ // Block indefinitely
+ select(highestfd, &fdset, NULL, NULL, NULL);
+ }
+ }
+}
+
+
+/*
+====================
+NET_Restart_f
+====================
+*/
+void NET_Restart( void ) {
+ NET_Config( networkingEnabled );
+}
diff --git a/src/qcommon/q_math.c b/src/qcommon/q_math.c
index 0973f31c..e987b6b5 100644
--- a/src/qcommon/q_math.c
+++ b/src/qcommon/q_math.c
@@ -496,7 +496,7 @@ void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal )
inv_denom = 1.0f / DotProduct( normal, normal );
#ifndef Q3_VM
- assert( Q_fabs(inv_denom) != 0.0f ); // bk010122 - zero vectors get here
+ assert( Q_fabs(inv_denom) != 0.0f ); // zero vectors get here
#endif
inv_denom = 1.0f / inv_denom;
@@ -564,7 +564,6 @@ float Q_rsqrt( float number )
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
// y = y * ( threehalfs - ( x2 * y * y ) ); // 2nd iteration, this can be removed
- //assert( !isnan(y) ); // bk010122 - FPE?
return y;
}
@@ -1159,17 +1158,11 @@ vec_t VectorNormalize2( const vec3_t v, vec3_t out) {
if (length)
{
-#ifndef Q3_VM // bk0101022 - FPE related
-// assert( ((Q_fabs(v[0])!=0.0f) || (Q_fabs(v[1])!=0.0f) || (Q_fabs(v[2])!=0.0f)) );
-#endif
ilength = 1/length;
out[0] = v[0]*ilength;
out[1] = v[1]*ilength;
out[2] = v[2]*ilength;
} else {
-#ifndef Q3_VM // bk0101022 - FPE related
-// assert( ((Q_fabs(v[0])==0.0f) && (Q_fabs(v[1])==0.0f) && (Q_fabs(v[2])==0.0f)) );
-#endif
VectorClear( out );
}
diff --git a/src/qcommon/q_platform.h b/src/qcommon/q_platform.h
index ad9a9382..361526dc 100644
--- a/src/qcommon/q_platform.h
+++ b/src/qcommon/q_platform.h
@@ -169,7 +169,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//=============================================================== FreeBSD ===
-#ifdef __FreeBSD__ // rb010123
+#ifdef __FreeBSD__
#include <machine/endian.h>
diff --git a/src/qcommon/q_shared.c b/src/qcommon/q_shared.c
index aa8d55d5..bb70444f 100644
--- a/src/qcommon/q_shared.c
+++ b/src/qcommon/q_shared.c
@@ -56,6 +56,28 @@ char *COM_SkipPath (char *pathname)
/*
============
+COM_GetExtension
+============
+*/
+const char *COM_GetExtension( const char *name ) {
+ int length, i;
+
+ length = strlen(name)-1;
+ i = length;
+
+ while (name[i] != '.')
+ {
+ i--;
+ if (name[i] == '/' || i == 0)
+ return ""; // no extension
+ }
+
+ return &name[i+1];
+}
+
+
+/*
+============
COM_StripExtension
============
*/
@@ -713,7 +735,6 @@ Safe strncpy that ensures a trailing zero
=============
*/
void Q_strncpyz( char *dest, const char *src, int destsize ) {
- // bk001129 - also NULL dest
if ( !dest ) {
Com_Error( ERR_FATAL, "Q_strncpyz: NULL dest" );
}
@@ -731,7 +752,6 @@ void Q_strncpyz( char *dest, const char *src, int destsize ) {
int Q_stricmpn (const char *s1, const char *s2, int n) {
int c1, c2;
- // bk001129 - moved in 1.17 fix not in id codebase
if ( s1 == NULL ) {
if ( s2 == NULL )
return 0;
@@ -825,6 +845,38 @@ void Q_strcat( char *dest, int size, const char *src ) {
Q_strncpyz( dest + l1, src, size - l1 );
}
+/*
+* Find the first occurrence of find in s.
+*/
+const char *Q_stristr( const char *s, const char *find)
+{
+ char c, sc;
+ size_t len;
+
+ if ((c = *find++) != 0)
+ {
+ if (c >= 'a' && c <= 'z')
+ {
+ c -= ('a' - 'A');
+ }
+ len = strlen(find);
+ do
+ {
+ do
+ {
+ if ((sc = *s++) == 0)
+ return NULL;
+ if (sc >= 'a' && sc <= 'z')
+ {
+ sc -= ('a' - 'A');
+ }
+ } while (sc != c);
+ } while (Q_stricmpn(s, find, len) != 0);
+ s--;
+ }
+ return s;
+}
+
int Q_PrintStrlen( const char *string ) {
int len;
diff --git a/src/qcommon/q_shared.h b/src/qcommon/q_shared.h
index 2e3a153c..7a6644ec 100644
--- a/src/qcommon/q_shared.h
+++ b/src/qcommon/q_shared.h
@@ -27,15 +27,16 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// q_shared.h -- included first by ALL program modules.
// A user mod should never modify this file
-#define VERSION_NUMBER "1.1.0"
-#define Q3_VERSION "tremulous " VERSION_NUMBER
-#ifndef SVN_VERSION
-#define SVN_VERSION Q3_VERSION
+#define VERSION_NUMBER "1.1.0"
+#define Q3_VERSION_BASE "tremulous " VERSION_NUMBER
+#ifdef SVN_VERSION
+# define Q3_VERSION Q3_VERSION_BASE "_SVN" SVN_VERSION
+#else
+# define Q3_VERSION Q3_VERSION_BASE
#endif
-#define CLIENT_WINDOW_TITLE "Tremulous " VERSION_NUMBER
-#define CLIENT_WINDOW_ICON "Tremulous"
-#define CONSOLE_WINDOW_TITLE "Tremulous " VERSION_NUMBER " console"
-#define CONSOLE_WINDOW_ICON "Tremulous console"
+
+#define CLIENT_WINDOW_TITLE "Tremulous " VERSION_NUMBER
+#define CLIENT_WINDOW_MIN_TITLE "Tremulous"
#define MAX_TEAMNAME 32
@@ -262,14 +263,6 @@ void *Hunk_AllocDebug( int size, ha_pref preference, char *label, char *file, in
void *Hunk_Alloc( int size, ha_pref preference );
#endif
-#if defined(__GNUC__) && !defined(__MINGW32__) && !defined(MACOS_X)
-// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=371
-// custom Snd_Memset implementation for glibc memset bug workaround
-void Snd_Memset (void* dest, const int val, const size_t count);
-#else
-#define Snd_Memset Com_Memset
-#endif
-
#define Com_Memset memset
#define Com_Memcpy memcpy
@@ -656,6 +649,7 @@ vec_t DistanceBetweenLineSegments(
float Com_Clamp( float min, float max, float value );
char *COM_SkipPath( char *pathname );
+const char *COM_GetExtension( const char *name );
void COM_StripExtension(const char *in, char *out, int destsize);
void COM_DefaultExtension( char *path, int maxSize, const char *extension );
@@ -734,6 +728,7 @@ int Q_stricmpn (const char *s1, const char *s2, int n);
char *Q_strlwr( char *s1 );
char *Q_strupr( char *s1 );
char *Q_strrchr( const char* string, int c );
+const char *Q_stristr( const char *s, const char *find);
// buffer size safe library replacements
void Q_strncpyz( char *dest, const char *src, int destsize );
diff --git a/src/qcommon/qcommon.h b/src/qcommon/qcommon.h
index 630d4da9..e59490b7 100644
--- a/src/qcommon/qcommon.h
+++ b/src/qcommon/qcommon.h
@@ -134,9 +134,7 @@ typedef enum {
NA_BAD, // an address lookup failed
NA_LOOPBACK,
NA_BROADCAST,
- NA_IP,
- NA_IPX,
- NA_BROADCAST_IPX
+ NA_IP
} netadrtype_t;
typedef enum {
@@ -148,7 +146,6 @@ typedef struct {
netadrtype_t type;
byte ip[4];
- byte ipx[10];
unsigned short port;
} netadr_t;
@@ -684,31 +681,53 @@ MISC
==============================================================
*/
-// TTimo
// vsnprintf is ISO/IEC 9899:1999
// abstracting this to make it portable
#ifdef WIN32
#define Q_vsnprintf _vsnprintf
#else
-// TODO: do we need Mac define?
#define Q_vsnprintf vsnprintf
#endif
-// returnbed by Sys_GetProcessorId
-#define CPUID_GENERIC 0 // any unrecognized processor
+// returned by Sys_GetProcessorFeatures
+typedef enum
+{
+ CF_RDTSC = 1 << 0,
+ CF_MMX = 1 << 1,
+ CF_MMX_EXT = 1 << 2,
+ CF_3DNOW = 1 << 3,
+ CF_3DNOW_EXT = 1 << 4,
+ CF_SSE = 1 << 5,
+ CF_SSE2 = 1 << 6,
+ CF_ALTIVEC = 1 << 7
+} cpuFeatures_t;
-#define CPUID_AXP 0x10
+// centralized and cleaned, that's the max string you can send to a Com_Printf / Com_DPrintf (above gets truncated)
+#define MAXPRINTMSG 4096
-#define CPUID_INTEL_UNSUPPORTED 0x20 // Intel 386/486
-#define CPUID_INTEL_PENTIUM 0x21 // Intel Pentium or PPro
-#define CPUID_INTEL_MMX 0x22 // Intel Pentium/MMX or P2/MMX
-#define CPUID_INTEL_KATMAI 0x23 // Intel Katmai
-#define CPUID_AMD_3DNOW 0x30 // AMD K6 3DNOW!
+typedef enum {
+ // SE_NONE must be zero
+ SE_NONE = 0, // evTime is still valid
+ SE_KEY, // evValue is a key code, evValue2 is the down flag
+ SE_CHAR, // evValue is an ascii char
+ SE_MOUSE, // evValue and evValue2 are reletive signed x / y moves
+ SE_JOYSTICK_AXIS, // evValue is an axis number and evValue2 is the current state (-127 to 127)
+ SE_CONSOLE, // evPtr is a char*
+ SE_PACKET // evPtr is a netadr_t followed by data bytes to evPtrLength
+} sysEventType_t;
+
+typedef struct {
+ int evTime;
+ sysEventType_t evType;
+ int evValue, evValue2;
+ int evPtrLength; // bytes of data pointed to by evPtr, for journaling
+ void *evPtr; // this must be manually freed if not NULL
+} sysEvent_t;
-// TTimo
-// centralized and cleaned, that's the max string you can send to a Com_Printf / Com_DPrintf (above gets truncated)
-#define MAXPRINTMSG 4096
+void Com_QueueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr );
+int Com_EventLoop( void );
+sysEvent_t Com_GetSystemEvent( void );
char *CopyString( const char *in );
void Info_Print( const char *s );
@@ -719,7 +738,7 @@ void QDECL Com_Printf( const char *fmt, ... ) __attribute__ ((format (printf,
void QDECL Com_DPrintf( const char *fmt, ... ) __attribute__ ((format (printf, 1, 2)));
void QDECL Com_Error( int code, const char *fmt, ... ) __attribute__ ((format (printf, 2, 3)));
void Com_Quit_f( void );
-int Com_EventLoop( void );
+
int Com_Milliseconds( void ); // will be journaled properly
unsigned Com_BlockChecksum( const void *buffer, int length );
char *Com_MD5File(const char *filename, int length, const char *prefix, int prefix_len);
@@ -741,12 +760,14 @@ extern cvar_t *com_speeds;
extern cvar_t *com_timescale;
extern cvar_t *com_sv_running;
extern cvar_t *com_cl_running;
-extern cvar_t *com_viewlog; // 0 = hidden, 1 = visible, 2 = minimized
extern cvar_t *com_version;
extern cvar_t *com_blood;
extern cvar_t *com_buildScript; // for building release pak files
extern cvar_t *com_journal;
extern cvar_t *com_cameraMode;
+extern cvar_t *com_ansiColor;
+extern cvar_t *com_unfocused;
+extern cvar_t *com_minimized;
extern cvar_t *com_altivec;
// both client and server must agree to pause
@@ -890,7 +911,7 @@ void CL_ShutdownAll( void );
void CL_FlushMemory( void );
// dump all memory on an error
-void CL_StartHunkUsers( void );
+void CL_StartHunkUsers( qboolean rendererOnly );
// start all the client stuff using the hunk
void Key_WriteBindings( fileHandle_t f );
@@ -934,31 +955,9 @@ typedef enum {
MAX_JOYSTICK_AXIS
} joystickAxis_t;
-typedef enum {
- // bk001129 - make sure SE_NONE is zero
- SE_NONE = 0, // evTime is still valid
- SE_KEY, // evValue is a key code, evValue2 is the down flag
- SE_CHAR, // evValue is an ascii char
- SE_MOUSE, // evValue and evValue2 are reletive signed x / y moves
- SE_JOYSTICK_AXIS, // evValue is an axis number and evValue2 is the current state (-127 to 127)
- SE_CONSOLE, // evPtr is a char*
- SE_PACKET // evPtr is a netadr_t followed by data bytes to evPtrLength
-} sysEventType_t;
-
-typedef struct {
- int evTime;
- sysEventType_t evType;
- int evValue, evValue2;
- int evPtrLength; // bytes of data pointed to by evPtr, for journaling
- void *evPtr; // this must be manually freed if not NULL
-} sysEvent_t;
-
-sysEvent_t Sys_GetEvent( void );
-
void Sys_Init (void);
// general development dll loading for virtual machine testing
-// fqpath param added 7/20/02 by T.Ray - Sys_LoadDll is only called in vm.c at this time
void * QDECL Sys_LoadDll( const char *name, char *fqpath , intptr_t (QDECL **entryPoint)(int, ...),
intptr_t (QDECL *systemcalls)(intptr_t, ...) );
void Sys_UnloadDll( void *dllHandle );
@@ -995,17 +994,12 @@ qboolean Sys_RandomBytes( byte *string, int len );
// the system console is shown when a dedicated server is running
void Sys_DisplaySystemConsole( qboolean show );
-int Sys_GetProcessorId( void );
-
-void Sys_BeginStreamedFile( fileHandle_t f, int readahead );
-void Sys_EndStreamedFile( fileHandle_t f );
-int Sys_StreamedRead( void *buffer, int size, int count, fileHandle_t f );
-void Sys_StreamSeek( fileHandle_t f, int offset, int origin );
+cpuFeatures_t Sys_GetProcessorFeatures( void );
-void Sys_ShowConsole( int level, qboolean quitOnClose );
void Sys_SetErrorText( const char *text );
void Sys_SendPacket( int length, const void *data, netadr_t to );
+qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message );
qboolean Sys_StringToAdr( const char *s, netadr_t *a );
//Does NOT parse port numbers, only base addresses.
@@ -1013,29 +1007,20 @@ qboolean Sys_StringToAdr( const char *s, netadr_t *a );
qboolean Sys_IsLANAddress (netadr_t adr);
void Sys_ShowIP(void);
-qboolean Sys_CheckCD( void );
-
void Sys_Mkdir( const char *path );
char *Sys_Cwd( void );
-void Sys_SetDefaultCDPath(const char *path);
-char *Sys_DefaultCDPath(void);
void Sys_SetDefaultInstallPath(const char *path);
char *Sys_DefaultInstallPath(void);
void Sys_SetDefaultHomePath(const char *path);
char *Sys_DefaultHomePath(void);
+const char *Sys_Dirname( char *path );
+const char *Sys_Basename( char *path );
+char *Sys_ConsoleInput(void);
char **Sys_ListFiles( const char *directory, const char *extension, char *filter, int *numfiles, qboolean wantsubs );
void Sys_FreeFileList( char **list );
-void Sys_BeginProfiling( void );
-void Sys_EndProfiling( void );
-
qboolean Sys_LowPhysicalMemory( void );
-unsigned int Sys_ProcessorCount( void );
-
-int Sys_MonkeyShouldBeSpanked( void );
-
-qboolean Sys_DetectAltivec( void );
/* This is based on the Adaptive Huffman algorithm described in Sayood's Data
* Compression book. The ranks are not actually stored, but implicitly defined
diff --git a/src/qcommon/vm.c b/src/qcommon/vm.c
index 0017b417..c9cac7a4 100644
--- a/src/qcommon/vm.c
+++ b/src/qcommon/vm.c
@@ -37,8 +37,8 @@ and one exported function: Perform
#include "vm_local.h"
-vm_t *currentVM = NULL; // bk001212
-vm_t *lastVM = NULL; // bk001212
+vm_t *currentVM = NULL;
+vm_t *lastVM = NULL;
int vm_debugLevel;
#define MAX_VM 3
@@ -544,13 +544,6 @@ vm_t *VM_Create( const char *module, intptr_t (*systemCalls)(intptr_t *),
Q_strncpyz( vm->name, module, sizeof( vm->name ) );
vm->systemCall = systemCalls;
- // never allow dll loading with a demo
- if ( interpret == VMI_NATIVE ) {
- if ( Cvar_VariableValue( "fs_restrict" ) ) {
- interpret = VMI_COMPILED;
- }
- }
-
if ( interpret == VMI_NATIVE ) {
// try to load as a system dll
Com_Printf( "Loading dll file %s.\n", vm->name );
@@ -656,7 +649,7 @@ void *VM_ArgPtr( intptr_t intValue ) {
if ( !intValue ) {
return NULL;
}
- // bk001220 - currentVM is missing on reconnect
+ // currentVM is missing on reconnect
if ( currentVM==NULL )
return NULL;
@@ -673,7 +666,7 @@ void *VM_ExplicitArgPtr( vm_t *vm, intptr_t intValue ) {
return NULL;
}
- // bk010124 - currentVM is missing on reconnect here as well?
+ // currentVM is missing on reconnect here as well?
if ( currentVM==NULL )
return NULL;
@@ -774,7 +767,7 @@ intptr_t QDECL VM_Call( vm_t *vm, int callnum, ... ) {
#endif
}
- if ( oldVM != NULL ) // bk001220 - assert(currentVM!=NULL) for oldVM==NULL
+ if ( oldVM != NULL )
currentVM = oldVM;
return r;
}
diff --git a/src/qcommon/vm_interpreted.c b/src/qcommon/vm_interpreted.c
index 35096e5b..428d56f2 100644
--- a/src/qcommon/vm_interpreted.c
+++ b/src/qcommon/vm_interpreted.c
@@ -23,7 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "vm_local.h"
//#define DEBUG_VM
-#ifdef DEBUG_VM // bk001204
+#ifdef DEBUG_VM
static char *opnames[256] = {
"OP_UNDEF",
diff --git a/src/qcommon/vm_local.h b/src/qcommon/vm_local.h
index 27b52260..59725a11 100644
--- a/src/qcommon/vm_local.h
+++ b/src/qcommon/vm_local.h
@@ -161,7 +161,6 @@ struct vm_s {
int breakFunction; // increment breakCount on function entry to this
int breakCount;
-// fqpath member added 7/20/02 by T.Ray
char fqpath[MAX_QPATH+1] ;
byte *jumpTableTargets;
diff --git a/src/qcommon/vm_x86.c b/src/qcommon/vm_x86.c
index d298b755..5eb49b0b 100644
--- a/src/qcommon/vm_x86.c
+++ b/src/qcommon/vm_x86.c
@@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <windows.h>
#endif
-#ifdef __FreeBSD__ // rb0101023
+#ifdef __FreeBSD__
#include <sys/types.h>
#endif
@@ -78,13 +78,11 @@ static int asmCallPtr = (int)AsmCall;
#else // _MSC_VER
#if defined( FTOL_PTR )
-// bk001213 - BEWARE: does not work! UI menu etc. broken - stack!
-// bk001119 - added: int gftol( float x ) { return (int)x; }
-int qftol( void ); // bk001213 - label, see unix/ftol.nasm
-int qftol027F( void ); // bk001215 - fixed FPU control variants
+int qftol( void );
+int qftol027F( void );
int qftol037F( void );
-int qftol0E7F( void ); // bk010102 - fixed bogus bits (duh)
+int qftol0E7F( void );
int qftol0F7F( void );
@@ -96,7 +94,7 @@ static int asmCallPtr = (int)doAsmCall;
#endif
-static int callMask = 0; // bk001213 - init
+static int callMask = 0;
static int instruction, pass;
static int lastConst = 0;
@@ -1021,7 +1019,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
EmitString( "D9 1F" ); // fstp dword ptr [edi]
break;
case OP_CVFI:
-#ifndef FTOL_PTR // WHENHELLISFROZENOVER // bk001213 - was used in 1.17
+#ifndef FTOL_PTR // WHENHELLISFROZENOVER
// not IEEE complient, but simple and fast
EmitString( "D9 07" ); // fld dword ptr [edi]
EmitString( "DB 1F" ); // fistp dword ptr [edi]
diff --git a/src/qcommon/vm_x86_64.c b/src/qcommon/vm_x86_64.c
index 814acfef..0e56d1fc 100644
--- a/src/qcommon/vm_x86_64.c
+++ b/src/qcommon/vm_x86_64.c
@@ -110,7 +110,7 @@ static long callAsmCall(long callProgramStack, long callSyscallNum)
return ret;
}
-#ifdef DEBUG_VM // bk001204
+#ifdef DEBUG_VM
static char *opnames[256] = {
"OP_UNDEF",