mirror of
https://github.com/ReactionQuake3/reaction.git
synced 2025-01-31 13:50:55 +00:00
Update to ioquake3 2018-12-21 part 2 (engine)
This commit is contained in:
parent
be3161dfce
commit
dfb9bed2b8
225 changed files with 11585 additions and 8180 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
|||
build
|
||||
*.swp
|
||||
*tags
|
||||
*~
|
||||
|
||||
# OS X
|
||||
####################
|
||||
|
|
35
.travis.yml
35
.travis.yml
|
@ -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
4
BUGS
|
@ -1,4 +0,0 @@
|
|||
- On Solaris/SPARC gcc optimizations higher than -O0 currently lead
|
||||
to a segfault
|
||||
|
||||
https://bugzilla.icculus.org/ for more.
|
18
ChangeLog
18
ChangeLog
|
@ -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
410
Makefile
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
1
NOTTODO
1
NOTTODO
|
@ -1 +0,0 @@
|
|||
http://wiki.ioquake3.org/NotToDo
|
32
README.md
32
README.md
|
@ -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
165
autoupdater-readme.txt
Normal 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.
|
||||
|
1043
code/autoupdater/autoupdater.c
Normal file
1043
code/autoupdater/autoupdater.c
Normal file
File diff suppressed because it is too large
Load diff
8
code/autoupdater/rsa_tools/.gitignore
vendored
Normal file
8
code/autoupdater/rsa_tools/.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
crypt-*.tar.bz2
|
||||
tfm-*.tar.xz
|
||||
libtomcrypt-*
|
||||
tomsfastmath-*
|
||||
rsa_make_keys
|
||||
rsa_sign
|
||||
rsa_verify
|
||||
*.exe
|
79
code/autoupdater/rsa_tools/build-libtom-unix.sh
Normal file
79
code/autoupdater/rsa_tools/build-libtom-unix.sh
Normal 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 ...
|
||||
|
33
code/autoupdater/rsa_tools/build-rsa-tools.sh
Normal file
33
code/autoupdater/rsa_tools/build-rsa-tools.sh
Normal 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!"
|
||||
|
61
code/autoupdater/rsa_tools/rsa_common.c
Normal file
61
code/autoupdater/rsa_tools/rsa_common.c
Normal 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));
|
||||
}
|
||||
}
|
||||
|
30
code/autoupdater/rsa_tools/rsa_common.h
Normal file
30
code/autoupdater/rsa_tools/rsa_common.h
Normal 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 ... */
|
||||
|
45
code/autoupdater/rsa_tools/rsa_make_keys.c
Normal file
45
code/autoupdater/rsa_tools/rsa_make_keys.c
Normal 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 ... */
|
75
code/autoupdater/rsa_tools/rsa_sign.c
Normal file
75
code/autoupdater/rsa_tools/rsa_sign.c
Normal 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 ... */
|
||||
|
60
code/autoupdater/rsa_tools/rsa_verify.c
Normal file
60
code/autoupdater/rsa_tools/rsa_verify.c
Normal 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 ... */
|
||||
|
17
code/autoupdater/rsa_tools/test-rsa-tools.sh
Normal file
17
code/autoupdater/rsa_tools/test-rsa-tools.sh
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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: -
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
//===========================================================================
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
//===========================================================================
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 "\\"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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';
|
||||
//
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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-- )
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -344,6 +344,8 @@ typedef struct {
|
|||
|
||||
netadr_t authorizeServer;
|
||||
|
||||
netadr_t rconAddress;
|
||||
|
||||
// rendering info
|
||||
glconfig_t glconfig;
|
||||
qhandle_t charSetShader;
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
229
code/client/snd_altivec.c
Normal 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
|
||||
|
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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++)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 ) {
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -148,7 +148,7 @@ vec3_t bytedirs[NUMVERTEXNORMALS] =
|
|||
//==============================================================
|
||||
|
||||
int Q_rand( int *seed ) {
|
||||
*seed = (69069 * *seed + 1);
|
||||
*seed = (69069U * *seed + 1U);
|
||||
return *seed;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
=============
|
||||
*/
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
1222
code/qcommon/vm_armv7l.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
|
|
|
@ -170,6 +170,7 @@ struct vm_s {
|
|||
|
||||
byte *dataBase;
|
||||
int dataMask;
|
||||
int dataAlloc; // actually allocated
|
||||
|
||||
int stackBottom; // if programStack < stackBottom, error
|
||||
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue