mirror of
https://github.com/Q3Rally-Team/q3rally.git
synced 2024-11-28 14:42:33 +00:00
- ioquake3 resync to revision 2098 from 1834 (?)
This commit is contained in:
parent
c471d516dd
commit
339deb2bff
295 changed files with 36044 additions and 16126 deletions
|
@ -480,7 +480,7 @@
|
|||
2002-7-31 Timothee Besset <ttimo@idsoftware.com>
|
||||
+ https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=513
|
||||
https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=506
|
||||
porting fix from RTCW codebase. client re-orders it's pk3s to scan in the same order than the server
|
||||
porting fix from RTCW codebase. client re-orders its pk3s to scan in the same order than the server
|
||||
this eliminates several 'Invalid .PK3 file referenced' situations (caused by client not referencing the same thing as server)
|
||||
+ fixed border remnants in ta ui
|
||||
+ https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=517
|
||||
|
@ -505,7 +505,7 @@
|
|||
+ fix broken link in Linux FAQ
|
||||
|
||||
2002-7-27 Timothee Besset <ttimo@idsoftware.com>
|
||||
+ ta ui: PB display in the browser, in it's additional tab, with sorting
|
||||
+ ta ui: PB display in the browser, in its additional tab, with sorting
|
||||
|
||||
2002-7-26 Timothee Besset <ttimo@idsoftware.com>
|
||||
+ PB UI: for baseq3/ AND missionpack/
|
||||
|
@ -2775,7 +2775,7 @@
|
|||
Can't find menu/art/unknownmap.tga
|
||||
|
||||
* Q3TA: after nearly 6 months, a code update from id. SOS access
|
||||
even. Got it to compile, link and start, but its currently broken
|
||||
even. Got it to compile, link and start, but it's currently broken
|
||||
(menu doesn't render in full, can't get into game etc.). Need
|
||||
a baseline 1.17 to diff against. Last code dump was May 16, with
|
||||
bspc code updated May 19. Checking working directory of bk000520
|
||||
|
|
268
engine/Makefile
268
engine/Makefile
|
@ -4,7 +4,7 @@
|
|||
# GNU Make required
|
||||
#
|
||||
|
||||
COMPILE_PLATFORM=$(shell uname|sed -e s/_.*//|tr '[:upper:]' '[:lower:]')
|
||||
COMPILE_PLATFORM=$(shell uname|sed -e s/_.*//|tr '[:upper:]' '[:lower:]'|sed -e 's/\//_/g')
|
||||
|
||||
COMPILE_ARCH=$(shell uname -m | sed -e s/i.86/i386/)
|
||||
|
||||
|
@ -50,7 +50,7 @@ ifneq ($(PLATFORM),darwin)
|
|||
endif
|
||||
|
||||
# ioquake3 svn version that this is based on
|
||||
IOQ3_REVISION = 1834
|
||||
IOQ3_REVISION = 2098
|
||||
|
||||
#############################################################################
|
||||
#
|
||||
|
@ -106,6 +106,10 @@ ifndef BUILD_DIR
|
|||
BUILD_DIR=build
|
||||
endif
|
||||
|
||||
ifndef TEMPDIR
|
||||
TEMPDIR=/tmp
|
||||
endif
|
||||
|
||||
ifndef GENERATE_DEPENDENCIES
|
||||
GENERATE_DEPENDENCIES=1
|
||||
endif
|
||||
|
@ -150,6 +154,10 @@ ifndef USE_INTERNAL_ZLIB
|
|||
USE_INTERNAL_ZLIB=1
|
||||
endif
|
||||
|
||||
ifndef USE_INTERNAL_JPEG
|
||||
USE_INTERNAL_JPEG=1
|
||||
endif
|
||||
|
||||
ifndef USE_LOCAL_HEADERS
|
||||
USE_LOCAL_HEADERS=1
|
||||
endif
|
||||
|
@ -158,6 +166,10 @@ ifndef DEBUG_CFLAGS
|
|||
DEBUG_CFLAGS=-g -O0
|
||||
endif
|
||||
|
||||
ifndef USE_OLD_VM64
|
||||
USE_OLD_VM64=0
|
||||
endif
|
||||
|
||||
#############################################################################
|
||||
|
||||
BD=$(BUILD_DIR)/debug-$(PLATFORM)-$(ARCH)
|
||||
|
@ -175,7 +187,7 @@ BLIBDIR=$(MOUNT_DIR)/botlib
|
|||
NDIR=$(MOUNT_DIR)/null
|
||||
UIDIR=$(MOUNT_DIR)/ui
|
||||
Q3UIDIR=$(MOUNT_DIR)/q3_ui
|
||||
JPDIR=$(MOUNT_DIR)/jpeg-6b
|
||||
JPDIR=$(MOUNT_DIR)/jpeg-8c
|
||||
SPEEXDIR=$(MOUNT_DIR)/libspeex
|
||||
ZDIR=$(MOUNT_DIR)/zlib
|
||||
Q3ASMDIR=$(MOUNT_DIR)/tools/asm
|
||||
|
@ -187,7 +199,6 @@ LOKISETUPDIR=misc/setup
|
|||
NSISDIR=misc/nsis
|
||||
SDLHDIR=$(MOUNT_DIR)/SDL12
|
||||
LIBSDIR=$(MOUNT_DIR)/libs
|
||||
TEMPDIR=/tmp
|
||||
|
||||
bin_path=$(shell which $(1) 2> /dev/null)
|
||||
|
||||
|
@ -244,10 +255,10 @@ LIB=lib
|
|||
INSTALL=install
|
||||
MKDIR=mkdir
|
||||
|
||||
ifeq ($(PLATFORM),linux)
|
||||
ifneq (,$(findstring "$(PLATFORM)", "linux" "gnu_kfreebsd" "kfreebsd-gnu"))
|
||||
|
||||
ifeq ($(ARCH),alpha)
|
||||
ARCH=axp
|
||||
ifeq ($(ARCH),axp)
|
||||
ARCH=alpha
|
||||
else
|
||||
ifeq ($(ARCH),x86_64)
|
||||
LIB=lib64
|
||||
|
@ -315,6 +326,11 @@ ifeq ($(PLATFORM),linux)
|
|||
OPTIMIZEVM += -mtune=ultrasparc3 -mv8plus
|
||||
HAVE_VM_COMPILED=true
|
||||
endif
|
||||
ifeq ($(ARCH),alpha)
|
||||
# According to http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=410555
|
||||
# -ffast-math will cause the client to die with SIGFPE on Alpha
|
||||
OPTIMIZE = $(OPTIMIZEVM)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -551,8 +567,7 @@ ifeq ($(PLATFORM),mingw32)
|
|||
$(LIBSDIR)/win32/libSDL.dll.a
|
||||
else
|
||||
CLIENT_LIBS += $(LIBSDIR)/win64/libSDLmain.a \
|
||||
$(LIBSDIR)/win64/libSDL.dll.a \
|
||||
$(LIBSDIR)/win64/libSDL.a
|
||||
$(LIBSDIR)/win64/libSDL64.dll.a
|
||||
endif
|
||||
else
|
||||
CLIENT_CFLAGS += $(SDL_CFLAGS)
|
||||
|
@ -611,9 +626,6 @@ ifeq ($(PLATFORM),freebsd)
|
|||
|
||||
ifeq ($(USE_CODEC_VORBIS),1)
|
||||
CLIENT_CFLAGS += -DUSE_CODEC_VORBIS
|
||||
endif
|
||||
|
||||
ifeq ($(USE_CODEC_VORBIS),1)
|
||||
CLIENT_LIBS += -lvorbisfile -lvorbis -logg
|
||||
endif
|
||||
|
||||
|
@ -637,11 +649,10 @@ else # ifeq freebsd
|
|||
|
||||
ifeq ($(PLATFORM),openbsd)
|
||||
|
||||
#default to i386, no tests done on anything else
|
||||
ARCH=i386
|
||||
ARCH=$(shell uname -m)
|
||||
|
||||
BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes \
|
||||
-DUSE_ICON
|
||||
-DUSE_ICON -DMAP_ANONYMOUS=MAP_ANON
|
||||
CLIENT_CFLAGS = $(SDL_CFLAGS)
|
||||
SERVER_CFLAGS =
|
||||
|
||||
|
@ -729,7 +740,7 @@ else # ifeq netbsd
|
|||
|
||||
ifeq ($(PLATFORM),irix64)
|
||||
|
||||
ARCH=mips #default to MIPS
|
||||
ARCH=mips
|
||||
|
||||
CC = c99
|
||||
MKDIR = mkdir -p
|
||||
|
@ -910,6 +921,13 @@ else
|
|||
LIBS += -lz
|
||||
endif
|
||||
|
||||
ifeq ($(USE_INTERNAL_JPEG),1)
|
||||
BASE_CFLAGS += -DUSE_INTERNAL_JPEG
|
||||
BASE_CFLAGS += -I$(JPDIR)
|
||||
else
|
||||
CLIENT_LIBS += -ljpeg
|
||||
endif
|
||||
|
||||
ifdef DEFAULT_BASEDIR
|
||||
BASE_CFLAGS += -DDEFAULT_BASEDIR=\\\"$(DEFAULT_BASEDIR)\\\"
|
||||
endif
|
||||
|
@ -935,6 +953,10 @@ else
|
|||
endif
|
||||
|
||||
BASE_CFLAGS += -DPRODUCT_VERSION=\\\"$(VERSION)\\\"
|
||||
BASE_CFLAGS += -Wformat=2 -Wno-format-zero-length -Wformat-security -Wno-format-nonliteral
|
||||
BASE_CFLAGS += -Wstrict-aliasing=2 -Wmissing-format-attribute
|
||||
BASE_CFLAGS += -Wdisabled-optimization
|
||||
BASE_CFLAGS += -Werror-implicit-function-declaration
|
||||
|
||||
ifeq ($(V),1)
|
||||
echo_cmd=@:
|
||||
|
@ -1403,43 +1425,6 @@ Q3OBJ = \
|
|||
$(B)/client/l_precomp.o \
|
||||
$(B)/client/l_script.o \
|
||||
$(B)/client/l_struct.o \
|
||||
\
|
||||
$(B)/client/jcapimin.o \
|
||||
$(B)/client/jcapistd.o \
|
||||
$(B)/client/jccoefct.o \
|
||||
$(B)/client/jccolor.o \
|
||||
$(B)/client/jcdctmgr.o \
|
||||
$(B)/client/jchuff.o \
|
||||
$(B)/client/jcinit.o \
|
||||
$(B)/client/jcmainct.o \
|
||||
$(B)/client/jcmarker.o \
|
||||
$(B)/client/jcmaster.o \
|
||||
$(B)/client/jcomapi.o \
|
||||
$(B)/client/jcparam.o \
|
||||
$(B)/client/jcphuff.o \
|
||||
$(B)/client/jcprepct.o \
|
||||
$(B)/client/jcsample.o \
|
||||
$(B)/client/jdapimin.o \
|
||||
$(B)/client/jdapistd.o \
|
||||
$(B)/client/jdatasrc.o \
|
||||
$(B)/client/jdcoefct.o \
|
||||
$(B)/client/jdcolor.o \
|
||||
$(B)/client/jddctmgr.o \
|
||||
$(B)/client/jdhuff.o \
|
||||
$(B)/client/jdinput.o \
|
||||
$(B)/client/jdmainct.o \
|
||||
$(B)/client/jdmarker.o \
|
||||
$(B)/client/jdmaster.o \
|
||||
$(B)/client/jdpostct.o \
|
||||
$(B)/client/jdsample.o \
|
||||
$(B)/client/jdtrans.o \
|
||||
$(B)/client/jerror.o \
|
||||
$(B)/client/jfdctflt.o \
|
||||
$(B)/client/jidctflt.o \
|
||||
$(B)/client/jmemmgr.o \
|
||||
$(B)/client/jmemnobs.o \
|
||||
$(B)/client/jutils.o \
|
||||
\
|
||||
$(B)/client/tr_animation.o \
|
||||
$(B)/client/tr_backend.o \
|
||||
$(B)/client/tr_bsp.o \
|
||||
|
@ -1459,6 +1444,7 @@ Q3OBJ = \
|
|||
$(B)/client/tr_marks.o \
|
||||
$(B)/client/tr_mesh.o \
|
||||
$(B)/client/tr_model.o \
|
||||
$(B)/client/tr_model_iqm.o \
|
||||
$(B)/client/tr_noise.o \
|
||||
$(B)/client/tr_scene.o \
|
||||
$(B)/client/tr_shade.o \
|
||||
|
@ -1477,19 +1463,84 @@ Q3OBJ = \
|
|||
$(B)/client/con_log.o \
|
||||
$(B)/client/sys_main.o
|
||||
|
||||
ifneq ($(USE_INTERNAL_JPEG),0)
|
||||
Q3OBJ += \
|
||||
$(B)/client/jaricom.o \
|
||||
$(B)/client/jcapimin.o \
|
||||
$(B)/client/jcapistd.o \
|
||||
$(B)/client/jcarith.o \
|
||||
$(B)/client/jccoefct.o \
|
||||
$(B)/client/jccolor.o \
|
||||
$(B)/client/jcdctmgr.o \
|
||||
$(B)/client/jchuff.o \
|
||||
$(B)/client/jcinit.o \
|
||||
$(B)/client/jcmainct.o \
|
||||
$(B)/client/jcmarker.o \
|
||||
$(B)/client/jcmaster.o \
|
||||
$(B)/client/jcomapi.o \
|
||||
$(B)/client/jcparam.o \
|
||||
$(B)/client/jcprepct.o \
|
||||
$(B)/client/jcsample.o \
|
||||
$(B)/client/jctrans.o \
|
||||
$(B)/client/jdapimin.o \
|
||||
$(B)/client/jdapistd.o \
|
||||
$(B)/client/jdarith.o \
|
||||
$(B)/client/jdatadst.o \
|
||||
$(B)/client/jdatasrc.o \
|
||||
$(B)/client/jdcoefct.o \
|
||||
$(B)/client/jdcolor.o \
|
||||
$(B)/client/jddctmgr.o \
|
||||
$(B)/client/jdhuff.o \
|
||||
$(B)/client/jdinput.o \
|
||||
$(B)/client/jdmainct.o \
|
||||
$(B)/client/jdmarker.o \
|
||||
$(B)/client/jdmaster.o \
|
||||
$(B)/client/jdmerge.o \
|
||||
$(B)/client/jdpostct.o \
|
||||
$(B)/client/jdsample.o \
|
||||
$(B)/client/jdtrans.o \
|
||||
$(B)/client/jerror.o \
|
||||
$(B)/client/jfdctflt.o \
|
||||
$(B)/client/jfdctfst.o \
|
||||
$(B)/client/jfdctint.o \
|
||||
$(B)/client/jidctflt.o \
|
||||
$(B)/client/jidctfst.o \
|
||||
$(B)/client/jidctint.o \
|
||||
$(B)/client/jmemmgr.o \
|
||||
$(B)/client/jmemnobs.o \
|
||||
$(B)/client/jquant1.o \
|
||||
$(B)/client/jquant2.o \
|
||||
$(B)/client/jutils.o
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),i386)
|
||||
Q3OBJ += \
|
||||
$(B)/client/snd_mixa.o \
|
||||
$(B)/client/matha.o \
|
||||
$(B)/client/ftola.o \
|
||||
$(B)/client/snapvectora.o
|
||||
$(B)/client/snapvector.o \
|
||||
$(B)/client/ftola.o
|
||||
endif
|
||||
ifeq ($(ARCH),x86)
|
||||
Q3OBJ += \
|
||||
$(B)/client/snd_mixa.o \
|
||||
$(B)/client/matha.o \
|
||||
$(B)/client/ftola.o \
|
||||
$(B)/client/snapvectora.o
|
||||
$(B)/client/snapvector.o \
|
||||
$(B)/client/ftola.o
|
||||
endif
|
||||
ifeq ($(ARCH),x86_64)
|
||||
Q3OBJ += \
|
||||
$(B)/client/snapvector.o \
|
||||
$(B)/client/ftola.o
|
||||
endif
|
||||
ifeq ($(ARCH),amd64)
|
||||
Q3OBJ += \
|
||||
$(B)/client/snapvector.o \
|
||||
$(B)/client/ftola.o
|
||||
endif
|
||||
ifeq ($(ARCH),x64)
|
||||
Q3OBJ += \
|
||||
$(B)/client/snapvector.o \
|
||||
$(B)/client/ftola.o
|
||||
endif
|
||||
|
||||
ifeq ($(USE_VOIP),1)
|
||||
|
@ -1550,19 +1601,42 @@ endif
|
|||
|
||||
ifeq ($(HAVE_VM_COMPILED),true)
|
||||
ifeq ($(ARCH),i386)
|
||||
Q3OBJ += $(B)/client/vm_x86.o
|
||||
Q3OBJ += \
|
||||
$(B)/client/vm_x86.o
|
||||
endif
|
||||
ifeq ($(ARCH),x86)
|
||||
Q3OBJ += $(B)/client/vm_x86.o
|
||||
Q3OBJ += \
|
||||
$(B)/client/vm_x86.o
|
||||
endif
|
||||
ifeq ($(ARCH),x86_64)
|
||||
Q3OBJ += $(B)/client/vm_x86_64.o $(B)/client/vm_x86_64_assembler.o
|
||||
ifeq ($(USE_OLD_VM64),1)
|
||||
Q3OBJ += \
|
||||
$(B)/client/vm_x86_64.o \
|
||||
$(B)/client/vm_x86_64_assembler.o
|
||||
else
|
||||
Q3OBJ += \
|
||||
$(B)/client/vm_x86.o
|
||||
endif
|
||||
endif
|
||||
ifeq ($(ARCH),amd64)
|
||||
Q3OBJ += $(B)/client/vm_x86_64.o $(B)/client/vm_x86_64_assembler.o
|
||||
ifeq ($(USE_OLD_VM64),1)
|
||||
Q3OBJ += \
|
||||
$(B)/client/vm_x86_64.o \
|
||||
$(B)/client/vm_x86_64_assembler.o
|
||||
else
|
||||
Q3OBJ += \
|
||||
$(B)/client/vm_x86.o
|
||||
endif
|
||||
endif
|
||||
ifeq ($(ARCH),x64)
|
||||
Q3OBJ += $(B)/client/vm_x86_64.o $(B)/client/vm_x86_64_assembler.o
|
||||
ifeq ($(USE_OLD_VM64),1)
|
||||
Q3OBJ += \
|
||||
$(B)/client/vm_x86_64.o \
|
||||
$(B)/client/vm_x86_64_assembler.o
|
||||
else
|
||||
Q3OBJ += \
|
||||
$(B)/client/vm_x86.o
|
||||
endif
|
||||
endif
|
||||
ifeq ($(ARCH),ppc)
|
||||
Q3OBJ += $(B)/client/vm_powerpc.o $(B)/client/vm_powerpc_asm.o
|
||||
|
@ -1698,15 +1772,30 @@ Q3DOBJ = \
|
|||
|
||||
ifeq ($(ARCH),i386)
|
||||
Q3DOBJ += \
|
||||
$(B)/ded/ftola.o \
|
||||
$(B)/ded/snapvectora.o \
|
||||
$(B)/ded/matha.o
|
||||
$(B)/ded/matha.o \
|
||||
$(B)/ded/snapvector.o \
|
||||
$(B)/ded/ftola.o
|
||||
endif
|
||||
ifeq ($(ARCH),x86)
|
||||
Q3DOBJ += \
|
||||
$(B)/ded/ftola.o \
|
||||
$(B)/ded/snapvectora.o \
|
||||
$(B)/ded/matha.o
|
||||
$(B)/ded/matha.o \
|
||||
$(B)/ded/snapvector.o \
|
||||
$(B)/ded/ftola.o
|
||||
endif
|
||||
ifeq ($(ARCH),x86_64)
|
||||
Q3DOBJ += \
|
||||
$(B)/ded/snapvector.o \
|
||||
$(B)/ded/ftola.o
|
||||
endif
|
||||
ifeq ($(ARCH),amd64)
|
||||
Q3DOBJ += \
|
||||
$(B)/ded/snapvector.o \
|
||||
$(B)/ded/ftola.o
|
||||
endif
|
||||
ifeq ($(ARCH),x64)
|
||||
Q3DOBJ += \
|
||||
$(B)/ded/snapvector.o \
|
||||
$(B)/ded/ftola.o
|
||||
endif
|
||||
|
||||
ifeq ($(USE_INTERNAL_ZLIB),1)
|
||||
|
@ -1721,19 +1810,42 @@ endif
|
|||
|
||||
ifeq ($(HAVE_VM_COMPILED),true)
|
||||
ifeq ($(ARCH),i386)
|
||||
Q3DOBJ += $(B)/ded/vm_x86.o
|
||||
Q3DOBJ += \
|
||||
$(B)/ded/vm_x86.o
|
||||
endif
|
||||
ifeq ($(ARCH),x86)
|
||||
Q3DOBJ += $(B)/ded/vm_x86.o
|
||||
Q3DOBJ += \
|
||||
$(B)/ded/vm_x86.o
|
||||
endif
|
||||
ifeq ($(ARCH),x86_64)
|
||||
Q3DOBJ += $(B)/ded/vm_x86_64.o $(B)/ded/vm_x86_64_assembler.o
|
||||
ifeq ($(USE_OLD_VM64),1)
|
||||
Q3DOBJ += \
|
||||
$(B)/ded/vm_x86_64.o \
|
||||
$(B)/ded/vm_x86_64_assembler.o
|
||||
else
|
||||
Q3DOBJ += \
|
||||
$(B)/ded/vm_x86.o
|
||||
endif
|
||||
endif
|
||||
ifeq ($(ARCH),amd64)
|
||||
Q3DOBJ += $(B)/ded/vm_x86_64.o $(B)/ded/vm_x86_64_assembler.o
|
||||
ifeq ($(USE_OLD_VM64),1)
|
||||
Q3DOBJ += \
|
||||
$(B)/ded/vm_x86_64.o \
|
||||
$(B)/ded/vm_x86_64_assembler.o
|
||||
else
|
||||
Q3DOBJ += \
|
||||
$(B)/ded/vm_x86.o
|
||||
endif
|
||||
endif
|
||||
ifeq ($(ARCH),x64)
|
||||
Q3DOBJ += $(B)/ded/vm_x86_64.o $(B)/ded/vm_x86_64_assembler.o
|
||||
ifeq ($(USE_OLD_VM64),1)
|
||||
Q3DOBJ += \
|
||||
$(B)/ded/vm_x86_64.o \
|
||||
$(B)/ded/vm_x86_64_assembler.o
|
||||
else
|
||||
Q3DOBJ += \
|
||||
$(B)/ded/vm_x86.o
|
||||
endif
|
||||
endif
|
||||
ifeq ($(ARCH),ppc)
|
||||
Q3DOBJ += $(B)/ded/vm_powerpc.o $(B)/ded/vm_powerpc_asm.o
|
||||
|
@ -1790,6 +1902,7 @@ Q3CGOBJ_ = \
|
|||
$(B)/baseq3r/cgame/cg_info.o \
|
||||
$(B)/baseq3r/cgame/cg_localents.o \
|
||||
$(B)/baseq3r/cgame/cg_marks.o \
|
||||
$(B)/baseq3r/cgame/cg_particles.o \
|
||||
$(B)/baseq3r/cgame/cg_players.o \
|
||||
$(B)/baseq3r/cgame/cg_playerstate.o \
|
||||
$(B)/baseq3r/cgame/cg_predict.o \
|
||||
|
@ -1842,6 +1955,7 @@ MPCGOBJ_ = \
|
|||
$(B)/missionpack/cgame/cg_info.o \
|
||||
$(B)/missionpack/cgame/cg_localents.o \
|
||||
$(B)/missionpack/cgame/cg_marks.o \
|
||||
$(B)/missionpack/cgame/cg_particles.o \
|
||||
$(B)/missionpack/cgame/cg_players.o \
|
||||
$(B)/missionpack/cgame/cg_playerstate.o \
|
||||
$(B)/missionpack/cgame/cg_predict.o \
|
||||
|
@ -2089,6 +2203,10 @@ $(B)/missionpack/vm/ui.qvm: $(MPUIVMOBJ) $(UIDIR)/ui_syscalls.asm $(Q3ASM)
|
|||
$(B)/client/%.o: $(ASMDIR)/%.s
|
||||
$(DO_AS)
|
||||
|
||||
# k8 so inline assembler knows about SSE
|
||||
$(B)/client/%.o: $(ASMDIR)/%.c
|
||||
$(DO_CC) -march=k8
|
||||
|
||||
$(B)/client/%.o: $(CDIR)/%.c
|
||||
$(DO_CC)
|
||||
|
||||
|
@ -2132,6 +2250,10 @@ $(B)/client/%.o: $(SYSDIR)/%.rc
|
|||
$(B)/ded/%.o: $(ASMDIR)/%.s
|
||||
$(DO_AS)
|
||||
|
||||
# k8 so inline assembler knows about SSE
|
||||
$(B)/ded/%.o: $(ASMDIR)/%.c
|
||||
$(DO_CC) -march=k8
|
||||
|
||||
$(B)/ded/%.o: $(SDIR)/%.c
|
||||
$(DO_DED_CC)
|
||||
|
||||
|
|
465
engine/README
465
engine/README
|
@ -77,22 +77,32 @@ script to match your environment.
|
|||
The following variables may be set, either on the command line or in
|
||||
Makefile.local:
|
||||
|
||||
CFLAGS - use this for custom CFLAGS
|
||||
V - set to show cc command line when building
|
||||
DEFAULT_BASEDIR - extra path to search for baseq3 and such
|
||||
BUILD_SERVER - build the 'ioq3ded' server binary
|
||||
BUILD_CLIENT - build the 'ioquake3' client binary
|
||||
BUILD_CLIENT_SMP - build the 'ioquake3-smp' client binary
|
||||
BUILD_GAME_SO - build the game shared libraries
|
||||
BUILD_GAME_QVM - build the game qvms
|
||||
BUILD_STANDALONE - build binaries suited for stand-alone games
|
||||
USE_OPENAL - use OpenAL where available
|
||||
USE_OPENAL_DLOPEN - link with OpenAL at runtime
|
||||
USE_CURL - use libcurl for http/ftp download support
|
||||
USE_CURL_DLOPEN - link with libcurl at runtime
|
||||
USE_CODEC_VORBIS - enable Ogg Vorbis support
|
||||
USE_LOCAL_HEADERS - use headers local to ioq3 instead of system ones
|
||||
COPYDIR - the target installation directory
|
||||
CFLAGS - use this for custom CFLAGS
|
||||
V - set to show cc command line when building
|
||||
DEFAULT_BASEDIR - extra path to search for baseq3 and such
|
||||
BUILD_SERVER - build the 'ioq3ded' server binary
|
||||
BUILD_CLIENT - build the 'ioquake3' client binary
|
||||
BUILD_CLIENT_SMP - build the 'ioquake3-smp' client binary
|
||||
BUILD_GAME_SO - build the game shared libraries
|
||||
BUILD_GAME_QVM - build the game qvms
|
||||
BUILD_STANDALONE - build binaries suited for stand-alone games
|
||||
USE_OPENAL - use OpenAL where available
|
||||
USE_OPENAL_DLOPEN - link with OpenAL at runtime
|
||||
USE_CURL - use libcurl for http/ftp download support
|
||||
USE_CURL_DLOPEN - link with libcurl at runtime
|
||||
USE_CODEC_VORBIS - enable Ogg Vorbis support
|
||||
USE_MUMBLE - enable Mumble support
|
||||
USE_VOIP - enable built-in VoIP support
|
||||
USE_INTERNAL_SPEEX - build internal speex library instead of dynamically
|
||||
linking against system libspeex
|
||||
USE_OLD_VM64 - use Ludwig Nussel's old JIT compiler implementation
|
||||
for x86_64
|
||||
USE_INTERNAL_ZLIB - build and link against internal zlib
|
||||
USE_INTERNAL_JPEG - build and link against internal JPEG library
|
||||
USE_LOCAL_HEADERS - use headers local to ioq3 instead of system ones
|
||||
DEBUG_CFLAGS - C compiler flags to use for building debug version
|
||||
COPYDIR - the target installation directory
|
||||
TEMPDIR - specify user defined directory for temp files
|
||||
|
||||
The defaults for these variables differ depending on the target platform.
|
||||
|
||||
|
@ -110,6 +120,28 @@ New cvars
|
|||
cl_mouseAccelStyle - Set to 1 for QuakeLive mouse acceleration
|
||||
behaviour, 0 for standard q3
|
||||
cl_mouseAccelOffset - Tuning the acceleration curve, see below
|
||||
cl_gamename - Gamename sent to master server in
|
||||
getserversExt query
|
||||
|
||||
in_joystickUseAnalog - Do not translate joystick axis events
|
||||
to keyboard commands
|
||||
|
||||
j_forward - Joystick analogue to m_forward,
|
||||
for forward movement speed/direction.
|
||||
j_side - Joystick analogue to m_side,
|
||||
for side movement speed/direction.
|
||||
j_pitch - Joystick analogue to m_pitch,
|
||||
for pitch rotation speed/direction.
|
||||
j_yaw - Joystick analogue to m_yaw,
|
||||
for yaw rotation speed/direction.
|
||||
j_forward_axis - Selects which joystick axis
|
||||
controls forward/back.
|
||||
j_side_axis - Selects which joystick axis
|
||||
controls left/right.
|
||||
j_pitch_axis - Selects which joystick axis
|
||||
controls pitch.
|
||||
j_yaw_axis - Selects which joystick axis
|
||||
controls yaw.
|
||||
|
||||
s_useOpenAL - use the OpenAL sound backend if available
|
||||
s_alPrecache - cache OpenAL sounds before use
|
||||
|
@ -129,6 +161,8 @@ New cvars
|
|||
s_alDriver - which OpenAL library to use
|
||||
s_alDevice - which OpenAL device to use
|
||||
s_alAvailableDevices - list of available OpenAL devices
|
||||
s_alInputDevice - which OpenAL input device to use
|
||||
s_alAvailableInputDevices - list of available OpenAL input devices
|
||||
s_sdlBits - SDL bit resolution
|
||||
s_sdlSpeed - SDL sample rate
|
||||
s_sdlChannels - SDL number of channels
|
||||
|
@ -138,20 +172,47 @@ New cvars
|
|||
backend
|
||||
s_muteWhenMinimized - mute sound when minimized
|
||||
s_muteWhenUnfocused - mute sound when window is unfocused
|
||||
sv_dlRate - bandwidth allotted to PK3 file downloads
|
||||
via UDP, in kbyte/s
|
||||
|
||||
com_ansiColor - enable use of ANSI escape codes in the tty
|
||||
com_altivec - enable use of altivec on PowerPC systems
|
||||
com_standalone - Run in standalone mode
|
||||
com_standalone (read only) - If set to 1, quake3 is running in
|
||||
standalone mode
|
||||
com_basegame - Use a different base than baseq3. If no
|
||||
original Quake3 or TeamArena pak files
|
||||
are found, this will enable running in
|
||||
standalone mode
|
||||
com_homepath - Specify name that is to be appended to the
|
||||
home path
|
||||
com_legacyprotocol - Specify protocol version number for
|
||||
legacy Quake3 1.32c protocol, see
|
||||
"Network protocols" section below
|
||||
(startup only)
|
||||
com_maxfpsUnfocused - Maximum frames per second when unfocused
|
||||
com_maxfpsMinimized - Maximum frames per second when minimized
|
||||
com_busyWait - Will use a busy loop to wait for rendering
|
||||
next frame when set to non-zero value
|
||||
com_pipefile - Specify filename to create a named pipe
|
||||
through which other processes can control
|
||||
the server while it is running.
|
||||
Nonfunctional on Windows.
|
||||
com_protocol - Specify protocol version number for
|
||||
current ioquake3 protocol, see
|
||||
"Network protocols" section below
|
||||
(startup only)
|
||||
|
||||
in_joystickNo - select which joystick to use
|
||||
in_availableJoysticks - list of available Joysticks
|
||||
in_keyboardDebug - print keyboard debug info
|
||||
|
||||
sv_dlURL - the base of the HTTP or FTP site that
|
||||
holds custom pk3 files for your server
|
||||
sv_banFile - Name of the file that is used for storing
|
||||
the server bans.
|
||||
the server bans
|
||||
sv_heartbeat - Heartbeat string sent to master server
|
||||
sv_flatline - Heartbeat string sent to master server
|
||||
when server is killed
|
||||
|
||||
net_ip6 - IPv6 address to bind to
|
||||
net_port6 - port to bind to using the ipv6 address
|
||||
|
@ -169,7 +230,8 @@ New cvars
|
|||
r_ext_texture_filter_anisotropic - anisotropic texture filtering
|
||||
r_zProj - distance of observer camera to projection
|
||||
plane in quake3 standard units
|
||||
r_greyscale - render black and white images
|
||||
r_greyscale - desaturate textures, useful for anaglyph,
|
||||
supports values in the range of 0 to 1
|
||||
r_stereoEnabled - enable stereo rendering for techniques
|
||||
like shutter glasses (untested)
|
||||
r_anaglyphMode - Enable rendering of anaglyph images
|
||||
|
@ -195,11 +257,16 @@ New cvars
|
|||
backend being used
|
||||
r_noborder - Remove window decoration from window
|
||||
managers, like borders and titlebar.
|
||||
r_screenshotJpegQuality - Controls quality of jpeg screenshots
|
||||
captured using screenshotJPEG
|
||||
r_aviMotionJpegQuality - Controls quality of video capture when
|
||||
cl_aviMotionJpeg is enabled
|
||||
|
||||
New commands
|
||||
video [filename] - start video capture (use with demo command)
|
||||
stopvideo - stop video capture
|
||||
stopmusic - stop background music
|
||||
minimize - Minimize the game and show desktop
|
||||
|
||||
print - print out the contents of a cvar
|
||||
unset - unset a user created cvar
|
||||
|
@ -217,7 +284,10 @@ New commands
|
|||
net_restart - restart network subsystem to change latched settings
|
||||
game_restart <fs_game> - Switch to another mod
|
||||
|
||||
------------------------------------------------------------ Miscellaneous -----
|
||||
which <filename/path> - print out the path on disk to a loaded item
|
||||
|
||||
|
||||
--------------------------------------------------------- README for Users -----
|
||||
|
||||
Using shared libraries instead of qvm
|
||||
To force Q3 to use shared libraries instead of qvms run it with the following
|
||||
|
@ -235,146 +305,15 @@ Using Demo Data Files
|
|||
data, nor is it something that we like to spend much time maintaining or
|
||||
supporting.
|
||||
|
||||
QuakeLive mouse acceleration (patch and this text written by TTimo from id)
|
||||
I've been using an experimental mouse acceleration code for a while, and
|
||||
decided to make it available to everyone. Don't be too worried if you don't
|
||||
understand the explanations below, this is mostly intended for advanced
|
||||
players:
|
||||
To enable it, set cl_mouseAccelStyle 1 (0 is the default/legacy behavior)
|
||||
|
||||
New style is controlled with 3 cvars:
|
||||
|
||||
sensitivity
|
||||
cl_mouseAccel
|
||||
cl_mouseAccelOffset
|
||||
|
||||
The old code (cl_mouseAccelStyle 0) can be difficult to calibrate because if
|
||||
you have a base sensitivity setup, as soon as you set a non zero acceleration
|
||||
your base sensitivity at low speeds will change as well. The other problem
|
||||
with style 0 is that you are stuck on a square (power of two) acceleration
|
||||
curve.
|
||||
|
||||
The new code tries to solve both problems:
|
||||
|
||||
Once you setup your sensitivity to feel comfortable and accurate enough for
|
||||
low mouse deltas with no acceleration (cl_mouseAccel 0), you can start
|
||||
increasing cl_mouseAccel and tweaking cl_mouseAccelOffset to get the
|
||||
amplification you want for high deltas with little effect on low mouse deltas.
|
||||
|
||||
cl_mouseAccel is a power value. Should be >= 1, 2 will be the same power curve
|
||||
as style 0. The higher the value, the faster the amplification grows with the
|
||||
mouse delta.
|
||||
|
||||
cl_mouseAccelOffset sets how much base mouse delta will be doubled by
|
||||
acceleration. The closer to zero you bring it, the more acceleration will
|
||||
happen at low speeds. This is also very useful if you are changing to a new
|
||||
mouse with higher dpi, if you go from 500 to 1000 dpi, you can divide your
|
||||
cl_mouseAccelOffset by two to keep the same overall 'feel' (you will likely
|
||||
gain in precision when you do that, but that is not related to mouse
|
||||
acceleration).
|
||||
|
||||
Mouse acceleration is tricky to configure, and when you do you'll have to
|
||||
re-learn your aiming. But you will find that it's very much forth it in the
|
||||
long run.
|
||||
|
||||
If you try the new acceleration code and start using it, I'd be very
|
||||
interested by your feedback.
|
||||
|
||||
64bit mods
|
||||
If you wish to compile external mods as shared libraries on a 64bit platform,
|
||||
and the mod source is derived from the id Q3 SDK, you will need to modify the
|
||||
interface code a little. Open the files ending in _syscalls.c and change
|
||||
every instance of int to intptr_t in the declaration of the syscall function
|
||||
pointer and the dllEntry function. Also find the vmMain function for each
|
||||
module (usually in cg_main.c g_main.c etc.) and similarly replace the return
|
||||
value in the prototype with intptr_t (arg0, arg1, ...stay int).
|
||||
|
||||
Add the following code snippet to q_shared.h:
|
||||
|
||||
#ifdef Q3_VM
|
||||
typedef int intptr_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
Note if you simply wish to run mods on a 64bit platform you do not need to
|
||||
recompile anything since by default Q3 uses a virtual machine system.
|
||||
|
||||
Creating mods compatible with Q3 1.32b
|
||||
If you're using this package to create mods for the last official release of
|
||||
Q3, it is necessary to pass the commandline option '-vq3' to your invocation
|
||||
of q3asm. This is because by default q3asm outputs an updated qvm format that
|
||||
is necessary to fix a bug involving the optimizing pass of the x86 vm JIT
|
||||
compiler.
|
||||
|
||||
Creating standalone games
|
||||
Have you finished the daunting task of removing all dependencies on the Q3
|
||||
game data? You probably now want to give your users the opportunity to play
|
||||
the game without owning a copy of Q3, which consequently means removing cd-key
|
||||
and authentication server checks. In addition to being a straightforward Q3
|
||||
client, ioquake3 also purports to be a reliable and stable code base on which
|
||||
to base your game project.
|
||||
|
||||
However, before you start compiling your own version of ioquake3, you have to
|
||||
ask yourself: Have we changed or will we need to change anything of importance
|
||||
in the engine?
|
||||
|
||||
If your answer to this question is "no", it probably makes no sense to build
|
||||
your own binaries. Instead, you can just use the pre-built binaries on the
|
||||
website. Just make sure the game is called with:
|
||||
|
||||
+set com_standalone 1 +set fs_game <yourgamedir>
|
||||
|
||||
in any links/scripts you install for your users to start the game. Note that
|
||||
the com_standalone setting is rendered ineffective, if the binary detects pk3
|
||||
files in the directory "baseq3", so you cannot use that one as game dir.
|
||||
|
||||
If you really changed parts that would make vanilla ioquake3 incompatible with
|
||||
your mod, we have included another way to conveniently build a stand-alone
|
||||
binary. Just run make with the option BUILD_STANDALONE=1. Don't forget to edit
|
||||
the PRODUCT_NAME and subsequent #defines in qcommon/q_shared.h with
|
||||
information appropriate for your project.
|
||||
|
||||
While a lot of work has been put into ioquake3 that you can benefit from free
|
||||
of charge, it does not mean that you have no obligations to fulfil. Please be
|
||||
aware that as soon as you start distributing your game with an engine based on
|
||||
our sources we expect you to fully comply with the requirements as stated in
|
||||
the GPL. That includes making sources and modifications you made to the
|
||||
ioquake3 engine as well as the game-code used to compile the .qvm files for
|
||||
the game logic freely available to everyone. Furthermore, note that the "QIIIA
|
||||
Game Source License" prohibits distribution of mods that are intended to
|
||||
operate on a version of Q3 not sanctioned by id software:
|
||||
|
||||
"with this Agreement, ID grants to you the non-exclusive and limited right
|
||||
to distribute copies of the Software ... for operation only with the full
|
||||
version of the software game QUAKE III ARENA"
|
||||
|
||||
This means that if you're creating a standalone game, you cannot use said
|
||||
license on any portion of the product. As the only other license this code has
|
||||
been released under is the GPL, this is the only option.
|
||||
|
||||
This does NOT mean that you cannot market this game commercially. The GPL does
|
||||
not prohibit commercial exploitation and all assets (e.g. textures, sounds,
|
||||
maps) created by yourself are your property and can be sold like every other
|
||||
game you find in stores.
|
||||
|
||||
cl_guid Support
|
||||
cl_guid is a cvar which is part of the client's USERINFO string. Its value
|
||||
is a 32 character string made up of [a-f] and [0-9] characters. This
|
||||
value is pseudo-unique for every player. Id's Quake 3 Arena client also
|
||||
sets cl_guid, but only if Punkbuster is enabled on the client.
|
||||
|
||||
If cl_guidServerUniq is non-zero (the default), then this value is also
|
||||
pseudo-unique for each server a client connects to (based on IP:PORT of
|
||||
the server).
|
||||
|
||||
The purpose of cl_guid is to add an identifier for each player on
|
||||
a server. This value can be reset by the client at any time so it's not
|
||||
useful for blocking access. However, it can have at least two uses in
|
||||
your mod's game code:
|
||||
1) improve logging to allow statistical tools to index players by more
|
||||
than just name
|
||||
2) granting some weak admin rights to players without requiring passwords
|
||||
Help! Ioquake3 won't give me an fps of X anymore when setting com_maxfps!
|
||||
Ioquake3 now uses the select() system call to wait for the rendering of the
|
||||
next frame when com_maxfps was hit. This will improve your CPU load
|
||||
considerably in these cases. However, not all systems may support a
|
||||
granularity for its timing functions that is required to perform this waiting
|
||||
correctly. For instance, ioquake3 tells select() to wait 2 milliseconds, but
|
||||
really it can only wait for a multiple of 5ms, i.e. 5, 10, 15, 20... ms.
|
||||
In this case you can always revert back to the old behaviour by setting the
|
||||
cvar com_busyWait to 1.
|
||||
|
||||
Using HTTP/FTP Download Support (Server)
|
||||
You can enable redirected downloads on your server even if it's not
|
||||
|
@ -400,6 +339,11 @@ Using HTTP/FTP Download Support (Server)
|
|||
that ioquake3 sets which is "ioQ3://{SERVER_IP}:{SERVER_PORT}". For,
|
||||
example, Apache's mod_rewrite can restrict access based on HTTP_REFERER.
|
||||
|
||||
On a sidenote, downloading via UDP has been improved and yields higher data
|
||||
rates now. You can configure the maximum bandwidth for UDP downloads via the
|
||||
cvar sv_dlRate. Due to system-specific limits the download rate is capped
|
||||
at about 1 Mbyte/s per client, so curl downloading may still be faster.
|
||||
|
||||
Using HTTP/FTP Download Support (Client)
|
||||
Simply setting cl_allowDownload to 1 will enable HTTP/FTP downloads
|
||||
assuming ioquake3 was compiled with USE_CURL=1 (the default).
|
||||
|
@ -479,6 +423,207 @@ SDL Keyboard Differences
|
|||
text. Also, in addition to the nominated console keys, Shift-ESC is hard
|
||||
coded to always toggle the console.
|
||||
|
||||
QuakeLive mouse acceleration (patch and this text written by TTimo from id)
|
||||
I've been using an experimental mouse acceleration code for a while, and
|
||||
decided to make it available to everyone. Don't be too worried if you don't
|
||||
understand the explanations below, this is mostly intended for advanced
|
||||
players:
|
||||
To enable it, set cl_mouseAccelStyle 1 (0 is the default/legacy behavior)
|
||||
|
||||
New style is controlled with 3 cvars:
|
||||
|
||||
sensitivity
|
||||
cl_mouseAccel
|
||||
cl_mouseAccelOffset
|
||||
|
||||
The old code (cl_mouseAccelStyle 0) can be difficult to calibrate because if
|
||||
you have a base sensitivity setup, as soon as you set a non zero acceleration
|
||||
your base sensitivity at low speeds will change as well. The other problem
|
||||
with style 0 is that you are stuck on a square (power of two) acceleration
|
||||
curve.
|
||||
|
||||
The new code tries to solve both problems:
|
||||
|
||||
Once you setup your sensitivity to feel comfortable and accurate enough for
|
||||
low mouse deltas with no acceleration (cl_mouseAccel 0), you can start
|
||||
increasing cl_mouseAccel and tweaking cl_mouseAccelOffset to get the
|
||||
amplification you want for high deltas with little effect on low mouse deltas.
|
||||
|
||||
cl_mouseAccel is a power value. Should be >= 1, 2 will be the same power curve
|
||||
as style 0. The higher the value, the faster the amplification grows with the
|
||||
mouse delta.
|
||||
|
||||
cl_mouseAccelOffset sets how much base mouse delta will be doubled by
|
||||
acceleration. The closer to zero you bring it, the more acceleration will
|
||||
happen at low speeds. This is also very useful if you are changing to a new
|
||||
mouse with higher dpi, if you go from 500 to 1000 dpi, you can divide your
|
||||
cl_mouseAccelOffset by two to keep the same overall 'feel' (you will likely
|
||||
gain in precision when you do that, but that is not related to mouse
|
||||
acceleration).
|
||||
|
||||
Mouse acceleration is tricky to configure, and when you do you'll have to
|
||||
re-learn your aiming. But you will find that it's very much forth it in the
|
||||
long run.
|
||||
|
||||
If you try the new acceleration code and start using it, I'd be very
|
||||
interested by your feedback.
|
||||
|
||||
|
||||
---------------------------------------------------- README for Developers -----
|
||||
|
||||
64bit mods
|
||||
If you wish to compile external mods as shared libraries on a 64bit platform,
|
||||
and the mod source is derived from the id Q3 SDK, you will need to modify the
|
||||
interface code a little. Open the files ending in _syscalls.c and change
|
||||
every instance of int to intptr_t in the declaration of the syscall function
|
||||
pointer and the dllEntry function. Also find the vmMain function for each
|
||||
module (usually in cg_main.c g_main.c etc.) and similarly replace the return
|
||||
value in the prototype with intptr_t (arg0, arg1, ...stay int).
|
||||
|
||||
Add the following code snippet to q_shared.h:
|
||||
|
||||
#ifdef Q3_VM
|
||||
typedef int intptr_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
Note if you simply wish to run mods on a 64bit platform you do not need to
|
||||
recompile anything since by default Q3 uses a virtual machine system.
|
||||
|
||||
Creating mods compatible with Q3 1.32b
|
||||
If you're using this package to create mods for the last official release of
|
||||
Q3, it is necessary to pass the commandline option '-vq3' to your invocation
|
||||
of q3asm. This is because by default q3asm outputs an updated qvm format that
|
||||
is necessary to fix a bug involving the optimizing pass of the x86 vm JIT
|
||||
compiler.
|
||||
|
||||
Creating standalone games
|
||||
Have you finished the daunting task of removing all dependencies on the Q3
|
||||
game data? You probably now want to give your users the opportunity to play
|
||||
the game without owning a copy of Q3, which consequently means removing cd-key
|
||||
and authentication server checks. In addition to being a straightforward Q3
|
||||
client, ioquake3 also purports to be a reliable and stable code base on which
|
||||
to base your game project.
|
||||
|
||||
However, before you start compiling your own version of ioquake3, you have to
|
||||
ask yourself: Have we changed or will we need to change anything of importance
|
||||
in the engine?
|
||||
|
||||
If your answer to this question is "no", it probably makes no sense to build
|
||||
your own binaries. Instead, you can just use the pre-built binaries on the
|
||||
website. Just make sure the game is called with:
|
||||
|
||||
+set com_basegame <yournewbase>
|
||||
|
||||
in any links/scripts you install for your users to start the game. The
|
||||
binary must not detect any original quake3 game pak files. If this
|
||||
condition is met, the game will set com_standalone to 1 and is then running
|
||||
in stand alone mode.
|
||||
|
||||
If you want the engine to use a different directory in your homepath than
|
||||
e.g. "Quake3" on Windows or ".q3a" on Linux, then set a new name at startup
|
||||
by adding
|
||||
|
||||
+set com_homepath <homedirname>
|
||||
|
||||
to the command line. You can also control which kind of messages to send to
|
||||
the master server:
|
||||
|
||||
+set sv_heartbeat <heartbeat> +set sv_flatline <flatline>
|
||||
+set cl_gamename <gamename>
|
||||
|
||||
The <heartbeat> and <flatline> message can be specific to your game. The
|
||||
flatline message is sent to signal the master server that the game server is
|
||||
quitting. Vanilla quake3 uses "QuakeArena-1" both for the heartbeat and
|
||||
flatline messages.
|
||||
The cl_gamename message is for dpmaster to specify which game the client
|
||||
wants a server list for. It is only used in the new ipv6 based getServersExt
|
||||
query.
|
||||
|
||||
Example line:
|
||||
|
||||
+set com_basegame basefoo +set com_homepath .foo
|
||||
+set sv_heartbeat fooalive +set sv_flatline foodead
|
||||
+set cl_gamename foo
|
||||
|
||||
|
||||
If you really changed parts that would make vanilla ioquake3 incompatible with
|
||||
your mod, we have included another way to conveniently build a stand-alone
|
||||
binary. Just run make with the option BUILD_STANDALONE=1. Don't forget to edit
|
||||
the PRODUCT_NAME and subsequent #defines in qcommon/q_shared.h with
|
||||
information appropriate for your project.
|
||||
|
||||
While a lot of work has been put into ioquake3 that you can benefit from free
|
||||
of charge, it does not mean that you have no obligations to fulfil. Please be
|
||||
aware that as soon as you start distributing your game with an engine based on
|
||||
our sources we expect you to fully comply with the requirements as stated in
|
||||
the GPL. That includes making sources and modifications you made to the
|
||||
ioquake3 engine as well as the game-code used to compile the .qvm files for
|
||||
the game logic freely available to everyone. Furthermore, note that the "QIIIA
|
||||
Game Source License" prohibits distribution of mods that are intended to
|
||||
operate on a version of Q3 not sanctioned by id software:
|
||||
|
||||
"with this Agreement, ID grants to you the non-exclusive and limited right
|
||||
to distribute copies of the Software ... for operation only with the full
|
||||
version of the software game QUAKE III ARENA"
|
||||
|
||||
This means that if you're creating a standalone game, you cannot use said
|
||||
license on any portion of the product. As the only other license this code has
|
||||
been released under is the GPL, this is the only option.
|
||||
|
||||
This does NOT mean that you cannot market this game commercially. The GPL does
|
||||
not prohibit commercial exploitation and all assets (e.g. textures, sounds,
|
||||
maps) created by yourself are your property and can be sold like every other
|
||||
game you find in stores.
|
||||
|
||||
Network protocols
|
||||
There are now two cvars that give you some degree of freedom over the reported
|
||||
protocol versions between clients and servers: "com_protocol" and
|
||||
"com_legacyprotocol".
|
||||
The reason for this is that some standalone games increased the protocol
|
||||
number even though nothing really changed in their protocol and the ioquake3
|
||||
engine is still fully compatible.
|
||||
|
||||
In order to harden the network protocol against UDP spoofing attacks a new
|
||||
network protocol was introduced that defends against such attacks.
|
||||
Unfortunately, this protocol will be incompatible to the original quake3 1.32c
|
||||
which is the latest official release from id.
|
||||
Luckily, ioquake3 has backwards compatibility, on the client as well as on the
|
||||
server. This means ioquake3 players can play on old servers just as ioquake3
|
||||
servers are able to service old clients.
|
||||
|
||||
The cvar "com_protocol" denotes the protocol version for the new hardened
|
||||
protocol, whereas the "com_legacyprotocol" cvar denotes the protocol version
|
||||
for the legacy protocol.
|
||||
If the value for "com_protocol" and "com_legacyprotocol" is identical, then
|
||||
the legacy protocol is always used. If "com_legacyprotocol" is set to 0, then
|
||||
support for the legacy protocol is disabled.
|
||||
|
||||
Mods that use a standalone engine obviously do not require dual protocol
|
||||
support, and it is turned off if the engine is compiled with STANDALONE per
|
||||
default. If you desire backwards compatibility to older versions of your
|
||||
game you can still enable it in q_shared.h by defining
|
||||
LEGACY_PROTOCOL.
|
||||
|
||||
cl_guid Support
|
||||
cl_guid is a cvar which is part of the client's USERINFO string. Its value
|
||||
is a 32 character string made up of [a-f] and [0-9] characters. This
|
||||
value is pseudo-unique for every player. Id's Quake 3 Arena client also
|
||||
sets cl_guid, but only if Punkbuster is enabled on the client.
|
||||
|
||||
If cl_guidServerUniq is non-zero (the default), then this value is also
|
||||
pseudo-unique for each server a client connects to (based on IP:PORT of
|
||||
the server).
|
||||
|
||||
The purpose of cl_guid is to add an identifier for each player on
|
||||
a server. This value can be reset by the client at any time so it's not
|
||||
useful for blocking access. However, it can have at least two uses in
|
||||
your mod's game code:
|
||||
1) improve logging to allow statistical tools to index players by more
|
||||
than just name
|
||||
2) granting some weak admin rights to players without requiring passwords
|
||||
|
||||
PNG support
|
||||
ioquake3 supports the use of PNG (Portable Network Graphic) images as
|
||||
textures. It should be noted that the use of such images in a map will
|
||||
|
|
|
@ -123,6 +123,7 @@ typedef void ALCvoid;
|
|||
*/
|
||||
#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004
|
||||
#define ALC_DEVICE_SPECIFIER 0x1005
|
||||
#define ALC_ALL_DEVICES_SPECIFIER 0x1013
|
||||
#define ALC_EXTENSIONS 0x1006
|
||||
|
||||
#define ALC_MAJOR_VERSION 0x1000
|
||||
|
|
90
engine/code/asm/ftola.asm
Normal file
90
engine/code/asm/ftola.asm
Normal file
|
@ -0,0 +1,90 @@
|
|||
; ===========================================================================
|
||||
; Copyright (C) 2011 Thilo Schulz <thilo@tjps.eu>
|
||||
;
|
||||
; 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
|
||||
; ===========================================================================
|
||||
|
||||
; MASM ftol conversion functions using SSE or FPU
|
||||
; assume __cdecl calling convention is being used for x86, __fastcall for x64
|
||||
|
||||
IFNDEF idx64
|
||||
.model flat, c
|
||||
ENDIF
|
||||
|
||||
; .data
|
||||
|
||||
; ifndef idx64
|
||||
; fpucw WORD 0F7Fh
|
||||
; endif
|
||||
|
||||
.code
|
||||
|
||||
IFDEF idx64
|
||||
; qftol using SSE
|
||||
|
||||
qftolsse PROC
|
||||
cvttss2si eax, xmm0
|
||||
ret
|
||||
qftolsse ENDP
|
||||
|
||||
qvmftolsse PROC
|
||||
movss xmm0, dword ptr [rdi + rbx * 4]
|
||||
cvttss2si eax, xmm0
|
||||
ret
|
||||
qvmftolsse ENDP
|
||||
|
||||
ELSE
|
||||
; qftol using FPU
|
||||
|
||||
qftolx87m macro src
|
||||
; not necessary, fpucw is set with _controlfp at startup
|
||||
; sub esp, 2
|
||||
; fnstcw word ptr [esp]
|
||||
; fldcw fpucw
|
||||
fld dword ptr src
|
||||
fistp dword ptr src
|
||||
; fldcw [esp]
|
||||
mov eax, src
|
||||
; add esp, 2
|
||||
ret
|
||||
endm
|
||||
|
||||
qftolx87 PROC
|
||||
; need this line when storing FPU control word on stack
|
||||
; qftolx87m [esp + 6]
|
||||
qftolx87m [esp + 4]
|
||||
qftolx87 ENDP
|
||||
|
||||
qvmftolx87 PROC
|
||||
qftolx87m [edi + ebx * 4]
|
||||
qvmftolx87 ENDP
|
||||
|
||||
; qftol using SSE
|
||||
qftolsse PROC
|
||||
movss xmm0, dword ptr [esp + 4]
|
||||
cvttss2si eax, xmm0
|
||||
ret
|
||||
qftolsse ENDP
|
||||
|
||||
qvmftolsse PROC
|
||||
movss xmm0, dword ptr [edi + ebx * 4]
|
||||
cvttss2si eax, xmm0
|
||||
ret
|
||||
qvmftolsse ENDP
|
||||
ENDIF
|
||||
|
||||
end
|
88
engine/code/asm/ftola.c
Normal file
88
engine/code/asm/ftola.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2011 Thilo Schulz <thilo@tjps.eu>
|
||||
|
||||
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 "qasm-inline.h"
|
||||
|
||||
/*
|
||||
* GNU inline asm ftol conversion functions using SSE or FPU
|
||||
*/
|
||||
|
||||
long qftolsse(float f)
|
||||
{
|
||||
long retval;
|
||||
|
||||
__asm__ volatile
|
||||
(
|
||||
"cvttss2si %1, %0\n"
|
||||
: "=r" (retval)
|
||||
: "x" (f)
|
||||
);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int qvmftolsse(void)
|
||||
{
|
||||
int retval;
|
||||
|
||||
__asm__ volatile
|
||||
(
|
||||
"movss (" EDI ", " EBX ", 4), %%xmm0\n"
|
||||
"cvttss2si %%xmm0, %0\n"
|
||||
: "=r" (retval)
|
||||
:
|
||||
: "%xmm0"
|
||||
);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
long qftolx87(float f)
|
||||
{
|
||||
long retval;
|
||||
|
||||
__asm__ volatile
|
||||
(
|
||||
"flds %1\n"
|
||||
"fistpl %1\n"
|
||||
"mov %1, %0\n"
|
||||
: "=r" (retval)
|
||||
: "m" (f)
|
||||
);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int qvmftolx87(void)
|
||||
{
|
||||
int retval;
|
||||
|
||||
__asm__ volatile
|
||||
(
|
||||
"flds (" EDI ", " EBX ", 4)\n"
|
||||
"fistpl (" EDI ", " EBX ", 4)\n"
|
||||
"mov (" EDI ", " EBX ", 4), %0\n"
|
||||
: "=r" (retval)
|
||||
);
|
||||
|
||||
return retval;
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
//
|
||||
// qftol -- fast floating point to long conversion.
|
||||
//
|
||||
|
||||
// 23/09/05 Ported to gas by intel2gas, best supporting actor Tim Angus
|
||||
// <tim@ngus.net>
|
||||
|
||||
#include "qasm.h"
|
||||
|
||||
#if id386
|
||||
|
||||
.data
|
||||
|
||||
temp: .single 0.0
|
||||
fpucw: .long 0
|
||||
|
||||
// Precision Control Field , 2 bits / 0x0300
|
||||
// PC24 0x0000 Single precision (24 bits).
|
||||
// PC53 0x0200 Double precision (53 bits).
|
||||
// PC64 0x0300 Extended precision (64 bits).
|
||||
|
||||
// Rounding Control Field, 2 bits / 0x0C00
|
||||
// RCN 0x0000 Rounding to nearest (even).
|
||||
// RCD 0x0400 Rounding down (directed, minus).
|
||||
// RCU 0x0800 Rounding up (directed plus).
|
||||
// RC0 0x0C00 Rounding towards zero (chop mode).
|
||||
|
||||
|
||||
// rounding towards nearest (even)
|
||||
cw027F: .long 0x027F
|
||||
cw037F: .long 0x037F
|
||||
|
||||
// rounding towards zero (chop mode)
|
||||
cw0E7F: .long 0x0E7F
|
||||
cw0F7F: .long 0x0F7F
|
||||
|
||||
|
||||
.text
|
||||
|
||||
//
|
||||
// int qftol( void ) - default control word
|
||||
//
|
||||
|
||||
.globl C(qftol)
|
||||
|
||||
C(qftol):
|
||||
fistpl temp
|
||||
movl temp,%eax
|
||||
ret
|
||||
|
||||
|
||||
//
|
||||
// int qftol027F( void ) - DirectX FPU
|
||||
//
|
||||
|
||||
.globl C(qftol027F)
|
||||
|
||||
C(qftol027F):
|
||||
fnstcw fpucw
|
||||
fldcw cw027F
|
||||
fistpl temp
|
||||
fldcw fpucw
|
||||
movl temp,%eax
|
||||
ret
|
||||
|
||||
//
|
||||
// int qftol037F( void ) - Linux FPU
|
||||
//
|
||||
|
||||
.globl C(qftol037F)
|
||||
|
||||
C(qftol037F):
|
||||
fnstcw fpucw
|
||||
fldcw cw037F
|
||||
fistpl temp
|
||||
fldcw fpucw
|
||||
movl temp,%eax
|
||||
ret
|
||||
|
||||
|
||||
//
|
||||
// int qftol0F7F( void ) - ANSI
|
||||
//
|
||||
|
||||
.globl C(qftol0F7F)
|
||||
|
||||
C(qftol0F7F):
|
||||
fnstcw fpucw
|
||||
fldcw cw0F7F
|
||||
fistpl temp
|
||||
fldcw fpucw
|
||||
movl temp,%eax
|
||||
ret
|
||||
|
||||
//
|
||||
// int qftol0E7F( void )
|
||||
//
|
||||
|
||||
.globl C(qftol0E7F)
|
||||
|
||||
C(qftol0E7F):
|
||||
fnstcw fpucw
|
||||
fldcw cw0E7F
|
||||
fistpl temp
|
||||
fldcw fpucw
|
||||
movl temp,%eax
|
||||
ret
|
||||
|
||||
|
||||
|
||||
//
|
||||
// long Q_ftol( float q )
|
||||
//
|
||||
|
||||
.globl C(Q_ftol)
|
||||
|
||||
C(Q_ftol):
|
||||
flds 4(%esp)
|
||||
fistpl temp
|
||||
movl temp,%eax
|
||||
ret
|
||||
|
||||
|
||||
//
|
||||
// long qftol0F7F( float q ) - Linux FPU
|
||||
//
|
||||
|
||||
.globl C(Q_ftol0F7F)
|
||||
|
||||
C(Q_ftol0F7F):
|
||||
fnstcw fpucw
|
||||
flds 4(%esp)
|
||||
fldcw cw0F7F
|
||||
fistpl temp
|
||||
fldcw fpucw
|
||||
movl temp,%eax
|
||||
ret
|
||||
#endif
|
|
@ -15,7 +15,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
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
|
||||
===========================================================================
|
||||
*/
|
||||
|
|
39
engine/code/asm/qasm-inline.h
Normal file
39
engine/code/asm/qasm-inline.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
===========================================================================
|
||||
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
|
||||
===========================================================================
|
||||
*/
|
||||
#ifndef __ASM_INLINE_I386__
|
||||
#define __ASM_INLINE_I386__
|
||||
|
||||
#include "../qcommon/q_platform.h"
|
||||
|
||||
#if idx64
|
||||
#define EAX "%%rax"
|
||||
#define EBX "%%rbx"
|
||||
#define ESP "%%rsp"
|
||||
#define EDI "%%rdi"
|
||||
#else
|
||||
#define EAX "%%eax"
|
||||
#define EBX "%%ebx"
|
||||
#define ESP "%%esp"
|
||||
#define EDI "%%edi"
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -28,7 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
.section .note.GNU-stack,"",@progbits
|
||||
#endif
|
||||
|
||||
#ifdef __ELF__
|
||||
#if defined(__ELF__) || defined(__WIN64__)
|
||||
#define C(label) label
|
||||
#else
|
||||
#define C(label) _##label
|
||||
|
|
107
engine/code/asm/snapvector.asm
Normal file
107
engine/code/asm/snapvector.asm
Normal file
|
@ -0,0 +1,107 @@
|
|||
; ===========================================================================
|
||||
; Copyright (C) 2011 Thilo Schulz <thilo@tjps.eu>
|
||||
;
|
||||
; 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
|
||||
; ===========================================================================
|
||||
|
||||
; MASM version of snapvector conversion function using SSE or FPU
|
||||
; assume __cdecl calling convention is being used for x86, __fastcall for x64
|
||||
;
|
||||
; function prototype:
|
||||
; void qsnapvector(vec3_t vec)
|
||||
|
||||
IFNDEF idx64
|
||||
.model flat, c
|
||||
ENDIF
|
||||
|
||||
.data
|
||||
|
||||
ALIGN 16
|
||||
ssemask DWORD 0FFFFFFFFh, 0FFFFFFFFh, 0FFFFFFFFh, 00000000h
|
||||
ssecw DWORD 00001F80h
|
||||
|
||||
IFNDEF idx64
|
||||
fpucw WORD 037Fh
|
||||
ENDIF
|
||||
|
||||
.code
|
||||
|
||||
IFDEF idx64
|
||||
; qsnapvector using SSE
|
||||
|
||||
qsnapvectorsse PROC
|
||||
sub rsp, 8
|
||||
stmxcsr [rsp] ; save SSE control word
|
||||
ldmxcsr ssecw ; set to round nearest
|
||||
|
||||
push rdi
|
||||
mov rdi, rcx ; maskmovdqu uses rdi as implicit memory operand
|
||||
movaps xmm1, ssemask ; initialize the mask register for maskmovdqu
|
||||
movups xmm0, [rdi] ; here is stored our vector. Read 4 values in one go
|
||||
cvtps2dq xmm0, xmm0 ; convert 4 single fp to int
|
||||
cvtdq2ps xmm0, xmm0 ; convert 4 int to single fp
|
||||
maskmovdqu xmm0, xmm1 ; write 3 values back to memory
|
||||
pop rdi
|
||||
|
||||
ldmxcsr [rsp] ; restore sse control word to old value
|
||||
add rsp, 8
|
||||
ret
|
||||
qsnapvectorsse ENDP
|
||||
|
||||
ELSE
|
||||
|
||||
qsnapvectorsse PROC
|
||||
sub esp, 8
|
||||
stmxcsr [esp] ; save SSE control word
|
||||
ldmxcsr ssecw ; set to round nearest
|
||||
|
||||
push edi
|
||||
mov edi, dword ptr 16[esp] ; maskmovdqu uses edi as implicit memory operand
|
||||
movaps xmm1, ssemask ; initialize the mask register for maskmovdqu
|
||||
movups xmm0, [edi] ; here is stored our vector. Read 4 values in one go
|
||||
cvtps2dq xmm0, xmm0 ; convert 4 single fp to int
|
||||
cvtdq2ps xmm0, xmm0 ; convert 4 int to single fp
|
||||
maskmovdqu xmm0, xmm1 ; write 3 values back to memory
|
||||
pop edi
|
||||
|
||||
ldmxcsr [esp] ; restore sse control word to old value
|
||||
add esp, 8
|
||||
ret
|
||||
qsnapvectorsse ENDP
|
||||
|
||||
qroundx87 macro src
|
||||
fld dword ptr src
|
||||
fistp dword ptr src
|
||||
fild dword ptr src
|
||||
fstp dword ptr src
|
||||
endm
|
||||
|
||||
qsnapvectorx87 PROC
|
||||
mov eax, dword ptr 4[esp]
|
||||
sub esp, 2
|
||||
fnstcw word ptr [esp]
|
||||
fldcw fpucw
|
||||
qroundx87 [eax]
|
||||
qroundx87 4[eax]
|
||||
qroundx87 8[eax]
|
||||
fldcw [esp]
|
||||
add esp, 2
|
||||
qsnapvectorx87 ENDP
|
||||
|
||||
ENDIF
|
||||
|
||||
end
|
87
engine/code/asm/snapvector.c
Normal file
87
engine/code/asm/snapvector.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2011 Thilo Schulz <thilo@tjps.eu>
|
||||
|
||||
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 "qasm-inline.h"
|
||||
#include "../qcommon/q_shared.h"
|
||||
|
||||
/*
|
||||
* GNU inline asm version of qsnapvector
|
||||
* See MASM snapvector.asm for commentary
|
||||
*/
|
||||
|
||||
static unsigned char ssemask[16] __attribute__((aligned(16))) =
|
||||
{
|
||||
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00"
|
||||
};
|
||||
|
||||
static const unsigned int ssecw __attribute__((aligned(16))) = 0x00001F80;
|
||||
static const unsigned short fpucw = 0x037F;
|
||||
|
||||
void qsnapvectorsse(vec3_t vec)
|
||||
{
|
||||
uint32_t oldcw __attribute__((aligned(16)));
|
||||
|
||||
__asm__ volatile
|
||||
(
|
||||
"stmxcsr %3\n"
|
||||
"ldmxcsr %1\n"
|
||||
|
||||
"movaps (%0), %%xmm1\n"
|
||||
"movups (%2), %%xmm0\n"
|
||||
"cvtps2dq %%xmm0, %%xmm0\n"
|
||||
"cvtdq2ps %%xmm0, %%xmm0\n"
|
||||
// vec MUST reside in register rdi as maskmovdqu uses
|
||||
// it as an implicit operand. The "D" constraint makes
|
||||
// sure of that.
|
||||
"maskmovdqu %%xmm1, %%xmm0\n"
|
||||
|
||||
"ldmxcsr %3\n"
|
||||
:
|
||||
: "r" (ssemask), "m" (ssecw), "D" (vec), "m" (oldcw)
|
||||
: "memory", "%xmm0", "%xmm1"
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
#define QROUNDX87(src) \
|
||||
"flds " src "\n" \
|
||||
"fistp " src "\n" \
|
||||
"fild " src "\n" \
|
||||
"fstp " src "\n"
|
||||
|
||||
void qsnapvectorx87(vec3_t vec)
|
||||
{
|
||||
__asm__ volatile
|
||||
(
|
||||
"sub $2, " ESP "\n"
|
||||
"fnstcw (" ESP ")\n"
|
||||
"fldcw %0\n"
|
||||
QROUNDX87("(%1)")
|
||||
QROUNDX87("4(%1)")
|
||||
QROUNDX87("8(%1)")
|
||||
"fldcw (" ESP ")\n"
|
||||
"add $2, " ESP "\n"
|
||||
:
|
||||
: "m" (fpucw), "r" (vec)
|
||||
: "memory"
|
||||
);
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
//
|
||||
// Sys_SnapVector NASM code (Andrew Henderson)
|
||||
// See win32/win_shared.c for the Win32 equivalent
|
||||
// This code is provided to ensure that the
|
||||
// rounding behavior (and, if necessary, the
|
||||
// precision) of DLL and QVM code are identical
|
||||
// e.g. for network-visible operations.
|
||||
// See ftol.nasm for operations on a single float,
|
||||
// as used in compiled VM and DLL code that does
|
||||
// not use this system trap.
|
||||
//
|
||||
|
||||
// 23/09/05 Ported to gas by intel2gas, best supporting actor Tim Angus
|
||||
// <tim@ngus.net>
|
||||
|
||||
#include "qasm.h"
|
||||
|
||||
#if id386
|
||||
.data
|
||||
|
||||
fpucw: .long 0
|
||||
cw037F: .long 0x037F
|
||||
|
||||
.text
|
||||
|
||||
// void Sys_SnapVector( float *v )
|
||||
.globl C(Sys_SnapVector)
|
||||
C(Sys_SnapVector):
|
||||
pushl %eax
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
|
||||
fnstcw fpucw
|
||||
movl 12(%ebp),%eax
|
||||
fldcw cw037F
|
||||
flds (%eax)
|
||||
fistpl (%eax)
|
||||
fildl (%eax)
|
||||
fstps (%eax)
|
||||
flds 4(%eax)
|
||||
fistpl 4(%eax)
|
||||
fildl 4(%eax)
|
||||
fstps 4(%eax)
|
||||
flds 8(%eax)
|
||||
fistpl 8(%eax)
|
||||
fildl 8(%eax)
|
||||
fstps 8(%eax)
|
||||
fldcw fpucw
|
||||
|
||||
popl %ebp
|
||||
popl %eax
|
||||
ret
|
||||
|
||||
// void Sys_SnapVectorCW( float *v, unsigned short int cw )
|
||||
.globl C(Sys_SnapVectorCW)
|
||||
C(Sys_SnapVectorCW):
|
||||
pushl %eax
|
||||
pushl %ebp
|
||||
movl %esp,%ebp
|
||||
|
||||
fnstcw fpucw
|
||||
movl 12(%ebp),%eax
|
||||
fldcw 16(%ebp)
|
||||
flds (%eax)
|
||||
fistpl (%eax)
|
||||
fildl (%eax)
|
||||
fstps (%eax)
|
||||
flds 4(%eax)
|
||||
fistpl 4(%eax)
|
||||
fildl 4(%eax)
|
||||
fstps 4(%eax)
|
||||
flds 8(%eax)
|
||||
fistpl 8(%eax)
|
||||
fildl 8(%eax)
|
||||
fstps 8(%eax)
|
||||
fldcw fpucw
|
||||
|
||||
popl %ebp
|
||||
popl %eax
|
||||
ret
|
||||
#endif
|
|
@ -15,7 +15,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
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
|
||||
===========================================================================
|
||||
*/
|
||||
|
|
76
engine/code/asm/vm_x86_64.asm
Normal file
76
engine/code/asm/vm_x86_64.asm
Normal file
|
@ -0,0 +1,76 @@
|
|||
; ===========================================================================
|
||||
; Copyright (C) 2011 Thilo Schulz <thilo@tjps.eu>
|
||||
;
|
||||
; 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
|
||||
; ===========================================================================
|
||||
|
||||
; Call wrapper for vm_x86 when built with MSVC in 64 bit mode,
|
||||
; since MSVC does not support inline x64 assembler code anymore.
|
||||
;
|
||||
; assumes __fastcall calling convention
|
||||
|
||||
DoSyscall PROTO
|
||||
|
||||
.code
|
||||
|
||||
; Call to static void DoSyscall(int syscallNum, int programStack, int *opStackBase, uint8_t opStackOfs, intptr_t arg)
|
||||
|
||||
qsyscall64 PROC
|
||||
sub rsp, 28h ; after this esp will be aligned to 16 byte boundary
|
||||
mov qword ptr [rsp + 20h], rcx ; 5th parameter "arg" is passed on stack
|
||||
mov r9b, bl ; opStackOfs
|
||||
mov r8, rdi ; opStackBase
|
||||
mov edx, esi ; programStack
|
||||
mov ecx, eax ; syscallNum
|
||||
mov rax, DoSyscall ; store call address of DoSyscall in rax
|
||||
call rax
|
||||
add rsp, 28h
|
||||
ret
|
||||
qsyscall64 ENDP
|
||||
|
||||
|
||||
; Call to compiled code after setting up the register environment for the VM
|
||||
; prototype:
|
||||
; uint8_t qvmcall64(int *programStack, int *opStack, intptr_t *instructionPointers, byte *dataBase);
|
||||
|
||||
qvmcall64 PROC
|
||||
push rsi ; push non-volatile registers to stack
|
||||
push rdi
|
||||
push rbx
|
||||
; need to save pointer in rcx so we can write back the programData value to caller
|
||||
push rcx
|
||||
|
||||
; registers r8 and r9 have correct value already thanx to __fastcall
|
||||
xor rbx, rbx ; opStackOfs starts out being 0
|
||||
mov rdi, rdx ; opStack
|
||||
mov esi, dword ptr [rcx] ; programStack
|
||||
|
||||
call qword ptr [r8] ; instructionPointers[0] is also the entry point
|
||||
|
||||
pop rcx
|
||||
|
||||
mov dword ptr [rcx], esi ; write back the programStack value
|
||||
mov al, bl ; return opStack offset
|
||||
|
||||
pop rbx
|
||||
pop rdi
|
||||
pop rsi
|
||||
|
||||
ret
|
||||
qvmcall64 ENDP
|
||||
|
||||
end
|
|
@ -216,7 +216,7 @@ void AAS_ContinueInit(float time)
|
|||
//save the AAS file
|
||||
if (AAS_WriteAASFile(aasworld.filename))
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "%s written succesfully\n", aasworld.filename);
|
||||
botimport.Print(PRT_MESSAGE, "%s written successfully\n", aasworld.filename);
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
|
|
|
@ -34,7 +34,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
extern aas_t aasworld;
|
||||
|
||||
//AAS error message
|
||||
void QDECL AAS_Error(char *fmt, ...);
|
||||
void QDECL AAS_Error(char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
//set AAS initialized
|
||||
void AAS_SetInitialized(void);
|
||||
//setup AAS with the given number of entities and clients
|
||||
|
|
|
@ -1556,7 +1556,7 @@ int AAS_Reachability_Step_Barrier_WaterJump_WalkOffLedge(int area1num, int area2
|
|||
if (AAS_PointAreaNum(trace.endpos) == area2num)
|
||||
{
|
||||
//if not going through a cluster portal
|
||||
numareas = AAS_TraceAreas(start, end, areas, NULL, sizeof(areas) / sizeof(int));
|
||||
numareas = AAS_TraceAreas(start, end, areas, NULL, ARRAY_LEN(areas));
|
||||
for (i = 0; i < numareas; i++)
|
||||
if (AAS_AreaClusterPortal(areas[i]))
|
||||
break;
|
||||
|
@ -2311,7 +2311,7 @@ int AAS_Reachability_Jump(int area1num, int area2num)
|
|||
//because the predicted jump could have rushed through the area
|
||||
VectorMA(move.endpos, -64, dir, teststart);
|
||||
teststart[2] += 1;
|
||||
numareas = AAS_TraceAreas(move.endpos, teststart, areas, NULL, sizeof(areas) / sizeof(int));
|
||||
numareas = AAS_TraceAreas(move.endpos, teststart, areas, NULL, ARRAY_LEN(areas));
|
||||
for (j = 0; j < numareas; j++)
|
||||
{
|
||||
if (areas[j] == area2num)
|
||||
|
@ -4254,7 +4254,7 @@ void AAS_Reachability_WalkOffLedge(int areanum)
|
|||
break;
|
||||
} //end if
|
||||
//if not going through a cluster portal
|
||||
numareas = AAS_TraceAreas(mid, testend, areas, NULL, sizeof(areas) / sizeof(int));
|
||||
numareas = AAS_TraceAreas(mid, testend, areas, NULL, ARRAY_LEN(areas));
|
||||
for (p = 0; p < numareas; p++)
|
||||
if (AAS_AreaClusterPortal(areas[p]))
|
||||
break;
|
||||
|
|
|
@ -1065,7 +1065,7 @@ int AAS_ReadRouteCache(void)
|
|||
botimport.FS_Read(&routecacheheader, sizeof(routecacheheader_t), fp );
|
||||
if (routecacheheader.ident != RCID)
|
||||
{
|
||||
AAS_Error("%s is not a route cache dump\n");
|
||||
AAS_Error("%s is not a route cache dump\n", filename);
|
||||
return qfalse;
|
||||
} //end if
|
||||
if (routecacheheader.version != RCVERSION)
|
||||
|
|
|
@ -698,7 +698,7 @@ bot_synonymlist_t *BotLoadSynonyms(char *filename)
|
|||
StripDoubleQuotes(token.string);
|
||||
if (strlen(token.string) <= 0)
|
||||
{
|
||||
SourceError(source, "empty string", token.string);
|
||||
SourceError(source, "empty string");
|
||||
FreeSource(source);
|
||||
return NULL;
|
||||
} //end if
|
||||
|
@ -2198,7 +2198,7 @@ bot_chat_t *BotLoadInitialChat(char *chatfile, char *chatname)
|
|||
#ifdef DEBUG
|
||||
botimport.Print(PRT_MESSAGE, "initial chats loaded in %d msec\n", Sys_MilliSeconds() - starttime);
|
||||
#endif //DEBUG
|
||||
//character was read succesfully
|
||||
//character was read successfully
|
||||
return chat;
|
||||
} //end of the function BotLoadInitialChat
|
||||
//===========================================================================
|
||||
|
|
|
@ -2366,7 +2366,7 @@ bot_moveresult_t BotTravel_FuncBobbing(bot_movestate_t *ms, aas_reachability_t *
|
|||
VectorSubtract(reach->start, ms->origin, dir1);
|
||||
if (!(ms->moveflags & MFL_SWIMMING)) dir1[2] = 0;
|
||||
dist1 = VectorNormalize(dir1);
|
||||
//if func_bobbing is Not it's start position
|
||||
//if func_bobbing is Not its start position
|
||||
VectorSubtract(bob_origin, bob_start, dir);
|
||||
if (VectorLength(dir) > 16)
|
||||
{
|
||||
|
@ -3027,7 +3027,7 @@ void BotMoveToGoal(bot_moveresult_t *result, int movestate, bot_goal_t *goal, in
|
|||
ms = BotMoveStateFromHandle(movestate);
|
||||
if (!ms) return;
|
||||
//reset the grapple before testing if the bot has a valid goal
|
||||
//because the bot could loose all it's goals when stuck to a wall
|
||||
//because the bot could lose all its goals when stuck to a wall
|
||||
BotResetGrapple(ms);
|
||||
//
|
||||
if (!goal)
|
||||
|
@ -3509,7 +3509,7 @@ void BotResetLastAvoidReach(int movestate)
|
|||
if (latesttime)
|
||||
{
|
||||
ms->avoidreachtimes[latest] = 0;
|
||||
if (ms->avoidreachtries[i] > 0) ms->avoidreachtries[latest]--;
|
||||
if (ms->avoidreachtries[latest] > 0) ms->avoidreachtries[latest]--;
|
||||
} //end if
|
||||
} //end of the function BotResetLastAvoidReach
|
||||
//===========================================================================
|
||||
|
|
|
@ -83,7 +83,7 @@ static fielddef_t weaponinfo_fields[] =
|
|||
static fielddef_t projectileinfo_fields[] =
|
||||
{
|
||||
{"name", PROJECTILE_OFS(name), FT_STRING}, //name of the projectile
|
||||
{"model", WEAPON_OFS(model), FT_STRING}, //model of the projectile
|
||||
{"model", PROJECTILE_OFS(model), FT_STRING}, //model of the projectile
|
||||
{"flags", PROJECTILE_OFS(flags), FT_INT}, //special flags
|
||||
{"gravity", PROJECTILE_OFS(gravity), FT_FLOAT}, //amount of gravity applied to the projectile [0,1]
|
||||
{"damage", PROJECTILE_OFS(damage), FT_INT}, //damage of the projectile
|
||||
|
|
|
@ -40,7 +40,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#define MAX_USERMOVE 400
|
||||
#define MAX_COMMANDARGUMENTS 10
|
||||
#define ACTION_JUMPEDLASTFRAME 128
|
||||
|
||||
bot_input_t *botinputs;
|
||||
|
||||
|
@ -416,24 +415,6 @@ void EA_View(int client, vec3_t viewangles)
|
|||
//===========================================================================
|
||||
void EA_EndRegular(int client, float thinktime)
|
||||
{
|
||||
/*
|
||||
bot_input_t *bi;
|
||||
int jumped = qfalse;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
bi->actionflags &= ~ACTION_JUMPEDLASTFRAME;
|
||||
|
||||
bi->thinktime = thinktime;
|
||||
botimport.BotInput(client, bi);
|
||||
|
||||
bi->thinktime = 0;
|
||||
VectorClear(bi->dir);
|
||||
bi->speed = 0;
|
||||
jumped = bi->actionflags & ACTION_JUMP;
|
||||
bi->actionflags = 0;
|
||||
if (jumped) bi->actionflags |= ACTION_JUMPEDLASTFRAME;
|
||||
*/
|
||||
} //end of the function EA_EndRegular
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -444,23 +425,10 @@ void EA_EndRegular(int client, float thinktime)
|
|||
void EA_GetInput(int client, float thinktime, bot_input_t *input)
|
||||
{
|
||||
bot_input_t *bi;
|
||||
// int jumped = qfalse;
|
||||
|
||||
bi = &botinputs[client];
|
||||
|
||||
// bi->actionflags &= ~ACTION_JUMPEDLASTFRAME;
|
||||
|
||||
bi->thinktime = thinktime;
|
||||
Com_Memcpy(input, bi, sizeof(bot_input_t));
|
||||
|
||||
/*
|
||||
bi->thinktime = 0;
|
||||
VectorClear(bi->dir);
|
||||
bi->speed = 0;
|
||||
jumped = bi->actionflags & ACTION_JUMP;
|
||||
bi->actionflags = 0;
|
||||
if (jumped) bi->actionflags |= ACTION_JUMPEDLASTFRAME;
|
||||
*/
|
||||
} //end of the function EA_GetInput
|
||||
//===========================================================================
|
||||
//
|
||||
|
@ -474,7 +442,6 @@ void EA_ResetInput(int client)
|
|||
int jumped = qfalse;
|
||||
|
||||
bi = &botinputs[client];
|
||||
bi->actionflags &= ~ACTION_JUMPEDLASTFRAME;
|
||||
|
||||
bi->thinktime = 0;
|
||||
VectorClear(bi->dir);
|
||||
|
|
|
@ -144,16 +144,19 @@ int Export_BotLibSetup(void)
|
|||
|
||||
if(botDeveloper)
|
||||
{
|
||||
char *homedir, *gamedir;
|
||||
char *homedir, *gamedir, *basedir;
|
||||
char logfilename[MAX_OSPATH];
|
||||
|
||||
homedir = LibVarGetString("homedir");
|
||||
gamedir = LibVarGetString("gamedir");
|
||||
basedir = LibVarGetString("com_basegame");
|
||||
|
||||
if (*homedir)
|
||||
{
|
||||
if(*gamedir)
|
||||
Com_sprintf(logfilename, sizeof(logfilename), "%s%c%s%cbotlib.log", homedir, PATH_SEP, gamedir, PATH_SEP);
|
||||
else if(*basedir)
|
||||
Com_sprintf(logfilename, sizeof(logfilename), "%s%c%s%cbotlib.log", homedir, PATH_SEP, basedir, PATH_SEP);
|
||||
else
|
||||
Com_sprintf(logfilename, sizeof(logfilename), "%s%c" BASEGAME "%cbotlib.log", homedir, PATH_SEP, PATH_SEP);
|
||||
}
|
||||
|
|
|
@ -80,27 +80,28 @@ struct weaponinfo_s;
|
|||
#define BLERR_CANNOTLOADWEAPONCONFIG 12 //cannot load weapon config
|
||||
|
||||
//action flags
|
||||
#define ACTION_ATTACK 0x0000001
|
||||
#define ACTION_USE 0x0000002
|
||||
#define ACTION_RESPAWN 0x0000008
|
||||
#define ACTION_JUMP 0x0000010
|
||||
#define ACTION_MOVEUP 0x0000020
|
||||
#define ACTION_CROUCH 0x0000080
|
||||
#define ACTION_MOVEDOWN 0x0000100
|
||||
#define ACTION_MOVEFORWARD 0x0000200
|
||||
#define ACTION_MOVEBACK 0x0000800
|
||||
#define ACTION_MOVELEFT 0x0001000
|
||||
#define ACTION_MOVERIGHT 0x0002000
|
||||
#define ACTION_DELAYEDJUMP 0x0008000
|
||||
#define ACTION_TALK 0x0010000
|
||||
#define ACTION_GESTURE 0x0020000
|
||||
#define ACTION_WALK 0x0080000
|
||||
#define ACTION_AFFIRMATIVE 0x0100000
|
||||
#define ACTION_NEGATIVE 0x0200000
|
||||
#define ACTION_GETFLAG 0x0800000
|
||||
#define ACTION_GUARDBASE 0x1000000
|
||||
#define ACTION_PATROL 0x2000000
|
||||
#define ACTION_FOLLOWME 0x8000000
|
||||
#define ACTION_ATTACK 0x00000001
|
||||
#define ACTION_USE 0x00000002
|
||||
#define ACTION_RESPAWN 0x00000008
|
||||
#define ACTION_JUMP 0x00000010
|
||||
#define ACTION_MOVEUP 0x00000020
|
||||
#define ACTION_CROUCH 0x00000080
|
||||
#define ACTION_MOVEDOWN 0x00000100
|
||||
#define ACTION_MOVEFORWARD 0x00000200
|
||||
#define ACTION_MOVEBACK 0x00000800
|
||||
#define ACTION_MOVELEFT 0x00001000
|
||||
#define ACTION_MOVERIGHT 0x00002000
|
||||
#define ACTION_DELAYEDJUMP 0x00008000
|
||||
#define ACTION_TALK 0x00010000
|
||||
#define ACTION_GESTURE 0x00020000
|
||||
#define ACTION_WALK 0x00080000
|
||||
#define ACTION_AFFIRMATIVE 0x00100000
|
||||
#define ACTION_NEGATIVE 0x00200000
|
||||
#define ACTION_GETFLAG 0x00800000
|
||||
#define ACTION_GUARDBASE 0x01000000
|
||||
#define ACTION_PATROL 0x02000000
|
||||
#define ACTION_FOLLOWME 0x08000000
|
||||
#define ACTION_JUMPEDLASTFRAME 0x10000000
|
||||
|
||||
//the bot input, will be converted to an usercmd_t
|
||||
typedef struct bot_input_s
|
||||
|
@ -170,7 +171,7 @@ typedef struct bot_entitystate_s
|
|||
typedef struct botlib_import_s
|
||||
{
|
||||
//print messages from the bot library
|
||||
void (QDECL *Print)(int type, char *fmt, ...);
|
||||
void (QDECL *Print)(int type, char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
//trace a bbox through the world
|
||||
void (*Trace)(bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask);
|
||||
//trace a bbox against a specific entity
|
||||
|
|
|
@ -36,9 +36,9 @@ void Log_Close(void);
|
|||
//close log file if present
|
||||
void Log_Shutdown(void);
|
||||
//write to the current opened log file
|
||||
void QDECL Log_Write(char *fmt, ...);
|
||||
void QDECL Log_Write(char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
//write to the current opened log file with a time stamp
|
||||
void QDECL Log_WriteTimeStamped(char *fmt, ...);
|
||||
void QDECL Log_WriteTimeStamped(char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
||||
//returns a pointer to the log file
|
||||
FILE *Log_FilePointer(void);
|
||||
//flush log file
|
||||
|
|
|
@ -271,7 +271,7 @@ token_t *PC_CopyToken(token_t *token)
|
|||
#ifdef BSPC
|
||||
Error("out of token space\n");
|
||||
#else
|
||||
Com_Error(ERR_FATAL, "out of token space\n");
|
||||
Com_Error(ERR_FATAL, "out of token space");
|
||||
#endif
|
||||
return NULL;
|
||||
} //end if
|
||||
|
@ -1362,7 +1362,7 @@ define_t *PC_DefineFromString(char *string)
|
|||
#endif //DEFINEHASHING
|
||||
//
|
||||
FreeScript(script);
|
||||
//if the define was created succesfully
|
||||
//if the define was created successfully
|
||||
if (res > 0) return def;
|
||||
//free the define is created
|
||||
if (src.defines) PC_FreeDefine(def);
|
||||
|
|
|
@ -152,9 +152,9 @@ source_t *LoadSourceMemory(char *ptr, int length, char *name);
|
|||
//free the given source
|
||||
void FreeSource(source_t *source);
|
||||
//print a source error
|
||||
void QDECL SourceError(source_t *source, char *str, ...);
|
||||
void QDECL SourceError(source_t *source, char *str, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
//print a source warning
|
||||
void QDECL SourceWarning(source_t *source, char *str, ...);
|
||||
void QDECL SourceWarning(source_t *source, char *str, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
|
||||
#ifdef BSPC
|
||||
// some of BSPC source does include game/q_shared.h and some does not
|
||||
|
|
|
@ -421,7 +421,7 @@ int PS_ReadEscapeCharacter(script_t *script, char *ch)
|
|||
script->script_p++;
|
||||
//store the escape character
|
||||
*ch = c;
|
||||
//succesfully read escape character
|
||||
//successfully read escape character
|
||||
return 1;
|
||||
} //end of the function PS_ReadEscapeCharacter
|
||||
//============================================================================
|
||||
|
@ -431,7 +431,7 @@ int PS_ReadEscapeCharacter(script_t *script, char *ch)
|
|||
//
|
||||
// Parameter: script : script to read from
|
||||
// token : buffer to store the string
|
||||
// Returns: qtrue when a string was read succesfully
|
||||
// Returns: qtrue when a string was read successfully
|
||||
// Changes Globals: -
|
||||
//============================================================================
|
||||
int PS_ReadString(script_t *script, token_t *token, int quote)
|
||||
|
@ -912,7 +912,7 @@ int PS_ReadToken(script_t *script, token_t *token)
|
|||
} //end if
|
||||
//copy the token into the script structure
|
||||
Com_Memcpy(&script->token, token, sizeof(token_t));
|
||||
//succesfully read a token
|
||||
//successfully read a token
|
||||
return 1;
|
||||
} //end of the function PS_ReadToken
|
||||
//============================================================================
|
||||
|
@ -990,7 +990,7 @@ int PS_ExpectTokenType(script_t *script, int type, int subtype, token_t *token)
|
|||
if (token->subtype != subtype)
|
||||
{
|
||||
ScriptError(script, "expected %s, found %s",
|
||||
script->punctuations[subtype], token->string);
|
||||
script->punctuations[subtype].p, token->string);
|
||||
return 0;
|
||||
} //end if
|
||||
} //end else if
|
||||
|
@ -1158,7 +1158,7 @@ float ReadSignedFloat(script_t *script)
|
|||
{
|
||||
if(!PS_ExpectAnyToken(script, &token))
|
||||
{
|
||||
ScriptError(script, "Missing float value\n", token.string);
|
||||
ScriptError(script, "Missing float value\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1189,7 +1189,7 @@ signed long int ReadSignedInt(script_t *script)
|
|||
{
|
||||
if(!PS_ExpectAnyToken(script, &token))
|
||||
{
|
||||
ScriptError(script, "Missing integer value\n", token.string);
|
||||
ScriptError(script, "Missing integer value\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -240,8 +240,8 @@ void FreeScript(script_t *script);
|
|||
//set the base folder to load files from
|
||||
void PS_SetBaseFolder(char *path);
|
||||
//print a script error with filename and line number
|
||||
void QDECL ScriptError(script_t *script, char *str, ...);
|
||||
void QDECL ScriptError(script_t *script, char *str, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
//print a script warning with filename and line number
|
||||
void QDECL ScriptWarning(script_t *script, char *str, ...);
|
||||
void QDECL ScriptWarning(script_t *script, char *str, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ qboolean ReadNumber(source_t *source, fielddef_t *fd, void *p)
|
|||
} //end if
|
||||
if (intval < intmin || intval > intmax)
|
||||
{
|
||||
SourceError(source, "value %d out of range [%d, %d]", intval, intmin, intmax);
|
||||
SourceError(source, "value %ld out of range [%ld, %ld]", intval, intmin, intmax);
|
||||
return 0;
|
||||
} //end if
|
||||
} //end if
|
||||
|
@ -160,7 +160,7 @@ qboolean ReadNumber(source_t *source, fielddef_t *fd, void *p)
|
|||
{
|
||||
if (intval < fd->floatmin || intval > fd->floatmax)
|
||||
{
|
||||
SourceError(source, "value %d out of range [%f, %f]", intval, fd->floatmin, fd->floatmax);
|
||||
SourceError(source, "value %ld out of range [%f, %f]", intval, fd->floatmin, fd->floatmax);
|
||||
return 0;
|
||||
} //end if
|
||||
} //end if
|
||||
|
|
|
@ -675,7 +675,7 @@ qboolean CG_ConsoleCommand( void ) {
|
|||
|
||||
cmd = CG_Argv(0);
|
||||
|
||||
for ( i = 0 ; i < sizeof( commands ) / sizeof( commands[0] ) ; i++ ) {
|
||||
for ( i = 0 ; i < ARRAY_LEN( commands ) ; i++ ) {
|
||||
if ( !Q_stricmp( cmd, commands[i].cmd ) ) {
|
||||
commands[i].function();
|
||||
return qtrue;
|
||||
|
@ -697,7 +697,7 @@ so it can perform tab completion
|
|||
void CG_InitConsoleCommands( void ) {
|
||||
int i;
|
||||
|
||||
for ( i = 0 ; i < sizeof( commands ) / sizeof( commands[0] ) ; i++ ) {
|
||||
for ( i = 0 ; i < ARRAY_LEN( commands ) ; i++ ) {
|
||||
trap_AddCommand( commands[i].cmd );
|
||||
}
|
||||
|
||||
|
|
|
@ -2641,7 +2641,7 @@ static void CG_ScanForCrosshairEntity( void ) {
|
|||
}
|
||||
|
||||
// if the player is in fog, don't show it
|
||||
content = trap_CM_PointContents( trace.endpos, 0 );
|
||||
content = CG_PointContents( trace.endpos, 0 );
|
||||
if ( content & CONTENTS_FOG ) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -783,7 +783,7 @@ static void UI_DrawBannerString2( int x, int y, const char* str, vec4_t color )
|
|||
trap_R_SetColor( color );
|
||||
|
||||
ax = x * cgs.screenXScale + cgs.screenXBias;
|
||||
ay = y * cgs.screenXScale;
|
||||
ay = y * cgs.screenYScale;
|
||||
|
||||
s = str;
|
||||
while ( *s )
|
||||
|
@ -799,7 +799,7 @@ static void UI_DrawBannerString2( int x, int y, const char* str, vec4_t color )
|
|||
fwidth = (float)propMapB[ch][2] / 256.0f;
|
||||
fheight = (float)PROPB_HEIGHT / 256.0f;
|
||||
aw = (float)propMapB[ch][2] * cgs.screenXScale;
|
||||
ah = (float)PROPB_HEIGHT * cgs.screenXScale;
|
||||
ah = (float)PROPB_HEIGHT * cgs.screenYScale;
|
||||
trap_R_DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol+fwidth, frow+fheight, cgs.media.charsetPropB );
|
||||
ax += (aw + (float)PROPB_GAP_WIDTH * cgs.screenXScale);
|
||||
}
|
||||
|
@ -907,7 +907,7 @@ static void UI_DrawProportionalString2( int x, int y, const char* str, vec4_t co
|
|||
fwidth = (float)propMap[ch][2] / 256.0f;
|
||||
fheight = (float)PROP_HEIGHT / 256.0f;
|
||||
aw = (float)propMap[ch][2] * cgs.screenXScale * sizeScale;
|
||||
ah = (float)PROP_HEIGHT * cgs.screenXScale * sizeScale;
|
||||
ah = (float)PROP_HEIGHT * cgs.screenYScale * sizeScale;
|
||||
trap_R_DrawStretchPic( ax, ay, aw, ah, fcol, frow, fcol+fwidth, frow+fheight, charset );
|
||||
} else {
|
||||
aw = 0;
|
||||
|
|
|
@ -1063,10 +1063,10 @@ void CG_StartEarthquake(int intensity, int duration)
|
|||
earthquakeStoptime = cg.time + duration;
|
||||
}
|
||||
|
||||
void CG_Earthquake()
|
||||
void CG_Earthquake(void)
|
||||
{
|
||||
static float terremotoX, terremotoY, terremotoZ;
|
||||
static terremotoTime = 0;
|
||||
static int terremotoTime = 0;
|
||||
float realInt;
|
||||
|
||||
if ( !flagEarthquake )
|
||||
|
|
|
@ -147,16 +147,17 @@ static void CG_EntityEffects( centity_t *cent ) {
|
|||
|
||||
|
||||
// constant light glow
|
||||
if ( cent->currentState.constantLight ) {
|
||||
if(cent->currentState.constantLight)
|
||||
{
|
||||
int cl;
|
||||
int i, r, g, b;
|
||||
float i, r, g, b;
|
||||
|
||||
cl = cent->currentState.constantLight;
|
||||
r = cl & 255;
|
||||
g = ( cl >> 8 ) & 255;
|
||||
b = ( cl >> 16 ) & 255;
|
||||
i = ( ( cl >> 24 ) & 255 ) * 4;
|
||||
trap_R_AddLightToScene( cent->lerpOrigin, i, r, g, b );
|
||||
r = (float) (cl & 0xFF) / 255.0;
|
||||
g = (float) ((cl >> 8) & 0xFF) / 255.0;
|
||||
b = (float) ((cl >> 16) & 0xFF) / 255.0;
|
||||
i = (float) ((cl >> 24) & 0xFF) * 4.0;
|
||||
trap_R_AddLightToScene(cent->lerpOrigin, i, r, g, b);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -301,6 +302,11 @@ static void CG_Item( centity_t *cent ) {
|
|||
|
||||
cent->lerpOrigin[2] += 8; // an extra height boost
|
||||
}
|
||||
|
||||
if( item->giType == IT_WEAPON && item->giTag == WP_RAILGUN ) {
|
||||
clientInfo_t *ci = &cgs.clientinfo[cg.snap->ps.clientNum];
|
||||
Byte4Copy( ci->c1RGBA, ent.shaderRGBA );
|
||||
}
|
||||
|
||||
ent.hModel = cg_items[es->modelindex].models[0];
|
||||
|
||||
|
@ -461,7 +467,7 @@ static void CG_Missile( centity_t *cent ) {
|
|||
// int col;
|
||||
|
||||
s1 = ¢->currentState;
|
||||
if ( s1->weapon > WP_NUM_WEAPONS ) {
|
||||
if ( s1->weapon >= WP_NUM_WEAPONS ) {
|
||||
s1->weapon = 0;
|
||||
}
|
||||
weapon = &cg_weapons[s1->weapon];
|
||||
|
@ -618,7 +624,7 @@ static void CG_Grapple( centity_t *cent ) {
|
|||
const weaponInfo_t *weapon;
|
||||
|
||||
s1 = ¢->currentState;
|
||||
if ( s1->weapon > WP_NUM_WEAPONS ) {
|
||||
if ( s1->weapon >= WP_NUM_WEAPONS ) {
|
||||
s1->weapon = 0;
|
||||
}
|
||||
weapon = &cg_weapons[s1->weapon];
|
||||
|
|
|
@ -254,7 +254,7 @@ static void CG_Obituary( entityState_t *ent ) {
|
|||
if( gender == GENDER_FEMALE ) {
|
||||
message = "found her prox mine";
|
||||
} else if ( gender == GENDER_NEUTER ) {
|
||||
message = "found it's prox mine";
|
||||
message = "found its prox mine";
|
||||
} else {
|
||||
message = "found his prox mine";
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ void CG_LoadingClient( int clientNum ) {
|
|||
|
||||
if ( loadingPlayerIconCount < MAX_LOADING_PLAYER_ICONS ) {
|
||||
Q_strncpyz( model, Info_ValueForKey( info, "model" ), sizeof( model ) );
|
||||
skin = Q_strrchr( model, '/' );
|
||||
skin = strrchr( model, '/' );
|
||||
if ( skin ) {
|
||||
*skin++ = '\0';
|
||||
} else {
|
||||
|
|
|
@ -179,6 +179,8 @@ typedef struct {
|
|||
vec3_t railgunImpact;
|
||||
qboolean railgunFlash;
|
||||
|
||||
int railFireTime;
|
||||
|
||||
// machinegun spinning
|
||||
float barrelAngle;
|
||||
int barrelTime;
|
||||
|
@ -419,6 +421,9 @@ typedef struct {
|
|||
|
||||
vec3_t color1;
|
||||
vec3_t color2;
|
||||
|
||||
byte c1RGBA[4];
|
||||
byte c2RGBA[4];
|
||||
|
||||
int score; // updated by score servercmds
|
||||
int location; // location index for team mode
|
||||
|
@ -699,8 +704,10 @@ typedef struct {
|
|||
int spectatorOffset; // current offset from start
|
||||
int spectatorPaintLen; // current offset from start
|
||||
|
||||
#ifdef MISSIONPACK
|
||||
// skull trails
|
||||
skulltrail_t skulltrails[MAX_CLIENTS];
|
||||
#endif
|
||||
|
||||
// centerprinting
|
||||
int centerPrintTime;
|
||||
|
@ -717,9 +724,6 @@ typedef struct {
|
|||
// low ammo warning state
|
||||
int lowAmmoWarning; // 1 = low, 2 = empty
|
||||
|
||||
// kill timers for carnage reward
|
||||
int lastKillTime;
|
||||
|
||||
// crosshair client ID
|
||||
int crosshairClientNum;
|
||||
int crosshairClientTime;
|
||||
|
@ -782,9 +786,6 @@ typedef struct {
|
|||
float v_dmg_pitch;
|
||||
float v_dmg_roll;
|
||||
|
||||
vec3_t kick_angles; // weapon kicks
|
||||
vec3_t kick_origin;
|
||||
|
||||
// temp working variables for player view
|
||||
float bobfracsin;
|
||||
int bobcycle;
|
||||
|
@ -832,10 +833,12 @@ typedef struct {
|
|||
qhandle_t flameExplosionShader;
|
||||
// Q3Rally Code END
|
||||
|
||||
#ifdef MISSIONPACK
|
||||
qhandle_t redCubeModel;
|
||||
qhandle_t blueCubeModel;
|
||||
qhandle_t redCubeIcon;
|
||||
qhandle_t blueCubeIcon;
|
||||
#endif
|
||||
qhandle_t redFlagModel;
|
||||
qhandle_t blueFlagModel;
|
||||
qhandle_t neutralFlagModel;
|
||||
|
@ -1532,10 +1535,10 @@ extern vmCvar_t cg_drawBotPaths;
|
|||
const char *CG_ConfigString( int index );
|
||||
const char *CG_Argv( int arg );
|
||||
|
||||
void QDECL CG_Printf( const char *msg, ... );
|
||||
void QDECL CG_Error( const char *msg, ... );
|
||||
void QDECL CG_Printf( const char *msg, ... ) __attribute__ ((format (printf, 1, 2)));
|
||||
void QDECL CG_Error( const char *msg, ... ) __attribute__ ((noreturn, format (printf, 1, 2)));
|
||||
// Q3Rally Code Start
|
||||
void QDECL CG_DebugLogPrintf( const char *fmt, ... );
|
||||
void QDECL CG_DebugLogPrintf( const char *fmt, ... ) __attribute__ ((format (printf, 1, 2)));
|
||||
// Q3Rally Code END
|
||||
|
||||
void CG_StartMusic( void );
|
||||
|
@ -1661,7 +1664,7 @@ sfxHandle_t CG_CustomSound( int clientNum, const char *soundName );
|
|||
// cg_predict.c
|
||||
//
|
||||
// Q3Rally Code Start
|
||||
void QDECL Com_LogPrintf( const char *fmt, ... );
|
||||
void QDECL Com_LogPrintf( const char *fmt, ... ) __attribute__ ((format (printf, 1, 2)));
|
||||
void CG_UpdateCarFromPS ( playerState_t *ps );
|
||||
// Q3Rally Code END
|
||||
void CG_BuildSolidList( void );
|
||||
|
@ -1786,6 +1789,11 @@ void CG_InvulnerabilityJuiced( vec3_t org );
|
|||
void CG_LightningBoltBeam( vec3_t start, vec3_t end );
|
||||
#endif
|
||||
void CG_ScorePlum( int client, vec3_t org, int score );
|
||||
void CG_ShowDebris( vec3_t srcOrigin, int count, int evType );
|
||||
void CG_StartEarthquake(int intensity, int duration);
|
||||
void CG_Earthquake(void);
|
||||
void CG_ParticlesFromEntityState( vec3_t origin, int type, entityState_t *es);
|
||||
|
||||
|
||||
// Q3Rally Code Start
|
||||
// void CG_GibPlayer( vec3_t playerOrigin );
|
||||
|
@ -1969,7 +1977,7 @@ void CG_DropBio( centity_t *cent );
|
|||
void trap_Print( const char *fmt );
|
||||
|
||||
// abort the game
|
||||
void trap_Error( const char *fmt );
|
||||
void trap_Error(const char *fmt) __attribute__((noreturn));
|
||||
|
||||
// milliseconds should only be used for performance tuning, never
|
||||
// for anything game related. Get time from the CG_DrawActiveFrame parameter
|
||||
|
|
|
@ -154,7 +154,7 @@ void CG_PuffTrail( localEntity_t *le ) {
|
|||
mediaShader = cgs.media.smokePuffShader;
|
||||
verticalMovement = -40;
|
||||
}
|
||||
else if ( le->leTrailType == LETT_DEBRIS_WOOD ) {
|
||||
else /*if ( le->leTrailType == LETT_DEBRIS_WOOD )*/ {
|
||||
step = 25;
|
||||
r = 0.5;
|
||||
g = 0.42;
|
||||
|
@ -403,7 +403,7 @@ void CG_AddFragment( localEntity_t *le ) {
|
|||
// if it is in a nodrop zone, remove it
|
||||
// this keeps gibs from waiting at the bottom of pits of death
|
||||
// and floating levels
|
||||
if ( trap_CM_PointContents( trace.endpos, 0 ) & CONTENTS_NODROP ) {
|
||||
if ( CG_PointContents( trace.endpos, 0 ) & CONTENTS_NODROP ) {
|
||||
CG_FreeLocalEntity( le );
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -430,7 +430,7 @@ static cvarTable_t cvarTable[] = {
|
|||
// { &cg_pmove_fixed, "cg_pmove_fixed", "0", CVAR_USERINFO | CVAR_ARCHIVE }
|
||||
};
|
||||
|
||||
static int cvarTableSize = sizeof( cvarTable ) / sizeof( cvarTable[0] );
|
||||
static int cvarTableSize = ARRAY_LEN( cvarTable );
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -499,7 +499,7 @@ void CG_UpdateCvars( void ) {
|
|||
|
||||
// check for modications here
|
||||
|
||||
// If team overlay is on, ask for updates from the server. If its off,
|
||||
// If team overlay is on, ask for updates from the server. If it's off,
|
||||
// let the server know so we don't receive it
|
||||
if ( drawTeamOverlayModificationCount != cg_drawTeamOverlay.modificationCount ) {
|
||||
drawTeamOverlayModificationCount = cg_drawTeamOverlay.modificationCount;
|
||||
|
@ -1081,17 +1081,13 @@ static void CG_RegisterGraphics( void ) {
|
|||
cgs.media.hastePuffShader = trap_R_RegisterShader("hasteSmokePuff" );
|
||||
|
||||
#ifdef MISSIONPACK
|
||||
if ( cgs.gametype == GT_CTF || cgs.gametype == GT_1FCTF || cgs.gametype == GT_HARVESTER || cg_buildScript.integer ) {
|
||||
#else
|
||||
if ( cgs.gametype == GT_CTF || cg_buildScript.integer ) {
|
||||
#endif
|
||||
if ( cgs.gametype == GT_HARVESTER || cg_buildScript.integer ) {
|
||||
cgs.media.redCubeModel = trap_R_RegisterModel( "models/powerups/orb/r_orb.md3" );
|
||||
cgs.media.blueCubeModel = trap_R_RegisterModel( "models/powerups/orb/b_orb.md3" );
|
||||
cgs.media.redCubeIcon = trap_R_RegisterShader( "icons/skull_red" );
|
||||
cgs.media.blueCubeIcon = trap_R_RegisterShader( "icons/skull_blue" );
|
||||
}
|
||||
|
||||
#ifdef MISSIONPACK
|
||||
if ( cgs.gametype == GT_CTF || cgs.gametype == GT_1FCTF || cgs.gametype == GT_HARVESTER || cg_buildScript.integer ) {
|
||||
#else
|
||||
if ( cgs.gametype == GT_CTF || cg_buildScript.integer ) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -24,6 +24,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#include "cg_local.h"
|
||||
|
||||
//#define WOLF_PARTICLES
|
||||
|
||||
#define BLOODRED 2
|
||||
#define EMISIVEFADE 3
|
||||
#define GREY75 4
|
||||
|
@ -91,6 +93,21 @@ typedef enum
|
|||
#define MAX_SHADER_ANIMS 32
|
||||
#define MAX_SHADER_ANIM_FRAMES 64
|
||||
|
||||
#ifndef WOLF_PARTICLES
|
||||
static char *shaderAnimNames[MAX_SHADER_ANIMS] = {
|
||||
"explode1",
|
||||
NULL
|
||||
};
|
||||
static qhandle_t shaderAnims[MAX_SHADER_ANIMS][MAX_SHADER_ANIM_FRAMES];
|
||||
static int shaderAnimCounts[MAX_SHADER_ANIMS] = {
|
||||
23
|
||||
};
|
||||
static float shaderAnimSTRatio[MAX_SHADER_ANIMS] = {
|
||||
1.0f
|
||||
};
|
||||
static int numShaderAnims;
|
||||
// done.
|
||||
#else
|
||||
static char *shaderAnimNames[MAX_SHADER_ANIMS] = {
|
||||
"explode1",
|
||||
"blacksmokeanim",
|
||||
|
@ -117,11 +134,15 @@ static float shaderAnimSTRatio[MAX_SHADER_ANIMS] = {
|
|||
1.0f,
|
||||
1.0f,
|
||||
};
|
||||
static int numShaderAnims;
|
||||
// done.
|
||||
#endif
|
||||
|
||||
#define PARTICLE_GRAVITY 40
|
||||
|
||||
#ifdef WOLF_PARTICLES
|
||||
#define MAX_PARTICLES 1024 * 8
|
||||
#else
|
||||
#define MAX_PARTICLES 1024
|
||||
#endif
|
||||
|
||||
cparticle_t *active_particles, *free_particles;
|
||||
cparticle_t particles[MAX_PARTICLES];
|
||||
|
@ -331,7 +352,11 @@ void CG_AddParticleToScene (cparticle_t *p, vec3_t org, float alpha)
|
|||
vec3_t rr, ru;
|
||||
vec3_t rotate_ang;
|
||||
|
||||
#ifdef WOLF_PARTICLES
|
||||
VectorSet (color, 1.0, 1.0, 1.0);
|
||||
#else
|
||||
VectorSet (color, 1.0, 1.0, 0.5);
|
||||
#endif
|
||||
time = cg.time - p->time;
|
||||
time2 = p->endtime - p->time;
|
||||
ratio = time / time2;
|
||||
|
@ -1252,7 +1277,7 @@ void CG_ParticleExplosion (char *animStr, vec3_t origin, vec3_t vel, int duratio
|
|||
|
||||
// find the animation string
|
||||
for (anim=0; shaderAnimNames[anim]; anim++) {
|
||||
if (!stricmp( animStr, shaderAnimNames[anim] ))
|
||||
if (!Q_stricmp( animStr, shaderAnimNames[anim] ))
|
||||
break;
|
||||
}
|
||||
if (!shaderAnimNames[anim]) {
|
||||
|
@ -1267,7 +1292,11 @@ void CG_ParticleExplosion (char *animStr, vec3_t origin, vec3_t vel, int duratio
|
|||
p->next = active_particles;
|
||||
active_particles = p;
|
||||
p->time = cg.time;
|
||||
#ifdef WOLF_PARTICLES
|
||||
p->alpha = 1.0;
|
||||
#else
|
||||
p->alpha = 0.5;
|
||||
#endif
|
||||
p->alphavel = 0;
|
||||
|
||||
if (duration < 0) {
|
||||
|
|
|
@ -677,7 +677,7 @@ static qboolean CG_RegisterClientSkin( clientInfo_t *ci, const char *modelName,
|
|||
|
||||
if (ci->plateSkinName[0] != 0){
|
||||
// Com_sprintf( filename, sizeof( filename ), "models/players/plates/player%d.tga", ci->clientNum );
|
||||
Com_sprintf( filename, sizeof( filename ), "models/players/plates/default.tga", ci->clientNum );
|
||||
Com_sprintf( filename, sizeof( filename ), "models/players/plates/default.tga" );
|
||||
ci->plateShader = trap_R_RegisterShader(filename);
|
||||
if( !ci->plateShader ) {
|
||||
Com_Printf( S_COLOR_YELLOW "Q3R Warning: Failed to load plate shader: %s\n", filename );
|
||||
|
@ -1124,7 +1124,7 @@ static qboolean CG_ScanForExistingClientInfo( clientInfo_t *ci ) {
|
|||
&& !Q_stricmp( ci->blueTeam, match->blueTeam )
|
||||
&& !Q_stricmp( ci->redTeam, match->redTeam )
|
||||
&& (cgs.gametype < GT_TEAM || ci->team == match->team) ) {
|
||||
// this clientinfo is identical, so use it's handles
|
||||
// this clientinfo is identical, so use its handles
|
||||
|
||||
ci->deferred = qfalse;
|
||||
|
||||
|
@ -1251,9 +1251,19 @@ void CG_NewClientInfo( int clientNum ) {
|
|||
v = Info_ValueForKey( configstring, "c1" );
|
||||
CG_ColorFromString( v, newInfo.color1 );
|
||||
|
||||
newInfo.c1RGBA[0] = 255 * newInfo.color1[0];
|
||||
newInfo.c1RGBA[1] = 255 * newInfo.color1[1];
|
||||
newInfo.c1RGBA[2] = 255 * newInfo.color1[2];
|
||||
newInfo.c1RGBA[3] = 255;
|
||||
|
||||
v = Info_ValueForKey( configstring, "c2" );
|
||||
CG_ColorFromString( v, newInfo.color2 );
|
||||
|
||||
newInfo.c2RGBA[0] = 255 * newInfo.color2[0];
|
||||
newInfo.c2RGBA[1] = 255 * newInfo.color2[1];
|
||||
newInfo.c2RGBA[2] = 255 * newInfo.color2[2];
|
||||
newInfo.c2RGBA[3] = 255;
|
||||
|
||||
// bot skill
|
||||
v = Info_ValueForKey( configstring, "skill" );
|
||||
newInfo.botSkill = atoi( v );
|
||||
|
@ -1374,7 +1384,7 @@ void CG_NewClientInfo( int clientNum ) {
|
|||
char *skin;
|
||||
|
||||
if( cgs.gametype >= GT_TEAM ) {
|
||||
Q_strncpyz( newInfo.headModelName, DEFAULT_TEAM_MODEL, sizeof( newInfo.headModelName ) );
|
||||
Q_strncpyz( newInfo.headModelName, DEFAULT_TEAM_HEAD, sizeof( newInfo.headModelName ) );
|
||||
Q_strncpyz( newInfo.headSkinName, "default", sizeof( newInfo.headSkinName ) );
|
||||
} else {
|
||||
trap_Cvar_VariableStringBuffer( "headmodel", modelStr, sizeof( modelStr ) );
|
||||
|
@ -1971,7 +1981,7 @@ static void CG_BreathPuffs( centity_t *cent, refEntity_t *head) {
|
|||
if ( cent->currentState.eFlags & EF_DEAD ) {
|
||||
return;
|
||||
}
|
||||
contents = trap_CM_PointContents( head->origin, 0 );
|
||||
contents = CG_PointContents( head->origin, 0 );
|
||||
if ( contents & ( CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) ) {
|
||||
return;
|
||||
}
|
||||
|
@ -2612,7 +2622,7 @@ static void CG_PlayerSplash( centity_t *cent ) {
|
|||
|
||||
// if the feet aren't in liquid, don't make a mark
|
||||
// this won't handle moving water brushes, but they wouldn't draw right anyway...
|
||||
contents = trap_CM_PointContents( end, 0 );
|
||||
contents = CG_PointContents( end, 0 );
|
||||
if ( !( contents & ( CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) ) ) {
|
||||
return;
|
||||
}
|
||||
|
@ -2621,7 +2631,7 @@ static void CG_PlayerSplash( centity_t *cent ) {
|
|||
start[2] += 32;
|
||||
|
||||
// if the head isn't out of liquid, don't make a mark
|
||||
contents = trap_CM_PointContents( start, 0 );
|
||||
contents = CG_PointContents( start, 0 );
|
||||
if ( contents & ( CONTENTS_SOLID | CONTENTS_WATER | CONTENTS_SLIME | CONTENTS_LAVA ) ) {
|
||||
return;
|
||||
}
|
||||
|
@ -4032,7 +4042,7 @@ void CG_ResetPlayerEntity( centity_t *cent ) {
|
|||
cent->pe.torso.pitching = qfalse;
|
||||
|
||||
if ( cg_debugPosition.integer ) {
|
||||
CG_Printf("%i ResetPlayerEntity yaw=%i\n", cent->currentState.number, cent->pe.torso.yawAngle );
|
||||
CG_Printf("%i ResetPlayerEntity yaw=%f\n", cent->currentState.number, cent->pe.torso.yawAngle );
|
||||
}
|
||||
*/
|
||||
// END
|
||||
|
|
|
@ -269,7 +269,7 @@ int CG_PointContents( const vec3_t point, int passEntityNum ) {
|
|||
continue;
|
||||
}
|
||||
|
||||
contents |= trap_CM_TransformedPointContents( point, cmodel, ent->origin, ent->angles );
|
||||
contents |= trap_CM_TransformedPointContents( point, cmodel, cent->lerpOrigin, cent->lerpAngles );
|
||||
}
|
||||
|
||||
return contents;
|
||||
|
@ -499,7 +499,7 @@ static void CG_TouchItem( centity_t *cent ) {
|
|||
// don't touch it again this prediction
|
||||
cent->miscTime = cg.time;
|
||||
|
||||
// if its a weapon, give them some predicted ammo so the autoswitch will work
|
||||
// if it's a weapon, give them some predicted ammo so the autoswitch will work
|
||||
if ( item->giType == IT_WEAPON ) {
|
||||
cg.predictedPlayerState.stats[ STAT_WEAPONS ] |= 1 << item->giTag;
|
||||
if ( !cg.predictedPlayerState.ammo[ item->giTag ] ) {
|
||||
|
|
|
@ -23,29 +23,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#include "cg_local.h"
|
||||
|
||||
static int allocPoint = 0;
|
||||
|
||||
#ifdef Q3_VM
|
||||
|
||||
#define POOLSIZE (512 * 1024)
|
||||
|
||||
static char memoryPool[POOLSIZE];
|
||||
static int allocPoint = 0;
|
||||
|
||||
void *malloc( size_t count ){
|
||||
char *p;
|
||||
|
||||
if ( allocPoint + count > POOLSIZE ) {
|
||||
CG_Error( "CG_Alloc: failed on allocation of %i bytes\n", count );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = &memoryPool[allocPoint];
|
||||
|
||||
allocPoint += ( count + 31 ) & ~31;
|
||||
|
||||
return p;
|
||||
}
|
||||
/*
|
||||
static void *CG_Alloc( int size ) {
|
||||
char *p;
|
||||
|
||||
|
@ -60,15 +42,15 @@ static void *CG_Alloc( int size ) {
|
|||
|
||||
return p;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
static void CG_Free( int size ){
|
||||
static void CG_Free( int size ) {
|
||||
allocPoint -= ( size + 31 ) & ~31;
|
||||
}
|
||||
*/
|
||||
|
||||
int memcmp( const unsigned char *dest, const unsigned char *src, size_t count ){
|
||||
#ifdef Q3_VM
|
||||
int memcmp( const unsigned char *dest, const unsigned char *src, size_t count ) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++){
|
||||
|
@ -81,8 +63,10 @@ int memcmp( const unsigned char *dest, const unsigned char *src, size_t count ){
|
|||
|
||||
return qtrue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
static qboolean CG_Memcmp(byte *s1, byte *s2, int size){
|
||||
static qboolean CG_Memcmp(byte *s1, byte *s2, int size) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++){
|
||||
|
@ -97,8 +81,6 @@ static qboolean CG_Memcmp(byte *s1, byte *s2, int size){
|
|||
}
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
byte *imageData; // Image Data (Up To 32 Bits)
|
||||
|
@ -159,7 +141,7 @@ qboolean LoadTGA(TextureImage *texture, const char *filename){
|
|||
bytesPerPixel = texture->bpp / 8; // Divide By 8 To Get The Bytes Per Pixel
|
||||
imageSize = texture->width * texture->height * bytesPerPixel; // Calculate The Memory Required For The TGA Data
|
||||
|
||||
texture->imageData = (unsigned char*)malloc(imageSize); // Reserve Memory To Hold The TGA Data
|
||||
texture->imageData = (unsigned char*)CG_Alloc(imageSize); // Reserve Memory To Hold The TGA Data
|
||||
|
||||
trap_FS_Read(texture->imageData, imageSize, imageFile);
|
||||
|
||||
|
|
|
@ -627,16 +627,16 @@ void CG_DrawOldTourneyScoreboard( void ) {
|
|||
trap_SendClientCommand( "score" );
|
||||
}
|
||||
|
||||
color[0] = 1;
|
||||
color[1] = 1;
|
||||
color[2] = 1;
|
||||
color[3] = 1;
|
||||
|
||||
// draw the dialog background
|
||||
color[0] = color[1] = color[2] = 0;
|
||||
color[3] = 1;
|
||||
CG_FillRect( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, color );
|
||||
|
||||
color[0] = 1;
|
||||
color[1] = 1;
|
||||
color[2] = 1;
|
||||
color[3] = 1;
|
||||
|
||||
// print the mesage of the day
|
||||
s = CG_ConfigString( CS_MOTD );
|
||||
if ( !s[0] ) {
|
||||
|
|
|
@ -45,7 +45,7 @@ static const orderTask_t validOrders[] = {
|
|||
{ VOICECHAT_FOLLOWFLAGCARRIER, TEAMTASK_ESCORT }
|
||||
};
|
||||
|
||||
static const int numValidOrders = sizeof(validOrders) / sizeof(orderTask_t);
|
||||
static const int numValidOrders = ARRAY_LEN(validOrders);
|
||||
|
||||
#ifdef MISSIONPACK
|
||||
static int CG_ValidOrder(const char *p) {
|
||||
|
@ -517,6 +517,7 @@ static void CG_MapRestart( void ) {
|
|||
cg.timelimitWarnings = 0;
|
||||
|
||||
cg.intermissionStarted = qfalse;
|
||||
cg.levelShot = qfalse;
|
||||
|
||||
cgs.voteTime = 0;
|
||||
|
||||
|
|
|
@ -47,8 +47,11 @@ void trap_Print( const char *fmt ) {
|
|||
syscall( CG_PRINT, fmt );
|
||||
}
|
||||
|
||||
void trap_Error( const char *fmt ) {
|
||||
syscall( CG_ERROR, fmt );
|
||||
void trap_Error(const char *fmt)
|
||||
{
|
||||
syscall(CG_ERROR, fmt);
|
||||
// shut up GCC warning about returning functions, because we know better
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int trap_Milliseconds( void ) {
|
||||
|
|
|
@ -353,9 +353,6 @@ static void CG_OffsetFirstPersonView( void ) {
|
|||
return;
|
||||
}
|
||||
|
||||
// add angles based on weapon kick
|
||||
VectorAdd (angles, cg.kick_angles, angles);
|
||||
|
||||
// add angles based on damage kick
|
||||
if ( cg.damageTime ) {
|
||||
ratio = cg.time - cg.damageTime;
|
||||
|
@ -442,10 +439,6 @@ static void CG_OffsetFirstPersonView( void ) {
|
|||
// add step offset
|
||||
CG_StepOffset();
|
||||
|
||||
// add kick offset
|
||||
|
||||
VectorAdd (origin, cg.kick_origin, origin);
|
||||
|
||||
// pivot the eye based on a neck length
|
||||
#if 0
|
||||
{
|
||||
|
|
|
@ -714,6 +714,7 @@ void CG_RegisterWeapon( int weaponNum ) {
|
|||
MAKERGB( weaponInfo->missileDlightColor, 1, 0.75f, 0 );
|
||||
weaponInfo->readySound = trap_S_RegisterSound( "sound/weapons/melee/fsthum.wav", qfalse );
|
||||
weaponInfo->firingSound = trap_S_RegisterSound( "sound/weapons/melee/fstrun.wav", qfalse );
|
||||
cgs.media.lightningShader = trap_R_RegisterShader( "lightningBoltNew");
|
||||
break;
|
||||
*/
|
||||
|
||||
|
@ -1026,6 +1027,7 @@ static void CG_LightningBolt( centity_t *cent, vec3_t origin ) {
|
|||
refEntity_t beam;
|
||||
vec3_t forward;
|
||||
vec3_t muzzlePoint, endPoint;
|
||||
//int anim;
|
||||
|
||||
// Q3Rally Code Start
|
||||
//vec3_t delta, angles, mins, maxs;
|
||||
|
@ -1079,9 +1081,15 @@ static void CG_LightningBolt( centity_t *cent, vec3_t origin ) {
|
|||
VectorCopy(cent->lerpOrigin, muzzlePoint );
|
||||
}
|
||||
|
||||
// FIXME: crouch
|
||||
// Q3Rally Code Start
|
||||
// muzzlePoint[2] += DEFAULT_VIEWHEIGHT;
|
||||
/*
|
||||
anim = cent->currentState.legsAnim & ~ANIM_TOGGLEBIT;
|
||||
if ( anim == LEGS_WALKCR || anim == LEGS_IDLECR ) {
|
||||
muzzlePoint[2] += CROUCH_VIEWHEIGHT;
|
||||
} else {
|
||||
muzzlePoint[2] += DEFAULT_VIEWHEIGHT;
|
||||
}
|
||||
*/
|
||||
VectorMA( muzzlePoint, CAR_HEIGHT/2, up, muzzlePoint );
|
||||
// END
|
||||
VectorMA( muzzlePoint, 14, forward, muzzlePoint );
|
||||
|
@ -1320,21 +1328,18 @@ void CG_AddPlayerWeapon( refEntity_t *parent, playerState_t *ps, centity_t *cent
|
|||
gun.renderfx = parent->renderfx;
|
||||
|
||||
// set custom shading for railgun refire rate
|
||||
if ( ps ) {
|
||||
if ( cg.predictedPlayerState.weapon == WP_RAILGUN
|
||||
&& cg.predictedPlayerState.weaponstate == WEAPON_FIRING ) {
|
||||
float f;
|
||||
|
||||
f = (float)cg.predictedPlayerState.weaponTime / 1500;
|
||||
gun.shaderRGBA[1] = 0;
|
||||
gun.shaderRGBA[0] =
|
||||
gun.shaderRGBA[2] = 255 * ( 1.0 - f );
|
||||
} else {
|
||||
gun.shaderRGBA[0] = 255;
|
||||
gun.shaderRGBA[1] = 255;
|
||||
gun.shaderRGBA[2] = 255;
|
||||
if( weaponNum == WP_RAILGUN ) {
|
||||
clientInfo_t *ci = &cgs.clientinfo[cent->currentState.clientNum];
|
||||
if( cent->pe.railFireTime + 1500 > cg.time ) {
|
||||
int scale = 255 * ( cg.time - cent->pe.railFireTime ) / 1500;
|
||||
gun.shaderRGBA[0] = ( ci->c1RGBA[0] * scale ) >> 8;
|
||||
gun.shaderRGBA[1] = ( ci->c1RGBA[1] * scale ) >> 8;
|
||||
gun.shaderRGBA[2] = ( ci->c1RGBA[2] * scale ) >> 8;
|
||||
gun.shaderRGBA[3] = 255;
|
||||
}
|
||||
else {
|
||||
Byte4Copy( ci->c1RGBA, gun.shaderRGBA );
|
||||
}
|
||||
}
|
||||
|
||||
// Q3Rally Code Start
|
||||
|
@ -1824,6 +1829,10 @@ void CG_FireWeapon( centity_t *cent ) {
|
|||
}
|
||||
}
|
||||
|
||||
if( ent->weapon == WP_RAILGUN ) {
|
||||
cent->pe.railFireTime = cg.time;
|
||||
}
|
||||
|
||||
// play quad sound if needed
|
||||
if ( cent->currentState.powerups & ( 1 << PW_QUAD ) ) {
|
||||
trap_S_StartSound (NULL, cent->currentState.number, CHAN_ITEM, cgs.media.quadSound );
|
||||
|
@ -2114,6 +2123,10 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, im
|
|||
if ( weapon == WP_RAILGUN ) {
|
||||
// colorize with client color
|
||||
VectorCopy( cgs.clientinfo[clientNum].color1, le->color );
|
||||
le->refEntity.shaderRGBA[0] = le->color[0] * 0xff;
|
||||
le->refEntity.shaderRGBA[1] = le->color[1] * 0xff;
|
||||
le->refEntity.shaderRGBA[2] = le->color[2] * 0xff;
|
||||
le->refEntity.shaderRGBA[3] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2125,7 +2138,7 @@ void CG_MissileHitWall( int weapon, int clientNum, vec3_t origin, vec3_t dir, im
|
|||
float *color;
|
||||
|
||||
// colorize with client color
|
||||
color = cgs.clientinfo[clientNum].color2;
|
||||
color = cgs.clientinfo[clientNum].color1;
|
||||
CG_ImpactMark( mark, origin, dir, random()*360, color[0],color[1], color[2],1, alphaFade, radius, qfalse );
|
||||
} else {
|
||||
CG_ImpactMark( mark, origin, dir, random()*360, 1,1,1,1, alphaFade, radius, qfalse );
|
||||
|
@ -2146,6 +2159,8 @@ void CG_MissileHitPlayer( int weapon, vec3_t origin, vec3_t dir, int entityNum )
|
|||
switch ( weapon ) {
|
||||
case WP_GRENADE_LAUNCHER:
|
||||
case WP_ROCKET_LAUNCHER:
|
||||
case WP_PLASMAGUN:
|
||||
case WP_BFG:
|
||||
// Q3Rally Code Start
|
||||
case RWP_MINE:
|
||||
// END
|
||||
|
@ -2182,8 +2197,8 @@ static void CG_ShotgunPellet( vec3_t start, vec3_t end, int skipNum ) {
|
|||
|
||||
CG_Trace( &tr, start, NULL, NULL, end, skipNum, MASK_SHOT );
|
||||
|
||||
sourceContentType = trap_CM_PointContents( start, 0 );
|
||||
destContentType = trap_CM_PointContents( tr.endpos, 0 );
|
||||
sourceContentType = CG_PointContents( start, 0 );
|
||||
destContentType = CG_PointContents( tr.endpos, 0 );
|
||||
|
||||
|
||||
// FIXME: should probably move this cruft into CG_BubbleTrail
|
||||
|
@ -2275,7 +2290,7 @@ void CG_ShotgunFire( entityState_t *es ) {
|
|||
// ragepro can't alpha fade, so don't even bother with smoke
|
||||
vec3_t up;
|
||||
|
||||
contents = trap_CM_PointContents( es->pos.trBase, 0 );
|
||||
contents = CG_PointContents( es->pos.trBase, 0 );
|
||||
if ( !( contents & CONTENTS_WATER ) ) {
|
||||
VectorSet( up, 0, 0, 8 );
|
||||
CG_SmokePuff( v, up, 32, 1, 1, 1, 0.33f, 900, cg.time, 0, LEF_PUFF_DONT_SCALE, cgs.media.shotgunSmokePuffShader );
|
||||
|
@ -2443,8 +2458,8 @@ void CG_Bullet( vec3_t end, int sourceEntityNum, vec3_t normal, qboolean flesh,
|
|||
// do trail effects
|
||||
if ( sourceEntityNum >= 0 && cg_tracerChance.value > 0 ) {
|
||||
if ( CG_CalcMuzzlePoint( sourceEntityNum, start ) ) {
|
||||
sourceContentType = trap_CM_PointContents( start, 0 );
|
||||
destContentType = trap_CM_PointContents( end, 0 );
|
||||
sourceContentType = CG_PointContents( start, 0 );
|
||||
destContentType = CG_PointContents( end, 0 );
|
||||
|
||||
// do a complete bubble trail if necessary
|
||||
if ( ( sourceContentType == destContentType ) && ( sourceContentType & CONTENTS_WATER ) ) {
|
||||
|
|
|
@ -82,7 +82,7 @@ SafeFS_Write
|
|||
static ID_INLINE void SafeFS_Write( const void *buffer, int len, fileHandle_t f )
|
||||
{
|
||||
if( FS_Write( buffer, len, f ) < len )
|
||||
Com_Error( ERR_DROP, "Failed to write avi file\n" );
|
||||
Com_Error( ERR_DROP, "Failed to write avi file" );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -142,7 +142,7 @@ static ID_INLINE void START_CHUNK( const char *s )
|
|||
{
|
||||
if( afd.chunkStackTop == MAX_RIFF_CHUNKS )
|
||||
{
|
||||
Com_Error( ERR_DROP, "ERROR: Top of chunkstack breached\n" );
|
||||
Com_Error( ERR_DROP, "ERROR: Top of chunkstack breached" );
|
||||
}
|
||||
|
||||
afd.chunkStack[ afd.chunkStackTop ] = bufIndex;
|
||||
|
@ -162,7 +162,7 @@ static ID_INLINE void END_CHUNK( void )
|
|||
|
||||
if( afd.chunkStackTop <= 0 )
|
||||
{
|
||||
Com_Error( ERR_DROP, "ERROR: Bottom of chunkstack breached\n" );
|
||||
Com_Error( ERR_DROP, "ERROR: Bottom of chunkstack breached" );
|
||||
}
|
||||
|
||||
afd.chunkStackTop--;
|
||||
|
@ -368,8 +368,13 @@ qboolean CL_OpenAVIForWriting( const char *fileName )
|
|||
else
|
||||
afd.motionJpeg = qfalse;
|
||||
|
||||
afd.cBuffer = Z_Malloc( afd.width * afd.height * 4 );
|
||||
afd.eBuffer = Z_Malloc( afd.width * afd.height * 4 );
|
||||
// Buffers only need to store RGB pixels.
|
||||
// Allocate a bit more space for the capture buffer to account for possible
|
||||
// padding at the end of pixel lines, and padding for alignment
|
||||
#define MAX_PACK_LEN 16
|
||||
afd.cBuffer = Z_Malloc((afd.width * 3 + MAX_PACK_LEN - 1) * afd.height + MAX_PACK_LEN - 1);
|
||||
// raw avi files have pixel lines start on 4-byte boundaries
|
||||
afd.eBuffer = Z_Malloc(PAD(afd.width * 3, AVI_LINE_PADDING) * afd.height);
|
||||
|
||||
afd.a.rate = dma.speed;
|
||||
afd.a.format = WAV_FORMAT_PCM;
|
||||
|
@ -467,7 +472,7 @@ void CL_WriteAVIVideoFrame( const byte *imageBuffer, int size )
|
|||
{
|
||||
int chunkOffset = afd.fileSize - afd.moviOffset - 8;
|
||||
int chunkSize = 8 + size;
|
||||
int paddingSize = PAD( size, 2 ) - size;
|
||||
int paddingSize = PADLEN(size, 2);
|
||||
byte padding[ 4 ] = { 0 };
|
||||
|
||||
if( !afd.fileOpen )
|
||||
|
@ -541,7 +546,7 @@ void CL_WriteAVIAudioFrame( const byte *pcmBuffer, int size )
|
|||
{
|
||||
int chunkOffset = afd.fileSize - afd.moviOffset - 8;
|
||||
int chunkSize = 8 + bytesInBuffer;
|
||||
int paddingSize = PAD( bytesInBuffer, 2 ) - bytesInBuffer;
|
||||
int paddingSize = PADLEN(bytesInBuffer, 2);
|
||||
byte padding[ 4 ] = { 0 };
|
||||
|
||||
bufIndex = 0;
|
||||
|
|
|
@ -300,7 +300,7 @@ rescan:
|
|||
if ( argc >= 2 )
|
||||
Com_Error( ERR_SERVERDISCONNECT, "Server disconnected - %s", Cmd_Argv( 1 ) );
|
||||
else
|
||||
Com_Error( ERR_SERVERDISCONNECT, "Server disconnected\n" );
|
||||
Com_Error( ERR_SERVERDISCONNECT, "Server disconnected" );
|
||||
}
|
||||
|
||||
if ( !strcmp( cmd, "bcs0" ) ) {
|
||||
|
@ -431,7 +431,7 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
|
|||
Cvar_Update( VMA(1) );
|
||||
return 0;
|
||||
case CG_CVAR_SET:
|
||||
Cvar_Set( VMA(1), VMA(2) );
|
||||
Cvar_SetSafe( VMA(1), VMA(2) );
|
||||
return 0;
|
||||
case CG_CVAR_VARIABLESTRINGBUFFER:
|
||||
Cvar_VariableStringBuffer( VMA(1), VMA(2), args[3] );
|
||||
|
@ -464,7 +464,7 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
|
|||
CL_AddCgameCommand( VMA(1) );
|
||||
return 0;
|
||||
case CG_REMOVECOMMAND:
|
||||
Cmd_RemoveCommand( VMA(1) );
|
||||
Cmd_RemoveCommandSafe( VMA(1) );
|
||||
return 0;
|
||||
case CG_SENDCLIENTCOMMAND:
|
||||
CL_AddReliableCommand(VMA(1), qfalse);
|
||||
|
@ -548,6 +548,7 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
|
|||
return re.RegisterShaderNoMip( VMA(1) );
|
||||
case CG_R_REGISTERFONT:
|
||||
re.RegisterFont( VMA(1), args[2], VMA(3));
|
||||
return 0;
|
||||
case CG_R_CLEARSCENE:
|
||||
re.ClearScene();
|
||||
return 0;
|
||||
|
@ -659,7 +660,7 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
|
|||
case CG_REAL_TIME:
|
||||
return Com_RealTime( VMA(1) );
|
||||
case CG_SNAPVECTOR:
|
||||
Sys_SnapVector( VMA(1) );
|
||||
Q_SnapVector(VMA(1));
|
||||
return 0;
|
||||
|
||||
case CG_CIN_PLAYCINEMATIC:
|
||||
|
@ -742,7 +743,7 @@ void CL_InitCGame( void ) {
|
|||
if ( !cgvm ) {
|
||||
Com_Error( ERR_DROP, "VM_Create on cgame failed" );
|
||||
}
|
||||
cls.state = CA_LOADING;
|
||||
clc.state = CA_LOADING;
|
||||
|
||||
// init for this gamestate
|
||||
// use the lastExecutedServerCommand instead of the serverCommandSequence
|
||||
|
@ -755,7 +756,7 @@ void CL_InitCGame( void ) {
|
|||
|
||||
// we will send a usercmd this frame, which
|
||||
// will cause the server to send us the first snapshot
|
||||
cls.state = CA_PRIMED;
|
||||
clc.state = CA_PRIMED;
|
||||
|
||||
t2 = Sys_Milliseconds();
|
||||
|
||||
|
@ -893,7 +894,7 @@ void CL_FirstSnapshot( void ) {
|
|||
if ( cl.snap.snapFlags & SNAPFLAG_NOT_ACTIVE ) {
|
||||
return;
|
||||
}
|
||||
cls.state = CA_ACTIVE;
|
||||
clc.state = CA_ACTIVE;
|
||||
|
||||
// set the timedelta so we are exactly on this first frame
|
||||
cl.serverTimeDelta = cl.snap.serverTime - cls.realtime;
|
||||
|
@ -964,8 +965,8 @@ CL_SetCGameTime
|
|||
*/
|
||||
void CL_SetCGameTime( void ) {
|
||||
// getting a valid frame message ends the connection process
|
||||
if ( cls.state != CA_ACTIVE ) {
|
||||
if ( cls.state != CA_PRIMED ) {
|
||||
if ( clc.state != CA_ACTIVE ) {
|
||||
if ( clc.state != CA_PRIMED ) {
|
||||
return;
|
||||
}
|
||||
if ( clc.demoplaying ) {
|
||||
|
@ -981,7 +982,7 @@ void CL_SetCGameTime( void ) {
|
|||
cl.newSnapshots = qfalse;
|
||||
CL_FirstSnapshot();
|
||||
}
|
||||
if ( cls.state != CA_ACTIVE ) {
|
||||
if ( clc.state != CA_ACTIVE ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1094,7 +1095,7 @@ void CL_SetCGameTime( void ) {
|
|||
// feed another messag, which should change
|
||||
// the contents of cl.snap
|
||||
CL_ReadDemoMessage();
|
||||
if ( cls.state != CA_ACTIVE ) {
|
||||
if ( clc.state != CA_ACTIVE ) {
|
||||
return; // end of demo
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1281,7 +1281,7 @@ static void RoQShutdown( void ) {
|
|||
}
|
||||
|
||||
if (cinTable[currentHandle].alterGameState) {
|
||||
cls.state = CA_DISCONNECTED;
|
||||
clc.state = CA_DISCONNECTED;
|
||||
// we can't just do a vstr nextmap, because
|
||||
// if we are aborting the intro cinematic with
|
||||
// a devmap command, nextmap would be valid by
|
||||
|
@ -1314,7 +1314,7 @@ e_status CIN_StopCinematic(int handle) {
|
|||
}
|
||||
|
||||
if (cinTable[currentHandle].alterGameState) {
|
||||
if ( cls.state != CA_CINEMATIC ) {
|
||||
if ( clc.state != CA_CINEMATIC ) {
|
||||
return cinTable[currentHandle].status;
|
||||
}
|
||||
}
|
||||
|
@ -1355,7 +1355,7 @@ e_status CIN_RunCinematic (int handle)
|
|||
currentHandle = handle;
|
||||
|
||||
if (cinTable[currentHandle].alterGameState) {
|
||||
if ( cls.state != CA_CINEMATIC ) {
|
||||
if ( clc.state != CA_CINEMATIC ) {
|
||||
return cinTable[currentHandle].status;
|
||||
}
|
||||
}
|
||||
|
@ -1479,7 +1479,7 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
|
|||
Com_DPrintf("trFMV::play(), playing %s\n", arg);
|
||||
|
||||
if (cinTable[currentHandle].alterGameState) {
|
||||
cls.state = CA_CINEMATIC;
|
||||
clc.state = CA_CINEMATIC;
|
||||
}
|
||||
|
||||
Con_Close();
|
||||
|
@ -1508,6 +1508,66 @@ void CIN_SetLooping(int handle, qboolean loop) {
|
|||
cinTable[handle].looping = loop;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CIN_ResampleCinematic
|
||||
|
||||
Resample cinematic to 256x256 and store in buf2
|
||||
==================
|
||||
*/
|
||||
void CIN_ResampleCinematic(int handle, int *buf2) {
|
||||
int ix, iy, *buf3, xm, ym, ll;
|
||||
byte *buf;
|
||||
|
||||
buf = cinTable[handle].buf;
|
||||
|
||||
xm = cinTable[handle].CIN_WIDTH/256;
|
||||
ym = cinTable[handle].CIN_HEIGHT/256;
|
||||
ll = 8;
|
||||
if (cinTable[handle].CIN_WIDTH==512) {
|
||||
ll = 9;
|
||||
}
|
||||
|
||||
buf3 = (int*)buf;
|
||||
if (xm==2 && ym==2) {
|
||||
byte *bc2, *bc3;
|
||||
int ic, iiy;
|
||||
|
||||
bc2 = (byte *)buf2;
|
||||
bc3 = (byte *)buf3;
|
||||
for (iy = 0; iy<256; iy++) {
|
||||
iiy = iy<<12;
|
||||
for (ix = 0; ix<2048; ix+=8) {
|
||||
for(ic = ix;ic<(ix+4);ic++) {
|
||||
*bc2=(bc3[iiy+ic]+bc3[iiy+4+ic]+bc3[iiy+2048+ic]+bc3[iiy+2048+4+ic])>>2;
|
||||
bc2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (xm==2 && ym==1) {
|
||||
byte *bc2, *bc3;
|
||||
int ic, iiy;
|
||||
|
||||
bc2 = (byte *)buf2;
|
||||
bc3 = (byte *)buf3;
|
||||
for (iy = 0; iy<256; iy++) {
|
||||
iiy = iy<<11;
|
||||
for (ix = 0; ix<2048; ix+=8) {
|
||||
for(ic = ix;ic<(ix+4);ic++) {
|
||||
*bc2=(bc3[iiy+ic]+bc3[iiy+4+ic])>>1;
|
||||
bc2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (iy = 0; iy<256; iy++) {
|
||||
for (ix = 0; ix<256; ix++) {
|
||||
buf2[(iy<<8)+ix] = buf3[((iy*ym)<<ll) + (ix*xm)];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SCR_DrawCinematic
|
||||
|
@ -1532,54 +1592,12 @@ void CIN_DrawCinematic (int handle) {
|
|||
SCR_AdjustFrom640( &x, &y, &w, &h );
|
||||
|
||||
if (cinTable[handle].dirty && (cinTable[handle].CIN_WIDTH != cinTable[handle].drawX || cinTable[handle].CIN_HEIGHT != cinTable[handle].drawY)) {
|
||||
int ix, iy, *buf2, *buf3, xm, ym, ll;
|
||||
|
||||
xm = cinTable[handle].CIN_WIDTH/256;
|
||||
ym = cinTable[handle].CIN_HEIGHT/256;
|
||||
ll = 8;
|
||||
if (cinTable[handle].CIN_WIDTH==512) {
|
||||
ll = 9;
|
||||
}
|
||||
|
||||
buf3 = (int*)buf;
|
||||
int *buf2;
|
||||
|
||||
buf2 = Hunk_AllocateTempMemory( 256*256*4 );
|
||||
if (xm==2 && ym==2) {
|
||||
byte *bc2, *bc3;
|
||||
int ic, iiy;
|
||||
|
||||
bc2 = (byte *)buf2;
|
||||
bc3 = (byte *)buf3;
|
||||
for (iy = 0; iy<256; iy++) {
|
||||
iiy = iy<<12;
|
||||
for (ix = 0; ix<2048; ix+=8) {
|
||||
for(ic = ix;ic<(ix+4);ic++) {
|
||||
*bc2=(bc3[iiy+ic]+bc3[iiy+4+ic]+bc3[iiy+2048+ic]+bc3[iiy+2048+4+ic])>>2;
|
||||
bc2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (xm==2 && ym==1) {
|
||||
byte *bc2, *bc3;
|
||||
int ic, iiy;
|
||||
|
||||
bc2 = (byte *)buf2;
|
||||
bc3 = (byte *)buf3;
|
||||
for (iy = 0; iy<256; iy++) {
|
||||
iiy = iy<<11;
|
||||
for (ix = 0; ix<2048; ix+=8) {
|
||||
for(ic = ix;ic<(ix+4);ic++) {
|
||||
*bc2=(bc3[iiy+ic]+bc3[iiy+4+ic])>>1;
|
||||
bc2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (iy = 0; iy<256; iy++) {
|
||||
for (ix = 0; ix<256; ix++) {
|
||||
buf2[(iy<<8)+ix] = buf3[((iy*ym)<<ll) + (ix*xm)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CIN_ResampleCinematic(handle, buf2);
|
||||
|
||||
re.DrawStretchRaw( x, y, w, h, 256, 256, (byte *)buf2, handle, qtrue);
|
||||
cinTable[handle].dirty = qfalse;
|
||||
Hunk_FreeTempMemory(buf2);
|
||||
|
@ -1596,7 +1614,7 @@ void CL_PlayCinematic_f(void) {
|
|||
int bits = CIN_system;
|
||||
|
||||
Com_DPrintf("CL_PlayCinematic_f\n");
|
||||
if (cls.state == CA_CINEMATIC) {
|
||||
if (clc.state == CA_CINEMATIC) {
|
||||
SCR_StopCinematic();
|
||||
}
|
||||
|
||||
|
@ -1659,7 +1677,25 @@ void CIN_UploadCinematic(int handle) {
|
|||
}
|
||||
}
|
||||
}
|
||||
re.UploadCinematic( 256, 256, 256, 256, cinTable[handle].buf, handle, cinTable[handle].dirty);
|
||||
|
||||
// Resample the video if needed
|
||||
if (cinTable[handle].dirty && (cinTable[handle].CIN_WIDTH != cinTable[handle].drawX || cinTable[handle].CIN_HEIGHT != cinTable[handle].drawY)) {
|
||||
int *buf2;
|
||||
|
||||
buf2 = Hunk_AllocateTempMemory( 256*256*4 );
|
||||
|
||||
CIN_ResampleCinematic(handle, buf2);
|
||||
|
||||
re.UploadCinematic( cinTable[handle].CIN_WIDTH, cinTable[handle].CIN_HEIGHT, 256, 256, (byte *)buf2, handle, qtrue);
|
||||
cinTable[handle].dirty = qfalse;
|
||||
Hunk_FreeTempMemory(buf2);
|
||||
} else {
|
||||
// Upload video at normal resolution
|
||||
re.UploadCinematic( cinTable[handle].CIN_WIDTH, cinTable[handle].CIN_HEIGHT, cinTable[handle].drawX, cinTable[handle].drawY,
|
||||
cinTable[handle].buf, handle, cinTable[handle].dirty);
|
||||
cinTable[handle].dirty = qfalse;
|
||||
}
|
||||
|
||||
if (cl_inGameVideo->integer == 0 && cinTable[handle].playonwalls == 1) {
|
||||
cinTable[handle].playonwalls--;
|
||||
}
|
||||
|
|
|
@ -62,8 +62,6 @@ cvar_t *con_notifytime;
|
|||
|
||||
#define DEFAULT_CONSOLE_WIDTH 78
|
||||
|
||||
vec4_t console_color = {1.0, 1.0, 1.0, 1.0};
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
|
@ -72,7 +70,7 @@ Con_ToggleConsole_f
|
|||
*/
|
||||
void Con_ToggleConsole_f (void) {
|
||||
// Can't toggle the console when it's the only thing available
|
||||
if ( cls.state == CA_DISCONNECTED && Key_GetCatcher( ) == KEYCATCH_CONSOLE ) {
|
||||
if ( clc.state == CA_DISCONNECTED && Key_GetCatcher( ) == KEYCATCH_CONSOLE ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -309,7 +307,7 @@ Cmd_CompleteTxtName
|
|||
*/
|
||||
void Cmd_CompleteTxtName( char *args, int argNum ) {
|
||||
if( argNum == 2 ) {
|
||||
Field_CompleteFilename( "", "txt", qfalse );
|
||||
Field_CompleteFilename( "", "txt", qfalse, qtrue );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -343,6 +341,21 @@ void Con_Init (void) {
|
|||
Cmd_SetCommandCompletionFunc( "condump", Cmd_CompleteTxtName );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Con_Shutdown
|
||||
================
|
||||
*/
|
||||
void Con_Shutdown(void)
|
||||
{
|
||||
Cmd_RemoveCommand("toggleconsole");
|
||||
Cmd_RemoveCommand("messagemode");
|
||||
Cmd_RemoveCommand("messagemode2");
|
||||
Cmd_RemoveCommand("messagemode3");
|
||||
Cmd_RemoveCommand("messagemode4");
|
||||
Cmd_RemoveCommand("clear");
|
||||
Cmd_RemoveCommand("condump");
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
|
@ -380,9 +393,9 @@ If no console is visible, the text will appear at the top of the game window
|
|||
================
|
||||
*/
|
||||
void CL_ConsolePrint( char *txt ) {
|
||||
int y;
|
||||
int c, l;
|
||||
int color;
|
||||
int y, l;
|
||||
unsigned char c;
|
||||
unsigned short color;
|
||||
qboolean skipnotify = qfalse; // NERVE - SMF
|
||||
int prev; // NERVE - SMF
|
||||
|
||||
|
@ -410,7 +423,7 @@ void CL_ConsolePrint( char *txt ) {
|
|||
|
||||
color = ColorIndex(COLOR_WHITE);
|
||||
|
||||
while ( (c = *txt) != 0 ) {
|
||||
while ( (c = *((unsigned char *) txt)) != 0 ) {
|
||||
if ( Q_IsColorString( txt ) ) {
|
||||
color = ColorIndex( *(txt+1) );
|
||||
txt += 2;
|
||||
|
@ -445,10 +458,8 @@ void CL_ConsolePrint( char *txt ) {
|
|||
y = con.current % con.totallines;
|
||||
con.text[y*con.linewidth+con.x] = (color << 8) | c;
|
||||
con.x++;
|
||||
if (con.x >= con.linewidth) {
|
||||
if(con.x >= con.linewidth)
|
||||
Con_Linefeed(skipnotify);
|
||||
con.x = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -489,7 +500,7 @@ Draw the editline after a ] prompt
|
|||
void Con_DrawInput (void) {
|
||||
int y;
|
||||
|
||||
if ( cls.state != CA_DISCONNECTED && !(Key_GetCatcher( ) & KEYCATCH_CONSOLE ) ) {
|
||||
if ( clc.state != CA_DISCONNECTED && !(Key_GetCatcher( ) & KEYCATCH_CONSOLE ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -706,7 +717,7 @@ void Con_DrawConsole( void ) {
|
|||
Con_CheckResize ();
|
||||
|
||||
// if disconnected, render console full screen
|
||||
if ( cls.state == CA_DISCONNECTED ) {
|
||||
if ( clc.state == CA_DISCONNECTED ) {
|
||||
if ( !( Key_GetCatcher( ) & (KEYCATCH_UI | KEYCATCH_CGAME)) ) {
|
||||
Con_DrawSolidConsole( 1.0 );
|
||||
return;
|
||||
|
@ -717,7 +728,7 @@ void Con_DrawConsole( void ) {
|
|||
Con_DrawSolidConsole( con.displayFrac );
|
||||
} else {
|
||||
// draw notify lines
|
||||
if ( cls.state == CA_ACTIVE ) {
|
||||
if ( clc.state == CA_ACTIVE ) {
|
||||
Con_DrawNotify ();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -251,13 +251,13 @@ void CL_cURL_BeginDownload( const char *localName, const char *remoteURL )
|
|||
clc.downloadCURL = qcurl_easy_init();
|
||||
if(!clc.downloadCURL) {
|
||||
Com_Error(ERR_DROP, "CL_cURL_BeginDownload: qcurl_easy_init() "
|
||||
"failed\n");
|
||||
"failed");
|
||||
return;
|
||||
}
|
||||
clc.download = FS_SV_FOpenFileWrite(clc.downloadTempName);
|
||||
if(!clc.download) {
|
||||
Com_Error(ERR_DROP, "CL_cURL_BeginDownload: failed to open "
|
||||
"%s for writing\n", clc.downloadTempName);
|
||||
"%s for writing", clc.downloadTempName);
|
||||
return;
|
||||
}
|
||||
qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEDATA, clc.download);
|
||||
|
@ -284,7 +284,7 @@ void CL_cURL_BeginDownload( const char *localName, const char *remoteURL )
|
|||
qcurl_easy_cleanup(clc.downloadCURL);
|
||||
clc.downloadCURL = NULL;
|
||||
Com_Error(ERR_DROP, "CL_cURL_BeginDownload: qcurl_multi_init() "
|
||||
"failed\n");
|
||||
"failed");
|
||||
return;
|
||||
}
|
||||
qcurl_multi_add_handle(clc.downloadCURLM, clc.downloadCURL);
|
||||
|
|
|
@ -416,15 +416,19 @@ void CL_JoystickMove( usercmd_t *cmd ) {
|
|||
}
|
||||
|
||||
if ( !in_strafe.active ) {
|
||||
cl.viewangles[YAW] += anglespeed * cl_yawspeed->value * cl.joystickAxis[AXIS_SIDE];
|
||||
cl.viewangles[YAW] += anglespeed * j_yaw->value * cl.joystickAxis[j_yaw_axis->integer];
|
||||
cmd->rightmove = ClampChar( cmd->rightmove + (int) (j_side->value * cl.joystickAxis[j_side_axis->integer]) );
|
||||
} else {
|
||||
cmd->rightmove = ClampChar( cmd->rightmove + cl.joystickAxis[AXIS_SIDE] );
|
||||
cl.viewangles[YAW] += anglespeed * j_side->value * cl.joystickAxis[j_side_axis->integer];
|
||||
cmd->rightmove = ClampChar( cmd->rightmove + (int) (j_yaw->value * cl.joystickAxis[j_yaw_axis->integer]) );
|
||||
}
|
||||
|
||||
if ( in_mlooking ) {
|
||||
cl.viewangles[PITCH] += anglespeed * cl_pitchspeed->value * cl.joystickAxis[AXIS_FORWARD];
|
||||
cl.viewangles[PITCH] += anglespeed * j_forward->value * cl.joystickAxis[j_forward_axis->integer];
|
||||
cmd->forwardmove = ClampChar( cmd->forwardmove + (int) (j_pitch->value * cl.joystickAxis[j_pitch_axis->integer]) );
|
||||
} else {
|
||||
cmd->forwardmove = ClampChar( cmd->forwardmove + cl.joystickAxis[AXIS_FORWARD] );
|
||||
cl.viewangles[PITCH] += anglespeed * j_pitch->value * cl.joystickAxis[j_pitch_axis->integer];
|
||||
cmd->forwardmove = ClampChar( cmd->forwardmove + (int) (j_forward->value * cl.joystickAxis[j_forward_axis->integer]) );
|
||||
}
|
||||
|
||||
cmd->upmove = ClampChar( cmd->upmove + cl.joystickAxis[AXIS_UP] );
|
||||
|
@ -636,7 +640,7 @@ void CL_CreateNewCommands( void ) {
|
|||
int cmdNum;
|
||||
|
||||
// no need to create usercmds until we have a gamestate
|
||||
if ( cls.state < CA_PRIMED ) {
|
||||
if ( clc.state < CA_PRIMED ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -673,7 +677,7 @@ qboolean CL_ReadyToSendPacket( void ) {
|
|||
int delta;
|
||||
|
||||
// don't send anything if playing back a demo
|
||||
if ( clc.demoplaying || cls.state == CA_CINEMATIC ) {
|
||||
if ( clc.demoplaying || clc.state == CA_CINEMATIC ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
@ -685,8 +689,8 @@ qboolean CL_ReadyToSendPacket( void ) {
|
|||
|
||||
// if we don't have a valid gamestate yet, only send
|
||||
// one packet a second
|
||||
if ( cls.state != CA_ACTIVE &&
|
||||
cls.state != CA_PRIMED &&
|
||||
if ( clc.state != CA_ACTIVE &&
|
||||
clc.state != CA_PRIMED &&
|
||||
!*clc.downloadTempName &&
|
||||
cls.realtime - clc.lastPacketSentTime < 1000 ) {
|
||||
return qfalse;
|
||||
|
@ -750,7 +754,7 @@ void CL_WritePacket( void ) {
|
|||
int count, key;
|
||||
|
||||
// don't send anything if playing back a demo
|
||||
if ( clc.demoplaying || cls.state == CA_CINEMATIC ) {
|
||||
if ( clc.demoplaying || clc.state == CA_CINEMATIC ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -836,8 +840,6 @@ void CL_WritePacket( void ) {
|
|||
cl_voipSendTarget->modified = qfalse;
|
||||
}
|
||||
|
||||
MSG_WriteByte (&buf, clc_EOF); // placate legacy servers.
|
||||
MSG_WriteByte (&buf, clc_extension);
|
||||
MSG_WriteByte (&buf, clc_voip);
|
||||
MSG_WriteByte (&buf, clc.voipOutgoingGeneration);
|
||||
MSG_WriteLong (&buf, clc.voipOutgoingSequence);
|
||||
|
@ -859,8 +861,6 @@ void CL_WritePacket( void ) {
|
|||
MSG_Init (&fakemsg, fakedata, sizeof (fakedata));
|
||||
MSG_Bitstream (&fakemsg);
|
||||
MSG_WriteLong (&fakemsg, clc.reliableAcknowledge);
|
||||
MSG_WriteByte (&fakemsg, svc_EOF);
|
||||
MSG_WriteByte (&fakemsg, svc_extension);
|
||||
MSG_WriteByte (&fakemsg, svc_voip);
|
||||
MSG_WriteShort (&fakemsg, clc.clientNum);
|
||||
MSG_WriteByte (&fakemsg, clc.voipOutgoingGeneration);
|
||||
|
@ -924,16 +924,6 @@ void CL_WritePacket( void ) {
|
|||
}
|
||||
|
||||
CL_Netchan_Transmit (&clc.netchan, &buf);
|
||||
|
||||
// clients never really should have messages large enough
|
||||
// to fragment, but in case they do, fire them all off
|
||||
// at once
|
||||
// TTimo: this causes a packet burst, which is bad karma for winsock
|
||||
// added a WARNING message, we'll see if there are legit situations where this happens
|
||||
while ( clc.netchan.unsentFragments ) {
|
||||
Com_DPrintf( "WARNING: #462 unsent fragments (not supposed to happen!)\n" );
|
||||
CL_Netchan_TransmitNextFragment( &clc.netchan );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -945,7 +935,7 @@ Called every frame to builds and sends a command packet to the server.
|
|||
*/
|
||||
void CL_SendCmd( void ) {
|
||||
// don't send any message if not connected
|
||||
if ( cls.state < CA_CONNECTED ) {
|
||||
if ( clc.state < CA_CONNECTED ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1043,3 +1033,77 @@ void CL_InitInput( void ) {
|
|||
cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0);
|
||||
cl_debugMove = Cvar_Get ("cl_debugMove", "0", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
CL_ShutdownInput
|
||||
============
|
||||
*/
|
||||
void CL_ShutdownInput(void)
|
||||
{
|
||||
Cmd_RemoveCommand("centerview");
|
||||
|
||||
Cmd_RemoveCommand("+moveup");
|
||||
Cmd_RemoveCommand("-moveup");
|
||||
Cmd_RemoveCommand("+movedown");
|
||||
Cmd_RemoveCommand("-movedown");
|
||||
Cmd_RemoveCommand("+left");
|
||||
Cmd_RemoveCommand("-left");
|
||||
Cmd_RemoveCommand("+right");
|
||||
Cmd_RemoveCommand("-right");
|
||||
Cmd_RemoveCommand("+forward");
|
||||
Cmd_RemoveCommand("-forward");
|
||||
Cmd_RemoveCommand("+back");
|
||||
Cmd_RemoveCommand("-back");
|
||||
Cmd_RemoveCommand("+lookup");
|
||||
Cmd_RemoveCommand("-lookup");
|
||||
Cmd_RemoveCommand("+lookdown");
|
||||
Cmd_RemoveCommand("-lookdown");
|
||||
Cmd_RemoveCommand("+strafe");
|
||||
Cmd_RemoveCommand("-strafe");
|
||||
Cmd_RemoveCommand("+moveleft");
|
||||
Cmd_RemoveCommand("-moveleft");
|
||||
Cmd_RemoveCommand("+moveright");
|
||||
Cmd_RemoveCommand("-moveright");
|
||||
Cmd_RemoveCommand("+speed");
|
||||
Cmd_RemoveCommand("-speed");
|
||||
Cmd_RemoveCommand("+attack");
|
||||
Cmd_RemoveCommand("-attack");
|
||||
Cmd_RemoveCommand("+button0");
|
||||
Cmd_RemoveCommand("-button0");
|
||||
Cmd_RemoveCommand("+button1");
|
||||
Cmd_RemoveCommand("-button1");
|
||||
Cmd_RemoveCommand("+button2");
|
||||
Cmd_RemoveCommand("-button2");
|
||||
Cmd_RemoveCommand("+button3");
|
||||
Cmd_RemoveCommand("-button3");
|
||||
Cmd_RemoveCommand("+button4");
|
||||
Cmd_RemoveCommand("-button4");
|
||||
Cmd_RemoveCommand("+button5");
|
||||
Cmd_RemoveCommand("-button5");
|
||||
Cmd_RemoveCommand("+button6");
|
||||
Cmd_RemoveCommand("-button6");
|
||||
Cmd_RemoveCommand("+button7");
|
||||
Cmd_RemoveCommand("-button7");
|
||||
Cmd_RemoveCommand("+button8");
|
||||
Cmd_RemoveCommand("-button8");
|
||||
Cmd_RemoveCommand("+button9");
|
||||
Cmd_RemoveCommand("-button9");
|
||||
Cmd_RemoveCommand("+button10");
|
||||
Cmd_RemoveCommand("-button10");
|
||||
Cmd_RemoveCommand("+button11");
|
||||
Cmd_RemoveCommand("-button11");
|
||||
Cmd_RemoveCommand("+button12");
|
||||
Cmd_RemoveCommand("-button12");
|
||||
Cmd_RemoveCommand("+button13");
|
||||
Cmd_RemoveCommand("-button13");
|
||||
Cmd_RemoveCommand("+button14");
|
||||
Cmd_RemoveCommand("-button14");
|
||||
Cmd_RemoveCommand("+mlook");
|
||||
Cmd_RemoveCommand("-mlook");
|
||||
|
||||
#ifdef USE_VOIP
|
||||
Cmd_RemoveCommand("+voiprecord");
|
||||
Cmd_RemoveCommand("-voiprecord");
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -586,7 +586,7 @@ void Console_Key (int key) {
|
|||
// enter finishes the line
|
||||
if ( key == K_ENTER || key == K_KP_ENTER ) {
|
||||
// if not in the game explicitly prepend a slash if needed
|
||||
if ( cls.state != CA_ACTIVE &&
|
||||
if ( clc.state != CA_ACTIVE &&
|
||||
g_consoleField.buffer[0] &&
|
||||
g_consoleField.buffer[0] != '\\' &&
|
||||
g_consoleField.buffer[0] != '/' ) {
|
||||
|
@ -625,7 +625,7 @@ void Console_Key (int key) {
|
|||
|
||||
CL_SaveConsoleHistory( );
|
||||
|
||||
if ( cls.state == CA_DISCONNECTED ) {
|
||||
if ( clc.state == CA_DISCONNECTED ) {
|
||||
SCR_UpdateScreen (); // force an update, because the command
|
||||
} // may take some time
|
||||
return;
|
||||
|
@ -731,7 +731,7 @@ void Message_Key( int key ) {
|
|||
|
||||
if ( key == K_ENTER || key == K_KP_ENTER )
|
||||
{
|
||||
if ( chatField.buffer[0] && cls.state == CA_ACTIVE ) {
|
||||
if ( chatField.buffer[0] && clc.state == CA_ACTIVE ) {
|
||||
if (chat_playerNum != -1 )
|
||||
|
||||
Com_sprintf( buffer, sizeof( buffer ), "tell %i \"%s\"\n", chat_playerNum, chatField.buffer );
|
||||
|
@ -1175,7 +1175,7 @@ void CL_KeyDownEvent( int key, unsigned time )
|
|||
{
|
||||
keys[key].down = qtrue;
|
||||
keys[key].repeats++;
|
||||
if( keys[key].repeats == 1 )
|
||||
if( keys[key].repeats == 1 && key != K_SCROLLOCK && key != K_KP_NUMLOCK && key != K_CAPSLOCK )
|
||||
anykeydown++;
|
||||
|
||||
if( keys[K_ALT].down && key == K_ENTER )
|
||||
|
@ -1196,7 +1196,7 @@ void CL_KeyDownEvent( int key, unsigned time )
|
|||
|
||||
// keys can still be used for bound actions
|
||||
if ( ( key < 128 || key == K_MOUSE1 ) &&
|
||||
( clc.demoplaying || cls.state == CA_CINEMATIC ) && Key_GetCatcher( ) == 0 ) {
|
||||
( clc.demoplaying || clc.state == CA_CINEMATIC ) && Key_GetCatcher( ) == 0 ) {
|
||||
|
||||
if (Cvar_VariableValue ("com_cameraMode") == 0) {
|
||||
Cvar_Set ("nextdemo","");
|
||||
|
@ -1220,10 +1220,10 @@ void CL_KeyDownEvent( int key, unsigned time )
|
|||
}
|
||||
|
||||
if ( !( Key_GetCatcher( ) & KEYCATCH_UI ) ) {
|
||||
if ( cls.state == CA_ACTIVE && !clc.demoplaying ) {
|
||||
if ( clc.state == CA_ACTIVE && !clc.demoplaying ) {
|
||||
VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_INGAME );
|
||||
}
|
||||
else if ( cls.state != CA_DISCONNECTED ) {
|
||||
else if ( clc.state != CA_DISCONNECTED ) {
|
||||
CL_Disconnect_f();
|
||||
S_StopAllSounds();
|
||||
VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_MAIN );
|
||||
|
@ -1248,7 +1248,7 @@ void CL_KeyDownEvent( int key, unsigned time )
|
|||
}
|
||||
} else if ( Key_GetCatcher( ) & KEYCATCH_MESSAGE ) {
|
||||
Message_Key( key );
|
||||
} else if ( cls.state == CA_DISCONNECTED ) {
|
||||
} else if ( clc.state == CA_DISCONNECTED ) {
|
||||
Console_Key( key );
|
||||
} else {
|
||||
// send the bound action
|
||||
|
@ -1268,7 +1268,9 @@ void CL_KeyUpEvent( int key, unsigned time )
|
|||
{
|
||||
keys[key].repeats = 0;
|
||||
keys[key].down = qfalse;
|
||||
anykeydown--;
|
||||
if (key != K_SCROLLOCK && key != K_KP_NUMLOCK && key != K_CAPSLOCK)
|
||||
anykeydown--;
|
||||
|
||||
if (anykeydown < 0) {
|
||||
anykeydown = 0;
|
||||
}
|
||||
|
@ -1283,7 +1285,7 @@ void CL_KeyUpEvent( int key, unsigned time )
|
|||
// console mode and menu mode, to keep the character from continuing
|
||||
// an action started before a mode switch.
|
||||
//
|
||||
if( cls.state != CA_DISCONNECTED )
|
||||
if( clc.state != CA_DISCONNECTED )
|
||||
CL_ParseBinding( key, qfalse, time );
|
||||
|
||||
if ( Key_GetCatcher( ) & KEYCATCH_UI && uivm ) {
|
||||
|
@ -1334,7 +1336,7 @@ void CL_CharEvent( int key ) {
|
|||
{
|
||||
Field_CharEvent( &chatField, key );
|
||||
}
|
||||
else if ( cls.state == CA_DISCONNECTED )
|
||||
else if ( clc.state == CA_DISCONNECTED )
|
||||
{
|
||||
Field_CharEvent( &g_consoleField, key );
|
||||
}
|
||||
|
@ -1353,6 +1355,9 @@ void Key_ClearStates (void)
|
|||
anykeydown = 0;
|
||||
|
||||
for ( i=0 ; i < MAX_KEYS ; i++ ) {
|
||||
if (i == K_SCROLLOCK || i == K_KP_NUMLOCK || i == K_CAPSLOCK)
|
||||
continue;
|
||||
|
||||
if ( keys[i].down ) {
|
||||
CL_KeyEvent( i, qfalse, 0 );
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include "../qcommon/qcommon.h"
|
||||
#include "client.h"
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
/*
|
||||
==============
|
||||
CL_Netchan_Encode
|
||||
|
@ -125,14 +126,22 @@ static void CL_Netchan_Decode( msg_t *msg ) {
|
|||
*(msg->data + i) = *(msg->data + i) ^ key;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_Netchan_TransmitNextFragment
|
||||
=================
|
||||
*/
|
||||
void CL_Netchan_TransmitNextFragment( netchan_t *chan ) {
|
||||
Netchan_TransmitNextFragment( chan );
|
||||
qboolean CL_Netchan_TransmitNextFragment(netchan_t *chan)
|
||||
{
|
||||
if(chan->unsentFragments)
|
||||
{
|
||||
Netchan_TransmitNextFragment(chan);
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -143,12 +152,19 @@ CL_Netchan_Transmit
|
|||
void CL_Netchan_Transmit( netchan_t *chan, msg_t* msg ) {
|
||||
MSG_WriteByte( msg, clc_EOF );
|
||||
|
||||
CL_Netchan_Encode( msg );
|
||||
Netchan_Transmit( chan, msg->cursize, msg->data );
|
||||
}
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(chan->compat)
|
||||
CL_Netchan_Encode(msg);
|
||||
#endif
|
||||
|
||||
extern int oldsize;
|
||||
int newsize = 0;
|
||||
Netchan_Transmit(chan, msg->cursize, msg->data);
|
||||
|
||||
// Transmit all fragments without delay
|
||||
while(CL_Netchan_TransmitNextFragment(chan))
|
||||
{
|
||||
Com_DPrintf("WARNING: #462 unsent fragments (not supposed to happen!)\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -161,7 +177,11 @@ qboolean CL_Netchan_Process( netchan_t *chan, msg_t *msg ) {
|
|||
ret = Netchan_Process( chan, msg );
|
||||
if (!ret)
|
||||
return qfalse;
|
||||
CL_Netchan_Decode( msg );
|
||||
newsize += msg->cursize;
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(chan->compat)
|
||||
CL_Netchan_Decode(msg);
|
||||
#endif
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ char *svc_strings[256] = {
|
|||
"svc_download",
|
||||
"svc_snapshot",
|
||||
"svc_EOF",
|
||||
"svc_extension",
|
||||
"svc_voip",
|
||||
};
|
||||
|
||||
|
@ -265,7 +264,7 @@ void CL_ParseSnapshot( msg_t *msg ) {
|
|||
|
||||
if(len > sizeof(newSnap.areamask))
|
||||
{
|
||||
Com_Error (ERR_DROP,"CL_ParseSnapshot: Invalid size %d for areamask.", len);
|
||||
Com_Error (ERR_DROP,"CL_ParseSnapshot: Invalid size %d for areamask", len);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -330,10 +329,6 @@ void CL_ParseSnapshot( msg_t *msg ) {
|
|||
int cl_connectedToPureServer;
|
||||
int cl_connectedToCheatServer;
|
||||
|
||||
#ifdef USE_VOIP
|
||||
int cl_connectedToVoipServer;
|
||||
#endif
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_SystemInfoChanged
|
||||
|
@ -363,14 +358,18 @@ void CL_SystemInfoChanged( void ) {
|
|||
}
|
||||
|
||||
#ifdef USE_VOIP
|
||||
// in the future, (val) will be a protocol version string, so only
|
||||
// accept explicitly 1, not generally non-zero.
|
||||
s = Info_ValueForKey( systemInfo, "sv_voip" );
|
||||
if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER || Cvar_VariableValue("ui_singlePlayerActive"))
|
||||
cl_connectedToVoipServer = qfalse;
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
if(clc.compat)
|
||||
clc.voipEnabled = qfalse;
|
||||
else
|
||||
cl_connectedToVoipServer = (atoi( s ) == 1);
|
||||
|
||||
#endif
|
||||
{
|
||||
s = Info_ValueForKey( systemInfo, "sv_voip" );
|
||||
if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER || Cvar_VariableValue("ui_singlePlayerActive"))
|
||||
clc.voipEnabled = qfalse;
|
||||
else
|
||||
clc.voipEnabled = atoi(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
s = Info_ValueForKey( systemInfo, "sv_cheats" );
|
||||
|
@ -416,13 +415,13 @@ void CL_SystemInfoChanged( void ) {
|
|||
else
|
||||
{
|
||||
// If this cvar may not be modified by a server discard the value.
|
||||
if(!(cvar_flags & (CVAR_SYSTEMINFO | CVAR_SERVER_CREATED)))
|
||||
if(!(cvar_flags & (CVAR_SYSTEMINFO | CVAR_SERVER_CREATED | CVAR_USER_CREATED)))
|
||||
{
|
||||
Com_Printf(S_COLOR_YELLOW "WARNING: server is not allowed to set %s=%s\n", key, value);
|
||||
continue;
|
||||
}
|
||||
|
||||
Cvar_Set(key, value);
|
||||
Cvar_SetSafe(key, value);
|
||||
}
|
||||
}
|
||||
// if game folder should not be set and it is set at the client side
|
||||
|
@ -463,6 +462,7 @@ void CL_ParseGamestate( msg_t *msg ) {
|
|||
entityState_t nullstate;
|
||||
int cmd;
|
||||
char *s;
|
||||
char oldGame[MAX_QPATH];
|
||||
|
||||
Con_Close();
|
||||
|
||||
|
@ -518,6 +518,9 @@ void CL_ParseGamestate( msg_t *msg ) {
|
|||
// read the checksum feed
|
||||
clc.checksumFeed = MSG_ReadLong( msg );
|
||||
|
||||
// save old gamedir
|
||||
Cvar_VariableStringBuffer("fs_game", oldGame, sizeof(oldGame));
|
||||
|
||||
// parse useful values out of CS_SERVERINFO
|
||||
CL_ParseServerInfo();
|
||||
|
||||
|
@ -529,7 +532,11 @@ void CL_ParseGamestate( msg_t *msg ) {
|
|||
CL_StopRecord_f();
|
||||
|
||||
// reinitialize the filesystem if the game directory has changed
|
||||
FS_ConditionalRestart( clc.checksumFeed );
|
||||
if(FS_ConditionalRestart(clc.checksumFeed, qfalse) && !cls.oldGameSet)
|
||||
{
|
||||
cls.oldGameSet = qtrue;
|
||||
Q_strncpyz(cls.oldGame, oldGame, sizeof(cls.oldGame));
|
||||
}
|
||||
|
||||
// This used to call CL_StartHunkUsers, but now we enter the download state before loading the
|
||||
// cgame
|
||||
|
@ -552,7 +559,7 @@ A download message has been received from the server
|
|||
void CL_ParseDownload ( msg_t *msg ) {
|
||||
int size;
|
||||
unsigned char data[MAX_MSGLEN];
|
||||
int block;
|
||||
uint16_t block;
|
||||
|
||||
if (!*clc.downloadTempName) {
|
||||
Com_Printf("Server sending download, but no download was requested\n");
|
||||
|
@ -563,7 +570,7 @@ void CL_ParseDownload ( msg_t *msg ) {
|
|||
// read the data
|
||||
block = MSG_ReadShort ( msg );
|
||||
|
||||
if ( !block )
|
||||
if(!block && !clc.downloadBlock)
|
||||
{
|
||||
// block zero is special, contains file size
|
||||
clc.downloadSize = MSG_ReadLong ( msg );
|
||||
|
@ -580,14 +587,15 @@ void CL_ParseDownload ( msg_t *msg ) {
|
|||
size = MSG_ReadShort ( msg );
|
||||
if (size < 0 || size > sizeof(data))
|
||||
{
|
||||
Com_Error(ERR_DROP, "CL_ParseDownload: Invalid size %d for download chunk.", size);
|
||||
Com_Error(ERR_DROP, "CL_ParseDownload: Invalid size %d for download chunk", size);
|
||||
return;
|
||||
}
|
||||
|
||||
MSG_ReadData(msg, data, size);
|
||||
|
||||
if (clc.downloadBlock != block) {
|
||||
Com_DPrintf( "CL_ParseDownload: Expected block %d, got %d\n", clc.downloadBlock, block);
|
||||
if((clc.downloadBlock & 0xFFFF) != block)
|
||||
{
|
||||
Com_DPrintf( "CL_ParseDownload: Expected block %d, got %d\n", (clc.downloadBlock & 0xFFFF), block);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -856,19 +864,6 @@ void CL_ParseServerMessage( msg_t *msg ) {
|
|||
|
||||
cmd = MSG_ReadByte( msg );
|
||||
|
||||
// See if this is an extension command after the EOF, which means we
|
||||
// got data that a legacy client should ignore.
|
||||
if ((cmd == svc_EOF) && (MSG_LookaheadByte( msg ) == svc_extension)) {
|
||||
SHOWNET( msg, "EXTENSION" );
|
||||
MSG_ReadByte( msg ); // throw the svc_extension byte away.
|
||||
cmd = MSG_ReadByte( msg ); // something legacy clients can't do!
|
||||
// sometimes you get a svc_extension at end of stream...dangling
|
||||
// bits in the huffman decoder giving a bogus value?
|
||||
if (cmd == -1) {
|
||||
cmd = svc_EOF;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd == svc_EOF) {
|
||||
SHOWNET( msg, "END OF MESSAGE" );
|
||||
break;
|
||||
|
@ -885,7 +880,7 @@ void CL_ParseServerMessage( msg_t *msg ) {
|
|||
// other commands
|
||||
switch ( cmd ) {
|
||||
default:
|
||||
Com_Error (ERR_DROP,"CL_ParseServerMessage: Illegible server message\n");
|
||||
Com_Error (ERR_DROP,"CL_ParseServerMessage: Illegible server message");
|
||||
break;
|
||||
case svc_nop:
|
||||
break;
|
||||
|
|
|
@ -360,9 +360,9 @@ void SCR_DrawVoipMeter( void ) {
|
|||
return; // player doesn't want to show meter at all.
|
||||
else if (!cl_voipSend->integer)
|
||||
return; // not recording at the moment.
|
||||
else if (cls.state != CA_ACTIVE)
|
||||
else if (clc.state != CA_ACTIVE)
|
||||
return; // not connected to a server.
|
||||
else if (!cl_connectedToVoipServer)
|
||||
else if (!clc.voipEnabled)
|
||||
return; // server doesn't support VoIP.
|
||||
else if (clc.demoplaying)
|
||||
return; // playing back a demo.
|
||||
|
@ -480,11 +480,15 @@ This will be called twice if rendering in stereo mode
|
|||
==================
|
||||
*/
|
||||
void SCR_DrawScreenField( stereoFrame_t stereoFrame ) {
|
||||
qboolean uiFullscreen;
|
||||
|
||||
re.BeginFrame( stereoFrame );
|
||||
|
||||
uiFullscreen = (uivm && VM_Call( uivm, UI_IS_FULLSCREEN ));
|
||||
|
||||
// wide aspect ratio screens need to have the sides cleared
|
||||
// unless they are displaying game renderings
|
||||
if ( cls.state != CA_ACTIVE && cls.state != CA_CINEMATIC ) {
|
||||
if ( uiFullscreen || (clc.state != CA_ACTIVE && clc.state != CA_CINEMATIC) ) {
|
||||
if ( cls.glconfig.vidWidth * 480 > cls.glconfig.vidHeight * 640 ) {
|
||||
re.SetColor( g_color_table[0] );
|
||||
re.DrawStretchPic( 0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, 0, 0, 0, 0, cls.whiteShader );
|
||||
|
@ -494,10 +498,10 @@ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) {
|
|||
|
||||
// if the menu is going to cover the entire screen, we
|
||||
// don't need to render anything under it
|
||||
if ( uivm && !VM_Call( uivm, UI_IS_FULLSCREEN )) {
|
||||
switch( cls.state ) {
|
||||
if ( uivm && !uiFullscreen ) {
|
||||
switch( clc.state ) {
|
||||
default:
|
||||
Com_Error( ERR_FATAL, "SCR_DrawScreenField: bad cls.state" );
|
||||
Com_Error( ERR_FATAL, "SCR_DrawScreenField: bad clc.state" );
|
||||
break;
|
||||
case CA_CINEMATIC:
|
||||
SCR_DrawCinematic();
|
||||
|
|
|
@ -35,8 +35,8 @@ GetClientState
|
|||
*/
|
||||
static void GetClientState( uiClientState_t *state ) {
|
||||
state->connectPacketCount = clc.connectPacketCount;
|
||||
state->connState = cls.state;
|
||||
Q_strncpyz( state->servername, cls.servername, sizeof( state->servername ) );
|
||||
state->connState = clc.state;
|
||||
Q_strncpyz( state->servername, clc.servername, sizeof( state->servername ) );
|
||||
Q_strncpyz( state->updateInfoString, cls.updateInfoString, sizeof( state->updateInfoString ) );
|
||||
Q_strncpyz( state->messageString, clc.serverMessage, sizeof( state->messageString ) );
|
||||
state->clientNum = cl.snap.ps.clientNum;
|
||||
|
@ -298,6 +298,8 @@ static void LAN_GetServerInfo( int source, int n, char *buf, int buflen ) {
|
|||
Info_SetValueForKey( info, "nettype", va("%i",server->netType));
|
||||
Info_SetValueForKey( info, "addr", NET_AdrToStringwPort(server->adr));
|
||||
Info_SetValueForKey( info, "punkbuster", va("%i", server->punkbuster));
|
||||
Info_SetValueForKey( info, "g_needpass", va("%i", server->g_needpass));
|
||||
Info_SetValueForKey( info, "g_humanplayers", va("%i", server->g_humanplayers));
|
||||
Q_strncpyz(buf, info, buflen);
|
||||
} else {
|
||||
if (buf) {
|
||||
|
@ -729,7 +731,7 @@ intptr_t CL_UISystemCalls( intptr_t *args ) {
|
|||
return 0;
|
||||
|
||||
case UI_CVAR_SET:
|
||||
Cvar_Set( VMA(1), VMA(2) );
|
||||
Cvar_SetSafe( VMA(1), VMA(2) );
|
||||
return 0;
|
||||
|
||||
case UI_CVAR_VARIABLEVALUE:
|
||||
|
@ -740,7 +742,7 @@ intptr_t CL_UISystemCalls( intptr_t *args ) {
|
|||
return 0;
|
||||
|
||||
case UI_CVAR_SETVALUE:
|
||||
Cvar_SetValue( VMA(1), VMF(2) );
|
||||
Cvar_SetValueSafe( VMA(1), VMF(2) );
|
||||
return 0;
|
||||
|
||||
case UI_CVAR_RESET:
|
||||
|
@ -1113,7 +1115,7 @@ void CL_InitUI( void ) {
|
|||
if (v == UI_OLD_API_VERSION) {
|
||||
// Com_Printf(S_COLOR_YELLOW "WARNING: loading old Quake III Arena User Interface version %d\n", v );
|
||||
// init for this gamestate
|
||||
VM_Call( uivm, UI_INIT, (cls.state >= CA_AUTHORIZING && cls.state < CA_ACTIVE));
|
||||
VM_Call( uivm, UI_INIT, (clc.state >= CA_AUTHORIZING && clc.state < CA_ACTIVE));
|
||||
}
|
||||
else if (v != UI_API_VERSION) {
|
||||
Com_Error( ERR_DROP, "User Interface is version %d, expected %d", v, UI_API_VERSION );
|
||||
|
@ -1121,12 +1123,8 @@ void CL_InitUI( void ) {
|
|||
}
|
||||
else {
|
||||
// init for this gamestate
|
||||
VM_Call( uivm, UI_INIT, (cls.state >= CA_AUTHORIZING && cls.state < CA_ACTIVE) );
|
||||
VM_Call( uivm, UI_INIT, (clc.state >= CA_AUTHORIZING && clc.state < CA_ACTIVE) );
|
||||
}
|
||||
|
||||
// reset any CVAR_CHEAT cvars registered by ui
|
||||
if ( !clc.demoplaying && !cl_connectedToCheatServer )
|
||||
Cvar_SetCheatState();
|
||||
}
|
||||
|
||||
#ifndef STANDALONE
|
||||
|
|
|
@ -162,10 +162,13 @@ demo through a file.
|
|||
|
||||
typedef struct {
|
||||
|
||||
connstate_t state; // connection status
|
||||
|
||||
int clientNum;
|
||||
int lastPacketSentTime; // for retransmits during connection
|
||||
int lastPacketTime; // for timeouts
|
||||
|
||||
char servername[MAX_OSPATH]; // name of server from original connect (used by reconnect)
|
||||
netadr_t serverAddress;
|
||||
int connectTime; // for connection retransmits
|
||||
int connectPacketCount; // for display on connection dialog
|
||||
|
@ -231,6 +234,7 @@ typedef struct {
|
|||
unsigned char timeDemoDurations[ MAX_TIMEDEMO_DURATIONS ]; // log of frame durations
|
||||
|
||||
#ifdef USE_VOIP
|
||||
qboolean voipEnabled;
|
||||
qboolean speexInitialized;
|
||||
int speexFrameSize;
|
||||
int speexSampleRate;
|
||||
|
@ -260,6 +264,10 @@ typedef struct {
|
|||
float voipPower;
|
||||
#endif
|
||||
|
||||
#ifdef LEGACY_PROTOCOL
|
||||
qboolean compat;
|
||||
#endif
|
||||
|
||||
// big stuff at end of structure so most offsets are 15 bits or less
|
||||
netchan_t netchan;
|
||||
} clientConnection_t;
|
||||
|
@ -296,15 +304,13 @@ typedef struct {
|
|||
int ping;
|
||||
qboolean visible;
|
||||
int punkbuster;
|
||||
int g_humanplayers;
|
||||
int g_needpass;
|
||||
} serverInfo_t;
|
||||
|
||||
typedef struct {
|
||||
connstate_t state; // connection status
|
||||
|
||||
qboolean cddialog; // bring up the cd needed dialog next frame
|
||||
|
||||
char servername[MAX_OSPATH]; // name of server from original connect (used by reconnect)
|
||||
|
||||
// when the server clears the hunk, all of these must be restarted
|
||||
qboolean rendererStarted;
|
||||
qboolean soundStarted;
|
||||
|
@ -331,6 +337,9 @@ typedef struct {
|
|||
serverInfo_t favoriteServers[MAX_OTHER_SERVERS];
|
||||
|
||||
int pingUpdateSource; // source currently pinging or updating
|
||||
|
||||
char oldGame[MAX_QPATH];
|
||||
qboolean oldGameSet;
|
||||
|
||||
// update server info
|
||||
netadr_t updateServer;
|
||||
|
@ -389,6 +398,15 @@ extern cvar_t *m_forward;
|
|||
extern cvar_t *m_side;
|
||||
extern cvar_t *m_filter;
|
||||
|
||||
extern cvar_t *j_pitch;
|
||||
extern cvar_t *j_yaw;
|
||||
extern cvar_t *j_forward;
|
||||
extern cvar_t *j_side;
|
||||
extern cvar_t *j_pitch_axis;
|
||||
extern cvar_t *j_yaw_axis;
|
||||
extern cvar_t *j_forward_axis;
|
||||
extern cvar_t *j_side_axis;
|
||||
|
||||
extern cvar_t *cl_timedemo;
|
||||
extern cvar_t *cl_aviFrameRate;
|
||||
extern cvar_t *cl_aviMotionJpeg;
|
||||
|
@ -431,8 +449,6 @@ extern cvar_t *cl_voip;
|
|||
//
|
||||
|
||||
void CL_Init (void);
|
||||
void CL_FlushMemory(void);
|
||||
void CL_ShutdownAll(void);
|
||||
void CL_AddReliableCommand(const char *cmd, qboolean isDisconnectCmd);
|
||||
|
||||
void CL_StartHunkUsers( qboolean rendererOnly );
|
||||
|
@ -480,7 +496,8 @@ extern kbutton_t in_speed;
|
|||
extern kbutton_t in_voiprecord;
|
||||
#endif
|
||||
|
||||
void CL_InitInput (void);
|
||||
void CL_InitInput(void);
|
||||
void CL_ShutdownInput(void);
|
||||
void CL_SendCmd (void);
|
||||
void CL_ClearState (void);
|
||||
void CL_ReadPackets (void);
|
||||
|
@ -501,7 +518,6 @@ extern int cl_connectedToPureServer;
|
|||
extern int cl_connectedToCheatServer;
|
||||
|
||||
#ifdef USE_VOIP
|
||||
extern int cl_connectedToVoipServer;
|
||||
void CL_Voip_f( void );
|
||||
#endif
|
||||
|
||||
|
@ -524,7 +540,8 @@ qboolean CL_UpdateVisiblePings_f( int source );
|
|||
void Con_DrawCharacter (int cx, int line, int num);
|
||||
|
||||
void Con_CheckResize (void);
|
||||
void Con_Init (void);
|
||||
void Con_Init(void);
|
||||
void Con_Shutdown(void);
|
||||
void Con_Clear_f (void);
|
||||
void Con_ToggleConsole_f (void);
|
||||
void Con_DrawNotify (void);
|
||||
|
@ -605,7 +622,6 @@ void LAN_SaveServersToCache( void );
|
|||
// cl_net_chan.c
|
||||
//
|
||||
void CL_Netchan_Transmit( netchan_t *chan, msg_t* msg); //int length, const byte *data );
|
||||
void CL_Netchan_TransmitNextFragment( netchan_t *chan );
|
||||
qboolean CL_Netchan_Process( netchan_t *chan, msg_t *msg );
|
||||
|
||||
//
|
||||
|
|
|
@ -25,6 +25,9 @@
|
|||
#define uint32_t UINT32
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#ifdef __sun
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
#endif
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
|
|
@ -47,6 +47,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/* Hack to enable compiling both on OpenAL SDK and OpenAL-soft. */
|
||||
#ifndef ALC_ENUMERATE_ALL_EXT
|
||||
# define ALC_ENUMERATE_ALL_EXT 1
|
||||
# define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012
|
||||
# define ALC_ALL_DEVICES_SPECIFIER 0x1013
|
||||
#endif
|
||||
|
||||
#ifdef USE_OPENAL_DLOPEN
|
||||
extern LPALENABLE qalEnable;
|
||||
extern LPALDISABLE qalDisable;
|
||||
|
|
|
@ -28,71 +28,90 @@ static snd_codec_t *codecs;
|
|||
|
||||
/*
|
||||
=================
|
||||
S_FileExtension
|
||||
S_CodecGetSound
|
||||
|
||||
Opens/loads a sound, tries codec based on the sound's file extension
|
||||
then tries all supported codecs.
|
||||
=================
|
||||
*/
|
||||
static char *S_FileExtension(const char *fni)
|
||||
static void *S_CodecGetSound(const char *filename, snd_info_t *info)
|
||||
{
|
||||
// we should search from the ending to the last '/'
|
||||
snd_codec_t *codec;
|
||||
snd_codec_t *orgCodec = NULL;
|
||||
qboolean orgNameFailed = qfalse;
|
||||
char localName[ MAX_QPATH ];
|
||||
const char *ext;
|
||||
char altName[ MAX_QPATH ];
|
||||
void *rtn = NULL;
|
||||
|
||||
char *fn = (char *) fni + strlen(fni) - 1;
|
||||
char *eptr = NULL;
|
||||
Q_strncpyz(localName, filename, MAX_QPATH);
|
||||
|
||||
while(*fn != '/' && fn != fni)
|
||||
ext = COM_GetExtension(localName);
|
||||
|
||||
if( *ext )
|
||||
{
|
||||
if(*fn == '.')
|
||||
// Look for the correct loader and use it
|
||||
for( codec = codecs; codec; codec = codec->next )
|
||||
{
|
||||
eptr = fn;
|
||||
break;
|
||||
}
|
||||
fn--;
|
||||
}
|
||||
|
||||
return eptr;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_FindCodecForFile
|
||||
|
||||
Select an appropriate codec for a file based on its extension
|
||||
=================
|
||||
*/
|
||||
static snd_codec_t *S_FindCodecForFile(const char *filename)
|
||||
{
|
||||
char *ext = S_FileExtension(filename);
|
||||
snd_codec_t *codec = codecs;
|
||||
|
||||
if(!ext)
|
||||
{
|
||||
// No extension - auto-detect
|
||||
while(codec)
|
||||
{
|
||||
char fn[MAX_QPATH];
|
||||
|
||||
// there is no extension so we do not need to subtract 4 chars
|
||||
Q_strncpyz(fn, filename, MAX_QPATH);
|
||||
COM_DefaultExtension(fn, MAX_QPATH, codec->ext);
|
||||
|
||||
// Check it exists
|
||||
if(FS_ReadFile(fn, NULL) != -1)
|
||||
return codec;
|
||||
|
||||
// Nope. Next!
|
||||
codec = codec->next;
|
||||
if( !Q_stricmp( ext, codec->ext ) )
|
||||
{
|
||||
// Load
|
||||
if( info )
|
||||
rtn = codec->load(localName, info);
|
||||
else
|
||||
rtn = codec->open(localName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Nothin'
|
||||
return NULL;
|
||||
// A loader was found
|
||||
if( codec )
|
||||
{
|
||||
if( !rtn )
|
||||
{
|
||||
// Loader failed, most likely because the file isn't there;
|
||||
// try again without the extension
|
||||
orgNameFailed = qtrue;
|
||||
orgCodec = codec;
|
||||
COM_StripExtension( filename, localName, MAX_QPATH );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Something loaded
|
||||
return rtn;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(codec)
|
||||
// Try and find a suitable match using all
|
||||
// the sound codecs supported
|
||||
for( codec = codecs; codec; codec = codec->next )
|
||||
{
|
||||
if(!Q_stricmp(ext, codec->ext))
|
||||
return codec;
|
||||
codec = codec->next;
|
||||
if( codec == orgCodec )
|
||||
continue;
|
||||
|
||||
Com_sprintf( altName, sizeof (altName), "%s.%s", localName, codec->ext );
|
||||
|
||||
// Load
|
||||
if( info )
|
||||
rtn = codec->load(altName, info);
|
||||
else
|
||||
rtn = codec->open(altName);
|
||||
|
||||
if( rtn )
|
||||
{
|
||||
if( orgNameFailed )
|
||||
{
|
||||
Com_DPrintf(S_COLOR_YELLOW "WARNING: %s not present, using %s instead\n",
|
||||
filename, altName );
|
||||
}
|
||||
|
||||
return rtn;
|
||||
}
|
||||
}
|
||||
|
||||
Com_Printf(S_COLOR_YELLOW "WARNING: Failed to %s sound %s!\n", info ? "load" : "open", filename);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -104,10 +123,13 @@ S_CodecInit
|
|||
void S_CodecInit()
|
||||
{
|
||||
codecs = NULL;
|
||||
S_CodecRegister(&wav_codec);
|
||||
|
||||
#ifdef USE_CODEC_VORBIS
|
||||
S_CodecRegister(&ogg_codec);
|
||||
#endif
|
||||
|
||||
// Register wav codec last so that it is always tried first when a file extension was not found
|
||||
S_CodecRegister(&wav_codec);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -138,20 +160,7 @@ S_CodecLoad
|
|||
*/
|
||||
void *S_CodecLoad(const char *filename, snd_info_t *info)
|
||||
{
|
||||
snd_codec_t *codec;
|
||||
char fn[MAX_QPATH];
|
||||
|
||||
codec = S_FindCodecForFile(filename);
|
||||
if(!codec)
|
||||
{
|
||||
Com_Printf("Unknown extension for %s\n", filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strncpy(fn, filename, sizeof(fn));
|
||||
COM_DefaultExtension(fn, sizeof(fn), codec->ext);
|
||||
|
||||
return codec->load(fn, info);
|
||||
return S_CodecGetSound(filename, info);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -161,20 +170,7 @@ S_CodecOpenStream
|
|||
*/
|
||||
snd_stream_t *S_CodecOpenStream(const char *filename)
|
||||
{
|
||||
snd_codec_t *codec;
|
||||
char fn[MAX_QPATH];
|
||||
|
||||
codec = S_FindCodecForFile(filename);
|
||||
if(!codec)
|
||||
{
|
||||
Com_Printf("Unknown extension for %s\n", filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strncpy(fn, filename, sizeof(fn));
|
||||
COM_DefaultExtension(fn, sizeof(fn), codec->ext);
|
||||
|
||||
return codec->open(fn);
|
||||
return S_CodecGetSound(filename, NULL);
|
||||
}
|
||||
|
||||
void S_CodecCloseStream(snd_stream_t *stream)
|
||||
|
@ -205,7 +201,7 @@ snd_stream_t *S_CodecUtilOpen(const char *filename, snd_codec_t *codec)
|
|||
length = FS_FOpenFileRead(filename, &hnd, qtrue);
|
||||
if(!hnd)
|
||||
{
|
||||
Com_Printf("Can't read sound file %s\n", filename);
|
||||
Com_DPrintf("Can't read sound file %s\n", filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
// Q3 OGG codec
|
||||
snd_codec_t ogg_codec =
|
||||
{
|
||||
".ogg",
|
||||
"ogg",
|
||||
S_OGG_CodecLoad,
|
||||
S_OGG_CodecOpenStream,
|
||||
S_OGG_CodecReadStream,
|
||||
|
@ -450,7 +450,7 @@ void *S_OGG_CodecLoad(const char *filename, snd_info_t *info)
|
|||
|
||||
// allocate a buffer
|
||||
// this buffer must be free-ed by the caller of this function
|
||||
buffer = Z_Malloc(info->size);
|
||||
buffer = Hunk_AllocateTempMemory(info->size);
|
||||
if(!buffer)
|
||||
{
|
||||
S_OGG_CodecCloseStream(stream);
|
||||
|
@ -464,7 +464,7 @@ void *S_OGG_CodecLoad(const char *filename, snd_info_t *info)
|
|||
// we don't even have read a single byte
|
||||
if(bytesRead <= 0)
|
||||
{
|
||||
Z_Free(buffer);
|
||||
Hunk_FreeTempMemory(buffer);
|
||||
S_OGG_CodecCloseStream(stream);
|
||||
|
||||
return NULL;
|
||||
|
|
|
@ -183,7 +183,7 @@ static qboolean S_ReadRIFFHeader(fileHandle_t file, snd_info_t *info)
|
|||
// WAV codec
|
||||
snd_codec_t wav_codec =
|
||||
{
|
||||
".wav",
|
||||
"wav",
|
||||
S_WAV_CodecLoad,
|
||||
S_WAV_CodecOpenStream,
|
||||
S_WAV_CodecReadStream,
|
||||
|
@ -205,8 +205,6 @@ void *S_WAV_CodecLoad(const char *filename, snd_info_t *info)
|
|||
FS_FOpenFileRead(filename, &file, qtrue);
|
||||
if(!file)
|
||||
{
|
||||
Com_Printf( S_COLOR_RED "ERROR: Could not open \"%s\"\n",
|
||||
filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -220,7 +218,7 @@ void *S_WAV_CodecLoad(const char *filename, snd_info_t *info)
|
|||
}
|
||||
|
||||
// Allocate some memory
|
||||
buffer = Z_Malloc(info->size);
|
||||
buffer = Hunk_AllocateTempMemory(info->size);
|
||||
if(!buffer)
|
||||
{
|
||||
FS_FCloseFile(file);
|
||||
|
|
|
@ -259,10 +259,10 @@ static sfx_t *S_FindName( const char *name ) {
|
|||
sfx_t *sfx;
|
||||
|
||||
if (!name) {
|
||||
Com_Error (ERR_FATAL, "S_FindName: NULL\n");
|
||||
Com_Error (ERR_FATAL, "S_FindName: NULL");
|
||||
}
|
||||
if (!name[0]) {
|
||||
Com_Error (ERR_FATAL, "S_FindName: empty name\n");
|
||||
Com_Error (ERR_FATAL, "S_FindName: empty name");
|
||||
}
|
||||
|
||||
if (strlen(name) >= MAX_QPATH) {
|
||||
|
@ -391,9 +391,8 @@ void S_Base_BeginRegistration( void ) {
|
|||
if (s_numSfx == 0) {
|
||||
SND_setup();
|
||||
|
||||
s_numSfx = 0;
|
||||
Com_Memset( s_knownSfx, 0, sizeof( s_knownSfx ) );
|
||||
Com_Memset(sfxHash, 0, sizeof(sfx_t *)*LOOP_HASH);
|
||||
Com_Memset(s_knownSfx, '\0', sizeof(s_knownSfx));
|
||||
Com_Memset(sfxHash, '\0', sizeof(sfx_t *) * LOOP_HASH);
|
||||
|
||||
S_Base_RegisterSound("sound/misc/silence.wav", qfalse);
|
||||
}
|
||||
|
@ -1467,8 +1466,10 @@ void S_Base_Shutdown( void ) {
|
|||
}
|
||||
|
||||
SNDDMA_Shutdown();
|
||||
SND_shutdown();
|
||||
|
||||
s_soundStarted = 0;
|
||||
s_numSfx = 0;
|
||||
|
||||
Cmd_RemoveCommand("s_info");
|
||||
}
|
||||
|
|
|
@ -202,6 +202,7 @@ qboolean S_LoadSound( sfx_t *sfx );
|
|||
void SND_free(sndBuffer *v);
|
||||
sndBuffer* SND_malloc( void );
|
||||
void SND_setup( void );
|
||||
void SND_shutdown(void);
|
||||
|
||||
void S_PaintChannels(int endtime);
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Foobar; if not, write to the Free Software
|
||||
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
|
||||
===========================================================================
|
||||
*/
|
||||
|
@ -410,12 +410,9 @@ void S_Play_f( void ) {
|
|||
|
||||
i = 1;
|
||||
while ( i<Cmd_Argc() ) {
|
||||
if ( !Q_strrchr(Cmd_Argv(i), '.') ) {
|
||||
Com_sprintf( name, sizeof(name), "%s.wav", Cmd_Argv(1) );
|
||||
} else {
|
||||
Q_strncpyz( name, Cmd_Argv(i), sizeof(name) );
|
||||
}
|
||||
Q_strncpyz( name, Cmd_Argv(i), sizeof(name) );
|
||||
h = si.RegisterSound( name, qfalse );
|
||||
|
||||
if( h ) {
|
||||
si.StartLocalSound( h, CHAN_LOCAL_SOUND );
|
||||
}
|
||||
|
@ -512,7 +509,7 @@ void S_Init( void )
|
|||
|
||||
if( started ) {
|
||||
if( !S_ValidSoundInterface( &si ) ) {
|
||||
Com_Error( ERR_FATAL, "Sound interface invalid." );
|
||||
Com_Error( ERR_FATAL, "Sound interface invalid" );
|
||||
}
|
||||
|
||||
S_SoundInfo( );
|
||||
|
|
|
@ -100,6 +100,12 @@ void SND_setup(void) {
|
|||
Com_Printf("Sound memory manager started\n");
|
||||
}
|
||||
|
||||
void SND_shutdown(void)
|
||||
{
|
||||
free(sfxScratchBuffer);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
ResampleSfx
|
||||
|
@ -255,7 +261,7 @@ qboolean S_LoadSound( sfx_t *sfx )
|
|||
}
|
||||
|
||||
Hunk_FreeTempMemory(samples);
|
||||
Z_Free(data);
|
||||
Hunk_FreeTempMemory(data);
|
||||
|
||||
return qtrue;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,15 @@ cvar_t *s_alRolloff;
|
|||
cvar_t *s_alGraceDistance;
|
||||
cvar_t *s_alDriver;
|
||||
cvar_t *s_alDevice;
|
||||
cvar_t *s_alInputDevice;
|
||||
cvar_t *s_alAvailableDevices;
|
||||
cvar_t *s_alAvailableInputDevices;
|
||||
|
||||
static qboolean enumeration_ext = qfalse;
|
||||
static qboolean enumeration_all_ext = qfalse;
|
||||
#ifdef USE_VOIP
|
||||
static qboolean capture_ext = qfalse;
|
||||
#endif
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -142,7 +150,7 @@ static qboolean alBuffersInitialised = qfalse;
|
|||
// Sound effect storage, data structures
|
||||
#define MAX_SFX 4096
|
||||
static alSfx_t knownSfx[MAX_SFX];
|
||||
static int numSfx = 0;
|
||||
static sfxHandle_t numSfx = 0;
|
||||
|
||||
static sfxHandle_t default_sfx;
|
||||
|
||||
|
@ -221,7 +229,7 @@ S_AL_BufferUseDefault
|
|||
static void S_AL_BufferUseDefault(sfxHandle_t sfx)
|
||||
{
|
||||
if(sfx == default_sfx)
|
||||
Com_Error(ERR_FATAL, "Can't load default sound effect %s\n", knownSfx[sfx].filename);
|
||||
Com_Error(ERR_FATAL, "Can't load default sound effect %s", knownSfx[sfx].filename);
|
||||
|
||||
Com_Printf( S_COLOR_YELLOW "WARNING: Using default sound for %s\n", knownSfx[sfx].filename);
|
||||
knownSfx[sfx].isDefault = qtrue;
|
||||
|
@ -326,7 +334,7 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache)
|
|||
if (!cache)
|
||||
{
|
||||
// Don't create AL cache
|
||||
Z_Free(data);
|
||||
Hunk_FreeTempMemory(data);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -338,7 +346,7 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache)
|
|||
if((error = qalGetError()) != AL_NO_ERROR)
|
||||
{
|
||||
S_AL_BufferUseDefault(sfx);
|
||||
Z_Free(data);
|
||||
Hunk_FreeTempMemory(data);
|
||||
Com_Printf( S_COLOR_RED "ERROR: Can't create a sound buffer for %s - %s\n",
|
||||
curSfx->filename, S_AL_ErrorMsg(error));
|
||||
return;
|
||||
|
@ -363,7 +371,7 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache)
|
|||
if( !S_AL_BufferEvict( ) )
|
||||
{
|
||||
S_AL_BufferUseDefault(sfx);
|
||||
Z_Free(data);
|
||||
Hunk_FreeTempMemory(data);
|
||||
Com_Printf( S_COLOR_RED "ERROR: Out of memory loading %s\n", curSfx->filename);
|
||||
return;
|
||||
}
|
||||
|
@ -377,7 +385,7 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache)
|
|||
if(error != AL_NO_ERROR)
|
||||
{
|
||||
S_AL_BufferUseDefault(sfx);
|
||||
Z_Free(data);
|
||||
Hunk_FreeTempMemory(data);
|
||||
Com_Printf( S_COLOR_RED "ERROR: Can't fill sound buffer for %s - %s\n",
|
||||
curSfx->filename, S_AL_ErrorMsg(error));
|
||||
return;
|
||||
|
@ -386,7 +394,7 @@ static void S_AL_BufferLoad(sfxHandle_t sfx, qboolean cache)
|
|||
curSfx->info = info;
|
||||
|
||||
// Free the memory
|
||||
Z_Free(data);
|
||||
Hunk_FreeTempMemory(data);
|
||||
|
||||
// Woo!
|
||||
curSfx->inMemory = qtrue;
|
||||
|
@ -454,7 +462,7 @@ void S_AL_BufferShutdown( void )
|
|||
S_AL_BufferUnload(i);
|
||||
|
||||
// Clear the tables
|
||||
memset(knownSfx, 0, sizeof(knownSfx));
|
||||
numSfx = 0;
|
||||
|
||||
// All undone
|
||||
alBuffersInitialised = qfalse;
|
||||
|
@ -2199,6 +2207,8 @@ S_AL_BeginRegistration
|
|||
static
|
||||
void S_AL_BeginRegistration( void )
|
||||
{
|
||||
if(!numSfx)
|
||||
S_AL_BufferInit();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2267,22 +2277,34 @@ void S_AL_MasterGain( float gain )
|
|||
S_AL_SoundInfo
|
||||
=================
|
||||
*/
|
||||
static
|
||||
void S_AL_SoundInfo( void )
|
||||
static void S_AL_SoundInfo(void)
|
||||
{
|
||||
Com_Printf( "OpenAL info:\n" );
|
||||
Com_Printf( " Vendor: %s\n", qalGetString( AL_VENDOR ) );
|
||||
Com_Printf( " Version: %s\n", qalGetString( AL_VERSION ) );
|
||||
Com_Printf( " Renderer: %s\n", qalGetString( AL_RENDERER ) );
|
||||
Com_Printf( " AL Extensions: %s\n", qalGetString( AL_EXTENSIONS ) );
|
||||
Com_Printf( " Vendor: %s\n", qalGetString( AL_VENDOR ) );
|
||||
Com_Printf( " Version: %s\n", qalGetString( AL_VERSION ) );
|
||||
Com_Printf( " Renderer: %s\n", qalGetString( AL_RENDERER ) );
|
||||
Com_Printf( " AL Extensions: %s\n", qalGetString( AL_EXTENSIONS ) );
|
||||
Com_Printf( " ALC Extensions: %s\n", qalcGetString( alDevice, ALC_EXTENSIONS ) );
|
||||
if(qalcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT"))
|
||||
|
||||
if(enumeration_all_ext)
|
||||
Com_Printf(" Device: %s\n", qalcGetString(alDevice, ALC_ALL_DEVICES_SPECIFIER));
|
||||
else if(enumeration_ext)
|
||||
Com_Printf(" Device: %s\n", qalcGetString(alDevice, ALC_DEVICE_SPECIFIER));
|
||||
|
||||
if(enumeration_all_ext || enumeration_ext)
|
||||
Com_Printf(" Available Devices:\n%s", s_alAvailableDevices->string);
|
||||
|
||||
#ifdef USE_VOIP
|
||||
if(capture_ext)
|
||||
{
|
||||
Com_Printf(" Device: %s\n", qalcGetString(alDevice, ALC_DEVICE_SPECIFIER));
|
||||
Com_Printf("Available Devices:\n%s", s_alAvailableDevices->string);
|
||||
Com_Printf(" Input Device: %s\n", qalcGetString(alCaptureDevice, ALC_CAPTURE_DEVICE_SPECIFIER));
|
||||
Com_Printf(" Available Input Devices:\n%s", s_alAvailableInputDevices->string);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
S_AL_Shutdown
|
||||
|
@ -2331,6 +2353,7 @@ qboolean S_AL_Init( soundInterface_t *si )
|
|||
{
|
||||
#ifdef USE_OPENAL
|
||||
const char* device = NULL;
|
||||
const char* inputdevice = NULL;
|
||||
int i;
|
||||
|
||||
if( !si ) {
|
||||
|
@ -2356,6 +2379,7 @@ qboolean S_AL_Init( soundInterface_t *si )
|
|||
|
||||
s_alDriver = Cvar_Get( "s_alDriver", ALDRIVER_DEFAULT, CVAR_ARCHIVE | CVAR_LATCH );
|
||||
|
||||
s_alInputDevice = Cvar_Get( "s_alInputDevice", "", CVAR_ARCHIVE | CVAR_LATCH );
|
||||
s_alDevice = Cvar_Get("s_alDevice", "", CVAR_ARCHIVE | CVAR_LATCH);
|
||||
|
||||
// Load QAL
|
||||
|
@ -2369,35 +2393,59 @@ qboolean S_AL_Init( soundInterface_t *si )
|
|||
if(device && !*device)
|
||||
device = NULL;
|
||||
|
||||
// Device enumeration support (extension is implemented reasonably only on Windows right now).
|
||||
if(qalcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT"))
|
||||
inputdevice = s_alInputDevice->string;
|
||||
if(inputdevice && !*inputdevice)
|
||||
inputdevice = NULL;
|
||||
|
||||
|
||||
// Device enumeration support
|
||||
enumeration_all_ext = qalcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT");
|
||||
enumeration_ext = qalcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT");
|
||||
|
||||
if(enumeration_ext || enumeration_all_ext)
|
||||
{
|
||||
char devicenames[1024] = "";
|
||||
char devicenames[16384] = "";
|
||||
const char *devicelist;
|
||||
const char *defaultdevice;
|
||||
int curlen;
|
||||
|
||||
|
||||
// get all available devices + the default device name.
|
||||
devicelist = qalcGetString(NULL, ALC_DEVICE_SPECIFIER);
|
||||
defaultdevice = qalcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||
if(enumeration_all_ext)
|
||||
{
|
||||
devicelist = qalcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
|
||||
defaultdevice = qalcGetString(NULL, ALC_DEFAULT_ALL_DEVICES_SPECIFIER);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We don't have ALC_ENUMERATE_ALL_EXT but normal enumeration.
|
||||
devicelist = qalcGetString(NULL, ALC_DEVICE_SPECIFIER);
|
||||
defaultdevice = qalcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||
enumeration_ext = qtrue;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
// check whether the default device is generic hardware. If it is, change to
|
||||
// Generic Software as that one works more reliably with various sound systems.
|
||||
// If it's not, use OpenAL's default selection as we don't want to ignore
|
||||
// native hardware acceleration.
|
||||
if(!device && !strcmp(defaultdevice, "Generic Hardware"))
|
||||
if(!device && defaultdevice && !strcmp(defaultdevice, "Generic Hardware"))
|
||||
device = "Generic Software";
|
||||
#endif
|
||||
|
||||
// dump a list of available devices to a cvar for the user to see.
|
||||
while((curlen = strlen(devicelist)))
|
||||
{
|
||||
Q_strcat(devicenames, sizeof(devicenames), devicelist);
|
||||
Q_strcat(devicenames, sizeof(devicenames), "\n");
|
||||
|
||||
devicelist += curlen + 1;
|
||||
if(devicelist)
|
||||
{
|
||||
while((curlen = strlen(devicelist)))
|
||||
{
|
||||
Q_strcat(devicenames, sizeof(devicenames), devicelist);
|
||||
Q_strcat(devicenames, sizeof(devicenames), "\n");
|
||||
|
||||
devicelist += curlen + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
devicelist = "";
|
||||
|
||||
s_alAvailableDevices = Cvar_Get("s_alAvailableDevices", devicenames, CVAR_ROM | CVAR_NORESTART);
|
||||
}
|
||||
|
@ -2468,15 +2516,40 @@ qboolean S_AL_Init( soundInterface_t *si )
|
|||
}
|
||||
else
|
||||
{
|
||||
char inputdevicenames[16384] = "";
|
||||
const char *inputdevicelist;
|
||||
const char *defaultinputdevice;
|
||||
int curlen;
|
||||
|
||||
capture_ext = qtrue;
|
||||
|
||||
// get all available input devices + the default input device name.
|
||||
inputdevicelist = qalcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
|
||||
defaultinputdevice = qalcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
|
||||
|
||||
// dump a list of available devices to a cvar for the user to see.
|
||||
while((curlen = strlen(inputdevicelist)))
|
||||
{
|
||||
Q_strcat(inputdevicenames, sizeof(inputdevicenames), inputdevicelist);
|
||||
Q_strcat(inputdevicenames, sizeof(inputdevicenames), "\n");
|
||||
inputdevicelist += curlen + 1;
|
||||
}
|
||||
|
||||
s_alAvailableInputDevices = Cvar_Get("s_alAvailableInputDevices", inputdevicenames, CVAR_ROM | CVAR_NORESTART);
|
||||
|
||||
// !!! FIXME: 8000Hz is what Speex narrowband mode needs, but we
|
||||
// !!! FIXME: should probably open the capture device after
|
||||
// !!! FIXME: initializing Speex so we can change to wideband
|
||||
// !!! FIXME: if we like.
|
||||
Com_Printf("OpenAL default capture device is '%s'\n",
|
||||
qalcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
|
||||
alCaptureDevice = qalcCaptureOpenDevice(NULL, 8000, AL_FORMAT_MONO16, 4096);
|
||||
Com_Printf("OpenAL default capture device is '%s'\n", defaultinputdevice);
|
||||
alCaptureDevice = qalcCaptureOpenDevice(inputdevice, 8000, AL_FORMAT_MONO16, 4096);
|
||||
if( !alCaptureDevice && inputdevice )
|
||||
{
|
||||
Com_Printf( "Failed to open OpenAL Input device '%s', trying default.\n", inputdevice );
|
||||
alCaptureDevice = qalcCaptureOpenDevice(NULL, 8000, AL_FORMAT_MONO16, 4096);
|
||||
}
|
||||
Com_Printf( "OpenAL capture device %s.\n",
|
||||
(alCaptureDevice == NULL) ? "failed to open" : "opened");
|
||||
(alCaptureDevice == NULL) ? "failed to open" : "opened");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -22,8 +22,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#include "snd_local.h"
|
||||
|
||||
long myftol( float f );
|
||||
|
||||
#define C0 0.4829629131445341
|
||||
#define C1 0.8365163037378079
|
||||
#define C2 0.2241438680420134
|
||||
|
|
|
@ -1470,7 +1470,7 @@ void BotClearPath(bot_state_t *bs, bot_moveresult_t *moveresult) {
|
|||
moveresult->flags |= MOVERESULT_MOVEMENTWEAPON | MOVERESULT_MOVEMENTVIEW;
|
||||
// if holding the right weapon
|
||||
if (bs->cur_ps.weapon == moveresult->weapon) {
|
||||
// if the bot is pretty close with it's aim
|
||||
// if the bot is pretty close with its aim
|
||||
// Q3Rally Code Start
|
||||
// if (InFieldOfVision(bs->viewangles, 20, moveresult->ideal_viewangles)) {
|
||||
if (InFieldOfVision(bs->cur_ps.viewangles, 20, moveresult->ideal_viewangles)) {
|
||||
|
@ -1530,7 +1530,7 @@ void BotClearPath(bot_state_t *bs, bot_moveresult_t *moveresult) {
|
|||
moveresult->flags |= MOVERESULT_MOVEMENTWEAPON | MOVERESULT_MOVEMENTVIEW;
|
||||
// if holding the right weapon
|
||||
if (bs->cur_ps.weapon == moveresult->weapon) {
|
||||
// if the bot is pretty close with it's aim
|
||||
// if the bot is pretty close with its aim
|
||||
// Q3Rally Code Start
|
||||
// if (InFieldOfVision(bs->viewangles, 20, moveresult->ideal_viewangles)) {
|
||||
if (InFieldOfVision(bs->cur_ps.viewangles, 20, moveresult->ideal_viewangles)) {
|
||||
|
@ -1623,7 +1623,7 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) {
|
|||
if (bs->cur_ps.weapon == bs->activatestack->weapon) {
|
||||
VectorSubtract(bs->activatestack->target, bs->eye, dir);
|
||||
vectoangles(dir, ideal_viewangles);
|
||||
// if the bot is pretty close with it's aim
|
||||
// if the bot is pretty close with its aim
|
||||
// Q3Rally Code Start
|
||||
// if (InFieldOfVision(bs->viewangles, 20, ideal_viewangles)) {
|
||||
if (InFieldOfVision(bs->cur_ps.viewangles, 20, ideal_viewangles)) {
|
||||
|
|
|
@ -685,7 +685,7 @@ void BotCTFSeekGoals(bot_state_t *bs) {
|
|||
if ( bs->lastgoal_ltgtype ) {
|
||||
bs->teamgoal_time += 60;
|
||||
}
|
||||
// if the bot decided to do something on it's own and has a last ordered goal
|
||||
// if the bot decided to do something on its own and has a last ordered goal
|
||||
if ( !bs->ordered && bs->lastgoal_ltgtype ) {
|
||||
bs->ltgtype = 0;
|
||||
}
|
||||
|
@ -931,7 +931,7 @@ void Bot1FCTFSeekGoals(bot_state_t *bs) {
|
|||
if ( bs->lastgoal_ltgtype ) {
|
||||
bs->teamgoal_time += 60;
|
||||
}
|
||||
// if the bot decided to do something on it's own and has a last ordered goal
|
||||
// if the bot decided to do something on its own and has a last ordered goal
|
||||
if ( !bs->ordered && bs->lastgoal_ltgtype ) {
|
||||
bs->ltgtype = 0;
|
||||
}
|
||||
|
@ -1503,7 +1503,8 @@ char *EasyClientName(int client, char *buf, int size) {
|
|||
char *str1, *str2, *ptr, c;
|
||||
char name[128];
|
||||
|
||||
strcpy(name, ClientName(client, name, sizeof(name)));
|
||||
ClientName(client, name, sizeof(name));
|
||||
|
||||
for (i = 0; name[i]; i++) name[i] &= 127;
|
||||
//remove all spaces
|
||||
for (ptr = strstr(name, " "); ptr; ptr = strstr(name, " ")) {
|
||||
|
@ -4603,7 +4604,7 @@ BotAIPredictObstacles
|
|||
|
||||
Predict the route towards the goal and check if the bot
|
||||
will be blocked by certain obstacles. When the bot has obstacles
|
||||
on it's path the bot should figure out if they can be removed
|
||||
on its path the bot should figure out if they can be removed
|
||||
by activating certain entities.
|
||||
==================
|
||||
*/
|
||||
|
|
|
@ -35,7 +35,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
void BotSetupDeathmatchAI(void);
|
||||
//shutdown the deathmatch AI
|
||||
void BotShutdownDeathmatchAI(void);
|
||||
//let the bot live within it's deathmatch AI net
|
||||
//let the bot live within its deathmatch AI net
|
||||
void BotDeathmatchAI(bot_state_t *bs, float thinktime);
|
||||
//free waypoints
|
||||
void BotFreeWaypoints(bot_waypoint_t *wp);
|
||||
|
|
|
@ -132,7 +132,7 @@ typedef struct bot_state_s
|
|||
playerState_t cur_ps; //current player state
|
||||
int last_eFlags; //last ps flags
|
||||
usercmd_t lastucmd; //usercmd from last frame
|
||||
int entityeventTime[1024]; //last entity event time
|
||||
int entityeventTime[MAX_GENTITIES]; //last entity event time
|
||||
//
|
||||
bot_settings_t settings; //several bot settings
|
||||
int (*ainode)(struct bot_state_s *bs); //current AI node
|
||||
|
@ -232,7 +232,7 @@ typedef struct bot_state_s
|
|||
int decisionmaker; //player who decided to go for this goal
|
||||
int ordered; //true if ordered to do something
|
||||
float order_time; //time ordered to do something
|
||||
int owndecision_time; //time the bot made it's own decision
|
||||
int owndecision_time; //time the bot made its own decision
|
||||
bot_goal_t teamgoal; //the team goal
|
||||
bot_goal_t altroutegoal; //alternative route goal
|
||||
float reachedaltroutegoal_time; //time the bot reached the alt route goal
|
||||
|
@ -294,7 +294,7 @@ extern float floattime;
|
|||
#define FloatTime() floattime
|
||||
|
||||
// from the game source
|
||||
void QDECL BotAI_Print(int type, char *fmt, ...);
|
||||
void QDECL BotAI_Print(int type, char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
|
||||
void QDECL QDECL BotAI_BotInitialChat( bot_state_t *bs, char *type, ... );
|
||||
void BotAI_Trace(bsp_trace_t *bsptrace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask);
|
||||
int BotAI_GetClientState( int clientNum, playerState_t *state );
|
||||
|
|
|
@ -48,14 +48,6 @@ static const char rcsid[] =
|
|||
static char* med3(char *, char *, char *, cmp_t *);
|
||||
static void swapfunc(char *, char *, int, int);
|
||||
|
||||
// STONELANCE - moved to header
|
||||
/*
|
||||
#ifndef min
|
||||
#define min(a, b) (a) < (b) ? a : b
|
||||
#endif
|
||||
*/
|
||||
// END
|
||||
|
||||
/*
|
||||
* Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
|
||||
*/
|
||||
|
@ -171,9 +163,9 @@ loop: SWAPINIT(a, es);
|
|||
}
|
||||
|
||||
pn = (char *)a + n * es;
|
||||
r = min(pa - (char *)a, pb - pa);
|
||||
r = MIN(pa - (char *)a, pb - pa);
|
||||
vecswap(a, pb - r, r);
|
||||
r = min(pd - pc, pn - pd - es);
|
||||
r = MIN(pd - pc, pn - pd - es);
|
||||
vecswap(pb, pn - r, r);
|
||||
if ((r = pb - pa) > es)
|
||||
qsort(a, r / es, es, cmp);
|
||||
|
@ -241,7 +233,29 @@ char *strchr( const char *string, int c ) {
|
|||
}
|
||||
string++;
|
||||
}
|
||||
return (char *)0;
|
||||
|
||||
if(c)
|
||||
return NULL;
|
||||
else
|
||||
return (char *) string;
|
||||
}
|
||||
|
||||
char *strrchr(const char *string, int c)
|
||||
{
|
||||
const char *found = NULL;
|
||||
|
||||
while(*string)
|
||||
{
|
||||
if(*string == c)
|
||||
found = string;
|
||||
|
||||
string++;
|
||||
}
|
||||
|
||||
if(c)
|
||||
return (char *) found;
|
||||
else
|
||||
return (char *) string;
|
||||
}
|
||||
|
||||
char *strstr( const char *string, const char *strCharSet ) {
|
||||
|
@ -276,21 +290,33 @@ int toupper( int c ) {
|
|||
return c;
|
||||
}
|
||||
|
||||
void *memmove( void *dest, const void *src, size_t count ) {
|
||||
int i;
|
||||
void *memmove(void *dest, const void *src, size_t count)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if ( dest > src ) {
|
||||
for ( i = count-1 ; i >= 0 ; i-- ) {
|
||||
((char *)dest)[i] = ((char *)src)[i];
|
||||
if(count)
|
||||
{
|
||||
if(dest > src)
|
||||
{
|
||||
i = count;
|
||||
|
||||
do
|
||||
{
|
||||
i--;
|
||||
((char *) dest)[i] = ((char *) src)[i];
|
||||
} while(i > 0);
|
||||
}
|
||||
} else {
|
||||
for ( i = 0 ; i < count ; i++ ) {
|
||||
((char *)dest)[i] = ((char *)src)[i];
|
||||
else
|
||||
{
|
||||
for(i = 0; i < count; i++)
|
||||
((char *) dest)[i] = ((char *) src)[i];
|
||||
}
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
double floor( double x ) {
|
||||
|
@ -487,10 +513,7 @@ double sin( double x ) {
|
|||
int index;
|
||||
int quad;
|
||||
|
||||
// STONELANCE
|
||||
// index = 1024 * x / (M_PI * 0.5);
|
||||
index = 1024 * x / (M_PI_2);
|
||||
// END
|
||||
index = 1024 * x / (M_PI * 0.5);
|
||||
quad = ( index >> 10 ) & 3;
|
||||
index &= 1023;
|
||||
switch ( quad ) {
|
||||
|
@ -511,10 +534,7 @@ double cos( double x ) {
|
|||
int index;
|
||||
int quad;
|
||||
|
||||
// STONELANCE
|
||||
// index = 1024 * x / (M_PI * 0.5);
|
||||
index = 1024 * x / (M_PI_2);
|
||||
// END
|
||||
index = 1024 * x / (M_PI * 0.5);
|
||||
quad = ( index >> 10 ) & 3;
|
||||
index &= 1023;
|
||||
switch ( quad ) {
|
||||
|
@ -754,6 +774,7 @@ double atan2( double y, double x ) {
|
|||
return base + dir * i * ( M_PI/2048);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
double tan( double x ) {
|
||||
|
@ -1093,7 +1114,7 @@ The variable pointed to by endptr will hold the location of the first character
|
|||
in the nptr string that was not used in the conversion
|
||||
==============
|
||||
*/
|
||||
double strtod( const char *nptr, const char **endptr )
|
||||
double strtod( const char *nptr, char **endptr )
|
||||
{
|
||||
double res;
|
||||
qboolean neg = qfalse;
|
||||
|
@ -1106,12 +1127,10 @@ double strtod( const char *nptr, const char **endptr )
|
|||
if( Q_stricmpn( nptr, "nan", 3 ) == 0 )
|
||||
{
|
||||
floatint_t nan;
|
||||
if( endptr == NULL )
|
||||
{
|
||||
nan.ui = 0x7fffffff;
|
||||
return nan.f;
|
||||
}
|
||||
*endptr = &nptr[3];
|
||||
|
||||
if( endptr )
|
||||
*endptr = (char *)&nptr[3];
|
||||
|
||||
// nan can be followed by a bracketed number (in hex, octal,
|
||||
// or decimal) which is then put in the mantissa
|
||||
// this can be used to generate signalling or quiet NaNs, for
|
||||
|
@ -1119,7 +1138,7 @@ double strtod( const char *nptr, const char **endptr )
|
|||
// note that nan(0) is infinity!
|
||||
if( nptr[3] == '(' )
|
||||
{
|
||||
const char *end;
|
||||
char *end;
|
||||
int mantissa = strtol( &nptr[4], &end, 0 );
|
||||
if( *end == ')' )
|
||||
{
|
||||
|
@ -1139,9 +1158,9 @@ double strtod( const char *nptr, const char **endptr )
|
|||
if( endptr == NULL )
|
||||
return inf.f;
|
||||
if( Q_stricmpn( &nptr[3], "inity", 5 ) == 0 )
|
||||
*endptr = &nptr[8];
|
||||
*endptr = (char *)&nptr[8];
|
||||
else
|
||||
*endptr = &nptr[3];
|
||||
*endptr = (char *)&nptr[3];
|
||||
return inf.f;
|
||||
}
|
||||
|
||||
|
@ -1207,12 +1226,12 @@ double strtod( const char *nptr, const char **endptr )
|
|||
float res2;
|
||||
// apparently (confusingly) the exponent should be
|
||||
// decimal
|
||||
exp = strtol( &nptr[1], &end, 10 );
|
||||
exp = strtol( &nptr[1], (char **)&end, 10 );
|
||||
if( &nptr[1] == end )
|
||||
{
|
||||
// no exponent
|
||||
if( endptr )
|
||||
*endptr = nptr;
|
||||
*endptr = (char *)nptr;
|
||||
return res;
|
||||
}
|
||||
if( exp > 0 )
|
||||
|
@ -1239,7 +1258,7 @@ double strtod( const char *nptr, const char **endptr )
|
|||
}
|
||||
}
|
||||
if( endptr )
|
||||
*endptr = end;
|
||||
*endptr = (char *)end;
|
||||
return res;
|
||||
}
|
||||
// decimal
|
||||
|
@ -1271,12 +1290,12 @@ double strtod( const char *nptr, const char **endptr )
|
|||
{
|
||||
int exp;
|
||||
float res10;
|
||||
exp = strtol( &nptr[1], &end, 10 );
|
||||
exp = strtol( &nptr[1], (char **)&end, 10 );
|
||||
if( &nptr[1] == end )
|
||||
{
|
||||
// no exponent
|
||||
if( endptr )
|
||||
*endptr = nptr;
|
||||
*endptr = (char *)nptr;
|
||||
return res;
|
||||
}
|
||||
if( exp > 0 )
|
||||
|
@ -1305,7 +1324,7 @@ double strtod( const char *nptr, const char **endptr )
|
|||
}
|
||||
}
|
||||
if( endptr )
|
||||
*endptr = end;
|
||||
*endptr = (char *)end;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
@ -1415,13 +1434,13 @@ Will not overflow - returns LONG_MIN or LONG_MAX as appropriate
|
|||
*endptr is set to the location of the first character not used
|
||||
==============
|
||||
*/
|
||||
long strtol( const char *nptr, const char **endptr, int base )
|
||||
long strtol( const char *nptr, char **endptr, int base )
|
||||
{
|
||||
long res;
|
||||
qboolean pos = qtrue;
|
||||
|
||||
if( endptr )
|
||||
*endptr = nptr;
|
||||
*endptr = (char *)nptr;
|
||||
// bases other than 0, 2, 8, 16 are very rarely used, but they're
|
||||
// not much extra effort to support
|
||||
if( base < 0 || base == 1 || base > 36 )
|
||||
|
@ -1443,14 +1462,14 @@ long strtol( const char *nptr, const char **endptr, int base )
|
|||
nptr++;
|
||||
// 0 is always a valid digit
|
||||
if( endptr )
|
||||
*endptr = nptr;
|
||||
*endptr = (char *)nptr;
|
||||
if( *nptr == 'x' || *nptr == 'X' )
|
||||
{
|
||||
if( base != 0 && base != 16 )
|
||||
{
|
||||
// can't be hex, reject x (accept 0)
|
||||
if( endptr )
|
||||
*endptr = nptr;
|
||||
*endptr = (char *)nptr;
|
||||
return 0;
|
||||
}
|
||||
nptr++;
|
||||
|
@ -1483,7 +1502,7 @@ long strtol( const char *nptr, const char **endptr, int base )
|
|||
res = res * base - val;
|
||||
nptr++;
|
||||
if( endptr )
|
||||
*endptr = nptr;
|
||||
*endptr = (char *)nptr;
|
||||
}
|
||||
if( pos )
|
||||
{
|
||||
|
@ -1636,8 +1655,6 @@ static int dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
|
|||
#define DP_C_LDOUBLE 4
|
||||
|
||||
#define char_to_int(p) (p - '0')
|
||||
#define MAX(p,q) ((p >= q) ? p : q)
|
||||
#define MIN(p,q) ((p <= q) ? p : q)
|
||||
|
||||
static int dopr (char *buffer, size_t maxlen, const char *format, va_list args)
|
||||
{
|
||||
|
@ -1920,13 +1937,8 @@ static int dopr (char *buffer, size_t maxlen, const char *format, va_list args)
|
|||
break; /* some picky compilers need this */
|
||||
}
|
||||
}
|
||||
if (buffer != NULL)
|
||||
{
|
||||
if (currlen < maxlen - 1)
|
||||
buffer[currlen] = '\0';
|
||||
else
|
||||
buffer[maxlen - 1] = '\0';
|
||||
}
|
||||
if (maxlen > 0)
|
||||
buffer[currlen] = '\0';
|
||||
return total;
|
||||
}
|
||||
|
||||
|
@ -2249,23 +2261,9 @@ static int dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
|
|||
|
||||
int Q_vsnprintf(char *str, size_t length, const char *fmt, va_list args)
|
||||
{
|
||||
if (str != NULL)
|
||||
str[0] = 0;
|
||||
return dopr(str, length, fmt, args);
|
||||
}
|
||||
|
||||
int Q_snprintf(char *str, size_t length, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int retval;
|
||||
|
||||
va_start(ap, fmt);
|
||||
retval = Q_vsnprintf(str, length, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* this is really crappy */
|
||||
int sscanf( const char *buffer, const char *fmt, ... ) {
|
||||
int cmd;
|
||||
|
@ -2320,4 +2318,3 @@ int sscanf( const char *buffer, const char *fmt, ... ) {
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
typedef int size_t;
|
||||
typedef unsigned int size_t;
|
||||
|
||||
typedef char * va_list;
|
||||
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
|
||||
|
@ -89,6 +89,7 @@ char *strcat( char *strDestination, const char *strSource );
|
|||
char *strcpy( char *strDestination, const char *strSource );
|
||||
int strcmp( const char *string1, const char *string2 );
|
||||
char *strchr( const char *string, int c );
|
||||
char *strrchr(const char *string, int c);
|
||||
char *strstr( const char *string, const char *strCharSet );
|
||||
char *strncpy( char *strDest, const char *strSource, size_t count );
|
||||
int tolower( int c );
|
||||
|
@ -96,13 +97,12 @@ int toupper( int c );
|
|||
|
||||
double atof( const char *string );
|
||||
double _atof( const char **stringPtr );
|
||||
double strtod( const char *nptr, const char **endptr );
|
||||
double strtod( const char *nptr, char **endptr );
|
||||
int atoi( const char *string );
|
||||
int _atoi( const char **stringPtr );
|
||||
long strtol( const char *nptr, const char **endptr, int base );
|
||||
long strtol( const char *nptr, char **endptr, int base );
|
||||
|
||||
int Q_vsnprintf( char *buffer, size_t length, const char *fmt, va_list argptr );
|
||||
int Q_snprintf( char *buffer, size_t length, const char *fmt, ... ) __attribute__ ((format (printf, 3, 4)));
|
||||
|
||||
int sscanf( const char *buffer, const char *fmt, ... ) __attribute__ ((format (scanf, 2, 3)));
|
||||
|
||||
|
|
|
@ -65,7 +65,6 @@ extern pml_t pml;
|
|||
extern float pm_stopspeed;
|
||||
extern float pm_duckScale;
|
||||
extern float pm_swimScale;
|
||||
extern float pm_wadeScale;
|
||||
|
||||
extern float pm_accelerate;
|
||||
extern float pm_airaccelerate;
|
||||
|
|
|
@ -1156,7 +1156,7 @@ Only in One Flag CTF games
|
|||
{NULL}
|
||||
};
|
||||
|
||||
int bg_numItems = sizeof(bg_itemlist) / sizeof(bg_itemlist[0]) - 1;
|
||||
int bg_numItems = ARRAY_LEN( bg_itemlist ) - 1;
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -35,7 +35,6 @@ pml_t pml;
|
|||
float pm_stopspeed = 100.0f;
|
||||
float pm_duckScale = 0.25f;
|
||||
float pm_swimScale = 0.50f;
|
||||
float pm_wadeScale = 0.70f;
|
||||
|
||||
float pm_accelerate = 10.0f;
|
||||
float pm_airaccelerate = 1.0f;
|
||||
|
|
|
@ -130,6 +130,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#define CHARACTERISTIC_EASY_FRAGGER 45 //float [0, 1]
|
||||
//how alert the bot is (view distance)
|
||||
#define CHARACTERISTIC_ALERTNESS 46 //float [0, 1]
|
||||
//how much the bot fires it's weapon
|
||||
//how much the bot fires its weapon
|
||||
#define CHARACTERISTIC_FIRETHROTTLE 47 //float [0, 1]
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ Com_LogPrintf
|
|||
Print to the logfile
|
||||
=================
|
||||
*/
|
||||
void QDECL Com_LogPrintf( const char *fmt, ... ) {
|
||||
static __attribute__ ((format (printf, 1, 2))) void QDECL Com_LogPrintf( const char *fmt, ... ) {
|
||||
va_list argptr;
|
||||
char string[1024];
|
||||
fileHandle_t logFile;
|
||||
|
@ -685,7 +685,7 @@ void ClientTimerActions( gentity_t *ent, int msec ) {
|
|||
if( bg_itemlist[client->ps.stats[STAT_PERSISTANT_POWERUP]].giTag == PW_AMMOREGEN ) {
|
||||
int w, max, inc, t, i;
|
||||
int weapList[]={WP_MACHINEGUN,WP_SHOTGUN,WP_GRENADE_LAUNCHER,WP_ROCKET_LAUNCHER,WP_LIGHTNING,WP_RAILGUN,WP_PLASMAGUN,WP_BFG,WP_NAILGUN,WP_PROX_LAUNCHER,WP_CHAINGUN,WP_FLAME_THROWER};
|
||||
int weapCount = sizeof(weapList) / sizeof(int);
|
||||
int weapCount = ARRAY_LEN( weapList );
|
||||
//
|
||||
for (i = 0; i < weapCount; i++) {
|
||||
w = weapList[i];
|
||||
|
|
|
@ -218,7 +218,7 @@ static void PlayerIntroSound( const char *modelAndSkin ) {
|
|||
char *skin;
|
||||
|
||||
Q_strncpyz( model, modelAndSkin, sizeof(model) );
|
||||
skin = Q_strrchr( model, '/' );
|
||||
skin = strrchr( model, '/' );
|
||||
if ( skin ) {
|
||||
*skin++ = '\0';
|
||||
}
|
||||
|
|
|
@ -787,7 +787,7 @@ Forces a client's skin (for teamplay)
|
|||
static void ForceClientSkin( gclient_t *client, char *model, const char *skin ) {
|
||||
char *p;
|
||||
|
||||
if ((p = Q_strrchr(model, '/')) != 0) {
|
||||
if ((p = strrchr(model, '/')) != 0) {
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ void DeathmatchScoreboardMessage( gentity_t *ent ) {
|
|||
// END
|
||||
|
||||
j = strlen(entry);
|
||||
if (stringlength + j > 1024)
|
||||
if (stringlength + j >= sizeof(string))
|
||||
break;
|
||||
strcpy (string + stringlength, entry);
|
||||
stringlength += j;
|
||||
|
@ -461,31 +461,34 @@ and sends over a command to the client to resize the view,
|
|||
hide the scoreboard, and take a special screenshot
|
||||
==================
|
||||
*/
|
||||
void Cmd_LevelShot_f( gentity_t *ent ) {
|
||||
if ( !CheatsOk( ent ) ) {
|
||||
void Cmd_LevelShot_f(gentity_t *ent)
|
||||
{
|
||||
if(!ent->client->pers.localClient)
|
||||
{
|
||||
trap_SendServerCommand(ent-g_entities,
|
||||
"print \"The levelshot command must be executed by a local client\n\"");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!CheatsOk(ent))
|
||||
return;
|
||||
|
||||
// doesn't work in single player
|
||||
if ( g_gametype.integer != 0 ) {
|
||||
trap_SendServerCommand( ent-g_entities,
|
||||
"print \"Must be in g_gametype 0 for levelshot\n\"" );
|
||||
if(g_gametype.integer == GT_SINGLE_PLAYER)
|
||||
{
|
||||
trap_SendServerCommand(ent-g_entities,
|
||||
"print \"Must not be in singleplayer mode for levelshot\n\"" );
|
||||
return;
|
||||
}
|
||||
|
||||
BeginIntermission();
|
||||
trap_SendServerCommand( ent-g_entities, "clientLevelShot" );
|
||||
trap_SendServerCommand(ent-g_entities, "clientLevelShot");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
Cmd_LevelShot_f
|
||||
|
||||
This is just to help generate the level pictures
|
||||
for the menus. It goes to the intermission immediately
|
||||
and sends over a command to the client to resize the view,
|
||||
hide the scoreboard, and take a special screenshot
|
||||
Cmd_TeamTask_f
|
||||
==================
|
||||
*/
|
||||
void Cmd_TeamTask_f( gentity_t *ent ) {
|
||||
|
@ -507,7 +510,6 @@ void Cmd_TeamTask_f( gentity_t *ent ) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
Cmd_Kill_f
|
||||
|
@ -745,10 +747,10 @@ void SetTeam( gentity_t *ent, char *s ) {
|
|||
player_die (ent, ent, ent, 100000, MOD_SUICIDE);
|
||||
|
||||
}
|
||||
|
||||
// they go to the end of the line for tournements
|
||||
if ( team == TEAM_SPECTATOR ) {
|
||||
client->sess.spectatorTime = level.time;
|
||||
}
|
||||
if(team == TEAM_SPECTATOR && oldTeam != team)
|
||||
AddTournamentQueue(client);
|
||||
|
||||
client->sess.sessionTeam = team;
|
||||
client->sess.spectatorState = specState;
|
||||
|
@ -1384,7 +1386,7 @@ void Cmd_GameCommand_f( gentity_t *ent ) {
|
|||
if ( player < 0 || player >= MAX_CLIENTS ) {
|
||||
return;
|
||||
}
|
||||
if ( order < 0 || order > sizeof(gc_orders)/sizeof(char *) ) {
|
||||
if ( order < 0 || order > ARRAY_LEN( gc_orders ) ) {
|
||||
return;
|
||||
}
|
||||
G_Say( ent, &g_entities[player], SAY_TELL, gc_orders[order] );
|
||||
|
|
|
@ -551,7 +551,7 @@ void player_die( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int
|
|||
killerName = "<world>";
|
||||
}
|
||||
|
||||
if ( meansOfDeath < 0 || meansOfDeath >= sizeof( modNames ) / sizeof( modNames[0] ) ) {
|
||||
if ( meansOfDeath < 0 || meansOfDeath >= ARRAY_LEN( modNames ) ) {
|
||||
obit = "<bad obituary>";
|
||||
} else {
|
||||
obit = modNames[ meansOfDeath ];
|
||||
|
|
|
@ -296,7 +296,7 @@ typedef struct {
|
|||
// MUST be dealt with in G_InitSessionData() / G_ReadSessionData() / G_WriteSessionData()
|
||||
typedef struct {
|
||||
team_t sessionTeam;
|
||||
int spectatorTime; // for determining next-in-line to play
|
||||
int spectatorNum; // for determining next-in-line to play
|
||||
spectatorState_t spectatorState;
|
||||
// STOENLANCE
|
||||
qboolean spectatorWilling; // for determining if the spectator should remain
|
||||
|
@ -430,7 +430,7 @@ typedef struct {
|
|||
|
||||
struct gentity_s *gentities;
|
||||
int gentitySize;
|
||||
int num_entities; // current number, <= MAX_GENTITIES
|
||||
int num_entities; // MAX_CLIENTS <= num_entities <= ENTITYNUM_MAX_NORMAL
|
||||
|
||||
int warmupTime; // restart match at this time
|
||||
|
||||
|
@ -609,6 +609,8 @@ void G_SetOrigin( gentity_t *ent, vec3_t origin );
|
|||
void AddRemap(const char *oldShader, const char *newShader, float timeOffset);
|
||||
const char *BuildShaderStateConfig( void );
|
||||
|
||||
int PickDebrisType( int spawnflags );
|
||||
|
||||
//
|
||||
// g_combat.c
|
||||
//
|
||||
|
@ -673,6 +675,7 @@ gentity_t *fire_prox( gentity_t *self, vec3_t start, vec3_t aimdir );
|
|||
//
|
||||
void G_RunMover( gentity_t *ent );
|
||||
void Touch_DoorTrigger( gentity_t *ent, gentity_t *other, trace_t *trace );
|
||||
void Break_Breakable(gentity_t *ent, gentity_t *other);
|
||||
|
||||
//
|
||||
// g_trigger.c
|
||||
|
@ -830,13 +833,14 @@ void FindIntermissionPoint( void );
|
|||
void SetLeader(int team, int client);
|
||||
void CheckTeamLeader( int team );
|
||||
void G_RunThink (gentity_t *ent);
|
||||
void QDECL G_LogPrintf( const char *fmt, ... );
|
||||
void AddTournamentQueue(gclient_t *client);
|
||||
void QDECL G_LogPrintf( const char *fmt, ... ) __attribute__ ((format (printf, 1, 2)));
|
||||
// STONELANCE
|
||||
void QDECL G_DebugLogPrintf( const char *fmt, ... );
|
||||
void QDECL G_DebugLogPrintf( const char *fmt, ... ) __attribute__ ((format (printf, 1, 2)));
|
||||
// END
|
||||
void SendScoreboardMessageToAllClients( void );
|
||||
void QDECL G_Printf( const char *fmt, ... );
|
||||
void QDECL G_Error( const char *fmt, ... );
|
||||
void QDECL G_Printf( const char *fmt, ... ) __attribute__ ((format (printf, 1, 2)));
|
||||
void QDECL G_Error( const char *fmt, ... ) __attribute__ ((format (printf, 1, 2)));
|
||||
|
||||
//
|
||||
// g_client.c
|
||||
|
|
|
@ -167,7 +167,7 @@ static cvarTable_t gameCvarTable[] = {
|
|||
{ &g_teamForceBalance, "g_teamForceBalance", "0", CVAR_ARCHIVE },
|
||||
|
||||
{ &g_warmup, "g_warmup", "20", CVAR_ARCHIVE, 0, qtrue },
|
||||
{ &g_doWarmup, "g_doWarmup", "0", 0, 0, qtrue },
|
||||
{ &g_doWarmup, "g_doWarmup", "0", CVAR_ARCHIVE, 0, qtrue },
|
||||
{ &g_log, "g_log", "games.log", CVAR_ARCHIVE, 0, qfalse },
|
||||
{ &g_logSync, "g_logSync", "0", CVAR_ARCHIVE, 0, qfalse },
|
||||
|
||||
|
@ -262,8 +262,7 @@ static cvarTable_t gameCvarTable[] = {
|
|||
|
||||
};
|
||||
|
||||
// bk001129 - made static to avoid aliasing
|
||||
static int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[0] );
|
||||
static int gameCvarTableSize = ARRAY_LEN( gameCvarTable );
|
||||
|
||||
|
||||
void G_InitGame( int levelTime, int randomSeed, int restart );
|
||||
|
@ -589,6 +588,10 @@ void G_InitGame( int levelTime, int randomSeed, int restart ) {
|
|||
// range are NEVER anything but clients
|
||||
level.num_entities = MAX_CLIENTS;
|
||||
|
||||
for ( i=0 ; i<MAX_CLIENTS ; i++ ) {
|
||||
g_entities[i].classname = "clientslot";
|
||||
}
|
||||
|
||||
// let the server system know where the entites are
|
||||
trap_LocateGameData( level.gentities, level.num_entities, sizeof( gentity_t ),
|
||||
&level.clients[0].ps, sizeof( level.clients[0] ) );
|
||||
|
@ -663,6 +666,7 @@ void G_ShutdownGame( int restart ) {
|
|||
G_LogPrintf("ShutdownGame:\n" );
|
||||
G_LogPrintf("------------------------------------------------------------\n" );
|
||||
trap_FS_FCloseFile( level.logFile );
|
||||
level.logFile = 0;
|
||||
}
|
||||
|
||||
// write all the client session data so we can get it back
|
||||
|
@ -750,9 +754,8 @@ void AddTournamentPlayer( void ) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if ( !nextInLine || client->sess.spectatorTime < nextInLine->sess.spectatorTime ) {
|
||||
if(!nextInLine || client->sess.spectatorNum > nextInLine->sess.spectatorNum)
|
||||
nextInLine = client;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !nextInLine ) {
|
||||
|
@ -765,6 +768,33 @@ void AddTournamentPlayer( void ) {
|
|||
SetTeam( &g_entities[ nextInLine - level.clients ], "f" );
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
AddTournamentQueue
|
||||
|
||||
Add client to end of tournament queue
|
||||
=======================
|
||||
*/
|
||||
|
||||
void AddTournamentQueue(gclient_t *client)
|
||||
{
|
||||
int index;
|
||||
gclient_t *curclient;
|
||||
|
||||
for(index = 0; index < level.maxclients; index++)
|
||||
{
|
||||
curclient = &level.clients[index];
|
||||
|
||||
if(curclient->pers.connected != CON_DISCONNECTED)
|
||||
{
|
||||
if(curclient == client)
|
||||
curclient->sess.spectatorNum = 0;
|
||||
else if(curclient->sess.sessionTeam == TEAM_SPECTATOR)
|
||||
curclient->sess.spectatorNum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
RemoveTournamentLoser
|
||||
|
@ -870,10 +900,10 @@ int QDECL SortRanks( const void *a, const void *b ) {
|
|||
|
||||
// then spectators
|
||||
if ( ca->sess.sessionTeam == TEAM_SPECTATOR && cb->sess.sessionTeam == TEAM_SPECTATOR ) {
|
||||
if ( ca->sess.spectatorTime < cb->sess.spectatorTime ) {
|
||||
if ( ca->sess.spectatorNum > cb->sess.spectatorNum ) {
|
||||
return -1;
|
||||
}
|
||||
if ( ca->sess.spectatorTime > cb->sess.spectatorTime ) {
|
||||
if ( ca->sess.spectatorNum < cb->sess.spectatorNum ) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -971,9 +1001,10 @@ void CalculateRanks( void ) {
|
|||
level.numNonSpectatorClients = 0;
|
||||
level.numPlayingClients = 0;
|
||||
humanplayers = 0; //level.numVotingClients = 0; // don't count bots
|
||||
for ( i = 0; i < TEAM_NUM_TEAMS; i++ ) {
|
||||
|
||||
for (i = 0; i < ARRAY_LEN(level.numteamVotingClients); i++)
|
||||
level.numteamVotingClients[i] = 0;
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < level.maxclients ; i++ ) {
|
||||
if ( level.clients[i].pers.connected != CON_DISCONNECTED ) {
|
||||
level.sortedClients[level.numConnectedClients] = i;
|
||||
|
@ -1321,7 +1352,7 @@ void QDECL G_LogPrintf( const char *fmt, ... ) {
|
|||
char string[1024];
|
||||
int min, tens, sec;
|
||||
|
||||
sec = level.time / 1000;
|
||||
sec = ( level.time - level.startTime ) / 1000;
|
||||
|
||||
min = sec / 60;
|
||||
sec -= min * 60;
|
||||
|
|
|
@ -125,6 +125,7 @@ void G_BounceMissile( gentity_t *ent, trace_t *trace ) {
|
|||
// check for stop
|
||||
if ( trace->plane.normal[2] > 0.2 && VectorLength( ent->s.pos.trDelta ) < 40 ) {
|
||||
G_SetOrigin( ent, trace->endpos );
|
||||
ent->s.time = level.time / 4;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -343,7 +343,7 @@ qboolean G_MoverPush( gentity_t *pusher, vec3_t move, vec3_t amove, gentity_t **
|
|||
|
||||
listedEntities = trap_EntitiesInBox( totalMins, totalMaxs, entityList, MAX_GENTITIES );
|
||||
|
||||
// move the pusher to it's final position
|
||||
// move the pusher to its final position
|
||||
VectorAdd( pusher->r.currentOrigin, move, pusher->r.currentOrigin );
|
||||
VectorAdd( pusher->r.currentAngles, amove, pusher->r.currentAngles );
|
||||
trap_LinkEntity( pusher );
|
||||
|
@ -1548,7 +1548,7 @@ void Touch_Button(gentity_t *ent, gentity_t *other, trace_t *trace ) {
|
|||
|
||||
|
||||
/*QUAKED func_button (0 .5 .8) ?
|
||||
When a button is touched, it moves some distance in the direction of it's angle, triggers all of it's targets, waits some time, then returns to it's original position where it can be triggered again.
|
||||
When a button is touched, it moves some distance in the direction of its angle, triggers all of its targets, waits some time, then returns to its original position where it can be triggered again.
|
||||
|
||||
"model2" .md3 model to also draw
|
||||
"angle" determines the opening direction
|
||||
|
@ -1708,7 +1708,7 @@ void Think_SetupTrainTargets( gentity_t *ent ) {
|
|||
if ( !strcmp( ent->classname, "func_train" ) )
|
||||
G_Printf( "func_train at %s with an unfound target\n", vtos(ent->r.absmin) );
|
||||
else //path_corner
|
||||
G_Printf( "Train corner at %s without a target\n", ent->s.origin );
|
||||
G_Printf( "Train corner at %s without a target\n", vtos(ent->s.origin) );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1858,12 +1858,12 @@ void Break_Breakable(gentity_t *ent, gentity_t *other) {
|
|||
int count = 0;
|
||||
int spawnflags = 0;
|
||||
gentity_t *tmp;
|
||||
int type = EV_EMIT_DEBRIS_LIGHT;
|
||||
//int type = EV_EMIT_DEBRIS_LIGHT;
|
||||
|
||||
// Get the center of the glass (code donated by Perle)
|
||||
VectorSubtract(ent->r.maxs, ent->r.mins, size);
|
||||
VectorScale(size, 0.5, size);
|
||||
VectorAdd(ent->r.mins, size, center);
|
||||
VectorScale(size, 0.5, size);
|
||||
VectorAdd(ent->r.mins, size, center);
|
||||
|
||||
|
||||
ent->takedamage = qfalse;
|
||||
|
|
|
@ -55,7 +55,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
|
||||
typedef struct {
|
||||
entityState_t s; // communicated by server to clients
|
||||
entityState_t unused; // apparently this field was put here accidentally
|
||||
// (and is kept only for compatibility, as a struct pad)
|
||||
|
||||
qboolean linked; // qfalse if not in any good cluster
|
||||
int linkcount;
|
||||
|
@ -84,8 +85,8 @@ typedef struct {
|
|||
// when a trace call is made and passEntityNum != ENTITYNUM_NONE,
|
||||
// an ent will be excluded from testing if:
|
||||
// ent->s.number == passEntityNum (don't interact with self)
|
||||
// ent->s.ownerNum = passEntityNum (don't interact with your own missiles)
|
||||
// entity[ent->s.ownerNum].ownerNum = passEntityNum (don't interact with other missiles from owner)
|
||||
// ent->r.ownerNum == passEntityNum (don't interact with your own missiles)
|
||||
// entity[ent->r.ownerNum].r.ownerNum == passEntityNum (don't interact with other missiles from owner)
|
||||
int ownerNum;
|
||||
} entityShared_t;
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ void G_WriteClientSessionData( gclient_t *client ) {
|
|||
|
||||
s = va("%i %i %i %i %i %i %i",
|
||||
client->sess.sessionTeam,
|
||||
client->sess.spectatorTime,
|
||||
client->sess.spectatorNum,
|
||||
client->sess.spectatorState,
|
||||
client->sess.spectatorClient,
|
||||
client->sess.wins,
|
||||
|
@ -79,7 +79,7 @@ void G_ReadSessionData( gclient_t *client ) {
|
|||
|
||||
sscanf( s, "%i %i %i %i %i %i %i",
|
||||
&sessionTeam,
|
||||
&client->sess.spectatorTime,
|
||||
&client->sess.spectatorNum,
|
||||
&spectatorState,
|
||||
&client->sess.spectatorClient,
|
||||
&client->sess.wins,
|
||||
|
@ -188,7 +188,7 @@ void G_InitSessionData( gclient_t *client, char *userinfo ) {
|
|||
}
|
||||
|
||||
sess->spectatorState = SPECTATOR_FREE;
|
||||
sess->spectatorTime = level.time;
|
||||
AddTournamentQueue(client);
|
||||
|
||||
G_WriteClientSessionData( client );
|
||||
}
|
||||
|
|
|
@ -76,55 +76,49 @@ qboolean G_SpawnVector( const char *key, const char *defaultString, float *out )
|
|||
// fields are needed for spawning from the entity string
|
||||
//
|
||||
typedef enum {
|
||||
F_INT,
|
||||
F_INT,
|
||||
F_FLOAT,
|
||||
F_LSTRING, // string on disk, pointer in memory, TAG_LEVEL
|
||||
F_GSTRING, // string on disk, pointer in memory, TAG_GAME
|
||||
F_STRING,
|
||||
F_VECTOR,
|
||||
F_ANGLEHACK,
|
||||
F_ENTITY, // index on disk, pointer in memory
|
||||
F_ITEM, // index on disk, pointer in memory
|
||||
F_CLIENT, // index on disk, pointer in memory
|
||||
F_IGNORE
|
||||
F_ANGLEHACK
|
||||
} fieldtype_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
int ofs;
|
||||
size_t ofs;
|
||||
fieldtype_t type;
|
||||
int flags;
|
||||
} field_t;
|
||||
|
||||
field_t fields[] = {
|
||||
{"classname", FOFS(classname), F_LSTRING},
|
||||
{"classname", FOFS(classname), F_STRING},
|
||||
{"origin", FOFS(s.origin), F_VECTOR},
|
||||
{"model", FOFS(model), F_LSTRING},
|
||||
{"model2", FOFS(model2), F_LSTRING},
|
||||
{"model", FOFS(model), F_STRING},
|
||||
{"model2", FOFS(model2), F_STRING},
|
||||
{"spawnflags", FOFS(spawnflags), F_INT},
|
||||
{"speed", FOFS(speed), F_FLOAT},
|
||||
{"target", FOFS(target), F_LSTRING},
|
||||
{"targetname", FOFS(targetname), F_LSTRING},
|
||||
{"message", FOFS(message), F_LSTRING},
|
||||
{"team", FOFS(team), F_LSTRING},
|
||||
{"target", FOFS(target), F_STRING},
|
||||
{"targetname", FOFS(targetname), F_STRING},
|
||||
{"message", FOFS(message), F_STRING},
|
||||
{"team", FOFS(team), F_STRING},
|
||||
{"wait", FOFS(wait), F_FLOAT},
|
||||
{"random", FOFS(random), F_FLOAT},
|
||||
{"count", FOFS(count), F_INT},
|
||||
{"health", FOFS(health), F_INT},
|
||||
{"light", 0, F_IGNORE},
|
||||
{"dmg", FOFS(damage), F_INT},
|
||||
{"angles", FOFS(s.angles), F_VECTOR},
|
||||
{"angle", FOFS(s.angles), F_ANGLEHACK},
|
||||
{"targetShaderName", FOFS(targetShaderName), F_LSTRING},
|
||||
{"targetShaderNewName", FOFS(targetShaderNewName), F_LSTRING},
|
||||
{"targetShaderName", FOFS(targetShaderName), F_STRING},
|
||||
{"targetShaderNewName", FOFS(targetShaderNewName), F_STRING},
|
||||
// STONELANCE
|
||||
{"number", FOFS(number), F_INT},
|
||||
{"laps", FOFS(laps), F_INT},
|
||||
{"script", FOFS(script), F_LSTRING},
|
||||
{"script", FOFS(script), F_STRING},
|
||||
{"bezierPos", FOFS(s.origin2), F_VECTOR},
|
||||
{"bezierDir", FOFS(s.angles2), F_VECTOR},
|
||||
// END
|
||||
{"distance", FOFS(distance), F_FLOAT}, // Rotating Doors
|
||||
{"distance", FOFS(distance), F_FLOAT}, // Rotating Doors
|
||||
|
||||
{NULL}
|
||||
};
|
||||
|
@ -138,10 +132,6 @@ typedef struct {
|
|||
void SP_info_player_start (gentity_t *ent);
|
||||
void SP_info_player_deathmatch (gentity_t *ent);
|
||||
void SP_info_player_intermission (gentity_t *ent);
|
||||
void SP_info_firstplace(gentity_t *ent);
|
||||
void SP_info_secondplace(gentity_t *ent);
|
||||
void SP_info_thirdplace(gentity_t *ent);
|
||||
void SP_info_podium(gentity_t *ent);
|
||||
|
||||
void SP_func_plat (gentity_t *ent);
|
||||
void SP_func_static (gentity_t *ent);
|
||||
|
@ -167,7 +157,6 @@ void SP_target_delay (gentity_t *ent);
|
|||
void SP_target_speaker (gentity_t *ent);
|
||||
void SP_target_print (gentity_t *ent);
|
||||
void SP_target_laser (gentity_t *self);
|
||||
void SP_target_character (gentity_t *ent);
|
||||
void SP_target_score( gentity_t *ent );
|
||||
void SP_target_teleporter( gentity_t *ent );
|
||||
void SP_target_relay (gentity_t *ent);
|
||||
|
@ -428,7 +417,7 @@ void G_ParseField( const char *key, const char *value, gentity_t *ent ) {
|
|||
b = (byte *)ent;
|
||||
|
||||
switch( f->type ) {
|
||||
case F_LSTRING:
|
||||
case F_STRING:
|
||||
*(char **)(b+f->ofs) = G_NewString (value);
|
||||
break;
|
||||
case F_VECTOR:
|
||||
|
@ -449,17 +438,18 @@ void G_ParseField( const char *key, const char *value, gentity_t *ent ) {
|
|||
((float *)(b+f->ofs))[1] = v;
|
||||
((float *)(b+f->ofs))[2] = 0;
|
||||
break;
|
||||
default:
|
||||
case F_IGNORE:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define ADJUST_AREAPORTAL() \
|
||||
if(ent->s.eType == ET_MOVER) \
|
||||
{ \
|
||||
trap_LinkEntity(ent); \
|
||||
trap_AdjustAreaPortalState(ent, qtrue); \
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
|
@ -475,7 +465,7 @@ void G_SpawnGEntityFromSpawnVars( void ) {
|
|||
char *s, *value, *gametypeName;
|
||||
// UPDATE : change these
|
||||
// STONELANCE
|
||||
// static char *gametypeNames[] = {"ffa", "tournament", "single", "team", "ctf", "oneflag", "obelisk", "harvester", "teamtournament"};
|
||||
// static char *gametypeNames[] = {"ffa", "tournament", "single", "team", "ctf", "oneflag", "obelisk", "harvester"};
|
||||
static char *gametypeNames[] = {"racing", "racing_dm", "single", "derby", "dm", "team", "team_racing", "team_racing_dm", "ctf"};
|
||||
// END
|
||||
|
||||
|
@ -490,6 +480,7 @@ void G_SpawnGEntityFromSpawnVars( void ) {
|
|||
if ( g_gametype.integer == GT_SINGLE_PLAYER ) {
|
||||
G_SpawnInt( "notsingle", "0", &i );
|
||||
if ( i ) {
|
||||
ADJUST_AREAPORTAL();
|
||||
G_FreeEntity( ent );
|
||||
return;
|
||||
}
|
||||
|
@ -498,12 +489,14 @@ void G_SpawnGEntityFromSpawnVars( void ) {
|
|||
if ( g_gametype.integer >= GT_TEAM ) {
|
||||
G_SpawnInt( "notteam", "0", &i );
|
||||
if ( i ) {
|
||||
ADJUST_AREAPORTAL();
|
||||
G_FreeEntity( ent );
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
G_SpawnInt( "notfree", "0", &i );
|
||||
if ( i ) {
|
||||
ADJUST_AREAPORTAL();
|
||||
G_FreeEntity( ent );
|
||||
return;
|
||||
}
|
||||
|
@ -518,6 +511,7 @@ void G_SpawnGEntityFromSpawnVars( void ) {
|
|||
|
||||
s = strstr( value, gametypeName );
|
||||
if( !s ) {
|
||||
ADJUST_AREAPORTAL();
|
||||
G_FreeEntity( ent );
|
||||
return;
|
||||
}
|
||||
|
@ -741,8 +735,13 @@ void SP_worldspawn( void ) {
|
|||
// END
|
||||
|
||||
g_entities[ENTITYNUM_WORLD].s.number = ENTITYNUM_WORLD;
|
||||
g_entities[ENTITYNUM_WORLD].r.ownerNum = ENTITYNUM_NONE;
|
||||
g_entities[ENTITYNUM_WORLD].classname = "worldspawn";
|
||||
|
||||
g_entities[ENTITYNUM_NONE].s.number = ENTITYNUM_NONE;
|
||||
g_entities[ENTITYNUM_NONE].r.ownerNum = ENTITYNUM_NONE;
|
||||
g_entities[ENTITYNUM_NONE].classname = "nothing";
|
||||
|
||||
// see if we want a warmup time
|
||||
trap_SetConfigstring( CS_WARMUP, "" );
|
||||
if ( g_restarted.integer ) {
|
||||
|
|
|
@ -115,13 +115,13 @@ const char *TeamColorString(int team) {
|
|||
}
|
||||
|
||||
// NULL for everyone
|
||||
void QDECL PrintMsg( gentity_t *ent, const char *fmt, ... ) {
|
||||
static __attribute__ ((format (printf, 2, 3))) void QDECL PrintMsg( gentity_t *ent, const char *fmt, ... ) {
|
||||
char msg[1024];
|
||||
va_list argptr;
|
||||
char *p;
|
||||
|
||||
va_start (argptr,fmt);
|
||||
if (Q_vsnprintf (msg, sizeof(msg), fmt, argptr) > sizeof(msg)) {
|
||||
if (Q_vsnprintf (msg, sizeof(msg), fmt, argptr) >= sizeof(msg)) {
|
||||
G_Error ( "PrintMsg overrun" );
|
||||
}
|
||||
va_end (argptr);
|
||||
|
@ -735,7 +735,7 @@ int Team_TouchOurFlag( gentity_t *ent, gentity_t *other, int team ) {
|
|||
}
|
||||
|
||||
if ( ent->flags & FL_DROPPED_ITEM ) {
|
||||
// hey, its not home. return it by teleporting it back
|
||||
// hey, it's not home. return it by teleporting it back
|
||||
PrintMsg( NULL, "%s" S_COLOR_WHITE " returned the %s flag!\n",
|
||||
cl->pers.netname, TeamName(team));
|
||||
AddScore(other, ent->r.currentOrigin, CTF_RECOVERY_BONUS);
|
||||
|
|
|
@ -400,12 +400,13 @@ void SP_trigger_hurt( gentity_t *self ) {
|
|||
|
||||
self->r.contents = CONTENTS_TRIGGER;
|
||||
|
||||
if ( self->spawnflags & 2 ) {
|
||||
self->use = hurt_use;
|
||||
}
|
||||
self->use = hurt_use;
|
||||
|
||||
// link in to the world if starting active
|
||||
if ( ! (self->spawnflags & 1) ) {
|
||||
if ( self->spawnflags & 1 ) {
|
||||
trap_UnlinkEntity (self);
|
||||
}
|
||||
else {
|
||||
trap_LinkEntity (self);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,385 +0,0 @@
|
|||
The Independent JPEG Group's JPEG software
|
||||
==========================================
|
||||
|
||||
README for release 6b of 27-Mar-1998
|
||||
====================================
|
||||
|
||||
This distribution contains the sixth public release of the Independent JPEG
|
||||
Group's free JPEG software. You are welcome to redistribute this software and
|
||||
to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
|
||||
|
||||
Serious users of this software (particularly those incorporating it into
|
||||
larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to
|
||||
our electronic mailing list. Mailing list members are notified of updates
|
||||
and have a chance to participate in technical discussions, etc.
|
||||
|
||||
This software is the work of Tom Lane, Philip Gladstone, Jim Boucher,
|
||||
Lee Crocker, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi,
|
||||
Guido Vollbeding, Ge' Weijers, and other members of the Independent JPEG
|
||||
Group.
|
||||
|
||||
IJG is not affiliated with the official ISO JPEG standards committee.
|
||||
|
||||
|
||||
DOCUMENTATION ROADMAP
|
||||
=====================
|
||||
|
||||
This file contains the following sections:
|
||||
|
||||
OVERVIEW General description of JPEG and the IJG software.
|
||||
LEGAL ISSUES Copyright, lack of warranty, terms of distribution.
|
||||
REFERENCES Where to learn more about JPEG.
|
||||
ARCHIVE LOCATIONS Where to find newer versions of this software.
|
||||
RELATED SOFTWARE Other stuff you should get.
|
||||
FILE FORMAT WARS Software *not* to get.
|
||||
TO DO Plans for future IJG releases.
|
||||
|
||||
Other documentation files in the distribution are:
|
||||
|
||||
User documentation:
|
||||
install.doc How to configure and install the IJG software.
|
||||
usage.doc Usage instructions for cjpeg, djpeg, jpegtran,
|
||||
rdjpgcom, and wrjpgcom.
|
||||
*.1 Unix-style man pages for programs (same info as usage.doc).
|
||||
wizard.doc Advanced usage instructions for JPEG wizards only.
|
||||
change.log Version-to-version change highlights.
|
||||
Programmer and internal documentation:
|
||||
libjpeg.doc How to use the JPEG library in your own programs.
|
||||
example.c Sample code for calling the JPEG library.
|
||||
structure.doc Overview of the JPEG library's internal structure.
|
||||
filelist.doc Road map of IJG files.
|
||||
coderules.doc Coding style rules --- please read if you contribute code.
|
||||
|
||||
Please read at least the files install.doc and usage.doc. Useful information
|
||||
can also be found in the JPEG FAQ (Frequently Asked Questions) article. See
|
||||
ARCHIVE LOCATIONS below to find out where to obtain the FAQ article.
|
||||
|
||||
If you want to understand how the JPEG code works, we suggest reading one or
|
||||
more of the REFERENCES, then looking at the documentation files (in roughly
|
||||
the order listed) before diving into the code.
|
||||
|
||||
|
||||
OVERVIEW
|
||||
========
|
||||
|
||||
This package contains C software to implement JPEG image compression and
|
||||
decompression. JPEG (pronounced "jay-peg") is a standardized compression
|
||||
method for full-color and gray-scale images. JPEG is intended for compressing
|
||||
"real-world" scenes; line drawings, cartoons and other non-realistic images
|
||||
are not its strong suit. JPEG is lossy, meaning that the output image is not
|
||||
exactly identical to the input image. Hence you must not use JPEG if you
|
||||
have to have identical output bits. However, on typical photographic images,
|
||||
very good compression levels can be obtained with no visible change, and
|
||||
remarkably high compression levels are possible if you can tolerate a
|
||||
low-quality image. For more details, see the references, or just experiment
|
||||
with various compression settings.
|
||||
|
||||
This software implements JPEG baseline, extended-sequential, and progressive
|
||||
compression processes. Provision is made for supporting all variants of these
|
||||
processes, although some uncommon parameter settings aren't implemented yet.
|
||||
For legal reasons, we are not distributing code for the arithmetic-coding
|
||||
variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting
|
||||
the hierarchical or lossless processes defined in the standard.
|
||||
|
||||
We provide a set of library routines for reading and writing JPEG image files,
|
||||
plus two sample applications "cjpeg" and "djpeg", which use the library to
|
||||
perform conversion between JPEG and some other popular image file formats.
|
||||
The library is intended to be reused in other applications.
|
||||
|
||||
In order to support file conversion and viewing software, we have included
|
||||
considerable functionality beyond the bare JPEG coding/decoding capability;
|
||||
for example, the color quantization modules are not strictly part of JPEG
|
||||
decoding, but they are essential for output to colormapped file formats or
|
||||
colormapped displays. These extra functions can be compiled out of the
|
||||
library if not required for a particular application. We have also included
|
||||
"jpegtran", a utility for lossless transcoding between different JPEG
|
||||
processes, and "rdjpgcom" and "wrjpgcom", two simple applications for
|
||||
inserting and extracting textual comments in JFIF files.
|
||||
|
||||
The emphasis in designing this software has been on achieving portability and
|
||||
flexibility, while also making it fast enough to be useful. In particular,
|
||||
the software is not intended to be read as a tutorial on JPEG. (See the
|
||||
REFERENCES section for introductory material.) Rather, it is intended to
|
||||
be reliable, portable, industrial-strength code. We do not claim to have
|
||||
achieved that goal in every aspect of the software, but we strive for it.
|
||||
|
||||
We welcome the use of this software as a component of commercial products.
|
||||
No royalty is required, but we do ask for an acknowledgement in product
|
||||
documentation, as described under LEGAL ISSUES.
|
||||
|
||||
|
||||
LEGAL ISSUES
|
||||
============
|
||||
|
||||
In plain English:
|
||||
|
||||
1. We don't promise that this software works. (But if you find any bugs,
|
||||
please let us know!)
|
||||
2. You can use this software for whatever you want. You don't have to pay us.
|
||||
3. You may not pretend that you wrote this software. If you use it in a
|
||||
program, you must acknowledge somewhere in your documentation that
|
||||
you've used the IJG code.
|
||||
|
||||
In legalese:
|
||||
|
||||
The authors make NO WARRANTY or representation, either express or implied,
|
||||
with respect to this software, its quality, accuracy, merchantability, or
|
||||
fitness for a particular purpose. This software is provided "AS IS", and you,
|
||||
its user, assume the entire risk as to its quality and accuracy.
|
||||
|
||||
This software is copyright (C) 1991-1998, Thomas G. Lane.
|
||||
All Rights Reserved except as specified below.
|
||||
|
||||
Permission is hereby granted to use, copy, modify, and distribute this
|
||||
software (or portions thereof) for any purpose, without fee, subject to these
|
||||
conditions:
|
||||
(1) If any part of the source code for this software is distributed, then this
|
||||
README file must be included, with this copyright and no-warranty notice
|
||||
unaltered; and any additions, deletions, or changes to the original files
|
||||
must be clearly indicated in accompanying documentation.
|
||||
(2) If only executable code is distributed, then the accompanying
|
||||
documentation must state that "this software is based in part on the work of
|
||||
the Independent JPEG Group".
|
||||
(3) Permission for use of this software is granted only if the user accepts
|
||||
full responsibility for any undesirable consequences; the authors accept
|
||||
NO LIABILITY for damages of any kind.
|
||||
|
||||
These conditions apply to any software derived from or based on the IJG code,
|
||||
not just to the unmodified library. If you use our work, you ought to
|
||||
acknowledge us.
|
||||
|
||||
Permission is NOT granted for the use of any IJG author's name or company name
|
||||
in advertising or publicity relating to this software or products derived from
|
||||
it. This software may be referred to only as "the Independent JPEG Group's
|
||||
software".
|
||||
|
||||
We specifically permit and encourage the use of this software as the basis of
|
||||
commercial products, provided that all warranty or liability claims are
|
||||
assumed by the product vendor.
|
||||
|
||||
|
||||
ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
|
||||
sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
|
||||
ansi2knr.c is NOT covered by the above copyright and conditions, but instead
|
||||
by the usual distribution terms of the Free Software Foundation; principally,
|
||||
that you must include source code if you redistribute it. (See the file
|
||||
ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part
|
||||
of any program generated from the IJG code, this does not limit you more than
|
||||
the foregoing paragraphs do.
|
||||
|
||||
The Unix configuration script "configure" was produced with GNU Autoconf.
|
||||
It is copyright by the Free Software Foundation but is freely distributable.
|
||||
The same holds for its supporting scripts (config.guess, config.sub,
|
||||
ltconfig, ltmain.sh). Another support script, install-sh, is copyright
|
||||
by M.I.T. but is also freely distributable.
|
||||
|
||||
It appears that the arithmetic coding option of the JPEG spec is covered by
|
||||
patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot
|
||||
legally be used without obtaining one or more licenses. For this reason,
|
||||
support for arithmetic coding has been removed from the free JPEG software.
|
||||
(Since arithmetic coding provides only a marginal gain over the unpatented
|
||||
Huffman mode, it is unlikely that very many implementations will support it.)
|
||||
So far as we are aware, there are no patent restrictions on the remaining
|
||||
code.
|
||||
|
||||
The IJG distribution formerly included code to read and write GIF files.
|
||||
To avoid entanglement with the Unisys LZW patent, GIF reading support has
|
||||
been removed altogether, and the GIF writer has been simplified to produce
|
||||
"uncompressed GIFs". This technique does not use the LZW algorithm; the
|
||||
resulting GIF files are larger than usual, but are readable by all standard
|
||||
GIF decoders.
|
||||
|
||||
We are required to state that
|
||||
"The Graphics Interchange Format(c) is the Copyright property of
|
||||
CompuServe Incorporated. GIF(sm) is a Service Mark property of
|
||||
CompuServe Incorporated."
|
||||
|
||||
|
||||
REFERENCES
|
||||
==========
|
||||
|
||||
We highly recommend reading one or more of these references before trying to
|
||||
understand the innards of the JPEG software.
|
||||
|
||||
The best short technical introduction to the JPEG compression algorithm is
|
||||
Wallace, Gregory K. "The JPEG Still Picture Compression Standard",
|
||||
Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
|
||||
(Adjacent articles in that issue discuss MPEG motion picture compression,
|
||||
applications of JPEG, and related topics.) If you don't have the CACM issue
|
||||
handy, a PostScript file containing a revised version of Wallace's article is
|
||||
available at ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz. The file (actually
|
||||
a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
|
||||
omits the sample images that appeared in CACM, but it includes corrections
|
||||
and some added material. Note: the Wallace article is copyright ACM and IEEE,
|
||||
and it may not be used for commercial purposes.
|
||||
|
||||
A somewhat less technical, more leisurely introduction to JPEG can be found in
|
||||
"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by
|
||||
M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides
|
||||
good explanations and example C code for a multitude of compression methods
|
||||
including JPEG. It is an excellent source if you are comfortable reading C
|
||||
code but don't know much about data compression in general. The book's JPEG
|
||||
sample code is far from industrial-strength, but when you are ready to look
|
||||
at a full implementation, you've got one here...
|
||||
|
||||
The best full description of JPEG is the textbook "JPEG Still Image Data
|
||||
Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published
|
||||
by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp.
|
||||
The book includes the complete text of the ISO JPEG standards (DIS 10918-1
|
||||
and draft DIS 10918-2). This is by far the most complete exposition of JPEG
|
||||
in existence, and we highly recommend it.
|
||||
|
||||
The JPEG standard itself is not available electronically; you must order a
|
||||
paper copy through ISO or ITU. (Unless you feel a need to own a certified
|
||||
official copy, we recommend buying the Pennebaker and Mitchell book instead;
|
||||
it's much cheaper and includes a great deal of useful explanatory material.)
|
||||
In the USA, copies of the standard may be ordered from ANSI Sales at (212)
|
||||
642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI
|
||||
doesn't take credit card orders, but Global does.) It's not cheap: as of
|
||||
1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7%
|
||||
shipping/handling. The standard is divided into two parts, Part 1 being the
|
||||
actual specification, while Part 2 covers compliance testing methods. Part 1
|
||||
is titled "Digital Compression and Coding of Continuous-tone Still Images,
|
||||
Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS
|
||||
10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of
|
||||
Continuous-tone Still Images, Part 2: Compliance testing" and has document
|
||||
numbers ISO/IEC IS 10918-2, ITU-T T.83.
|
||||
|
||||
Some extensions to the original JPEG standard are defined in JPEG Part 3,
|
||||
a newer ISO standard numbered ISO/IEC IS 10918-3 and ITU-T T.84. IJG
|
||||
currently does not support any Part 3 extensions.
|
||||
|
||||
The JPEG standard does not specify all details of an interchangeable file
|
||||
format. For the omitted details we follow the "JFIF" conventions, revision
|
||||
1.02. A copy of the JFIF spec is available from:
|
||||
Literature Department
|
||||
C-Cube Microsystems, Inc.
|
||||
1778 McCarthy Blvd.
|
||||
Milpitas, CA 95035
|
||||
phone (408) 944-6300, fax (408) 944-6314
|
||||
A PostScript version of this document is available by FTP at
|
||||
ftp://ftp.uu.net/graphics/jpeg/jfif.ps.gz. There is also a plain text
|
||||
version at ftp://ftp.uu.net/graphics/jpeg/jfif.txt.gz, but it is missing
|
||||
the figures.
|
||||
|
||||
The TIFF 6.0 file format specification can be obtained by FTP from
|
||||
ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme
|
||||
found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems.
|
||||
IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6).
|
||||
Instead, we recommend the JPEG design proposed by TIFF Technical Note #2
|
||||
(Compression tag 7). Copies of this Note can be obtained from ftp.sgi.com or
|
||||
from ftp://ftp.uu.net/graphics/jpeg/. It is expected that the next revision
|
||||
of the TIFF spec will replace the 6.0 JPEG design with the Note's design.
|
||||
Although IJG's own code does not support TIFF/JPEG, the free libtiff library
|
||||
uses our library to implement TIFF/JPEG per the Note. libtiff is available
|
||||
from ftp://ftp.sgi.com/graphics/tiff/.
|
||||
|
||||
|
||||
ARCHIVE LOCATIONS
|
||||
=================
|
||||
|
||||
The "official" archive site for this software is ftp.uu.net (Internet
|
||||
address 192.48.96.9). The most recent released version can always be found
|
||||
there in directory graphics/jpeg. This particular version will be archived
|
||||
as ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz. If you don't have
|
||||
direct Internet access, UUNET's archives are also available via UUCP; contact
|
||||
help@uunet.uu.net for information on retrieving files that way.
|
||||
|
||||
Numerous Internet sites maintain copies of the UUNET files. However, only
|
||||
ftp.uu.net is guaranteed to have the latest official version.
|
||||
|
||||
You can also obtain this software in DOS-compatible "zip" archive format from
|
||||
the SimTel archives (ftp://ftp.simtel.net/pub/simtelnet/msdos/graphics/), or
|
||||
on CompuServe in the Graphics Support forum (GO CIS:GRAPHSUP), library 12
|
||||
"JPEG Tools". Again, these versions may sometimes lag behind the ftp.uu.net
|
||||
release.
|
||||
|
||||
The JPEG FAQ (Frequently Asked Questions) article is a useful source of
|
||||
general information about JPEG. It is updated constantly and therefore is
|
||||
not included in this distribution. The FAQ is posted every two weeks to
|
||||
Usenet newsgroups comp.graphics.misc, news.answers, and other groups.
|
||||
It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/
|
||||
and other news.answers archive sites, including the official news.answers
|
||||
archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/.
|
||||
If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu
|
||||
with body
|
||||
send usenet/news.answers/jpeg-faq/part1
|
||||
send usenet/news.answers/jpeg-faq/part2
|
||||
|
||||
|
||||
RELATED SOFTWARE
|
||||
================
|
||||
|
||||
Numerous viewing and image manipulation programs now support JPEG. (Quite a
|
||||
few of them use this library to do so.) The JPEG FAQ described above lists
|
||||
some of the more popular free and shareware viewers, and tells where to
|
||||
obtain them on Internet.
|
||||
|
||||
If you are on a Unix machine, we highly recommend Jef Poskanzer's free
|
||||
PBMPLUS software, which provides many useful operations on PPM-format image
|
||||
files. In particular, it can convert PPM images to and from a wide range of
|
||||
other formats, thus making cjpeg/djpeg considerably more useful. The latest
|
||||
version is distributed by the NetPBM group, and is available from numerous
|
||||
sites, notably ftp://wuarchive.wustl.edu/graphics/graphics/packages/NetPBM/.
|
||||
Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software is;
|
||||
you are likely to have difficulty making it work on any non-Unix machine.
|
||||
|
||||
A different free JPEG implementation, written by the PVRG group at Stanford,
|
||||
is available from ftp://havefun.stanford.edu/pub/jpeg/. This program
|
||||
is designed for research and experimentation rather than production use;
|
||||
it is slower, harder to use, and less portable than the IJG code, but it
|
||||
is easier to read and modify. Also, the PVRG code supports lossless JPEG,
|
||||
which we do not. (On the other hand, it doesn't do progressive JPEG.)
|
||||
|
||||
|
||||
FILE FORMAT WARS
|
||||
================
|
||||
|
||||
Some JPEG programs produce files that are not compatible with our library.
|
||||
The root of the problem is that the ISO JPEG committee failed to specify a
|
||||
concrete file format. Some vendors "filled in the blanks" on their own,
|
||||
creating proprietary formats that no one else could read. (For example, none
|
||||
of the early commercial JPEG implementations for the Macintosh were able to
|
||||
exchange compressed files.)
|
||||
|
||||
The file format we have adopted is called JFIF (see REFERENCES). This format
|
||||
has been agreed to by a number of major commercial JPEG vendors, and it has
|
||||
become the de facto standard. JFIF is a minimal or "low end" representation.
|
||||
We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF
|
||||
Technical Note #2) for "high end" applications that need to record a lot of
|
||||
additional data about an image. TIFF/JPEG is fairly new and not yet widely
|
||||
supported, unfortunately.
|
||||
|
||||
The upcoming JPEG Part 3 standard defines a file format called SPIFF.
|
||||
SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should
|
||||
be able to read the most common variant of SPIFF. SPIFF has some technical
|
||||
advantages over JFIF, but its major claim to fame is simply that it is an
|
||||
official standard rather than an informal one. At this point it is unclear
|
||||
whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto
|
||||
standard. IJG intends to support SPIFF once the standard is frozen, but we
|
||||
have not decided whether it should become our default output format or not.
|
||||
(In any case, our decoder will remain capable of reading JFIF indefinitely.)
|
||||
|
||||
Various proprietary file formats incorporating JPEG compression also exist.
|
||||
We have little or no sympathy for the existence of these formats. Indeed,
|
||||
one of the original reasons for developing this free software was to help
|
||||
force convergence on common, open format standards for JPEG files. Don't
|
||||
use a proprietary file format!
|
||||
|
||||
|
||||
TO DO
|
||||
=====
|
||||
|
||||
The major thrust for v7 will probably be improvement of visual quality.
|
||||
The current method for scaling the quantization tables is known not to be
|
||||
very good at low Q values. We also intend to investigate block boundary
|
||||
smoothing, "poor man's variable quantization", and other means of improving
|
||||
quality-vs-file-size performance without sacrificing compatibility.
|
||||
|
||||
In future versions, we are considering supporting some of the upcoming JPEG
|
||||
Part 3 extensions --- principally, variable quantization and the SPIFF file
|
||||
format.
|
||||
|
||||
As always, speeding things up is of great interest.
|
||||
|
||||
Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net.
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue