summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2006-05-06 17:18:02 +0000
committerTim Angus <tim@ngus.net>2006-05-06 17:18:02 +0000
commitbb7bd83aaec4504b4fb90919cccaaf4d9a7b418d (patch)
treea99058fef0dbf93af48dab4581b9f785d93e68ff
parentbd9d761dd958aef00218de084bae00eb9bf788a4 (diff)
* Merged ioq3-r775
- SDL_GammaRamp stuff - Anisotropic texture filtering - q3testesque r_flares - cl_guid - Security fixes
-rw-r--r--Makefile6
-rw-r--r--src/botlib/be_interface.c14
-rw-r--r--src/cgame/cg_weapons.c6
-rw-r--r--src/client/cl_main.c31
-rw-r--r--src/client/client.h3
-rw-r--r--src/qcommon/common.c21
-rw-r--r--src/qcommon/files.c17
-rw-r--r--src/qcommon/md4.c43
-rw-r--r--src/qcommon/md5.c299
-rw-r--r--src/qcommon/q_shared.c4
-rw-r--r--src/qcommon/q_shared.h13
-rw-r--r--src/qcommon/qcommon.h1
-rw-r--r--src/qcommon/vm.c2
-rw-r--r--src/renderer/qgl.h18
-rw-r--r--src/renderer/tr_bsp.c2
-rw-r--r--src/renderer/tr_flares.c128
-rw-r--r--src/renderer/tr_image.c7
-rw-r--r--src/renderer/tr_init.c16
-rw-r--r--src/renderer/tr_local.h7
-rw-r--r--src/renderer/tr_shader.c24
-rw-r--r--src/renderer/tr_surface.c67
-rw-r--r--src/renderer/tr_types.h4
-rw-r--r--src/server/sv_ccmds.c31
-rw-r--r--src/server/sv_client.c4
-rw-r--r--src/server/sv_init.c2
-rw-r--r--src/server/sv_main.c2
-rw-r--r--src/tools/asm/Makefile2
-rw-r--r--src/tools/lcc/Makefile2
-rw-r--r--src/ui/ui_main.c2
-rw-r--r--src/unix/linux_glimp.c24
-rw-r--r--src/unix/linux_signals.c1
-rw-r--r--src/unix/sdl_glimp.c64
-rw-r--r--src/win32/win_glimp.c25
-rw-r--r--ui/ingame_options.menu47
34 files changed, 756 insertions, 183 deletions
diff --git a/Makefile b/Makefile
index deb40a0c..be943372 100644
--- a/Makefile
+++ b/Makefile
@@ -136,8 +136,8 @@ LIBSDIR=$(MOUNT_DIR)/libs
MASTERDIR=$(MOUNT_DIR)/master
# extract version info
-VERSION=$(shell grep Q3_VERSION $(CMDIR)/q_shared.h | \
- sed -e 's/.*tremulous\ \(.*\)"/\1/')
+VERSION=$(shell grep "#define VERSION_NUMBER" $(CMDIR)/q_shared.h | \
+ sed -e 's/[^"]*"\(.*\)"/\1/')
ifeq ($(wildcard .svn),.svn)
SVN_VERSION=$(VERSION)_SVN$(shell LANG=C svnversion .)
@@ -778,6 +778,7 @@ Q3OBJ = \
$(B)/client/cvar.o \
$(B)/client/files.o \
$(B)/client/md4.o \
+ $(B)/client/md5.o \
$(B)/client/msg.o \
$(B)/client/net_chan.o \
$(B)/client/huffman.o \
@@ -1021,6 +1022,7 @@ $(B)/client/common.o : $(CMDIR)/common.c; $(DO_CC)
$(B)/client/cvar.o : $(CMDIR)/cvar.c; $(DO_CC)
$(B)/client/files.o : $(CMDIR)/files.c; $(DO_CC)
$(B)/client/md4.o : $(CMDIR)/md4.c; $(DO_CC)
+$(B)/client/md5.o : $(CMDIR)/md5.c; $(DO_CC)
$(B)/client/msg.o : $(CMDIR)/msg.c; $(DO_CC)
$(B)/client/net_chan.o : $(CMDIR)/net_chan.c; $(DO_CC)
$(B)/client/huffman.o : $(CMDIR)/huffman.c; $(DO_CC)
diff --git a/src/botlib/be_interface.c b/src/botlib/be_interface.c
index e70a6d4a..2980674e 100644
--- a/src/botlib/be_interface.c
+++ b/src/botlib/be_interface.c
@@ -138,12 +138,24 @@ int Export_BotLibSetup(void)
{
int errnum;
char logfilename[MAX_QPATH];
+ char *homedir, *gamedir;
bot_developer = LibVarGetValue("bot_developer");
memset( &botlibglobals, 0, sizeof(botlibglobals) ); // bk001207 - init
//initialize byte swapping (litte endian etc.)
// Swap_Init();
- Com_sprintf(logfilename, sizeof(logfilename), "%s%cbotlib.log", LibVarGetString("homedir"), PATH_SEP);
+ homedir = LibVarGetString("homedir");
+ gamedir = LibVarGetString("gamedir");
+ if (homedir[0]) {
+ if (gamedir[0]) {
+ Com_sprintf(logfilename, sizeof(logfilename), "%s%c%s%cbotlib.log", homedir, PATH_SEP, gamedir, PATH_SEP);
+ }
+ else {
+ /*Com_sprintf(logfilename, sizeof(logfilename), "%s%c" BASEGAME "%cbotlib.log", homedir, PATH_SEP, PATH_SEP);*/
+ }
+ } else {
+ Com_sprintf(logfilename, sizeof(logfilename), "botlib.log");
+ }
Log_Open(logfilename);
//
botimport.Print(PRT_MESSAGE, "------- BotLib Initialization -------\n");
diff --git a/src/cgame/cg_weapons.c b/src/cgame/cg_weapons.c
index ecb2499b..671bc4ae 100644
--- a/src/cgame/cg_weapons.c
+++ b/src/cgame/cg_weapons.c
@@ -503,17 +503,17 @@ static qboolean CG_ParseWeaponFile( const char *filename, weaponInfo_t *wi )
CG_Printf( S_COLOR_RED "ERROR: weapon model not found %s\n", token );
strcpy( path, token );
- COM_StripExtension( path, path );
+ COM_StripExtension( path, path, MAX_QPATH );
strcat( path, "_flash.md3" );
wi->flashModel = trap_R_RegisterModel( path );
strcpy( path, token );
- COM_StripExtension( path, path );
+ COM_StripExtension( path, path, MAX_QPATH );
strcat( path, "_barrel.md3" );
wi->barrelModel = trap_R_RegisterModel( path );
strcpy( path, token );
- COM_StripExtension( path, path );
+ COM_StripExtension( path, path, MAX_QPATH );
strcat( path, "_hand.md3" );
wi->handsModel = trap_R_RegisterModel( path );
diff --git a/src/client/cl_main.c b/src/client/cl_main.c
index 28e5021f..af8c1d76 100644
--- a/src/client/cl_main.c
+++ b/src/client/cl_main.c
@@ -2012,7 +2012,7 @@ void CL_Frame ( int msec ) {
}
Q_strncpyz( mapName, COM_SkipPath( cl.mapname ), sizeof( cl.mapname ) );
- COM_StripExtension( mapName, mapName );
+ COM_StripExtension(mapName, mapName, sizeof(mapName));
Cbuf_ExecuteText( EXEC_NOW,
va( "record %s-%s-%s", nowString, serverName, mapName ) );
@@ -2324,6 +2324,28 @@ void CL_StopVideo_f( void )
CL_CloseAVI( );
}
+static void CL_GenerateQKey(void)
+{
+ int len = 0;
+ unsigned char buff[2048];
+
+ len = FS_ReadFile(QKEY_FILE, NULL);
+ if(len >= (int)sizeof(buff)) {
+ Com_Printf("QKEY found.\n");
+ return;
+ }
+ else {
+ int i;
+ srand(time(0));
+ for(i = 0; i < sizeof(buff) - 1; i++) {
+ buff[i] = (unsigned char)(rand() % 255);
+ }
+ buff[i] = 0;
+ Com_Printf("QKEY generated\n");
+ FS_WriteFile(QKEY_FILE, buff, sizeof(buff));
+ }
+}
+
/*
====================
CL_Init
@@ -2472,6 +2494,9 @@ void CL_Init( void ) {
Cvar_Set( "cl_running", "1" );
+ CL_GenerateQKey();
+ Cvar_Get("cl_guid", Com_MD5File(QKEY_FILE, 0), CVAR_USERINFO | CVAR_ROM);
+
Com_Printf( "----- Client Initialization Complete -----\n" );
}
@@ -2485,6 +2510,10 @@ CL_Shutdown
void CL_Shutdown( void ) {
static qboolean recursive = qfalse;
+ // check whether the client is running at all.
+ if(!(com_cl_running && com_cl_running->integer))
+ return;
+
Com_Printf( "----- CL_Shutdown -----\n" );
if ( recursive ) {
diff --git a/src/client/client.h b/src/client/client.h
index a7db023f..e5f5d596 100644
--- a/src/client/client.h
+++ b/src/client/client.h
@@ -31,6 +31,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../cgame/cg_public.h"
#include "../game/bg_public.h"
+// tjw: file full of random crap that gets used to create cl_guid
+#define QKEY_FILE "qkey"
+
#define RETRANSMIT_TIMEOUT 3000 // time between connection packet retransmits
diff --git a/src/qcommon/common.c b/src/qcommon/common.c
index 5c3726ff..44174ead 100644
--- a/src/qcommon/common.c
+++ b/src/qcommon/common.c
@@ -181,11 +181,22 @@ void QDECL Com_Printf( const char *fmt, ... ) {
newtime = localtime( &aclock );
logfile = FS_FOpenFileWrite( "qconsole.log" );
- Com_Printf( "logfile opened on %s\n", asctime( newtime ) );
- if ( com_logfile->integer > 1 ) {
- // force it to not buffer so we get valid
- // data even if we are crashing
- FS_ForceFlush(logfile);
+
+ if(logfile)
+ {
+ Com_Printf( "logfile opened on %s\n", asctime( newtime ) );
+
+ if ( com_logfile->integer > 1 )
+ {
+ // force it to not buffer so we get valid
+ // data even if we are crashing
+ FS_ForceFlush(logfile);
+ }
+ }
+ else
+ {
+ Com_Printf("Opening qconsole.log failed!\n");
+ Cvar_SetValue("logfile", 0);
}
opening_qconsole = qfalse;
diff --git a/src/qcommon/files.c b/src/qcommon/files.c
index 84db5b18..ce380438 100644
--- a/src/qcommon/files.c
+++ b/src/qcommon/files.c
@@ -2175,8 +2175,8 @@ int FS_GetModList( char *listbuf, int bufsize ) {
if (bDrop) {
continue;
}
- // we drop "base" "." and ".."
- if (Q_stricmp(name, "base") && Q_stricmpn(name, ".", 1)) {
+ // 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
@@ -2550,9 +2550,16 @@ FS_idPak
*/
qboolean FS_idPak( char *pak, char *base ) {
int i;
+ char pakbuf[MAX_QPATH], *pakptr;
+
+ // Chop off filename extension if necessary.
+ Com_sprintf(pakbuf, sizeof(pakbuf), "%s", pak);
+ pakptr = Q_strrchr(pakbuf, '.');
+ if(pakptr)
+ *pakptr = '\0';
for (i = 0; i < NUM_ID_PAKS; i++) {
- if ( !FS_FilenameCompare(pak, va("%s/pak%d", base, i)) ) {
+ if ( !FS_FilenameCompare(pakbuf, va("%s/pak%d", base, i)) ) {
break;
}
}
@@ -2605,7 +2612,7 @@ qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ) {
havepak = qfalse;
// never autodownload any of the tremulous paks
- if ( FS_idPak(fs_serverReferencedPakNames[i], "base") ) {
+ if ( FS_idPak(fs_serverReferencedPakNames[i], BASEGAME) ) {
continue;
}
@@ -3377,7 +3384,7 @@ void FS_FilenameCompletion( const char *dir, const char *ext,
Q_strncpyz( filename, filenames[ i ], MAX_STRING_CHARS );
if( stripExt ) {
- COM_StripExtension( filename, filename );
+ COM_StripExtension(filename, filename, sizeof(filename));
}
callback( filename );
diff --git a/src/qcommon/md4.c b/src/qcommon/md4.c
index 1b491be8..2501b2b6 100644
--- a/src/qcommon/md4.c
+++ b/src/qcommon/md4.c
@@ -30,21 +30,9 @@
#include "q_shared.h"
#include "qcommon.h"
-#ifndef int32
-#define int32 int
-#endif
-
-#if SIZEOF_INT > 4
-#define LARGE_INT32
-#endif
-
-#ifndef uint32
-#define uint32 unsigned int32
-#endif
-
struct mdfour {
- uint32 A, B, C, D;
- uint32 totalN;
+ uint32_t A, B, C, D;
+ uint32_t totalN;
};
@@ -58,23 +46,19 @@ static struct mdfour *m;
#define F(X,Y,Z) (((X)&(Y)) | ((~(X))&(Z)))
#define G(X,Y,Z) (((X)&(Y)) | ((X)&(Z)) | ((Y)&(Z)))
#define H(X,Y,Z) ((X)^(Y)^(Z))
-#ifdef LARGE_INT32
-#define lshift(x,s) ((((x)<<(s))&0xFFFFFFFF) | (((x)>>(32-(s)))&0xFFFFFFFF))
-#else
#define lshift(x,s) (((x)<<(s)) | ((x)>>(32-(s))))
-#endif
#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s)
#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + 0x5A827999,s)
#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + 0x6ED9EBA1,s)
/* this applies md4 to 64 byte chunks */
-static void mdfour64(uint32 *M)
+static void mdfour64(uint32_t *M)
{
int j;
- uint32 AA, BB, CC, DD;
- uint32 X[16];
- uint32 A,B,C,D;
+ uint32_t AA, BB, CC, DD;
+ uint32_t X[16];
+ uint32_t A,B,C,D;
for (j=0;j<16;j++)
X[j] = M[j];
@@ -111,18 +95,13 @@ static void mdfour64(uint32 *M)
A += AA; B += BB; C += CC; D += DD;
-#ifdef LARGE_INT32
- A &= 0xFFFFFFFF; B &= 0xFFFFFFFF;
- C &= 0xFFFFFFFF; D &= 0xFFFFFFFF;
-#endif
-
for (j=0;j<16;j++)
X[j] = 0;
m->A = A; m->B = B; m->C = C; m->D = D;
}
-static void copy64(uint32 *M, byte *in)
+static void copy64(uint32_t *M, byte *in)
{
int i;
@@ -131,7 +110,7 @@ static void copy64(uint32 *M, byte *in)
(in[i*4+1]<<8) | (in[i*4+0]<<0);
}
-static void copy4(byte *out,uint32 x)
+static void copy4(byte *out,uint32_t x)
{
out[0] = x&0xFF;
out[1] = (x>>8)&0xFF;
@@ -152,8 +131,8 @@ void mdfour_begin(struct mdfour *md)
static void mdfour_tail(byte *in, int n)
{
byte buf[128];
- uint32 M[16];
- uint32 b;
+ uint32_t M[16];
+ uint32_t b;
m->totalN += n;
@@ -178,7 +157,7 @@ static void mdfour_tail(byte *in, int n)
static void mdfour_update(struct mdfour *md, byte *in, int n)
{
- uint32 M[16];
+ uint32_t M[16];
if (n == 0) mdfour_tail(in, n);
diff --git a/src/qcommon/md5.c b/src/qcommon/md5.c
new file mode 100644
index 00000000..ffe77527
--- /dev/null
+++ b/src/qcommon/md5.c
@@ -0,0 +1,299 @@
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+#include "q_shared.h"
+#include "qcommon.h"
+
+typedef struct MD5Context {
+ uint32_t buf[4];
+ uint32_t bits[2];
+ unsigned char in[64];
+} MD5_CTX;
+
+#ifndef Q3_BIG_ENDIAN
+ #define byteReverse(buf, len) /* Nothing */
+#else
+ static void byteReverse(unsigned char *buf, unsigned longs);
+
+ /*
+ * Note: this code is harmless on little-endian machines.
+ */
+ static void byteReverse(unsigned char *buf, unsigned longs)
+ {
+ uint32_t t;
+ do {
+ t = (uint32_t)
+ ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+ ((unsigned) buf[1] << 8 | buf[0]);
+ *(uint32_t *) buf = t;
+ buf += 4;
+ } while (--longs);
+ }
+#endif // Q3_BIG_ENDIAN
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+static void MD5Init(struct MD5Context *ctx)
+{
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
+
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+static void MD5Transform(uint32_t buf[4],
+ uint32_t const in[16])
+{
+ register uint32_t a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+static void MD5Update(struct MD5Context *ctx, unsigned char const *buf,
+ unsigned len)
+{
+ uint32_t t;
+
+ /* Update bitcount */
+
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
+ ctx->bits[1]++; /* Carry from low to high */
+ ctx->bits[1] += len >> 29;
+
+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
+
+ /* Handle any leading odd-sized chunks */
+
+ if (t) {
+ unsigned char *p = (unsigned char *) ctx->in + t;
+
+ t = 64 - t;
+ if (len < t) {
+ memcpy(p, buf, len);
+ return;
+ }
+ memcpy(p, buf, t);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+ buf += t;
+ len -= t;
+ }
+ /* Process data in 64-byte chunks */
+
+ while (len >= 64) {
+ memcpy(ctx->in, buf, 64);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+
+ memcpy(ctx->in, buf, len);
+}
+
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+static void MD5Final(struct MD5Context *ctx, unsigned char *digest)
+{
+ unsigned count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset(p, 0, count);
+ byteReverse(ctx->in, 16);
+ MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+
+ /* Now fill the next block with 56 bytes */
+ memset(ctx->in, 0, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ memset(p, 0, count - 8);
+ }
+ byteReverse(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ((uint32_t *) ctx->in)[14] = ctx->bits[0];
+ ((uint32_t *) ctx->in)[15] = ctx->bits[1];
+
+ MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+ byteReverse((unsigned char *) ctx->buf, 4);
+
+ if (digest!=NULL)
+ memcpy(digest, ctx->buf, 16);
+ memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
+}
+
+
+char *Com_MD5File(const char *fn, int length)
+{
+ static char final[33] = {"unknown"};
+ unsigned char digest[16] = {""};
+ fileHandle_t f;
+ MD5_CTX md5;
+ char buffer[2048];
+ int i;
+ int filelen = 0;
+ int r = 0;
+ int total = 0;
+
+ filelen = FS_FOpenFileRead(fn, &f, qtrue);
+ if(filelen < 1) {
+ return final;
+ }
+ if(filelen < length || !length) {
+ length = filelen;
+ }
+
+ MD5Init(&md5);
+ for(;;) {
+ r = FS_Read2(buffer, sizeof(buffer), f);
+ if(r < 1)
+ break;
+ if(r + total > length)
+ r = length - total;
+ total += r;
+ MD5Update(&md5 , (unsigned char *)buffer, r);
+ if(r < sizeof(buffer) || total >= length)
+ break;
+ }
+ FS_FCloseFile(f);
+ MD5Final(&md5, digest);
+ final[0] = '\0';
+ for(i = 0; i < 16; i++) {
+ Q_strcat(final, sizeof(final), va("%02X", digest[i]));
+ }
+ return final;
+}
diff --git a/src/qcommon/q_shared.c b/src/qcommon/q_shared.c
index 9f152d62..93c1dc20 100644
--- a/src/qcommon/q_shared.c
+++ b/src/qcommon/q_shared.c
@@ -59,10 +59,10 @@ char *COM_SkipPath (char *pathname)
COM_StripExtension
============
*/
-void COM_StripExtension( const char *in, char *out ) {
+void COM_StripExtension( const char *in, char *out, int destsize ) {
int length;
- strcpy( out, in );
+ Q_strncpyz(out, in, destsize);
length = strlen(out)-1;
while (length > 0 && out[length] != '.')
diff --git a/src/qcommon/q_shared.h b/src/qcommon/q_shared.h
index 6d276630..0127fd90 100644
--- a/src/qcommon/q_shared.h
+++ b/src/qcommon/q_shared.h
@@ -108,10 +108,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//=============================================================
#ifdef Q3_VM
-typedef int intptr_t;
+ typedef int intptr_t;
#else
# ifndef _MSC_VER
# include <stdint.h>
+# else
+ typedef __int64 int64_t;
+ typedef __int32 int32_t;
+ typedef __int16 int16_t;
+ typedef __int8 int8_t;
+ typedef unsigned __int64 uint64_t;
+ typedef unsigned __int32 uint32_t;
+ typedef unsigned __int16 uint16_t;
+ typedef unsigned __int8 uint8_t;
# endif
#endif
@@ -633,7 +642,7 @@ vec_t DistanceBetweenLineSegments(
float Com_Clamp( float min, float max, float value );
char *COM_SkipPath( char *pathname );
-void COM_StripExtension( const char *in, char *out );
+void COM_StripExtension(const char *in, char *out, int destsize);
void COM_DefaultExtension( char *path, int maxSize, const char *extension );
void COM_BeginParseSession( const char *name );
diff --git a/src/qcommon/qcommon.h b/src/qcommon/qcommon.h
index eb89de47..f9ca82fc 100644
--- a/src/qcommon/qcommon.h
+++ b/src/qcommon/qcommon.h
@@ -720,6 +720,7 @@ 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);
int Com_HashKey(char *string, int maxlen);
int Com_Filter(char *filter, char *name, int casesensitive);
int Com_FilterPath(char *filter, char *name, int casesensitive);
diff --git a/src/qcommon/vm.c b/src/qcommon/vm.c
index 0235ffea..8fb588db 100644
--- a/src/qcommon/vm.c
+++ b/src/qcommon/vm.c
@@ -231,7 +231,7 @@ void VM_LoadSymbols( vm_t *vm ) {
return;
}
- COM_StripExtension( vm->name, name );
+ COM_StripExtension(vm->name, name, sizeof(name));
Com_sprintf( symbols, sizeof( symbols ), "vm/%s.map", name );
len = FS_ReadFile( symbols, (void **)&mapfile );
if ( !mapfile ) {
diff --git a/src/renderer/qgl.h b/src/renderer/qgl.h
index e1945f8b..5bf52e13 100644
--- a/src/renderer/qgl.h
+++ b/src/renderer/qgl.h
@@ -92,11 +92,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//===========================================================================
+// <Timbo> I hate this section so much
/*
** multitexture extension definitions
*/
#if !defined(__sun)
+
#define GL_ACTIVE_TEXTURE_ARB 0x84E0
#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
#define GL_MAX_ACTIVE_TEXTURES_ARB 0x84E2
@@ -105,10 +107,24 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define GL_TEXTURE1_ARB 0x84C1
#define GL_TEXTURE2_ARB 0x84C2
#define GL_TEXTURE3_ARB 0x84C3
+
#else
+
#define GL_MAX_ACTIVE_TEXTURES_ARB 0x84E2
+
#endif /* defined(__sun) */
+// anisotropic filtering constants
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+
+// define for skyboxes without black seams on non SDL-versions.
+#if !defined(GL_VERSION_1_2) && !defined(GL_CLAMP_TO_EDGE)
+ #define GL_CLAMP_TO_EDGE 0x812F
+#endif
+
+//===========================================================================
+
// NOTE: some Linux platforms would need those prototypes
#if defined(MACOS_X) || ( defined(__sun) && defined(__sparc) )
typedef void (APIENTRY * PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s);
@@ -175,7 +191,7 @@ extern void ( APIENTRY * qglUnlockArraysEXT) (void);
//===========================================================================
-// non-windows systems will just redefine qgl* to gl*
+// non-dlopening systems will just redefine qgl* to gl*
#if !defined( _WIN32 ) && !defined(MACOS_X) && !defined( __linux__ ) && !defined( __FreeBSD__ ) && !defined(__sun) // rb010123
#include "qgl_linked.h"
diff --git a/src/renderer/tr_bsp.c b/src/renderer/tr_bsp.c
index eb57da8f..2eff8349 100644
--- a/src/renderer/tr_bsp.c
+++ b/src/renderer/tr_bsp.c
@@ -1824,7 +1824,7 @@ void RE_LoadWorldMap( const char *name ) {
Q_strncpyz( s_worldData.name, name, sizeof( s_worldData.name ) );
Q_strncpyz( s_worldData.baseName, COM_SkipPath( s_worldData.name ), sizeof( s_worldData.name ) );
- COM_StripExtension( s_worldData.baseName, s_worldData.baseName );
+ COM_StripExtension(s_worldData.baseName, s_worldData.baseName, sizeof(s_worldData.baseName));
startMarker = ri.Hunk_Alloc(0, h_low);
c_gridVerts = 0;
diff --git a/src/renderer/tr_flares.c b/src/renderer/tr_flares.c
index 17e21976..f8fb222d 100644
--- a/src/renderer/tr_flares.c
+++ b/src/renderer/tr_flares.c
@@ -76,6 +76,7 @@ typedef struct flare_s {
int windowX, windowY;
float eyeZ;
+ vec3_t origin;
vec3_t color;
} flare_t;
@@ -84,6 +85,8 @@ typedef struct flare_s {
flare_t r_flareStructs[MAX_FLARES];
flare_t *r_activeFlares, *r_inactiveFlares;
+int flareCoeff;
+
/*
==================
R_ClearFlares
@@ -114,11 +117,22 @@ void RB_AddFlare( void *surface, int fogNum, vec3_t point, vec3_t color, vec3_t
int i;
flare_t *f, *oldest;
vec3_t local;
- float d;
+ float d = 1;
vec4_t eye, clip, normalized, window;
backEnd.pc.c_flareAdds++;
+ if(normal && (normal[0] || normal[1] || normal[2]))
+ {
+ VectorSubtract( backEnd.viewParms.or.origin, point, local );
+ VectorNormalizeFast(local);
+ d = DotProduct(local, normal);
+
+ // If the viewer is behind the flare don't add it.
+ if(d < 0)
+ return;
+ }
+
// if the point is off the screen, don't bother adding it
// calculate screen coordinates and depth
R_TransformModelToClip( point, backEnd.or.modelMatrix,
@@ -172,16 +186,12 @@ void RB_AddFlare( void *surface, int fogNum, vec3_t point, vec3_t color, vec3_t
f->addedFrame = backEnd.viewParms.frameCount;
f->fogNum = fogNum;
+ VectorCopy(point, f->origin);
VectorCopy( color, f->color );
// fade the intensity of the flare down as the
// light surface turns away from the viewer
- if ( normal ) {
- VectorSubtract( backEnd.viewParms.or.origin, point, local );
- VectorNormalizeFast( local );
- d = DotProduct( local, normal );
- VectorScale( f->color, d, f->color );
- }
+ VectorScale( f->color, d, f->color );
// save info needed to test
f->windowX = backEnd.viewParms.viewportX + window[0];
@@ -198,31 +208,39 @@ RB_AddDlightFlares
void RB_AddDlightFlares( void ) {
dlight_t *l;
int i, j, k;
- fog_t *fog;
+ fog_t *fog = NULL;
if ( !r_flares->integer ) {
return;
}
l = backEnd.refdef.dlights;
- fog = tr.world->fogs;
+
+ if(tr.world)
+ fog = tr.world->fogs;
+
for (i=0 ; i<backEnd.refdef.num_dlights ; i++, l++) {
- // find which fog volume the light is in
- for ( j = 1 ; j < tr.world->numfogs ; j++ ) {
- fog = &tr.world->fogs[j];
- for ( k = 0 ; k < 3 ; k++ ) {
- if ( l->origin[k] < fog->bounds[0][k] || l->origin[k] > fog->bounds[1][k] ) {
+ if(fog)
+ {
+ // find which fog volume the light is in
+ for ( j = 1 ; j < tr.world->numfogs ; j++ ) {
+ fog = &tr.world->fogs[j];
+ for ( k = 0 ; k < 3 ; k++ ) {
+ if ( l->origin[k] < fog->bounds[0][k] || l->origin[k] > fog->bounds[1][k] ) {
+ break;
+ }
+ }
+ if ( k == 3 ) {
break;
}
}
- if ( k == 3 ) {
- break;
+ if ( j == tr.world->numfogs ) {
+ j = 0;
}
}
- if ( j == tr.world->numfogs ) {
+ else
j = 0;
- }
RB_AddFlare( (void *)l, j, l->origin, l->color, NULL );
}
@@ -295,16 +313,65 @@ void RB_RenderFlare( flare_t *f ) {
float size;
vec3_t color;
int iColor[3];
+ float distance, intensity, factor;
+ byte fogFactors[3] = {255, 255, 255};
backEnd.pc.c_flareRenders++;
- VectorScale( f->color, f->drawIntensity*tr.identityLight, color );
- iColor[0] = color[0] * 255;
- iColor[1] = color[1] * 255;
- iColor[2] = color[2] * 255;
+ // We don't want too big values anyways when dividing by distance.
+ if(f->eyeZ > -1.0f)
+ distance = 1.0f;
+ else
+ distance = -f->eyeZ;
+
+ // calculate the flare size..
+ size = backEnd.viewParms.viewportWidth * ( r_flareSize->value/640.0f + 8 / distance );
- size = backEnd.viewParms.viewportWidth * ( r_flareSize->value/640.0f + 8 / -f->eyeZ );
+/*
+ * This is an alternative to intensity scaling. It changes the size of the flare on screen instead
+ * with growing distance. See in the description at the top why this is not the way to go.
+ // size will change ~ 1/r.
+ size = backEnd.viewParms.viewportWidth * (r_flareSize->value / (distance * -2.0f));
+*/
+/*
+ * As flare sizes stay nearly constant with increasing distance we must decrease the intensity
+ * to achieve a reasonable visual result. The intensity is ~ (size^2 / distance^2) which can be
+ * got by considering the ratio of
+ * (flaresurface on screen) : (Surface of sphere defined by flare origin and distance from flare)
+ * An important requirement is:
+ * intensity <= 1 for all distances.
+ *
+ * The formula used here to compute the intensity is as follows:
+ * intensity = flareCoeff * size^2 / (distance + size*sqrt(flareCoeff))^2
+ * As you can see, the intensity will have a max. of 1 when the distance is 0.
+ * The coefficient flareCoeff will determine the falloff speed with increasing distance.
+ */
+
+ factor = distance + size * sqrt(flareCoeff);
+
+ intensity = flareCoeff * size * size / (factor * factor);
+
+ VectorScale(f->color, f->drawIntensity * intensity, color);
+
+// Calculations for fogging
+ if(tr.world && f->fogNum < tr.world->numfogs)
+ {
+ tess.numVertexes = 1;
+ VectorCopy(f->origin, tess.xyz[0]);
+ tess.fogNum = f->fogNum;
+
+ RB_CalcModulateColorsByFog(fogFactors);
+
+ // We don't need to render the flare if colors are 0 anyways.
+ if(!(fogFactors[0] || fogFactors[1] || fogFactors[2]))
+ return;
+ }
+
+ iColor[0] = color[0] * fogFactors[0];
+ iColor[1] = color[1] * fogFactors[1];
+ iColor[2] = color[2] * fogFactors[2];
+
RB_BeginSurface( tr.flareShader, f->fogNum );
// FIXME: use quadstamp?
@@ -383,6 +450,21 @@ void RB_RenderFlares (void) {
return;
}
+ if(r_flareCoeff->modified)
+ {
+ if(r_flareCoeff->value == 0.0f)
+ flareCoeff = atof(FLARE_STDCOEFF);
+ else
+ flareCoeff = r_flareCoeff->value;
+
+ r_flareCoeff->modified = qfalse;
+ }
+
+ // Reset currentEntity to world so that any previously referenced entities
+ // don't have influence on the rendering of these flares (i.e. RF_ renderer flags).
+ backEnd.currentEntity = &tr.worldEntity;
+ backEnd.or = backEnd.viewParms.world;
+
// RB_AddDlightFlares();
// perform z buffer readback on each flare in this view
diff --git a/src/renderer/tr_image.c b/src/renderer/tr_image.c
index 692f00c6..d4beacd8 100644
--- a/src/renderer/tr_image.c
+++ b/src/renderer/tr_image.c
@@ -700,11 +700,18 @@ done:
if (mipmap)
{
+ if ( glConfig.textureFilterAnisotropic )
+ qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
+ (GLint)Com_Clamp( 1, glConfig.maxAnisotropy, r_ext_max_anisotropy->integer ) );
+
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
}
else
{
+ if ( glConfig.textureFilterAnisotropic )
+ qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1 );
+
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
}
diff --git a/src/renderer/tr_init.c b/src/renderer/tr_init.c
index 475a37c6..f9cdc911 100644
--- a/src/renderer/tr_init.c
+++ b/src/renderer/tr_init.c
@@ -25,12 +25,16 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "tr_local.h"
glconfig_t glConfig;
+qboolean textureFilterAnisotropic = qfalse;
+int maxAnisotropy = 0;
+
glstate_t glState;
static void GfxInfo_f( void );
cvar_t *r_flareSize;
cvar_t *r_flareFade;
+cvar_t *r_flareCoeff;
cvar_t *r_railWidth;
cvar_t *r_railCoreWidth;
@@ -81,6 +85,8 @@ cvar_t *r_ext_gamma_control;
cvar_t *r_ext_multitexture;
cvar_t *r_ext_compiled_vertex_array;
cvar_t *r_ext_texture_env_add;
+cvar_t *r_ext_texture_filter_anisotropic;
+cvar_t *r_ext_max_anisotropy;
cvar_t *r_ignoreGLErrors;
cvar_t *r_logFile;
@@ -995,6 +1001,10 @@ void R_Register( void )
r_picmip = ri.Cvar_Get ("r_picmip", GENERIC_HW_R_PICMIP_DEFAULT,
CVAR_ARCHIVE | CVAR_LATCH );
+ r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic",
+ "0", CVAR_ARCHIVE | CVAR_LATCH );
+ r_ext_max_anisotropy = ri.Cvar_Get( "r_ext_max_anisotropy", "2", CVAR_ARCHIVE | CVAR_LATCH );
+
r_roundImagesDown = ri.Cvar_Get ("r_roundImagesDown", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_colorMipLevels = ri.Cvar_Get ("r_colorMipLevels", "0", CVAR_LATCH );
AssertCvarRange( r_picmip, 0, 16, qtrue );
@@ -1079,6 +1089,7 @@ void R_Register( void )
r_flareSize = ri.Cvar_Get ("r_flareSize", "40", CVAR_CHEAT);
r_flareFade = ri.Cvar_Get ("r_flareFade", "7", CVAR_CHEAT);
+ r_flareCoeff = ri.Cvar_Get ("r_flareCoeff", FLARE_STDCOEFF, CVAR_CHEAT);
r_showSmp = ri.Cvar_Get ("r_showSmp", "0", CVAR_CHEAT);
r_skipBackEnd = ri.Cvar_Get ("r_skipBackEnd", "0", CVAR_CHEAT);
@@ -1141,6 +1152,11 @@ void R_Init( void ) {
Com_Memset( &backEnd, 0, sizeof( backEnd ) );
Com_Memset( &tess, 0, sizeof( tess ) );
+ if(sizeof(glconfig_t) != 11332)
+ {
+ ri.Error( ERR_FATAL, "Mod ABI incompatible: sizeof(glconfig_t) == %zd != 11332", sizeof(glconfig_t));
+ }
+
// Swap_Init();
if ( (int)tess.xyz & 15 ) {
diff --git a/src/renderer/tr_local.h b/src/renderer/tr_local.h
index a80590ca..7c694759 100644
--- a/src/renderer/tr_local.h
+++ b/src/renderer/tr_local.h
@@ -971,12 +971,14 @@ extern trGlobals_t tr;
extern glconfig_t glConfig; // outside of TR since it shouldn't be cleared during ref re-init
extern glstate_t glState; // outside of TR since it shouldn't be cleared during ref re-init
-
//
// cvars
//
extern cvar_t *r_flareSize;
extern cvar_t *r_flareFade;
+// coefficient for the flare intensity falloff function.
+#define FLARE_STDCOEFF "150"
+extern cvar_t *r_flareCoeff;
extern cvar_t *r_railWidth;
extern cvar_t *r_railCoreWidth;
@@ -1039,6 +1041,9 @@ extern cvar_t *r_ext_multitexture;
extern cvar_t *r_ext_compiled_vertex_array;
extern cvar_t *r_ext_texture_env_add;
+extern cvar_t *r_ext_texture_filter_anisotropic;
+extern cvar_t *r_ext_max_anisotropy;
+
extern cvar_t *r_nobind; // turns off binding to appropriate textures
extern cvar_t *r_singleShader; // make most world faces use default shader
extern cvar_t *r_roundImagesDown;
diff --git a/src/renderer/tr_shader.c b/src/renderer/tr_shader.c
index 380f9bf6..0e4504ef 100644
--- a/src/renderer/tr_shader.c
+++ b/src/renderer/tr_shader.c
@@ -96,7 +96,7 @@ void R_RemapShader(const char *shaderName, const char *newShaderName, const char
// remap all the shaders with the given name
// even tho they might have different lightmaps
- COM_StripExtension( shaderName, strippedName );
+ COM_StripExtension(shaderName, strippedName, sizeof(strippedName));
hash = generateHashValue(strippedName, FILE_HASH_SIZE);
for (sh = hashTable[hash]; sh; sh = sh->next) {
if (Q_stricmp(sh->name, strippedName) == 0) {
@@ -2366,7 +2366,7 @@ shader_t *R_FindShaderByName( const char *name ) {
return tr.defaultShader;
}
- COM_StripExtension( name, strippedName );
+ COM_StripExtension(name, strippedName, sizeof(strippedName));
hash = generateHashValue(strippedName, FILE_HASH_SIZE);
@@ -2434,7 +2434,7 @@ shader_t *R_FindShader( const char *name, int lightmapIndex, qboolean mipRawImag
lightmapIndex = LIGHTMAP_BY_VERTEX;
}
- COM_StripExtension( name, strippedName );
+ COM_StripExtension(name, strippedName, sizeof(strippedName));
hash = generateHashValue(strippedName, FILE_HASH_SIZE);
@@ -3010,8 +3010,22 @@ static void CreateInternalShaders( void ) {
static void CreateExternalShaders( void ) {
tr.projectionShadowShader = R_FindShader( "projectionShadow", LIGHTMAP_NONE, qtrue );
- //tr.flareShader = R_FindShader( "flareShader", LIGHTMAP_NONE, qtrue );
- //tr.sunShader = R_FindShader( "sun", LIGHTMAP_NONE, qtrue );
+ tr.flareShader = R_FindShader( "flareShader", LIGHTMAP_NONE, qtrue );
+
+ // Hack to make fogging work correctly on flares. Fog colors are calculated
+ // in tr_flare.c already.
+ if(!tr.flareShader->defaultShader)
+ {
+ int index;
+
+ for(index = 0; index < tr.flareShader->numUnfoggedPasses; index++)
+ {
+ tr.flareShader->stages[index]->adjustColorsForFog = ACFF_NONE;
+ tr.flareShader->stages[index]->stateBits |= GLS_DEPTHTEST_DISABLE;
+ }
+ }
+
+ tr.sunShader = R_FindShader( "sun", LIGHTMAP_NONE, qtrue );
}
/*
diff --git a/src/renderer/tr_surface.c b/src/renderer/tr_surface.c
index a65b17db..2a291c84 100644
--- a/src/renderer/tr_surface.c
+++ b/src/renderer/tr_surface.c
@@ -1215,71 +1215,12 @@ void RB_SurfaceBad( surfaceType_t *surfType ) {
ri.Printf( PRINT_ALL, "Bad surface tesselated.\n" );
}
-#if 0
-
-void RB_SurfaceFlare( srfFlare_t *surf ) {
- vec3_t left, up;
- float radius;
- byte color[4];
- vec3_t dir;
- vec3_t origin;
- float d;
-
- // calculate the xyz locations for the four corners
- radius = 30;
- VectorScale( backEnd.viewParms.or.axis[1], radius, left );
- VectorScale( backEnd.viewParms.or.axis[2], radius, up );
- if ( backEnd.viewParms.isMirror ) {
- VectorSubtract( vec3_origin, left, left );
- }
-
- color[0] = color[1] = color[2] = color[3] = 255;
-
- VectorMA( surf->origin, 3, surf->normal, origin );
- VectorSubtract( origin, backEnd.viewParms.or.origin, dir );
- VectorNormalize( dir );
- VectorMA( origin, r_ignore->value, dir, origin );
-
- d = -DotProduct( dir, surf->normal );
- if ( d < 0 ) {
- return;
- }
-#if 0
- color[0] *= d;
- color[1] *= d;
- color[2] *= d;
-#endif
-
- RB_AddQuadStamp( origin, left, up, color );
-}
-
-#else
-
-void RB_SurfaceFlare( srfFlare_t *surf ) {
-#if 0
- vec3_t left, up;
- byte color[4];
-
- color[0] = surf->color[0] * 255;
- color[1] = surf->color[1] * 255;
- color[2] = surf->color[2] * 255;
- color[3] = 255;
-
- VectorClear( left );
- VectorClear( up );
-
- left[0] = r_ignore->value;
-
- up[1] = r_ignore->value;
-
- RB_AddQuadStampExt( surf->origin, left, up, color, 0, 0, 1, 1 );
-#endif
+void RB_SurfaceFlare(srfFlare_t *surf)
+{
+ if (r_flares->integer)
+ RB_AddFlare(surf, tess.fogNum, surf->origin, surf->color, surf->normal);
}
-#endif
-
-
-
void RB_SurfaceDisplayList( srfDisplayList_t *surf ) {
// all apropriate state must be set in RB_BeginSurface
// this isn't implemented yet...
diff --git a/src/renderer/tr_types.h b/src/renderer/tr_types.h
index e3aabc3b..5aa08aed 100644
--- a/src/renderer/tr_types.h
+++ b/src/renderer/tr_types.h
@@ -201,6 +201,10 @@ typedef struct {
qboolean isFullscreen;
qboolean stereoEnabled;
qboolean smpActive; // dual processor
+
+ qboolean textureFilterAnisotropic;
+ int maxAnisotropy;
+
} glconfig_t;
// FIXME: VM should be OS agnostic .. in theory
diff --git a/src/server/sv_ccmds.c b/src/server/sv_ccmds.c
index 55ee62fd..0e016056 100644
--- a/src/server/sv_ccmds.c
+++ b/src/server/sv_ccmds.c
@@ -35,12 +35,12 @@ These commands can only be entered from stdin or by a remote operator datagram
/*
==================
-SV_GetPlayerByName
+SV_GetPlayerByHandle
-Returns the player with name from Cmd_Argv(1)
+Returns the player with player id or name from Cmd_Argv(1)
==================
*/
-static client_t *SV_GetPlayerByName( void ) {
+static client_t *SV_GetPlayerByHandle( void ) {
client_t *cl;
int i;
char *s;
@@ -58,6 +58,23 @@ static client_t *SV_GetPlayerByName( void ) {
s = Cmd_Argv(1);
+ // Check whether this is a numeric player handle
+ for(i = 0; s[i] >= '0' && s[i] <= '9'; i++);
+
+ if(!s[i])
+ {
+ int plid = atoi(s);
+
+ // Check for numeric playerid match
+ if(plid >= 0 && plid < sv_maxclients->integer)
+ {
+ cl = &svs.clients[plid];
+
+ if(cl->state)
+ return cl;
+ }
+ }
+
// check for a name match
for ( i=0, cl=svs.clients ; i < sv_maxclients->integer ; i++,cl++ ) {
if ( !cl->state ) {
@@ -218,7 +235,7 @@ static void SV_MapRestart_f( void ) {
delay = 5;
}
if( delay && !Cvar_VariableValue("g_doWarmup") ) {
- sv.restartTime = svs.time + delay * 1000;
+ sv.restartTime = sv.time + delay * 1000;
SV_SetConfigstring( CS_WARMUP, va("%i", sv.restartTime) );
return;
}
@@ -355,7 +372,7 @@ static void SV_Kick_f( void ) {
return;
}
- cl = SV_GetPlayerByName();
+ cl = SV_GetPlayerByHandle();
if ( !cl ) {
return;
}
@@ -390,7 +407,7 @@ static void SV_Ban_f( void ) {
return;
}
- cl = SV_GetPlayerByName();
+ cl = SV_GetPlayerByHandle();
if (!cl) {
return;
@@ -675,7 +692,7 @@ static void SV_DumpUser_f( void ) {
return;
}
- cl = SV_GetPlayerByName();
+ cl = SV_GetPlayerByHandle();
if ( !cl ) {
return;
}
diff --git a/src/server/sv_client.c b/src/server/sv_client.c
index 92a91bb7..fe7cc905 100644
--- a/src/server/sv_client.c
+++ b/src/server/sv_client.c
@@ -340,7 +340,7 @@ void SV_DropClient( client_t *drop, const char *reason ) {
return; // already dropped
}
- if ( !drop->gentity || !(drop->gentity->r.svFlags & SVF_BOT) ) {
+ if (drop->netchan.remoteAddress.type != NA_BOT) {
// see if we already have a challenge for this ip
challenge = &svs.challenges[0];
@@ -630,7 +630,7 @@ void SV_WriteDownloadToClient( client_t *cl , msg_t *msg )
Com_Printf( "clientDownload: %d : begining \"%s\"\n", cl - svs.clients, cl->downloadName );
missionPack = FS_idPak(cl->downloadName, "missionpack");
- idPack = missionPack || FS_idPak(cl->downloadName, "baseq3");
+ idPack = missionPack || FS_idPak(cl->downloadName, BASEGAME);
if ( !sv_allowDownload->integer || idPack ||
( cl->downloadSize = FS_SV_FOpenFileRead( cl->downloadName, &cl->download ) ) <= 0 ) {
diff --git a/src/server/sv_init.c b/src/server/sv_init.c
index d0a6a3c0..76cb8297 100644
--- a/src/server/sv_init.c
+++ b/src/server/sv_init.c
@@ -634,7 +634,7 @@ void SV_FinalMessage( char *message ) {
if (cl->state >= CS_CONNECTED) {
// don't send a disconnect to a local client
if ( cl->netchan.remoteAddress.type != NA_LOOPBACK ) {
- SV_SendServerCommand( cl, "print \"%s\"\n", message );
+ SV_SendServerCommand( cl, "print \"%s\n\"\n", message );
SV_SendServerCommand( cl, "disconnect" );
}
// force a snapshot to be sent
diff --git a/src/server/sv_main.c b/src/server/sv_main.c
index b40d173f..2e3135b6 100644
--- a/src/server/sv_main.c
+++ b/src/server/sv_main.c
@@ -834,7 +834,7 @@ void SV_Frame( int msec ) {
return;
}
- if( sv.restartTime && svs.time >= sv.restartTime ) {
+ if( sv.restartTime && sv.time >= sv.restartTime ) {
sv.restartTime = 0;
Cbuf_AddText( "map_restart 0\n" );
return;
diff --git a/src/tools/asm/Makefile b/src/tools/asm/Makefile
index f03025ca..df355719 100644
--- a/src/tools/asm/Makefile
+++ b/src/tools/asm/Makefile
@@ -6,7 +6,7 @@ else
BINEXT=
endif
-ifeq ($(PLATFORM),SunOS)
+ifeq ($(PLATFORM),sunos)
INSTALL=ginstall
else
INSTALL=install
diff --git a/src/tools/lcc/Makefile b/src/tools/lcc/Makefile
index 381b48ee..8dd5fb2b 100644
--- a/src/tools/lcc/Makefile
+++ b/src/tools/lcc/Makefile
@@ -30,7 +30,7 @@ ifeq ($(PLATFORM),darwin)
LCC_CFLAGS += -DMACOS_X
endif
-ifeq ($(PLATFORM),SunOS)
+ifeq ($(PLATFORM),sunos)
INSTALL=ginstall
else
INSTALL=install
diff --git a/src/ui/ui_main.c b/src/ui/ui_main.c
index c7b90a6a..7873fb63 100644
--- a/src/ui/ui_main.c
+++ b/src/ui/ui_main.c
@@ -5371,7 +5371,7 @@ static void UI_BuildQ3Model_List( void )
{
filelen = strlen(fileptr);
- COM_StripExtension(fileptr,skinname);
+ COM_StripExtension(fileptr,skinname,2048);
// look for icon_????
if (Q_stricmpn(skinname, "icon_", 5) == 0 && !(Q_stricmp(skinname,"icon_blue") == 0 || Q_stricmp(skinname,"icon_red") == 0))
diff --git a/src/unix/linux_glimp.c b/src/unix/linux_glimp.c
index e6a86997..36e3dc36 100644
--- a/src/unix/linux_glimp.c
+++ b/src/unix/linux_glimp.c
@@ -1324,6 +1324,30 @@ static void GLW_InitExtensions( void )
ri.Printf( PRINT_ALL, "...GL_EXT_compiled_vertex_array not found\n" );
}
+ glConfig.textureFilterAnisotropic = qfalse;
+ if ( strstr( glConfig.extensions_string, "GL_EXT_texture_filter_anisotropic" ) )
+ {
+ if ( r_ext_texture_filter_anisotropic->integer ) {
+ qglGetIntegerv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.maxAnisotropy );
+ if ( glConfig.maxAnisotropy <= 0 ) {
+ ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not properly supported!\n" );
+ glConfig.maxAnisotropy = 0;
+ }
+ else
+ {
+ ri.Printf( PRINT_ALL, "...using GL_EXT_texture_filter_anisotropic (max: %i)\n", glConfig.maxAnisotropy );
+ glConfig.textureFilterAnisotropic = qtrue;
+ }
+ }
+ else
+ {
+ ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_filter_anisotropic\n" );
+ }
+ }
+ else
+ {
+ ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not found\n" );
+ }
}
static void GLW_InitGamma(void)
diff --git a/src/unix/linux_signals.c b/src/unix/linux_signals.c
index 5d94f68b..72c5a522 100644
--- a/src/unix/linux_signals.c
+++ b/src/unix/linux_signals.c
@@ -47,6 +47,7 @@ static void signal_handler(int sig) // bk010104 - replace this... (NOTE TTimo hu
// rcg08312005 Agreed: changed to CL_Shutdown... --ryan.
CL_Shutdown();
#endif
+ SV_Shutdown("Signal caught");
Sys_Exit(0); // bk010104 - abstraction NOTE TTimo send a 0 to avoid DOUBLE SIGNAL FAULT
}
diff --git a/src/unix/sdl_glimp.c b/src/unix/sdl_glimp.c
index f7720790..4469f9e0 100644
--- a/src/unix/sdl_glimp.c
+++ b/src/unix/sdl_glimp.c
@@ -439,15 +439,35 @@ void IN_DeactivateMouse( void )
*/
void GLimp_SetGamma( unsigned char red[256], unsigned char green[256], unsigned char blue[256] )
{
- // NOTE TTimo we get the gamma value from cvar, because we can't work with the s_gammatable
- // the API wasn't changed to avoid breaking other OSes
- float g;
+ Uint16 table[3][256];
+ int i, j;
+// float g;
- if ( r_ignorehwgamma->integer )
- return;
+ if(r_ignorehwgamma->integer)
+ return;
+
+ // taken from win_gamma.c:
+ for (i = 0; i < 256; i++)
+ {
+ table[0][i] = ( ( ( Uint16 ) red[i] ) << 8 ) | red[i];
+ table[1][i] = ( ( ( Uint16 ) green[i] ) << 8 ) | green[i];
+ table[2][i] = ( ( ( Uint16 ) blue[i] ) << 8 ) | blue[i];
+ }
- g = Cvar_Get("r_gamma", "1.0", 0)->value;
- SDL_SetGamma(g, g, g);
+ // enforce constantly increasing
+ for (j = 0; j < 3; j++)
+ {
+ for (i = 1; i < 256; i++)
+ {
+ if (table[j][i] < table[j][i-1])
+ table[j][i] = table[j][i-1];
+ }
+ }
+
+ SDL_SetGammaRamp(table[0], table[1], table[2]);
+
+// g = Cvar_Get("r_gamma", "1.0", 0)->value;
+// SDL_SetGamma(g, g, g);
}
/*
@@ -554,7 +574,12 @@ static int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen )
Uint32 flags = SDL_OPENGL;
if (fullscreen)
+ {
flags |= SDL_FULLSCREEN;
+ glConfig.isFullscreen = qtrue;
+ }
+ else
+ glConfig.isFullscreen = qfalse;
if (!r_colorbits->value)
colorbits = 24;
@@ -626,7 +651,6 @@ static int GLW_SetMode( const char *drivername, int mode, qboolean fullscreen )
tstencilbits = 0;
}
- sdlcolorbits = 4;
if (tcolorbits == 24)
sdlcolorbits = 8;
@@ -804,6 +828,30 @@ static void GLW_InitExtensions( void )
ri.Printf( PRINT_ALL, "...GL_EXT_compiled_vertex_array not found\n" );
}
+ glConfig.textureFilterAnisotropic = qfalse;
+ if ( strstr( glConfig.extensions_string, "GL_EXT_texture_filter_anisotropic" ) )
+ {
+ if ( r_ext_texture_filter_anisotropic->integer ) {
+ qglGetIntegerv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.maxAnisotropy );
+ if ( glConfig.maxAnisotropy <= 0 ) {
+ ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not properly supported!\n" );
+ glConfig.maxAnisotropy = 0;
+ }
+ else
+ {
+ ri.Printf( PRINT_ALL, "...using GL_EXT_texture_filter_anisotropic (max: %i)\n", glConfig.maxAnisotropy );
+ glConfig.textureFilterAnisotropic = qtrue;
+ }
+ }
+ else
+ {
+ ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_filter_anisotropic\n" );
+ }
+ }
+ else
+ {
+ ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not found\n" );
+ }
}
static void GLW_InitGamma( void )
diff --git a/src/win32/win_glimp.c b/src/win32/win_glimp.c
index 187fd7b9..22e98e5f 100644
--- a/src/win32/win_glimp.c
+++ b/src/win32/win_glimp.c
@@ -1112,6 +1112,31 @@ static void GLW_InitExtensions( void )
{
ri.Printf( PRINT_ALL, "...WGL_3DFX_gamma_control not found\n" );
}
+
+ glConfig.textureFilterAnisotropic = qfalse;
+ if ( strstr( glConfig.extensions_string, "GL_EXT_texture_filter_anisotropic" ) )
+ {
+ if ( r_ext_texture_filter_anisotropic->integer ) {
+ qglGetIntegerv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &glConfig.maxAnisotropy );
+ if ( glConfig.maxAnisotropy <= 0 ) {
+ ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not properly supported!\n" );
+ glConfig.maxAnisotropy = 0;
+ }
+ else
+ {
+ ri.Printf( PRINT_ALL, "...using GL_EXT_texture_filter_anisotropic (max: %i)\n", glConfig.maxAnisotropy );
+ glConfig.textureFilterAnisotropic = qtrue;
+ }
+ }
+ else
+ {
+ ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_filter_anisotropic\n" );
+ }
+ }
+ else
+ {
+ ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not found\n" );
+ }
}
/*
diff --git a/ui/ingame_options.menu b/ui/ingame_options.menu
index 75adbd3d..47914b4a 100644
--- a/ui/ingame_options.menu
+++ b/ui/ingame_options.menu
@@ -1255,7 +1255,7 @@
text "Quality:"
cvar "ui_glCustom"
cvarFloatList { "High Quality" 0 "Normal" 1 "Fast" 2 "Fastest" 3 "Custom" 4 }
- rect 96 55 192 15
+ rect 96 50 192 15
textalign ITEM_ALIGN_RIGHT
textalignx 100
textaligny 12
@@ -1277,7 +1277,7 @@
text "GL Driver:"
cvar "r_gldriver"
//cvarFloatList { }
- rect 96 70 192 15
+ rect 96 65 192 15
textalign ITEM_ALIGN_RIGHT
textalignx 100
textaligny 12
@@ -1294,7 +1294,7 @@
type ITEM_TYPE_YESNO
text "GL Extensions:"
cvar "r_allowExtensions"
- rect 96 85 192 15
+ rect 96 80 192 15
textalign ITEM_ALIGN_RIGHT
textalignx 100
textaligny 12
@@ -1318,7 +1318,7 @@
cvarFloatList { "320x240" 0 "400x300" 1 "512x384" 2 "640x480" 3
"800x600" 4 "960x720" 5 "1024x768" 6 "1152x864" 7
"1280x1024" 8 "1600x1200" 9 "2048x1536" 10 "856x480 wide screen" 11 }
- rect 96 100 192 15
+ rect 96 95 192 15
textalign ITEM_ALIGN_RIGHT
textalignx 100
textaligny 12
@@ -1340,7 +1340,7 @@
text "Color Depth:"
cvar "r_colorbits"
cvarFloatList { "Default" 0 "16 bit" 16 "32 bit" 32 }
- rect 96 115 192 15
+ rect 96 110 192 15
textalign ITEM_ALIGN_RIGHT
textalignx 100
textaligny 12
@@ -1362,7 +1362,7 @@
type ITEM_TYPE_YESNO
text "Fullscreen:"
cvar "r_fullscreen"
- rect 96 130 192 15
+ rect 96 125 192 15
textalign ITEM_ALIGN_RIGHT
textalignx 100
textaligny 12
@@ -1384,7 +1384,7 @@
text "Lighting:"
cvar "r_vertexlight"
cvarFloatList { "Light Map (high)" 0 "Vertex (low)" 1 }
- rect 96 145 192 15
+ rect 96 140 192 15
textalign ITEM_ALIGN_RIGHT
textalignx 100
textaligny 12
@@ -1406,7 +1406,7 @@
text "Geometric Detail:"
cvar "r_lodbias"
cvarFloatList { "High" 0 "Medium" 1 "Low" 2 }
- rect 96 160 192 15
+ rect 96 155 192 15
textalign ITEM_ALIGN_RIGHT
textalignx 100
textaligny 12
@@ -1429,7 +1429,7 @@
text "Texture Detail:"
cvar "r_picmip"
cvarFloatList { "Low" 2 "Normal" 1 "High" 0 }
- rect 96 175 192 15
+ rect 96 170 192 15
textalign ITEM_ALIGN_RIGHT
textalignx 100
textaligny 12
@@ -1451,7 +1451,7 @@
text "Texture Quality:"
cvar "r_texturebits"
cvarFloatList { "Default" 0 "16 bit" 16 "32 bit" 32 }
- rect 96 190 192 15
+ rect 96 185 192 15
textalign ITEM_ALIGN_RIGHT
textalignx 100
textaligny 12
@@ -1472,7 +1472,28 @@
text "Texture Filter:"
cvar "r_texturemode"
cvarStrList { "Bilinear", "GL_LINEAR_MIPMAP_NEAREST", "Trilinear", "GL_LINEAR_MIPMAP_LINEAR" }
- rect 96 205 192 15
+ rect 96 200 192 15
+ textalign ITEM_ALIGN_RIGHT
+ textalignx 100
+ textaligny 12
+ textscale .25
+ forecolor 1 1 1 1
+ visible 0
+ action
+ {
+ play "sound/misc/menu1.wav";
+ uiScript glCustom
+ }
+ }
+
+ itemDef
+ {
+ name ghardware
+ group optionsGrp
+ type ITEM_TYPE_YESNO
+ text "Anisotropic Filtering:"
+ cvar "r_ext_texture_filter_anisotropic"
+ rect 96 215 192 15
textalign ITEM_ALIGN_RIGHT
textalignx 100
textaligny 12
@@ -1493,7 +1514,7 @@
type ITEM_TYPE_YESNO
text "Compress Textures:"
cvar "r_ext_compressed_textures "
- rect 96 220 192 15
+ rect 96 230 192 15
textalign ITEM_ALIGN_RIGHT
textalignx 100
textaligny 12
@@ -1515,7 +1536,7 @@
text "APPLY"
textscale .25
style WINDOW_STYLE_EMPTY
- rect 144 240 75 20
+ rect 144 245 75 20
textalign ITEM_ALIGN_CENTER
textalignx 37
textaligny 15