Update to ioquake3 2018-12-21 part 2 (engine)

This commit is contained in:
Zack Middleton 2019-01-04 20:16:41 -06:00
parent be3161dfce
commit dfb9bed2b8
225 changed files with 11585 additions and 8180 deletions

1
.gitignore vendored
View file

@ -1,6 +1,7 @@
build
*.swp
*tags
*~
# OS X
####################

View file

@ -1,3 +1,8 @@
# sudo is required for travis-ci to use ubuntu trusty
# ubuntu trusty is required for libsdl2-dev
sudo: required
dist: trusty
language: c
env:
@ -6,19 +11,27 @@ env:
- CC=gcc
- CC=clang
# extra libs
- CC=gcc USE_CODEC_VORBIS=1 USE_FREETYPE=1
- CC=clang USE_CODEC_VORBIS=1 USE_FREETYPE=1
- CC=gcc USE_FREETYPE=1
- CC=clang USE_FREETYPE=1
# cross-compile using mingw
- CC= PLATFORM="mingw32" ARCH="x86"
- CC= PLATFORM="mingw32" ARCH="x86_64"
# dlopen curl to workaround link error because mingw-w64 in trusty is missing strtok_r required by libcurl.a
- CC= PLATFORM="mingw32" ARCH="x86" USE_CURL_DLOPEN=1
- CC= PLATFORM="mingw32" ARCH="x86_64" USE_CURL_DLOPEN=1
script: ./travis-ci-build.sh
before_install:
- echo "yes" | sudo apt-add-repository ppa:zoogie/sdl2-snapshots
- sudo apt-get update -qq
- sudo apt-get remove -qq -y mingw32
- sudo apt-get install -q -y libgl1-mesa-dev libsdl2-dev libfreetype6-dev mingw-w64
notifications:
email: false
email: false
addons:
apt:
packages:
- binutils-mingw-w64-i686
- gcc-mingw-w64-i686
- binutils-mingw-w64-x86-64
- gcc-mingw-w64-x86-64
- gcc-mingw-w64
- mingw-w64
- libgl1-mesa-dev
- libsdl2-dev
- libfreetype6-dev

4
BUGS
View file

@ -1,4 +0,0 @@
- On Solaris/SPARC gcc optimizations higher than -O0 currently lead
to a segfault
https://bugzilla.icculus.org/ for more.

View file

@ -634,7 +634,7 @@
#1 current directory
#2 fs_homepath
#3 fs_basepath
this was needed to make mod developement easier
this was needed to make mod development easier
2001-10-09 Timothee Besset <ttimo@idsoftware.com>
+ https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=51
@ -814,7 +814,7 @@
* rebuilding 1.28b, various fixes on linux build:
- SetProgramPath was renamed to Sys_SetDefaultCDPath in unix_shared.c
updated unix_main.c accordingly
- some prototypes in qgl.h are guarded by #ifndef GL_VERSION_1_2 (ARB extentions)
- some prototypes in qgl.h are guarded by #ifndef GL_VERSION_1_2 (ARB extensions)
those prototypes are needed by linux_glimp for importing functions and casting, added a #ifdef __linux__
(not a clean solution)
- game/q_shared.h
@ -861,7 +861,7 @@
2001-04-23 Timothee Besset <ttimo@idsoftware.com>
* cleanup the mod selection code, remove duplicates
* some issues with release builds, my main developement box doesn't build stable binaries with release settings
* some issues with release builds, my main development box doesn't build stable binaries with release settings
removing -fomit-frame-pointer seems to fix (there's probably a performance hit)
see OMIT-FRAME-POINTER.txt
@ -984,7 +984,7 @@
//* or // /* or variations of this. I reverted to exact mirror
image of SOS to be sure - short of removing it's too easy to mistake
live code for dead one.
Later: have to change 5 occurences to avoid gcc complaints about
Later: have to change 5 occurrences to avoid gcc complaints about
nested comment tokens.
TODO: somebody please get rid of the cruft in here.
@ -1235,7 +1235,7 @@
* code/game/g_cmds.c (G_SayTo): CON_CONNECTED.
* code/game/ai_main.c: HOOK added (SOS).
* code/botlib/be_aas_move.c (AAS_HorizontalVelocityForJump):
correct fix for FPE occuring (SOS).
correct fix for FPE occurring (SOS).
* code/game/ai_dmq3.c: initmove.viewoffset (SOS).
* code/game/q_math.c: guard asser/isnan with Q3_VM (q3asm).
@ -1679,7 +1679,7 @@
* code/game/q_shared.c: Q_strncpyz does zero padding (duh).
Note: calls strncpy, which does a zero fill up to destsize.
If destsize exceeds memory size, zero padding will overwrite
adjacent memory. Suspicion was this happend to botimport.
adjacent memory. Suspicion was this happened to botimport.
* code/qcommon/cvar.c: possible problem in Q_strncpyz call.
@ -1783,7 +1783,7 @@
* TEST: running with RC4 data files.
TODO: "bot library used before setup" (Q3+TA)
TODO: Q3 old mods wreak havoc (graceful bounce)
TODO: supress "FreeType code not available" in renderer
TODO: suppress "FreeType code not available" in renderer
TODO: can't move in Q3
TODO: items flicker in Q3
TODO: no decals in Q3
@ -2015,7 +2015,7 @@
* TEST: tried executing a script - get bounced.
TODO: is there any way to jump into a map?
TODO: cl_cinematics 0 (supress all fullscreen RoQ)
TODO: cl_cinematics 0 (suppress all fullscreen RoQ)
Next: used r_logfile 200 in Win32 (RC4) and Linux.
There is a buckload of setup code seemingly not done
at all in Linux? Either that, or logging is enabled
@ -2983,7 +2983,7 @@
Modules:
code: the Q3 engine code, including a jpeg-6/ copy
common: code shared by tools
libs: code shared by tools, inlcuding a jpeg6/ copy
libs: code shared by tools, including a jpeg6/ copy
q3asm: VM bytecode assembly
q3data: misc. Q3 data conversions
q3map: BSP builder

410
Makefile
View file

@ -3,18 +3,12 @@
#
# GNU Make required
#
COMPILE_PLATFORM=$(shell uname|sed -e s/_.*//|tr '[:upper:]' '[:lower:]'|sed -e 's/\//_/g')
COMPILE_ARCH=$(shell uname -m | sed -e s/i.86/x86/ | sed -e 's/^arm.*/arm/')
COMPILE_PLATFORM=$(shell uname | sed -e 's/_.*//' | tr '[:upper:]' '[:lower:]' | sed -e 's/\//_/g')
COMPILE_ARCH=$(shell uname -m | sed -e 's/i.86/x86/' | sed -e 's/^arm.*/arm/')
ifeq ($(COMPILE_PLATFORM),sunos)
# Solaris uname and GNU uname differ
COMPILE_ARCH=$(shell uname -p | sed -e s/i.86/x86/)
endif
ifeq ($(COMPILE_PLATFORM),darwin)
# Apple does some things a little differently...
COMPILE_ARCH=$(shell uname -p | sed -e s/i.86/x86/)
COMPILE_ARCH=$(shell uname -p | sed -e 's/i.86/x86/')
endif
ifndef BUILD_STANDALONE
@ -41,6 +35,9 @@ endif
ifndef BUILD_RENDERER_OPENGL2
BUILD_RENDERER_OPENGL2=
endif
ifndef BUILD_AUTOUPDATER # DON'T build unless you mean to!
BUILD_AUTOUPDATER=0
endif
#############################################################################
#
@ -179,7 +176,7 @@ ifndef USE_CURL_DLOPEN
endif
ifndef USE_CODEC_VORBIS
USE_CODEC_VORBIS=0
USE_CODEC_VORBIS=1
endif
ifndef USE_CODEC_OPUS
@ -230,8 +227,16 @@ ifndef USE_RENDERER_DLOPEN
USE_RENDERER_DLOPEN=1
endif
ifndef USE_YACC
USE_YACC=0
endif
ifndef USE_AUTOUPDATER # DON'T include unless you mean to!
USE_AUTOUPDATER=0
endif
ifndef DEBUG_CFLAGS
DEBUG_CFLAGS=-g -O0
DEBUG_CFLAGS=-ggdb -O0
endif
#############################################################################
@ -264,6 +269,9 @@ LBURGDIR=$(MOUNT_DIR)/tools/lcc/lburg
Q3CPPDIR=$(MOUNT_DIR)/tools/lcc/cpp
Q3LCCETCDIR=$(MOUNT_DIR)/tools/lcc/etc
Q3LCCSRCDIR=$(MOUNT_DIR)/tools/lcc/src
AUTOUPDATERSRCDIR=$(MOUNT_DIR)/autoupdater
LIBTOMCRYPTSRCDIR=$(AUTOUPDATERSRCDIR)/rsa_tools/libtomcrypt-1.17
TOMSFASTMATHSRCDIR=$(AUTOUPDATERSRCDIR)/rsa_tools/tomsfastmath-0.13.1
LOKISETUPDIR=misc/setup
NSISDIR=misc/nsis
SDLHDIR=$(MOUNT_DIR)/SDL2
@ -271,29 +279,42 @@ LIBSDIR=$(MOUNT_DIR)/libs
bin_path=$(shell which $(1) 2> /dev/null)
# The autoupdater uses curl, so figure out its flags no matter what.
# We won't need this if we only build the server
ifneq ($(BUILD_CLIENT),0)
# set PKG_CONFIG_PATH to influence this, e.g.
# PKG_CONFIG_PATH=/opt/cross/i386-mingw32msvc/lib/pkgconfig
ifneq ($(call bin_path, pkg-config),)
CURL_CFLAGS ?= $(shell pkg-config --silence-errors --cflags libcurl)
CURL_LIBS ?= $(shell pkg-config --silence-errors --libs libcurl)
OPENAL_CFLAGS ?= $(shell pkg-config --silence-errors --cflags openal)
OPENAL_LIBS ?= $(shell pkg-config --silence-errors --libs openal)
SDL_CFLAGS ?= $(shell pkg-config --silence-errors --cflags sdl2|sed 's/-Dmain=SDL_main//')
SDL_LIBS ?= $(shell pkg-config --silence-errors --libs sdl2)
FREETYPE_CFLAGS ?= $(shell pkg-config --silence-errors --cflags freetype2)
else
# assume they're in the system default paths (no -I or -L needed)
CURL_LIBS ?= -lcurl
OPENAL_LIBS ?= -lopenal
endif
# Use sdl2-config if all else fails
ifeq ($(SDL_CFLAGS),)
ifneq ($(call bin_path, sdl2-config),)
SDL_CFLAGS ?= $(shell sdl2-config --cflags)
SDL_LIBS ?= $(shell sdl2-config --libs)
endif
# set PKG_CONFIG_PATH or PKG_CONFIG to influence this, e.g.
# PKG_CONFIG_PATH=/opt/cross/i386-mingw32msvc/lib/pkgconfig or
# PKG_CONFIG=arm-linux-gnueabihf-pkg-config
ifeq ($(CROSS_COMPILING),0)
PKG_CONFIG ?= pkg-config
else
ifneq ($(PKG_CONFIG_PATH),)
PKG_CONFIG ?= pkg-config
else
# Don't use host pkg-config when cross-compiling.
# (unknown-pkg-config is meant to be a non-existant command.)
PKG_CONFIG ?= unknown-pkg-config
endif
endif
ifneq ($(call bin_path, $(PKG_CONFIG)),)
CURL_CFLAGS ?= $(shell $(PKG_CONFIG) --silence-errors --cflags libcurl)
CURL_LIBS ?= $(shell $(PKG_CONFIG) --silence-errors --libs libcurl)
OPENAL_CFLAGS ?= $(shell $(PKG_CONFIG) --silence-errors --cflags openal)
OPENAL_LIBS ?= $(shell $(PKG_CONFIG) --silence-errors --libs openal)
SDL_CFLAGS ?= $(shell $(PKG_CONFIG) --silence-errors --cflags sdl2|sed 's/-Dmain=SDL_main//')
SDL_LIBS ?= $(shell $(PKG_CONFIG) --silence-errors --libs sdl2)
else
# assume they're in the system default paths (no -I or -L needed)
CURL_LIBS ?= -lcurl
OPENAL_LIBS ?= -lopenal
endif
# Use sdl2-config if all else fails
ifeq ($(SDL_CFLAGS),)
ifneq ($(call bin_path, sdl2-config),)
SDL_CFLAGS = $(shell sdl2-config --cflags)
SDL_LIBS = $(shell sdl2-config --libs)
endif
endif
@ -313,7 +334,7 @@ endif
#############################################################################
INSTALL=install
MKDIR=mkdir
MKDIR=mkdir -p
EXTRA_FILES=
CLIENT_EXTRA_FILES=
@ -340,11 +361,11 @@ ifneq (,$(findstring "$(PLATFORM)", "linux" "gnu_kfreebsd" "kfreebsd-gnu" "gnu")
HAVE_VM_COMPILED=true
else
ifeq ($(ARCH),ppc)
BASE_CFLAGS += -maltivec
ALTIVEC_CFLAGS = -maltivec
HAVE_VM_COMPILED=true
endif
ifeq ($(ARCH),ppc64)
BASE_CFLAGS += -maltivec
ALTIVEC_CFLAGS = -maltivec
HAVE_VM_COMPILED=true
endif
ifeq ($(ARCH),sparc)
@ -352,6 +373,9 @@ ifneq (,$(findstring "$(PLATFORM)", "linux" "gnu_kfreebsd" "kfreebsd-gnu" "gnu")
OPTIMIZEVM += -mtune=ultrasparc3 -mv8plus
HAVE_VM_COMPILED=true
endif
ifeq ($(ARCH),armv7l)
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
@ -366,9 +390,10 @@ ifneq (,$(findstring "$(PLATFORM)", "linux" "gnu_kfreebsd" "kfreebsd-gnu" "gnu")
THREAD_LIBS=-lpthread
LIBS=-ldl -lm
AUTOUPDATER_LIBS += -ldl
CLIENT_LIBS=$(SDL_LIBS)
RENDERER_LIBS = $(SDL_LIBS) -lGL
RENDERER_LIBS = $(SDL_LIBS)
ifeq ($(USE_OPENAL),1)
ifneq ($(USE_OPENAL_DLOPEN),1)
@ -406,17 +431,35 @@ ifeq ($(PLATFORM),darwin)
LIBS = -framework Cocoa
CLIENT_LIBS=
RENDERER_LIBS=
OPTIMIZEVM=
OPTIMIZEVM = -O3
BASE_CFLAGS = -Wall -Wimplicit -Wstrict-prototypes -mmacosx-version-min=10.5 \
-DMAC_OS_X_VERSION_MIN_REQUIRED=1050 -DREACTION
# Default minimum Mac OS X version
ifeq ($(MACOSX_VERSION_MIN),)
MACOSX_VERSION_MIN=10.7
endif
MACOSX_MAJOR=$(shell echo $(MACOSX_VERSION_MIN) | cut -d. -f1)
MACOSX_MINOR=$(shell echo $(MACOSX_VERSION_MIN) | cut -d. -f2)
ifeq ($(shell test $(MACOSX_MINOR) -gt 9; echo $$?),0)
# Multiply and then remove decimal. 10.10 -> 101000.0 -> 101000
MAC_OS_X_VERSION_MIN_REQUIRED=$(shell echo "$(MACOSX_MAJOR) * 10000 + $(MACOSX_MINOR) * 100" | bc | cut -d. -f1)
else
# Multiply by 100 and then remove decimal. 10.7 -> 1070.0 -> 1070
MAC_OS_X_VERSION_MIN_REQUIRED=$(shell echo "$(MACOSX_VERSION_MIN) * 100" | bc | cut -d. -f1)
endif
LDFLAGS += -mmacosx-version-min=$(MACOSX_VERSION_MIN)
BASE_CFLAGS += -mmacosx-version-min=$(MACOSX_VERSION_MIN) \
-DMAC_OS_X_VERSION_MIN_REQUIRED=$(MAC_OS_X_VERSION_MIN_REQUIRED) \
-DREACTION
ifeq ($(ARCH),ppc)
BASE_CFLAGS += -arch ppc -faltivec
OPTIMIZEVM += -O3
BASE_CFLAGS += -arch ppc
ALTIVEC_CFLAGS = -faltivec
endif
ifeq ($(ARCH),ppc64)
BASE_CFLAGS += -arch ppc64 -faltivec
BASE_CFLAGS += -arch ppc64
ALTIVEC_CFLAGS = -faltivec
endif
ifeq ($(ARCH),x86)
OPTIMIZEVM += -march=prescott -mfpmath=sse
@ -425,7 +468,8 @@ ifeq ($(PLATFORM),darwin)
BASE_CFLAGS += -arch i386 -m32 -mstackrealign
endif
ifeq ($(ARCH),x86_64)
OPTIMIZEVM += -arch x86_64 -mfpmath=sse
OPTIMIZEVM += -mfpmath=sse
BASE_CFLAGS += -arch x86_64
endif
# When compiling on OSX for OSX, we're not cross compiling as far as the
@ -447,13 +491,14 @@ ifeq ($(PLATFORM),darwin)
$(error Architecture $(ARCH) is not supported when cross compiling)
endif
endif
else
TOOLS_CFLAGS += -DMACOS_X
endif
BASE_CFLAGS += -fno-strict-aliasing -DMACOS_X -fno-common -pipe
BASE_CFLAGS += -fno-strict-aliasing -fno-common -pipe
ifeq ($(USE_OPENAL),1)
ifneq ($(USE_LOCAL_HEADERS),1)
CLIENT_CFLAGS += -I/System/Library/Frameworks/OpenAL.framework/Headers
endif
ifneq ($(USE_OPENAL_DLOPEN),1)
CLIENT_LIBS += -framework OpenAL
endif
@ -468,18 +513,29 @@ ifeq ($(PLATFORM),darwin)
BASE_CFLAGS += -D_THREAD_SAFE=1
ifeq ($(USE_LOCAL_HEADERS),1)
BASE_CFLAGS += -I$(SDLHDIR)/include
endif
CLIENT_LIBS += -framework IOKit
RENDERER_LIBS += -framework OpenGL
# We copy sdlmain before ranlib'ing it so that subversion doesn't think
# the file has been modified by each build.
LIBSDLMAIN=$(B)/libSDL2main.a
LIBSDLMAINSRC=$(LIBSDIR)/macosx/libSDL2main.a
CLIENT_LIBS += -framework IOKit \
$(LIBSDIR)/macosx/libSDL2-2.0.0.dylib
RENDERER_LIBS += -framework OpenGL $(LIBSDIR)/macosx/libSDL2-2.0.0.dylib
CLIENT_EXTRA_FILES += $(LIBSDIR)/macosx/libSDL2-2.0.0.dylib
ifeq ($(USE_LOCAL_HEADERS),1)
# libSDL2-2.0.0.dylib for PPC is SDL 2.0.1 + changes to compile
ifneq ($(findstring $(ARCH),ppc ppc64),)
BASE_CFLAGS += -I$(SDLHDIR)/include-macppc
else
BASE_CFLAGS += -I$(SDLHDIR)/include
endif
# We copy sdlmain before ranlib'ing it so that subversion doesn't think
# the file has been modified by each build.
LIBSDLMAIN=$(B)/libSDL2main.a
LIBSDLMAINSRC=$(LIBSDIR)/macosx/libSDL2main.a
CLIENT_LIBS += $(LIBSDIR)/macosx/libSDL2-2.0.0.dylib
RENDERER_LIBS += $(LIBSDIR)/macosx/libSDL2-2.0.0.dylib
CLIENT_EXTRA_FILES += $(LIBSDIR)/macosx/libSDL2-2.0.0.dylib
else
BASE_CFLAGS += -I/Library/Frameworks/SDL2.framework/Headers
CLIENT_LIBS += -framework SDL2
RENDERER_LIBS += -framework SDL2
endif
OPTIMIZE = $(OPTIMIZEVM) -ffast-math
@ -507,20 +563,20 @@ ifdef MINGW
# We need to figure out the correct gcc and windres
ifeq ($(ARCH),x86_64)
MINGW_PREFIXES=amd64-mingw32msvc x86_64-w64-mingw32
MINGW_PREFIXES=x86_64-w64-mingw32 amd64-mingw32msvc
endif
ifeq ($(ARCH),x86)
MINGW_PREFIXES=i586-mingw32msvc i686-w64-mingw32 i686-pc-mingw32
MINGW_PREFIXES=i686-w64-mingw32 i586-mingw32msvc i686-pc-mingw32
endif
ifndef CC
CC=$(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
$(call bin_path, $(MINGW_PREFIX)-gcc)))
CC=$(firstword $(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
$(call bin_path, $(MINGW_PREFIX)-gcc))))
endif
ifndef WINDRES
WINDRES=$(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
$(call bin_path, $(MINGW_PREFIX)-windres)))
WINDRES=$(firstword $(strip $(foreach MINGW_PREFIX, $(MINGW_PREFIXES), \
$(call bin_path, $(MINGW_PREFIX)-windres))))
endif
else
# Some MinGW installations define CC to cc, but don't actually provide cc,
@ -529,9 +585,11 @@ ifdef MINGW
CC=gcc
endif
ifndef WINDRES
WINDRES=windres
endif
endif
# using generic windres if specific one is not present
ifndef WINDRES
WINDRES=windres
endif
ifeq ($(CC),)
@ -580,12 +638,14 @@ ifdef MINGW
endif
LIBS= -lws2_32 -lwinmm -lpsapi
AUTOUPDATER_LIBS += -lwininet
# clang 3.4 doesn't support this
ifneq ("$(CC)", $(findstring "$(CC)", "clang" "clang++"))
CLIENT_LDFLAGS += -mwindows
endif
CLIENT_LIBS = -lgdi32 -lole32
RENDERER_LIBS = -lgdi32 -lole32 -lopengl32
RENDERER_LIBS = -lgdi32 -lole32 -static-libgcc
ifeq ($(USE_FREETYPE),1)
FREETYPE_CFLAGS = -Ifreetype2
@ -597,9 +657,9 @@ ifdef MINGW
ifeq ($(USE_LOCAL_HEADERS),1)
CLIENT_CFLAGS += -DCURL_STATICLIB
ifeq ($(ARCH),x86_64)
CLIENT_LIBS += $(LIBSDIR)/win64/libcurl.a
CLIENT_LIBS += $(LIBSDIR)/win64/libcurl.a -lcrypt32
else
CLIENT_LIBS += $(LIBSDIR)/win32/libcurl.a
CLIENT_LIBS += $(LIBSDIR)/win32/libcurl.a -lcrypt32
endif
else
CLIENT_LIBS += $(CURL_LIBS)
@ -651,13 +711,13 @@ else # ifdef MINGW
ifeq ($(PLATFORM),freebsd)
# flags
BASE_CFLAGS = $(shell env MACHINE_ARCH=$(ARCH) make -f /dev/null -VCFLAGS) \
BASE_CFLAGS = \
-Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes \
-DUSE_ICON -DMAP_ANONYMOUS=MAP_ANON -DREACTION
CLIENT_CFLAGS += $(SDL_CFLAGS)
HAVE_VM_COMPILED = true
OPTIMIZEVM = -O3
OPTIMIZEVM =
OPTIMIZE = $(OPTIMIZEVM) -ffast-math
SHLIBEXT=so
@ -671,7 +731,7 @@ ifeq ($(PLATFORM),freebsd)
CLIENT_LIBS =
CLIENT_LIBS += $(SDL_LIBS)
RENDERER_LIBS = $(SDL_LIBS) -lGL
RENDERER_LIBS = $(SDL_LIBS)
# optional features/libraries
ifeq ($(USE_OPENAL),1)
@ -724,11 +784,11 @@ ifeq ($(PLATFORM),openbsd)
HAVE_VM_COMPILED=true
else
ifeq ($(ARCH),ppc)
BASE_CFLAGS += -maltivec
ALTIVEC_CFLAGS = -maltivec
HAVE_VM_COMPILED=true
endif
ifeq ($(ARCH),ppc64)
BASE_CFLAGS += -maltivec
ALTIVEC_CFLAGS = -maltivec
HAVE_VM_COMPILED=true
endif
ifeq ($(ARCH),sparc64)
@ -762,7 +822,7 @@ ifeq ($(PLATFORM),openbsd)
CLIENT_LIBS =
CLIENT_LIBS += $(SDL_LIBS)
RENDERER_LIBS = $(SDL_LIBS) -lGL
RENDERER_LIBS = $(SDL_LIBS)
ifeq ($(USE_OPENAL),1)
ifneq ($(USE_OPENAL_DLOPEN),1)
@ -808,7 +868,6 @@ ifeq ($(PLATFORM),irix64)
ARCH=mips
CC = c99
MKDIR = mkdir -p
BASE_CFLAGS=-Dstricmp=strcasecmp -Xcpluscomm -woff 1185 \
-I. -I$(ROOT)/usr/include -DREACTION
@ -820,10 +879,12 @@ ifeq ($(PLATFORM),irix64)
SHLIBLDFLAGS=-shared
LIBS=-ldl -lm -lgen
AUTOUPDATER_LIBS += -ldl
# FIXME: The X libraries probably aren't necessary?
CLIENT_LIBS=-L/usr/X11/$(LIB) $(SDL_LIBS) \
-lX11 -lXext -lm
RENDERER_LIBS = $(SDL_LIBS) -lGL
RENDERER_LIBS = $(SDL_LIBS)
else # ifeq IRIX
@ -835,7 +896,7 @@ ifeq ($(PLATFORM),sunos)
CC=gcc
INSTALL=ginstall
MKDIR=gmkdir
MKDIR=gmkdir -p
COPYDIR="/usr/local/share/games/quake3"
ifneq ($(ARCH),x86)
@ -874,11 +935,12 @@ ifeq ($(PLATFORM),sunos)
THREAD_LIBS=-lpthread
LIBS=-lsocket -lnsl -ldl -lm
AUTOUPDATER_LIBS += -ldl
BOTCFLAGS=-O0
CLIENT_LIBS +=$(SDL_LIBS) -lX11 -lXext -liconv -lm
RENDERER_LIBS = $(SDL_LIBS) -lGL
RENDERER_LIBS = $(SDL_LIBS)
else # ifeq sunos
@ -972,6 +1034,16 @@ ifneq ($(BUILD_GAME_QVM),0)
endif
endif
ifneq ($(BUILD_AUTOUPDATER),0)
# PLEASE NOTE that if you run an exe on Windows Vista or later
# with "setup", "install", "update" or other related terms, it
# will unconditionally trigger a UAC prompt, and in the case of
# ioq3 calling CreateProcess() on it, it'll just fail immediately.
# So don't call this thing "autoupdater" here!
AUTOUPDATER_BIN := autosyncerator$(FULLBINEXT)
TARGETS += $(B)/$(AUTOUPDATER_BIN)
endif
ifeq ($(USE_OPENAL),1)
CLIENT_CFLAGS += -DUSE_OPENAL
ifeq ($(USE_OPENAL_DLOPEN),1)
@ -1003,8 +1075,8 @@ ifeq ($(NEED_OPUS),1)
-I$(OPUSDIR)/include -I$(OPUSDIR)/celt -I$(OPUSDIR)/silk \
-I$(OPUSDIR)/silk/float -I$(OPUSFILEDIR)/include
else
OPUS_CFLAGS ?= $(shell pkg-config --silence-errors --cflags opusfile opus || true)
OPUS_LIBS ?= $(shell pkg-config --silence-errors --libs opusfile opus || echo -lopusfile -lopus)
OPUS_CFLAGS ?= $(shell $(PKG_CONFIG) --silence-errors --cflags opusfile opus || true)
OPUS_LIBS ?= $(shell $(PKG_CONFIG) --silence-errors --libs opusfile opus || echo -lopusfile -lopus)
endif
CLIENT_CFLAGS += $(OPUS_CFLAGS)
CLIENT_LIBS += $(OPUS_LIBS)
@ -1016,8 +1088,8 @@ ifeq ($(USE_CODEC_VORBIS),1)
ifeq ($(USE_INTERNAL_VORBIS),1)
CLIENT_CFLAGS += -I$(VORBISDIR)/include -I$(VORBISDIR)/lib
else
VORBIS_CFLAGS ?= $(shell pkg-config --silence-errors --cflags vorbisfile vorbis || true)
VORBIS_LIBS ?= $(shell pkg-config --silence-errors --libs vorbisfile vorbis || echo -lvorbisfile -lvorbis)
VORBIS_CFLAGS ?= $(shell $(PKG_CONFIG) --silence-errors --cflags vorbisfile vorbis || true)
VORBIS_LIBS ?= $(shell $(PKG_CONFIG) --silence-errors --libs vorbisfile vorbis || echo -lvorbisfile -lvorbis)
endif
CLIENT_CFLAGS += $(VORBIS_CFLAGS)
CLIENT_LIBS += $(VORBIS_LIBS)
@ -1028,8 +1100,8 @@ ifeq ($(NEED_OGG),1)
ifeq ($(USE_INTERNAL_OGG),1)
OGG_CFLAGS = -I$(OGGDIR)/include
else
OGG_CFLAGS ?= $(shell pkg-config --silence-errors --cflags ogg || true)
OGG_LIBS ?= $(shell pkg-config --silence-errors --libs ogg || echo -logg)
OGG_CFLAGS ?= $(shell $(PKG_CONFIG) --silence-errors --cflags ogg || true)
OGG_LIBS ?= $(shell $(PKG_CONFIG) --silence-errors --libs ogg || echo -logg)
endif
CLIENT_CFLAGS += $(OGG_CFLAGS)
CLIENT_LIBS += $(OGG_LIBS)
@ -1046,8 +1118,8 @@ endif
ifeq ($(USE_INTERNAL_ZLIB),1)
ZLIB_CFLAGS = -DNO_GZIP -I$(ZDIR)
else
ZLIB_CFLAGS ?= $(shell pkg-config --silence-errors --cflags zlib || true)
ZLIB_LIBS ?= $(shell pkg-config --silence-errors --libs zlib || echo -lz)
ZLIB_CFLAGS ?= $(shell $(PKG_CONFIG) --silence-errors --cflags zlib || true)
ZLIB_LIBS ?= $(shell $(PKG_CONFIG) --silence-errors --libs zlib || echo -lz)
endif
BASE_CFLAGS += $(ZLIB_CFLAGS)
LIBS += $(ZLIB_LIBS)
@ -1058,20 +1130,29 @@ ifeq ($(USE_INTERNAL_JPEG),1)
else
# IJG libjpeg doesn't have pkg-config, but libjpeg-turbo uses libjpeg.pc;
# we fall back to hard-coded answers if libjpeg.pc is unavailable
JPEG_CFLAGS ?= $(shell pkg-config --silence-errors --cflags libjpeg || true)
JPEG_LIBS ?= $(shell pkg-config --silence-errors --libs libjpeg || echo -ljpeg)
JPEG_CFLAGS ?= $(shell $(PKG_CONFIG) --silence-errors --cflags libjpeg || true)
JPEG_LIBS ?= $(shell $(PKG_CONFIG) --silence-errors --libs libjpeg || echo -ljpeg)
BASE_CFLAGS += $(JPEG_CFLAGS)
RENDERER_LIBS += $(JPEG_LIBS)
endif
ifeq ($(USE_FREETYPE),1)
FREETYPE_CFLAGS ?= $(shell pkg-config --silence-errors --cflags freetype2 || true)
FREETYPE_LIBS ?= $(shell pkg-config --silence-errors --libs freetype2 || echo -lfreetype)
FREETYPE_CFLAGS ?= $(shell $(PKG_CONFIG) --silence-errors --cflags freetype2 || true)
FREETYPE_LIBS ?= $(shell $(PKG_CONFIG) --silence-errors --libs freetype2 || echo -lfreetype)
BASE_CFLAGS += -DBUILD_FREETYPE $(FREETYPE_CFLAGS)
RENDERER_LIBS += $(FREETYPE_LIBS)
endif
ifeq ($(USE_AUTOUPDATER),1)
CLIENT_CFLAGS += -DUSE_AUTOUPDATER -DAUTOUPDATER_BIN=\\\"$(AUTOUPDATER_BIN)\\\"
SERVER_CFLAGS += -DUSE_AUTOUPDATER -DAUTOUPDATER_BIN=\\\"$(AUTOUPDATER_BIN)\\\"
endif
ifeq ($(BUILD_AUTOUPDATER),1)
AUTOUPDATER_LIBS += $(LIBTOMCRYPTSRCDIR)/libtomcrypt.a $(TOMSFASTMATHSRCDIR)/libtfm.a
endif
ifeq ("$(CC)", $(findstring "$(CC)", "clang" "clang++"))
BASE_CFLAGS += -Qunused-arguments
endif
@ -1100,6 +1181,11 @@ else
STRIP_FLAG = -s
endif
# https://reproducible-builds.org/specs/source-date-epoch/
ifdef SOURCE_DATE_EPOCH
BASE_CFLAGS += -DPRODUCT_DATE=\\\"$(shell date --date="@$$SOURCE_DATE_EPOCH" "+%b %_d %Y" | sed -e 's/ /\\\ /'g)\\\"
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
@ -1119,16 +1205,26 @@ $(echo_cmd) "CC $<"
$(Q)$(CC) $(NOTSHLIBCFLAGS) $(CFLAGS) $(CLIENT_CFLAGS) $(OPTIMIZE) -o $@ -c $<
endef
define DO_CC_ALTIVEC
$(echo_cmd) "CC $<"
$(Q)$(CC) $(NOTSHLIBCFLAGS) $(CFLAGS) $(CLIENT_CFLAGS) $(OPTIMIZE) $(ALTIVEC_CFLAGS) -o $@ -c $<
endef
define DO_REF_CC
$(echo_cmd) "REF_CC $<"
$(Q)$(CC) $(SHLIBCFLAGS) $(CFLAGS) $(CLIENT_CFLAGS) $(OPTIMIZE) -o $@ -c $<
endef
define DO_REF_CC_ALTIVEC
$(echo_cmd) "REF_CC $<"
$(Q)$(CC) $(SHLIBCFLAGS) $(CFLAGS) $(CLIENT_CFLAGS) $(OPTIMIZE) $(ALTIVEC_CFLAGS) -o $@ -c $<
endef
define DO_REF_STR
$(echo_cmd) "REF_STR $<"
$(Q)rm -f $@
$(Q)echo "const char *fallbackShader_$(notdir $(basename $<)) =" >> $@
$(Q)cat $< | sed 's/^/\"/;s/$$/\\n\"/' >> $@
$(Q)cat $< | sed -e 's/^/\"/;s/$$/\\n\"/' | tr -d '\r' >> $@
$(Q)echo ";" >> $@
endef
@ -1274,6 +1370,8 @@ targets: makedirs
@echo " VERSION: $(VERSION)"
@echo " COMPILE_PLATFORM: $(COMPILE_PLATFORM)"
@echo " COMPILE_ARCH: $(COMPILE_ARCH)"
@echo " HAVE_VM_COMPILED: $(HAVE_VM_COMPILED)"
@echo " PKG_CONFIG: $(PKG_CONFIG)"
@echo " CC: $(CC)"
ifeq ($(PLATFORM),mingw32)
@echo " WINDRES: $(WINDRES)"
@ -1297,6 +1395,9 @@ endif
@echo " CLIENT_LIBS:"
$(call print_wrapped, $(CLIENT_LIBS))
@echo ""
@echo " AUTOUPDATER_LIBS:"
$(call print_wrapped, $(AUTOUPDATER_LIBS))
@echo ""
@echo " Output:"
$(call print_list, $(NAKED_TARGETS))
@echo ""
@ -1320,33 +1421,28 @@ ifneq ($(PLATFORM),darwin)
endif
makedirs:
@if [ ! -d $(BUILD_DIR) ];then $(MKDIR) $(BUILD_DIR);fi
@if [ ! -d $(B) ];then $(MKDIR) $(B);fi
@if [ ! -d $(B)/client ];then $(MKDIR) $(B)/client;fi
@if [ ! -d $(B)/client/opus ];then $(MKDIR) $(B)/client/opus;fi
@if [ ! -d $(B)/client/vorbis ];then $(MKDIR) $(B)/client/vorbis;fi
@if [ ! -d $(B)/renderergl1 ];then $(MKDIR) $(B)/renderergl1;fi
@if [ ! -d $(B)/renderergl2 ];then $(MKDIR) $(B)/renderergl2;fi
@if [ ! -d $(B)/renderergl2/glsl ];then $(MKDIR) $(B)/renderergl2/glsl;fi
@if [ ! -d $(B)/ded ];then $(MKDIR) $(B)/ded;fi
@if [ ! -d $(B)/$(BASEGAME) ];then $(MKDIR) $(B)/$(BASEGAME);fi
@if [ ! -d $(B)/$(BASEGAME)/cgame ];then $(MKDIR) $(B)/$(BASEGAME)/cgame;fi
@if [ ! -d $(B)/$(BASEGAME)/game ];then $(MKDIR) $(B)/$(BASEGAME)/game;fi
@if [ ! -d $(B)/$(BASEGAME)/ui ];then $(MKDIR) $(B)/$(BASEGAME)/ui;fi
@if [ ! -d $(B)/$(BASEGAME)/qcommon ];then $(MKDIR) $(B)/$(BASEGAME)/qcommon;fi
@if [ ! -d $(B)/$(BASEGAME)/vm ];then $(MKDIR) $(B)/$(BASEGAME)/vm;fi
@if [ ! -d $(B)/$(MISSIONPACK) ];then $(MKDIR) $(B)/$(MISSIONPACK);fi
@if [ ! -d $(B)/$(MISSIONPACK)/cgame ];then $(MKDIR) $(B)/$(MISSIONPACK)/cgame;fi
@if [ ! -d $(B)/$(MISSIONPACK)/game ];then $(MKDIR) $(B)/$(MISSIONPACK)/game;fi
@if [ ! -d $(B)/$(MISSIONPACK)/ui ];then $(MKDIR) $(B)/$(MISSIONPACK)/ui;fi
@if [ ! -d $(B)/$(MISSIONPACK)/qcommon ];then $(MKDIR) $(B)/$(MISSIONPACK)/qcommon;fi
@if [ ! -d $(B)/$(MISSIONPACK)/vm ];then $(MKDIR) $(B)/$(MISSIONPACK)/vm;fi
@if [ ! -d $(B)/tools ];then $(MKDIR) $(B)/tools;fi
@if [ ! -d $(B)/tools/asm ];then $(MKDIR) $(B)/tools/asm;fi
@if [ ! -d $(B)/tools/etc ];then $(MKDIR) $(B)/tools/etc;fi
@if [ ! -d $(B)/tools/rcc ];then $(MKDIR) $(B)/tools/rcc;fi
@if [ ! -d $(B)/tools/cpp ];then $(MKDIR) $(B)/tools/cpp;fi
@if [ ! -d $(B)/tools/lburg ];then $(MKDIR) $(B)/tools/lburg;fi
@$(MKDIR) $(B)/autoupdater
@$(MKDIR) $(B)/client/opus
@$(MKDIR) $(B)/client/vorbis
@$(MKDIR) $(B)/renderergl1
@$(MKDIR) $(B)/renderergl2
@$(MKDIR) $(B)/renderergl2/glsl
@$(MKDIR) $(B)/ded
@$(MKDIR) $(B)/$(BASEGAME)/cgame
@$(MKDIR) $(B)/$(BASEGAME)/game
@$(MKDIR) $(B)/$(BASEGAME)/ui
@$(MKDIR) $(B)/$(BASEGAME)/qcommon
@$(MKDIR) $(B)/$(BASEGAME)/vm
@$(MKDIR) $(B)/$(MISSIONPACK)/cgame
@$(MKDIR) $(B)/$(MISSIONPACK)/game
@$(MKDIR) $(B)/$(MISSIONPACK)/ui
@$(MKDIR) $(B)/$(MISSIONPACK)/qcommon
@$(MKDIR) $(B)/$(MISSIONPACK)/vm
@$(MKDIR) $(B)/tools/asm
@$(MKDIR) $(B)/tools/etc
@$(MKDIR) $(B)/tools/rcc
@$(MKDIR) $(B)/tools/cpp
@$(MKDIR) $(B)/tools/lburg
#############################################################################
# QVM BUILD TOOLS
@ -1357,6 +1453,10 @@ ifndef TOOLS_CC
TOOLS_CC = gcc
endif
ifndef YACC
YACC = yacc
endif
TOOLS_OPTIMIZE = -g -Wall -fno-strict-aliasing
TOOLS_CFLAGS += $(TOOLS_OPTIMIZE) \
-DTEMPDIR=\"$(TEMPDIR)\" -DSYSTEM=\"\" \
@ -1369,6 +1469,12 @@ ifeq ($(GENERATE_DEPENDENCIES),1)
TOOLS_CFLAGS += -MMD
endif
define DO_YACC
$(echo_cmd) "YACC $<"
$(Q)$(YACC) $<
$(Q)mv -f y.tab.c $@
endef
define DO_TOOLS_CC
$(echo_cmd) "TOOLS_CC $<"
$(Q)$(TOOLS_CC) $(TOOLS_CFLAGS) -o $@ -c $<
@ -1390,6 +1496,12 @@ LBURGOBJ= \
$(B)/tools/lburg/lburg.o \
$(B)/tools/lburg/gram.o
# override GNU Make built-in rule for converting gram.y to gram.c
%.c: %.y
ifeq ($(USE_YACC),1)
$(DO_YACC)
endif
$(B)/tools/lburg/%.o: $(LBURGDIR)/%.c
$(DO_TOOLS_CC)
@ -1525,6 +1637,26 @@ $(Q3ASM): $(Q3ASMOBJ)
$(Q)$(TOOLS_CC) $(TOOLS_CFLAGS) $(TOOLS_LDFLAGS) -o $@ $^ $(TOOLS_LIBS)
#############################################################################
# AUTOUPDATER
#############################################################################
define DO_AUTOUPDATER_CC
$(echo_cmd) "AUTOUPDATER_CC $<"
$(Q)$(CC) $(CFLAGS) -I$(LIBTOMCRYPTSRCDIR)/src/headers -I$(TOMSFASTMATHSRCDIR)/src/headers $(CURL_CFLAGS) -o $@ -c $<
endef
Q3AUTOUPDATEROBJ = \
$(B)/autoupdater/autoupdater.o
$(B)/autoupdater/%.o: $(AUTOUPDATERSRCDIR)/%.c
$(DO_AUTOUPDATER_CC)
$(B)/$(AUTOUPDATER_BIN): $(Q3AUTOUPDATEROBJ)
$(echo_cmd) "AUTOUPDATER_LD $@"
$(Q)$(CC) $(LDFLAGS) -o $@ $(Q3AUTOUPDATEROBJ) $(AUTOUPDATER_LIBS)
#############################################################################
# CLIENT/SERVER
#############################################################################
@ -1559,6 +1691,7 @@ Q3OBJ = \
$(B)/client/net_ip.o \
$(B)/client/huffman.o \
\
$(B)/client/snd_altivec.o \
$(B)/client/snd_adpcm.o \
$(B)/client/snd_dma.o \
$(B)/client/snd_mem.o \
@ -1628,6 +1761,7 @@ Q3OBJ = \
$(B)/client/sdl_snd.o \
\
$(B)/client/con_log.o \
$(B)/client/sys_autoupdater.o \
$(B)/client/sys_main.o
ifdef MINGW
@ -1711,6 +1845,7 @@ Q3R2STRINGOBJ = \
$(B)/renderergl2/glsl/tonemap_vp.o
Q3ROBJ = \
$(B)/renderergl1/tr_altivec.o \
$(B)/renderergl1/tr_animation.o \
$(B)/renderergl1/tr_backend.o \
$(B)/renderergl1/tr_bsp.o \
@ -2026,6 +2161,9 @@ ifeq ($(HAVE_VM_COMPILED),true)
ifeq ($(ARCH),sparc)
Q3OBJ += $(B)/client/vm_sparc.o
endif
ifeq ($(ARCH),armv7l)
Q3OBJ += $(B)/client/vm_armv7l.o
endif
endif
ifdef MINGW
@ -2050,7 +2188,7 @@ endif
ifneq ($(USE_RENDERER_DLOPEN),0)
$(B)/$(CLIENTBIN)$(FULLBINEXT): $(Q3OBJ) $(LIBSDLMAIN)
$(echo_cmd) "LD $@"
$(Q)$(CC) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) \
$(Q)$(CC) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) $(NOTSHLIBLDFLAGS) \
-o $@ $(Q3OBJ) \
$(LIBSDLMAIN) $(CLIENT_LIBS) $(LIBS)
@ -2066,13 +2204,13 @@ $(B)/renderer_opengl2_$(SHLIBNAME): $(Q3R2OBJ) $(Q3R2STRINGOBJ) $(JPGOBJ)
else
$(B)/$(CLIENTBIN)$(FULLBINEXT): $(Q3OBJ) $(Q3ROBJ) $(JPGOBJ) $(LIBSDLMAIN)
$(echo_cmd) "LD $@"
$(Q)$(CC) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) \
$(Q)$(CC) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) $(NOTSHLIBLDFLAGS) \
-o $@ $(Q3OBJ) $(Q3ROBJ) $(JPGOBJ) \
$(LIBSDLMAIN) $(CLIENT_LIBS) $(RENDERER_LIBS) $(LIBS)
$(B)/$(CLIENTBIN)_opengl2$(FULLBINEXT): $(Q3OBJ) $(Q3R2OBJ) $(Q3R2STRINGOBJ) $(JPGOBJ) $(LIBSDLMAIN)
$(echo_cmd) "LD $@"
$(Q)$(CC) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) \
$(Q)$(CC) $(CLIENT_CFLAGS) $(CFLAGS) $(CLIENT_LDFLAGS) $(LDFLAGS) $(NOTSHLIBLDFLAGS) \
-o $@ $(Q3OBJ) $(Q3R2OBJ) $(Q3R2STRINGOBJ) $(JPGOBJ) \
$(LIBSDLMAIN) $(CLIENT_LIBS) $(RENDERER_LIBS) $(LIBS)
endif
@ -2159,6 +2297,7 @@ Q3DOBJ = \
$(B)/ded/null_snddma.o \
\
$(B)/ded/con_log.o \
$(B)/ded/sys_autoupdater.o \
$(B)/ded/sys_main.o
ifeq ($(ARCH),x86)
@ -2194,6 +2333,9 @@ ifeq ($(HAVE_VM_COMPILED),true)
ifeq ($(ARCH),sparc)
Q3DOBJ += $(B)/ded/vm_sparc.o
endif
ifeq ($(ARCH),armv7l)
Q3DOBJ += $(B)/client/vm_armv7l.o
endif
endif
ifdef MINGW
@ -2214,7 +2356,7 @@ endif
$(B)/$(SERVERBIN)$(FULLBINEXT): $(Q3DOBJ)
$(echo_cmd) "LD $@"
$(Q)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(Q3DOBJ) $(LIBS)
$(Q)$(CC) $(CFLAGS) $(LDFLAGS) $(NOTSHLIBLDFLAGS) -o $@ $(Q3DOBJ) $(LIBS)
@ -2490,6 +2632,9 @@ $(B)/client/%.o: $(ASMDIR)/%.s
$(B)/client/%.o: $(ASMDIR)/%.c
$(DO_CC) -march=k8
$(B)/client/snd_altivec.o: $(CDIR)/snd_altivec.c
$(DO_CC_ALTIVEC)
$(B)/client/%.o: $(CDIR)/%.c
$(DO_CC)
@ -2535,7 +2680,7 @@ $(B)/client/%.o: $(SYSDIR)/%.c
$(B)/client/%.o: $(SYSDIR)/%.m
$(DO_CC)
$(B)/client/%.o: $(SYSDIR)/%.rc
$(B)/client/win_resource.o: $(SYSDIR)/win_resource.rc $(SYSDIR)/win_manifest.xml
$(DO_WINDRES)
@ -2554,6 +2699,9 @@ $(B)/renderergl1/%.o: $(RCOMMONDIR)/%.c
$(B)/renderergl1/%.o: $(RGL1DIR)/%.c
$(DO_REF_CC)
$(B)/renderergl1/tr_altivec.o: $(RGL1DIR)/tr_altivec.c
$(DO_REF_CC_ALTIVEC)
$(B)/renderergl2/glsl/%.c: $(RGL2DIR)/glsl/%.glsl
$(DO_REF_STR)
@ -2592,7 +2740,7 @@ $(B)/ded/%.o: $(SYSDIR)/%.c
$(B)/ded/%.o: $(SYSDIR)/%.m
$(DO_DED_CC)
$(B)/ded/%.o: $(SYSDIR)/%.rc
$(B)/ded/win_resource.o: $(SYSDIR)/win_resource.rc $(SYSDIR)/win_manifest.xml
$(DO_WINDRES)
$(B)/ded/%.o: $(NDIR)/%.c
@ -2600,9 +2748,9 @@ $(B)/ded/%.o: $(NDIR)/%.c
# Extra dependencies to ensure the git version is incorporated
ifeq ($(USE_GIT),1)
$(B)/client/cl_console.o : .git/index
$(B)/client/common.o : .git/index
$(B)/ded/common.o : .git/index
$(B)/client/cl_console.o : .git
$(B)/client/common.o : .git
$(B)/ded/common.o : .git
endif
@ -2701,10 +2849,10 @@ copyfiles: release
@if [ ! -d $(COPYDIR)/$(BASEGAME) ]; then echo "You need to set COPYDIR to where your Quake3 data is!"; fi
ifneq ($(BUILD_GAME_SO),0)
ifneq ($(BUILD_BASEGAME),0)
-$(MKDIR) -p -m 0755 $(COPYDIR)/$(BASEGAME)
-$(MKDIR) -m 0755 $(COPYDIR)/$(BASEGAME)
endif
ifneq ($(BUILD_MISSIONPACK),0)
-$(MKDIR) -p -m 0755 $(COPYDIR)/$(MISSIONPACK)
-$(MKDIR) -m 0755 $(COPYDIR)/$(MISSIONPACK)
endif
endif

View file

@ -1,10 +1,9 @@
BUILD_STANDALONE = 1
BUILD_CLIENT = 1
BUILD_CLIENT_SMP = 1
BUILD_SERVER = 1
BUILD_GAME_SO = 1
BUILD_GAME_QVM = 1
BUILD_MISSIONPACK = 0
USE_RENDERER_DLOPEN = 1
BUILD_RENDERER_REND2 = 1
BUILD_RENDERER_OPENGL2 = 1

View file

@ -1 +0,0 @@
http://wiki.ioquake3.org/NotToDo

View file

@ -11,7 +11,7 @@ The intent of this project is to provide a baseline Quake 3 which may be used
for further development and baseq3 fun.
Some of the major features currently implemented are:
* SDL backend
* SDL 2 backend
* OpenAL sound API support (multiple speaker support and better sound
quality)
* Full x86_64 support on Linux
@ -36,11 +36,15 @@ use a modern copy from http://icculus.org/gtkradiant/.
The original id software readme that accompanied the Q3 source release has been
renamed to id-readme.txt so as to prevent confusion. Please refer to the
web-site for updated status.
website for updated status.
More documentation is on:
More documentation including a Player's Guide and Sysadmin Guide is on:
http://wiki.ioquake3.org/
If you've got issues that you aren't sure are worth filing as bugs, or just
want to chat, please visit our forums:
http://discourse.ioquake.org
# Compilation and installation
For *nix
@ -89,6 +93,7 @@ Makefile.local:
SERVERBIN - rename 'ioq3ded' server binary
CLIENTBIN - rename 'ioquake3' client binary
USE_RENDERER_DLOPEN - build and use the renderer in a library
USE_YACC - use yacc to update code/tools/lcc/lburg/gram.c
BASEGAME - rename 'baseq3'
BASEGAME_CFLAGS - custom CFLAGS for basegame
MISSIONPACK - rename 'missionpack'
@ -101,13 +106,11 @@ Makefile.local:
USE_CODEC_OPUS - enable Ogg Opus support
USE_MUMBLE - enable Mumble support
USE_VOIP - enable built-in VoIP support
USE_FREETYPE - enable FreeType support for rendering fonts
USE_INTERNAL_LIBS - build internal libraries instead of dynamically
linking against system libraries; this just sets
the default for USE_INTERNAL_SPEEX etc.
the default for USE_INTERNAL_ZLIB etc.
and USE_LOCAL_HEADERS
USE_INTERNAL_SPEEX - build internal speex library instead of dynamically
linking against system libspeex
USE_FREETYPE - enable FreeType support for rendering fonts
USE_INTERNAL_ZLIB - build and link against internal zlib
USE_INTERNAL_JPEG - build and link against internal JPEG library
USE_INTERNAL_OGG - build and link against internal ogg library
@ -137,6 +140,12 @@ The defaults for these variables differ depending on the target platform.
behaviour, 0 for standard q3
cl_mouseAccelOffset - Tuning the acceleration curve, see below
con_autochat - Set to 0 to disable sending console input
text as chat when there is not a slash
at the beginning
con_autoclear - Set to 0 to disable clearing console
input text when console is closed
in_joystickUseAnalog - Do not translate joystick axis events
to keyboard commands
@ -244,7 +253,7 @@ The defaults for these variables differ depending on the target platform.
ipv6 servers on the local network
net_mcastiface - outgoing interface to use for scan
r_allowResize - make window resizable (SDL only)
r_allowResize - make window resizable
r_ext_texture_filter_anisotropic - anisotropic texture filtering
r_zProj - distance of observer camera to projection
plane in quake3 standard units
@ -324,6 +333,8 @@ The defaults for these variables differ depending on the target platform.
cvar_modified [filter] - list modified cvars, can filter results (such as "r*"
for renderer cvars) like cvarlist which lists all cvars
addbot random - the bot name "random" now selects a random bot
```
@ -480,6 +491,7 @@ The focus for ioq3 is to develop a stable base suitable for further development
and provide players with the same Quake 3 experience they've had for years.
We do have graphical improvements with the new renderer, but they are off by default.
See opengl2-readme.md for more information.
# Building Official Installers
@ -502,13 +514,11 @@ but we have some general guidelines:
providing pak0.pk3 and the patch pk3s are not referred to or included in the
installer.
* Please include at least an SDL so/dylib/dll on every platform.
* Please include at least a libSDL2 so/dylib/dll on every platform.
* Please include an OpenAL so/dylib/dll, since every platform should be using
it by now.
* Please contact the mailing list when you've made your installer.
* Please be prepared to alter your installer on the whim of the maintainers.
* Your installer will be mirrored to an "official" directory, thus making it

165
autoupdater-readme.txt Normal file
View file

@ -0,0 +1,165 @@
The updater program's code is public domain. The rest of ioquake3 is not.
The source code to the autoupdater is in the code/autoupdater directory.
There is a small piece of code in ioquake3 itself at startup, too; this is
in code/sys/sys_autoupdater.c ...
(This is all Unix terminology, but similar approaches on Windows apply.)
The updater is a separate program, written in C, with no dependencies on
the game. It (statically) links to libcurl and uses the C runtime, but
otherwise has no external dependencies. It has to be a single binary file
with no shared libraries.
The basic flow looks like this:
- The game launches as usual.
- Right after main() starts, the game creates a pipe, forks off a new process,
and execs the updater in that process. The game won't ever touch the pipe
again. It's just there to block the child app until the game terminates.
- The updater has no UI. It writes a log file.
- The updater downloads a manifest from a known URL over https://, using
libCurl. The base URL is platform-specific (it might be
https://example.com/mac/, or https://example.com/linux-x86/, whatever).
The url might have other features, like a updater version or a specific
product name, etc.
The manifest is at $BASEURL/manifest.txt
- The updater also downloads $BASEURL/manifest.txt.sig, which is a digital
signature for the manifest. It checks the manifest against this signature
and a known public RSA key; if the manifest doesn't match the signature,
the updater refuses to continue.
- The manifest looks like this: three lines per item...
Contents/MacOS/baseq3/uix86_64.dylib
332428
a49bbe77f8eb6c195265ea136f881f7830db58e4d8a883b27f59e1e23e396a20
- That's the file's path, its size in bytes, and an sha256 hash of the data.
- The file will be at this path under the base url on the webserver.
- The manifest only lists files that ever needed updating; it's not necessary
to list every file in the game's installation (unless you want to allow the
entire game to download).
- The updater will check each item in the manifest:
- Does the file not exist in the install? Needs downloading.
- Does the file have a different size? Needs downloading.
- Does the file have a different sha256sum? Needs downloading.
- Otherwise, file is up to date, leave it alone.
- If an item needs downloading, do these same checks against the file in the
download directory (if it's already there and matches, don't download again.)
- Download necessary files with libcurl, put it in a download directory.
- The downloaded file is also checked for size and sha256 vs the manifest, to
make sure there was no corruption or confusion. If a downloaded file doesn't
match what was expected, the updater aborts and will try again next time.
This could fail checksum due to i/o errors and compromised security, but
it might just be that a new version was being published and bad luck
happened, and a retry later could correct everything.
- If the updater itself needs upgrading, we deal with that first. It's
downloaded, then the updater relaunches from the downloaded binary with
a special command line. That relaunched process copies itself to the proper
location, and then relaunches _again_ to restart the normal updating
process with the new updater in its correct position.
- Once the downloads are complete and the updater itself doesn't need
upgrading, we are ready to start the normal upgrade. Since we can't replace
executables on some platforms while they are running, and swapping out a
game's data files at runtime isn't wise in general, the updater will now
block until the game terminates. It does this by reading on the pipe that
the game created when forking the updater; since the game never writes
anything to this pipe, it causes the updater to block until the pipe closes.
Since the game never deliberately closes the pipe either, it remains open
until the OS forcibly closes it as the game process terminates. Being an
unnamed pipe, it just vaporizes at this point, leaving no state that might
accidentally hang us up later, like a global semaphore or whatnot. This
technique also lets us localize the game's code changes to one small block
of C code, with no need to manage these resources elsewhere.
- As a sanity check, the updater will also kill(game_process_id, 0) until it
fails, sleeping for 100 milliseconds between each attempt, in case the
process is still being cleaned up by the OS after closing the pipe.
- Once the updater is confident the game process is gone, it will start
upgrading the appropriate files. It does this in two steps: it moves
the old file to a "rollback" directory so it's out of the way but still
available, then it moves the newly-downloaded file into place. Since these
are all simple renames and not copies, this can move fast. Any missing
parent directories are created, in case the update is adding a new file
in a directory that didn't previously exist.
- If something goes wrong at this point (file i/o error, etc), the updater
will roll back the changes by deleting the updated files, and moving the
files in the "rollback" directory back to their original locations. Then
the updater aborts.
- If nothing went wrong, the rollback files are deleted. And we are officially
up to date! The updater terminates.
The updater is designed to fail at any point. If a download fails, it'll
pick up and try again next time, etc. Completed downloads will remain, so it
will just need to download any missing/incomplete files.
The server side just needs to be able to serve static files over HTTPS from
any standard Apache/nginx/whatever process.
Failure points:
- If the updater fails when still downloading data, it just picks up on next
restart.
- If the updater fails when replacing files, it rolls back any changes it has
made.
- If the updater fails when rolling back, then running the updater again after
fixing the specific problem (disk error, etc?) will redownload and replace
any files that were left in an uncertain state. The only true point of
risk is crashing during a rollback and then having the updater bricked for
some reason, but that's an extremely small surface area, knock on wood.
- If the updater crashes or totally bricks, ioquake3 should just keep being
ioquake3. It will still launch and play, even if the updater is quietly
segfaulting in the background on startup.
- If an update bricks ioquake3 to the point where it can't run the updater,
running the updater directly should let it recover (assuming a future update
fixes the problem).
- If the download server is compromised, they would need the private key
(not stored on the download server) to alter the manifest to serve
compromised files to players. If they try to change a file or the manifest,
the updater will know to abort without updating anything.
- If the private key is compromised, we generate a new one, ship new
installers with an updated public key, and re-sign the manifest with the
new private key. Existing installations will never update again until they
do a fresh install, or at least update their copy of the public key.
How manifest signing works:
Some admin will generate a public/private key with the rsa_make_keys program,
keeping the private key secret. Using the private key and the rsa_sign
program, the admin will sign the manifest, generating manifest.txt.sig.
The public key ships with the game (adding 270 bytes to the download), the
.sig is downloaded with the manifest by the autoupdater (256 bytes extra
download), then the autoupdater checks the manifest against the signature
with the public key. if the signature isn't valid (the manifest was tampered
with or corrupt), the autoupdater refuses to continue.
If the manifest is to be trusted, it lists sha256 checksums for every file to
download, so there's no need to sign every file; if they can't tamper with the
manifest, they can't tamper with any other file to be updated since the file's
listed sha256 won't match.
If the private key is compromised, we generate new keys and ship new
installers, so new installations will be able to update but existing ones
will need to do a new install to keep getting updates. Don't let the private
key get compromised. The private key doesn't go on a public server. Maybe it
doesn't even live on the admin's laptop hard drive.
If the download server is compromised and serving malware, the autoupdater
will reject it outright if they haven't compromised the private key, generated
a new manifest, and signed it with the private key.
Items to consider for future revisions:
- Maybe put a limit on the number manifest downloads, so we only check once
every hour? Every day?
- Channels? Stable (what everyone gets by default), Nightly (once a day),
Experimental (some other work-in-progress branch), Bloody (literally the
latest commit).
- Let mods update, separate from the main game?
Questions? Ask Ryan: icculus@icculus.org
--ryan.

File diff suppressed because it is too large Load diff

8
code/autoupdater/rsa_tools/.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
crypt-*.tar.bz2
tfm-*.tar.xz
libtomcrypt-*
tomsfastmath-*
rsa_make_keys
rsa_sign
rsa_verify
*.exe

View file

@ -0,0 +1,79 @@
#!/bin/bash
TFMVER=0.13.1
LTCVER=1.17
set -e
OSTYPE=`uname -s`
if [ "$OSTYPE" = "Linux" ]; then
NCPU=`cat /proc/cpuinfo |grep vendor_id |wc -l`
let NCPU=$NCPU+1
elif [ "$OSTYPE" = "Darwin" ]; then
NCPU=`sysctl -n hw.ncpu`
export CFLAGS="$CFLAGS -mmacosx-version-min=10.7 -DMAC_OS_X_VERSION_MIN_REQUIRED=1070"
export LDFLAGS="$LDFLAGS -mmacosx-version-min=10.7"
elif [ "$OSTYPE" = "SunOS" ]; then
NCPU=`/usr/sbin/psrinfo |wc -l |sed -e 's/^ *//g;s/ *$//g'`
else
NCPU=1
fi
if [ -z "$NCPU" ]; then
NCPU=1
elif [ "$NCPU" = "0" ]; then
NCPU=1
fi
if [ ! -f tfm-$TFMVER.tar.xz ]; then
echo "Downloading TomsFastMath $TFMVER sources..."
curl -L -o tfm-$TFMVER.tar.xz https://github.com/libtom/tomsfastmath/releases/download/v$TFMVER/tfm-$TFMVER.tar.xz || exit 1
fi
if [ ! -f ./crypt-$LTCVER.tar.bz2 ]; then
echo "Downloading LibTomCrypt $LTCVER sources..."
curl -L -o crypt-$LTCVER.tar.bz2 https://github.com/libtom/libtomcrypt/releases/download/$LTCVER/crypt-$LTCVER.tar.bz2 || exit 1
fi
if [ ! -d tomsfastmath-$TFMVER ]; then
echo "Checking TomsFastMath archive hash..."
if [ "`shasum -a 256 tfm-$TFMVER.tar.xz |awk '{print $1;}'`" != "47c97a1ada3ccc9fcbd2a8a922d5859a84b4ba53778c84c1d509c1a955ac1738" ]; then
echo "Uhoh, tfm-$TFMVER.tar.xz does not have the sha256sum we expected!"
exit 1
fi
echo "Unpacking TomsFastMath $TFMVER sources..."
tar -xJvvf ./tfm-$TFMVER.tar.xz
fi
if [ ! -d libtomcrypt-$LTCVER ]; then
if [ "`shasum -a 256 crypt-$LTCVER.tar.bz2 |awk '{print $1;}'`" != "e33b47d77a495091c8703175a25c8228aff043140b2554c08a3c3cd71f79d116" ]; then
echo "Uhoh, crypt-$LTCVER.tar.bz2 does not have the sha256sum we expected!"
exit 1
fi
echo "Unpacking LibTomCrypt $LTCVER sources..."
tar -xjvvf ./crypt-$LTCVER.tar.bz2
fi
echo
echo
echo "Will use make -j$NCPU. If this is wrong, check NCPU at top of script."
echo
echo
set -e
set -x
# Some compilers can't handle the ROLC inline asm; just turn it off.
cd tomsfastmath-$TFMVER
make -j$NCPU
cd ..
export CFLAGS="$CFLAGS -DTFM_DESC -DLTC_NO_ROLC -I ../tomsfastmath-$TFMVER/src/headers"
cd libtomcrypt-$LTCVER
make -j$NCPU
cd ..
set +x
echo "All done."
# end of build-libtom-unix.sh ...

View file

@ -0,0 +1,33 @@
#!/bin/bash
export TFMDIR="tomsfastmath-0.13.1"
export LTCDIR="libtomcrypt-1.17"
OSTYPE=`uname -s`
if [ -z "$CC" ]; then
if [ "`uname -o`" = "Cygwin" ]; then
export CC=/usr/bin/i686-w64-mingw32-gcc
else
export CC=cc
fi
fi
function build {
if [ "$OSTYPE" = "Darwin" ]; then
$CC -mmacosx-version-min=10.7 -DMAC_OS_X_VERSION_MIN_REQUIRED=1070 -I $TFMDIR/src/headers -I $LTCDIR/src/headers -o "$1" -Wall -O3 "$1.c" rsa_common.c $LTCDIR/libtomcrypt.a $TFMDIR/libtfm.a
else
$CC -I $TFMDIR/src/headers -I $LTCDIR/src/headers -o "$1" -Wall -O3 "$1.c" rsa_common.c $LTCDIR/libtomcrypt.a $TFMDIR/libtfm.a
fi
}
set -e
set -x
./build-libtom-unix.sh
build rsa_make_keys
build rsa_sign
build rsa_verify
set +x
echo "rsa_tools are compiled!"

View file

@ -0,0 +1,61 @@
#include "rsa_common.h"
void fail(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fputs("\n", stderr);
fflush(stderr);
exit(1);
}
void write_file(const char *fname, const void *buf, const unsigned long len)
{
FILE *io = fopen(fname, "wb");
if (!io) {
fail("Can't open '%s' for writing: %s", fname, strerror(errno));
}
if (fwrite(buf, len, 1, io) != 1) {
fail("Couldn't write '%s': %s", fname, strerror(errno));
}
if (fclose(io) != 0) {
fail("Couldn't flush '%s' to disk: %s", fname, strerror(errno));
}
}
void read_file(const char *fname, void *buf, unsigned long *len)
{
ssize_t br;
FILE *io = fopen(fname, "rb");
if (!io) {
fail("Can't open '%s' for reading: %s", fname, strerror(errno));
}
br = fread(buf, 1, *len, io);
if (ferror(io)) {
fail("Couldn't read '%s': %s", fname, strerror(errno));
} else if (!feof(io)) {
fail("Buffer too small to read '%s'", fname);
}
fclose(io);
*len = (unsigned long) br;
}
void read_rsakey(rsa_key *key, const char *fname)
{
unsigned char buf[4096];
unsigned long len = sizeof (buf);
int rc;
read_file(fname, buf, &len);
if ((rc = rsa_import(buf, len, key)) != CRYPT_OK) {
fail("rsa_import for '%s' failed: %s", fname, error_to_string(rc));
}
}

View file

@ -0,0 +1,30 @@
#ifndef _INCL_RSA_COMMON_H_
#define _INCL_RSA_COMMON_H_ 1
#include <stdarg.h>
#include <stdio.h>
#include <errno.h>
#define TFM_DESC
#define LTC_NO_ROLC
#include "tomcrypt.h"
#define SALT_LEN 8
#if defined(__GNUC__) || defined(__clang__)
#define NEVER_RETURNS __attribute__((noreturn))
#define PRINTF_FUNC(fmtargnum, dotargnum) __attribute__ (( format( __printf__, fmtargnum, dotargnum )))
#else
#define NEVER_RETURNS
#define PRINTF_FUNC(fmtargnum, dotargnum)
#endif
void fail(const char *fmt, ...) NEVER_RETURNS PRINTF_FUNC(1, 2);
void write_file(const char *fname, const void *buf, const unsigned long len);
void read_file(const char *fname, void *buf, unsigned long *len);
void read_rsakey(rsa_key *key, const char *fname);
#endif
/* end of rsa_common.h ... */

View file

@ -0,0 +1,45 @@
#include "rsa_common.h"
static void write_rsakey(rsa_key *key, const int type, const char *fname)
{
unsigned char buf[4096];
unsigned long len = sizeof (buf);
int rc;
if ((rc = rsa_export(buf, &len, type, key)) != CRYPT_OK) {
fail("rsa_export for '%s' failed: %s", fname, error_to_string(rc));
}
write_file(fname, buf, len);
}
int main(int argc, char **argv)
{
int rc = 0;
prng_state prng;
int prng_index;
rsa_key key;
ltc_mp = tfm_desc;
prng_index = register_prng(&sprng_desc); /* (fortuna_desc is a good choice if your platform's PRNG sucks.) */
if (prng_index == -1) {
fail("Failed to register a RNG");
}
if ((rc = rng_make_prng(128, prng_index, &prng, NULL)) != CRYPT_OK) {
fail("rng_make_prng failed: %s", error_to_string(rc));
}
if ((rc = rsa_make_key(&prng, prng_index, 256, 65537, &key)) != CRYPT_OK) {
fail("rng_make_key failed: %s", error_to_string(rc));
}
write_rsakey(&key, PK_PRIVATE, "privatekey.bin");
write_rsakey(&key, PK_PUBLIC, "publickey.bin");
rsa_free(&key);
return 0;
}
/* end of rsa_make_keys.c ... */

View file

@ -0,0 +1,75 @@
#include "rsa_common.h"
static void sign_file(const char *fname, rsa_key *key, prng_state *prng, const int prng_index, const int hash_index)
{
const size_t sigfnamelen = strlen(fname) + 5;
char *sigfname = (char *) malloc(sigfnamelen);
unsigned char hash[256];
unsigned long hashlen = sizeof (hash);
unsigned char sig[1024];
unsigned long siglen = sizeof (sig);
int rc = 0;
int status = 0;
if (!sigfname) {
fail("out of memory");
}
if ((rc = hash_file(hash_index, fname, hash, &hashlen)) != CRYPT_OK) {
fail("hash_file for '%s' failed: %s", fname, error_to_string(rc));
}
if ((rc = rsa_sign_hash(hash, hashlen, sig, &siglen, prng, prng_index, hash_index, SALT_LEN, key)) != CRYPT_OK) {
fail("rsa_sign_hash for '%s' failed: %s", fname, error_to_string(rc));
}
if ((rc = rsa_verify_hash(sig, siglen, hash, hashlen, hash_index, SALT_LEN, &status, key)) != CRYPT_OK) {
fail("rsa_verify_hash for '%s' failed: %s", fname, error_to_string(rc));
}
if (!status) {
fail("Generated signature isn't valid! Bug in the program!");
}
snprintf(sigfname, sigfnamelen, "%s.sig", fname);
write_file(sigfname, sig, siglen);
free(sigfname);
}
int main(int argc, char **argv)
{
int rc = 0;
prng_state prng;
int prng_index, hash_index;
rsa_key key;
int i;
ltc_mp = tfm_desc;
prng_index = register_prng(&sprng_desc); /* (fortuna_desc is a good choice if your platform's PRNG sucks.) */
if (prng_index == -1) {
fail("Failed to register a RNG");
}
hash_index = register_hash(&sha256_desc);
if (hash_index == -1) {
fail("Failed to register sha256 hasher");
}
if ((rc = rng_make_prng(128, prng_index, &prng, NULL)) != CRYPT_OK) {
fail("rng_make_prng failed: %s", error_to_string(rc));
}
read_rsakey(&key, "privatekey.bin");
for (i = 1; i < argc; i++) {
sign_file(argv[i], &key, &prng, prng_index, hash_index);
}
rsa_free(&key);
return 0;
}
/* end of rsa_sign.c ... */

View file

@ -0,0 +1,60 @@
#include "rsa_common.h"
static void verify_file(const char *fname, rsa_key *key, const int hash_index)
{
const size_t sigfnamelen = strlen(fname) + 5;
char *sigfname = (char *) malloc(sigfnamelen);
unsigned char hash[256];
unsigned long hashlen = sizeof (hash);
unsigned char sig[1024];
unsigned long siglen = sizeof (sig);
int status = 0;
int rc = 0;
if (!sigfname) {
fail("out of memory");
}
snprintf(sigfname, sigfnamelen, "%s.sig", fname);
read_file(sigfname, sig, &siglen);
free(sigfname);
if ((rc = hash_file(hash_index, fname, hash, &hashlen)) != CRYPT_OK) {
fail("hash_file for '%s' failed: %s", fname, error_to_string(rc));
}
if ((rc = rsa_verify_hash(sig, siglen, hash, hashlen, hash_index, SALT_LEN, &status, key)) != CRYPT_OK) {
fail("rsa_verify_hash for '%s' failed: %s", fname, error_to_string(rc));
}
if (!status) {
fail("Invalid signature for '%s'! Don't trust this file!", fname);
}
}
int main(int argc, char **argv)
{
int hash_index;
rsa_key key;
int i;
ltc_mp = tfm_desc;
hash_index = register_hash(&sha256_desc);
if (hash_index == -1) {
fail("Failed to register sha256 hasher");
}
read_rsakey(&key, "publickey.bin");
for (i = 1; i < argc; i++) {
verify_file(argv[i], &key, hash_index);
}
rsa_free(&key);
return 0;
}
/* end of rsa_verify.c ... */

View file

@ -0,0 +1,17 @@
#!/bin/bash
if [ -f privatekey.bin ]; then
echo "move your existing keys out of the way."
exit 1
fi
( ./rsa_make_keys && echo "key making okay") || echo "key making NOT okay"
echo "The quick brown fox jumped over the lazy dog." >testmsg.txt
( ./rsa_sign testmsg.txt && echo "signing okay" ) || echo "signing NOT okay"
( ./rsa_verify testmsg.txt && echo "basic verifying okay" ) || echo "basic verifying NOT okay"
echo "The quick brown fox jumped over the lazy dog!" >testmsg.txt
( ./rsa_verify testmsg.txt 2>/dev/null && echo "tamper test NOT okay" ) || echo "tamper test okay"
echo "The quick brown fox jumped over the lazy dog." >testmsg.txt
( ./rsa_verify testmsg.txt && echo "reverify okay" ) || echo "reverify NOT okay"
rm -f testmsg.txt testmsg.txt.sig publickey.bin privatekey.bin

View file

@ -65,8 +65,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define FACE_LADDER 2 //ladder
#define FACE_GROUND 4 //standing on ground when in this face
#define FACE_GAP 8 //gap in the ground
#define FACE_LIQUID 16 //face seperating two areas with liquid
#define FACE_LIQUIDSURFACE 32 //face seperating liquid and air
#define FACE_LIQUID 16 //face separating two areas with liquid
#define FACE_LIQUIDSURFACE 32 //face separating liquid and air
#define FACE_BRIDGE 64 //can walk over this face if bridge is closed
//area contents
@ -191,7 +191,7 @@ typedef struct aas_edge_s
//edge index, negative if vertexes are reversed
typedef int aas_edgeindex_t;
//a face bounds an area, often it will also seperate two areas
//a face bounds an area, often it will also separate two areas
typedef struct aas_face_s
{
int planenum; //number of the plane this face is in

View file

@ -70,7 +70,7 @@ typedef struct bsp_entity_s
bsp_epair_t *epairs;
} bsp_entity_t;
//id Sofware BSP data
//id Software BSP data
typedef struct bsp_s
{
//true when bsp file is loaded

View file

@ -152,7 +152,7 @@ int AAS_UpdatePortal(int areanum, int clusternum)
{
//remove the cluster portal flag contents
aasworld.areasettings[areanum].contents &= ~AREACONTENTS_CLUSTERPORTAL;
Log_Write("portal area %d is seperating more than two clusters\r\n", areanum);
Log_Write("portal area %d is separating more than two clusters\r\n", areanum);
return qfalse;
} //end else
if (aasworld.portalindexsize >= AAS_MAX_PORTALINDEXSIZE)
@ -1168,7 +1168,7 @@ void AAS_RemoveNotClusterClosingPortals(void)
if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL) continue;
//if the area already has a cluster set
if (aasworld.areasettings[otherareanum].cluster) continue;
//another cluster is seperated by this portal
//another cluster is separated by this portal
numseperatedclusters++;
//flood the cluster
AAS_FloodCluster_r(otherareanum, numseperatedclusters);
@ -1185,13 +1185,13 @@ void AAS_RemoveNotClusterClosingPortals(void)
if (aasworld.areasettings[otherareanum].contents & AREACONTENTS_CLUSTERPORTAL) continue;
//if the area already has a cluster set
if (aasworld.areasettings[otherareanum].cluster) continue;
//another cluster is seperated by this portal
//another cluster is separated by this portal
numseperatedclusters++;
//flood the cluster
AAS_FloodCluster_r(otherareanum, numseperatedclusters);
AAS_FloodClusterReachabilities(numseperatedclusters);
} //end for
//a portal must seperate no more and no less than 2 clusters
//a portal must separate no more and no less than 2 clusters
if (numseperatedclusters != 2)
{
aasworld.areasettings[i].contents &= ~AREACONTENTS_CLUSTERPORTAL;

View file

@ -774,4 +774,5 @@ void AAS_FloodAreas(vec3_t origin)
areanum = AAS_PointAreaNum(origin);
cluster = AAS_AreaCluster(areanum);
AAS_FloodAreas_r(areanum, cluster, done);
FreeMemory(done);
}

View file

@ -39,10 +39,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define DF_AASENTCLIENT(x) (x - aasworld.entities - 1)
#define DF_CLIENTAASENT(x) (&aasworld.entities[x + 1])
#ifndef MAX_PATH
#define MAX_PATH MAX_QPATH
#endif
//structure to link entities to areas and areas to entities
typedef struct aas_link_s
{
@ -187,8 +183,8 @@ typedef struct aas_s
float time;
int numframes;
//name of the aas file
char filename[MAX_PATH];
char mapname[MAX_PATH];
char filename[MAX_QPATH];
char mapname[MAX_QPATH];
//bounding boxes
int numbboxes;
aas_bbox_t *bboxes;

View file

@ -390,9 +390,9 @@ int AAS_NearestEntity(vec3_t origin, int modelindex)
ent = &aasworld.entities[i];
if (ent->i.modelindex != modelindex) continue;
VectorSubtract(ent->i.origin, origin, dir);
if (abs(dir[0]) < 40)
if (fabsf(dir[0]) < 40)
{
if (abs(dir[1]) < 40)
if (fabsf(dir[1]) < 40)
{
dist = VectorLength(dir);
if (dist < bestdist)

View file

@ -61,8 +61,8 @@ void AAS_SwapAASData(void)
aasworld.bboxes[i].flags = LittleLong(aasworld.bboxes[i].flags);
for (j = 0; j < 3; j++)
{
aasworld.bboxes[i].mins[j] = LittleLong(aasworld.bboxes[i].mins[j]);
aasworld.bboxes[i].maxs[j] = LittleLong(aasworld.bboxes[i].maxs[j]);
aasworld.bboxes[i].mins[j] = LittleFloat(aasworld.bboxes[i].mins[j]);
aasworld.bboxes[i].maxs[j] = LittleFloat(aasworld.bboxes[i].maxs[j]);
} //end for
} //end for
//vertexes

View file

@ -220,10 +220,9 @@ void AAS_ProjectPointOntoVector( vec3_t point, vec3_t vStart, vec3_t vEnd, vec3_
int AAS_LoadFiles(const char *mapname)
{
int errnum;
char aasfile[MAX_PATH];
// char bspfile[MAX_PATH];
char aasfile[MAX_QPATH];
strcpy(aasworld.mapname, mapname);
Q_strncpyz(aasworld.mapname, mapname, sizeof(aasworld.mapname));
//NOTE: first reset the entity links into the AAS areas and BSP leaves
// the AAS link heap and BSP link heap are reset after respectively the
// AAS file and BSP file are loaded
@ -232,17 +231,17 @@ int AAS_LoadFiles(const char *mapname)
AAS_LoadBSPFile();
//load the aas file
Com_sprintf(aasfile, MAX_PATH, "maps/%s.aas", mapname);
Com_sprintf(aasfile, sizeof(aasfile), "maps/%s.aas", mapname);
errnum = AAS_LoadAASFile(aasfile);
if (errnum != BLERR_NOERROR)
return errnum;
botimport.Print(PRT_MESSAGE, "loaded %s\n", aasfile);
strncpy(aasworld.filename, aasfile, MAX_PATH);
Q_strncpyz(aasworld.filename, aasfile, sizeof(aasworld.filename));
return BLERR_NOERROR;
} //end of the function AAS_LoadFiles
//===========================================================================
// called everytime a map changes
// called every time a map changes
//
// Parameter: -
// Returns: -

View file

@ -168,7 +168,7 @@ int AAS_AgainstLadder(vec3_t origin)
//get the plane the face is in
plane = &aasworld.planes[face->planenum ^ side];
//if the origin is pretty close to the plane
if (abs(DotProduct(plane->normal, origin) - plane->dist) < 3)
if (fabsf(DotProduct(plane->normal, origin) - plane->dist) < 3)
{
if (AAS_PointInsideFace(abs(facenum), origin, 0.1f)) return qtrue;
} //end if
@ -553,7 +553,7 @@ int AAS_ClientMovementPrediction(struct aas_clientmove_s *move,
//if on the ground or swimming
if (onground || swimming)
{
friction = swimming ? phys_friction : phys_waterfriction;
friction = swimming ? phys_waterfriction : phys_friction;
//apply friction
VectorScale(frame_test_vel, 1/frametime, frame_test_vel);
AAS_ApplyFriction(frame_test_vel, friction, phys_stopspeed, frametime);

View file

@ -439,7 +439,7 @@ int AAS_BestReachableArea(vec3_t origin, vec3_t mins, vec3_t maxs, vec3_t goalor
//VectorSubtract(absmaxs, bbmins, absmaxs);
//link an invalid (-1) entity
areas = AAS_LinkEntityClientBBox(absmins, absmaxs, -1, PRESENCE_CROUCH);
//get the reachable link arae
//get the reachable link area
areanum = AAS_BestReachableLinkArea(areas);
//unlink the invalid entity
AAS_UnlinkFromAreas(areas);
@ -1416,7 +1416,7 @@ int AAS_Reachability_Step_Barrier_WaterJump_WalkOffLedge(int area1num, int area2
//if there IS water the sv_maxwaterjump height below the bestend point
if (aasworld.areasettings[AAS_PointAreaNum(testpoint)].areaflags & AREA_LIQUID)
{
//don't create rediculous water jump reachabilities from areas very far below
//don't create ridiculous water jump reachabilities from areas very far below
//the water surface
if (water_bestdist < aassettings.phys_maxwaterjump + 24)
{
@ -2465,8 +2465,8 @@ int AAS_Reachability_Ladder(int area1num, int area2num)
VectorMA(area1point, -32, dir, area1point);
VectorMA(area2point, 32, dir, area2point);
//
ladderface1vertical = abs(DotProduct(plane1->normal, up)) < 0.1;
ladderface2vertical = abs(DotProduct(plane2->normal, up)) < 0.1;
ladderface1vertical = fabsf(DotProduct(plane1->normal, up)) < 0.1;
ladderface2vertical = fabsf(DotProduct(plane2->normal, up)) < 0.1;
//there's only reachability between vertical ladder faces
if (!ladderface1vertical && !ladderface2vertical) return qfalse;
//if both vertical ladder faces
@ -2474,7 +2474,7 @@ int AAS_Reachability_Ladder(int area1num, int area2num)
//and the ladder faces do not make a sharp corner
&& DotProduct(plane1->normal, plane2->normal) > 0.7
//and the shared edge is not too vertical
&& abs(DotProduct(sharededgevec, up)) < 0.7)
&& fabsf(DotProduct(sharededgevec, up)) < 0.7)
{
//create a new reachability link
lreach = AAS_AllocReachability();
@ -2599,7 +2599,7 @@ int AAS_Reachability_Ladder(int area1num, int area2num)
if (face2->faceflags & FACE_LADDER)
{
plane2 = &aasworld.planes[face2->planenum];
if (abs(DotProduct(plane2->normal, up)) < 0.1) break;
if (fabsf(DotProduct(plane2->normal, up)) < 0.1) break;
} //end if
} //end for
//if from another area without vertical ladder faces
@ -3054,7 +3054,7 @@ void AAS_Reachability_Elevator(void)
bottomorg[2] += 24;
} //end else
//look at adjacent areas around the top of the plat
//make larger steps to outside the plat everytime
//make larger steps to outside the plat every time
for (n = 0; n < 3; n++)
{
for (k = 0; k < 3; k++)

View file

@ -1603,7 +1603,7 @@ int AAS_AreaRouteToGoalArea(int areanum, vec3_t origin, int goalareanum, int tra
*reachnum = 0;
return qtrue;
}
//
//check !AAS_AreaReachability(areanum) with custom developer-only debug message
if (areanum <= 0 || areanum >= aasworld.numareas)
{
if (botDeveloper)
@ -1620,6 +1620,10 @@ int AAS_AreaRouteToGoalArea(int areanum, vec3_t origin, int goalareanum, int tra
} //end if
return qfalse;
} //end if
if (!aasworld.areasettings[areanum].numreachableareas || !aasworld.areasettings[goalareanum].numreachableareas)
{
return qfalse;
} //end if
// make sure the routing cache doesn't grow to large
while(AvailableMemory() < 1 * 1024 * 1024) {
if (!AAS_FreeOldestCache()) break;

View file

@ -688,7 +688,7 @@ aas_trace_t AAS_TraceClientBBox(vec3_t start, vec3_t end, int presencetype,
side = front < 0;
//first put the end part of the line on the stack (back side)
VectorCopy(cur_mid, tstack_p->start);
//not necesary to store because still on stack
//not necessary to store because still on stack
//VectorCopy(cur_end, tstack_p->end);
tstack_p->planenum = aasnode->planenum;
tstack_p->nodenum = aasnode->children[!side];
@ -874,7 +874,7 @@ int AAS_TraceAreas(vec3_t start, vec3_t end, int *areas, vec3_t *points, int max
side = front < 0;
//first put the end part of the line on the stack (back side)
VectorCopy(cur_mid, tstack_p->start);
//not necesary to store because still on stack
//not necessary to store because still on stack
//VectorCopy(cur_end, tstack_p->end);
tstack_p->planenum = aasnode->planenum;
tstack_p->nodenum = aasnode->children[!side];
@ -959,7 +959,7 @@ qboolean AAS_InsideFace(aas_face_t *face, vec3_t pnormal, vec3_t point, float ep
//edge) and through both the edge vector and the normal vector
//of the plane
AAS_OrthogonalToVectors(edgevec, pnormal, sepnormal);
//check on wich side of the above plane the point is
//check on which side of the above plane the point is
//this is done by checking the sign of the dot product of the
//vector orthogonal vector from above and the vector from the
//origin (first vertex of edge) to the point

View file

@ -342,7 +342,7 @@ void BotQueueConsoleMessage(int chatstate, int type, char *message)
m->handle = cs->handle;
m->time = AAS_Time();
m->type = type;
strncpy(m->message, message, MAX_MESSAGE_SIZE);
Q_strncpyz(m->message, message, MAX_MESSAGE_SIZE);
m->next = NULL;
if (cs->lastmessage)
{
@ -553,11 +553,11 @@ void StringReplaceWords(char *string, char *synonym, char *replacement)
//find the synonym in the string
str = StringContainsWord(string, synonym, qfalse);
//if the synonym occured in the string
//if the synonym occurred in the string
while(str)
{
//if the synonym isn't part of the replacement which is already in the string
//usefull for abreviations
//useful for abbreviations
str2 = StringContainsWord(string, replacement, qfalse);
while(str2)
{
@ -1456,7 +1456,7 @@ int BotFindMatch(char *str, bot_match_t *match, unsigned long int context)
int i;
bot_matchtemplate_t *ms;
strncpy(match->string, str, MAX_MESSAGE_SIZE);
Q_strncpyz(match->string, str, MAX_MESSAGE_SIZE);
//remove any trailing enters
while(strlen(match->string) &&
match->string[strlen(match->string)-1] == '\n')
@ -2114,7 +2114,7 @@ bot_chat_t *BotLoadInitialChat(char *chatfile, char *chatname)
if (pass && ptr)
{
chattype = (bot_chattype_t *) ptr;
strncpy(chattype->name, token.string, MAX_CHATTYPE_NAME);
Q_strncpyz(chattype->name, token.string, MAX_CHATTYPE_NAME);
chattype->firstchatmessage = NULL;
//add the chat type to the chat
chattype->next = chat->types;
@ -2884,7 +2884,7 @@ void BotSetChatName(int chatstate, char *name, int client)
if (!cs) return;
cs->client = client;
Com_Memset(cs->name, 0, sizeof(cs->name));
strncpy(cs->name, name, sizeof(cs->name));
strncpy(cs->name, name, sizeof(cs->name)-1);
cs->name[sizeof(cs->name)-1] = '\0';
} //end of the function BotSetChatName
//===========================================================================

View file

@ -62,7 +62,7 @@ int GeneticSelection(int numranks, float *rankings)
} //end for
if (sum > 0)
{
//select a bot where the ones with the higest rankings have
//select a bot where the ones with the highest rankings have
//the highest chance of being selected
//sum *= random();
for (i = 0; i < numranks; i++)

View file

@ -227,6 +227,9 @@ void BotInterbreedGoalFuzzyLogic(int parent1, int parent2, int child)
p2 = BotGoalStateFromHandle(parent2);
c = BotGoalStateFromHandle(child);
if (!p1 || !p2 || !c)
return;
InterbreedWeightConfigs(p1->itemweightconfig, p2->itemweightconfig,
c->itemweightconfig);
} //end of the function BotInterbreedingGoalFuzzyLogic
@ -241,7 +244,7 @@ void BotSaveGoalFuzzyLogic(int goalstate, char *filename)
//bot_goalstate_t *gs;
//gs = BotGoalStateFromHandle(goalstate);
//if (!gs) return;
//WriteWeightConfig(filename, gs->itemweightconfig);
} //end of the function BotSaveGoalFuzzyLogic
//===========================================================================
@ -255,7 +258,7 @@ void BotMutateGoalFuzzyLogic(int goalstate, float range)
bot_goalstate_t *gs;
gs = BotGoalStateFromHandle(goalstate);
if (!gs) return;
EvolveWeightConfig(gs->itemweightconfig);
} //end of the function BotMutateGoalFuzzyLogic
//===========================================================================
@ -268,7 +271,7 @@ itemconfig_t *LoadItemConfig(char *filename)
{
int max_iteminfo;
token_t token;
char path[MAX_PATH];
char path[MAX_QPATH];
source_t *source;
itemconfig_t *ic;
iteminfo_t *ii;
@ -281,7 +284,7 @@ itemconfig_t *LoadItemConfig(char *filename)
LibVarSet( "max_iteminfo", "256" );
}
strncpy( path, filename, MAX_PATH );
Q_strncpyz(path, filename, sizeof(path));
PC_SetBaseFolder(BOTFILESBASEFOLDER);
source = LoadSourceFile( path );
if( !source ) {
@ -314,7 +317,7 @@ itemconfig_t *LoadItemConfig(char *filename)
return NULL;
} //end if
StripDoubleQuotes(token.string);
strncpy(ii->classname, token.string, sizeof(ii->classname)-1);
Q_strncpyz(ii->classname, token.string, sizeof(ii->classname));
if (!ReadStructure(source, &iteminfo_struct, (char *) ii))
{
FreeMemory(ic);
@ -685,8 +688,7 @@ void BotGoalName(int number, char *name, int size)
{
if (li->number == number)
{
strncpy(name, itemconfig->iteminfo[li->iteminfo].name, size-1);
name[size-1] = '\0';
Q_strncpyz(name, itemconfig->iteminfo[li->iteminfo].name, size);
return;
} //end for
} //end for
@ -895,6 +897,7 @@ int BotGetLevelItemGoal(int index, char *name, bot_goal_t *goal)
goal->number = li->number;
goal->flags = GFL_ITEM;
if (li->timeout) goal->flags |= GFL_DROPPED;
goal->iteminfo = li->iteminfo;
//botimport.Print(PRT_MESSAGE, "found li %s\n", itemconfig->iteminfo[li->iteminfo].name);
return li->number;
} //end if
@ -921,6 +924,9 @@ int BotGetMapLocationGoal(char *name, bot_goal_t *goal)
goal->entitynum = 0;
VectorCopy(mins, goal->mins);
VectorCopy(maxs, goal->maxs);
goal->number = 0;
goal->flags = 0;
goal->iteminfo = 0;
return qtrue;
} //end if
} //end for
@ -949,6 +955,9 @@ int BotGetNextCampSpotGoal(int num, bot_goal_t *goal)
goal->entitynum = 0;
VectorCopy(mins, goal->mins);
VectorCopy(maxs, goal->maxs);
goal->number = 0;
goal->flags = 0;
goal->iteminfo = 0;
return num+1;
} //end if
} //end for

View file

@ -1605,7 +1605,7 @@ bot_moveresult_t BotTravel_WalkOffLedge(bot_movestate_t *ms, aas_reachability_t
VectorSubtract(reach->start, ms->origin, dir);
VectorNormalize(dir);
BotCheckBlocked(ms, dir, qtrue, &result);
//if the reachability start and end are practially above each other
//if the reachability start and end are practically above each other
VectorSubtract(reach->end, reach->start, dir);
dir[2] = 0;
reachhordist = VectorLength(dir);
@ -2054,7 +2054,7 @@ bot_moveresult_t BotTravel_Elevator(bot_movestate_t *ms, aas_reachability_t *rea
botimport.Print(PRT_MESSAGE, "bot on elevator\n");
#endif //DEBUG_ELEVATOR
//if vertically not too far from the end point
if (abs(ms->origin[2] - reach->end[2]) < sv_maxbarrier->value)
if (fabsf(ms->origin[2] - reach->end[2]) < sv_maxbarrier->value)
{
#ifdef DEBUG_ELEVATOR
botimport.Print(PRT_MESSAGE, "bot moving to end\n");
@ -2744,7 +2744,7 @@ bot_moveresult_t BotTravel_RocketJump(bot_movestate_t *ms, aas_reachability_t *r
result.ideal_viewangles[PITCH] = 90;
//set the view angles directly
EA_View(ms->client, result.ideal_viewangles);
//view is important for the movment
//view is important for the movement
result.flags |= MOVERESULT_MOVEMENTVIEWSET;
//select the rocket launcher
EA_SelectWeapon(ms->client, (int) weapindex_rocketlauncher->value);
@ -2804,7 +2804,7 @@ bot_moveresult_t BotTravel_BFGJump(bot_movestate_t *ms, aas_reachability_t *reac
result.ideal_viewangles[PITCH] = 90;
//set the view angles directly
EA_View(ms->client, result.ideal_viewangles);
//view is important for the movment
//view is important for the movement
result.flags |= MOVERESULT_MOVEMENTVIEWSET;
//select the rocket launcher
EA_SelectWeapon(ms->client, (int) weapindex_bfg10k->value);

View file

@ -199,7 +199,7 @@ weaponconfig_t *LoadWeaponConfig(char *filename)
{
int max_weaponinfo, max_projectileinfo;
token_t token;
char path[MAX_PATH];
char path[MAX_QPATH];
int i, j;
source_t *source;
weaponconfig_t *wc;
@ -219,7 +219,7 @@ weaponconfig_t *LoadWeaponConfig(char *filename)
max_projectileinfo = 32;
LibVarSet("max_projectileinfo", "32");
} //end if
strncpy(path, filename, MAX_PATH);
Q_strncpyz(path, filename, sizeof(path));
PC_SetBaseFolder(BOTFILESBASEFOLDER);
source = LoadSourceFile(path);
if (!source)

View file

@ -726,7 +726,7 @@ void EvolveFuzzySeperator_r(fuzzyseperator_t *fs)
//every once in a while an evolution leap occurs, mutation
if (random() < 0.01) fs->weight += crandom() * (fs->maxweight - fs->minweight);
else fs->weight += crandom() * (fs->maxweight - fs->minweight) * 0.5;
//modify bounds if necesary because of mutation
//modify bounds if necessary because of mutation
if (fs->weight < fs->minweight) fs->minweight = fs->weight;
else if (fs->weight > fs->maxweight) fs->maxweight = fs->weight;
} //end else if

View file

@ -64,7 +64,7 @@ typedef struct weightconfig_s
weightconfig_t *ReadWeightConfig(char *filename);
//free a weight configuration
void FreeWeightConfig(weightconfig_t *config);
//writes a weight configuration, returns true if successfull
//writes a weight configuration, returns true if successful
qboolean WriteWeightConfig(char *filename, weightconfig_t *config);
//find the fuzzy weight with the given name
int FindFuzzyWeight(weightconfig_t *wc, char *name);

View file

@ -39,7 +39,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "be_ea.h"
#define MAX_USERMOVE 400
#define MAX_COMMANDARGUMENTS 10
bot_input_t *botinputs;

View file

@ -144,26 +144,7 @@ int Export_BotLibSetup(void)
if(botDeveloper)
{
char *homedir, *gamedir, *basegame;
char logfilename[MAX_OSPATH];
homedir = LibVarGetString("homedir");
gamedir = LibVarGetString("gamedir");
basegame = LibVarGetString("basegame");
if (*homedir)
{
if(*gamedir)
Com_sprintf(logfilename, sizeof(logfilename), "%s%c%s%cbotlib.log", homedir, PATH_SEP, gamedir, PATH_SEP);
else if(*basegame)
Com_sprintf(logfilename, sizeof(logfilename), "%s%c%s%cbotlib.log", homedir, PATH_SEP, basegame, PATH_SEP);
else
Com_sprintf(logfilename, sizeof(logfilename), "%s%c" BASEGAME "%cbotlib.log", homedir, PATH_SEP, PATH_SEP);
}
else
Com_sprintf(logfilename, sizeof(logfilename), "botlib.log");
Log_Open(logfilename);
Log_Open("botlib.log");
}
botimport.Print(PRT_MESSAGE, "------- BotLib Initialization -------\n");
@ -238,7 +219,7 @@ int Export_BotLibShutdown(void)
// Returns: -
// Changes Globals: -
//===========================================================================
int Export_BotLibVarSet(char *var_name, char *value)
int Export_BotLibVarSet(const char *var_name, const char *value)
{
LibVarSet(var_name, value);
return BLERR_NOERROR;
@ -249,7 +230,7 @@ int Export_BotLibVarSet(char *var_name, char *value)
// Returns: -
// Changes Globals: -
//===========================================================================
int Export_BotLibVarGet(char *var_name, char *value, int size)
int Export_BotLibVarGet(const char *var_name, char *value, int size)
{
char *varvalue;

View file

@ -409,9 +409,9 @@ typedef struct botlib_export_s
//shutdown the bot library, returns BLERR_
int (*BotLibShutdown)(void);
//sets a library variable returns BLERR_
int (*BotLibVarSet)(char *var_name, char *value);
int (*BotLibVarSet)(const char *var_name, const char *value);
//gets a library variable returns BLERR_
int (*BotLibVarGet)(char *var_name, char *value, int size);
int (*BotLibVarGet)(const char *var_name, char *value, int size);
//sets a C-like define returns BLERR_
int (*PC_AddGlobalDefine)(char *string);

View file

@ -42,7 +42,7 @@ libvar_t *libvarlist = NULL;
// Returns: -
// Changes Globals: -
//===========================================================================
float LibVarStringValue(char *string)
float LibVarStringValue(const char *string)
{
int dotfound = 0;
float value = 0;
@ -80,7 +80,7 @@ float LibVarStringValue(char *string)
// Returns: -
// Changes Globals: -
//===========================================================================
libvar_t *LibVarAlloc(char *var_name)
libvar_t *LibVarAlloc(const char *var_name)
{
libvar_t *v;
@ -128,7 +128,7 @@ void LibVarDeAllocAll(void)
// Returns: -
// Changes Globals: -
//===========================================================================
libvar_t *LibVarGet(char *var_name)
libvar_t *LibVarGet(const char *var_name)
{
libvar_t *v;
@ -147,7 +147,7 @@ libvar_t *LibVarGet(char *var_name)
// Returns: -
// Changes Globals: -
//===========================================================================
char *LibVarGetString(char *var_name)
char *LibVarGetString(const char *var_name)
{
libvar_t *v;
@ -167,7 +167,7 @@ char *LibVarGetString(char *var_name)
// Returns: -
// Changes Globals: -
//===========================================================================
float LibVarGetValue(char *var_name)
float LibVarGetValue(const char *var_name)
{
libvar_t *v;
@ -187,7 +187,7 @@ float LibVarGetValue(char *var_name)
// Returns: -
// Changes Globals: -
//===========================================================================
libvar_t *LibVar(char *var_name, char *value)
libvar_t *LibVar(const char *var_name, const char *value)
{
libvar_t *v;
v = LibVarGet(var_name);
@ -210,7 +210,7 @@ libvar_t *LibVar(char *var_name, char *value)
// Returns: -
// Changes Globals: -
//===========================================================================
char *LibVarString(char *var_name, char *value)
char *LibVarString(const char *var_name, const char *value)
{
libvar_t *v;
@ -223,7 +223,7 @@ char *LibVarString(char *var_name, char *value)
// Returns: -
// Changes Globals: -
//===========================================================================
float LibVarValue(char *var_name, char *value)
float LibVarValue(const char *var_name, const char *value)
{
libvar_t *v;
@ -236,7 +236,7 @@ float LibVarValue(char *var_name, char *value)
// Returns: -
// Changes Globals: -
//===========================================================================
void LibVarSet(char *var_name, char *value)
void LibVarSet(const char *var_name, const char *value)
{
libvar_t *v;
@ -263,7 +263,7 @@ void LibVarSet(char *var_name, char *value)
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean LibVarChanged(char *var_name)
qboolean LibVarChanged(const char *var_name)
{
libvar_t *v;
@ -283,7 +283,7 @@ qboolean LibVarChanged(char *var_name)
// Returns: -
// Changes Globals: -
//===========================================================================
void LibVarSetNotModified(char *var_name)
void LibVarSetNotModified(const char *var_name)
{
libvar_t *v;

View file

@ -43,21 +43,21 @@ typedef struct libvar_s
//removes all library variables
void LibVarDeAllocAll(void);
//gets the library variable with the given name
libvar_t *LibVarGet(char *var_name);
libvar_t *LibVarGet(const char *var_name);
//gets the string of the library variable with the given name
char *LibVarGetString(char *var_name);
char *LibVarGetString(const char *var_name);
//gets the value of the library variable with the given name
float LibVarGetValue(char *var_name);
float LibVarGetValue(const char *var_name);
//creates the library variable if not existing already and returns it
libvar_t *LibVar(char *var_name, char *value);
libvar_t *LibVar(const char *var_name, const char *value);
//creates the library variable if not existing already and returns the value
float LibVarValue(char *var_name, char *value);
float LibVarValue(const char *var_name, const char *value);
//creates the library variable if not existing already and returns the value string
char *LibVarString(char *var_name, char *value);
char *LibVarString(const char *var_name, const char *value);
//sets the library variable
void LibVarSet(char *var_name, char *value);
void LibVarSet(const char *var_name, const char *value);
//returns true if the library variable has been modified
qboolean LibVarChanged(char *var_name);
qboolean LibVarChanged(const char *var_name);
//sets the library variable to unmodified
void LibVarSetNotModified(char *var_name);
void LibVarSetNotModified(const char *var_name);

View file

@ -34,6 +34,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include <string.h>
#include "../qcommon/q_shared.h"
#include "../qcommon/qcommon.h"
#include "botlib.h"
#include "be_interface.h" //for botimport.Print
#include "l_libvar.h"
@ -58,6 +59,7 @@ static logfile_t logfile;
//===========================================================================
void Log_Open(char *filename)
{
char *ospath;
if (!LibVarValue("log", "0")) return;
if (!filename || !strlen(filename))
{
@ -69,13 +71,14 @@ void Log_Open(char *filename)
botimport.Print(PRT_ERROR, "log file %s is already opened\n", logfile.filename);
return;
} //end if
logfile.fp = fopen(filename, "wb");
ospath = FS_BuildOSPath(Cvar_VariableString("fs_homepath"), Cvar_VariableString("fs_game"), filename);
logfile.fp = fopen(ospath, "wb");
if (!logfile.fp)
{
botimport.Print(PRT_ERROR, "can't open the log file %s\n", filename);
return;
} //end if
strncpy(logfile.filename, filename, MAX_LOGFILENAMESIZE);
Q_strncpyz(logfile.filename, filename, MAX_LOGFILENAMESIZE);
botimport.Print(PRT_MESSAGE, "Opened log %s\n", logfile.filename);
} //end of the function Log_Create
//===========================================================================

View file

@ -548,7 +548,7 @@ void PC_PrintDefineHashTable(define_t **definehash)
int PC_NameHash(char *name)
{
int register hash, i;
int hash, i;
hash = 0;
for (i = 0; name[i] != '\0'; i++)
@ -971,7 +971,7 @@ int PC_Directive_include(source_t *source)
{
script_t *script;
token_t token;
char path[MAX_PATH];
char path[MAX_QPATH];
#ifdef QUAKE
foundfile_t file;
#endif //QUAKE
@ -1035,7 +1035,7 @@ int PC_Directive_include(source_t *source)
{
Com_Memset(&file, 0, sizeof(foundfile_t));
script = LoadScriptFile(path);
if (script) strncpy(script->filename, path, MAX_PATH);
if (script) Q_strncpyz(script->filename, path, sizeof(script->filename));
} //end if
#endif //QUAKE
if (!script)
@ -1323,7 +1323,7 @@ define_t *PC_DefineFromString(char *string)
script = LoadScriptMemory(string, strlen(string), "*extern");
//create a new source
Com_Memset(&src, 0, sizeof(source_t));
strncpy(src.filename, "*extern", MAX_PATH);
Q_strncpyz(src.filename, "*extern", sizeof(src.filename));
src.scriptstack = script;
#if DEFINEHASHING
src.definehash = GetClearedMemory(DEFINEHASHSIZE * sizeof(define_t *));
@ -2960,7 +2960,7 @@ void PC_SetIncludePath(source_t *source, char *path)
{
size_t len;
Q_strncpyz(source->includepath, path, MAX_PATH-1);
Q_strncpyz(source->includepath, path, sizeof(source->includepath)-1);
len = strlen(source->includepath);
//add trailing path seperator
@ -3001,7 +3001,7 @@ source_t *LoadSourceFile(const char *filename)
source = (source_t *) GetMemory(sizeof(source_t));
Com_Memset(source, 0, sizeof(source_t));
strncpy(source->filename, filename, MAX_PATH);
Q_strncpyz(source->filename, filename, sizeof(source->filename));
source->scriptstack = script;
source->tokens = NULL;
source->defines = NULL;
@ -3034,7 +3034,7 @@ source_t *LoadSourceMemory(char *ptr, int length, char *name)
source = (source_t *) GetMemory(sizeof(source_t));
Com_Memset(source, 0, sizeof(source_t));
strncpy(source->filename, name, MAX_PATH);
Q_strncpyz(source->filename, name, sizeof(source->filename));
source->scriptstack = script;
source->tokens = NULL;
source->defines = NULL;

View file

@ -29,10 +29,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef MAX_PATH
#define MAX_PATH MAX_QPATH
#endif
#ifndef PATH_SEPERATORSTR
#if defined(WIN32)|defined(_WIN32)|defined(__NT__)|defined(__WINDOWS__)|defined(__WINDOWS_386__)
#define PATHSEPERATOR_STR "\\"

View file

@ -160,9 +160,7 @@ punctuation_t default_punctuations[] =
{NULL, 0}
};
#ifdef BSPC
char basefolder[MAX_PATH];
#else
#ifdef BOTLIB
char basefolder[MAX_QPATH];
#endif
@ -220,7 +218,7 @@ char *PunctuationFromNum(script_t *script, int num)
{
if (script->punctuations[i].n == num) return script->punctuations[i].p;
} //end for
return "unkown punctuation";
return "unknown punctuation";
} //end of the function PunctuationFromNum
//===========================================================================
//
@ -804,7 +802,7 @@ int PS_ReadPunctuation(script_t *script, token_t *token)
//if the script contains the punctuation
if (!strncmp(script->script_p, p, len))
{
strncpy(token->string, p, MAX_TOKEN);
Q_strncpyz(token->string, p, MAX_TOKEN);
script->script_p += len;
token->type = TT_PUNCTUATION;
//sub type is the number of the punctuation
@ -838,7 +836,7 @@ int PS_ReadPrimitive(script_t *script, token_t *token)
token->string[len] = 0;
//copy the token into the script structure
Com_Memcpy(&script->token, token, sizeof(token_t));
//primitive reading successfull
//primitive reading successful
return 1;
} //end of the function PS_ReadPrimitive
//============================================================================
@ -1441,9 +1439,7 @@ void FreeScript(script_t *script)
//============================================================================
void PS_SetBaseFolder(char *path)
{
#ifdef BSPC
sprintf(basefolder, path);
#else
#ifdef BOTLIB
Com_sprintf(basefolder, sizeof(basefolder), "%s", path);
#endif
} //end of the function PS_SetBaseFolder

View file

@ -221,7 +221,7 @@ int ReadString(source_t *source, fielddef_t *fd, void *p)
//remove the double quotes
StripDoubleQuotes(token.string);
//copy the string
strncpy((char *) p, token.string, MAX_STRINGFIELD);
strncpy((char *) p, token.string, MAX_STRINGFIELD-1);
//make sure the string is closed with a zero
((char *)p)[MAX_STRINGFIELD-1] = '\0';
//

View file

@ -30,8 +30,5 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*****************************************************************************/
#define Vector2Angles(v,a) vectoangles(v,a)
#ifndef MAX_PATH
#define MAX_PATH MAX_QPATH
#endif
#define Maximum(x,y) (x > y ? x : y)
#define Minimum(x,y) (x < y ? x : y)

View file

@ -368,6 +368,9 @@ qboolean CL_OpenAVIForWriting( const char *fileName )
afd.a.rate = dma.speed;
afd.a.format = WAV_FORMAT_PCM;
afd.a.channels = dma.channels;
/* !!! FIXME: if CL_WriteAVIAudioFrame() is ever called from somewhere other
!!! FIXME: than S_TransferStereo16(), we will need to handle/convert
!!! FIXME: float32 samples for AVI writing. */
afd.a.bits = dma.samplebits;
afd.a.sampleSize = ( afd.a.bits / 8 ) * afd.a.channels;

View file

@ -340,7 +340,7 @@ rescan:
// the clientLevelShot command is used during development
// to generate 128*128 screenshots from the intermission
// point of levels for the menu system to use
// we pass it along to the cgame to make apropriate adjustments,
// we pass it along to the cgame to make appropriate adjustments,
// but we also clear the console and notify lines here
if ( !strcmp( cmd, "clientLevelShot" ) ) {
// don't do it if we aren't running the server locally,
@ -450,7 +450,7 @@ intptr_t CL_CgameSystemCalls( intptr_t *args ) {
case CG_FS_FOPENFILE:
return FS_FOpenFileByMode( VMA(1), VMA(2), args[3] );
case CG_FS_READ:
FS_Read2( VMA(1), args[2], args[3] );
FS_Read( VMA(1), args[2], args[3] );
return 0;
case CG_FS_WRITE:
FS_Write( VMA(1), args[2], args[3] );
@ -1040,7 +1040,7 @@ void CL_SetCGameTime( void ) {
}
// if we are playing a demo back, we can just keep reading
// messages from the demo file until the cgame definately
// messages from the demo file until the cgame definitely
// has valid snapshots to interpolate between
// a timedemo will always use a deterministic set of time samples

View file

@ -577,8 +577,12 @@ static unsigned short yuv_to_rgb( long y, long u, long v )
g = (YY + ROQ_UG_tab[u] + ROQ_VG_tab[v]) >> 8;
b = (YY + ROQ_UB_tab[u]) >> 9;
if (r<0) r = 0; if (g<0) g = 0; if (b<0) b = 0;
if (r > 31) r = 31; if (g > 63) g = 63; if (b > 31) b = 31;
if (r<0) r = 0;
if (g<0) g = 0;
if (b<0) b = 0;
if (r > 31) r = 31;
if (g > 63) g = 63;
if (b > 31) b = 31;
return (unsigned short)((r<<11)+(g<<5)+(b));
}
@ -598,10 +602,14 @@ static unsigned int yuv_to_rgb24( long y, long u, long v )
g = (YY + ROQ_UG_tab[u] + ROQ_VG_tab[v]) >> 6;
b = (YY + ROQ_UB_tab[u]) >> 6;
if (r<0) r = 0; if (g<0) g = 0; if (b<0) b = 0;
if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255;
if (r<0) r = 0;
if (g<0) g = 0;
if (b<0) b = 0;
if (r > 255) r = 255;
if (g > 255) g = 255;
if (b > 255) b = 255;
return LittleLong ((r)|(g<<8)|(b<<16)|(255<<24));
return LittleLong ((unsigned long)((r)|(g<<8)|(b<<16))|(255UL<<24));
}
/******************************************************************************
@ -1384,6 +1392,7 @@ e_status CIN_RunCinematic (int handle)
RoQReset();
} else {
RoQShutdown();
return FMV_EOF;
}
}

View file

@ -56,6 +56,7 @@ typedef struct {
console_t con;
cvar_t *con_conspeed;
cvar_t *con_autoclear;
cvar_t *con_notifytime;
#define DEFAULT_CONSOLE_WIDTH 78
@ -72,7 +73,10 @@ void Con_ToggleConsole_f (void) {
return;
}
Field_Clear( &g_consoleField );
if ( con_autoclear->integer ) {
Field_Clear( &g_consoleField );
}
g_consoleField.widthInChars = g_console_field_width;
Con_ClearNotify ();
@ -191,6 +195,12 @@ void Con_Dump_f (void)
Q_strncpyz( filename, Cmd_Argv( 1 ), sizeof( filename ) );
COM_DefaultExtension( filename, sizeof( filename ), ".txt" );
if (!COM_CompareExtension(filename, ".txt"))
{
Com_Printf("Con_Dump_f: Only the \".txt\" extension is supported by this command!\n");
return;
}
f = FS_FOpenFileWrite( filename );
if (!f)
{
@ -348,6 +358,7 @@ void Con_Init (void) {
con_notifytime = Cvar_Get ("con_notifytime", "3", 0);
con_conspeed = Cvar_Get ("scr_conspeed", "3", 0);
con_autoclear = Cvar_Get("con_autoclear", "1", CVAR_ARCHIVE);
Field_Clear( &g_consoleField );
g_consoleField.widthInChars = g_console_field_width;

View file

@ -299,6 +299,9 @@ void CL_cURL_BeginDownload( const char *localName, const char *remoteURL )
qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_FAILONERROR, 1);
qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_FOLLOWLOCATION, 1);
qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_MAXREDIRS, 5);
qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_PROTOCOLS,
CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | CURLPROTO_FTPS);
qcurl_easy_setopt_warn(clc.downloadCURL, CURLOPT_BUFFERSIZE, CURL_MAX_READ_SIZE);
clc.downloadCURLM = qcurl_multi_init();
if(!clc.downloadCURLM) {
qcurl_easy_cleanup(clc.downloadCURL);

View file

@ -37,7 +37,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#ifdef WIN32
#define DEFAULT_CURL_LIB "libcurl-4.dll"
#define ALTERNATE_CURL_LIB "libcurl-3.dll"
#elif defined(MACOS_X)
#elif defined(__APPLE__)
#define DEFAULT_CURL_LIB "libcurl.dylib"
#else
#define DEFAULT_CURL_LIB "libcurl.so.4"

View file

@ -320,7 +320,7 @@ void CL_KeyMove( usercmd_t *cmd ) {
//
// adjust for speed key / running
// the walking flag is to keep animations consistant
// the walking flag is to keep animations consistent
// even during acceleration and develeration
//
if ( in_speed.active ^ cl_run->integer ) {
@ -392,6 +392,12 @@ CL_JoystickMove
void CL_JoystickMove( usercmd_t *cmd ) {
float anglespeed;
float yaw = j_yaw->value * cl.joystickAxis[j_yaw_axis->integer];
float right = j_side->value * cl.joystickAxis[j_side_axis->integer];
float forward = j_forward->value * cl.joystickAxis[j_forward_axis->integer];
float pitch = j_pitch->value * cl.joystickAxis[j_pitch_axis->integer];
float up = j_up->value * cl.joystickAxis[j_up_axis->integer];
if ( !(in_speed.active ^ cl_run->integer) ) {
cmd->buttons |= BUTTON_WALKING;
}
@ -403,22 +409,22 @@ void CL_JoystickMove( usercmd_t *cmd ) {
}
if ( !in_strafe.active ) {
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]) );
cl.viewangles[YAW] += anglespeed * yaw;
cmd->rightmove = ClampChar( cmd->rightmove + (int)right );
} else {
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]) );
cl.viewangles[YAW] += anglespeed * right;
cmd->rightmove = ClampChar( cmd->rightmove + (int)yaw );
}
if ( in_mlooking ) {
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]) );
cl.viewangles[PITCH] += anglespeed * forward;
cmd->forwardmove = ClampChar( cmd->forwardmove + (int)pitch );
} else {
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]) );
cl.viewangles[PITCH] += anglespeed * pitch;
cmd->forwardmove = ClampChar( cmd->forwardmove + (int)forward );
}
cmd->upmove = ClampChar( cmd->upmove + (int) (j_up->value * cl.joystickAxis[j_up_axis->integer]) );
cmd->upmove = ClampChar( cmd->upmove + (int)up );
}
/*

View file

@ -177,7 +177,7 @@ keyname_t keynames[] =
{"PAUSE", K_PAUSE},
{"SEMICOLON", ';'}, // because a raw semicolon seperates commands
{"SEMICOLON", ';'}, // because a raw semicolon separates commands
{"WORLD_0", K_WORLD_0},
{"WORLD_1", K_WORLD_1},
@ -289,6 +289,33 @@ keyname_t keynames[] =
{"EURO", K_EURO},
{"UNDO", K_UNDO},
{"PAD0_A", K_PAD0_A },
{"PAD0_B", K_PAD0_B },
{"PAD0_X", K_PAD0_X },
{"PAD0_Y", K_PAD0_Y },
{"PAD0_BACK", K_PAD0_BACK },
{"PAD0_GUIDE", K_PAD0_GUIDE },
{"PAD0_START", K_PAD0_START },
{"PAD0_LEFTSTICK_CLICK", K_PAD0_LEFTSTICK_CLICK },
{"PAD0_RIGHTSTICK_CLICK", K_PAD0_RIGHTSTICK_CLICK },
{"PAD0_LEFTSHOULDER", K_PAD0_LEFTSHOULDER },
{"PAD0_RIGHTSHOULDER", K_PAD0_RIGHTSHOULDER },
{"PAD0_DPAD_UP", K_PAD0_DPAD_UP },
{"PAD0_DPAD_DOWN", K_PAD0_DPAD_DOWN },
{"PAD0_DPAD_LEFT", K_PAD0_DPAD_LEFT },
{"PAD0_DPAD_RIGHT", K_PAD0_DPAD_RIGHT },
{"PAD0_LEFTSTICK_LEFT", K_PAD0_LEFTSTICK_LEFT },
{"PAD0_LEFTSTICK_RIGHT", K_PAD0_LEFTSTICK_RIGHT },
{"PAD0_LEFTSTICK_UP", K_PAD0_LEFTSTICK_UP },
{"PAD0_LEFTSTICK_DOWN", K_PAD0_LEFTSTICK_DOWN },
{"PAD0_RIGHTSTICK_LEFT", K_PAD0_RIGHTSTICK_LEFT },
{"PAD0_RIGHTSTICK_RIGHT", K_PAD0_RIGHTSTICK_RIGHT },
{"PAD0_RIGHTSTICK_UP", K_PAD0_RIGHTSTICK_UP },
{"PAD0_RIGHTSTICK_DOWN", K_PAD0_RIGHTSTICK_DOWN },
{"PAD0_LEFTTRIGGER", K_PAD0_LEFTTRIGGER },
{"PAD0_RIGHTTRIGGER", K_PAD0_RIGHTTRIGGER },
{NULL,0}
};
@ -586,7 +613,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 ( clc.state != CA_ACTIVE &&
if ( clc.state != CA_ACTIVE && con_autochat->integer &&
g_consoleField.buffer[0] &&
g_consoleField.buffer[0] != '\\' &&
g_consoleField.buffer[0] != '/' ) {
@ -608,7 +635,10 @@ void Console_Key (int key) {
if ( !g_consoleField.buffer[0] ) {
return; // empty lines just scroll the console without adding to history
} else {
Cbuf_AddText ("cmd say ");
if ( con_autochat->integer ) {
Cbuf_AddText ("cmd say ");
}
Cbuf_AddText( g_consoleField.buffer );
Cbuf_AddText ("\n");
}
@ -795,6 +825,7 @@ to be configured even if they don't have defined names.
*/
int Key_StringToKeynum( char *str ) {
keyname_t *kn;
int n;
if ( !str || !str[0] ) {
return -1;
@ -804,12 +835,9 @@ int Key_StringToKeynum( char *str ) {
}
// check for hex code
if ( strlen( str ) == 4 ) {
int n = Com_HexStrToInt( str );
if ( n >= 0 ) {
return n;
}
n = Com_HexStrToInt( str );
if ( n >= 0 && n < MAX_KEYS ) {
return n;
}
// scan for a text match
@ -889,7 +917,7 @@ void Key_SetBinding( int keynum, const char *binding ) {
keys[keynum].binding = CopyString( binding );
// consider this like modifying an archived cvar, so the
// file write will be triggered at the next oportunity
// file write will be triggered at the next opportunity
cvar_modifiedFlags |= CVAR_ARCHIVE;
}
@ -1212,6 +1240,11 @@ void CL_KeyDownEvent( int key, unsigned time )
if( keys[K_ALT].down && key == K_ENTER )
{
// don't repeat fullscreen toggle when keys are held down
if ( keys[K_ENTER].repeats > 1 ) {
return;
}
Cvar_SetValue( "r_fullscreen",
!Cvar_VariableIntegerValue( "r_fullscreen" ) );
return;
@ -1270,7 +1303,7 @@ void CL_KeyDownEvent( int key, unsigned time )
// send the bound action
CL_ParseBinding( key, qtrue, time );
// distribute the key down event to the apropriate handler
// distribute the key down event to the appropriate handler
if ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) {
Console_Key( key );
} else if ( Key_GetCatcher( ) & KEYCATCH_UI ) {
@ -1352,7 +1385,7 @@ void CL_CharEvent( int key ) {
return;
}
// distribute the key down event to the apropriate handler
// distribute the key down event to the appropriate handler
if ( Key_GetCatcher( ) & KEYCATCH_CONSOLE )
{
Field_CharEvent( &g_consoleField, key );
@ -1443,9 +1476,10 @@ void CL_LoadConsoleHistory( void )
return;
}
if( consoleSaveBufferSize <= MAX_CONSOLE_SAVE_BUFFER &&
if( consoleSaveBufferSize < MAX_CONSOLE_SAVE_BUFFER &&
FS_Read( consoleSaveBuffer, consoleSaveBufferSize, f ) == consoleSaveBufferSize )
{
consoleSaveBuffer[consoleSaveBufferSize] = '\0';
text_p = consoleSaveBuffer;
for( i = COMMAND_HISTORY - 1; i >= 0; i-- )

View file

@ -573,7 +573,7 @@ CLIENT RELIABLE COMMAND COMMUNICATION
======================
CL_AddReliableCommand
The given command will be transmitted to the server, and is gauranteed to
The given command will be transmitted to the server, and is guaranteed to
not have future usercmd_t executed before it is executed
======================
*/
@ -1069,7 +1069,8 @@ demo <demoname>
*/
void CL_PlayDemo_f( void ) {
char name[MAX_OSPATH];
char *arg, *ext_test;
char arg[MAX_OSPATH];
char *ext_test;
int protocol, i;
char retry[MAX_OSPATH];
@ -1083,7 +1084,7 @@ void CL_PlayDemo_f( void ) {
Cvar_Set( "sv_killserver", "2" );
// open the demo file
arg = Cmd_Argv(1);
Q_strncpyz( arg, Cmd_Argv(1), sizeof( arg ) );
CL_Disconnect( qtrue );
@ -1244,7 +1245,7 @@ void CL_ClearMemory(qboolean shutdownRef)
CL_ShutdownAll(shutdownRef);
// if not running a server clear the whole hunk
if ( !com_sv_running->integer ) {
if ( !com_sv_running || !com_sv_running->integer ) {
// clear the whole hunk
Hunk_Clear();
// clear collision map data
@ -1417,6 +1418,7 @@ void CL_Disconnect( qboolean showMainMenu ) {
for (i = 0; i < MAX_CLIENTS; i++) {
opus_decoder_destroy(clc.opusDecoder[i]);
}
clc.voipCodecInitialized = qfalse;
}
Cmd_RemoveCommand ("voip");
#endif
@ -1537,7 +1539,7 @@ void CL_RequestMotd( void ) {
info[0] = 0;
Com_sprintf( cls.updateChallenge, sizeof( cls.updateChallenge ), "%i", ((rand() << 16) ^ rand()) ^ Com_Milliseconds());
Com_sprintf( cls.updateChallenge, sizeof( cls.updateChallenge ), "%i", (int)((((unsigned int)rand() << 16) ^ (unsigned int)rand()) ^ Com_Milliseconds()));
Info_SetValueForKey( info, "challenge", cls.updateChallenge );
Info_SetValueForKey( info, "renderer", cls.glconfig.renderer_string );
@ -1689,7 +1691,7 @@ CL_Connect_f
================
*/
void CL_Connect_f( void ) {
char *server;
char server[MAX_OSPATH];
const char *serverString;
int argc = Cmd_Argc();
netadrtype_t family = NA_UNSPEC;
@ -1700,7 +1702,7 @@ void CL_Connect_f( void ) {
}
if(argc == 2)
server = Cmd_Argv(1);
Q_strncpyz( server, Cmd_Argv(1), sizeof( server ) );
else
{
if(!strcmp(Cmd_Argv(1), "-4"))
@ -1710,7 +1712,7 @@ void CL_Connect_f( void ) {
else
Com_Printf( "warning: only -4 or -6 as address type understood.\n");
server = Cmd_Argv(2);
Q_strncpyz( server, Cmd_Argv(2), sizeof( server ) );
}
// save arguments for reconnect
@ -1766,7 +1768,7 @@ void CL_Connect_f( void ) {
clc.state = CA_CONNECTING;
// Set a client challenge number that ideally is mirrored back by the server.
clc.challenge = ((rand() << 16) ^ rand()) ^ Com_Milliseconds();
clc.challenge = (((unsigned int)rand() << 16) ^ (unsigned int)rand()) ^ Com_Milliseconds();
}
Key_SetCatcher( 0 );
@ -1806,7 +1808,7 @@ static void CL_CompletePlayerName( char *args, int argNum )
if( argNum == 2 )
{
char names[MAX_CLIENTS][MAX_NAME_LENGTH];
char *namesPtr[MAX_CLIENTS];
const char *namesPtr[MAX_CLIENTS];
int i;
int clientCount;
int nameCount;
@ -1889,6 +1891,7 @@ void CL_Rcon_f( void ) {
}
NET_SendPacket (NS_CLIENT, strlen(message)+1, message, to);
cls.rconAddress = to;
}
/*
@ -1957,7 +1960,7 @@ void CL_Vid_Restart_f( void ) {
CL_ShutdownCGame();
// shutdown the renderer and clear the renderer interface
CL_ShutdownRef();
// client is no longer pure untill new checksums are sent
// client is no longer pure until new checksums are sent
CL_ResetPureClientAtServer();
// clear pak references
FS_ClearPakReferences( FS_UI_REF | FS_CGAME_REF );
@ -1968,7 +1971,7 @@ void CL_Vid_Restart_f( void ) {
cls.cgameStarted = qfalse;
cls.soundRegistered = qfalse;
// unpause so the cgame definately gets a snapshot and renders a frame
// unpause so the cgame definitely gets a snapshot and renders a frame
Cvar_Set("cl_paused", "0");
// initialize the renderer interface
@ -2468,7 +2471,7 @@ void CL_ServersResponsePacket( const netadr_t* from, msg_t *msg, qboolean extend
byte* buffptr;
byte* buffend;
Com_Printf("CL_ServersResponsePacket\n");
Com_Printf("CL_ServersResponsePacket from %s\n", NET_AdrToStringwPort(*from));
if (cls.numglobalservers == -1) {
// state to detect lack of servers or lack of response
@ -2747,7 +2750,10 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
// echo request from server
if ( !Q_stricmp(c, "echo") ) {
NET_OutOfBandPrint( NS_CLIENT, from, "%s", Cmd_Argv(1) );
// NOTE: we may have to add exceptions for auth and update servers
if ( NET_CompareAdr( from, clc.serverAddress ) || NET_CompareAdr( from, cls.rconAddress ) ) {
NET_OutOfBandPrint( NS_CLIENT, from, "%s", Cmd_Argv(1) );
}
return;
}
@ -2764,12 +2770,14 @@ void CL_ConnectionlessPacket( netadr_t from, msg_t *msg ) {
}
// echo request from server
if(!Q_stricmp(c, "print")){
s = MSG_ReadString( msg );
Q_strncpyz( clc.serverMessage, s, sizeof( clc.serverMessage ) );
Com_Printf( "%s", s );
if ( !Q_stricmp(c, "print") ) {
// NOTE: we may have to add exceptions for auth and update servers
if ( NET_CompareAdr( from, clc.serverAddress ) || NET_CompareAdr( from, cls.rconAddress ) ) {
s = MSG_ReadString( msg );
Q_strncpyz( clc.serverMessage, s, sizeof( clc.serverMessage ) );
Com_Printf( "%s", s );
}
return;
}
@ -3208,7 +3216,7 @@ void CL_InitRef( void ) {
Com_Printf("failed:\n\"%s\"\n", Sys_LibraryError());
Cvar_ForceReset("cl_renderer");
Com_sprintf(dllName, sizeof(dllName), "renderer_opengl1_" ARCH_STRING DLL_EXT);
Com_sprintf(dllName, sizeof(dllName), "renderer_opengl2_" ARCH_STRING DLL_EXT);
rendererLib = Sys_LoadDll(dllName, qfalse);
}
@ -3293,7 +3301,7 @@ void CL_InitRef( void ) {
re = *ret;
// unpause so the cgame definately gets a snapshot and renders a frame
// unpause so the cgame definitely gets a snapshot and renders a frame
Cvar_Set( "cl_paused", "0" );
}
@ -3550,11 +3558,11 @@ void CL_Init( void ) {
cl_allowDownload = Cvar_Get ("cl_allowDownload", "0", CVAR_ARCHIVE);
#ifdef USE_CURL_DLOPEN
cl_cURLLib = Cvar_Get("cl_cURLLib", DEFAULT_CURL_LIB, CVAR_ARCHIVE);
cl_cURLLib = Cvar_Get("cl_cURLLib", DEFAULT_CURL_LIB, CVAR_ARCHIVE | CVAR_PROTECTED);
#endif
cl_conXOffset = Cvar_Get ("cl_conXOffset", "0", 0);
#ifdef MACOS_X
#ifdef __APPLE__
// In game video is REALLY slow in Mac OS X right now due to driver slowness
cl_inGameVideo = Cvar_Get ("r_inGameVideo", "0", CVAR_ARCHIVE);
#else
@ -3571,7 +3579,7 @@ void CL_Init( void ) {
m_yaw = Cvar_Get ("m_yaw", "0.022", CVAR_ARCHIVE);
m_forward = Cvar_Get ("m_forward", "0.25", CVAR_ARCHIVE);
m_side = Cvar_Get ("m_side", "0.25", CVAR_ARCHIVE);
#ifdef MACOS_X
#ifdef __APPLE__
// Input is jittery on OS X w/o this
m_filter = Cvar_Get ("m_filter", "1", CVAR_ARCHIVE);
#else
@ -3582,13 +3590,13 @@ void CL_Init( void ) {
j_yaw = Cvar_Get ("j_yaw", "-0.022", CVAR_ARCHIVE);
j_forward = Cvar_Get ("j_forward", "-0.25", CVAR_ARCHIVE);
j_side = Cvar_Get ("j_side", "0.25", CVAR_ARCHIVE);
j_up = Cvar_Get ("j_up", "1", CVAR_ARCHIVE);
j_up = Cvar_Get ("j_up", "0", CVAR_ARCHIVE);
j_pitch_axis = Cvar_Get ("j_pitch_axis", "3", CVAR_ARCHIVE);
j_yaw_axis = Cvar_Get ("j_yaw_axis", "4", CVAR_ARCHIVE);
j_yaw_axis = Cvar_Get ("j_yaw_axis", "2", CVAR_ARCHIVE);
j_forward_axis = Cvar_Get ("j_forward_axis", "1", CVAR_ARCHIVE);
j_side_axis = Cvar_Get ("j_side_axis", "0", CVAR_ARCHIVE);
j_up_axis = Cvar_Get ("j_up_axis", "2", CVAR_ARCHIVE);
j_up_axis = Cvar_Get ("j_up_axis", "4", CVAR_ARCHIVE);
Cvar_CheckRange(j_pitch_axis, 0, MAX_JOYSTICK_AXIS-1, qtrue);
Cvar_CheckRange(j_yaw_axis, 0, MAX_JOYSTICK_AXIS-1, qtrue);
@ -4157,6 +4165,10 @@ void CL_LocalServers_f( void ) {
/*
==================
CL_GlobalServers_f
Originally master 0 was Internet and master 1 was MPlayer.
ioquake3 2008; added support for requesting five separate master servers using 0-4.
ioquake3 2017; made master 0 fetch all master servers and 1-5 request a single master server.
==================
*/
void CL_GlobalServers_f( void ) {
@ -4164,13 +4176,36 @@ void CL_GlobalServers_f( void ) {
int count, i, masterNum;
char command[1024], *masteraddress;
if ((count = Cmd_Argc()) < 3 || (masterNum = atoi(Cmd_Argv(1))) < 0 || masterNum > MAX_MASTER_SERVERS - 1)
if ((count = Cmd_Argc()) < 3 || (masterNum = atoi(Cmd_Argv(1))) < 0 || masterNum > MAX_MASTER_SERVERS)
{
Com_Printf("usage: globalservers <master# 0-%d> <protocol> [keywords]\n", MAX_MASTER_SERVERS - 1);
Com_Printf("usage: globalservers <master# 0-%d> <protocol> [keywords]\n", MAX_MASTER_SERVERS);
return;
}
sprintf(command, "sv_master%d", masterNum + 1);
// request from all master servers
if ( masterNum == 0 ) {
int numAddress = 0;
for ( i = 1; i <= MAX_MASTER_SERVERS; i++ ) {
sprintf(command, "sv_master%d", i);
masteraddress = Cvar_VariableString(command);
if(!*masteraddress)
continue;
numAddress++;
Com_sprintf(command, sizeof(command), "globalservers %d %s %s\n", i, Cmd_Argv(2), Cmd_ArgsFrom(3));
Cbuf_AddText(command);
}
if ( !numAddress ) {
Com_Printf( "CL_GlobalServers_f: Error: No master server addresses.\n");
}
return;
}
sprintf(command, "sv_master%d", masterNum);
masteraddress = Cvar_VariableString(command);
if(!*masteraddress)
@ -4192,7 +4227,7 @@ void CL_GlobalServers_f( void ) {
else if(i == 2)
to.port = BigShort(PORT_MASTER);
Com_Printf("Requesting servers from master %s...\n", masteraddress);
Com_Printf("Requesting servers from %s (%s)...\n", masteraddress, NET_AdrToStringwPort(to));
cls.numglobalservers = -1;
cls.pingUpdateSource = AS_GLOBAL;

View file

@ -399,7 +399,7 @@ void CL_SystemInfoChanged( void ) {
// ehw!
if (!Q_stricmp(key, "fs_game"))
{
if(FS_CheckDirTraversal(value))
if(FS_InvalidGameDir(value))
{
Com_Printf(S_COLOR_YELLOW "WARNING: Server sent invalid fs_game value %s\n", value);
continue;
@ -804,10 +804,10 @@ void CL_ParseVoip ( msg_t *msg, qboolean ignoreData ) {
#if 0
static FILE *encio = NULL;
if (encio == NULL) encio = fopen("voip-incoming-encoded.bin", "wb");
if (encio != NULL) { fwrite(encoded, len, 1, encio); fflush(encio); }
if (encio != NULL) { fwrite(encoded, packetsize, 1, encio); fflush(encio); }
static FILE *decio = NULL;
if (decio == NULL) decio = fopen("voip-incoming-decoded.bin", "wb");
if (decio != NULL) { fwrite(decoded+written, clc.speexFrameSize*2, 1, decio); fflush(decio); }
if (decio != NULL) { fwrite(decoded+written, numSamples*2, 1, decio); fflush(decio); }
#endif
written += numSamples;

View file

@ -374,6 +374,7 @@ LAN_CompareServers
static int LAN_CompareServers( int source, int sortKey, int sortDir, int s1, int s2 ) {
int res;
serverInfo_t *server1, *server2;
int clients1, clients2;
server1 = LAN_GetServerPtr(source, s1);
server2 = LAN_GetServerPtr(source, s2);
@ -391,10 +392,19 @@ static int LAN_CompareServers( int source, int sortKey, int sortDir, int s1, int
res = Q_stricmp( server1->mapName, server2->mapName );
break;
case SORT_CLIENTS:
if (server1->clients < server2->clients) {
// sub sort by max clients
if ( server1->clients == server2->clients ) {
clients1 = server1->maxClients;
clients2 = server2->maxClients;
} else {
clients1 = server1->clients;
clients2 = server2->clients;
}
if (clients1 < clients2) {
res = -1;
}
else if (server1->clients > server2->clients) {
else if (clients1 > clients2) {
res = 1;
}
else {
@ -629,9 +639,9 @@ CLUI_GetCDKey
*/
static void CLUI_GetCDKey( char *buf, int buflen ) {
#ifndef STANDALONE
cvar_t *fs;
fs = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO );
if (UI_usesUniqueCDKey() && fs && fs->string[0] != 0) {
const char *gamedir;
gamedir = Cvar_VariableString( "fs_game" );
if (UI_usesUniqueCDKey() && gamedir[0] != 0) {
Com_Memcpy( buf, &cl_cdkey[16], 16);
buf[16] = 0;
} else {
@ -651,9 +661,9 @@ CLUI_SetCDKey
*/
#ifndef STANDALONE
static void CLUI_SetCDKey( char *buf ) {
cvar_t *fs;
fs = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO );
if (UI_usesUniqueCDKey() && fs && fs->string[0] != 0) {
const char *gamedir;
gamedir = Cvar_VariableString( "fs_game" );
if (UI_usesUniqueCDKey() && gamedir[0] != 0) {
Com_Memcpy( &cl_cdkey[16], buf, 16 );
cl_cdkey[32] = 0;
// set the flag so the fle will be written at the next opportunity
@ -780,7 +790,7 @@ intptr_t CL_UISystemCalls( intptr_t *args ) {
return FS_FOpenFileByMode( VMA(1), VMA(2), args[3] );
case UI_FS_READ:
FS_Read2( VMA(1), args[2], args[3] );
FS_Read( VMA(1), args[2], args[3] );
return 0;
case UI_FS_WRITE:

View file

@ -344,6 +344,8 @@ typedef struct {
netadr_t authorizeServer;
netadr_t rconAddress;
// rendering info
glconfig_t glconfig;
qhandle_t charSetShader;

View file

@ -260,6 +260,36 @@ typedef enum {
K_EURO,
K_UNDO,
// Gamepad controls
// Ordered to match SDL2 game controller buttons and axes
// Do not change this order without also changing IN_GamepadMove() in SDL_input.c
K_PAD0_A,
K_PAD0_B,
K_PAD0_X,
K_PAD0_Y,
K_PAD0_BACK,
K_PAD0_GUIDE,
K_PAD0_START,
K_PAD0_LEFTSTICK_CLICK,
K_PAD0_RIGHTSTICK_CLICK,
K_PAD0_LEFTSHOULDER,
K_PAD0_RIGHTSHOULDER,
K_PAD0_DPAD_UP,
K_PAD0_DPAD_DOWN,
K_PAD0_DPAD_LEFT,
K_PAD0_DPAD_RIGHT,
K_PAD0_LEFTSTICK_LEFT,
K_PAD0_LEFTSTICK_RIGHT,
K_PAD0_LEFTSTICK_UP,
K_PAD0_LEFTSTICK_DOWN,
K_PAD0_RIGHTSTICK_LEFT,
K_PAD0_RIGHTSTICK_RIGHT,
K_PAD0_RIGHTSTICK_UP,
K_PAD0_RIGHTSTICK_DOWN,
K_PAD0_LEFTTRIGGER,
K_PAD0_RIGHTTRIGGER,
// Pseudo-key that brings the console down
K_CONSOLE,

View file

@ -37,8 +37,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../AL/al.h"
#include "../AL/alc.h"
#else
#ifdef _MSC_VER
#if defined(_MSC_VER) || defined(__APPLE__)
// MSVC users must install the OpenAL SDK which doesn't use the AL/*.h scheme.
// OSX framework also needs this
#include <al.h>
#include <alc.h>
#else

View file

@ -25,7 +25,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/*
** Intel/DVI ADPCM coder/decoder.
**
** The algorithm for this coder was taken from the IMA Compatability Project
** The algorithm for this coder was taken from the IMA Compatibility Project
** proceedings, Vol 2, Number 2; May 1992.
**
** Version 1.2, 18-Dec-92.

229
code/client/snd_altivec.c Normal file
View file

@ -0,0 +1,229 @@
/*
===========================================================================
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
===========================================================================
*/
/* This file is only compiled for PowerPC builds with Altivec support.
Altivec intrinsics need to be in a separate file, so GCC's -maltivec
command line can enable them, but give us the option to _not_ use that
on other files, where the compiler might then generate Altivec
instructions for normal floating point, crashing on G3 (etc) processors. */
#include "client.h"
#include "snd_local.h"
#if idppc_altivec
#if !defined(__APPLE__)
#include <altivec.h>
#endif
void S_PaintChannelFrom16_altivec( portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE], int snd_vol, channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset ) {
int data, aoff, boff;
int leftvol, rightvol;
int i, j;
portable_samplepair_t *samp;
sndBuffer *chunk;
short *samples;
float ooff, fdata[2], fdiv, fleftvol, frightvol;
if (sc->soundChannels <= 0) {
return;
}
samp = &paintbuffer[ bufferOffset ];
if (ch->doppler) {
sampleOffset = sampleOffset*ch->oldDopplerScale;
}
if ( sc->soundChannels == 2 ) {
sampleOffset *= sc->soundChannels;
if ( sampleOffset & 1 ) {
sampleOffset &= ~1;
}
}
chunk = sc->soundData;
while (sampleOffset>=SND_CHUNK_SIZE) {
chunk = chunk->next;
sampleOffset -= SND_CHUNK_SIZE;
if (!chunk) {
chunk = sc->soundData;
}
}
if (!ch->doppler || ch->dopplerScale==1.0f) {
vector signed short volume_vec;
vector unsigned int volume_shift;
int vectorCount, samplesLeft, chunkSamplesLeft;
leftvol = ch->leftvol*snd_vol;
rightvol = ch->rightvol*snd_vol;
samples = chunk->sndChunk;
((short *)&volume_vec)[0] = leftvol;
((short *)&volume_vec)[1] = leftvol;
((short *)&volume_vec)[4] = leftvol;
((short *)&volume_vec)[5] = leftvol;
((short *)&volume_vec)[2] = rightvol;
((short *)&volume_vec)[3] = rightvol;
((short *)&volume_vec)[6] = rightvol;
((short *)&volume_vec)[7] = rightvol;
volume_shift = vec_splat_u32(8);
i = 0;
while(i < count) {
/* Try to align destination to 16-byte boundary */
while(i < count && (((unsigned long)&samp[i] & 0x1f) || ((count-i) < 8) || ((SND_CHUNK_SIZE - sampleOffset) < 8))) {
data = samples[sampleOffset++];
samp[i].left += (data * leftvol)>>8;
if ( sc->soundChannels == 2 ) {
data = samples[sampleOffset++];
}
samp[i].right += (data * rightvol)>>8;
if (sampleOffset == SND_CHUNK_SIZE) {
chunk = chunk->next;
samples = chunk->sndChunk;
sampleOffset = 0;
}
i++;
}
/* Destination is now aligned. Process as many 8-sample
chunks as we can before we run out of room from the current
sound chunk. We do 8 per loop to avoid extra source data reads. */
samplesLeft = count - i;
chunkSamplesLeft = SND_CHUNK_SIZE - sampleOffset;
if(samplesLeft > chunkSamplesLeft)
samplesLeft = chunkSamplesLeft;
vectorCount = samplesLeft / 8;
if(vectorCount)
{
vector unsigned char tmp;
vector short s0, s1, sampleData0, sampleData1;
vector signed int merge0, merge1;
vector signed int d0, d1, d2, d3;
vector unsigned char samplePermute0 =
VECCONST_UINT8(0, 1, 4, 5, 0, 1, 4, 5, 2, 3, 6, 7, 2, 3, 6, 7);
vector unsigned char samplePermute1 =
VECCONST_UINT8(8, 9, 12, 13, 8, 9, 12, 13, 10, 11, 14, 15, 10, 11, 14, 15);
vector unsigned char loadPermute0, loadPermute1;
// Rather than permute the vectors after we load them to do the sample
// replication and rearrangement, we permute the alignment vector so
// we do everything in one step below and avoid data shuffling.
tmp = vec_lvsl(0,&samples[sampleOffset]);
loadPermute0 = vec_perm(tmp,tmp,samplePermute0);
loadPermute1 = vec_perm(tmp,tmp,samplePermute1);
s0 = *(vector short *)&samples[sampleOffset];
while(vectorCount)
{
/* Load up source (16-bit) sample data */
s1 = *(vector short *)&samples[sampleOffset+7];
/* Load up destination sample data */
d0 = *(vector signed int *)&samp[i];
d1 = *(vector signed int *)&samp[i+2];
d2 = *(vector signed int *)&samp[i+4];
d3 = *(vector signed int *)&samp[i+6];
sampleData0 = vec_perm(s0,s1,loadPermute0);
sampleData1 = vec_perm(s0,s1,loadPermute1);
merge0 = vec_mule(sampleData0,volume_vec);
merge0 = vec_sra(merge0,volume_shift); /* Shift down to proper range */
merge1 = vec_mulo(sampleData0,volume_vec);
merge1 = vec_sra(merge1,volume_shift);
d0 = vec_add(merge0,d0);
d1 = vec_add(merge1,d1);
merge0 = vec_mule(sampleData1,volume_vec);
merge0 = vec_sra(merge0,volume_shift); /* Shift down to proper range */
merge1 = vec_mulo(sampleData1,volume_vec);
merge1 = vec_sra(merge1,volume_shift);
d2 = vec_add(merge0,d2);
d3 = vec_add(merge1,d3);
/* Store destination sample data */
*(vector signed int *)&samp[i] = d0;
*(vector signed int *)&samp[i+2] = d1;
*(vector signed int *)&samp[i+4] = d2;
*(vector signed int *)&samp[i+6] = d3;
i += 8;
vectorCount--;
s0 = s1;
sampleOffset += 8;
}
if (sampleOffset == SND_CHUNK_SIZE) {
chunk = chunk->next;
samples = chunk->sndChunk;
sampleOffset = 0;
}
}
}
} else {
fleftvol = ch->leftvol*snd_vol;
frightvol = ch->rightvol*snd_vol;
ooff = sampleOffset;
samples = chunk->sndChunk;
for ( i=0 ; i<count ; i++ ) {
aoff = ooff;
ooff = ooff + ch->dopplerScale * sc->soundChannels;
boff = ooff;
fdata[0] = fdata[1] = 0;
for (j=aoff; j<boff; j += sc->soundChannels) {
if (j == SND_CHUNK_SIZE) {
chunk = chunk->next;
if (!chunk) {
chunk = sc->soundData;
}
samples = chunk->sndChunk;
ooff -= SND_CHUNK_SIZE;
}
if ( sc->soundChannels == 2 ) {
fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
fdata[1] += samples[(j+1)&(SND_CHUNK_SIZE-1)];
} else {
fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
fdata[1] += samples[j&(SND_CHUNK_SIZE-1)];
}
}
fdiv = 256 * (boff-aoff) / sc->soundChannels;
samp[i].left += (fdata[0] * fleftvol)/fdiv;
samp[i].right += (fdata[1] * frightvol)/fdiv;
}
}
}
#endif

View file

@ -98,9 +98,9 @@ void S_Base_SoundInfo(void) {
if (!s_soundStarted) {
Com_Printf ("sound system not started\n");
} else {
Com_Printf("%5d stereo\n", dma.channels - 1);
Com_Printf("%5d channels\n", dma.channels);
Com_Printf("%5d samples\n", dma.samples);
Com_Printf("%5d samplebits\n", dma.samplebits);
Com_Printf("%5d samplebits (%s)\n", dma.samplebits, dma.isfloat ? "float" : "int");
Com_Printf("%5d submission_chunk\n", dma.submission_chunk);
Com_Printf("%5d speed\n", dma.speed);
Com_Printf("%p dma buffer\n", dma.buffer);
@ -119,32 +119,31 @@ void S_Base_SoundInfo(void) {
static
void S_Base_StartCapture( void )
{
// !!! FIXME: write me.
SNDDMA_StartCapture();
}
static
int S_Base_AvailableCaptureSamples( void )
{
// !!! FIXME: write me.
return 0;
return SNDDMA_AvailableCaptureSamples();
}
static
void S_Base_Capture( int samples, byte *data )
{
// !!! FIXME: write me.
SNDDMA_Capture(samples, data);
}
static
void S_Base_StopCapture( void )
{
// !!! FIXME: write me.
SNDDMA_StopCapture();
}
static
void S_Base_MasterGain( float val )
{
// !!! FIXME: write me.
SNDDMA_MasterGain(val);
}
#endif
@ -432,7 +431,7 @@ void S_SpatializeOrigin (vec3_t origin, int master_vol, int *left_vol, int *righ
const float dist_mult = SOUND_ATTENUATE;
// calculate stereo seperation and distance attenuation
// calculate stereo separation and distance attenuation
VectorSubtract(origin, listener_origin, source_vec);
dist = VectorNormalize(source_vec);
@ -1243,9 +1242,6 @@ void S_GetSoundtime(void)
int samplepos;
static int buffers;
static int oldsamplepos;
int fullsamples;
fullsamples = dma.samples / dma.channels;
if( CL_VideoRecording( ) )
{
@ -1269,13 +1265,13 @@ void S_GetSoundtime(void)
if (s_paintedtime > 0x40000000)
{ // time to chop things off to avoid 32 bit limits
buffers = 0;
s_paintedtime = fullsamples;
s_paintedtime = dma.fullsamples;
S_Base_StopAllSounds ();
}
}
oldsamplepos = samplepos;
s_soundtime = buffers*fullsamples + samplepos/dma.channels;
s_soundtime = buffers*dma.fullsamples + samplepos/dma.channels;
#if 0
// check to make sure that we haven't overshot
@ -1296,7 +1292,6 @@ void S_GetSoundtime(void)
void S_Update_(void) {
unsigned endtime;
int samps;
static float lastTime = 0.0f;
float ma, op;
float thisTime, sane;
@ -1340,9 +1335,8 @@ void S_Update_(void) {
& ~(dma.submission_chunk-1);
// never mix more than the complete buffer
samps = dma.samples >> (dma.channels-1);
if (endtime - s_soundtime > samps)
endtime = s_soundtime + samps;
if (endtime - s_soundtime > dma.fullsamples)
endtime = s_soundtime + dma.fullsamples;

View file

@ -65,8 +65,10 @@ typedef struct sfx_s {
typedef struct {
int channels;
int samples; // mono samples in buffer
int fullsamples; // samples with all channels in buffer (samples divided by channels)
int submission_chunk; // don't mix less than this #
int samplebits;
int isfloat;
int speed;
byte *buffer;
} dma_t;
@ -175,6 +177,15 @@ void SNDDMA_BeginPainting (void);
void SNDDMA_Submit(void);
#ifdef USE_VOIP
void SNDDMA_StartCapture(void);
int SNDDMA_AvailableCaptureSamples(void);
void SNDDMA_Capture(int samples, byte *data);
void SNDDMA_StopCapture(void);
void SNDDMA_MasterGain(float val);
#endif
//====================================================================
#define MAX_CHANNELS 96
@ -254,3 +265,7 @@ typedef enum
typedef int srcHandle_t;
qboolean S_AL_Init( soundInterface_t *si );
#ifdef idppc_altivec
void S_PaintChannelFrom16_altivec( portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE], int snd_vol, channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset );
#endif

View file

@ -498,7 +498,7 @@ void S_Init( void )
Cmd_AddCommand( "s_stop", S_StopAllSounds );
Cmd_AddCommand( "s_info", S_SoundInfo );
cv = Cvar_Get( "s_useOpenAL", "1", CVAR_ARCHIVE );
cv = Cvar_Get( "s_useOpenAL", "1", CVAR_ARCHIVE | CVAR_LATCH );
if( cv->integer ) {
//OpenAL
started = S_AL_Init( &si );

View file

@ -126,20 +126,22 @@ static int ResampleSfx( sfx_t *sfx, int channels, int inrate, int inwidth, int s
outcount = samples / stepscale;
srcsample = 0;
samplefrac = 0;
fracstep = stepscale * 256 * channels;
chunk = sfx->soundData;
for (i=0 ; i<outcount ; i++)
{
srcsample = samplefrac >> 8;
srcsample += samplefrac >> 8;
samplefrac &= 255;
samplefrac += fracstep;
for (j=0 ; j<channels ; j++)
{
if( inwidth == 2 ) {
sample = ( ((short *)data)[srcsample+j] );
} else {
sample = (int)( (unsigned char)(data[srcsample+j]) - 128) << 8;
sample = (unsigned int)( (unsigned char)(data[srcsample+j]) - 128) << 8;
}
part = (i*channels+j)&(SND_CHUNK_SIZE-1);
if (part == 0) {
@ -178,12 +180,14 @@ static int ResampleSfxRaw( short *sfx, int channels, int inrate, int inwidth, in
outcount = samples / stepscale;
srcsample = 0;
samplefrac = 0;
fracstep = stepscale * 256 * channels;
for (i=0 ; i<outcount ; i++)
{
srcsample = samplefrac >> 8;
srcsample += samplefrac >> 8;
samplefrac &= 255;
samplefrac += fracstep;
for (j=0 ; j<channels ; j++)
{

View file

@ -23,9 +23,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "client.h"
#include "snd_local.h"
#if idppc_altivec && !defined(MACOS_X)
#include <altivec.h>
#endif
static portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE];
static int snd_vol;
@ -122,24 +119,24 @@ void S_TransferStereo16 (unsigned long *pbuf, int endtime)
while (ls_paintedtime < endtime)
{
// handle recirculating buffer issues
lpos = ls_paintedtime & ((dma.samples>>1)-1);
lpos = ls_paintedtime % dma.fullsamples;
snd_out = (short *) pbuf + (lpos<<1);
snd_out = (short *) pbuf + (lpos<<1); // lpos * dma.channels
snd_linear_count = (dma.samples>>1) - lpos;
snd_linear_count = dma.fullsamples - lpos;
if (ls_paintedtime + snd_linear_count > endtime)
snd_linear_count = endtime - ls_paintedtime;
snd_linear_count <<= 1;
snd_linear_count <<= 1; // snd_linear_count *= dma.channels
// write a linear blast of samples
S_WriteLinearBlastStereo16 ();
snd_p += snd_linear_count;
ls_paintedtime += (snd_linear_count>>1);
ls_paintedtime += (snd_linear_count>>1); // snd_linear_count / dma.channels
if( CL_VideoRecording( ) )
CL_WriteAVIAudioFrame( (byte *)snd_out, snd_linear_count << 1 );
CL_WriteAVIAudioFrame( (byte *)snd_out, snd_linear_count << 1 ); // snd_linear_count * (dma.samplebits/8)
}
}
@ -153,18 +150,16 @@ void S_TransferPaintBuffer(int endtime)
{
int out_idx;
int count;
int out_mask;
int *p;
int step;
int val;
int i;
unsigned long *pbuf;
pbuf = (unsigned long *)dma.buffer;
if ( s_testsound->integer ) {
int i;
// write a fixed sine wave
count = (endtime - s_paintedtime);
for (i=0 ; i<count ; i++)
@ -180,38 +175,73 @@ void S_TransferPaintBuffer(int endtime)
{ // general case
p = (int *) paintbuffer;
count = (endtime - s_paintedtime) * dma.channels;
out_mask = dma.samples - 1;
out_idx = s_paintedtime * dma.channels & out_mask;
step = 3 - dma.channels;
out_idx = (s_paintedtime * dma.channels) % dma.samples;
step = 3 - MIN(dma.channels, 2);
if (dma.samplebits == 16)
if ((dma.isfloat) && (dma.samplebits == 32))
{
float *out = (float *) pbuf;
for (i=0 ; i<count ; i++)
{
if ((i % dma.channels) >= 2)
{
val = 0;
}
else
{
val = *p >> 8;
p+= step;
}
if (val > 0x7fff)
val = 0x7fff;
else if (val < -32767) /* clamp to one less than max to make division max out at -1.0f. */
val = -32767;
out[out_idx] = ((float) val) / 32767.0f;
out_idx = (out_idx + 1) % dma.samples;
}
}
else if (dma.samplebits == 16)
{
short *out = (short *) pbuf;
while (count--)
for (i=0 ; i<count ; i++)
{
val = *p >> 8;
p+= step;
if ((i % dma.channels) >= 2)
{
val = 0;
}
else
{
val = *p >> 8;
p+= step;
}
if (val > 0x7fff)
val = 0x7fff;
else if (val < -32768)
val = -32768;
out[out_idx] = val;
out_idx = (out_idx + 1) & out_mask;
out_idx = (out_idx + 1) % dma.samples;
}
}
else if (dma.samplebits == 8)
{
unsigned char *out = (unsigned char *) pbuf;
while (count--)
for (i=0 ; i<count ; i++)
{
val = *p >> 8;
p+= step;
if ((i % dma.channels) >= 2)
{
val = 0;
}
else
{
val = *p >> 8;
p+= step;
}
if (val > 0x7fff)
val = 0x7fff;
else if (val < -32768)
val = -32768;
out[out_idx] = (val>>8) + 128;
out_idx = (out_idx + 1) & out_mask;
out_idx = (out_idx + 1) % dma.samples;
}
}
}
@ -226,197 +256,6 @@ CHANNEL MIXING
===============================================================================
*/
#if idppc_altivec
static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset ) {
int data, aoff, boff;
int leftvol, rightvol;
int i, j;
portable_samplepair_t *samp;
sndBuffer *chunk;
short *samples;
float ooff, fdata[2], fdiv, fleftvol, frightvol;
if (sc->soundChannels <= 0) {
return;
}
samp = &paintbuffer[ bufferOffset ];
if (ch->doppler) {
sampleOffset = sampleOffset*ch->oldDopplerScale;
}
if ( sc->soundChannels == 2 ) {
sampleOffset *= sc->soundChannels;
if ( sampleOffset & 1 ) {
sampleOffset &= ~1;
}
}
chunk = sc->soundData;
while (sampleOffset>=SND_CHUNK_SIZE) {
chunk = chunk->next;
sampleOffset -= SND_CHUNK_SIZE;
if (!chunk) {
chunk = sc->soundData;
}
}
if (!ch->doppler || ch->dopplerScale==1.0f) {
vector signed short volume_vec;
vector unsigned int volume_shift;
int vectorCount, samplesLeft, chunkSamplesLeft;
leftvol = ch->leftvol*snd_vol;
rightvol = ch->rightvol*snd_vol;
samples = chunk->sndChunk;
((short *)&volume_vec)[0] = leftvol;
((short *)&volume_vec)[1] = leftvol;
((short *)&volume_vec)[4] = leftvol;
((short *)&volume_vec)[5] = leftvol;
((short *)&volume_vec)[2] = rightvol;
((short *)&volume_vec)[3] = rightvol;
((short *)&volume_vec)[6] = rightvol;
((short *)&volume_vec)[7] = rightvol;
volume_shift = vec_splat_u32(8);
i = 0;
while(i < count) {
/* Try to align destination to 16-byte boundary */
while(i < count && (((unsigned long)&samp[i] & 0x1f) || ((count-i) < 8) || ((SND_CHUNK_SIZE - sampleOffset) < 8))) {
data = samples[sampleOffset++];
samp[i].left += (data * leftvol)>>8;
if ( sc->soundChannels == 2 ) {
data = samples[sampleOffset++];
}
samp[i].right += (data * rightvol)>>8;
if (sampleOffset == SND_CHUNK_SIZE) {
chunk = chunk->next;
samples = chunk->sndChunk;
sampleOffset = 0;
}
i++;
}
/* Destination is now aligned. Process as many 8-sample
chunks as we can before we run out of room from the current
sound chunk. We do 8 per loop to avoid extra source data reads. */
samplesLeft = count - i;
chunkSamplesLeft = SND_CHUNK_SIZE - sampleOffset;
if(samplesLeft > chunkSamplesLeft)
samplesLeft = chunkSamplesLeft;
vectorCount = samplesLeft / 8;
if(vectorCount)
{
vector unsigned char tmp;
vector short s0, s1, sampleData0, sampleData1;
vector signed int merge0, merge1;
vector signed int d0, d1, d2, d3;
vector unsigned char samplePermute0 =
VECCONST_UINT8(0, 1, 4, 5, 0, 1, 4, 5, 2, 3, 6, 7, 2, 3, 6, 7);
vector unsigned char samplePermute1 =
VECCONST_UINT8(8, 9, 12, 13, 8, 9, 12, 13, 10, 11, 14, 15, 10, 11, 14, 15);
vector unsigned char loadPermute0, loadPermute1;
// Rather than permute the vectors after we load them to do the sample
// replication and rearrangement, we permute the alignment vector so
// we do everything in one step below and avoid data shuffling.
tmp = vec_lvsl(0,&samples[sampleOffset]);
loadPermute0 = vec_perm(tmp,tmp,samplePermute0);
loadPermute1 = vec_perm(tmp,tmp,samplePermute1);
s0 = *(vector short *)&samples[sampleOffset];
while(vectorCount)
{
/* Load up source (16-bit) sample data */
s1 = *(vector short *)&samples[sampleOffset+7];
/* Load up destination sample data */
d0 = *(vector signed int *)&samp[i];
d1 = *(vector signed int *)&samp[i+2];
d2 = *(vector signed int *)&samp[i+4];
d3 = *(vector signed int *)&samp[i+6];
sampleData0 = vec_perm(s0,s1,loadPermute0);
sampleData1 = vec_perm(s0,s1,loadPermute1);
merge0 = vec_mule(sampleData0,volume_vec);
merge0 = vec_sra(merge0,volume_shift); /* Shift down to proper range */
merge1 = vec_mulo(sampleData0,volume_vec);
merge1 = vec_sra(merge1,volume_shift);
d0 = vec_add(merge0,d0);
d1 = vec_add(merge1,d1);
merge0 = vec_mule(sampleData1,volume_vec);
merge0 = vec_sra(merge0,volume_shift); /* Shift down to proper range */
merge1 = vec_mulo(sampleData1,volume_vec);
merge1 = vec_sra(merge1,volume_shift);
d2 = vec_add(merge0,d2);
d3 = vec_add(merge1,d3);
/* Store destination sample data */
*(vector signed int *)&samp[i] = d0;
*(vector signed int *)&samp[i+2] = d1;
*(vector signed int *)&samp[i+4] = d2;
*(vector signed int *)&samp[i+6] = d3;
i += 8;
vectorCount--;
s0 = s1;
sampleOffset += 8;
}
if (sampleOffset == SND_CHUNK_SIZE) {
chunk = chunk->next;
samples = chunk->sndChunk;
sampleOffset = 0;
}
}
}
} else {
fleftvol = ch->leftvol*snd_vol;
frightvol = ch->rightvol*snd_vol;
ooff = sampleOffset;
samples = chunk->sndChunk;
for ( i=0 ; i<count ; i++ ) {
aoff = ooff;
ooff = ooff + ch->dopplerScale * sc->soundChannels;
boff = ooff;
fdata[0] = fdata[1] = 0;
for (j=aoff; j<boff; j += sc->soundChannels) {
if (j == SND_CHUNK_SIZE) {
chunk = chunk->next;
if (!chunk) {
chunk = sc->soundData;
}
samples = chunk->sndChunk;
ooff -= SND_CHUNK_SIZE;
}
if ( sc->soundChannels == 2 ) {
fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
fdata[1] += samples[(j+1)&(SND_CHUNK_SIZE-1)];
} else {
fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
fdata[1] += samples[j&(SND_CHUNK_SIZE-1)];
}
}
fdiv = 256 * (boff-aoff) / sc->soundChannels;
samp[i].left += (fdata[0] * fleftvol)/fdiv;
samp[i].right += (fdata[1] * frightvol)/fdiv;
}
}
}
#endif
static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset ) {
int data, aoff, boff;
int leftvol, rightvol;
@ -515,8 +354,8 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
static void S_PaintChannelFrom16( channel_t *ch, const sfx_t *sc, int count, int sampleOffset, int bufferOffset ) {
#if idppc_altivec
if (com_altivec->integer) {
// must be in a seperate function or G3 systems will crash.
S_PaintChannelFrom16_altivec( ch, sc, count, sampleOffset, bufferOffset );
// must be in a separate translation unit or G3 systems will crash.
S_PaintChannelFrom16_altivec( paintbuffer, snd_vol, ch, sc, count, sampleOffset, bufferOffset );
return;
}
#endif

View file

@ -692,7 +692,7 @@ typedef struct src_s
qboolean local; // Is this local (relative to the cam)
} src_t;
#ifdef MACOS_X
#ifdef __APPLE__
#define MAX_SRC 64
#else
#define MAX_SRC 128
@ -1031,7 +1031,8 @@ static void S_AL_NewLoopMaster(src_t *rmSource, qboolean iskilled)
S_AL_SaveLoopPos(rmSource, rmSource->alSource);
}
}
else if(rmSource == &srcList[curSfx->masterLoopSrc])
else if(curSfx->masterLoopSrc != -1 &&
rmSource == &srcList[curSfx->masterLoopSrc])
{
int firstInactive = -1;
@ -2350,9 +2351,11 @@ static ALCdevice *alCaptureDevice;
static cvar_t *s_alCapture;
#endif
#ifdef _WIN32
#if defined(_WIN64)
#define ALDRIVER_DEFAULT "OpenAL64.dll"
#elif defined(_WIN32)
#define ALDRIVER_DEFAULT "OpenAL32.dll"
#elif defined(MACOS_X)
#elif defined(__APPLE__)
#define ALDRIVER_DEFAULT "/System/Library/Frameworks/OpenAL.framework/OpenAL"
#elif defined(__OpenBSD__)
#define ALDRIVER_DEFAULT "libopenal.so"
@ -3266,7 +3269,7 @@ qboolean S_AL_Init( soundInterface_t *si )
s_alRolloff = Cvar_Get( "s_alRolloff", "2", CVAR_CHEAT);
s_alGraceDistance = Cvar_Get("s_alGraceDistance", "512", CVAR_CHEAT);
s_alDriver = Cvar_Get( "s_alDriver", ALDRIVER_DEFAULT, CVAR_ARCHIVE | CVAR_LATCH );
s_alDriver = Cvar_Get( "s_alDriver", ALDRIVER_DEFAULT, CVAR_ARCHIVE | CVAR_LATCH | CVAR_PROTECTED );
s_alInputDevice = Cvar_Get( "s_alInputDevice", "", CVAR_ARCHIVE | CVAR_LATCH );
s_alDevice = Cvar_Get("s_alDevice", "", CVAR_ARCHIVE | CVAR_LATCH);
@ -3404,7 +3407,7 @@ qboolean S_AL_Init( soundInterface_t *si )
#endif
else
{
#ifdef MACOS_X
#ifdef __APPLE__
// !!! FIXME: Apple has a 1.1-compliant OpenAL, which includes
// !!! FIXME: capture support, but they don't list it in the
// !!! FIXME: extension string. We need to check the version string,

View file

@ -30,7 +30,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
void daub4(float b[], unsigned long n, int isign)
{
float wksp[4097] = { 0.0f };
float *a=b-1; // numerical recipies so a[1] = b[0]
#define a(x) b[(x)-1] // numerical recipies so a[1] = b[0]
unsigned long nh,nh1,i,j;
@ -39,22 +39,23 @@ void daub4(float b[], unsigned long n, int isign)
nh1=(nh=n >> 1)+1;
if (isign >= 0) {
for (i=1,j=1;j<=n-3;j+=2,i++) {
wksp[i] = C0*a[j]+C1*a[j+1]+C2*a[j+2]+C3*a[j+3];
wksp[i+nh] = C3*a[j]-C2*a[j+1]+C1*a[j+2]-C0*a[j+3];
wksp[i] = C0*a(j)+C1*a(j+1)+C2*a(j+2)+C3*a(j+3);
wksp[i+nh] = C3*a(j)-C2*a(j+1)+C1*a(j+2)-C0*a(j+3);
}
wksp[i ] = C0*a[n-1]+C1*a[n]+C2*a[1]+C3*a[2];
wksp[i+nh] = C3*a[n-1]-C2*a[n]+C1*a[1]-C0*a[2];
wksp[i ] = C0*a(n-1)+C1*a(n)+C2*a(1)+C3*a(2);
wksp[i+nh] = C3*a(n-1)-C2*a(n)+C1*a(1)-C0*a(2);
} else {
wksp[1] = C2*a[nh]+C1*a[n]+C0*a[1]+C3*a[nh1];
wksp[2] = C3*a[nh]-C0*a[n]+C1*a[1]-C2*a[nh1];
wksp[1] = C2*a(nh)+C1*a(n)+C0*a(1)+C3*a(nh1);
wksp[2] = C3*a(nh)-C0*a(n)+C1*a(1)-C2*a(nh1);
for (i=1,j=3;i<nh;i++) {
wksp[j++] = C2*a[i]+C1*a[i+nh]+C0*a[i+1]+C3*a[i+nh1];
wksp[j++] = C3*a[i]-C0*a[i+nh]+C1*a[i+1]-C2*a[i+nh1];
wksp[j++] = C2*a(i)+C1*a(i+nh)+C0*a(i+1)+C3*a(i+nh1);
wksp[j++] = C3*a(i)-C0*a(i+nh)+C1*a(i+1)-C2*a(i+nh1);
}
}
for (i=1;i<=n;i++) {
a[i]=wksp[i];
a(i)=wksp[i];
}
#undef a
}
void wt1(float a[], unsigned long n, int isign)

View file

@ -19,7 +19,7 @@ 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 "tr_common.h"
#include "../renderercommon/tr_common.h"
qboolean ( * qwglSwapIntervalEXT)( int interval );
@ -35,8 +35,7 @@ void ( * qglUnlockArraysEXT) ( void );
void GLimp_EndFrame( void ) {
}
int GLimp_Init( void )
{
void GLimp_Init( void ) {
}
void GLimp_Shutdown( void ) {
@ -45,12 +44,18 @@ void GLimp_Shutdown( void ) {
void GLimp_EnableLogging( qboolean enable ) {
}
void GLimp_LogComment( char *comment ) {
void GLimp_LogComment( char *comment ) {
}
qboolean QGL_Init( const char *dllname ) {
qboolean QGL_Init( const char *dllname ) {
return qtrue;
}
void QGL_Shutdown( void ) {
}
void GLimp_SetGamma( unsigned char red[256], unsigned char green[256], unsigned char blue[256] ) {
}
void GLimp_Minimize( void ) {
}

View file

@ -48,6 +48,30 @@ void SNDDMA_Submit(void)
{
}
#ifdef USE_VOIP
void SNDDMA_StartCapture(void)
{
}
int SNDDMA_AvailableCaptureSamples(void)
{
return 0;
}
void SNDDMA_Capture(int samples, byte *data)
{
}
void SNDDMA_StopCapture(void)
{
}
void SNDDMA_MasterGain( float val )
{
}
#endif
sfxHandle_t S_RegisterSound( const char *name, qboolean compressed )
{
return 0;

View file

@ -826,7 +826,7 @@ CM_AddFacetBevels
void CM_AddFacetBevels( facet_t *facet ) {
int i, j, k, l;
int axis, dir, order, flipped;
int axis, dir, flipped;
float plane[4], d, newplane[4];
winding_t *w, *w2;
vec3_t mins, maxs, vec, vec2;
@ -852,10 +852,9 @@ void CM_AddFacetBevels( facet_t *facet ) {
WindingBounds(w, mins, maxs);
// add the axial planes
order = 0;
for ( axis = 0 ; axis < 3 ; axis++ )
{
for ( dir = -1 ; dir <= 1 ; dir += 2, order++ )
for ( dir = -1 ; dir <= 1 ; dir += 2 )
{
VectorClear(plane);
plane[axis] = dir;
@ -869,7 +868,7 @@ void CM_AddFacetBevels( facet_t *facet ) {
if (CM_PlaneEqual(&planes[facet->surfacePlane], plane, &flipped)) {
continue;
}
// see if the plane is allready present
// see if the plane is already present
for ( i = 0 ; i < facet->numBorders ; i++ ) {
if (CM_PlaneEqual(&planes[facet->borderPlanes[i]], plane, &flipped))
break;
@ -933,7 +932,7 @@ void CM_AddFacetBevels( facet_t *facet ) {
if (CM_PlaneEqual(&planes[facet->surfacePlane], plane, &flipped)) {
continue;
}
// see if the plane is allready present
// see if the plane is already present
for ( i = 0 ; i < facet->numBorders ; i++ ) {
if (CM_PlaneEqual(&planes[facet->borderPlanes[i]], plane, &flipped)) {
break;
@ -1106,7 +1105,7 @@ static void CM_PatchCollideFromGrid( cGrid_t *grid, patchCollide_t *pf ) {
numFacets++;
}
} else {
// two seperate triangles
// two separate triangles
facet->surfacePlane = gridPlanes[i][j][0];
facet->numBorders = 3;
facet->borderPlanes[0] = borders[EN_TOP];
@ -1215,7 +1214,7 @@ struct patchCollide_s *CM_GeneratePatchCollide( int width, int height, vec3_t *p
CM_RemoveDegenerateColumns( &grid );
// we now have a grid of points exactly on the curve
// the aproximate surface defined by these points will be
// the approximate surface defined by these points will be
// collided against
pf = Hunk_Alloc( sizeof( *pf ), h_high );
ClearBounds( pf->bounds[0], pf->bounds[1] );
@ -1370,7 +1369,7 @@ int CM_CheckFacetPlane(float *plane, vec3_t start, vec3_t end, float *enterFrac,
return qfalse;
}
// if it doesn't cross the plane, the plane isn't relevent
// if it doesn't cross the plane, the plane isn't relevant
if (d1 <= 0 && d2 <= 0 ) {
return qtrue;
}
@ -1434,7 +1433,7 @@ void CM_TraceThroughPatchCollide( traceWork_t *tw, const struct patchCollide_s *
VectorCopy(planes->plane, plane);
plane[3] = planes->plane[3];
if ( tw->sphere.use ) {
// adjust the plane distance apropriately for radius
// adjust the plane distance appropriately for radius
plane[3] += tw->sphere.radius;
// find the closest point on the capsule to the plane
@ -1473,7 +1472,7 @@ void CM_TraceThroughPatchCollide( traceWork_t *tw, const struct patchCollide_s *
plane[3] = planes->plane[3];
}
if ( tw->sphere.use ) {
// adjust the plane distance apropriately for radius
// adjust the plane distance appropriately for radius
plane[3] += tw->sphere.radius;
// find the closest point on the capsule to the plane
@ -1562,7 +1561,7 @@ qboolean CM_PositionTestInPatchCollide( traceWork_t *tw, const struct patchColli
VectorCopy(planes->plane, plane);
plane[3] = planes->plane[3];
if ( tw->sphere.use ) {
// adjust the plane distance apropriately for radius
// adjust the plane distance appropriately for radius
plane[3] += tw->sphere.radius;
// find the closest point on the capsule to the plane
@ -1595,7 +1594,7 @@ qboolean CM_PositionTestInPatchCollide( traceWork_t *tw, const struct patchColli
plane[3] = planes->plane[3];
}
if ( tw->sphere.use ) {
// adjust the plane distance apropriately for radius
// adjust the plane distance appropriately for radius
plane[3] += tw->sphere.radius;
// find the closest point on the capsule to the plane

View file

@ -276,7 +276,7 @@ winding_t *CopyWinding (winding_t *w)
winding_t *c;
c = AllocWinding (w->numpoints);
size = (intptr_t) ((winding_t *)0)->p[w->numpoints];
size = (intptr_t)&(w->p[w->numpoints]) - (intptr_t)w;
Com_Memcpy (c, w, size);
return c;
}
@ -353,7 +353,7 @@ void ClipWindingEpsilon (winding_t *in, vec3_t normal, vec_t dist,
return;
}
maxpts = in->numpoints+4; // cant use counts[0]+2 because
maxpts = in->numpoints+4; // can't use counts[0]+2 because
// of fp grouping errors
*front = f = AllocWinding (maxpts);
@ -462,7 +462,7 @@ void ChopWindingInPlace (winding_t **inout, vec3_t normal, vec_t dist, vec_t eps
if (!counts[1])
return; // inout stays the same
maxpts = in->numpoints+4; // cant use counts[0]+2 because
maxpts = in->numpoints+4; // can't use counts[0]+2 because
// of fp grouping errors
f = AllocWinding (maxpts);
@ -574,7 +574,7 @@ void CheckWinding (winding_t *w)
if (d < -ON_EPSILON || d > ON_EPSILON)
Com_Error (ERR_DROP, "CheckWinding: point off plane");
// check the edge isnt degenerate
// check the edge isn't degenerate
p2 = w->p[j];
VectorSubtract (p2, p1, dir);

View file

@ -189,7 +189,7 @@ void CM_TestBoxInBrush( traceWork_t *tw, cbrush_t *brush ) {
side = brush->sides + i;
plane = side->plane;
// adjust the plane distance apropriately for radius
// adjust the plane distance appropriately for radius
dist = plane->dist + tw->sphere.radius;
// find the closest point on the capsule to the plane
t = DotProduct( plane->normal, tw->sphere.offset );
@ -214,7 +214,7 @@ void CM_TestBoxInBrush( traceWork_t *tw, cbrush_t *brush ) {
side = brush->sides + i;
plane = side->plane;
// adjust the plane distance apropriately for mins/maxs
// adjust the plane distance appropriately for mins/maxs
dist = plane->dist - DotProduct( tw->offsets[ plane->signbits ], plane->normal );
d1 = DotProduct( tw->start, plane->normal ) - dist;
@ -517,7 +517,7 @@ void CM_TraceThroughBrush( traceWork_t *tw, cbrush_t *brush ) {
side = brush->sides + i;
plane = side->plane;
// adjust the plane distance apropriately for radius
// adjust the plane distance appropriately for radius
dist = plane->dist + tw->sphere.radius;
// find the closest point on the capsule to the plane
@ -548,7 +548,7 @@ void CM_TraceThroughBrush( traceWork_t *tw, cbrush_t *brush ) {
return;
}
// if it doesn't cross the plane, the plane isn't relevent
// if it doesn't cross the plane, the plane isn't relevant
if (d1 <= 0 && d2 <= 0 ) {
continue;
}
@ -584,7 +584,7 @@ void CM_TraceThroughBrush( traceWork_t *tw, cbrush_t *brush ) {
side = brush->sides + i;
plane = side->plane;
// adjust the plane distance apropriately for mins/maxs
// adjust the plane distance appropriately for mins/maxs
dist = plane->dist - DotProduct( tw->offsets[ plane->signbits ], plane->normal );
d1 = DotProduct( tw->start, plane->normal ) - dist;
@ -602,7 +602,7 @@ void CM_TraceThroughBrush( traceWork_t *tw, cbrush_t *brush ) {
return;
}
// if it doesn't cross the plane, the plane isn't relevent
// if it doesn't cross the plane, the plane isn't relevant
if (d1 <= 0 && d2 <= 0 ) {
continue;
}
@ -1053,13 +1053,13 @@ void CM_TraceThroughTree( traceWork_t *tw, int num, float p1f, float p2f, vec3_t
}
//
// find the point distances to the seperating plane
// find the point distances to the separating plane
// and the offset for the size of the box
//
node = cm.nodes + num;
plane = node->plane;
// adjust the plane distance apropriately for mins/maxs
// adjust the plane distance appropriately for mins/maxs
if ( plane->type < 3 ) {
t1 = p1[plane->type] - plane->dist;
t2 = p2[plane->type] - plane->dist;
@ -1204,7 +1204,7 @@ void CM_Trace( trace_t *results, const vec3_t start, const vec3_t end, vec3_t mi
tw.maxOffset = tw.size[1][0] + tw.size[1][1] + tw.size[1][2];
// tw.offsets[signbits] = vector to apropriate corner from origin
// tw.offsets[signbits] = vector to appropriate corner from origin
tw.offsets[0][0] = tw.size[0][0];
tw.offsets[0][1] = tw.size[0][1];
tw.offsets[0][2] = tw.size[0][2];

View file

@ -489,8 +489,8 @@ void Cmd_Args_Sanitize(void)
Cmd_TokenizeString
Parses the given string into command line tokens.
The text is copied to a seperate buffer and 0 characters
are inserted in the apropriate place, The argv array
The text is copied to a separate buffer and 0 characters
are inserted in the appropriate place, The argv array
will point into this temporary buffer.
============
*/
@ -689,9 +689,7 @@ void Cmd_RemoveCommand( const char *cmd_name ) {
}
if ( !strcmp( cmd_name, cmd->name ) ) {
*back = cmd->next;
if (cmd->name) {
Z_Free(cmd->name);
}
Z_Free (cmd->name);
Z_Free (cmd);
return;
}

View file

@ -46,7 +46,7 @@ int demo_protocols[] =
int com_argc;
char *com_argv[MAX_NUM_ARGVS+1];
jmp_buf abortframe; // an ERR_DROP occured, exit the entire frame
jmp_buf abortframe; // an ERR_DROP occurred, exit the entire frame
FILE *debuglogfile;
@ -72,7 +72,9 @@ cvar_t *com_showtrace;
cvar_t *com_version;
cvar_t *com_blood;
cvar_t *com_buildScript; // for automated data building scripts
#ifdef CINEMATICS_INTRO
cvar_t *com_introPlayed;
#endif
cvar_t *cl_paused;
cvar_t *sv_paused;
cvar_t *cl_packetdelay;
@ -93,6 +95,9 @@ cvar_t *com_legacyprotocol;
cvar_t *com_basegame;
cvar_t *com_homepath;
cvar_t *com_busyWait;
#ifndef DEDICATED
cvar_t *con_autochat;
#endif
#if idx64
int (*Q_VMftol)(void);
@ -113,6 +118,7 @@ int com_frameNumber;
qboolean com_errorEntered = qfalse;
qboolean com_fullyInitialized = qfalse;
qboolean com_gameRestarting = qfalse;
qboolean com_gameClientRestarting = qfalse;
char com_errorMessage[MAXPRINTMSG];
@ -152,7 +158,7 @@ void Com_EndRedirect (void)
Com_Printf
Both client and server can use this, and it will output
to the apropriate place.
to the appropriate place.
A raw string should NEVER be passed as fmt, because of "%f" type crashers.
=============
@ -262,6 +268,7 @@ void QDECL Com_Error( int code, const char *fmt, ... ) {
static int lastErrorTime;
static int errorCount;
int currentTime;
qboolean restartClient;
if(com_errorEntered)
Sys_Error("recursive error after: %s", com_errorMessage);
@ -294,9 +301,17 @@ void QDECL Com_Error( int code, const char *fmt, ... ) {
if (code != ERR_DISCONNECT && code != ERR_NEED_CD)
Cvar_Set("com_errorMessage", com_errorMessage);
restartClient = com_gameClientRestarting && !( com_cl_running && com_cl_running->integer );
com_gameRestarting = qfalse;
com_gameClientRestarting = qfalse;
if (code == ERR_DISCONNECT || code == ERR_SERVERDISCONNECT) {
VM_Forced_Unload_Start();
SV_Shutdown( "Server disconnected" );
if ( restartClient ) {
CL_Init();
}
CL_Disconnect( qtrue );
CL_FlushMemory( );
VM_Forced_Unload_Done();
@ -308,6 +323,9 @@ void QDECL Com_Error( int code, const char *fmt, ... ) {
Com_Printf ("********************\nERROR: %s\n********************\n", com_errorMessage);
VM_Forced_Unload_Start();
SV_Shutdown (va("Server crashed: %s", com_errorMessage));
if ( restartClient ) {
CL_Init();
}
CL_Disconnect( qtrue );
CL_FlushMemory( );
VM_Forced_Unload_Done();
@ -317,6 +335,9 @@ void QDECL Com_Error( int code, const char *fmt, ... ) {
} else if ( code == ERR_NEED_CD ) {
VM_Forced_Unload_Start();
SV_Shutdown( "Server didn't have CD" );
if ( restartClient ) {
CL_Init();
}
if ( com_cl_running && com_cl_running->integer ) {
CL_Disconnect( qtrue );
CL_FlushMemory( );
@ -349,7 +370,7 @@ void QDECL Com_Error( int code, const char *fmt, ... ) {
Com_Quit_f
Both client and server can use this, and it will
do the apropriate things.
do the appropriate things.
=============
*/
void Com_Quit_f( void ) {
@ -377,7 +398,7 @@ void Com_Quit_f( void ) {
COMMAND LINE FUNCTIONS
+ characters seperate the commandLine string into multiple console
+ characters separate the commandLine string into multiple console
command lines.
All of these are valid:
@ -409,7 +430,7 @@ void Com_ParseCommandLine( char *commandLine ) {
if (*commandLine == '"') {
inq = !inq;
}
// look for a + seperating character
// look for a + separating character
// if commandLine came from a file, we might have real line seperators
if ( (*commandLine == '+' && !inq) || *commandLine == '\n' || *commandLine == '\r' ) {
if ( com_numConsoleLines == MAX_CONSOLE_LINES ) {
@ -473,9 +494,9 @@ void Com_StartupVariable( const char *match ) {
if(!match || !strcmp(s, match))
{
if(Cvar_Flags(s) == CVAR_NONEXISTENT)
Cvar_Get(s, Cmd_Argv(2), CVAR_USER_CREATED);
Cvar_Get(s, Cmd_ArgsFrom(2), CVAR_USER_CREATED);
else
Cvar_Set2(s, Cmd_Argv(2), qfalse);
Cvar_Set2(s, Cmd_ArgsFrom(2), qfalse);
}
}
}
@ -486,7 +507,7 @@ void Com_StartupVariable( const char *match ) {
Com_AddStartupCommands
Adds command line parameters as script statements
Commands are seperated by + signs
Commands are separated by + signs
Returns qtrue if any late commands were added, which
will keep the demoloop from immediately starting
@ -504,7 +525,7 @@ qboolean Com_AddStartupCommands( void ) {
}
// set commands already added with Com_StartupVariable
if ( !Q_stricmpn( com_consoleLines[i], "set", 3 ) ) {
if ( !Q_stricmpn( com_consoleLines[i], "set ", 4 ) ) {
continue;
}
@ -773,19 +794,19 @@ typedef struct {
} memzone_t;
// main zone for all "dynamic" memory allocation
memzone_t *mainzone;
static memzone_t *mainzone;
// we also have a small zone for small allocations that would only
// fragment the main zone (think of cvar and cmd strings)
memzone_t *smallzone;
static memzone_t *smallzone;
void Z_CheckHeap( void );
static void Z_CheckHeap( void );
/*
========================
Z_ClearZone
========================
*/
void Z_ClearZone( memzone_t *zone, int size ) {
static void Z_ClearZone( memzone_t *zone, int size ) {
memblock_t *block;
// set the entire zone to one free block
@ -810,7 +831,7 @@ void Z_ClearZone( memzone_t *zone, int size ) {
Z_AvailableZoneMemory
========================
*/
int Z_AvailableZoneMemory( memzone_t *zone ) {
static int Z_AvailableZoneMemory( memzone_t *zone ) {
return zone->size - zone->used;
}
@ -897,7 +918,6 @@ Z_FreeTags
================
*/
void Z_FreeTags( int tag ) {
int count;
memzone_t *zone;
if ( tag == TAG_SMALL ) {
@ -906,13 +926,11 @@ void Z_FreeTags( int tag ) {
else {
zone = mainzone;
}
count = 0;
// use the rover as our pointer, because
// Z_Free automatically adjusts it
zone->rover = zone->blocklist.next;
do {
if ( zone->rover->tag == tag ) {
count++;
Z_Free( (void *)(zone->rover + 1) );
continue;
}
@ -1058,7 +1076,7 @@ void *S_Malloc( int size ) {
Z_CheckHeap
========================
*/
void Z_CheckHeap( void ) {
static void Z_CheckHeap( void ) {
memblock_t *block;
for (block = mainzone->blocklist.next ; ; block = block->next) {
@ -1191,7 +1209,7 @@ char *CopyString( const char *in ) {
==============================================================================
Goals:
reproducable without history effects -- no out of memory errors on weird map to map changes
reproducible without history effects -- no out of memory errors on weird map to map changes
allow restarting of the client without fragmentation
minimize total pages in use at run time
minimize total pages needed during load time
@ -1266,7 +1284,7 @@ Com_Meminfo_f
void Com_Meminfo_f( void ) {
memblock_t *block;
int zoneBytes, zoneBlocks;
int smallZoneBytes, smallZoneBlocks;
int smallZoneBytes;
int botlibBytes, rendererBytes;
int unused;
@ -1304,11 +1322,9 @@ void Com_Meminfo_f( void ) {
}
smallZoneBytes = 0;
smallZoneBlocks = 0;
for (block = smallzone->blocklist.next ; ; block = block->next) {
if ( block->tag ) {
smallZoneBytes += block->size;
smallZoneBlocks++;
}
if (block->next == &smallzone->blocklist) {
@ -1360,7 +1376,7 @@ Touch all known used data to make sure it is paged in
void Com_TouchMemory( void ) {
int start, end;
int i, j;
int sum;
unsigned sum;
memblock_t *block;
Z_CheckHeap();
@ -1945,6 +1961,19 @@ void Com_QueueEvent( int time, sysEventType_t type, int value, int value2, int p
{
sysEvent_t *ev;
// combine mouse movement with previous mouse event
if ( type == SE_MOUSE && eventHead != eventTail )
{
ev = &eventQueue[ ( eventHead + MAX_QUEUED_EVENTS - 1 ) & MASK_QUEUED_EVENTS ];
if ( ev->evType == SE_MOUSE )
{
ev->evValue += value;
ev->evValue2 += value2;
return;
}
}
ev = &eventQueue[ eventHead & MASK_QUEUED_EVENTS ];
if ( eventHead - eventTail >= MAX_QUEUED_EVENTS )
@ -2360,16 +2389,14 @@ void Com_GameRestart(int checksumFeed, qboolean disconnect)
// make sure no recursion can be triggered
if(!com_gameRestarting && com_fullyInitialized)
{
int clWasRunning;
com_gameRestarting = qtrue;
clWasRunning = com_cl_running->integer;
com_gameClientRestarting = com_cl_running->integer;
// Kill server if we have one
if(com_sv_running->integer)
SV_Shutdown("Game directory changed");
if(clWasRunning)
if(com_gameClientRestarting)
{
if(disconnect)
CL_Disconnect(qfalse);
@ -2391,13 +2418,14 @@ void Com_GameRestart(int checksumFeed, qboolean disconnect)
NET_Restart_f();
}
if(clWasRunning)
if(com_gameClientRestarting)
{
CL_Init();
CL_StartHunkUsers(qfalse);
}
com_gameRestarting = qfalse;
com_gameClientRestarting = qfalse;
}
}
@ -2411,16 +2439,7 @@ Expose possibility to change current running mod to the user
void Com_GameRestart_f(void)
{
if(!FS_FilenameCompare(Cmd_Argv(1), com_basegame->string))
{
// This is the standard base game. Servers and clients should
// use "" and not the standard basegame name because this messes
// up pak file negotiation and lots of other stuff
Cvar_Set("fs_game", "");
}
else
Cvar_Set("fs_game", Cmd_Argv(1));
Cvar_Set("fs_game", Cmd_Argv(1));
Com_GameRestart(0, qtrue);
}
@ -2592,7 +2611,7 @@ static void Com_DetectSSE(void)
#endif
Q_VMftol = qvmftolsse;
Com_Printf("Have SSE support\n");
Com_Printf("SSE instruction set enabled\n");
#if !idx64
}
else
@ -2601,7 +2620,7 @@ static void Com_DetectSSE(void)
Q_VMftol = qvmftolx87;
Q_SnapVector = qsnapvectorx87;
Com_Printf("No SSE support on this machine\n");
Com_Printf("SSE instruction set not available\n");
}
#endif
}
@ -2637,7 +2656,7 @@ void Com_Init( char *commandLine ) {
char *s;
int qport;
Com_Printf( "%s %s %s\n", Q3_VERSION, PLATFORM_STRING, __DATE__ );
Com_Printf( "%s %s %s\n", Q3_VERSION, PLATFORM_STRING, PRODUCT_DATE );
if ( setjmp (abortframe) ) {
Sys_Error ("Error during initialization");
@ -2678,10 +2697,7 @@ void Com_Init( char *commandLine ) {
com_standalone = Cvar_Get("com_standalone", "0", CVAR_ROM);
com_basegame = Cvar_Get("com_basegame", BASEGAME, CVAR_INIT);
com_homepath = Cvar_Get("com_homepath", "", CVAR_INIT);
if(!com_basegame->string[0])
Cvar_ForceReset("com_basegame");
com_homepath = Cvar_Get("com_homepath", "", CVAR_INIT|CVAR_PROTECTED);
FS_InitFilesystem ();
@ -2754,9 +2770,11 @@ void Com_Init( char *commandLine ) {
com_busyWait = Cvar_Get("com_busyWait", "0", CVAR_ARCHIVE);
Cvar_Get("com_errorMessage", "", CVAR_ROM | CVAR_NORESTART);
#ifdef CINEMATICS_INTRO
com_introPlayed = Cvar_Get( "com_introplayed", "0", CVAR_ARCHIVE);
#endif
s = va("%s %s %s", Q3_VERSION, PLATFORM_STRING, __DATE__ );
s = va("%s %s %s", Q3_VERSION, PLATFORM_STRING, PRODUCT_DATE );
com_version = Cvar_Get ("version", s, CVAR_ROM | CVAR_SERVERINFO );
com_gamename = Cvar_Get("com_gamename", GAMENAME_FOR_MASTER, CVAR_SERVERINFO | CVAR_INIT);
com_protocol = Cvar_Get("com_protocol", va("%i", PROTOCOL_VERSION), CVAR_SERVERINFO | CVAR_INIT);
@ -2770,19 +2788,13 @@ void Com_Init( char *commandLine ) {
#endif
Cvar_Get("protocol", com_protocol->string, CVAR_ROM);
#ifndef DEDICATED
con_autochat = Cvar_Get("con_autochat", "1", CVAR_ARCHIVE);
#endif
Sys_Init();
if( Sys_WritePIDFile( ) ) {
#ifndef DEDICATED
const char *message = "The last time " CLIENT_WINDOW_TITLE " ran, "
"it didn't exit properly. This may be due to inappropriate video "
"settings. Would you like to start with \"safe\" video settings?";
if( Sys_Dialog( DT_YES_NO, message, "Abnormal Exit" ) == DR_YES ) {
Cvar_Set( "com_abnormalExit", "1" );
}
#endif
}
Sys_InitPIDFile( FS_GetCurrentGameDir() );
// Pick a random port value
Com_RandomBytes( (byte*)&qport, sizeof(int) );
@ -2805,11 +2817,15 @@ void Com_Init( char *commandLine ) {
if ( !Com_AddStartupCommands() ) {
// if the user didn't give any commands, run default action
if ( !com_dedicated->integer ) {
Cbuf_AddText ("cinematic Reactionlogo.RoQ\n");
#ifdef CINEMATICS_LOGO
Cbuf_AddText ("cinematic " CINEMATICS_LOGO "\n");
#endif
#ifdef CINEMATICS_INTRO
if( !com_introPlayed->integer ) {
Cvar_Set( com_introPlayed->name, "1" );
Cvar_Set( "nextmap", "cinematic intro.RoQ" );
Cvar_Set( "nextmap", "cinematic " CINEMATICS_INTRO );
}
#endif
}
}
@ -2915,9 +2931,6 @@ Writes key bindings and archived cvars to config file if modified
===============
*/
void Com_WriteConfiguration( void ) {
#if !defined(DEDICATED) && !defined(STANDALONE)
cvar_t *fs;
#endif
// if we are quiting without fully initializing, make sure
// we don't write out anything
if ( !com_fullyInitialized ) {
@ -2933,12 +2946,12 @@ void Com_WriteConfiguration( void ) {
// not needed for dedicated or standalone
#if !defined(DEDICATED) && !defined(STANDALONE)
fs = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO );
if(!com_standalone->integer)
{
if (UI_usesUniqueCDKey() && fs && fs->string[0] != 0) {
Com_WriteCDKey( fs->string, &cl_cdkey[16] );
const char *gamedir;
gamedir = Cvar_VariableString( "fs_game" );
if (UI_usesUniqueCDKey() && gamedir[0] != 0) {
Com_WriteCDKey( gamedir, &cl_cdkey[16] );
} else {
Com_WriteCDKey( BASEGAME, cl_cdkey );
}
@ -2964,6 +2977,13 @@ void Com_WriteConfig_f( void ) {
Q_strncpyz( filename, Cmd_Argv(1), sizeof( filename ) );
COM_DefaultExtension( filename, sizeof( filename ), ".cfg" );
if (!COM_CompareExtension(filename, ".cfg"))
{
Com_Printf("Com_WriteConfig_f: Only the \".cfg\" extension is supported by this command!\n");
return;
}
Com_Printf( "Writing %s.\n", filename );
Com_WriteConfigToFile( filename );
}
@ -3127,6 +3147,8 @@ void Com_Frame( void ) {
NET_Sleep(timeVal - 1);
} while(Com_TimeVal(minMsec));
IN_Frame();
lastTime = com_frameTime;
com_frameTime = Com_EventLoop();
@ -3456,8 +3478,8 @@ void Field_CompleteCommand( char *cmd,
completionString = Cmd_Argv( completionArgument - 1 );
#ifndef DEDICATED
// Unconditionally add a '\' to the start of the buffer
if( completionField->buffer[ 0 ] &&
// add a '\' to the start of the buffer if it might be sent as chat otherwise
if( con_autochat->integer && completionField->buffer[ 0 ] &&
completionField->buffer[ 0 ] != '\\' )
{
if( completionField->buffer[ 0 ] != '/' )
@ -3699,7 +3721,7 @@ qboolean Com_PlayerNameToFieldString( char *str, int length, const char *name )
return qtrue;
}
void Field_CompletePlayerName( char **names, int nameCount )
void Field_CompletePlayerName( const char **names, int nameCount )
{
qboolean whitespace;

View file

@ -569,6 +569,12 @@ cvar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force ) {
return var;
}
if ((var->flags & CVAR_CHEAT) && !cvar_cheats->integer)
{
Com_Printf ("%s is cheat protected.\n", var_name);
return var;
}
if (var->flags & CVAR_LATCH)
{
if (var->latchedString)
@ -589,13 +595,6 @@ cvar_t *Cvar_Set2( const char *var_name, const char *value, qboolean force ) {
var->modificationCount++;
return var;
}
if ( (var->flags & CVAR_CHEAT) && !cvar_cheats->integer )
{
Com_Printf ("%s is cheat protected.\n", var_name);
return var;
}
}
else
{
@ -1332,12 +1331,42 @@ void Cvar_Register(vmCvar_t *vmCvar, const char *varName, const char *defaultVal
// flags. Unfortunately some historical game code (including single player
// baseq3) sets both flags. We unset CVAR_ROM for such cvars.
if ((flags & (CVAR_ARCHIVE | CVAR_ROM)) == (CVAR_ARCHIVE | CVAR_ROM)) {
Com_DPrintf( S_COLOR_YELLOW "WARNING: Unsetting CVAR_ROM cvar '%s', "
Com_DPrintf( S_COLOR_YELLOW "WARNING: Unsetting CVAR_ROM from cvar '%s', "
"since it is also CVAR_ARCHIVE\n", varName );
flags &= ~CVAR_ROM;
}
cv = Cvar_Get(varName, defaultValue, flags | CVAR_VM_CREATED);
// Don't allow VM to specific a different creator or other internal flags.
if ( flags & CVAR_USER_CREATED ) {
Com_DPrintf( S_COLOR_YELLOW "WARNING: VM tried to set CVAR_USER_CREATED on cvar '%s'\n", varName );
flags &= ~CVAR_USER_CREATED;
}
if ( flags & CVAR_SERVER_CREATED ) {
Com_DPrintf( S_COLOR_YELLOW "WARNING: VM tried to set CVAR_SERVER_CREATED on cvar '%s'\n", varName );
flags &= ~CVAR_SERVER_CREATED;
}
if ( flags & CVAR_PROTECTED ) {
Com_DPrintf( S_COLOR_YELLOW "WARNING: VM tried to set CVAR_PROTECTED on cvar '%s'\n", varName );
flags &= ~CVAR_PROTECTED;
}
if ( flags & CVAR_MODIFIED ) {
Com_DPrintf( S_COLOR_YELLOW "WARNING: VM tried to set CVAR_MODIFIED on cvar '%s'\n", varName );
flags &= ~CVAR_MODIFIED;
}
if ( flags & CVAR_NONEXISTENT ) {
Com_DPrintf( S_COLOR_YELLOW "WARNING: VM tried to set CVAR_NONEXISTENT on cvar '%s'\n", varName );
flags &= ~CVAR_NONEXISTENT;
}
cv = Cvar_FindVar(varName);
// Don't modify cvar if it's protected.
if ( cv && ( cv->flags & CVAR_PROTECTED ) ) {
Com_DPrintf( S_COLOR_YELLOW "WARNING: VM tried to register protected cvar '%s' with value '%s'%s\n",
varName, defaultValue, ( flags & ~cv->flags ) != 0 ? " and new flags" : "" );
} else {
cv = Cvar_Get(varName, defaultValue, flags | CVAR_VM_CREATED);
}
if (!vmCvar)
return;

View file

@ -88,7 +88,7 @@ File search order: when FS_FOpenFileRead gets called it will go through the fs_s
structure and stop on the first successful hit. fs_searchpaths is built with successive
calls to FS_AddGameDirectory
Additionaly, we search in several subdirectories:
Additionally, we search in several subdirectories:
current game is the current mode
base game is a variable to allow mods based on other mods
(such as baseq3 + missionpack content combination in a mod for instance)
@ -174,6 +174,7 @@ or configs will never get loaded from disk!
// every time a new demo pk3 file is built, this checksum must be updated.
// the easiest way to get it is to just run the game and see what it spits out
#ifndef STANDALONE
#define DEMO_PAK0_CHECKSUM 2985612116u
static const unsigned int pak_checksums[] = {
1566731103u,
@ -194,6 +195,7 @@ static const unsigned int missionpak_checksums[] =
2662638993u,
1438664554u
};
#endif
// if this is defined, the executable positively won't work with any paks other
// than the demo pak, even if productid is present. This is only used for our
@ -246,11 +248,12 @@ static char fs_gamedir[MAX_OSPATH]; // this will be a single file name with no
static cvar_t *fs_debug;
static cvar_t *fs_homepath;
#ifdef MACOS_X
#ifdef __APPLE__
// Also search the .app bundle for .pk3 files
static cvar_t *fs_apppath;
#endif
static cvar_t *fs_steampath;
static cvar_t *fs_gogpath;
static cvar_t *fs_basepath;
static cvar_t *fs_basegame;
@ -280,7 +283,6 @@ typedef struct {
int zipFilePos;
int zipFileLen;
qboolean zipFile;
qboolean streamed;
char name[MAX_ZPATH];
} fileHandleData_t;
@ -303,6 +305,8 @@ static char *fs_serverReferencedPakNames[MAX_SEARCH_PATHS]; // pk3 names
// last valid game folder used
char lastValidBase[MAX_OSPATH];
char lastValidComBaseGame[MAX_OSPATH];
char lastValidFsBaseGame[MAX_OSPATH];
char lastValidGame[MAX_OSPATH];
#ifdef FS_MISSING
@ -564,7 +568,7 @@ static void FS_CheckFilenameIsMutable( const char *filename,
const char *function )
{
// Check if the filename ends with the library, QVM, or pk3 extension
if( COM_CompareExtension( filename, DLL_EXT )
if( Sys_DllExtension( filename )
|| COM_CompareExtension( filename, ".qvm" )
|| COM_CompareExtension( filename, ".pk3" ) )
{
@ -749,7 +753,7 @@ long FS_SV_FOpenFileRead(const char *filename, fileHandle_t *fp)
fsh[f].handleSync = qfalse;
}
// Check fs_steampath too
// Check fs_steampath
if (!fsh[f].handleFiles.file.o && fs_steampath->string[0])
{
ospath = FS_BuildOSPath( fs_steampath->string, filename, "" );
@ -764,6 +768,21 @@ long FS_SV_FOpenFileRead(const char *filename, fileHandle_t *fp)
fsh[f].handleSync = qfalse;
}
// Check fs_gogpath
if (!fsh[f].handleFiles.file.o && fs_gogpath->string[0])
{
ospath = FS_BuildOSPath( fs_gogpath->string, filename, "" );
ospath[strlen(ospath)-1] = '\0';
if ( fs_debug->integer )
{
Com_Printf( "FS_SV_FOpenFileRead (fs_gogpath): %s\n", ospath );
}
fsh[f].handleFiles.file.o = Sys_FOpen( ospath, "rb" );
fsh[f].handleSync = qfalse;
}
if ( !fsh[f].handleFiles.file.o )
{
f = 0;
@ -1362,12 +1381,18 @@ long FS_FOpenFileRead(const char *filename, fileHandle_t *file, qboolean uniqueF
{
searchpath_t *search;
long len;
qboolean isLocalConfig;
if(!fs_searchpaths)
Com_Error(ERR_FATAL, "Filesystem call made without initialization");
isLocalConfig = !strcmp(filename, "autoexec.cfg") || !strcmp(filename, Q3CONFIG_CFG);
for(search = fs_searchpaths; search; search = search->next)
{
// autoexec.cfg and q3config.cfg can only be loaded outside of pk3 files.
if (isLocalConfig && search->pack)
continue;
len = FS_FOpenFileReadDir(filename, search, file, uniqueFILE, qfalse);
if(file == NULL)
@ -1395,7 +1420,7 @@ long FS_FOpenFileRead(const char *filename, fileHandle_t *file, qboolean uniqueF
}
else
{
// When file is NULL, we're querying the existance of the file
// When file is NULL, we're querying the existence of the file
// If we've got here, it doesn't exist
return 0;
}
@ -1502,25 +1527,6 @@ FS_Read
Properly handles partial reads
=================
*/
int FS_Read2( void *buffer, int len, fileHandle_t f ) {
if ( !fs_searchpaths ) {
Com_Error( ERR_FATAL, "Filesystem call made without initialization" );
}
if ( !f ) {
return 0;
}
if (fsh[f].streamed) {
int r;
fsh[f].streamed = qfalse;
r = FS_Read( buffer, len, f );
fsh[f].streamed = qtrue;
return r;
} else {
return FS_Read( buffer, len, f);
}
}
int FS_Read( void *buffer, int len, fileHandle_t f ) {
int block, remaining;
int read;
@ -1647,14 +1653,6 @@ int FS_Seek( fileHandle_t f, long offset, int origin ) {
return -1;
}
if (fsh[f].streamed) {
int r;
fsh[f].streamed = qfalse;
r = FS_Seek( f, offset, origin );
fsh[f].streamed = qtrue;
return r;
}
if (fsh[f].zipFile == qtrue) {
//FIXME: this is really, really crappy
//(but better than what was here before)
@ -2208,7 +2206,7 @@ static int FS_AddFileToList( char *name, char *list[MAX_FOUND_FILES], int nfiles
}
for ( i = 0 ; i < nfiles ; i++ ) {
if ( !Q_stricmp( name, list[i] ) ) {
return nfiles; // allready in list
return nfiles; // already in list
}
}
list[nfiles] = CopyString( name );
@ -2482,124 +2480,129 @@ static char** Sys_ConcatenateFileLists( char **list0, char **list1 )
return cat;
}
/*
================
FS_GetModDescription
================
*/
void FS_GetModDescription( const char *modDir, char *description, int descriptionLen ) {
fileHandle_t descHandle;
char descPath[MAX_QPATH];
int nDescLen;
FILE *file;
Com_sprintf( descPath, sizeof ( descPath ), "%s%cdescription.txt", modDir, PATH_SEP );
nDescLen = FS_SV_FOpenFileRead( descPath, &descHandle );
if ( nDescLen > 0 ) {
file = FS_FileForHandle(descHandle);
Com_Memset( description, 0, descriptionLen );
nDescLen = fread(description, 1, descriptionLen, file);
if (nDescLen >= 0) {
description[nDescLen] = '\0';
}
} else {
Q_strncpyz( description, modDir, descriptionLen );
}
if ( descHandle ) {
FS_FCloseFile( descHandle );
}
}
/*
================
FS_GetModList
Returns a list of mod directory names
A mod directory is a peer to baseq3 with a pk3 in it
The directories are searched in base path, cd path and home path
A mod directory is a peer to baseq3 with a pk3 or pk3dir in it
================
*/
int FS_GetModList( char *listbuf, int bufsize ) {
int nMods, i, j, nTotal, nLen, nPaks, nPotential, nDescLen;
int nMods, i, j, k, nTotal, nLen, nPaks, nDirs, nPakDirs, nPotential, nDescLen;
char **pFiles = NULL;
char **pPaks = NULL;
char **pDirs = NULL;
char *name, *path;
char descPath[MAX_OSPATH];
fileHandle_t descHandle;
char description[MAX_OSPATH];
int dummy;
char **pFiles0 = NULL;
char **pFiles1 = NULL;
char **pFiles2 = NULL;
char **pFiles3 = NULL;
qboolean bDrop = qfalse;
// paths to search for mods
const char * const paths[] = { fs_basepath->string, fs_homepath->string, fs_steampath->string, fs_gogpath->string };
*listbuf = 0;
nMods = nTotal = 0;
pFiles0 = Sys_ListFiles( fs_homepath->string, NULL, NULL, &dummy, qtrue );
pFiles1 = Sys_ListFiles( fs_basepath->string, NULL, NULL, &dummy, qtrue );
pFiles2 = Sys_ListFiles( fs_steampath->string, NULL, NULL, &dummy, qtrue );
// we searched for mods in the three paths
// it is likely that we have duplicate names now, which we will cleanup below
pFiles3 = Sys_ConcatenateFileLists( pFiles0, pFiles1 );
pFiles = Sys_ConcatenateFileLists( pFiles2, pFiles3 );
// iterate through paths and get list of potential mods
for (i = 0; i < ARRAY_LEN(paths); i++) {
pFiles0 = Sys_ListFiles(paths[i], NULL, NULL, &dummy, qtrue);
// Sys_ConcatenateFileLists frees the lists so Sys_FreeFileList isn't required
pFiles = Sys_ConcatenateFileLists(pFiles, pFiles0);
}
nPotential = Sys_CountFileList(pFiles);
for ( i = 0 ; i < nPotential ; i++ ) {
for (i = 0; i < nPotential; i++) {
name = pFiles[i];
// NOTE: cleaner would involve more changes
// ignore duplicate mod directories
if (i!=0) {
if (i != 0) {
bDrop = qfalse;
for(j=0; j<i; j++)
{
if (Q_stricmp(pFiles[j],name)==0) {
for (j = 0; j < i; j++) {
if (Q_stricmp(pFiles[j], name) == 0) {
// this one can be dropped
bDrop = qtrue;
break;
}
}
}
if (bDrop) {
// we also drop "baseq3" "." and ".."
if (bDrop || Q_stricmp(name, com_basegame->string) == 0 || Q_stricmpn(name, ".", 1) == 0) {
continue;
}
// we drop "baseq3" "." and ".."
if (Q_stricmp(name, com_basegame->string) && Q_stricmpn(name, ".", 1)) {
// now we need to find some .pk3 files to validate the mod
// NOTE TTimo: (actually I'm not sure why .. what if it's a mod under developement with no .pk3?)
// we didn't keep the information when we merged the directory names, as to what OS Path it was found under
// so it could be in base path, cd path or home path
// we will try each three of them here (yes, it's a bit messy)
path = FS_BuildOSPath( fs_basepath->string, name, "" );
nPaks = 0;
pPaks = Sys_ListFiles(path, ".pk3", NULL, &nPaks, qfalse);
Sys_FreeFileList( pPaks ); // we only use Sys_ListFiles to check wether .pk3 files are present
/* try on home path */
if ( nPaks <= 0 )
{
path = FS_BuildOSPath( fs_homepath->string, name, "" );
nPaks = 0;
pPaks = Sys_ListFiles( path, ".pk3", NULL, &nPaks, qfalse );
Sys_FreeFileList( pPaks );
// in order to be a valid mod the directory must contain at least one .pk3 or .pk3dir
// we didn't keep the information when we merged the directory names, as to what OS Path it was found under
// so we will try each of them here
for (j = 0; j < ARRAY_LEN(paths); j++) {
path = FS_BuildOSPath(paths[j], name, "");
nPaks = nDirs = nPakDirs = 0;
pPaks = Sys_ListFiles(path, ".pk3", NULL, &nPaks, qfalse);
pDirs = Sys_ListFiles(path, "/", NULL, &nDirs, qfalse);
for (k = 0; k < nDirs; k++) {
// we only want to count directories ending with ".pk3dir"
if (FS_IsExt(pDirs[k], ".pk3dir", strlen(pDirs[k]))) {
nPakDirs++;
}
}
// we only use Sys_ListFiles to check whether files are present
Sys_FreeFileList(pPaks);
Sys_FreeFileList(pDirs);
/* try on steam path */
if ( nPaks <= 0 )
{
path = FS_BuildOSPath( fs_steampath->string, name, "" );
nPaks = 0;
pPaks = Sys_ListFiles( path, ".pk3", NULL, &nPaks, qfalse );
Sys_FreeFileList( pPaks );
if (nPaks > 0 || nPakDirs > 0) {
break;
}
}
if (nPaks > 0) {
nLen = strlen(name) + 1;
// nLen is the length of the mod path
// we need to see if there is a description available
descPath[0] = '\0';
strcpy(descPath, name);
strcat(descPath, "/description.txt");
nDescLen = FS_SV_FOpenFileRead( descPath, &descHandle );
if ( nDescLen > 0 && descHandle) {
FILE *file;
file = FS_FileForHandle(descHandle);
Com_Memset( descPath, 0, sizeof( descPath ) );
nDescLen = fread(descPath, 1, 48, file);
if (nDescLen >= 0) {
descPath[nDescLen] = '\0';
}
FS_FCloseFile(descHandle);
} else {
strcpy(descPath, name);
}
nDescLen = strlen(descPath) + 1;
if (nPaks > 0 || nPakDirs > 0) {
nLen = strlen(name) + 1;
// nLen is the length of the mod path
// we need to see if there is a description available
FS_GetModDescription(name, description, sizeof(description));
nDescLen = strlen(description) + 1;
if (nTotal + nLen + 1 + nDescLen + 1 < bufsize) {
strcpy(listbuf, name);
listbuf += nLen;
strcpy(listbuf, descPath);
listbuf += nDescLen;
nTotal += nLen + nDescLen;
nMods++;
}
else {
break;
}
if (nTotal + nLen + 1 + nDescLen + 1 < bufsize) {
strcpy(listbuf, name);
listbuf += nLen;
strcpy(listbuf, description);
listbuf += nDescLen;
nTotal += nLen + nDescLen;
nMods++;
} else {
break;
}
}
}
@ -3067,6 +3070,23 @@ qboolean FS_CheckDirTraversal(const char *checkdir)
return qfalse;
}
/*
================
FS_InvalidGameDir
return true if path is a reference to current directory or directory traversal
or a sub-directory
================
*/
qboolean FS_InvalidGameDir( const char *gamedir ) {
if ( !strcmp( gamedir, "." ) || !strcmp( gamedir, ".." )
|| strchr( gamedir, '/' ) || strchr( gamedir, '\\' ) ) {
return qtrue;
}
return qfalse;
}
/*
================
FS_ComparePaks
@ -3309,7 +3329,32 @@ static void FS_Startup( const char *gameName )
fs_homepath = Cvar_Get ("fs_homepath", homePath, CVAR_INIT|CVAR_PROTECTED );
fs_gamedirvar = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO );
if (!gameName[0]) {
Cvar_ForceReset( "com_basegame" );
}
if (!FS_FilenameCompare(fs_gamedirvar->string, gameName)) {
// This is the standard base game. Servers and clients should
// use "" and not the standard basegame name because this messes
// up pak file negotiation and lots of other stuff
Cvar_ForceReset( "fs_game" );
}
if (FS_InvalidGameDir(gameName)) {
Com_Error( ERR_DROP, "Invalid com_basegame '%s'", gameName );
}
if (FS_InvalidGameDir(fs_basegame->string)) {
Com_Error( ERR_DROP, "Invalid fs_basegame '%s'", fs_basegame->string );
}
if (FS_InvalidGameDir(fs_gamedirvar->string)) {
Com_Error( ERR_DROP, "Invalid fs_game '%s'", fs_gamedirvar->string );
}
// add search path elements in reverse priority order
fs_gogpath = Cvar_Get ("fs_gogpath", Sys_GogPath(), CVAR_INIT|CVAR_PROTECTED );
if (fs_gogpath->string[0]) {
FS_AddGameDirectory( fs_gogpath->string, gameName );
}
fs_steampath = Cvar_Get ("fs_steampath", Sys_SteamPath(), CVAR_INIT|CVAR_PROTECTED );
if (fs_steampath->string[0]) {
FS_AddGameDirectory( fs_steampath->string, gameName );
@ -3319,7 +3364,7 @@ static void FS_Startup( const char *gameName )
}
// fs_homepath is somewhat particular to *nix systems, only add if relevant
#ifdef MACOS_X
#ifdef __APPLE__
fs_apppath = Cvar_Get ("fs_apppath", Sys_DefaultAppPath(), CVAR_INIT|CVAR_PROTECTED );
// Make MacOSX also include the base path included with the .app bundle
if (fs_apppath->string[0])
@ -3334,6 +3379,9 @@ static void FS_Startup( const char *gameName )
// check for additional base game so mods can be based upon other mods
if ( fs_basegame->string[0] && Q_stricmp( fs_basegame->string, gameName ) ) {
if (fs_gogpath->string[0]) {
FS_AddGameDirectory(fs_gogpath->string, fs_basegame->string);
}
if (fs_steampath->string[0]) {
FS_AddGameDirectory(fs_steampath->string, fs_basegame->string);
}
@ -3347,6 +3395,9 @@ static void FS_Startup( const char *gameName )
// check for additional game folder for mods
if ( fs_gamedirvar->string[0] && Q_stricmp( fs_gamedirvar->string, gameName ) ) {
if (fs_gogpath->string[0]) {
FS_AddGameDirectory(fs_gogpath->string, fs_gamedirvar->string);
}
if (fs_steampath->string[0]) {
FS_AddGameDirectory(fs_steampath->string, fs_gamedirvar->string);
}
@ -3359,14 +3410,10 @@ static void FS_Startup( const char *gameName )
}
#ifndef STANDALONE
if(!com_standalone->integer)
{
cvar_t *fs;
if (!com_standalone->integer) {
Com_ReadCDKey(BASEGAME);
fs = Cvar_Get ("fs_game", "", CVAR_INIT|CVAR_SYSTEMINFO );
if (fs && fs->string[0] != 0) {
Com_AppendCDKey( fs->string );
if (fs_gamedirvar->string[0]) {
Com_AppendCDKey(fs_gamedirvar->string);
}
}
#endif
@ -3414,17 +3461,17 @@ static void FS_CheckPak0( void )
{
searchpath_t *path;
pack_t *curpack;
const char *pakBasename;
qboolean founddemo = qfalse;
unsigned int foundPak = 0, foundTA = 0;
for( path = fs_searchpaths; path; path = path->next )
{
const char* pakBasename = path->pack->pakBasename;
if(!path->pack)
continue;
curpack = path->pack;
pakBasename = curpack->pakBasename;
if(!Q_stricmpn( curpack->pakGamename, "demoq3", MAX_OSPATH )
&& !Q_stricmpn( pakBasename, "pak0", MAX_OSPATH ))
@ -3921,7 +3968,7 @@ void FS_PureServerSetReferencedPaks( const char *pakSums, const char *pakNames )
================
FS_InitFilesystem
Called only at inital startup, not when the filesystem
Called only at initial startup, not when the filesystem
is resetting due to a game change
================
*/
@ -3952,6 +3999,8 @@ void FS_InitFilesystem( void ) {
}
Q_strncpyz(lastValidBase, fs_basepath->string, sizeof(lastValidBase));
Q_strncpyz(lastValidComBaseGame, com_basegame->string, sizeof(lastValidComBaseGame));
Q_strncpyz(lastValidFsBaseGame, fs_basegame->string, sizeof(lastValidFsBaseGame));
Q_strncpyz(lastValidGame, fs_gamedirvar->string, sizeof(lastValidGame));
}
@ -3962,6 +4011,7 @@ FS_Restart
================
*/
void FS_Restart( int checksumFeed ) {
const char *lastGameDir;
// free anything we currently have loaded
FS_Shutdown(qfalse);
@ -3988,8 +4038,12 @@ void FS_Restart( int checksumFeed ) {
if (lastValidBase[0]) {
FS_PureServerSetLoadedPaks("", "");
Cvar_Set("fs_basepath", lastValidBase);
Cvar_Set("com_basegame", lastValidComBaseGame);
Cvar_Set("fs_basegame", lastValidFsBaseGame);
Cvar_Set("fs_game", lastValidGame);
lastValidBase[0] = '\0';
lastValidComBaseGame[0] = '\0';
lastValidFsBaseGame[0] = '\0';
lastValidGame[0] = '\0';
FS_Restart(checksumFeed);
Com_Error( ERR_DROP, "Invalid game folder" );
@ -3998,7 +4052,12 @@ void FS_Restart( int checksumFeed ) {
Com_Error( ERR_FATAL, "Couldn't load default.cfg" );
}
if ( Q_stricmp(fs_gamedirvar->string, lastValidGame) ) {
lastGameDir = ( lastValidGame[0] ) ? lastValidGame : lastValidComBaseGame;
if ( Q_stricmp( FS_GetCurrentGameDir(), lastGameDir ) ) {
Sys_RemovePIDFile( lastGameDir );
Sys_InitPIDFile( FS_GetCurrentGameDir() );
// skip the q3config.cfg if "safe" is on the command line
if ( !Com_SafeMode() ) {
Cbuf_AddText ("exec " Q3CONFIG_CFG "\n");
@ -4006,6 +4065,8 @@ void FS_Restart( int checksumFeed ) {
}
Q_strncpyz(lastValidBase, fs_basepath->string, sizeof(lastValidBase));
Q_strncpyz(lastValidComBaseGame, com_basegame->string, sizeof(lastValidComBaseGame));
Q_strncpyz(lastValidFsBaseGame, fs_basegame->string, sizeof(lastValidFsBaseGame));
Q_strncpyz(lastValidGame, fs_gamedirvar->string, sizeof(lastValidGame));
}
@ -4086,11 +4147,6 @@ int FS_FOpenFileByMode( const char *qpath, fileHandle_t *f, fsMode_t mode ) {
if ( *f ) {
fsh[*f].fileSize = r;
fsh[*f].streamed = qfalse;
if (mode == FS_READ) {
fsh[*f].streamed = qtrue;
}
}
fsh[*f].handleSync = sync;

View file

@ -279,9 +279,14 @@ int Huff_Receive (node_t *node, int *ch, byte *fin) {
}
/* Get a symbol */
void Huff_offsetReceive (node_t *node, int *ch, byte *fin, int *offset) {
void Huff_offsetReceive (node_t *node, int *ch, byte *fin, int *offset, int maxoffset) {
bloc = *offset;
while (node && node->symbol == INTERNAL_NODE) {
if (bloc >= maxoffset) {
*ch = 0;
*offset = maxoffset + 1;
return;
}
if (get_bit(fin)) {
node = node->right;
} else {
@ -298,11 +303,15 @@ void Huff_offsetReceive (node_t *node, int *ch, byte *fin, int *offset) {
}
/* Send the prefix code for this node */
static void send(node_t *node, node_t *child, byte *fout) {
static void send(node_t *node, node_t *child, byte *fout, int maxoffset) {
if (node->parent) {
send(node->parent, node, fout);
send(node->parent, node, fout, maxoffset);
}
if (child) {
if (bloc >= maxoffset) {
bloc = maxoffset + 1;
return;
}
if (node->right == child) {
add_bit(1, fout);
} else {
@ -312,22 +321,22 @@ static void send(node_t *node, node_t *child, byte *fout) {
}
/* Send a symbol */
void Huff_transmit (huff_t *huff, int ch, byte *fout) {
void Huff_transmit (huff_t *huff, int ch, byte *fout, int maxoffset) {
int i;
if (huff->loc[ch] == NULL) {
/* node_t hasn't been transmitted, send a NYT, then the symbol */
Huff_transmit(huff, NYT, fout);
Huff_transmit(huff, NYT, fout, maxoffset);
for (i = 7; i >= 0; i--) {
add_bit((char)((ch >> i) & 0x1), fout);
}
} else {
send(huff->loc[ch], NULL, fout);
send(huff->loc[ch], NULL, fout, maxoffset);
}
}
void Huff_offsetTransmit (huff_t *huff, int ch, byte *fout, int *offset) {
void Huff_offsetTransmit (huff_t *huff, int ch, byte *fout, int *offset, int maxoffset) {
bloc = *offset;
send(huff->loc[ch], NULL, fout);
send(huff->loc[ch], NULL, fout, maxoffset);
*offset = bloc;
}
@ -392,7 +401,7 @@ void Huff_Compress(msg_t *mbuf, int offset) {
huff_t huff;
size = mbuf->cursize - offset;
buffer = mbuf->data+ + offset;
buffer = mbuf->data + offset;
if (size<=0) {
return;
@ -413,7 +422,7 @@ void Huff_Compress(msg_t *mbuf, int offset) {
for (i=0; i<size; i++ ) {
ch = buffer[i];
Huff_transmit(&huff, ch, seq); /* Transmit symbol */
Huff_transmit(&huff, ch, seq, size<<3); /* Transmit symbol */
Huff_addRef(&huff, (byte)ch); /* Do update */
}

View file

@ -106,8 +106,11 @@ static void copy64(uint32_t *M, byte *in)
int i;
for (i=0;i<16;i++)
M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) |
(in[i*4+1]<<8) | (in[i*4+0]<<0);
M[i] =
((uint32_t)in[i*4+3] << 24) |
((uint32_t)in[i*4+2] << 16) |
((uint32_t)in[i*4+1] << 8) |
((uint32_t)in[i*4+0] << 0) ;
}
static void copy4(byte *out,uint32_t x)

View file

@ -78,7 +78,7 @@ static void MD5Init(struct MD5Context *ctx)
static void MD5Transform(uint32_t buf[4],
uint32_t const in[16])
{
register uint32_t a, b, c, d;
uint32_t a, b, c, d;
a = buf[0];
b = buf[1];
@ -290,7 +290,7 @@ char *Com_MD5File( const char *fn, int length, const char *prefix, int prefix_le
MD5Update(&md5 , (unsigned char *)prefix, prefix_len);
for(;;) {
r = FS_Read2(buffer, sizeof(buffer), f);
r = FS_Read(buffer, sizeof(buffer), f);
if(r < 1)
break;
if(r + total > length)

View file

@ -101,18 +101,13 @@ bit functions
=============================================================================
*/
int overflows;
// negative bit values include signs
void MSG_WriteBits( msg_t *msg, int value, int bits ) {
int i;
// FILE* fp;
oldsize += bits;
// this isn't an exact overflow check, but close enough
if ( msg->maxsize - msg->cursize < 4 ) {
msg->overflowed = qtrue;
if ( msg->overflowed ) {
return;
}
@ -120,69 +115,60 @@ void MSG_WriteBits( msg_t *msg, int value, int bits ) {
Com_Error( ERR_DROP, "MSG_WriteBits: bad bits %i", bits );
}
// check for overflows
if ( bits != 32 ) {
if ( bits > 0 ) {
if ( value > ( ( 1 << bits ) - 1 ) || value < 0 ) {
overflows++;
}
} else {
int r;
r = 1 << (bits-1);
if ( value > r - 1 || value < -r ) {
overflows++;
}
}
}
if ( bits < 0 ) {
bits = -bits;
}
if (msg->oob) {
if(bits==8)
{
if ( msg->oob ) {
if ( msg->cursize + ( bits >> 3 ) > msg->maxsize ) {
msg->overflowed = qtrue;
return;
}
if ( bits == 8 ) {
msg->data[msg->cursize] = value;
msg->cursize += 1;
msg->bit += 8;
}
else if(bits==16)
{
} else if ( bits == 16 ) {
short temp = value;
CopyLittleShort(&msg->data[msg->cursize], &temp);
CopyLittleShort( &msg->data[msg->cursize], &temp );
msg->cursize += 2;
msg->bit += 16;
}
else if(bits==32)
{
CopyLittleLong(&msg->data[msg->cursize], &value);
} else if ( bits==32 ) {
CopyLittleLong( &msg->data[msg->cursize], &value );
msg->cursize += 4;
msg->bit += 32;
} else {
Com_Error( ERR_DROP, "can't write %d bits", bits );
}
else
Com_Error(ERR_DROP, "can't write %d bits", bits);
} else {
// fp = fopen("c:\\netchan.bin", "a");
value &= (0xffffffff>>(32-bits));
if (bits&7) {
value &= (0xffffffff >> (32 - bits));
if ( bits&7 ) {
int nbits;
nbits = bits&7;
for(i=0;i<nbits;i++) {
Huff_putBit((value&1), msg->data, &msg->bit);
value = (value>>1);
if ( msg->bit + nbits > msg->maxsize << 3 ) {
msg->overflowed = qtrue;
return;
}
for( i = 0; i < nbits; i++ ) {
Huff_putBit( (value & 1), msg->data, &msg->bit );
value = (value >> 1);
}
bits = bits - nbits;
}
if (bits) {
for(i=0;i<bits;i+=8) {
// fwrite(bp, 1, 1, fp);
Huff_offsetTransmit (&msgHuff.compressor, (value&0xff), msg->data, &msg->bit);
value = (value>>8);
if ( bits ) {
for( i = 0; i < bits; i += 8 ) {
Huff_offsetTransmit( &msgHuff.compressor, (value & 0xff), msg->data, &msg->bit, msg->maxsize << 3 );
value = (value >> 8);
if ( msg->bit > msg->maxsize << 3 ) {
msg->overflowed = qtrue;
return;
}
}
}
msg->cursize = (msg->bit>>3)+1;
// fclose(fp);
msg->cursize = (msg->bit >> 3) + 1;
}
}
@ -193,6 +179,10 @@ int MSG_ReadBits( msg_t *msg, int bits ) {
int i, nbits;
// FILE* fp;
if ( msg->readcount > msg->cursize ) {
return 0;
}
value = 0;
if ( bits < 0 ) {
@ -203,6 +193,11 @@ int MSG_ReadBits( msg_t *msg, int bits ) {
}
if (msg->oob) {
if (msg->readcount + (bits>>3) > msg->cursize) {
msg->readcount = msg->cursize + 1;
return 0;
}
if(bits==8)
{
value = msg->data[msg->readcount];
@ -230,6 +225,10 @@ int MSG_ReadBits( msg_t *msg, int bits ) {
nbits = 0;
if (bits&7) {
nbits = bits&7;
if (msg->bit + nbits > msg->cursize << 3) {
msg->readcount = msg->cursize + 1;
return 0;
}
for(i=0;i<nbits;i++) {
value |= (Huff_getBit(msg->data, &msg->bit)<<i);
}
@ -238,9 +237,14 @@ int MSG_ReadBits( msg_t *msg, int bits ) {
if (bits) {
// fp = fopen("c:\\netchan.bin", "a");
for(i=0;i<bits;i+=8) {
Huff_offsetReceive (msgHuff.decompressor.tree, &get, msg->data, &msg->bit);
Huff_offsetReceive (msgHuff.decompressor.tree, &get, msg->data, &msg->bit, msg->cursize<<3);
// fwrite(&get, 1, 1, fp);
value |= (get<<(i+nbits));
value = (unsigned int)value | ((unsigned int)get<<(i+nbits));
if (msg->bit > msg->cursize<<3) {
msg->readcount = msg->cursize + 1;
return 0;
}
}
// fclose(fp);
}
@ -458,12 +462,14 @@ char *MSG_ReadString( msg_t *msg ) {
if ( c > 127 ) {
c = '.';
}
string[l] = c;
l++;
} while (l < sizeof(string)-1);
// break only after reading all expected data from bitstream
if ( l >= sizeof(string)-1 ) {
break;
}
string[l++] = c;
} while (1);
string[l] = 0;
string[l] = '\0';
return string;
}
@ -486,12 +492,14 @@ char *MSG_ReadBigString( msg_t *msg ) {
if ( c > 127 ) {
c = '.';
}
string[l] = c;
l++;
} while (l < sizeof(string)-1);
// break only after reading all expected data from bitstream
if ( l >= sizeof(string)-1 ) {
break;
}
string[l++] = c;
} while (1);
string[l] = 0;
string[l] = '\0';
return string;
}
@ -514,12 +522,14 @@ char *MSG_ReadStringLine( msg_t *msg ) {
if ( c > 127 ) {
c = '.';
}
string[l] = c;
l++;
} while (l < sizeof(string)-1);
// break only after reading all expected data from bitstream
if ( l >= sizeof(string)-1 ) {
break;
}
string[l++] = c;
} while (1);
string[l] = 0;
string[l] = '\0';
return string;
}
@ -552,55 +562,10 @@ int MSG_HashKey(const char *string, int maxlen) {
return hash;
}
/*
=============================================================================
delta functions
=============================================================================
*/
extern cvar_t *cl_shownet;
#define LOG(x) if( cl_shownet && cl_shownet->integer == 4 ) { Com_Printf("%s ", x ); };
void MSG_WriteDelta( msg_t *msg, int oldV, int newV, int bits ) {
if ( oldV == newV ) {
MSG_WriteBits( msg, 0, 1 );
return;
}
MSG_WriteBits( msg, 1, 1 );
MSG_WriteBits( msg, newV, bits );
}
int MSG_ReadDelta( msg_t *msg, int oldV, int bits ) {
if ( MSG_ReadBits( msg, 1 ) ) {
return MSG_ReadBits( msg, bits );
}
return oldV;
}
void MSG_WriteDeltaFloat( msg_t *msg, float oldV, float newV ) {
floatint_t fi;
if ( oldV == newV ) {
MSG_WriteBits( msg, 0, 1 );
return;
}
fi.f = newV;
MSG_WriteBits( msg, 1, 1 );
MSG_WriteBits( msg, fi.i, 32 );
}
float MSG_ReadDeltaFloat( msg_t *msg, float oldV ) {
if ( MSG_ReadBits( msg, 1 ) ) {
floatint_t fi;
fi.i = MSG_ReadBits( msg, 32 );
return fi.f;
}
return oldV;
}
/*
=============================================================================

View file

@ -52,7 +52,7 @@ to the new value before sending out any replies.
#define FRAGMENT_SIZE (MAX_PACKETLEN - 100)
#define PACKET_HEADER 10 // two ints and a short
#define FRAGMENT_BIT (1<<31)
#define FRAGMENT_BIT (1U<<31)
cvar_t *showpackets;
cvar_t *showdrop;

View file

@ -1268,7 +1268,7 @@ static void NET_AddLocalAddress(char *ifname, struct sockaddr *addr, struct sock
}
}
#if defined(__linux__) || defined(MACOSX) || defined(__BSD__)
#if defined(__linux__) || defined(__APPLE__) || defined(__BSD__)
static void NET_GetLocalAddress(void)
{
struct ifaddrs *ifap, *search;

View file

@ -148,7 +148,7 @@ vec3_t bytedirs[NUMVERTEXNORMALS] =
//==============================================================
int Q_rand( int *seed ) {
*seed = (69069 * *seed + 1);
*seed = (69069U * *seed + 1U);
return *seed;
}

View file

@ -46,7 +46,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define idppc 1
#if defined(__VEC__)
#define idppc_altivec 1
#ifdef MACOS_X // Apple's GCC does this differently than the FSF.
#ifdef __APPLE__ // Apple's GCC does this differently than the FSF.
#define VECCONST_UINT8(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
(vector unsigned char) (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)
#else
@ -139,12 +139,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//============================================================== MAC OS X ===
#if defined(MACOS_X) || defined(__APPLE_CC__)
// make sure this is defined, just for sanity's sake...
#ifndef MACOS_X
#define MACOS_X
#endif
#if defined(__APPLE__) || defined(__APPLE_CC__)
#define OS_STRING "macosx"
#define ID_INLINE inline

View file

@ -23,6 +23,24 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// q_shared.c -- stateless support routines that are included in each code dll
#include "q_shared.h"
#if 0
qboolean Q_IsColorString(const char *p) {
if (!p)
return qfalse;
if (p[0] != Q_COLOR_ESCAPE)
return qfalse;
if (p[1] == 0)
return qfalse;
if (p[1] == Q_COLOR_ESCAPE)
return qfalse;
return qtrue;
}
#endif
float Com_Clamp( float min, float max, float value ) {
if ( value < min ) {
return min;
@ -660,15 +678,15 @@ Com_HexStrToInt
*/
int Com_HexStrToInt( const char *str )
{
if ( !str || !str[ 0 ] )
if ( !str )
return -1;
// check for hex code
if( str[ 0 ] == '0' && str[ 1 ] == 'x' )
if( str[ 0 ] == '0' && str[ 1 ] == 'x' && str[ 2 ] != '\0' )
{
int i, n = 0;
int i, n = 0, len = strlen( str );
for( i = 2; i < strlen( str ); i++ )
for( i = 2; i < len; i++ )
{
char digit;
@ -746,13 +764,14 @@ qboolean Q_isintegral( float f )
return (int)f == f;
}
#ifdef _MSC_VER
#ifdef _WIN32
/*
=============
Q_vsnprintf
Special wrapper function for Microsoft's broken _vsnprintf() function.
MinGW comes with its own snprintf() which is not broken.
MinGW comes with its own vsnprintf() which is not broken. mingw-w64
however, uses Microsoft's broken _vsnprintf() function.
=============
*/

View file

@ -35,8 +35,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define HOMEPATH_NAME_WIN "Reaction"
#define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
// #define STEAMPATH_NAME "Foo Bar"
// #define STEAMPATH_APPID ""
// #define STEAMPATH_APPID ""
// #define GOGPATH_ID ""
#define GAMENAME_FOR_MASTER "Reaction"
#define CINEMATICS_LOGO "Reactionlogo.RoQ"
#define CINEMATICS_INTRO "intro.RoQ"
// #define LEGACY_PROTOCOL // You probably don't need this for your standalone game
#else
#define PRODUCT_NAME "Reaction"
@ -47,8 +50,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define HOMEPATH_NAME_WIN "Reaction"
#define HOMEPATH_NAME_MACOSX HOMEPATH_NAME_WIN
// #define STEAMPATH_NAME "Foo Bar"
// #define STEAMPATH_APPID ""
// #define STEAMPATH_APPID ""
// #define GOGPATH_ID ""
#define GAMENAME_FOR_MASTER "Reaction"
#define CINEMATICS_LOGO "Reactionlogo.RoQ"
#define CINEMATICS_INTRO "intro.RoQ"
// #define LEGACY_PROTOCOL
#endif
@ -66,6 +72,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#define PRODUCT_VERSION "1.36"
#endif
#ifndef PRODUCT_DATE
# define PRODUCT_DATE __DATE__
#endif
#define Q3_VERSION PRODUCT_NAME " " PRODUCT_VERSION
#define MAX_TEAMNAME 32
@ -151,6 +161,7 @@ typedef int intptr_t;
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
@ -167,13 +178,15 @@ typedef int intptr_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int8 uint8_t;
#else
#include <stdint.h>
#endif
#ifdef _WIN32
// vsnprintf is ISO/IEC 9899:1999
// abstracting this to make it portable
int Q_vsnprintf(char *str, size_t size, const char *format, va_list ap);
#else
#include <stdint.h>
#define Q_vsnprintf vsnprintf
#endif
@ -260,7 +273,7 @@ typedef int clipHandle_t;
#define MAX_SAY_TEXT 150
// paramters for command buffer stuffing
// parameters for command buffer stuffing
typedef enum {
EXEC_NOW, // don't return until completed, a VM should NEVER use this,
// because some commands might cause the VM to be unloaded...
@ -403,8 +416,7 @@ extern vec4_t colorMdGrey;
extern vec4_t colorDkGrey;
#define Q_COLOR_ESCAPE '^'
//#define Q_IsColorString(p) ((p) && *(p) == Q_COLOR_ESCAPE && *((p)+1) && isalnum(*((p)+1))) // ^[0-9a-zA-Z]
#define Q_IsColorString(p) ( p && *(p) == Q_COLOR_ESCAPE && *((p)+1) && *((p)+1) != Q_COLOR_ESCAPE )
#define Q_IsColorString(p) ((p) && *(p) == Q_COLOR_ESCAPE && *((p)+1) && *((p)+1) != Q_COLOR_ESCAPE)
#define COLOR_BLACK '0'
#define COLOR_RED '1'
@ -1243,7 +1255,7 @@ typedef struct playerState_s {
#define BUTTON_TALK 2 // displays talk balloon and disables actions
#define BUTTON_USE_HOLDABLE 4
#define BUTTON_GESTURE 8
#define BUTTON_WALKING 16 // walking can't just be infered from MOVE_RUN
#define BUTTON_WALKING 16 // walking can't just be inferred from MOVE_RUN
// because a key pressed late in the frame will
// only generate a small move value for that frame
// walking will use different animations and

View file

@ -637,6 +637,8 @@ int FS_LoadStack( void );
int FS_GetFileList( const char *path, const char *extension, char *listbuf, int bufsize );
int FS_GetModList( char *listbuf, int bufsize );
void FS_GetModDescription( const char *modDir, char *description, int descriptionLen );
fileHandle_t FS_FOpenFileWrite( const char *qpath );
fileHandle_t FS_FOpenFileAppend( const char *filename );
fileHandle_t FS_FCreateOpenPipeFile( const char *filename );
@ -657,7 +659,6 @@ int FS_FileIsInPAK(const char *filename, int *pChecksum );
int FS_Write( const void *buffer, int len, fileHandle_t f );
int FS_Read2( void *buffer, int len, fileHandle_t f );
int FS_Read( void *buffer, int len, fileHandle_t f );
// properly handles partial reads and reads from other dlls
@ -668,7 +669,7 @@ long FS_ReadFileDir(const char *qpath, void *searchPath, qboolean unpure, void *
long FS_ReadFile(const char *qpath, void **buffer);
// returns the length of the file
// a null buffer will just return the file length without loading
// as a quick check for existance. -1 length == not present
// as a quick check for existence. -1 length == not present
// A 0 byte will always be appended at the end, so string ops are safe.
// the buffer should be considered read-only, because it may be cached
// for other uses.
@ -725,6 +726,7 @@ void FS_PureServerSetLoadedPaks( const char *pakSums, const char *pakNames );
// sole exception of .cfg files.
qboolean FS_CheckDirTraversal(const char *checkdir);
qboolean FS_InvalidGameDir(const char *gamedir);
qboolean FS_idPak(char *pak, char *base, int numPaks);
qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring );
@ -762,7 +764,7 @@ void Field_CompleteFilename( const char *dir,
const char *ext, qboolean stripExt, qboolean allowNonPureFilesOnDisk );
void Field_CompleteCommand( char *cmd,
qboolean doCommands, qboolean doCvars );
void Field_CompletePlayerName( char **names, int count );
void Field_CompletePlayerName( const char **names, int count );
/*
==============================================================
@ -880,6 +882,9 @@ extern cvar_t *com_protocol;
#ifdef LEGACY_PROTOCOL
extern cvar_t *com_legacyprotocol;
#endif
#ifndef DEDICATED
extern cvar_t *con_autochat;
#endif
// com_speeds times
extern int time_game;
@ -1054,6 +1059,14 @@ int SV_SendQueuedPackets(void);
qboolean UI_GameCommand( void );
qboolean UI_usesUniqueCDKey(void);
//
// input interface
//
void IN_Init( void *windowData );
void IN_Frame( void );
void IN_Shutdown( void );
void IN_Restart( void );
/*
==============================================================
@ -1071,6 +1084,8 @@ void * QDECL Sys_LoadGameDll( const char *name, intptr_t (QDECL **entryPoint)(in
intptr_t (QDECL *systemcalls)(intptr_t, ...) );
void Sys_UnloadDll( void *dllHandle );
qboolean Sys_DllExtension( const char *name );
char *Sys_GetCurrentUser( void );
void QDECL Sys_Error( const char *error, ...) __attribute__ ((noreturn, format (printf, 1, 2)));
@ -1107,8 +1122,9 @@ char *Sys_Cwd( void );
void Sys_SetDefaultInstallPath(const char *path);
char *Sys_DefaultInstallPath(void);
char *Sys_SteamPath(void);
char *Sys_GogPath(void);
#ifdef MACOS_X
#ifdef __APPLE__
char *Sys_DefaultAppPath(void);
#endif
@ -1145,7 +1161,8 @@ typedef enum
dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *title );
qboolean Sys_WritePIDFile( void );
void Sys_RemovePIDFile( const char *gamedir );
void Sys_InitPIDFile( const char *gamedir );
/* This is based on the Adaptive Huffman algorithm described in Sayood's Data
* Compression book. The ranks are not actually stored, but implicitly defined
@ -1188,9 +1205,9 @@ void Huff_Decompress(msg_t *buf, int offset);
void Huff_Init(huffman_t *huff);
void Huff_addRef(huff_t* huff, byte ch);
int Huff_Receive (node_t *node, int *ch, byte *fin);
void Huff_transmit (huff_t *huff, int ch, byte *fout);
void Huff_offsetReceive (node_t *node, int *ch, byte *fin, int *offset);
void Huff_offsetTransmit (huff_t *huff, int ch, byte *fout, int *offset);
void Huff_transmit (huff_t *huff, int ch, byte *fout, int maxoffset);
void Huff_offsetReceive (node_t *node, int *ch, byte *fin, int *offset, int maxoffset);
void Huff_offsetTransmit (huff_t *huff, int ch, byte *fout, int *offset, int maxoffset);
void Huff_putBit( int bit, byte *fout, int *offset);
int Huff_getBit( byte *fout, int *offset);

View file

@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
// This file must be identical in the quake and utils directories
// contents flags are seperate bits
// contents flags are separate bits
// a given brush can contribute multiple content bits
// these definitions also need to be in q_shared.h!

View file

@ -151,7 +151,7 @@ typedef struct
/* ===========================================================================
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
for end of file.
IN assertion: the stream s has been sucessfully opened for reading.
IN assertion: the stream s has been successfully opened for reading.
*/
@ -290,8 +290,8 @@ local int strcmpcasenosensitive_internal (fileName1,fileName2)
/*
Compare two filename (fileName1,fileName2).
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
If iCaseSenisivity = 1, comparison is case sensitivity (like strcmp)
If iCaseSenisivity = 2, comparison is not case sensitivity (like strcmpi
or strcasecmp)
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
(like 1 on Unix, 2 on Windows)

View file

@ -125,8 +125,8 @@ extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
int iCaseSensitivity));
/*
Compare two filename (fileName1,fileName2).
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
If iCaseSenisivity = 1, comparison is case sensitivity (like strcmp)
If iCaseSenisivity = 2, comparison is not case sensitivity (like strcmpi
or strcasecmp)
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
(like 1 on Unix, 2 on Windows)

View file

@ -451,13 +451,15 @@ vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc, qboolean unpure)
if(alloc)
{
// allocate zero filled space for initialized and uninitialized data
vm->dataBase = Hunk_Alloc(dataLength, h_high);
// leave some space beyond data mask so we can secure all mask operations
vm->dataAlloc = dataLength + 4;
vm->dataBase = Hunk_Alloc(vm->dataAlloc, h_high);
vm->dataMask = dataLength - 1;
}
else
{
// clear the data, but make sure we're not clearing more than allocated
if(vm->dataMask + 1 != dataLength)
if(vm->dataAlloc != dataLength + 4)
{
VM_Free(vm);
FS_FreeFile(header.v);
@ -467,7 +469,7 @@ vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc, qboolean unpure)
return NULL;
}
Com_Memset(vm->dataBase, 0, dataLength);
Com_Memset(vm->dataBase, 0, vm->dataAlloc);
}
// copy the intialized data

1222
code/qcommon/vm_armv7l.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -317,8 +317,8 @@ locals from sp
int VM_CallInterpreted( vm_t *vm, int *args ) {
byte stack[OPSTACK_SIZE + 15];
register int *opStack;
register uint8_t opStackOfs;
int *opStack;
uint8_t opStackOfs;
int programCounter;
int programStack;
int stackOnEntry;
@ -436,31 +436,31 @@ nextInstruction2:
return 0;
}
#endif
r0 = opStack[opStackOfs] = *(int *) &image[r0 & dataMask & ~3 ];
r0 = opStack[opStackOfs] = *(int *) &image[ r0 & dataMask ];
goto nextInstruction2;
case OP_LOAD2:
r0 = opStack[opStackOfs] = *(unsigned short *)&image[ r0&dataMask&~1 ];
r0 = opStack[opStackOfs] = *(unsigned short *)&image[ r0 & dataMask ];
goto nextInstruction2;
case OP_LOAD1:
r0 = opStack[opStackOfs] = image[ r0&dataMask ];
r0 = opStack[opStackOfs] = image[ r0 & dataMask ];
goto nextInstruction2;
case OP_STORE4:
*(int *)&image[ r1&(dataMask & ~3) ] = r0;
*(int *)&image[ r1 & dataMask ] = r0;
opStackOfs -= 2;
goto nextInstruction;
case OP_STORE2:
*(short *)&image[ r1&(dataMask & ~1) ] = r0;
*(short *)&image[ r1 & dataMask ] = r0;
opStackOfs -= 2;
goto nextInstruction;
case OP_STORE1:
image[ r1&dataMask ] = r0;
image[ r1 & dataMask ] = r0;
opStackOfs -= 2;
goto nextInstruction;
case OP_ARG:
// single byte offset from programStack
*(int *)&image[ (codeImage[programCounter] + programStack)&dataMask&~3 ] = r0;
*(int *)&image[ (codeImage[programCounter] + programStack) & dataMask ] = r0;
opStackOfs--;
programCounter += 1;
goto nextInstruction;

View file

@ -170,6 +170,7 @@ struct vm_s {
byte *dataBase;
int dataMask;
int dataAlloc; // actually allocated
int stackBottom; // if programStack < stackBottom, error

View file

@ -401,7 +401,7 @@ struct symbolic_jump {
// extensions / modifiers (branch-link)
unsigned long ext;
// dest_instruction refering to this jump
// dest_instruction referring to this jump
dest_instruction_t *parent;
// next jump
@ -656,7 +656,7 @@ PPC_MakeFastMask( int mask )
* function local registers,
*
* normally only volatile registers are used, but if there aren't enough
* or function has to preserve some value while calling annother one
* or function has to preserve some value while calling another one
* then caller safe registers are used as well
*/
static const long int gpr_list[] = {

Some files were not shown because too many files have changed in this diff Show more