Merge pull request #596 from a1batross/vulkan

Merge upstream

It's me again, bringing you changes from upstream master branch.

No really interesting changes yet, mostly code refactoring, bug fixes, optimizations.
* We finally migrated all cvars to static allocation, making it's easier for CPU to access cvar values. I do not recommend migrating for renderers yet because of known bug with `GLCONFIG` cvars.
* In OpenGL renderer we started to use `GenTextures` call instead of directly binding arbitrary texture IDs, which also fixed few bugs with overlay programs.
* I probably finally fixed the bug where the engine crashes on startup on Linux, somewhere deep in SDL. At least, I haven't seen it for a while.
* We also finally allow C99 code in the engine. I don't think engine will be ported to new old standard overnight, it's just now fine for new code. 
* We support `.pk3dir`. It's a Quake engine's convention to allow mounting directories that end with `.pk3dir`, as if they were archives. It simplifies development process, where current dev version of assets could be in `pk3dir` and packaged into `pk3` for release.
* I added simple tool called `xar` that unpacks data from `.pak`, `.pk3` and `.wad` archives using `filesystem_stdio`.
This commit is contained in:
Ivan Avdeev 2023-10-06 21:33:42 -07:00 committed by GitHub
commit c5bbcae242
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
200 changed files with 5815 additions and 8483 deletions

4
.gitignore vendored
View File

@ -60,6 +60,7 @@ Makefile.dep
ALL_BUILD.*
INSTALL.*
ZERO_CHECK.*
CMakeLists.txt
# Visual Studio
*.obj
@ -339,3 +340,6 @@ core
.history/*
.cache/*
enc_temp_folder/
# KDevelop4
*.kdev4

2
3rdparty/gl-wes-v2 vendored

@ -1 +1 @@
Subproject commit 0be6803f816b5cc3a9f7b990f3d19449559eb0bd
Subproject commit 7ba4631bf5e921284100d10923b6980af66d98e8

@ -1 +1 @@
Subproject commit 277be116c1fce0c0344ab41359aeadfa7f023b93
Subproject commit 5226f5f9370eebe874dae0525ad5d878a3b66faf

2
3rdparty/mainui vendored

@ -1 +1 @@
Subproject commit 262128c0d1368177d85072d1642521f738942f9a
Subproject commit 07421520b8635056007853ddf7c7abd6ee7bc604

2
3rdparty/nanogl vendored

@ -1 +1 @@
Subproject commit 5f2892a37e70e8baaccecfba84be424d2bd29aa7
Subproject commit 6b6a947ee0c32abceea3e111364b0225af36df61

@ -1 +1 @@
Subproject commit e7b56e7b26b240f811a8a192f6e2880f0d3898d3
Subproject commit 521cf5cb6c3ee0804e5478d8858ec3fba67c1377

112
Documentation/gameinfo.md Normal file
View File

@ -0,0 +1,112 @@
# Game definition and information file
gameinfo.txt is an essential part of any Xash3D based game. It allows basic customization for games creators, like setting game title, DLL paths, etc.
This document defines gameinfo.txt syntax, supported keys and liblist.gam conversion rules for the latest version of the engine. Note for engine developers, keep this document in sync with an implementation.
## gameinfo.txt syntax
* gameinfo.txt is a simple list of keys and values, separated by newline.
* You can add single line comments using double slashes (//).
* Keys can accept integer, float, string or boolean values.
* Boolean keys use 0 as false and 1 as true value.
* To have spaces in string values, you must enclose them in double quotes. Then, to have double quotes, you must escape it with backslash, and to have a backslash you need to use double backslashes.
The example:
```
// this is a comment :)
// this is another comment
some_integer_key 123
this_is_float_key 13.37 // optional comment
enable_feature 1 // boolean, 1 to enable, 0 to disable
example_string_key string_value
example_spaces "string with spaces"
example_title "Fate\\Stay Night" // engine will parse it as Fate\Stay Night
```
## gameinfo.txt keys
This is a list of all gameinfo.txt keys supported by the engine. Be aware that the engine will silently skip all unrecognized keys.
| Key | Type | Default value | Description |
| ---------------- | ---------- | --------------- | ----------- |
| `ambient0` | string | Empty string | Automatic ambient sound |
| `ambient1` | string | Empty string | Automatic ambient sound |
| `ambient2` | string | Empty string | Automatic ambient sound |
| `ambient3` | string | Empty string | Automatic ambient sound |
| `basedir` | string | `valve` | Game base directory, used to share assets between games |
| `date` | string | Empty string | Game release date. Unused. |
| `dllpath` | string | `cl_dlls` | Game DLL path. Engine will search custom DLLs (client or menu, for example) in this directory, except `gamedll`, see below. |
| `fallback_dir` | string | Empty string | Additional game base directory |
| `gamedir` | string | Current gamedir | Game directory, ignored in FWGS, as game directory is defined by the game directory name |
| `gamedll` | string | `dlls/hl.dll` | Game server DLL for 32-bit x86 Windows (see LibraryNaming.md for details) |
| `gamemode` | string | Empty string | Game type. When set to `singleplayer_only` or `multiplayer_only` marks the game as SP or MP only respectively, hiding the option in game UI. Omitting this key or using custom values mark the game as both MP and SP compatible. |
| `icon` | string | `game.ico` | Game icon. Engine will automatically append .ico and may automatically switch to .tga icon as well |
| `max_beams` | integer | 128 | Beams limit, 64 min, 512 max |
| `max_edicts` | integer | 900 | Entities limit, 600 min, 8192 max (protocol limit). In FWGS, minimum is 64. |
| `max_particles` | integer | 4096 | Particles limit, 1024 min, 131072 max |
| `max_tempents` | integer | 500 | Temporary entities limit. 300 min, 2048 max |
| `mp_entity` | string | `info_player_deathmatch` | Entity used to mark maps as multiplayer |
| `mp_filter` | string | Empty string | When set, used to filter multiplayer maps instead of `mp_entity`.<br>If the map name starts with the same characters as this filter, it's considered a multiplayer map |
| `nomodels` | boolean | 0 | When set to 1, disallows changing player model in UI |
| `noskills` | boolean | 0 | When set to 1, disallows selection of game difficulty |
| `secure` | boolean | 0 | When set to 1, original Unkle Mike's engine will completely disable developer mode. FWGS ignores but preserves this value for compatibility. |
| `size` | integer | 0 | Game directory size in bytes, used in Change Game dialog only |
| `startmap` | string | `c0a0` | The name of the map used in new game |
| `sp_entity` | string | `info_player_start` | Entity used to mark map as single player. Used in map validation |
| `title` | string | `New Game` | Game title, used in window title, default server name, etc. |
| `trainmap` | string | `t0a0` | The name of the training map (Hazard Course) |
| `type` | string | Empty string | Game type, used in Change Game UI. |
| `url_info` | string | Empty string | Game homepage URL, used in Change Game UI |
| `url_update` | string | Empty string | Game updates URL, used in Settings UI |
| `version` | float | 1.0 | Game version, used in Change Game dialog and in server info |
## FWGS-specific gameinfo.txt keys
These strings are specific to Xash3D FWGS.
| Key | Type | Default value | Description |
| ----------------------- | ---------- | ------------------------ | ----------- |
| `autosave_aged_count` | integer | 2 | Auto saves limit used in saves rotation |
| `gamedll_linux` | string | Generated from `gamedll` | Game server DLL for 32-bit x86 Linux (see LibraryNaming.md for details) |
| `gamedll_osx` | string | Generated from `gamedll` | Game server DLL for 32-bit x86 macOS (see LibraryNaming.md for details) |
| `internal_vgui_support` | boolean | 0 | Only for programmers! Required to be set as 1 for PrimeXT!<br>When set to 1, the engine will not load vgui_support DLL, as VGUI support is done (or intentionally ignored) on the game side. |
| `render_picbutton_text` | boolean | 0 | When set to 1, the UI will not use prerendered `btns_main.bmp` and dynamically render them instead |
| `quicksave_aged_count` | integer | 2 | Quick saves limit used in saves rotation |
## Note on GoldSrc liblist.gam support
As Xash3D accidentally supports GoldSrc games, it also supports parsing liblist.gam.\
Xash3D will use this file if gameinfo.txt is absent, or if its modification timestamp is older than liblist.gam.
For game creators who plan supporting only Xash3D, using this file is not recommended.
The table below defines conversion rules from liblist.gam to gameinfo.txt. Some keys' interpretation does differ from `gameinfo.txt`, in this case a note will be left. If `liblist.gam` key isn't present in this table, it's ignored.
| `liblist.gam` key | `gameinfo.txt` key | Note |
| ----------------- | ------------------ | ---- |
| `edicts` | `max_edicts` | |
| `fallback_dir` | `fallback_dir` | |
| `game` | `title` | |
| `gamedir` | `gamedir` | |
| `gamedll` | `gamedll` | |
| `gamedll_linux` | `gamedll_linux` | |
| `gamedll_osx` | `gamedll_osx` | |
| `icon` | `icon` | |
| `mpentity` | `mp_entity` | |
| `mpfilter` | `mp_filter` | |
| `nomodels` | `nomodels` | |
| `secure` | `secure` | In GoldSrc it's used to mark the multiplayer game as anti-cheat enabled.<br>Original Xash3D misinterprets its value for disallowing console and developer mode.<br>FWGS ignores this key but preserves for compatibility. |
| `startmap` | `startmap` | |
| `size` | `size` | |
| `trainingmap` | `trainmap` | |
| `trainmap` | `trainmap` | |
| `type` | `type` & `gamemode`| In `liblist.gam` this key works as both `type` and `gamemode`.<br>If value is `singleplayer_only` or `multiplayer_only` the game is marked as SP or MP only, and `gameinfo.txt` type set to `Single` or `Multiplayer`.<br>Any custom value will mark the game as both SP and MP compatible, and type is set to whatever custom value. |
| `url_dl` | `url_update` | |
| `url_info` | `url_info` | |
| `version` | `version` | |

View File

@ -17,7 +17,7 @@ Mirrored on github - https://github.com/JoelTroch/am_src_rebirth
Mirrored on github - https://github.com/nekonomicon/BattleGrounds
## Bubblemod
Download page on official site - http://www.bubblemod.org/dl_default.php (dead link!)
Download page on official site(WM snapshot) - [http://www.bubblemod.org/dl_default.php](https://web.archive.org/web/20130717133158/http://www.bubblemod.org/dl_default.php)
Mirrored on github - https://github.com/HLSources/BubbleMod
@ -85,6 +85,9 @@ Official gitlab repository - https://gitlab.com/Sockman/hltopdown
## Half-Life: Update
Official github repository - https://github.com/Fograin/hl-subsmod-ex
## Half-Life: Rally
Official gitlab repository - https://gitlab.com/hlrally/src
## Half-Life: Weapon Edition
Available on ModDB - https://www.moddb.com/mods/half-life-weapon-edition/downloads/half-life-weapon-edition-1508-alpha-open-src

View File

@ -2,38 +2,32 @@ Xash3D FWGS is intended to be easily ported to specific platform, however main i
This page is about merged ports to main source tree and responsible for it developers.
For porting guidelines, look here(TODO!)
For porting guidelines, look engine-porting-guide.md.
Status:
* **Supported**: active, confirmed to be fully functional.
* **Supported**: active, was confirmed to be fully functional.
* **In progress**: active, under development.
* **Incomplete**: not active, but some work was accepted to main repository before
* **Old Engine**: port was for old engine fork
* **Not maintained**: lack of human resources
* **Not merged**: was done in third-party fork, real status unknown
* **Deprecated**: not supported anymore
Table is sorted by status.
Table is sorted by status and platform.
| Platform | Status | Maintainer | Note
| -------- | ------ | ---------- | ----
| Windows | Supported | @a1batross, @SNMetamorph |
| Android | Supported | @Velaron |
| *BSD | Supported | @nekonomicon |
| GNU/Linux(x86, amd64, arm) | Supported | @a1batross, @mittorn |
| Android | Supported | @a1batross, @mittorn |
| MotoMAGX | Supported | @a1batross |
| GNU/Linux(elbrus) | Supported | @a1batross, @mittorn | Rare and eventual access to e2k machine
| Haiku | Supported | not maintained | Was added by #478 and #483
| DOS4GW | Supported | @mittorn |
| GNU/Linux(mipsel) | Supported | @mittorn |
| GNU/Linux | Supported | @a1batross, @mittorn |
| Haiku | Supported | not maintained | Was added by #478 and #483
| macOS | Supported | @sofakng |
| MotoMAGX | Supported | @a1batross |
| PSVita | Supported | @fgsfdsfgs |
| Switch | Supported | @fgsfdsfgs |
| Wii | In progress | Collaborative effort | [GitHub Repository](https://github.com/saucesaft/xash3d-wii)
| Windows | Supported | @a1batross, @SNMetamorph |
| PSP | In progress | @Crow_bar, @Velaron | [GitHub Repository](https://github.com/Crow-bar/xash3d-fwgs)
| Wii | In progress | Collaborative effort | [GitHub Repository](https://github.com/saucesaft/xash3d-wii)
| Emscripten | Old Engine | not maintained |
| Oculus Quest | Old Engine fork | @DrBeef | [GitHub Repository](https://github.com/DrBeef/Lambda1VR)
| PSVita | Old Engine fork | not maintained | [GitHub Repository](https://github.com/fgsfdsfgs/vitaXash3D)
| Switch | Old Engine fork | not maintained | [GitHub Repository](https://github.com/switchports/xash3d-switch)
| 3DS | Old Engine fork | not maintained | [GitHub Repository](https://github.com/masterfeizz/Xash3DS)
| macOS | Deprecated | not maintained | See GitHub issue #61
| Oculus Quest | Old Engine fork | @DrBeef | [GitHub Repository](https://github.com/DrBeef/Lambda1VR)
| iOS | Deprecated | not maintained | See GitHub issue #61

View File

@ -18,21 +18,17 @@ GNU General Public License for more details.
// video backends (XASH_VIDEO)
#define VIDEO_NULL 0
#define VIDEO_SDL 1
#define VIDEO_ANDROID 2
#define VIDEO_FBDEV 3
#define VIDEO_DOS 4
// audio backends (XASH_SOUND)
#define SOUND_NULL 0
#define SOUND_SDL 1
#define SOUND_OPENSLES 2
#define SOUND_ALSA 3
// input (XASH_INPUT)
#define INPUT_NULL 0
#define INPUT_SDL 1
#define INPUT_ANDROID 2
#define INPUT_EVDEV 3
// timer (XASH_TIMER)
@ -45,16 +41,13 @@ GNU General Public License for more details.
// messageboxes (XASH_MESSAGEBOX)
#define MSGBOX_STDERR 0
#define MSGBOX_SDL 1
#define MSGBOX_ANDROID 2
#define MSGBOX_WIN32 3
#define MSGBOX_NSWITCH 4
// library loading (XASH_LIB)
#define LIB_NULL 0
#define LIB_POSIX 1
#define LIB_WIN32 2
#define LIB_STATIC 3
#endif /* BACKENDS_H */

View File

@ -52,26 +52,6 @@ SETUP BACKENDS DEFINITIONS
#endif
#endif // XASH_MESSAGEBOX
#endif
#elif XASH_ANDROID
// we are building for Android platform, use Android APIs
#ifndef XASH_VIDEO
#define XASH_VIDEO VIDEO_ANDROID
#endif // XASH_VIDEO
#ifndef XASH_INPUT
#define XASH_INPUT INPUT_ANDROID
#endif // XASH_INPUT
#ifndef XASH_SOUND
#define XASH_SOUND SOUND_OPENSLES
#endif // XASH_SOUND
#ifndef XASH_MESSAGEBOX
#define XASH_MESSAGEBOX MSGBOX_ANDROID
#endif // XASH_MESSAGEBOX
#define XASH_USE_EVDEV 1
#define XASH_DYNAMIC_DLADDR
#elif XASH_LINUX
// we are building for Linux without SDL2, can draw only to framebuffer yet
#ifndef XASH_VIDEO
@ -171,6 +151,8 @@ Default build-depended cvar and constant values
#define DEFAULT_MODE_WIDTH 960
#define DEFAULT_MODE_HEIGHT 544
#define DEFAULT_ALLOWCONSOLE 1
#elif XASH_ANDROID
#define DEFAULT_TOUCH_ENABLE "1"
#elif XASH_MOBILE_PLATFORM
#define DEFAULT_TOUCH_ENABLE "1"
#define DEFAULT_M_IGNORE "1"
@ -204,7 +186,7 @@ Default build-depended cvar and constant values
#endif // DEFAULT_ALLOWCONSOLE
#ifndef DEFAULT_FULLSCREEN
#define DEFAULT_FULLSCREEN 1
#define DEFAULT_FULLSCREEN "1" // must be a string
#endif // DEFAULT_FULLSCREEN
#endif // DEFAULTS_H

View File

@ -1,206 +0,0 @@
#############################################
# Makefile.linux - linux makefile
# Copyright (C) 2017 mittorn
# This program 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 3 of the License, or
# (at your option) any later version.
# This program 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.
##############################################
# Default options - optimized to debug on local machine
CC ?= gcc
CXX ?= g++
CFLAGS ?= -g -O1 -fsigned-char -Wall -Wextra -Wsign-compare -Wno-unknown-pragmas -Wno-missing-field-initializers -Wno-unused-parameter -Wno-unused-but-set-variable
LDFLAGS =
LBITS := $(shell getconf LONG_BIT)
DEPS :=
XASH_COMMIT := $(firstword $(shell git rev-parse --short=6 HEAD) unknown)
ifeq ($(XASH_COMMIT),unknown)
$(warning You seems to build xash3d without git)
$(warning Please use git if you are going to publish your build)
endif
# Pass 64BIT=1 to make arguments to allow amd64 builds
ifneq ($(64BIT),1)
ifeq ($(LBITS),64)
LDFLAGS += -m32
CFLAGS += -m32
endif
endif
TOPDIR = $(PWD)/..
INCLUDES :=
XASH_SINGLE_BINARY ?= 1
INSTALL_DIR ?= ./install/
ifeq ($(NANOGL),1)
INCLUDES += -Inanogl -Inanogl/GL
endif
INCLUDES += -I/usr/include/SDL2 -Icommon -I../common -I. -I../pm_shared -Iclient -Iserver -Iclient/vgui -Icommon/sdl
#############################
# Preprocessor defines:
#############################
DEFINES =
# Specify commit hash in version string
DEFINES += -DXASH_BUILD_COMMIT=\"$(XASH_COMMIT)\"
# Only SDL backend exists on linux
ifeq ($(XASH_DEDICATED),1)
DEFINES += -DXASH_DEDICATED
else
DEFINES += -DXASH_SDL
LIBS += -lSDL2
endif
#############################################
# GL/GLES translators.
# You need clone it to engine folder to use
# Only one translator should be enabled
#############################################
ifeq ($(NANOGL),1)
DEFINES += -DXASH_NANOGL -D__MULTITEXTURE_SUPPORT__ -DEGL_LIB=\"libEGL.so\"
endif
ifeq ($(WES),1)
DEFINES += -DXASH_WES -D__MULTITEXTURE_SUPPORT__ -DEGL_LIB=\"libEGL.so\"
endif
ifeq ($(REGAL),1)
DEFINES += -DXASH_REGAL -D__MULTITEXTURE_SUPPORT__ -DEGL_LIB=\"regal/lib/linux-32/libRegal.so\"
LIBS += regal/lib/linux-32/libRegal.so
endif
# Some libc implementations cannot use libdl in static builds, so disable it by default
ifeq ($(XASH_STATIC),1)
ifneq ($(XASH_STATIC_LIBDL),1)
DEFINES += -DNO_LIBDL
endif
XASH_SINGLE_BINARY := 1
endif
ifneq ($(XASH_STATIC),1)
LIBS += -ldl
endif
ifeq ($(XASH_STATIC_LIBDL),1)
LIBS += -ldl
endif
LIBS += -lm -pthread
ifeq ($(XASH_SINGLE_BINARY),1)
DEFINES += -DSINGLE_BINARY
endif
# Collect files
SRCS_CPP =
SRCS = $(wildcard server/*.c) $(wildcard client/vgui/*.c) $(wildcard client/avi/*.c) $(wildcard common/*.c) $(wildcard common/imagelib/*.c) $(wildcard common/soundlib/*.c) $(wildcard common/soundlib/libmpg/*.c)
ifneq ($(XASH_DEDICATED),1)
SRCS += $(wildcard client/*.c)
SRCS += $(wildcard platform/sdl/*.c)
ifeq ($(WES),1)
SRCS += $(wildcard gl-wes-v2/src/*.c)
endif
ifeq ($(NANOGL),1)
SRCS_CPP += $(wildcard nanogl/*.cpp)
endif
endif
OBJS = $(patsubst %.c,obj/%.o,$(SRCS))
OBJS_CPP = $(patsubst %.cpp,obj/%.o,$(SRCS_CPP))
#################################
# Windows DLL loader
# Should be enabled only on i386 builds
#################################
LOADER :=
ifeq ($(XASH_DLL_LOADER),1)
DEFINES += -DDLL_LOADER
ifeq ($(XASH_SINGLE_BINARY),1)
LOADER = libloader.a
else
LOADER = libloader.so
endif
DEPS += $(LOADER)
LIBS += $(LOADER)
endif
# Rules for binaries
ifeq ($(XASH_SINGLE_BINARY),0)
BINARIES = libxash.so
libxash.so : $(OBJS) $(OBJS_CPP) $(DEPS)
$(CC) -fvisibility=hidden -o libxash.so $(LDFLAGS) -shared $(OBJS) $(OBJS_CPP) $(LIBS)
else
BINARIES = xash
xash: $(OBJS) $(OBJS_CPP) $(DEPS)
ifeq ($(XASH_STATIC),1)
$(CC) -o xash -static $(LDFLAGS) $(OBJS) $(OBJS_CPP) $(LIBS)
else
$(CC) -o xash -fvisibility=hidden $(LDFLAGS) $(OBJS) $(OBJS_CPP) $(LIBS)
endif
endif
ifeq ($(XASH_DLL_LOADER),1)
$(LOADER):
$(MAKE) -f ../loader/Makefile.linux -C ../loader $(LOADER)
cp ../loader/$(LOADER) .
endif
# Create dirs for object files
DIRS := obj obj/server obj/client/avi obj/client/vgui obj/common/sdl obj/common/imagelib obj/common/soundlib/libmpg obj/platform/sdl obj/nanogl
$(OBJS): | $(DIRS)
$(DIRS) :
mkdir -p $(DIRS)
# Object rules
obj/%.o : %.c
$(CC) $(CFLAGS) $(INCLUDES) $(DEFINES) -c "$<" -o "$@" -Wno-unused-result -fvisibility=hidden
obj/%.o : %.cpp
$(CXX) $(CFLAGS) $(INCLUDES) $(DEFINES) -c "$<" -o "$@"
default: $(BINARIES)
.PHONY: depend clean list install
clean:
$(RM) $(OBJS) $(OBJS_CPP) $(BINARIES) ../loader/*.o ../loader/*.a ../loader/*.so $(LOADER)
list:
@echo Sources:
@echo $(SRCS)
@echo C++ Sources:
@echo $(SRCS_CPP)
@echo Objects:
@echo $(OBJS) $(OBJS_CPP)
@echo Dirs:
@echo $(DIRS)
@echo Dependencies:
@echo $(DEPS)
# Simple install rule
install: $(BINARIES)
mkdir -p $(INSTALL_DIR)
ifeq ($(XASH_SINGLE_BINARY),1)
cp xash $(INSTALL_DIR)/xash_bin
else
cp libxash.so $(INSTALL_DIR)/
cp libloader.so $(INSTALL_DIR)/
endif

View File

@ -1,269 +0,0 @@
**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*
- [Building](#building)
- [Manual build (without CMake)](#manual-build-without-cmake)
- [Building Engine](#building-engine)
- [Building launch binary](#building-launch-binary)
- [Building on Windows](#building-on-windows)
- [Visual Studio 2013 (recommended for Windows)](#visual-studio-2013-recommended-for-windows)
- [Visual Studio 6](#visual-studio-6)
- [MinGW](#mingw)
- [Building Game mods](#building-game-mods)
- [Linux](#linux)
- [microndk](#microndk)
- [Makefile.linux](#makefile-linux)
- [Windows](#windows)
- [Running](#running)
- [Manual running](#manual-running)
- [Running with GDB](#running-with-gdb)
- [Using DLL Loader](#using-dll-loader)
- [Running MinGW builds](#running-mingw-builds)
- [Running MinGW builds under GDB](#running-mingw-builds-under-gdb)
# Building
## Manual build (without CMake)
### Building engine
Clone Xash3D repository using git:
git clone https://github.com/FWGS/xash3d
Move to the Xash3D folder:
cd xash3d/engine
make -f Makefile.linux XASH_VGUI=1
or same for dedicated
make -f Makefile.linux XASH_DEDICATED=1
To enable dll support on linux, build loader library:
cd ../loader
make -f Makefile.linux libloader.so libloader.a
cp libloader.so libloader.a ../engine/
And built engine with XASH_DLL_LOADER=1:
cd ../engine
make -f Makefile.linux XASH_VGUI=1 XASH_SDL=1 XASH_DLL_LOADER=1
or same for dedicated server
cd ../engine
make -f Makefile.linux XASH_DEDICATED=1 XASH_DLL_LOADER=1
### Building engine in separate library
Some old distros does not support hidden symbol visibility
This results in crash when loading server library
Building launch binary
cd (xash3d)/game_launch
gcc xash.c -o xash -ldl -lrt -lm
Building engine library:
make -f Makefile.linux XASH_SINGLE_BINARY=0
## Building on Windows
### Visual Studio 2013 (recommended for Windows)
Download latest prebuilt SDL2 from
https://www.libsdl.org/release/SDL2-devel-2.0.4-VC.zip
Unzip and rename `SDL2-2.0.4` folder to `SDL2` and put it next to xash3d project folder.
..\xash3d\
..\SDL2\
Open `xash.sln` with Visual Studio 2013 and make a build. After building, copy contents of `Debug` or
`Release` folder to directory you choose. Copy `valve` folder and `vgui.dll` from your Half Life game
installation folder and `SDL2.dll` form `\SDL2\lib\x86\` to it.
Move `vgui_support.dll` into `valve` folder.
..\valve\
..\valve\vgui_support.dll
..\menu.dll
..\SDL2.dll
..\vgui.dll
..\xash.dll
..\xash.exe
Now you good to go, just run `xash.exe`.
### Visual Studio 6
This is legacy configuration, but msvc6 seems to generate more stable and more effective code
Setup your msvc6 enviroment, unpack SDL2-2.0.4 to xash3d folder and do:
cd (xash3d)\engine
..\msvc6\build.bat
cd (xash3d)\game_launch
..\msvc6\build_launch.bat
### MinGW
The most effective configuration, but maybe unstable.
Setup your MinGW environment and run:
cd (xash3d)\engine\
CC=gcc mingw32-make -f Makefile.mingw
engine will be built to single exe binary
## Building game mods
### Linux
#### microndk
All mods that ported to android may be build to linux using Android.mk with microndk:
[https://github.com/SDLash3D/microndk]
Clone microndk repo somewhere, change xash3d_config to preffered configuration (change arch to x86
for example)
Go to dlls folder if you are building server or cl_dlls if you are building client and do:
make -f /path/to/microndk/microndk.mk -j4
Do:
make -f /path/to/microndk/microndk.mk -j4 clean
every time when you build client after building server
#### Makefile.linux
### Windows
On windows common way is using Visual Studio as many mods does not correctly work with mingw.
Just open project and build it.
Other is using mingw and microndk, but it was not tested yet.
hlsdk-xash3d based mods may work fine with mingw.
You may use microndk to build it. Build process is very similar to linux one.
After setting up MinGW enviroment, do:<br>
`mingw32-make -f \path\to\microndk\Microndk.mk`
to build 64-bit library, use:<br>
`mingw32-make -f \path\to\microndk\Microndk.mk 64BIT=1`
Edit xash3d_config.mk to set optimal CFLAGS if you are running server
# Running
Copy **valve** folder from Half-Life:
cp -r $HOME/.steam/steam/steamapps/common/Half-Life/valve $HOME/Games/Xash3D
**NOTE**: If you build with CMake, you can now use `make install`. It will install binaries where
they must be located. So just run `xash3d` from command line in directory where is gamedata is located.
For additional info look to the CMakeLists.txt in repo root and xash3d.sh script.
After a successful build, copy the next files to some other directory where you want to run Xash3D:
cp engine/libxash.so game_launch/xash3d mainui/libxashmenu.so $HOME/Games/Xash3D
If you built it with XASH_VGUI, also copy vgui.so:
cp ../hlsdk/linux/vgui.so vgui_support/libvgui_support.so $HOME/Games/Xash3D
Copy script:
cp ../xash3d.sh $HOME/Games/Xash3D
Run:
cd $HOME/Games/Xash3D
./xash3d.sh
## Manual running
Put xash3d binaries and vgui(optionally) to you game data directory and run:
LD_LIBRARY_PATH=. ./xash -dev 5
## Running under GDB
LD_LIBRARY_PATH=. gdb --args ./xash -dev 5
## Using DLL Loader
Put vgui_support.dll from windows build to your game data folder and run:
LD_LIBRARY_PATH=. ./xash -dev 5 -vguilib vgui.dll -clientlib valve/cl_dlls/client.dll -dll dlls/hl.dll
## Running MinGW builds
Put exe file to your game data directory
cd (game)\
xash_bin -dev 5
### Running MinGW builds under GDB
gdb --args ./xash_bin.exe -dev 5
# Useful GDB commands
Start or restart process:
(gdb) r
Show backtrace:
(gdb) bt
Full backtrace:
(gdb) bt full
Continue execution:
(gdb) c
Recover from segmentation fault:
Skipping function:
(gdb) handle SIGSEGV nopass
(gdb) ret
(gdb) c
Restart frame for beginning:
(gdb) handle SIGSEGV nopass
(gdb) jump *Host_AbortCurrentFrame
Anti-Crash script (useful for scripting servers):
```
cd /path/to/rootdir
file xash
set args xash -dev 5 -nowcon
handle SIGSEGV nopass
catch signal SIGSEGV
set $crashes=0
commands
print $crashes++
if $crashes > 500
set $crashes=0
run
else
jump *Host_AbortCurrentFrame
end
end
run
```

View File

@ -1,7 +0,0 @@
#!/bin/sh
SCRIPTDIR=$(dirname "$0")
TOPDIR=$SCRIPTDIR/../../
cp $SCRIPTDIR/Makefile.dllloader $TOPDIR/loader/
cp $SCRIPTDIR/Makefile.emscripten $TOPDIR/engine/
cp $SCRIPTDIR/Makefile.linux $TOPDIR/engine/
cp $SCRIPTDIR/wscript $TOPDIR/engine/

View File

@ -1,73 +0,0 @@
#! /usr/bin/env python
# encoding: utf-8
# mittorn, 2018
VERSION='0.99'
APPNAME='xash3d-fwgs'
top = '.'
def options(opt):
opt.load('compiler_c')
# opt.load('msvs')
opt.add_option('--dedicated', action = 'store_true', help = 'build dedicated server only' )
opt.add_option('--64bits', dest = 'amd64', action = 'store_true', help = 'build 64-bit engine on x86_64' )
def configure(conf):
conf.load('compiler_c')
conf.env.append_unique('CFLAGS', '-O2')
conf.env.append_unique('DEFINES', 'SINGLE_BINARY')
conf.env.append_value('LINKFLAGS', '-ldl')
conf.env.append_value('LINKFLAGS', '-lm')
conf.env.append_value('LINKFLAGS', '-pthread')
# check for 64-bit builds
# TODO: check 32-bit toolchain and dependencies
if conf.env.DEST_CPU == 'x86_64' and not conf.options.amd64:
conf.env.append_value('LINKFLAGS', '-m32')
conf.env.append_value('CFLAGS', '-m32')
print('NOTE: will build engine with 64-bit toolchain using -m32')
else:
print('Warning: 64bit engine may be unstable')
# check for dedicated server build
if conf.options.dedicated:
conf.env.append_unique('DEFINES', 'XASH_DEDICATED')
conf.env.dedicated = True
else:
# TODO: add way to specify SDL2 path, move to separate function
try:
conf.check_cfg(path='sdl2-config', args='--cflags --libs', package='', msg='Checking for SDL2', uselib_store='SDL2')
except conf.errors.ConfigurationError:
conf.fatal('SDL2 not availiable! If you want to build dedicated server, specify --dedicated')
conf.env.append_unique('DEFINES', 'XASH_SDL')
def build(bld):
# basic build: dedicated only, no dependencies
use = [];
source = bld.path.ant_glob([
'common/*.c',
'common/imagelib/*.c',
'common/soundlib/*.c',
'common/soundlib/libmpg/*.c',
'server/*.c'])
# add client files and sdl2 library
if not bld.env.dedicated:
use += ['SDL2']
source += bld.path.ant_glob([
'client/*.c',
'client/vgui/*.c',
'client/avi/*.c',
'platform/sdl/*.c'])
bld(
target = 'xash',
features = 'c cprogram',
includes = ['../common', '../pm_shared', 'common', 'server', 'client', 'client/vgui', '.' ],
source = source,
use = use
)

View File

@ -206,7 +206,7 @@ void CL_ScreenShot_f( void )
if( !CL_ScreenshotGetName( i, checkname, sizeof( checkname )))
return; // no namespace
if( !FS_FileExists( checkname, false ))
if( !FS_FileExists( checkname, true ))
break;
}
@ -246,7 +246,7 @@ void CL_SnapShot_f( void )
if( !CL_SnapshotGetName( i, checkname, sizeof( checkname )))
return; // no namespace
if( !FS_FileExists( checkname, false ))
if( !FS_FileExists( checkname, true ))
break;
}

View File

@ -372,7 +372,7 @@ void CL_WriteDemoHeader( const char *name )
demo.header.id = IDEMOHEADER;
demo.header.dem_protocol = DEMO_PROTOCOL;
demo.header.net_protocol = cls.legacymode ? PROTOCOL_LEGACY_VERSION : PROTOCOL_VERSION;
demo.header.host_fps = bound( MIN_FPS, host_maxfps->value, MAX_FPS );
demo.header.host_fps = bound( MIN_FPS, host_maxfps.value, MAX_FPS );
Q_strncpy( demo.header.mapname, clgame.mapname, sizeof( demo.header.mapname ));
Q_strncpy( demo.header.comment, clgame.maptitle, sizeof( demo.header.comment ));
Q_strncpy( demo.header.gamedir, FS_Gamedir(), sizeof( demo.header.gamedir ));
@ -648,11 +648,13 @@ void CL_DemoStartPlayback( int mode )
{
if( cls.changedemo )
{
int maxclients = cl.maxclients;
S_StopAllSounds( true );
SCR_BeginLoadingPlaque( false );
CL_ClearState ();
CL_InitEdicts (); // re-arrange edicts
CL_ClearState( );
CL_InitEdicts( maxclients ); // re-arrange edicts
}
else
{
@ -698,7 +700,7 @@ void CL_DemoAborted( void )
cls.demofile = NULL;
cls.demonum = -1;
Cvar_SetValue( "v_dark", 0.0f );
Cvar_DirectSet( &v_dark, "0" );
}
/*
@ -716,7 +718,7 @@ void CL_DemoCompleted( void )
if( !CL_NextDemo() && !cls.changedemo )
UI_SetActiveMenu( true );
Cvar_SetValue( "v_dark", 0.0f );
Cvar_DirectSet( &v_dark, "0" );
}
/*
@ -1306,7 +1308,7 @@ void CL_CheckStartupDemos( void )
}
// run demos loop in background mode
Cvar_SetValue( "v_dark", 1.0f );
Cvar_DirectSet( &v_dark, "1" );
cls.demos_pending = false;
cls.demonum = 0;
CL_NextDemo ();
@ -1322,11 +1324,11 @@ static void CL_DemoGetName( int lastnum, char *filename, size_t size )
if( lastnum < 0 || lastnum > 9999 )
{
// bound
Q_strncpy( filename, "demo9999.dem", size );
Q_strncpy( filename, "demo9999", size );
return;
}
Q_snprintf( filename, size, "demo%04d.dem", lastnum );
Q_snprintf( filename, size, "demo%04d", lastnum );
}
/*
@ -1381,7 +1383,9 @@ void CL_Record_f( void )
for( n = 0; n < 10000; n++ )
{
CL_DemoGetName( n, demoname, sizeof( demoname ));
if( !FS_FileExists( demoname, true ))
Q_snprintf( demopath, sizeof( demopath ), "%s.dem", demoname );
if( !FS_FileExists( demopath, true ))
break;
}
@ -1468,7 +1472,7 @@ void CL_PlayDemo_f( void )
{
int c, neg = false;
demo.header.host_fps = host_maxfps->value;
demo.header.host_fps = host_maxfps.value;
while(( c = FS_Getc( cls.demofile )) != '\n' )
{

View File

@ -6,7 +6,7 @@
#include "r_efx.h"
#include "cl_tent.h"
#include "pm_local.h"
#define PART_SIZE Q_max( 0.5f, cl_draw_particles->value )
#define PART_SIZE Q_max( 0.5f, cl_draw_particles.value )
/*
==============================================================
@ -21,9 +21,9 @@ static int ramp2[8] = { 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66 };
static int ramp3[6] = { 0x6d, 0x6b, 6, 5, 4, 3 };
static int gSparkRamp[9] = { 0xfe, 0xfd, 0xfc, 0x6f, 0x6e, 0x6d, 0x6c, 0x67, 0x60 };
convar_t *tracerspeed;
convar_t *tracerlength;
convar_t *traceroffset;
static CVAR_DEFINE_AUTO( tracerspeed, "6000", 0, "tracer speed" );
static CVAR_DEFINE_AUTO( tracerlength, "0.8", 0, "tracer length factor" );
static CVAR_DEFINE_AUTO( traceroffset, "30", 0, "tracer starting offset" );
particle_t *cl_active_particles;
particle_t *cl_active_tracers;
@ -100,9 +100,9 @@ void CL_InitParticles( void )
cl_avelocities[i][2] = COM_RandomFloat( 0.0f, 2.55f );
}
tracerspeed = Cvar_Get( "tracerspeed", "6000", 0, "tracer speed" );
tracerlength = Cvar_Get( "tracerlength", "0.8", 0, "tracer length factor" );
traceroffset = Cvar_Get( "traceroffset", "30", 0, "tracer starting offset" );
Cvar_RegisterVariable( &tracerspeed );
Cvar_RegisterVariable( &tracerlength );
Cvar_RegisterVariable( &traceroffset );
}
/*
@ -171,7 +171,7 @@ particle_t * GAME_EXPORT R_AllocParticle( void (*callback)( particle_t*, float )
{
particle_t *p;
if( !cl_draw_particles->value )
if( !cl_draw_particles.value )
return NULL;
// never alloc particles when we not in game
@ -222,7 +222,7 @@ particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life )
{
particle_t *p;
if( !cl_draw_tracers->value )
if( !cl_draw_tracers.value )
return NULL;
// never alloc particles when we not in game
@ -249,7 +249,7 @@ particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life )
VectorCopy( org, p->org );
VectorCopy( vel, p->vel );
p->die = cl.time + life;
p->ramp = tracerlength->value;
p->ramp = tracerlength.value;
p->color = 4; // select custom color
p->packedColor = 255; // alpha
@ -1804,14 +1804,14 @@ void GAME_EXPORT R_TracerEffect( const vec3_t start, const vec3_t end )
float len, speed;
float offset;
speed = Q_max( tracerspeed->value, 3.0f );
speed = Q_max( tracerspeed.value, 3.0f );
VectorSubtract( end, start, dir );
len = VectorLength( dir );
if( len == 0.0f ) return;
VectorScale( dir, 1.0f / len, dir ); // normalize
offset = COM_RandomFloat( -10.0f, 9.0f ) + traceroffset->value;
offset = COM_RandomFloat( -10.0f, 9.0f ) + traceroffset.value;
VectorScale( dir, offset, vel );
VectorAdd( start, vel, pos );
VectorScale( dir, speed, vel );
@ -2067,16 +2067,16 @@ void CL_FreeDeadBeams( void )
void CL_DrawEFX( float time, qboolean fTrans )
{
CL_FreeDeadBeams();
if( CVAR_TO_BOOL( cl_draw_beams ))
if( cl_draw_beams.value )
ref.dllFuncs.CL_DrawBeams( fTrans, cl_active_beams );
if( fTrans )
{
R_FreeDeadParticles( &cl_active_particles );
if( CVAR_TO_BOOL( cl_draw_particles ))
if( cl_draw_particles.value )
ref.dllFuncs.CL_DrawParticles( time, cl_active_particles, PART_SIZE );
R_FreeDeadParticles( &cl_active_tracers );
if( CVAR_TO_BOOL( cl_draw_tracers ))
if( cl_draw_tracers.value )
ref.dllFuncs.CL_DrawTracers( time, cl_active_tracers );
}
}

View File

@ -84,7 +84,7 @@ void CL_DescribeEvent( event_info_t *ei, int slot )
con_nprint_t info;
string origin_str = { 0 }; //, angles_str = { 0 };
if( !cl_showevents->value )
if( !cl_showevents.value )
return;
info.time_to_live = 1.0f;
@ -225,6 +225,18 @@ qboolean CL_FireEvent( event_info_t *ei, int slot )
if( ev->index == ei->index )
{
name = cl.event_precache[ei->index];
if( cl_trace_events.value )
{
Con_Printf( "^3EVENT %s AT %.2f %.2f %.2f\n" // event name
"\t%.2f %.2f %i %i %s %s\n", // bool params
name, ei->args.origin[0], ei->args.origin[1], ei->args.origin[2],
ei->args.fparam1, ei->args.fparam2,
ei->args.iparam1, ei->args.iparam2,
ei->args.bparam1 ? "TRUE" : "FALSE", ei->args.bparam2 ? "TRUE" : "FALSE" );
}
if( ev->func )
{
CL_DescribeEvent( ei, slot );
@ -232,7 +244,6 @@ qboolean CL_FireEvent( event_info_t *ei, int slot )
return true;
}
name = cl.event_precache[ei->index];
Con_Reportf( S_ERROR "CL_FireEvent: %s not hooked\n", name );
break;
}

View File

@ -134,7 +134,7 @@ some ents will be ignore lerping
*/
qboolean CL_EntityIgnoreLerp( cl_entity_t *e )
{
if( cl_nointerp->value > 0.f )
if( cl_nointerp.value > 0.f )
return true;
if( e->model && e->model->type == mod_alias )
@ -464,13 +464,13 @@ int CL_InterpolateModel( cl_entity_t *e )
if( cl.maxclients <= 1 )
return 1;
if( e->model->type == mod_brush && !cl_bmodelinterp->value )
if( e->model->type == mod_brush && !cl_bmodelinterp.value )
return 1;
if( cl.local.moving && cl.local.onground == e->index )
return 1;
t = cl.time - cl_interp->value;
t = cl.time - cl_interp.value;
CL_FindInterpolationUpdates( e, t, &ph0, &ph1 );
if( ph0 == NULL || ph1 == NULL )
@ -537,7 +537,7 @@ void CL_ComputePlayerOrigin( cl_entity_t *ent )
if( !ent->player )
return;
if( cl_nointerp->value > 0.f )
if( cl_nointerp.value > 0.f )
{
VectorCopy( ent->curstate.angles, ent->angles );
VectorCopy( ent->curstate.origin, ent->origin );
@ -555,7 +555,7 @@ void CL_ComputePlayerOrigin( cl_entity_t *ent )
return;
}
targettime = cl.time - cl_interp->value;
targettime = cl.time - cl_interp.value;
CL_PureOrigin( ent, targettime, origin, angles );
VectorCopy( angles, ent->angles );

View File

@ -154,7 +154,7 @@ CL_CreatePlaylist
Create a default valve playlist
====================
*/
void CL_CreatePlaylist( const char *filename )
static void CL_CreatePlaylist( const char *filename )
{
file_t *f;
@ -458,7 +458,7 @@ void CL_DrawCenterPrint( void )
if( !clgame.centerPrint.time )
return;
if(( cl.time - clgame.centerPrint.time ) >= scr_centertime->value )
if(( cl.time - clgame.centerPrint.time ) >= scr_centertime.value )
{
// time expired
clgame.centerPrint.time = 0.0f;
@ -665,12 +665,12 @@ void CL_ParseTextMessage( sizebuf_t *msg )
text->g2 = MSG_ReadByte( msg );
text->b2 = MSG_ReadByte( msg );
text->a2 = MSG_ReadByte( msg );
text->fadein = (float)(MSG_ReadShort( msg ) / 256.0f );
text->fadeout = (float)(MSG_ReadShort( msg ) / 256.0f );
text->holdtime = (float)(MSG_ReadShort( msg ) / 256.0f );
text->fadein = (float)(MSG_ReadWord( msg ) / 256.0f );
text->fadeout = (float)(MSG_ReadWord( msg ) / 256.0f );
text->holdtime = (float)(MSG_ReadWord( msg ) / 256.0f );
if( text->effect == 2 )
text->fxtime = (float)(MSG_ReadShort( msg ) / 256.0f );
text->fxtime = (float)(MSG_ReadWord( msg ) / 256.0f );
else text->fxtime = 0.0f;
// to prevent grab too long messages
@ -914,7 +914,7 @@ void CL_DrawCrosshair( void )
int x, y, width, height;
float xscale, yscale;
if( !clgame.ds.pCrosshair || !cl_crosshair->value )
if( !clgame.ds.pCrosshair || !cl_crosshair.value )
return;
// any camera on or client is died
@ -1088,13 +1088,13 @@ void CL_ClearWorld( void )
clgame.numStatics = 0;
}
void CL_InitEdicts( void )
void CL_InitEdicts( int maxclients )
{
Assert( clgame.entities == NULL );
if( !clgame.mempool ) return; // Host_Error without client
#if XASH_LOW_MEMORY != 2
CL_UPDATE_BACKUP = ( cl.maxclients <= 1 ) ? SINGLEPLAYER_BACKUP : MULTIPLAYER_BACKUP;
CL_UPDATE_BACKUP = ( maxclients <= 1 ) ? SINGLEPLAYER_BACKUP : MULTIPLAYER_BACKUP;
#endif
cls.num_client_entities = CL_UPDATE_BACKUP * NUM_PACKET_ENTITIES;
cls.packet_entities = Mem_Realloc( clgame.mempool, cls.packet_entities, sizeof( entity_state_t ) * cls.num_client_entities );
@ -1140,7 +1140,7 @@ void CL_ClearEdicts( void )
// in case we stopped with error
clgame.maxEntities = 2;
CL_InitEdicts();
CL_InitEdicts( cl.maxclients );
}
/*
@ -1322,7 +1322,7 @@ pfnSPR_Load
=========
*/
HSPRITE EXPORT pfnSPR_Load( const char *szPicName )
static HSPRITE GAME_EXPORT pfnSPR_Load( const char *szPicName )
{
model_t *spr;
@ -1338,7 +1338,7 @@ CL_GetSpritePointer
=============
*/
const model_t *CL_GetSpritePointer( HSPRITE hSprite )
static const model_t *CL_GetSpritePointer( HSPRITE hSprite )
{
model_t *mod;
int index = hSprite - 1;
@ -1370,7 +1370,7 @@ pfnSPR_Frames
=========
*/
int EXPORT pfnSPR_Frames( HSPRITE hPic )
static int GAME_EXPORT pfnSPR_Frames( HSPRITE hPic )
{
int numFrames = 0;
@ -1630,14 +1630,14 @@ get actual screen info
*/
int GAME_EXPORT CL_GetScreenInfo( SCREENINFO *pscrinfo )
{
float scale_factor = hud_scale->value;
float scale_factor = hud_scale.value;
if( FBitSet( hud_fontscale->flags, FCVAR_CHANGED ))
if( FBitSet( hud_fontscale.flags, FCVAR_CHANGED ))
{
CL_FreeFont( &cls.creditsFont );
SCR_LoadCreditsFont();
ClearBits( hud_fontscale->flags, FCVAR_CHANGED );
ClearBits( hud_fontscale.flags, FCVAR_CHANGED );
}
// setup screen info
@ -1685,6 +1685,22 @@ static void GAME_EXPORT pfnSetCrosshair( HSPRITE hspr, wrect_t rc, int r, int g,
clgame.ds.rcCrosshair = rc;
}
/*
=============
pfnCvar_RegisterVariable
=============
*/
static cvar_t *GAME_EXPORT pfnCvar_RegisterClientVariable( const char *szName, const char *szValue, int flags )
{
// a1ba: try to mitigate outdated client.dll vulnerabilities
if( !Q_stricmp( szName, "motdfile" ))
flags |= FCVAR_PRIVILEGED;
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_CLIENTDLL, Cvar_BuildAutoDescription( szName, flags|FCVAR_CLIENTDLL ));
}
/*
=============
pfnHookUserMsg
@ -1889,7 +1905,7 @@ static int GAME_EXPORT pfnDrawCharacter( int x, int y, int number, int r, int g,
rgba_t color = { r, g, b, 255 };
int flags = FONT_DRAW_HUD;
if( hud_utf8->value )
if( hud_utf8.value )
flags |= FONT_DRAW_UTF8;
return CL_DrawCharacter( x, y, number, color, &cls.creditsFont, flags );
@ -1904,7 +1920,7 @@ drawing string like a console string
*/
int GAME_EXPORT pfnDrawConsoleString( int x, int y, char *string )
{
cl_font_t *font = Con_GetFont( con_fontsize->value );
cl_font_t *font = Con_GetFont( con_fontsize.value );
rgba_t color;
Vector4Copy( clgame.ds.textColor, color );
Vector4Set( clgame.ds.textColor, 255, 255, 255, 255 );
@ -1937,7 +1953,7 @@ compute string length in screen pixels
*/
void GAME_EXPORT pfnDrawConsoleStringLen( const char *pText, int *length, int *height )
{
cl_font_t *font = Con_GetFont( con_fontsize->value );
cl_font_t *font = Con_GetFont( con_fontsize.value );
if( height ) *height = font->charHeight;
CL_DrawStringLen( font, pText, length, NULL, FONT_DRAW_UTF8 | FONT_DRAW_HUD );
@ -1985,7 +2001,7 @@ static int GAME_EXPORT pfnGetWindowCenterX( void )
{
int x = 0;
#if XASH_WIN32
if( m_ignore->value )
if( m_ignore.value )
{
POINT pos;
GetCursorPos( &pos );
@ -2010,7 +2026,7 @@ static int GAME_EXPORT pfnGetWindowCenterY( void )
{
int y = 0;
#if XASH_WIN32
if( m_ignore->value )
if( m_ignore.value )
{
POINT pos;
GetCursorPos( &pos );
@ -2122,7 +2138,7 @@ pfnCalcShake
=============
*/
void GAME_EXPORT pfnCalcShake( void )
static void GAME_EXPORT pfnCalcShake( void )
{
screen_shake_t *const shake = &clgame.shake;
float frametime, fraction, freq;
@ -2178,7 +2194,7 @@ pfnApplyShake
=============
*/
void GAME_EXPORT pfnApplyShake( float *origin, float *angles, float factor )
static void GAME_EXPORT pfnApplyShake( float *origin, float *angles, float factor )
{
if( origin )
VectorMA( origin, factor, clgame.shake.applied_offset, origin );
@ -2306,7 +2322,7 @@ pfnPlaySound
=============
*/
void GAME_EXPORT pfnPlaySound( int ent, float *org, int chan, const char *samp, float vol, float attn, int flags, int pitch )
static void GAME_EXPORT pfnPlaySound( int ent, float *org, int chan, const char *samp, float vol, float attn, int flags, int pitch )
{
S_StartSound( org, ent, chan, S_RegisterSound( samp ), vol, attn, pitch, flags );
}
@ -2317,7 +2333,7 @@ CL_FindModelIndex
=============
*/
int GAME_EXPORT CL_FindModelIndex( const char *m )
static int GAME_EXPORT CL_FindModelIndex( const char *m )
{
char filepath[MAX_QPATH];
static float lasttimewarn;
@ -2354,7 +2370,7 @@ pfnIsLocal
=============
*/
int GAME_EXPORT pfnIsLocal( int playernum )
static int GAME_EXPORT pfnIsLocal( int playernum )
{
if( playernum == cl.playernum )
return true;
@ -2367,7 +2383,7 @@ pfnLocalPlayerDucking
=============
*/
int GAME_EXPORT pfnLocalPlayerDucking( void )
static int GAME_EXPORT pfnLocalPlayerDucking( void )
{
return (cl.local.usehull == 1) ? true : false;
}
@ -2378,7 +2394,7 @@ pfnLocalPlayerViewheight
=============
*/
void GAME_EXPORT pfnLocalPlayerViewheight( float *view_ofs )
static void GAME_EXPORT pfnLocalPlayerViewheight( float *view_ofs )
{
if( view_ofs ) VectorCopy( cl.viewheight, view_ofs );
}
@ -2389,7 +2405,7 @@ pfnLocalPlayerBounds
=============
*/
void GAME_EXPORT pfnLocalPlayerBounds( int hull, float *mins, float *maxs )
static void GAME_EXPORT pfnLocalPlayerBounds( int hull, float *mins, float *maxs )
{
if( hull >= 0 && hull < 4 )
{
@ -2404,7 +2420,7 @@ pfnIndexFromTrace
=============
*/
int GAME_EXPORT pfnIndexFromTrace( struct pmtrace_s *pTrace )
static int GAME_EXPORT pfnIndexFromTrace( struct pmtrace_s *pTrace )
{
#if 0 // Velaron: breaks compatibility with mods that call the function after CL_PopPMStates
if( pTrace->ent >= 0 && pTrace->ent < clgame.pmove->numphysent )
@ -2439,7 +2455,7 @@ pfnGetVisent
=============
*/
physent_t *pfnGetVisent( int idx )
static physent_t *pfnGetVisent( int idx )
{
if( idx >= 0 && idx < clgame.pmove->numvisent )
{
@ -2455,7 +2471,7 @@ pfnSetTraceHull
=============
*/
void GAME_EXPORT CL_SetTraceHull( int hull )
static void GAME_EXPORT CL_SetTraceHull( int hull )
{
clgame.pmove->usehull = bound( 0, hull, 3 );
}
@ -2466,7 +2482,7 @@ pfnPlayerTrace
=============
*/
void GAME_EXPORT CL_PlayerTrace( float *start, float *end, int traceFlags, int ignore_pe, pmtrace_t *tr )
static void GAME_EXPORT CL_PlayerTrace( float *start, float *end, int traceFlags, int ignore_pe, pmtrace_t *tr )
{
if( !tr ) return;
*tr = PM_PlayerTraceExt( clgame.pmove, start, end, traceFlags, clgame.pmove->numphysent, clgame.pmove->physents, ignore_pe, NULL );
@ -2478,7 +2494,7 @@ pfnPlayerTraceExt
=============
*/
void GAME_EXPORT CL_PlayerTraceExt( float *start, float *end, int traceFlags, int (*pfnIgnore)( physent_t *pe ), pmtrace_t *tr )
static void GAME_EXPORT CL_PlayerTraceExt( float *start, float *end, int traceFlags, int (*pfnIgnore)( physent_t *pe ), pmtrace_t *tr )
{
if( !tr ) return;
*tr = PM_PlayerTraceExt( clgame.pmove, start, end, traceFlags, clgame.pmove->numphysent, clgame.pmove->physents, -1, pfnIgnore );
@ -2523,7 +2539,7 @@ pfnStopAllSounds
=============
*/
void GAME_EXPORT pfnStopAllSounds( int ent, int entchannel )
static void GAME_EXPORT pfnStopAllSounds( int ent, int entchannel )
{
S_StopSound( ent, entchannel, NULL );
}
@ -2548,7 +2564,7 @@ model_t *CL_LoadModel( const char *modelname, int *index )
return CL_ModelHandle( i );
}
int GAME_EXPORT CL_AddEntity( int entityType, cl_entity_t *pEnt )
static int GAME_EXPORT CL_AddEntity( int entityType, cl_entity_t *pEnt )
{
if( !pEnt ) return false;
@ -2565,7 +2581,7 @@ pfnGetGameDirectory
=============
*/
const char *pfnGetGameDirectory( void )
static const char *pfnGetGameDirectory( void )
{
static char szGetGameDir[MAX_SYSPATH];
@ -2579,7 +2595,7 @@ Key_LookupBinding
=============
*/
const char *Key_LookupBinding( const char *pBinding )
static const char *Key_LookupBinding( const char *pBinding )
{
return Key_KeynumToString( Key_GetKey( pBinding ));
}
@ -2610,7 +2626,7 @@ pfnGetScreenFade
=============
*/
void GAME_EXPORT pfnGetScreenFade( struct screenfade_s *fade )
static void GAME_EXPORT pfnGetScreenFade( struct screenfade_s *fade )
{
if( fade ) *fade = clgame.fade;
}
@ -2632,7 +2648,7 @@ pfnLoadMapSprite
=============
*/
model_t *pfnLoadMapSprite( const char *filename )
static model_t *pfnLoadMapSprite( const char *filename )
{
model_t *mod;
@ -2650,7 +2666,7 @@ PlayerInfo_ValueForKey
=============
*/
const char *PlayerInfo_ValueForKey( int playerNum, const char *key )
static const char *PlayerInfo_ValueForKey( int playerNum, const char *key )
{
// find the player
if(( playerNum > cl.maxclients ) || ( playerNum < 1 ))
@ -2668,7 +2684,7 @@ PlayerInfo_SetValueForKey
=============
*/
void GAME_EXPORT PlayerInfo_SetValueForKey( const char *key, const char *value )
static void GAME_EXPORT PlayerInfo_SetValueForKey( const char *key, const char *value )
{
convar_t *var;
@ -2694,7 +2710,7 @@ pfnGetPlayerUniqueID
=============
*/
qboolean GAME_EXPORT pfnGetPlayerUniqueID( int iPlayer, char playerID[16] )
static qboolean GAME_EXPORT pfnGetPlayerUniqueID( int iPlayer, char playerID[16] )
{
if( iPlayer < 1 || iPlayer > cl.maxclients )
return false;
@ -2714,7 +2730,7 @@ pfnGetTrackerIDForPlayer
obsolete, unused
=============
*/
int GAME_EXPORT pfnGetTrackerIDForPlayer( int playerSlot )
static int GAME_EXPORT pfnGetTrackerIDForPlayer( int playerSlot )
{
return 0;
}
@ -2726,7 +2742,7 @@ pfnGetPlayerForTrackerID
obsolete, unused
=============
*/
int GAME_EXPORT pfnGetPlayerForTrackerID( int trackerID )
static int GAME_EXPORT pfnGetPlayerForTrackerID( int trackerID )
{
return 0;
}
@ -2737,7 +2753,7 @@ pfnServerCmdUnreliable
=============
*/
int GAME_EXPORT pfnServerCmdUnreliable( char *szCmdString )
static int GAME_EXPORT pfnServerCmdUnreliable( char *szCmdString )
{
if( !COM_CheckString( szCmdString ))
return 0;
@ -2754,7 +2770,7 @@ pfnGetMousePos
=============
*/
void GAME_EXPORT pfnGetMousePos( struct tagPOINT *ppt )
static void GAME_EXPORT pfnGetMousePos( struct tagPOINT *ppt )
{
if( !ppt )
return;
@ -2769,7 +2785,7 @@ pfnSetMouseEnable
legacy of dinput code
=============
*/
void GAME_EXPORT pfnSetMouseEnable( qboolean fEnable )
static void GAME_EXPORT pfnSetMouseEnable( qboolean fEnable )
{
}
@ -2888,7 +2904,7 @@ static int GAME_EXPORT pfnDrawString( int x, int y, const char *str, int r, int
rgba_t color = { r, g, b, 255 };
int flags = FONT_DRAW_HUD | FONT_DRAW_NOLF;
if( hud_utf8->value )
if( hud_utf8.value )
SetBits( flags, FONT_DRAW_UTF8 );
return CL_DrawString( x, y, str, color, &cls.creditsFont, flags );
@ -2906,7 +2922,7 @@ static int GAME_EXPORT pfnDrawStringReverse( int x, int y, const char *str, int
int flags = FONT_DRAW_HUD | FONT_DRAW_NOLF;
int width;
if( hud_utf8->value )
if( hud_utf8.value )
SetBits( flags, FONT_DRAW_UTF8 );
CL_DrawStringLen( &cls.creditsFont, str, &width, NULL, flags );
@ -2983,7 +2999,7 @@ pfnFillRGBABlend
=============
*/
void GAME_EXPORT CL_FillRGBABlend( int x, int y, int w, int h, int r, int g, int b, int a )
static void GAME_EXPORT CL_FillRGBABlend( int x, int y, int w, int h, int r, int g, int b, int a )
{
float _x = x, _y = y, _w = w, _h = h;
@ -3045,7 +3061,7 @@ pfnParseFile
handle colon separately
=============
*/
char *pfnParseFile( char *data, char *token )
static char *pfnParseFile( char *data, char *token )
{
return COM_ParseFileSafe( data, token, PFILE_TOKEN_MAX_LENGTH, PFILE_HANDLECOLON, NULL, NULL );
}
@ -3266,7 +3282,7 @@ NetAPI_InitNetworking
=================
*/
void GAME_EXPORT NetAPI_InitNetworking( void )
static void GAME_EXPORT NetAPI_InitNetworking( void )
{
NET_Config( true, false ); // allow remote
}
@ -3277,7 +3293,7 @@ NetAPI_InitNetworking
=================
*/
void GAME_EXPORT NetAPI_Status( net_status_t *status )
static void GAME_EXPORT NetAPI_Status( net_status_t *status )
{
qboolean connected = false;
int packet_loss = 0;
@ -3296,7 +3312,7 @@ void GAME_EXPORT NetAPI_Status( net_status_t *status )
status->remote_address = cls.netchan.remote_address;
status->packet_loss = packet_loss;
status->local_address = net_local;
status->rate = rate->value;
status->rate = rate.value;
}
/*
@ -3305,7 +3321,7 @@ NetAPI_SendRequest
=================
*/
void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags, double timeout, netadr_t *remote_address, net_api_response_func_t response )
static void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags, double timeout, netadr_t *remote_address, net_api_response_func_t response )
{
net_request_t *nr = NULL;
string req;
@ -3386,7 +3402,7 @@ NetAPI_CancelRequest
=================
*/
void GAME_EXPORT NetAPI_CancelRequest( int context )
static void GAME_EXPORT NetAPI_CancelRequest( int context )
{
net_request_t *nr;
int i;
@ -3450,7 +3466,7 @@ NetAPI_AdrToString
=================
*/
const char *NetAPI_AdrToString( netadr_t *a )
static const char *NetAPI_AdrToString( netadr_t *a )
{
return NET_AdrToString( *a );
}
@ -3461,7 +3477,7 @@ NetAPI_CompareAdr
=================
*/
int GAME_EXPORT NetAPI_CompareAdr( netadr_t *a, netadr_t *b )
static int GAME_EXPORT NetAPI_CompareAdr( netadr_t *a, netadr_t *b )
{
return NET_CompareAdr( *a, *b );
}
@ -3472,7 +3488,7 @@ NetAPI_StringToAdr
=================
*/
int GAME_EXPORT NetAPI_StringToAdr( char *s, netadr_t *a )
static int GAME_EXPORT NetAPI_StringToAdr( char *s, netadr_t *a )
{
return NET_StringToAdr( s, a );
}
@ -3483,7 +3499,7 @@ NetAPI_ValueForKey
=================
*/
const char *NetAPI_ValueForKey( const char *s, const char *key )
static const char * GAME_EXPORT NetAPI_ValueForKey( const char *s, const char *key )
{
return Info_ValueForKey( s, key );
}
@ -3494,7 +3510,7 @@ NetAPI_RemoveKey
=================
*/
void GAME_EXPORT NetAPI_RemoveKey( char *s, const char *key )
static void GAME_EXPORT NetAPI_RemoveKey( char *s, const char *key )
{
Info_RemoveKey( s, key );
}
@ -3505,7 +3521,7 @@ NetAPI_SetValueForKey
=================
*/
void GAME_EXPORT NetAPI_SetValueForKey( char *s, const char *key, const char *value, int maxsize )
static void GAME_EXPORT NetAPI_SetValueForKey( char *s, const char *key, const char *value, int maxsize )
{
if( key[0] == '*' ) return;
Info_SetValueForStarKey( s, key, value, maxsize );
@ -3525,7 +3541,7 @@ Voice_StartVoiceTweakMode
=================
*/
int GAME_EXPORT Voice_StartVoiceTweakMode( void )
static int GAME_EXPORT Voice_StartVoiceTweakMode( void )
{
return 0;
}
@ -3536,7 +3552,7 @@ Voice_EndVoiceTweakMode
=================
*/
void GAME_EXPORT Voice_EndVoiceTweakMode( void )
static void GAME_EXPORT Voice_EndVoiceTweakMode( void )
{
}
@ -3546,7 +3562,7 @@ Voice_SetControlFloat
=================
*/
void GAME_EXPORT Voice_SetControlFloat( VoiceTweakControl iControl, float value )
static void GAME_EXPORT Voice_SetControlFloat( VoiceTweakControl iControl, float value )
{
}
@ -3556,7 +3572,7 @@ Voice_GetControlFloat
=================
*/
float GAME_EXPORT Voice_GetControlFloat( VoiceTweakControl iControl )
static float GAME_EXPORT Voice_GetControlFloat( VoiceTweakControl iControl )
{
return 1.0f;
}
@ -3874,13 +3890,13 @@ void CL_UnloadProgs( void )
Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
Cvar_FullSet( "host_clientloaded", "0", FCVAR_READ_ONLY );
Cvar_Unlink( FCVAR_CLIENTDLL );
Cmd_Unlink( CMD_CLIENTDLL );
COM_FreeLibrary( clgame.hInstance );
Mem_FreePool( &cls.mempool );
Mem_FreePool( &clgame.mempool );
memset( &clgame, 0, sizeof( clgame ));
Cvar_Unlink( FCVAR_CLIENTDLL );
Cmd_Unlink( CMD_CLIENTDLL );
}
qboolean CL_LoadProgs( const char *name )
@ -4038,7 +4054,7 @@ qboolean CL_LoadProgs( const char *name )
if( !Mobile_Init() ) // Xash3D FWGS extension: mobile interface
Con_Reportf( S_WARN "CL_LoadProgs: couldn't get mobility API\n" );
CL_InitEdicts (); // initailize local player and world
CL_InitEdicts( cl.maxclients ); // initailize local player and world
CL_InitClientMove(); // initialize pm_shared
// initialize game

View File

@ -643,6 +643,17 @@ static void GAME_EXPORT pfnFillRGBA( int x, int y, int width, int height, int r,
ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
}
/*
=============
pfnCvar_RegisterVariable
=============
*/
static cvar_t *GAME_EXPORT pfnCvar_RegisterGameUIVariable( const char *szName, const char *szValue, int flags )
{
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_GAMEUIDLL, Cvar_BuildAutoDescription( szName, flags|FCVAR_GAMEUIDLL ));
}
/*
=============
pfnClientCmd
@ -1220,12 +1231,12 @@ void UI_UnloadProgs( void )
Cvar_FullSet( "host_gameuiloaded", "0", FCVAR_READ_ONLY );
Cvar_Unlink( FCVAR_GAMEUIDLL );
Cmd_Unlink( CMD_GAMEUIDLL );
COM_FreeLibrary( gameui.hInstance );
Mem_FreePool( &gameui.mempool );
memset( &gameui, 0, sizeof( gameui ));
Cvar_Unlink( FCVAR_GAMEUIDLL );
Cmd_Unlink( CMD_GAMEUIDLL );
}
qboolean UI_LoadProgs( void )

View File

@ -23,7 +23,6 @@ GNU General Public License for more details.
#include "library.h"
#include "vid_common.h"
#include "pm_local.h"
#include "sequence.h"
#define MAX_TOTAL_CMDS 32
#define MAX_CMD_BUFFER 8000
@ -42,49 +41,52 @@ CVAR_DEFINE_AUTO( cl_logofile, "lambda", FCVAR_ARCHIVE, "player logo name" );
CVAR_DEFINE_AUTO( cl_logocolor, "orange", FCVAR_ARCHIVE, "player logo color" );
CVAR_DEFINE_AUTO( cl_logoext, "bmp", FCVAR_ARCHIVE, "temporary cvar to tell engine which logo must be packed" );
CVAR_DEFINE_AUTO( cl_test_bandwidth, "1", FCVAR_ARCHIVE, "test network bandwith before connection" );
convar_t *rcon_address;
convar_t *cl_timeout;
convar_t *cl_nopred;
convar_t *cl_nodelta;
convar_t *cl_crosshair;
convar_t *cl_cmdbackup;
convar_t *cl_showerror;
convar_t *cl_bmodelinterp;
convar_t *cl_draw_particles;
convar_t *cl_draw_tracers;
convar_t *cl_lightstyle_lerping;
convar_t *cl_idealpitchscale;
convar_t *cl_nosmooth;
convar_t *cl_smoothtime;
convar_t *cl_clockreset;
convar_t *cl_fixtimerate;
convar_t *hud_fontscale;
convar_t *hud_scale;
convar_t *cl_solid_players;
convar_t *cl_draw_beams;
convar_t *cl_updaterate;
convar_t *cl_showevents;
convar_t *cl_cmdrate;
convar_t *cl_interp;
convar_t *cl_nointerp;
convar_t *cl_dlmax;
convar_t *cl_upmax;
convar_t *cl_lw;
convar_t *cl_charset;
convar_t *cl_trace_messages;
convar_t *cl_nat;
convar_t *hud_utf8;
convar_t *ui_renderworld;
CVAR_DEFINE( cl_draw_particles, "r_drawparticles", "1", FCVAR_CHEAT, "render particles" );
CVAR_DEFINE( cl_draw_tracers, "r_drawtracers", "1", FCVAR_CHEAT, "render tracers" );
CVAR_DEFINE( cl_draw_beams, "r_drawbeams", "1", FCVAR_CHEAT, "render beams" );
static CVAR_DEFINE_AUTO( rcon_address, "", FCVAR_PRIVILEGED, "remote control address" );
CVAR_DEFINE_AUTO( cl_timeout, "60", 0, "connect timeout (in-seconds)" );
CVAR_DEFINE_AUTO( cl_nopred, "0", FCVAR_ARCHIVE|FCVAR_USERINFO, "disable client movement prediction" );
CVAR_DEFINE_AUTO( cl_nodelta, "0", 0, "disable delta-compression for server messages" );
CVAR_DEFINE( cl_crosshair, "crosshair", "1", FCVAR_ARCHIVE, "show weapon chrosshair" );
static CVAR_DEFINE_AUTO( cl_cmdbackup, "10", FCVAR_ARCHIVE, "how many additional history commands are sent" );
CVAR_DEFINE_AUTO( cl_showerror, "0", FCVAR_ARCHIVE, "show prediction error" );
CVAR_DEFINE_AUTO( cl_bmodelinterp, "1", FCVAR_ARCHIVE, "enable bmodel interpolation" );
CVAR_DEFINE_AUTO( cl_lightstyle_lerping, "0", FCVAR_ARCHIVE, "enables animated light lerping (perfomance option)" );
CVAR_DEFINE_AUTO( cl_idealpitchscale, "0.8", 0, "how much to look up/down slopes and stairs when not using freelook" );
CVAR_DEFINE_AUTO( cl_nosmooth, "0", FCVAR_ARCHIVE, "disable smooth up stair climbing" );
CVAR_DEFINE_AUTO( cl_smoothtime, "0.1", FCVAR_ARCHIVE, "time to smooth up" );
CVAR_DEFINE_AUTO( cl_clockreset, "0.1", FCVAR_ARCHIVE, "frametime delta maximum value before reset" );
CVAR_DEFINE_AUTO( cl_fixtimerate, "7.5", FCVAR_ARCHIVE, "time in msec to client clock adjusting" );
CVAR_DEFINE_AUTO( hud_fontscale, "1.0", FCVAR_ARCHIVE|FCVAR_LATCH, "scale hud font texture" );
CVAR_DEFINE_AUTO( hud_scale, "0", FCVAR_ARCHIVE|FCVAR_LATCH, "scale hud at current resolution" );
CVAR_DEFINE_AUTO( cl_solid_players, "1", 0, "Make all players not solid (can't traceline them)" );
CVAR_DEFINE_AUTO( cl_updaterate, "20", FCVAR_USERINFO|FCVAR_ARCHIVE, "refresh rate of server messages" );
CVAR_DEFINE_AUTO( cl_showevents, "0", FCVAR_ARCHIVE, "show events playback" );
CVAR_DEFINE_AUTO( cl_cmdrate, "60", FCVAR_ARCHIVE, "Max number of command packets sent to server per second" );
CVAR_DEFINE( cl_interp, "ex_interp", "0.1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "Interpolate object positions starting this many seconds in past" );
CVAR_DEFINE_AUTO( cl_nointerp, "0", FCVAR_CLIENTDLL, "disable interpolation of entities and players" );
static CVAR_DEFINE_AUTO( cl_dlmax, "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "max allowed outcoming fragment size" );
static CVAR_DEFINE_AUTO( cl_upmax, "1200", FCVAR_ARCHIVE, "max allowed incoming fragment size" );
CVAR_DEFINE_AUTO( cl_lw, "1", FCVAR_ARCHIVE|FCVAR_USERINFO, "enable client weapon predicting" );
CVAR_DEFINE_AUTO( cl_charset, "utf-8", FCVAR_ARCHIVE, "1-byte charset to use (iconv style)" );
CVAR_DEFINE_AUTO( cl_trace_messages, "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable message names tracing (good for developers)");
CVAR_DEFINE_AUTO( cl_trace_events, "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable events tracing (good for developers)");
static CVAR_DEFINE_AUTO( cl_nat, "0", 0, "show servers running under NAT" );
CVAR_DEFINE_AUTO( hud_utf8, "0", FCVAR_ARCHIVE, "Use utf-8 encoding for hud text" );
CVAR_DEFINE_AUTO( ui_renderworld, "0", FCVAR_ARCHIVE, "render world when UI is visible" );
//
// userinfo
//
convar_t *name;
convar_t *model;
convar_t *topcolor;
convar_t *bottomcolor;
convar_t *rate;
static CVAR_DEFINE_AUTO( name, "player", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_PRINTABLEONLY|FCVAR_FILTERABLE, "player name" );
static CVAR_DEFINE_AUTO( model, "", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player model ('player' is a singleplayer model)" );
static CVAR_DEFINE_AUTO( topcolor, "0", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player top color" );
static CVAR_DEFINE_AUTO( bottomcolor, "0", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player bottom color" );
CVAR_DEFINE_AUTO( rate, "3500", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player network rate" );
client_t cl;
client_static_t cls;
@ -203,7 +205,7 @@ int CL_GetFragmentSize( void *unused, fragsize_t mode )
if( Netchan_IsLocal( &cls.netchan ))
return FRAGMENT_LOCAL_SIZE;
return cl_upmax->value;
return cl_upmax.value;
}
/*
@ -230,9 +232,6 @@ void CL_SignonReply( void )
if( cl.proxy_redirect && !cls.spectator )
CL_Disconnect();
cl.proxy_redirect = false;
if( cls.demoplayback )
Sequence_OnLevelLoad( clgame.mapname );
break;
}
}
@ -262,10 +261,10 @@ static float CL_LerpPoint( void )
return 1.0f;
}
if( cl_interp->value <= 0.001 )
if( cl_interp.value <= 0.001 )
return 1.0f;
frac = ( cl.time - cl.mtime[0] ) / cl_interp->value;
frac = ( cl.time - cl.mtime[0] ) / cl_interp.value;
return frac;
}
@ -312,13 +311,13 @@ void CL_ComputeClientInterpolationAmount( usercmd_t *cmd )
float max_interp = MAX_EX_INTERP;
float interpolation_time;
if( cl_updaterate->value < MIN_UPDATERATE )
if( cl_updaterate.value < MIN_UPDATERATE )
{
Con_Printf( "cl_updaterate minimum is %f, resetting to default (20)\n", MIN_UPDATERATE );
Cvar_Reset( "cl_updaterate" );
}
if( cl_updaterate->value > MAX_UPDATERATE )
if( cl_updaterate.value > MAX_UPDATERATE )
{
Con_Printf( "cl_updaterate clamped at maximum (%f)\n", MAX_UPDATERATE );
Cvar_SetValue( "cl_updaterate", MAX_UPDATERATE );
@ -327,15 +326,15 @@ void CL_ComputeClientInterpolationAmount( usercmd_t *cmd )
if( cls.spectator )
max_interp = 0.2f;
min_interp = 1.0f / cl_updaterate->value;
interpolation_time = cl_interp->value * 1000.0;
min_interp = 1.0f / cl_updaterate.value;
interpolation_time = cl_interp.value * 1000.0;
if( (cl_interp->value + epsilon) < min_interp )
if( (cl_interp.value + epsilon) < min_interp )
{
Con_Printf( "ex_interp forced up to %.1f msec\n", min_interp * 1000.f );
Cvar_SetValue( "ex_interp", min_interp );
}
else if( (cl_interp->value - epsilon) > max_interp )
else if( (cl_interp.value - epsilon) > max_interp )
{
Con_Printf( "ex_interp forced down to %.1f msec\n", max_interp * 1000.f );
Cvar_SetValue( "ex_interp", max_interp );
@ -480,7 +479,7 @@ qboolean CL_ProcessShowTexturesCmds( usercmd_t *cmd )
int changed;
int pressed, released;
if( !gl_showtextures->value || CL_IsDevOverviewMode( ))
if( !r_showtextures.value || CL_IsDevOverviewMode( ))
return false;
changed = (oldbuttons ^ cmd->buttons);
@ -488,9 +487,9 @@ qboolean CL_ProcessShowTexturesCmds( usercmd_t *cmd )
released = changed & (~cmd->buttons);
if( released & ( IN_RIGHT|IN_MOVERIGHT ))
Cvar_SetValue( "r_showtextures", gl_showtextures->value + 1 );
Cvar_SetValue( "r_showtextures", r_showtextures.value + 1 );
if( released & ( IN_LEFT|IN_MOVELEFT ))
Cvar_SetValue( "r_showtextures", Q_max( 1, gl_showtextures->value - 1 ));
Cvar_SetValue( "r_showtextures", Q_max( 1, r_showtextures.value - 1 ));
oldbuttons = cmd->buttons;
return true;
@ -511,7 +510,7 @@ qboolean CL_ProcessOverviewCmds( usercmd_t *cmd )
float step = (2.0f / size) * host.realframetime;
float step2 = step * 100.0f * (2.0f / ov->flZoom);
if( !CL_IsDevOverviewMode() || gl_showtextures->value )
if( !CL_IsDevOverviewMode() || r_showtextures.value )
return false;
if( ov->flZoom < 0.0f ) sign = -1;
@ -707,24 +706,24 @@ void CL_WritePacket( void )
MSG_Init( &buf, "ClientData", data, sizeof( data ));
// Determine number of backup commands to send along
numbackup = bound( 0, cl_cmdbackup->value, cls.legacymode ? MAX_LEGACY_BACKUP_CMDS : MAX_BACKUP_COMMANDS );
numbackup = bound( 0, cl_cmdbackup.value, cls.legacymode ? MAX_LEGACY_BACKUP_CMDS : MAX_BACKUP_COMMANDS );
if( cls.state == ca_connected ) numbackup = 0;
// clamp cmdrate
if( cl_cmdrate->value < 10.0f )
if( cl_cmdrate.value < 10.0f )
{
Cvar_SetValue( "cl_cmdrate", 10.0f );
Cvar_DirectSet( &cl_cmdrate, "10" );
}
else if( cl_cmdrate->value > 100.0f )
else if( cl_cmdrate.value > 100.0f )
{
Cvar_SetValue( "cl_cmdrate", 100.0f );
Cvar_DirectSet( &cl_cmdrate, "100" );
}
// Check to see if we can actually send this command
// In single player, send commands as fast as possible
// Otherwise, only send when ready and when not choking bandwidth
if( cl.maxclients == 1 || ( NET_IsLocalAddress( cls.netchan.remote_address ) && !host_limitlocal->value ))
if( cl.maxclients == 1 || ( NET_IsLocalAddress( cls.netchan.remote_address ) && !host_limitlocal.value ))
send_command = true;
if(( host.realtime >= cls.nextcmdtime ) && Netchan_CanPacket( &cls.netchan, true ))
@ -748,20 +747,20 @@ void CL_WritePacket( void )
if(( host.realtime - cls.netchan.last_received ) > CONNECTION_PROBLEM_TIME )
{
Con_NPrintf( 1, "^3Warning:^1 Connection Problem^7\n" );
Con_NPrintf( 2, "^1Auto-disconnect in %.1f seconds^7", cl_timeout->value - ( host.realtime - cls.netchan.last_received ));
Con_NPrintf( 2, "^1Auto-disconnect in %.1f seconds^7", cl_timeout.value - ( host.realtime - cls.netchan.last_received ));
cl.validsequence = 0;
}
}
if( cl_nodelta->value )
if( cl_nodelta.value )
cl.validsequence = 0;
if( send_command )
{
int outgoing_sequence;
if( cl_cmdrate->value > 0 ) // clamped between 10 and 100 fps
cls.nextcmdtime = host.realtime + bound( 0.1f, ( 1.0f / cl_cmdrate->value ), 0.01f );
if( cl_cmdrate.value > 0 ) // clamped between 10 and 100 fps
cls.nextcmdtime = host.realtime + bound( 0.1f, ( 1.0f / cl_cmdrate.value ), 0.01f );
else cls.nextcmdtime = host.realtime; // always able to send right away
if( cls.lastoutgoingcommand == -1 )
@ -1033,10 +1032,10 @@ void CL_SendConnectPacket( void )
if( cls.legacymode )
{
// set related userinfo keys
if( cl_dlmax->value >= 40000 || cl_dlmax->value < 100 )
if( cl_dlmax.value >= 40000 || cl_dlmax.value < 100 )
Info_SetValueForKey( cls.userinfo, "cl_maxpacket", "1400", sizeof( cls.userinfo ) );
else
Info_SetValueForKey( cls.userinfo, "cl_maxpacket", cl_dlmax->string, sizeof( cls.userinfo ) );
Info_SetValueForKey( cls.userinfo, "cl_maxpacket", cl_dlmax.string, sizeof( cls.userinfo ) );
if( !*Info_ValueForKey( cls.userinfo,"cl_maxpayload") )
Info_SetValueForKey( cls.userinfo, "cl_maxpayload", "1000", sizeof( cls.userinfo ) );
@ -1051,7 +1050,7 @@ void CL_SendConnectPacket( void )
{
int extensions = NET_EXT_SPLITSIZE;
if( cl_dlmax->value > FRAGMENT_MAX_SIZE || cl_dlmax->value < FRAGMENT_MIN_SIZE )
if( cl_dlmax.value > FRAGMENT_MAX_SIZE || cl_dlmax.value < FRAGMENT_MIN_SIZE )
Cvar_SetValue( "cl_dlmax", FRAGMENT_DEFAULT_SIZE );
Info_RemoveKey( cls.userinfo, "cl_maxpacket" );
@ -1246,7 +1245,7 @@ void CL_Connect_f( void )
// if running a local server, kill it and reissue
if( SV_Active( )) Host_ShutdownServer();
NET_Config( true, !CVAR_TO_BOOL( cl_nat )); // allow remote
NET_Config( true, !cl_nat.value ); // allow remote
Con_Printf( "server %s\n", server );
CL_Disconnect();
@ -1311,13 +1310,13 @@ void CL_Rcon_f( void )
}
else
{
if( !COM_CheckString( rcon_address->string ))
if( !COM_CheckString( rcon_address.string ))
{
Con_Printf( "You must either be connected or set the 'rcon_address' cvar to issue rcon commands\n" );
return;
}
NET_StringToAdr( rcon_address->string, &to );
NET_StringToAdr( rcon_address.string, &to );
if( to.port == 0 ) to.port = MSG_BigShort( PORT_SERVER );
}
@ -1410,12 +1409,12 @@ int CL_GetSplitSize( void )
if( !(cls.extensions & NET_EXT_SPLITSIZE) )
return 1400;
splitsize = cl_dlmax->value;
splitsize = cl_dlmax.value;
if( splitsize < FRAGMENT_MIN_SIZE || splitsize > FRAGMENT_MAX_SIZE )
Cvar_SetValue( "cl_dlmax", FRAGMENT_DEFAULT_SIZE );
return cl_dlmax->value;
return cl_dlmax.value;
}
/*
@ -1439,7 +1438,7 @@ void CL_Reconnect( qboolean setup_netchan )
{
// only enable incoming split for legacy mode
cls.netchan.split = true;
Con_Reportf( "^2NET_EXT_SPLIT enabled^7 (packet sizes is %d/%d)\n", (int)cl_dlmax->value, 65536 );
Con_Reportf( "^2NET_EXT_SPLIT enabled^7 (packet sizes is %d/%d)\n", (int)cl_dlmax.value, 65536 );
}
}
else
@ -1448,7 +1447,7 @@ void CL_Reconnect( qboolean setup_netchan )
if( cls.extensions & NET_EXT_SPLITSIZE )
{
Con_Reportf( "^2NET_EXT_SPLITSIZE enabled^7 (packet size is %d)\n", (int)cl_dlmax->value );
Con_Reportf( "^2NET_EXT_SPLITSIZE enabled^7 (packet size is %d)\n", (int)cl_dlmax.value );
}
}
@ -1556,6 +1555,8 @@ void CL_LocalServers_f( void )
{
netadr_t adr;
memset( &adr, 0, sizeof( adr ));
Con_Printf( "Scanning for servers on the local network area...\n" );
NET_Config( true, true ); // allow remote
@ -1588,7 +1589,9 @@ size_t CL_BuildMasterServerScanRequest( char *buf, size_t size, qboolean nat )
info[0] = 0;
#ifndef XASH_ALL_SERVERS
Info_SetValueForKey( info, "gamedir", GI->gamefolder, remaining );
#endif
Info_SetValueForKey( info, "clver", XASH_VERSION, remaining ); // let master know about client version
Info_SetValueForKey( info, "nat", nat ? "1" : "0", remaining );
@ -1604,7 +1607,7 @@ void CL_InternetServers_f( void )
{
char fullquery[512];
size_t len;
qboolean nat = cl_nat->value != 0.0f;
qboolean nat = cl_nat.value != 0.0f;
len = CL_BuildMasterServerScanRequest( fullquery, sizeof( fullquery ), nat );
@ -1990,6 +1993,11 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
int realsize;
dword crcValue2 = 0;
// this message only used during connection
// it doesn't make sense after client_connect
if( cls.state != ca_connecting )
return;
if( !CL_IsFromConnectingServer( from ))
return;
@ -2053,6 +2061,11 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
}
else if( !Q_strcmp( c, "challenge" ))
{
// this message only used during connection
// it doesn't make sense after client_connect
if( cls.state != ca_connecting )
return;
if( !CL_IsFromConnectingServer( from ))
return;
@ -2071,6 +2084,11 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
}
else if( !Q_strcmp( c, "disconnect" ))
{
// this message only used during connection
// it doesn't make sense after client_connect
if( cls.state != ca_connecting )
return;
if( !CL_IsFromConnectingServer( from ))
return;
@ -2365,7 +2383,7 @@ void CL_ReadPackets( void )
// check timeout
if( cls.state >= ca_connected && cls.state != ca_cinematic && !cls.demoplayback )
{
if( host.realtime - cls.netchan.last_received > cl_timeout->value )
if( host.realtime - cls.netchan.last_received > cl_timeout.value )
{
Con_Printf( "\nServer connection timed out.\n" );
CL_Disconnect();
@ -2859,55 +2877,57 @@ void CL_InitLocal( void )
VGui_RegisterCvars();
// register our variables
cl_crosshair = Cvar_Get( "crosshair", "1", FCVAR_ARCHIVE, "show weapon chrosshair" );
cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0, "disable delta-compression for server messages" );
cl_idealpitchscale = Cvar_Get( "cl_idealpitchscale", "0.8", 0, "how much to look up/down slopes and stairs when not using freelook" );
cl_solid_players = Cvar_Get( "cl_solid_players", "1", 0, "Make all players not solid (can't traceline them)" );
cl_interp = Cvar_Get( "ex_interp", "0.1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "Interpolate object positions starting this many seconds in past" );
cl_timeout = Cvar_Get( "cl_timeout", "60", 0, "connect timeout (in-seconds)" );
cl_charset = Cvar_Get( "cl_charset", "utf-8", FCVAR_ARCHIVE, "1-byte charset to use (iconv style)" );
hud_utf8 = Cvar_Get( "hud_utf8", "0", FCVAR_ARCHIVE, "Use utf-8 encoding for hud text" );
Cvar_RegisterVariable( &cl_crosshair );
Cvar_RegisterVariable( &cl_nodelta );
Cvar_RegisterVariable( &cl_idealpitchscale );
Cvar_RegisterVariable( &cl_solid_players );
Cvar_RegisterVariable( &cl_interp );
Cvar_RegisterVariable( &cl_timeout );
Cvar_RegisterVariable( &cl_charset );
Cvar_RegisterVariable( &hud_utf8 );
rcon_address = Cvar_Get( "rcon_address", "", FCVAR_PRIVILEGED, "remote control address" );
Cvar_RegisterVariable( &rcon_address );
cl_trace_messages = Cvar_Get( "cl_trace_messages", "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable message names tracing (good for developers)");
Cvar_RegisterVariable( &cl_trace_messages );
Cvar_RegisterVariable( &cl_trace_events );
// userinfo
cl_nopred = Cvar_Get( "cl_nopred", "0", FCVAR_ARCHIVE|FCVAR_USERINFO, "disable client movement prediction" );
name = Cvar_Get( "name", Sys_GetCurrentUser(), FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_PRINTABLEONLY, "player name" );
model = Cvar_Get( "model", "", FCVAR_USERINFO|FCVAR_ARCHIVE, "player model ('player' is a singleplayer model)" );
cl_updaterate = Cvar_Get( "cl_updaterate", "20", FCVAR_USERINFO|FCVAR_ARCHIVE, "refresh rate of server messages" );
cl_dlmax = Cvar_Get( "cl_dlmax", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "max allowed outcoming fragment size" );
cl_upmax = Cvar_Get( "cl_upmax", "1200", FCVAR_ARCHIVE, "max allowed incoming fragment size" );
cl_nat = Cvar_Get( "cl_nat", "0", 0, "show servers running under NAT" );
rate = Cvar_Get( "rate", "3500", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player network rate" );
topcolor = Cvar_Get( "topcolor", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "player top color" );
bottomcolor = Cvar_Get( "bottomcolor", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "player bottom color" );
cl_lw = Cvar_Get( "cl_lw", "1", FCVAR_ARCHIVE|FCVAR_USERINFO, "enable client weapon predicting" );
Cvar_RegisterVariable( &cl_nopred );
Cvar_RegisterVariable( &name );
Cvar_DirectSet( &name, Sys_GetCurrentUser( ));
Cvar_RegisterVariable( &model );
Cvar_RegisterVariable( &cl_updaterate );
Cvar_RegisterVariable( &cl_dlmax );
Cvar_RegisterVariable( &cl_upmax );
Cvar_RegisterVariable( &cl_nat );
Cvar_RegisterVariable( &rate );
Cvar_RegisterVariable( &topcolor );
Cvar_RegisterVariable( &bottomcolor );
Cvar_RegisterVariable( &cl_lw );
Cvar_Get( "cl_lc", "1", FCVAR_ARCHIVE|FCVAR_USERINFO, "enable lag compensation" );
Cvar_Get( "password", "", FCVAR_USERINFO, "server password" );
Cvar_Get( "team", "", FCVAR_USERINFO, "player team" );
Cvar_Get( "skin", "", FCVAR_USERINFO, "player skin" );
cl_nosmooth = Cvar_Get( "cl_nosmooth", "0", FCVAR_ARCHIVE, "disable smooth up stair climbing" );
cl_nointerp = Cvar_Get( "cl_nointerp", "0", FCVAR_CLIENTDLL, "disable interpolation of entities and players" );
cl_smoothtime = Cvar_Get( "cl_smoothtime", "0.1", FCVAR_ARCHIVE, "time to smooth up" );
cl_cmdbackup = Cvar_Get( "cl_cmdbackup", "10", FCVAR_ARCHIVE, "how many additional history commands are sent" );
cl_cmdrate = Cvar_Get( "cl_cmdrate", "60", FCVAR_ARCHIVE, "Max number of command packets sent to server per second" );
cl_draw_particles = Cvar_Get( "r_drawparticles", "1", FCVAR_CHEAT, "render particles" );
cl_draw_tracers = Cvar_Get( "r_drawtracers", "1", FCVAR_CHEAT, "render tracers" );
cl_draw_beams = Cvar_Get( "r_drawbeams", "1", FCVAR_CHEAT, "render beams" );
cl_lightstyle_lerping = Cvar_Get( "cl_lightstyle_lerping", "0", FCVAR_ARCHIVE, "enables animated light lerping (perfomance option)" );
cl_showerror = Cvar_Get( "cl_showerror", "0", FCVAR_ARCHIVE, "show prediction error" );
cl_bmodelinterp = Cvar_Get( "cl_bmodelinterp", "1", FCVAR_ARCHIVE, "enable bmodel interpolation" );
cl_clockreset = Cvar_Get( "cl_clockreset", "0.1", FCVAR_ARCHIVE, "frametime delta maximum value before reset" );
cl_fixtimerate = Cvar_Get( "cl_fixtimerate", "7.5", FCVAR_ARCHIVE, "time in msec to client clock adjusting" );
hud_fontscale = Cvar_Get( "hud_fontscale", "1.0", FCVAR_ARCHIVE|FCVAR_LATCH, "scale hud font texture" );
hud_scale = Cvar_Get( "hud_scale", "0", FCVAR_ARCHIVE|FCVAR_LATCH, "scale hud at current resolution" );
Cvar_RegisterVariable( &cl_nosmooth );
Cvar_RegisterVariable( &cl_nointerp );
Cvar_RegisterVariable( &cl_smoothtime );
Cvar_RegisterVariable( &cl_cmdbackup );
Cvar_RegisterVariable( &cl_cmdrate );
Cvar_RegisterVariable( &cl_draw_particles );
Cvar_RegisterVariable( &cl_draw_tracers );
Cvar_RegisterVariable( &cl_draw_beams );
Cvar_RegisterVariable( &cl_lightstyle_lerping );
Cvar_RegisterVariable( &cl_showerror );
Cvar_RegisterVariable( &cl_bmodelinterp );
Cvar_RegisterVariable( &cl_clockreset );
Cvar_RegisterVariable( &cl_fixtimerate );
Cvar_RegisterVariable( &hud_fontscale );
Cvar_RegisterVariable( &hud_scale );
Cvar_Get( "cl_background", "0", FCVAR_READ_ONLY, "indicate what background map is running" );
cl_showevents = Cvar_Get( "cl_showevents", "0", FCVAR_ARCHIVE, "show events playback" );
Cvar_RegisterVariable( &cl_showevents );
Cvar_Get( "lastdemo", "", FCVAR_ARCHIVE, "last played demo" );
ui_renderworld = Cvar_Get( "ui_renderworld", "0", FCVAR_ARCHIVE, "render world when UI is visible" );
Cvar_RegisterVariable( &ui_renderworld );
// these two added to shut up CS 1.5 about 'unknown' commands
Cvar_Get( "lightgamma", "1", FCVAR_ARCHIVE, "ambient lighting level (legacy, unused)" );
@ -2987,10 +3007,10 @@ to smooth lag effect
*/
void CL_AdjustClock( void )
{
if( cl.timedelta == 0.0f || !cl_fixtimerate->value )
if( cl.timedelta == 0.0f || !cl_fixtimerate.value )
return;
if( cl_fixtimerate->value < 0.0f )
if( cl_fixtimerate.value < 0.0f )
Cvar_SetValue( "cl_fixtimerate", 7.5f );
if( fabs( cl.timedelta ) >= 0.001f )
@ -3000,7 +3020,7 @@ void CL_AdjustClock( void )
msec = ( cl.timedelta * 1000.0 );
sign = ( msec < 0 ) ? 1.0 : -1.0;
msec = Q_min( cl_fixtimerate->value, fabs( msec ));
msec = Q_min( cl_fixtimerate.value, fabs( msec ));
adjust = sign * ( msec / 1000.0 );
if( fabs( adjust ) < fabs( cl.timedelta ))
@ -3118,7 +3138,6 @@ void CL_Init( void )
VID_Init(); // init video
S_Init(); // init sound
Voice_Init( VOICE_DEFAULT_CODEC, 3 ); // init voice
Sequence_Init();
// unreliable buffer. unsed for unreliable commands and voice stream
MSG_Init( &cls.datagram, "cls.datagram", cls.datagram_buf, sizeof( cls.datagram_buf ));
@ -3163,10 +3182,11 @@ void CL_Shutdown( void )
cls.initialized = false;
// for client-side VGUI support we use other order
if( !GI->internal_vgui_support )
if( FI && FI->GameInfo && !FI->GameInfo->internal_vgui_support )
VGui_Shutdown();
FS_Delete( "demoheader.tmp" ); // remove tmp file
if( g_fsapi.Delete )
g_fsapi.Delete( "demoheader.tmp" ); // remove tmp file
SCR_FreeCinematic (); // release AVI's *after* client.dll because custom renderer may use them
S_Shutdown ();
R_Shutdown ();

View File

@ -20,17 +20,17 @@ GNU General Public License for more details.
#include "input.h"
#include "platform/platform.h"
mobile_engfuncs_t *gMobileEngfuncs;
static mobile_engfuncs_t *gMobileEngfuncs;
convar_t *vibration_length;
convar_t *vibration_enable;
static CVAR_DEFINE_AUTO( vibration_length, "1.0", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "vibration length" );
static CVAR_DEFINE_AUTO( vibration_enable, "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "enable vibration" );
static cl_font_t g_scaled_font;
static float g_font_scale;
static void pfnVibrate( float life, char flags )
{
if( !vibration_enable->value )
if( !vibration_enable.value )
return;
if( life < 0.0f )
@ -42,7 +42,7 @@ static void pfnVibrate( float life, char flags )
//Con_Reportf( "Vibrate: %f %d\n", life, flags );
// here goes platform-specific backends
Platform_Vibrate( life * vibration_length->value, flags );
Platform_Vibrate( life * vibration_length.value, flags );
}
static void Vibrate_f( void )
@ -67,7 +67,7 @@ static int pfnDrawScaledCharacter( int x, int y, int number, int r, int g, int b
rgba_t color = { r, g, b, 255 };
int flags = FONT_DRAW_HUD;
if( hud_utf8->value )
if( hud_utf8.value )
SetBits( flags, FONT_DRAW_UTF8 );
if( fabs( g_font_scale - scale ) > 0.1f ||
@ -142,8 +142,8 @@ qboolean Mobile_Init( void )
success = true;
Cmd_AddCommand( "vibrate", (xcommand_t)Vibrate_f, "Vibrate for specified time");
vibration_length = Cvar_Get( "vibration_length", "1.0", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "Vibration length");
vibration_enable = Cvar_Get( "vibration_enable", "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "Enable vibration");
Cvar_RegisterVariable( &vibration_length );
Cvar_RegisterVariable( &vibration_enable );
return success;
}

View File

@ -33,12 +33,12 @@ GNU General Public License for more details.
#define NETGRAPH_NET_COLORS 5
#define NUM_LATENCY_SAMPLES 8
convar_t *net_graph;
static convar_t *net_graphpos;
static convar_t *net_graphwidth;
static convar_t *net_graphheight;
static convar_t *net_graphsolid;
static convar_t *net_scale;
CVAR_DEFINE_AUTO( net_graph, "0", FCVAR_ARCHIVE, "draw network usage graph" );
static CVAR_DEFINE_AUTO( net_graphpos, "1", FCVAR_ARCHIVE, "network usage graph position" );
static CVAR_DEFINE_AUTO( net_scale, "5", FCVAR_ARCHIVE, "network usage graph scale level" );
static CVAR_DEFINE_AUTO( net_graphwidth, "192", FCVAR_ARCHIVE, "network usage graph width" );
static CVAR_DEFINE_AUTO( net_graphheight, "64", FCVAR_ARCHIVE, "network usage graph height" );
static CVAR_DEFINE_AUTO( net_graphsolid, "1", FCVAR_ARCHIVE, "fill segments in network usage graph" );
static struct packet_latency_t
{
@ -211,7 +211,7 @@ static void NetGraph_GetFrameData( float *latency, int *latency_count )
else
{
int frame_latency = Q_min( 1.0f, f->latency );
p->latency = (( frame_latency + 0.1f ) / 1.1f ) * ( net_graphheight->value - NETGRAPH_LERP_HEIGHT - 2 );
p->latency = (( frame_latency + 0.1f ) / 1.1f ) * ( net_graphheight.value - NETGRAPH_LERP_HEIGHT - 2 );
if( i > cls.netchan.incoming_sequence - NUM_LATENCY_SAMPLES )
{
@ -260,7 +260,7 @@ static void NetGraph_DrawTimes( wrect_t rect, int x, int w )
for( a = 0; a < w; a++ )
{
i = ( cls.netchan.outgoing_sequence - a ) & NET_TIMINGS_MASK;
h = Q_min(( netstat_cmdinfo[i].cmd_lerp / 3.0f ) * NETGRAPH_LERP_HEIGHT, net_graphheight->value * 0.7f);
h = Q_min(( netstat_cmdinfo[i].cmd_lerp / 3.0f ) * NETGRAPH_LERP_HEIGHT, net_graphheight.value * 0.7f);
fill.left = x + w - a - 1;
fill.right = fill.bottom = 1;
@ -273,7 +273,7 @@ static void NetGraph_DrawTimes( wrect_t rect, int x, int w )
h -= extrap_point;
fill.top -= extrap_point;
if( !net_graphsolid->value )
if( !net_graphsolid.value )
{
fill.top -= (h - 1);
start = (h - 1);
@ -295,7 +295,7 @@ static void NetGraph_DrawTimes( wrect_t rect, int x, int w )
fill.top -= h;
h = extrap_point - h;
if( !net_graphsolid->value )
if( !net_graphsolid.value )
h = 1;
for( j = 0; j < h; j++ )
@ -334,7 +334,7 @@ NetGraph_DrawHatches
*/
static void NetGraph_DrawHatches( int x, int y )
{
int ystep = (int)( 10.0f / net_scale->value );
int ystep = (int)( 10.0f / net_scale.value );
byte colorminor[4] = { 0, 63, 63, 200 };
byte color[4] = { 0, 200, 0, 255 };
wrect_t hatch = { x, 4, y, 1 };
@ -342,9 +342,9 @@ static void NetGraph_DrawHatches( int x, int y )
ystep = Q_max( ystep, 1 );
for( starty = hatch.top; hatch.top > 0 && ((starty - hatch.top) * net_scale->value < (maxmsgbytes + 50)); hatch.top -= ystep )
for( starty = hatch.top; hatch.top > 0 && ((starty - hatch.top) * net_scale.value < (maxmsgbytes + 50)); hatch.top -= ystep )
{
if(!((int)((starty - hatch.top) * net_scale->value ) % 50 ))
if(!((int)((starty - hatch.top) * net_scale.value ) % 50 ))
{
NetGraph_DrawRect( &hatch, color );
}
@ -370,14 +370,14 @@ static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int coun
int pty = Q_max( rect.top + rect.bottom - NETGRAPH_LERP_HEIGHT - 3, 1 );
int out, i = ( cls.netchan.outgoing_sequence - 1 ) & NET_TIMINGS_MASK;
int j = cls.netchan.incoming_sequence & NET_TIMINGS_MASK;
int last_y = y - net_graphheight->value;
int last_y = y - net_graphheight.value;
if( count > 0 )
{
avg = avg / (float)( count - ( host.frametime * FRAMERATE_AVG_FRAC ));
if( cl_updaterate->value > 0.0f )
avg -= 1000.0f / cl_updaterate->value;
if( cl_updaterate.value > 0.0f )
avg -= 1000.0f / cl_updaterate.value;
// can't be below zero
avg = Q_max( 0.0f, avg );
@ -391,7 +391,7 @@ static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int coun
if( framerate > 0.0f )
{
y -= net_graphheight->value;
y -= net_graphheight.value;
CL_DrawStringf( font, x, y, colors, FONT_DRAW_NORENDERMODE, "%.1f fps" , 1.0f / framerate);
@ -422,9 +422,9 @@ static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int coun
}
if( graphtype < 3 )
CL_DrawStringf( font, ptx, pty, colors, FONT_DRAW_NORENDERMODE, "%i/s", (int)cl_cmdrate->value );
CL_DrawStringf( font, ptx, pty, colors, FONT_DRAW_NORENDERMODE, "%i/s", (int)cl_cmdrate.value );
CL_DrawStringf( font, ptx, last_y, colors, FONT_DRAW_NORENDERMODE, "%i/s" , (int)cl_updaterate->value );
CL_DrawStringf( font, ptx, last_y, colors, FONT_DRAW_NORENDERMODE, "%i/s" , (int)cl_updaterate.value );
}
/*
@ -435,12 +435,12 @@ NetGraph_DrawDataSegment
*/
static int NetGraph_DrawDataSegment( wrect_t *fill, int bytes, byte r, byte g, byte b, byte a )
{
float h = bytes / net_scale->value;
float h = bytes / net_scale.value;
byte colors[4] = { r, g, b, a };
fill->top -= (int)h;
if( net_graphsolid->value )
if( net_graphsolid.value )
fill->bottom = (int)h;
else fill->bottom = 1;
@ -498,7 +498,7 @@ NetGraph_DrawDataUsage
static void NetGraph_DrawDataUsage( int x, int y, int w, int graphtype )
{
int a, i, h, lastvalidh = 0, ping;
int pingheight = net_graphheight->value - NETGRAPH_LERP_HEIGHT - 2;
int pingheight = net_graphheight.value - NETGRAPH_LERP_HEIGHT - 2;
wrect_t fill = { 0 };
byte color[4];
@ -554,7 +554,7 @@ static void NetGraph_DrawDataUsage( int x, int y, int w, int graphtype )
continue;
color[0] = color[1] = color[2] = color[3] = 255;
fill.top = y - net_graphheight->value - 1;
fill.top = y - net_graphheight.value - 1;
fill.bottom = 1;
if( NetGraph_AtEdge( a, w ))
@ -589,7 +589,7 @@ static void NetGraph_DrawDataUsage( int x, int y, int w, int graphtype )
if( !NetGraph_DrawDataSegment( &fill, netstat_graph[i].voicebytes, 255, 255, 255, 255 ))
continue;
fill.top = y - net_graphheight->value - 1;
fill.top = y - net_graphheight.value - 1;
fill.bottom = 1;
fill.top -= 2;
@ -598,7 +598,7 @@ static void NetGraph_DrawDataUsage( int x, int y, int w, int graphtype )
}
if( graphtype >= 2 )
NetGraph_DrawHatches( x, y - net_graphheight->value - 1 );
NetGraph_DrawHatches( x, y - net_graphheight.value - 1 );
}
/*
@ -613,12 +613,12 @@ static void NetGraph_GetScreenPos( wrect_t *rect, int *w, int *x, int *y )
rect->right = refState.width;
rect->bottom = refState.height;
*w = Q_min( NET_TIMINGS, net_graphwidth->value );
*w = Q_min( NET_TIMINGS, net_graphwidth.value );
if( rect->right < *w + 10 )
*w = rect->right - 10;
// detect x and y position
switch( (int)net_graphpos->value )
switch( (int)net_graphpos.value )
{
case 1: // right sided
*x = rect->left + rect->right - 5 - *w;
@ -661,16 +661,16 @@ void SCR_DrawNetGraph( void )
{
graphtype = 2;
}
else if( net_graph->value != 0.0f )
else if( net_graph.value != 0.0f )
{
graphtype = (int)net_graph->value;
graphtype = (int)net_graph.value;
}
else
{
return;
}
if( net_scale->value <= 0 )
if( net_scale.value <= 0 )
Cvar_SetValue( "net_scale", 0.1f );
NetGraph_GetScreenPos( &rect, &w, &x, &y );
@ -697,12 +697,12 @@ void SCR_DrawNetGraph( void )
void CL_InitNetgraph( void )
{
net_graph = Cvar_Get( "net_graph", "0", FCVAR_ARCHIVE, "draw network usage graph" );
net_graphpos = Cvar_Get( "net_graphpos", "1", FCVAR_ARCHIVE, "network usage graph position" );
net_scale = Cvar_Get( "net_scale", "5", FCVAR_ARCHIVE, "network usage graph scale level" );
net_graphwidth = Cvar_Get( "net_graphwidth", "192", FCVAR_ARCHIVE, "network usage graph width" );
net_graphheight = Cvar_Get( "net_graphheight", "64", FCVAR_ARCHIVE, "network usage graph height" );
net_graphsolid = Cvar_Get( "net_graphsolid", "1", FCVAR_ARCHIVE, "fill segments in network usage graph" );
Cvar_RegisterVariable( &net_graph );
Cvar_RegisterVariable( &net_graphpos );
Cvar_RegisterVariable( &net_scale );
Cvar_RegisterVariable( &net_graphwidth );
Cvar_RegisterVariable( &net_graphheight );
Cvar_RegisterVariable( &net_graphsolid );
packet_loss = packet_choke = 0.0;
NetGraph_InitColors();

View File

@ -21,6 +21,7 @@ GNU General Public License for more details.
#include "shake.h"
#include "hltv.h"
#include "input.h"
#include "server.h"
#if XASH_LOW_MEMORY != 2
int CL_UPDATE_BACKUP = SINGLEPLAYER_BACKUP;
#endif
@ -196,7 +197,7 @@ void CL_ParseServerTime( sizebuf_t *msg )
dt = cl.time - cl.mtime[0];
if( fabs( dt ) > cl_clockreset->value ) // 0.1 by default
if( fabs( dt ) > cl_clockreset.value ) // 0.1 by default
{
cl.time = cl.mtime[0];
cl.timedelta = 0.0f;
@ -848,8 +849,10 @@ CL_ParseServerData
void CL_ParseServerData( sizebuf_t *msg, qboolean legacy )
{
char gamefolder[MAX_QPATH];
string mapfile;
qboolean background;
int i;
uint32_t mapCRC;
HPAK_CheckSize( CUSTOM_RES_PATH );
@ -912,6 +915,18 @@ void CL_ParseServerData( sizebuf_t *msg, qboolean legacy )
}
}
Q_snprintf( mapfile, sizeof( mapfile ), "maps/%s.bsp", clgame.mapname );
if( CRC32_MapFile( &mapCRC, mapfile, cl.maxclients > 1 ))
{
// validate map checksum
if( mapCRC != cl.checksum )
{
Con_Printf( S_ERROR "Your map [%s] differs from the server's.\n", clgame.mapname );
CL_Disconnect_f(); // for local game, call EndGame
Host_AbortCurrentFrame(); // to avoid svc_bad
}
}
if( clgame.maxModels > MAX_MODELS )
Con_Printf( S_WARN "server model limit is above client model limit %i > %i\n", clgame.maxModels, MAX_MODELS );
@ -931,10 +946,10 @@ void CL_ParseServerData( sizebuf_t *msg, qboolean legacy )
// loading user settings
CSCR_LoadDefaultCVars( "user.scr" );
if( r_decals->value > mp_decals.value )
Cvar_SetValue( "r_decals", mp_decals.value );
if( r_decals.value > mp_decals.value )
Cvar_DirectSet( &r_decals, mp_decals.string );
}
else Cvar_Reset( "r_decals" );
else Cvar_DirectSet( &r_decals, NULL );
// set the background state
if( cls.demoplayback && ( cls.demonum != -1 ))
@ -966,7 +981,7 @@ void CL_ParseServerData( sizebuf_t *msg, qboolean legacy )
Q_strncpy( gameui.globals->maptitle, clgame.maptitle, sizeof( gameui.globals->maptitle ));
if( !cls.changelevel && !cls.changedemo )
CL_InitEdicts (); // re-arrange edicts
CL_InitEdicts( cl.maxclients ); // re-arrange edicts
// get splash name
if( cls.demoplayback && ( cls.demonum != -1 ))
@ -974,9 +989,9 @@ void CL_ParseServerData( sizebuf_t *msg, qboolean legacy )
else Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, refState.wideScreen ? "16x9" : "4x3" ));
Cvar_SetValue( "scr_loading", 0.0f ); // reset progress bar
if(( cl_allow_levelshots->value && !cls.changelevel ) || cl.background )
if(( cl_allow_levelshots.value && !cls.changelevel ) || cl.background )
{
if( !FS_FileExists( va( "%s.bmp", cl_levelshot_name->string ), true ))
if( !FS_FileExists( va( "%s.bmp", cl_levelshot_name.string ), true ))
Cvar_Set( "cl_levelshot_name", "*black" ); // render a black screen
cls.scrshot_request = scrshot_plaque; // request levelshot even if exist (check filetime)
}
@ -1240,7 +1255,7 @@ CL_ParseSetAngle
set the view angle to this absolute value
================
*/
static void CL_ParseSetAngle( sizebuf_t *msg )
void CL_ParseSetAngle( sizebuf_t *msg )
{
MSG_ReadVec3Angles( msg, cl.viewangles );
}
@ -1550,7 +1565,7 @@ CL_StartDark
*/
static void CL_StartDark( void )
{
if( Cvar_VariableValue( "v_dark" ))
if( v_dark.value )
{
screenfade_t *sf = &clgame.fade;
float fadetime = 5.0f;
@ -1575,7 +1590,7 @@ static void CL_StartDark( void )
sf->fadeReset += cl.time;
sf->fadeEnd += sf->fadeReset;
Cvar_SetValue( "v_dark", 0.0f );
Cvar_DirectSet( &v_dark, "0" );
}
}
@ -2153,7 +2168,7 @@ void CL_ParseUserMessage( sizebuf_t *msg, int svc_num )
// parse user message into buffer
MSG_ReadBytes( msg, pbuf, iSize );
if( cl_trace_messages->value )
if( cl_trace_messages.value )
{
Con_Reportf( "^3USERMSG %s SIZE %i SVC_NUM %i\n",
clgame.msg[i].name, iSize, clgame.msg[i].number );
@ -2260,6 +2275,8 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
old_background = cl.background;
if( MSG_ReadOneBit( msg ))
{
int maxclients = cl.maxclients;
cls.changelevel = true;
S_StopAllSounds( true );
@ -2271,8 +2288,8 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
cls.changedemo = true;
}
CL_ClearState ();
CL_InitEdicts (); // re-arrange edicts
CL_ClearState();
CL_InitEdicts( maxclients ); // re-arrange edicts
}
else Con_Printf( "Server disconnected, reconnecting\n" );
@ -2491,666 +2508,3 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
}
}
}
/*
==================
CL_ParseStaticEntity
static client entity
==================
*/
void CL_LegacyParseStaticEntity( sizebuf_t *msg )
{
int i;
entity_state_t state;
cl_entity_t *ent;
memset( &state, 0, sizeof( state ));
state.modelindex = MSG_ReadShort( msg );
state.sequence = MSG_ReadByte( msg );
state.frame = MSG_ReadByte( msg );
state.colormap = MSG_ReadWord( msg );
state.skin = MSG_ReadByte( msg );
for( i = 0; i < 3; i++ )
{
state.origin[i] = MSG_ReadCoord( msg );
state.angles[i] = MSG_ReadBitAngle( msg, 16 );
}
state.rendermode = MSG_ReadByte( msg );
if( state.rendermode != kRenderNormal )
{
state.renderamt = MSG_ReadByte( msg );
state.rendercolor.r = MSG_ReadByte( msg );
state.rendercolor.g = MSG_ReadByte( msg );
state.rendercolor.b = MSG_ReadByte( msg );
state.renderfx = MSG_ReadByte( msg );
}
i = clgame.numStatics;
if( i >= MAX_STATIC_ENTITIES )
{
Con_Printf( S_ERROR "MAX_STATIC_ENTITIES limit exceeded!\n" );
return;
}
ent = &clgame.static_entities[i];
clgame.numStatics++;
// all states are same
ent->baseline = ent->curstate = ent->prevstate = state;
ent->index = 0; // static entities doesn't has the numbers
// statics may be respawned in game e.g. for demo recording
if( cls.state == ca_connected || cls.state == ca_validate )
ent->trivial_accept = INVALID_HANDLE;
// setup the new static entity
VectorCopy( ent->curstate.origin, ent->origin );
VectorCopy( ent->curstate.angles, ent->angles );
ent->model = CL_ModelHandle( state.modelindex );
ent->curstate.framerate = 1.0f;
CL_ResetLatchedVars( ent, true );
if( ent->curstate.rendermode == kRenderNormal && ent->model != NULL )
{
// auto 'solid' faces
if( FBitSet( ent->model->flags, MODEL_TRANSPARENT ) && Host_IsQuakeCompatible( ))
{
ent->curstate.rendermode = kRenderTransAlpha;
ent->curstate.renderamt = 255;
}
}
R_AddEfrags( ent ); // add link
}
void CL_LegacyParseSoundPacket( sizebuf_t *msg, qboolean is_ambient )
{
vec3_t pos;
int chan, sound;
float volume, attn;
int flags, pitch, entnum;
sound_t handle = 0;
flags = MSG_ReadWord( msg );
if( flags & SND_LEGACY_LARGE_INDEX )
{
sound = MSG_ReadWord( msg );
flags &= ~SND_LEGACY_LARGE_INDEX;
}
else
sound = MSG_ReadByte( msg );
chan = MSG_ReadByte( msg );
if( FBitSet( flags, SND_VOLUME ))
volume = (float)MSG_ReadByte( msg ) / 255.0f;
else volume = VOL_NORM;
if( FBitSet( flags, SND_ATTENUATION ))
attn = (float)MSG_ReadByte( msg ) / 64.0f;
else attn = ATTN_NONE;
if( FBitSet( flags, SND_PITCH ))
pitch = MSG_ReadByte( msg );
else pitch = PITCH_NORM;
// entity reletive
entnum = MSG_ReadWord( msg );
// positioned in space
MSG_ReadVec3Coord( msg, pos );
if( FBitSet( flags, SND_SENTENCE ))
{
char sentenceName[32];
//if( FBitSet( flags, SND_SEQUENCE ))
//Q_snprintf( sentenceName, sizeof( sentenceName ), "!#%i", sound + MAX_SOUNDS );
//else
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
handle = S_RegisterSound( sentenceName );
}
else handle = cl.sound_index[sound]; // see precached sound
if( !cl.audio_prepped )
return; // too early
// g-cont. sound and ambient sound have only difference with channel
if( is_ambient )
{
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
}
else
{
S_StartSound( pos, entnum, chan, handle, volume, attn, pitch, flags );
}
}
/*
================
CL_PrecacheSound
prceache sound from server
================
*/
void CL_LegacyPrecacheSound( sizebuf_t *msg )
{
int soundIndex;
soundIndex = MSG_ReadUBitLong( msg, MAX_SOUND_BITS );
if( soundIndex < 0 || soundIndex >= MAX_SOUNDS )
Host_Error( "CL_PrecacheSound: bad soundindex %i\n", soundIndex );
Q_strncpy( cl.sound_precache[soundIndex], MSG_ReadString( msg ), sizeof( cl.sound_precache[0] ));
// when we loading map all resources is precached sequentially
//if( !cl.audio_prepped ) return;
cl.sound_index[soundIndex] = S_RegisterSound( cl.sound_precache[soundIndex] );
}
void CL_LegacyPrecacheModel( sizebuf_t *msg )
{
int modelIndex;
string model;
modelIndex = MSG_ReadUBitLong( msg, MAX_LEGACY_MODEL_BITS );
if( modelIndex < 0 || modelIndex >= MAX_MODELS )
Host_Error( "CL_PrecacheModel: bad modelindex %i\n", modelIndex );
Q_strncpy( model, MSG_ReadString( msg ), MAX_STRING );
//Q_strncpy( cl.model_precache[modelIndex], BF_ReadString( msg ), sizeof( cl.model_precache[0] ));
// when we loading map all resources is precached sequentially
//if( !cl.video_prepped ) return;
if( modelIndex == 1 && !cl.worldmodel )
{
CL_ClearWorld ();
cl.models[modelIndex] = cl.worldmodel = Mod_LoadWorld( model, true );
return;
}
//Mod_RegisterModel( cl.model_precache[modelIndex], modelIndex );
cl.models[modelIndex] = Mod_ForName( model, false, false );
cl.nummodels = Q_max( cl.nummodels, modelIndex );
}
void CL_LegacyPrecacheEvent( sizebuf_t *msg )
{
int eventIndex;
eventIndex = MSG_ReadUBitLong( msg, MAX_EVENT_BITS );
if( eventIndex < 0 || eventIndex >= MAX_EVENTS )
Host_Error( "CL_PrecacheEvent: bad eventindex %i\n", eventIndex );
Q_strncpy( cl.event_precache[eventIndex], MSG_ReadString( msg ), sizeof( cl.event_precache[0] ));
// can be set now
CL_SetEventIndex( cl.event_precache[eventIndex], eventIndex );
}
#if XASH_LOW_MEMORY == 0
#define MAX_LEGACY_RESOURCES 2048
#elif XASH_LOW_MEMORY == 2
#define MAX_LEGACY_RESOURCES 1
#elif XASH_LOW_MEMORY == 1
#define MAX_LEGACY_RESOURCES 512
#endif
/*
==============
CL_ParseResourceList
==============
*/
void CL_LegacyParseResourceList( sizebuf_t *msg )
{
int i = 0;
static struct
{
int rescount;
int restype[MAX_LEGACY_RESOURCES];
char resnames[MAX_LEGACY_RESOURCES][MAX_QPATH];
} reslist;
memset( &reslist, 0, sizeof( reslist ));
reslist.rescount = MSG_ReadWord( msg ) - 1;
if( reslist.rescount > MAX_LEGACY_RESOURCES )
Host_Error("MAX_RESOURCES reached\n");
for( i = 0; i < reslist.rescount; i++ )
{
reslist.restype[i] = MSG_ReadWord( msg );
Q_strncpy( reslist.resnames[i], MSG_ReadString( msg ), MAX_QPATH );
}
if( CL_IsPlaybackDemo() )
{
return;
}
HTTP_ResetProcessState();
host.downloadcount = 0;
for( i = 0; i < reslist.rescount; i++ )
{
char soundpath[MAX_VA_STRING];
const char *path;
if( reslist.restype[i] == t_sound )
{
Q_snprintf( soundpath, sizeof( soundpath ), DEFAULT_SOUNDPATH "%s", reslist.resnames[i] );
path = soundpath;
}
else path = reslist.resnames[i];
if( FS_FileExists( path, false ))
continue; // already exists
host.downloadcount++;
HTTP_AddDownload( path, -1, true );
}
if( !host.downloadcount )
{
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
MSG_WriteString( &cls.netchan.message, "continueloading" );
}
}
/*
=====================
CL_ParseLegacyServerMessage
dispatch messages
=====================
*/
void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
{
size_t bufStart, playerbytes;
int cmd, param1, param2;
int old_background;
const char *s;
cls.starting_count = MSG_GetNumBytesRead( msg ); // updates each frame
CL_Parse_Debug( true ); // begin parsing
if( normal_message )
{
// assume no entity/player update this packet
if( cls.state == ca_active )
{
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].valid = false;
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = false;
}
else
{
CL_ResetFrame( &cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK] );
}
}
// parse the message
while( 1 )
{
if( MSG_CheckOverflow( msg ))
{
Host_Error( "CL_ParseServerMessage: overflow!\n" );
return;
}
// mark start position
bufStart = MSG_GetNumBytesRead( msg );
// end of message (align bits)
if( MSG_GetNumBitsLeft( msg ) < 8 )
break;
cmd = MSG_ReadServerCmd( msg );
// record command for debugging spew on parse problem
CL_Parse_RecordCommand( cmd, bufStart );
// other commands
switch( cmd )
{
case svc_bad:
Host_Error( "svc_bad\n" );
break;
case svc_nop:
// this does nothing
break;
case svc_disconnect:
CL_Drop ();
Host_AbortCurrentFrame ();
break;
case svc_legacy_event:
CL_ParseEvent( msg );
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_legacy_changing:
old_background = cl.background;
if( MSG_ReadOneBit( msg ))
{
cls.changelevel = true;
S_StopAllSounds( true );
Con_Printf( "Server changing, reconnecting\n" );
if( cls.demoplayback )
{
SCR_BeginLoadingPlaque( cl.background );
cls.changedemo = true;
}
CL_ClearState ();
CL_InitEdicts (); // re-arrange edicts
}
else Con_Printf( "Server disconnected, reconnecting\n" );
if( cls.demoplayback )
{
cl.background = (cls.demonum != -1) ? true : false;
cls.state = ca_connected;
}
else
{
// g-cont. local client skip the challenge
if( SV_Active( ))
cls.state = ca_disconnected;
else cls.state = ca_connecting;
cl.background = old_background;
cls.connect_time = MAX_HEARTBEAT;
cls.connect_retry = 0;
}
break;
case svc_setview:
CL_ParseViewEntity( msg );
break;
case svc_sound:
CL_LegacyParseSoundPacket( msg, false );
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_legacy_ambientsound:
CL_LegacyParseSoundPacket( msg, true );
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_time:
CL_ParseServerTime( msg );
break;
case svc_print:
Con_Printf( "%s", MSG_ReadString( msg ));
break;
case svc_stufftext:
s = MSG_ReadString( msg );
#ifdef HACKS_RELATED_HLMODS
// disable Cry Of Fear antisave protection
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
break; // too early
#endif
Con_Reportf( "Stufftext: %s", s );
Cbuf_AddFilteredText( s );
break;
case svc_setangle:
CL_ParseSetAngle( msg );
break;
case svc_serverdata:
Cbuf_Execute(); // make sure any stuffed commands are done
CL_ParseServerData( msg, true );
break;
case svc_lightstyle:
CL_ParseLightStyle( msg );
break;
case svc_updateuserinfo:
CL_UpdateUserinfo( msg, true );
break;
case svc_deltatable:
Delta_ParseTableField( msg );
break;
case svc_clientdata:
CL_ParseClientData( msg );
cl.frames[cl.parsecountmod].graphdata.client += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_resource:
CL_ParseResource( msg );
break;
case svc_pings:
CL_UpdateUserPings( msg );
break;
case svc_particle:
CL_ParseParticles( msg );
break;
case svc_restoresound:
CL_ParseRestoreSoundPacket( msg );
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_spawnstatic:
CL_LegacyParseStaticEntity( msg );
break;
case svc_event_reliable:
CL_ParseReliableEvent( msg );
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_spawnbaseline:
CL_ParseBaseline( msg, true );
break;
case svc_temp_entity:
CL_ParseTempEntity( msg );
cl.frames[cl.parsecountmod].graphdata.tentities += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_setpause:
cl.paused = ( MSG_ReadOneBit( msg ) != 0 );
break;
case svc_signonnum:
CL_ParseSignon( msg );
break;
case svc_centerprint:
CL_CenterPrint( MSG_ReadString( msg ), 0.25f );
break;
case svc_intermission:
cl.intermission = 1;
break;
case svc_legacy_modelindex:
CL_LegacyPrecacheModel( msg );
break;
case svc_legacy_soundindex:
CL_LegacyPrecacheSound( msg );
break;
case svc_cdtrack:
param1 = MSG_ReadByte( msg );
param1 = bound( 1, param1, MAX_CDTRACKS ); // tracknum
param2 = MSG_ReadByte( msg );
param2 = bound( 1, param2, MAX_CDTRACKS ); // loopnum
S_StartBackgroundTrack( clgame.cdtracks[param1-1], clgame.cdtracks[param2-1], 0, false );
break;
case svc_restore:
CL_ParseRestore( msg );
break;
case svc_legacy_eventindex:
CL_LegacyPrecacheEvent(msg);
break;
case svc_weaponanim:
param1 = MSG_ReadByte( msg ); // iAnim
param2 = MSG_ReadByte( msg ); // body
CL_WeaponAnim( param1, param2 );
break;
case svc_bspdecal:
CL_ParseStaticDecal( msg );
break;
case svc_roomtype:
param1 = MSG_ReadShort( msg );
Cvar_SetValue( "room_type", param1 );
break;
case svc_addangle:
CL_ParseAddAngle( msg );
break;
case svc_usermessage:
CL_RegisterUserMessage( msg );
break;
case svc_packetentities:
playerbytes = CL_ParsePacketEntities( msg, false );
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
break;
case svc_deltapacketentities:
playerbytes = CL_ParsePacketEntities( msg, true );
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
break;
case svc_legacy_chokecount:
{
int i, j;
i = MSG_ReadByte( msg );
j = cls.netchan.incoming_acknowledged - 1;
for( ; i > 0 && j > cls.netchan.outgoing_sequence - CL_UPDATE_BACKUP; j-- )
{
if( cl.frames[j & CL_UPDATE_MASK].receivedtime != -3.0 )
{
cl.frames[j & CL_UPDATE_MASK].choked = true;
cl.frames[j & CL_UPDATE_MASK].receivedtime = -2.0;
i--;
}
}
break;
}
//cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = true;
//cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].receivedtime = -2.0;
break;
case svc_resourcelist:
CL_LegacyParseResourceList( msg );
break;
case svc_deltamovevars:
CL_ParseMovevars( msg );
break;
case svc_resourcerequest:
CL_ParseResourceRequest( msg );
break;
case svc_customization:
CL_ParseCustomization( msg );
break;
case svc_crosshairangle:
CL_ParseCrosshairAngle( msg );
break;
case svc_soundfade:
CL_ParseSoundFade( msg );
break;
case svc_filetxferfailed:
CL_ParseFileTransferFailed( msg );
break;
case svc_hltv:
CL_ParseHLTV( msg );
break;
case svc_director:
CL_ParseDirector( msg );
break;
case svc_resourcelocation:
CL_ParseResLocation( msg );
break;
case svc_querycvarvalue:
CL_ParseCvarValue( msg, false );
break;
case svc_querycvarvalue2:
CL_ParseCvarValue( msg, true );
break;
default:
CL_ParseUserMessage( msg, cmd );
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;
break;
}
}
cl.frames[cl.parsecountmod].graphdata.msgbytes += MSG_GetNumBytesRead( msg ) - cls.starting_count;
CL_Parse_Debug( false ); // done
// we don't know if it is ok to save a demo message until
// after we have parsed the frame
if( !cls.demoplayback )
{
if( cls.demorecording && !cls.demowaiting )
{
CL_WriteDemoMessage( false, cls.starting_count, msg );
}
else if( cls.state != ca_active )
{
CL_WriteDemoMessage( true, cls.starting_count, msg );
}
}
}
void CL_LegacyPrecache_f( void )
{
int spawncount, i;
model_t *mod;
if( !cls.legacymode )
return;
spawncount = Q_atoi( Cmd_Argv( 1 ));
Con_Printf( "Setting up renderer...\n" );
// load tempent sprites (glowshell, muzzleflashes etc)
CL_LoadClientSprites ();
// invalidate all decal indexes
memset( cl.decal_index, 0, sizeof( cl.decal_index ));
cl.video_prepped = true;
cl.audio_prepped = true;
if( clgame.entities )
clgame.entities->model = cl.worldmodel;
// update the ref state.
R_UpdateRefState ();
// tell rendering system we have a new set of models.
ref.dllFuncs.R_NewMap ();
CL_SetupOverviewParams();
// release unused SpriteTextures
for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ )
{
if( mod->needload == NL_UNREFERENCED && COM_CheckString( mod->name ))
Mod_FreeModel( mod );
}
// Mod_FreeUnused ();
if( host_developer.value <= DEV_NONE )
Con_ClearNotify(); // clear any lines of console text
// done with all resources, issue prespawn command.
// Include server count in case server disconnects and changes level during d/l
MSG_BeginClientCmd( &cls.netchan.message, clc_stringcmd );
MSG_WriteStringf( &cls.netchan.message, "begin %i", spawncount );
cls.signon = SIGNONS;
}
void CL_LegacyUpdateInfo( void )
{
if( !cls.legacymode )
return;
if( cls.state != ca_active )
return;
MSG_BeginClientCmd( &cls.netchan.message, clc_legacy_userinfo );
MSG_WriteString( &cls.netchan.message, cls.userinfo );
}
qboolean CL_LegacyMode( void )
{
return cls.legacymode;
}

695
engine/client/cl_parse_48.c Normal file
View File

@ -0,0 +1,695 @@
/*
cl_parse.c - parse a message received from the server
Copyright (C) 2008 Uncle Mike
This program 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 3 of the License, or
(at your option) any later version.
This program 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.
*/
#include "common.h"
#include "client.h"
#include "net_encode.h"
#include "particledef.h"
#include "cl_tent.h"
#include "shake.h"
#include "hltv.h"
#include "input.h"
/*
==================
CL_ParseStaticEntity
static client entity
==================
*/
void CL_LegacyParseStaticEntity( sizebuf_t *msg )
{
int i;
entity_state_t state;
cl_entity_t *ent;
memset( &state, 0, sizeof( state ));
state.modelindex = MSG_ReadShort( msg );
state.sequence = MSG_ReadByte( msg );
state.frame = MSG_ReadByte( msg );
state.colormap = MSG_ReadWord( msg );
state.skin = MSG_ReadByte( msg );
for( i = 0; i < 3; i++ )
{
state.origin[i] = MSG_ReadCoord( msg );
state.angles[i] = MSG_ReadBitAngle( msg, 16 );
}
state.rendermode = MSG_ReadByte( msg );
if( state.rendermode != kRenderNormal )
{
state.renderamt = MSG_ReadByte( msg );
state.rendercolor.r = MSG_ReadByte( msg );
state.rendercolor.g = MSG_ReadByte( msg );
state.rendercolor.b = MSG_ReadByte( msg );
state.renderfx = MSG_ReadByte( msg );
}
i = clgame.numStatics;
if( i >= MAX_STATIC_ENTITIES )
{
Con_Printf( S_ERROR "MAX_STATIC_ENTITIES limit exceeded!\n" );
return;
}
ent = &clgame.static_entities[i];
clgame.numStatics++;
// all states are same
ent->baseline = ent->curstate = ent->prevstate = state;
ent->index = 0; // static entities doesn't has the numbers
// statics may be respawned in game e.g. for demo recording
if( cls.state == ca_connected || cls.state == ca_validate )
ent->trivial_accept = INVALID_HANDLE;
// setup the new static entity
VectorCopy( ent->curstate.origin, ent->origin );
VectorCopy( ent->curstate.angles, ent->angles );
ent->model = CL_ModelHandle( state.modelindex );
ent->curstate.framerate = 1.0f;
CL_ResetLatchedVars( ent, true );
if( ent->curstate.rendermode == kRenderNormal && ent->model != NULL )
{
// auto 'solid' faces
if( FBitSet( ent->model->flags, MODEL_TRANSPARENT ) && Host_IsQuakeCompatible( ))
{
ent->curstate.rendermode = kRenderTransAlpha;
ent->curstate.renderamt = 255;
}
}
R_AddEfrags( ent ); // add link
}
void CL_LegacyParseSoundPacket( sizebuf_t *msg, qboolean is_ambient )
{
vec3_t pos;
int chan, sound;
float volume, attn;
int flags, pitch, entnum;
sound_t handle = 0;
flags = MSG_ReadWord( msg );
if( flags & SND_LEGACY_LARGE_INDEX )
{
sound = MSG_ReadWord( msg );
flags &= ~SND_LEGACY_LARGE_INDEX;
}
else
sound = MSG_ReadByte( msg );
chan = MSG_ReadByte( msg );
if( FBitSet( flags, SND_VOLUME ))
volume = (float)MSG_ReadByte( msg ) / 255.0f;
else volume = VOL_NORM;
if( FBitSet( flags, SND_ATTENUATION ))
attn = (float)MSG_ReadByte( msg ) / 64.0f;
else attn = ATTN_NONE;
if( FBitSet( flags, SND_PITCH ))
pitch = MSG_ReadByte( msg );
else pitch = PITCH_NORM;
// entity reletive
entnum = MSG_ReadWord( msg );
// positioned in space
MSG_ReadVec3Coord( msg, pos );
if( FBitSet( flags, SND_SENTENCE ))
{
char sentenceName[32];
//if( FBitSet( flags, SND_SEQUENCE ))
//Q_snprintf( sentenceName, sizeof( sentenceName ), "!#%i", sound + MAX_SOUNDS );
//else
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
handle = S_RegisterSound( sentenceName );
}
else handle = cl.sound_index[sound]; // see precached sound
if( !cl.audio_prepped )
return; // too early
// g-cont. sound and ambient sound have only difference with channel
if( is_ambient )
{
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
}
else
{
S_StartSound( pos, entnum, chan, handle, volume, attn, pitch, flags );
}
}
/*
================
CL_PrecacheSound
prceache sound from server
================
*/
void CL_LegacyPrecacheSound( sizebuf_t *msg )
{
int soundIndex;
soundIndex = MSG_ReadUBitLong( msg, MAX_SOUND_BITS );
if( soundIndex < 0 || soundIndex >= MAX_SOUNDS )
Host_Error( "CL_PrecacheSound: bad soundindex %i\n", soundIndex );
Q_strncpy( cl.sound_precache[soundIndex], MSG_ReadString( msg ), sizeof( cl.sound_precache[0] ));
// when we loading map all resources is precached sequentially
//if( !cl.audio_prepped ) return;
cl.sound_index[soundIndex] = S_RegisterSound( cl.sound_precache[soundIndex] );
}
void CL_LegacyPrecacheModel( sizebuf_t *msg )
{
int modelIndex;
string model;
modelIndex = MSG_ReadUBitLong( msg, MAX_LEGACY_MODEL_BITS );
if( modelIndex < 0 || modelIndex >= MAX_MODELS )
Host_Error( "CL_PrecacheModel: bad modelindex %i\n", modelIndex );
Q_strncpy( model, MSG_ReadString( msg ), MAX_STRING );
//Q_strncpy( cl.model_precache[modelIndex], BF_ReadString( msg ), sizeof( cl.model_precache[0] ));
// when we loading map all resources is precached sequentially
//if( !cl.video_prepped ) return;
if( modelIndex == 1 && !cl.worldmodel )
{
CL_ClearWorld ();
cl.models[modelIndex] = cl.worldmodel = Mod_LoadWorld( model, true );
return;
}
//Mod_RegisterModel( cl.model_precache[modelIndex], modelIndex );
cl.models[modelIndex] = Mod_ForName( model, false, false );
cl.nummodels = Q_max( cl.nummodels, modelIndex );
}
void CL_LegacyPrecacheEvent( sizebuf_t *msg )
{
int eventIndex;
eventIndex = MSG_ReadUBitLong( msg, MAX_EVENT_BITS );
if( eventIndex < 0 || eventIndex >= MAX_EVENTS )
Host_Error( "CL_PrecacheEvent: bad eventindex %i\n", eventIndex );
Q_strncpy( cl.event_precache[eventIndex], MSG_ReadString( msg ), sizeof( cl.event_precache[0] ));
// can be set now
CL_SetEventIndex( cl.event_precache[eventIndex], eventIndex );
}
#if XASH_LOW_MEMORY == 0
#define MAX_LEGACY_RESOURCES 2048
#elif XASH_LOW_MEMORY == 2
#define MAX_LEGACY_RESOURCES 1
#elif XASH_LOW_MEMORY == 1
#define MAX_LEGACY_RESOURCES 512
#endif
/*
==============
CL_ParseResourceList
==============
*/
void CL_LegacyParseResourceList( sizebuf_t *msg )
{
int i = 0;
static struct
{
int rescount;
int restype[MAX_LEGACY_RESOURCES];
char resnames[MAX_LEGACY_RESOURCES][MAX_QPATH];
} reslist;
memset( &reslist, 0, sizeof( reslist ));
reslist.rescount = MSG_ReadWord( msg ) - 1;
if( reslist.rescount > MAX_LEGACY_RESOURCES )
Host_Error("MAX_RESOURCES reached\n");
for( i = 0; i < reslist.rescount; i++ )
{
reslist.restype[i] = MSG_ReadWord( msg );
Q_strncpy( reslist.resnames[i], MSG_ReadString( msg ), MAX_QPATH );
}
if( CL_IsPlaybackDemo() )
{
return;
}
HTTP_ResetProcessState();
host.downloadcount = 0;
for( i = 0; i < reslist.rescount; i++ )
{
char soundpath[MAX_VA_STRING];
const char *path;
if( reslist.restype[i] == t_sound )
{
Q_snprintf( soundpath, sizeof( soundpath ), DEFAULT_SOUNDPATH "%s", reslist.resnames[i] );
path = soundpath;
}
else path = reslist.resnames[i];
if( FS_FileExists( path, false ))
continue; // already exists
host.downloadcount++;
HTTP_AddDownload( path, -1, true );
}
if( !host.downloadcount )
{
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
MSG_WriteString( &cls.netchan.message, "continueloading" );
}
}
/*
=====================
CL_ParseLegacyServerMessage
dispatch messages
=====================
*/
void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
{
size_t bufStart, playerbytes;
int cmd, param1, param2;
int old_background;
const char *s;
cls.starting_count = MSG_GetNumBytesRead( msg ); // updates each frame
CL_Parse_Debug( true ); // begin parsing
if( normal_message )
{
// assume no entity/player update this packet
if( cls.state == ca_active )
{
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].valid = false;
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = false;
}
else
{
CL_ResetFrame( &cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK] );
}
}
// parse the message
while( 1 )
{
if( MSG_CheckOverflow( msg ))
{
Host_Error( "CL_ParseServerMessage: overflow!\n" );
return;
}
// mark start position
bufStart = MSG_GetNumBytesRead( msg );
// end of message (align bits)
if( MSG_GetNumBitsLeft( msg ) < 8 )
break;
cmd = MSG_ReadServerCmd( msg );
// record command for debugging spew on parse problem
CL_Parse_RecordCommand( cmd, bufStart );
// other commands
switch( cmd )
{
case svc_bad:
Host_Error( "svc_bad\n" );
break;
case svc_nop:
// this does nothing
break;
case svc_disconnect:
CL_Drop ();
Host_AbortCurrentFrame ();
break;
case svc_legacy_event:
CL_ParseEvent( msg );
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_legacy_changing:
old_background = cl.background;
if( MSG_ReadOneBit( msg ))
{
int maxclients = cl.maxclients;
cls.changelevel = true;
S_StopAllSounds( true );
Con_Printf( "Server changing, reconnecting\n" );
if( cls.demoplayback )
{
SCR_BeginLoadingPlaque( cl.background );
cls.changedemo = true;
}
CL_ClearState( );
// a1ba: need to restore cl.maxclients because engine chooses
// frame backups count depending on this value
// In general, it's incorrect to call CL_InitEdicts right after
// CL_ClearState because of this bug. Some time later this logic
// should be re-done.
CL_InitEdicts( maxclients ); // re-arrange edicts
}
else Con_Printf( "Server disconnected, reconnecting\n" );
if( cls.demoplayback )
{
cl.background = (cls.demonum != -1) ? true : false;
cls.state = ca_connected;
}
else
{
// g-cont. local client skip the challenge
if( SV_Active( ))
cls.state = ca_disconnected;
else cls.state = ca_connecting;
cl.background = old_background;
cls.connect_time = MAX_HEARTBEAT;
cls.connect_retry = 0;
}
break;
case svc_setview:
CL_ParseViewEntity( msg );
break;
case svc_sound:
CL_LegacyParseSoundPacket( msg, false );
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_legacy_ambientsound:
CL_LegacyParseSoundPacket( msg, true );
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_time:
CL_ParseServerTime( msg );
break;
case svc_print:
Con_Printf( "%s", MSG_ReadString( msg ));
break;
case svc_stufftext:
s = MSG_ReadString( msg );
#ifdef HACKS_RELATED_HLMODS
// disable Cry Of Fear antisave protection
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
break; // too early
#endif
Con_Reportf( "Stufftext: %s", s );
Cbuf_AddFilteredText( s );
break;
case svc_setangle:
CL_ParseSetAngle( msg );
break;
case svc_serverdata:
Cbuf_Execute(); // make sure any stuffed commands are done
CL_ParseServerData( msg, true );
break;
case svc_lightstyle:
CL_ParseLightStyle( msg );
break;
case svc_updateuserinfo:
CL_UpdateUserinfo( msg, true );
break;
case svc_deltatable:
Delta_ParseTableField( msg );
break;
case svc_clientdata:
CL_ParseClientData( msg );
cl.frames[cl.parsecountmod].graphdata.client += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_resource:
CL_ParseResource( msg );
break;
case svc_pings:
CL_UpdateUserPings( msg );
break;
case svc_particle:
CL_ParseParticles( msg );
break;
case svc_restoresound:
CL_ParseRestoreSoundPacket( msg );
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_spawnstatic:
CL_LegacyParseStaticEntity( msg );
break;
case svc_event_reliable:
CL_ParseReliableEvent( msg );
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_spawnbaseline:
CL_ParseBaseline( msg, true );
break;
case svc_temp_entity:
CL_ParseTempEntity( msg );
cl.frames[cl.parsecountmod].graphdata.tentities += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_setpause:
cl.paused = ( MSG_ReadOneBit( msg ) != 0 );
break;
case svc_signonnum:
CL_ParseSignon( msg );
break;
case svc_centerprint:
CL_CenterPrint( MSG_ReadString( msg ), 0.25f );
break;
case svc_intermission:
cl.intermission = 1;
break;
case svc_legacy_modelindex:
CL_LegacyPrecacheModel( msg );
break;
case svc_legacy_soundindex:
CL_LegacyPrecacheSound( msg );
break;
case svc_cdtrack:
param1 = MSG_ReadByte( msg );
param1 = bound( 1, param1, MAX_CDTRACKS ); // tracknum
param2 = MSG_ReadByte( msg );
param2 = bound( 1, param2, MAX_CDTRACKS ); // loopnum
S_StartBackgroundTrack( clgame.cdtracks[param1-1], clgame.cdtracks[param2-1], 0, false );
break;
case svc_restore:
CL_ParseRestore( msg );
break;
case svc_legacy_eventindex:
CL_LegacyPrecacheEvent(msg);
break;
case svc_weaponanim:
param1 = MSG_ReadByte( msg ); // iAnim
param2 = MSG_ReadByte( msg ); // body
CL_WeaponAnim( param1, param2 );
break;
case svc_bspdecal:
CL_ParseStaticDecal( msg );
break;
case svc_roomtype:
param1 = MSG_ReadShort( msg );
Cvar_SetValue( "room_type", param1 );
break;
case svc_addangle:
CL_ParseAddAngle( msg );
break;
case svc_usermessage:
CL_RegisterUserMessage( msg );
break;
case svc_packetentities:
playerbytes = CL_ParsePacketEntities( msg, false );
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
break;
case svc_deltapacketentities:
playerbytes = CL_ParsePacketEntities( msg, true );
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
break;
case svc_legacy_chokecount:
{
int i, j;
i = MSG_ReadByte( msg );
j = cls.netchan.incoming_acknowledged - 1;
for( ; i > 0 && j > cls.netchan.outgoing_sequence - CL_UPDATE_BACKUP; j-- )
{
if( cl.frames[j & CL_UPDATE_MASK].receivedtime != -3.0 )
{
cl.frames[j & CL_UPDATE_MASK].choked = true;
cl.frames[j & CL_UPDATE_MASK].receivedtime = -2.0;
i--;
}
}
break;
}
//cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = true;
//cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].receivedtime = -2.0;
break;
case svc_resourcelist:
CL_LegacyParseResourceList( msg );
break;
case svc_deltamovevars:
CL_ParseMovevars( msg );
break;
case svc_resourcerequest:
CL_ParseResourceRequest( msg );
break;
case svc_customization:
CL_ParseCustomization( msg );
break;
case svc_crosshairangle:
CL_ParseCrosshairAngle( msg );
break;
case svc_soundfade:
CL_ParseSoundFade( msg );
break;
case svc_filetxferfailed:
CL_ParseFileTransferFailed( msg );
break;
case svc_hltv:
CL_ParseHLTV( msg );
break;
case svc_director:
CL_ParseDirector( msg );
break;
case svc_resourcelocation:
CL_ParseResLocation( msg );
break;
case svc_querycvarvalue:
CL_ParseCvarValue( msg, false );
break;
case svc_querycvarvalue2:
CL_ParseCvarValue( msg, true );
break;
default:
CL_ParseUserMessage( msg, cmd );
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;
break;
}
}
cl.frames[cl.parsecountmod].graphdata.msgbytes += MSG_GetNumBytesRead( msg ) - cls.starting_count;
CL_Parse_Debug( false ); // done
// we don't know if it is ok to save a demo message until
// after we have parsed the frame
if( !cls.demoplayback )
{
if( cls.demorecording && !cls.demowaiting )
{
CL_WriteDemoMessage( false, cls.starting_count, msg );
}
else if( cls.state != ca_active )
{
CL_WriteDemoMessage( true, cls.starting_count, msg );
}
}
}
void CL_LegacyPrecache_f( void )
{
int spawncount, i;
model_t *mod;
if( !cls.legacymode )
return;
spawncount = Q_atoi( Cmd_Argv( 1 ));
Con_Printf( "Setting up renderer...\n" );
// load tempent sprites (glowshell, muzzleflashes etc)
CL_LoadClientSprites ();
// invalidate all decal indexes
memset( cl.decal_index, 0, sizeof( cl.decal_index ));
cl.video_prepped = true;
cl.audio_prepped = true;
if( clgame.entities )
clgame.entities->model = cl.worldmodel;
// update the ref state.
R_UpdateRefState ();
// tell rendering system we have a new set of models.
ref.dllFuncs.R_NewMap ();
CL_SetupOverviewParams();
// release unused SpriteTextures
for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ )
{
if( mod->needload == NL_UNREFERENCED && COM_CheckString( mod->name ))
Mod_FreeModel( mod );
}
// Mod_FreeUnused ();
if( host_developer.value <= DEV_NONE )
Con_ClearNotify(); // clear any lines of console text
// done with all resources, issue prespawn command.
// Include server count in case server disconnects and changes level during d/l
MSG_BeginClientCmd( &cls.netchan.message, clc_stringcmd );
MSG_WriteStringf( &cls.netchan.message, "begin %i", spawncount );
cls.signon = SIGNONS;
}
void CL_LegacyUpdateInfo( void )
{
if( !cls.legacymode )
return;
if( cls.state != ca_active )
return;
MSG_BeginClientCmd( &cls.netchan.message, clc_legacy_userinfo );
MSG_WriteString( &cls.netchan.message, cls.userinfo );
}
qboolean CL_LegacyMode( void )
{
return cls.legacymode;
}

View File

@ -86,7 +86,7 @@ CL_IsPredicted
*/
qboolean CL_IsPredicted( void )
{
if( cl_nopred->value || cl.intermission )
if( cl_nopred.value || cl.intermission )
return false;
// never predict the quake demos
@ -183,7 +183,7 @@ void CL_SetIdealPitch( void )
}
if( steps < 2 ) return;
cl.local.idealpitch = -dir * cl_idealpitchscale->value;
cl.local.idealpitch = -dir * cl_idealpitchscale.value;
}
/*
@ -234,7 +234,7 @@ void CL_CheckPredictionError( void )
// save the prediction error for interpolation
if( dist > MAX_PREDICTION_ERROR )
{
if( cl_showerror->value && host_developer.value )
if( cl_showerror.value && host_developer.value )
Con_NPrintf( 10 + ( ++pos & 3 ), "^3player teleported:^7 %.3f units\n", dist );
// a teleport or something or gamepaused
@ -242,7 +242,7 @@ void CL_CheckPredictionError( void )
}
else
{
if( cl_showerror->value && dist > MIN_PREDICTION_EPSILON && host_developer.value )
if( cl_showerror.value && dist > MIN_PREDICTION_EPSILON && host_developer.value )
Con_NPrintf( 10 + ( ++pos & 3 ), "^1prediction error:^7 %.3f units\n", dist );
VectorCopy( cl.frames[cmd].playerstate[cl.playernum].origin, cl.local.predicted_origins[frame] );
@ -253,7 +253,7 @@ void CL_CheckPredictionError( void )
// GoldSrc checks for singleplayer
// we would check for local server
if( dist > MIN_CORRECTION_DISTANCE && !SV_Active() )
cls.correction_time = cl_smoothtime->value;
cls.correction_time = cl_smoothtime.value;
}
}
@ -533,7 +533,7 @@ void GAME_EXPORT CL_SetSolidPlayers( int playernum )
physent_t *pe;
int i;
if( !cl_solid_players->value )
if( !cl_solid_players.value )
return;
for( i = 0; i < MAX_CLIENTS; i++ )
@ -1105,7 +1105,7 @@ void CL_PredictMovement( qboolean repredicting )
cl.local.onground = frame->playerstate[cl.playernum].onground;
else cl.local.onground = -1;
if( !repredicting || !CVAR_TO_BOOL( cl_lw ))
if( !repredicting || !cl_lw.value )
cl.local.viewmodel = to->client.viewmodel;
cl.local.repredicting = false;
cl.local.moving = false;
@ -1137,7 +1137,7 @@ void CL_PredictMovement( qboolean repredicting )
cl.local.waterlevel = to->client.waterlevel;
cl.local.usehull = to->playerstate.usehull;
if( !repredicting || !CVAR_TO_BOOL( cl_lw ))
if( !repredicting || !cl_lw.value )
cl.local.viewmodel = to->client.viewmodel;
if( FBitSet( to->client.flags, FL_ONGROUND ))
@ -1167,7 +1167,7 @@ void CL_PredictMovement( qboolean repredicting )
cl.local.moving = false;
}
if( cls.correction_time > 0 && !cl_nosmooth->value && cl_smoothtime->value )
if( cls.correction_time > 0 && !cl_nosmooth.value && cl_smoothtime.value )
{
vec3_t delta;
float frac;
@ -1177,14 +1177,14 @@ void CL_PredictMovement( qboolean repredicting )
cls.correction_time -= host.frametime;
// Make sure smoothtime is postive
if( cl_smoothtime->value <= 0.0f )
Cvar_DirectSet( cl_smoothtime, "0.1" );
if( cl_smoothtime.value <= 0.0f )
Cvar_DirectSet( &cl_smoothtime, "0.1" );
// Clamp from 0 to cl_smoothtime.value
cls.correction_time = bound( 0.0, cls.correction_time, cl_smoothtime->value );
cls.correction_time = bound( 0.0, cls.correction_time, cl_smoothtime.value );
// Compute backward interpolation fraction along full correction
frac = 1.0f - cls.correction_time / cl_smoothtime->value;
frac = 1.0f - cls.correction_time / cl_smoothtime.value;
// Determine how much error we still have to make up for
VectorSubtract( cl.simorg, cl.local.lastorigin, delta );

View File

@ -232,10 +232,10 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
// loading user settings
CSCR_LoadDefaultCVars( "user.scr" );
if( r_decals->value > mp_decals.value )
Cvar_SetValue( "r_decals", mp_decals.value );
if( r_decals.value > mp_decals.value )
Cvar_DirectSet( &r_decals, mp_decals.string );
}
else Cvar_Reset( "r_decals" );
else Cvar_DirectSet( &r_decals, NULL );
if( cl.background ) // tell the game parts about background state
Cvar_FullSet( "cl_background", "1", FCVAR_READ_ONLY );
@ -258,7 +258,7 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
Q_strncpy( gameui.globals->maptitle, clgame.maptitle, sizeof( gameui.globals->maptitle ));
if( !cls.changelevel && !cls.changedemo )
CL_InitEdicts (); // re-arrange edicts
CL_InitEdicts( cl.maxclients ); // re-arrange edicts
// Quake just have a large packet of initialization data
for( i = 1; i < MAX_MODELS; i++ )
@ -302,9 +302,9 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
else Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, refState.wideScreen ? "16x9" : "4x3" ));
Cvar_SetValue( "scr_loading", 0.0f ); // reset progress bar
if(( cl_allow_levelshots->value && !cls.changelevel ) || cl.background )
if(( cl_allow_levelshots.value && !cls.changelevel ) || cl.background )
{
if( !FS_FileExists( va( "%s.bmp", cl_levelshot_name->string ), true ))
if( !FS_FileExists( va( "%s.bmp", cl_levelshot_name.string ), true ))
Cvar_Set( "cl_levelshot_name", "*black" ); // render a black screen
cls.scrshot_request = scrshot_plaque; // request levelshot even if exist (check filetime)
}
@ -694,17 +694,13 @@ static void CL_ParseQuakeBaseline( sizebuf_t *msg )
cl_entity_t *ent;
int newnum;
memset( &state, 0, sizeof( state ));
newnum = MSG_ReadWord( msg ); // entnum
if( newnum >= clgame.maxEntities )
Host_Error( "CL_AllocEdict: no free edicts\n" );
ent = CL_EDICT_NUM( newnum );
memset( &ent->prevstate, 0, sizeof( ent->prevstate ));
ent->index = newnum;
// parse baseline
memset( &state, 0, sizeof( state ));
state.modelindex = MSG_ReadByte( msg );
state.frame = MSG_ReadByte( msg );
state.colormap = MSG_ReadByte( msg );
@ -715,8 +711,10 @@ static void CL_ParseQuakeBaseline( sizebuf_t *msg )
state.angles[1] = MSG_ReadAngle( msg );
state.origin[2] = MSG_ReadCoord( msg );
state.angles[2] = MSG_ReadAngle( msg );
ent->player = CL_IsPlayerIndex( newnum );
ent = CL_EDICT_NUM( newnum );
ent->index = newnum;
ent->player = CL_IsPlayerIndex( newnum );
memcpy( &ent->baseline, &state, sizeof( entity_state_t ));
memcpy( &ent->prevstate, &state, sizeof( entity_state_t ));
}

View File

@ -41,11 +41,24 @@ CL_CmpStudioTextures
return true if equal
====================
*/
qboolean CL_CmpStudioTextures( int numtexs, mstudiotexture_t *p1, mstudiotexture_t *p2 )
static qboolean CL_CmpStudioTextures( int numtexs, mstudiotexture_t *p1, remap_info_t *remap )
{
int i;
mstudiotexture_t *p2;
if( !p1 || !p2 ) return false;
if( !p1 ) // no textures
return false;
if( !remap ) // current model has no remap
return false;
if( !remap->textures ) // shouldn't happen, just in case
return false;
if( numtexs != remap->numtextures ) // amount of textures differs, it's a different model
return false;
p2 = remap->ptexture;
for( i = 0; i < numtexs; i++, p1++, p2++ )
{
@ -282,10 +295,9 @@ void CL_AllocRemapInfo( cl_entity_t *entity, model_t *model, int topcolor, int b
if( !phdr ) return; // bad model?
src = (mstudiotexture_t *)(((byte *)phdr) + phdr->textureindex);
dst = (clgame.remap_info[i] ? clgame.remap_info[i]->ptexture : NULL);
// NOTE: we must copy all the structures 'mstudiotexture_t' for easy access when model is rendering
if( !CL_CmpStudioTextures( phdr->numtextures, src, dst ) || clgame.remap_info[i]->model != model )
if( !CL_CmpStudioTextures( phdr->numtextures, src, clgame.remap_info[i] ) || clgame.remap_info[i]->model != model )
{
// this code catches studiomodel change with another studiomodel with remap textures
// e.g. playermodel 'barney' with playermodel 'gordon'

View File

@ -164,6 +164,14 @@ intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRe
return (intptr_t)world.deluxedata;
case PARM_SHADOWDATA:
return (intptr_t)world.shadowdata;
case PARM_FULLSCREEN:
return refState.fullScreen;
case PARM_WIDESCREEN:
return refState.wideScreen;
case PARM_SCREEN_WIDTH:
return refState.width;
case PARM_SCREEN_HEIGHT:
return refState.height;
default:
// indicates call from client.dll
if( checkRef )

View File

@ -20,18 +20,18 @@ GNU General Public License for more details.
#include "input.h"
#include "library.h"
convar_t *scr_centertime;
convar_t *scr_loading;
convar_t *scr_download;
convar_t *scr_viewsize;
convar_t *cl_testlights;
convar_t *cl_allow_levelshots;
convar_t *cl_levelshot_name;
static convar_t *cl_envshot_size;
convar_t *v_dark;
static convar_t *net_speeds;
static convar_t *cl_showfps;
static convar_t *cl_showpos;
CVAR_DEFINE_AUTO( scr_centertime, "2.5", 0, "centerprint hold time" );
CVAR_DEFINE_AUTO( scr_loading, "0", 0, "loading bar progress" );
CVAR_DEFINE_AUTO( scr_download, "-1", 0, "downloading bar progress" );
CVAR_DEFINE( scr_viewsize, "viewsize", "120", FCVAR_ARCHIVE, "screen size (quake only)" );
CVAR_DEFINE_AUTO( cl_testlights, "0", 0, "test dynamic lights" );
CVAR_DEFINE( cl_allow_levelshots, "allow_levelshots", "0", FCVAR_ARCHIVE, "allow engine to use indivdual levelshots instead of 'loading' image" );
CVAR_DEFINE_AUTO( cl_levelshot_name, "*black", 0, "contains path to current levelshot" );
static CVAR_DEFINE_AUTO( cl_envshot_size, "256", FCVAR_ARCHIVE, "envshot size of cube side" );
CVAR_DEFINE_AUTO( v_dark, "0", 0, "starts level from dark screen" );
static CVAR_DEFINE_AUTO( net_speeds, "0", FCVAR_ARCHIVE, "show network packets" );
static CVAR_DEFINE_AUTO( cl_showfps, "0", FCVAR_ARCHIVE, "show client fps" );
static CVAR_DEFINE_AUTO( cl_showpos, "0", FCVAR_ARCHIVE, "show local player position and velocity" );
typedef struct
{
@ -59,7 +59,7 @@ void SCR_DrawFPS( int height )
char fpsstring[64];
int offset;
if( cls.state != ca_active || !cl_showfps->value || cl.background )
if( cls.state != ca_active || !cl_showfps.value || cl.background )
return;
switch( cls.scrshot_action )
@ -95,7 +95,7 @@ void SCR_DrawFPS( int height )
if( curfps < minfps ) minfps = curfps;
if( curfps > maxfps ) maxfps = curfps;
if( cl_showfps->value == 2 )
if( cl_showfps.value == 2 )
Q_snprintf( fpsstring, sizeof( fpsstring ), "fps: ^1%4i min, ^3%4i cur, ^2%4i max", minfps, curfps, maxfps );
else Q_snprintf( fpsstring, sizeof( fpsstring ), "%4i fps", curfps );
MakeRGBA( color, 255, 255, 255, 255 );
@ -119,7 +119,7 @@ void SCR_DrawPos( void )
cl_entity_t *ent;
rgba_t color;
if( cls.state != ca_active || !cl_showpos->value || cl.background )
if( cls.state != ca_active || !cl_showpos.value || cl.background )
return;
ent = CL_GetLocalPlayer();
@ -164,7 +164,7 @@ void SCR_NetSpeeds( void )
if( !host.allow_console )
return;
if( !net_speeds->value || cls.state != ca_active )
if( !net_speeds.value || cls.state != ca_active )
return;
// prevent to get too big values at max
@ -290,7 +290,7 @@ void SCR_MakeScreenShot( void )
if( cls.envshot_viewsize > 0 )
viewsize = cls.envshot_viewsize;
else viewsize = cl_envshot_size->value;
else viewsize = cl_envshot_size.value;
switch( cls.scrshot_action )
{
@ -344,9 +344,9 @@ SCR_DrawPlaque
*/
void SCR_DrawPlaque( void )
{
if(( cl_allow_levelshots->value && !cls.changelevel ) || cl.background )
if(( cl_allow_levelshots.value && !cls.changelevel ) || cl.background )
{
int levelshot = ref.dllFuncs.GL_LoadTexture( cl_levelshot_name->string, NULL, 0, TF_IMAGE );
int levelshot = ref.dllFuncs.GL_LoadTexture( cl_levelshot_name.string, NULL, 0, TF_IMAGE );
ref.dllFuncs.GL_SetRenderMode( kRenderNormal );
ref.dllFuncs.R_DrawStretchPic( 0, 0, refState.width, refState.height, 0, 0, 1, 1, levelshot );
if( !cl.background ) CL_DrawHUD( CL_LOADING );
@ -366,7 +366,7 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
cl.video_prepped = false;
if( !Host_IsDedicated() )
oldclear = gl_clear->value;
oldclear = gl_clear.value;
if( CL_IsInMenu( ) && !cls.changedemo && !is_background )
{
@ -382,7 +382,7 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
return;
if( !Host_IsDedicated() )
gl_clear->value = 0.0f;
gl_clear.value = 0.0f;
if( is_background ) IN_MouseSavePos( );
cls.draw_changelevel = !is_background;
@ -391,7 +391,7 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
cl.background = is_background; // set right state before svc_serverdata is came
if( !Host_IsDedicated() )
gl_clear->value = oldclear;
gl_clear.value = oldclear;
// SNDDMA_LockSound();
}
@ -442,7 +442,7 @@ void SCR_TileClear( void )
int i, top, bottom, left, right;
dirty_t clear;
if( scr_viewsize->value >= 120 )
if( scr_viewsize.value >= 120 )
return; // full screen rendering
// erase rect will be the union of the past three frames
@ -558,7 +558,7 @@ void SCR_LoadCreditsFont( void )
{
cl_font_t *const font = &cls.creditsFont;
qboolean success = false;
float scale = hud_fontscale->value;
float scale = hud_fontscale.value;
dword crc = 0;
// replace default gfx.wad textures by current charset's font
@ -652,13 +652,13 @@ void SCR_RegisterTextures( void )
if( FS_FileExists( "gfx/lambda.lmp", false ))
{
if( cl_allow_levelshots->value )
if( cl_allow_levelshots.value )
cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE );
else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE );
}
else if( FS_FileExists( "gfx/loading.lmp", false ))
{
if( cl_allow_levelshots->value )
if( cl_allow_levelshots.value )
cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE );
else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE );
}
@ -675,7 +675,7 @@ Keybinding command
*/
void SCR_SizeUp_f( void )
{
Cvar_SetValue( "viewsize", Q_min( scr_viewsize->value + 10, 120 ));
Cvar_SetValue( "viewsize", Q_min( scr_viewsize.value + 10, 120 ));
}
@ -688,7 +688,7 @@ Keybinding command
*/
void SCR_SizeDown_f( void )
{
Cvar_SetValue( "viewsize", Q_max( scr_viewsize->value - 10, 30 ));
Cvar_SetValue( "viewsize", Q_max( scr_viewsize.value - 10, 30 ));
}
/*
@ -737,18 +737,18 @@ void SCR_Init( void )
{
if( scr_init ) return;
scr_centertime = Cvar_Get( "scr_centertime", "2.5", 0, "centerprint hold time" );
cl_levelshot_name = Cvar_Get( "cl_levelshot_name", "*black", 0, "contains path to current levelshot" );
cl_allow_levelshots = Cvar_Get( "allow_levelshots", "0", FCVAR_ARCHIVE, "allow engine to use indivdual levelshots instead of 'loading' image" );
scr_loading = Cvar_Get( "scr_loading", "0", 0, "loading bar progress" );
scr_download = Cvar_Get( "scr_download", "-1", 0, "downloading bar progress" );
cl_testlights = Cvar_Get( "cl_testlights", "0", 0, "test dynamic lights" );
cl_envshot_size = Cvar_Get( "cl_envshot_size", "256", FCVAR_ARCHIVE, "envshot size of cube side" );
v_dark = Cvar_Get( "v_dark", "0", 0, "starts level from dark screen" );
scr_viewsize = Cvar_Get( "viewsize", "120", FCVAR_ARCHIVE, "screen size" );
net_speeds = Cvar_Get( "net_speeds", "0", FCVAR_ARCHIVE, "show network packets" );
cl_showfps = Cvar_Get( "cl_showfps", "0", FCVAR_ARCHIVE, "show client fps" );
cl_showpos = Cvar_Get( "cl_showpos", "0", FCVAR_ARCHIVE, "show local player position and velocity" );
Cvar_RegisterVariable( &scr_centertime );
Cvar_RegisterVariable( &cl_levelshot_name );
Cvar_RegisterVariable( &cl_allow_levelshots );
Cvar_RegisterVariable( &scr_loading );
Cvar_RegisterVariable( &scr_download );
Cvar_RegisterVariable( &cl_testlights );
Cvar_RegisterVariable( &cl_envshot_size );
Cvar_RegisterVariable( &v_dark );
Cvar_RegisterVariable( &scr_viewsize );
Cvar_RegisterVariable( &net_speeds );
Cvar_RegisterVariable( &cl_showfps );
Cvar_RegisterVariable( &cl_showpos );
// register our commands
Cmd_AddCommand( "skyname", CL_SetSky_f, "set new skybox by basename" );

View File

@ -2846,10 +2846,10 @@ void CL_TestLights( void )
float f, r;
dlight_t *dl;
if( !CVAR_TO_BOOL( cl_testlights ))
if( !cl_testlights.value )
return;
numLights = bound( 1, cl_testlights->value, MAX_DLIGHTS );
numLights = bound( 1, cl_testlights.value, MAX_DLIGHTS );
AngleVectors( cl.viewangles, forward, right, NULL );
for( i = 0; i < numLights; i++ )

View File

@ -39,7 +39,7 @@ void V_CalcViewRect( void )
{
// intermission is always full screen
if( cl.intermission ) size = 120.0f;
else size = scr_viewsize->value;
else size = scr_viewsize.value;
if( size >= 120.0f )
sb_lines = 0; // no status bar at all
@ -47,12 +47,12 @@ void V_CalcViewRect( void )
sb_lines = 24; // no inventory
else sb_lines = 48;
if( scr_viewsize->value >= 100.0f )
if( scr_viewsize.value >= 100.0f )
{
full = true;
size = 100.0f;
}
else size = scr_viewsize->value;
else size = scr_viewsize.value;
if( cl.intermission )
{
@ -144,7 +144,7 @@ void V_SetRefParams( ref_params_t *fd )
VectorCopy( cl.viewangles, fd->cl_viewangles );
fd->health = cl.local.health;
VectorCopy( cl.crosshairangle, fd->crosshairangle );
fd->viewsize = scr_viewsize->value;
fd->viewsize = scr_viewsize.value;
VectorCopy( cl.punchangle, fd->punchangle );
fd->maxclients = cl.maxclients;
@ -311,7 +311,7 @@ void V_GetRefParams( ref_params_t *fd, ref_viewpass_t *rvp )
rvp->fov_y = V_CalcFov( &rvp->fov_x, clgame.viewport[2], clgame.viewport[3] );
// adjust FOV for widescreen
if( refState.wideScreen && r_adjust_fov->value )
if( refState.wideScreen && r_adjust_fov.value )
V_AdjustFov( &rvp->fov_x, &rvp->fov_y, clgame.viewport[2], clgame.viewport[3], false );
rvp->flags = 0;
@ -339,7 +339,7 @@ qboolean V_PreRender( void )
// if the screen is disabled (loading plaque is up)
if( cls.disable_screen )
{
if(( host.realtime - cls.disable_screen ) > cl_timeout->value )
if(( host.realtime - cls.disable_screen ) > cl_timeout.value )
{
Con_Reportf( "V_PreRender: loading plaque timed out\n" );
cls.disable_screen = 0.0f;
@ -364,11 +364,13 @@ V_RenderView
*/
void V_RenderView( void )
{
ref_params_t rp;
// HACKHACK: make ref params static
// not really critical but allows client.dll to take address of refdef and don't trigger ASan
static ref_params_t rp;
ref_viewpass_t rvp;
int viewnum = 0;
if( !cl.video_prepped || ( !ui_renderworld->value && UI_IsVisible() && !cl.background ))
if( !cl.video_prepped || ( !ui_renderworld.value && UI_IsVisible() && !cl.background ))
return; // still loading
V_CalcViewRect (); // compute viewport rectangle
@ -472,7 +474,7 @@ void R_ShowTree( void )
float y = NODE_INTERVAL_Y(1.0f);
mleaf_t *viewleaf;
if( !cl.worldmodel || !CVAR_TO_BOOL( r_showtree ))
if( !cl.worldmodel || !r_showtree.value )
return;
world.recursion_level = 0;

View File

@ -659,46 +659,47 @@ extern convar_t cl_logocolor;
extern convar_t cl_allow_download;
extern convar_t cl_allow_upload;
extern convar_t cl_download_ingame;
extern convar_t *cl_nopred;
extern convar_t *cl_timeout;
extern convar_t *cl_nodelta;
extern convar_t *cl_interp;
extern convar_t *cl_nointerp;
extern convar_t *cl_showerror;
extern convar_t *cl_nosmooth;
extern convar_t *cl_smoothtime;
extern convar_t *cl_crosshair;
extern convar_t *cl_testlights;
extern convar_t *cl_cmdrate;
extern convar_t *cl_updaterate;
extern convar_t *cl_solid_players;
extern convar_t *cl_idealpitchscale;
extern convar_t *cl_allow_levelshots;
extern convar_t *cl_lightstyle_lerping;
extern convar_t *cl_draw_particles;
extern convar_t *cl_draw_tracers;
extern convar_t *cl_levelshot_name;
extern convar_t *cl_draw_beams;
extern convar_t *cl_clockreset;
extern convar_t *cl_fixtimerate;
extern convar_t *hud_fontscale;
extern convar_t *hud_scale;
extern convar_t *gl_showtextures;
extern convar_t *cl_bmodelinterp;
extern convar_t *cl_lw; // local weapons
extern convar_t *cl_charset;
extern convar_t *cl_trace_messages;
extern convar_t *hud_utf8;
extern convar_t *cl_showevents;
extern convar_t *scr_centertime;
extern convar_t *scr_viewsize;
extern convar_t *scr_loading;
extern convar_t *v_dark; // start from dark
extern convar_t *net_graph;
extern convar_t *rate;
extern convar_t *m_ignore;
extern convar_t *r_showtree;
extern convar_t *ui_renderworld;
extern convar_t cl_nopred;
extern convar_t cl_timeout;
extern convar_t cl_nodelta;
extern convar_t cl_interp;
extern convar_t cl_nointerp;
extern convar_t cl_showerror;
extern convar_t cl_nosmooth;
extern convar_t cl_smoothtime;
extern convar_t cl_crosshair;
extern convar_t cl_testlights;
extern convar_t cl_cmdrate;
extern convar_t cl_updaterate;
extern convar_t cl_solid_players;
extern convar_t cl_idealpitchscale;
extern convar_t cl_allow_levelshots;
extern convar_t cl_lightstyle_lerping;
extern convar_t cl_draw_particles;
extern convar_t cl_draw_tracers;
extern convar_t cl_levelshot_name;
extern convar_t cl_draw_beams;
extern convar_t cl_clockreset;
extern convar_t cl_fixtimerate;
extern convar_t hud_fontscale;
extern convar_t hud_scale;
extern convar_t r_showtextures;
extern convar_t cl_bmodelinterp;
extern convar_t cl_lw; // local weapons
extern convar_t cl_charset;
extern convar_t cl_trace_messages;
extern convar_t cl_trace_events;
extern convar_t hud_utf8;
extern convar_t cl_showevents;
extern convar_t scr_centertime;
extern convar_t scr_viewsize;
extern convar_t scr_loading;
extern convar_t v_dark; // start from dark
extern convar_t net_graph;
extern convar_t rate;
extern convar_t m_ignore;
extern convar_t r_showtree;
extern convar_t ui_renderworld;
//=============================================================================
@ -830,7 +831,7 @@ void CL_LinkUserMessage( char *pszName, const int svc_num, int iSize );
void CL_ParseFinaleCutscene( sizebuf_t *msg, int level );
void CL_ParseTextMessage( sizebuf_t *msg );
void CL_DrawHUD( int state );
void CL_InitEdicts( void );
void CL_InitEdicts( int maxclients );
void CL_FreeEdicts( void );
void CL_ClearWorld( void );
void CL_DrawCenterPrint( void );
@ -838,29 +839,21 @@ void CL_ClearSpriteTextures( void );
void CL_CenterPrint( const char *text, float y );
void CL_TextMessageParse( byte *pMemFile, int fileSize );
client_textmessage_t *CL_TextMessageGet( const char *pName );
int pfnDecalIndexFromName( const char *szDecalName );
int pfnIndexFromTrace( struct pmtrace_s *pTrace );
model_t *CL_ModelHandle( int modelindex );
void NetAPI_CancelAllRequests( void );
int CL_FindModelIndex( const char *m );
cl_entity_t *CL_GetLocalPlayer( void );
model_t *CL_LoadClientSprite( const char *filename );
model_t *CL_LoadModel( const char *modelname, int *index );
HSPRITE EXPORT pfnSPR_Load( const char *szPicName );
HSPRITE pfnSPR_LoadExt( const char *szPicName, uint texFlags );
void SPR_AdjustSize( float *x, float *y, float *w, float *h );
void SPR_AdjustTexCoords( float width, float height, float *s1, float *t1, float *s2, float *t2 );
int CL_GetScreenInfo( SCREENINFO *pscrinfo );
void CL_FillRGBA( int x, int y, int width, int height, int r, int g, int b, int a );
void CL_PlayerTrace( float *start, float *end, int traceFlags, int ignore_pe, pmtrace_t *tr );
void CL_PlayerTraceExt( float *start, float *end, int traceFlags, int (*pfnIgnore)( physent_t *pe ), pmtrace_t *tr );
pmtrace_t *PM_CL_TraceLine( float *start, float *end, int flags, int usehull, int ignore_pe );
const char *PM_CL_TraceTexture( int ground, float *vstart, float *vend );
int PM_CL_PointContents( const float *p, int *truecontents );
void CL_SetTraceHull( int hull );
void CL_GetMousePosition( int *mx, int *my ); // TODO: move to input
cl_entity_t* CL_GetViewModel( void );
void pfnGetScreenFade( struct screenfade_s *fade );
physent_t *pfnGetPhysent( int idx );
struct msurface_s *pfnTraceSurface( int ground, float *vstart, float *vend );
movevars_t *pfnGetMoveVars( void );
@ -886,10 +879,32 @@ _inline cl_entity_t *CL_EDICT_NUM( int n )
//
// cl_parse.c
//
void CL_ParseSetAngle( sizebuf_t *msg );
void CL_ParseServerData( sizebuf_t *msg, qboolean legacy );
void CL_ParseLightStyle( sizebuf_t *msg );
void CL_UpdateUserinfo( sizebuf_t *msg, qboolean legacy );
void CL_ParseResource( sizebuf_t *msg );
void CL_ParseClientData( sizebuf_t *msg );
void CL_UpdateUserPings( sizebuf_t *msg );
void CL_ParseParticles( sizebuf_t *msg );
void CL_ParseRestoreSoundPacket( sizebuf_t *msg );
void CL_ParseBaseline( sizebuf_t *msg, qboolean legacy );
void CL_ParseSignon( sizebuf_t *msg );
void CL_ParseRestore( sizebuf_t *msg );
void CL_ParseStaticDecal( sizebuf_t *msg );
void CL_ParseAddAngle( sizebuf_t *msg );
void CL_RegisterUserMessage( sizebuf_t *msg );
void CL_ParseMovevars( sizebuf_t *msg );
void CL_ParseResourceRequest( sizebuf_t *msg );
void CL_ParseCustomization( sizebuf_t *msg );
void CL_ParseCrosshairAngle( sizebuf_t *msg );
void CL_ParseSoundFade( sizebuf_t *msg );
void CL_ParseFileTransferFailed( sizebuf_t *msg );
void CL_ParseHLTV( sizebuf_t *msg );
void CL_ParseDirector( sizebuf_t *msg );
void CL_ParseResLocation( sizebuf_t *msg );
void CL_ParseCvarValue( sizebuf_t *msg, const qboolean ext );
void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message );
void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message );
void CL_LegacyPrecache_f( void );
void CL_ParseTempEntity( sizebuf_t *msg );
qboolean CL_DispatchUserMessage( const char *pszName, int iSize, void *pbuf );
qboolean CL_RequestMissingResources( void );
@ -897,6 +912,12 @@ void CL_RegisterResources ( sizebuf_t *msg );
void CL_ParseViewEntity( sizebuf_t *msg );
void CL_ParseServerTime( sizebuf_t *msg );
//
// cl_parse_48.c
//
void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message );
void CL_LegacyPrecache_f( void );
//
// cl_scrn.c
//
@ -1005,7 +1026,6 @@ void R_AddEfrags( cl_entity_t *ent );
// cl_tent.c
//
struct particle_s;
int CL_AddEntity( int entityType, cl_entity_t *pEnt );
void CL_WeaponAnim( int iAnim, int body );
void CL_ClearEffects( void );
void CL_ClearEfrags( void );
@ -1039,7 +1059,7 @@ void CL_RunLightStyles( void );
//
// console.c
//
extern convar_t *con_fontsize;
extern convar_t con_fontsize;
int Con_Visible( void );
qboolean Con_FixedFont( void );
void Con_VidInit( void );

View File

@ -22,13 +22,14 @@ GNU General Public License for more details.
#include "wadfile.h"
#include "input.h"
convar_t *con_notifytime;
convar_t *scr_conspeed;
convar_t *con_fontsize;
convar_t *con_charset;
convar_t *con_fontscale;
convar_t *con_fontnum;
convar_t *con_color;
static CVAR_DEFINE_AUTO( scr_conspeed, "600", FCVAR_ARCHIVE, "console moving speed" );
static CVAR_DEFINE_AUTO( con_notifytime, "3", FCVAR_ARCHIVE, "notify time to live" );
CVAR_DEFINE_AUTO( con_fontsize, "1", FCVAR_ARCHIVE, "console font number (0, 1 or 2)" );
static CVAR_DEFINE_AUTO( con_charset, "cp1251", FCVAR_ARCHIVE, "console font charset (only cp1251 supported now)" );
static CVAR_DEFINE_AUTO( con_fontscale, "1.0", FCVAR_ARCHIVE, "scale font texture" );
static CVAR_DEFINE_AUTO( con_fontnum, "-1", FCVAR_ARCHIVE, "console font number (0, 1 or 2), -1 for autoselect" );
static CVAR_DEFINE_AUTO( con_color, "240 180 24", FCVAR_ARCHIVE, "set a custom console color" );
static int g_codepage = 0;
static qboolean g_utf8 = false;
@ -162,14 +163,13 @@ Con_SetColor
*/
static void Con_SetColor( void )
{
vec3_t color;
int r, g, b;
int num;
if( !FBitSet( con_color->flags, FCVAR_CHANGED ))
if( !FBitSet( con_color.flags, FCVAR_CHANGED ))
return;
num = sscanf( con_color->string, "%i %i %i", &r, &g, &b );
num = sscanf( con_color.string, "%i %i %i", &r, &g, &b );
switch( num )
{
@ -180,11 +180,11 @@ static void Con_SetColor( void )
Con_DefaultColor( r, g, b );
break;
default:
Cvar_DirectSet( con_color, con_color->def_string );
Cvar_DirectSet( &con_color, con_color.def_string );
break;
}
ClearBits( con_color->flags, FCVAR_CHANGED );
ClearBits( con_color.flags, FCVAR_CHANGED );
}
/*
@ -538,7 +538,7 @@ INTERNAL RESOURCE
static void Con_LoadConsoleFont( int fontNumber, cl_font_t *font )
{
qboolean success = false;
float scale = con_fontscale->value;
float scale = con_fontscale.value;
if( font->valid )
return; // already loaded
@ -593,8 +593,8 @@ static void Con_LoadConchars( void )
Con_LoadConsoleFont( i, con.chars + i );
// select properly fontsize
if( con_fontnum->value >= 0 && con_fontnum->value <= CON_NUMFONTS - 1 )
fontSize = con_fontnum->value;
if( con_fontnum.value >= 0 && con_fontnum.value <= CON_NUMFONTS - 1 )
fontSize = con_fontnum.value;
else if( refState.width <= 640 )
fontSize = 0;
else if( refState.width >= 1280 )
@ -830,19 +830,17 @@ Con_Init
*/
void Con_Init( void )
{
int i;
if( host.type == HOST_DEDICATED )
return; // dedicated server already have console
// must be init before startup video subsystem
scr_conspeed = Cvar_Get( "scr_conspeed", "600", FCVAR_ARCHIVE, "console moving speed" );
con_notifytime = Cvar_Get( "con_notifytime", "3", FCVAR_ARCHIVE, "notify time to live" );
con_fontsize = Cvar_Get( "con_fontsize", "1", FCVAR_ARCHIVE, "console font number (0, 1 or 2)" );
con_charset = Cvar_Get( "con_charset", "cp1251", FCVAR_ARCHIVE, "console font charset (only cp1251 supported now)" );
con_fontscale = Cvar_Get( "con_fontscale", "1.0", FCVAR_ARCHIVE, "scale font texture" );
con_fontnum = Cvar_Get( "con_fontnum", "-1", FCVAR_ARCHIVE, "console font number (0, 1 or 2), -1 for autoselect" );
con_color = Cvar_Get( "con_color", "240 180 24", FCVAR_ARCHIVE, "set a custom console color" );
Cvar_RegisterVariable( &scr_conspeed );
Cvar_RegisterVariable( &con_notifytime );
Cvar_RegisterVariable( &con_fontsize );
Cvar_RegisterVariable( &con_charset );
Cvar_RegisterVariable( &con_fontscale );
Cvar_RegisterVariable( &con_fontnum );
Cvar_RegisterVariable( &con_color );
// init the console buffer
con.bufsize = CON_TEXTSIZE;
@ -1481,6 +1479,10 @@ static void Con_SaveHistory( con_history_t *self )
int historyStart = self->next - CON_HISTORY, i;
file_t *f;
// do not save history if nothing was executed
if( self->next == 0 )
return;
if( historyStart < 0 )
historyStart = 0;
@ -1750,11 +1752,15 @@ void Con_DrawDebug( void )
string dlstring;
int x, y;
if( scr_download->value != -1.0f )
if( scr_download.value != -1.0f )
{
int length;
Q_snprintf( dlstring, sizeof( dlstring ), "Downloading [%d remaining]: ^2%s^7 %5.1f%% time %.f secs",
host.downloadcount, host.downloadfile, scr_download->value, Sys_DoubleTime() - timeStart );
x = refState.width - 500;
host.downloadcount, host.downloadfile, scr_download.value, Sys_DoubleTime() - timeStart );
Con_DrawStringLen( dlstring, &length, NULL );
length = Q_max( length, 500 );
x = refState.width - length * 1.05f;
y = con.curFont->charHeight * 1.05f;
Con_DrawString( x, y, dlstring, g_color_table[7] );
}
@ -1795,7 +1801,7 @@ void Con_DrawNotify( void )
{
con_lineinfo_t *l = &CON_LINES( i );
if( l->addtime < ( time - con_notifytime->value ))
if( l->addtime < ( time - con_notifytime.value ))
continue;
Con_DrawString( x, y, l->start, g_color_table[7] );
@ -1977,7 +1983,7 @@ void Con_DrawConsole( void )
if( cls.state == ca_connecting || cls.state == ca_connected )
{
if( !cl_allow_levelshots->value )
if( !cl_allow_levelshots.value )
{
if(( Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" )) && cls.key_dest != key_console )
con.vislines = con.showlines = 0;
@ -2052,16 +2058,13 @@ void Con_DrawVersion( void )
break;
}
if( !host.force_draw_version )
{
if(( cls.key_dest != key_menu && !draw_version ) || CL_IsDevOverviewMode() == 2 || net_graph->value )
return;
}
if( host.force_draw_version_time > host.realtime )
host.force_draw_version = false;
draw_version = true;
if( host.force_draw_version || draw_version )
if(( cls.key_dest != key_menu && !draw_version ) || CL_IsDevOverviewMode() == 2 || net_graph.value )
return;
if( draw_version )
Q_snprintf( curbuild, MAX_STRING, XASH_ENGINE_NAME " v%i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
else Q_snprintf( curbuild, MAX_STRING, "v%i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
@ -2094,7 +2097,7 @@ void Con_RunConsole( void )
}
else con.showlines = 0; // none visible
lines_per_frame = fabs( scr_conspeed->value ) * host.realframetime;
lines_per_frame = fabs( scr_conspeed.value ) * host.realframetime;
if( con.showlines < con.vislines )
{
@ -2109,35 +2112,35 @@ void Con_RunConsole( void )
con.vislines = con.showlines;
}
if( FBitSet( con_charset->flags, FCVAR_CHANGED ) ||
FBitSet( con_fontscale->flags, FCVAR_CHANGED ) ||
FBitSet( con_fontnum->flags, FCVAR_CHANGED ) ||
FBitSet( cl_charset->flags, FCVAR_CHANGED ))
if( FBitSet( con_charset.flags, FCVAR_CHANGED ) ||
FBitSet( con_fontscale.flags, FCVAR_CHANGED ) ||
FBitSet( con_fontnum.flags, FCVAR_CHANGED ) ||
FBitSet( cl_charset.flags, FCVAR_CHANGED ))
{
// update codepage parameters
if( !Q_stricmp( con_charset->string, "cp1251" ))
if( !Q_stricmp( con_charset.string, "cp1251" ))
{
g_codepage = 1251;
}
else if( !Q_stricmp( con_charset->string, "cp1252" ))
else if( !Q_stricmp( con_charset.string, "cp1252" ))
{
g_codepage = 1252;
}
else
{
Con_Printf( S_WARN "Unknown charset %s, defaulting to cp1252", con_charset->string );
Con_Printf( S_WARN "Unknown charset %s, defaulting to cp1252", con_charset.string );
Cvar_DirectSet( con_charset, "cp1252" );
Cvar_DirectSet( &con_charset, "cp1252" );
g_codepage = 1252;
}
g_utf8 = !Q_stricmp( cl_charset->string, "utf-8" );
g_utf8 = !Q_stricmp( cl_charset.string, "utf-8" );
Con_InvalidateFonts();
Con_LoadConchars();
ClearBits( con_charset->flags, FCVAR_CHANGED );
ClearBits( con_fontnum->flags, FCVAR_CHANGED );
ClearBits( con_fontscale->flags, FCVAR_CHANGED );
ClearBits( cl_charset->flags, FCVAR_CHANGED );
ClearBits( con_charset.flags, FCVAR_CHANGED );
ClearBits( con_fontnum.flags, FCVAR_CHANGED );
ClearBits( con_fontscale.flags, FCVAR_CHANGED );
ClearBits( cl_charset.flags, FCVAR_CHANGED );
}
}

View File

@ -44,22 +44,25 @@ static struct joy_axis_s
short prevval;
} joyaxis[MAX_AXES] = { 0 };
static byte currentbinding; // add posibility to remap keys, to place it in joykeys[]
convar_t *joy_enable;
static convar_t *joy_pitch;
static convar_t *joy_yaw;
static convar_t *joy_forward;
static convar_t *joy_side;
static convar_t *joy_found;
static convar_t *joy_index;
static convar_t *joy_lt_threshold;
static convar_t *joy_rt_threshold;
static convar_t *joy_side_deadzone;
static convar_t *joy_forward_deadzone;
static convar_t *joy_side_key_threshold;
static convar_t *joy_forward_key_threshold;
static convar_t *joy_pitch_deadzone;
static convar_t *joy_yaw_deadzone;
static convar_t *joy_axis_binding;
static qboolean joy_initialized;
static CVAR_DEFINE_AUTO( joy_pitch, "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick pitch sensitivity" );
static CVAR_DEFINE_AUTO( joy_yaw, "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick yaw sensitivity" );
static CVAR_DEFINE_AUTO( joy_side, "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick side sensitivity. Values from -1.0 to 1.0" );
static CVAR_DEFINE_AUTO( joy_forward, "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick forward sensitivity. Values from -1.0 to 1.0" );
static CVAR_DEFINE_AUTO( joy_lt_threshold, "16384", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "left trigger threshold. Value from 0 to 32767");
static CVAR_DEFINE_AUTO( joy_rt_threshold, "16384", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "right trigger threshold. Value from 0 to 32767" );
static CVAR_DEFINE_AUTO( joy_side_key_threshold, "24576", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "side axis key event emit threshold. Value from 0 to 32767" );
static CVAR_DEFINE_AUTO( joy_forward_key_threshold, "24576", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "forward axis key event emit threshold. Value from 0 to 32767");
static CVAR_DEFINE_AUTO( joy_side_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "side axis deadzone. Value from 0 to 32767" );
static CVAR_DEFINE_AUTO( joy_forward_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "forward axis deadzone. Value from 0 to 32767");
static CVAR_DEFINE_AUTO( joy_pitch_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "pitch axis deadzone. Value from 0 to 32767");
static CVAR_DEFINE_AUTO( joy_yaw_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "yaw axis deadzone. Value from 0 to 32767" );
static CVAR_DEFINE_AUTO( joy_axis_binding, "sfpyrl", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "axis hardware id to engine inner axis binding, "
"s - side, f - forward, y - yaw, p - pitch, r - left trigger, l - right trigger" );
static CVAR_DEFINE_AUTO( joy_found, "0", FCVAR_READ_ONLY, "is joystick is connected" );
static CVAR_DEFINE_AUTO( joy_index, "0", FCVAR_READ_ONLY, "current active joystick" );
CVAR_DEFINE_AUTO( joy_enable, "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable joystick" );
/*
============
@ -68,7 +71,7 @@ Joy_IsActive
*/
qboolean Joy_IsActive( void )
{
return joy_found->value && joy_enable->value;
return joy_found.value && joy_enable.value;
}
/*
@ -93,7 +96,7 @@ void Joy_HatMotionEvent( byte hat, byte value )
};
int i;
if( !joy_found->value )
if( !joy_found.value )
return;
for( i = 0; i < ARRAYSIZE( keys ); i++ )
@ -124,11 +127,11 @@ static void Joy_ProcessTrigger( const engineAxis_t engineAxis, short value )
{
case JOY_AXIS_RT:
trigButton = K_JOY2;
trigThreshold = joy_rt_threshold->value;
trigThreshold = joy_rt_threshold.value;
break;
case JOY_AXIS_LT:
trigButton = K_JOY1;
trigThreshold = joy_lt_threshold->value;
trigThreshold = joy_lt_threshold.value;
break;
default:
Con_Reportf( S_ERROR "Joy_ProcessTrigger: invalid axis = %i", engineAxis );
@ -158,12 +161,12 @@ static int Joy_GetHatValueForAxis( const engineAxis_t engineAxis )
switch( engineAxis )
{
case JOY_AXIS_SIDE:
threshold = joy_side_key_threshold->value;
threshold = joy_side_key_threshold.value;
negative = JOY_HAT_LEFT;
positive = JOY_HAT_RIGHT;
break;
case JOY_AXIS_FWD:
threshold = joy_side_key_threshold->value;
threshold = joy_side_key_threshold.value;
negative = JOY_HAT_UP;
positive = JOY_HAT_DOWN;
break;
@ -197,10 +200,10 @@ static void Joy_ProcessStick( const engineAxis_t engineAxis, short value )
switch( engineAxis )
{
case JOY_AXIS_FWD: deadzone = joy_forward_deadzone->value; break;
case JOY_AXIS_SIDE: deadzone = joy_side_deadzone->value; break;
case JOY_AXIS_PITCH: deadzone = joy_pitch_deadzone->value; break;
case JOY_AXIS_YAW: deadzone = joy_yaw_deadzone->value; break;
case JOY_AXIS_FWD: deadzone = joy_forward_deadzone.value; break;
case JOY_AXIS_SIDE: deadzone = joy_side_deadzone.value; break;
case JOY_AXIS_PITCH: deadzone = joy_pitch_deadzone.value; break;
case JOY_AXIS_YAW: deadzone = joy_yaw_deadzone.value; break;
default:
Con_Reportf( S_ERROR "Joy_ProcessStick: invalid axis = %i", engineAxis );
break;
@ -235,7 +238,7 @@ Axis events
*/
void Joy_AxisMotionEvent( byte axis, short value )
{
if( !joy_found->value )
if( !joy_found.value )
return;
if( axis >= MAX_AXES )
@ -270,7 +273,7 @@ Trackball events. UNDONE
*/
void Joy_BallMotionEvent( byte ball, short xrel, short yrel )
{
//if( !joy_found->value )
//if( !joy_found.value )
// return;
}
@ -283,7 +286,7 @@ Button events
*/
void Joy_ButtonEvent( byte button, byte down )
{
if( !joy_found->value )
if( !joy_found.value )
return;
// generic game button code.
@ -308,7 +311,7 @@ Called when joystick is removed. For future expansion
*/
void Joy_RemoveEvent( void )
{
if( joy_found->value )
if( joy_found.value )
Cvar_FullSet( "joy_found", "0", FCVAR_READ_ONLY );
}
@ -321,7 +324,7 @@ Called when joystick is removed. For future expansion
*/
void Joy_AddEvent( void )
{
if( joy_enable->value && !joy_found->value )
if( joy_enable.value && !joy_found.value )
Cvar_FullSet( "joy_found", "1", FCVAR_READ_ONLY );
}
@ -337,9 +340,9 @@ void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw )
if( !Joy_IsActive() )
return;
if( FBitSet( joy_axis_binding->flags, FCVAR_CHANGED ) )
if( FBitSet( joy_axis_binding.flags, FCVAR_CHANGED ) )
{
const char *bind = joy_axis_binding->string;
const char *bind = joy_axis_binding.string;
size_t i;
for( i = 0; bind[i]; i++ )
@ -356,18 +359,18 @@ void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw )
}
}
ClearBits( joy_axis_binding->flags, FCVAR_CHANGED );
ClearBits( joy_axis_binding.flags, FCVAR_CHANGED );
}
*fw -= joy_forward->value * (float)joyaxis[JOY_AXIS_FWD ].val/(float)SHRT_MAX; // must be form -1.0 to 1.0
*side += joy_side->value * (float)joyaxis[JOY_AXIS_SIDE].val/(float)SHRT_MAX;
*fw -= joy_forward.value * (float)joyaxis[JOY_AXIS_FWD ].val/(float)SHRT_MAX; // must be form -1.0 to 1.0
*side += joy_side.value * (float)joyaxis[JOY_AXIS_SIDE].val/(float)SHRT_MAX;
#if !defined(XASH_SDL)
*dpitch += joy_pitch->value * (float)joyaxis[JOY_AXIS_PITCH].val/(float)SHRT_MAX * host.realframetime; // abs axis rotate is frametime related
*dyaw -= joy_yaw->value * (float)joyaxis[JOY_AXIS_YAW ].val/(float)SHRT_MAX * host.realframetime;
*dpitch += joy_pitch.value * (float)joyaxis[JOY_AXIS_PITCH].val/(float)SHRT_MAX * host.realframetime; // abs axis rotate is frametime related
*dyaw -= joy_yaw.value * (float)joyaxis[JOY_AXIS_YAW ].val/(float)SHRT_MAX * host.realframetime;
#else
// HACKHACK: SDL have inverted look axis.
*dpitch -= joy_pitch->value * (float)joyaxis[JOY_AXIS_PITCH].val/(float)SHRT_MAX * host.realframetime;
*dyaw += joy_yaw->value * (float)joyaxis[JOY_AXIS_YAW ].val/(float)SHRT_MAX * host.realframetime;
*dpitch -= joy_pitch.value * (float)joyaxis[JOY_AXIS_PITCH].val/(float)SHRT_MAX * host.realframetime;
*dyaw += joy_yaw.value * (float)joyaxis[JOY_AXIS_YAW ].val/(float)SHRT_MAX * host.realframetime;
#endif
}
@ -380,40 +383,43 @@ Main init procedure
*/
void Joy_Init( void )
{
joy_pitch = Cvar_Get( "joy_pitch", "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick pitch sensitivity" );
joy_yaw = Cvar_Get( "joy_yaw", "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick yaw sensitivity" );
joy_side = Cvar_Get( "joy_side", "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick side sensitivity. Values from -1.0 to 1.0" );
joy_forward = Cvar_Get( "joy_forward", "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick forward sensitivity. Values from -1.0 to 1.0" );
Cvar_RegisterVariable( &joy_pitch );
Cvar_RegisterVariable( &joy_yaw );
Cvar_RegisterVariable( &joy_side );
Cvar_RegisterVariable( &joy_forward );
joy_lt_threshold = Cvar_Get( "joy_lt_threshold", "16384", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "left trigger threshold. Value from 0 to 32767");
joy_rt_threshold = Cvar_Get( "joy_rt_threshold", "16384", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "right trigger threshold. Value from 0 to 32767" );
Cvar_RegisterVariable( &joy_lt_threshold );
Cvar_RegisterVariable( &joy_rt_threshold );
// emit a key event at 75% axis move
joy_side_key_threshold = Cvar_Get( "joy_side_key_threshold", "24576", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "side axis key event emit threshold. Value from 0 to 32767" );
joy_forward_key_threshold = Cvar_Get( "joy_forward_key_threshold", "24576", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "forward axis key event emit threshold. Value from 0 to 32767");
Cvar_RegisterVariable( &joy_side_key_threshold );
Cvar_RegisterVariable( &joy_forward_key_threshold );
// by default, we rely on deadzone detection come from system, but some glitchy devices report false deadzones
joy_side_deadzone = Cvar_Get( "joy_side_deadzone", DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "side axis deadzone. Value from 0 to 32767" );
joy_forward_deadzone = Cvar_Get( "joy_forward_deadzone", DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "forward axis deadzone. Value from 0 to 32767");
joy_pitch_deadzone = Cvar_Get( "joy_pitch_deadzone", DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "pitch axis deadzone. Value from 0 to 32767");
joy_yaw_deadzone = Cvar_Get( "joy_yaw_deadzone", DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "yaw axis deadzone. Value from 0 to 32767" );
Cvar_RegisterVariable( &joy_side_deadzone );
Cvar_RegisterVariable( &joy_forward_deadzone );
Cvar_RegisterVariable( &joy_pitch_deadzone );
Cvar_RegisterVariable( &joy_yaw_deadzone );
joy_axis_binding = Cvar_Get( "joy_axis_binding", "sfpyrl", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "axis hardware id to engine inner axis binding, "
"s - side, f - forward, y - yaw, p - pitch, r - left trigger, l - right trigger" );
joy_found = Cvar_Get( "joy_found", "0", FCVAR_READ_ONLY, "is joystick is connected" );
Cvar_RegisterVariable( &joy_axis_binding );
Cvar_RegisterVariable( &joy_found );
// we doesn't loaded config.cfg yet, so this cvar is not archive.
// change by +set joy_index in cmdline
joy_index = Cvar_Get( "joy_index", "0", FCVAR_READ_ONLY, "current active joystick" );
Cvar_RegisterVariable( &joy_index );
joy_enable = Cvar_Get( "joy_enable", "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable joystick" );
Cvar_RegisterVariable( &joy_enable );
if( Sys_CheckParm( "-nojoy" ))
// renamed from -nojoy to -noenginejoy to not conflict with
// client.dll's joystick support
if( Sys_CheckParm( "-noenginejoy" ))
{
Cvar_FullSet( "joy_enable", "0", FCVAR_READ_ONLY );
return;
}
Cvar_FullSet( "joy_found", va( "%d", Platform_JoyInit( joy_index->value )), FCVAR_READ_ONLY );
Cvar_FullSet( "joy_found", va( "%d", Platform_JoyInit( joy_index.value )), FCVAR_READ_ONLY );
joy_initialized = true;
}
/*
@ -425,5 +431,8 @@ Shutdown joystick code
*/
void Joy_Shutdown( void )
{
Cvar_FullSet( "joy_found", 0, FCVAR_READ_ONLY );
if( joy_initialized )
{
Cvar_FullSet( "joy_found", 0, FCVAR_READ_ONLY );
}
}

View File

@ -140,28 +140,27 @@ static struct touch_s
touchdefaultbutton_t g_DefaultButtons[256];
int g_LastDefaultButton;
convar_t *touch_pitch;
convar_t *touch_yaw;
convar_t *touch_forwardzone;
convar_t *touch_sidezone;
convar_t *touch_nonlinear_look;
convar_t *touch_pow_mult;
convar_t *touch_pow_factor;
convar_t *touch_exp_mult;
convar_t *touch_grid_enable;
convar_t *touch_grid_count;
convar_t *touch_config_file;
convar_t *touch_in_menu;
convar_t *touch_joy_radius;
convar_t *touch_dpad_radius;
convar_t *touch_move_indicator;
convar_t *touch_highlight_r;
convar_t *touch_highlight_g;
convar_t *touch_highlight_b;
convar_t *touch_highlight_a;
convar_t *touch_precise_amount;
convar_t *touch_joy_texture;
static CVAR_DEFINE_AUTO( touch_in_menu, "0", FCVAR_FILTERABLE, "draw touch in menu (for internal use only)" );
static CVAR_DEFINE_AUTO( touch_forwardzone, "0.06", FCVAR_FILTERABLE, "forward touch zone" );
static CVAR_DEFINE_AUTO( touch_sidezone, "0.06", FCVAR_FILTERABLE, "side touch zone" );
static CVAR_DEFINE_AUTO( touch_pitch, "90", FCVAR_FILTERABLE, "touch pitch sensitivity" );
static CVAR_DEFINE_AUTO( touch_yaw, "120", FCVAR_FILTERABLE, "touch yaw sensitivity" );
static CVAR_DEFINE_AUTO( touch_nonlinear_look, "0", FCVAR_FILTERABLE, "enable nonlinear touch look" );
static CVAR_DEFINE_AUTO( touch_pow_factor, "1.3", FCVAR_FILTERABLE, "set > 1 to enable" );
static CVAR_DEFINE_AUTO( touch_pow_mult, "400.0", FCVAR_FILTERABLE, "power multiplier, usually 200-1000" );
static CVAR_DEFINE_AUTO( touch_exp_mult, "0", FCVAR_FILTERABLE, "exponent multiplier, usually 20-200, 0 to disable" );
static CVAR_DEFINE_AUTO( touch_grid_count, "50", FCVAR_FILTERABLE, "touch grid count" );
static CVAR_DEFINE_AUTO( touch_grid_enable, "1", FCVAR_FILTERABLE, "enable touch grid" );
static CVAR_DEFINE_AUTO( touch_config_file, "touch.cfg", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "current touch profile file" );
static CVAR_DEFINE_AUTO( touch_precise_amount, "0.5", FCVAR_FILTERABLE, "sensitivity multiplier for precise-look" );
static CVAR_DEFINE_AUTO( touch_highlight_r, "1.0", 0, "highlight r color" );
static CVAR_DEFINE_AUTO( touch_highlight_g, "1.0", 0, "highlight g color" );
static CVAR_DEFINE_AUTO( touch_highlight_b, "1.0", 0, "highlight b color" );
static CVAR_DEFINE_AUTO( touch_highlight_a, "1.0", 0, "highlight alpha" );
static CVAR_DEFINE_AUTO( touch_dpad_radius, "1.0", FCVAR_FILTERABLE, "dpad radius multiplier" );
static CVAR_DEFINE_AUTO( touch_joy_radius, "1.0", FCVAR_FILTERABLE, "joy radius multiplier" );
static CVAR_DEFINE_AUTO( touch_move_indicator, "0.0", FCVAR_FILTERABLE, "indicate move events (0 to disable)" );
static CVAR_DEFINE_AUTO( touch_joy_texture, "touch_default/joy", FCVAR_FILTERABLE, "texture for move indicator");
CVAR_DEFINE_AUTO( touch_enable, DEFAULT_TOUCH_ENABLE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable touch controls" );
CVAR_DEFINE_AUTO( touch_emulate, "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "emulate touch with mouse" );
@ -242,31 +241,31 @@ qboolean Touch_DumpConfig( const char *name, const char *profilename )
FS_Printf( f, "\ntouch_config_file \"%s\"\n", profilename );
FS_Printf( f, "\n// touch cvars\n" );
FS_Printf( f, "\n// sensitivity settings\n" );
FS_Printf( f, "touch_pitch \"%f\"\n", touch_pitch->value );
FS_Printf( f, "touch_yaw \"%f\"\n", touch_yaw->value );
FS_Printf( f, "touch_forwardzone \"%f\"\n", touch_forwardzone->value );
FS_Printf( f, "touch_sidezone \"%f\"\n", touch_sidezone->value );
FS_Printf( f, "touch_nonlinear_look \"%d\"\n", CVAR_TO_BOOL(touch_nonlinear_look));
FS_Printf( f, "touch_pow_factor \"%f\"\n", touch_pow_factor->value );
FS_Printf( f, "touch_pow_mult \"%f\"\n", touch_pow_mult->value );
FS_Printf( f, "touch_exp_mult \"%f\"\n", touch_exp_mult->value );
FS_Printf( f, "touch_pitch \"%f\"\n", touch_pitch.value );
FS_Printf( f, "touch_yaw \"%f\"\n", touch_yaw.value );
FS_Printf( f, "touch_forwardzone \"%f\"\n", touch_forwardzone.value );
FS_Printf( f, "touch_sidezone \"%f\"\n", touch_sidezone.value );
FS_Printf( f, "touch_nonlinear_look \"%d\"\n", touch_nonlinear_look.value ? 1 : 0 );
FS_Printf( f, "touch_pow_factor \"%f\"\n", touch_pow_factor.value );
FS_Printf( f, "touch_pow_mult \"%f\"\n", touch_pow_mult.value );
FS_Printf( f, "touch_exp_mult \"%f\"\n", touch_exp_mult.value );
FS_Printf( f, "\n// grid settings\n" );
FS_Printf( f, "touch_grid_count \"%d\"\n", (int)touch_grid_count->value );
FS_Printf( f, "touch_grid_enable \"%d\"\n", CVAR_TO_BOOL(touch_grid_enable));
FS_Printf( f, "touch_grid_count \"%d\"\n", (int)touch_grid_count.value );
FS_Printf( f, "touch_grid_enable \"%d\"\n", touch_grid_enable.value ? 1 : 0 );
FS_Printf( f, "\n// global overstroke (width, r, g, b, a)\n" );
FS_Printf( f, "touch_set_stroke %d %d %d %d %d\n", touch.swidth, touch.scolor[0], touch.scolor[1], touch.scolor[2], touch.scolor[3] );
FS_Printf( f, "\n// highlight when pressed\n" );
FS_Printf( f, "touch_highlight_r \"%f\"\n", touch_highlight_r->value );
FS_Printf( f, "touch_highlight_g \"%f\"\n", touch_highlight_g->value );
FS_Printf( f, "touch_highlight_b \"%f\"\n", touch_highlight_b->value );
FS_Printf( f, "touch_highlight_a \"%f\"\n", touch_highlight_a->value );
FS_Printf( f, "touch_highlight_r \"%f\"\n", touch_highlight_r.value );
FS_Printf( f, "touch_highlight_g \"%f\"\n", touch_highlight_g.value );
FS_Printf( f, "touch_highlight_b \"%f\"\n", touch_highlight_b.value );
FS_Printf( f, "touch_highlight_a \"%f\"\n", touch_highlight_a.value );
FS_Printf( f, "\n// _joy and _dpad options\n" );
FS_Printf( f, "touch_dpad_radius \"%f\"\n", touch_dpad_radius->value );
FS_Printf( f, "touch_joy_radius \"%f\"\n", touch_joy_radius->value );
FS_Printf( f, "touch_dpad_radius \"%f\"\n", touch_dpad_radius.value );
FS_Printf( f, "touch_joy_radius \"%f\"\n", touch_joy_radius.value );
FS_Printf( f, "\n// how much slowdown when Precise Look button pressed\n" );
FS_Printf( f, "touch_precise_amount \"%f\"\n", touch_precise_amount->value );
FS_Printf( f, "touch_precise_amount \"%f\"\n", touch_precise_amount.value );
FS_Printf( f, "\n// enable/disable move indicator\n" );
FS_Printf( f, "touch_move_indicator \"%f\"\n", touch_move_indicator->value );
FS_Printf( f, "touch_move_indicator \"%f\"\n", touch_move_indicator.value );
FS_Printf( f, "\n// reset menu state when execing config\n" );
FS_Printf( f, "touch_setclientonly 0\n" );
@ -301,18 +300,18 @@ void Touch_WriteConfig( void )
if( Sys_CheckParm( "-nowriteconfig" ) || !touch.configchanged || !touch.config_loaded )
return;
Con_DPrintf( "Touch_WriteConfig(): %s\n", touch_config_file->string );
Con_DPrintf( "Touch_WriteConfig(): %s\n", touch_config_file.string );
Q_snprintf( newconfigfile, sizeof( newconfigfile ), "%s.new", touch_config_file->string );
Q_snprintf( oldconfigfile, sizeof( oldconfigfile ), "%s.bak", touch_config_file->string );
Q_snprintf( newconfigfile, sizeof( newconfigfile ), "%s.new", touch_config_file.string );
Q_snprintf( oldconfigfile, sizeof( oldconfigfile ), "%s.bak", touch_config_file.string );
if( Touch_DumpConfig( newconfigfile, touch_config_file->string ))
if( Touch_DumpConfig( newconfigfile, touch_config_file.string ))
{
FS_Delete( oldconfigfile );
FS_Rename( touch_config_file->string, oldconfigfile );
FS_Rename( touch_config_file.string, oldconfigfile );
FS_Delete( touch_config_file->string );
FS_Rename( newconfigfile, touch_config_file->string );
FS_Delete( touch_config_file.string );
FS_Rename( newconfigfile, touch_config_file.string );
}
}
@ -393,7 +392,7 @@ static void Touch_RoundAll_f( void )
{
touch_button_t *button;
if( !touch_grid_enable->value )
if( !touch_grid_enable.value )
return;
for( button = touch.list_user.first; button; button = button->next )
@ -737,7 +736,7 @@ static void Touch_ReloadConfig_f( void )
touch.edit = touch.selection = NULL;
touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1;
Cbuf_AddTextf( "exec %s\n", touch_config_file->string );
Cbuf_AddTextf( "exec %s\n", touch_config_file.string );
}
static touch_button_t *Touch_AddButton( touchbuttonlist_t *list,
@ -935,7 +934,7 @@ static void Touch_DisableEdit_f( void )
touch.edit = touch.selection = NULL;
touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1;
if( CVAR_TO_BOOL( touch_in_menu ))
if( touch_in_menu.value )
{
Cvar_Set( "touch_in_menu", "0" );
}
@ -1054,31 +1053,31 @@ void Touch_Init( void )
Cmd_AddRestrictedCommand( "touch_toggleselection", Touch_ToggleSelection_f, "toggle vidibility on selected button in editor" );
// not saved, just runtime state for scripting
touch_in_menu = Cvar_Get( "touch_in_menu", "0", FCVAR_FILTERABLE, "draw touch in menu (for internal use only)" );
Cvar_RegisterVariable( &touch_in_menu );
// sensitivity configuration
touch_forwardzone = Cvar_Get( "touch_forwardzone", "0.06", FCVAR_FILTERABLE, "forward touch zone" );
touch_sidezone = Cvar_Get( "touch_sidezone", "0.06", FCVAR_FILTERABLE, "side touch zone" );
touch_pitch = Cvar_Get( "touch_pitch", "90", FCVAR_FILTERABLE, "touch pitch sensitivity" );
touch_yaw = Cvar_Get( "touch_yaw", "120", FCVAR_FILTERABLE, "touch yaw sensitivity" );
touch_nonlinear_look = Cvar_Get( "touch_nonlinear_look", "0", FCVAR_FILTERABLE, "enable nonlinear touch look" );
touch_pow_factor = Cvar_Get( "touch_pow_factor", "1.3", FCVAR_FILTERABLE, "set > 1 to enable" );
touch_pow_mult = Cvar_Get( "touch_pow_mult", "400.0", FCVAR_FILTERABLE, "power multiplier, usually 200-1000" );
touch_exp_mult = Cvar_Get( "touch_exp_mult", "0", FCVAR_FILTERABLE, "exponent multiplier, usually 20-200, 0 to disable" );
Cvar_RegisterVariable( &touch_forwardzone );
Cvar_RegisterVariable( &touch_sidezone );
Cvar_RegisterVariable( &touch_pitch );
Cvar_RegisterVariable( &touch_yaw );
Cvar_RegisterVariable( &touch_nonlinear_look );
Cvar_RegisterVariable( &touch_pow_factor );
Cvar_RegisterVariable( &touch_pow_mult );
Cvar_RegisterVariable( &touch_exp_mult );
// touch.cfg
touch_grid_count = Cvar_Get( "touch_grid_count", "50", FCVAR_FILTERABLE, "touch grid count" );
touch_grid_enable = Cvar_Get( "touch_grid_enable", "1", FCVAR_FILTERABLE, "enable touch grid" );
touch_config_file = Cvar_Get( "touch_config_file", "touch.cfg", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "current touch profile file" );
touch_precise_amount = Cvar_Get( "touch_precise_amount", "0.5", FCVAR_FILTERABLE, "sensitivity multiplier for precise-look" );
touch_highlight_r = Cvar_Get( "touch_highlight_r", "1.0", 0, "highlight r color" );
touch_highlight_g = Cvar_Get( "touch_highlight_g", "1.0", 0, "highlight g color" );
touch_highlight_b = Cvar_Get( "touch_highlight_b", "1.0", 0, "highlight b color" );
touch_highlight_a = Cvar_Get( "touch_highlight_a", "1.0", 0, "highlight alpha" );
touch_dpad_radius = Cvar_Get( "touch_dpad_radius", "1.0", FCVAR_FILTERABLE, "dpad radius multiplier" );
touch_joy_radius = Cvar_Get( "touch_joy_radius", "1.0", FCVAR_FILTERABLE, "joy radius multiplier" );
touch_move_indicator = Cvar_Get( "touch_move_indicator", "0.0", FCVAR_FILTERABLE, "indicate move events (0 to disable)" );
touch_joy_texture = Cvar_Get( "touch_joy_texture", "touch_default/joy", FCVAR_FILTERABLE, "texture for move indicator");
Cvar_RegisterVariable( &touch_grid_count );
Cvar_RegisterVariable( &touch_grid_enable );
Cvar_RegisterVariable( &touch_config_file );
Cvar_RegisterVariable( &touch_precise_amount );
Cvar_RegisterVariable( &touch_highlight_r );
Cvar_RegisterVariable( &touch_highlight_g );
Cvar_RegisterVariable( &touch_highlight_b );
Cvar_RegisterVariable( &touch_highlight_a );
Cvar_RegisterVariable( &touch_dpad_radius );
Cvar_RegisterVariable( &touch_joy_radius );
Cvar_RegisterVariable( &touch_move_indicator );
Cvar_RegisterVariable( &touch_joy_texture );
// input devices cvar
Cvar_RegisterVariable( &touch_enable );
@ -1109,9 +1108,9 @@ static void Touch_InitConfig( void )
/// TODO: hud font
//pfnGetScreenInfo( NULL ); //HACK: update hud screen parameters like iHeight
if( FS_FileExists( touch_config_file->string, true ) )
if( FS_FileExists( touch_config_file.string, true ) )
{
Cbuf_AddTextf( "exec \"%s\"\n", touch_config_file->string );
Cbuf_AddTextf( "exec \"%s\"\n", touch_config_file.string );
Cbuf_Execute();
}
else
@ -1120,7 +1119,7 @@ static void Touch_InitConfig( void )
}
Touch_InitEditor();
touch.joytexture = ref.dllFuncs.GL_LoadTexture( touch_joy_texture->string, NULL, 0, TF_NOMIPMAP );
touch.joytexture = ref.dllFuncs.GL_LoadTexture( touch_joy_texture.string, NULL, 0, TF_NOMIPMAP );
touch.whitetexture = R_GetBuiltinTexture( REF_WHITE_TEXTURE );
touch.configchanged = false;
touch.config_loaded = true;
@ -1170,8 +1169,8 @@ static void Touch_DrawTexture ( float x1, float y1, float x2, float y2, int text
0, 0, 1, 1, texture );
}
#define GRID_COUNT_X ((int)touch_grid_count->value)
#define GRID_COUNT_Y (((int)touch_grid_count->value) * SCR_H / SCR_W)
#define GRID_COUNT_X ((int)touch_grid_count.value)
#define GRID_COUNT_Y (((int)touch_grid_count.value) * SCR_H / SCR_W)
#define GRID_X (1.0f/GRID_COUNT_X)
#define GRID_Y (SCR_W/SCR_H/GRID_COUNT_X)
#define GRID_ROUND_X(x) ((float)round( x * GRID_COUNT_X ) / GRID_COUNT_X)
@ -1192,7 +1191,7 @@ static void IN_TouchCheckCoords( float *x1, float *y1, float *x2, float *y2 )
*y1 -= *y2 - 1, *y2 = 1;
if( *x2 > 1 )
*x1 -= *x2 - 1, *x2 = 1;
if( CVAR_TO_BOOL( touch_grid_enable ))
if( touch_grid_enable.value )
{
*x1 = GRID_ROUND_X( *x1 );
*x2 = GRID_ROUND_X( *x2 );
@ -1288,10 +1287,10 @@ static void Touch_DrawButtons( touchbuttonlist_t *list )
if( ( B( finger ) != -1 ) && !FBitSet( B( flags ), TOUCH_FL_CLIENT ) )
{
color[0] = bound( 0,(float) color[0] * touch_highlight_r->value, 255 );
color[1] = bound( 0,(float) color[1] * touch_highlight_g->value, 255 );
color[2] = bound( 0,(float) color[2] * touch_highlight_b->value, 255 );
color[3] = bound( 0,(float) color[3] * touch_highlight_a->value, 255 );
color[0] = bound( 0,(float) color[0] * touch_highlight_r.value, 255 );
color[1] = bound( 0,(float) color[1] * touch_highlight_g.value, 255 );
color[2] = bound( 0,(float) color[2] * touch_highlight_b.value, 255 );
color[3] = bound( 0,(float) color[3] * touch_highlight_a.value, 255 );
}
color[3] *= B( fade );
@ -1360,15 +1359,15 @@ void Touch_Draw( void )
Touch_InitConfig();
if( cls.key_dest != key_game && !CVAR_TO_BOOL(touch_in_menu) )
if( cls.key_dest != key_game && !touch_in_menu.value )
return;
ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture );
if( touch.state >= state_edit && CVAR_TO_BOOL(touch_grid_enable) )
if( touch.state >= state_edit && touch_grid_enable.value )
{
float x;
if( CVAR_TO_BOOL(touch_in_menu) )
if( touch_in_menu.value )
Touch_DrawTexture( 0, 0, 1, 1, touch.whitetexture, 32, 32, 32, 255 );
else
Touch_DrawTexture( 0, 0, 1, 1, touch.whitetexture, 0, 0, 0, 112 );
@ -1429,19 +1428,19 @@ void Touch_Draw( void )
ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
if( ( touch.move_finger != -1 ) && touch.move_button && touch_move_indicator->value )
if( ( touch.move_finger != -1 ) && touch.move_button && touch_move_indicator.value )
{
float width;
float height;
if( FBitSet( touch_joy_texture->flags, FCVAR_CHANGED ) )
if( FBitSet( touch_joy_texture.flags, FCVAR_CHANGED ) )
{
ClearBits( touch_joy_texture->flags, FCVAR_CHANGED );
touch.joytexture = ref.dllFuncs.GL_LoadTexture( touch_joy_texture->string, NULL, 0, TF_NOMIPMAP );
ClearBits( touch_joy_texture.flags, FCVAR_CHANGED );
touch.joytexture = ref.dllFuncs.GL_LoadTexture( touch_joy_texture.string, NULL, 0, TF_NOMIPMAP );
}
if( touch.move_button->type == touch_move )
{
width = touch_sidezone->value;
height = touch_forwardzone->value;
width = touch_sidezone.value;
height = touch_forwardzone.value;
}
else
{
@ -1449,13 +1448,13 @@ void Touch_Draw( void )
height = (touch.move_button->y2 - touch.move_button->y1)/2;
}
ref.dllFuncs.Color4ub( 255, 255, 255, 128 );
ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( touch.move_start_x - GRID_X * touch_move_indicator->value ),
TO_SCRN_Y( touch.move_start_y - GRID_Y * touch_move_indicator->value ),
TO_SCRN_X( GRID_X * 2 * touch_move_indicator->value ), TO_SCRN_Y( GRID_Y * 2 * touch_move_indicator->value ), 0, 0, 1, 1, touch.joytexture );
ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( touch.move_start_x - GRID_X * touch_move_indicator.value ),
TO_SCRN_Y( touch.move_start_y - GRID_Y * touch_move_indicator.value ),
TO_SCRN_X( GRID_X * 2 * touch_move_indicator.value ), TO_SCRN_Y( GRID_Y * 2 * touch_move_indicator.value ), 0, 0, 1, 1, touch.joytexture );
ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( touch.move_start_x + touch.side * width - GRID_X * touch_move_indicator->value ),
TO_SCRN_Y( touch.move_start_y - touch.forward * height - GRID_Y * touch_move_indicator->value ),
TO_SCRN_X( GRID_X * 2 * touch_move_indicator->value ), TO_SCRN_Y( GRID_Y * 2 * touch_move_indicator->value ), 0, 0, 1, 1, touch.joytexture );
ref.dllFuncs.R_DrawStretchPic( TO_SCRN_X( touch.move_start_x + touch.side * width - GRID_X * touch_move_indicator.value ),
TO_SCRN_Y( touch.move_start_y - touch.forward * height - GRID_Y * touch_move_indicator.value ),
TO_SCRN_X( GRID_X * 2 * touch_move_indicator.value ), TO_SCRN_Y( GRID_Y * 2 * touch_move_indicator.value ), 0, 0, 1, 1, touch.joytexture );
}
@ -1564,28 +1563,28 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f
if( fingerID == touch.move_finger )
{
// check bounds
if( touch_forwardzone->value <= 0 )
if( touch_forwardzone.value <= 0 )
Cvar_SetValue( "touch_forwardzone", 0.5 );
if( touch_sidezone->value <= 0 )
if( touch_sidezone.value <= 0 )
Cvar_SetValue( "touch_sidezone", 0.3 );
if( !touch.move_button || touch.move_button->type == touch_move )
{
// move relative to touch start
touch.forward = ( touch.move_start_y - y ) / touch_forwardzone->value;
touch.side = ( x - touch.move_start_x ) / touch_sidezone->value;
touch.forward = ( touch.move_start_y - y ) / touch_forwardzone.value;
touch.side = ( x - touch.move_start_x ) / touch_sidezone.value;
}
else if( touch.move_button->type == touch_joy )
{
// move relative to joy center
touch.forward = ( ( touch.move_button->y2 + touch.move_button->y1 ) - y * 2 ) / ( touch.move_button->y2 - touch.move_button->y1 ) * touch_joy_radius->value;
touch.side = ( x * 2 - ( touch.move_button->x2 + touch.move_button->x1 ) ) / ( touch.move_button->x2 - touch.move_button->x1 ) * touch_joy_radius->value;
touch.forward = ( ( touch.move_button->y2 + touch.move_button->y1 ) - y * 2 ) / ( touch.move_button->y2 - touch.move_button->y1 ) * touch_joy_radius.value;
touch.side = ( x * 2 - ( touch.move_button->x2 + touch.move_button->x1 ) ) / ( touch.move_button->x2 - touch.move_button->x1 ) * touch_joy_radius.value;
}
else if( touch.move_button->type == touch_dpad )
{
// like joy, but without acceleration. useful for bhop
touch.forward = round( ( (touch.move_button->y2 + touch.move_button->y1) - y * 2 ) / ( touch.move_button->y2 - touch.move_button->y1 ) * touch_dpad_radius->value );
touch.side = round( ( x * 2 - (touch.move_button->x2 + touch.move_button->x1) ) / ( touch.move_button->x2 - touch.move_button->x1 ) * touch_dpad_radius->value );
touch.forward = round( ( (touch.move_button->y2 + touch.move_button->y1) - y * 2 ) / ( touch.move_button->y2 - touch.move_button->y1 ) * touch_dpad_radius.value );
touch.side = round( ( x * 2 - (touch.move_button->x2 + touch.move_button->x1) ) / ( touch.move_button->x2 - touch.move_button->x1 ) * touch_dpad_radius.value );
}
touch.forward = bound( -1, touch.forward, 1 );
@ -1596,9 +1595,9 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f
if( fingerID == touch.look_finger )
{
if( touch.precision )
dx *= touch_precise_amount->value, dy *= touch_precise_amount->value;
dx *= touch_precise_amount.value, dy *= touch_precise_amount.value;
if( CVAR_TO_BOOL(touch_nonlinear_look) )
if( touch_nonlinear_look.value )
{
float dabs, dcos, dsin;
@ -1611,11 +1610,11 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f
dcos = dx / dabs;
dsin = dy / dabs;
if( touch_exp_mult->value > 1 )
dabs = ( exp( dabs * touch_exp_mult->value ) - 1 ) / touch_exp_mult->value;
if( touch_exp_mult.value > 1 )
dabs = ( exp( dabs * touch_exp_mult.value ) - 1 ) / touch_exp_mult.value;
if( touch_pow_mult->value > 1 && touch_pow_factor->value > 1 )
dabs = pow( dabs * touch_pow_mult->value, touch_pow_factor->value ) / touch_pow_mult->value;
if( touch_pow_mult.value > 1 && touch_pow_factor.value > 1 )
dabs = pow( dabs * touch_pow_mult.value, touch_pow_factor.value ) / touch_pow_mult.value;
dx = dabs * dcos;
dy = dabs * dsin;
@ -1626,7 +1625,7 @@ static void Touch_Motion( touchEventType type, int fingerID, float x, float y, f
return;
// accumulate
touch.yaw -= dx * touch_yaw->value, touch.pitch += dy * touch_pitch->value;
touch.yaw -= dx * touch_yaw.value, touch.pitch += dy * touch_pitch.value;
}
}
@ -1950,7 +1949,7 @@ static int Touch_ControlsEvent( touchEventType type, int fingerID, float x, floa
int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy )
{
// simulate menu mouse click
if( cls.key_dest != key_game && !CVAR_TO_BOOL( touch_in_menu ))
if( cls.key_dest != key_game && !touch_in_menu.value )
{
touch.move_finger = touch.resize_finger = touch.look_finger = -1;
// Hack for keyboard, hope it help

View File

@ -36,16 +36,15 @@ static struct inputstate_s
float lastpitch, lastyaw;
} inputstate;
extern convar_t *vid_fullscreen;
convar_t *m_pitch;
convar_t *m_yaw;
CVAR_DEFINE_AUTO( m_pitch, "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse pitch value" );
CVAR_DEFINE_AUTO( m_yaw, "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse yaw value" );
CVAR_DEFINE_AUTO( m_ignore, DEFAULT_M_IGNORE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "ignore mouse events" );
static CVAR_DEFINE_AUTO( look_filter, "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "filter look events making it smoother" );
static CVAR_DEFINE_AUTO( m_rawinput, "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable mouse raw input" );
convar_t *m_ignore;
convar_t *cl_forwardspeed;
convar_t *cl_sidespeed;
convar_t *cl_backspeed;
convar_t *look_filter;
convar_t *m_rawinput;
static CVAR_DEFINE_AUTO( cl_forwardspeed, "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default forward move speed" );
static CVAR_DEFINE_AUTO( cl_backspeed, "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default back move speed" );
static CVAR_DEFINE_AUTO( cl_sidespeed, "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default side move speed" );
/*
================
@ -58,7 +57,7 @@ uint IN_CollectInputDevices( void )
{
uint ret = 0;
if( !m_ignore->value ) // no way to check is mouse connected, so use cvar only
if( !m_ignore.value ) // no way to check is mouse connected, so use cvar only
ret |= INPUT_DEVICE_MOUSE;
if( touch_enable.value )
@ -86,18 +85,18 @@ player is connected to the server
*/
void IN_LockInputDevices( qboolean lock )
{
extern convar_t *joy_enable; // private to input system
extern convar_t joy_enable; // private to input system
if( lock )
{
SetBits( m_ignore->flags, FCVAR_READ_ONLY );
SetBits( joy_enable->flags, FCVAR_READ_ONLY );
SetBits( m_ignore.flags, FCVAR_READ_ONLY );
SetBits( joy_enable.flags, FCVAR_READ_ONLY );
SetBits( touch_enable.flags, FCVAR_READ_ONLY );
}
else
{
ClearBits( m_ignore->flags, FCVAR_READ_ONLY );
ClearBits( joy_enable->flags, FCVAR_READ_ONLY );
ClearBits( m_ignore.flags, FCVAR_READ_ONLY );
ClearBits( joy_enable.flags, FCVAR_READ_ONLY );
ClearBits( touch_enable.flags, FCVAR_READ_ONLY );
}
}
@ -110,12 +109,12 @@ IN_StartupMouse
*/
void IN_StartupMouse( void )
{
m_ignore = Cvar_Get( "m_ignore", DEFAULT_M_IGNORE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "ignore mouse events" );
Cvar_RegisterVariable( &m_ignore );
m_pitch = Cvar_Get( "m_pitch", "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse pitch value" );
m_yaw = Cvar_Get( "m_yaw", "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse yaw value" );
look_filter = Cvar_Get( "look_filter", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "filter look events making it smoother" );
m_rawinput = Cvar_Get( "m_rawinput", "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable mouse raw input" );
Cvar_RegisterVariable( &m_pitch );
Cvar_RegisterVariable( &m_yaw );
Cvar_RegisterVariable( &look_filter );
Cvar_RegisterVariable( &m_rawinput );
// You can use -nomouse argument to prevent using mouse from client
// -noenginemouse will disable all mouse input
@ -180,9 +179,6 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
{
Platform_SetCursorType( dc_arrow );
#if XASH_ANDROID
Android_ShowMouse( true );
#endif
#if XASH_USE_EVDEV
Evdev_SetGrab( false );
#endif
@ -191,9 +187,6 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
{
Platform_SetCursorType( dc_none );
#if XASH_ANDROID
Android_ShowMouse( false );
#endif
#if XASH_USE_EVDEV
Evdev_SetGrab( true );
#endif
@ -214,7 +207,7 @@ void IN_CheckMouseState( qboolean active )
static qboolean s_bRawInput, s_bMouseGrab;
#if XASH_WIN32
qboolean useRawInput = ( CVAR_TO_BOOL( m_rawinput ) && clgame.client_dll_uses_sdl ) || clgame.dllFuncs.pfnLookEvent != NULL;
qboolean useRawInput = ( m_rawinput.value && clgame.client_dll_uses_sdl ) || clgame.dllFuncs.pfnLookEvent != NULL;
#else
qboolean useRawInput = true; // always use SDL code
#endif
@ -414,9 +407,9 @@ IN_Init
*/
void IN_Init( void )
{
cl_forwardspeed = Cvar_Get( "cl_forwardspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default forward move speed" );
cl_backspeed = Cvar_Get( "cl_backspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default back move speed" );
cl_sidespeed = Cvar_Get( "cl_sidespeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default side move speed" );
Cvar_RegisterVariable( &cl_forwardspeed );
Cvar_RegisterVariable( &cl_backspeed );
Cvar_RegisterVariable( &cl_sidespeed );
if( !Host_IsDedicated() )
{
@ -453,8 +446,8 @@ static void IN_JoyAppendMove( usercmd_t *cmd, float forwardmove, float sidemove
{
static uint moveflags = T | S;
if( forwardmove ) cmd->forwardmove = forwardmove * cl_forwardspeed->value;
if( sidemove ) cmd->sidemove = sidemove * cl_sidespeed->value;
if( forwardmove ) cmd->forwardmove = forwardmove * cl_forwardspeed.value;
if( sidemove ) cmd->sidemove = sidemove * cl_sidespeed.value;
if( forwardmove )
{
@ -529,8 +522,8 @@ static void IN_CollectInput( float *forward, float *side, float *pitch, float *y
{
float x, y;
Platform_MouseMove( &x, &y );
*pitch += y * m_pitch->value;
*yaw -= x * m_yaw->value;
*pitch += y * m_pitch.value;
*yaw -= x * m_yaw.value;
#if XASH_USE_EVDEV
IN_EvdevMove( yaw, pitch );
@ -540,7 +533,7 @@ static void IN_CollectInput( float *forward, float *side, float *pitch, float *y
Joy_FinalizeMove( forward, side, yaw, pitch );
Touch_GetMove( forward, side, yaw, pitch );
if( look_filter->value )
if( look_filter.value )
{
*pitch = ( inputstate.lastpitch + *pitch ) / 2;
*yaw = ( inputstate.lastyaw + *yaw ) / 2;
@ -598,7 +591,7 @@ void IN_Commands( void )
{
float forward = 0, side = 0, pitch = 0, yaw = 0;
IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized && !CVAR_TO_BOOL( m_ignore ) );
IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized && !m_ignore.value );
if( cls.key_dest == key_game )
{

View File

@ -46,8 +46,8 @@ uint IN_CollectInputDevices( void );
void IN_LockInputDevices( qboolean lock );
void IN_EngineAppendMove( float frametime, void *cmd, qboolean active );
extern convar_t *m_yaw;
extern convar_t *m_pitch;
extern convar_t m_yaw;
extern convar_t m_pitch;
//
// in_touch.c
//

View File

@ -144,8 +144,8 @@ keyname_t keynames[] =
static void OSK_EnableTextInput( qboolean enable, qboolean force );
static qboolean OSK_KeyEvent( int key, int down );
static convar_t *osk_enable;
static convar_t *key_rotate;
static CVAR_DEFINE_AUTO( osk_enable, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "enable built-in on-screen keyboard" );
static CVAR_DEFINE_AUTO( key_rotate, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "rotate arrow keys (0-3)" );
/*
===================
@ -513,8 +513,8 @@ void Key_Init( void )
// setup default binding. "unbindall" from config.cfg will be reset it
for( kn = keynames; kn->name; kn++ ) Key_SetBinding( kn->keynum, kn->binding );
osk_enable = Cvar_Get( "osk_enable", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable built-in on-screen keyboard" );
key_rotate = Cvar_Get( "key_rotate", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "rotate arrow keys (0-3)" );
Cvar_RegisterVariable( &osk_enable );
Cvar_RegisterVariable( &key_rotate );
}
@ -590,7 +590,7 @@ static qboolean Key_IsAllowedAutoRepeat( int key )
static int Key_Rotate( int key )
{
if( key_rotate->value == 1.0f ) // CW
if( key_rotate.value == 1.0f ) // CW
{
if( key == K_UPARROW )
key = K_LEFTARROW;
@ -602,7 +602,7 @@ static int Key_Rotate( int key )
key = K_RIGHTARROW;
}
else if( key_rotate->value == 3.0f ) // CCW
else if( key_rotate.value == 3.0f ) // CCW
{
if( key == K_UPARROW )
key = K_RIGHTARROW;
@ -614,7 +614,7 @@ static int Key_Rotate( int key )
key = K_LEFTARROW;
}
else if( key_rotate->value == 2.0f )
else if( key_rotate.value == 2.0f )
{
if( key == K_UPARROW )
key = K_DOWNARROW;
@ -719,10 +719,10 @@ void GAME_EXPORT Key_Event( int key, int down )
switch( cls.key_dest )
{
case key_game:
if( CVAR_TO_BOOL( gl_showtextures ))
if( r_showtextures.value )
{
// close texture atlas
Cvar_SetValue( "r_showtextures", 0.0f );
Cvar_DirectSet( &r_showtextures, "0" );
return;
}
else if( host.mouse_visible && cls.state != ca_cinematic )
@ -797,7 +797,7 @@ Key_EnableTextInput
*/
void Key_EnableTextInput( qboolean enable, qboolean force )
{
if( CVAR_TO_BOOL( osk_enable ) )
if( osk_enable.value )
{
OSK_EnableTextInput( enable, force );
return;
@ -995,7 +995,7 @@ struct osk_s
static qboolean OSK_KeyEvent( int key, int down )
{
if( !osk.enable || !CVAR_TO_BOOL( osk_enable ) )
if( !osk.enable || !osk_enable.value )
return false;
if( osk.sending )
@ -1055,7 +1055,7 @@ static qboolean OSK_KeyEvent( int key, int down )
break;
}
if( !Q_stricmp( cl_charset->string, "utf-8" ) )
if( !Q_stricmp( cl_charset.string, "utf-8" ) )
ch = (unsigned char)osk.curbutton.val;
else
ch = Con_UtfProcessCharForce( (unsigned char)osk.curbutton.val );
@ -1190,7 +1190,7 @@ void OSK_Draw( void )
float x, y;
int i, j;
if( !osk.enable || !CVAR_TO_BOOL(osk_enable) || !osk.curbutton.val )
if( !osk.enable || !osk_enable.value || !osk.curbutton.val )
return;
// draw keyboard

View File

@ -8,15 +8,15 @@
struct ref_state_s ref;
ref_globals_t refState;
convar_t *gl_vsync;
convar_t *gl_showtextures;
convar_t *r_decals;
convar_t *r_adjust_fov;
convar_t *r_showtree;
convar_t *gl_msaa_samples;
convar_t *gl_clear;
convar_t *r_refdll;
convar_t *r_refdll_loaded;
CVAR_DEFINE_AUTO( gl_vsync, "0", FCVAR_ARCHIVE, "enable vertical syncronization" );
CVAR_DEFINE_AUTO( r_showtextures, "0", FCVAR_CHEAT, "show all uploaded textures" );
CVAR_DEFINE_AUTO( r_adjust_fov, "1", FCVAR_ARCHIVE, "making FOV adjustment for wide-screens" );
CVAR_DEFINE_AUTO( r_decals, "4096", FCVAR_ARCHIVE, "sets the maximum number of decals" );
CVAR_DEFINE_AUTO( gl_msaa_samples, "0", FCVAR_GLCONFIG, "samples number for multisample anti-aliasing" );
CVAR_DEFINE_AUTO( gl_clear, "0", FCVAR_ARCHIVE, "clearing screen after each frame" );
CVAR_DEFINE_AUTO( r_showtree, "0", FCVAR_ARCHIVE, "build the graph of visible BSP tree" );
static CVAR_DEFINE_AUTO( r_refdll, "", FCVAR_RENDERINFO, "choose renderer implementation, if supported" );
static CVAR_DEFINE_AUTO( r_refdll_loaded, "", FCVAR_READ_ONLY, "currently loaded renderer" );
void R_GetTextureParms( int *w, int *h, int texnum )
{
@ -232,7 +232,7 @@ static ref_api_t gEngfuncs =
Cvar_VariableString,
Cvar_SetValue,
Cvar_Set,
(void*)Cvar_RegisterVariable,
Cvar_RegisterVariable,
Cvar_FullSet,
Cmd_AddRefCommand,
@ -384,14 +384,14 @@ static void R_UnloadProgs( void )
Cvar_FullSet( "host_refloaded", "0", FCVAR_READ_ONLY );
Cvar_Unlink( FCVAR_RENDERINFO | FCVAR_GLCONFIG );
Cmd_Unlink( CMD_REFDLL );
COM_FreeLibrary( ref.hInstance );
ref.hInstance = NULL;
memset( &refState, 0, sizeof( refState ));
memset( &ref.dllFuncs, 0, sizeof( ref.dllFuncs ));
Cvar_Unlink( FCVAR_RENDERINFO | FCVAR_GLCONFIG );
Cmd_Unlink( CMD_REFDLL );
}
static void CL_FillTriAPIFromRef( triangleapi_t *dst, const ref_interface_t *src )
@ -563,11 +563,11 @@ static void SetFullscreenModeFromCommandLine( void )
#if !XASH_MOBILE_PLATFORM
if( Sys_CheckParm( "-fullscreen" ))
{
Cvar_Set( "fullscreen", "1" );
Cvar_DirectSet( &vid_fullscreen, "1" );
}
else if( Sys_CheckParm( "-windowed" ))
{
Cvar_Set( "fullscreen", "0" );
Cvar_DirectSet( &vid_fullscreen, "0" );
}
#endif
}
@ -627,7 +627,7 @@ static void R_CollectRendererNames( void )
const ref_device_t *R_GetRenderDevice( unsigned int idx )
{
if( !Q_stricmp( r_refdll_loaded->string, "vk" ))
if( !Q_stricmp( r_refdll_loaded.string, "vk" ))
{
if( !ref.dllFuncs.pfnGetVulkanRenderDevice )
return NULL;
@ -661,10 +661,10 @@ static void R_GetRenderDevices_f( void )
int i = 0;
const ref_device_t *device = NULL;
if( Q_stricmp( r_refdll_loaded->string, "vk" ) ||
if( Q_stricmp( r_refdll_loaded.string, "vk" ) ||
!ref.dllFuncs.pfnGetVulkanRenderDevice )
{
Con_Printf( "Renderer %s doesn't implement this!\n", r_refdll_loaded->string );
Con_Printf( "Renderer %s doesn't implement this!\n", r_refdll_loaded.string );
return;
}
@ -689,15 +689,15 @@ qboolean R_Init( void )
qboolean success = false;
string requested;
gl_vsync = Cvar_Get( "gl_vsync", "0", FCVAR_ARCHIVE, "enable vertical syncronization" );
gl_showtextures = Cvar_Get( "r_showtextures", "0", FCVAR_CHEAT, "show all uploaded textures" );
r_adjust_fov = Cvar_Get( "r_adjust_fov", "1", FCVAR_ARCHIVE, "making FOV adjustment for wide-screens" );
r_decals = Cvar_Get( "r_decals", "4096", FCVAR_ARCHIVE, "sets the maximum number of decals" );
gl_msaa_samples = Cvar_Get( "gl_msaa_samples", "0", FCVAR_GLCONFIG, "samples number for multisample anti-aliasing" );
gl_clear = Cvar_Get( "gl_clear", "0", FCVAR_ARCHIVE, "clearing screen after each frame" );
r_showtree = Cvar_Get( "r_showtree", "0", FCVAR_ARCHIVE, "build the graph of visible BSP tree" );
r_refdll = Cvar_Get( "r_refdll", "", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "choose renderer implementation, if supported" );
r_refdll_loaded = Cvar_Get( "r_refdll_loaded", "", FCVAR_READ_ONLY, "currently loaded renderer" );
Cvar_RegisterVariable( &gl_vsync );
Cvar_RegisterVariable( &r_showtextures );
Cvar_RegisterVariable( &r_adjust_fov );
Cvar_RegisterVariable( &r_decals );
Cvar_RegisterVariable( &gl_msaa_samples );
Cvar_RegisterVariable( &gl_clear );
Cvar_RegisterVariable( &r_showtree );
Cvar_RegisterVariable( &r_refdll );
Cvar_RegisterVariable( &r_refdll_loaded );
// cvars that are expected to exist
Cvar_Get( "r_speeds", "0", FCVAR_ARCHIVE, "shows renderer speeds" );
@ -743,9 +743,9 @@ qboolean R_Init( void )
if( !success && Sys_GetParmFromCmdLine( "-ref", requested ))
success = R_LoadRenderer( requested );
if( !success && COM_CheckString( r_refdll->string ))
if( !success && COM_CheckString( r_refdll.string ))
{
Q_strncpy( requested, r_refdll->string, sizeof( requested ));
Q_strncpy( requested, r_refdll.string, sizeof( requested ));
success = R_LoadRenderer( requested );
}
@ -765,7 +765,7 @@ qboolean R_Init( void )
if( !success )
{
Host_Error( "Can't initialize any renderer. Check your video drivers!" );
Host_Error( "Can't initialize any renderer. Check your video drivers!\n" );
return false;
}

View File

@ -46,9 +46,9 @@ void R_GetTextureParms( int *w, int *h, int texnum );
void GL_RenderFrame( const struct ref_viewpass_s *rvp );
// common engine and renderer cvars
extern convar_t *r_decals;
extern convar_t *r_adjust_fov;
extern convar_t *gl_clear;
extern convar_t r_decals;
extern convar_t r_adjust_fov;
extern convar_t gl_clear;
qboolean R_Init( void );
void R_Shutdown( void );

View File

@ -78,7 +78,7 @@ typedef struct dly_s
int *lpdelayline;
} dly_t;
const sx_preset_t rgsxpre[] =
static const sx_preset_t rgsxpre[] =
{
// -------reverb-------- -------delay--------
// lp mod size refl rvblp delay feedback dlylp left
@ -115,7 +115,7 @@ const sx_preset_t rgsxpre[] =
// 0x0045dca8 enginegl.exe
// SHA256: 42383d32cd712e59ee2c1bd78b7ba48814e680e7026c4223e730111f34a60d66
const sx_preset_t rgsxpre_hlalpha052[] =
static const sx_preset_t rgsxpre_hlalpha052[] =
{
// -------reverb-------- -------delay--------
// lp mod size refl rvblp delay feedback dlylp left
@ -150,51 +150,50 @@ const sx_preset_t rgsxpre_hlalpha052[] =
{ 0.0, 0.0, 0.001, 0.999, 0.0, 0.2, 0.8, 2.0, 0.05 }, // 28
};
const sx_preset_t *ptable = rgsxpre;
static const sx_preset_t *ptable = rgsxpre;
// cvars
convar_t *dsp_off; // disable dsp
convar_t *roomwater_type; // water room_type
convar_t *room_type; // current room type
convar_t *hisound; // DSP quality
static CVAR_DEFINE_AUTO( dsp_off, "0", FCVAR_ARCHIVE, "disable DSP processing" );
static CVAR_DEFINE_AUTO( dsp_coeff_table, "0", FCVAR_ARCHIVE, "select DSP coefficient table: 0 for release or 1 for alpha 0.52" );
static CVAR_DEFINE_AUTO( room_type, "0", 0, "current room type preset" );
static CVAR_DEFINE( roomwater_type, "waterroom_type", "14", 0, "water room type" );
static CVAR_DEFINE( hisound, "room_hires", "2", FCVAR_ARCHIVE, "dsp quality. 1 for 22k, 2 for 44k(recommended) and 3 for 96k" );
// underwater/special fx modulations
convar_t *sxmod_mod;
convar_t *sxmod_lowpass;
static CVAR_DEFINE( sxmod_mod, "room_mod", "0", 0, "stereo amptitude modulation for room" );
static CVAR_DEFINE( sxmod_lowpass, "room_lp", "0", 0, "for water fx, lowpass for entire room" );
// stereo delay(no feedback)
convar_t *sxste_delay; // straight left delay
static CVAR_DEFINE( sxste_delay, "room_left", "0", 0, "left channel delay time" );
// mono reverb
convar_t *sxrvb_lp; // lowpass
convar_t *sxrvb_feedback; // reverb decay. Higher -- longer
convar_t *sxrvb_size; // room size. Higher -- larger
static CVAR_DEFINE( sxrvb_lp, "room_rvblp", "1", 0, "reverb: low pass filtering level" );
static CVAR_DEFINE( sxrvb_feedback, "room_refl", "0", 0, "reverb: decay time" );
static CVAR_DEFINE( sxrvb_size, "room_size", "0", 0, "reverb: initial reflection size" );
// mono delay
convar_t *sxdly_lp; // lowpass
convar_t *sxdly_feedback; // cycles
convar_t *sxdly_delay; // current delay in seconds
static CVAR_DEFINE( sxdly_lp, "room_dlylp", "1", 0, "mono delay: low pass filtering level" );
static CVAR_DEFINE( sxdly_feedback, "room_feedback", "0.2", 0, "mono delay: decay time" );
static CVAR_DEFINE( sxdly_delay, "room_delay", "0.8", 0, "mono delay: delay time" );
convar_t *dsp_room; // for compability
convar_t *dsp_coeff_table; // use release or 0.52 style
int idsp_dma_speed;
static int idsp_dma_speed;
int idsp_room;
int room_typeprev;
static int room_typeprev;
// routines
int sxamodl, sxamodr; // amplitude modulation values
int sxamodlt, sxamodrt; // modulation targets
int sxmod1cur, sxmod2cur;
int sxmod1, sxmod2;
int sxhires;
static int sxamodl, sxamodr; // amplitude modulation values
static int sxamodlt, sxamodrt; // modulation targets
static int sxmod1cur, sxmod2cur;
static int sxmod1, sxmod2;
static int sxhires;
portable_samplepair_t *paintto = NULL;
static portable_samplepair_t *paintto = NULL;
dly_t rgsxdly[MAXDLY]; // stereo is last
int rgsxlp[MAXLP];
static dly_t rgsxdly[MAXDLY]; // stereo is last
static int rgsxlp[MAXLP];
void SX_Profiling_f( void );
static void SX_Profiling_f( void );
/*
============
@ -202,14 +201,12 @@ SX_ReloadRoomFX
============
*/
void SX_ReloadRoomFX( void )
static void SX_ReloadRoomFX( void )
{
if( !dsp_room ) return; // not initialized
SetBits( sxste_delay->flags, FCVAR_CHANGED );
SetBits( sxrvb_feedback->flags, FCVAR_CHANGED );
SetBits( sxdly_delay->flags, FCVAR_CHANGED );
SetBits( room_type->flags, FCVAR_CHANGED );
SetBits( sxste_delay.flags, FCVAR_CHANGED );
SetBits( sxrvb_feedback.flags, FCVAR_CHANGED );
SetBits( sxdly_delay.flags, FCVAR_CHANGED );
SetBits( room_type.flags, FCVAR_CHANGED );
}
/*
@ -227,36 +224,33 @@ void SX_Init( void )
sxamodr = sxamodl = sxamodrt = sxamodlt = 255;
idsp_dma_speed = SOUND_11k;
hisound = Cvar_Get( "room_hires", "2", FCVAR_ARCHIVE, "dsp quality. 1 for 22k, 2 for 44k(recommended) and 3 for 96k" );
Cvar_RegisterVariable( &hisound );
sxhires = 2;
sxmod1cur = sxmod1 = 350 * ( idsp_dma_speed / SOUND_11k );
sxmod2cur = sxmod2 = 450 * ( idsp_dma_speed / SOUND_11k );
dsp_off = Cvar_Get( "dsp_off", "0", FCVAR_ARCHIVE, "disable DSP processing" );
dsp_coeff_table = Cvar_Get( "dsp_coeff_table", "0", FCVAR_ARCHIVE, "select DSP coefficient table: 0 for release or 1 for alpha 0.52" );
Cvar_RegisterVariable( &dsp_off );
Cvar_RegisterVariable( &dsp_coeff_table );
roomwater_type = Cvar_Get( "waterroom_type", "14", 0, "water room type" );
room_type = Cvar_Get( "room_type", "0", 0, "current room type preset" );
Cvar_RegisterVariable( &roomwater_type );
Cvar_RegisterVariable( &room_type );
sxmod_lowpass = Cvar_Get( "room_lp", "0", 0, "for water fx, lowpass for entire room" );
sxmod_mod = Cvar_Get( "room_mod", "0", 0, "stereo amptitude modulation for room" );
Cvar_RegisterVariable( &sxmod_lowpass );
Cvar_RegisterVariable( &sxmod_mod );
sxrvb_size = Cvar_Get( "room_size", "0", 0, "reverb: initial reflection size" );
sxrvb_feedback = Cvar_Get( "room_refl", "0", 0, "reverb: decay time" );
sxrvb_lp = Cvar_Get( "room_rvblp", "1", 0, "reverb: low pass filtering level" );
Cvar_RegisterVariable( &sxrvb_size );
Cvar_RegisterVariable( &sxrvb_feedback );
Cvar_RegisterVariable( &sxrvb_lp );
sxdly_delay = Cvar_Get( "room_delay", "0.8", 0, "mono delay: delay time" );
sxdly_feedback = Cvar_Get( "room_feedback", "0.2", 0, "mono delay: decay time" );
sxdly_lp = Cvar_Get( "room_dlylp", "1", 0, "mono delay: low pass filtering level" );
Cvar_RegisterVariable( &sxdly_delay );
Cvar_RegisterVariable( &sxdly_feedback );
Cvar_RegisterVariable( &sxdly_lp );
sxste_delay = Cvar_Get( "room_left", "0", 0, "left channel delay time" );
Cvar_RegisterVariable( &sxste_delay );
Cmd_AddCommand( "dsp_profile", SX_Profiling_f, "dsp stress-test, first argument is room_type" );
// for compability
dsp_room = room_type;
SX_ReloadRoomFX();
}
@ -267,7 +261,7 @@ DLY_Free
Free memory allocated for DSP
===========
*/
void DLY_Free( int idelay )
static void DLY_Free( int idelay )
{
Assert( idelay >= 0 && idelay < MAXDLY );
@ -303,7 +297,7 @@ DLY_Init
Initialize dly
===========
*/
int DLY_Init( int idelay, float delay )
static int DLY_Init( int idelay, float delay )
{
dly_t *cur;
@ -355,12 +349,12 @@ DLY_CheckNewStereoDelayVal
Update stereo processor settings if we are in new room
=============
*/
void DLY_CheckNewStereoDelayVal( void )
static void DLY_CheckNewStereoDelayVal( void )
{
dly_t *const dly = &rgsxdly[STEREODLY];
float delay = sxste_delay->value;
float delay = sxste_delay.value;
if( !FBitSet( sxste_delay->flags, FCVAR_CHANGED ))
if( !FBitSet( sxste_delay.flags, FCVAR_CHANGED ))
return;
if( delay == 0 )
@ -403,7 +397,7 @@ DLY_DoStereoDelay
Do stereo processing
=============
*/
void DLY_DoStereoDelay( int count )
static void DLY_DoStereoDelay( int count )
{
int delay, samplexf;
dly_t *const dly = &rgsxdly[STEREODLY];
@ -468,12 +462,12 @@ DLY_CheckNewDelayVal
Update delay processor settings if we are in new room
=============
*/
void DLY_CheckNewDelayVal( void )
static void DLY_CheckNewDelayVal( void )
{
float delay = sxdly_delay->value;
float delay = sxdly_delay.value;
dly_t *const dly = &rgsxdly[MONODLY];
if( FBitSet( sxdly_delay->flags, FCVAR_CHANGED ))
if( FBitSet( sxdly_delay.flags, FCVAR_CHANGED ))
{
if( delay == 0 )
{
@ -503,8 +497,8 @@ void DLY_CheckNewDelayVal( void )
}
}
dly->lp = sxdly_lp->value;
dly->delayfeedback = 255 * sxdly_feedback->value;
dly->lp = sxdly_lp.value;
dly->delayfeedback = 255 * sxdly_feedback.value;
}
/*
@ -514,7 +508,7 @@ DLY_DoDelay
Do delay processing
=============
*/
void DLY_DoDelay( int count )
static void DLY_DoDelay( int count )
{
dly_t *const dly = &rgsxdly[MONODLY];
portable_samplepair_t *paint = paintto;
@ -565,7 +559,7 @@ RVB_SetUpDly
Set up dly for reverb
===========
*/
void RVB_SetUpDly( int pos, float delay, int kmod )
static void RVB_SetUpDly( int pos, float delay, int kmod )
{
int samples;
@ -601,13 +595,13 @@ RVB_CheckNewReverbVal
Update reverb settings if we are in new room
===========
*/
void RVB_CheckNewReverbVal( void )
static void RVB_CheckNewReverbVal( void )
{
dly_t *const dly1 = &rgsxdly[REVERBPOS];
dly_t *const dly2 = &rgsxdly[REVERBPOS + 1];
float delay = sxrvb_size->value;
float delay = sxrvb_size.value;
if( FBitSet( sxrvb_size->flags, FCVAR_CHANGED ))
if( FBitSet( sxrvb_size.flags, FCVAR_CHANGED ))
{
if( delay == 0.0f )
{
@ -616,13 +610,13 @@ void RVB_CheckNewReverbVal( void )
}
else
{
RVB_SetUpDly( REVERBPOS, sxrvb_size->value, 500 );
RVB_SetUpDly( REVERBPOS+1, sxrvb_size->value * 0.71f, 700 );
RVB_SetUpDly( REVERBPOS, sxrvb_size.value, 500 );
RVB_SetUpDly( REVERBPOS+1, sxrvb_size.value * 0.71f, 700 );
}
}
dly1->lp = dly2->lp = sxrvb_lp->value;
dly1->delayfeedback = dly2->delayfeedback = (int)(255 * sxrvb_feedback->value);
dly1->lp = dly2->lp = sxrvb_lp.value;
dly1->delayfeedback = dly2->delayfeedback = (int)(255 * sxrvb_feedback.value);
}
/*
@ -632,7 +626,7 @@ RVB_DoReverbForOneDly
Do reverberation for one dly
===========
*/
int RVB_DoReverbForOneDly( dly_t *dly, const int vlr, const portable_samplepair_t *samplepair )
static int RVB_DoReverbForOneDly( dly_t *dly, const int vlr, const portable_samplepair_t *samplepair )
{
int delay;
int samplexf;
@ -706,7 +700,7 @@ RVB_DoReverb
Do reverberation processing
===========
*/
void RVB_DoReverb( int count )
static void RVB_DoReverb( int count )
{
dly_t *const dly1 = &rgsxdly[REVERBPOS];
dly_t *const dly2 = &rgsxdly[REVERBPOS+1];
@ -723,7 +717,7 @@ void RVB_DoReverb( int count )
voutm = RVB_DoReverbForOneDly( dly1, vlr, paint );
voutm += RVB_DoReverbForOneDly( dly2, vlr, paint );
if( dsp_coeff_table->value == 1.0f )
if( dsp_coeff_table.value == 1.0f )
voutm /= 6; // alpha
else voutm = (11 * voutm) >> 6;
@ -739,18 +733,18 @@ RVB_DoAMod
Do amplification modulation processing
===========
*/
void RVB_DoAMod( int count )
static void RVB_DoAMod( int count )
{
portable_samplepair_t *paint = paintto;
if( !sxmod_lowpass->value && !sxmod_mod->value )
if( !sxmod_lowpass.value && !sxmod_mod.value )
return;
for( ; count; count--, paint++ )
{
portable_samplepair_t res = *paint;
if( sxmod_lowpass->value )
if( sxmod_lowpass.value )
{
res.left = rgsxlp[0] + rgsxlp[1] + rgsxlp[2] + rgsxlp[3] + rgsxlp[4] + res.left;
res.right = rgsxlp[5] + rgsxlp[6] + rgsxlp[7] + rgsxlp[8] + rgsxlp[9] + res.right;
@ -772,7 +766,7 @@ void RVB_DoAMod( int count )
rgsxlp[8] = rgsxlp[9];
}
if( sxmod_mod->value )
if( sxmod_mod.value )
{
if( --sxmod1cur < 0 )
sxmod1cur = sxmod1;
@ -814,7 +808,7 @@ DSP_Process
*/
void DSP_Process( int idsp, portable_samplepair_t *pbfront, int sampleCount )
{
if( dsp_off->value )
if( dsp_off.value )
return;
// don't process DSP while in menu
@ -852,12 +846,12 @@ CheckNewDspPresets
*/
void CheckNewDspPresets( void )
{
if( dsp_off->value != 0.0f )
if( dsp_off.value != 0.0f )
return;
if( FBitSet( dsp_coeff_table->flags, FCVAR_CHANGED ))
if( FBitSet( dsp_coeff_table.flags, FCVAR_CHANGED ))
{
switch( (int)dsp_coeff_table->value )
switch( (int)dsp_coeff_table.value )
{
case 0: // release
ptable = rgsxpre;
@ -873,20 +867,20 @@ void CheckNewDspPresets( void )
SX_ReloadRoomFX();
room_typeprev = -1;
ClearBits( dsp_coeff_table->flags, FCVAR_CHANGED );
ClearBits( dsp_coeff_table.flags, FCVAR_CHANGED );
}
if( s_listener.waterlevel > 2 )
idsp_room = roomwater_type->value;
else idsp_room = room_type->value;
idsp_room = roomwater_type.value;
else idsp_room = room_type.value;
// don't pass invalid presets
idsp_room = bound( 0, idsp_room, MAX_ROOM_TYPES );
if( FBitSet( hisound->flags, FCVAR_CHANGED ))
if( FBitSet( hisound.flags, FCVAR_CHANGED ))
{
sxhires = hisound->value;
ClearBits( hisound->flags, FCVAR_CHANGED );
sxhires = hisound.value;
ClearBits( hisound.flags, FCVAR_CHANGED );
}
if( idsp_room == room_typeprev && idsp_room == 0 )
@ -915,15 +909,15 @@ void CheckNewDspPresets( void )
DLY_CheckNewDelayVal( );
DLY_CheckNewStereoDelayVal();
ClearBits( sxrvb_size->flags, FCVAR_CHANGED );
ClearBits( sxdly_delay->flags, FCVAR_CHANGED );
ClearBits( sxste_delay->flags, FCVAR_CHANGED );
ClearBits( sxrvb_size.flags, FCVAR_CHANGED );
ClearBits( sxdly_delay.flags, FCVAR_CHANGED );
ClearBits( sxste_delay.flags, FCVAR_CHANGED );
}
void SX_Profiling_f( void )
static void SX_Profiling_f( void )
{
portable_samplepair_t testbuffer[512];
float oldroom = room_type->value;
float oldroom = room_type.value;
double start, end;
int i, calls;

View File

@ -16,7 +16,6 @@ GNU General Public License for more details.
#include "common.h"
#include "sound.h"
#include "const.h"
#include "sequence.h"
#include <ctype.h>
static int cszrawsentences = 0;
@ -165,23 +164,11 @@ static const char *VOX_LookupString( const char *pszin )
int i = -1, len;
const char *c;
// check if we are a CSCZ or immediate sentence
// check if we are an immediate sentence
if( *pszin == '#' )
{
// Q_atoi is too smart and allows negative values
// so check with Q_isdigit beforehand
if( Q_isdigit( pszin + 1 ))
{
sentenceEntry_s *sentenceEntry;
i = Q_atoi( pszin + 1 );
if(( sentenceEntry = Sequence_GetSentenceByIndex( i )))
return sentenceEntry->data;
}
else
{
// immediate sentence, probably coming from "speak" command
return pszin + 1;
}
// immediate sentence, probably coming from "speak" command
return pszin + 1;
}
// check if we received an index

View File

@ -219,7 +219,6 @@ extern dma_t dma;
extern convar_t s_musicvolume;
extern convar_t s_lerping;
extern convar_t *dsp_off;
extern convar_t s_test; // cvar to testify new effects
extern convar_t s_samplecount;
extern convar_t snd_mute_losefocus;

View File

@ -20,21 +20,21 @@ GNU General Public License for more details.
#include "vid_common.h"
#include "platform/platform.h"
#define WINDOW_NAME XASH_ENGINE_NAME " Window" // Half-Life
convar_t *vid_fullscreen;
convar_t *vid_mode;
convar_t *vid_brightness;
convar_t *vid_gamma;
convar_t *vid_highdpi;
static CVAR_DEFINE( window_width, "width", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen width" );
static CVAR_DEFINE( window_height, "height", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen height" );
static CVAR_DEFINE( vid_brightness, "brightness", "0.0", FCVAR_ARCHIVE, "brightness factor" );
static CVAR_DEFINE( vid_gamma, "gamma", "2.5", FCVAR_ARCHIVE, "gamma amount" );
static CVAR_DEFINE_AUTO( vid_mode, "0", FCVAR_RENDERINFO, "current video mode index (used only for storage)" );
static CVAR_DEFINE_AUTO( vid_rotate, "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen rotation (0-3)" );
static CVAR_DEFINE_AUTO( vid_scale, "1.0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "pixel scale" );
CVAR_DEFINE_AUTO( vid_highdpi, "1", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable High-DPI mode" );
CVAR_DEFINE( vid_fullscreen, "fullscreen", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable fullscreen mode" );
CVAR_DEFINE( window_xpos, "_window_xpos", "-1", FCVAR_RENDERINFO, "window position by horizontal" );
CVAR_DEFINE( window_ypos, "_window_ypos", "-1", FCVAR_RENDERINFO, "window position by vertical" );
glwstate_t glw_state;
convar_t *window_xpos;
convar_t *window_ypos;
convar_t *vid_rotate;
convar_t *vid_scale;
/*
=================
VID_StartupGamma
@ -42,10 +42,10 @@ VID_StartupGamma
*/
void VID_StartupGamma( void )
{
BuildGammaTable( vid_gamma->value, vid_brightness->value );
Con_Reportf( "VID_StartupGamma: gamma %g brightness %g\n", vid_gamma->value, vid_brightness->value );
ClearBits( vid_brightness->flags, FCVAR_CHANGED );
ClearBits( vid_gamma->flags, FCVAR_CHANGED );
BuildGammaTable( vid_gamma.value, vid_brightness.value );
Con_Reportf( "VID_StartupGamma: gamma %g brightness %g\n", vid_gamma.value, vid_brightness.value );
ClearBits( vid_brightness.flags, FCVAR_CHANGED );
ClearBits( vid_gamma.flags, FCVAR_CHANGED );
}
/*
@ -124,11 +124,11 @@ check vid modes and fullscreen
*/
void VID_CheckChanges( void )
{
if( FBitSet( cl_allow_levelshots->flags, FCVAR_CHANGED ))
if( FBitSet( cl_allow_levelshots.flags, FCVAR_CHANGED ))
{
//GL_FreeTexture( cls.loadingBar );
SCR_RegisterTextures(); // reload 'lambda' image
ClearBits( cl_allow_levelshots->flags, FCVAR_CHANGED );
ClearBits( cl_allow_levelshots.flags, FCVAR_CHANGED );
}
if( host.renderinfo_changed )
@ -145,6 +145,36 @@ void VID_CheckChanges( void )
}
}
/*
===============
VID_SetDisplayTransform
notify ref dll about screen transformations
===============
*/
void VID_SetDisplayTransform( int *render_w, int *render_h )
{
uint rotate = vid_rotate.value;
if( ref.dllFuncs.R_SetDisplayTransform( rotate, 0, 0, vid_scale.value, vid_scale.value ))
{
if( rotate & 1 )
{
int swap = *render_w;
*render_w = *render_h;
*render_h = swap;
}
*render_h /= vid_scale.value;
*render_w /= vid_scale.value;
}
else
{
Con_Printf( S_WARN "failed to setup screen transform\n" );
}
}
static void VID_Mode_f( void )
{
int w, h;
@ -177,25 +207,24 @@ static void VID_Mode_f( void )
return;
}
R_ChangeDisplaySettings( w, h, Cvar_VariableInteger( "fullscreen" ) );
R_ChangeDisplaySettings( w, h, !!vid_fullscreen.value );
}
void VID_Init( void )
{
// system screen width and height (don't suppose for change from console at all)
Cvar_Get( "width", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen width" );
Cvar_Get( "height", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen height" );
Cvar_RegisterVariable( &window_width );
Cvar_RegisterVariable( &window_height );
window_xpos = Cvar_Get( "_window_xpos", "-1", FCVAR_RENDERINFO, "window position by horizontal" );
window_ypos = Cvar_Get( "_window_ypos", "-1", FCVAR_RENDERINFO, "window position by vertical" );
vid_gamma = Cvar_Get( "gamma", "2.5", FCVAR_ARCHIVE, "gamma amount" );
vid_brightness = Cvar_Get( "brightness", "0.0", FCVAR_ARCHIVE, "brightness factor" );
vid_fullscreen = Cvar_Get( "fullscreen", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable fullscreen mode" );
vid_mode = Cvar_Get( "vid_mode", "0", FCVAR_RENDERINFO, "current video mode index (used just for storage)" );
vid_highdpi = Cvar_Get( "vid_highdpi", "1", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable High-DPI mode" );
vid_rotate = Cvar_Get( "vid_rotate", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen rotation (0-3)" );
vid_scale = Cvar_Get( "vid_scale", "1.0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "pixel scale" );
Cvar_RegisterVariable( &vid_mode );
Cvar_RegisterVariable( &vid_highdpi );
Cvar_RegisterVariable( &vid_rotate );
Cvar_RegisterVariable( &vid_scale );
Cvar_RegisterVariable( &vid_fullscreen );
Cvar_RegisterVariable( &vid_brightness );
Cvar_RegisterVariable( &vid_gamma );
Cvar_RegisterVariable( &window_xpos );
Cvar_RegisterVariable( &window_ypos );
// a1ba: planned to be named vid_mode for compability
// but supported mode list is filled by backends, so numbers are not portable any more

View File

@ -28,13 +28,14 @@ extern glwstate_t glw_state;
#define VID_MIN_HEIGHT 200
#define VID_MIN_WIDTH 320
extern convar_t *vid_fullscreen;
extern convar_t *vid_highdpi;
extern convar_t *vid_rotate;
extern convar_t *vid_scale;
extern convar_t vid_fullscreen;
extern convar_t vid_highdpi;
extern convar_t window_xpos;
extern convar_t window_ypos;
extern convar_t gl_msaa_samples;
extern convar_t *gl_msaa_samples;
void R_SaveVideoMode( int w, int h, int render_w, int render_h );
void VID_SetDisplayTransform( int *render_w, int *render_h );
void VID_CheckChanges( void );
const char *VID_GetModeString( int vid_mode );
void VID_StartupGamma( void );

View File

@ -382,7 +382,7 @@ void Voice_RecordStart( void )
{
Sound_Process( &voice.input_file, voice.samplerate, voice.width, SOUND_RESAMPLE );
voice.input_file_pos = 0;
voice.start_time = Sys_DoubleTime();
voice.is_recording = true;
}
@ -499,7 +499,7 @@ void CL_AddVoiceToDatagram( void )
if( cls.state != ca_active || !Voice_IsRecording() || !voice.encoder )
return;
size = Voice_GetOpusCompressedData( voice.output_buffer, sizeof( voice.output_buffer ), &frames );
if( size > 0 && MSG_GetNumBytesLeft( &cls.datagram ) >= size + 32 )
@ -600,8 +600,10 @@ qboolean Voice_Init( const char *pszCodecName, int quality )
}
// reinitialize only if codec parameters are different
if( Q_strcmp( voice.codec, pszCodecName ) && voice.quality != quality )
Voice_Shutdown();
if( !Q_strcmp( voice.codec, pszCodecName ) && voice.quality == quality )
return true;
Voice_Shutdown();
voice.autogain.block_size = 128;

View File

@ -547,7 +547,7 @@ int GAME_EXPORT Cmd_Argc( void )
Cmd_Argv
============
*/
const char *Cmd_Argv( int arg )
const char *GAME_EXPORT Cmd_Argv( int arg )
{
if((uint)arg >= cmd_argc )
return "";
@ -559,7 +559,7 @@ const char *Cmd_Argv( int arg )
Cmd_Args
============
*/
const char *Cmd_Args( void )
const char *GAME_EXPORT Cmd_Args( void )
{
return cmd_args;
}
@ -996,7 +996,7 @@ static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPr
cmd_condlevel = 0;
// cvar value substitution
if( CVAR_TO_BOOL( cmd_scripting ) && isPrivileged )
if( cmd_scripting.value && isPrivileged )
{
while( *text )
{
@ -1357,7 +1357,7 @@ inserts escape sequences
void Cmd_Escape( char *newCommand, const char *oldCommand, int len )
{
int c;
int scripting = CVAR_TO_BOOL( cmd_scripting );
int scripting = cmd_scripting.value;
while( (c = *oldCommand++) && len > 1 )
{

View File

@ -22,7 +22,6 @@ GNU General Public License for more details.
#include "const.h"
#include "client.h"
#include "library.h"
#include "sequence.h"
static const char *file_exts[] =
{
@ -104,7 +103,7 @@ static float fran1( void )
return temp;
}
void COM_SetRandomSeed( int lSeed )
void GAME_EXPORT COM_SetRandomSeed( int lSeed )
{
if( lSeed ) idum = lSeed;
else idum = -time( NULL );
@ -267,7 +266,7 @@ static void LZSS_BuildHash( lzss_state_t *state, const byte *source )
list->start = node;
}
byte *LZSS_CompressNoAlloc( lzss_state_t *state, byte *pInput, int input_length, byte *pOutputBuf, uint *pOutputSize )
static byte *LZSS_CompressNoAlloc( lzss_state_t *state, byte *pInput, int input_length, byte *pOutputBuf, uint *pOutputSize )
{
byte *pStart = pOutputBuf; // allocate the output buffer, compressed buffer is expected to be less, caller will free
byte *pEnd = pStart + input_length - sizeof( lzss_header_t ) - 8; // prevent compression failure
@ -553,7 +552,6 @@ This doesn't search in the pak file.
*/
int GAME_EXPORT COM_ExpandFilename( const char *fileName, char *nameOutBuffer, int nameOutBufferSize )
{
const char *path;
char result[MAX_SYSPATH];
if( !COM_CheckString( fileName ) || !nameOutBuffer || nameOutBufferSize <= 0 )
@ -562,10 +560,8 @@ int GAME_EXPORT COM_ExpandFilename( const char *fileName, char *nameOutBuffer, i
// filename examples:
// media\sierra.avi - D:\Xash3D\valve\media\sierra.avi
// models\barney.mdl - D:\Xash3D\bshift\models\barney.mdl
if(( path = FS_GetDiskPath( fileName, false )) != NULL )
if( g_fsapi.GetFullDiskPath( result, sizeof( result ), fileName, false ))
{
Q_snprintf( result, sizeof( result ), "%s/%s", host.rootdir, path );
// check for enough room
if( Q_strlen( result ) > nameOutBufferSize )
return 0;
@ -616,7 +612,7 @@ COM_Nibble
Returns the 4 bit nibble for a hex character
==================
*/
byte COM_Nibble( char c )
static byte COM_Nibble( char c )
{
if(( c >= '0' ) && ( c <= '9' ))
{
@ -664,7 +660,7 @@ COM_MemFgets
=============
*/
char *COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize )
char *GAME_EXPORT COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize )
{
int i, last, stop;
@ -718,7 +714,7 @@ Cache_Check
consistency check
====================
*/
void *Cache_Check( poolhandle_t mempool, cache_user_t *c )
void *GAME_EXPORT Cache_Check( poolhandle_t mempool, cache_user_t *c )
{
if( !c->data )
return NULL;
@ -735,7 +731,7 @@ COM_LoadFileForMe
=============
*/
byte* GAME_EXPORT COM_LoadFileForMe( const char *filename, int *pLength )
byte *GAME_EXPORT COM_LoadFileForMe( const char *filename, int *pLength )
{
string name;
byte *file, *pfile;
@ -775,7 +771,7 @@ COM_LoadFile
=============
*/
byte *COM_LoadFile( const char *filename, int usehunk, int *pLength )
byte *GAME_EXPORT COM_LoadFile( const char *filename, int usehunk, int *pLength )
{
return COM_LoadFileForMe( filename, pLength );
}
@ -861,59 +857,6 @@ void GAME_EXPORT pfnGetModelBounds( model_t *mod, float *mins, float *maxs )
}
}
/*
=============
pfnCvar_RegisterServerVariable
standard path to register game variable
=============
*/
void GAME_EXPORT pfnCvar_RegisterServerVariable( cvar_t *variable )
{
if( variable != NULL )
SetBits( variable->flags, FCVAR_EXTDLL );
Cvar_RegisterVariable( (convar_t *)variable );
}
/*
=============
pfnCvar_RegisterEngineVariable
use with precaution: this cvar will NOT unlinked
after game.dll is unloaded
=============
*/
void GAME_EXPORT pfnCvar_RegisterEngineVariable( cvar_t *variable )
{
Cvar_RegisterVariable( (convar_t *)variable );
}
/*
=============
pfnCvar_RegisterVariable
=============
*/
cvar_t *pfnCvar_RegisterClientVariable( const char *szName, const char *szValue, int flags )
{
// a1ba: try to mitigate outdated client.dll vulnerabilities
if( !Q_stricmp( szName, "motdfile" ))
flags |= FCVAR_PRIVILEGED;
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_CLIENTDLL, Cvar_BuildAutoDescription( szName, flags|FCVAR_CLIENTDLL ));
}
/*
=============
pfnCvar_RegisterVariable
=============
*/
cvar_t *pfnCvar_RegisterGameUIVariable( const char *szName, const char *szValue, int flags )
{
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_GAMEUIDLL, Cvar_BuildAutoDescription( szName, flags|FCVAR_GAMEUIDLL ));
}
/*
=============
pfnCVarGetPointer
@ -921,7 +864,7 @@ pfnCVarGetPointer
can return NULL
=============
*/
cvar_t *pfnCVarGetPointer( const char *szVarName )
cvar_t *GAME_EXPORT pfnCVarGetPointer( const char *szVarName )
{
return (cvar_t *)Cvar_FindVar( szVarName );
}
@ -1103,7 +1046,7 @@ void *GAME_EXPORT pfnSequenceGet( const char *fileName, const char *entryName )
{
Msg( "Sequence_Get: file %s, entry %s\n", fileName, entryName );
return Sequence_Get( fileName, entryName );
return NULL;
}
/*
@ -1117,7 +1060,7 @@ void *GAME_EXPORT pfnSequencePickSentence( const char *groupName, int pickMethod
{
Msg( "Sequence_PickSentence: group %s, pickMethod %i\n", groupName, pickMethod );
return Sequence_PickSentence( groupName, pickMethod, picked );
return NULL;
}
@ -1128,30 +1071,7 @@ pfnIsCareerMatch
used by CS:CZ (client stub)
=============
*/
int GAME_EXPORT GAME_EXPORT pfnIsCareerMatch( void )
{
return 0;
}
/*
=============
pfnRegisterTutorMessageShown
only exists in PlayStation version
=============
*/
void GAME_EXPORT pfnRegisterTutorMessageShown( int mid )
{
}
/*
=============
pfnGetTimesTutorMessageShown
only exists in PlayStation version
=============
*/
int GAME_EXPORT pfnGetTimesTutorMessageShown( int mid )
int GAME_EXPORT pfnIsCareerMatch( void )
{
return 0;
}

View File

@ -144,7 +144,7 @@ typedef enum
#define GameState (&host.game)
#define FORCE_DRAW_VERSION_TIME 5.0f // draw version for 5 seconds
#define FORCE_DRAW_VERSION_TIME 5.0 // draw version for 5 seconds
#ifdef _DEBUG
void DBG_AssertFunction( qboolean fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage );
@ -153,16 +153,14 @@ void DBG_AssertFunction( qboolean fExpr, const char* szExpr, const char* szFile,
#define Assert( f )
#endif
extern convar_t *gl_vsync;
extern convar_t *scr_loading;
extern convar_t *scr_download;
extern convar_t *cmd_scripting;
extern convar_t *sv_maxclients;
extern convar_t *cl_allow_levelshots;
extern convar_t gl_vsync;
extern convar_t scr_loading;
extern convar_t scr_download;
extern convar_t cmd_scripting;
extern convar_t cl_allow_levelshots;
extern convar_t host_developer;
extern convar_t *host_limitlocal;
extern convar_t *host_framerate;
extern convar_t *host_maxfps;
extern convar_t host_limitlocal;
extern convar_t host_maxfps;
extern convar_t sys_timescale;
extern convar_t cl_filterstuffcmd;
extern convar_t rcon_password;
@ -273,40 +271,6 @@ typedef struct
double forcedEnd;
} soundlist_t;
typedef struct
{
char model[MAX_QPATH]; // curstate.modelindex = SV_ModelIndex
vec3_t tentOffset; // if attached, client origin + tentOffset = tent origin.
short clientIndex;
float fadeSpeed;
float bounceFactor;
byte hitSound;
qboolean high_priority;
float x, y, z;
int flags;
float time;
// base state
vec3_t velocity; // baseline.origin
vec3_t avelocity; // baseline.angles
int fadeamount; // baseline.renderamt
float sparklife; // baseline.framerate
float thinkTime; // baseline.scale
// current state
vec3_t origin; // entity.origin
vec3_t angles; // entity.angles
float renderamt; // curstate.renderamt
color24 rendercolor; // curstate.rendercolor
int rendermode; // curstate.rendermode
int renderfx; // curstate.renderfx
float framerate; // curstate.framerate
float frame; // curstate.frame
byte body; // curstate.body
byte skin; // curstate.skin
float scale; // curstate.scale
} tentlist_t;
typedef enum bugcomp_e
{
// default mode, we assume that user dlls are not relying on engine bugs
@ -360,8 +324,7 @@ typedef struct host_parm_s
qboolean change_game; // initialize when game is changed
qboolean mouse_visible; // vgui override cursor control (never change outside Platform_SetCursorType!)
qboolean shutdown_issued; // engine is shutting down
qboolean force_draw_version; // used when fraps is loaded
float force_draw_version_time;
double force_draw_version_time;
qboolean apply_game_config; // when true apply only to game cvars and ignore all other commands
qboolean apply_opengl_config;// when true apply only to opengl cvars and ignore all other commands
qboolean config_executed; // a bit who indicated was config.cfg already executed e.g. from valve.rc
@ -629,10 +592,6 @@ qboolean SV_Active( void );
==============================================================
*/
void pfnCvar_RegisterServerVariable( cvar_t *variable );
void pfnCvar_RegisterEngineVariable( cvar_t *variable );
cvar_t *pfnCvar_RegisterClientVariable( const char *szName, const char *szValue, int flags );
cvar_t *pfnCvar_RegisterGameUIVariable( const char *szName, const char *szValue, int flags );
char *COM_MemFgets( byte *pMemFile, int fileSize, int *filePos, char *pBuffer, int bufferSize );
void COM_HexConvert( const char *pszInput, int nInputLength, byte *pOutput );
int COM_SaveFile( const char *filename, const void *data, int len );
@ -649,7 +608,6 @@ void pfnGetModelBounds( model_t *mod, float *mins, float *maxs );
void pfnCVarDirectSet( cvar_t *var, const char *szValue );
int COM_CheckParm( char *parm, char **ppnext );
void pfnGetGameDir( char *szGetGameDir );
int pfnDecalIndex( const char *m );
int pfnGetModelType( model_t *mod );
int pfnIsMapValid( char *filename );
void Con_Reportf( const char *szFmt, ... ) _format( 1 );
@ -669,8 +627,6 @@ void *pfnSequencePickSentence( const char *groupName, int pickMethod, int *picke
int pfnIsCareerMatch( void );
// Decay engfuncs (stubs)
int pfnGetTimesTutorMessageShown( int mid );
void pfnRegisterTutorMessageShown( int mid );
void pfnConstructTutorMessageDecayBuffer( int *buffer, int buflen );
void pfnProcessTutorMessageDecayBuffer( int *buffer, int bufferLength );
void pfnResetTutorMessageDecayData( void );
@ -755,7 +711,6 @@ struct cmd_s *Cmd_GetNextFunctionHandle( struct cmd_s *cmd );
struct cmdalias_s *Cmd_AliasGetList( void );
const char *Cmd_GetName( struct cmd_s *cmd );
void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float attn, int flags, int pitch );
void SV_StartMusic( const char *curtrack, const char *looptrack, int position );
void SV_CreateDecal( sizebuf_t *msg, const float *origin, int decalIndex, int entityIndex, int modelIndex, int flags, float scale );
void Log_Printf( const char *fmt, ... ) _format( 1 );
void SV_BroadcastCommand( const char *fmt, ... ) _format( 1 );
@ -792,7 +747,7 @@ void SV_ShutdownGame( void );
void SV_ExecLoadLevel( void );
void SV_ExecLoadGame( void );
void SV_ExecChangeLevel( void );
void SV_InitGameProgs( void );
qboolean SV_InitGameProgs( void );
void SV_FreeGameProgs( void );
void CL_WriteMessageHistory( void );
void CL_SendCmd( void );

View File

@ -18,7 +18,7 @@ GNU General Public License for more details.
#include "const.h"
#include "kbutton.h"
extern convar_t *con_gamemaps;
extern convar_t con_gamemaps;
#define CON_MAXCMDS 4096 // auto-complete intermediate list
@ -76,7 +76,7 @@ int Cmd_ListMaps( search_t *t, char *lastmapname, size_t len )
compiler[0] = '\0';
generator[0] = '\0';
f = FS_Open( t->filenames[i], "rb", con_gamemaps->value );
f = FS_Open( t->filenames[i], "rb", con_gamemaps.value );
if( f )
{
@ -190,7 +190,7 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
string matchbuf;
int i, nummaps;
t = FS_Search( va( "maps/%s*.bsp", s ), true, con_gamemaps->value );
t = FS_Search( va( "maps/%s*.bsp", s ), true, con_gamemaps.value );
if( !t ) return false;
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
@ -1423,12 +1423,14 @@ save serverinfo variables into server.cfg (using for dedicated server too)
*/
void GAME_EXPORT Host_WriteServerConfig( const char *name )
{
qboolean already_loaded;
file_t *f;
string newconfigfile;
Q_snprintf( newconfigfile, MAX_STRING, "%s.new", name );
SV_InitGameProgs(); // collect user variables
// TODO: remove this mechanism, make it safer for now
already_loaded = SV_InitGameProgs(); // collect user variables
// FIXME: move this out until menu parser is done
CSCR_LoadDefaultCVars( "settings.scr" );
@ -1447,7 +1449,9 @@ void GAME_EXPORT Host_WriteServerConfig( const char *name )
}
else Con_DPrintf( S_ERROR "Couldn't write %s.\n", name );
SV_FreeGameProgs(); // release progs with all variables
// don't unload library that wasn't loaded by us
if( !already_loaded )
SV_FreeGameProgs(); // release progs with all variables
}
/*

View File

@ -334,24 +334,6 @@ void Sys_RestoreCrashHandler( void )
static struct sigaction oldFilter;
#ifdef XASH_DYNAMIC_DLADDR
static int d_dladdr( void *sym, Dl_info *info )
{
static int (*dladdr_real) ( void *sym, Dl_info *info );
if( !dladdr_real )
dladdr_real = dlsym( (void*)(size_t)(-1), "dladdr" );
memset( info, 0, sizeof( *info ) );
if( !dladdr_real )
return -1;
return dladdr_real( sym, info );
}
#define dladdr d_dladdr
#endif
static int Sys_PrintFrame( char *buf, int len, int i, void *addr )
{
Dl_info dlinfo;
@ -406,9 +388,9 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
bp = (void**)ucontext->uc_mcontext.mc_ebp;
sp = (void**)ucontext->uc_mcontext.mc_esp;
#elif XASH_NETBSD
pc = (void*)ucontext->uc_mcontext.__gregs[REG_EIP];
bp = (void**)ucontext->uc_mcontext.__gregs[REG_EBP];
sp = (void**)ucontext->uc_mcontext.__gregs[REG_ESP];
pc = (void*)ucontext->uc_mcontext.__gregs[_REG_EIP];
bp = (void**)ucontext->uc_mcontext.__gregs[_REG_EBP];
sp = (void**)ucontext->uc_mcontext.__gregs[_REG_ESP];
#elif XASH_OPENBSD
pc = (void*)ucontext->sc_eip;
bp = (void**)ucontext->sc_ebp;

View File

@ -19,7 +19,7 @@ GNU General Public License for more details.
#include "eiface.h" // ARRAYSIZE
convar_t *cvar_vars = NULL; // head of list
convar_t *cmd_scripting;
CVAR_DEFINE_AUTO( cmd_scripting, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED, "enable simple condition checking and variable operations" );
#ifdef HACKS_RELATED_HLMODS
typedef struct cvar_filter_quirks_s
@ -211,7 +211,7 @@ const char *Cvar_ValidateString( convar_t *var, const char *value )
int len = 0;
// step through the string, only copying back in characters that are printable
while( *pszValue && len < MAX_STRING )
while( *pszValue && len < ( MAX_STRING - 1 ))
{
if( ((byte)*pszValue) < 32 )
{
@ -681,18 +681,18 @@ void Cvar_DirectSet( convar_t *var, const char *value )
{
const char *pszValue;
if( !var ) return; // ???
if( unlikely( !var )) return; // ???
// lookup for registration
if( CVAR_CHECK_SENTINEL( var ) || ( var->next == NULL && !FBitSet( var->flags, FCVAR_EXTENDED|FCVAR_ALLOCATED )))
if( unlikely( CVAR_CHECK_SENTINEL( var ) || ( var->next == NULL && !FBitSet( var->flags, FCVAR_EXTENDED|FCVAR_ALLOCATED ))))
{
// need to registering cvar fisrt
Cvar_RegisterVariable( var ); // ok, register it
}
// lookup for registration again
if( var != Cvar_FindVar( var->name ))
return; // how this possible?
// lookup for registration again
if( var != Cvar_FindVar( var->name ))
return; // how this possible?
}
if( FBitSet( var->flags, FCVAR_READ_ONLY ))
{
@ -1240,7 +1240,7 @@ void Cvar_Init( void )
{
cvar_vars = NULL;
cvar_active_filter_quirks = NULL;
cmd_scripting = Cvar_Get( "cmd_scripting", "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED, "enable simple condition checking and variable operations" );
Cvar_RegisterVariable( &cmd_scripting );
Cvar_RegisterVariable( &host_developer ); // early registering for dev
Cvar_RegisterVariable( &cl_filterstuffcmd );
Cmd_AddRestrictedCommand( "setgl", Cvar_SetGL_f, "change the value of a opengl variable" ); // OBSOLETE

View File

@ -56,8 +56,7 @@ typedef struct convar_s
#define CVAR_DEFINE_AUTO( cv, cvstr, cvflags, cvdesc ) \
CVAR_DEFINE( cv, #cv, cvstr, cvflags, cvdesc )
#define CVAR_TO_BOOL( x ) ((x) && ((x)->value != 0.0f) ? true : false )
#ifndef REF_DLL
cvar_t *Cvar_GetList( void );
#define Cvar_FindVar( name ) Cvar_FindVarExt( name, 0 )
convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group );
@ -81,5 +80,6 @@ qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged );
void Cvar_Init( void );
void Cvar_PostFSInit( void );
void Cvar_Unlink( int group );
#endif // REF_DLL
#endif//CVAR_H

View File

@ -218,11 +218,6 @@ void GAME_EXPORT Con_NXPrintf( struct con_nprint_s *info, const char *fmt, ...
}
const byte *GL_TextureData( unsigned int texnum )
{
return NULL;
}
void SCR_CheckStartupVids( void )
{

View File

@ -18,6 +18,7 @@ GNU General Public License for more details.
#include "common.h"
#include "library.h"
#include "platform/platform.h"
fs_api_t g_fsapi;
fs_globals_t *FI;
@ -51,12 +52,17 @@ static fs_interface_t fs_memfuncs =
_Mem_Alloc,
_Mem_Realloc,
_Mem_Free,
Platform_GetNativeObject,
};
static void FS_UnloadProgs( void )
{
COM_FreeLibrary( fs_hInstance );
fs_hInstance = 0;
if( fs_hInstance )
{
COM_FreeLibrary( fs_hInstance );
fs_hInstance = 0;
}
}
#ifdef XASH_INTERNAL_GAMELIBS
@ -104,22 +110,16 @@ FS_Init
*/
void FS_Init( void )
{
qboolean caseinsensitive = true;
string gamedir;
Cmd_AddRestrictedCommand( "fs_rescan", FS_Rescan_f, "rescan filesystem search pathes" );
Cmd_AddRestrictedCommand( "fs_path", FS_Path_f_, "show filesystem search pathes" );
Cmd_AddRestrictedCommand( "fs_clearpaths", FS_ClearPaths_f, "clear filesystem search pathes" );
#if !XASH_WIN32
if( Sys_CheckParm( "-casesensitive" ) )
caseinsensitive = false;
#endif
if( !Sys_GetParmFromCmdLine( "-game", gamedir ))
Q_strncpy( gamedir, SI.basedirName, sizeof( gamedir )); // gamedir == basedir
if( !FS_InitStdio( caseinsensitive, host.rootdir, SI.basedirName, gamedir, host.rodir ))
if( !FS_InitStdio( true, host.rootdir, SI.basedirName, gamedir, host.rodir ))
{
Host_Error( "Can't init filesystem_stdio!\n" );
return;
@ -139,9 +139,8 @@ FS_Shutdown
*/
void FS_Shutdown( void )
{
int i;
FS_ShutdownStdio();
if( g_fsapi.ShutdownStdio )
g_fsapi.ShutdownStdio();
memset( &SI, 0, sizeof( sysinfo_t ));

View File

@ -54,114 +54,113 @@ CVAR_DEFINE( host_developer, "developer", "0", FCVAR_FILTERABLE, "engine is in d
CVAR_DEFINE_AUTO( sys_timescale, "1.0", FCVAR_CHEAT|FCVAR_FILTERABLE, "scale frame time" );
CVAR_DEFINE_AUTO( sys_ticrate, "100", 0, "framerate in dedicated mode" );
convar_t *host_serverstate;
convar_t *host_gameloaded;
convar_t *host_clientloaded;
convar_t *host_limitlocal;
convar_t *host_maxfps;
convar_t *host_framerate;
convar_t *host_sleeptime;
convar_t *con_gamemaps;
convar_t *build, *ver;
static CVAR_DEFINE_AUTO( host_serverstate, "0", FCVAR_READ_ONLY, "displays current server state" );
static CVAR_DEFINE_AUTO( host_gameloaded, "0", FCVAR_READ_ONLY, "inidcates a loaded game.dll" );
static CVAR_DEFINE_AUTO( host_clientloaded, "0", FCVAR_READ_ONLY, "inidcates a loaded client.dll" );
CVAR_DEFINE_AUTO( host_limitlocal, "0", 0, "apply cl_cmdrate and rate to loopback connection" );
CVAR_DEFINE( host_maxfps, "fps_max", "72", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "host fps upper limit" );
static CVAR_DEFINE_AUTO( host_framerate, "0", FCVAR_FILTERABLE, "locks frame timing to this value in seconds" );
static CVAR_DEFINE( host_sleeptime, "sleeptime", "1", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "milliseconds to sleep for each frame. higher values reduce fps accuracy" );
CVAR_DEFINE( con_gamemaps, "con_mapfilter", "1", FCVAR_ARCHIVE, "when true show only maps in game folder" );
void Sys_PrintUsage( void )
{
string version_str;
const char *usage_str;
#define O(x,y) " "x" "y"\n"
Q_snprintf( version_str, sizeof( version_str ),
XASH_ENGINE_NAME " %i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
usage_str = ""
#if XASH_MESSAGEBOX == MSGBOX_STDERR
"\n" // dirty hack to not have Xash Error: Usage: on same line
#endif // XASH_MESSAGEBOX == MSGBOX_STDERR
S_USAGE "\n"
#if !XASH_MOBILE_PLATFORM
#if XASH_WIN32
O("<xash>.exe [options] [+command1] [+command2 arg]","")
#else // XASH_WIN32
O("<xash> [options] [+command1] [+command2 arg]","")
#endif // !XASH_WIN32
#endif // !XASH_MOBILE_PLATFORM
"Options:\n"
O("-dev [level] ","set log verbosity 0-2")
O("-log ","write log to \"engine.log\"")
O("-nowriteconfig ","disable config save")
#if XASH_WIN32
#define XASH_EXE "(xash).exe"
#else
#define XASH_EXE "(xash)"
#endif
#if !XASH_WIN32
O("-casesensitive ","disable case-insensitive FS emulation")
#endif // !XASH_WIN32
#define O( x, y ) " "x" "y"\n"
#if !XASH_MOBILE_PLATFORM
O("-daemonize ","run engine in background, dedicated only")
#endif // !XASH_MOBILE_PLATFORM
usage_str = S_USAGE XASH_EXE " [options] [+command] [+command2 arg] ...\n"
"\nCommon options:\n"
O("-dev [level] ", "set log verbosity 0-2")
O("-log ", "write log to \"engine.log\"")
O("-nowriteconfig ", "disable config save")
O("-noch ", "disable crashhandler")
#if XASH_WIN32 // !!!!
O("-minidumps ", "enable writing minidumps when game is crashed")
#endif
O("-rodir <path> ", "set read-only base directory")
O("-bugcomp ", "enable precise bug compatibility. Will break games that don't require it")
O(" ", "Refer to engine documentation for more info")
O("-disablehelp ", "disable this message")
#if !XASH_DEDICATED
O("-toconsole ","run engine witn console open")
O("-width <n> ","set window width")
O("-height <n> ","set window height")
O("-oldfont ","enable unused Quake font in Half-Life")
O("-dedicated ", "run engine in dedicated mode")
#endif
"\nNetworking options:\n"
O("-noip ", "disable IPv4")
O("-ip <ip> ", "set IPv4 address")
O("-port <port> ", "set IPv4 port")
O("-noip6 ", "disable IPv6")
O("-ip6 <ip> ", "set IPv6 address")
O("-port6 <port> ", "set IPv6 port")
O("-clockwindow <cw>", "adjust clockwindow used to ignore client commands to prevent speed hacks")
"\nGame options:\n"
O("-dll <path> ", "override server DLL path")
#if !XASH_DEDICATED
O("-clientlib <path>", "override client DLL path")
O("-console ", "run engine with console enabled")
O("-toconsole ", "run engine witn console open")
O("-oldfont ", "enable unused Quake font in Half-Life")
O("-width <n> ", "set window width")
O("-height <n> ", "set window height")
O("-fullscreen ", "run engine in fullscreen mode")
O("-windowed ", "run engine in windowed mode")
O("-ref <name> ", "use selected renderer dll")
O("-gldebug ", "enable OpenGL debug log")
#if XASH_WIN32
O("-noavi ", "disable AVI support")
O("-nointro ", "disable intro video")
#endif
O("-noenginejoy ", "disable engine builtin joystick support")
O("-noenginemouse ", "disable engine builtin mouse support")
O("-nosound ", "disable sound output")
#endif
"\nPlatform-specific options:\n"
#if !XASH_MOBILE_PLATFORM
O("-fullscreen ","run engine in fullscreen mode")
O("-windowed ","run engine in windowed mode")
O("-dedicated ","run engine in dedicated server mode")
#endif // XASH_MOBILE_PLATFORM
O("-daemonize ", "run engine as a daemon")
#endif
#if XASH_SDL == 2
O("-sdl_joy_old_api ","use SDL legacy joystick API")
O("-sdl_renderer <n>","use alternative SDL_Renderer for software")
#endif // XASH_SDL
#if XASH_ANDROID
O("-nativeegl ","use native egl implementation. Use if screen does not update or black")
#endif // XASH_ANDROID
#if XASH_WIN32
O("-noavi ","disable AVI support")
O("-nointro ","disable intro video")
O("-minidumps ","enable writing minidumps when game crashed")
#endif // XASH_WIN32
#if XASH_DOS
O("-novesa ","disable vesa")
#endif // XASH_DOS
#if XASH_VIDEO == VIDEO_FBDEV
O("-fbdev <path> ","open selected framebuffer")
O("-ttygfx ","set graphics mode in tty")
O("-doublebuffer ","enable doublebuffering")
#endif // XASH_VIDEO == VIDEO_FBDEV
#if XASH_SOUND == SOUND_ALSA
O("-alsadev <dev> ","open selected ALSA device")
#endif // XASH_SOUND == SOUND_ALSA
O("-nojoy ","disable joystick support")
#ifdef XASH_SDL
O("-sdl_joy_old_api ","use SDL legacy joystick API")
O("-sdl_renderer <n>","use alternative SDL_Renderer for software")
#endif // XASH_SDL
O("-nosound ","disable sound")
O("-noenginemouse ","disable mouse completely")
O("-ref <name> ","use selected renderer dll")
O("-gldebug ","enable OpenGL debug log")
#endif // XASH_DEDICATED
O("-noip ","disable TCP/IP")
O("-noch ","disable crashhandler")
O("-disablehelp ","disable this message")
O("-dll <path> ","override server DLL path")
#if !XASH_DEDICATED
O("-clientlib <path>","override client DLL path")
#endif
O("-rodir <path> ","set read-only base directory, experimental")
O("-bugcomp ","enable precise bug compatibility. Will break games that don't require it")
O(" ","Refer to engine documentation for more info")
O("-ip <ip> ","set custom ip")
O("-port <port> ","set custom host port")
O("-clockwindow <cw>","adjust clockwindow")
;
#undef O
#undef O
Sys_Error( "%s", usage_str );
// HACKHACK: pretty output in dedicated
#if XASH_MESSAGEBOX != MSGBOX_STDERR
Platform_MessageBox( version_str, usage_str, false );
#else
fprintf( stderr, "%s\n%s", version_str, usage_str );
#endif
Sys_Quit();
}
int Host_CompareFileTime( int ft1, int ft2 )
@ -278,27 +277,27 @@ static int Host_CalcSleep( void )
#ifndef XASH_DEDICATED
// never sleep in timedemo for benchmarking purposes
// also don't sleep with vsync for less lag
if( CL_IsTimeDemo( ) || CVAR_TO_BOOL( gl_vsync ))
if( CL_IsTimeDemo( ) || gl_vsync.value )
return 0;
#endif
if( Host_IsDedicated() )
{
// let the dedicated server some sleep
return host_sleeptime->value;
return host_sleeptime.value;
}
switch( host.status )
{
case HOST_NOFOCUS:
if( SV_Active() && CL_IsInGame())
return host_sleeptime->value;
return host_sleeptime.value;
// fallthrough
case HOST_SLEEP:
return 20;
}
return host_sleeptime->value;
return host_sleeptime.value;
}
void Host_NewInstance( const char *name, const char *finalmsg )
@ -599,14 +598,14 @@ double Host_CalcFPS( void )
}
else if( Host_IsLocalGame( ))
{
if( !CVAR_TO_BOOL( gl_vsync ))
fps = host_maxfps->value;
if( !gl_vsync.value )
fps = host_maxfps.value;
}
else
{
if( !CVAR_TO_BOOL( gl_vsync ))
if( !gl_vsync.value )
{
fps = host_maxfps->value;
fps = host_maxfps.value;
if( fps == 0.0 ) fps = MAX_FPS;
fps = bound( MIN_FPS, fps, MAX_FPS );
}
@ -681,8 +680,8 @@ qboolean Host_FilterTime( float time )
oldtime = host.realtime;
// NOTE: allow only in singleplayer while demos are not active
if( host_framerate->value > 0.0f && Host_IsLocalGame() && !CL_IsPlaybackDemo() && !CL_IsRecordDemo( ))
host.frametime = bound( MIN_FRAMETIME, host_framerate->value * scale, MAX_FRAMETIME );
if( host_framerate.value > 0.0f && Host_IsLocalGame() && !CL_IsPlaybackDemo() && !CL_IsRecordDemo( ))
host.frametime = bound( MIN_FRAMETIME, host_framerate.value * scale, MAX_FRAMETIME );
else host.frametime = bound( MIN_FRAMETIME, host.frametime, MAX_FRAMETIME );
return true;
@ -1077,10 +1076,9 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha
FS_LoadProgs();
if( FS_SetCurrentDirectory( host.rootdir ) != 0 )
Con_Reportf( "%s is working directory now\n", host.rootdir );
else
Sys_Error( "Changing working directory to %s failed.\n", host.rootdir );
// TODO: this function will cause engine to stop in case of fail
// when it will have an option to return string error, restore Sys_Error
FS_SetCurrentDirectory( host.rootdir );
FS_Init();
@ -1165,18 +1163,18 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
Cmd_AddRestrictedCommand ( "crash", Host_Crash_f, "a way to force a bus error for development reasons");
}
host_serverstate = Cvar_Get( "host_serverstate", "0", FCVAR_READ_ONLY, "displays current server state" );
host_maxfps = Cvar_Get( "fps_max", "72", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "host fps upper limit" );
host_framerate = Cvar_Get( "host_framerate", "0", FCVAR_FILTERABLE, "locks frame timing to this value in seconds" );
host_sleeptime = Cvar_Get( "sleeptime", "1", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "milliseconds to sleep for each frame. higher values reduce fps accuracy" );
host_gameloaded = Cvar_Get( "host_gameloaded", "0", FCVAR_READ_ONLY, "inidcates a loaded game.dll" );
host_clientloaded = Cvar_Get( "host_clientloaded", "0", FCVAR_READ_ONLY, "inidcates a loaded client.dll" );
host_limitlocal = Cvar_Get( "host_limitlocal", "0", 0, "apply cl_cmdrate and rate to loopback connection" );
con_gamemaps = Cvar_Get( "con_mapfilter", "1", FCVAR_ARCHIVE, "when true show only maps in game folder" );
Cvar_RegisterVariable( &host_serverstate );
Cvar_RegisterVariable( &host_maxfps );
Cvar_RegisterVariable( &host_framerate );
Cvar_RegisterVariable( &host_sleeptime );
Cvar_RegisterVariable( &host_gameloaded );
Cvar_RegisterVariable( &host_clientloaded );
Cvar_RegisterVariable( &host_limitlocal );
Cvar_RegisterVariable( &con_gamemaps );
Cvar_RegisterVariable( &sys_timescale );
build = Cvar_Getf( "buildnum", FCVAR_READ_ONLY, "returns a current build number", "%i", Q_buildnum_compat());
ver = Cvar_Getf( "ver", FCVAR_READ_ONLY, "shows an engine version", "%i/%s (hw build %i)", PROTOCOL_VERSION, XASH_COMPAT_VERSION, Q_buildnum_compat());
Cvar_Getf( "buildnum", FCVAR_READ_ONLY, "returns a current build number", "%i", Q_buildnum_compat());
Cvar_Getf( "ver", FCVAR_READ_ONLY, "shows an engine version", "%i/%s (hw build %i)", PROTOCOL_VERSION, XASH_COMPAT_VERSION, Q_buildnum_compat());
Cvar_Getf( "host_ver", FCVAR_READ_ONLY, "detailed info about this build", "%i " XASH_VERSION " %s %s %s", Q_buildnum(), Q_buildos(), Q_buildarch(), Q_buildcommit());
Cvar_Getf( "host_lowmemorymode", FCVAR_READ_ONLY, "indicates if engine compiled for low RAM consumption (0 - normal, 1 - low engine limits, 2 - low protocol limits)", "%i", XASH_LOW_MEMORY );

View File

@ -189,7 +189,7 @@ Searches the string for the given
key and returns the associated value, or an empty string.
===============
*/
const char *Info_ValueForKey( const char *s, const char *key )
const char *GAME_EXPORT Info_ValueForKey( const char *s, const char *key )
{
char pkey[MAX_KV_SIZE];
static char value[4][MAX_KV_SIZE]; // use two buffers so compares work without stomping on each other

View File

@ -177,7 +177,9 @@ bool ParseIPv6Addr( const char *pszText, unsigned char *pOutIP, int *pOutPort, u
{
// Next thing must be a quad, or end of input. Is it a quad?
int quadDigit = ParseIPv6Addr_HexDigitVal( *s );
const char *pszStartQuad;
int quad;
if ( quadDigit < 0 )
{
if ( bQuadMustFollow )
@ -189,6 +191,7 @@ bool ParseIPv6Addr( const char *pszText, unsigned char *pOutIP, int *pOutPort, u
if ( d >= pEndIP )
return false;
pszStartQuad = s;
++s;
quad = quadDigit;
@ -214,6 +217,60 @@ bool ParseIPv6Addr( const char *pszText, unsigned char *pOutIP, int *pOutPort, u
}
}
// Check if we hit a period, which would happen if we
// have an IPv4 dotted decimal. For example, "::ffff:192.168.1.210"
if ( *s == '.' )
{
// Make sure we would have room to store four more bytes.
unsigned char *pEndDottedDecimal = d+4;
if ( pEndDottedDecimal > pEndIP )
return false;
// Parse 4 octets
s = pszStartQuad;
for (;;)
{
// Parse 1-3 decimal digits
int octet = ParseIPv6Addr_DecimalDigitVal( *s );
int dig;
if ( octet < 0 )
return false;
++s;
dig = ParseIPv6Addr_DecimalDigitVal( *s );
if ( dig >= 0 )
{
++s;
octet = octet*10 + dig;
dig = ParseIPv6Addr_DecimalDigitVal( *s );
if ( dig >= 0 )
{
++s;
octet = octet*10 + dig;
// Make sure value is in range.
if ( octet > 255 )
return false;
}
}
*(d++) = (unsigned char)octet;
// All done?
if ( d >= pEndDottedDecimal )
break;
// Next thing must be dot dot separator
if ( *s != '.' )
return false;
// Eat dot
++s;
}
break;
}
// Stash it in the next slot, ignoring for now the issue
// of compressed zeros
*(d++) = (unsigned char)( quad >> 8 );
@ -288,7 +345,7 @@ bool ParseIPv6Addr( const char *pszText, unsigned char *pOutIP, int *pOutPort, u
int nScopeDigit;
++s;
nScopeDigit = ParseIPv6Addr_DecimalDigitVal( *s );
if ( nScopeDigit < 0 )
return false;

View File

@ -25,8 +25,10 @@ extern "C" {
extern void IPv6IPToString( char *pszOutText, const unsigned char *ip );
/// Format IPv6 IP and port to string. This uses the recommended
/// bracket notation, eg [1234::1]:12345. Your buffer must be
/// bracket notation, eg [1234::1]:12345. Your buffer MUST be
/// at least k_ncchMaxIPV6AddrStringWithPort bytes.
///
/// If the scope is zero, it is not printed.
extern void IPv6AddrToString( char *pszOutText, const unsigned char *ip, uint16_t port, uint32_t scope );
/// Parse IPv6 address string. Returns true if parsed OK. Returns false
@ -41,7 +43,7 @@ extern void IPv6AddrToString( char *pszOutText, const unsigned char *ip, uint16_
///
/// Leading and trailing whitespace is OK around the entire string,
/// but not internal whitespace. The different methods for separating the
/// port in RFC5952 are supported section 6, except the ambiguous case
/// port in RFC5952 section 6 are supported, except the ambiguous case
/// of a colon to separate the port, when the IP contains a double-colon.
/// Brackets around an IP are OK, even if there is no port.
///

View File

@ -2051,7 +2051,7 @@ static void Mod_LoadTextureData( dbspmodel_t *bmod, int textureIndex )
// 2. Internal from map
// Try WAD texture (force while r_wadtextures is 1)
if(( r_wadtextures->value && bmod->wadlist.count > 0 ) || mipTex->offsets[0] <= 0 )
if(( r_wadtextures.value && bmod->wadlist.count > 0 ) || mipTex->offsets[0] <= 0 )
{
char texpath[MAX_VA_STRING];
int wadIndex = Mod_FindTextureInWadList( &bmod->wadlist, mipTex->name, texpath, sizeof( texpath ));
@ -3174,7 +3174,7 @@ Mod_CheckLump
check lump for existing
==================
*/
int Mod_CheckLump( const char *filename, const int lump, int *lumpsize )
int GAME_EXPORT Mod_CheckLump( const char *filename, const int lump, int *lumpsize )
{
file_t *f = FS_Open( filename, "rb", false );
byte buffer[sizeof( dheader_t ) + sizeof( dextrahdr_t )];
@ -3233,7 +3233,7 @@ Mod_ReadLump
reading random lump by user request
==================
*/
int Mod_ReadLump( const char *filename, const int lump, void **lumpdata, int *lumpsize )
int GAME_EXPORT Mod_ReadLump( const char *filename, const int lump, void **lumpdata, int *lumpsize )
{
file_t *f = FS_Open( filename, "rb", false );
byte buffer[sizeof( dheader_t ) + sizeof( dextrahdr_t )];
@ -3315,7 +3315,7 @@ writing lump by user request
only empty lumps is allows
==================
*/
int Mod_SaveLump( const char *filename, const int lump, void *lumpdata, int lumpsize )
int GAME_EXPORT Mod_SaveLump( const char *filename, const int lump, void *lumpdata, int lumpsize )
{
byte buffer[sizeof( dheader_t ) + sizeof( dextrahdr_t )];
size_t prefetch_size = sizeof( buffer );

View File

@ -119,9 +119,9 @@ typedef struct world_static_s
extern world_static_t world;
extern poolhandle_t com_studiocache;
extern model_t *loadmodel;
extern convar_t *mod_studiocache;
extern convar_t *r_wadtextures;
extern convar_t *r_showhull;
extern convar_t mod_studiocache;
extern convar_t r_wadtextures;
extern convar_t r_showhull;
//
// model.c

View File

@ -239,7 +239,7 @@ hull_t *Mod_HullForStudio( model_t *model, float frame, int sequence, vec3_t ang
bSkipShield = false;
*numhitboxes = 0; // assume error
if( mod_studiocache->value )
if( mod_studiocache.value )
{
bonecache = Mod_CheckStudioCache( model, frame, sequence, angles, origin, size, pcontroller, pblending );
@ -286,7 +286,7 @@ hull_t *Mod_HullForStudio( model_t *model, float frame, int sequence, vec3_t ang
// tell trace code about hitbox count
*numhitboxes = (bSkipShield) ? (mod_studiohdr->numhitboxes - 1) : (mod_studiohdr->numhitboxes);
if( mod_studiocache->value )
if( mod_studiocache.value )
Mod_AddToStudioCache( frame, sequence, angles, origin, size, pcontroller, pblending, model, studio_hull, *numhitboxes );
return studio_hull;

View File

@ -28,9 +28,9 @@ static model_info_t mod_crcinfo[MAX_MODELS];
static model_t mod_known[MAX_MODELS];
static int mod_numknown = 0;
poolhandle_t com_studiocache; // cache for submodels
convar_t *mod_studiocache;
convar_t *r_wadtextures;
convar_t *r_showhull;
CVAR_DEFINE( mod_studiocache, "r_studiocache", "1", FCVAR_ARCHIVE, "enables studio cache for speedup tracing hitboxes" );
CVAR_DEFINE_AUTO( r_wadtextures, "0", 0, "completely ignore textures in the bsp-file if enabled" );
CVAR_DEFINE_AUTO( r_showhull, "0", 0, "draw collision hulls 1-3" );
model_t *loadmodel;
/*
@ -134,9 +134,9 @@ Mod_Init
void Mod_Init( void )
{
com_studiocache = Mem_AllocPool( "Studio Cache" );
mod_studiocache = Cvar_Get( "r_studiocache", "1", FCVAR_ARCHIVE, "enables studio cache for speedup tracing hitboxes" );
r_wadtextures = Cvar_Get( "r_wadtextures", "0", 0, "completely ignore textures in the bsp-file if enabled" );
r_showhull = Cvar_Get( "r_showhull", "0", 0, "draw collision hulls 1-3" );
Cvar_RegisterVariable( &mod_studiocache );
Cvar_RegisterVariable( &r_wadtextures );
Cvar_RegisterVariable( &r_showhull );
Cmd_AddCommand( "mapstats", Mod_PrintWorldStats_f, "show stats for currently loaded map" );
Cmd_AddCommand( "modellist", Mod_Modellist_f, "display loaded models list" );
@ -403,7 +403,7 @@ static void Mod_PurgeStudioCache( void )
int i;
// refresh hull data
SetBits( r_showhull->flags, FCVAR_CHANGED );
SetBits( r_showhull.flags, FCVAR_CHANGED );
#if !XASH_DEDICATED
Mod_ReleaseHullPolygons();
#endif

View File

@ -23,8 +23,8 @@ GNU General Public License for more details.
// precalculated bit masks for WriteUBitLong.
// Using these tables instead of doing the calculations
// gives a 33% speedup in WriteUBitLong.
static dword BitWriteMasks[32][33];
static dword ExtraMasks[32];
static uint32_t BitWriteMasks[32][33];
static uint32_t ExtraMasks[32];
const char *svc_strings[svc_lastmsg+1] =
{
"svc_bad",
@ -119,7 +119,7 @@ void MSG_InitExt( sizebuf_t *sb, const char *pDebugName, void *pData, int nBytes
void MSG_StartWriting( sizebuf_t *sb, void *pData, int nBytes, int iStartBit, int nBits )
{
// make sure it's dword aligned and padded.
Assert(((dword)pData & 3 ) == 0 );
Assert(((uint32_t)pData & 3 ) == 0 );
sb->pDebugName = "Unnamed";
sb->pData = (byte *)pData;
@ -219,14 +219,14 @@ void MSG_WriteUBitLong( sizebuf_t *sb, uint curData, int numbits )
int nBitsLeft = numbits;
int iCurBit = sb->iCurBit;
uint iDWord = iCurBit >> 5; // Mask in a dword.
dword iCurBitMasked;
uint32_t iCurBitMasked;
int nBitsWritten;
Assert(( iDWord * 4 + sizeof( int )) <= (uint)MSG_GetMaxBytes( sb ));
iCurBitMasked = iCurBit & 31;
((dword *)sb->pData)[iDWord] &= BitWriteMasks[iCurBitMasked][nBitsLeft];
((dword *)sb->pData)[iDWord] |= curData << iCurBitMasked;
((uint32_t *)sb->pData)[iDWord] &= BitWriteMasks[iCurBitMasked][nBitsLeft];
((uint32_t *)sb->pData)[iDWord] |= curData << iCurBitMasked;
// did it span a dword?
nBitsWritten = 32 - iCurBitMasked;
@ -238,8 +238,8 @@ void MSG_WriteUBitLong( sizebuf_t *sb, uint curData, int numbits )
curData >>= nBitsWritten;
iCurBitMasked = iCurBit & 31;
((dword *)sb->pData)[iDWord+1] &= BitWriteMasks[iCurBitMasked][nBitsLeft];
((dword *)sb->pData)[iDWord+1] |= curData << iCurBitMasked;
((uint32_t *)sb->pData)[iDWord+1] &= BitWriteMasks[iCurBitMasked][nBitsLeft];
((uint32_t *)sb->pData)[iDWord+1] |= curData << iCurBitMasked;
}
sb->iCurBit += numbits;
}
@ -284,7 +284,7 @@ qboolean MSG_WriteBits( sizebuf_t *sb, const void *pData, int nBits )
int nBitsLeft = nBits;
// get output dword-aligned.
while((( dword )pOut & 3 ) != 0 && nBitsLeft >= 8 )
while((( uint32_t )pOut & 3 ) != 0 && nBitsLeft >= 8 )
{
MSG_WriteUBitLong( sb, *pOut, 8 );
@ -295,9 +295,9 @@ qboolean MSG_WriteBits( sizebuf_t *sb, const void *pData, int nBits )
// read dwords.
while( nBitsLeft >= 32 )
{
MSG_WriteUBitLong( sb, *(( dword *)pOut ), 32 );
MSG_WriteUBitLong( sb, *(( uint32_t *)pOut ), 32 );
pOut += sizeof( dword );
pOut += sizeof( uint32_t );
nBitsLeft -= 32;
}
@ -383,37 +383,37 @@ void MSG_WriteCmdExt( sizebuf_t *sb, int cmd, netsrc_t type, const char *name )
}
}
#endif
MSG_WriteUBitLong( sb, cmd, sizeof( byte ) << 3 );
MSG_WriteUBitLong( sb, cmd, sizeof( uint8_t ) << 3 );
}
void MSG_WriteChar( sizebuf_t *sb, int val )
{
MSG_WriteSBitLong( sb, val, sizeof( char ) << 3 );
MSG_WriteSBitLong( sb, val, sizeof( int8_t ) << 3 );
}
void MSG_WriteByte( sizebuf_t *sb, int val )
{
MSG_WriteUBitLong( sb, val, sizeof( byte ) << 3 );
MSG_WriteUBitLong( sb, val, sizeof( uint8_t ) << 3 );
}
void MSG_WriteShort( sizebuf_t *sb, int val )
{
MSG_WriteSBitLong( sb, val, sizeof(short ) << 3 );
MSG_WriteSBitLong( sb, val, sizeof( int16_t ) << 3 );
}
void MSG_WriteWord( sizebuf_t *sb, int val )
{
MSG_WriteUBitLong( sb, val, sizeof( word ) << 3 );
MSG_WriteUBitLong( sb, val, sizeof( uint16_t ) << 3 );
}
void MSG_WriteLong( sizebuf_t *sb, int val )
{
MSG_WriteSBitLong( sb, val, sizeof( int ) << 3 );
MSG_WriteSBitLong( sb, val, sizeof( int32_t ) << 3 );
}
void MSG_WriteDword( sizebuf_t *sb, dword val )
void MSG_WriteDword( sizebuf_t *sb, uint val )
{
MSG_WriteUBitLong( sb, val, sizeof( dword ) << 3 );
MSG_WriteUBitLong( sb, val, sizeof( uint32_t ) << 3 );
}
void MSG_WriteFloat( sizebuf_t *sb, float val )
@ -518,7 +518,7 @@ qboolean MSG_ReadBits( sizebuf_t *sb, void *pOutData, int nBits )
int nBitsLeft = nBits;
// get output dword-aligned.
while((( dword )pOut & 3) != 0 && nBitsLeft >= 8 )
while((( uint32_t )pOut & 3) != 0 && nBitsLeft >= 8 )
{
*pOut = (byte)MSG_ReadUBitLong( sb, 8 );
++pOut;
@ -528,8 +528,8 @@ qboolean MSG_ReadBits( sizebuf_t *sb, void *pOutData, int nBits )
// read dwords.
while( nBitsLeft >= 32 )
{
*((dword *)pOut) = MSG_ReadUBitLong( sb, 32 );
pOut += sizeof( dword );
*((uint32_t *)pOut) = MSG_ReadUBitLong( sb, 32 );
pOut += sizeof( uint32_t );
nBitsLeft -= 32;
}
@ -591,7 +591,7 @@ uint MSG_ReadBitLong( sizebuf_t *sb, int numbits, qboolean bSigned )
int MSG_ReadCmd( sizebuf_t *sb, netsrc_t type )
{
int cmd = MSG_ReadUBitLong( sb, sizeof( byte ) << 3 );
int cmd = MSG_ReadUBitLong( sb, sizeof( uint8_t ) << 3 );
#ifdef DEBUG_NET_MESSAGES_READ
if( type == NS_SERVER )
@ -608,22 +608,22 @@ int MSG_ReadCmd( sizebuf_t *sb, netsrc_t type )
int MSG_ReadChar( sizebuf_t *sb )
{
return MSG_ReadSBitLong( sb, sizeof( char ) << 3 );
return MSG_ReadSBitLong( sb, sizeof( int8_t ) << 3 );
}
int MSG_ReadByte( sizebuf_t *sb )
{
return MSG_ReadUBitLong( sb, sizeof( byte ) << 3 );
return MSG_ReadUBitLong( sb, sizeof( uint8_t ) << 3 );
}
int MSG_ReadShort( sizebuf_t *sb )
{
return MSG_ReadSBitLong( sb, sizeof( short ) << 3 );
return MSG_ReadSBitLong( sb, sizeof( int16_t ) << 3 );
}
int MSG_ReadWord( sizebuf_t *sb )
{
return MSG_ReadUBitLong( sb, sizeof( word ) << 3 );
return MSG_ReadUBitLong( sb, sizeof( uint16_t ) << 3 );
}
float MSG_ReadCoord( sizebuf_t *sb )
@ -650,12 +650,12 @@ void MSG_ReadVec3Angles( sizebuf_t *sb, vec3_t fa )
int MSG_ReadLong( sizebuf_t *sb )
{
return MSG_ReadSBitLong( sb, sizeof( int ) << 3 );
return MSG_ReadSBitLong( sb, sizeof( int32_t ) << 3 );
}
dword MSG_ReadDword( sizebuf_t *sb )
uint MSG_ReadDword( sizebuf_t *sb )
{
return MSG_ReadUBitLong( sb, sizeof( dword ) << 3 );
return MSG_ReadUBitLong( sb, sizeof( uint32_t ) << 3 );
}
float MSG_ReadFloat( sizebuf_t *sb )

View File

@ -94,7 +94,7 @@ void MSG_WriteByte( sizebuf_t *sb, int val );
void MSG_WriteShort( sizebuf_t *sb, int val );
void MSG_WriteWord( sizebuf_t *sb, int val );
void MSG_WriteLong( sizebuf_t *sb, int val );
void MSG_WriteDword( sizebuf_t *sb, dword val );
void MSG_WriteDword( sizebuf_t *sb, uint val );
void MSG_WriteCoord( sizebuf_t *sb, float val );
void MSG_WriteFloat( sizebuf_t *sb, float val );
void MSG_WriteVec3Coord( sizebuf_t *sb, const float *fa );
@ -131,7 +131,7 @@ int MSG_ReadByte( sizebuf_t *sb );
int MSG_ReadShort( sizebuf_t *sb );
int MSG_ReadWord( sizebuf_t *sb );
int MSG_ReadLong( sizebuf_t *sb );
dword MSG_ReadDword( sizebuf_t *sb );
uint MSG_ReadDword( sizebuf_t *sb );
float MSG_ReadCoord( sizebuf_t *sb );
float MSG_ReadFloat( sizebuf_t *sb );
void MSG_ReadVec3Coord( sizebuf_t *sb, vec3_t fa );

View File

@ -84,10 +84,10 @@ such as during the connection stage while waiting for the client to load,
then a packet only needs to be delivered if there is something in the
unacknowledged reliable
*/
convar_t *net_showpackets;
convar_t *net_chokeloopback;
convar_t *net_showdrop;
convar_t *net_qport;
CVAR_DEFINE_AUTO( net_showpackets, "0", 0, "show network packets" );
CVAR_DEFINE_AUTO( net_chokeloop, "0", 0, "apply bandwidth choke to loopback packets" );
CVAR_DEFINE_AUTO( net_showdrop, "0", 0, "show packets that are dropped" );
CVAR_DEFINE_AUTO( net_qport, "0", FCVAR_READ_ONLY, "current quake netport" );
int net_drop;
netadr_t net_from;
@ -243,15 +243,18 @@ Netchan_Init
*/
void Netchan_Init( void )
{
char buf[32];
int port;
// pick a port value that should be nice and random
port = COM_RandomLong( 1, 65535 );
Q_snprintf( buf, sizeof( buf ), "%i", port );
net_showpackets = Cvar_Get ("net_showpackets", "0", 0, "show network packets" );
net_chokeloopback = Cvar_Get( "net_chokeloop", "0", 0, "apply bandwidth choke to loopback packets" );
net_showdrop = Cvar_Get( "net_showdrop", "0", 0, "show packets that are dropped" );
net_qport = Cvar_Getf( "net_qport", FCVAR_READ_ONLY, "current quake netport", "%i", port );
Cvar_RegisterVariable( &net_showpackets );
Cvar_RegisterVariable( &net_chokeloop );
Cvar_RegisterVariable( &net_showdrop );
Cvar_RegisterVariable( &net_qport );
Cvar_FullSet( net_qport.name, buf, net_qport.flags );
net_mempool = Mem_AllocPool( "Network Pool" );
@ -349,7 +352,7 @@ Returns true if the bandwidth choke isn't active
qboolean Netchan_CanPacket( netchan_t *chan, qboolean choke )
{
// never choke loopback packets.
if( !choke || ( !net_chokeloopback->value && NET_IsLocalAddress( chan->remote_address ) ))
if( !choke || ( !net_chokeloop.value && NET_IsLocalAddress( chan->remote_address ) ))
{
chan->cleartime = host.realtime;
return true;
@ -1331,7 +1334,7 @@ void Netchan_UpdateProgress( netchan_t *chan )
if( host.downloadcount == 0 )
{
scr_download->value = -1.0f;
scr_download.value = -1.0f;
host.downloadfile[0] = '\0';
}
@ -1399,7 +1402,7 @@ void Netchan_UpdateProgress( netchan_t *chan )
}
scr_download->value = bestpercent;
scr_download.value = bestpercent;
#endif // XASH_DEDICATED
}
@ -1699,7 +1702,7 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
chan->cleartime += ( MSG_GetNumBytesWritten( &send ) + UDP_HEADER_SIZE ) * fRate;
if( net_showpackets->value && net_showpackets->value != 2.0f )
if( net_showpackets.value && net_showpackets.value != 2.0f )
{
Con_Printf( " %s --> sz=%i seq=%i ack=%i rel=%i tm=%f\n"
, ns_strings[chan->sock]
@ -1769,7 +1772,7 @@ qboolean Netchan_Process( netchan_t *chan, sizebuf_t *msg )
sequence_ack &= ~BIT( 30 );
sequence_ack &= ~BIT( 31 );
if( net_showpackets->value && net_showpackets->value != 3.0f )
if( net_showpackets.value && net_showpackets.value != 3.0f )
{
Con_Printf( " %s <-- sz=%i seq=%i ack=%i rel=%i tm=%f\n"
, ns_strings[chan->sock]
@ -1783,7 +1786,7 @@ qboolean Netchan_Process( netchan_t *chan, sizebuf_t *msg )
// discard stale or duplicated packets
if( sequence <= (uint)chan->incoming_sequence )
{
if( net_showdrop->value )
if( net_showdrop.value )
{
const char *adr = NET_AdrToString( chan->remote_address );
@ -1796,7 +1799,7 @@ qboolean Netchan_Process( netchan_t *chan, sizebuf_t *msg )
// dropped packets don't keep the message from being used
net_drop = sequence - ( chan->incoming_sequence + 1 );
if( net_drop > 0 && net_showdrop->value )
if( net_drop > 0 && net_showdrop.value )
Con_Printf( "%s:dropped %i packets at %i\n", NET_AdrToString( chan->remote_address ), net_drop, sequence );
// if the current outgoing reliable message has been acknowledged

View File

@ -315,16 +315,28 @@ static const delta_field_t ent_fields[] =
{ NULL },
};
enum
{
DT_EVENT_T = 0,
DT_MOVEVARS_T,
DT_USERCMD_T,
DT_CLIENTDATA_T,
DT_WEAPONDATA_T,
DT_ENTITY_STATE_T,
DT_ENTITY_STATE_PLAYER_T,
DT_CUSTOM_ENTITY_STATE_T,
};
static delta_info_t dt_info[] =
{
{ "event_t", ev_fields, NUM_FIELDS( ev_fields ) },
{ "movevars_t", pm_fields, NUM_FIELDS( pm_fields ) },
{ "usercmd_t", cmd_fields, NUM_FIELDS( cmd_fields ) },
{ "clientdata_t", cd_fields, NUM_FIELDS( cd_fields ) },
{ "weapon_data_t", wd_fields, NUM_FIELDS( wd_fields ) },
{ "entity_state_t", ent_fields, NUM_FIELDS( ent_fields ) },
{ "entity_state_player_t", ent_fields, NUM_FIELDS( ent_fields ) },
{ "custom_entity_state_t", ent_fields, NUM_FIELDS( ent_fields ) },
[DT_EVENT_T] = { "event_t", ev_fields, NUM_FIELDS( ev_fields ) },
[DT_MOVEVARS_T] = { "movevars_t", pm_fields, NUM_FIELDS( pm_fields ) },
[DT_USERCMD_T] = { "usercmd_t", cmd_fields, NUM_FIELDS( cmd_fields ) },
[DT_CLIENTDATA_T] = { "clientdata_t", cd_fields, NUM_FIELDS( cd_fields ) },
[DT_WEAPONDATA_T] = { "weapon_data_t", wd_fields, NUM_FIELDS( wd_fields ) },
[DT_ENTITY_STATE_T] = { "entity_state_t", ent_fields, NUM_FIELDS( ent_fields ) },
[DT_ENTITY_STATE_PLAYER_T] = { "entity_state_player_t", ent_fields, NUM_FIELDS( ent_fields ) },
[DT_CUSTOM_ENTITY_STATE_T] = { "custom_entity_state_t", ent_fields, NUM_FIELDS( ent_fields ) },
{ NULL },
};
@ -347,16 +359,13 @@ static delta_info_t *Delta_FindStruct( const char *name )
return NULL;
}
int Delta_NumTables( void )
static int Delta_NumTables( void )
{
return NUM_FIELDS( dt_info );
}
delta_info_t *Delta_FindStructByIndex( int index )
static delta_info_t *Delta_FindStructByIndex( int index )
{
if( index < 0 || index >= NUM_FIELDS( dt_info ))
return NULL;
return &dt_info[index];
}
@ -435,17 +444,12 @@ static int Delta_IndexForFieldInfo( const delta_field_t *pInfo, const char *fiel
return -1;
}
static qboolean Delta_AddField( const char *pStructName, const char *pName, int flags, int bits, float mul, float post_mul )
static qboolean Delta_AddField( delta_info_t *dt, const char *pName, int flags, int bits, float mul, float post_mul )
{
delta_info_t *dt;
delta_field_t *pFieldInfo;
delta_t *pField;
int i;
// get the delta struct
dt = Delta_FindStruct( pStructName );
Assert( dt != NULL );
// check for coexisting field
for( i = 0, pField = dt->pFields; i < dt->numFields; i++, pField++ )
{
@ -464,13 +468,13 @@ static qboolean Delta_AddField( const char *pStructName, const char *pName, int
pFieldInfo = Delta_FindFieldInfo( dt->pInfo, pName );
if( !pFieldInfo )
{
Con_DPrintf( S_ERROR "Delta_Add: couldn't find description for %s->%s\n", pStructName, pName );
Con_DPrintf( S_ERROR "Delta_Add: couldn't find description for %s->%s\n", dt->pName, pName );
return false;
}
if( dt->numFields + 1 > dt->maxFields )
{
Con_DPrintf( S_WARN "Delta_Add: can't add %s->%s encoder list is full\n", pStructName, pName );
Con_DPrintf( S_WARN "Delta_Add: can't add %s->%s encoder list is full\n", dt->pName, pName );
return false; // too many fields specified (duplicated ?)
}
@ -491,7 +495,7 @@ static qboolean Delta_AddField( const char *pStructName, const char *pName, int
return true;
}
void Delta_WriteTableField( sizebuf_t *msg, int tableIndex, const delta_t *pField )
static void Delta_WriteTableField( sizebuf_t *msg, int tableIndex, const delta_t *pField )
{
int nameIndex;
delta_info_t *dt;
@ -572,7 +576,7 @@ void Delta_ParseTableField( sizebuf_t *msg )
Delta_Shutdown();
// add field to table
Delta_AddField( dt->pName, pName, flags, bits, mul, post_mul );
Delta_AddField( dt, pName, flags, bits, mul, post_mul );
}
static qboolean Delta_ParseField( char **delta_script, const delta_field_t *pInfo, delta_t *pField, qboolean bPost )
@ -820,43 +824,43 @@ void Delta_Init( void )
Delta_InitFields (); // initialize fields
delta_init = true;
dt = Delta_FindStruct( "movevars_t" );
dt = Delta_FindStructByIndex( DT_MOVEVARS_T );
Assert( dt != NULL );
if( dt->bInitialized ) return; // "movevars_t" already specified by user
// create movevars_t delta internal
Delta_AddField( "movevars_t", "gravity", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "stopspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "maxspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "spectatormaxspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "accelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "airaccelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "wateraccelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "friction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "edgefriction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "waterfriction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "bounce", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "stepsize", DT_FLOAT|DT_SIGNED, 16, 16.0f, 1.0f );
Delta_AddField( "movevars_t", "maxvelocity", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( dt, "gravity", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( dt, "stopspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( dt, "maxspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( dt, "spectatormaxspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( dt, "accelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( dt, "airaccelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( dt, "wateraccelerate", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( dt, "friction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( dt, "edgefriction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( dt, "waterfriction", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( dt, "bounce", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( dt, "stepsize", DT_FLOAT|DT_SIGNED, 16, 16.0f, 1.0f );
Delta_AddField( dt, "maxvelocity", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
if( FBitSet( host.features, ENGINE_WRITE_LARGE_COORD ))
Delta_AddField( "movevars_t", "zmax", DT_FLOAT|DT_SIGNED, 18, 1.0f, 1.0f );
else Delta_AddField( "movevars_t", "zmax", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f );
Delta_AddField( dt, "zmax", DT_FLOAT|DT_SIGNED, 18, 1.0f, 1.0f );
else Delta_AddField( dt, "zmax", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f );
Delta_AddField( "movevars_t", "waveHeight", DT_FLOAT|DT_SIGNED, 16, 16.0f, 1.0f );
Delta_AddField( "movevars_t", "skyName", DT_STRING, 1, 1.0f, 1.0f );
Delta_AddField( "movevars_t", "footsteps", DT_INTEGER, 1, 1.0f, 1.0f );
Delta_AddField( "movevars_t", "rollangle", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
Delta_AddField( "movevars_t", "rollspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( "movevars_t", "skycolor_r", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f ); // 0 - 264
Delta_AddField( "movevars_t", "skycolor_g", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f );
Delta_AddField( "movevars_t", "skycolor_b", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f );
Delta_AddField( "movevars_t", "skyvec_x", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f ); // 0 - 1
Delta_AddField( "movevars_t", "skyvec_y", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
Delta_AddField( "movevars_t", "skyvec_z", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
Delta_AddField( "movevars_t", "wateralpha", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
Delta_AddField( "movevars_t", "fog_settings", DT_INTEGER, 32, 1.0f, 1.0f );
Delta_AddField( dt, "waveHeight", DT_FLOAT|DT_SIGNED, 16, 16.0f, 1.0f );
Delta_AddField( dt, "skyName", DT_STRING, 1, 1.0f, 1.0f );
Delta_AddField( dt, "footsteps", DT_INTEGER, 1, 1.0f, 1.0f );
Delta_AddField( dt, "rollangle", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
Delta_AddField( dt, "rollspeed", DT_FLOAT|DT_SIGNED, 16, 8.0f, 1.0f );
Delta_AddField( dt, "skycolor_r", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f ); // 0 - 264
Delta_AddField( dt, "skycolor_g", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f );
Delta_AddField( dt, "skycolor_b", DT_FLOAT|DT_SIGNED, 16, 1.0f, 1.0f );
Delta_AddField( dt, "skyvec_x", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f ); // 0 - 1
Delta_AddField( dt, "skyvec_y", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
Delta_AddField( dt, "skyvec_z", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
Delta_AddField( dt, "wateralpha", DT_FLOAT|DT_SIGNED, 16, 32.0f, 1.0f );
Delta_AddField( dt, "fog_settings", DT_INTEGER, 32, 1.0f, 1.0f );
dt->numFields = NUM_FIELDS( pm_fields ) - 4;
// now done
@ -914,7 +918,7 @@ Delta_ClampIntegerField
prevent data to out of range
=====================
*/
static int Delta_ClampIntegerField( delta_t *pField, int iValue, qboolean bSigned, int numbits )
static int Delta_ClampIntegerField( delta_t *pField, int iValue, int signbit, int numbits )
{
#ifdef _DEBUG
if( numbits < 32 && abs( iValue ) >= (uint)BIT( numbits ))
@ -922,10 +926,13 @@ static int Delta_ClampIntegerField( delta_t *pField, int iValue, qboolean bSigne
#endif
if( numbits < 32 )
{
int signbits = bSigned ? ( numbits - 1 ) : numbits;
int signbits = numbits - signbit;
int maxnum = BIT( signbits ) - 1;
int minnum = bSigned ? ( -maxnum - 1 ) : 0;
iValue = bound( minnum, iValue, maxnum );
if( iValue > maxnum )
iValue = maxnum;
else if( signbit && iValue < -maxnum - 1 )
iValue = -maxnum - 1;
}
return iValue; // clamped;
@ -941,7 +948,7 @@ assume from and to is valid
*/
static qboolean Delta_CompareField( delta_t *pField, void *from, void *to, double timebase )
{
qboolean bSigned = ( pField->flags & DT_SIGNED ) ? true : false;
int signbit = ( pField->flags & DT_SIGNED ) ? 1 : 0;
float val_a, val_b;
int fromF, toF;
@ -956,65 +963,67 @@ static qboolean Delta_CompareField( delta_t *pField, void *from, void *to, doubl
if( pField->flags & DT_BYTE )
{
if( pField->flags & DT_SIGNED )
if( signbit )
{
fromF = *(signed char *)((byte *)from + pField->offset );
toF = *(signed char *)((byte *)to + pField->offset );
fromF = *(int8_t *)((int8_t *)from + pField->offset );
toF = *(int8_t *)((int8_t *)to + pField->offset );
}
else
{
fromF = *(byte *)((byte *)from + pField->offset );
toF = *(byte *)((byte *)to + pField->offset );
fromF = *(uint8_t *)((int8_t *)from + pField->offset );
toF = *(uint8_t *)((int8_t *)to + pField->offset );
}
fromF = Delta_ClampIntegerField( pField, fromF, bSigned, pField->bits );
toF = Delta_ClampIntegerField( pField, toF, bSigned, pField->bits );
fromF = Delta_ClampIntegerField( pField, fromF, signbit, pField->bits );
toF = Delta_ClampIntegerField( pField, toF, signbit, pField->bits );
if( !Q_equal(pField->multiplier, 1.0) )
if( !Q_equal(pField->multiplier, 1.0f ))
fromF *= pField->multiplier;
if( !Q_equal( pField->multiplier, 1.0 ) )
if( !Q_equal( pField->multiplier, 1.0f ))
toF *= pField->multiplier;
}
else if( pField->flags & DT_SHORT )
{
if( pField->flags & DT_SIGNED )
if( signbit )
{
fromF = *(short *)((byte *)from + pField->offset );
toF = *(short *)((byte *)to + pField->offset );
fromF = *(int16_t *)((int8_t *)from + pField->offset );
toF = *(int16_t *)((int8_t *)to + pField->offset );
}
else
{
fromF = *(word *)((byte *)from + pField->offset );
toF = *(word *)((byte *)to + pField->offset );
fromF = *(uint16_t *)((int8_t *)from + pField->offset );
toF = *(uint16_t *)((int8_t *)to + pField->offset );
}
fromF = Delta_ClampIntegerField( pField, fromF, bSigned, pField->bits );
toF = Delta_ClampIntegerField( pField, toF, bSigned, pField->bits );
fromF = Delta_ClampIntegerField( pField, fromF, signbit, pField->bits );
toF = Delta_ClampIntegerField( pField, toF, signbit, pField->bits );
if( !Q_equal( pField->multiplier, 1.0 ) )
if( !Q_equal(pField->multiplier, 1.0f ))
fromF *= pField->multiplier;
if( !Q_equal( pField->multiplier, 1.0 ) )
if( !Q_equal( pField->multiplier, 1.0f ))
toF *= pField->multiplier;
}
else if( pField->flags & DT_INTEGER )
{
if( pField->flags & DT_SIGNED )
if( signbit )
{
fromF = *(int *)((byte *)from + pField->offset );
toF = *(int *)((byte *)to + pField->offset );
fromF = *(int32_t *)((int8_t *)from + pField->offset );
toF = *(int32_t *)((int8_t *)to + pField->offset );
}
else
{
fromF = *(uint *)((byte *)from + pField->offset );
toF = *(uint *)((byte *)to + pField->offset );
fromF = *(uint32_t *)((int8_t *)from + pField->offset );
toF = *(uint32_t *)((int8_t *)to + pField->offset );
}
fromF = Delta_ClampIntegerField( pField, fromF, bSigned, pField->bits );
toF = Delta_ClampIntegerField( pField, toF, bSigned, pField->bits );
if( !Q_equal( pField->multiplier, 1.0 ) )
fromF = Delta_ClampIntegerField( pField, fromF, signbit, pField->bits );
toF = Delta_ClampIntegerField( pField, toF, signbit, pField->bits );
if( !Q_equal(pField->multiplier, 1.0f ))
fromF *= pField->multiplier;
if( !Q_equal( pField->multiplier, 1.0 ) )
if( !Q_equal( pField->multiplier, 1.0f ))
toF *= pField->multiplier;
}
else if( pField->flags & ( DT_ANGLE|DT_FLOAT ))
@ -1025,8 +1034,8 @@ static qboolean Delta_CompareField( delta_t *pField, void *from, void *to, doubl
}
else if( pField->flags & DT_TIMEWINDOW_8 )
{
val_a = Q_rint((*(float *)((byte *)from + pField->offset )) * 100.0 );
val_b = Q_rint((*(float *)((byte *)to + pField->offset )) * 100.0 );
val_a = Q_rint((*(float *)((byte *)from + pField->offset )) * 100.0f );
val_b = Q_rint((*(float *)((byte *)to + pField->offset )) * 100.0f );
val_a -= Q_rint(timebase * 100.0);
val_b -= Q_rint(timebase * 100.0);
fromF = FloatAsInt( val_a );
@ -1037,7 +1046,7 @@ static qboolean Delta_CompareField( delta_t *pField, void *from, void *to, doubl
val_a = (*(float *)((byte *)from + pField->offset ));
val_b = (*(float *)((byte *)to + pField->offset ));
if( !Q_equal( pField->multiplier, 1.0 ) )
if( !Q_equal( pField->multiplier, 1.0f ))
{
val_a *= pField->multiplier;
val_b *= pField->multiplier;
@ -1063,7 +1072,7 @@ static qboolean Delta_CompareField( delta_t *pField, void *from, void *to, doubl
toF = Q_strcmp( s1, s2 );
}
return ( fromF == toF ) ? true : false;
return fromF == toF;
}
/*
@ -1089,10 +1098,10 @@ int Delta_TestBaseline( entity_state_t *from, entity_state_t *to, qboolean playe
}
if( FBitSet( to->entityType, ENTITY_BEAM ))
dt = Delta_FindStruct( "custom_entity_state_t" );
dt = Delta_FindStructByIndex( DT_CUSTOM_ENTITY_STATE_T );
else if( player )
dt = Delta_FindStruct( "entity_state_player_t" );
else dt = Delta_FindStruct( "entity_state_t" );
dt = Delta_FindStructByIndex( DT_ENTITY_STATE_PLAYER_T );
else dt = Delta_FindStructByIndex( DT_ENTITY_STATE_T );
Assert( dt && dt->bInitialized );
@ -1133,7 +1142,7 @@ assume from and to is valid
*/
static qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, void *to, double timebase )
{
qboolean bSigned = ( pField->flags & DT_SIGNED ) ? true : false;
int signbit = FBitSet( pField->flags, DT_SIGNED ) ? 1 : 0;
float flValue, flAngle;
uint iValue;
const char *pStr;
@ -1148,49 +1157,49 @@ static qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, v
if( pField->flags & DT_BYTE )
{
if( bSigned )
if( signbit )
iValue = *(int8_t *)((int8_t *)to + pField->offset );
else
iValue = *(uint8_t *)((int8_t *)to + pField->offset );
iValue = Delta_ClampIntegerField( pField, iValue, bSigned, pField->bits );
iValue = Delta_ClampIntegerField( pField, iValue, signbit, pField->bits );
if( !Q_equal( pField->multiplier, 1.0 ) )
iValue *= pField->multiplier;
MSG_WriteBitLong( msg, iValue, pField->bits, bSigned );
MSG_WriteBitLong( msg, iValue, pField->bits, signbit );
}
else if( pField->flags & DT_SHORT )
{
if( bSigned )
if( signbit )
iValue = *(int16_t *)((int8_t *)to + pField->offset );
else
iValue = *(uint16_t *)((int8_t *)to + pField->offset );
iValue = Delta_ClampIntegerField( pField, iValue, bSigned, pField->bits );
iValue = Delta_ClampIntegerField( pField, iValue, signbit, pField->bits );
if( !Q_equal( pField->multiplier, 1.0 ) )
iValue *= pField->multiplier;
MSG_WriteBitLong( msg, iValue, pField->bits, bSigned );
MSG_WriteBitLong( msg, iValue, pField->bits, signbit );
}
else if( pField->flags & DT_INTEGER )
{
if( bSigned )
if( signbit )
iValue = *(int32_t *)((int8_t *)to + pField->offset );
else
iValue = *(uint32_t *)((int8_t *)to + pField->offset );
iValue = Delta_ClampIntegerField( pField, iValue, bSigned, pField->bits );
iValue = Delta_ClampIntegerField( pField, iValue, signbit, pField->bits );
if( !Q_equal( pField->multiplier, 1.0 ) )
iValue *= pField->multiplier;
MSG_WriteBitLong( msg, iValue, pField->bits, bSigned );
MSG_WriteBitLong( msg, iValue, pField->bits, signbit );
}
else if( pField->flags & DT_FLOAT )
{
flValue = *(float *)((byte *)to + pField->offset );
iValue = (int)((double)flValue * pField->multiplier);
iValue = Delta_ClampIntegerField( pField, iValue, bSigned, pField->bits );
MSG_WriteBitLong( msg, iValue, pField->bits, bSigned );
iValue = Delta_ClampIntegerField( pField, iValue, signbit, pField->bits );
MSG_WriteBitLong( msg, iValue, pField->bits, signbit );
}
else if( pField->flags & DT_ANGLE )
{
@ -1202,19 +1211,19 @@ static qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, v
}
else if( pField->flags & DT_TIMEWINDOW_8 )
{
bSigned = true; // timewindow is always signed
signbit = 1; // timewindow is always signed
flValue = *(float *)((byte *)to + pField->offset );
iValue = (int)Q_rint( timebase * 100.0 ) - (int)Q_rint( flValue * 100.0 );
iValue = Delta_ClampIntegerField( pField, iValue, bSigned, pField->bits );
MSG_WriteBitLong( msg, iValue, pField->bits, bSigned );
iValue = Delta_ClampIntegerField( pField, iValue, signbit, pField->bits );
MSG_WriteBitLong( msg, iValue, pField->bits, signbit );
}
else if( pField->flags & DT_TIMEWINDOW_BIG )
{
bSigned = true; // timewindow is always signed
signbit = 1; // timewindow is always signed
flValue = *(float *)((byte *)to + pField->offset );
iValue = (int)Q_rint( timebase * pField->multiplier ) - (int)Q_rint( flValue * pField->multiplier );
iValue = Delta_ClampIntegerField( pField, iValue, bSigned, pField->bits );
MSG_WriteBitLong( msg, iValue, pField->bits, bSigned );
iValue = Delta_ClampIntegerField( pField, iValue, signbit, pField->bits );
MSG_WriteBitLong( msg, iValue, pField->bits, signbit );
}
else if( pField->flags & DT_STRING )
{
@ -1396,7 +1405,7 @@ void MSG_WriteDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to )
delta_info_t *dt;
int i;
dt = Delta_FindStruct( "usercmd_t" );
dt = Delta_FindStructByIndex( DT_USERCMD_T );
Assert( dt && dt->bInitialized );
pField = dt->pFields;
@ -1423,7 +1432,7 @@ void MSG_ReadDeltaUsercmd( sizebuf_t *msg, usercmd_t *from, usercmd_t *to )
delta_info_t *dt;
int i;
dt = Delta_FindStruct( "usercmd_t" );
dt = Delta_FindStructByIndex( DT_USERCMD_T );
Assert( dt && dt->bInitialized );
pField = dt->pFields;
@ -1458,7 +1467,7 @@ void MSG_WriteDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to )
delta_info_t *dt;
int i;
dt = Delta_FindStruct( "event_t" );
dt = Delta_FindStructByIndex( DT_EVENT_T );
Assert( dt && dt->bInitialized );
pField = dt->pFields;
@ -1485,7 +1494,7 @@ void MSG_ReadDeltaEvent( sizebuf_t *msg, event_args_t *from, event_args_t *to )
delta_info_t *dt;
int i;
dt = Delta_FindStruct( "event_t" );
dt = Delta_FindStructByIndex( DT_EVENT_T );
Assert( dt && dt->bInitialized );
pField = dt->pFields;
@ -1514,7 +1523,7 @@ qboolean MSG_WriteDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *t
int i, startBit;
int numChanges = 0;
dt = Delta_FindStruct( "movevars_t" );
dt = Delta_FindStructByIndex( DT_MOVEVARS_T );
Assert( dt && dt->bInitialized );
pField = dt->pFields;
@ -1549,7 +1558,7 @@ void MSG_ReadDeltaMovevars( sizebuf_t *msg, movevars_t *from, movevars_t *to )
delta_info_t *dt;
int i;
dt = Delta_FindStruct( "movevars_t" );
dt = Delta_FindStructByIndex( DT_MOVEVARS_T );
Assert( dt && dt->bInitialized );
pField = dt->pFields;
@ -1586,7 +1595,7 @@ void MSG_WriteClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to,
int i, startBit;
int numChanges = 0;
dt = Delta_FindStruct( "clientdata_t" );
dt = Delta_FindStructByIndex( DT_CLIENTDATA_T );
Assert( dt && dt->bInitialized );
pField = dt->pFields;
@ -1627,7 +1636,7 @@ void MSG_ReadClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, d
int i;
qboolean noChanges;
dt = Delta_FindStruct( "clientdata_t" );
dt = Delta_FindStructByIndex( DT_CLIENTDATA_T );
Assert( dt && dt->bInitialized );
pField = dt->pFields;
@ -1667,7 +1676,7 @@ void MSG_WriteWeaponData( sizebuf_t *msg, weapon_data_t *from, weapon_data_t *to
int i, startBit;
int numChanges = 0;
dt = Delta_FindStruct( "weapon_data_t" );
dt = Delta_FindStructByIndex( DT_WEAPONDATA_T );
Assert( dt && dt->bInitialized );
pField = dt->pFields;
@ -1705,7 +1714,7 @@ void MSG_ReadWeaponData( sizebuf_t *msg, weapon_data_t *from, weapon_data_t *to,
delta_info_t *dt;
int i;
dt = Delta_FindStruct( "weapon_data_t" );
dt = Delta_FindStructByIndex( DT_WEAPONDATA_T );
Assert( dt && dt->bInitialized );
pField = dt->pFields;
@ -1788,15 +1797,15 @@ void MSG_WriteDeltaEntity( entity_state_t *from, entity_state_t *to, sizebuf_t *
if( FBitSet( to->entityType, ENTITY_BEAM ))
{
dt = Delta_FindStruct( "custom_entity_state_t" );
dt = Delta_FindStructByIndex( DT_CUSTOM_ENTITY_STATE_T );
}
else if( delta_type == DELTA_PLAYER )
{
dt = Delta_FindStruct( "entity_state_player_t" );
dt = Delta_FindStructByIndex( DT_ENTITY_STATE_PLAYER_T );
}
else
{
dt = Delta_FindStruct( "entity_state_t" );
dt = Delta_FindStructByIndex( DT_ENTITY_STATE_T );
}
Assert( dt && dt->bInitialized );
@ -1906,15 +1915,15 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state
if( cls.legacymode ? ( to->entityType == ENTITY_BEAM ) : FBitSet( to->entityType, ENTITY_BEAM ))
{
dt = Delta_FindStruct( "custom_entity_state_t" );
dt = Delta_FindStructByIndex( DT_CUSTOM_ENTITY_STATE_T );
}
else if( delta_type == DELTA_PLAYER )
{
dt = Delta_FindStruct( "entity_state_player_t" );
dt = Delta_FindStructByIndex( DT_ENTITY_STATE_PLAYER_T );
}
else
{
dt = Delta_FindStruct( "entity_state_t" );
dt = Delta_FindStructByIndex( DT_ENTITY_STATE_T );
}
Assert( dt && dt->bInitialized );
@ -1932,6 +1941,27 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state
return true;
}
/*
==================
Delta_WriteDescriptionToClient
send delta communication encoding
==================
*/
void Delta_WriteDescriptionToClient( sizebuf_t *msg )
{
int tableIndex;
int fieldIndex;
for( tableIndex = 0; tableIndex < Delta_NumTables(); tableIndex++ )
{
delta_info_t *dt = Delta_FindStructByIndex( tableIndex );
for( fieldIndex = 0; fieldIndex < dt->numFields; fieldIndex++ )
Delta_WriteTableField( msg, tableIndex, &dt->pFields[fieldIndex] );
}
}
/*
=============================================================================

View File

@ -77,8 +77,6 @@ typedef struct
void Delta_Init( void );
void Delta_InitClient( void );
void Delta_Shutdown( void );
int Delta_NumTables( void );
delta_info_t *Delta_FindStructByIndex( int index );
void Delta_AddEncoder( char *name, pfnDeltaEncode encodeFunc );
int Delta_FindField( delta_t *pFields, const char *fieldname );
void Delta_SetField( delta_t *pFields, const char *fieldname );
@ -87,7 +85,7 @@ void Delta_SetFieldByIndex( delta_t *pFields, int fieldNumber );
void Delta_UnsetFieldByIndex( delta_t *pFields, int fieldNumber );
// send table over network
void Delta_WriteTableField( sizebuf_t *msg, int tableIndex, const delta_t *pField );
void Delta_WriteDescriptionToClient( sizebuf_t *msg );
void Delta_ParseTableField( sizebuf_t *msg );

View File

@ -108,23 +108,24 @@ typedef struct
} net_state_t;
static net_state_t net;
static convar_t *net_ipname;
static convar_t *net_hostport;
static convar_t *net_iphostport;
static convar_t *net_clientport;
static convar_t *net_ipclientport;
static convar_t *net_fakelag;
static convar_t *net_fakeloss;
static convar_t *net_address;
convar_t *net_clockwindow;
static CVAR_DEFINE_AUTO( net_address, "0", FCVAR_PRIVILEGED|FCVAR_READ_ONLY, "contain local address of current client" );
static CVAR_DEFINE( net_ipname, "ip", "localhost", FCVAR_PRIVILEGED, "network ip address" );
static CVAR_DEFINE( net_iphostport, "ip_hostport", "0", FCVAR_READ_ONLY, "network ip host port" );
static CVAR_DEFINE( net_hostport, "hostport", "0", FCVAR_READ_ONLY, "network default host port" );
static CVAR_DEFINE( net_ipclientport, "ip_clientport", "0", FCVAR_READ_ONLY, "network ip client port" );
static CVAR_DEFINE( net_clientport, "clientport", "0", FCVAR_READ_ONLY, "network default client port" );
static CVAR_DEFINE( net_fakelag, "fakelag", "0", FCVAR_PRIVILEGED, "lag all incoming network data (including loopback) by xxx ms." );
static CVAR_DEFINE( net_fakeloss, "fakeloss", "0", FCVAR_PRIVILEGED, "act like we dropped the packet this % of the time." );
CVAR_DEFINE( net_clockwindow, "clockwindow", "0.5", FCVAR_PRIVILEGED, "timewindow to execute client moves" );
netadr_t net_local;
netadr_t net6_local;
// cvars equivalents for IPv6
static convar_t *net_ip6name;
static convar_t *net_ip6hostport;
static convar_t *net_ip6clientport;
static convar_t *net6_address;
static CVAR_DEFINE( net_ip6name, "ip6", "localhost", FCVAR_PRIVILEGED, "network ip6 address" );
static CVAR_DEFINE( net_ip6hostport, "ip6_hostport", "0", FCVAR_READ_ONLY, "network ip6 host port" );
static CVAR_DEFINE( net_ip6clientport, "ip6_clientport", "0", FCVAR_READ_ONLY, "network ip6 client port" );
static CVAR_DEFINE_AUTO( net6_address, "0", FCVAR_PRIVILEGED|FCVAR_READ_ONLY, "contain local IPv6 address of current client" );
/*
====================
@ -722,7 +723,7 @@ const char *NET_AdrToString( const netadr_t a )
if( a.type == NA_LOOPBACK )
return "loopback";
if( a.type6 == NA_IP6 )
if( a.type6 == NA_IP6 || a.type6 == NA_MULTICAST_IP6 )
{
uint8_t ip6[16];
@ -749,7 +750,7 @@ const char *NET_BaseAdrToString( const netadr_t a )
if( a.type == NA_LOOPBACK )
return "loopback";
if( a.type6 == NA_IP6 )
if( a.type6 == NA_IP6 || a.type6 == NA_MULTICAST_IP6 )
{
uint8_t ip6[16];
@ -1065,7 +1066,7 @@ net_gai_state_t NET_StringToAdrNB( const char *string, netadr_t *adr )
if( !Q_stricmp( string, "localhost" ) || !Q_stricmp( string, "loopback" ))
{
adr->type = NA_LOOPBACK;
return true;
return NET_EAI_OK;
}
res = NET_StringToSockaddr( string, &s, true, AF_UNSPEC );
@ -1243,11 +1244,11 @@ static void NET_AdjustLag( void )
dt = bound( 0.0, dt, 0.1 );
lasttime = host.realtime;
if( host_developer.value || !net_fakelag->value )
if( host_developer.value || !net_fakelag.value )
{
if( net_fakelag->value != net.fakelag )
if( net_fakelag.value != net.fakelag )
{
diff = net_fakelag->value - net.fakelag;
diff = net_fakelag.value - net.fakelag;
converge = dt * 200.0f;
if( fabs( diff ) < converge )
converge = fabs( diff );
@ -1288,14 +1289,14 @@ static qboolean NET_LagPacket( qboolean newdata, netsrc_t sock, netadr_t *from,
if( newdata )
{
if( net_fakeloss->value != 0.0f )
if( net_fakeloss.value != 0.0f )
{
if( host_developer.value )
{
net.losscount[sock]++;
if( net_fakeloss->value <= 0.0f )
if( net_fakeloss.value <= 0.0f )
{
ninterval = fabs( net_fakeloss->value );
ninterval = fabs( net_fakeloss.value );
if( ninterval < 2 ) ninterval = 2;
if(( net.losscount[sock] % ninterval ) == 0 )
@ -1303,7 +1304,7 @@ static qboolean NET_LagPacket( qboolean newdata, netsrc_t sock, netadr_t *from,
}
else
{
if( COM_RandomLong( 0, 100 ) <= net_fakeloss->value )
if( COM_RandomLong( 0, 100 ) <= net_fakeloss.value )
return false;
}
}
@ -1392,7 +1393,7 @@ qboolean NET_GetLong( byte *pData, int size, size_t *outSize, int splitsize )
for( i = 0; i < NET_MAX_FRAGMENTS; i++ )
net.split_flags[i] = -1;
if( net_showpackets && net_showpackets->value == 4.0f )
if( net_showpackets.value == 4.0f )
Con_Printf( "<-- Split packet restart %i count %i seq\n", net.split.split_count, sequence_number );
}
@ -1406,7 +1407,7 @@ qboolean NET_GetLong( byte *pData, int size, size_t *outSize, int splitsize )
net.split.split_count--;
net.split_flags[packet_number] = sequence_number;
if( net_showpackets && net_showpackets->value == 4.0f )
if( net_showpackets.value == 4.0f )
Con_Printf( "<-- Split packet %i of %i, %i bytes %i seq\n", packet_number + 1, packet_count, size, sequence_number );
}
else
@ -1577,7 +1578,7 @@ int NET_SendLong( netsrc_t sock, int net_socket, const char *buf, size_t len, in
pPacket->packet_id = (packet_number << 8) + packet_count;
memcpy( packet + sizeof( SPLITPACKET ), buf + ( packet_number * body_size ), size );
if( net_showpackets && net_showpackets->value == 3.0f )
if( net_showpackets.value == 3.0f )
{
netadr_t adr;
@ -1813,14 +1814,14 @@ static void NET_OpenIP( qboolean change_port, int *sockets, const char *net_ifac
qboolean sv_nat = Cvar_VariableInteger("sv_nat");
qboolean cl_nat = Cvar_VariableInteger("cl_nat");
if( change_port && ( FBitSet( net_hostport->flags, FCVAR_CHANGED ) || sv_nat ))
if( change_port && ( FBitSet( net_hostport.flags, FCVAR_CHANGED ) || sv_nat ))
{
// reopen socket to set random port
if( NET_IsSocketValid( sockets[NS_SERVER] ))
closesocket( sockets[NS_SERVER] );
sockets[NS_SERVER] = INVALID_SOCKET;
ClearBits( net_hostport->flags, FCVAR_CHANGED );
ClearBits( net_hostport.flags, FCVAR_CHANGED );
}
if( !NET_IsSocketValid( sockets[NS_SERVER] ))
@ -1828,7 +1829,7 @@ static void NET_OpenIP( qboolean change_port, int *sockets, const char *net_ifac
port = hostport;
if( !port )
{
port = sv_nat ? PORT_ANY : net_hostport->value;
port = sv_nat ? PORT_ANY : net_hostport.value;
if( !port )
port = PORT_SERVER; // forcing to default
@ -1842,14 +1843,14 @@ static void NET_OpenIP( qboolean change_port, int *sockets, const char *net_ifac
// dedicated servers don't need client ports
if( Host_IsDedicated( )) return;
if( change_port && ( FBitSet( net_clientport->flags, FCVAR_CHANGED ) || cl_nat ))
if( change_port && ( FBitSet( net_clientport.flags, FCVAR_CHANGED ) || cl_nat ))
{
// reopen socket to set random port
if( NET_IsSocketValid( sockets[NS_CLIENT] ))
closesocket( sockets[NS_CLIENT] );
sockets[NS_CLIENT] = INVALID_SOCKET;
ClearBits( net_clientport->flags, FCVAR_CHANGED );
ClearBits( net_clientport.flags, FCVAR_CHANGED );
}
if( !NET_IsSocketValid( sockets[NS_CLIENT] ))
@ -1857,7 +1858,7 @@ static void NET_OpenIP( qboolean change_port, int *sockets, const char *net_ifac
port = clientport;
if( !port )
{
port = cl_nat ? PORT_ANY : net_clientport->value;
port = cl_nat ? PORT_ANY : net_clientport.value;
if( !port )
port = PORT_ANY; // forcing to default
@ -1865,7 +1866,7 @@ static void NET_OpenIP( qboolean change_port, int *sockets, const char *net_ifac
sockets[NS_CLIENT] = NET_IPSocket( net_iface, port, family );
if( !NET_IsSocketValid( sockets[NS_CLIENT] ))
sockets[NS_CLIENT] = NET_IPSocket( net_ipname->string, PORT_ANY, family );
sockets[NS_CLIENT] = NET_IPSocket( net_ipname.string, PORT_ANY, family );
}
return;
@ -1901,8 +1902,8 @@ void NET_GetLocalAddress( void )
if( net.allow_ip )
{
// If we have changed the ip var from the command line, use that instead.
if( Q_stricmp( net_ipname->string, "localhost" ))
Q_strncpy( buff, net_ipname->string, sizeof( buff ));
if( Q_stricmp( net_ipname.string, "localhost" ))
Q_strncpy( buff, net_ipname.string, sizeof( buff ));
else Q_strncpy( buff, hostname, sizeof( buff ));
if( NET_StringToAdrEx( buff, &net_local, AF_INET ))
@ -1914,7 +1915,7 @@ void NET_GetLocalAddress( void )
net_local.port = ((struct sockaddr_in *)&address)->sin_port;
net_addr_string = NET_AdrToString( net_local );
Con_Printf( "Server IPv4 address %s\n", net_addr_string );
Cvar_FullSet( "net_address", net_addr_string, net_address->flags );
Cvar_FullSet( "net_address", net_addr_string, net_address.flags );
}
else Con_DPrintf( S_ERROR "Could not get TCP/IPv4 address. Reason: %s\n", NET_ErrorString( ));
}
@ -1924,8 +1925,8 @@ void NET_GetLocalAddress( void )
if( net.allow_ip6 )
{
// If we have changed the ip var from the command line, use that instead.
if( Q_stricmp( net_ip6name->string, "localhost" ))
Q_strncpy( buff, net_ip6name->string, sizeof( buff ));
if( Q_stricmp( net_ip6name.string, "localhost" ))
Q_strncpy( buff, net_ip6name.string, sizeof( buff ));
else Q_strncpy( buff, hostname, sizeof( buff ));
if( NET_StringToAdrEx( buff, &net6_local, AF_INET6 ))
@ -1937,7 +1938,7 @@ void NET_GetLocalAddress( void )
net6_local.port = ((struct sockaddr_in6 *)&address)->sin6_port;
net_addr_string = NET_AdrToString( net6_local );
Con_Printf( "Server IPv6 address %s\n", net_addr_string );
Cvar_FullSet( "net6_address", net_addr_string, net6_address->flags );
Cvar_FullSet( "net6_address", net_addr_string, net6_address.flags );
}
else Con_DPrintf( S_ERROR "Could not get TCP/IPv6 address. Reason: %s\n", NET_ErrorString( ));
}
@ -1969,10 +1970,10 @@ void NET_Config( qboolean multiplayer, qboolean changeport )
{
// open sockets
if( net.allow_ip )
NET_OpenIP( changeport, net.ip_sockets, net_ipname->string, net_iphostport->value, net_ipclientport->value, AF_INET );
NET_OpenIP( changeport, net.ip_sockets, net_ipname.string, net_iphostport.value, net_ipclientport.value, AF_INET );
if( net.allow_ip6 )
NET_OpenIP( changeport, net.ip6_sockets, net_ip6name->string, net_ip6hostport->value, net_ip6clientport->value, AF_INET6 );
NET_OpenIP( changeport, net.ip6_sockets, net_ip6name.string, net_ip6hostport.value, net_ip6clientport.value, AF_INET6 );
// validate sockets for dedicated
if( Host_IsDedicated( ))
@ -2100,21 +2101,23 @@ void NET_Init( void )
if( net.initialized ) return;
net_clockwindow = Cvar_Get( "clockwindow", "0.5", FCVAR_PRIVILEGED, "timewindow to execute client moves" );
net_address = Cvar_Get( "net_address", "0", FCVAR_PRIVILEGED|FCVAR_READ_ONLY, "contain local address of current client" );
net_ipname = Cvar_Get( "ip", "localhost", FCVAR_PRIVILEGED, "network ip address" );
net_iphostport = Cvar_Get( "ip_hostport", "0", FCVAR_READ_ONLY, "network ip host port" );
net_hostport = Cvar_Getf( "hostport", FCVAR_READ_ONLY, "network default host port", "%i", PORT_SERVER );
net_ipclientport = Cvar_Get( "ip_clientport", "0", FCVAR_READ_ONLY, "network ip client port" );
net_clientport = Cvar_Getf( "clientport", FCVAR_READ_ONLY, "network default client port", "%i", PORT_CLIENT );
net_fakelag = Cvar_Get( "fakelag", "0", FCVAR_PRIVILEGED, "lag all incoming network data (including loopback) by xxx ms." );
net_fakeloss = Cvar_Get( "fakeloss", "0", FCVAR_PRIVILEGED, "act like we dropped the packet this % of the time." );
Cvar_RegisterVariable( &net_address );
Cvar_RegisterVariable( &net_ipname );
Cvar_RegisterVariable( &net_iphostport );
Cvar_RegisterVariable( &net_hostport );
Cvar_RegisterVariable( &net_ipclientport );
Cvar_RegisterVariable( &net_clientport );
Cvar_RegisterVariable( &net_fakelag );
Cvar_RegisterVariable( &net_fakeloss );
Q_snprintf( cmd, sizeof( cmd ), "%i", PORT_SERVER );
Cvar_FullSet( "hostport", cmd, FCVAR_READ_ONLY );
// cvar equivalents for IPv6
net_ip6name = Cvar_Get( "ip6", "localhost", FCVAR_PRIVILEGED, "network ip6 address" );
net_ip6hostport = Cvar_Get( "ip6_hostport", "0", FCVAR_READ_ONLY, "network ip6 host port" );
net_ip6clientport = Cvar_Get( "ip6_clientport", "0", FCVAR_READ_ONLY, "network ip6 client port" );
net6_address = Cvar_Get( "net6_address", "0", FCVAR_PRIVILEGED|FCVAR_READ_ONLY, "contain local IPv6 address of current client" );
Cvar_RegisterVariable( &net_ip6name );
Cvar_RegisterVariable( &net_ip6hostport );
Cvar_RegisterVariable( &net_ip6clientport );
Cvar_RegisterVariable( &net6_address );
// prepare some network data
for( i = 0; i < NS_COUNT; i++ )
@ -2150,11 +2153,11 @@ void NET_Init( void )
// specify custom ip
if( Sys_GetParmFromCmdLine( "-ip", cmd ))
Cvar_FullSet( "ip", cmd, net_ipname->flags );
Cvar_FullSet( "ip", cmd, net_ipname.flags );
// specify custom ip6
if( Sys_GetParmFromCmdLine( "-ip6", cmd ))
Cvar_FullSet( "ip6", cmd, net_ip6name->flags );
Cvar_FullSet( "ip6", cmd, net_ip6name.flags );
// adjust clockwindow
if( Sys_GetParmFromCmdLine( "-clockwindow", cmd ))
@ -2246,10 +2249,10 @@ static struct http_static_s
} http;
static convar_t *http_useragent;
static convar_t *http_autoremove;
static convar_t *http_timeout;
static convar_t *http_maxconnections;
static CVAR_DEFINE_AUTO( http_useragent, "", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "User-Agent string" );
static CVAR_DEFINE_AUTO( http_autoremove, "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "remove broken files" );
static CVAR_DEFINE_AUTO( http_timeout, "45", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "timeout for http downloader" );
static CVAR_DEFINE_AUTO( http_maxconnections, "4", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "maximum http connection number" );
/*
========================
@ -2304,7 +2307,7 @@ static void HTTP_FreeFile( httpfile_t *file, qboolean error )
}
// Called because there was no servers to download, free file now
if( http_autoremove->value == 1 ) // remove broken file
if( http_autoremove.value == 1 ) // remove broken file
FS_Delete( incname );
else // autoremove disabled, keep file
Con_Printf( "cannot download %s from any server. "
@ -2525,7 +2528,7 @@ void HTTP_Run( void )
{
char name[MAX_SYSPATH];
if( iActiveCount > http_maxconnections->value )
if( iActiveCount > http_maxconnections.value )
continue;
if( !curfile->server )
@ -2624,14 +2627,14 @@ void HTTP_Run( void )
{
string useragent;
if( !COM_CheckStringEmpty( http_useragent->string ) || !Q_strcmp( http_useragent->string, "xash3d" ))
if( !COM_CheckStringEmpty( http_useragent.string ) || !Q_strcmp( http_useragent.string, "xash3d" ))
{
Q_snprintf( useragent, sizeof( useragent ), "%s/%s (%s-%s; build %d; %s)",
XASH_ENGINE_NAME, XASH_VERSION, Q_buildos( ), Q_buildarch( ), Q_buildnum( ), Q_buildcommit( ));
}
else
{
Q_strncpy( useragent, http_useragent->string, sizeof( useragent ));
Q_strncpy( useragent, http_useragent.string, sizeof( useragent ));
}
curfile->query_length = Q_snprintf( curfile->buf, sizeof( curfile->buf ),
@ -2666,7 +2669,7 @@ void HTTP_Run( void )
curfile->blocktime += host.frametime;
wait = true;
if( curfile->blocktime > http_timeout->value )
if( curfile->blocktime > http_timeout.value )
{
Con_Printf( S_ERROR "timeout on request send:\n%s\n", curfile->buf );
HTTP_FreeFile( curfile, true );
@ -2708,7 +2711,7 @@ void HTTP_Run( void )
else
curfile->blocktime += host.frametime;
if( curfile->blocktime > http_timeout->value )
if( curfile->blocktime > http_timeout.value )
{
Con_Printf( S_ERROR "timeout on receiving data!\n");
HTTP_FreeFile( curfile, true );
@ -2986,10 +2989,11 @@ void HTTP_Init( void )
Cmd_AddRestrictedCommand( "http_clear", HTTP_Clear_f, "cancel all downloads" );
Cmd_AddRestrictedCommand( "http_list", HTTP_List_f, "list all queued downloads" );
Cmd_AddCommand( "http_addcustomserver", HTTP_AddCustomServer_f, "add custom fastdl server");
http_useragent = Cvar_Get( "http_useragent", "", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "User-Agent string" );
http_autoremove = Cvar_Get( "http_autoremove", "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "remove broken files" );
http_timeout = Cvar_Get( "http_timeout", "45", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "timeout for http downloader" );
http_maxconnections = Cvar_Get( "http_maxconnections", "4", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "maximum http connection number" );
Cvar_RegisterVariable( &http_useragent );
Cvar_RegisterVariable( &http_autoremove );
Cvar_RegisterVariable( &http_timeout );
Cvar_RegisterVariable( &http_maxconnections );
// Read servers from fastdl.txt
line = serverfile = (char *)FS_LoadFile( "fastdl.txt", 0, false );

View File

@ -50,8 +50,8 @@ typedef enum
#include "netadr.h"
extern convar_t *net_showpackets;
extern convar_t *net_clockwindow;
extern convar_t net_showpackets;
extern convar_t net_clockwindow;
void NET_Init( void );
void NET_Shutdown( void );

View File

@ -73,7 +73,6 @@ GNU General Public License for more details.
#define MS_SCAN_REQUEST "1\xFF" "0.0.0.0:0\0"
#define PORT_MASTER 27010
#define PORT_CLIENT 27005
#define PORT_SERVER 27015
#define MULTIPLAYER_BACKUP 64 // how many data slots to use when in multiplayer (must be power of 2)

View File

@ -138,7 +138,7 @@ PM_HullPointContents
==================
*/
int PM_HullPointContents( hull_t *hull, int num, const vec3_t p )
int GAME_EXPORT PM_HullPointContents( hull_t *hull, int num, const vec3_t p )
{
mplane_t *plane;

File diff suppressed because it is too large Load Diff

View File

@ -85,7 +85,7 @@ static qboolean Sound_ParseID3Frame( const did3v2_frame_t *frame, const byte *bu
string key, value;
int32_t key_len, value_len;
if( buffer[0] == 0x00 || buffer[1] == 0x03 )
if( buffer[0] == 0x00 || buffer[0] == 0x03 )
{
key_len = Q_strncpy( key, &buffer[1], sizeof( key ));
value_len = frame_length - (1 + key_len + 1);
@ -129,7 +129,7 @@ static qboolean Sound_ParseID3Tag( const byte *buffer, fs_offset_t filesize )
{
// old id3v1 header found
if( CHECK_IDENT( header->ident, 'T', 'A', 'G' ))
Con_Printf( S_ERROR "Sound_ParseID3Tag: ID3v1 is not supported! Convert to ID3v2.4!\n", header->major_ver );
Con_Printf( S_ERROR "Sound_ParseID3Tag: ID3v1 is not supported! Convert to ID3v2.4!\n" );
return true; // missing tag header is not an error
}

View File

@ -95,12 +95,16 @@ byte *Sound_Copy( size_t size )
uint GAME_EXPORT Sound_GetApproxWavePlayLen( const char *filepath )
{
string name;
file_t *f;
wavehdr_t wav;
size_t filesize;
uint msecs;
f = FS_Open( filepath, "rb", false );
Q_strncpy( name, filepath, sizeof( name ));
COM_FixSlashes( name );
f = FS_Open( name, "rb", false );
if( !f )
return 0;

View File

@ -1,6 +1,7 @@
/*
snd_wav.c - wav format load & save
Copyright (C) 2010 Uncle Mike
Copyright (C) 2023 FTEQW developers
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -13,6 +14,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
#include <stddef.h>
#include "soundlib.h"
static const byte *iff_data;
@ -60,32 +62,41 @@ static int GetLittleLong( void )
FindNextChunk
=================
*/
static void FindNextChunk( const char *name )
static void FindNextChunk( const char *filename, const char *name )
{
while( 1 )
{
iff_dataPtr = iff_lastChunk;
ptrdiff_t remaining = iff_end - iff_lastChunk;
if( iff_dataPtr >= iff_end )
if( remaining < 8 )
{
// didn't find the chunk
iff_dataPtr = NULL;
return;
}
iff_dataPtr += 4;
iff_chunkLen = GetLittleLong();
iff_dataPtr = iff_lastChunk + 4;
remaining -= 8;
iff_chunkLen = GetLittleLong();
if( iff_chunkLen < 0 )
{
iff_dataPtr = NULL;
return;
}
iff_dataPtr -= 8;
iff_lastChunk = iff_dataPtr + 8 + ((iff_chunkLen + 1) & ~1);
if( iff_chunkLen > remaining )
{
Con_DPrintf( "%s: '%s' truncated by %i bytes\n", __func__, filename, iff_chunkLen - remaining );
iff_chunkLen = remaining;
}
if( !Q_strncmp( (const char *)iff_dataPtr, name, 4 ))
remaining -= iff_chunkLen;
iff_dataPtr -= 8;
iff_lastChunk = iff_dataPtr + 8 + iff_chunkLen;
if ((iff_chunkLen&1) && remaining)
iff_lastChunk++;
if (!Q_strncmp(iff_dataPtr, name, 4))
return;
}
}
@ -95,10 +106,10 @@ static void FindNextChunk( const char *name )
FindChunk
=================
*/
static void FindChunk( const char *name )
static void FindChunk( const char *filename, const char *name )
{
iff_lastChunk = iff_data;
FindNextChunk( name );
FindNextChunk( filename, name );
}
/*
@ -151,7 +162,7 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
iff_end = buffer + filesize;
// find "RIFF" chunk
FindChunk( "RIFF" );
FindChunk( name, "RIFF" );
if( !( iff_dataPtr && !Q_strncmp( (const char *)iff_dataPtr + 8, "WAVE", 4 )))
{
@ -161,7 +172,7 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
// get "fmt " chunk
iff_data = iff_dataPtr + 12;
FindChunk( "fmt " );
FindChunk( name, "fmt " );
if( !iff_dataPtr )
{
@ -206,13 +217,13 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
}
// get cue chunk
FindChunk( "cue " );
FindChunk( name, "cue " );
if( iff_dataPtr )
{
iff_dataPtr += 32;
sound.loopstart = GetLittleLong();
FindNextChunk( "LIST" ); // if the next chunk is a LIST chunk, look for a cue length marker
FindNextChunk( name, "LIST" ); // if the next chunk is a LIST chunk, look for a cue length marker
if( iff_dataPtr )
{
@ -231,7 +242,7 @@ qboolean Sound_LoadWAV( const char *name, const byte *buffer, fs_offset_t filesi
}
// find data chunk
FindChunk( "data" );
FindChunk( name, "data" );
if( !iff_dataPtr )
{

View File

@ -30,8 +30,8 @@ GNU General Public License for more details.
#if !XASH_WIN32 && !XASH_MOBILE_PLATFORM && !XASH_LOW_MEMORY
#define XASH_COLORIZE_CONSOLE true
// use with caution, running engine in Qt Creator may cause a freeze in read() call
// I was never encountered this bug anywhere else, so still enable by default
// #define XASH_USE_SELECT 1
// I have never encountered this bug anywhere else, so still enable by default
#define XASH_USE_SELECT 1
#else
#define XASH_COLORIZE_CONSOLE false
#endif
@ -54,6 +54,7 @@ static LogData s_ld;
char *Sys_Input( void )
{
#if XASH_USE_SELECT
if( Host_IsDedicated( ))
{
fd_set rfds;
static char line[1024];

View File

@ -30,9 +30,9 @@ extern "C" {
#include "crtlib.h"
#include "platform/platform.h"
#define MSGBOX( x ) Platform_MessageBox( "Xash Error", (x), false );
#define MSGBOX2( x ) Platform_MessageBox( "Host Error", (x), true );
#define MSGBOX3( x ) Platform_MessageBox( "Host Recursive Error", (x), true );
#define MSGBOX( x ) Platform_MessageBox( "Xash Error", (x), false )
#define MSGBOX2( x ) Platform_MessageBox( "Host Error", (x), true )
#define MSGBOX3( x ) Platform_MessageBox( "Host Recursive Error", (x), true )
#define ASSERT( exp ) if(!( exp )) Sys_Error( "assert failed at %s:%i\n", __FILE__, __LINE__ )
/*

View File

@ -795,9 +795,9 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
return length;
}
#elif defined(__sgi) || defined(__SWITCH__) || defined(__vita__)
#elif defined(__sgi)
/*
/*
* These functions are stubbed for now to get the code compiling.
* In the future it may be possible to get these working in some way.
* Current ideas are checking the working directory for a binary with
@ -813,13 +813,29 @@ int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
WAI_FUNCSPEC
int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
{
return -1;
return -1;
}
WAI_FUNCSPEC
int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
{
return -1;
return -1;
}
#elif defined(__SWITCH__) || defined(__vita__)
/* Not possible on this platform */
WAI_FUNCSPEC
int WAI_PREFIX(getExecutablePath)(char* out, int capacity, int* dirname_length)
{
return -1;
}
WAI_FUNCSPEC
int WAI_PREFIX(getModulePath)(char* out, int capacity, int* dirname_length)
{
return -1;
}
#else

File diff suppressed because it is too large Load Diff

View File

@ -1,46 +0,0 @@
#pragma once
#ifndef ANDROID_PRIV_H
#define ANDROID_PRIV_H
#include <EGL/egl.h>
#include <android/log.h>
#include <jni.h>
extern struct jnimethods_s
{
jclass actcls;
JavaVM *vm;
JNIEnv *env;
jmethodID enableTextInput;
jmethodID vibrate;
jmethodID messageBox;
jmethodID notify;
jmethodID setTitle;
jmethodID setIcon;
jmethodID getAndroidId;
jmethodID saveID;
jmethodID loadID;
jmethodID showMouse;
jmethodID shellExecute;
jmethodID swapBuffers;
jmethodID toggleEGL;
jmethodID createGLContext;
jmethodID getGLAttribute;
jmethodID deleteGLContext;
jmethodID getSelectedPixelFormat;
jmethodID getSurface;
int width, height;
} jni;
extern struct jnimouse_s
{
float x, y;
} jnimouse;
//
// vid_android.c
//
void Android_UpdateSurface( qboolean active );
#endif // ANDROID_PRIV_H

View File

@ -43,7 +43,7 @@ void *ANDROID_LoadLibrary( const char *dllname )
}
// HACKHACK: keep old behaviour for compability
if( Q_strstr( dllname, "." OS_LIB_EXT ) || Q_strstr( dllname, PATH_SPLITTER ))
if( Q_strstr( dllname, "." OS_LIB_EXT ) || Q_strstr( dllname, "/" ))
{
pHandle = dlopen( dllname, RTLD_LAZY );
if( pHandle )

View File

@ -140,10 +140,10 @@ struct soinfo {
#endif
#if defined(USE_RELA)
Elf_Rela* plt_rela;
Elf_RelA* plt_rela;
size_t plt_rela_count;
Elf_Rela* rela;
Elf_RelA* rela;
size_t rela_count;
#else
Elf_Rel* plt_rel;

View File

@ -1,277 +0,0 @@
/*
Copyright (C) 2015 SiPlus, Chasseur de bots
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "common.h"
#include "platform/platform.h"
#if XASH_SOUND == SOUND_OPENSLES
#include <SLES/OpenSLES.h>
#include "pthread.h"
#include "sound.h"
extern dma_t dma;
static SLObjectItf snddma_android_engine = NULL;
static SLObjectItf snddma_android_outputMix = NULL;
static SLObjectItf snddma_android_player = NULL;
static SLBufferQueueItf snddma_android_bufferQueue;
static SLPlayItf snddma_android_play;
static pthread_mutex_t snddma_android_mutex = PTHREAD_MUTEX_INITIALIZER;
static int snddma_android_size;
static const SLInterfaceID *pSL_IID_ENGINE;
static const SLInterfaceID *pSL_IID_BUFFERQUEUE;
static const SLInterfaceID *pSL_IID_PLAY;
static SLresult SLAPIENTRY (*pslCreateEngine)(
SLObjectItf *pEngine,
SLuint32 numOptions,
const SLEngineOption *pEngineOptions,
SLuint32 numInterfaces,
const SLInterfaceID *pInterfaceIds,
const SLboolean * pInterfaceRequired
);
void SNDDMA_Activate( qboolean active )
{
if( !dma.initialized )
return;
if( active )
{
memset( dma.buffer, 0, snddma_android_size * 2 );
(*snddma_android_bufferQueue)->Enqueue( snddma_android_bufferQueue, dma.buffer, snddma_android_size );
(*snddma_android_play)->SetPlayState( snddma_android_play, SL_PLAYSTATE_PLAYING );
}
else
{
(*snddma_android_play)->SetPlayState( snddma_android_play, SL_PLAYSTATE_STOPPED );
(*snddma_android_bufferQueue)->Clear( snddma_android_bufferQueue );
}
}
static void SNDDMA_Android_Callback( SLBufferQueueItf bq, void *context )
{
uint8_t *buffer2;
pthread_mutex_lock( &snddma_android_mutex );
buffer2 = ( uint8_t * )dma.buffer + snddma_android_size;
(*bq)->Enqueue( bq, buffer2, snddma_android_size );
memcpy( buffer2, dma.buffer, snddma_android_size );
memset( dma.buffer, 0, snddma_android_size );
dma.samplepos += dma.samples;
pthread_mutex_unlock( &snddma_android_mutex );
}
static const char *SNDDMA_Android_Init( void )
{
SLresult result;
SLEngineItf engine;
int freq;
SLDataLocator_BufferQueue sourceLocator;
SLDataFormat_PCM sourceFormat;
SLDataSource source;
SLDataLocator_OutputMix sinkLocator;
SLDataSink sink;
SLInterfaceID interfaceID;
SLboolean interfaceRequired;
int samples;
void *handle = dlopen( "libOpenSLES.so", RTLD_LAZY );
if( !handle )
return "dlopen for libOpenSLES.so";
pslCreateEngine = dlsym( handle, "slCreateEngine" );
if( !pslCreateEngine )
return "resolve slCreateEngine";
pSL_IID_ENGINE = dlsym( handle, "SL_IID_ENGINE" );
if( !pSL_IID_ENGINE )
return "resolve SL_IID_ENGINE";
pSL_IID_PLAY = dlsym( handle, "SL_IID_PLAY" );
if( !pSL_IID_PLAY )
return "resolve SL_IID_PLAY";
pSL_IID_BUFFERQUEUE = dlsym( handle, "SL_IID_BUFFERQUEUE" );
if( !pSL_IID_BUFFERQUEUE )
return "resolve SL_IID_BUFFERQUEUE";
result = pslCreateEngine( &snddma_android_engine, 0, NULL, 0, NULL, NULL );
if( result != SL_RESULT_SUCCESS ) return "slCreateEngine";
result = (*snddma_android_engine)->Realize( snddma_android_engine, SL_BOOLEAN_FALSE );
if( result != SL_RESULT_SUCCESS ) return "engine->Realize";
result = (*snddma_android_engine)->GetInterface( snddma_android_engine, *pSL_IID_ENGINE, &engine );
if( result != SL_RESULT_SUCCESS ) return "engine->GetInterface(ENGINE)";
result = (*engine)->CreateOutputMix( engine, &snddma_android_outputMix, 0, NULL, NULL );
if( result != SL_RESULT_SUCCESS ) return "engine->CreateOutputMix";
result = (*snddma_android_outputMix)->Realize( snddma_android_outputMix, SL_BOOLEAN_FALSE );
if( result != SL_RESULT_SUCCESS ) return "outputMix->Realize";
freq = SOUND_DMA_SPEED;
sourceLocator.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
sourceLocator.numBuffers = 2;
sourceFormat.formatType = SL_DATAFORMAT_PCM;
sourceFormat.numChannels = 2; // always stereo, because engine supports only stereo
sourceFormat.samplesPerSec = freq * 1000;
sourceFormat.bitsPerSample = 16; // always 16 bit audio
sourceFormat.containerSize = sourceFormat.bitsPerSample;
sourceFormat.channelMask = SL_SPEAKER_FRONT_LEFT|SL_SPEAKER_FRONT_RIGHT;
sourceFormat.endianness = SL_BYTEORDER_LITTLEENDIAN;
source.pLocator = &sourceLocator;
source.pFormat = &sourceFormat;
sinkLocator.locatorType = SL_DATALOCATOR_OUTPUTMIX;
sinkLocator.outputMix = snddma_android_outputMix;
sink.pLocator = &sinkLocator;
sink.pFormat = NULL;
interfaceID = *pSL_IID_BUFFERQUEUE;
interfaceRequired = SL_BOOLEAN_TRUE;
result = (*engine)->CreateAudioPlayer( engine, &snddma_android_player, &source, &sink, 1, &interfaceID, &interfaceRequired );
if( result != SL_RESULT_SUCCESS ) return "engine->CreateAudioPlayer";
result = (*snddma_android_player)->Realize( snddma_android_player, SL_BOOLEAN_FALSE );
if( result != SL_RESULT_SUCCESS ) return "player->Realize";
result = (*snddma_android_player)->GetInterface( snddma_android_player, *pSL_IID_BUFFERQUEUE, &snddma_android_bufferQueue );
if( result != SL_RESULT_SUCCESS ) return "player->GetInterface(BUFFERQUEUE)";
result = (*snddma_android_player)->GetInterface( snddma_android_player, *pSL_IID_PLAY, &snddma_android_play );
if( result != SL_RESULT_SUCCESS ) return "player->GetInterface(PLAY)";
result = (*snddma_android_bufferQueue)->RegisterCallback( snddma_android_bufferQueue, SNDDMA_Android_Callback, NULL );
if( result != SL_RESULT_SUCCESS ) return "bufferQueue->RegisterCallback";
samples = s_samplecount.value;
if( !samples )
samples = 4096;
dma.format.channels = sourceFormat.numChannels;
dma.samples = samples * sourceFormat.numChannels;
dma.format.speed = freq;
snddma_android_size = dma.samples * ( sourceFormat.bitsPerSample >> 3 );
dma.buffer = Z_Malloc( snddma_android_size * 2 );
dma.samplepos = 0;
// dma.sampleframes = dma.samples / dma.format.channels;
dma.format.width = 2;
if( !dma.buffer ) return "malloc";
//snddma_android_mutex = trap_Mutex_Create();
dma.initialized = true;
SNDDMA_Activate( true );
return NULL;
}
qboolean SNDDMA_Init( void )
{
const char *initError;
Msg( "OpenSL ES audio device initializing...\n" );
initError = SNDDMA_Android_Init();
if( initError )
{
Msg( S_ERROR "SNDDMA_Init: %s failed.\n", initError );
SNDDMA_Shutdown();
return false;
}
Msg( "OpenSL ES audio initialized.\n" );
dma.backendName = "OpenSL ES";
return true;
}
void SNDDMA_Shutdown( void )
{
Msg( "Closing OpenSL ES audio device...\n" );
if( snddma_android_player )
{
(*snddma_android_player)->Destroy( snddma_android_player );
snddma_android_player = NULL;
}
if( snddma_android_outputMix )
{
(*snddma_android_outputMix)->Destroy( snddma_android_outputMix );
snddma_android_outputMix = NULL;
}
if( snddma_android_engine )
{
(*snddma_android_engine)->Destroy( snddma_android_engine );
snddma_android_engine = NULL;
}
if( dma.buffer )
{
Z_Free( dma.buffer );
dma.buffer = NULL;
}
//if( snddma_android_mutex )
//trap_Mutex_Destroy( &snddma_android_mutex );
Msg( "OpenSL ES audio device shut down.\n" );
}
void SNDDMA_Submit( void )
{
pthread_mutex_unlock( &snddma_android_mutex );
}
void SNDDMA_BeginPainting( void )
{
pthread_mutex_lock( &snddma_android_mutex );
}
qboolean VoiceCapture_Init( void )
{
return false;
}
qboolean VoiceCapture_Activate( qboolean activate )
{
return false;
}
qboolean VoiceCapture_Lock( qboolean lock )
{
return false;
}
void VoiceCapture_Shutdown( void )
{
}
#endif

View File

@ -1,664 +0,0 @@
#include "platform/platform.h"
#include "input.h"
#include "client.h"
#include "filesystem.h"
#include "platform/android/android_priv.h"
#include "vid_common.h"
#include <android/native_window.h>
#include <android/native_window_jni.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
static struct vid_android_s
{
int gl_attribs[REF_GL_ATTRIBUTES_COUNT];
qboolean gl_attribs_set[REF_GL_ATTRIBUTES_COUNT];
EGLint gl_api;
qboolean gles1;
void *libgles1, *libgles2;
qboolean has_context;
ANativeWindow* window;
} vid_android;
static struct nw_s
{
void (*release)(ANativeWindow* window);
int32_t (*getWidth)(ANativeWindow* window);
int32_t (*getHeight)(ANativeWindow* window);
int32_t (*getFormat)(ANativeWindow* window);
int32_t (*setBuffersGeometry)(ANativeWindow* window, int32_t width, int32_t height, int32_t format);
int32_t (*lock)(ANativeWindow* window, ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);
int32_t (*unlockAndPost)(ANativeWindow* window);
ANativeWindow* (*fromSurface)(JNIEnv* env, jobject surface);
} nw;
#define NW_FF(x) {"ANativeWindow_"#x, (void*)&nw.x}
static dllfunc_t android_funcs[] =
{
NW_FF(release),
NW_FF(getWidth),
NW_FF(getHeight),
NW_FF(getFormat),
NW_FF(setBuffersGeometry),
NW_FF(lock),
NW_FF(unlockAndPost),
NW_FF(fromSurface),
{ NULL, NULL }
};
#undef NW_FF
dll_info_t android_info = { "libandroid.so", android_funcs, false };
static struct egl_s
{
EGLSurface (*GetCurrentSurface)(EGLint readdraw);
EGLDisplay (*GetCurrentDisplay)(void);
EGLint (*GetError)(void);
EGLBoolean (*SwapBuffers)(EGLDisplay dpy, EGLSurface surface);
EGLBoolean (*SwapInterval)(EGLDisplay dpy, EGLint interval);
void *(*GetProcAddress)(const char *procname);
} egl;
#undef GetProcAddress
#define EGL_FF(x) {"egl"#x, (void*)&egl.x}
static dllfunc_t egl_funcs[] =
{
EGL_FF(SwapInterval),
EGL_FF(SwapBuffers),
EGL_FF(GetError),
EGL_FF(GetCurrentDisplay),
EGL_FF(GetCurrentSurface),
EGL_FF(GetProcAddress),
{ NULL, NULL }
};
#undef EGL_FF
dll_info_t egl_info = { "libEGL.so", egl_funcs, false };
static struct nativeegl_s
{
qboolean valid;
void *window;
EGLDisplay dpy;
EGLSurface surface;
EGLContext context;
EGLConfig cfg;
EGLint numCfg;
const char *extensions;
} negl;
/*
========================
Android_SwapInterval
========================
*/
static void Android_SwapInterval( int interval )
{
if( negl.valid )
egl.SwapInterval( negl.dpy, interval );
}
/*
========================
Android_SetTitle
========================
*/
static void Android_SetTitle( const char *title )
{
(*jni.env)->CallStaticVoidMethod( jni.env, jni.actcls, jni.setTitle, (*jni.env)->NewStringUTF( jni.env, title ) );
}
/*
========================
Android_SetIcon
========================
*/
static void Android_SetIcon( const char *path )
{
(*jni.env)->CallStaticVoidMethod( jni.env, jni.actcls, jni.setIcon, (*jni.env)->NewStringUTF( jni.env, path ) );
}
/*
========================
Android_GetScreenRes
Resolution got from last resize event
========================
*/
static void Android_GetScreenRes( int *width, int *height )
{
*width=jni.width, *height=jni.height;
}
/*
========================
Android_SwapBuffers
Update screen. Use native EGL if possible
========================
*/
void GL_SwapBuffers( void )
{
if( negl.valid )
{
egl.SwapBuffers( negl.dpy, negl.surface );
}
else
{
(*jni.env)->CallStaticVoidMethod( jni.env, jni.actcls, jni.swapBuffers );
}
}
/*
========================
Android_UpdateSurface
Check if we may use native EGL without jni calls
========================
*/
void Android_UpdateSurface( qboolean active )
{
negl.valid = false;
if( nw.release )
{
if( vid_android.window && !active )
{
nw.release( vid_android.window );
vid_android.window = NULL;
}
if( active )
{
jobject surf;
if( vid_android.window )
nw.release( vid_android.window );
surf = (*jni.env)->CallStaticObjectMethod(jni.env, jni.actcls, jni.getSurface);
Con_Printf("s %p\n", surf);
vid_android.window = nw.fromSurface(jni.env, surf);
Con_Printf("w %p\n", vid_android.window);
nw.setBuffersGeometry(vid_android.window, 0, 0, WINDOW_FORMAT_RGB_565 );
(*jni.env)->DeleteLocalRef( jni.env, surf );
}
return;
}
if( !vid_android.has_context )
return;
if( ( active && host.status == HOST_FRAME ) || !active )
(*jni.env)->CallStaticVoidMethod( jni.env, jni.actcls, jni.toggleEGL, 0 );
if( active )
(*jni.env)->CallStaticVoidMethod( jni.env, jni.actcls, jni.toggleEGL, 1 );
if( !Sys_CheckParm("-nativeegl") || !active )
return; // enabled by user
if( !egl.GetCurrentDisplay )
return;
negl.dpy = egl.GetCurrentDisplay();
if( negl.dpy == EGL_NO_DISPLAY )
return;
negl.surface = egl.GetCurrentSurface(EGL_DRAW);
if( negl.surface == EGL_NO_SURFACE )
return;
// now check if swapBuffers does not give error
if( egl.SwapBuffers( negl.dpy, negl.surface ) == EGL_FALSE )
return;
// double check
if( egl.GetError() != EGL_SUCCESS )
return;
__android_log_print( ANDROID_LOG_VERBOSE, "Xash", "native EGL enabled" );
negl.valid = true;
}
/*
========================
Android_GetGLAttribute
========================
*/
static int Android_GetGLAttribute( int eglAttr )
{
int ret = (*jni.env)->CallStaticIntMethod( jni.env, jni.actcls, jni.getGLAttribute, eglAttr );
// Con_Reportf( "Android_GetGLAttribute( %i ) => %i\n", eglAttr, ret );
return ret;
}
int Android_GetSelectedPixelFormat( void )
{
return (*jni.env)->CallStaticIntMethod( jni.env, jni.actcls, jni.getSelectedPixelFormat );
}
qboolean R_Init_Video( const int type )
{
char buf[MAX_VA_STRING];
qboolean retval;
switch( Android_GetSelectedPixelFormat() )
{
case 1:
refState.desktopBitsPixel = 16;
break;
case 2:
refState.desktopBitsPixel = 8;
break;
default:
refState.desktopBitsPixel = 32;
break;
}
if( FS_FileExists( GI->iconpath, true ) )
{
Q_snprintf( buf, sizeof( buf ), "%s/%s/%s", COM_CheckStringEmpty( host.rodir ) ? host.rodir : host.rootdir, GI->gamefolder, GI->iconpath );
Android_SetIcon( buf );
}
Android_SetTitle( GI->title );
VID_StartupGamma();
glw_state.context_type = type;
switch( type )
{
case REF_SOFTWARE:
break;
case REF_GL:
Sys_LoadLibrary( &egl_info );
if( !glw_state.safe && Sys_GetParmFromCmdLine( "-safegl", buf ) )
glw_state.safe = bound( SAFE_NO, Q_atoi( buf ), SAFE_DONTCARE );
break;
default:
Host_Error( "Can't initialize unknown context type %d!\n", type );
break;
}
if( glw_state.context_type == REF_SOFTWARE )
{
uint arg;
// Con_Reportf( S_ERROR "Native software mode isn't supported on Android yet! :(\n" );
// return false;
Sys_LoadLibrary( &android_info );
Android_UpdateSurface( true );
if( !SW_CreateBuffer( jni.width, jni.height, &arg, &arg, &arg, &arg, &arg ) )
return false;
}
while( !(retval = VID_SetMode()) )
{
glw_state.safe++;
if( glw_state.safe > SAFE_LAST )
return false;
}
switch( type )
{
case REF_GL:
// refdll also can check extensions
ref.dllFuncs.GL_InitExtensions();
break;
case REF_SOFTWARE:
default:
break;
}
host.renderinfo_changed = false;
return true;
}
void R_Free_Video( void )
{
// (*jni.env)->CallStaticBooleanMethod( jni.env, jni.actcls, jni.deleteGLContext );
// VID_DestroyWindow ();
// R_FreeVideoModes();
Sys_FreeLibrary( &android_info );
Sys_FreeLibrary( &egl_info );
vid_android.has_context = false;
ref.dllFuncs.GL_ClearExtensions();
}
#define COPY_ATTR_IF_SET( refattr, attr ) \
if( vid_android.gl_attribs_set[refattr] ) \
{ \
attribs[i++] = attr; \
attribs[i++] = vid_android.gl_attribs[refattr]; \
}
static size_t VID_GenerateConfig( EGLint *attribs, size_t size )
{
size_t i = 0;
memset( attribs, 0, size * sizeof( EGLint ) );
vid_android.gles1 = false;
memset( vid_android.gl_attribs, 0, sizeof( vid_android.gl_attribs ));
memset( vid_android.gl_attribs_set, 0, sizeof( vid_android.gl_attribs_set ));
// refdll can request some attributes
ref.dllFuncs.GL_SetupAttributes( glw_state.safe );
COPY_ATTR_IF_SET( REF_GL_RED_SIZE, EGL_RED_SIZE );
COPY_ATTR_IF_SET( REF_GL_GREEN_SIZE, EGL_GREEN_SIZE );
COPY_ATTR_IF_SET( REF_GL_BLUE_SIZE, EGL_BLUE_SIZE );
COPY_ATTR_IF_SET( REF_GL_ALPHA_SIZE, EGL_ALPHA_SIZE );
COPY_ATTR_IF_SET( REF_GL_DEPTH_SIZE, EGL_DEPTH_SIZE );
COPY_ATTR_IF_SET( REF_GL_STENCIL_SIZE, EGL_STENCIL_SIZE );
COPY_ATTR_IF_SET( REF_GL_MULTISAMPLEBUFFERS, EGL_SAMPLE_BUFFERS );
COPY_ATTR_IF_SET( REF_GL_MULTISAMPLESAMPLES, EGL_SAMPLES );
if( vid_android.gl_attribs_set[REF_GL_ACCELERATED_VISUAL] )
{
attribs[i++] = EGL_CONFIG_CAVEAT;
attribs[i++] = vid_android.gl_attribs[REF_GL_ACCELERATED_VISUAL] ? EGL_NONE : EGL_DONT_CARE;
}
// BigGL support
attribs[i++] = EGL_RENDERABLE_TYPE;
vid_android.gl_api = EGL_OPENGL_ES_API;
if( vid_android.gl_attribs_set[REF_GL_CONTEXT_PROFILE_MASK] &&
!( vid_android.gl_attribs[REF_GL_CONTEXT_PROFILE_MASK] & REF_GL_CONTEXT_PROFILE_ES ))
{
attribs[i++] = EGL_OPENGL_BIT;
vid_android.gl_api = EGL_OPENGL_API;
}
else if( vid_android.gl_attribs_set[REF_GL_CONTEXT_MAJOR_VERSION] &&
vid_android.gl_attribs[REF_GL_CONTEXT_MAJOR_VERSION] >= 2 )
{
attribs[i++] = EGL_OPENGL_ES2_BIT;
}
else
{
i--; // erase EGL_RENDERABLE_TYPE
vid_android.gles1 = true;
}
attribs[i++] = EGL_NONE;
return i;
}
static size_t VID_GenerateContextConfig( EGLint *attribs, size_t size )
{
size_t i = 0;
memset( attribs, 0, size * sizeof( EGLint ));
/*if( Q_strcmp( negl.extensions, " EGL_KHR_create_context ") )
{
if( vid_android.gl_attribs_set[REF_GL_CONTEXT_FLAGS] )
{
attribs[i++] = 0x30FC; // EGL_CONTEXT_FLAGS_KHR
attribs[i++] = vid_android.gl_attribs[REF_GL_CONTEXT_FLAGS] & ((REF_GL_CONTEXT_ROBUST_ACCESS_FLAG << 1) - 1);
}
if( vid_android.gl_attribs_set[REF_GL_CONTEXT_PROFILE_MASK] )
{
int val = vid_android.gl_attribs[REF_GL_CONTEXT_PROFILE_MASK];
if( val & ( (REF_GL_CONTEXT_PROFILE_COMPATIBILITY << 1) - 1 ) )
{
attribs[i++] = 0x30FD; // EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
attribs[i++] = val;
}
}
COPY_ATTR_IF_SET( REF_GL_CONTEXT_MAJOR_VERSION, EGL_CONTEXT_CLIENT_VERSION );
COPY_ATTR_IF_SET( REF_GL_CONTEXT_MINOR_VERSION, 0x30FB );
}
else*/
{
// without extension we can set only major version
COPY_ATTR_IF_SET( REF_GL_CONTEXT_MAJOR_VERSION, EGL_CONTEXT_CLIENT_VERSION );
}
attribs[i++] = EGL_NONE;
return i;
}
qboolean VID_SetMode( void )
{
EGLint format;
jintArray attribs, contextAttribs;
static EGLint nAttribs[32+1], nContextAttribs[32+1];
const size_t attribsSize = ARRAYSIZE( nAttribs );
size_t s1, s2;
if( vid_android.has_context )
{
R_ChangeDisplaySettings( 0, 0, false ); // width and height are ignored anyway
return true;
}
s1 = VID_GenerateConfig(nAttribs, attribsSize);
s2 = VID_GenerateContextConfig(nContextAttribs, attribsSize);
attribs = (*jni.env)->NewIntArray( jni.env, s1 );
contextAttribs = (*jni.env)->NewIntArray( jni.env, s2 );
(*jni.env)->SetIntArrayRegion( jni.env, attribs, 0, s1, nAttribs );
(*jni.env)->SetIntArrayRegion( jni.env, contextAttribs, 0, s2, nContextAttribs );
R_ChangeDisplaySettings( 0, 0, false ); // width and height are ignored anyway
if( glw_state.context_type == REF_SOFTWARE )
return true;
if( (*jni.env)->CallStaticBooleanMethod( jni.env, jni.actcls, jni.createGLContext, attribs, contextAttribs ) )
{
vid_android.has_context = true;
return true;
}
return false;
}
rserr_t R_ChangeDisplaySettings( int width, int height, qboolean fullscreen )
{
int render_w, render_h;
uint rotate = vid_rotate->value;
Android_GetScreenRes(&width, &height);
render_w = width;
render_h = height;
Con_Reportf( "R_ChangeDisplaySettings: forced resolution to %dx%d)\n", width, height);
if( ref.dllFuncs.R_SetDisplayTransform( rotate, 0, 0, vid_scale->value, vid_scale->value ) )
{
if( rotate & 1 )
{
int swap = render_w;
render_w = render_h;
render_h = swap;
}
render_h /= vid_scale->value;
render_w /= vid_scale->value;
}
else
{
Con_Printf( S_WARN "failed to setup screen transform\n" );
}
R_SaveVideoMode( width, height, render_w, render_h );
refState.wideScreen = true; // V_AdjustFov will check for widescreen
return rserr_ok;
}
int GL_SetAttribute( int attr, int val )
{
if( attr < 0 || attr >= REF_GL_ATTRIBUTES_COUNT )
return -1;
vid_android.gl_attribs[attr] = val;
vid_android.gl_attribs_set[attr] = true;
return 0;
}
int GL_GetAttribute( int attr, int *val )
{
EGLBoolean ret;
if( attr < 0 || attr >= REF_GL_ATTRIBUTES_COUNT )
return -1;
if( !val )
return -1;
switch( attr )
{
case REF_GL_RED_SIZE:
*val = Android_GetGLAttribute( EGL_RED_SIZE );
return 0;
case REF_GL_GREEN_SIZE:
*val = Android_GetGLAttribute( EGL_GREEN_SIZE );
return 0;
case REF_GL_BLUE_SIZE:
*val = Android_GetGLAttribute( EGL_BLUE_SIZE );
return 0;
case REF_GL_ALPHA_SIZE:
*val = Android_GetGLAttribute( EGL_ALPHA_SIZE );
return 0;
case REF_GL_DEPTH_SIZE:
*val = Android_GetGLAttribute( EGL_DEPTH_SIZE );
return 0;
case REF_GL_STENCIL_SIZE:
*val = Android_GetGLAttribute( EGL_STENCIL_SIZE );
return 0;
case REF_GL_MULTISAMPLESAMPLES:
*val = Android_GetGLAttribute( EGL_SAMPLES );
return 0;
}
return -1;
}
int R_MaxVideoModes( void )
{
return 0;
}
vidmode_t* R_GetVideoMode( int num )
{
return NULL;
}
void* GL_GetProcAddress( const char *name ) // RenderAPI requirement
{
void *gles;
void *addr;
if( vid_android.gles1 )
{
if( !vid_android.libgles1 )
vid_android.libgles1 = dlopen("libGLESv1_CM.so", RTLD_NOW);
gles = vid_android.libgles1;
}
else
{
if( !vid_android.libgles2 )
vid_android.libgles2 = dlopen("libGLESv2.so", RTLD_NOW);
gles = vid_android.libgles2;
}
if( gles && ( addr = dlsym(gles, name ) ) )
return addr;
if( !egl.GetProcAddress )
return NULL;
return egl.GetProcAddress( name );
}
void GL_UpdateSwapInterval( void )
{
// disable VSync while level is loading
if( cls.state < ca_active )
{
Android_SwapInterval( 0 );
SetBits( gl_vsync->flags, FCVAR_CHANGED );
}
else if( FBitSet( gl_vsync->flags, FCVAR_CHANGED ))
{
ClearBits( gl_vsync->flags, FCVAR_CHANGED );
Android_SwapInterval( gl_vsync->value );
}
}
void *SW_LockBuffer( void )
{
ANativeWindow_Buffer buffer;
if( !nw.lock || !vid_android.window )
return NULL;
if( nw.lock( vid_android.window, &buffer, NULL ) )
return NULL;
if( buffer.width < refState.width || buffer.height < refState.height )
return NULL;
return buffer.bits;
}
void SW_UnlockBuffer( void )
{
if( nw.unlockAndPost )
nw.unlockAndPost( vid_android.window );
}
qboolean SW_CreateBuffer( int width, int height, uint *stride, uint *bpp, uint *r, uint *g, uint *b )
{
ANativeWindow_Buffer buffer;
int lock;
if( !nw.lock || !vid_android.window )
return false;
nw.unlockAndPost( vid_android.window );
if( ( lock = nw.lock( vid_android.window, &buffer, NULL ) ) )
{
Con_Printf( "SW_CreateBuffer: lock %d\n", lock );
return false;
}
nw.unlockAndPost( vid_android.window );
Con_Printf( "SW_CreateBuffer: buffer %d %d %x %d %p\n", buffer.width, buffer.height, buffer.format, buffer.stride, buffer.bits );
if( width > buffer.width || height > buffer.height )
{
Con_Printf( "SW_CreateBuffer: buffer too small %d %d\n", width, height );
// resize event missed?
if( jni.width < buffer.width )
jni.width = buffer.width;
if( jni.height < buffer.height )
jni.width = buffer.height;
VID_SetMode();
Android_UpdateSurface( 1 );
return false;
}
if( buffer.format != WINDOW_FORMAT_RGB_565 )
{
Con_Printf( "SW_CreateBuffer: wrong format %d\n", buffer.format );
return false;
}
Con_Printf( "SW_CreateBuffer: ok\n" );
*stride = buffer.stride;
*bpp = 2;
*r = (((1 << 5) - 1) << (5+6));
*g = (((1 << 6) - 1) << (5));
*b = (((1 << 5) - 1) << (0));
return true;
}

View File

@ -25,13 +25,6 @@ void Platform_SetClipboardText( const char *buffer, size_t size )
}
void *Platform_GetNativeObject( const char *name )
{
return NULL;
}
void Platform_Vibrate(float life, char flags)
{
@ -89,7 +82,7 @@ static void __interrupt __far timerhandler()
// in_dos.c
extern void __interrupt __far keyhandler( void );
void Platform_Init( void )
void DOS_Init( void )
{
// save original vectors
orig_int_1c = _dos_getvect( 0x1c );
@ -104,7 +97,7 @@ void Platform_Init( void )
}
void Platform_Shutdown( void )
void DOS_Shutdown( void )
{
// restore freq
outp( 0x43, 0x34 );

View File

@ -37,7 +37,7 @@ struct evdev_s
qboolean shift;
} evdev;
static convar_t *evdev_keydebug;
static CVAR_DEFINE_AUTO( evdev_keydebug, "0", 0, "print key events to console" );
static int KeycodeFromEvdev(int keycode, int value)
{
@ -360,7 +360,7 @@ void IN_EvdevFrame ( void )
{
int key = KeycodeFromEvdev( ev.code, ev.value );
if( CVAR_TO_BOOL( evdev_keydebug ))
if( evdev_keydebug.value )
Con_Printf( "key %d %d %d\n", ev.code, key, ev.value );
Key_Event( key , ev.value );
@ -387,11 +387,11 @@ void IN_EvdevFrame ( void )
Key_ClearStates();
}
if( CVAR_TO_BOOL(m_ignore) )
if( m_ignore.value )
continue;
evdev.x += -dx * m_yaw->value;
evdev.y += dy * m_pitch->value;
evdev.x += -dx * m_yaw.value;
evdev.y += dy * m_pitch.value;
}
if( evdev.grabtime <= host.realtime )
evdev.grab = false;
@ -457,7 +457,7 @@ void Evdev_Shutdown( void )
Cmd_RemoveCommand( "evdev_open" );
Cmd_RemoveCommand( "evdev_close" );
Cmd_RemoveCommand( "evdev_autodetect" );
evdev_keydebug = Cvar_Get( "evdev_keydebug", "0", 0, "print key events to console" );
Cvar_RegisterVariable( &evdev_keydebug );
for( i = 0; i < evdev.devices; i++ )
{

View File

@ -16,8 +16,12 @@ GNU General Public License for more details.
#include <time.h>
#include <stdlib.h>
#include <fcntl.h>
#include <dlfcn.h>
#include "platform/platform.h"
static void *g_hsystemd;
static int (*g_pfn_sd_notify)( int unset_environment, const char *state );
qboolean Sys_DebuggerPresent( void )
{
char buf[4096];
@ -50,3 +54,52 @@ qboolean Sys_DebuggerPresent( void )
return false;
}
void Platform_SetStatus( const char *status )
{
string notify_str;
if( !g_pfn_sd_notify )
return;
// TODO: report STOPPING=1
Q_snprintf( notify_str, sizeof( notify_str ),
"READY=1\n"
"WATCHDOG=1\n"
"STATUS=%s\n", status );
// Quote: In order to support both service managers that implement this
// scheme and those which do not, it is generally recommended to ignore
// the return value of this call
// a1ba: ok, you asked for no error handling :)
g_pfn_sd_notify( false, notify_str );
}
void Linux_Init( void )
{
// sd_notify only for dedicated targets, don't waste time on full client
if( !Host_IsDedicated( ))
return;
if(( g_hsystemd = dlopen( "libsystemd.so.0", RTLD_LAZY )) == NULL )
return;
if(( g_pfn_sd_notify = dlsym( g_hsystemd, "sd_notify" )) == NULL )
{
dlclose( g_hsystemd );
g_hsystemd = NULL;
}
Con_Reportf( "%s: sd_notify found, will report status to systemd\n", __func__ );
}
void Linux_Shutdown( void )
{
g_pfn_sd_notify = NULL;
if( g_hsystemd )
{
dlclose( g_hsystemd );
g_hsystemd = NULL;
}
}

View File

@ -122,7 +122,6 @@ qboolean VID_SetMode( void )
rserr_t R_ChangeDisplaySettings( int width, int height, qboolean fullscreen )
{
int render_w, render_h;
uint rotate = vid_rotate->value;
FB_GetScreenRes( &width, &height );
@ -131,23 +130,7 @@ rserr_t R_ChangeDisplaySettings( int width, int height, qboolean fullscreen )
Con_Reportf( "R_ChangeDisplaySettings: forced resolution to %dx%d)\n", width, height );
if( ref.dllFuncs.R_SetDisplayTransform( rotate, 0, 0, vid_scale->value, vid_scale->value ) )
{
if( rotate & 1 )
{
int swap = render_w;
render_w = render_h;
render_h = swap;
}
render_h /= vid_scale->value;
render_w /= vid_scale->value;
}
else
{
Con_Printf( S_WARN "failed to setup screen transform\n" );
}
VID_SetDisplayTransform( &render_w, &render_h );
R_SaveVideoMode( width, height, render_w, render_h );
return rserr_ok;
@ -185,11 +168,11 @@ void GL_UpdateSwapInterval( void )
{
// setup fb vsync here
fb.vsync = false;
SetBits( gl_vsync->flags, FCVAR_CHANGED );
SetBits( gl_vsync.flags, FCVAR_CHANGED );
}
else if( FBitSet( gl_vsync->flags, FCVAR_CHANGED ))
else if( FBitSet( gl_vsync.flags, FCVAR_CHANGED ))
{
ClearBits( gl_vsync->flags, FCVAR_CHANGED );
ClearBits( gl_vsync.flags, FCVAR_CHANGED );
fb.vsync = true;
}
}
@ -289,11 +272,6 @@ void Platform_RunEvents( void )
}
void *Platform_GetNativeObject( const char *name )
{
return NULL;
}
void GAME_EXPORT Platform_GetMousePos( int *x, int *y )
{
*x = *y = 0;

View File

@ -31,25 +31,40 @@ GNU General Public License for more details.
==============================================================================
*/
void Platform_Init( void );
void Platform_Shutdown( void );
double Platform_DoubleTime( void );
void Platform_Sleep( int msec );
void Platform_ShellExecute( const char *path, const char *parms );
void Platform_MessageBox( const char *title, const char *message, qboolean parentMainWindow );
qboolean Sys_DebuggerPresent( void ); // optional, see Sys_DebugBreak
void Platform_SetStatus( const char *status );
#if XASH_WIN32 || XASH_LINUX
#define XASH_PLATFORM_HAVE_STATUS 1
#else
#undef XASH_PLATFORM_HAVE_STATUS
#endif
#if XASH_POSIX
void Posix_Daemonize( void );
#endif
#if XASH_SDL
void SDLash_Init( void );
void SDLash_Shutdown( void );
#endif
#if XASH_ANDROID
const char *Android_GetAndroidID( void );
const char *Android_LoadID( void );
void Android_SaveID( const char *id );
void Android_Init( void );
void *Android_GetNativeObject( const char *name );
int Android_GetKeyboardHeight( void );
#endif
#if XASH_WIN32
void Platform_UpdateStatusLine( void );
#else
static inline void Platform_UpdateStatusLine( void ) { }
void Wcon_CreateConsole( void );
void Wcon_DestroyConsole( void );
#endif
#if XASH_NSWITCH
@ -65,6 +80,72 @@ int PSVita_GetArgv( int in_argc, char **in_argv, char ***out_argv );
void PSVita_InputUpdate( void );
#endif
#if XASH_DOS
void DOS_Init( void );
void DOS_Shutdown( void );
#endif
#if XASH_LINUX
void Linux_Init( void );
void Linux_Shutdown( void );
#endif
static inline void Platform_Init( void )
{
#if XASH_POSIX
// daemonize as early as possible, because we need to close our file descriptors
Posix_Daemonize( );
#endif
#if XASH_SDL
SDLash_Init( );
#endif
#if XASH_ANDROID
Android_Init( );
#elif XASH_NSWITCH
NSwitch_Init( );
#elif XASH_PSVITA
PSVita_Init( );
#elif XASH_DOS
DOS_Init( );
#elif XASH_WIN32
Wcon_CreateConsole( );
#elif XASH_LINUX
Linux_Init( );
#endif
}
static inline void Platform_Shutdown( void )
{
#if XASH_NSWITCH
NSwitch_Shutdown( );
#elif XASH_PSVITA
PSVita_Shutdown( );
#elif XASH_DOS
DOS_Shutdown( );
#elif XASH_WIN32
Wcon_DestroyConsole( );
#elif XASH_LINUX
Linux_Shutdown( );
#endif
#if XASH_SDL
SDLash_Shutdown( );
#endif
}
static inline void *Platform_GetNativeObject( const char *name )
{
void *ptr = NULL;
#if XASH_ANDROID
ptr = Android_GetNativeObject( name );
#endif
return ptr;
}
/*
==============================================================================
@ -109,11 +190,6 @@ void Platform_SetClipboardText( const char *buffer );
#define SDL_VERSION_ATLEAST( x, y, z ) 0
#endif
#if XASH_ANDROID
void Android_ShowMouse( qboolean show );
void Android_MouseMove( float *x, float *y );
#endif
/*
==============================================================================

View File

@ -200,24 +200,6 @@ void *COM_FunctionFromName( void *hInstance, const char *pName )
return COM_GetProcAddress( hInstance, pName );
}
#ifdef XASH_DYNAMIC_DLADDR
static int d_dladdr( void *sym, Dl_info *info )
{
static int (*dladdr_real) ( void *sym, Dl_info *info );
if( !dladdr_real )
dladdr_real = dlsym( (void*)(size_t)(-1), "dladdr" );
memset( info, 0, sizeof( *info ) );
if( !dladdr_real )
return -1;
return dladdr_real( sym, info );
}
#define dladdr d_dladdr
#endif
const char *COM_NameForFunction( void *hInstance, void *function )
{
#ifdef XASH_DLL_LOADER

View File

@ -146,22 +146,13 @@ void Posix_Daemonize( void )
}
#if !XASH_SDL && !XASH_ANDROID
void Platform_Init( void )
{
Posix_Daemonize();
}
void Platform_Shutdown( void ) {}
#endif
#if XASH_TIMER == TIMER_POSIX
double Platform_DoubleTime( void )
{
struct timespec ts;
#if XASH_IRIX
clock_gettime( CLOCK_SGI_CYCLE, &ts );
#else
#else
clock_gettime( CLOCK_MONOTONIC, &ts );
#endif
return (double) ts.tv_sec + (double) ts.tv_nsec/1000000000.0;

View File

@ -22,6 +22,7 @@ GNU General Public License for more details.
#include <vitasdk.h>
#include <vitaGL.h>
#include <vrtld.h>
#include <sys/reent.h>
#define DATA_PATH "data/xash3d"
#define MAX_ARGV 5 // "" -log -dev X NULL
@ -33,6 +34,10 @@ unsigned int _pthread_stack_default_user = 512 * 1024;
unsigned int _newlib_heap_size_user = 200 * 1024 * 1024;
#define VGL_MEM_THRESHOLD ( 40 * 1024 * 1024 )
// HACKHACK: create some slack at the end of the RX segment of the ELF
// for vita-elf-create to put the generated symbol table into
const char vitaelf_slack __attribute__ ((aligned (0x20000))) = 0xFF;
/* HACKHACK: force-export stuff required by the dynamic libs */
extern void *__aeabi_idiv;
@ -50,6 +55,7 @@ static const vrtld_export_t aux_exports[] =
VRTLD_EXPORT_SYMBOL( __aeabi_uidivmod ),
VRTLD_EXPORT_SYMBOL( __aeabi_uidiv ),
VRTLD_EXPORT_SYMBOL( __aeabi_ul2d ),
VRTLD_EXPORT_SYMBOL( _impure_ptr ),
VRTLD_EXPORT_SYMBOL( ctime ),
VRTLD_EXPORT_SYMBOL( vasprintf ),
VRTLD_EXPORT_SYMBOL( vsprintf ),

View File

@ -25,7 +25,7 @@ GNU General Public License for more details.
#include "sound.h"
#include "vid_common.h"
#if ! SDL_VERSION_ATLEAST( 2, 0, 0 )
#if !SDL_VERSION_ATLEAST( 2, 0, 0 )
#define SDL_SCANCODE_A SDLK_a
#define SDL_SCANCODE_Z SDLK_z
#define SDL_SCANCODE_1 SDLK_1
@ -150,6 +150,13 @@ static void SDLash_KeyEvent( SDL_KeyboardEvent key )
#endif
qboolean numLock = SDL_GetModState() & KMOD_NUM;
#if XASH_ANDROID
if( keynum == SDL_SCANCODE_VOLUMEUP || keynum == SDL_SCANCODE_VOLUMEDOWN )
{
host.force_draw_version_time = host.realtime + FORCE_DRAW_VERSION_TIME;
}
#endif
if( SDL_IsTextInputActive() && down && cls.key_dest != key_game )
{
if( SDL_GetModState() & KMOD_CTRL )
@ -202,6 +209,7 @@ static void SDLash_KeyEvent( SDL_KeyboardEvent key )
case SDL_SCANCODE_MINUS: keynum = '-'; break;
case SDL_SCANCODE_TAB: keynum = K_TAB; break;
case SDL_SCANCODE_RETURN: keynum = K_ENTER; break;
case SDL_SCANCODE_AC_BACK:
case SDL_SCANCODE_ESCAPE: keynum = K_ESCAPE; break;
case SDL_SCANCODE_SPACE: keynum = K_SPACE; break;
case SDL_SCANCODE_BACKSPACE: keynum = K_BACKSPACE; break;
@ -248,7 +256,6 @@ static void SDLash_KeyEvent( SDL_KeyboardEvent key )
case SDL_SCANCODE_COMMA: keynum = ','; break;
case SDL_SCANCODE_PRINTSCREEN:
{
host.force_draw_version = true;
host.force_draw_version_time = host.realtime + FORCE_DRAW_VERSION_TIME;
break;
}
@ -262,6 +269,7 @@ static void SDLash_KeyEvent( SDL_KeyboardEvent key )
case SDL_SCANCODE_VOLUMEDOWN:
case SDL_SCANCODE_BRIGHTNESSDOWN:
case SDL_SCANCODE_BRIGHTNESSUP:
case SDL_SCANCODE_SELECT:
return;
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
case SDL_SCANCODE_UNKNOWN:
@ -347,7 +355,7 @@ static void SDLash_InputEvent( SDL_TextInputEvent input )
{
int ch;
if( !Q_stricmp( cl_charset->string, "utf-8" ) )
if( !Q_stricmp( cl_charset.string, "utf-8" ) )
ch = (unsigned char)*text;
else
ch = Con_UtfProcessCharForce( (unsigned char)*text );
@ -374,9 +382,8 @@ static void SDLash_ActiveEvent( int gain )
{
SNDDMA_Activate( true );
}
host.force_draw_version = true;
host.force_draw_version_time = host.realtime + FORCE_DRAW_VERSION_TIME;
if( vid_fullscreen->value )
if( vid_fullscreen.value )
VID_SetMode();
}
else
@ -398,8 +405,7 @@ static void SDLash_ActiveEvent( int gain )
{
SNDDMA_Activate( false );
}
host.force_draw_version = true;
host.force_draw_version_time = host.realtime + 2;
host.force_draw_version_time = host.realtime + 2.0;
VID_RestoreScreenResolution();
}
}
@ -409,10 +415,12 @@ static size_t num_open_game_controllers = 0;
static void SDLash_GameController_Add( int index )
{
extern convar_t *joy_enable; // private to input system
extern convar_t joy_enable; // private to input system
SDL_GameController *controller;
if( !joy_enable->value )
if( !joy_enable.value )
return;
controller = SDL_GameControllerOpen( index );
if( !controller )
{
@ -614,10 +622,15 @@ static void SDLash_EventFilter( SDL_Event *event )
switch( event->window.event )
{
case SDL_WINDOWEVENT_MOVED:
if( !vid_fullscreen->value )
if( !vid_fullscreen.value )
{
Cvar_SetValue( "_window_xpos", (float)event->window.data1 );
Cvar_SetValue( "_window_ypos", (float)event->window.data2 );
char val[32];
Q_snprintf( val, sizeof( val ), "%d", event->window.data1 );
Cvar_DirectSet( &window_xpos, val );
Q_snprintf( val, sizeof( val ), "%d", event->window.data2 );
Cvar_DirectSet( &window_ypos, val );
}
break;
case SDL_WINDOWEVENT_MINIMIZED:
@ -626,9 +639,8 @@ static void SDLash_EventFilter( SDL_Event *event )
break;
case SDL_WINDOWEVENT_RESTORED:
host.status = HOST_FRAME;
host.force_draw_version = true;
host.force_draw_version_time = host.realtime + FORCE_DRAW_VERSION_TIME;
if( vid_fullscreen->value )
if( vid_fullscreen.value )
VID_SetMode();
break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
@ -639,7 +651,7 @@ static void SDLash_EventFilter( SDL_Event *event )
break;
case SDL_WINDOWEVENT_RESIZED:
{
if( vid_fullscreen->value )
if( vid_fullscreen.value )
break;
VID_SaveWindowSize( event->window.data1, event->window.data2 );
@ -677,11 +689,6 @@ void Platform_RunEvents( void )
#endif
}
void* Platform_GetNativeObject( const char *name )
{
return NULL; // SDL don't have it
}
/*
========================
Platform_PreCreateMove
@ -692,7 +699,7 @@ TODO: kill mouse in win32 clients too
*/
void Platform_PreCreateMove( void )
{
if( CVAR_TO_BOOL( m_ignore ))
if( m_ignore.value )
{
SDL_GetRelativeMouseState( NULL, NULL );
SDL_ShowCursor( SDL_TRUE );

View File

@ -122,8 +122,10 @@ Platform_Vibrate
*/
void Platform_Vibrate( float time, char flags )
{
#if SDL_VERSION_ATLEAST( 2, 0, 9 )
if( g_joy )
SDL_JoystickRumble( g_joy, 0xFFFF, 0xFFFF, time * 1000.0f );
#endif // SDL_VERSION_ATLEAST( 2, 0, 9 )
}
#if !XASH_PSVITA

View File

@ -21,13 +21,12 @@ GNU General Public License for more details.
#include "voice.h"
#include <SDL.h>
#include <stdlib.h>
#define SAMPLE_16BIT_SHIFT 1
#define SECONDARY_BUFFER_SIZE 0x10000
#if ! SDL_VERSION_ATLEAST( 2, 0, 0 )
#include <stdlib.h>
#define SDL_setenv setenv
#define SDL_GetCurrentAudioDriver() "legacysdl"
#define SDL_OpenAudioDevice( a, b, c, d, e ) SDL_OpenAudio( ( c ), ( d ) )
#define SDL_CloseAudioDevice( a ) SDL_CloseAudio()
@ -50,20 +49,26 @@ static SDL_AudioDeviceID in_dev = 0;
static SDL_AudioFormat sdl_format;
static char sdl_backend_name[32];
//static qboolean snd_firsttime = true;
//static qboolean primary_format_set;
void SDL_SoundCallback( void *userdata, Uint8 *stream, int len )
{
int size = dma.samples << 1;
int pos = dma.samplepos << 1;
int wrapped = pos + len - size;
const int size = dma.samples << 1;
int pos;
int wrapped;
#if ! SDL_VERSION_ATLEAST( 2, 0, 0 )
if( !dma.buffer )
{
memset( stream, 0, len );
return;
}
#endif
pos = dma.samplepos << 1;
if( pos >= size )
pos = dma.samplepos = 0;
wrapped = pos + len - size;
if( wrapped < 0 )
{
memcpy( stream, dma.buffer + pos, len );
@ -72,10 +77,14 @@ void SDL_SoundCallback( void *userdata, Uint8 *stream, int len )
else
{
int remaining = size - pos;
memcpy( stream, dma.buffer + pos, remaining );
memcpy( stream + remaining, dma.buffer, wrapped );
dma.samplepos = wrapped >> 1;
}
if( dma.samplepos >= size )
dma.samplepos = 0;
}
/*
@ -91,17 +100,17 @@ qboolean SNDDMA_Init( void )
SDL_AudioSpec desired, obtained;
int samplecount;
if( SDL_Init( SDL_INIT_AUDIO ) )
{
Con_Reportf( S_ERROR "Audio: SDL: %s \n", SDL_GetError( ) );
return false;
}
// even if we don't have PA
// we still can safely set env variables
SDL_setenv( "PULSE_PROP_application.name", GI->title, 1 );
SDL_setenv( "PULSE_PROP_media.role", "game", 1 );
if( SDL_Init( SDL_INIT_AUDIO ))
{
Con_Reportf( S_ERROR "Audio: SDL: %s \n", SDL_GetError( ) );
return false;
}
memset( &desired, 0, sizeof( desired ) );
desired.freq = SOUND_DMA_SPEED;
desired.format = AUDIO_S16LSB;
@ -165,7 +174,7 @@ Makes sure dma.buffer is valid
*/
void SNDDMA_BeginPainting( void )
{
// SDL_LockAudioDevice( sdl_dev );
SDL_LockAudioDevice( sdl_dev );
}
/*
@ -178,7 +187,7 @@ Also unlocks the dsound buffer
*/
void SNDDMA_Submit( void )
{
// SDL_UnlockAudioDevice( sdl_dev );
SDL_UnlockAudioDevice( sdl_dev );
}
/*

View File

@ -45,13 +45,12 @@ void Platform_MessageBox( const char *title, const char *message, qboolean paren
SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR, title, message, parentMainWindow ? host.hWnd : NULL );
}
#endif // XASH_MESSAGEBOX == MSGBOX_SDL
void Posix_Daemonize( void );
void Platform_Init( void )
void SDLash_Init( void )
{
#ifndef SDL_INIT_EVENTS
#define SDL_INIT_EVENTS 0
#endif
if( SDL_Init( SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_EVENTS ) )
{
Sys_Warn( "SDL_Init failed: %s", SDL_GetError() );
@ -63,29 +62,10 @@ void Platform_Init( void )
SDL_StopTextInput();
#endif // XASH_SDL == 2
#if XASH_WIN32
Wcon_CreateConsole(); // system console used by dedicated server or show fatal errors
#elif XASH_POSIX
Posix_Daemonize();
#if XASH_PSVITA
PSVita_Init();
#elif XASH_NSWITCH
NSwitch_Init();
#endif
#endif // XASH_POSIX
SDLash_InitCursors();
}
void Platform_Shutdown( void )
void SDLash_Shutdown( void )
{
SDLash_FreeCursors();
#if XASH_NSWITCH
NSwitch_Shutdown();
#elif XASH_WIN32
Wcon_DestroyConsole();
#elif XASH_PSVITA
PSVita_Shutdown();
#endif
}

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