- ioquake3 resync to revision 2098 from 1834 (?)

This commit is contained in:
zturtleman 2011-07-26 08:52:24 +00:00
parent c471d516dd
commit 339deb2bff
295 changed files with 36044 additions and 16126 deletions

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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
View 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
View 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;
}

View file

@ -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

View file

@ -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
===========================================================================
*/

View 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

View file

@ -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

View 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

View 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"
);
}

View file

@ -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

View file

@ -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
===========================================================================
*/

View 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

View file

@ -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
{

View file

@ -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

View file

@ -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;

View file

@ -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)

View file

@ -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
//===========================================================================

View file

@ -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
//===========================================================================

View file

@ -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

View file

@ -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);

View file

@ -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);
}

View file

@ -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

View file

@ -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

View 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);

View file

@ -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

View file

@ -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;
}

View file

@ -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)));

View file

@ -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

View file

@ -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 );
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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 )

View file

@ -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 = &cent->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 = &cent->currentState;
if ( s1->weapon > WP_NUM_WEAPONS ) {
if ( s1->weapon >= WP_NUM_WEAPONS ) {
s1->weapon = 0;
}
weapon = &cg_weapons[s1->weapon];

View file

@ -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";
}

View file

@ -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 {

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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) {

View file

@ -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

View file

@ -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 ] ) {

View file

@ -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);

View file

@ -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] ) {

View file

@ -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;

View file

@ -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 ) {

View file

@ -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
{

View file

@ -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 ) ) {

View file

@ -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;

View file

@ -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
}
}

View file

@ -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--;
}

View file

@ -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 ();
}
}

View file

@ -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);

View file

@ -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
}

View file

@ -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

View file

@ -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;
}

View file

@ -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;

View file

@ -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();

View file

@ -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

View file

@ -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 );
//

View file

@ -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>

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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);

View 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");
}

View file

@ -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);

View file

@ -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( );

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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)) {

View file

@ -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.
==================
*/

View file

@ -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);

View file

@ -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 );

View file

@ -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

View file

@ -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)));

View file

@ -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;

View file

@ -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;
/*

View file

@ -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;

View file

@ -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]

View file

@ -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];

View file

@ -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';
}

View file

@ -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;
}

View file

@ -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] );

View file

@ -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 ];

View file

@ -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

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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 );
}

View file

@ -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 ) {

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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