warn clients when stuff will be invisible due to protocol limits. this does not include extra features, only limits.

try to handle mvd prespawning a little more generically, to enable support for vweps (when protocol extensions are active). also fix issues with mid-demo map changes, which can potentially affect qtv streams.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4795 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-12-02 02:00:41 +00:00
parent 512fad39fb
commit 4d9ee2395a
17 changed files with 213 additions and 77 deletions

View file

@ -38,12 +38,14 @@ RELEASE_DIR=$(BASE_DIR)/release
DEBUG_DIR=$(BASE_DIR)/debug DEBUG_DIR=$(BASE_DIR)/debug
PROFILE_DIR=$(BASE_DIR)/profile PROFILE_DIR=$(BASE_DIR)/profile
COMPILE_SYS:=$(shell uname -o 2>&1) COMPILE_SYS:=$(shell uname -o 2>&1)
NATIVE_ABSBASE_DIR:=$(realpath $(BASE_DIR))
ifeq ($(COMPILE_SYS),Cygwin) ifeq ($(COMPILE_SYS),Cygwin)
OUT_DIR?=. OUT_DIR?=.
NATIVE_OUT_DIR:=$(shell cygpath -m $(OUT_DIR)) NATIVE_OUT_DIR:=$(shell cygpath -m $(OUT_DIR))
NATIVE_BASE_DIR:=$(shell cygpath -m $(BASE_DIR)) NATIVE_BASE_DIR:=$(shell cygpath -m $(BASE_DIR))
NATIVE_RELEASE_DIR:=$(shell cygpath -m $(RELEASE_DIR)) NATIVE_RELEASE_DIR:=$(shell cygpath -m $(RELEASE_DIR))
NATIVE_DEBUG_DIR:=$(shell cygpath -m $(DEBUG_DIR)) NATIVE_DEBUG_DIR:=$(shell cygpath -m $(DEBUG_DIR))
NATIVE_ABSBASE_DIR:=$(shell cygpath -m $(NATIVE_ABSBASE_DIR))
endif endif
NATIVE_OUT_DIR?=$(OUT_DIR) NATIVE_OUT_DIR?=$(OUT_DIR)
NATIVE_BASE_DIR?=$(BASE_DIR) NATIVE_BASE_DIR?=$(BASE_DIR)
@ -122,19 +124,34 @@ ifeq ($(FTE_TARGET),droid)
#if we're running under windows, then we want to run some other binary #if we're running under windows, then we want to run some other binary
ifeq ($(shell uname -o 2>&1 | grep Cygwin),) ifeq ($(shell uname -o 2>&1 | grep Cygwin),)
#set up for linux #set up for linux
TOOLCHAIN:=$(ANDROID_NDK_ROOT)/toolchains/arm-linux-androideabi-4.7/prebuilt/linux-x86/bin/arm-linux-androideabi- ifeq ($(DROID_ARCH),x86)
TOOLCHAINPATH:=$(ANDROID_NDK_ROOT)/toolchains/x86-4.7/prebuilt/linux-x86/bin/
TOOLCHAIN:=$(TOOLCHAINPATH)i686-linux-androideabi-
else
TOOLCHAINPATH:=$(ANDROID_NDK_ROOT)/toolchains/arm-linux-androideabi-4.7/prebuilt/linux-x86/bin/
TOOLCHAIN:=$(TOOLCHAINPATH)arm-linux-androideabi-
endif
TOOLOVERRIDES=PATH="/usr/bin:$(realpath $(TOOLCHAINPATH))" CFLAGS=--sysroot="$(realpath $(ANDROID_NDK_ROOT)/platforms/android-$(DROID_API_LEVEL)/$(DROID_PLAT_INC))" CPPFLAGS=--sysroot="$(realpath $(ANDROID_NDK_ROOT)/platforms/android-$(DROID_API_LEVEL)/$(DROID_PLAT_INC))"
CONFIGARGS= --with-sysroot="$(realpath $(ANDROID_NDK_ROOT)/platforms/android-$(DROID_API_LEVEL)/$(DROID_PLAT_INC))"
else else
#FIXME: support mingw too... #FIXME: support mingw too...
#we're running upon windows #we're running upon windows
ifeq ($(DROID_ARCH),x86) ifeq ($(DROID_ARCH),x86)
TOOLCHAIN:=$(ANDROID_NDK_ROOT)/toolchains/x86-4.7/prebuilt/windows-x86_64/bin/i686-linux-android- TOOLCHAINPATH:=$(ANDROID_NDK_ROOT)/toolchains/x86-4.7/prebuilt/windows-x86_64/bin/
TOOLCHAIN:=$(TOOLCHAINPATH)i686-linux-android-
else else
TOOLCHAIN:=$(ANDROID_NDK_ROOT)/toolchains/arm-linux-androideabi-4.7/prebuilt/windows-x86_64/bin/arm-linux-androideabi- TOOLCHAINPATH:=$(ANDROID_NDK_ROOT)/toolchains/arm-linux-androideabi-4.7/prebuilt/windows-x86_64/bin/
TOOLCHAIN:=$(TOOLCHAINPATH)arm-linux-androideabi-
endif endif
ANDROID_SCRIPT=android.bat ANDROID_SCRIPT=android.bat
#make can't cope with absolute win32 paths in dependancy files #make can't cope with absolute win32 paths in dependancy files
DEPCC= DEPCC=
#configure hates android, with its broken default sysroot and lack of path etc
TOOLOVERRIDES=PATH="/usr/bin:$(shell cygpath -u $(realpath $(TOOLCHAINPATH)))" CFLAGS=--sysroot="$(shell cygpath -m $(realpath $(ANDROID_NDK_ROOT)/platforms/android-$(DROID_API_LEVEL)/$(DROID_PLAT_INC)))" CPPFLAGS=--sysroot="$(shell cygpath -m $(realpath $(ANDROID_NDK_ROOT)/platforms/android-$(DROID_API_LEVEL)/$(DROID_PLAT_INC)))"
CONFIGARGS= --with-sysroot="$(shell cygpath -u $(realpath $(ANDROID_NDK_ROOT)/platforms/android-$(DROID_API_LEVEL)/$(DROID_PLAT_INC)))"
endif endif
DROID_API_LEVEL=4 DROID_API_LEVEL=4
@ -152,10 +169,11 @@ ifeq ($(FTE_TARGET),droid)
#armv7+neon #armv7+neon
DROID_ABI?=-mfloat-abi=softfp DROID_ABI?=-mfloat-abi=softfp
endif endif
CC:=$(TOOLCHAIN)gcc --sysroot="$(shell cygpath -m $(realpath $(ANDROID_NDK_ROOT)/platforms/android-$(DROID_API_LEVEL)/$(DROID_PLAT_INC)))" -DANDROID $(DROID_ABI) -fno-strict-aliasing
DO_LD:=$(DO_ECHO) $(CC) -Wl,-soname,libftedroid.so -shared -Wl,--no-undefined -Wl,-z,noexecstack -o $@ $(LTO_LD) $(WCFLAGS) $(BRANDFLAGS) $(CFLAGS) -llog -lc -lz -lm
LD:=$(TOOLCHAIN)ld
AR:=$(TOOLCHAIN)ar
STRIP=$(TOOLCHAIN)strip STRIP=$(TOOLCHAIN)strip
CC=$(TOOLCHAIN)gcc -I$(ANDROID_NDK_ROOT)/platforms/android-$(DROID_API_LEVEL)/$(DROID_PLAT_INC)/usr/include/ -DANDROID $(DROID_ABI) -fno-strict-aliasing
DO_LD=$(DO_ECHO) $(CC) -Wl,-soname,libftedroid.so -shared -Wl,--no-undefined -Wl,-z,noexecstack --sysroot=$(ANDROID_NDK_ROOT)/platforms/android-$(DROID_API_LEVEL)/$(DROID_PLAT_INC) -L$(NDK_PATH)/platforms/android-$(DROID_API_LEVEL)/$(DROID_PLAT_INC)/usr/lib -o $@ $(LTO_LD) $(WCFLAGS) $(BRANDFLAGS) $(CFLAGS) -llog -lc -lz -lm
endif endif
@ -1751,23 +1769,41 @@ $(BASE_DIR)/libs/SDL2-2.0.1/i686-w64-mingw32/bin/sdl2-config:
rm $(BASE_DIR)/sdl2.tar.gz rm $(BASE_DIR)/sdl2.tar.gz
$(BASE_DIR)/libs/SDL2-2.0.1/x86_64-w64-mingw32/bin/sdl2-config: $(BASE_DIR)/libs/SDL2-2.0.1/i686-w64-mingw32/bin/sdl2-config $(BASE_DIR)/libs/SDL2-2.0.1/x86_64-w64-mingw32/bin/sdl2-config: $(BASE_DIR)/libs/SDL2-2.0.1/i686-w64-mingw32/bin/sdl2-config
#update these to download+build a different version. this assumes that the url+subdirs etc contain a consistant version everywhere.
JPEGVER=9a
ZLIBVER=1.2.8
PNGVER=1.6.14
OGGVER=1.3.2
VORBISVER=1.3.4
#makes sure the configure scripts get the right idea.
AR?=$(ARCH)-ar
CONFIGARGS+= -host=$(ARCH) --enable-shared=no
#--disable-silent-rules
makelibs: makelibs:
#lock these down, to avoid expanding them too often
#TOOLOVERRIDES:=$(TOOLOVERRIDES)
#CONFIGARGS:=$(CONFIGARGS)
ifndef ARCH ifndef ARCH
$(MAKE) makelibs ARCH=$(shell $(CC) -dumpmachine) $(MAKE) makelibs ARCH=$(shell $(CC) -dumpmachine)
else else
mkdir -p libs-$(ARCH) mkdir -p libs-$(ARCH)
test -f jpegsrc.v9.tar.gz || wget http://www.ijg.org/files/jpegsrc.v9.tar.gz test -f jpegsrc.v$(JPEGVER).tar.gz || wget http://www.ijg.org/files/jpegsrc.v$(JPEGVER).tar.gz
-test -f libs-$(ARCH)/libjpeg.a || (cd libs-$(ARCH) && tar -xvzf ../jpegsrc.v9.tar.gz && cd jpeg-9 && ./configure -host=$(ARCH) && $(MAKE) && cp .libs/libjpeg.a ../ && $(ARCH)-ar -s ../libjpeg.a ) -test -f libs-$(ARCH)/libjpeg.a || (cd libs-$(ARCH) && tar -xvzf ../jpegsrc.v$(JPEGVER).tar.gz && cd jpeg-$(JPEGVER) && $(TOOLOVERRIDES) ./configure $(CONFIGARGS) && $(TOOLOVERRIDES) $(MAKE) && cp .libs/libjpeg.a ../ && $(TOOLOVERRIDES) $(AR) -s ../libjpeg.a && cp jconfig.h jerror.h jmorecfg.h jpeglib.h jversion.h ../ )
test -f zlib-1.2.8.tar.gz || wget http://zlib.net/zlib-1.2.8.tar.gz test -f zlib-$(ZLIBVER).tar.gz || wget http://zlib.net/zlib-$(ZLIBVER).tar.gz
-test -f libs-$(ARCH)/libz.a || (cd libs-$(ARCH) && tar -xvzf ../zlib-1.2.8.tar.gz && cd zlib-1.2.8 && CC="$(CC) $(W32_CFLAGS)" ./configure --static && $(MAKE) libz.a CC="$(CC) $(W32_CFLAGS)" && cp libz.a ../ && $(ARCH)-ar -s ../libz.a ) -test -f libs-$(ARCH)/libz.a || (cd libs-$(ARCH) && tar -xvzf ../zlib-$(ZLIBVER).tar.gz && cd zlib-$(ZLIBVER) && $(TOOLOVERRIDES) ./configure --static && $(TOOLOVERRIDES) $(MAKE) libz.a CC="$(CC) $(W32_CFLAGS)" && cp libz.a ../ && $(TOOLOVERRIDES) $(AR) -s ../libz.a && cp zlib.h zconf.h zutil.h ../ )
test -f libpng-1.6.2.tar.gz || wget http://prdownloads.sourceforge.net/libpng/libpng-1.6.2.tar.gz?download -O libpng-1.6.2.tar.gz test -f libpng-$(PNGVER).tar.gz || wget http://prdownloads.sourceforge.net/libpng/libpng-$(PNGVER).tar.gz?download -O libpng-$(PNGVER).tar.gz
-test -f libs-$(ARCH)/libpng.a || (cd libs-$(ARCH) && tar -xvzf ../libpng-1.6.2.tar.gz && cd libpng-1.6.2 && ./configure -host=$(ARCH) CFLAGS=-I$(realpath libs-$(ARCH)/zlib-1.2.8/) LDFLAGS=-L$(realpath libs-$(ARCH)) && $(MAKE) && cp .libs/libpng16.a ../libpng.a ) -test -f libs-$(ARCH)/libpng.a || (cd libs-$(ARCH) && tar -xvzf ../libpng-$(PNGVER).tar.gz && cd libpng-$(PNGVER) && $(TOOLOVERRIDES) ./configure $(CONFIGARGS) --with-zlib-prefix=$(NATIVE_ABSBASE_DIR)/libs-$(ARCH)/zlib-$(ZLIBVER)/ && $(TOOLOVERRIDES) $(MAKE) && cp .libs/libpng16.a ../libpng.a && cp png*.h ../ )
test -f libogg-1.3.0.tar.gz || wget http://downloads.xiph.org/releases/ogg/libogg-1.3.0.tar.gz test -f libogg-$(OGGVER).tar.gz || wget http://downloads.xiph.org/releases/ogg/libogg-$(OGGVER).tar.gz
-test -f libs-$(ARCH)/libogg.a || (cd libs-$(ARCH) && tar -xvzf ../libogg-1.3.0.tar.gz && cd libogg-1.3.0 && ./configure -host=$(ARCH) && $(MAKE) && cp src/.libs/libogg.a ../ && $(ARCH)-ar -s ../libogg.a) -test -f libs-$(ARCH)/libogg.a || (cd libs-$(ARCH) && tar -xvzf ../libogg-$(OGGVER).tar.gz && cd libogg-$(OGGVER) && $(TOOLOVERRIDES) ./configure $(CONFIGARGS) && $(TOOLOVERRIDES) $(MAKE) && cp src/.libs/libogg.a ../ && $(TOOLOVERRIDES) $(AR) -s ../libogg.a)
test -f libvorbis-1.3.3.tar.gz || wget http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.3.tar.gz test -f libvorbis-$(VORBISVER).tar.gz || wget http://downloads.xiph.org/releases/vorbis/libvorbis-$(VORBISVER).tar.gz
-test -f libs-$(ARCH)/libvorbisfile.a || (cd libs-$(ARCH) && tar -xvzf ../libvorbis-1.3.3.tar.gz && cd libvorbis-1.3.3 && ./configure PKG_CONFIG= -host=$(ARCH) --disable-oggtest --with-ogg-libraries=.. --with-ogg-includes=$(realpath libs-$(ARCH)/libogg-1.3.0/include) && $(MAKE) && cp lib/.libs/libvorbis.a ../ && cp lib/.libs/libvorbisfile.a ../ ) -test -f libs-$(ARCH)/libvorbisfile.a || (cd libs-$(ARCH) && tar -xvzf ../libvorbis-$(VORBISVER).tar.gz && cd libvorbis-$(VORBISVER) && $(TOOLOVERRIDES) ./configure PKG_CONFIG= $(CONFIGARGS) --disable-oggtest --with-ogg-libraries=.. --with-ogg-includes=$(NATIVE_ABSBASE_DIR)/libs-$(ARCH)/libogg-$(OGGVER)/include && $(TOOLOVERRIDES) $(MAKE) && cp lib/.libs/libvorbis.a ../ && cp lib/.libs/libvorbisfile.a ../ )
endif endif

View file

@ -438,7 +438,7 @@ int CG_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projecti
VectorNormalize(axis[2]); VectorNormalize(axis[2]);
VectorNormalize2(projection, axis[0]); VectorNormalize2(projection, axis[0]);
numtris = Q1BSP_ClipDecal(center, axis[0], axis[1], axis[2], radius, &clippedpoints); numtris = Q1BSP_ClipDecal(cl.worldmodel, center, axis[0], axis[1], axis[2], radius, &clippedpoints);
if (numtris > maxFragments) if (numtris > maxFragments)
numtris = maxFragments; numtris = maxFragments;
if (numtris > maxPoints/3) if (numtris > maxPoints/3)

View file

@ -2520,7 +2520,7 @@ void CL_AddDecal(shader_t *shader, vec3_t origin, vec3_t up, vec3_t side, vec3_t
VectorScale(tang, s/l, tang); VectorScale(tang, s/l, tang);
num = Q1BSP_ClipDecal(origin, up, side, tang, 2, &verts); num = Q1BSP_ClipDecal(cl.worldmodel, origin, up, side, tang, 2, &verts);
if (!num) if (!num)
return; return;
@ -2637,7 +2637,7 @@ void CLQ1_AddShadow(entity_t *ent)
AngleVectors(eang, axis[0], axis[1], axis[2]); AngleVectors(eang, axis[0], axis[1], axis[2]);
VectorNegate(axis[2], axis[2]); VectorNegate(axis[2], axis[2]);
num = Q1BSP_ClipDecal(shadoworg, axis[2], axis[1], axis[0], radius, &verts); num = Q1BSP_ClipDecal(cl.worldmodel, shadoworg, axis[2], axis[1], axis[0], radius, &verts);
if (!num) if (!num)
return; return;
@ -3748,16 +3748,6 @@ extern int cl_spikeindex, cl_playerindex, cl_flagindex, cl_rocketindex, cl_gren
entity_t *CL_NewTempEntity (void); entity_t *CL_NewTempEntity (void);
#define DF_ORIGIN 1
#define DF_ANGLES (1<<3)
#define DF_EFFECTS (1<<6)
#define DF_SKINNUM (1<<7)
#define DF_DEAD (1<<8)
#define DF_GIB (1<<9)
#define DF_WEAPONFRAME (1<<10)
#define DF_MODEL (1<<11)
static int MVD_TranslateFlags(int src) static int MVD_TranslateFlags(int src)
{ {
int dst = 0; int dst = 0;
@ -3849,7 +3839,7 @@ void CL_ParsePlayerinfo (void)
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
if (flags & (DF_ORIGIN << i)) if (flags & (DF_ORIGINX << i))
state->origin[i] = MSG_ReadCoord (); state->origin[i] = MSG_ReadCoord ();
} }
@ -3859,7 +3849,7 @@ void CL_ParsePlayerinfo (void)
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
if (flags & (DF_ANGLES << i)) if (flags & (DF_ANGLEX << i))
{ {
state->command.angles[i] = MSG_ReadShort(); state->command.angles[i] = MSG_ReadShort();
} }

View file

@ -3616,7 +3616,7 @@ void CL_Init (void)
Cmd_AddCommand ("qtvplay", CL_QTVPlay_f); Cmd_AddCommand ("qtvplay", CL_QTVPlay_f);
Cmd_AddCommand ("qtvlist", CL_QTVList_f); Cmd_AddCommand ("qtvlist", CL_QTVList_f);
Cmd_AddCommand ("qtvdemos", CL_QTVDemos_f); Cmd_AddCommand ("qtvdemos", CL_QTVDemos_f);
Cmd_AddCommand ("demo_jump", CL_DemoJump_f); Cmd_AddCommandD ("demo_jump", CL_DemoJump_f, "Jump to a specified time in a demo. Prefix with a + or - for a relative offset. Seeking backwards will restart the demo and the fast forward, which can take some time in long demos.");
Cmd_AddCommand ("timedemo", CL_TimeDemo_f); Cmd_AddCommand ("timedemo", CL_TimeDemo_f);
Cmd_AddCommand ("crashme_endgame", CL_CrashMeEndgame_f); Cmd_AddCommand ("crashme_endgame", CL_CrashMeEndgame_f);
@ -3630,7 +3630,7 @@ void CL_Init (void)
Cmd_AddCommand ("allskins", Skin_AllSkins_f); Cmd_AddCommand ("allskins", Skin_AllSkins_f);
Cmd_AddCommand ("cl_status", CL_Status_f); Cmd_AddCommand ("cl_status", CL_Status_f);
Cmd_AddCommand ("quit", CL_Quit_f); Cmd_AddCommandD ("quit", CL_Quit_f, "Use this command when you get angry. Does not save any cvars. Use cfg_save to save settings, or use the menu for a prompt.");
Cmd_AddCommandD ("connect", CL_Connect_f, "connect scheme://address:port\nConnect to a server. Use a scheme of tcp:// or tls:// to connect via non-udp protocols." Cmd_AddCommandD ("connect", CL_Connect_f, "connect scheme://address:port\nConnect to a server. Use a scheme of tcp:// or tls:// to connect via non-udp protocols."
#if defined(NQPROT) || defined(Q2CLIENT) || defined(Q3CLIENT) #if defined(NQPROT) || defined(Q2CLIENT) || defined(Q3CLIENT)

View file

@ -816,7 +816,7 @@ qboolean Master_LoadMasterList (char *filename, qboolean withcomment, int defaul
favourite = true; favourite = true;
} }
if (!*name) if (!*name && next)
{ {
sep = name; sep = name;
while(*next == ' ' || *next == '\t') while(*next == ' ' || *next == '\t')

View file

@ -3667,7 +3667,6 @@ static void PScript_EffectSpawned(part_type_t *ptype, vec3_t org, vec3_t axis[3]
Surf_AddStain(org, ptype->stain_rgb[0], ptype->stain_rgb[1], ptype->stain_rgb[2], ptype->stain_radius); Surf_AddStain(org, ptype->stain_rgb[0], ptype->stain_rgb[1], ptype->stain_rgb[2], ptype->stain_radius);
} }
int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent, vec3_t tangent2, float size, float **out);
static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, int typenum, trailstate_t **tsk) static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, int typenum, trailstate_t **tsk)
{ {
part_type_t *ptype = &part_type[typenum]; part_type_t *ptype = &part_type[typenum];
@ -3823,7 +3822,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
sw /= m; sw /= m;
tw /= m; tw /= m;
decalcount = Q1BSP_ClipDecal(bestorg, dir, tangent, t2, m, &decverts); decalcount = Q1BSP_ClipDecal(cl.worldmodel, bestorg, dir, tangent, t2, m, &decverts);
while(decalcount) while(decalcount)
{ {
if (!free_decals) if (!free_decals)

View file

@ -776,6 +776,25 @@ enum clcq2_ops_e
#define Q2U_SOUND (1<<26) #define Q2U_SOUND (1<<26)
#define Q2U_SOLID (1<<27) #define Q2U_SOLID (1<<27)
//==============================================
//obsolete demo players info
#define DF_ORIGINX (1u<<0)
#define DF_ORIGINY (1u<<1)
#define DF_ORIGINZ (1u<<2)
#define DF_ORIGINALL (DF_ORIGINX|DF_ORIGINY|DF_ORIGINZ)
#define DF_ANGLEX (1u<<3)
#define DF_ANGLEY (1u<<4)
#define DF_ANGLEZ (1u<<5)
#define DF_ANGLESALL (DF_ANGLEX|DF_ANGLEY|DF_ANGLEZ)
#define DF_EFFECTS (1u<<6)
#define DF_SKINNUM (1u<<7)
#define DF_DEAD (1u<<8)
#define DF_GIB (1u<<9)
#define DF_WEAPONFRAME (1u<<10)
#define DF_MODEL (1u<<11)
#define DF_RESET (DF_ORIGINALL|DF_ANGLESALL|DF_EFFECTS|DF_SKINNUM|DF_WEAPONFRAME|DF_MODEL)
//============================================== //==============================================
// a sound with no channel is a local only sound // a sound with no channel is a local only sound

View file

@ -1291,12 +1291,20 @@ void Fragment_ClipPoly(fragmentdecal_t *dec, int numverts, float *inverts)
float verts2[MAXFRAGMENTVERTS*C]; float verts2[MAXFRAGMENTVERTS*C];
float *cverts; float *cverts;
int flip; int flip;
vec3_t d1, d2, n;
if (numverts > MAXFRAGMENTTRIS) if (numverts > MAXFRAGMENTTRIS)
return; return;
if (dec->numtris == MAXFRAGMENTTRIS) if (dec->numtris == MAXFRAGMENTTRIS)
return; //don't bother return; //don't bother
VectorSubtract(inverts+C*1, inverts+C*0, d1);
VectorSubtract(inverts+C*2, inverts+C*0, d2);
CrossProduct(d1, d2, n);
VectorNormalizeFast(n);
if (DotProduct(n, dec->normal) > 0.1)
return; //faces too far way from the normal
//clip to the first plane specially, so we don't have extra copys //clip to the first plane specially, so we don't have extra copys
numverts = Fragment_ClipPolyToPlane(inverts, verts, numverts, dec->planenorm[0], dec->planedist[0]); numverts = Fragment_ClipPolyToPlane(inverts, verts, numverts, dec->planenorm[0], dec->planedist[0]);
@ -1366,7 +1374,7 @@ static void Fragment_Mesh (fragmentdecal_t *dec, mesh_t *mesh)
} }
} }
static void Q1BSP_ClipDecalToNodes (fragmentdecal_t *dec, mnode_t *node) static void Q1BSP_ClipDecalToNodes (model_t *mod, fragmentdecal_t *dec, mnode_t *node)
{ {
mplane_t *splitplane; mplane_t *splitplane;
float dist; float dist;
@ -1381,17 +1389,17 @@ static void Q1BSP_ClipDecalToNodes (fragmentdecal_t *dec, mnode_t *node)
if (dist > dec->radius) if (dist > dec->radius)
{ {
Q1BSP_ClipDecalToNodes (dec, node->children[0]); Q1BSP_ClipDecalToNodes (mod, dec, node->children[0]);
return; return;
} }
if (dist < -dec->radius) if (dist < -dec->radius)
{ {
Q1BSP_ClipDecalToNodes (dec, node->children[1]); Q1BSP_ClipDecalToNodes (mod, dec, node->children[1]);
return; return;
} }
// mark the polygons // mark the polygons
surf = cl.worldmodel->surfaces + node->firstsurface; surf = mod->surfaces + node->firstsurface;
for (i=0 ; i<node->numsurfaces ; i++, surf++) for (i=0 ; i<node->numsurfaces ; i++, surf++)
{ {
if (surf->flags & SURF_PLANEBACK) if (surf->flags & SURF_PLANEBACK)
@ -1407,8 +1415,8 @@ static void Q1BSP_ClipDecalToNodes (fragmentdecal_t *dec, mnode_t *node)
Fragment_Mesh(dec, surf->mesh); Fragment_Mesh(dec, surf->mesh);
} }
Q1BSP_ClipDecalToNodes (dec, node->children[0]); Q1BSP_ClipDecalToNodes (mod, dec, node->children[0]);
Q1BSP_ClipDecalToNodes (dec, node->children[1]); Q1BSP_ClipDecalToNodes (mod, dec, node->children[1]);
} }
#ifdef RTLIGHTS #ifdef RTLIGHTS
@ -1463,7 +1471,8 @@ static void Q3BSP_ClipDecalToNodes (fragmentdecal_t *dec, mnode_t *node)
} }
#endif #endif
int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, float **out) //returns trisoup within a 3d volume.
int Q1BSP_ClipDecal(model_t *mod, vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, float **out)
{ //quad marks a full, independant quad { //quad marks a full, independant quad
int p; int p;
float r; float r;
@ -1493,19 +1502,19 @@ int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangen
sh_shadowframe++; sh_shadowframe++;
if (!cl.worldmodel || cl.worldmodel->type != mod_brush) if (!mod || mod->type != mod_brush)
{ {
} }
else if (cl.worldmodel->fromgame == fg_quake) else if (mod->fromgame == fg_quake)
Q1BSP_ClipDecalToNodes(&dec, cl.worldmodel->nodes); Q1BSP_ClipDecalToNodes(mod, &dec, mod->nodes);
#ifdef Q3BSPS #ifdef Q3BSPS
else if (cl.worldmodel->fromgame == fg_quake3) else if (cl.worldmodel->fromgame == fg_quake3)
Q3BSP_ClipDecalToNodes(&dec, cl.worldmodel->nodes); Q3BSP_ClipDecalToNodes(&dec, mod->nodes);
#endif #endif
#ifdef TERRAIN #ifdef TERRAIN
if (cl.worldmodel && cl.worldmodel->terrain) if (cl.worldmodel && cl.worldmodel->terrain)
Terrain_ClipDecal(&dec, center, dec.radius, cl.worldmodel); Terrain_ClipDecal(&dec, center, dec.radius, mod);
#endif #endif
*out = (float *)decalfragmentverts; *out = (float *)decalfragmentverts;

View file

@ -379,8 +379,6 @@ void D3D9Shader_Init(void)
sh_config.pCreateProgram = D3D9Shader_CreateProgram; sh_config.pCreateProgram = D3D9Shader_CreateProgram;
sh_config.pProgAutoFields = D3D9Shader_ProgAutoFields; sh_config.pProgAutoFields = D3D9Shader_ProgAutoFields;
sh_config.texture_non_power_of_two = 0;
sh_config.texture_non_power_of_two_pic = 0;
sh_config.tex_env_combine = 1; sh_config.tex_env_combine = 1;
sh_config.nv_tex_env_combine4 = 1; sh_config.nv_tex_env_combine4 = 1;
sh_config.env_add = 1; sh_config.env_add = 1;
@ -395,6 +393,18 @@ void D3D9Shader_Init(void)
sh_config.texfmt[PTI_ARGB4444] = true; sh_config.texfmt[PTI_ARGB4444] = true;
IDirect3DDevice9_GetDeviceCaps(pD3DDev9, &caps); IDirect3DDevice9_GetDeviceCaps(pD3DDev9, &caps);
if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
{ //this flag is a LIMITATION, not a capability.
sh_config.texture_non_power_of_two = false;
sh_config.texture_non_power_of_two_pic = !!(caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL); //pic npot is supported if both flags are set.
}
else
{ //modern cards support npot
sh_config.texture_non_power_of_two_pic = true;
sh_config.texture_non_power_of_two = true;
}
sh_config.texture_maxsize = min(caps.MaxTextureWidth, caps.MaxTextureHeight); sh_config.texture_maxsize = min(caps.MaxTextureWidth, caps.MaxTextureHeight);
} }
#endif #endif

View file

@ -497,7 +497,7 @@ void Q1BSP_Init(void);
void *Q1BSPX_FindLump(char *lumpname, int *lumpsize); void *Q1BSPX_FindLump(char *lumpname, int *lumpsize);
void Q1BSPX_Setup(struct model_s *mod, char *filebase, unsigned int filelen, lump_t *lumps, int numlumps); void Q1BSPX_Setup(struct model_s *mod, char *filebase, unsigned int filelen, lump_t *lumps, int numlumps);
int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, float **out); int Q1BSP_ClipDecal(struct model_s *mod, vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, float **out);
void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node); void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node);
void GLQ1BSP_LightPointValues(struct model_s *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); void GLQ1BSP_LightPointValues(struct model_s *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);

View file

@ -1234,6 +1234,7 @@ void R_Clear (void)
/*tbh, this entire function should be in the backend*/ /*tbh, this entire function should be in the backend*/
GL_ForceDepthWritable(); GL_ForceDepthWritable();
{ {
qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
if (r_clear.ival && R_GameRectIsFullscreen() && !(r_refdef.flags & RDF_NOWORLDMODEL)) if (r_clear.ival && R_GameRectIsFullscreen() && !(r_refdef.flags & RDF_NOWORLDMODEL))
{ {
qglClearColor(1, 0, 0, 0); qglClearColor(1, 0, 0, 0);

View file

@ -320,6 +320,7 @@ void (APIENTRY myGLDEBUGPROCAMD)(GLenum source,
break; break;
default: default:
case GL_DEBUG_TYPE_OTHER_ARB: case GL_DEBUG_TYPE_OTHER_ARB:
return;
OutputDebugStringA("Other: "); OutputDebugStringA("Other: ");
break; break;
} }

View file

@ -1078,10 +1078,17 @@ char *PDECL ED_NewString (pubprogfuncs_t *ppf, const char *string, int minlength
if (demarkup && string[i] == '\\' && i < l-1 && string[i+1] != 0) if (demarkup && string[i] == '\\' && i < l-1 && string[i+1] != 0)
{ {
i++; i++;
if (string[i] == 'n') switch(string[i])
*new_p++ = '\n'; {
else case 'n': *new_p++ = '\n'; break;
case '\'': *new_p++ = '\''; break;
case '\"': *new_p++ = '\"'; break;
case 'r': *new_p++ = '\r'; break;
default:
*new_p++ = '\\'; *new_p++ = '\\';
i--;
break;
}
} }
else else
*new_p++ = string[i]; *new_p++ = string[i];

View file

@ -357,6 +357,13 @@ enum
PRESPAWN_DONE PRESPAWN_DONE
}; };
enum
{ //'soft' limits that result in warnings if the client's protocol is too limited.
PLIMIT_ENTITIES = 1u<<0,
PLIMIT_MODELS = 1u<<1,
PLIMIT_SOUNDS = 1u<<2
};
typedef struct client_s typedef struct client_s
{ {
client_conn_state_t state; client_conn_state_t state;
@ -601,6 +608,8 @@ typedef struct client_s
int realip_num; int realip_num;
int realip_ping; int realip_ping;
unsigned int plimitwarned;
float delay; float delay;
laggedpacket_t *laggedpacket; laggedpacket_t *laggedpacket;
laggedpacket_t *laggedpacket_last; laggedpacket_t *laggedpacket_last;
@ -693,6 +702,7 @@ typedef struct
float statsf[MAX_CLIENTS][MAX_CL_STATS]; // ouch! float statsf[MAX_CLIENTS][MAX_CL_STATS]; // ouch!
char *statss[MAX_CLIENTS][MAX_CL_STATS]; // ouch! char *statss[MAX_CLIENTS][MAX_CL_STATS]; // ouch!
client_t recorder; client_t recorder;
qboolean playerreset[MAX_CLIENTS]; //will ensure that the model etc is written when this player is next written.
qboolean fixangle[MAX_CLIENTS]; qboolean fixangle[MAX_CLIENTS];
float fixangletime[MAX_CLIENTS]; float fixangletime[MAX_CLIENTS];
vec3_t angles[MAX_CLIENTS]; vec3_t angles[MAX_CLIENTS];

View file

@ -1202,7 +1202,7 @@ void SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizebuf_t
client->pendingentbits[j] = (client->pendingentbits[j] & ~UF_REMOVE) | UF_RESET2; client->pendingentbits[j] = (client->pendingentbits[j] & ~UF_REMOVE) | UF_RESET2;
client->pendingentbits[j] |= SVFTE_DeltaCalcBits(o, n); client->pendingentbits[j] |= SVFTE_DeltaCalcBits(o, n);
//even if prediction is disabled, we want to force velocity info to be sent for the local player. This is used by view bob and things. //even if prediction is disabled, we want to force velocity info to be sent for the local player. This is used by view bob and things.
if (j == client->edict->entnum && (n->u.q1.velocity[0] || n->u.q1.velocity[1] || n->u.q1.velocity[2])) if (client->edict && j == client->edict->entnum && (n->u.q1.velocity[0] || n->u.q1.velocity[1] || n->u.q1.velocity[2]))
client->pendingentbits[j] |= UF_PREDINFO; client->pendingentbits[j] |= UF_PREDINFO;
} }
*o = *n; *o = *n;
@ -2058,8 +2058,6 @@ void SV_WritePlayersToMVD (client_t *client, client_frame_t *frame, sizebuf_t *m
demo_frame_t *demo_frame; demo_frame_t *demo_frame;
demo_client_t *dcl; demo_client_t *dcl;
#define DF_DEAD (1<<8)
#define DF_GIB (1<<9)
demo_frame = &demo.frames[demo.parsecount&DEMO_FRAMES_MASK]; demo_frame = &demo.frames[demo.parsecount&DEMO_FRAMES_MASK];
for (j=0,cl=svs.clients, dcl = demo_frame->clients; j < svs.allocated_client_slots ; j++,cl++, dcl++) for (j=0,cl=svs.clients, dcl = demo_frame->clients; j < svs.allocated_client_slots ; j++,cl++, dcl++)
@ -3171,7 +3169,16 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, pvscamera_t
else else
e = 1; e = 1;
limit = min(client->max_net_ents, sv.world.num_edicts); limit = sv.world.num_edicts;
if (client->max_net_ents < limit)
{
limit = client->max_net_ents;
if (!(client->plimitwarned & PLIMIT_ENTITIES))
{
client->plimitwarned |= PLIMIT_ENTITIES;
SV_ClientPrintf(client, PRINT_HIGH, "WARNING: Your client's network protocol only supports %i entities. Please upgrade or enable extensions.\n", client->max_net_ents);
}
}
if (client->penalties & BAN_BLIND) if (client->penalties & BAN_BLIND)
{ {

View file

@ -756,7 +756,7 @@ void SV_MVDPings (void)
client_t *client; client_t *client;
int j; int j;
for (j = 0, client = svs.clients; j < demo.recorder.max_net_clients; j++, client++) for (j = 0, client = svs.clients; j < demo.recorder.max_net_clients && j < svs.allocated_client_slots; j++, client++)
{ {
if (client->state != cs_spawned) if (client->state != cs_spawned)
continue; continue;
@ -1060,15 +1060,6 @@ float adjustangle(float current, float ideal, float fraction)
return (current + move); return (current + move);
} }
#define DF_ORIGIN 1
#define DF_ANGLES (1<<3)
#define DF_EFFECTS (1<<6)
#define DF_SKINNUM (1<<7)
#define DF_DEAD (1<<8)
#define DF_GIB (1<<9)
#define DF_WEAPONFRAME (1<<10)
#define DF_MODEL (1<<11)
qboolean SV_MVDWritePackets (int num) qboolean SV_MVDWritePackets (int num)
{ {
demo_frame_t *frame, *nextframe; demo_frame_t *frame, *nextframe;
@ -1145,7 +1136,13 @@ qboolean SV_MVDWritePackets (int num)
} }
// now write it to buf // now write it to buf
flags = cl->flags; flags = cl->flags; //df_dead/df_gib
if (demo.playerreset[i])
{
demo.playerreset[i] = false;
flags |= DF_RESET;
}
if (cl->fixangle) if (cl->fixangle)
{ {
@ -1154,13 +1151,13 @@ qboolean SV_MVDWritePackets (int num)
for (j=0; j < 3; j++) for (j=0; j < 3; j++)
if (origin[j] != demoinfo->origin[i]) if (origin[j] != demoinfo->origin[i])
flags |= DF_ORIGIN << j; flags |= DF_ORIGINX << j;
if (cl->fixangle || demo.fixangletime[i] != cl->cmdtime) if (cl->fixangle || demo.fixangletime[i] != cl->cmdtime)
{ {
for (j=0; j < 3; j++) for (j=0; j < 3; j++)
if (angles[j] != demoinfo->angles[j]) if (angles[j] != demoinfo->angles[j])
flags |= DF_ANGLES << j; flags |= DF_ANGLEX << j;
} }
if (cl->info.model != demoinfo->model) if (cl->info.model != demoinfo->model)
@ -1179,11 +1176,11 @@ qboolean SV_MVDWritePackets (int num)
MSG_WriteByte (&msg, cl->frame); MSG_WriteByte (&msg, cl->frame);
for (j=0 ; j<3 ; j++) for (j=0 ; j<3 ; j++)
if (flags & (DF_ORIGIN << j)) if (flags & (DF_ORIGINX << j))
MSG_WriteCoord (&msg, origin[j]); MSG_WriteCoord (&msg, origin[j]);
for (j=0 ; j<3 ; j++) for (j=0 ; j<3 ; j++)
if (flags & (DF_ANGLES << j)) if (flags & (DF_ANGLEX << j))
MSG_WriteAngle16 (&msg, angles[j]); MSG_WriteAngle16 (&msg, angles[j]);
@ -1686,7 +1683,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
{ {
sizebuf_t buf; sizebuf_t buf;
char buf_data[MAX_QWMSGLEN]; char buf_data[MAX_QWMSGLEN];
int n, i; int n, i, j;
const char *s; const char *s;
client_t *player; client_t *player;
@ -1764,6 +1761,29 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
MSG_WriteFloat(&buf, movevars.waterfriction); MSG_WriteFloat(&buf, movevars.waterfriction);
MSG_WriteFloat(&buf, movevars.entgravity); MSG_WriteFloat(&buf, movevars.entgravity);
SV_WriteRecordMVDMessage (&buf);
SZ_Clear (&buf);
#if 1
demo.recorder.prespawn_stage = PRESPAWN_SERVERINFO;
demo.recorder.prespawn_idx = 0;
demo.recorder.netchan.message = buf;
while (demo.recorder.prespawn_stage != PRESPAWN_DONE)
{
if (demo.recorder.prespawn_stage == PRESPAWN_MAPCHECK)
{
demo.recorder.prespawn_stage++;//client won't reply, so don't wait.
demo.recorder.prespawn_idx = 0;
}
if (demo.recorder.prespawn_stage == PRESPAWN_SOUNDLIST || demo.recorder.prespawn_stage == PRESPAWN_MODELLIST)
demo.recorder.prespawn_idx &= ~0x80000000; //normally set for the server to wait for ack. we don't want to wait.
SV_SendClientPrespawnInfo(&demo.recorder);
SV_WriteRecordMVDMessage (&demo.recorder.netchan.message);
SZ_Clear (&demo.recorder.netchan.message);
}
memset(&demo.recorder.netchan.message, 0, sizeof(demo.recorder.netchan.message));
#else
// send music // send music
MSG_WriteByte (&buf, svc_cdtrack); MSG_WriteByte (&buf, svc_cdtrack);
MSG_WriteByte (&buf, 0); // none in demos MSG_WriteByte (&buf, 0); // none in demos
@ -1933,10 +1953,10 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
SV_WriteRecordMVDMessage (&buf); SV_WriteRecordMVDMessage (&buf);
SZ_Clear (&buf); SZ_Clear (&buf);
} }
#endif
// send current status of all other players // send current status of all other players
for (i = 0; i < demo.recorder.max_net_clients; i++) for (i = 0; i < demo.recorder.max_net_clients && i < svs.allocated_client_slots; i++)
{ {
player = &svs.clients[i]; player = &svs.clients[i];
@ -1975,6 +1995,17 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
} }
} }
//invalidate stats+players somehow
for (i = 0; i < MAX_CLIENTS; i++)
{
for (j = 0; j < MAX_CL_STATS; j++)
{
demo.statsi[i][j] ^= -1;
demo.statsf[i][j] *= -0.41426712; //randomish value
}
demo.playerreset[i] = true;
}
// get the client to check and download skins // get the client to check and download skins
// when that is completed, a begin command will be issued // when that is completed, a begin command will be issued
MSG_WriteByte (&buf, svc_stufftext); MSG_WriteByte (&buf, svc_stufftext);

View file

@ -597,10 +597,13 @@ void SVNQ_New_f (void)
MSG_WriteString (&host_client->netchan.message,message); MSG_WriteString (&host_client->netchan.message,message);
//fixme: don't send too many models.
for (i = 1; sv.strings.model_precache[i] ; i++) for (i = 1; sv.strings.model_precache[i] ; i++)
MSG_WriteString (&host_client->netchan.message, sv.strings.model_precache[i]); MSG_WriteString (&host_client->netchan.message, sv.strings.model_precache[i]);
MSG_WriteByte (&host_client->netchan.message, 0); MSG_WriteByte (&host_client->netchan.message, 0);
//fixme: don't send too many sounds.
for (i = 1; *sv.strings.sound_precache[i] ; i++) for (i = 1; *sv.strings.sound_precache[i] ; i++)
MSG_WriteString (&host_client->netchan.message, sv.strings.sound_precache[i]); MSG_WriteString (&host_client->netchan.message, sv.strings.sound_precache[i]);
MSG_WriteByte (&host_client->netchan.message, 0); MSG_WriteByte (&host_client->netchan.message, 0);
@ -979,7 +982,7 @@ void SV_SendClientPrespawnInfo(client_t *client)
if (client->prespawn_stage == PRESPAWN_SOUNDLIST) if (client->prespawn_stage == PRESPAWN_SOUNDLIST)
{ {
if (!ISQWCLIENT(client)) if (!ISQWCLIENT(client))
client->prespawn_stage++; client->prespawn_stage++; //nq sends sound lists as part of the svc_serverdata
else else
{ {
int maxclientsupportedsounds = 256; int maxclientsupportedsounds = 256;
@ -1015,6 +1018,11 @@ void SV_SendClientPrespawnInfo(client_t *client)
if (client->prespawn_idx >= maxclientsupportedsounds || !*sv.strings.sound_precache[client->prespawn_idx]) if (client->prespawn_idx >= maxclientsupportedsounds || !*sv.strings.sound_precache[client->prespawn_idx])
{ {
if (*sv.strings.sound_precache[client->prespawn_idx] && !(client->plimitwarned & PLIMIT_SOUNDS))
{
client->plimitwarned |= PLIMIT_SOUNDS;
SV_ClientPrintf(client, PRINT_HIGH, "WARNING: Your client's network protocol only supports %i sounds. Please upgrade or enable extensions.\n", client->prespawn_idx);
}
//write final-end-of-list //write final-end-of-list
MSG_WriteByte (&client->netchan.message, 0); MSG_WriteByte (&client->netchan.message, 0);
MSG_WriteByte (&client->netchan.message, 0); MSG_WriteByte (&client->netchan.message, 0);
@ -1112,6 +1120,11 @@ void SV_SendClientPrespawnInfo(client_t *client)
if (client->prespawn_idx >= client->maxmodels || !sv.strings.model_precache[client->prespawn_idx]) if (client->prespawn_idx >= client->maxmodels || !sv.strings.model_precache[client->prespawn_idx])
{ {
if (*sv.strings.model_precache[client->prespawn_idx] && !(client->plimitwarned & PLIMIT_MODELS))
{
client->plimitwarned |= PLIMIT_MODELS;
SV_ClientPrintf(client, PRINT_HIGH, "WARNING: Your client's network protocol only supports %i models. Please upgrade or enable extensions.\n", client->prespawn_idx);
}
//write final-end-of-list //write final-end-of-list
MSG_WriteByte (&client->netchan.message, 0); MSG_WriteByte (&client->netchan.message, 0);
MSG_WriteByte (&client->netchan.message, 0); MSG_WriteByte (&client->netchan.message, 0);
@ -4972,6 +4985,9 @@ void SVNQ_PreSpawn_f (void)
host_client->checksum = ~0u; host_client->checksum = ~0u;
host_client->prespawn_stage = PRESPAWN_MAPCHECK+1; host_client->prespawn_stage = PRESPAWN_MAPCHECK+1;
host_client->prespawn_idx = 0; host_client->prespawn_idx = 0;
if (sv_mapcheck.value)
Con_Printf("Warning: %s does cannot be applied to NQ clients.\n", sv_mapcheck.name); //as you can fake it in a client anyway, this is hardly a significant issue.
} }
host_client->send_message = true; host_client->send_message = true;