Compare commits
1 Commits
continuous
...
apidocs
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03a9d08053 |
12
.cirrus.yml
@@ -1,13 +1,14 @@
|
||||
task:
|
||||
name: freebsd-14-amd64
|
||||
freebsd_instance:
|
||||
image_family: freebsd-14-2
|
||||
image_family: freebsd-14-0
|
||||
setup_script:
|
||||
- pkg update
|
||||
- pkg install -y pkgconf git sdl2 python fontconfig libvorbis opusfile bzip2 libbacktrace
|
||||
- pkg install -y pkgconf git sdl2 python fontconfig opus
|
||||
- git submodule update --init --recursive
|
||||
test_script:
|
||||
- ./scripts/cirrus/build_freebsd.sh
|
||||
- ./scripts/cirrus/build_freebsd.sh dedicated
|
||||
- ./scripts/cirrus/build_freebsd.sh full
|
||||
|
||||
task:
|
||||
name: freebsd-15-amd64
|
||||
@@ -15,7 +16,8 @@ task:
|
||||
image_family: freebsd-15-0-snap
|
||||
setup_script:
|
||||
- pkg update
|
||||
- pkg install -y pkgconf git sdl2 python fontconfig libvorbis opusfile bzip2 libbacktrace
|
||||
- pkg install -y pkgconf git sdl2 python fontconfig opus
|
||||
- git submodule update --init --recursive
|
||||
test_script:
|
||||
- ./scripts/cirrus/build_freebsd.sh
|
||||
- ./scripts/cirrus/build_freebsd.sh dedicated
|
||||
- ./scripts/cirrus/build_freebsd.sh full
|
||||
|
||||
28
.github/workflows/c-cpp.yml
vendored
@@ -15,39 +15,35 @@ jobs:
|
||||
include:
|
||||
# Linux build specifically want oldest Ubuntu as possible
|
||||
# to be crossdistribution compatible, otherwise use ubuntu-latest
|
||||
- os: ubuntu-22.04
|
||||
- os: ubuntu-20.04
|
||||
targetos: linux
|
||||
targetarch: amd64
|
||||
- os: ubuntu-22.04
|
||||
- os: ubuntu-20.04
|
||||
targetos: linux
|
||||
targetarch: i386
|
||||
- os: ubuntu-22.04
|
||||
- os: ubuntu-20.04
|
||||
targetos: linux
|
||||
targetarch: arm64
|
||||
cross: true
|
||||
- os: ubuntu-22.04
|
||||
- os: ubuntu-20.04
|
||||
targetos: linux
|
||||
targetarch: armhf
|
||||
cross: true
|
||||
- os: ubuntu-24.04 # riscv64 would benefit from having latest compilers
|
||||
- os: ubuntu-20.04
|
||||
targetos: linux
|
||||
targetarch: riscv64
|
||||
cross: true
|
||||
- os: ubuntu-22.04
|
||||
- os: ubuntu-20.04
|
||||
targetos: linux
|
||||
targetarch: ppc64el
|
||||
cross: true
|
||||
# - os: ubuntu-aarch64-22.04
|
||||
# - os: ubuntu-aarch64-20.04
|
||||
# targetos: linux
|
||||
# targetarch: aarch64
|
||||
- os: ubuntu-latest
|
||||
targetos: linux
|
||||
targetarch: e2k-8c
|
||||
cross: true
|
||||
- os: ubuntu-latest
|
||||
- os: ubuntu-20.04
|
||||
targetos: android
|
||||
targetarch: multiarch
|
||||
# - os: ubuntu-22.04
|
||||
# - os: ubuntu-20.04
|
||||
# targetos: motomagx
|
||||
# targetarch: armv6
|
||||
|
||||
@@ -70,7 +66,7 @@ jobs:
|
||||
targetos: apple
|
||||
targetarch: amd64
|
||||
env:
|
||||
SDL_VERSION: 2.32.0
|
||||
SDL_VERSION: 2.30.11
|
||||
GH_CPU_ARCH: ${{ matrix.targetarch }}
|
||||
GH_CROSSCOMPILING: ${{ matrix.cross }}
|
||||
steps:
|
||||
@@ -91,7 +87,6 @@ jobs:
|
||||
path: artifacts/*
|
||||
flatpak:
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
@@ -105,7 +100,7 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Build flatpak (Compat.i386)
|
||||
uses: FWGS/flatpak-github-actions/flatpak-builder@v6.3-fix
|
||||
uses: FWGS/flatpak-github-actions/flatpak-builder@v6.3
|
||||
with:
|
||||
bundle: ${{ matrix.app }}.flatpak
|
||||
manifest-path: scripts/flatpak/${{ matrix.app }}.yml
|
||||
@@ -124,6 +119,7 @@ jobs:
|
||||
--yes \
|
||||
--cleanup-tag \
|
||||
--repo "$GITHUB_REPOSITORY" || true
|
||||
sleep 20s
|
||||
gh run download "$GITHUB_RUN_ID" \
|
||||
--dir artifacts/ \
|
||||
--repo "$GITHUB_REPOSITORY"
|
||||
|
||||
12
.gitmodules
vendored
@@ -27,16 +27,10 @@
|
||||
url = https://github.com/FWGS/MultiEmulator
|
||||
[submodule "3rdparty/libogg/libogg"]
|
||||
path = 3rdparty/libogg/libogg
|
||||
url = https://github.com/xiph/ogg.git
|
||||
url = https://gitlab.xiph.org/xiph/ogg.git
|
||||
[submodule "3rdparty/vorbis/vorbis-src"]
|
||||
path = 3rdparty/vorbis/vorbis-src
|
||||
url = https://github.com/xiph/vorbis.git
|
||||
url = https://gitlab.xiph.org/xiph/vorbis.git
|
||||
[submodule "3rdparty/opusfile/opusfile"]
|
||||
path = 3rdparty/opusfile/opusfile
|
||||
url = https://github.com/xiph/opusfile.git
|
||||
[submodule "3rdparty/libbacktrace/libbacktrace"]
|
||||
path = 3rdparty/libbacktrace/libbacktrace
|
||||
url = https://github.com/ianlancetaylor/libbacktrace
|
||||
[submodule "3rdparty/maintui"]
|
||||
path = 3rdparty/maintui
|
||||
url = https://github.com/numas13/xash3d-maintui.git
|
||||
url = https://gitlab.xiph.org/xiph/opusfile.git
|
||||
|
||||
2
3rdparty/MultiEmulator
vendored
1
3rdparty/extras/wscript
vendored
@@ -25,4 +25,5 @@ def build(bld):
|
||||
name = 'extras.pk3',
|
||||
files = srcdir.ant_glob('**/*'),
|
||||
relative_to = srcdir,
|
||||
compresslevel = 0,
|
||||
install_path = install_path)
|
||||
|
||||
2
3rdparty/extras/xash-extras
vendored
2
3rdparty/gl4es/gl4es
vendored
1
3rdparty/libbacktrace/libbacktrace
vendored
183
3rdparty/libbacktrace/wscript
vendored
@@ -1,183 +0,0 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
from waflib import TaskGen
|
||||
from waflib.Tools.c_config import DEFKEYS
|
||||
|
||||
FRAGMENT_ATOMIC='''int i;
|
||||
int main(void) {
|
||||
__atomic_load_n(&i, __ATOMIC_ACQUIRE);
|
||||
__atomic_store_n(&i, 1, __ATOMIC_RELEASE);
|
||||
return 0;
|
||||
}'''
|
||||
|
||||
FRAGMENT_SYNC='''int i;
|
||||
int main (void) {
|
||||
__sync_bool_compare_and_swap (&i, i, i);
|
||||
__sync_lock_test_and_set (&i, 1);
|
||||
__sync_lock_release (&i);
|
||||
return 0;
|
||||
}'''
|
||||
|
||||
FRAGMENT_GETPAGESIZE='''#include <unistd.h>
|
||||
int main(void) { return getpagesize() }'''
|
||||
|
||||
FRAGMENT_GETEXECNAME='''#include <stdlib.h>
|
||||
int main(void) { return getexecname() != 0 }'''
|
||||
|
||||
FRAGMENT_STRNLEN='''#include <string.h>
|
||||
int main(int argc, char **argv) { return (int)strnlen(argv[0], 10); }'''
|
||||
|
||||
FRAGMENT_DL_ITERATE_PHDR='''#include <%s>
|
||||
int main(void) { return dl_iterate_phdr(0, 0); }'''
|
||||
|
||||
FRAGMENT_FCNTL='''#include <fcntl.h>
|
||||
int main(void) { return fcntl(0, 0, 0); }'''
|
||||
|
||||
FRAGMENT_GETIPINFO='''#include "unwind.h"
|
||||
struct _Unwind_Context *context;
|
||||
int ip_before_insn = 0;
|
||||
int main(void) { return _Unwind_GetIPInfo(context, &ip_before_insn); }'''
|
||||
|
||||
FRAGMENT_LOADQUERY='''#include <sys/ldr.h>
|
||||
#include <sys/debug.h>
|
||||
int main(void) { return loadquery(0, 0, 0); }'''
|
||||
|
||||
FRAGMENT_KERN_PROC='''#include <sys/sysctl.h>
|
||||
#if !defined(%s) || !defined(KERN_PROC_PATHNAME)
|
||||
#error
|
||||
#endif
|
||||
int main(void) { return 0; }'''
|
||||
|
||||
FRAGMENT_LSTAT='''#include <sys/stat.h>
|
||||
struct stat st;
|
||||
int main(int argc, char **argv) { return lstat(argv[0], &st); }'''
|
||||
|
||||
FRAGMENT_READLINK='''#include <unistd.h>
|
||||
char buf[100];
|
||||
int main(int argc, char **argv) { return readlink(argv[0], buf, sizeof(buf)); }'''
|
||||
|
||||
def options(opt):
|
||||
pass
|
||||
|
||||
def configure(conf):
|
||||
# add unsupported platforms here
|
||||
if conf.env.DEST_OS in ['nswitch', 'psvita', 'dos']:
|
||||
conf.env.DISABLE_LIBBACKTRACE = True
|
||||
return
|
||||
|
||||
# win32 has it's own dbghelp-based backtrace, that's why we ship PDBs
|
||||
if conf.env.COMPILER_CC == 'msvc':
|
||||
conf.env.DISABLE_LIBBACKTRACE = True
|
||||
return
|
||||
|
||||
if not conf.path.find_dir('libbacktrace') or not conf.path.find_dir('libbacktrace/config'):
|
||||
conf.fatal('Can\'t find libbacktrace submodule. Run `git submodule update --init --recursive`.')
|
||||
return
|
||||
|
||||
conf.define('BACKTRACE_ELF_SIZE', 64 if conf.env.DEST_SIZEOF_VOID_P == 8 else 32)
|
||||
conf.define('BACKTRACE_XCOFF_SIZE', 64 if conf.env.DEST_SIZEOF_VOID_P == 8 else 32)
|
||||
conf.define('_ALL_SOURCE', 1)
|
||||
conf.define('_GNU_SOURCE', 1)
|
||||
conf.define('_POSIX_PTHREAD_SEMANTICS', 1)
|
||||
conf.define('_TANDEM_SOURCE', 1)
|
||||
conf.define('__EXTENSIONS__', 1)
|
||||
conf.define('_DARWIN_USE_64_BIT_INODE', 1)
|
||||
conf.define('_LARGE_FILES', 1)
|
||||
conf.check_large_file(compiler='c', execute=False, mandatory=False) # sets _FILE_OFFSET_BITS
|
||||
|
||||
conf.env.CFLAGS_EXTRAFLAGS = conf.filter_cflags(['-funwind-tables', '-g'], [])
|
||||
|
||||
if conf.filter_cflags(['-frandom-seed=test'], []):
|
||||
conf.env.HAVE_FRANDOM_SEED = True
|
||||
|
||||
def check_header(hdr):
|
||||
return {'header_name':hdr, 'msg':'... %s header' % hdr, 'mandatory':False, 'id':hdr}
|
||||
|
||||
conf.multicheck(
|
||||
check_header('dlfcn.h'),
|
||||
check_header('inttypes.h'),
|
||||
check_header('link.h'),
|
||||
check_header('sys/link.h'),
|
||||
check_header('mach-o/dyld.h'),
|
||||
check_header('memory.h'),
|
||||
check_header('stdint.h'),
|
||||
check_header('stdlib.h'),
|
||||
check_header('strings.h'),
|
||||
check_header('string.h'),
|
||||
check_header('sys/ldr.h'),
|
||||
check_header('sys/mman.h'),
|
||||
check_header('sys/stat.h'),
|
||||
check_header('sys/types.h'),
|
||||
check_header('tlhelp32.h'),
|
||||
check_header('unistd.h'),
|
||||
check_header('windows.h'),
|
||||
|
||||
{'fragment':FRAGMENT_ATOMIC, 'msg':'... __atomic extensions', 'define_name':'HAVE_ATOMIC_FUNCTIONS', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_SYNC, 'msg':'... __sync extensions', 'define_name':'HAVE_SYNC_FUNCTIONS', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_GETPAGESIZE, 'msg':'... getpagesize function', 'define_name':'HAVE_DECL_GETPAGESIZE', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_STRNLEN, 'msg':'... strnlen function', 'define_name':'HAVE_DECL_STRNLEN', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_DL_ITERATE_PHDR % 'link.h', 'msg':'... dl_iterate_phdr function in link.h', 'define_name':'HAVE_DL_ITERATE_PHDR', 'after_tests': ['link.h'], 'mandatory':False},
|
||||
{'fragment':FRAGMENT_DL_ITERATE_PHDR % 'sys/link.h', 'msg':'... dl_iterate_phdr function in sys/link.h', 'define_name':'HAVE_DL_ITERATE_PHDR', 'after_tests': ['sys/link.h'], 'mandatory':False},
|
||||
{'fragment':FRAGMENT_FCNTL,'msg':'... fnctl function', 'define_name':'HAVE_FCNTL', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_GETEXECNAME,'msg':'... getexecname function','define_name':'HAVE_GETEXECNAME', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_GETIPINFO, 'msg':'... _Unwind_GetIPInfo function', 'define_name':'HAVE_GETIPINFO', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_KERN_PROC % 'KERN_PROC', 'msg': '... KERN_PROC and KERN_PROC_PATHNAME defines', 'define_name':'HAVE_KERN_PROC', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_KERN_PROC % 'KERN_PROC_ARGS', 'msg': '... KERN_PROC_ARGS and KERN_PROC_PATHNAME defines', 'define_name':'HAVE_KERN_PROC_ARGS', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_LOADQUERY, 'msg': '... loadquery function', 'define_name':'HAVE_LOADQUERY', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_LSTAT, 'msg': '... lstat function', 'define_name':'HAVE_LSTAT', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_READLINK, 'msg': '... readlink function', 'define_name':'HAVE_READLINK', 'mandatory':False},
|
||||
|
||||
# {'lib':'lzma', 'define_name':'HAVE_LIBLZMA', 'uselib_store':'lzma', 'msg':'... lzma library', 'mandatory':False},
|
||||
# {'lib':'z', 'define_name':'HAVE_ZLIB', 'uselib_store':'z', 'msg':'... zlib library', 'mandatory':False},
|
||||
# {'lib':'zstd', 'define_name':'HAVE_ZSTD', 'uselib_store':'zstd', 'msg':'... zstd library', 'mandatory':False},
|
||||
msg='Checking for in parallel'
|
||||
)
|
||||
|
||||
conf.env[DEFKEYS].sort()
|
||||
|
||||
conf.write_config_header()
|
||||
|
||||
conf.define('BACKTRACE_SUPPORTED', 1)
|
||||
conf.define('BACKTRACE_USES_MALLOC', 0)
|
||||
conf.define('BACKTRACE_SUPPORTS_THREADS', 1)
|
||||
conf.define('BACKTRACE_SUPPORTS_DATA', conf.env.DEST_BINFMT in ['elf', 'mac-o'])
|
||||
|
||||
conf.write_config_header('backtrace-supported.h')
|
||||
|
||||
@TaskGen.feature('frandomseed')
|
||||
@TaskGen.after_method('propagate_uselib_vars')
|
||||
def process_frandom_seed(ctx):
|
||||
tasks = getattr(ctx, 'compiled_tasks', [])
|
||||
|
||||
for task in tasks:
|
||||
out = task.outputs[0]
|
||||
task.env.CFLAGS = list(task.env.CFLAGS) # need a copy
|
||||
task.env.CFLAGS += ['-frandom-seed=%s' % out.path_from(out.ctx.bldnode)]
|
||||
|
||||
def build(bld):
|
||||
if bld.env.DISABLE_LIBBACKTRACE:
|
||||
return
|
||||
|
||||
# we specifically only want mmap-based allocators because calling malloc is not safe from signal handlers
|
||||
sources = ['atomic.c', 'dwarf.c', 'fileline.c', 'posix.c', 'print.c', 'sort.c', 'state.c', 'backtrace.c', 'simple.c', 'mmap.c', 'mmapio.c']
|
||||
|
||||
if bld.env.DEST_BINFMT == 'pe':
|
||||
sources += ['pecoff.c']
|
||||
elif bld.env.DEST_BINFMT == 'mac-o':
|
||||
sources += ['macho.c']
|
||||
elif bld.env.DEST_BINFMT == 'elf':
|
||||
sources += ['elf.c']
|
||||
else:
|
||||
sources += ['unknown.c']
|
||||
|
||||
task = bld.stlib(
|
||||
source = ['libbacktrace/' + i for i in sources],
|
||||
target = 'backtrace',
|
||||
features = 'frandomseed' if bld.env.HAVE_FRANDOM_SEED else '',
|
||||
use = 'EXTRAFLAGS lzma z zstd',
|
||||
includes = '. libbacktrace/',
|
||||
export_defines = 'HAVE_LIBBACKTRACE=1',
|
||||
export_includes = 'libbacktrace/'
|
||||
)
|
||||
|
||||
1
3rdparty/maintui
vendored
2
3rdparty/mainui
vendored
2
3rdparty/vgui_support
vendored
@@ -45,8 +45,3 @@
|
||||
Tags can be any: subsystem, simple feature name or even just a filename, without extension.
|
||||
Just keep them always same, it helps keep history clean and commit messages short.
|
||||
|
||||
## LLM-based tools usage.
|
||||
|
||||
While we wouldn't recommend using any LLM-based (also misleadingly called AI) tools, we understand that they are here to stay.
|
||||
|
||||
Whether you're reporting bug or contributing the code, you take complete authorship and responsibility over provided content and the same rules will apply to you as for everybody else, so validate the bug report or the patch before sending it.
|
||||
|
||||
5
Documentation/api/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Welcome to the GoldSource API docs
|
||||
|
||||
This documentation is an attempt on explaining inner workings of Valve's Half-Life (R) engine, also known as GoldSource, from programmer's perspective. A deep knowledge of Quake (NQ, QW and Q2) engines is required.
|
||||
|
||||
Everything discussed here is it's author assumption based on studying Xash3D source code and reverse engineering Half-Life mods. Xash3D API extensions is out of scope of this document and will be explained separately.
|
||||
20
Documentation/api/client/01-init.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Initializing client.dll
|
||||
|
||||
`client.dll` has got multiple ways of initialization during it's life but we will go through the simplest and the most common route here.
|
||||
|
||||
Here we expect that reader has knowledge of loading dynamic shared objects on their platform. On Windows it's done through `LoadLibrary`/`GetProcAddress`/`FreeLibrary` functions, on POSIX-complaint systems it's done through `dlopen`/`dlsym`/`dlclose` functions.
|
||||
|
||||
## client.dll lifetime
|
||||
|
||||
`client.dll` is expected to be loaded during client initialization and unloaded on client shutdown. Essentially, in non-dedicated builds, it always exists during the engine lifetime. Judging by the API, it might look like `client.dll` might be safely unloaded and loaded again, for example for implementing classic `Change Game` functionality from WON versions of Half-Life, but in practice it's nearly impossible to do this clean in standard and portable manner. If you want to implement changing games, consider using `execv`-like functions.
|
||||
|
||||
## client.dll exported functions
|
||||
|
||||
The first thing you should do, is to acquire pointers to all exported functions, which you can find in the next chapter. Some of them are optional, and might not present in the `client.dll`, and will be labeled as such.
|
||||
|
||||
## client.dll initialization process
|
||||
|
||||
1. The first function you call is `Initialize` function, which lets `client.dll` to store a copy of an engine API functions.
|
||||
2. Since SDK 2.0, `client.dll` have player movement code in it, which you must initialize through `HUD_PlayerMoveInit` function. `client.dll` might want to override player hulls, which can be grabbed with `HUD_GetHullBounds` function.
|
||||
3. HUD functionality must be started up with `HUD_Init` function and can be de-initialized with `HUD_Shutdown` export function.
|
||||
4. And finally, SDK 2.1 brings studio model renderer, which has separate set of API functions, which must be initialized with `HUD_GetStudioModelInterface` function.
|
||||
286
Documentation/api/client/02-exports.md
Normal file
@@ -0,0 +1,286 @@
|
||||
# List of client.dll exported functions
|
||||
|
||||
### `int Initialize( cl_enginefuncs_t *enginefuncs, int version )`
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This function is only called once.
|
||||
|
||||
Called after loading DLL and exports engine API to the `client.dll`.
|
||||
* `enginefuncs` must be set to a pointer to a struct filled with engine function pointers, it will be described in next chapters.
|
||||
* `version` must be always set to `7`. (HLSDK 1.0 uses version `6`, and is binary incompatible with `7`).
|
||||
Return value: `0` on error, otherwise success.
|
||||
|
||||
### `void HUD_PlayerMoveInit( struct playermove_s *ppmove, int server )`
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This function is only called once.
|
||||
|
||||
Called on player movement prediction initialization, before HUD. In GoldSrc, engine only runs prediction loop, the players physics are implemented in `client.dll`.
|
||||
* `ppmove` must be set to a pointer to a client instance of player movement structure, which also exports it's own API and will be discussed in the next chapters.
|
||||
* `server` must be always set to `0` on client side.
|
||||
This function is called only once.
|
||||
|
||||
### `void HUD_Init( void )`
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This function is only called once.
|
||||
|
||||
Called to initialize the HUD. At this moment engine should be ready to register new commands, console variables and user messages. No rendering or loading graphics done at this moment.
|
||||
|
||||
### `int HUD_GetStudioModelInterface( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio )`
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This function is only called once.
|
||||
|
||||
This function is called after initializing HUD and exports studio model interface to the `client.dll`.
|
||||
* `version` must be always set to `1`.
|
||||
* `ppinterface` will be set by `client.dll` to a pointer to `r_studio_interface_s` structure.
|
||||
* `pstudio` must be set to a pointer to `engine_studio_api_s` structure. The studio model interface will be discussed in the next chapters.
|
||||
Return value: `0` on error, otherwise success.
|
||||
|
||||
### `void HUD_Shutdown( void )`
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This function is only called once.
|
||||
|
||||
Called at client shutdown.
|
||||
|
||||
### `int HUD_GetHullBounds( int hull, vec3_t mins, vec3_t maxs )`
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This function is only called once.
|
||||
|
||||
Called by the engine after `HUD_PlayerMoveInit` to let `client.dll` override hull bounds used for in player movement prediction.
|
||||
|
||||
* `hull` is the hull index (0: player standing, 1: player crouched, 2: point hull, 3: large hull).
|
||||
* `mins` will contain hull mins.
|
||||
* `maxs` will contain hull maxs.
|
||||
Return value: if 0, don't override this hull and stop reading, non-zero means hull is valid _and_ there is more.
|
||||
|
||||
> [!NOTE]
|
||||
> This function is broken in most implementations. It might return non-zero value, but don't write anything to the `mins` and `maxs` vectors, so be prepared to have some default values.
|
||||
|
||||
### `int HUD_VidInit( void )`
|
||||
|
||||
Called when client receives `svc_serverdata` message. It is called before any parsing of that message is done, thus the state is preserved from the previous connection. It lets `client.dll` to re-initialize graphics, if required. At this point, engine is expected to have video subsystem running, but no rendering is done here.
|
||||
|
||||
### `int HUD_Redraw( float flTime, int intermission )`
|
||||
|
||||
Called each frame to redraw the HUD. Only 2D is drawn here.
|
||||
* `flTime` must be set to `cl.time`, i.e. synchronized with server.
|
||||
* `intermission` must be set to `1` during intermission (set through `svc_intermission` message), otherwise it's set to `0`.
|
||||
Return value: ignored.
|
||||
|
||||
### `void HUD_Reset( void )`
|
||||
|
||||
Called on demo recording or playback start and stop.
|
||||
|
||||
### `int HUD_UpdateClientData( client_data_t *cdata, float flTime )`
|
||||
|
||||
Called each frame after taking input.
|
||||
* `cdata` contains pointer to `client_data_t` structure, populated by engine.
|
||||
* `flTime` must be set to `cl.time`, i.e. synchronized with server.
|
||||
Return value: if non-zero, will override engine viewangles and FOV value.
|
||||
|
||||
### `void HUD_PlayerMove( struct playermove_s *pmove, int server )`
|
||||
|
||||
When prediction is enabled, use this function to run player movement prediction. Note that this correlates to QW/Q2's prediction mechanism. It does not include weapon prediction.
|
||||
|
||||
* `pmove` is a pointer to playermove object
|
||||
* `server` must be always set to `0`
|
||||
|
||||
### `char HUD_PlayerMoveTexture( char *name )`
|
||||
|
||||
Not used in the engine.
|
||||
|
||||
### `int HUD_ConnectionlessPacket( const netadr_t *from, const char *args, char *response_buffer, int *response_buffer_size )`
|
||||
|
||||
Called by the engine on unknown connectionless packets. Lets `client.dll` and `server.dll` have custom query protocol.
|
||||
|
||||
* `from` is set to network address where this packet is coming from.
|
||||
* `args` raw network buffer, minus the connectionless packet header (0xFFFFFFFF).
|
||||
* `response_buffer` set by `client.dll` if there is a response.
|
||||
* `response_buffer_size` is initialized by the engine with buffer maximum size. Set by `client.dll` if there is a response.
|
||||
Return value: non-zero if handled.
|
||||
|
||||
### `void HUD_Frame( double time )`
|
||||
|
||||
Called each frame after sending command to the remote server. No rendering is normally done in this function.
|
||||
|
||||
* `time` is the local delta time between previous and this frame (i.e. `host.frametime`)
|
||||
|
||||
### `void HUD_PostRunCmd( struct local_state_s *from, struct local_state_s *to, usercmd_t *cmd, int runfuncs, double time, unsigned int random_seed )`
|
||||
|
||||
Always called after `HUD_PlayerMove`, even if movement prediction is disabled. Used for weapon prediction stuff.
|
||||
|
||||
* `from` is a pointer to `local_state_s` object of the previous predicted frame
|
||||
* `to` is a pointer to `local_state_s` object of this current frame
|
||||
* `cmd` is current user command
|
||||
* `runfuncs` is set to `1` if this frame was never predicted before, and to `0` if it is being predicted again
|
||||
* `random_seed` is set to `incoming_acknowledged` plus number of predicted frames starting with `1`. This way it's synchronized between client and server.
|
||||
|
||||
### `int HUD_Key_Event( int down, int key, const char *current_binding )`
|
||||
|
||||
Called on keyboard event.
|
||||
|
||||
* `down` is set to `1` if key is being pressed or set to `0` on being released.
|
||||
* `key` is set to the key number. The key IDs are predefined.
|
||||
* `current_binding` is set to a null-terminated string with commands bound to this key
|
||||
Return value: `0` if `client.dll` wants engine to ignore that key.
|
||||
|
||||
### `int HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname )`
|
||||
|
||||
Called before adding entity to the rendering list.
|
||||
|
||||
* `type` is set to an entity type, see `entity_state_t::entityType`
|
||||
* `ent` is a pointer to `cl_entity_t` object.
|
||||
* `modelname` is a null-terminated string with that entity model name.
|
||||
Return value: `0` if `client.dll` wants engine to not draw this entity.
|
||||
|
||||
### `void HUD_CreateEntities( void )`
|
||||
|
||||
Called each frame after all network entities (including players) are linked to let `client.dll` spawn client-side entities.
|
||||
|
||||
### `void HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *ent )`
|
||||
|
||||
Studio models have events tied to the frame, on which engine calls this function.
|
||||
|
||||
* `event` is a pointer to a studio event object
|
||||
* `ent` is a pointer to a client entity object
|
||||
|
||||
### `void HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client )`
|
||||
|
||||
When client processes entity updates, for local client it might be truncated, don't have enough precision, miss some critical info, so engine calls this function as `client.dll` might choose to use client data came from `svc_clientdata` message. Note that it is called on raw, non-interpolated networked entity state.
|
||||
|
||||
* `state` is a pointer to the local client entity state coming from the network
|
||||
* `client` is a pointer to local client data object
|
||||
|
||||
### `void HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src )`
|
||||
|
||||
When client processes entity updates, it calls this function for player entities as `client.dll` might want to override some data or fill the missing parts, but usually it just copies from `src` to `dst`.
|
||||
|
||||
* `src` is a target pointer to the player entity data (stored in frames, for example)
|
||||
* `dst` is a source pointer to the player entity data coming from network
|
||||
|
||||
### `void HUD_TxferPredictionData( struct entity_state_s *ps, const struct entity_state_s *pps, struct clientdata_s *pcd, const struct clientdata_s *ppcd, struct weapon_data_s *wd, const weapon_data_s *pwd )`
|
||||
|
||||
When client receives `svc_clientdata` message, this function is called before any parsing is done, so that the `client.dll` fills in data from prediction.
|
||||
|
||||
* `ps`, `pcd`, `wd` are pointers to current network frame data.
|
||||
* `pps`, `ppcd`, `pwd` are pointers to predicted frame data.
|
||||
|
||||
### `void HUD_TempEntUpdate( double frametime, double client_time, double cl_gravity, TEMPENTITY **ppTempEntFree, TEMPENTITY **ppTempEntActive, int ( *AddVisibleEntity )( cl_entity_t *pEntity ), void ( *TempEntPlaySound)( TEMPENTITY *pTemp, float damp ))`
|
||||
|
||||
Called each frame after network entities are processed and after `HUD_CreateEntities`, to let `client.dll` process temporary entities logic.
|
||||
|
||||
* `frametime` is the delta between `cl.time` and `cl.oldtime`, i.e. server time.
|
||||
* `client_time` is `cl.time`
|
||||
* `gravity` is the synchronized gravity value from the server
|
||||
* `ppTempEntFree` is a pointer to the head of linked list of free temp entities
|
||||
* `ppTempEntActive` is a pointer to the head of linked list of active temp entities
|
||||
* `AddVisibleEntity` is a pointer to function that lets `client.dll` add this entity to the rendering list.
|
||||
* `TempEntPlaySound` is a pointer to function that's called by `client.dll` when temp entity needs to play predefined hit sound. The `damp` argument of this argument only makes sound to NOT play, if it's zero or negative.
|
||||
|
||||
### `void HUD_DrawNormalTriangles( void )`
|
||||
|
||||
Called each rendering frame to let `client.dll` draw custom solid triangles through TriAPI or direct OpenGL calls.
|
||||
|
||||
### `void HUD_DrawTransparentTriangles( void )`
|
||||
|
||||
Called each rendering frame to let `client.dll` draw custom transparent triangles through TriAPI or direct OpenGL calls.
|
||||
|
||||
### `struct cl_entity_s *HUD_GetUserEntity( int index )`
|
||||
|
||||
Called by engine when beam start/end indices are negative, thus allowing attaching beams to a temporary or client-only entity.
|
||||
|
||||
* `index` is the fixed up entity index, as beam start/end indices encode real entity index in low 12 bits (i.e. `beament_start & 0xFFF`).
|
||||
|
||||
### `void Demo_ReadBuffer( int size, unsigned char *buffer )`
|
||||
|
||||
Called by engine on demo playback, if `client.dll` saved some custom data on demo recording prior.
|
||||
|
||||
* `size` is the size of buffer in bytes
|
||||
* `buffer` is the pointer to custom data stored by `client.dll` in demo
|
||||
|
||||
### `void CAM_Think( void )`
|
||||
|
||||
Called each frame before rendering starts to let `client.dll` run custom camera logic, like advanced thirdperson follow camera for example.
|
||||
|
||||
### `int CL_IsThirdPerson( void )`
|
||||
|
||||
Returns non-zero value if camera is in thirdperson mode, lets engine figure out whether add local client entity to the rendering list or not.
|
||||
|
||||
### `void CL_CameraOffset( vec3_t offset )`
|
||||
|
||||
Not used in the engine.
|
||||
|
||||
### `void CL_CreateMove( float frametime, usercmd_t *cmd, int active )`
|
||||
|
||||
Called when `usercmd_t` is being created to let `client.dll` record user commands before they are being sent over the network.
|
||||
|
||||
* `frametime` is the delta time between previous and current frames.
|
||||
* `cmd` is the pointer to `usercmd_t` object, where player's intentions and impulses are added.
|
||||
* `active` is set to `1` when client is finished signing on to the server (as movement commands are being sent even if client is not fully spawned yet).
|
||||
|
||||
### `void IN_ActivateMouse( void )`
|
||||
|
||||
Called from similarly named NQ/QW function.
|
||||
|
||||
### `void IN_DeactivateMouse( void )`
|
||||
|
||||
Called from similarly named NQ/QW function.
|
||||
|
||||
### `void IN_MouseEvent( int mstate )`
|
||||
|
||||
Called from similarly named NQ/QW function.
|
||||
|
||||
### `void IN_Accumulate( void )`
|
||||
|
||||
Called from similarly named NQ/QW function.
|
||||
|
||||
### `void IN_ClearStates( void )`
|
||||
|
||||
Called from similarly named NQ/QW function.
|
||||
|
||||
### `void V_CalcRefdef( struct ref_params_s *params )`
|
||||
|
||||
Called each frame before rendering starts. This is close to the similarly named function found in NQ/QW and lets `client.dll` to run custom view logic.
|
||||
|
||||
* `params` is the refdef parameters object. It is also used as return value and might request from the engine to not draw anything (by `onlyClientDraws` field) or to run this multiple times (by `nextview` field)
|
||||
|
||||
### `kbutton_t *KB_Find( const char *name )`
|
||||
|
||||
Called by engine to find extra keys and their state.
|
||||
|
||||
Only few are really used by the engine:
|
||||
* `in_mlook` for mouse look
|
||||
* `in_jlook` for joystick look
|
||||
* `in_graph` for net_graph toggle
|
||||
|
||||
Return value: returns pointer to `kbutton_t` if found. `kbutton_t` structure matches the same structure that can be found in NQ and QW.
|
||||
|
||||
### `void HUD_DirectorMessage( int size, void *buf )`
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This function is optional.
|
||||
|
||||
Called to notify `client.dll` about an `svc_director` message. This feature is used for HLTV, though mods use it to spawn text messages or execute commands (bypassing `svc_stufftext` filter in old `client.dll`) but `svc_director` message structure isn't enforced by engine, so it in theory mods might modify it for their own needs.
|
||||
|
||||
* `size` is the size of the payload
|
||||
* `buf` raw `svc_director` payload
|
||||
|
||||
### `void HUD_VoiceStatus( int entindex, qboolean talking )`
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This function is optional.
|
||||
|
||||
Called to notify `client.dll` about a client status of using voice chat.
|
||||
* `entindex` an entity index (client index plus one, because zero is always world). When set to -1, notifies `client.dll` about local client recording. When set to -2, notifies `client.dll` about a loopback (i.e. local client's voice message was sent to server and received back)
|
||||
* `talking` if true, this client is talking
|
||||
|
||||
### `void HUD_ChatInputPosition( int *x, int *y )`
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This function is optional.
|
||||
|
||||
When called, returns desired X and Y positions of chat box.
|
||||
9
Documentation/api/client/README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# What is client.dll in GoldSource?
|
||||
|
||||
One of technical differences a programmer working with Quake engine might notice is the client.dll file. Historically, it appeared somewhere in between Alpha 0.52 and NetTest1 development and judging by Half-Life SDK 1.0 was meant to handle HUD rendering. The time moved forward, SDK 2.0 finalized `client.dll` API at version 7, added an in-game UI, custom input processing, player movement and weapon prediction, very basic rendering through TriAPI. SDK 2.1 added ability to re-define studio model rendering, and so on.
|
||||
|
||||
It somewhat resembles `cgame` module from Quake 3, but more crudely designed and sometimes feels like an afterthought, considering how many engine internal structures it exposes and the main point of incompatibilities with mods, which these days sometimes use `client.dll` as a way to inject custom rendering into the game.
|
||||
|
||||
In this document I will try to go through each step, letting you, dear reader, implement your own GoldSrc compatible API in your Quake fork, targetting vanilla Half-Life `client.dll` from latest update, which at the time of writing, is 25-th anniversary update.
|
||||
|
||||
Despite that we call it `client.dll`, since SDK 2.4 (unofficial naming, it's the first SDK Valve published on GitHub) it is considered portable and only has SDL2 and VGUI libraries in it's external dependences. It's only called this way to avoid possible misunderstandings with engine developers, who might interpret client as `cl_` prefixed part of Quake engine.
|
||||
120
Documentation/api/client/xx-structs.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# `client.dll` shared structs and enums
|
||||
|
||||
GoldSource exposes a lot of structs to `client.dll`. Some of them are specific to `client.dll` and only used for passing data between engine and client, some of them are used in the engine everywhere, but still exposed in the public SDK. However, many mods rely on internal structs as well, and I will try to shed light on them as well.
|
||||
|
||||
When implementing them in C, consider the default to 32-bit systems alignment of 4 bytes and ILP32 data type model.
|
||||
|
||||
This file won't have API structs, for that, there should be separate chapters.
|
||||
|
||||
## Enums
|
||||
|
||||
### Entity types enum
|
||||
|
||||
This enum has no real name.
|
||||
|
||||
| Value | Description |
|
||||
|-------|-----------------|
|
||||
| `0` | Normal entities |
|
||||
| `1` | Players |
|
||||
| `2` | Temp entities |
|
||||
| `3` | Beams |
|
||||
| `4` | Fragmented entities. |
|
||||
|
||||
### edict->solid
|
||||
|
||||
It matches QuakeWorld definition.
|
||||
|
||||
## `client_data_t`
|
||||
|
||||
Used only to pass data to `client.dll` through `HUD_UpdateClientData`.
|
||||
|
||||
| Type | Name | Description |
|
||||
|----------|---------------|--------------------------------------------------------------|
|
||||
| `vec3_t` | `origin` | Local client origin. Cannot be changed by `client.dll` here. |
|
||||
| `vec3_t` | `viewangles` | Local client viewangles. This and next fields can be changed by `client.dll` |
|
||||
| `int` | `iWeaponBits` | Bit vector of weapons held by client. |
|
||||
| `float` | `fov` | Local client's field of view. |
|
||||
|
||||
## `netadr_t`
|
||||
|
||||
Matches Quake-2 structure with the similar name.
|
||||
|
||||
## `local_state_t`
|
||||
|
||||
Only consists of another structs. All of these structs are used to store prediction data, so one `local_state_t` for each predicted frame.
|
||||
|
||||
| Type | Name | Description |
|
||||
|---------------------|---------------|--------------------------------------|
|
||||
| `entity_state_t` | `playerstate` | Contains local player's entity state |
|
||||
| `clientdata_t` | `client` | Additional information about local client. _Do not get confused with `client_data_t`, note the underscore._ |
|
||||
| `weapon_data_t[64]` | `weapondata` | Array of 64 predictable weapons. |
|
||||
|
||||
## `entity_state_t`
|
||||
|
||||
This structure is similar to the one that can be found in QW, but contains much more data, though most of these fields are not used by the engine, but might be used by mods.
|
||||
|
||||
| Type | Name | Description |
|
||||
|-------------|----------------|------------------------------------------------------|
|
||||
| `int` | `entityType` | Entity type (see entity type enum above) |
|
||||
| `int` | `number` | Index of this entity on the server |
|
||||
| `float` | `msg_time` | Server time at which this entity had been updated |
|
||||
| `int` | `messagenum` | `parsecount` at which this entity had been updated |
|
||||
| `vec3_t` | `origin` | Non-interpolated entity position |
|
||||
| `vec3_t` | `angles` | Non-interpolated entity angles |
|
||||
| `int` | `modelindex` | Server model index |
|
||||
| `int` | `sequence` | Model animation sequence |
|
||||
| `int` | `frame` | Model animation frame |
|
||||
| `int` | `colormap` | Texture's top and bottom colors, like Quake |
|
||||
| `short` | `skin` | Texture number |
|
||||
| `short` | `solid` | `edict->solid` enum |
|
||||
| `int` | `effects` | Bitmask of entity effects |
|
||||
| `float` | `scale` | Entity scale value |
|
||||
| `byte` | `eflags` | |
|
||||
| `int` | `eflags` | |
|
||||
| `int` | `eflags` | |
|
||||
| `color24` | `eflags` | |
|
||||
| `int` | `eflags` | |
|
||||
| `int` | `eflags` | |
|
||||
| `float` | `eflags` | |
|
||||
| `float` | `eflags` | |
|
||||
| `int` | `eflags` | |
|
||||
| `byte[4]` | `eflags` | |
|
||||
| `byte[4]` | `eflags` | |
|
||||
| `vec3_t` | `eflags` | |
|
||||
| `vec3_t` | `eflags` | |
|
||||
| `vec3_t` | `eflags` | |
|
||||
| `vec3_t` | `maxs` | |
|
||||
| `int` | `eflags` | |
|
||||
| `int` | `eflags` | |
|
||||
| `float` | `eflags` | |
|
||||
| `float` | `eflags` | |
|
||||
| `int` | `eflags` | |
|
||||
| `int` | `eflags` | |
|
||||
| `int` | `eflags` | |
|
||||
| `qboolean` | `eflags` | |
|
||||
| `int` | `eflags` | |
|
||||
| `int` | `eflags` | |
|
||||
| `vec3_t` | `eflags` | |
|
||||
| `int` | `eflags` | |
|
||||
| `int` | `eflags` | |
|
||||
| `int` | `eflags` | |
|
||||
| `int` | `eflags` | |
|
||||
| `float` | `eflags` | |
|
||||
| `float` | `eflags` | |
|
||||
| `int` | `eflags` | |
|
||||
| `vec3_t` | `eflags` | |
|
||||
| `vec3_t` | `eflags` | |
|
||||
| `float` | `eflags` | |
|
||||
| `float` | `eflags` | |
|
||||
| `int` | `iuser1` | Few more extra fields for mods |
|
||||
| `int` | `iuser2` | |
|
||||
| `int` | `iuser3` | |
|
||||
| `int` | `iuser4` | |
|
||||
| `float` | `fuser1` | |
|
||||
| `float` | `fuser2` | |
|
||||
| `float` | `fuser3` | |
|
||||
| `float` | `fuser4` | |
|
||||
| `vec3_t` | `vuser1` | |
|
||||
| `vec3_t` | `vuser2` | |
|
||||
| `vec3_t` | `vuser3` | |
|
||||
| `vec3_t` | `vuser4` | |
|
||||
@@ -2,27 +2,23 @@
|
||||
|
||||
On this page you can find links where you can support each developer individually, who has provided public sponsorship information.
|
||||
|
||||
## [a1batross](https://github.com/a1batross)
|
||||
### [a1batross](https://github.com/a1batross)
|
||||
|
||||
Initial Xash3D SDL2/Linux port author, Xash3D FWGS engine maintainer, creator of non-commercial Flying With Gauss organization.
|
||||
* Initial Xash3D SDL2/Linux port author, Xash3D FWGS engine maintainer, creator of non-commercial Flying With Gauss organization.
|
||||
* Boosty page: https://boosty.to/a1ba
|
||||
|
||||
* [Boosty page](https://boosty.to/a1ba)
|
||||
### [nekonomicon](https://github.com/nekonomicon)
|
||||
|
||||
## [nekonomicon](https://github.com/nekonomicon)
|
||||
* [hlsdk-portable](https://github.com/FWGS/hlsdk-portable), [mdldec](../utils/mdldec), [opensource-mods.md](opensource-mods.md) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=nekonomicon) (*BSD/clang port, PNG support, etc).
|
||||
* Boosty page: https://boosty.to/nekonomicon
|
||||
|
||||
[hlsdk-portable](https://github.com/FWGS/hlsdk-portable), [mdldec](../utils/mdldec), [opensource-mods.md](opensource-mods.md) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=nekonomicon) (*BSD/clang port, PNG support, etc).
|
||||
### [Velaron](https://github.com/Velaron)
|
||||
* [cs16-client](https://github.com/Velaron/cs16-client) & [tf15-client](https://github.com/Velaron/tf15-client) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=Velaron) (Android port, voice chat, etc).
|
||||
* BuyMeACoffee page: https://www.buymeacoffee.com/velaron
|
||||
|
||||
* [Boosty page](https://boosty.to/nekonomicon)
|
||||
|
||||
## [Velaron](https://github.com/Velaron)
|
||||
|
||||
[cs16-client](https://github.com/Velaron/cs16-client) & [tf15-client](https://github.com/Velaron/tf15-client) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=Velaron) (Android port, voice chat, etc).
|
||||
|
||||
* [BuyMeACoffee page](https://www.buymeacoffee.com/velaron)
|
||||
|
||||
## [SNMetamorph](https://github.com/SNMetamorph)
|
||||
|
||||
[PrimeXT](https://github.com/SNMetamorph/PrimeXT) & [GoldSrc Monitor](https://github.com/SNMetamorph/goldsrc-monitor) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=SNMetamorph) (Windows port, voice chat, etc).
|
||||
|
||||
* [Boosty page](https://boosty.to/snmetamorph)
|
||||
* [Other donation methods](https://snmetamorph.github.io/donate)
|
||||
### [SNMetamorph](https://github.com/SNMetamorph)
|
||||
* [PrimeXT](https://github.com/SNMetamorph/PrimeXT) & [GoldSrc Monitor](https://github.com/SNMetamorph/goldsrc-monitor) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=SNMetamorph) (Windows port, voice chat, etc).
|
||||
* BTC: `16GAzK3qei5AwBW7sggXp3yNcFHBtdpxXj`
|
||||
* ETH (ERC20): `0xb580eeca9756e3881f9d6d026e28db28eb72a383`
|
||||
* USDT (ERC20): `0xb580eeca9756e3881f9d6d026e28db28eb72a383`
|
||||
* USDC (ERC20): `0xb580eeca9756e3881f9d6d026e28db28eb72a383`
|
||||
|
||||
@@ -6,7 +6,7 @@ For connecting to GoldSrc-based servers, use this command:
|
||||
connect ip:port gs
|
||||
```
|
||||
|
||||
But keep in mind, there are requirement for server to be able to accept connections from Xash3D-based clients: it should use Reunion.
|
||||
But keep in mind, there are requirement for server to be able to accept connections from Xash3D-based clients: it should use Reunion or Dproto.
|
||||
Without this requirement, you will just get "Steam validation rejected" error on connecting.
|
||||
|
||||
That is because proper authorization with Steam API is not implemented in engine yet (but we have plans on it).
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 82 KiB |
|
Before Width: | Height: | Size: 212 KiB |
|
Before Width: | Height: | Size: 400 KiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 1.1 MiB |
@@ -2,19 +2,10 @@
|
||||
|
||||
|Name |Version |Why not working |What was made for that
|
||||
|---- |------- |--------------- |----------------------
|
||||
|Area 51 |Update 1 |Uses outdated BSP31 map format and custom HLFX SDK libraries. |You can try [this tool](https://hlfx.ru/forum/showthread.php?threadid=5250) to convert maps but there no warranty if it works.
|
||||
|Arrange Mod: Rebirth |v150 |No idea yet. |
|
||||
|Blue Shift |The latest steam release |Uses vgui2 library which xash3d does not support. |Recreated source code here: https://github.com/FWGS/hlsdk-xash3d/tree/bshift.
|
||||
|Counter Strike |Beta 6.5- |Uses an old WON HL 1.0.0.16- interface. |
|
||||
| |1.4 |Has encrypted blob instead of normal client.dll. |You can try [this tool](https://aluigi.altervista.org/papers/hldlldec.zip) to decrypt client.dll but there no warranty if it works.
|
||||
| |1.5 |Has encrypted blob instead of normal client.dll. |Decrypted blob here: https://csm.dev/threads/cs-1-5-client-dll-decrypted-patched-for-usage.38845.
|
||||
| |1.6(The latest steam release) |Uses vgui2 library which xash3d does not support. |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface. Recreated Client Source Code here: https://github.com/Velaron/cs16-client.
|
||||
|Counter Strike: Condition Zero |The latest steam release |Uses vgui2 library which xash3d does not support. |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface. Recreated Client Source Code here: https://github.com/Velaron/cs16-client.
|
||||
|Counter Strike: Condition Zero - Deleted scenes |The latest steam release |Uses vgui2 library which xash3d does not support. Uses new sequences code on engine-side that was never used in any other mods before. |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface.
|
||||
|Day of Defeat |The latest steam release |Uses vgui2 library which xash3d does not support. |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface.
|
||||
|Half-Life: Extended |Day One demo |Uses many hooks to GoldSource engine and version check. |Just wait new version or use more old version.
|
||||
|Icon of Hell |Beta 0.99 |Uses outdated BSP31 map format and paranoia 2 libraries. |You can try [this tool](https://hlfx.ru/forum/showthread.php?threadid=5250) to convert maps and use Paranoia 2: The Savior 1.51 libraries but there no warranty if it works.
|
||||
|Paranoia 2: The Savior |All builds older 1.51 |Uses an old renderer interface and engine features. |
|
||||
|Rebellion |1.0 |Uses an old WON HL 1.0.0.16- interface. |Recreated source code here: https://github.com/FWGS/hlsdk-xash3d/tree/rebellion.
|
||||
|Sven-Coop |5.0+ |Uses custom GoldSrc engine. |
|
||||
|Time Shadows |Beta 0.1 |Uses Direct3D renderer. |
|
||||
|Blue Shift |The latest steam release |Uses vgui2 library which xash3d does not support |Recreated source code here: https://github.com/FWGS/hlsdk-xash3d/tree/bshift
|
||||
|Counter Strike |1.6(The latest steam release) |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|
||||
|Counter Strike: Condition Zero |The latest steam release |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|
||||
|Counter Strike: Condition Zero - Deleted scenes |The latest steam release |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|
||||
|Day of Defeat |The latest steam release |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|
||||
|Sven-Coop |5.0+ |Uses custom GoldSrc engine |
|
||||
|
||||
|
||||
@@ -32,18 +32,12 @@ Version 1.9 mirrored on github - https://github.com/solidi/hl-mods/tree/master/c
|
||||
## Cold Ice Ressurection
|
||||
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/cir
|
||||
|
||||
## Counter-Life
|
||||
Available on ModDB - https://www.moddb.com/mods/counter-life/downloads/cl-version-1-source-code
|
||||
|
||||
## Cthulhu
|
||||
Uploaded to github by Oleg Cherkasky - https://github.com/gunrunners-paradise/Cthulhu-HLmod-SDK
|
||||
|
||||
## Deathmatch Classic
|
||||
Available in Valve's Half-Life repository - https://github.com/ValveSoftware/halflife/tree/master/dmc
|
||||
|
||||
## Delta Particles
|
||||
Available on ModDB - https://www.moddb.com/mods/half-life-delta/downloads/delta-particles-full-sources-maps-and-c-code
|
||||
|
||||
## Earth Special Forces
|
||||
Alpha 2.0 - https://www.gamers-desire.de/details/2830
|
||||
|
||||
|
||||
@@ -2,14 +2,11 @@
|
||||
|
||||
### Prerequisites
|
||||
1. Make sure your PSVita is [set up to run homebrew applications](https://vita.hacks.guide/).
|
||||
2. Install [kubridge](https://github.com/TheOfficialFloW/kubridge/releases/). It is recommended to use kubridge version `0.1`, because other versions aren't tested, we don't know are they suitable or not.
|
||||
|
||||
Worth to notice, we got reports that automatic plugins management app EasyPlugin have issues with installing kubridge plugin, so it's better to install it manually: by copying `kubridge.suprx` to your taiHEN plugins folder (usually `ux0:/tai`, but could be `ur0:/tai`) and add it to your `config.txt`, for example:
|
||||
2. Install [kubridge](https://github.com/TheOfficialFloW/kubridge/releases/) by copying `kubridge.suprx` to your taiHEN plugins folder (usually `ux0:/tai`) and add it to your `config.txt`, for example:
|
||||
```
|
||||
*KERNEL
|
||||
ux0:tai/kubridge.skprx
|
||||
```
|
||||
|
||||
3. Install `libshacccg.suprx` by following [this guide](https://cimmerian.gitbook.io/vita-troubleshooting-guide/shader-compiler/extract-libshacccg.suprx).
|
||||
|
||||
### Installation
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
# Touch controls configuring
|
||||
|
||||
## Introduction
|
||||
|
||||
Thanks to mittorn, we have the ability to fully customize the controls in Xash3D. The new config allows you to not only add and change control buttons, but also create custom menus. There is also a built-in visual editor available, which simplifies the customization process without the need for manual file editing.
|
||||
|
||||
## Editor mode usage
|
||||
|
||||
1. Launch Xash3D and start the game.
|
||||
2. To enter the edit mode, click on the gear icon (command `touch_enableedit`).
|
||||
3. In the edit mode, the grid is displayed. The number of cells can be changed with the command `touch_grid_count` (default is 50). The grid can be disabled with the command `touch_grid_enable 0`.
|
||||
|
||||
*Touch controls layout editor*
|
||||

|
||||
|
||||
*Touch profiles window*
|
||||

|
||||
|
||||
*Touch buttons parameters window*
|
||||

|
||||
|
||||
## Layout editor features
|
||||
|
||||
* **Moving buttons**: click on a button, drag it to the desired location, and release.
|
||||
* **Resizing buttons**: place your first finger on the top left corner of the button, and use your second finger to resize it.
|
||||
* **Hiding/showing buttons**: select the button (it will turn red), then use the menu:
|
||||
* **Close**: closes the editing mode (`touch_disableedit`).
|
||||
* **Reset**: resets the button to its default values.
|
||||
* **Hide/Show**: hides or shows the button (`touch_hide <name>` / `touch_show <name>`).
|
||||
|
||||
## Working with configuration files / console
|
||||
|
||||
All changes made in the visual editor are automatically saved to the touch profile file. The files are located in the `touch_profiles` folder inside game directory. The file name depends on the selected profile.
|
||||
|
||||
### Common commands in configuration files
|
||||
|
||||
```
|
||||
// Comment: lines starting with // are ignored.
|
||||
|
||||
// Swipe zones for movement. Specify how far you need to swipe to speed up.
|
||||
// The default values are set to be optimal for a small swipe to immediately walk quickly.
|
||||
touch_forwardzone "0.060000" ; touch_sidezone "0.060000"
|
||||
|
||||
// Sensitivity settings (pitch - horizontal, yaw - vertical).
|
||||
touch_pitch ; touch_yaw
|
||||
|
||||
// Grid settings (see above).
|
||||
touch_grid_count ; touch_grid_enable
|
||||
|
||||
// Draws a border around the button.
|
||||
touch_set_stroke <thickness> <c> <v> <e> <t>
|
||||
(<r> - red; <g> - green; <b> - blue; <a> - alpha/transparency)
|
||||
|
||||
// Show (1) or hide (0) client buttons.
|
||||
touch_setclientonly
|
||||
|
||||
// Removes all buttons from the screen.
|
||||
touch_removeall
|
||||
|
||||
// Shows all available buttons in the configuration file.
|
||||
touch_list
|
||||
|
||||
// Saves the config after editing. You can specify a new file name.
|
||||
touch_config_file command.cfg
|
||||
```
|
||||
|
||||
*The full list of buttons in the standard `touch.cfg` file, displayed in the console when using `touch_list`.*
|
||||

|
||||
|
||||
|
||||
## Adding new buttons
|
||||
|
||||
To add a new button, use the console command:
|
||||
|
||||
```
|
||||
touch_addbutton "digits" "touch/key_1.png" "toggle_digits" 0.340000 0.782222 0.400000 0.888889 255 255 255 100 0
|
||||
```
|
||||
|
||||
### Parameters of `touch_addbutton` command
|
||||
|
||||
| Parameter | Description |
|
||||
| --- | --- |
|
||||
| `"digits"` | Unique name of the button. |
|
||||
| `"touch/key_1.png"` | Path to the icon file (`.png` format). If the icon is not needed, leave `""`. |
|
||||
| `"toggle_digits"` | Command to execute after clicking (for example, `"buy"` for purchase). |
|
||||
| `0.340000` | X coordinate of the upper-left corner of the button. |
|
||||
| `0.782222` | Y coordinate of the upper-left corner of the button. |
|
||||
| `0.400000` | X coordinate of the lower-right corner of the button. |
|
||||
| `0.888889` | Y coordinate of the lower-right corner of the button. |
|
||||
| `255 255 255` | Button color in RGB format. |
|
||||
| `100` | Button transparency (0 - fully transparent, 255 - fully opaque). |
|
||||
| `0` | Flags (see next section). |
|
||||
|
||||
## List of flags
|
||||
|
||||
Flags define the behavior of the button. Their values are powers of two:
|
||||
|
||||
| Flag | Value | Description |
|
||||
| --- | --- | --- |
|
||||
| `TOUCH_FL_HIDE` | 1 | Hides the button (not displayed in the game, but visible in the editor). |
|
||||
| `TOUCH_FL_NOEDIT` | 2 | Disables editing of the button in the editor. |
|
||||
| `TOUCH_FL_CLIENT` | 4 | The button is client-side (not saved in the main control file). |
|
||||
| `TOUCH_FL_MP` | 8 | The button is displayed only in multiplayer. |
|
||||
| `TOUCH_FL_SP` | 16 | The button is displayed only in singleplayer. |
|
||||
| `TOUCH_FL_DEF_SHOW` | 32 | The button is always displayed on startup. |
|
||||
| `TOUCH_FL_DEF_HIDE` | 64 | The button is always hidden on startup. |
|
||||
| `TOUCH_FL_DRAW_ADDITIVE` | 128 | The button colors are added together in blend mode. |
|
||||
| `TOUCH_FL_STROKE` | 256 | Enables outline stroke around the button. |
|
||||
|
||||
Flags can be combined by adding their values together. For example, `5 = 1 + 4` is the combination of `TOUCH_FL_HIDE` and `TOUCH_FL_CLIENT` flags, which is a hidden client button.
|
||||
|
||||
*In the image below, the `spray`, `scores`, `messagemode` buttons are displayed simultaneously with the flag 8 and `loadquick`, `savequick` with the flag 16, and each is displayed in the corresponding game mode.*
|
||||

|
||||
|
||||
## Useful commands
|
||||
|
||||
* `touch_hide <pattern>`: hides buttons by pattern.
|
||||
* `touch_setcommand`: changes the command bound to a button.
|
||||
* `touch_settexture`: quickly changes the button image.
|
||||
* `touch_setcolor`: sets the button color.
|
||||
* `touch_exportconfig`: exports the current configuration, including aspect ratio.
|
||||
|
||||
## Usage examples
|
||||
|
||||
* `touch_hide menu*` hides all buttons with names starting with `menu`.
|
||||
* `touch_setcolor "attack" 255 160 0 128` changes the color of the primary fire button from opaque white to translucent orange, similar to the color of the HUD in Half-Life.
|
||||
|
||||
*Result of executing this command*
|
||||

|
||||
|
||||
* Example of adding a new button with a custom icon (the `lastinv` command is used - quick change between weapons)
|
||||

|
||||
|
||||
*View of this button in layout editor*
|
||||

|
||||
|
||||
## Tips
|
||||
|
||||
* To prevent the `look` and `move` buttons from interfering with editing other elements, place them before the others in the configuration file.
|
||||
* And vice versa, to make a button appear on top of others, place it at the end of the configuration file.
|
||||
* You can assign commands to buttons that change other buttons, see the previous section "Usage examples".
|
||||
* After editing each parameter of each individual button in the Touch Buttons section, do not forget to press Save, otherwise the applied parameters will not be saved.
|
||||
* To create your own icon for the button, you can use any graphics editor (for Android, Photo Editor by iudesk is suitable). Saving conditions:
|
||||
* Image format - `.png` with transparency (e.g. alpha channel)
|
||||
* Aspect ratio / size - 1:1 / 256x256
|
||||
* Path to the icons location - `touch/gfx` inside game directory.
|
||||
|
||||
### Additional links
|
||||
* [Handy palette for selecting color in RGB format](https://www.rapidtables.com/web/color/RGB_Color.html)
|
||||
15
README.md
@@ -1,7 +1,6 @@
|
||||
# Xash3D FWGS Engine <img align="right" width="128" height="128" src="https://github.com/FWGS/xash3d-fwgs/raw/master/game_launch/icon-xash-material.png" alt="Xash3D FWGS icon" />
|
||||
[](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) \
|
||||
[](http://fwgsdiscord.mentality.rip/) [](https://t.me/flyingwithgauss) \
|
||||
[](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous)
|
||||
[](https://builds.sr.ht/~a1batross/xash3d-fwgs?) [](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) [](http://fwgsdiscord.mentality.rip/) \
|
||||
[](https://github.com/FWGS/xash3d-fwgs/releases/latest) [](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous)
|
||||
|
||||
Xash3D ([pronounced](https://ipa-reader.com/?text=ks%C9%91%CA%82) `[ksɑʂ]`) FWGS is a game engine, aimed to provide compatibility with Half-Life Engine and extend it, as well as to give game developers well known workflow.
|
||||
|
||||
@@ -44,7 +43,7 @@ For additional info, run Xash3D with `-help` command line key.
|
||||
## Build instructions
|
||||
We are using Waf build system. If you have some Waf-related questions, I recommend you to read [Waf Book](https://waf.io/book/).
|
||||
|
||||
**NOTE: NEVER USE GitHub's ZIP ARCHIVES. GitHub doesn't include external dependencies we're using!**
|
||||
NOTE: NEVER USE GitHub's ZIP ARCHIVES. GitHub doesn't include external dependencies we're using!
|
||||
|
||||
### Prerequisites
|
||||
If your CPU is x86 compatible and you're on Windows or Linux, we are building 32-bit code by default. This was done to maintain compatibility with Steam releases of Half-Life and based on it's engine games.
|
||||
@@ -66,21 +65,21 @@ This repository contains our fork of HLSDK and restored source code for Half-Lif
|
||||
* Only for 32-bit engine on 64-bit x86 operating system:
|
||||
* Enable i386 on your system: `$ sudo dpkg --add-architecture i386`.
|
||||
* Install `aptitude` ([why?](https://github.com/FWGS/xash3d-fwgs/issues/1828#issuecomment-2415131759)): `$ sudo apt update && sudo apt upgrade && sudo apt install aptitude`
|
||||
* Install development tools: `$ sudo aptitude --without-recommends install git build-essential gcc-multilib g++-multilib libsdl2-dev:i386 libfreetype-dev:i386 libopus-dev:i386 libbz2-dev:i386 libvorbis-dev:i386 libopusfile-dev:i386 libogg-dev:i386`.
|
||||
* Install development tools: `$ sudo aptitude --without-recommends install git build-essential gcc-multilib g++-multilib libsdl2-dev:i386 libfontconfig-dev:i386 libfreetype-dev:i386 libopus-dev:i386 libbz2-dev:i386`.
|
||||
* Set PKG_CONFIG_PATH environment variable to point at 32-bit libraries: `$ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig`.
|
||||
|
||||
* For 64-bit engine on 64-bit x86 and other non-x86 systems:
|
||||
* Install development tools: `$ sudo apt install git build-essential python libsdl2-dev libfreetype6-dev libopus-dev libbz2-dev libvorbis-dev libopusfile-dev libogg-dev`.
|
||||
* Install development tools: `$ sudo apt install git build-essential python libsdl2-dev libfontconfig-dev libfreetype6-dev libopus-dev libbz2-dev`.
|
||||
|
||||
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
|
||||
|
||||
##### RedHat/Fedora
|
||||
* Only for 32-bit engine on 64-bit x86 operating system:
|
||||
* Install development tools: `$ sudo dnf install git gcc gcc-c++ glibc-devel.i686 SDL2-devel.i686 opus-devel.i686 freetype-devel.i686 bzip2-devel.i686 libvorbis-devel.i686 opusfile-devel.i686 libogg-devel.i686`.
|
||||
* Install development tools: `$ sudo dnf install git gcc gcc-c++ glibc-devel.i686 SDL2-devel.i686 opus-devel.i686 fontconfig-devel.i686 freetype-devel.i686 bzip2-devel.i686`.
|
||||
* Set PKG_CONFIG_PATH environment variable to point at 32-bit libraries: `$ export PKG_CONFIG_PATH=/usr/lib/pkgconfig`.
|
||||
|
||||
* For 64-bit engine on 64-bit x86 and other non-x86 systems:
|
||||
* Install development tools: `$ sudo dnf install git gcc gcc-c++ SDL2-devel opus-devel freetype-devel bzip2-devel libvorbis-devel opusfile-devel libogg-devel`.
|
||||
* Install development tools: `$ sudo dnf install git gcc gcc-c++ SDL2-devel opus-devel fontconfig-devel freetype-devel bzip2-devel`.
|
||||
|
||||
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
|
||||
|
||||
|
||||
@@ -1,39 +1,49 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
|
||||
# Only used to build Android project
|
||||
|
||||
project(XASH_ANDROID)
|
||||
|
||||
# armeabi-v7a requires cpufeatures library
|
||||
if(ANDROID)
|
||||
include_directories(${ANDROID_NDK}/sources/android/cpufeatures)
|
||||
add_library(cpufeatures ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c)
|
||||
target_link_libraries(cpufeatures dl)
|
||||
endif()
|
||||
include(AndroidNdkModules)
|
||||
android_ndk_import_module_cpufeatures()
|
||||
|
||||
include(FindPython)
|
||||
find_package(PythonInterp 2.7 REQUIRED)
|
||||
|
||||
get_filename_component(C_COMPILER_ID ${CMAKE_C_COMPILER} NAME_WE)
|
||||
get_filename_component(CXX_COMPILER_ID ${CMAKE_CXX_COMPILER} NAME_WE)
|
||||
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||
set(BUILD_TYPE "debug")
|
||||
else()
|
||||
set(BUILD_TYPE "release")
|
||||
list(APPEND WAF_EXTRA_ARGS --enable-poly-opt --enable-lto --enable-limited-debuginfo)
|
||||
list(APPEND WAF_EXTRA_ARGS --enable-poly-opt --enable-lto)
|
||||
endif()
|
||||
|
||||
if(ANDROID_ABI STREQUAL "x86")
|
||||
# HACKHACK: I don't know why but engine gets built as 64-bit binary here
|
||||
list(APPEND WAF_EXTRA_ARGS -4)
|
||||
if(CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||
set(64BIT ON CACHE BOOL "" FORCE)
|
||||
list(APPEND WAF_EXTRA_ARGS -8) # only required for x86 when testing this cmakelist under linux
|
||||
endif()
|
||||
|
||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
|
||||
set(WAF_CC "${CMAKE_C_COMPILER} --target=${CMAKE_C_COMPILER_TARGET}")
|
||||
set(WAF_CXX "${CMAKE_CXX_COMPILER} --target=${CMAKE_CXX_COMPILER_TARGET}")
|
||||
|
||||
# not cleanest way to get upper directory
|
||||
set(ENGINE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../")
|
||||
|
||||
set(WAF_CC "${CMAKE_C_COMPILER} --target=${CMAKE_C_COMPILER_TARGET}")
|
||||
set(WAF_CXX "${CMAKE_CXX_COMPILER} --target=${CMAKE_CXX_COMPILER_TARGET}")
|
||||
set(WAF ${Python_EXECUTABLE} ${ENGINE_SOURCE_DIR}waf -t ${ENGINE_SOURCE_DIR} -o ${CMAKE_CURRENT_BINARY_DIR}/xash3d-fwgs)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E env
|
||||
CC=${WAF_CC} CXX=${WAF_CXX}
|
||||
AR=${CMAKE_AR} STRIP=${CMAKE_STRIP}
|
||||
${PYTHON_EXECUTABLE} waf configure -T ${BUILD_TYPE} ${WAF_EXTRA_ARGS} cmake
|
||||
--check-c-compiler=${C_COMPILER_ID} --check-cxx-compiler=${CXX_COMPILER_ID}
|
||||
-s "${ENGINE_SOURCE_DIR}/SDL" --skip-sdl2-sanity-check --enable-bundled-deps
|
||||
WORKING_DIRECTORY "${ENGINE_SOURCE_DIR}"
|
||||
)
|
||||
|
||||
add_subdirectory("${ENGINE_SOURCE_DIR}/3rdparty/hlsdk-portable" hlsdk-portable)
|
||||
|
||||
# try to build minimal SDL. Enable features as we're gonna use them
|
||||
set(SDL_RENDER OFF)
|
||||
@@ -46,50 +56,5 @@ set(SDL_VULKAN OFF)
|
||||
set(SDL_OFFSCREEN OFF)
|
||||
set(SDL_STATIC OFF)
|
||||
add_subdirectory("${ENGINE_SOURCE_DIR}/3rdparty/SDL" SDL)
|
||||
|
||||
include(ExternalProject)
|
||||
|
||||
# gradle passes backslashes to cmake, how does this even work for everybody else?
|
||||
string(REPLACE "\\" "/" CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
|
||||
|
||||
ExternalProject_Add(
|
||||
Xash3DFWGS
|
||||
SOURCE_DIR ${ENGINE_SOURCE_DIR}
|
||||
INSTALL_DIR ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
|
||||
BUILD_IN_SOURCE TRUE
|
||||
DEPENDS SDL2
|
||||
BUILD_ALWAYS TRUE
|
||||
LOG_CONFIGURE TRUE
|
||||
LOG_BUILD TRUE
|
||||
LOG_INSTALL TRUE
|
||||
LOG_OUTPUT_ON_FAILURE TRUE
|
||||
LOG_MERGED_STDOUTERR TRUE
|
||||
|
||||
# USES_TERMINAL_CONFIGURE TRUE
|
||||
# USES_TERMINAL_BUILD TRUE
|
||||
# USES_TERMINAL_INSTALL TRUE
|
||||
|
||||
# NOTE: setting up WAFLOCK is important to avoid possible race conditions
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env
|
||||
ANDROID_NDK=${ANDROID_NDK}
|
||||
BUILD_CMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
|
||||
WAFLOCK=.lock-waf_android_${ANDROID_ABI}_build
|
||||
${WAF} configure -T ${BUILD_TYPE} --android=${ANDROID_ABI},,${CMAKE_SYSTEM_VERSION}
|
||||
-s "${ENGINE_SOURCE_DIR}/3rdparty/SDL" --enable-bundled-deps ${WAF_EXTRA_ARGS}
|
||||
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} -E env
|
||||
WAFLOCK=.lock-waf_android_${ANDROID_ABI}_build
|
||||
${WAF} build -v
|
||||
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} -E env
|
||||
WAFLOCK=.lock-waf_android_${ANDROID_ABI}_build
|
||||
${WAF} install --destdir=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
|
||||
)
|
||||
|
||||
add_subdirectory("${ENGINE_SOURCE_DIR}/3rdparty/hlsdk-portable" hlsdk-portable)
|
||||
|
||||
# a1ba: without this, xash3d target will be ignored as nothing depends on it
|
||||
add_dependencies(client Xash3DFWGS)
|
||||
add_dependencies(server Xash3DFWGS)
|
||||
|
||||
|
||||
add_subdirectory("${ENGINE_SOURCE_DIR}/" xash3d-fwgs)
|
||||
add_subdirectory("${ENGINE_SOURCE_DIR}/3rdparty/mainui" mainui)
|
||||
|
||||
@@ -9,7 +9,7 @@ plugins {
|
||||
|
||||
android {
|
||||
namespace = "su.xash.engine"
|
||||
ndkVersion = "28.0.13004108"
|
||||
ndkVersion = "27.2.12479018"
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "su.xash"
|
||||
@@ -96,7 +96,6 @@ android {
|
||||
packaging {
|
||||
jniLibs {
|
||||
useLegacyPackaging = true
|
||||
keepDebugSymbols.add("**/*.so")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,7 +112,7 @@ dependencies {
|
||||
implementation("androidx.preference:preference-ktx:1.2.1")
|
||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
||||
implementation("androidx.work:work-runtime-ktx:2.9.0")
|
||||
// implementation "androidx.legacy:legacy-support-v4:1.0.0"
|
||||
// implementation "androidx.legacy:legacy-support-v4:1.0.0"
|
||||
|
||||
implementation("com.madgag.spongycastle:prov:1.58.0.0")
|
||||
implementation("in.dragonbra:javasteam:1.2.0")
|
||||
|
||||
@@ -2,7 +2,6 @@ package su.xash.engine.ui.library
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
@@ -11,7 +10,6 @@ import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
@@ -75,16 +73,11 @@ class LibraryFragment : Fragment(), MenuProvider {
|
||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||
when (menuItem.itemId) {
|
||||
R.id.action_browse -> {
|
||||
try {
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_VIEW).setDataAndType(
|
||||
null, "vnd.android.document/directory"
|
||||
)
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_VIEW).setDataAndType(
|
||||
null, "vnd.android.document/directory"
|
||||
)
|
||||
}
|
||||
catch(e: ActivityNotFoundException) {
|
||||
Toast.makeText(getActivity(), R.string.library_fragment_no_file_manager, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
R.id.action_install -> {
|
||||
@@ -98,4 +91,4 @@ class LibraryFragment : Fragment(), MenuProvider {
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,5 +33,4 @@
|
||||
<string name="preferences_client_package">Client package</string>
|
||||
<string name="preferences_server_package">Server package</string>
|
||||
<string name="preferences_use_icons">Use icons instead of backgrounds</string>
|
||||
<string name="library_fragment_no_file_manager">File manager is missing</string>
|
||||
</resources>
|
||||
</resources>
|
||||
@@ -20,7 +20,4 @@ kotlin.code.style=official
|
||||
# Enables namespacing of each library's R class so that its R class includes only the
|
||||
# resources declared in the library itself and none from the library's dependencies,
|
||||
# thereby reducing the size of the R class for that library
|
||||
android.nonTransitiveRClass=true
|
||||
|
||||
# Enable verbose output for CMake
|
||||
android.native.buildOutput=verbose
|
||||
android.nonTransitiveRClass=true
|
||||
@@ -140,13 +140,13 @@ Default build-depended cvar and constant values
|
||||
|
||||
// Platform overrides
|
||||
#if XASH_NSWITCH
|
||||
#define DEFAULT_TOUCH_ENABLE "1"
|
||||
#define DEFAULT_TOUCH_ENABLE "0"
|
||||
#define DEFAULT_M_IGNORE "1"
|
||||
#define DEFAULT_MODE_WIDTH 1280
|
||||
#define DEFAULT_MODE_HEIGHT 720
|
||||
#define DEFAULT_ALLOWCONSOLE 1
|
||||
#elif XASH_PSVITA
|
||||
#define DEFAULT_TOUCH_ENABLE "1"
|
||||
#define DEFAULT_TOUCH_ENABLE "0"
|
||||
#define DEFAULT_M_IGNORE "1"
|
||||
#define DEFAULT_MODE_WIDTH 960
|
||||
#define DEFAULT_MODE_HEIGHT 544
|
||||
@@ -158,7 +158,7 @@ Default build-depended cvar and constant values
|
||||
#define DEFAULT_M_IGNORE "1"
|
||||
#endif // !XASH_MOBILE_PLATFORM && !XASH_NSWITCH
|
||||
|
||||
#if (XASH_ANDROID && !XASH_TERMUX) || XASH_IOS || XASH_EMSCRIPTEN
|
||||
#if XASH_ANDROID || XASH_IOS || XASH_EMSCRIPTEN
|
||||
// this means that libraries are provided with engine, but not in game data
|
||||
// You need add library loading code to library.c when adding new platform
|
||||
#define XASH_INTERNAL_GAMELIBS
|
||||
|
||||
@@ -28,17 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#define PORT_ANY -1
|
||||
|
||||
typedef enum netadrtype_e
|
||||
{
|
||||
NA_UNDEFINED = 0,
|
||||
NA_LOOPBACK,
|
||||
NA_BROADCAST,
|
||||
NA_IP,
|
||||
NA_IPX,
|
||||
NA_BROADCAST_IPX,
|
||||
NA_IP6,
|
||||
NA_MULTICAST_IP6
|
||||
} netadrtype_t;
|
||||
typedef enum {NA_LOOPBACK = 1, NA_BROADCAST, NA_IP, NA_IPX, NA_BROADCAST_IPX, NA_IP6, NA_MULTICAST_IP6} netadrtype_t;
|
||||
|
||||
/*
|
||||
Original Quake-2 structure:
|
||||
@@ -56,60 +46,29 @@ typedef struct
|
||||
#pragma pack( push, 1 )
|
||||
typedef struct netadr_s
|
||||
{
|
||||
// the reason we do this evil thing, is that when this struct contains IPv6
|
||||
// address the `type` is 2-byte wide, but when it doesn't `type` must 4-byte
|
||||
// wide _and_ ip6_0 must be zeroed, to keep it binary compatible.
|
||||
#if XASH_LITTLE_ENDIAN
|
||||
uint16_t type;
|
||||
uint8_t ip6_0[2];
|
||||
#elif XASH_BIG_ENDIAN
|
||||
uint8_t ip6_0[2];
|
||||
uint16_t type;
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
|
||||
union
|
||||
{
|
||||
// IPv6 struct
|
||||
uint8_t ip6_1[14];
|
||||
struct
|
||||
{
|
||||
uint16_t type6;
|
||||
uint8_t ip6[16];
|
||||
};
|
||||
struct
|
||||
{
|
||||
uint32_t type; // must be netadrtype_t but will break with short enums
|
||||
union
|
||||
{
|
||||
uint8_t ip[4];
|
||||
uint32_t ip4; // for easier conversions
|
||||
uint8_t ip[4];
|
||||
uint32_t ip4; // for easier conversions
|
||||
};
|
||||
uint8_t ipx[10];
|
||||
};
|
||||
};
|
||||
uint16_t port;
|
||||
uint16_t port;
|
||||
} netadr_t;
|
||||
#pragma pack( pop )
|
||||
|
||||
static inline netadrtype_t NET_NetadrType( const netadr_t *a )
|
||||
{
|
||||
if( a->type == NA_IP6 || a->type == NA_MULTICAST_IP6 )
|
||||
return (netadrtype_t)a->type;
|
||||
|
||||
if( a->ip6_0[0] || a->ip6_0[1] )
|
||||
return NA_UNDEFINED;
|
||||
|
||||
return (netadrtype_t)a->type;
|
||||
}
|
||||
|
||||
static inline void NET_NetadrSetType( netadr_t *a, netadrtype_t type )
|
||||
{
|
||||
if( type == NA_IP6 || type == NA_MULTICAST_IP6 )
|
||||
{
|
||||
a->type = type;
|
||||
return;
|
||||
}
|
||||
|
||||
a->ip6_0[0] = a->ip6_0[1] = 0;
|
||||
a->type = type;
|
||||
}
|
||||
|
||||
STATIC_CHECK_SIZEOF( netadr_t, 20, 20 );
|
||||
|
||||
#endif // NET_ADR_H
|
||||
|
||||
@@ -86,4 +86,8 @@ GNU General Public License for more details.
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#if defined XASH_SDL && !defined REF_DLL
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#endif // PORT_H
|
||||
|
||||
@@ -13,44 +13,47 @@
|
||||
#endif // _WIN32
|
||||
|
||||
#include <sys/types.h> // off_t
|
||||
#ifdef STDINT_H
|
||||
#include STDINT_H
|
||||
#else // !STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif // !STDINT_H
|
||||
#include <assert.h>
|
||||
|
||||
typedef uint8_t byte;
|
||||
typedef float vec_t;
|
||||
typedef vec_t vec2_t[2];
|
||||
#ifndef vec3_t // SDK renames it to Vector
|
||||
typedef vec_t vec3_t[3];
|
||||
#endif
|
||||
typedef vec_t vec4_t[4];
|
||||
typedef vec_t quat_t[4];
|
||||
typedef byte rgba_t[4]; // unsigned byte colorpack
|
||||
typedef byte rgb_t[3]; // unsigned byte colorpack
|
||||
typedef vec_t matrix3x4[3][4];
|
||||
typedef vec_t matrix4x4[4][4];
|
||||
typedef uint32_t poolhandle_t;
|
||||
typedef unsigned char byte;
|
||||
typedef int sound_t;
|
||||
typedef float vec_t;
|
||||
typedef vec_t vec2_t[2];
|
||||
typedef vec_t vec3_t[3];
|
||||
typedef vec_t vec4_t[4];
|
||||
typedef vec_t quat_t[4];
|
||||
typedef byte rgba_t[4]; // unsigned byte colorpack
|
||||
typedef byte rgb_t[3]; // unsigned byte colorpack
|
||||
typedef vec_t matrix3x4[3][4];
|
||||
typedef vec_t matrix4x4[4][4];
|
||||
|
||||
typedef uint32_t poolhandle_t;
|
||||
|
||||
#undef true
|
||||
#undef false
|
||||
|
||||
// true and false are keywords in C++ and C23
|
||||
#if !__cplusplus && __STDC_VERSION__ < 202311L
|
||||
enum { false, true };
|
||||
#endif
|
||||
#ifndef __cplusplus
|
||||
typedef enum { false, true } qboolean;
|
||||
#else
|
||||
typedef int qboolean;
|
||||
#endif
|
||||
|
||||
#define MAX_STRING 256 // generic string
|
||||
#define MAX_VA_STRING 1024 // compatibility macro
|
||||
#define MAX_SYSPATH 1024 // system filepath
|
||||
#define MAX_MODS 512 // environment games that engine can keep visible
|
||||
typedef uint64_t longtime_t;
|
||||
|
||||
#define MAX_STRING 256 // generic string
|
||||
#define MAX_INFO_STRING 256 // infostrings are transmitted across network
|
||||
#define MAX_SERVERINFO_STRING 512 // server handles too many settings. expand to 1024?
|
||||
#define MAX_LOCALINFO_STRING 32768 // localinfo used on server and not sended to the clients
|
||||
#define MAX_SYSPATH 1024 // system filepath
|
||||
#define MAX_VA_STRING 1024 // string length returned by va()
|
||||
#define MAX_PRINT_MSG 8192 // how many symbols can handle single call of Con_Printf or Con_DPrintf
|
||||
#define MAX_TOKEN 2048 // parse token length
|
||||
#define MAX_MODS 512 // environment games that engine can keep visible
|
||||
#define MAX_USERMSG_LENGTH 2048 // don't modify it's relies on a client-side definitions
|
||||
|
||||
#define BIT( n ) ( 1U << ( n ))
|
||||
#define BIT64( n ) ( 1ULL << ( n ))
|
||||
|
||||
#define SetBits( iBitVector, bits ) ((iBitVector) = (iBitVector) | (bits))
|
||||
#define ClearBits( iBitVector, bits ) ((iBitVector) = (iBitVector) & ~(bits))
|
||||
#define FBitSet( iBitVector, bit ) ((iBitVector) & (bit))
|
||||
@@ -67,8 +70,6 @@ typedef int qboolean;
|
||||
#define IsColorString( p ) ( p && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' )
|
||||
#define ColorIndex( c ) ((( c ) - '0' ) & 7 )
|
||||
|
||||
#undef EXPORT
|
||||
|
||||
#if defined( __GNUC__ )
|
||||
#if defined( __i386__ )
|
||||
#define EXPORT __attribute__(( visibility( "default" ), force_align_arg_pointer ))
|
||||
@@ -91,10 +92,8 @@ typedef int qboolean;
|
||||
#define NORETURN __attribute__(( noreturn ))
|
||||
#define NONNULL __attribute__(( nonnull ))
|
||||
#define RETURNS_NONNULL __attribute__(( returns_nonnull ))
|
||||
#if __clang__ || __MCST__
|
||||
// clang has bugged returns_nonnull for functions pointers, it's ignored and generates a warning about objective-c? O_o
|
||||
// lcc doesn't support it at all
|
||||
#define PFN_RETURNS_NONNULL
|
||||
#if __clang__
|
||||
#define PFN_RETURNS_NONNULL // clang has bugged returns_nonnull for functions pointers, it's ignored and generates a warning about objective-c? O_o
|
||||
#else
|
||||
#define PFN_RETURNS_NONNULL RETURNS_NONNULL
|
||||
#endif
|
||||
@@ -210,16 +209,35 @@ _inline float LittleFloat( float f )
|
||||
#endif
|
||||
|
||||
|
||||
typedef unsigned int dword;
|
||||
typedef unsigned int uint;
|
||||
typedef char string[MAX_STRING];
|
||||
typedef off_t fs_offset_t;
|
||||
typedef unsigned int dword;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
typedef char string[MAX_STRING];
|
||||
typedef struct file_s file_t; // normal file
|
||||
typedef struct stream_s stream_t; // sound stream for background music playing
|
||||
typedef off_t fs_offset_t;
|
||||
#if XASH_WIN32
|
||||
typedef int fs_size_t; // return type of _read, _write funcs
|
||||
typedef int fs_size_t; // return type of _read, _write funcs
|
||||
#else /* !XASH_WIN32 */
|
||||
typedef ssize_t fs_size_t;
|
||||
typedef ssize_t fs_size_t;
|
||||
#endif /* !XASH_WIN32 */
|
||||
|
||||
typedef struct dllfunc_s
|
||||
{
|
||||
const char *name;
|
||||
void **func;
|
||||
} dllfunc_t;
|
||||
|
||||
typedef struct dll_info_s
|
||||
{
|
||||
const char *name; // name of library
|
||||
const dllfunc_t *fcts; // list of dll exports
|
||||
const size_t num_fcts;
|
||||
qboolean crash; // crash if dll not found
|
||||
void *link; // hinstance of loading library
|
||||
} dll_info_t;
|
||||
|
||||
typedef void (*setpair_t)( const char *key, const void *value, const void *buffer, void *numpairs );
|
||||
typedef void *(*pfnCreateInterface_t)( const char *, int * );
|
||||
|
||||
// config strings are a general means of communication from
|
||||
|
||||
@@ -152,6 +152,19 @@ void CL_PlayCDTrack_f( void )
|
||||
else Con_Printf( "%s: unknown command %s\n", Cmd_Argv( 0 ), command );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ScreenshotGetName
|
||||
==================
|
||||
*/
|
||||
static qboolean CL_ScreenshotGetName( const char *fmt, int lastnum, char *filename, size_t size )
|
||||
{
|
||||
if( lastnum < 0 || lastnum > 9999 )
|
||||
return false;
|
||||
|
||||
return Q_snprintf( filename, size, fmt, clgame.mapname, lastnum ) > 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
@@ -257,6 +270,7 @@ void CL_GenericShot_f( void )
|
||||
case scrshot_normal:
|
||||
case scrshot_snapshot:
|
||||
{
|
||||
const char *fmt;
|
||||
string checkname;
|
||||
int i;
|
||||
|
||||
@@ -268,18 +282,15 @@ void CL_GenericShot_f( void )
|
||||
}
|
||||
|
||||
if( type == scrshot_snapshot )
|
||||
{
|
||||
fmt = "../%s_%04d.png";
|
||||
FS_AllowDirectPaths( true );
|
||||
}
|
||||
else fmt = "scrshots/%s_shot%04d.png";
|
||||
|
||||
for( i = 0; i < 9999; i++ )
|
||||
{
|
||||
int ret;
|
||||
|
||||
if( type == scrshot_snapshot )
|
||||
ret = Q_snprintf( checkname, sizeof( checkname ), "../%s_%04d.png", clgame.mapname, i );
|
||||
else
|
||||
ret = Q_snprintf( checkname, sizeof( checkname ), "scrshots/%s_shot%04d.png", clgame.mapname, i );
|
||||
|
||||
if( ret <= 0 )
|
||||
if( !CL_ScreenshotGetName( fmt, i, checkname, sizeof( checkname )))
|
||||
{
|
||||
Con_Printf( S_ERROR "unable to write %s\n", argv0 );
|
||||
FS_AllowDirectPaths( false );
|
||||
|
||||
@@ -198,44 +198,3 @@ void CL_WriteMessageHistory( void )
|
||||
CL_WriteErrorMessage( old->starting_offset, msg );
|
||||
cls_message_debug.parsing = false;
|
||||
}
|
||||
|
||||
void CL_ReplayBufferDat_f( void )
|
||||
{
|
||||
file_t *f = FS_Open( Cmd_Argv( 1 ), "rb", true );
|
||||
sizebuf_t msg;
|
||||
char buffer[NET_MAX_MESSAGE];
|
||||
int starting_count, current_count, protocol;
|
||||
fs_offset_t len;
|
||||
|
||||
if( !f )
|
||||
return;
|
||||
|
||||
FS_Read( f, &starting_count, sizeof( starting_count ));
|
||||
FS_Read( f, ¤t_count, sizeof( current_count ));
|
||||
FS_Read( f, &protocol, sizeof( protocol ));
|
||||
|
||||
cls.legacymode = protocol;
|
||||
|
||||
len = FS_Read( f, buffer, sizeof( buffer ));
|
||||
FS_Close( f );
|
||||
|
||||
MSG_Init( &msg, __func__, buffer, len );
|
||||
|
||||
Delta_Shutdown();
|
||||
Delta_Init();
|
||||
|
||||
clgame.maxEntities = MAX_EDICTS;
|
||||
clgame.entities = Mem_Calloc( clgame.mempool, sizeof( *clgame.entities ) * clgame.maxEntities );
|
||||
|
||||
// ad-hoc implement
|
||||
#if 0
|
||||
{
|
||||
const int message_pos = 12; // put real number here
|
||||
MSG_SeekToBit( &msg, ( message_pos - 12 + 1 ) << 3, SEEK_SET );
|
||||
|
||||
CL_ParseYourMom( &msg, protocol );
|
||||
}
|
||||
#endif
|
||||
|
||||
Sys_Quit( __func__ );
|
||||
}
|
||||
|
||||
@@ -373,7 +373,7 @@ CL_WriteDemoUserMessage
|
||||
Dumps the user message (demoaction)
|
||||
====================
|
||||
*/
|
||||
void GAME_EXPORT CL_WriteDemoUserMessage( int size, byte *buffer )
|
||||
void CL_WriteDemoUserMessage( const byte *buffer, size_t size )
|
||||
{
|
||||
if( !cls.demorecording || cls.demowaiting )
|
||||
return;
|
||||
@@ -642,7 +642,9 @@ static void CL_ReadDemoUserCmd( qboolean discard )
|
||||
pcmd->sendsize = 1;
|
||||
|
||||
// always delta'ing from null
|
||||
MSG_ReadDeltaUsercmd( &buf, &nullcmd, &pcmd->cmd );
|
||||
cl.cmd = &pcmd->cmd;
|
||||
|
||||
MSG_ReadDeltaUsercmd( &buf, &nullcmd, cl.cmd );
|
||||
|
||||
// make sure what interp info contain angles from different frames
|
||||
// or lerping will stop working
|
||||
@@ -654,16 +656,13 @@ static void CL_ReadDemoUserCmd( qboolean discard )
|
||||
|
||||
// record update
|
||||
a->starttime = demo.timestamp;
|
||||
VectorCopy( pcmd->cmd.viewangles, a->viewangles );
|
||||
VectorCopy( cl.cmd->viewangles, a->viewangles );
|
||||
demo.lasttime = demo.timestamp;
|
||||
}
|
||||
|
||||
// NOTE: we need to have the current outgoing sequence correct
|
||||
// so we can do prediction correctly during playback
|
||||
cls.netchan.outgoing_sequence = outgoing_sequence;
|
||||
|
||||
// save last usercmd
|
||||
cl.cmd = pcmd->cmd;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1146,7 +1145,8 @@ void CL_DemoInterpolateAngles( void )
|
||||
QuaternionSlerp( q2, q1, frac, q );
|
||||
QuaternionAngle( q, cl.viewangles );
|
||||
}
|
||||
else VectorCopy( cl.cmd.viewangles, cl.viewangles );
|
||||
else if( cl.cmd != NULL )
|
||||
VectorCopy( cl.cmd->viewangles, cl.viewangles );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -2229,3 +2229,4 @@ void CL_ThinkParticle( double frametime, particle_t *p )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -405,11 +405,7 @@ void CL_ParseReliableEvent( sizebuf_t *msg, connprotocol_t proto )
|
||||
}
|
||||
|
||||
if( args.entindex > 0 && args.entindex <= cl.maxclients )
|
||||
{
|
||||
args.angles[PITCH] *= 3.0f;
|
||||
if( !FBitSet( host.features, ENGINE_COMPENSATE_QUAKE_BUG ))
|
||||
args.angles[PITCH] = -args.angles[PITCH];
|
||||
}
|
||||
args.angles[PITCH] *= -3.0f;
|
||||
|
||||
CL_QueueEvent( FEV_RELIABLE|FEV_SERVER, event_index, delay, &args );
|
||||
}
|
||||
@@ -481,9 +477,7 @@ void CL_ParseEvent( sizebuf_t *msg, connprotocol_t proto )
|
||||
|
||||
if( state->number > 0 && state->number <= cl.maxclients )
|
||||
{
|
||||
args.angles[PITCH] *= 3.0f;
|
||||
if( !FBitSet( host.features, ENGINE_COMPENSATE_QUAKE_BUG ))
|
||||
args.angles[PITCH] = -args.angles[PITCH];
|
||||
args.angles[PITCH] *= -3.0f;
|
||||
CL_CalcPlayerVelocity( state->number, args.velocity );
|
||||
args.ducking = ( state->usehull == 1 );
|
||||
}
|
||||
@@ -493,11 +487,7 @@ void CL_ParseEvent( sizebuf_t *msg, connprotocol_t proto )
|
||||
if( args.entindex != 0 )
|
||||
{
|
||||
if( args.entindex > 0 && args.entindex <= cl.maxclients )
|
||||
{
|
||||
args.angles[PITCH] /= 3.0f;
|
||||
if( !FBitSet( host.features, ENGINE_COMPENSATE_QUAKE_BUG ))
|
||||
args.angles[PITCH] = -args.angles[PITCH];
|
||||
}
|
||||
args.angles[PITCH] /= -3.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ static int CL_CalcTabStop( const cl_font_t *font, int x )
|
||||
return stop;
|
||||
}
|
||||
|
||||
int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_t *font, int flags )
|
||||
int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *font, int flags )
|
||||
{
|
||||
wrect_t *rc;
|
||||
float w, h;
|
||||
@@ -231,7 +231,7 @@ int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_
|
||||
return font->charWidths[number];
|
||||
}
|
||||
|
||||
int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_t *font, int flags )
|
||||
int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *font, int flags )
|
||||
{
|
||||
rgba_t current_color;
|
||||
int draw_len = 0;
|
||||
@@ -287,7 +287,7 @@ int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_
|
||||
return draw_len;
|
||||
}
|
||||
|
||||
int CL_DrawStringf( cl_font_t *font, float x, float y, const rgba_t color, int flags, const char *fmt, ... )
|
||||
int CL_DrawStringf( cl_font_t *font, float x, float y, rgba_t color, int flags, const char *fmt, ... )
|
||||
{
|
||||
va_list va;
|
||||
char buf[MAX_VA_STRING];
|
||||
|
||||
@@ -13,12 +13,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#if XASH_SDL == 2
|
||||
#include <SDL.h> // SDL_GetWindowPosition
|
||||
#elif XASH_SDL == 3
|
||||
#include <SDL3/SDL.h> // SDL_GetWindowPosition
|
||||
#endif // XASH_SDL
|
||||
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "const.h"
|
||||
@@ -312,22 +306,21 @@ void SPR_AdjustSize( float *x, float *y, float *w, float *h )
|
||||
|
||||
static void SPR_AdjustTexCoords( int texnum, float width, float height, float *s1, float *t1, float *s2, float *t2 )
|
||||
{
|
||||
const qboolean filtering = REF_GET_PARM( PARM_TEX_FILTERING, texnum );
|
||||
const int xremainder = refState.width % clgame.scrInfo.iWidth;
|
||||
const int yremainder = refState.height % clgame.scrInfo.iHeight;
|
||||
|
||||
if(( filtering || xremainder ) && refState.width != clgame.scrInfo.iWidth )
|
||||
if( REF_GET_PARM( PARM_TEX_FILTERING, texnum ))
|
||||
{
|
||||
// align to texel if scaling
|
||||
*s1 += 0.5f;
|
||||
*s2 -= 0.5f;
|
||||
}
|
||||
if( refState.width != clgame.scrInfo.iWidth )
|
||||
{
|
||||
// align to texel if scaling
|
||||
*s1 += 0.5f;
|
||||
*s2 -= 0.5f;
|
||||
}
|
||||
|
||||
if(( filtering || yremainder ) && refState.height != clgame.scrInfo.iHeight )
|
||||
{
|
||||
// align to texel if scaling
|
||||
*t1 += 0.5f;
|
||||
*t2 -= 0.5f;
|
||||
if( refState.height != clgame.scrInfo.iHeight )
|
||||
{
|
||||
// align to texel if scaling
|
||||
*t1 += 0.5f;
|
||||
*t2 -= 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
*s1 /= width;
|
||||
@@ -563,7 +556,7 @@ static void CL_InitTitles( const char *filename )
|
||||
|
||||
Q_snprintf( name, sizeof( name ), TEXT_MSGNAME, i );
|
||||
|
||||
cl_textmessage[i].pName = copystringpool( clgame.mempool, name );
|
||||
cl_textmessage[i].pName = _copystring( clgame.mempool, name, __FILE__, __LINE__ );
|
||||
cl_textmessage[i].pMessage = cl_textbuffer[i];
|
||||
}
|
||||
|
||||
@@ -1690,7 +1683,7 @@ get actual screen info
|
||||
*/
|
||||
int GAME_EXPORT CL_GetScreenInfo( SCREENINFO *pscrinfo )
|
||||
{
|
||||
qboolean apply_scale_factor = false; // we don't want floating point inaccuracies
|
||||
qboolean apply_scale_factor = false;
|
||||
float scale_factor = hud_scale.value;
|
||||
|
||||
if( FBitSet( hud_fontscale.flags, FCVAR_CHANGED ))
|
||||
@@ -1705,12 +1698,7 @@ int GAME_EXPORT CL_GetScreenInfo( SCREENINFO *pscrinfo )
|
||||
clgame.scrInfo.iSize = sizeof( clgame.scrInfo );
|
||||
clgame.scrInfo.iFlags = SCRINFO_SCREENFLASH;
|
||||
|
||||
if( hud_scale.value >= 320.0f && hud_scale.value >= hud_scale_minimal_width.value )
|
||||
{
|
||||
scale_factor = refState.width / hud_scale.value;
|
||||
apply_scale_factor = scale_factor > 1.0f;
|
||||
}
|
||||
else if( scale_factor && scale_factor != 1.0f )
|
||||
if( scale_factor && scale_factor != 1.0f )
|
||||
{
|
||||
float scaled_width = (float)refState.width / scale_factor;
|
||||
if( scaled_width >= hud_scale_minimal_width.value )
|
||||
@@ -2085,7 +2073,6 @@ GetWindowCenterX
|
||||
static int GAME_EXPORT pfnGetWindowCenterX( void )
|
||||
{
|
||||
int x = 0;
|
||||
|
||||
#if XASH_WIN32
|
||||
if( m_ignore.value )
|
||||
{
|
||||
@@ -2095,7 +2082,7 @@ static int GAME_EXPORT pfnGetWindowCenterX( void )
|
||||
}
|
||||
#endif
|
||||
|
||||
#if XASH_SDL >= 2
|
||||
#if XASH_SDL == 2
|
||||
SDL_GetWindowPosition( host.hWnd, &x, NULL );
|
||||
#endif
|
||||
|
||||
@@ -2111,7 +2098,6 @@ GetWindowCenterY
|
||||
static int GAME_EXPORT pfnGetWindowCenterY( void )
|
||||
{
|
||||
int y = 0;
|
||||
|
||||
#if XASH_WIN32
|
||||
if( m_ignore.value )
|
||||
{
|
||||
@@ -2121,7 +2107,7 @@ static int GAME_EXPORT pfnGetWindowCenterY( void )
|
||||
}
|
||||
#endif
|
||||
|
||||
#if XASH_SDL >= 2
|
||||
#if XASH_SDL == 2
|
||||
SDL_GetWindowPosition( host.hWnd, NULL, &y );
|
||||
#endif
|
||||
|
||||
@@ -3362,6 +3348,28 @@ DemoApi implementation
|
||||
|
||||
=================
|
||||
*/
|
||||
/*
|
||||
=================
|
||||
Demo_IsRecording
|
||||
|
||||
=================
|
||||
*/
|
||||
static int GAME_EXPORT Demo_IsRecording( void )
|
||||
{
|
||||
return cls.demorecording;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Demo_IsPlayingback
|
||||
|
||||
=================
|
||||
*/
|
||||
static int GAME_EXPORT Demo_IsPlayingback( void )
|
||||
{
|
||||
return cls.demoplayback;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Demo_IsTimeDemo
|
||||
@@ -3373,6 +3381,17 @@ static int GAME_EXPORT Demo_IsTimeDemo( void )
|
||||
return cls.timedemo;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Demo_WriteBuffer
|
||||
|
||||
=================
|
||||
*/
|
||||
static void GAME_EXPORT Demo_WriteBuffer( int size, byte *buffer )
|
||||
{
|
||||
CL_WriteDemoUserMessage( buffer, size );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
NetworkApi implementation
|
||||
@@ -3414,7 +3433,7 @@ static void GAME_EXPORT NetAPI_Status( net_status_t *status )
|
||||
status->latency = (connected) ? cl.frames[cl.parsecountmod].latency : 0.0;
|
||||
status->remote_address = cls.netchan.remote_address;
|
||||
status->packet_loss = packet_loss;
|
||||
NET_GetLocalAddress( &status->local_address, NULL ); // NetAPI doesn't know about IPv6
|
||||
status->local_address = net_local;
|
||||
status->rate = rate.value;
|
||||
}
|
||||
|
||||
@@ -3435,7 +3454,7 @@ static void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags,
|
||||
return;
|
||||
}
|
||||
|
||||
if( NET_NetadrType( remote_address ) == NA_IPX || NET_NetadrType( remote_address ) == NA_BROADCAST_IPX )
|
||||
if( remote_address->type == NA_IPX || remote_address->type == NA_BROADCAST_IPX )
|
||||
return; // IPX no longer support
|
||||
|
||||
if( request == NETAPI_REQUEST_SERVERLIST )
|
||||
@@ -3558,6 +3577,28 @@ static int GAME_EXPORT NetAPI_CompareAdr( netadr_t *a, netadr_t *b )
|
||||
return NET_CompareAdr( *a, *b );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
NetAPI_StringToAdr
|
||||
|
||||
=================
|
||||
*/
|
||||
static int GAME_EXPORT NetAPI_StringToAdr( char *s, netadr_t *a )
|
||||
{
|
||||
return NET_StringToAdr( s, a );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
NetAPI_ValueForKey
|
||||
|
||||
=================
|
||||
*/
|
||||
static const char * GAME_EXPORT NetAPI_ValueForKey( const char *s, const char *key )
|
||||
{
|
||||
return Info_ValueForKey( s, key );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
NetAPI_RemoveKey
|
||||
@@ -3754,10 +3795,10 @@ static event_api_t gEventApi =
|
||||
|
||||
static demo_api_t gDemoApi =
|
||||
{
|
||||
(void *)CL_IsRecordDemo,
|
||||
(void *)CL_IsPlaybackDemo,
|
||||
Demo_IsRecording,
|
||||
Demo_IsPlayingback,
|
||||
Demo_IsTimeDemo,
|
||||
CL_WriteDemoUserMessage,
|
||||
Demo_WriteBuffer,
|
||||
};
|
||||
|
||||
net_api_t gNetApi =
|
||||
@@ -3769,8 +3810,8 @@ net_api_t gNetApi =
|
||||
NetAPI_CancelAllRequests,
|
||||
NetAPI_AdrToString,
|
||||
NetAPI_CompareAdr,
|
||||
(void *)NET_StringToAdr,
|
||||
Info_ValueForKey,
|
||||
NetAPI_StringToAdr,
|
||||
NetAPI_ValueForKey,
|
||||
NetAPI_RemoveKey,
|
||||
NetAPI_SetValueForKey,
|
||||
};
|
||||
|
||||
@@ -1273,16 +1273,16 @@ static void pfnEnableTextInput( int enable )
|
||||
Key_EnableTextInput( enable, false );
|
||||
}
|
||||
|
||||
static int pfnGetRenderers( unsigned int num, char *short_name, size_t size1, char *long_name, size_t size2 )
|
||||
static int pfnGetRenderers( unsigned int num, char *shortName, size_t size1, char *readableName, size_t size2 )
|
||||
{
|
||||
if( num >= ref.num_renderers )
|
||||
if( num >= ref.numRenderers )
|
||||
return 0;
|
||||
|
||||
if( short_name && size1 )
|
||||
Q_strncpy( short_name, ref.short_names[num], size1 );
|
||||
if( shortName && size1 )
|
||||
Q_strncpy( shortName, ref.shortNames[num], size1 );
|
||||
|
||||
if( long_name && size2 )
|
||||
Q_strncpy( long_name, ref.long_names[num], size2 );
|
||||
if( readableName && size2 )
|
||||
Q_strncpy( readableName, ref.readableNames[num], size2 );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -68,15 +68,14 @@ CVAR_DEFINE_AUTO( hud_scale_minimal_width, "640", FCVAR_ARCHIVE|FCVAR_LATCH, "if
|
||||
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, "30", FCVAR_ARCHIVE, "Max number of command packets sent to server per second" );
|
||||
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", 0, "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, "508", FCVAR_ARCHIVE, "max allowed incoming 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_consistency, "0", FCVAR_ARCHIVE, "enable consistency info tracing (good for developers)" );
|
||||
CVAR_DEFINE_AUTO( cl_trace_stufftext, "0", FCVAR_ARCHIVE, "enable stufftext (server-to-client console commands) tracing (good for developers)" );
|
||||
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)" );
|
||||
@@ -94,10 +93,11 @@ static CVAR_DEFINE_AUTO( name, username, FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_PRIN
|
||||
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, "25000", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player network rate" );
|
||||
CVAR_DEFINE_AUTO( rate, "3500", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player network rate" );
|
||||
|
||||
static CVAR_DEFINE_AUTO( cl_ticket_generator, "revemu2013", FCVAR_ARCHIVE, "you wouldn't steal a car" );
|
||||
|
||||
|
||||
client_t cl;
|
||||
client_static_t cls;
|
||||
clgame_static_t clgame;
|
||||
@@ -673,7 +673,7 @@ static void CL_CreateCmd( void )
|
||||
}
|
||||
|
||||
// demo always have commands so don't overwrite them
|
||||
if( !cls.demoplayback ) cl.cmd = pcmd->cmd;
|
||||
if( !cls.demoplayback ) cl.cmd = &pcmd->cmd;
|
||||
|
||||
// predict all unacknowledged movements
|
||||
CL_PredictMovement( false );
|
||||
@@ -717,20 +717,11 @@ static void CL_WritePacket( void )
|
||||
int numbackup, maxbackup, maxcmds;
|
||||
const connprotocol_t proto = cls.legacymode;
|
||||
|
||||
// FIXME: on Xash protocol we don't send move commands until ca_active
|
||||
// to prevent outgoing_command outrun incoming_acknowledged
|
||||
// which is fatal for some buggy mods like TFC
|
||||
//
|
||||
// ... but GoldSrc don't have (real) ca_validate state, so we consider
|
||||
// ca_validate the same as ca_active, otherwise we don't pass validation
|
||||
// of server-side mods like ReAuthCheck
|
||||
const connstate_t min_state = proto == PROTO_GOLDSRC ? ca_validate : ca_active;
|
||||
|
||||
// don't send anything if playing back a demo
|
||||
if( cls.demoplayback || cls.state < ca_connected || cls.state == ca_cinematic )
|
||||
return;
|
||||
|
||||
if( cls.state < min_state )
|
||||
if( cls.state <= ca_connected )
|
||||
{
|
||||
Netchan_TransmitBits( &cls.netchan, 0, "" );
|
||||
return;
|
||||
@@ -1008,7 +999,7 @@ static void CL_WriteSteamTicket( sizebuf_t *send )
|
||||
const char *s;
|
||||
uint32_t crc;
|
||||
char buf[768] = { 0 }; // setti and steamemu return 768
|
||||
int i = sizeof( buf );
|
||||
size_t i = sizeof( buf );
|
||||
|
||||
if( !Q_strcmp( cl_ticket_generator.string, "null" ))
|
||||
{
|
||||
@@ -1027,7 +1018,24 @@ static void CL_WriteSteamTicket( sizebuf_t *send )
|
||||
CRC32_Init( &crc );
|
||||
CRC32_ProcessBuffer( &crc, s, Q_strlen( s ));
|
||||
crc = CRC32_Final( crc );
|
||||
i = GenerateRevEmu2013( buf, s, crc );
|
||||
|
||||
if( !Q_stricmp( cl_ticket_generator.string, "revemu2013" ))
|
||||
i = GenerateRevEmu2013( buf, crc );
|
||||
else if( !Q_stricmp( cl_ticket_generator.string, "sc2009" ))
|
||||
i = GenerateSC2009( buf, crc );
|
||||
else if( !Q_stricmp( cl_ticket_generator.string, "oldrevemu" ))
|
||||
i = GenerateOldRevEmu( buf, crc );
|
||||
else if( !Q_stricmp( cl_ticket_generator.string, "steamemu" ))
|
||||
i = GenerateSteamEmu( buf, crc );
|
||||
else if( !Q_stricmp( cl_ticket_generator.string, "revemu" ))
|
||||
i = GenerateRevEmu( buf, crc );
|
||||
else if( !Q_stricmp( cl_ticket_generator.string, "setti" ))
|
||||
i = GenerateSetti( buf );
|
||||
else if( !Q_stricmp( cl_ticket_generator.string, "avsmp" ))
|
||||
i = GenerateAVSMP( buf, crc, true );
|
||||
else
|
||||
Con_Printf( "%s: unknown generator %s, supported are: null, revemu2003, sc2009, oldrevemu, steamemu, revemu, setti, avsmp\n", __func__, cl_ticket_generator.string );
|
||||
|
||||
MSG_WriteBytes( send, buf, i );
|
||||
}
|
||||
|
||||
@@ -1045,7 +1053,6 @@ static void CL_SendConnectPacket( connprotocol_t proto, int challenge )
|
||||
const char *key = ID_GetMD5();
|
||||
netadr_t adr = { 0 };
|
||||
int input_devices;
|
||||
netadrtype_t adrtype;
|
||||
|
||||
protinfo[0] = 0;
|
||||
|
||||
@@ -1056,16 +1063,14 @@ static void CL_SendConnectPacket( connprotocol_t proto, int challenge )
|
||||
return;
|
||||
}
|
||||
|
||||
adrtype = NET_NetadrType( &adr );
|
||||
|
||||
if( adr.port == 0 ) adr.port = MSG_BigShort( PORT_SERVER );
|
||||
|
||||
input_devices = IN_CollectInputDevices();
|
||||
IN_LockInputDevices( adrtype != NA_LOOPBACK ? true : false );
|
||||
IN_LockInputDevices( adr.type != NA_LOOPBACK ? true : false );
|
||||
|
||||
// GoldSrc doesn't need sv_cheats set to 0, it's handled by svc_goldsrc_sendextrainfo
|
||||
// it also doesn't need useragent string
|
||||
if( adrtype != NA_LOOPBACK && proto != PROTO_GOLDSRC )
|
||||
if( adr.type != NA_LOOPBACK && proto != PROTO_GOLDSRC )
|
||||
{
|
||||
Cvar_SetCheatState();
|
||||
Cvar_FullSet( "sv_cheats", "0", FCVAR_READ_ONLY | FCVAR_SERVER );
|
||||
@@ -1165,11 +1170,7 @@ Returns bandwidth test fragment size
|
||||
*/
|
||||
static int CL_GetTestFragmentSize( void )
|
||||
{
|
||||
// const int fragmentSizes[CL_TEST_RETRIES] = { 64000, 32000, 10666, 5200, 1400 };
|
||||
|
||||
// it turns out, even if we pass the bandwidth test, it doesn't mean we can use such large fragments
|
||||
// as a temporary solution, use smaller fragment sizes
|
||||
const int fragmentSizes[CL_TEST_RETRIES] = { 1400, 1200, 1000, 800, 508 };
|
||||
const int fragmentSizes[CL_TEST_RETRIES] = { 64000, 32000, 10666, 5200, 1400 };
|
||||
if( cls.connect_retry >= 0 && cls.connect_retry < CL_TEST_RETRIES )
|
||||
return bound( FRAGMENT_MIN_SIZE, fragmentSizes[cls.connect_retry], FRAGMENT_MAX_SIZE );
|
||||
else
|
||||
@@ -1207,7 +1208,7 @@ static void CL_CheckForResend( void )
|
||||
cls.signon = 0;
|
||||
cls.state = ca_connecting;
|
||||
Q_strncpy( cls.servername, "localhost", sizeof( cls.servername ));
|
||||
NET_NetadrSetType( &cls.serveradr, NA_LOOPBACK );
|
||||
cls.serveradr.type = NA_LOOPBACK;
|
||||
cls.legacymode = PROTO_CURRENT;
|
||||
|
||||
// we don't need a challenge on the localhost
|
||||
@@ -1543,8 +1544,8 @@ static void CL_SendDisconnectMessage( connprotocol_t proto )
|
||||
MSG_WriteString( &buf, "dropclient\n" );
|
||||
else MSG_WriteString( &buf, "disconnect" );
|
||||
|
||||
if( NET_NetadrType( &cls.netchan.remote_address ) == NA_UNDEFINED )
|
||||
NET_NetadrSetType( &cls.netchan.remote_address, NA_LOOPBACK );
|
||||
if( !cls.netchan.remote_address.type )
|
||||
cls.netchan.remote_address.type = NA_LOOPBACK;
|
||||
|
||||
// make sure message will be delivered
|
||||
Netchan_TransmitBits( &cls.netchan, MSG_GetNumBitsWritten( &buf ), MSG_GetData( &buf ));
|
||||
@@ -1587,9 +1588,6 @@ void CL_SetupNetchanForProtocol( connprotocol_t proto )
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if( !Host_IsLocalClient( ))
|
||||
SetBits( flags, NETCHAN_USE_LZSS );
|
||||
|
||||
cls.extensions = Q_atoi( Info_ValueForKey( Cmd_Argv( 1 ), "ext" ));
|
||||
|
||||
if( FBitSet( cls.extensions, NET_EXT_SPLITSIZE ))
|
||||
@@ -1713,17 +1711,19 @@ CL_LocalServers_f
|
||||
*/
|
||||
static void CL_LocalServers_f( void )
|
||||
{
|
||||
netadr_t adr = { 0 };
|
||||
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
|
||||
|
||||
// send a broadcast packet
|
||||
NET_NetadrSetType( &adr, NA_BROADCAST );
|
||||
adr.type = NA_BROADCAST;
|
||||
adr.port = MSG_BigShort( PORT_SERVER );
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, A2A_INFO" %i", PROTOCOL_VERSION );
|
||||
|
||||
NET_NetadrSetType( &adr, NA_MULTICAST_IP6 );
|
||||
adr.type = NA_MULTICAST_IP6;
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, A2A_INFO" %i", PROTOCOL_VERSION );
|
||||
}
|
||||
|
||||
@@ -2467,18 +2467,18 @@ static void CL_ServerList( netadr_t from, sizebuf_t *msg )
|
||||
while( MSG_GetNumBitsLeft( msg ) > 8 )
|
||||
{
|
||||
uint8_t addr[16];
|
||||
netadr_t servadr = { 0 };
|
||||
netadr_t servadr;
|
||||
|
||||
if( NET_NetadrType( &from ) == NA_IP6 ) // IPv6 master server only sends IPv6 addresses
|
||||
if( from.type6 == NA_IP6 ) // IPv6 master server only sends IPv6 addresses
|
||||
{
|
||||
MSG_ReadBytes( msg, addr, sizeof( addr ));
|
||||
NET_IP6BytesToNetadr( &servadr, addr );
|
||||
NET_NetadrSetType( &servadr, NA_IP6 );
|
||||
servadr.type6 = NA_IP6;
|
||||
}
|
||||
else
|
||||
{
|
||||
MSG_ReadBytes( msg, servadr.ip, sizeof( servadr.ip )); // 4 bytes for IP
|
||||
NET_NetadrSetType( &servadr, NA_IP );
|
||||
servadr.type = NA_IP;
|
||||
}
|
||||
servadr.port = MSG_ReadShort( msg ); // 2 bytes for Port
|
||||
|
||||
@@ -3126,9 +3126,6 @@ static qboolean CL_ShouldRescanFilesystem( void )
|
||||
}
|
||||
}
|
||||
|
||||
if( FBitSet( fs_mount_lv.flags|fs_mount_hd.flags|fs_mount_addon.flags|fs_mount_l10n.flags|ui_language.flags, FCVAR_CHANGED ))
|
||||
retval = true;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -3138,7 +3135,7 @@ qboolean CL_PrecacheResources( void )
|
||||
|
||||
// if we downloaded new WAD files or any other archives they must be added to searchpath
|
||||
if( CL_ShouldRescanFilesystem( ))
|
||||
FS_Rescan_f();
|
||||
g_fsapi.Rescan();
|
||||
|
||||
// NOTE: world need to be loaded as first model
|
||||
for( pRes = cl.resourcesonhand.pNext; pRes && pRes != &cl.resourcesonhand; pRes = pRes->pNext )
|
||||
@@ -3384,7 +3381,6 @@ static void CL_InitLocal( void )
|
||||
|
||||
Cvar_RegisterVariable( &rcon_address );
|
||||
|
||||
Cvar_RegisterVariable( &cl_trace_consistency );
|
||||
Cvar_RegisterVariable( &cl_trace_stufftext );
|
||||
Cvar_RegisterVariable( &cl_trace_messages );
|
||||
Cvar_RegisterVariable( &cl_trace_events );
|
||||
@@ -3462,10 +3458,10 @@ static void CL_InitLocal( void )
|
||||
Cmd_AddRestrictedCommand ("userinfo", CL_SetInfo_f, "examine or change the userinfo string (alias of setinfo)" );
|
||||
Cmd_AddCommand ("physinfo", CL_Physinfo_f, "print current client physinfo" );
|
||||
Cmd_AddCommand ("disconnect", CL_Disconnect_f, "disconnect from server" );
|
||||
Cmd_AddRestrictedCommand( "record", CL_Record_f, "record a demo" );
|
||||
Cmd_AddCommand ("record", CL_Record_f, "record a demo" );
|
||||
Cmd_AddCommand ("playdemo", CL_PlayDemo_f, "play a demo" );
|
||||
Cmd_AddCommand ("timedemo", CL_TimeDemo_f, "demo benchmark" );
|
||||
Cmd_AddRestrictedCommand( "killdemo", CL_DeleteDemo_f, "delete a specified demo file" );
|
||||
Cmd_AddCommand ("killdemo", CL_DeleteDemo_f, "delete a specified demo file" );
|
||||
Cmd_AddCommand ("startdemos", CL_StartDemos_f, "start playing back the selected demos sequentially" );
|
||||
Cmd_AddCommand ("demos", CL_Demos_f, "restart looping demos defined by the last startdemos command" );
|
||||
Cmd_AddCommand ("movie", CL_PlayVideo_f, "play a movie" );
|
||||
@@ -3479,8 +3475,6 @@ static void CL_InitLocal( void )
|
||||
Cmd_AddCommand ("fullserverinfo", CL_FullServerinfo_f, "sent by server when serverinfo changes" );
|
||||
Cmd_AddCommand ("upload", CL_BeginUpload_f, "uploading file to the server" );
|
||||
|
||||
Cmd_AddRestrictedCommand( "replaybufferdat", CL_ReplayBufferDat_f, "development and debugging tool" );
|
||||
|
||||
Cmd_AddRestrictedCommand ("quit", CL_Quit_f, "quit from game" );
|
||||
Cmd_AddRestrictedCommand ("exit", CL_Quit_f, "quit from game" );
|
||||
|
||||
@@ -3658,8 +3652,6 @@ void CL_Init( void )
|
||||
if( !CL_LoadProgs( libpath ))
|
||||
Host_Error( "can't initialize %s: %s\n", libpath, COM_GetLibraryError( ));
|
||||
|
||||
ID_Init();
|
||||
|
||||
cls.build_num = 0;
|
||||
cls.initialized = true;
|
||||
cl.maxclients = 1; // allow to drawing player in menu
|
||||
@@ -3677,7 +3669,7 @@ void CL_Shutdown( void )
|
||||
{
|
||||
Con_Printf( "%s()\n", __func__ );
|
||||
|
||||
if( host.status != HOST_CRASHED && cls.initialized )
|
||||
if( !host.crashed && cls.initialized )
|
||||
{
|
||||
Host_WriteOpenGLConfig ();
|
||||
Host_WriteVideoConfig ();
|
||||
|
||||
@@ -92,11 +92,6 @@ static char *pfnParseFileSafe( char *data, char *buf, const int size, unsigned i
|
||||
return COM_ParseFileSafe( data, buf, size, flags, len, NULL );
|
||||
}
|
||||
|
||||
static void GAME_EXPORT pfnSetCustomClientID( const char *id )
|
||||
{
|
||||
// deprecated
|
||||
}
|
||||
|
||||
static const mobile_engfuncs_t gMobileEngfuncs =
|
||||
{
|
||||
MOBILITY_API_VERSION,
|
||||
@@ -111,7 +106,7 @@ static const mobile_engfuncs_t gMobileEngfuncs =
|
||||
pfnDrawScaledCharacter,
|
||||
Sys_Warn,
|
||||
Sys_GetNativeObject,
|
||||
pfnSetCustomClientID,
|
||||
ID_SetCustomClientID,
|
||||
pfnParseFileSafe
|
||||
};
|
||||
|
||||
|
||||
@@ -1614,23 +1614,6 @@ void CL_UpdateUserPings( sizebuf_t *msg )
|
||||
}
|
||||
}
|
||||
|
||||
static const char *CL_CheckTypeToString( int check_type )
|
||||
{
|
||||
// renamed so they have same width and look better in console output
|
||||
switch( check_type )
|
||||
{
|
||||
case force_exactfile:
|
||||
return "exactfile";
|
||||
case force_model_samebounds:
|
||||
return "samebounds";
|
||||
case force_model_specifybounds:
|
||||
return "specbounds";
|
||||
case force_model_specifybounds_if_avail:
|
||||
return "specbounds2";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static void CL_SendConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
{
|
||||
qboolean user_changed_diskfile;
|
||||
@@ -1896,9 +1879,6 @@ static void CL_ParseConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
return;
|
||||
}
|
||||
|
||||
if( cl_trace_consistency.value )
|
||||
Con_Printf( "Server wants consistency of the following resources:\n" );
|
||||
|
||||
skip_crc_change = NULL;
|
||||
lastcheck = 0;
|
||||
|
||||
@@ -1930,7 +1910,7 @@ static void CL_ParseConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
pc = &cl.consistency_list[cl.num_consistency];
|
||||
cl.num_consistency++;
|
||||
|
||||
memset( pc, 0, sizeof( *pc ));
|
||||
memset( pc, 0, sizeof( consistency_t ));
|
||||
pc->filename = pResource->szFileName;
|
||||
pc->issound = (pResource->type == t_sound);
|
||||
pc->orig_index = delta;
|
||||
@@ -1943,9 +1923,6 @@ static void CL_ParseConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
pc->check_type = pResource->rguc_reserved[0];
|
||||
}
|
||||
|
||||
if( cl_trace_consistency.value )
|
||||
Con_Printf( "%s\t%s\t%s\n", COM_ResourceTypeFromIndex( pResource->type ), CL_CheckTypeToString( pc->check_type ), pc->filename );
|
||||
|
||||
skip_crc_change = pResource;
|
||||
lastcheck = delta;
|
||||
}
|
||||
|
||||
@@ -83,10 +83,7 @@ static void CL_ParseNewMovevars( sizebuf_t *msg )
|
||||
R_SetupSky( clgame.movevars.skyName );
|
||||
|
||||
clgame.oldmovevars = clgame.movevars;
|
||||
|
||||
// FIXME: set world wave height when entities will be allocated
|
||||
if( clgame.entities )
|
||||
clgame.entities->curstate.scale = clgame.movevars.waveHeight;
|
||||
clgame.entities->curstate.scale = clgame.movevars.waveHeight;
|
||||
|
||||
// keep features an actual!
|
||||
clgame.oldmovevars.features = clgame.movevars.features = host.features;
|
||||
@@ -94,11 +91,11 @@ static void CL_ParseNewMovevars( sizebuf_t *msg )
|
||||
|
||||
typedef struct delta_header_t
|
||||
{
|
||||
qboolean remove;
|
||||
qboolean custom;
|
||||
qboolean instanced;
|
||||
uint16_t instanced_baseline_index;
|
||||
uint16_t offset;
|
||||
qboolean remove : 1;
|
||||
qboolean custom : 1;
|
||||
qboolean instanced : 1;
|
||||
uint instanced_baseline_index : 6;
|
||||
uint offset : 6;
|
||||
} delta_header_t;
|
||||
|
||||
static int CL_ParseDeltaHeader( sizebuf_t *msg, qboolean delta, int oldnum, struct delta_header_t *hdr )
|
||||
@@ -163,47 +160,33 @@ static int CL_GetEntityDelta( const struct delta_header_t *hdr, int entnum )
|
||||
return DT_ENTITY_STATE_T;
|
||||
}
|
||||
|
||||
static int CL_FlushEntityPacketGS( frame_t *frame, sizebuf_t *msg )
|
||||
static void CL_FlushEntityPacketGS( frame_t *frame, sizebuf_t *msg )
|
||||
{
|
||||
int playerbytes = 0, numbase = 0;
|
||||
|
||||
frame->valid = false;
|
||||
cl.validsequence = 0; // can't render a frame
|
||||
|
||||
// read it all but ignore it
|
||||
while( 1 )
|
||||
{
|
||||
int newnum, bufstart;
|
||||
int num = 0;
|
||||
entity_state_t from = { 0 }, to;
|
||||
delta_header_t hdr;
|
||||
qboolean player;
|
||||
|
||||
if( MSG_ReadWord( msg ) != 0 )
|
||||
{
|
||||
MSG_SeekToBit( msg, -16, SEEK_CUR );
|
||||
numbase = newnum = CL_ParseDeltaHeader( msg, true, numbase, &hdr );
|
||||
num = CL_ParseDeltaHeader( msg, false, num, &hdr );
|
||||
}
|
||||
else break;
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
Host_Error( "%s: overflow\n", __func__ );
|
||||
|
||||
player = CL_IsPlayerIndex( newnum );
|
||||
bufstart = MSG_GetNumBytesRead( msg );
|
||||
|
||||
if( hdr.remove )
|
||||
continue;
|
||||
|
||||
Delta_ReadGSFields( msg, CL_GetEntityDelta( &hdr, newnum ), &from, &to, cl.mtime[0] );
|
||||
|
||||
if( player )
|
||||
playerbytes += MSG_GetNumBytesRead( msg ) - bufstart;
|
||||
Delta_ReadGSFields( msg, CL_GetEntityDelta( &hdr, num ), &from, &to, cl.mtime[0] );
|
||||
}
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
Host_Error( "%s: overflow\n", __func__ );
|
||||
|
||||
return playerbytes;
|
||||
}
|
||||
|
||||
static void CL_DeltaEntityGS( const delta_header_t *hdr, sizebuf_t *msg, frame_t *frame, int newnum, const entity_state_t *from )
|
||||
@@ -220,7 +203,7 @@ static void CL_DeltaEntityGS( const delta_header_t *hdr, sizebuf_t *msg, frame_t
|
||||
if(( newnum < 0 ) || ( newnum >= clgame.maxEntities ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "CL_DeltaEntity: invalid newnum: %d\n", newnum );
|
||||
Host_Error( "%s: bad delta entity number: %i\n", __func__, newnum );
|
||||
Host_Error( "%s: bad delta entity number: %i", __func__, newnum );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -284,7 +267,7 @@ static void CL_CopyPacketEntity( frame_t *frame, int num, const entity_state_t *
|
||||
static int CL_ParsePacketEntitiesGS( sizebuf_t *msg, qboolean delta )
|
||||
{
|
||||
frame_t *frame, *oldframe;
|
||||
int oldindex, oldnum, numbase = 0;
|
||||
int oldindex, newnum, oldnum, numbase = 0;
|
||||
entity_state_t *oldent;
|
||||
int count;
|
||||
int playerbytes = 0;
|
||||
@@ -331,7 +314,7 @@ static int CL_ParsePacketEntitiesGS( sizebuf_t *msg, qboolean delta )
|
||||
// read it all but ignore it
|
||||
while( 1 )
|
||||
{
|
||||
int bufstart, newnum;
|
||||
int bufstart;
|
||||
qboolean player;
|
||||
delta_header_t hdr;
|
||||
int val = MSG_ReadWord( msg );
|
||||
|
||||
@@ -973,7 +973,7 @@ void CL_MoveSpectatorCamera( void )
|
||||
|
||||
CL_SetUpPlayerPrediction( false, true );
|
||||
CL_SetSolidPlayers( cl.playernum );
|
||||
CL_RunUsercmd( &cls.spectator_state, &cls.spectator_state, &cl.cmd, true, &time, (uint)( time * 100.0 ));
|
||||
CL_RunUsercmd( &cls.spectator_state, &cls.spectator_state, cl.cmd, true, &time, (uint)( time * 100.0 ));
|
||||
|
||||
VectorCopy( cls.spectator_state.client.velocity, cl.simvel );
|
||||
VectorCopy( cls.spectator_state.client.origin, cl.simorg );
|
||||
|
||||
@@ -233,11 +233,6 @@ static intptr_t pfnRenderGetParm( int parm, int arg )
|
||||
return CL_RenderGetParm( parm, arg, true );
|
||||
}
|
||||
|
||||
static void pfnAVI_StreamSound( void *avi, int entnum, float fvol, float attn, float synctime )
|
||||
{
|
||||
return; // stub, use AVI_SetParm and AVI_Think to stream AVI sound
|
||||
}
|
||||
|
||||
static render_api_t gRenderAPI =
|
||||
{
|
||||
pfnRenderGetParm, // GL_RenderGetParm,
|
||||
@@ -270,7 +265,7 @@ static render_api_t gRenderAPI =
|
||||
NULL, // R_UploadStretchRaw,
|
||||
(void*)AVI_FreeVideo,
|
||||
(void*)AVI_IsActive,
|
||||
(void*)pfnAVI_StreamSound,
|
||||
S_StreamAviSamples,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, // GL_Bind,
|
||||
|
||||
@@ -955,6 +955,7 @@ void GAME_EXPORT R_BloodSprite( const vec3_t org, int colorIndex, int modelIndex
|
||||
if( pTemp->entity.curstate.frame > 8.0f )
|
||||
pTemp->entity.curstate.frame = pTemp->frameMax;
|
||||
|
||||
pTemp->entity.baseline.origin[2] += COM_RandomFloat( 4.0f, 16.0f ) * size;
|
||||
pTemp->entity.angles[2] = COM_RandomFloat( 0.0f, 360.0f );
|
||||
pTemp->bounceFactor = 0.0f;
|
||||
}
|
||||
@@ -2428,7 +2429,7 @@ void CL_SetLightstyle( int style, const char *s, float f )
|
||||
|
||||
if( unlikely( style < 0 || style >= MAX_LIGHTSTYLES ))
|
||||
{
|
||||
Con_Printf( S_WARN "%s: ignored invalid lightstyle id %d\n", __func__, style );
|
||||
Con_Printf( S_WARN "%s: ignored invalid lightstyle id %d\n", style );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ static void V_SetRefParams( ref_params_t *fd )
|
||||
|
||||
// get pointers to movement vars and user cmd
|
||||
fd->movevars = &clgame.movevars;
|
||||
fd->cmd = &cl.cmd;
|
||||
fd->cmd = cl.cmd;
|
||||
|
||||
// setup viewport
|
||||
fd->viewport[0] = clgame.viewport[0];
|
||||
|
||||
@@ -234,7 +234,7 @@ typedef struct
|
||||
cl_local_data_t local;
|
||||
|
||||
// player final info
|
||||
usercmd_t cmd; // cl.commands[outgoing_sequence].cmd
|
||||
usercmd_t *cmd; // cl.commands[outgoing_sequence].cmd
|
||||
vec3_t viewangles;
|
||||
vec3_t viewheight;
|
||||
vec3_t punchangle;
|
||||
@@ -688,7 +688,6 @@ 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_consistency;
|
||||
extern convar_t cl_trace_stufftext;
|
||||
extern convar_t cl_trace_messages;
|
||||
extern convar_t cl_trace_events;
|
||||
@@ -737,7 +736,6 @@ void CL_ClearResourceLists( void );
|
||||
//
|
||||
// cl_debug.c
|
||||
//
|
||||
void CL_ReplayBufferDat_f( void );
|
||||
void CL_Parse_Debug( qboolean enable );
|
||||
void CL_Parse_RecordCommand( int cmd, int startoffset );
|
||||
void CL_ResetFrame( frame_t *frame );
|
||||
@@ -769,7 +767,7 @@ void CL_StartupDemoHeader( void );
|
||||
void CL_DrawDemoRecording( void );
|
||||
void CL_WriteDemoUserCmd( int cmdnumber );
|
||||
void CL_WriteDemoMessage( qboolean startup, int start, sizebuf_t *msg );
|
||||
void CL_WriteDemoUserMessage( int size, byte *buffer );
|
||||
void CL_WriteDemoUserMessage( const byte *buffer, size_t size );
|
||||
qboolean CL_DemoReadMessage( byte *buffer, size_t *length );
|
||||
void CL_DemoInterpolateAngles( void );
|
||||
void CL_CheckStartupDemos( void );
|
||||
@@ -807,11 +805,11 @@ qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float sc
|
||||
qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font, float scale, convar_t *rendermode, uint texFlags );
|
||||
void CL_FreeFont( cl_font_t *font );
|
||||
void CL_SetFontRendermode( cl_font_t *font );
|
||||
int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_t *font, int flags );
|
||||
int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_t *font, int flags );
|
||||
int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *font, int flags );
|
||||
int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *font, int flags );
|
||||
void CL_DrawCharacterLen( cl_font_t *font, int number, int *width, int *height );
|
||||
void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height, int flags );
|
||||
int CL_DrawStringf( cl_font_t *font, float x, float y, const rgba_t color, int flags, const char *fmt, ... ) FORMAT_CHECK( 6 );
|
||||
int CL_DrawStringf( cl_font_t *font, float x, float y, rgba_t color, int flags, const char *fmt, ... ) FORMAT_CHECK( 6 );
|
||||
|
||||
|
||||
//
|
||||
@@ -844,21 +842,19 @@ void CL_EnableScissor( scissor_state_t *scissor, int x, int y, int width, int he
|
||||
void CL_DisableScissor( scissor_state_t *scissor );
|
||||
qboolean CL_Scissor( const scissor_state_t *scissor, float *x, float *y, float *width, float *height, float *u0, float *v0, float *u1, float *v1 );
|
||||
|
||||
static inline cl_entity_t *CL_EDICT_NUM( int index )
|
||||
static inline cl_entity_t *CL_EDICT_NUM( int n )
|
||||
{
|
||||
if( !clgame.entities ) // not in game yet
|
||||
if( !clgame.entities )
|
||||
{
|
||||
Host_Error( "%s: clgame.entities is NULL\n", __func__ );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( index < 0 || index >= clgame.maxEntities )
|
||||
{
|
||||
Host_Error( "%s: bad number %i\n", __func__, index );
|
||||
return NULL;
|
||||
}
|
||||
if(( n >= 0 ) && ( n < clgame.maxEntities ))
|
||||
return clgame.entities + n;
|
||||
|
||||
return clgame.entities + index;
|
||||
Host_Error( "%s: bad number %i\n", __func__, n );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline cl_entity_t *CL_GetEntityByIndex( int index )
|
||||
@@ -869,7 +865,10 @@ static inline cl_entity_t *CL_GetEntityByIndex( int index )
|
||||
if( index < 0 || index >= clgame.maxEntities )
|
||||
return NULL;
|
||||
|
||||
return clgame.entities + index;
|
||||
if( index == 0 )
|
||||
return clgame.entities;
|
||||
|
||||
return CL_EDICT_NUM( index );
|
||||
}
|
||||
|
||||
static inline model_t *CL_ModelHandle( int modelindex )
|
||||
@@ -879,7 +878,7 @@ static inline model_t *CL_ModelHandle( int modelindex )
|
||||
|
||||
static inline qboolean CL_IsThirdPerson( void )
|
||||
{
|
||||
return clgame.dllFuncs.CL_IsThirdPerson();
|
||||
return clgame.dllFuncs.CL_IsThirdPerson() ? true : false;
|
||||
}
|
||||
|
||||
static inline cl_entity_t *CL_GetLocalPlayer( void )
|
||||
@@ -1107,7 +1106,7 @@ int Con_UtfMoveRight( char *str, int pos, int length );
|
||||
void Con_DefaultColor( int r, int g, int b, qboolean gameui );
|
||||
cl_font_t *Con_GetCurFont( void );
|
||||
cl_font_t *Con_GetFont( int num );
|
||||
int Con_DrawString( int x, int y, const char *string, const rgba_t setColor ); // legacy, use cl_font.c
|
||||
int Con_DrawString( int x, int y, const char *string, rgba_t setColor ); // legacy, use cl_font.c
|
||||
void GAME_EXPORT Con_DrawStringLen( const char *pText, int *length, int *height ); // legacy, use cl_font.c
|
||||
void Con_CharEvent( int key );
|
||||
void Key_Console( int key );
|
||||
@@ -1120,7 +1119,7 @@ void Con_PageUp( int lines );
|
||||
//
|
||||
// s_main.c
|
||||
//
|
||||
typedef int sound_t;
|
||||
void S_StreamAviSamples( void *Avi, int entnum, float fvol, float attn, float synctime );
|
||||
void S_StartBackgroundTrack( const char *intro, const char *loop, int position, qboolean fullpath );
|
||||
void S_StopBackgroundTrack( void );
|
||||
void S_StreamSetPause( int pause );
|
||||
@@ -1209,12 +1208,6 @@ void Key_EnableTextInput( qboolean enable, qboolean force );
|
||||
int Key_ToUpper( int key );
|
||||
void OSK_Draw( void );
|
||||
|
||||
//
|
||||
// identification.c
|
||||
//
|
||||
void ID_Init( void );
|
||||
const char *ID_GetMD5( void );
|
||||
|
||||
extern rgba_t g_color_table[8];
|
||||
extern triangleapi_t gTriApi;
|
||||
extern net_api_t gNetApi;
|
||||
|
||||
@@ -622,7 +622,7 @@ int Con_UtfProcessCharForce( int in )
|
||||
// TODO: get rid of global state where possible
|
||||
static utfstate_t state = { 0 };
|
||||
|
||||
uint32_t ch = Q_DecodeUTF8( &state, in );
|
||||
int ch = Q_DecodeUTF8( &state, in );
|
||||
|
||||
if( g_codepage == 1251 )
|
||||
return Q_UnicodeToCP1251( ch );
|
||||
@@ -759,7 +759,7 @@ Con_DrawString
|
||||
client version of routine
|
||||
====================
|
||||
*/
|
||||
int Con_DrawString( int x, int y, const char *string, const rgba_t setColor )
|
||||
int Con_DrawString( int x, int y, const char *string, rgba_t setColor )
|
||||
{
|
||||
return CL_DrawString( x, y, string, setColor, con.curFont, FONT_DRAW_UTF8 );
|
||||
}
|
||||
@@ -843,14 +843,11 @@ If no console is visible, the notify window will pop up.
|
||||
*/
|
||||
void Con_Print( const char *txt )
|
||||
{
|
||||
static qboolean cr_pending = false;
|
||||
static qboolean colorstring = false;
|
||||
static char buf[MAX_PRINT_MSG];
|
||||
static int lastlength = 0;
|
||||
static int bufpos = 0;
|
||||
static int charpos = 0;
|
||||
|
||||
qboolean norefresh = false;
|
||||
static int cr_pending = 0;
|
||||
static char buf[MAX_PRINT_MSG];
|
||||
qboolean norefresh = false;
|
||||
static int lastlength = 0;
|
||||
static int bufpos = 0;
|
||||
int c, mask = 0;
|
||||
|
||||
// client not running
|
||||
@@ -876,7 +873,7 @@ void Con_Print( const char *txt )
|
||||
if( cr_pending )
|
||||
{
|
||||
Con_DeleteLastLine();
|
||||
cr_pending = false;
|
||||
cr_pending = 0;
|
||||
}
|
||||
c = *txt;
|
||||
|
||||
@@ -889,42 +886,23 @@ void Con_Print( const char *txt )
|
||||
{
|
||||
Con_AddLine( buf, bufpos, true );
|
||||
lastlength = CON_LINES_LAST().length;
|
||||
cr_pending = true;
|
||||
cr_pending = 1;
|
||||
bufpos = 0;
|
||||
charpos = 0;
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
Con_AddLine( buf, bufpos, true );
|
||||
lastlength = CON_LINES_LAST().length;
|
||||
bufpos = 0;
|
||||
charpos = 0;
|
||||
break;
|
||||
default:
|
||||
|
||||
buf[bufpos++] = c | mask;
|
||||
|
||||
if( IsColorString( txt ))
|
||||
{
|
||||
// first color string character
|
||||
colorstring = true;
|
||||
}
|
||||
else if( colorstring )
|
||||
{
|
||||
// second color string character
|
||||
colorstring = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// not a color string, move char counter
|
||||
charpos++;
|
||||
}
|
||||
|
||||
if(( bufpos >= sizeof( buf ) - 1 ) || charpos >= ( con.linewidth - 1 ))
|
||||
if(( bufpos >= sizeof( buf ) - 1 ) || bufpos >= ( con.linewidth - 1 ))
|
||||
{
|
||||
Con_AddLine( buf, bufpos, true );
|
||||
lastlength = CON_LINES_LAST().length;
|
||||
bufpos = 0;
|
||||
charpos = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -940,7 +918,6 @@ void Con_Print( const char *txt )
|
||||
Con_AddLine( buf, bufpos, lastlength != 0 );
|
||||
lastlength = 0;
|
||||
bufpos = 0;
|
||||
charpos = 0;
|
||||
}
|
||||
|
||||
// pump messages to avoid window hanging
|
||||
@@ -1267,16 +1244,45 @@ static void Field_CharEvent( field_t *edit, int ch )
|
||||
Field_DrawInputLine
|
||||
==================
|
||||
*/
|
||||
static void Field_DrawInputLine( int x, int y, const field_t *edit )
|
||||
static void Field_DrawInputLine( int x, int y, field_t *edit )
|
||||
{
|
||||
int curPos;
|
||||
char str[MAX_SYSPATH];
|
||||
const byte *colorDefault = g_color_table[ColorIndex( COLOR_DEFAULT )];
|
||||
const int prestep = bound( 0, edit->scroll, sizeof( edit->buffer ) - 1 );
|
||||
const int drawLen = bound( 0, edit->widthInChars, sizeof( str ));
|
||||
const int cursorCharPos = bound( 0, edit->cursor - prestep, sizeof( str ));
|
||||
int len, cursorChar;
|
||||
int drawLen;
|
||||
int prestep, curPos;
|
||||
char str[MAX_SYSPATH];
|
||||
byte *colorDefault;
|
||||
|
||||
Q_strncpy( str, edit->buffer + prestep, drawLen );
|
||||
drawLen = edit->widthInChars;
|
||||
len = Q_strlen( edit->buffer ) + 1;
|
||||
colorDefault = g_color_table[ColorIndex( COLOR_DEFAULT )];
|
||||
|
||||
// guarantee that cursor will be visible
|
||||
if( len <= drawLen )
|
||||
{
|
||||
prestep = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( edit->scroll + drawLen > len )
|
||||
{
|
||||
edit->scroll = len - drawLen;
|
||||
if( edit->scroll < 0 ) edit->scroll = 0;
|
||||
}
|
||||
|
||||
prestep = edit->scroll;
|
||||
}
|
||||
|
||||
if( prestep + drawLen > len )
|
||||
drawLen = len - prestep;
|
||||
|
||||
// extract <drawLen> characters from the field at <prestep>
|
||||
drawLen = Q_min( drawLen, MAX_SYSPATH - 1 );
|
||||
|
||||
memcpy( str, edit->buffer + prestep, drawLen );
|
||||
str[drawLen] = 0;
|
||||
|
||||
// save char for overstrike
|
||||
cursorChar = str[edit->cursor - prestep];
|
||||
|
||||
// draw it
|
||||
CL_DrawString( x, y, str, colorDefault, con.curFont, FONT_DRAW_UTF8 );
|
||||
@@ -1285,7 +1291,7 @@ static void Field_DrawInputLine( int x, int y, const field_t *edit )
|
||||
if((int)( host.realtime * 4 ) & 1 ) return; // off blink
|
||||
|
||||
// calc cursor position
|
||||
str[cursorCharPos] = 0;
|
||||
str[edit->cursor - prestep] = 0;
|
||||
CL_DrawStringLen( con.curFont, str, &curPos, NULL, FONT_DRAW_UTF8 );
|
||||
|
||||
if( host.key_overstrike )
|
||||
@@ -1461,16 +1467,6 @@ Handles history and console scrollback
|
||||
*/
|
||||
void Key_Console( int key )
|
||||
{
|
||||
// exit the console by pressing MINUS on NSwitch
|
||||
// or both Back(Select)/Start buttons for everyone else
|
||||
if( key == K_BACK_BUTTON || key == K_START_BUTTON || key == K_ESCAPE )
|
||||
{
|
||||
if( cls.state == ca_active && !cl.background )
|
||||
Key_SetKeyDest( key_game );
|
||||
else UI_SetActiveMenu( true );
|
||||
return;
|
||||
}
|
||||
|
||||
// ctrl-L clears screen
|
||||
if( key == 'l' && Key_IsDown( K_CTRL ))
|
||||
{
|
||||
@@ -1579,6 +1575,16 @@ void Key_Console( int key )
|
||||
return;
|
||||
}
|
||||
|
||||
// exit the console by pressing MINUS on NSwitch
|
||||
// or both Back(Select)/Start buttons for everyone else
|
||||
if( key == K_BACK_BUTTON || key == K_START_BUTTON )
|
||||
{
|
||||
if( cls.state == ca_active && !cl.background )
|
||||
Key_SetKeyDest( key_game );
|
||||
else UI_SetActiveMenu( true );
|
||||
return;
|
||||
}
|
||||
|
||||
// pass to the normal editline routine
|
||||
Field_KeyDownEvent( &con.input, key );
|
||||
}
|
||||
@@ -2002,7 +2008,7 @@ void Con_DrawVersion( void )
|
||||
int start, height = refState.height;
|
||||
string curbuild;
|
||||
|
||||
if( !scr_drawversion.value )
|
||||
if( !scr_drawversion.value || CL_IsDevOverviewMode() == 2 || net_graph.value )
|
||||
return;
|
||||
|
||||
if( cls.key_dest == key_menu )
|
||||
@@ -2014,9 +2020,6 @@ void Con_DrawVersion( void )
|
||||
{
|
||||
qboolean draw_version;
|
||||
|
||||
if( CL_IsDevOverviewMode() == 2 || net_graph.value )
|
||||
return;
|
||||
|
||||
draw_version = cls.scrshot_action == scrshot_normal
|
||||
|| cls.scrshot_action == scrshot_snapshot
|
||||
|| host.force_draw_version_time > host.realtime;
|
||||
@@ -2089,7 +2092,10 @@ void Con_RunConsole( void )
|
||||
}
|
||||
else
|
||||
{
|
||||
g_codepage = 0;
|
||||
Con_Printf( S_WARN "Unknown charset %s, defaulting to cp1252", con_charset.string );
|
||||
|
||||
Cvar_DirectSet( &con_charset, "cp1252" );
|
||||
g_codepage = 1252;
|
||||
}
|
||||
|
||||
cls.accept_utf8 = !Q_stricmp( cl_charset.string, "utf-8" );
|
||||
@@ -2132,31 +2138,20 @@ void Con_CharEvent( int key )
|
||||
|
||||
static int Con_LoadSimpleConback( const char *name, int flags )
|
||||
{
|
||||
int i;
|
||||
const char *paths[] = {
|
||||
"gfx/shell/%s.dds",
|
||||
"gfx/shell/%s.bmp",
|
||||
"gfx/shell/%s.tga",
|
||||
"cached/%s640",
|
||||
"cached/%s",
|
||||
};
|
||||
size_t i;
|
||||
|
||||
for( i = 0; i < 5; i++ )
|
||||
for( i = 0; i < ARRAYSIZE( paths ); i++ )
|
||||
{
|
||||
string path;
|
||||
|
||||
switch( i )
|
||||
{
|
||||
case 0:
|
||||
Q_snprintf( path, sizeof( path ), "gfx/shell/%s.dds", name );
|
||||
break;
|
||||
case 1:
|
||||
Q_snprintf( path, sizeof( path ), "gfx/shell/%s.bmp", name );
|
||||
break;
|
||||
case 2:
|
||||
Q_snprintf( path, sizeof( path ), "gfx/shell/%s.tga", name );
|
||||
break;
|
||||
case 3:
|
||||
Q_snprintf( path, sizeof( path ), "cached/%s640", name );
|
||||
break;
|
||||
case 4:
|
||||
Q_snprintf( path, sizeof( path ), "cached/%s", name );
|
||||
break;
|
||||
}
|
||||
|
||||
Q_snprintf( path, sizeof( path ), paths[i], name );
|
||||
if( g_fsapi.FileExists( path, false ))
|
||||
{
|
||||
int gl_texturenum = ref.dllFuncs.GL_LoadTexture( path, NULL, 0, flags );
|
||||
|
||||
@@ -43,6 +43,7 @@ static struct joy_axis_s
|
||||
short val;
|
||||
short prevval;
|
||||
} joyaxis[MAX_AXES] = { 0 };
|
||||
static byte currentbinding; // add posibility to remap keys, to place it in joykeys[]
|
||||
static qboolean joy_initialized;
|
||||
|
||||
static CVAR_DEFINE_AUTO( joy_pitch, "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick pitch sensitivity" );
|
||||
@@ -59,9 +60,9 @@ static CVAR_DEFINE_AUTO( joy_pitch_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE
|
||||
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" );
|
||||
static CVAR_DEFINE_AUTO( joy_have_gyro, "0", FCVAR_READ_ONLY, "tells whether current active gamepad has gyroscope or not" );
|
||||
static CVAR_DEFINE_AUTO( joy_calibrated, "0", FCVAR_READ_ONLY, "tells whether current active gamepad gyroscope has been calibrated or not" );
|
||||
|
||||
/*
|
||||
============
|
||||
@@ -70,30 +71,7 @@ Joy_IsActive
|
||||
*/
|
||||
qboolean Joy_IsActive( void )
|
||||
{
|
||||
return joy_enable.value;
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
Joy_SetCapabilities
|
||||
===========
|
||||
*/
|
||||
void Joy_SetCapabilities( qboolean have_gyro )
|
||||
{
|
||||
Cvar_FullSet( joy_have_gyro.name, have_gyro ? "1" : "0", joy_have_gyro.flags );
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
Joy_SetCalibrationState
|
||||
===========
|
||||
*/
|
||||
void Joy_SetCalibrationState( joy_calibration_state_t state )
|
||||
{
|
||||
if( (int)joy_calibrated.value == state )
|
||||
return;
|
||||
|
||||
Cvar_FullSet( joy_calibrated.name, va( "%d", state ), joy_calibrated.flags );
|
||||
return joy_found.value && joy_enable.value;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -103,7 +81,7 @@ Joy_HatMotionEvent
|
||||
DPad events
|
||||
============
|
||||
*/
|
||||
static void Joy_HatMotionEvent( int value )
|
||||
void Joy_HatMotionEvent( byte hat, byte value )
|
||||
{
|
||||
struct
|
||||
{
|
||||
@@ -118,6 +96,9 @@ static void Joy_HatMotionEvent( int value )
|
||||
};
|
||||
int i;
|
||||
|
||||
if( !joy_found.value )
|
||||
return;
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( keys ); i++ )
|
||||
{
|
||||
if( value & keys[i].mask )
|
||||
@@ -244,7 +225,7 @@ static void Joy_ProcessStick( const engineAxis_t engineAxis, short value )
|
||||
val |= Joy_GetHatValueForAxis( JOY_AXIS_SIDE );
|
||||
val |= Joy_GetHatValueForAxis( JOY_AXIS_FWD );
|
||||
|
||||
Joy_HatMotionEvent( val );
|
||||
Joy_HatMotionEvent( 0, val );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,9 +236,23 @@ Joy_AxisMotionEvent
|
||||
Axis events
|
||||
=============
|
||||
*/
|
||||
void Joy_AxisMotionEvent( engineAxis_t engineAxis, short value )
|
||||
void Joy_AxisMotionEvent( byte axis, short value )
|
||||
{
|
||||
if( engineAxis >= JOY_AXIS_NULL )
|
||||
if( !joy_found.value )
|
||||
return;
|
||||
|
||||
if( axis >= MAX_AXES )
|
||||
{
|
||||
Con_Reportf( "Only 6 axes is supported\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
Joy_KnownAxisMotionEvent( joyaxesmap[axis], value );
|
||||
}
|
||||
|
||||
void Joy_KnownAxisMotionEvent( engineAxis_t engineAxis, short value )
|
||||
{
|
||||
if( engineAxis == JOY_AXIS_NULL )
|
||||
return;
|
||||
|
||||
if( value == joyaxis[engineAxis].val )
|
||||
@@ -271,14 +266,66 @@ void Joy_AxisMotionEvent( engineAxis_t engineAxis, short value )
|
||||
|
||||
/*
|
||||
=============
|
||||
Joy_GyroEvent
|
||||
Joy_BallMotionEvent
|
||||
|
||||
Gyroscope events
|
||||
Trackball events. UNDONE
|
||||
=============
|
||||
*/
|
||||
void Joy_GyroEvent( vec3_t data )
|
||||
void Joy_BallMotionEvent( byte ball, short xrel, short yrel )
|
||||
{
|
||||
//if( !joy_found.value )
|
||||
// return;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Joy_ButtonEvent
|
||||
|
||||
Button events
|
||||
=============
|
||||
*/
|
||||
void Joy_ButtonEvent( byte button, byte down )
|
||||
{
|
||||
if( !joy_found.value )
|
||||
return;
|
||||
|
||||
// generic game button code.
|
||||
if( button > 32 )
|
||||
{
|
||||
int origbutton = button;
|
||||
button = ( button & 31 ) + K_AUX1;
|
||||
|
||||
Con_Reportf( "Only 32 joybuttons is supported, converting %i button ID to %s\n", origbutton, Key_KeynumToString( button ) );
|
||||
}
|
||||
else button += K_AUX1;
|
||||
|
||||
Key_Event( button, down );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Joy_RemoveEvent
|
||||
|
||||
Called when joystick is removed. For future expansion
|
||||
=============
|
||||
*/
|
||||
void Joy_RemoveEvent( void )
|
||||
{
|
||||
if( joy_found.value )
|
||||
Cvar_FullSet( "joy_found", "0", FCVAR_READ_ONLY );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Joy_RemoveEvent
|
||||
|
||||
Called when joystick is removed. For future expansion
|
||||
=============
|
||||
*/
|
||||
void Joy_AddEvent( void )
|
||||
{
|
||||
if( joy_enable.value && !joy_found.value )
|
||||
Cvar_FullSet( "joy_found", "1", FCVAR_READ_ONLY );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -317,19 +364,14 @@ void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw )
|
||||
|
||||
*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;
|
||||
#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;
|
||||
}
|
||||
|
||||
static void Joy_CalibrateGyro_f( void )
|
||||
{
|
||||
if( !joy_have_gyro.value )
|
||||
{
|
||||
Con_Printf( "Current active gamepad doesn't have gyroscope\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
Platform_CalibrateGamepadGyro();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -341,8 +383,6 @@ Main init procedure
|
||||
*/
|
||||
void Joy_Init( void )
|
||||
{
|
||||
Cmd_AddRestrictedCommand( "joy_calibrate_gyro", Joy_CalibrateGyro_f, "calibrate gamepad gyroscope. You must to put gamepad on stationary surface" );
|
||||
|
||||
Cvar_RegisterVariable( &joy_pitch );
|
||||
Cvar_RegisterVariable( &joy_yaw );
|
||||
Cvar_RegisterVariable( &joy_side );
|
||||
@@ -362,9 +402,11 @@ void Joy_Init( void )
|
||||
Cvar_RegisterVariable( &joy_yaw_deadzone );
|
||||
|
||||
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
|
||||
Cvar_RegisterVariable( &joy_index );
|
||||
|
||||
Cvar_RegisterVariable( &joy_have_gyro );
|
||||
Cvar_RegisterVariable( &joy_calibrated );
|
||||
Cvar_RegisterVariable( &joy_enable );
|
||||
|
||||
// renamed from -nojoy to -noenginejoy to not conflict with
|
||||
@@ -375,7 +417,7 @@ void Joy_Init( void )
|
||||
return;
|
||||
}
|
||||
|
||||
Platform_JoyInit();
|
||||
Cvar_FullSet( "joy_found", va( "%d", Platform_JoyInit( joy_index.value )), FCVAR_READ_ONLY );
|
||||
|
||||
joy_initialized = true;
|
||||
}
|
||||
@@ -389,5 +431,8 @@ Shutdown joystick code
|
||||
*/
|
||||
void Joy_Shutdown( void )
|
||||
{
|
||||
Platform_JoyShutdown();
|
||||
if( joy_initialized )
|
||||
{
|
||||
Cvar_FullSet( "joy_found", 0, FCVAR_READ_ONLY );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,17 +13,16 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#if XASH_SDL == 2
|
||||
#include <SDL.h>
|
||||
#elif XASH_SDL == 3
|
||||
#include <SDL3/SDL.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include "input.h"
|
||||
#include "client.h"
|
||||
#include "vgui_draw.h"
|
||||
#include "cursor_type.h"
|
||||
|
||||
#if XASH_SDL
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
void* in_mousecursor;
|
||||
@@ -206,58 +205,50 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
|
||||
}
|
||||
}
|
||||
|
||||
void IN_SetRelativeMouseMode( qboolean set )
|
||||
static void IN_SetRelativeMouseMode( qboolean set, qboolean verbose )
|
||||
{
|
||||
static qboolean s_bRawInput;
|
||||
qboolean verbose = m_grab_debug.value ? true : false;
|
||||
|
||||
if( set && !s_bRawInput )
|
||||
{
|
||||
#if XASH_SDL >= 2
|
||||
SDL_GetRelativeMouseState( NULL, NULL );
|
||||
#if XASH_SDL == 2
|
||||
SDL_GetRelativeMouseState( NULL, NULL );
|
||||
SDL_SetRelativeMouseMode( SDL_TRUE );
|
||||
#else // XASH_SDL != 2
|
||||
SDL_SetWindowRelativeMouseMode( host.hWnd, true );
|
||||
#endif // XASH_SDL != 2
|
||||
#endif // XASH_SDL >= 2
|
||||
#endif
|
||||
s_bRawInput = true;
|
||||
if( verbose )
|
||||
Con_Printf( "%s: true\n", __func__ );
|
||||
}
|
||||
else if( !set && s_bRawInput )
|
||||
{
|
||||
#if XASH_SDL >= 2
|
||||
SDL_GetRelativeMouseState( NULL, NULL );
|
||||
#if XASH_SDL == 2
|
||||
SDL_GetRelativeMouseState( NULL, NULL );
|
||||
SDL_SetRelativeMouseMode( SDL_FALSE );
|
||||
#else // XASH_SDL != 2
|
||||
SDL_SetWindowRelativeMouseMode( host.hWnd, false );
|
||||
#endif // XASH_SDL != 2
|
||||
#endif // XASH_SDL >= 2
|
||||
|
||||
#endif
|
||||
s_bRawInput = false;
|
||||
if( verbose )
|
||||
Con_Printf( "%s: false\n", __func__ );
|
||||
}
|
||||
}
|
||||
|
||||
void IN_SetMouseGrab( qboolean set )
|
||||
static void IN_SetMouseGrab( qboolean set, qboolean verbose )
|
||||
{
|
||||
static qboolean s_bMouseGrab;
|
||||
qboolean verbose = m_grab_debug.value ? true : false;
|
||||
|
||||
if( set && !s_bMouseGrab )
|
||||
{
|
||||
Platform_SetMouseGrab( true );
|
||||
|
||||
#if XASH_SDL
|
||||
SDL_SetWindowGrab( host.hWnd, SDL_TRUE );
|
||||
#endif
|
||||
s_bMouseGrab = true;
|
||||
if( verbose )
|
||||
Con_Printf( "%s: true\n", __func__ );
|
||||
}
|
||||
else if( !set && s_bMouseGrab )
|
||||
{
|
||||
Platform_SetMouseGrab( false );
|
||||
#if XASH_SDL
|
||||
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
|
||||
#endif
|
||||
|
||||
s_bMouseGrab = false;
|
||||
if( verbose )
|
||||
@@ -267,7 +258,7 @@ void IN_SetMouseGrab( qboolean set )
|
||||
|
||||
static void IN_CheckMouseState( qboolean active )
|
||||
{
|
||||
qboolean use_raw_input;
|
||||
qboolean use_raw_input, verbose;
|
||||
|
||||
#if XASH_WIN32
|
||||
use_raw_input = ( m_rawinput.value && clgame.client_dll_uses_sdl ) || clgame.dllFuncs.pfnLookEvent != NULL;
|
||||
@@ -275,18 +266,20 @@ static void IN_CheckMouseState( qboolean active )
|
||||
use_raw_input = true; // always use SDL code
|
||||
#endif
|
||||
|
||||
verbose = m_grab_debug.value ? true : false;
|
||||
|
||||
if( m_ignore.value )
|
||||
active = false;
|
||||
|
||||
if( active && use_raw_input && !host.mouse_visible && cls.state == ca_active )
|
||||
IN_SetRelativeMouseMode( true );
|
||||
IN_SetRelativeMouseMode( true, verbose );
|
||||
else
|
||||
IN_SetRelativeMouseMode( false );
|
||||
IN_SetRelativeMouseMode( false, verbose );
|
||||
|
||||
if( active && !host.mouse_visible && cls.state == ca_active )
|
||||
IN_SetMouseGrab( true );
|
||||
IN_SetMouseGrab( true, verbose );
|
||||
else
|
||||
IN_SetMouseGrab( false );
|
||||
IN_SetMouseGrab( false, verbose );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -339,7 +332,7 @@ static void IN_MouseMove( void )
|
||||
if( !in_mouseinitialized )
|
||||
return;
|
||||
|
||||
if( Touch_WantVisibleCursor( ))
|
||||
if( Touch_Emulated( ))
|
||||
{
|
||||
// touch emulation overrides all input
|
||||
Touch_KeyEvent( 0, 0 );
|
||||
@@ -370,7 +363,7 @@ void IN_MouseEvent( int key, int down )
|
||||
else ClearBits( in_mstate, BIT( key ));
|
||||
|
||||
// touch emulation overrides all input
|
||||
if( Touch_WantVisibleCursor( ))
|
||||
if( Touch_Emulated( ))
|
||||
{
|
||||
Touch_KeyEvent( K_MOUSE1 + key, down );
|
||||
}
|
||||
|
||||
@@ -46,9 +46,6 @@ uint IN_CollectInputDevices( void );
|
||||
void IN_LockInputDevices( qboolean lock );
|
||||
void IN_EngineAppendMove( float frametime, usercmd_t *cmd, qboolean active );
|
||||
|
||||
void IN_SetRelativeMouseMode( qboolean set );
|
||||
void IN_SetMouseGrab( qboolean set );
|
||||
|
||||
extern convar_t m_yaw;
|
||||
extern convar_t m_pitch;
|
||||
//
|
||||
@@ -77,6 +74,7 @@ void Touch_ResetDefaultButtons( void );
|
||||
int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy );
|
||||
void Touch_KeyEvent( int key, int down );
|
||||
qboolean Touch_WantVisibleCursor( void );
|
||||
qboolean Touch_Emulated( void );
|
||||
void Touch_NotifyResize( void );
|
||||
|
||||
//
|
||||
@@ -106,21 +104,18 @@ typedef enum engineAxis_e
|
||||
JOY_AXIS_NULL
|
||||
} engineAxis_t;
|
||||
|
||||
typedef enum joy_calibration_state_s
|
||||
{
|
||||
JOY_NOT_CALIBRATED = 0,
|
||||
JOY_CALIBRATING,
|
||||
JOY_FAILED_TO_CALIBRATE,
|
||||
JOY_CALIBRATED
|
||||
} joy_calibration_state_t;
|
||||
|
||||
qboolean Joy_IsActive( void );
|
||||
void Joy_SetCapabilities( qboolean have_gyro );
|
||||
void Joy_SetCalibrationState( joy_calibration_state_t state );
|
||||
void Joy_AxisMotionEvent( engineAxis_t engineAxis, short value );
|
||||
void Joy_GyroEvent( vec3_t data );
|
||||
void Joy_HatMotionEvent( byte hat, byte value );
|
||||
void Joy_AxisMotionEvent( byte axis, short value );
|
||||
void Joy_KnownAxisMotionEvent( engineAxis_t engineAxis, short value );
|
||||
void Joy_BallMotionEvent( byte ball, short xrel, short yrel );
|
||||
void Joy_ButtonEvent( byte button, byte down );
|
||||
void Joy_AddEvent( void );
|
||||
void Joy_RemoveEvent( void );
|
||||
void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw );
|
||||
void Joy_Init( void );
|
||||
void Joy_Shutdown( void );
|
||||
void Joy_EnableTextInput(qboolean enable, qboolean force);
|
||||
|
||||
|
||||
#endif//INPUT_H
|
||||
|
||||
@@ -51,7 +51,7 @@ static const keyname_t keynames[] =
|
||||
{"CTRL", K_CTRL, "+attack" },
|
||||
{"SHIFT", K_SHIFT, "+speed" },
|
||||
{"CAPSLOCK", K_CAPSLOCK, "" },
|
||||
{"SCROLLOCK", K_SCROLLLOCK, "" },
|
||||
{"SCROLLOCK", K_SCROLLOCK, "" },
|
||||
{"F1", K_F1, "cmd help" },
|
||||
{"F2", K_F2, "menu_savegame" },
|
||||
{"F3", K_F3, "menu_loadgame" },
|
||||
@@ -215,7 +215,7 @@ const char *Key_KeynumToString( int keynum )
|
||||
return "<OUT OF RANGE>";
|
||||
|
||||
// check for printable ascii (don't use quote)
|
||||
if( keynum > 32 && keynum < 127 && keynum != '"' && keynum != ';' && keynum != K_SCROLLLOCK )
|
||||
if( keynum > 32 && keynum < 127 && keynum != '"' && keynum != ';' && keynum != K_SCROLLOCK )
|
||||
{
|
||||
tinystr[0] = keynum;
|
||||
tinystr[1] = 0;
|
||||
@@ -726,8 +726,18 @@ void GAME_EXPORT Key_Event( int key, int down )
|
||||
return; // handled in client.dll
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case key_message:
|
||||
Key_Message( key );
|
||||
return;
|
||||
case key_console:
|
||||
if( cls.state == ca_active && !cl.background )
|
||||
Key_SetKeyDest( key_game );
|
||||
else UI_SetActiveMenu( true );
|
||||
return;
|
||||
case key_menu:
|
||||
UI_KeyEvent( key, true );
|
||||
return;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -851,9 +861,7 @@ void GAME_EXPORT Key_ClearStates( void )
|
||||
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
if( i >= K_MOUSE1 && i <= K_MOUSE5 )
|
||||
IN_MouseEvent( i - K_MOUSE1, false );
|
||||
else
|
||||
if( keys[i].down && i < K_MOUSE1 && i > K_MOUSE5 )
|
||||
Key_Event( i, false );
|
||||
|
||||
keys[i].down = 0;
|
||||
@@ -861,6 +869,9 @@ void GAME_EXPORT Key_ClearStates( void )
|
||||
keys[i].gamedown = 0;
|
||||
}
|
||||
|
||||
for( i = K_MOUSE1; i < K_MOUSE5; i++ ) // from K_MOUSE1 to K_MOUSE5
|
||||
IN_MouseEvent( i - K_MOUSE1, false );
|
||||
|
||||
if( clgame.hInstance )
|
||||
clgame.dllFuncs.IN_ClearStates();
|
||||
}
|
||||
@@ -1097,7 +1108,7 @@ static qboolean OSK_KeyEvent( int key, int down )
|
||||
|
||||
/*
|
||||
=============
|
||||
OSK_EnableTextInput
|
||||
Joy_EnableTextInput
|
||||
|
||||
Enables built-in IME
|
||||
=============
|
||||
|
||||
@@ -433,8 +433,6 @@ static const ref_api_t gEngfuncs =
|
||||
&clgame.drawFuncs,
|
||||
|
||||
&g_fsapi,
|
||||
|
||||
R_GetWindowHandle,
|
||||
};
|
||||
|
||||
static void R_UnloadProgs( void )
|
||||
@@ -574,7 +572,7 @@ static void R_GetRendererName( char *dest, size_t size, const char *opt )
|
||||
}
|
||||
}
|
||||
|
||||
static qboolean R_LoadRenderer( const char *refopt, qboolean quiet )
|
||||
static qboolean R_LoadRenderer( const char *refopt )
|
||||
{
|
||||
string refdll;
|
||||
|
||||
@@ -585,8 +583,7 @@ static qboolean R_LoadRenderer( const char *refopt, qboolean quiet )
|
||||
if( !R_LoadProgs( refdll ))
|
||||
{
|
||||
R_Shutdown();
|
||||
if( !quiet )
|
||||
Sys_Warn( S_ERROR "Can't initialize %s renderer!\n", refdll );
|
||||
Sys_Warn( S_ERROR "Can't initialize %s renderer!\n", refdll );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -625,7 +622,7 @@ static void SetFullscreenModeFromCommandLine( void )
|
||||
static void R_CollectRendererNames( void )
|
||||
{
|
||||
// ordering is important!
|
||||
static const char *short_names[] =
|
||||
static const char *shortNames[] =
|
||||
{
|
||||
#if XASH_REF_GL_ENABLED
|
||||
"gl",
|
||||
@@ -648,7 +645,7 @@ static void R_CollectRendererNames( void )
|
||||
};
|
||||
|
||||
// ordering is important here too!
|
||||
static const char *long_names[ARRAYSIZE( short_names )] =
|
||||
static const char *readableNames[ARRAYSIZE( shortNames )] =
|
||||
{
|
||||
#if XASH_REF_GL_ENABLED
|
||||
"OpenGL",
|
||||
@@ -670,9 +667,9 @@ static void R_CollectRendererNames( void )
|
||||
#endif
|
||||
};
|
||||
|
||||
ref.num_renderers = ARRAYSIZE( short_names );
|
||||
ref.short_names = short_names;
|
||||
ref.long_names = long_names;
|
||||
ref.numRenderers = ARRAYSIZE( shortNames );
|
||||
ref.shortNames = shortNames;
|
||||
ref.readableNames = readableNames;
|
||||
}
|
||||
|
||||
qboolean R_Init( void )
|
||||
@@ -733,44 +730,28 @@ qboolean R_Init( void )
|
||||
requested_cvar[0] = 0;
|
||||
|
||||
if( Sys_GetParmFromCmdLine( "-ref", requested_cmdline ))
|
||||
success = R_LoadRenderer( requested_cmdline, false );
|
||||
success = R_LoadRenderer( requested_cmdline );
|
||||
|
||||
if( !success && COM_CheckString( r_refdll.string ) && Q_stricmp( requested_cmdline, r_refdll.string ))
|
||||
{
|
||||
Q_strncpy( requested_cvar, r_refdll.string, sizeof( requested_cvar ));
|
||||
|
||||
// do not show scary messages to user if renderer set in config cannot be loaded
|
||||
// as game data could be copied from one platform to another, where this renderer
|
||||
// might not be supported (ref_gl on Android for example)
|
||||
success = R_LoadRenderer( requested_cvar, !host_developer.value );
|
||||
success = R_LoadRenderer( requested_cvar );
|
||||
}
|
||||
|
||||
if( !success )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < ref.num_renderers; i++ )
|
||||
for( i = 0; i < ref.numRenderers && !success; i++ )
|
||||
{
|
||||
// skip renderer that was requested but failed to load
|
||||
if( !Q_strcmp( requested_cmdline, ref.short_names[i] ))
|
||||
if( !Q_strcmp( requested_cmdline, ref.shortNames[i] ))
|
||||
continue;
|
||||
|
||||
if( !Q_strcmp( requested_cvar, ref.short_names[i] ))
|
||||
if( !Q_strcmp( requested_cvar, ref.shortNames[i] ))
|
||||
continue;
|
||||
|
||||
// do not show bruteforcing attempts, however, warn user about falling back
|
||||
// to software mode
|
||||
if( !Q_strcmp( "soft", ref.short_names[i] ) && !host_developer.value )
|
||||
Sys_Warn( "Can't initialize any hardware accelerated renderer. Falling back to software rendering...\n" );
|
||||
|
||||
success = R_LoadRenderer( ref.short_names[i], !host_developer.value );
|
||||
|
||||
if( success )
|
||||
{
|
||||
// remember last valid renderer
|
||||
Cvar_DirectSet( &r_refdll, ref.short_names[i] );
|
||||
break;
|
||||
}
|
||||
success = R_LoadRenderer( ref.shortNames[i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,12 +24,12 @@ struct ref_state_s
|
||||
{
|
||||
HINSTANCE hInstance;
|
||||
qboolean initialized;
|
||||
int num_renderers;
|
||||
int numRenderers;
|
||||
ref_interface_t dllFuncs;
|
||||
|
||||
// depends on build configuration
|
||||
const char **short_names;
|
||||
const char **long_names;
|
||||
const char **shortNames;
|
||||
const char **readableNames;
|
||||
};
|
||||
|
||||
extern struct ref_state_s ref;
|
||||
|
||||
@@ -312,7 +312,7 @@ static int DLY_Init( int idelay, float delay )
|
||||
|
||||
cur = &rgsxdly[idelay];
|
||||
cur->cdelaysamplesmax = ((int)(delay * idsp_dma_speed) << sxhires) + 1;
|
||||
cur->lpdelayline = (int *)Mem_Calloc( sndpool, cur->cdelaysamplesmax * sizeof( int ));
|
||||
cur->lpdelayline = (int *)Z_Calloc( cur->cdelaysamplesmax * sizeof( int ));
|
||||
cur->xfade = 0;
|
||||
|
||||
// init modulation
|
||||
|
||||
@@ -107,18 +107,17 @@ S_CreateDefaultSound
|
||||
*/
|
||||
static wavdata_t *S_CreateDefaultSound( void )
|
||||
{
|
||||
wavdata_t *sc;
|
||||
uint samples = SOUND_DMA_SPEED;
|
||||
uint channels = 1;
|
||||
uint width = 2;
|
||||
size_t size = samples * width * channels;
|
||||
wavdata_t *sc;
|
||||
|
||||
sc = Mem_Calloc( sndpool, sizeof( wavdata_t ) + size );
|
||||
sc->width = width;
|
||||
sc->channels = channels;
|
||||
sc = Mem_Calloc( sndpool, sizeof( wavdata_t ));
|
||||
|
||||
sc->width = 2;
|
||||
sc->channels = 1;
|
||||
sc->loopStart = 0;
|
||||
sc->rate = SOUND_DMA_SPEED;
|
||||
sc->samples = samples;
|
||||
sc->size = size;
|
||||
sc->samples = SOUND_DMA_SPEED;
|
||||
sc->size = sc->samples * sc->width * sc->channels;
|
||||
sc->buffer = Mem_Calloc( sndpool, sc->size );
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
@@ -1207,6 +1207,86 @@ void S_RawSamples( uint samples, uint rate, word width, word channels, const byt
|
||||
S_RawEntSamples( entnum, samples, rate, width, channels, data, snd_vol );
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
S_PositionedRawSamples
|
||||
===================
|
||||
*/
|
||||
void S_StreamAviSamples( void *Avi, int entnum, float fvol, float attn, float synctime )
|
||||
{
|
||||
int bufferSamples;
|
||||
int fileSamples;
|
||||
byte raw[MAX_RAW_SAMPLES];
|
||||
float duration = 0.0f;
|
||||
int r, fileBytes;
|
||||
rawchan_t *ch = NULL;
|
||||
|
||||
if( !dma.initialized || s_listener.paused || !CL_IsInGame( ))
|
||||
return;
|
||||
|
||||
if( entnum < 0 || entnum >= GI->max_edicts )
|
||||
return;
|
||||
|
||||
if( !( ch = S_FindRawChannel( entnum, true )))
|
||||
return;
|
||||
|
||||
if( ch->sound_info.rate == 0 )
|
||||
{
|
||||
if( !AVI_GetAudioInfo( Avi, &ch->sound_info ))
|
||||
return; // no audiotrack
|
||||
}
|
||||
|
||||
ch->master_vol = bound( 0, fvol * 255, 255 );
|
||||
ch->dist_mult = (attn / SND_CLIP_DISTANCE);
|
||||
|
||||
// see how many samples should be copied into the raw buffer
|
||||
if( ch->s_rawend < soundtime )
|
||||
ch->s_rawend = soundtime;
|
||||
|
||||
// position is changed, synchronization is lost etc
|
||||
if( fabs( ch->oldtime - synctime ) > s_mixahead.value )
|
||||
ch->sound_info.loopStart = AVI_TimeToSoundPosition( Avi, synctime * 1000 );
|
||||
ch->oldtime = synctime; // keep actual time
|
||||
|
||||
while( ch->s_rawend < soundtime + ch->max_samples )
|
||||
{
|
||||
wavdata_t *info = &ch->sound_info;
|
||||
|
||||
bufferSamples = ch->max_samples - (ch->s_rawend - soundtime);
|
||||
|
||||
// decide how much data needs to be read from the file
|
||||
fileSamples = bufferSamples * ((float)info->rate / SOUND_DMA_SPEED );
|
||||
if( fileSamples <= 1 ) return; // no more samples need
|
||||
|
||||
// our max buffer size
|
||||
fileBytes = fileSamples * ( info->width * info->channels );
|
||||
|
||||
if( fileBytes > sizeof( raw ))
|
||||
{
|
||||
fileBytes = sizeof( raw );
|
||||
fileSamples = fileBytes / ( info->width * info->channels );
|
||||
}
|
||||
|
||||
// read audio stream
|
||||
r = AVI_GetAudioChunk( Avi, raw, info->loopStart, fileBytes );
|
||||
info->loopStart += r; // advance play position
|
||||
|
||||
if( r < fileBytes )
|
||||
{
|
||||
fileBytes = r;
|
||||
fileSamples = r / ( info->width * info->channels );
|
||||
}
|
||||
|
||||
if( r > 0 )
|
||||
{
|
||||
// add to raw buffer
|
||||
ch->s_rawend = S_RawSamplesStereo( ch->rawsamples, ch->s_rawend, ch->max_samples,
|
||||
fileSamples, info->rate, info->width, info->channels, raw );
|
||||
}
|
||||
else break; // no more samples for this frame
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
S_FreeIdleRawChannels
|
||||
@@ -1874,15 +1954,14 @@ qboolean S_Init( void )
|
||||
Cmd_AddCommand( "spk", S_SayReliable_f, "reliable play a specified sententce" );
|
||||
Cmd_AddCommand( "speak", S_Say_f, "playing a specified sententce" );
|
||||
|
||||
sndpool = Mem_AllocPool( "Sound Zone" );
|
||||
dma.backendName = "None";
|
||||
if( !SNDDMA_Init( ))
|
||||
if( !SNDDMA_Init( ) )
|
||||
{
|
||||
Con_Printf( "Audio: sound system can't be initialized\n" );
|
||||
Mem_FreePool( &sndpool );
|
||||
return false;
|
||||
}
|
||||
|
||||
sndpool = Mem_AllocPool( "Sound Zone" );
|
||||
soundtime = 0;
|
||||
paintedtime = 0;
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ GNU General Public License for more details.
|
||||
#include "common.h"
|
||||
#include "sound.h"
|
||||
#include "client.h"
|
||||
#include "soundlib.h"
|
||||
|
||||
static bg_track_t s_bgTrack;
|
||||
static musicfade_t musicfade; // controlled by game dlls
|
||||
@@ -213,7 +212,7 @@ void S_StreamBackgroundTrack( void )
|
||||
|
||||
while( ch->s_rawend < soundtime + ch->max_samples )
|
||||
{
|
||||
const stream_t *info = s_bgTrack.stream;
|
||||
wavdata_t *info = FS_StreamInfo( s_bgTrack.stream );
|
||||
|
||||
bufferSamples = ch->max_samples - (ch->s_rawend - soundtime);
|
||||
|
||||
|
||||
@@ -557,7 +557,7 @@ static void VOX_ReadSentenceFile_( byte *buf, fs_offset_t size )
|
||||
int index = cszrawsentences;
|
||||
int size = strlen( name ) + strlen( value ) + 2;
|
||||
|
||||
rgpszrawsentence[index] = Mem_Malloc( sndpool, size );
|
||||
rgpszrawsentence[index] = Mem_Malloc( host.mempool, size );
|
||||
memcpy( rgpszrawsentence[index], name, size );
|
||||
rgpszrawsentence[index][size - 1] = 0;
|
||||
cszrawsentences++;
|
||||
|
||||
@@ -114,6 +114,7 @@ typedef struct rawchan_s
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
volatile uint s_rawend;
|
||||
float oldtime; // catch time jumps
|
||||
wavdata_t sound_info; // advance play position
|
||||
size_t max_samples; // buffer length
|
||||
portable_samplepair_t rawsamples[]; // variable sized
|
||||
} rawchan_t;
|
||||
@@ -170,8 +171,6 @@ typedef struct
|
||||
int source; // may be game, menu, etc
|
||||
} bg_track_t;
|
||||
|
||||
typedef int sound_t;
|
||||
|
||||
//====================================================================
|
||||
|
||||
#define MAX_DYNAMIC_CHANNELS (60 + NUM_AMBIENTS)
|
||||
|
||||
@@ -29,20 +29,17 @@ static void Sound_Reset( void )
|
||||
|
||||
static MALLOC_LIKE( FS_FreeSound, 1 ) wavdata_t *SoundPack( void )
|
||||
{
|
||||
wavdata_t *pack = Mem_Malloc( host.soundpool, sizeof( *pack ) + sound.size );
|
||||
wavdata_t *pack = Mem_Calloc( host.soundpool, sizeof( wavdata_t ));
|
||||
|
||||
pack->buffer = sound.wav;
|
||||
pack->width = sound.width;
|
||||
pack->rate = sound.rate;
|
||||
pack->type = sound.type;
|
||||
pack->size = sound.size;
|
||||
pack->loopStart = sound.loopstart;
|
||||
pack->samples = sound.samples;
|
||||
pack->type = sound.type;
|
||||
pack->flags = sound.flags;
|
||||
pack->rate = sound.rate;
|
||||
pack->width = sound.width;
|
||||
pack->channels = sound.channels;
|
||||
memcpy( pack->buffer, sound.wav, sound.size );
|
||||
|
||||
Mem_Free( sound.wav );
|
||||
sound.wav = NULL;
|
||||
pack->flags = sound.flags;
|
||||
|
||||
return pack;
|
||||
}
|
||||
@@ -56,10 +53,12 @@ loading and unpack to wav any known sound
|
||||
*/
|
||||
wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size )
|
||||
{
|
||||
const char *ext = COM_FileExtension( filename );
|
||||
string loadname;
|
||||
qboolean anyformat = true;
|
||||
const loadwavfmt_t *format;
|
||||
const char *ext = COM_FileExtension( filename );
|
||||
string path, loadname;
|
||||
qboolean anyformat = true;
|
||||
fs_offset_t filesize = 0;
|
||||
const loadwavfmt_t *format;
|
||||
byte *f;
|
||||
|
||||
Sound_Reset(); // clear old sounddata
|
||||
Q_strncpy( loadname, filename, sizeof( loadname ));
|
||||
@@ -68,7 +67,7 @@ wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size )
|
||||
{
|
||||
// we needs to compare file extension with list of supported formats
|
||||
// and be sure what is real extension, not a filename with dot
|
||||
for( format = sound.loadformats; format && format->ext; format++ )
|
||||
for( format = sound.loadformats; format && format->formatstring; format++ )
|
||||
{
|
||||
if( !Q_stricmp( format->ext, ext ))
|
||||
{
|
||||
@@ -84,42 +83,28 @@ wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size )
|
||||
goto load_internal;
|
||||
|
||||
// now try all the formats in the selected list
|
||||
for( format = sound.loadformats; format && format->ext; format++)
|
||||
for( format = sound.loadformats; format && format->formatstring; format++)
|
||||
{
|
||||
if( anyformat || !Q_stricmp( ext, format->ext ))
|
||||
{
|
||||
qboolean success = false;
|
||||
fs_offset_t filesize = 0;
|
||||
byte *f;
|
||||
string path;
|
||||
|
||||
Q_snprintf( path, sizeof( path ), DEFAULT_SOUNDPATH "%s.%s", loadname, format->ext );
|
||||
Q_snprintf( path, sizeof( path ),
|
||||
format->formatstring, loadname, "", format->ext );
|
||||
|
||||
f = FS_LoadFile( path, &filesize, false );
|
||||
if( f && filesize > 0 )
|
||||
{
|
||||
success = format->loadfunc( path, f, filesize );
|
||||
Mem_Free( f ); // release buffer
|
||||
if( format->loadfunc( path, f, filesize ))
|
||||
{
|
||||
Mem_Free(f); // release buffer
|
||||
return SoundPack(); // loaded
|
||||
}
|
||||
else Mem_Free(f); // release buffer
|
||||
}
|
||||
|
||||
if( success )
|
||||
return SoundPack(); // loaded
|
||||
|
||||
Q_snprintf( path, sizeof( path ), "%s.%s", loadname, format->ext );
|
||||
f = FS_LoadFile( path, &filesize, false );
|
||||
if( f && filesize > 0 )
|
||||
{
|
||||
success = format->loadfunc( path, f, filesize );
|
||||
Mem_Free( f ); // release buffer
|
||||
}
|
||||
|
||||
if( success )
|
||||
return SoundPack();
|
||||
}
|
||||
}
|
||||
|
||||
load_internal:
|
||||
for( format = sound.loadformats; format && format->ext; format++ )
|
||||
for( format = sound.loadformats; format && format->formatstring; format++ )
|
||||
{
|
||||
if( anyformat || !Q_stricmp( ext, format->ext ))
|
||||
{
|
||||
@@ -147,6 +132,7 @@ free WAV buffer
|
||||
void FS_FreeSound( wavdata_t *pack )
|
||||
{
|
||||
if( !pack ) return;
|
||||
if( pack->buffer ) Mem_Free( pack->buffer );
|
||||
Mem_Free( pack );
|
||||
}
|
||||
|
||||
@@ -160,7 +146,7 @@ open and reading basic info from sound stream
|
||||
stream_t *FS_OpenStream( const char *filename )
|
||||
{
|
||||
const char *ext = COM_FileExtension( filename );
|
||||
string loadname;
|
||||
string path, loadname;
|
||||
qboolean anyformat = true;
|
||||
const streamfmt_t *format;
|
||||
stream_t *stream = NULL;
|
||||
@@ -172,7 +158,7 @@ stream_t *FS_OpenStream( const char *filename )
|
||||
{
|
||||
// we needs to compare file extension with list of supported formats
|
||||
// and be sure what is real extension, not a filename with dot
|
||||
for( format = sound.streamformat; format && format->ext; format++ )
|
||||
for( format = sound.streamformat; format && format->formatstring; format++ )
|
||||
{
|
||||
if( !Q_stricmp( format->ext, ext ))
|
||||
{
|
||||
@@ -184,13 +170,12 @@ stream_t *FS_OpenStream( const char *filename )
|
||||
}
|
||||
|
||||
// now try all the formats in the selected list
|
||||
for( format = sound.streamformat; format && format->ext; format++)
|
||||
for( format = sound.streamformat; format && format->formatstring; format++)
|
||||
{
|
||||
if( anyformat || !Q_stricmp( ext, format->ext ))
|
||||
{
|
||||
string path;
|
||||
|
||||
Q_snprintf( path, sizeof( path ), "%s.%s", loadname, format->ext );
|
||||
Q_snprintf( path, sizeof( path ),
|
||||
format->formatstring, loadname, "", format->ext );
|
||||
|
||||
if(( stream = format->openfunc( path )) != NULL )
|
||||
{
|
||||
@@ -214,6 +199,33 @@ stream_t *FS_OpenStream( const char *filename )
|
||||
return stream;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
FS_StreamInfo
|
||||
|
||||
get basic stream info
|
||||
================
|
||||
*/
|
||||
wavdata_t *FS_StreamInfo( stream_t *stream )
|
||||
{
|
||||
static wavdata_t info;
|
||||
|
||||
if( !stream ) return NULL;
|
||||
|
||||
// fill structure
|
||||
info.loopStart = 0;
|
||||
info.rate = stream->rate;
|
||||
info.width = stream->width;
|
||||
info.channels = stream->channels;
|
||||
info.flags = SOUND_STREAM;
|
||||
info.size = stream->size;
|
||||
info.buffer = NULL;
|
||||
info.samples = 0; // not actual for streams
|
||||
info.type = stream->type;
|
||||
|
||||
return &info;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
FS_ReadStream
|
||||
|
||||
@@ -17,7 +17,7 @@ GNU General Public License for more details.
|
||||
#include "base_cmd.h"
|
||||
#include "cdll_int.h"
|
||||
|
||||
#define HASH_SIZE 64 // 64 * 4 * 4 == 1024 bytes
|
||||
#define HASH_SIZE 128 // 128 * 4 * 4 == 2048 bytes
|
||||
|
||||
typedef struct base_command_hashmap_s base_command_hashmap_t;
|
||||
|
||||
@@ -26,11 +26,10 @@ struct base_command_hashmap_s
|
||||
base_command_t *basecmd; // base command: cvar, alias or command
|
||||
base_command_hashmap_t *next;
|
||||
base_command_type_e type; // type for faster searching
|
||||
char name[]; // key for searching
|
||||
char name[1]; // key for searching
|
||||
};
|
||||
|
||||
static base_command_hashmap_t *hashed_cmds[HASH_SIZE];
|
||||
static poolhandle_t basecmd_pool;
|
||||
|
||||
#define BaseCmd_HashKey( x ) COM_HashKey( name, HASH_SIZE )
|
||||
|
||||
@@ -43,27 +42,11 @@ Find base command in bucket
|
||||
*/
|
||||
static base_command_hashmap_t *BaseCmd_FindInBucket( base_command_hashmap_t *bucket, base_command_type_e type, const char *name )
|
||||
{
|
||||
base_command_hashmap_t *i;
|
||||
base_command_hashmap_t *i = bucket;
|
||||
for( ; i && ( i->type != type || Q_stricmp( name, i->name ) ); // filter out
|
||||
i = i->next );
|
||||
|
||||
for( i = bucket; i != NULL; i = i->next )
|
||||
{
|
||||
int cmp;
|
||||
|
||||
if( i->type != type )
|
||||
continue;
|
||||
|
||||
cmp = Q_stricmp( i->name, name );
|
||||
|
||||
if( cmp < 0 )
|
||||
continue;
|
||||
|
||||
if( cmp > 0 )
|
||||
break;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -102,38 +85,32 @@ BaseCmd_Find
|
||||
Find every type of base command and write into arguments
|
||||
============
|
||||
*/
|
||||
void BaseCmd_FindAll( const char *name, cmd_t **cmd, cmdalias_t **alias, convar_t **cvar )
|
||||
void BaseCmd_FindAll( const char *name, base_command_t **cmd, base_command_t **alias, base_command_t **cvar )
|
||||
{
|
||||
base_command_hashmap_t *base = BaseCmd_GetBucket( name );
|
||||
base_command_hashmap_t *i = base;
|
||||
|
||||
*cmd = NULL;
|
||||
*alias = NULL;
|
||||
*cvar = NULL;
|
||||
ASSERT( cmd && alias && cvar );
|
||||
|
||||
*cmd = *alias = *cvar = NULL;
|
||||
|
||||
for( ; i; i = i->next )
|
||||
{
|
||||
int cmp = Q_stricmp( i->name, name );
|
||||
|
||||
if( cmp < 0 )
|
||||
continue;
|
||||
|
||||
if( cmp > 0 )
|
||||
break;
|
||||
|
||||
switch( i->type )
|
||||
if( !Q_stricmp( i->name, name ) )
|
||||
{
|
||||
case HM_CMD:
|
||||
*cmd = (cmd_t *)i->basecmd;
|
||||
break;
|
||||
case HM_CMDALIAS:
|
||||
*alias = (cmdalias_t *)i->basecmd;
|
||||
break;
|
||||
case HM_CVAR:
|
||||
*cvar = (convar_t *)i->basecmd;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch( i->type )
|
||||
{
|
||||
case HM_CMD:
|
||||
*cmd = i->basecmd;
|
||||
break;
|
||||
case HM_CMDALIAS:
|
||||
*alias = i->basecmd;
|
||||
break;
|
||||
case HM_CVAR:
|
||||
*cvar = i->basecmd;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,14 +128,14 @@ void BaseCmd_Insert( base_command_type_e type, base_command_t *basecmd, const ch
|
||||
uint hash = BaseCmd_HashKey( name );
|
||||
size_t len = Q_strlen( name );
|
||||
|
||||
elem = Mem_Malloc( basecmd_pool, sizeof( base_command_hashmap_t ) + len + 1 );
|
||||
elem = Z_Malloc( sizeof( base_command_hashmap_t ) + len );
|
||||
elem->basecmd = basecmd;
|
||||
elem->type = type;
|
||||
Q_strncpy( elem->name, name, len + 1 );
|
||||
|
||||
// link the variable in alphanumerical order
|
||||
for( cur = NULL, find = hashed_cmds[hash];
|
||||
find && Q_stricmp( find->name, elem->name ) < 0;
|
||||
find && Q_strcmp( find->name, elem->name ) < 0;
|
||||
cur = find, find = find->next );
|
||||
|
||||
if( cur ) cur->next = elem;
|
||||
@@ -179,23 +156,9 @@ void BaseCmd_Remove( base_command_type_e type, const char *name )
|
||||
uint hash = BaseCmd_HashKey( name );
|
||||
base_command_hashmap_t *i, *prev;
|
||||
|
||||
for( prev = NULL, i = hashed_cmds[hash]; i != NULL; prev = i, i = i->next )
|
||||
{
|
||||
int cmp;
|
||||
|
||||
if( i->type != type )
|
||||
continue;
|
||||
|
||||
cmp = Q_stricmp( i->name, name );
|
||||
|
||||
if( cmp < 0 )
|
||||
continue;
|
||||
|
||||
if( cmp > 0 )
|
||||
i = NULL;
|
||||
|
||||
break;
|
||||
}
|
||||
for( prev = NULL, i = hashed_cmds[hash]; i &&
|
||||
( Q_strcmp( i->name, name ) || i->type != type); // filter out
|
||||
prev = i, i = i->next );
|
||||
|
||||
if( !i )
|
||||
{
|
||||
@@ -220,15 +183,9 @@ initialize base command hashmap system
|
||||
*/
|
||||
void BaseCmd_Init( void )
|
||||
{
|
||||
basecmd_pool = Mem_AllocPool( "BaseCmd" );
|
||||
memset( hashed_cmds, 0, sizeof( hashed_cmds ) );
|
||||
}
|
||||
|
||||
void BaseCmd_Shutdown( void )
|
||||
{
|
||||
Mem_FreePool( &basecmd_pool );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Stats_f
|
||||
|
||||
@@ -21,9 +21,6 @@ GNU General Public License for more details.
|
||||
|
||||
#ifdef XASH_HASHED_VARS
|
||||
|
||||
#include "common.h"
|
||||
#include "cdll_int.h"
|
||||
|
||||
typedef enum base_command_type
|
||||
{
|
||||
HM_DONTCARE = 0,
|
||||
@@ -35,9 +32,9 @@ typedef enum base_command_type
|
||||
typedef void base_command_t;
|
||||
|
||||
void BaseCmd_Init( void );
|
||||
void BaseCmd_Shutdown( void );
|
||||
base_command_t *BaseCmd_Find( base_command_type_e type, const char *name );
|
||||
void BaseCmd_FindAll( const char *name, cmd_t **cmd, cmdalias_t **alias, convar_t **cvar );
|
||||
void BaseCmd_FindAll( const char *name,
|
||||
base_command_t **cmd, base_command_t **alias, base_command_t **cvar );
|
||||
void BaseCmd_Insert ( base_command_type_e type, base_command_t *basecmd, const char *name );
|
||||
void BaseCmd_Remove ( base_command_type_e type, const char *name );
|
||||
void BaseCmd_Stats_f( void ); // to be registered later
|
||||
|
||||
@@ -46,7 +46,6 @@ static cmdalias_t *cmd_alias;
|
||||
static uint cmd_condition;
|
||||
static int cmd_condlevel;
|
||||
static qboolean cmd_currentCommandIsPrivileged;
|
||||
static poolhandle_t cmd_pool;
|
||||
|
||||
static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPrivileged );
|
||||
|
||||
@@ -433,7 +432,7 @@ static void Cmd_Alias_f( void )
|
||||
{
|
||||
if( !Q_strcmp( s, a->name ))
|
||||
{
|
||||
Mem_Free( a->value );
|
||||
Z_Free( a->value );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -442,7 +441,7 @@ static void Cmd_Alias_f( void )
|
||||
{
|
||||
cmdalias_t *cur, *prev;
|
||||
|
||||
a = Mem_Malloc( cmd_pool, sizeof( cmdalias_t ));
|
||||
a = Z_Malloc( sizeof( cmdalias_t ));
|
||||
|
||||
Q_strncpy( a->name, s, sizeof( a->name ));
|
||||
|
||||
@@ -470,7 +469,7 @@ static void Cmd_Alias_f( void )
|
||||
}
|
||||
|
||||
Q_strncat( cmd, "\n", sizeof( cmd ));
|
||||
a->value = copystringpool( cmd_pool, cmd );
|
||||
a->value = copystring( cmd );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -526,17 +525,51 @@ static void Cmd_UnAlias_f ( void )
|
||||
*/
|
||||
struct cmd_s
|
||||
{
|
||||
cmd_t *next;
|
||||
char *name;
|
||||
xcommand_t function;
|
||||
int flags;
|
||||
char desc[];
|
||||
struct cmd_s *next;
|
||||
char *name;
|
||||
xcommand_t function;
|
||||
int flags;
|
||||
char *desc;
|
||||
};
|
||||
|
||||
int cmd_argc;
|
||||
const char *cmd_args = NULL;
|
||||
char *cmd_argv[MAX_CMD_TOKENS];
|
||||
static cmd_t *cmd_functions; // possible commands to execute
|
||||
static int cmd_argc;
|
||||
static const char *cmd_args = NULL;
|
||||
static char *cmd_argv[MAX_CMD_TOKENS];
|
||||
static cmd_t *cmd_functions; // possible commands to execute
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_Argc
|
||||
============
|
||||
*/
|
||||
int GAME_EXPORT Cmd_Argc( void )
|
||||
{
|
||||
return cmd_argc;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_Argv
|
||||
============
|
||||
*/
|
||||
const char *GAME_EXPORT Cmd_Argv( int arg )
|
||||
{
|
||||
if((uint)arg >= cmd_argc )
|
||||
return "";
|
||||
return cmd_argv[arg];
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_Args
|
||||
============
|
||||
*/
|
||||
const char *GAME_EXPORT Cmd_Args( void )
|
||||
{
|
||||
return cmd_args;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========================
|
||||
|
||||
@@ -544,6 +577,8 @@ Client exports
|
||||
|
||||
===========================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_AliasGetList
|
||||
@@ -601,7 +636,7 @@ void Cmd_TokenizeString( const char *text )
|
||||
|
||||
// clear the args from the last string
|
||||
for( i = 0; i < cmd_argc; i++ )
|
||||
Mem_Free( cmd_argv[i] );
|
||||
Z_Free( cmd_argv[i] );
|
||||
|
||||
cmd_argc = 0; // clear previous args
|
||||
cmd_args = NULL;
|
||||
@@ -635,7 +670,7 @@ void Cmd_TokenizeString( const char *text )
|
||||
|
||||
if( cmd_argc < MAX_CMD_TOKENS )
|
||||
{
|
||||
cmd_argv[cmd_argc] = copystringpool( cmd_pool, cmd_token );
|
||||
cmd_argv[cmd_argc] = copystring( cmd_token );
|
||||
cmd_argc++;
|
||||
}
|
||||
}
|
||||
@@ -648,8 +683,7 @@ Cmd_AddCommandEx
|
||||
*/
|
||||
int Cmd_AddCommandEx( const char *cmd_name, xcommand_t function, const char *cmd_desc, int iFlags, const char *funcname )
|
||||
{
|
||||
cmd_t *cmd, *cur, *prev;
|
||||
size_t desc_len;
|
||||
cmd_t *cmd, *cur, *prev;
|
||||
|
||||
if( !COM_CheckString( cmd_name ))
|
||||
{
|
||||
@@ -673,8 +707,8 @@ int Cmd_AddCommandEx( const char *cmd_name, xcommand_t function, const char *cmd
|
||||
// unfortunately, we lose original command this way
|
||||
if( FBitSet( cmd->flags, CMD_OVERRIDABLE ))
|
||||
{
|
||||
desc_len = Q_strlen( cmd->desc ) + 1;
|
||||
Q_strncpy( cmd->desc, cmd_desc, desc_len );
|
||||
Mem_Free( cmd->desc );
|
||||
cmd->desc = copystring( cmd_desc );
|
||||
cmd->function = function;
|
||||
cmd->flags = iFlags;
|
||||
|
||||
@@ -689,10 +723,9 @@ int Cmd_AddCommandEx( const char *cmd_name, xcommand_t function, const char *cmd
|
||||
}
|
||||
|
||||
// use a small malloc to avoid zone fragmentation
|
||||
desc_len = Q_strlen( cmd_desc ) + 1;
|
||||
cmd = Mem_Malloc( cmd_pool, sizeof( cmd_t ) + desc_len );
|
||||
cmd->name = copystringpool( cmd_pool, cmd_name );
|
||||
Q_strncpy( cmd->desc, cmd_desc, desc_len );
|
||||
cmd = Z_Malloc( sizeof( cmd_t ) );
|
||||
cmd->name = copystring( cmd_name );
|
||||
cmd->desc = copystring( cmd_desc );
|
||||
cmd->function = function;
|
||||
cmd->flags = iFlags;
|
||||
|
||||
@@ -739,6 +772,9 @@ void GAME_EXPORT Cmd_RemoveCommand( const char *cmd_name )
|
||||
if( cmd->name )
|
||||
Mem_Free( cmd->name );
|
||||
|
||||
if( cmd->desc )
|
||||
Mem_Free( cmd->desc );
|
||||
|
||||
Mem_Free( cmd );
|
||||
return;
|
||||
}
|
||||
@@ -958,20 +994,24 @@ static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPr
|
||||
|
||||
if( !Cmd_Argc( )) return; // no tokens
|
||||
|
||||
#if defined( XASH_HASHED_VARS )
|
||||
BaseCmd_FindAll( cmd_argv[0], &cmd, &a, &cvar );
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
BaseCmd_FindAll( cmd_argv[0],
|
||||
(base_command_t**)&cmd,
|
||||
(base_command_t**)&a,
|
||||
(base_command_t**)&cvar );
|
||||
#endif
|
||||
|
||||
if( !host.apply_game_config )
|
||||
{
|
||||
#if !defined( XASH_HASHED_VARS )
|
||||
// check aliases
|
||||
for( a = cmd_alias; a; a = a->next )
|
||||
if( !a ) // if not found in basecmd
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], a->name ))
|
||||
break;
|
||||
for( a = cmd_alias; a; a = a->next )
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], a->name ))
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( a )
|
||||
{
|
||||
@@ -986,13 +1026,14 @@ static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPr
|
||||
// special mode for restore game.dll archived cvars
|
||||
if( !host.apply_game_config || !Q_strcmp( cmd_argv[0], "exec" ))
|
||||
{
|
||||
#if !defined( XASH_HASHED_VARS )
|
||||
for( cmd = cmd_functions; cmd; cmd = cmd->next )
|
||||
if( !cmd || !cmd->function ) // if not found in basecmd
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], cmd->name ) && cmd->function )
|
||||
break;
|
||||
for( cmd = cmd_functions; cmd; cmd = cmd->next )
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], cmd->name ) && cmd->function )
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// check functions
|
||||
if( cmd && cmd->function )
|
||||
@@ -1161,6 +1202,7 @@ void Cmd_Unlink( int group )
|
||||
*prev = cmd->next;
|
||||
|
||||
if( cmd->name ) Mem_Free( cmd->name );
|
||||
if( cmd->desc ) Mem_Free( cmd->desc );
|
||||
|
||||
Mem_Free( cmd );
|
||||
count++;
|
||||
@@ -1257,50 +1299,6 @@ void Cmd_Null_f( void )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Cmd_MakePrivileged_f
|
||||
=============
|
||||
*/
|
||||
static void Cmd_MakePrivileged_f( void )
|
||||
{
|
||||
const char *s = Cmd_Argv( 1 );
|
||||
convar_t *cv;
|
||||
cmd_t *cmd;
|
||||
cmdalias_t *alias;
|
||||
|
||||
if( Cmd_Argc( ) != 2 )
|
||||
{
|
||||
Con_Printf( S_USAGE "make_privileged <cvar or command>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined( XASH_HASHED_VARS )
|
||||
BaseCmd_FindAll( s, &cmd, &alias, &cv );
|
||||
#else
|
||||
cmd = Cmd_Exists( s );
|
||||
cv = Cvar_FindVar( s );
|
||||
#endif
|
||||
|
||||
if( !cv && !cmd )
|
||||
{
|
||||
Con_Printf( "Nothing was found.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( cv )
|
||||
{
|
||||
SetBits( cv->flags, FCVAR_PRIVILEGED );
|
||||
Con_Printf( "Cvar %s set to be privileged\n", cv->name );
|
||||
}
|
||||
|
||||
if( cmd )
|
||||
{
|
||||
SetBits( cmd->flags, CMD_PRIVILEGED );
|
||||
Con_Printf( "Command %s set to be privileged\n", cmd->name );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
Cmd_Escape
|
||||
@@ -1342,7 +1340,6 @@ Cmd_Init
|
||||
*/
|
||||
void Cmd_Init( void )
|
||||
{
|
||||
cmd_pool = Mem_AllocPool( "Console Commands" );
|
||||
cmd_functions = NULL;
|
||||
cmd_condition = 0;
|
||||
cmd_alias = NULL;
|
||||
@@ -1363,19 +1360,12 @@ void Cmd_Init( void )
|
||||
Cmd_AddRestrictedCommand( "if", Cmd_If_f, "compare and set condition bits" );
|
||||
Cmd_AddRestrictedCommand( "else", Cmd_Else_f, "invert condition bit" );
|
||||
|
||||
Cmd_AddRestrictedCommand( "make_privileged", Cmd_MakePrivileged_f, "makes command or variable privileged (protected from access attempts from server)" );
|
||||
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
Cmd_AddCommand( "basecmd_stats", BaseCmd_Stats_f, "print info about basecmd usage" );
|
||||
Cmd_AddCommand( "basecmd_test", BaseCmd_Test_f, "test basecmd" );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Cmd_Shutdown( void )
|
||||
{
|
||||
Mem_FreePool( &cmd_pool );
|
||||
}
|
||||
|
||||
#if XASH_ENGINE_TESTS
|
||||
#include "tests.h"
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ static void LZSS_BuildHash( lzss_state_t *state, const byte *source )
|
||||
{
|
||||
lzss_list_t *list;
|
||||
lzss_node_t *node;
|
||||
unsigned int targetindex = (uintptr_t)source & ( state->window_size - 1 );
|
||||
unsigned int targetindex = (uint)source & ( state->window_size - 1 );
|
||||
|
||||
node = &state->hash_node[targetindex];
|
||||
|
||||
@@ -900,7 +900,7 @@ float GAME_EXPORT pfnTime( void )
|
||||
qboolean COM_IsSafeFileToDownload( const char *filename )
|
||||
{
|
||||
char lwrfilename[4096];
|
||||
const char *last;
|
||||
const char *first, *last;
|
||||
const char *ext;
|
||||
size_t len;
|
||||
int i;
|
||||
@@ -934,27 +934,25 @@ qboolean COM_IsSafeFileToDownload( const char *filename )
|
||||
return true;
|
||||
}
|
||||
|
||||
for( i = 0; i < len; i++ )
|
||||
{
|
||||
if( !isprint( filename[i] ))
|
||||
return false;
|
||||
}
|
||||
|
||||
Q_strnlwr( filename, lwrfilename, sizeof( lwrfilename ));
|
||||
ext = COM_FileExtension( lwrfilename );
|
||||
|
||||
if( Q_strpbrk( lwrfilename, "\\:~" ) || Q_strstr( lwrfilename, ".." ))
|
||||
if( Q_strpbrk( lwrfilename, "\\:~" ) || Q_strstr( lwrfilename, ".." ) )
|
||||
return false;
|
||||
|
||||
if( lwrfilename[0] == '/' )
|
||||
return false;
|
||||
|
||||
first = Q_strchr( lwrfilename, '.' );
|
||||
last = Q_strrchr( lwrfilename, '.' );
|
||||
|
||||
if( last == NULL )
|
||||
if( first == NULL || last == NULL )
|
||||
return false;
|
||||
|
||||
if( Q_strlen( last ) != 4 )
|
||||
if( first != last )
|
||||
return false;
|
||||
|
||||
if( Q_strlen( first ) != 4 )
|
||||
return false;
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( file_exts ); i++ )
|
||||
@@ -1133,7 +1131,6 @@ void Test_RunCommon( void )
|
||||
{
|
||||
Msg( "Checking COM_IsSafeFileToDownload...\n" );
|
||||
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "models/bsg_props/[hl-lab.ru]bush.mdl" ), true );
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD5AAB5E8B307672DA86FBD10AC302BC732" ), true );
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD56f1ffd8c96bd64c9c27955309f6ecfe6" ), false );
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD5AAB5E8B307672DA86FBD10AC302B.exe" ), false );
|
||||
|
||||
@@ -76,14 +76,23 @@ XASH SPECIFIC - sort of hack that works only in Xash3D not in GoldSrc
|
||||
|
||||
#define HACKS_RELATED_HLMODS // some HL-mods works differently under Xash and can't be fixed without some hacks at least at current time
|
||||
|
||||
enum dev_level_e
|
||||
enum
|
||||
{
|
||||
DEV_NONE = 0,
|
||||
DEV_NORMAL,
|
||||
DEV_EXTENDED
|
||||
};
|
||||
|
||||
typedef enum instance_e
|
||||
enum
|
||||
{
|
||||
D_INFO = 1, // "-dev 1", shows various system messages
|
||||
D_WARN, // "-dev 2", shows not critical system warnings
|
||||
D_ERROR, // "-dev 3", shows critical warnings
|
||||
D_REPORT, // "-dev 4", special case for game reports
|
||||
D_NOTE // "-dev 5", show system notifications for engine developers
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
HOST_NORMAL, // listen server, singleplayer
|
||||
HOST_DEDICATED,
|
||||
@@ -99,14 +108,14 @@ typedef enum instance_e
|
||||
#include "com_model.h"
|
||||
#include "com_strings.h"
|
||||
#include "crtlib.h"
|
||||
#define FSCALLBACK_OVERRIDE_OPEN
|
||||
#define FSCALLBACK_OVERRIDE_LOADFILE
|
||||
#define FSCALLBACK_OVERRIDE_MALLOC_LIKE
|
||||
#include "fscallback.h"
|
||||
#include "cvar.h"
|
||||
#include "con_nprint.h"
|
||||
#include "crclib.h"
|
||||
#include "ref_api.h"
|
||||
#define FSCALLBACK_OVERRIDE_OPEN
|
||||
#define FSCALLBACK_OVERRIDE_LOADFILE
|
||||
#define FSCALLBACK_OVERRIDE_MALLOC_LIKE
|
||||
#include "fscallback.h"
|
||||
|
||||
// PERFORMANCE INFO
|
||||
#define MIN_FPS 20.0f // host minimum fps value for maxfps.
|
||||
@@ -137,11 +146,6 @@ typedef enum instance_e
|
||||
#define MAX_STATIC_ENTITIES 32 // static entities that moved on the client when level is spawn
|
||||
#endif
|
||||
|
||||
#define MAX_SERVERINFO_STRING 512 // server handles too many settings. expand to 1024?
|
||||
#define MAX_PRINT_MSG 8192 // how many symbols can handle single call of Con_Printf or Con_DPrintf
|
||||
#define MAX_TOKEN 2048 // parse token length
|
||||
#define MAX_USERMSG_LENGTH 2048 // don't modify it's relies on a client-side definitions
|
||||
|
||||
#define GameState (&host.game)
|
||||
|
||||
#define FORCE_DRAW_VERSION_TIME 5.0 // draw version for 5 seconds
|
||||
@@ -167,11 +171,6 @@ extern convar_t cl_filterstuffcmd;
|
||||
extern convar_t rcon_password;
|
||||
extern convar_t hpk_custom_file;
|
||||
extern convar_t con_gamemaps;
|
||||
extern convar_t fs_mount_lv;
|
||||
extern convar_t fs_mount_hd;
|
||||
extern convar_t fs_mount_addon;
|
||||
extern convar_t fs_mount_l10n;
|
||||
extern convar_t ui_language; // historically used for UI, but now controls mounted localization directory
|
||||
|
||||
#define Mod_AllowMaterials() ( host_allow_materials.value != 0.0f && !FBitSet( host.features, ENGINE_DISABLE_HDTEXTURES ))
|
||||
|
||||
@@ -190,7 +189,7 @@ GAMEINFO stuff
|
||||
internal shared gameinfo structure (readonly for engine parts)
|
||||
========================================================================
|
||||
*/
|
||||
typedef enum host_status_e
|
||||
typedef enum
|
||||
{
|
||||
HOST_INIT = 0, // initalize operations
|
||||
HOST_FRAME, // host running
|
||||
@@ -201,7 +200,7 @@ typedef enum host_status_e
|
||||
HOST_CRASHED // an exception handler called
|
||||
} host_status_t;
|
||||
|
||||
typedef enum host_state_e
|
||||
typedef enum
|
||||
{
|
||||
STATE_RUNFRAME = 0,
|
||||
STATE_LOAD_LEVEL,
|
||||
@@ -210,7 +209,7 @@ typedef enum host_state_e
|
||||
STATE_GAME_SHUTDOWN,
|
||||
} host_state_t;
|
||||
|
||||
typedef struct game_status_e
|
||||
typedef struct
|
||||
{
|
||||
host_state_t curstate;
|
||||
host_state_t nextstate;
|
||||
@@ -221,7 +220,7 @@ typedef struct game_status_e
|
||||
qboolean newGame; // unload the server.dll before start a new map
|
||||
} game_status_t;
|
||||
|
||||
typedef enum keydest_e
|
||||
typedef enum
|
||||
{
|
||||
key_console = 0,
|
||||
key_game,
|
||||
@@ -229,7 +228,7 @@ typedef enum keydest_e
|
||||
key_message
|
||||
} keydest_t;
|
||||
|
||||
typedef enum rdtype_e
|
||||
typedef enum
|
||||
{
|
||||
RD_NONE = 0,
|
||||
RD_CLIENT,
|
||||
@@ -239,7 +238,7 @@ typedef enum rdtype_e
|
||||
#include "net_ws.h"
|
||||
|
||||
// console field
|
||||
typedef struct field_e
|
||||
typedef struct
|
||||
{
|
||||
string buffer;
|
||||
int cursor;
|
||||
@@ -257,7 +256,7 @@ typedef struct host_redirect_s
|
||||
int lines;
|
||||
} host_redirect_t;
|
||||
|
||||
typedef struct soundlist_e
|
||||
typedef struct
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
short entnum;
|
||||
@@ -298,7 +297,7 @@ typedef struct host_parm_s
|
||||
|
||||
host_status_t status; // global host state
|
||||
game_status_t game; // game manager
|
||||
instance_t type; // running at
|
||||
uint type; // running at
|
||||
poolhandle_t mempool; // static mempool for misc allocations
|
||||
poolhandle_t imagepool; // imagelib mempool
|
||||
poolhandle_t soundpool; // soundlib mempool
|
||||
@@ -342,6 +341,7 @@ typedef struct host_parm_s
|
||||
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
|
||||
qboolean crashed; // set to true if crashed
|
||||
#if XASH_DLL_LOADER
|
||||
qboolean enabledll;
|
||||
#endif
|
||||
@@ -357,7 +357,6 @@ typedef struct host_parm_s
|
||||
int window_center_y;
|
||||
string gamedll;
|
||||
string clientlib;
|
||||
string menulib;
|
||||
} host_parm_t;
|
||||
|
||||
extern host_parm_t host;
|
||||
@@ -415,37 +414,11 @@ byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamediro
|
||||
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
|
||||
byte *FS_LoadDirectFile( const char *path, fs_offset_t *filesizeptr )
|
||||
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
|
||||
void FS_Rescan_f( void );
|
||||
void FS_CheckConfig( void );
|
||||
|
||||
//
|
||||
// cmd.c
|
||||
//
|
||||
typedef struct cmd_s cmd_t;
|
||||
|
||||
static inline int GAME_EXPORT Cmd_Argc( void )
|
||||
{
|
||||
extern int cmd_argc;
|
||||
return cmd_argc;
|
||||
}
|
||||
|
||||
static inline const char *GAME_EXPORT RETURNS_NONNULL Cmd_Argv( int arg )
|
||||
{
|
||||
extern int cmd_argc;
|
||||
extern char *cmd_argv[MAX_CMD_TOKENS];
|
||||
|
||||
if((uint)arg >= cmd_argc )
|
||||
return "";
|
||||
return cmd_argv[arg];
|
||||
}
|
||||
|
||||
static inline const char *GAME_EXPORT RETURNS_NONNULL Cmd_Args( void )
|
||||
{
|
||||
extern const char *cmd_args;
|
||||
|
||||
return cmd_args;
|
||||
}
|
||||
|
||||
void Cbuf_Clear( void );
|
||||
void Cbuf_AddText( const char *text );
|
||||
void Cbuf_AddTextf( const char *text, ... ) FORMAT_CHECK( 1 );
|
||||
@@ -455,8 +428,10 @@ void Cbuf_InsertTextLen( const char *text, size_t len, size_t requested_len );
|
||||
void Cbuf_ExecStuffCmds( void );
|
||||
void Cbuf_Execute (void);
|
||||
qboolean Cmd_CurrentCommandIsPrivileged( void );
|
||||
int Cmd_Argc( void );
|
||||
const char *Cmd_Args( void ) RETURNS_NONNULL;
|
||||
const char *Cmd_Argv( int arg ) RETURNS_NONNULL;
|
||||
void Cmd_Init( void );
|
||||
void Cmd_Shutdown( void );
|
||||
void Cmd_Unlink( int group );
|
||||
int Cmd_AddCommandEx( const char *cmd_name, xcommand_t function, const char *cmd_desc, int flags, const char *funcname );
|
||||
|
||||
@@ -515,7 +490,7 @@ internal sound format
|
||||
typically expanded to wav buffer
|
||||
========================================================================
|
||||
*/
|
||||
typedef enum sndformat_e
|
||||
typedef enum
|
||||
{
|
||||
WF_UNKNOWN = 0,
|
||||
WF_PCMDATA,
|
||||
@@ -526,7 +501,7 @@ typedef enum sndformat_e
|
||||
} sndformat_t;
|
||||
|
||||
// wavdata output flags
|
||||
typedef enum sndFlags_e
|
||||
typedef enum
|
||||
{
|
||||
// wavdata->flags
|
||||
SOUND_LOOPED = BIT( 0 ), // this is looped sound (contain cue markers)
|
||||
@@ -536,29 +511,29 @@ typedef enum sndFlags_e
|
||||
SOUND_RESAMPLE = BIT( 12 ), // resample sound to specified rate
|
||||
} sndFlags_t;
|
||||
|
||||
typedef struct wavdata_s
|
||||
typedef struct
|
||||
{
|
||||
size_t size; // for bounds checking
|
||||
word rate; // num samples per second (e.g. 11025 - 11 khz)
|
||||
byte width; // resolution - bum bits divided by 8 (8 bit is 1, 16 bit is 2)
|
||||
byte channels; // num channels (1 - mono, 2 - stereo)
|
||||
uint loopStart; // offset at this point sound will be looping while playing more than only once
|
||||
uint samples; // total samplecount in wav
|
||||
uint type; // compression type
|
||||
uint flags; // misc sound flags
|
||||
word rate; // num samples per second (e.g. 11025 - 11 khz)
|
||||
byte width; // resolution - bum bits divided by 8 (8 bit is 1, 16 bit is 2)
|
||||
byte channels; // num channels (1 - mono, 2 - stereo)
|
||||
byte buffer[]; // sound buffer
|
||||
byte *buffer; // sound buffer
|
||||
size_t size; // for bounds checking
|
||||
} wavdata_t;
|
||||
|
||||
//
|
||||
// soundlib
|
||||
//
|
||||
typedef struct stream_s stream_t;
|
||||
void Sound_Init( void );
|
||||
void Sound_Shutdown( void );
|
||||
void FS_FreeSound( wavdata_t *pack );
|
||||
void FS_FreeStream( stream_t *stream );
|
||||
wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size ) MALLOC_LIKE( FS_FreeSound, 1 ) WARN_UNUSED_RESULT;
|
||||
stream_t *FS_OpenStream( const char *filename ) MALLOC_LIKE( FS_FreeStream, 1 ) WARN_UNUSED_RESULT;
|
||||
wavdata_t *FS_StreamInfo( stream_t *stream );
|
||||
int FS_ReadStream( stream_t *stream, int bytes, void *buffer );
|
||||
int FS_SetStreamPos( stream_t *stream, int newpos );
|
||||
int FS_GetStreamPos( stream_t *stream );
|
||||
@@ -653,7 +628,6 @@ int pfnNumberOfEntities( void );
|
||||
int pfnIsInGame( void );
|
||||
float pfnTime( void );
|
||||
#define copystring( s ) _copystring( host.mempool, s, __FILE__, __LINE__ )
|
||||
#define copystringpool( pool, s ) _copystring( pool, s, __FILE__, __LINE__ )
|
||||
#define SV_CopyString( s ) _copystring( svgame.stringspool, s, __FILE__, __LINE__ )
|
||||
#define freestring( s ) if( s != NULL ) { Mem_Free( s ); s = NULL; }
|
||||
char *_copystring( poolhandle_t mempool, const char *s, const char *filename, int fileline );
|
||||
@@ -704,7 +678,6 @@ int CSCR_WriteGameCVars( file_t *cfg, const char *scriptfilename );
|
||||
//
|
||||
// hpak.c
|
||||
//
|
||||
const char *COM_ResourceTypeFromIndex( int index );
|
||||
void HPAK_Init( void );
|
||||
qboolean HPAK_GetDataPointer( const char *filename, struct resource_s *pRes, byte **buffer, int *size );
|
||||
qboolean HPAK_ResourceForHash( const char *filename, byte *hash, struct resource_s *pRes );
|
||||
@@ -752,7 +725,7 @@ qboolean UI_CreditsActive( void );
|
||||
int CL_GetMaxClients( void );
|
||||
#else
|
||||
static inline qboolean CL_Initialized( void ) { return false; }
|
||||
static inline qboolean CL_IsInGame( void ) { return true; } // always true for dedicated
|
||||
static inline qboolean CL_IsInGame( void ) { return false; }
|
||||
static inline qboolean CL_IsInConsole( void ) { return false; }
|
||||
static inline qboolean CL_IsIntermission( void ) { return false; }
|
||||
static inline qboolean CL_DisableVisibility( void ) { return false; }
|
||||
@@ -811,7 +784,7 @@ void Con_NPrintf( int idx, const char *fmt, ... ) FORMAT_CHECK( 2 );
|
||||
void Con_NXPrintf( con_nprint_t *info, const char *fmt, ... ) FORMAT_CHECK( 2 );
|
||||
void UI_NPrintf( int idx, const char *fmt, ... ) FORMAT_CHECK( 2 );
|
||||
void UI_NXPrintf( con_nprint_t *info, const char *fmt, ... ) FORMAT_CHECK( 2 );
|
||||
const char *Info_ValueForKey( const char *s, const char *key ) RETURNS_NONNULL NONNULL;
|
||||
const char *Info_ValueForKey( const char *s, const char *key );
|
||||
void Info_RemovePrefixedKeys( char *start, char prefix );
|
||||
qboolean Info_RemoveKey( char *s, const char *key );
|
||||
qboolean Info_SetValueForKey( char *s, const char *key, const char *value, int maxsize );
|
||||
@@ -894,6 +867,13 @@ void V_CheckGamma( void );
|
||||
void V_CheckGammaEnd( void );
|
||||
intptr_t V_GetGammaPtr( int parm );
|
||||
|
||||
//
|
||||
// identification.c
|
||||
//
|
||||
void ID_Init( void );
|
||||
const char *ID_GetMD5( void );
|
||||
void GAME_EXPORT ID_SetCustomClientID( const char *id );
|
||||
|
||||
//
|
||||
// masterlist.c
|
||||
//
|
||||
|
||||
@@ -498,6 +498,7 @@ static qboolean Cmd_GetSoundList( const char *s, char *completedname, int length
|
||||
return true;
|
||||
}
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
/*
|
||||
=====================================
|
||||
Cmd_GetItemsList
|
||||
@@ -507,7 +508,6 @@ Prints or complete item classname (weapons only)
|
||||
*/
|
||||
static qboolean Cmd_GetItemsList( const char *s, char *completedname, int length )
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
search_t *t;
|
||||
string matchbuf;
|
||||
int i, numitems;
|
||||
@@ -521,7 +521,7 @@ static qboolean Cmd_GetItemsList( const char *s, char *completedname, int length
|
||||
Q_strncpy( completedname, matchbuf, length );
|
||||
if( t->numfilenames == 1 ) return true;
|
||||
|
||||
for( i = 0, numitems = 0; i < t->numfilenames; i++ )
|
||||
for(i = 0, numitems = 0; i < t->numfilenames; i++)
|
||||
{
|
||||
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "txt" ))
|
||||
continue;
|
||||
@@ -544,8 +544,6 @@ static qboolean Cmd_GetItemsList( const char *s, char *completedname, int length
|
||||
}
|
||||
}
|
||||
return true;
|
||||
#endif // !XASH_DEDICATED
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -557,7 +555,6 @@ Autocomplete for bind command
|
||||
*/
|
||||
static qboolean Cmd_GetKeysList( const char *s, char *completedname, int length )
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
size_t i, numkeys;
|
||||
string keys[256];
|
||||
string matchbuf;
|
||||
@@ -598,9 +595,8 @@ static qboolean Cmd_GetKeysList( const char *s, char *completedname, int length
|
||||
}
|
||||
|
||||
return true;
|
||||
#endif // !XASH_DEDICATED
|
||||
return false;
|
||||
}
|
||||
#endif // XASH_DEDICATED
|
||||
|
||||
/*
|
||||
===============
|
||||
@@ -608,20 +604,13 @@ Con_AddCommandToList
|
||||
|
||||
===============
|
||||
*/
|
||||
static void Con_AddCommandToList( const char *s, const char *value, const void *ptoggle, void *_autocompleteList )
|
||||
static void Con_AddCommandToList( const char *s, const char *unused1, const char *unused2, void *_autocompleteList )
|
||||
{
|
||||
con_autocomplete_t *list = (con_autocomplete_t*)_autocompleteList;
|
||||
qboolean toggle = ptoggle != NULL && *(qboolean *)ptoggle;
|
||||
|
||||
if( *s == '@' ) return; // never show system cvars or cmds
|
||||
if( list->matchCount >= CON_MAXCMDS ) return; // list is full
|
||||
|
||||
if( toggle )
|
||||
{
|
||||
if( Q_strcmp( value, "0" ) && Q_strcmp( value, "1" ))
|
||||
return; // exclude non-toggable cvars
|
||||
}
|
||||
|
||||
if( Q_strnicmp( s, list->completionString, Q_strlen( list->completionString ) ) )
|
||||
return; // no match
|
||||
|
||||
@@ -645,11 +634,13 @@ Cmd_GetCommandsList
|
||||
Autocomplete for bind command
|
||||
=====================================
|
||||
*/
|
||||
static qboolean Cmd_GetCommandsAndCvarsList( const char *s, char *completedname, int length, qboolean cmds, qboolean cvars, qboolean toggle )
|
||||
static qboolean Cmd_GetCommandsList( const char *s, char *completedname, int length )
|
||||
{
|
||||
size_t i;
|
||||
string matchbuf;
|
||||
con_autocomplete_t list = { 0 }; // local autocomplete list
|
||||
con_autocomplete_t list; // local autocomplete list
|
||||
|
||||
memset( &list, 0, sizeof( list ));
|
||||
|
||||
list.completionString = s;
|
||||
|
||||
@@ -661,16 +652,8 @@ static qboolean Cmd_GetCommandsAndCvarsList( const char *s, char *completedname,
|
||||
return false;
|
||||
|
||||
// find matching commands and variables
|
||||
if( cvars )
|
||||
{
|
||||
Cvar_LookupVars( 0, &toggle, &list, (setpair_t)Con_AddCommandToList );
|
||||
}
|
||||
|
||||
if( cmds )
|
||||
{
|
||||
toggle = false;
|
||||
Cmd_LookupCmds( &toggle, &list, (setpair_t)Con_AddCommandToList );
|
||||
}
|
||||
Cmd_LookupCmds( NULL, &list, (setpair_t)Con_AddCommandToList );
|
||||
Cvar_LookupVars( 0, NULL, &list, (setpair_t)Con_AddCommandToList );
|
||||
|
||||
if( !list.matchCount ) return false;
|
||||
Q_strncpy( matchbuf, list.cmds[0], sizeof( matchbuf ));
|
||||
@@ -686,7 +669,7 @@ static qboolean Cmd_GetCommandsAndCvarsList( const char *s, char *completedname,
|
||||
Con_Printf( "%16s\n", matchbuf );
|
||||
}
|
||||
|
||||
Con_Printf( "\n^3 %i %s found.\n", list.matchCount, cmds ? "commands" : "variables" );
|
||||
Con_Printf( "\n^3 %i commands found.\n", list.matchCount );
|
||||
|
||||
if( completedname && length )
|
||||
{
|
||||
@@ -708,30 +691,6 @@ static qboolean Cmd_GetCommandsAndCvarsList( const char *s, char *completedname,
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================
|
||||
Cmd_GetCommandsList
|
||||
|
||||
Autocomplete for bind command
|
||||
=====================================
|
||||
*/
|
||||
static qboolean Cmd_GetCommandsList( const char *s, char *completedname, int length )
|
||||
{
|
||||
return Cmd_GetCommandsAndCvarsList( s, completedname, length, true, true, false );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================
|
||||
Cmd_GetCvarList
|
||||
|
||||
Autocomplete for bind command
|
||||
=====================================
|
||||
*/
|
||||
static qboolean Cmd_GetCvarsList( const char *s, char *completedname, int length )
|
||||
{
|
||||
qboolean toggle = !Q_stricmp( Cmd_Argv( 0 ), "toggle" );
|
||||
return Cmd_GetCommandsAndCvarsList( s, completedname, length, false, true, toggle );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================
|
||||
@@ -1051,38 +1010,36 @@ int GAME_EXPORT Cmd_CheckMapsList( int fRefresh )
|
||||
return Cmd_CheckMapsList_R( fRefresh, true );
|
||||
}
|
||||
|
||||
// keep this sorted
|
||||
static const autocomplete_list_t cmd_list[] =
|
||||
{
|
||||
{ "bind", 1, Cmd_GetKeysList },
|
||||
{ "bind", 2, Cmd_GetCommandsList },
|
||||
{ "cd", 1, Cmd_GetCDList },
|
||||
{ "map_background", 1, Cmd_GetMapList },
|
||||
{ "changelevel2", 1, Cmd_GetMapList },
|
||||
{ "changelevel", 1, Cmd_GetMapList },
|
||||
{ "drop", 1, Cmd_GetItemsList },
|
||||
{ "entpatch", 1, Cmd_GetMapList },
|
||||
{ "exec", 1, Cmd_GetConfigList },
|
||||
{ "game", 1, Cmd_GetGamesList },
|
||||
{ "give", 1, Cmd_GetItemsList },
|
||||
{ "hpkextract", 1, Cmd_GetCustomList },
|
||||
{ "hpklist", 1, Cmd_GetCustomList },
|
||||
{ "hpkval", 1, Cmd_GetCustomList },
|
||||
{ "listdemo", 1, Cmd_GetDemoList, },
|
||||
{ "load", 1, Cmd_GetSavesList },
|
||||
{ "map", 1, Cmd_GetMapList },
|
||||
{ "map_background", 1, Cmd_GetMapList },
|
||||
{ "movie", 1, Cmd_GetMovieList },
|
||||
{ "mp3", 1, Cmd_GetCDList },
|
||||
{ "music", 1, Cmd_GetMusicList, },
|
||||
{ "play", 1, Cmd_GetSoundList },
|
||||
{ "playdemo", 1, Cmd_GetDemoList, },
|
||||
{ "timedemo", 1, Cmd_GetDemoList, },
|
||||
{ "listdemo", 1, Cmd_GetDemoList, },
|
||||
{ "playvol", 1, Cmd_GetSoundList },
|
||||
{ "reset", 1, Cmd_GetCvarsList },
|
||||
{ "save", 1, Cmd_GetSavesList },
|
||||
{ "set", 1, Cmd_GetCvarsList },
|
||||
{ "timedemo", 1, Cmd_GetDemoList },
|
||||
{ "toggle", 1, Cmd_GetCvarsList },
|
||||
{ "hpkval", 1, Cmd_GetCustomList },
|
||||
{ "hpklist", 1, Cmd_GetCustomList },
|
||||
{ "hpkextract", 1, Cmd_GetCustomList },
|
||||
{ "entpatch", 1, Cmd_GetMapList },
|
||||
{ "music", 1, Cmd_GetMusicList, },
|
||||
{ "movie", 1, Cmd_GetMovieList },
|
||||
{ "exec", 1, Cmd_GetConfigList },
|
||||
#if !XASH_DEDICATED
|
||||
{ "give", 1, Cmd_GetItemsList },
|
||||
{ "drop", 1, Cmd_GetItemsList },
|
||||
{ "bind", 1, Cmd_GetKeysList },
|
||||
{ "unbind", 1, Cmd_GetKeysList },
|
||||
{ "bind", 2, Cmd_GetCommandsList },
|
||||
#endif
|
||||
{ "game", 1, Cmd_GetGamesList },
|
||||
{ "save", 1, Cmd_GetSavesList },
|
||||
{ "load", 1, Cmd_GetSavesList },
|
||||
{ "play", 1, Cmd_GetSoundList },
|
||||
{ "map", 1, Cmd_GetMapList },
|
||||
{ "cd", 1, Cmd_GetCDList },
|
||||
{ "mp3", 1, Cmd_GetCDList },
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1203,7 +1160,6 @@ void Con_CompleteCommand( field_t *field )
|
||||
{
|
||||
field_t temp;
|
||||
string filename;
|
||||
qboolean toggle = false;
|
||||
qboolean nextcmd;
|
||||
int i;
|
||||
|
||||
@@ -1238,8 +1194,8 @@ void Con_CompleteCommand( field_t *field )
|
||||
con.shortestMatch[0] = 0;
|
||||
|
||||
// find matching commands and variables
|
||||
Cmd_LookupCmds( &toggle, &con, (setpair_t)Con_AddCommandToList );
|
||||
Cvar_LookupVars( 0, &toggle, &con, (setpair_t)Con_AddCommandToList );
|
||||
Cmd_LookupCmds( NULL, &con, (setpair_t)Con_AddCommandToList );
|
||||
Cvar_LookupVars( 0, NULL, &con, (setpair_t)Con_AddCommandToList );
|
||||
|
||||
if( !con.matchCount ) return; // no matches
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ GNU General Public License for more details.
|
||||
#include "eiface.h" // ARRAYSIZE
|
||||
|
||||
static convar_t *cvar_vars = NULL; // head of list
|
||||
static poolhandle_t cvar_pool;
|
||||
CVAR_DEFINE_AUTO( cmd_scripting, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED, "enable simple condition checking and variable operations" );
|
||||
|
||||
typedef struct cvar_filter_quirks_s
|
||||
@@ -153,7 +152,7 @@ static qboolean Cvar_UpdateInfo( convar_t *var, const char *value, qboolean noti
|
||||
{
|
||||
if( FBitSet( var->flags, FCVAR_USERINFO ))
|
||||
{
|
||||
if( Host_IsDedicated() )
|
||||
if ( Host_IsDedicated() )
|
||||
{
|
||||
// g-cont. this is a very strange behavior...
|
||||
char *info = SV_Serverinfo();
|
||||
@@ -432,9 +431,8 @@ convar_t *Cvar_Get( const char *name, const char *value, int flags, const char *
|
||||
if( COM_CheckStringEmpty( var->desc ))
|
||||
{
|
||||
// directly set value
|
||||
size_t len = Q_strlen( value ) + 1;
|
||||
var->string = Mem_Realloc( cvar_pool, var->string, len );
|
||||
Q_strncpy( var->string, value, len );
|
||||
freestring( var->string );
|
||||
var->string = copystring( value );
|
||||
var->value = Q_atof( var->string );
|
||||
SetBits( var->flags, flags );
|
||||
|
||||
@@ -450,25 +448,22 @@ convar_t *Cvar_Get( const char *name, const char *value, int flags, const char *
|
||||
|
||||
if( FBitSet( var->flags, FCVAR_ALLOCATED ) && Q_strcmp( var_desc, var->desc ))
|
||||
{
|
||||
size_t len = Q_strlen( var_desc ) + 1;
|
||||
|
||||
if( !FBitSet( flags, FCVAR_GLCONFIG ))
|
||||
Con_Reportf( "%s change description from %s to %s\n", var->name, var->desc, var_desc );
|
||||
|
||||
// update description if needs
|
||||
var->desc = Mem_Realloc( cvar_pool, var->desc, len );
|
||||
Q_strncpy( var->desc, var_desc, len );
|
||||
freestring( var->desc );
|
||||
var->desc = copystring( var_desc );
|
||||
}
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
// allocate a new cvar
|
||||
var = Mem_Malloc( cvar_pool, sizeof( *var ));
|
||||
var->name = copystringpool( cvar_pool, name );
|
||||
var->string = copystringpool( cvar_pool, value );
|
||||
var->def_string = copystringpool( cvar_pool, value );
|
||||
var->desc = copystringpool( cvar_pool, var_desc );
|
||||
var = Z_Malloc( sizeof( *var ));
|
||||
var->name = copystring( name );
|
||||
var->string = copystring( value );
|
||||
var->def_string = copystring( value );
|
||||
var->desc = copystring( var_desc );
|
||||
var->value = Q_atof( var->string );
|
||||
var->flags = flags|FCVAR_ALLOCATED;
|
||||
|
||||
@@ -554,7 +549,7 @@ void Cvar_RegisterVariable( convar_t *var )
|
||||
if( FBitSet( var->flags, FCVAR_EXTENDED ))
|
||||
var->def_string = var->string; // just swap pointers
|
||||
|
||||
var->string = copystringpool( cvar_pool, var->string );
|
||||
var->string = copystring( var->string );
|
||||
var->value = Q_atof( var->string );
|
||||
|
||||
// find the supposed position in chain (alphanumerical order)
|
||||
@@ -606,10 +601,9 @@ Cvar_Set2
|
||||
static convar_t *Cvar_Set2( const char *var_name, const char *value )
|
||||
{
|
||||
convar_t *var;
|
||||
const char *pszValue;
|
||||
qboolean dll_variable = false;
|
||||
qboolean force = false;
|
||||
const char *fixed_string;
|
||||
size_t fixed_string_len;
|
||||
|
||||
if( !Cvar_ValidateVarName( var_name, false ))
|
||||
{
|
||||
@@ -673,20 +667,19 @@ static convar_t *Cvar_Set2( const char *var_name, const char *value )
|
||||
return var;
|
||||
}
|
||||
|
||||
fixed_string = Cvar_ValidateString( var, value );
|
||||
pszValue = Cvar_ValidateString( var, value );
|
||||
|
||||
// nothing to change
|
||||
if( !Q_strcmp( fixed_string, var->string ))
|
||||
if( !Q_strcmp( pszValue, var->string ))
|
||||
return var;
|
||||
|
||||
// fill it cls.userinfo, svs.serverinfo
|
||||
if( !Cvar_UpdateInfo( var, fixed_string, true ))
|
||||
if( !Cvar_UpdateInfo( var, pszValue, true ))
|
||||
return var;
|
||||
|
||||
// and finally change the cvar itself
|
||||
fixed_string_len = Q_strlen( fixed_string ) + 1;
|
||||
var->string = Mem_Realloc( cvar_pool, var->string, fixed_string_len );
|
||||
Q_strncpy( var->string, fixed_string, fixed_string_len );
|
||||
// and finally changed the cvar itself
|
||||
freestring( var->string );
|
||||
var->string = copystring( pszValue );
|
||||
var->value = Q_atof( var->string );
|
||||
|
||||
// tell engine about changes
|
||||
@@ -703,8 +696,7 @@ way to change value for many cvars
|
||||
*/
|
||||
void GAME_EXPORT Cvar_DirectSet( convar_t *var, const char *value )
|
||||
{
|
||||
const char *fixed_string;
|
||||
size_t fixed_string_len;
|
||||
const char *pszValue;
|
||||
|
||||
if( unlikely( !var )) return; // ???
|
||||
|
||||
@@ -734,20 +726,19 @@ void GAME_EXPORT Cvar_DirectSet( convar_t *var, const char *value )
|
||||
value = var->def_string; // reset to default value
|
||||
}
|
||||
|
||||
fixed_string = Cvar_ValidateString( var, value );
|
||||
pszValue = Cvar_ValidateString( var, value );
|
||||
|
||||
// nothing to change
|
||||
if( !Q_strcmp( fixed_string, var->string ))
|
||||
if( !Q_strcmp( pszValue, var->string ))
|
||||
return;
|
||||
|
||||
// fill it cls.userinfo, svs.serverinfo
|
||||
if( !Cvar_UpdateInfo( var, fixed_string, true ))
|
||||
if( !Cvar_UpdateInfo( var, pszValue, true ))
|
||||
return;
|
||||
|
||||
// and finally change the cvar itself
|
||||
fixed_string_len = Q_strlen( fixed_string ) + 1;
|
||||
var->string = Mem_Realloc( cvar_pool, var->string, fixed_string_len );
|
||||
Q_strncpy( var->string, fixed_string, fixed_string_len );
|
||||
// and finally changed the cvar itself
|
||||
freestring( var->string );
|
||||
var->string = copystring( pszValue );
|
||||
var->value = Q_atof( var->string );
|
||||
|
||||
// tell engine about changes
|
||||
@@ -781,8 +772,7 @@ can set any protected cvars
|
||||
*/
|
||||
void Cvar_FullSet( const char *var_name, const char *value, int flags )
|
||||
{
|
||||
convar_t *var = Cvar_FindVar( var_name );
|
||||
size_t len = Q_strlen( value ) + 1;
|
||||
convar_t *var = Cvar_FindVar( var_name );
|
||||
|
||||
if( !var )
|
||||
{
|
||||
@@ -790,8 +780,8 @@ void Cvar_FullSet( const char *var_name, const char *value, int flags )
|
||||
return;
|
||||
}
|
||||
|
||||
var->string = Mem_Realloc( cvar_pool, var->string, len );
|
||||
Q_strncpy( var->string, value, len );
|
||||
freestring( var->string );
|
||||
var->string = copystring( value );
|
||||
var->value = Q_atof( var->string );
|
||||
SetBits( var->flags, flags );
|
||||
|
||||
@@ -1030,11 +1020,9 @@ qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged )
|
||||
return true;
|
||||
}
|
||||
|
||||
#if !defined( XASH_HASHED_VARS )
|
||||
// check variables
|
||||
v = Cvar_FindVar( Cmd_Argv( 0 ));
|
||||
#endif
|
||||
|
||||
if( !v ) // already found in basecmd
|
||||
v = Cvar_FindVar( Cmd_Argv( 0 ));
|
||||
if( !v )
|
||||
return false;
|
||||
|
||||
@@ -1201,7 +1189,6 @@ static void Cvar_List_f( void )
|
||||
for( var = cvar_vars; var; var = var->next )
|
||||
{
|
||||
char value[MAX_VA_STRING];
|
||||
char *p;
|
||||
|
||||
if( var->name[0] == '@' )
|
||||
continue; // never shows system cvars
|
||||
@@ -1209,9 +1196,7 @@ static void Cvar_List_f( void )
|
||||
if( match && !Q_strnicmpext( match, var->name, matchlen ))
|
||||
continue;
|
||||
|
||||
p = Q_strchr( var->string, '^' );
|
||||
|
||||
if( IsColorString( p ))
|
||||
if( Q_colorstr( var->string ))
|
||||
Q_snprintf( value, sizeof( value ), "\"%s\"", var->string );
|
||||
else Q_snprintf( value, sizeof( value ), "\"^2%s^7\"", var->string );
|
||||
|
||||
@@ -1272,7 +1257,7 @@ pending_cvar_t *Cvar_PrepareToUnlink( int group )
|
||||
continue;
|
||||
|
||||
namelen = Q_strlen( cv->name ) + 1;
|
||||
p = Mem_Malloc( cvar_pool, sizeof( *list ) + namelen );
|
||||
p = Mem_Malloc( host.mempool, sizeof( *list ) + namelen );
|
||||
p->next = NULL;
|
||||
p->cv_cur = cv;
|
||||
p->cv_next = cv->next;
|
||||
@@ -1348,7 +1333,6 @@ Reads in all archived cvars
|
||||
*/
|
||||
void Cvar_Init( void )
|
||||
{
|
||||
cvar_pool = Mem_AllocPool( "Console Variables" );
|
||||
cvar_vars = NULL;
|
||||
cvar_active_filter_quirks = NULL;
|
||||
Cvar_RegisterVariable( &cmd_scripting );
|
||||
@@ -1361,11 +1345,6 @@ void Cvar_Init( void )
|
||||
Cmd_AddCommand( "cvarlist", Cvar_List_f, "display all console variables beginning with the specified prefix" );
|
||||
}
|
||||
|
||||
void Cvar_Shutdown( void )
|
||||
{
|
||||
Mem_FreePool( &cvar_pool );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_PostFSInit
|
||||
|
||||
@@ -30,8 +30,6 @@ typedef struct pending_cvar_s
|
||||
char cv_name[];
|
||||
} pending_cvar_t;
|
||||
|
||||
typedef void (*setpair_t)( const char *key, const void *value, const void *buffer, void *numpairs );
|
||||
|
||||
cvar_t *Cvar_GetList( void );
|
||||
#define Cvar_FindVar( name ) Cvar_FindVarExt( name, 0 )
|
||||
convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group );
|
||||
@@ -54,7 +52,6 @@ void Cvar_Reset( const char *var_name );
|
||||
void Cvar_SetCheatState( void );
|
||||
qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged );
|
||||
void Cvar_Init( void );
|
||||
void Cvar_Shutdown( void );
|
||||
void Cvar_PostFSInit( void );
|
||||
void Cvar_Unlink( int group );
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
filesystem.c - game filesystem based on DP fs
|
||||
Copyright (C) 2003-2006 Mathieu Olivier
|
||||
Copyright (C) 2000-2007 DarkPlaces contributors
|
||||
@@ -16,23 +16,11 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#if XASH_SDL == 2
|
||||
#include <SDL.h> // SDL_GetBasePath
|
||||
#elif XASH_SDL == 3
|
||||
#include <SDL3/SDL.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
#include "library.h"
|
||||
#include "platform/platform.h"
|
||||
|
||||
CVAR_DEFINE_AUTO( fs_mount_hd, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "mount high definition content folder" );
|
||||
CVAR_DEFINE_AUTO( fs_mount_lv, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "mount low violence models content folder" );
|
||||
CVAR_DEFINE_AUTO( fs_mount_addon, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "mount addon content folder" );
|
||||
CVAR_DEFINE_AUTO( fs_mount_l10n, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "mount localization content folder" );
|
||||
CVAR_DEFINE_AUTO( ui_language, "english", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "selected game language" );
|
||||
|
||||
fs_api_t g_fsapi;
|
||||
fs_globals_t *FI;
|
||||
|
||||
@@ -81,23 +69,9 @@ void *FS_GetNativeObject( const char *obj )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void FS_Rescan_f( void )
|
||||
static void FS_Rescan_f( void )
|
||||
{
|
||||
uint32_t flags = 0;
|
||||
|
||||
// FIXME: VFS shouldn't care about this, allow engine to mount gamedirs
|
||||
if( fs_mount_lv.value ) SetBits( flags, FS_MOUNT_LV );
|
||||
if( fs_mount_hd.value ) SetBits( flags, FS_MOUNT_HD );
|
||||
if( fs_mount_addon.value ) SetBits( flags, FS_MOUNT_ADDON );
|
||||
if( fs_mount_l10n.value ) SetBits( flags, FS_MOUNT_L10N );
|
||||
|
||||
g_fsapi.Rescan( flags, ui_language.string );
|
||||
|
||||
ClearBits( fs_mount_lv.flags, FCVAR_CHANGED );
|
||||
ClearBits( fs_mount_hd.flags, FCVAR_CHANGED );
|
||||
ClearBits( fs_mount_addon.flags, FCVAR_CHANGED );
|
||||
ClearBits( fs_mount_l10n.flags, FCVAR_CHANGED );
|
||||
ClearBits( ui_language.flags, FCVAR_CHANGED );
|
||||
FS_Rescan();
|
||||
}
|
||||
|
||||
static void FS_ClearPaths_f( void )
|
||||
@@ -209,23 +183,14 @@ static qboolean FS_DetermineRootDirectory( char *out, size_t size )
|
||||
#elif XASH_PSVITA
|
||||
if( PSVita_GetBasePath( out, size ))
|
||||
return true;
|
||||
Sys_Error( "couldn't find %s data directory", XASH_ENGINE_NAME );
|
||||
Sys_Error( "couldn't find Xash3D data directory" );
|
||||
return false;
|
||||
#elif ( XASH_SDL >= 2 ) && !XASH_NSWITCH // GetBasePath not impl'd in switch-sdl2
|
||||
#elif ( XASH_SDL == 2 ) && !XASH_NSWITCH // GetBasePath not impl'd in switch-sdl2
|
||||
path = SDL_GetBasePath();
|
||||
|
||||
#if XASH_APPLE
|
||||
if( path != NULL && Q_stristr( path, ".app" ))
|
||||
{
|
||||
SDL_free((void *)path );
|
||||
path = SDL_GetPrefPath( NULL, XASH_ENGINE_NAME );
|
||||
}
|
||||
#endif
|
||||
|
||||
if( path != NULL )
|
||||
{
|
||||
Q_strncpy( out, path, size );
|
||||
SDL_free((void *)path );
|
||||
SDL_free(( void *)path );
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -262,12 +227,6 @@ static qboolean FS_DetermineReadOnlyRootDirectory( char *out, size_t size )
|
||||
return false;
|
||||
}
|
||||
|
||||
void FS_CheckConfig( void )
|
||||
{
|
||||
if( fs_mount_lv.value || fs_mount_hd.value || fs_mount_addon.value || fs_mount_l10n.value )
|
||||
FS_Rescan_f();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
FS_Init
|
||||
@@ -320,19 +279,11 @@ void FS_Init( const char *basedir )
|
||||
Cmd_AddRestrictedCommand( "fs_clearpaths", FS_ClearPaths_f, "clear filesystem search pathes" );
|
||||
Cmd_AddRestrictedCommand( "fs_make_gameinfo", FS_MakeGameInfo_f, "create gameinfo.txt for current running game" );
|
||||
|
||||
Cvar_RegisterVariable( &fs_mount_hd );
|
||||
Cvar_RegisterVariable( &fs_mount_lv );
|
||||
Cvar_RegisterVariable( &fs_mount_addon );
|
||||
Cvar_RegisterVariable( &fs_mount_l10n );
|
||||
|
||||
if( !Sys_GetParmFromCmdLine( "-dll", host.gamedll ))
|
||||
host.gamedll[0] = 0;
|
||||
|
||||
if( !Sys_GetParmFromCmdLine( "-clientlib", host.clientlib ))
|
||||
host.clientlib[0] = 0;
|
||||
|
||||
if( !Sys_GetParmFromCmdLine( "-menulib", host.menulib ))
|
||||
host.menulib[0] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -14,6 +14,9 @@ GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "build.h"
|
||||
#ifdef XASH_SDL
|
||||
#include <SDL.h>
|
||||
#endif // XASH_SDL
|
||||
#include <stdarg.h> // va_args
|
||||
#if !XASH_WIN32
|
||||
#include <unistd.h> // fork
|
||||
@@ -74,7 +77,7 @@ static CVAR_DEFINE_AUTO( host_gameloaded, "0", FCVAR_READ_ONLY, "inidcates a loa
|
||||
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" );
|
||||
CVAR_DEFINE_AUTO( fps_override, "0", FCVAR_FILTERABLE, "unlock higher framerate values, not supported" );
|
||||
CVAR_DEFINE_AUTO( fps_override, "1", FCVAR_FILTERABLE, "unlock higher framerate values, not supported" );
|
||||
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" );
|
||||
static CVAR_DEFINE_AUTO( host_sleeptime_debug, "0", 0, "print sleeps between frames" );
|
||||
@@ -137,8 +140,7 @@ static void Sys_PrintUsage( const char *exename )
|
||||
|
||||
"\nCommon options:\n"
|
||||
O("-dev [level] ", "set log verbosity 0-2")
|
||||
O("-log [file name] ", "write log to \"engine.log\" or [file name] if specified")
|
||||
O("-logtime ", "enable writing timestamps to the log file")
|
||||
O("-log ", "write log to \"engine.log\"")
|
||||
O("-nowriteconfig ", "disable config save")
|
||||
O("-noch ", "disable crashhandler")
|
||||
#if XASH_WIN32 // !!!!
|
||||
@@ -174,7 +176,6 @@ static void Sys_PrintUsage( const char *exename )
|
||||
O("-dll <path> ", "override server DLL path")
|
||||
#if !XASH_DEDICATED
|
||||
O("-clientlib <path> ", "override client DLL path")
|
||||
O("-menulib <path> ", "override menu 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")
|
||||
@@ -200,6 +201,7 @@ static void Sys_PrintUsage( const char *exename )
|
||||
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 && !XASH_SDL
|
||||
@@ -539,6 +541,13 @@ static void Host_MemStats_f( void )
|
||||
}
|
||||
}
|
||||
|
||||
static void Host_Minimize_f( void )
|
||||
{
|
||||
#ifdef XASH_SDL
|
||||
if( host.hWnd ) SDL_MinimizeWindow( host.hWnd );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Host_RegisterDecal
|
||||
@@ -689,17 +698,17 @@ static qboolean Host_Autosleep( double dt, double scale )
|
||||
static double timewindow; // allocate a time window for sleeps
|
||||
static int counter; // for debug
|
||||
static double realsleeptime;
|
||||
const double sleeptime = sleep * 0.000001;
|
||||
const double sleeptime = sleep * 0.001;
|
||||
|
||||
if( dt < targetframetime * scale )
|
||||
{
|
||||
// if we have allocated time window, try to sleep
|
||||
if( timewindow > realsleeptime )
|
||||
{
|
||||
// Platform_Sleep isn't guaranteed to sleep an exact amount of microseconds
|
||||
// Platform_Sleep isn't guaranteed to sleep an exact amount of milliseconds
|
||||
// so we measure the real sleep time and use it to decrease the window
|
||||
double t1 = Sys_DoubleTime(), t2;
|
||||
Platform_NanoSleep( sleep * 1000 ); // in usec!
|
||||
Platform_Sleep( sleep ); // in msec!
|
||||
t2 = Sys_DoubleTime();
|
||||
realsleeptime = t2 - t1;
|
||||
|
||||
@@ -1035,7 +1044,7 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
|
||||
}
|
||||
|
||||
if( !Sys_CheckParm( "-noch" ))
|
||||
Sys_SetupCrashHandler( argv[0] );
|
||||
Sys_SetupCrashHandler();
|
||||
|
||||
#if XASH_DLL_LOADER
|
||||
host.enabledll = !Sys_CheckParm( "-nodll" );
|
||||
@@ -1122,7 +1131,7 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
|
||||
#if XASH_DEDICATED
|
||||
Platform_SetupSigtermHandling();
|
||||
#endif
|
||||
Platform_Init( Host_IsDedicated( ) || developer >= DEV_EXTENDED, basedir );
|
||||
Platform_Init( Host_IsDedicated( ) || developer >= DEV_EXTENDED );
|
||||
FS_Init( basedir );
|
||||
|
||||
Sys_InitLog();
|
||||
@@ -1227,14 +1236,6 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
Cvar_Getf( "host_ver", FCVAR_READ_ONLY, "detailed info about this build", "%i " XASH_VERSION " %s %s %s", Q_buildnum(), Q_buildos(), Q_buildarch(), g_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 );
|
||||
|
||||
Cvar_Get( "host_hl25_extended_structs",
|
||||
#if SUPPORT_HL25_EXTENDED_STRUCTS
|
||||
"1",
|
||||
#else
|
||||
"0",
|
||||
#endif
|
||||
FCVAR_READ_ONLY, "indicates if engine was compiled with extended msurface_t struct" );
|
||||
|
||||
Mod_Init();
|
||||
NET_Init();
|
||||
NET_InitMasters();
|
||||
@@ -1255,6 +1256,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
CL_Init();
|
||||
|
||||
HTTP_Init();
|
||||
ID_Init();
|
||||
SoundList_Init();
|
||||
|
||||
if( Host_IsDedicated( ))
|
||||
@@ -1269,7 +1271,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
Cmd_AddRestrictedCommand( "quit", Sys_Quit_f, "quit the game" );
|
||||
Cmd_AddRestrictedCommand( "exit", Sys_Quit_f, "quit the game" );
|
||||
}
|
||||
else Cmd_AddRestrictedCommand( "minimize", Platform_Minimize_f, "minimize main window to tray" );
|
||||
else Cmd_AddRestrictedCommand( "minimize", Host_Minimize_f, "minimize main window to tray" );
|
||||
|
||||
host.errorframe = 0;
|
||||
|
||||
@@ -1310,7 +1312,6 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
Cmd_RemoveCommand( "setgl" );
|
||||
Cbuf_ExecStuffCmds(); // execute stuffcmds (commandline)
|
||||
SCR_CheckStartupVids(); // must be last
|
||||
FS_CheckConfig();
|
||||
|
||||
if( Sys_GetParmFromCmdLine( "-timedemo", demoname ))
|
||||
Cbuf_AddTextf( "timedemo %s\n", demoname );
|
||||
@@ -1345,7 +1346,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
#endif // XASH_ANDROID
|
||||
|
||||
// main window message loop
|
||||
while( host.status != HOST_CRASHED )
|
||||
while( !host.crashed )
|
||||
{
|
||||
newtime = Sys_DoubleTime ();
|
||||
COM_Frame( newtime - oldtime );
|
||||
@@ -1399,10 +1400,6 @@ void Host_ShutdownWithReason( const char *reason )
|
||||
Host_FreeCommon();
|
||||
Platform_Shutdown();
|
||||
|
||||
BaseCmd_Shutdown();
|
||||
Cmd_Shutdown();
|
||||
Cvar_Shutdown();
|
||||
|
||||
// must be last, console uses this
|
||||
Mem_FreePool( &host.mempool );
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ static void HPAK_MaxSize_f( void )
|
||||
Con_Printf( S_ERROR "hpk_maxsize is deprecated, use hpk_max_size\n" );
|
||||
}
|
||||
|
||||
const char *COM_ResourceTypeFromIndex( int type )
|
||||
static const char *HPAK_TypeFromIndex( int type )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
@@ -220,7 +220,7 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource,
|
||||
|
||||
if( pResource->nDownloadSize < HPAK_ENTRY_MIN_SIZE || pResource->nDownloadSize > HPAK_ENTRY_MAX_SIZE )
|
||||
{
|
||||
Con_Printf( S_ERROR "%s: invalid size %s\n", name, Q_memprint( pResource->nDownloadSize ));
|
||||
Con_Printf( S_ERROR "%s: invalid size %s\n", name, Q_pretifymem( pResource->nDownloadSize, 2 ));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -441,7 +441,7 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
|
||||
if( dataDir[i].disksize < HPAK_ENTRY_MIN_SIZE || dataDir[i].disksize > HPAK_ENTRY_MAX_SIZE )
|
||||
{
|
||||
// odd max size
|
||||
Con_DPrintf( S_ERROR "%s: lump %i has invalid size %s\n", __func__, i, Q_memprint( dataDir[i].disksize ));
|
||||
Con_DPrintf( S_ERROR "%s: lump %i has invalid size %s\n", __func__, i, Q_pretifymem( dataDir[i].disksize, 2 ));
|
||||
Mem_Free( dataDir );
|
||||
FS_Close( f );
|
||||
if( delete ) FS_Delete( pakname );
|
||||
@@ -461,8 +461,8 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
|
||||
|
||||
if( !quiet )
|
||||
{
|
||||
Con_Printf( "%i: %s %s %s: ", i, COM_ResourceTypeFromIndex( pRes->type ),
|
||||
Q_memprint( pRes->nDownloadSize ), pRes->szFileName );
|
||||
Con_Printf( "%i: %s %s %s: ", i, HPAK_TypeFromIndex( pRes->type ),
|
||||
Q_pretifymem( pRes->nDownloadSize, 2 ), pRes->szFileName );
|
||||
}
|
||||
|
||||
if( memcmp( md5, pRes->rgucMD5_hash, 0x10 ))
|
||||
@@ -942,7 +942,7 @@ static void HPAK_List_f( void )
|
||||
{
|
||||
entry = &directory.entries[nCurrent];
|
||||
COM_FileBase( entry->resource.szFileName, lumpname, sizeof( lumpname ));
|
||||
type = COM_ResourceTypeFromIndex( entry->resource.type );
|
||||
type = HPAK_TypeFromIndex( entry->resource.type );
|
||||
size = Q_memprint( entry->resource.nDownloadSize );
|
||||
|
||||
Con_Printf( "%i: %10s %s %s\n : %s\n", nCurrent + 1, type, size, lumpname, MD5_Print( entry->resource.rgucMD5_hash ));
|
||||
@@ -1037,7 +1037,7 @@ static void HPAK_Extract_f( void )
|
||||
continue;
|
||||
|
||||
COM_FileBase( entry->resource.szFileName, lumpname, sizeof( lumpname ) );
|
||||
type = COM_ResourceTypeFromIndex( entry->resource.type );
|
||||
type = HPAK_TypeFromIndex( entry->resource.type );
|
||||
size = Q_memprint( entry->resource.nDownloadSize );
|
||||
|
||||
Con_Printf( "Extracting %i: %10s %s %s\n", nCurrent + 1, type, size, lumpname );
|
||||
|
||||
@@ -19,8 +19,8 @@ GNU General Public License for more details.
|
||||
#if !XASH_WIN32
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
static char id_md5[33];
|
||||
static char id_customid[MAX_STRING];
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
@@ -365,10 +365,10 @@ static int ID_GetKeyData( HKEY hRootKey, char *subKey, char *value, LPBYTE data,
|
||||
{
|
||||
HKEY hKey;
|
||||
|
||||
if( RegOpenKeyExA( hRootKey, subKey, 0, KEY_QUERY_VALUE, &hKey ) != ERROR_SUCCESS )
|
||||
if( RegOpenKeyEx( hRootKey, subKey, 0, KEY_QUERY_VALUE, &hKey ) != ERROR_SUCCESS )
|
||||
return 0;
|
||||
|
||||
if( RegQueryValueExA( hKey, value, NULL, NULL, data, &cbData ) != ERROR_SUCCESS )
|
||||
if( RegQueryValueEx( hKey, value, NULL, NULL, data, &cbData ) != ERROR_SUCCESS )
|
||||
{
|
||||
RegCloseKey( hKey );
|
||||
return 0;
|
||||
@@ -377,14 +377,13 @@ static int ID_GetKeyData( HKEY hRootKey, char *subKey, char *value, LPBYTE data,
|
||||
RegCloseKey( hKey );
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ID_SetKeyData( HKEY hRootKey, char *subKey, DWORD dwType, char *value, LPBYTE data, DWORD cbData )
|
||||
static int ID_SetKeyData( HKEY hRootKey, char *subKey, DWORD dwType, char *value, LPBYTE data, DWORD cbData)
|
||||
{
|
||||
HKEY hKey;
|
||||
if( RegCreateKeyA( hRootKey, subKey, &hKey ) != ERROR_SUCCESS )
|
||||
if( RegCreateKey( hRootKey, subKey, &hKey ) != ERROR_SUCCESS )
|
||||
return 0;
|
||||
|
||||
if( RegSetValueExA( hKey, value, 0, dwType, data, cbData ) != ERROR_SUCCESS )
|
||||
if( RegSetValueEx( hKey, value, 0, dwType, data, cbData ) != ERROR_SUCCESS )
|
||||
{
|
||||
RegCloseKey( hKey );
|
||||
return 0;
|
||||
@@ -396,7 +395,7 @@ static int ID_SetKeyData( HKEY hRootKey, char *subKey, DWORD dwType, char *value
|
||||
|
||||
#define BUFSIZE 4096
|
||||
|
||||
static int ID_RunWMIC( char *buffer, const wchar_t *cmdline )
|
||||
static int ID_RunWMIC(char *buffer, const char *cmdline)
|
||||
{
|
||||
HANDLE g_IN_Rd = NULL;
|
||||
HANDLE g_IN_Wr = NULL;
|
||||
@@ -404,92 +403,75 @@ static int ID_RunWMIC( char *buffer, const wchar_t *cmdline )
|
||||
HANDLE g_OUT_Wr = NULL;
|
||||
DWORD dwRead;
|
||||
BOOL bSuccess = FALSE;
|
||||
wchar_t *cmdline_copy;
|
||||
SECURITY_ATTRIBUTES saAttr;
|
||||
|
||||
PROCESS_INFORMATION pi = { 0 };
|
||||
SECURITY_ATTRIBUTES saAttr =
|
||||
{
|
||||
.nLength = sizeof( SECURITY_ATTRIBUTES ),
|
||||
.bInheritHandle = TRUE,
|
||||
.lpSecurityDescriptor = NULL,
|
||||
};
|
||||
STARTUPINFO si = {0};
|
||||
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
saAttr.bInheritHandle = TRUE;
|
||||
saAttr.lpSecurityDescriptor = NULL;
|
||||
|
||||
CreatePipe( &g_IN_Rd, &g_IN_Wr, &saAttr, 0 );
|
||||
CreatePipe( &g_OUT_Rd, &g_OUT_Wr, &saAttr, 0 );
|
||||
SetHandleInformation( g_IN_Wr, HANDLE_FLAG_INHERIT, 0 );
|
||||
|
||||
STARTUPINFO si =
|
||||
{
|
||||
.cb = sizeof( STARTUPINFO ),
|
||||
.dwFlags = STARTF_USESTDHANDLES,
|
||||
.hStdInput = g_IN_Rd,
|
||||
.hStdOutput = g_OUT_Wr,
|
||||
.hStdError = g_OUT_Wr,
|
||||
.wShowWindow = SW_HIDE,
|
||||
.dwFlags = STARTF_USESTDHANDLES,
|
||||
};
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
si.dwFlags = STARTF_USESTDHANDLES;
|
||||
si.hStdInput = g_IN_Rd;
|
||||
si.hStdOutput = g_OUT_Wr;
|
||||
si.hStdError = g_OUT_Wr;
|
||||
si.wShowWindow = SW_HIDE;
|
||||
si.dwFlags |= STARTF_USESTDHANDLES;
|
||||
|
||||
cmdline_copy = malloc( wcslen( cmdline ) * sizeof( *cmdline_copy ));
|
||||
CreateProcess( NULL, (char*)cmdline, NULL, NULL, true, CREATE_NO_WINDOW , NULL, NULL, &si, &pi );
|
||||
|
||||
if( !CreateProcessW( NULL, cmdline_copy, NULL, NULL, true, CREATE_NO_WINDOW, NULL, NULL, &si, &pi ))
|
||||
goto err;
|
||||
CloseHandle( g_OUT_Wr );
|
||||
CloseHandle( g_IN_Wr );
|
||||
|
||||
WaitForSingleObject( pi.hProcess, 500 );
|
||||
|
||||
bSuccess = ReadFile( g_OUT_Rd, buffer, BUFSIZE, &dwRead, NULL );
|
||||
buffer[BUFSIZE-1] = 0;
|
||||
|
||||
TerminateProcess( pi.hProcess, 0 );
|
||||
|
||||
CloseHandle( pi.hProcess );
|
||||
CloseHandle( pi.hThread );
|
||||
|
||||
err:
|
||||
CloseHandle( g_IN_Wr );
|
||||
CloseHandle( g_OUT_Wr );
|
||||
CloseHandle( g_IN_Rd );
|
||||
CloseHandle( g_OUT_Rd );
|
||||
|
||||
free( cmdline_copy );
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
static int ID_ProcessWMIC( bloomfilter_t *value, const wchar_t *cmdline )
|
||||
static int ID_ProcessWMIC( bloomfilter_t *value, const char *cmdline )
|
||||
{
|
||||
char buffer[BUFSIZE], token[BUFSIZE], *pbuf;
|
||||
int count = 0;
|
||||
|
||||
if( !ID_RunWMIC( buffer, cmdline ))
|
||||
if( !ID_RunWMIC( buffer, cmdline ) )
|
||||
return 0;
|
||||
|
||||
pbuf = COM_ParseFile( buffer, token, sizeof( token )); // Header
|
||||
while( pbuf = COM_ParseFile( pbuf, token, sizeof( token )))
|
||||
while( pbuf = COM_ParseFile( pbuf, token, sizeof( token ) ) )
|
||||
{
|
||||
if( !ID_VerifyHEX( token ))
|
||||
if( !ID_VerifyHEX( token ) )
|
||||
continue;
|
||||
|
||||
*value |= BloomFilter_ProcessStr( token );
|
||||
count++;
|
||||
count ++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int ID_CheckWMIC( bloomfilter_t value, const wchar_t *cmdline )
|
||||
static int ID_CheckWMIC( bloomfilter_t value, const char *cmdline )
|
||||
{
|
||||
char buffer[BUFSIZE], token[BUFSIZE], *pbuf;
|
||||
int count = 0;
|
||||
|
||||
if( !ID_RunWMIC( buffer, cmdline ))
|
||||
if( !ID_RunWMIC( buffer, cmdline ) )
|
||||
return 0;
|
||||
|
||||
pbuf = COM_ParseFile( buffer, token, sizeof( token )); // Header
|
||||
while( pbuf = COM_ParseFile( pbuf, token, sizeof( token )))
|
||||
while( pbuf = COM_ParseFile( pbuf, token, sizeof( token ) ) )
|
||||
{
|
||||
bloomfilter_t filter;
|
||||
|
||||
if( !ID_VerifyHEX( token ))
|
||||
if( !ID_VerifyHEX( token ) )
|
||||
continue;
|
||||
|
||||
filter = BloomFilter_ProcessStr( token );
|
||||
@@ -505,10 +487,6 @@ static int ID_CheckWMIC( bloomfilter_t value, const wchar_t *cmdline )
|
||||
char *IOS_GetUDID( void );
|
||||
#endif
|
||||
|
||||
#if XASH_PSVITA
|
||||
int PSVita_GetPSID( char *buf, const size_t buflen );
|
||||
#endif
|
||||
|
||||
static bloomfilter_t ID_GenerateRawId( void )
|
||||
{
|
||||
bloomfilter_t value = 0;
|
||||
@@ -530,22 +508,14 @@ static bloomfilter_t ID_GenerateRawId( void )
|
||||
count += ID_ProcessNetDevices( &value );
|
||||
#endif
|
||||
#if XASH_WIN32
|
||||
count += ID_ProcessWMIC( &value, L"wmic path win32_physicalmedia get SerialNumber " );
|
||||
count += ID_ProcessWMIC( &value, L"wmic bios get serialnumber " );
|
||||
count += ID_ProcessWMIC( &value, "wmic path win32_physicalmedia get SerialNumber " );
|
||||
count += ID_ProcessWMIC( &value, "wmic bios get serialnumber " );
|
||||
#endif
|
||||
#if XASH_IOS
|
||||
{
|
||||
value |= BloomFilter_ProcessStr(IOS_GetUDID());
|
||||
count ++;
|
||||
}
|
||||
#endif
|
||||
#if XASH_PSVITA
|
||||
{
|
||||
char data[16];
|
||||
PSVita_GetPSID( data, sizeof( data ));
|
||||
value |= BloomFilter_Process( data, sizeof( data ));
|
||||
count ++;
|
||||
}
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
@@ -574,8 +544,8 @@ static uint ID_CheckRawId( bloomfilter_t filter )
|
||||
#endif
|
||||
|
||||
#if XASH_WIN32
|
||||
count += ID_CheckWMIC( filter, L"wmic path win32_physicalmedia get SerialNumber" );
|
||||
count += ID_CheckWMIC( filter, L"wmic bios get serialnumber" );
|
||||
count += ID_CheckWMIC( filter, "wmic path win32_physicalmedia get SerialNumber" );
|
||||
count += ID_CheckWMIC( filter, "wmic bios get serialnumber" );
|
||||
#endif
|
||||
|
||||
#if XASH_IOS
|
||||
@@ -585,15 +555,6 @@ static uint ID_CheckRawId( bloomfilter_t filter )
|
||||
value = 0;
|
||||
}
|
||||
#endif
|
||||
#if XASH_PSVITA
|
||||
{
|
||||
char data[16];
|
||||
PSVita_GetPSID( data, sizeof( data ));
|
||||
value = BloomFilter_Process( data, sizeof( data ));
|
||||
count += (filter & value) == value;
|
||||
value = 0;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
Msg( "%s: %d\n", __func__, count );
|
||||
#endif
|
||||
@@ -629,9 +590,25 @@ static void ID_Check( void )
|
||||
|
||||
const char *ID_GetMD5( void )
|
||||
{
|
||||
if( id_customid[0] )
|
||||
return id_customid;
|
||||
return id_md5;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
ID_SetCustomClientID
|
||||
|
||||
===============
|
||||
*/
|
||||
void GAME_EXPORT ID_SetCustomClientID( const char *id )
|
||||
{
|
||||
if( !id )
|
||||
return;
|
||||
|
||||
Q_strncpy( id_customid, id, sizeof( id_customid ) );
|
||||
}
|
||||
|
||||
void ID_Init( void )
|
||||
{
|
||||
MD5Context_t hash = { 0 };
|
||||
@@ -655,7 +632,7 @@ void ID_Init( void )
|
||||
#elif XASH_WIN32
|
||||
{
|
||||
CHAR szBuf[MAX_PATH];
|
||||
ID_GetKeyData( HKEY_CURRENT_USER, "Software\\"XASH_ENGINE_NAME"\\", "xash_id", szBuf, MAX_PATH );
|
||||
ID_GetKeyData( HKEY_CURRENT_USER, "Software\\Xash3D\\", "xash_id", szBuf, MAX_PATH );
|
||||
|
||||
sscanf(szBuf, "%016"PRIX64, &id);
|
||||
id ^= SYSTEM_XOR_MASK;
|
||||
@@ -709,7 +686,7 @@ void ID_Init( void )
|
||||
{
|
||||
CHAR Buf[MAX_PATH];
|
||||
sprintf( Buf, "%016"PRIX64, id^SYSTEM_XOR_MASK );
|
||||
ID_SetKeyData( HKEY_CURRENT_USER, "Software\\"XASH_ENGINE_NAME"\\", REG_SZ, "xash_id", Buf, Q_strlen(Buf) );
|
||||
ID_SetKeyData( HKEY_CURRENT_USER, "Software\\Xash3D\\", REG_SZ, "xash_id", Buf, Q_strlen(Buf) );
|
||||
}
|
||||
#else
|
||||
{
|
||||
@@ -45,6 +45,7 @@ typedef enum
|
||||
|
||||
typedef struct loadformat_s
|
||||
{
|
||||
const char *formatstring;
|
||||
const char *ext;
|
||||
qboolean (*loadfunc)( const char *name, const byte *buffer, fs_offset_t filesize );
|
||||
image_hint_t hint;
|
||||
@@ -52,6 +53,7 @@ typedef struct loadformat_s
|
||||
|
||||
typedef struct saveformat_s
|
||||
{
|
||||
const char *formatstring;
|
||||
const char *ext;
|
||||
qboolean (*savefunc)( const char *name, rgbdata_t *pix );
|
||||
} savepixformat_t;
|
||||
|
||||
@@ -211,7 +211,7 @@ static const loadpixformat_t *Image_GetLoadFormatForExtension( const char *ext )
|
||||
if( !COM_CheckStringEmpty( ext ))
|
||||
return NULL;
|
||||
|
||||
for( format = image.loadformats; format->ext; format++ )
|
||||
for( format = image.loadformats; format->formatstring; format++ )
|
||||
{
|
||||
if( !Q_stricmp( ext, format->ext ))
|
||||
return format;
|
||||
@@ -237,7 +237,7 @@ static qboolean Image_ProbeLoadBuffer( const loadpixformat_t *fmt, const char *n
|
||||
// bruteforce all loaders
|
||||
if( !fmt )
|
||||
{
|
||||
for( fmt = image.loadformats; fmt->ext; fmt++ )
|
||||
for( fmt = image.loadformats; fmt->formatstring; fmt++ )
|
||||
{
|
||||
if( Image_ProbeLoadBuffer_( fmt, name, buf, size, override_hint ))
|
||||
return true;
|
||||
@@ -256,7 +256,7 @@ static qboolean Image_ProbeLoad_( const loadpixformat_t *fmt, const char *name,
|
||||
string path;
|
||||
byte *f;
|
||||
|
||||
Q_snprintf( path, sizeof( path ), "%s%s.%s", name, suffix, fmt->ext );
|
||||
Q_snprintf( path, sizeof( path ), fmt->formatstring, name, suffix, fmt->ext );
|
||||
f = FS_LoadFile( path, &filesize, false );
|
||||
|
||||
if( f )
|
||||
@@ -274,7 +274,7 @@ static qboolean Image_ProbeLoad( const loadpixformat_t *fmt, const char *name, c
|
||||
if( !fmt )
|
||||
{
|
||||
// bruteforce all formats to allow implicit extension
|
||||
for( fmt = image.loadformats; fmt->ext; fmt++ )
|
||||
for( fmt = image.loadformats; fmt->formatstring; fmt++ )
|
||||
{
|
||||
if( Image_ProbeLoad_( fmt, name, suffix, override_hint ))
|
||||
return true;
|
||||
@@ -417,13 +417,14 @@ qboolean FS_SaveImage( const char *filename, rgbdata_t *pix )
|
||||
picBuffer = pix->buffer;
|
||||
|
||||
// save all sides seperately
|
||||
for( format = image.saveformats; format && format->ext; format++ )
|
||||
for( format = image.saveformats; format && format->formatstring; format++ )
|
||||
{
|
||||
if( !Q_stricmp( ext, format->ext ))
|
||||
{
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
Q_snprintf( path, sizeof( path ), "%s%s.%s", savename, box[i].suf, format->ext );
|
||||
Q_snprintf( path, sizeof( path ),
|
||||
format->formatstring, savename, box[i].suf, format->ext );
|
||||
if( !format->savefunc( path, pix )) break; // there were errors
|
||||
pix->buffer += pix->size; // move pointer
|
||||
}
|
||||
@@ -441,11 +442,12 @@ qboolean FS_SaveImage( const char *filename, rgbdata_t *pix )
|
||||
}
|
||||
else
|
||||
{
|
||||
for( format = image.saveformats; format && format->ext; format++ )
|
||||
for( format = image.saveformats; format && format->formatstring; format++ )
|
||||
{
|
||||
if( !Q_stricmp( ext, format->ext ))
|
||||
{
|
||||
Q_snprintf( path, sizeof( path ), "%s.%s", savename, format->ext );
|
||||
Q_snprintf( path, sizeof( path ),
|
||||
format->formatstring, savename, "", format->ext );
|
||||
if( format->savefunc( path, pix ))
|
||||
{
|
||||
// clear any force flags
|
||||
|
||||
@@ -46,7 +46,7 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
short p, a, b, c, pa, pb, pc;
|
||||
byte *buf_p, *pixbuf, *raw, *prior, *idat_buf = NULL, *uncompressed_buffer = NULL;
|
||||
byte *pallete = NULL, *trns = NULL;
|
||||
uint chunk_len, trns_len = 0, plte_len = 0, crc32, crc32_check, oldsize = 0, newsize = 0, rowsize;
|
||||
uint chunk_len, trns_len, plte_len, crc32, crc32_check, oldsize = 0, newsize = 0, rowsize;
|
||||
uint uncompressed_size, pixel_size, pixel_count, i, y, filter_type, chunk_sign, r_alpha, g_alpha, b_alpha;
|
||||
qboolean has_iend_chunk = false;
|
||||
z_stream stream = {0};
|
||||
|
||||
@@ -90,23 +90,23 @@ static byte palette_hl[768] =
|
||||
// stub
|
||||
static const loadpixformat_t load_null[] =
|
||||
{
|
||||
{ NULL, NULL, IL_HINT_NO }
|
||||
{ NULL, NULL, NULL, IL_HINT_NO }
|
||||
};
|
||||
|
||||
static const loadpixformat_t load_game[] =
|
||||
{
|
||||
{ "dds", Image_LoadDDS, IL_HINT_NO }, // dds for world and studio models
|
||||
{ "bmp", Image_LoadBMP, IL_HINT_NO }, // WON menu images
|
||||
{ "tga", Image_LoadTGA, IL_HINT_NO }, // hl vgui menus
|
||||
{ "png", Image_LoadPNG, IL_HINT_NO }, // NightFire 007 menus
|
||||
{ "mip", Image_LoadMIP, IL_HINT_NO }, // hl textures from wad or buffer
|
||||
{ "mdl", Image_LoadMDL, IL_HINT_HL }, // hl studio model skins
|
||||
{ "spr", Image_LoadSPR, IL_HINT_HL }, // hl sprite frames
|
||||
{ "lmp", Image_LoadLMP, IL_HINT_NO }, // hl menu images (cached.wad etc)
|
||||
{ "fnt", Image_LoadFNT, IL_HINT_HL }, // hl console font (fonts.wad etc)
|
||||
{ "pal", Image_LoadPAL, IL_HINT_NO }, // install studio\sprite palette
|
||||
{ "ktx2", Image_LoadKTX2, IL_HINT_NO }, // ktx2 for world and studio models
|
||||
{ NULL, NULL, IL_HINT_NO }
|
||||
{ "%s%s.%s", "dds", Image_LoadDDS, IL_HINT_NO }, // dds for world and studio models
|
||||
{ "%s%s.%s", "bmp", Image_LoadBMP, IL_HINT_NO }, // WON menu images
|
||||
{ "%s%s.%s", "tga", Image_LoadTGA, IL_HINT_NO }, // hl vgui menus
|
||||
{ "%s%s.%s", "png", Image_LoadPNG, IL_HINT_NO }, // NightFire 007 menus
|
||||
{ "%s%s.%s", "mip", Image_LoadMIP, IL_HINT_NO }, // hl textures from wad or buffer
|
||||
{ "%s%s.%s", "mdl", Image_LoadMDL, IL_HINT_HL }, // hl studio model skins
|
||||
{ "%s%s.%s", "spr", Image_LoadSPR, IL_HINT_HL }, // hl sprite frames
|
||||
{ "%s%s.%s", "lmp", Image_LoadLMP, IL_HINT_NO }, // hl menu images (cached.wad etc)
|
||||
{ "%s%s.%s", "fnt", Image_LoadFNT, IL_HINT_HL }, // hl console font (fonts.wad etc)
|
||||
{ "%s%s.%s", "pal", Image_LoadPAL, IL_HINT_NO }, // install studio\sprite palette
|
||||
{ "%s%s.%s", "ktx2", Image_LoadKTX2, IL_HINT_NO }, // ktx2 for world and studio models
|
||||
{ NULL, NULL, NULL, IL_HINT_NO }
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -119,16 +119,16 @@ static const loadpixformat_t load_game[] =
|
||||
// stub
|
||||
static const savepixformat_t save_null[] =
|
||||
{
|
||||
{ NULL, NULL }
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
// Xash3D normal instance
|
||||
static const savepixformat_t save_game[] =
|
||||
{
|
||||
{ "tga", Image_SaveTGA }, // tga screenshots
|
||||
{ "bmp", Image_SaveBMP }, // bmp levelshots or screenshots
|
||||
{ "png", Image_SavePNG }, // png screenshots
|
||||
{ NULL, NULL }
|
||||
{ "%s%s.%s", "tga", Image_SaveTGA }, // tga screenshots
|
||||
{ "%s%s.%s", "bmp", Image_SaveBMP }, // bmp levelshots or screenshots
|
||||
{ "%s%s.%s", "png", Image_SavePNG }, // png screenshots
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
void Image_Setup( void )
|
||||
|
||||
@@ -28,20 +28,12 @@ Image_LoadPAL
|
||||
qboolean Image_LoadPAL( const char *name, const byte *buffer, fs_offset_t filesize )
|
||||
{
|
||||
int rendermode = LUMP_NORMAL;
|
||||
byte pal[768];
|
||||
|
||||
if( filesize > sizeof( pal ))
|
||||
if( filesize != 768 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: (%s) have invalid size (%li should be less or equal than %zu)\n", __func__, name, (long)filesize, sizeof( pal ));
|
||||
Con_DPrintf( S_ERROR "%s: (%s) have invalid size (%li should be %d)\n", __func__, name, (long)filesize, 768 );
|
||||
return false;
|
||||
}
|
||||
else if( filesize < sizeof( pal ) && buffer != NULL )
|
||||
{
|
||||
// palette might be truncated, fill it with zeros
|
||||
memset( pal, 0, sizeof( pal ));
|
||||
memcpy( pal, buffer, filesize );
|
||||
buffer = pal;
|
||||
}
|
||||
|
||||
if( name[0] == '#' )
|
||||
{
|
||||
@@ -52,8 +44,6 @@ qboolean Image_LoadPAL( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
rendermode = LUMP_MASKED;
|
||||
else if( Q_stristr( name, "gradient" ))
|
||||
rendermode = LUMP_GRADIENT;
|
||||
else if( Q_stristr( name, "texgamma" ))
|
||||
rendermode = LUMP_TEXGAMMA;
|
||||
else if( Q_stristr( name, "valve" ))
|
||||
{
|
||||
rendermode = LUMP_HALFLIFE;
|
||||
@@ -189,7 +179,7 @@ qboolean Image_LoadMDL( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
Image_GetPaletteLMP( pal, LUMP_MASKED );
|
||||
image.flags |= IMAGE_HAS_ALPHA|IMAGE_ONEBIT_ALPHA;
|
||||
}
|
||||
else Image_GetPaletteLMP( fin + pixels, LUMP_TEXGAMMA );
|
||||
else Image_GetPaletteLMP( fin + pixels, LUMP_NORMAL );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -228,7 +218,7 @@ qboolean Image_LoadSPR( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy( &pin, buffer, sizeof( dspriteframe_t ));
|
||||
memcpy( &pin, buffer, sizeof(dspriteframe_t) );
|
||||
image.width = pin.width;
|
||||
image.height = pin.height;
|
||||
|
||||
|
||||
@@ -128,9 +128,9 @@ dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath )
|
||||
|
||||
static void COM_GenerateCommonLibraryName( const char *name, const char *ext, char *out, size_t size )
|
||||
{
|
||||
#if ( XASH_WIN32 || ( XASH_LINUX && !XASH_ANDROID ) || XASH_APPLE ) && XASH_X86
|
||||
#if ( XASH_WIN32 || XASH_LINUX || XASH_APPLE ) && XASH_X86
|
||||
Q_snprintf( out, size, "%s.%s", name, ext );
|
||||
#elif XASH_WIN32 || ( XASH_LINUX && !XASH_ANDROID ) || XASH_APPLE
|
||||
#elif ( XASH_WIN32 || XASH_LINUX || XASH_APPLE )
|
||||
Q_snprintf( out, size, "%s_%s.%s", name, Q_buildarch(), ext );
|
||||
#else
|
||||
Q_snprintf( out, size, "%s_%s_%s.%s", name, Q_buildos(), Q_buildarch(), ext );
|
||||
@@ -185,12 +185,16 @@ static void COM_GenerateServerLibraryPath( char *out, size_t size )
|
||||
{
|
||||
#ifdef XASH_INTERNAL_GAMELIBS // assuming library loader knows where to get libraries
|
||||
Q_strncpy( out, "server", size );
|
||||
#elif XASH_X86 && XASH_WIN32
|
||||
#elif ( XASH_WIN32 || XASH_LINUX || XASH_APPLE ) && XASH_X86
|
||||
|
||||
#if XASH_WIN32
|
||||
Q_strncpy( out, GI->game_dll, size );
|
||||
#elif XASH_X86 && XASH_APPLE
|
||||
#elif XASH_APPLE
|
||||
Q_strncpy( out, GI->game_dll_osx, size );
|
||||
#elif XASH_X86 && XASH_LINUX && !XASH_ANDROID
|
||||
#else // XASH_LINUX
|
||||
Q_strncpy( out, GI->game_dll_linux, size );
|
||||
#endif
|
||||
|
||||
#else
|
||||
string dllpath;
|
||||
const char *ext;
|
||||
@@ -199,7 +203,7 @@ static void COM_GenerateServerLibraryPath( char *out, size_t size )
|
||||
Q_strncpy( dllpath, GI->game_dll, sizeof( dllpath ) );
|
||||
#elif XASH_APPLE
|
||||
Q_strncpy( dllpath, GI->game_dll_osx, sizeof( dllpath ) );
|
||||
#else
|
||||
#else // XASH_APPLE
|
||||
Q_strncpy( dllpath, GI->game_dll_linux, sizeof( dllpath ) );
|
||||
#endif
|
||||
|
||||
@@ -224,14 +228,7 @@ void COM_GetCommonLibraryPath( ECommonLibraryType eLibType, char *out, size_t si
|
||||
switch( eLibType )
|
||||
{
|
||||
case LIBRARY_GAMEUI:
|
||||
if( COM_CheckStringEmpty( host.menulib ))
|
||||
{
|
||||
Q_strncpy( out, host.menulib, size );
|
||||
}
|
||||
else
|
||||
{
|
||||
COM_GenerateClientLibraryPath( "menu", out, size );
|
||||
}
|
||||
COM_GenerateClientLibraryPath( "menu", out, size );
|
||||
break;
|
||||
case LIBRARY_CLIENT:
|
||||
if( COM_CheckStringEmpty( host.clientlib ))
|
||||
|
||||
@@ -419,21 +419,14 @@ void NET_InitMasters( void )
|
||||
|
||||
Cvar_RegisterVariable( &sv_verbose_heartbeats );
|
||||
|
||||
{ // IPv4-only
|
||||
NET_AddMaster( "mentality.rip:27010", false, false );
|
||||
NET_AddMaster( "ms2.mentality.rip:27010", false, false );
|
||||
NET_AddMaster( "ms3.mentality.rip:27010", false, false );
|
||||
}
|
||||
// keep main master always there
|
||||
NET_AddMaster( MASTERSERVER_ADR, false, false );
|
||||
NET_AddMaster( "mentality.rip:27011", false, false ); // testing server, might be offline
|
||||
NET_AddMaster( "ms2.mentality.rip:27010", false, false ); // secondary master
|
||||
|
||||
{ // IPv6-only
|
||||
NET_AddMaster( "aaaa.mentality.rip:27010", false, true );
|
||||
NET_AddMaster( "aaaa.ms2.mentality.rip:27010", false, true );
|
||||
}
|
||||
|
||||
{ // testing servers, might be offline
|
||||
NET_AddMaster( "mentality.rip:27011", false, false );
|
||||
NET_AddMaster( "aaaa.mentality.rip:27011", false, true );
|
||||
}
|
||||
NET_AddMaster( "aaaa.mentality.rip:27010", false, true ); // IPv6-only
|
||||
NET_AddMaster( "aaaa.mentality.rip:27011", false, true ); // IPv6-only, testing server, might be offline
|
||||
NET_AddMaster( "aaaa.ms2.mentality.rip:27010", false, false ); // secondary IPv6-only master
|
||||
|
||||
NET_LoadMasters( );
|
||||
}
|
||||
|
||||
@@ -129,10 +129,10 @@ typedef struct
|
||||
dclipnode32_t *clipnodes_out; // temporary 32-bit array to hold clipnodes
|
||||
|
||||
// misc stuff
|
||||
int lightmap_samples; // samples per lightmap (1 or 3)
|
||||
int version; // model version
|
||||
qboolean isworld;
|
||||
qboolean isbsp30ext;
|
||||
int lightmap_samples; // samples per lightmap (1 or 3)
|
||||
int version; // model version
|
||||
qboolean isworld;
|
||||
qboolean isbsp30ext;
|
||||
} dbspmodel_t;
|
||||
|
||||
typedef struct
|
||||
@@ -482,7 +482,7 @@ static int Mod_LoadTextureFromWadList( wadlist_t *list, const char *name, rgbdat
|
||||
return -1;
|
||||
}
|
||||
|
||||
static fs_offset_t Mod_CalculateMipTexSize( const mip_t *mt, qboolean palette )
|
||||
static fs_offset_t Mod_CalculateMipTexSize( mip_t *mt, qboolean palette )
|
||||
{
|
||||
if( !mt )
|
||||
return 0;
|
||||
@@ -1579,8 +1579,8 @@ static void CountClipNodes16_r( mclipnode16_t *src, hull_t *hull, int nodenum )
|
||||
// leaf?
|
||||
if( nodenum < 0 ) return;
|
||||
|
||||
if( hull->lastclipnode == MAX_MAP_CLIPNODES_HLBSP )
|
||||
Host_Error( "%s: MAX_MAP_CLIPNODES_HLBSP limit exceeded\n", __func__ );
|
||||
if( hull->lastclipnode == MAX_MAP_CLIPNODES )
|
||||
Host_Error( "MAX_MAP_CLIPNODES limit exceeded\n" );
|
||||
hull->lastclipnode++;
|
||||
|
||||
CountClipNodes16_r( src, hull, src[nodenum].children[0] );
|
||||
@@ -1592,25 +1592,25 @@ static void CountClipNodes32_r( mclipnode32_t *src, hull_t *hull, int nodenum )
|
||||
// leaf?
|
||||
if( nodenum < 0 ) return;
|
||||
|
||||
if( hull->lastclipnode == MAX_MAP_CLIPNODES_BSP2 )
|
||||
Host_Error( "%s: MAX_MAP_CLIPNODES_BSP2 limit exceeded\n", __func__ );
|
||||
if( hull->lastclipnode == MAX_MAP_CLIPNODES )
|
||||
Host_Error( "MAX_MAP_CLIPNODES limit exceeded\n" );
|
||||
hull->lastclipnode++;
|
||||
|
||||
CountClipNodes32_r( src, hull, src[nodenum].children[0] );
|
||||
CountClipNodes32_r( src, hull, src[nodenum].children[1] );
|
||||
}
|
||||
|
||||
static void CountDClipNodes_r( dclipnode32_t *src, hull_t *hull, int nodenum, const int max_clipnodes )
|
||||
static void CountDClipNodes_r( dclipnode32_t *src, hull_t *hull, int nodenum )
|
||||
{
|
||||
// leaf?
|
||||
if( nodenum < 0 ) return;
|
||||
|
||||
if( hull->lastclipnode == max_clipnodes )
|
||||
Host_Error( "%s: MAX_MAP_CLIPNODES (%d) limit exceeded\n", __func__, max_clipnodes );
|
||||
if( hull->lastclipnode == MAX_MAP_CLIPNODES )
|
||||
Host_Error( "MAX_MAP_CLIPNODES limit exceeded\n" );
|
||||
hull->lastclipnode++;
|
||||
|
||||
CountDClipNodes_r( src, hull, src[nodenum].children[0], max_clipnodes );
|
||||
CountDClipNodes_r( src, hull, src[nodenum].children[1], max_clipnodes );
|
||||
CountDClipNodes_r( src, hull, src[nodenum].children[0] );
|
||||
CountDClipNodes_r( src, hull, src[nodenum].children[1] );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1628,17 +1628,8 @@ static int RemapClipNodes_r( dbspmodel_t *bmod, dclipnode32_t *srcnodes, hull_t
|
||||
return nodenum;
|
||||
|
||||
// emit a clipnode
|
||||
if( bmod->version == QBSP2_VERSION )
|
||||
{
|
||||
if( hull->lastclipnode == MAX_MAP_CLIPNODES_BSP2 )
|
||||
Host_Error( "%s: MAX_MAP_CLIPNODES_BSP2 limit exceeded\n", __func__ );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( hull->lastclipnode == MAX_MAP_CLIPNODES_HLBSP )
|
||||
Host_Error( "%s: MAX_MAP_CLIPNODES_HLBSP limit exceeded\n", __func__ );
|
||||
}
|
||||
|
||||
if( hull->lastclipnode == MAX_MAP_CLIPNODES )
|
||||
Host_Error( "MAX_MAP_CLIPNODES limit exceeded\n" );
|
||||
src = srcnodes + nodenum;
|
||||
|
||||
c = hull->lastclipnode;
|
||||
@@ -1770,17 +1761,13 @@ static void Mod_SetupHull( dbspmodel_t *bmod, model_t *mod, poolhandle_t mempool
|
||||
if( VectorIsNull( hull->clip_mins ) && VectorIsNull( hull->clip_maxs ))
|
||||
return; // no hull specified
|
||||
|
||||
CountDClipNodes_r( bmod->clipnodes_out, hull, headnode );
|
||||
|
||||
// fit array to real count
|
||||
if( bmod->version == QBSP2_VERSION )
|
||||
{
|
||||
CountDClipNodes_r( bmod->clipnodes_out, hull, headnode, MAX_MAP_CLIPNODES_BSP2 );
|
||||
hull->clipnodes32 = Mem_Malloc( mempool, sizeof( *hull->clipnodes32 ) * hull->lastclipnode );
|
||||
}
|
||||
else
|
||||
{
|
||||
CountDClipNodes_r( bmod->clipnodes_out, hull, headnode, MAX_MAP_CLIPNODES_HLBSP );
|
||||
hull->clipnodes16 = Mem_Malloc( mempool, sizeof( *hull->clipnodes16 ) * hull->lastclipnode );
|
||||
}
|
||||
|
||||
hull->planes = mod->planes; // share planes
|
||||
hull->lastclipnode = 0; // restart counting
|
||||
@@ -2372,7 +2359,7 @@ static qboolean Mod_SearchForTextureReplacement( char *out, size_t size, const c
|
||||
return false;
|
||||
}
|
||||
|
||||
static void Mod_InitSkyClouds( model_t *mod, const mip_t *mt, texture_t *tx, qboolean custom_palette )
|
||||
static void Mod_InitSkyClouds( model_t *mod, mip_t *mt, texture_t *tx, qboolean custom_palette )
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
rgbdata_t r_temp, *r_sky;
|
||||
@@ -2529,6 +2516,9 @@ done:
|
||||
|
||||
static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureIndex )
|
||||
{
|
||||
texture_t *texture = NULL;
|
||||
mip_t *mipTex = NULL;
|
||||
qboolean usesCustomPalette = false;
|
||||
uint32_t txFlags = 0;
|
||||
char texpath[MAX_VA_STRING];
|
||||
char safemtname[16]; // only for external textures
|
||||
@@ -2536,10 +2526,12 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
|
||||
|
||||
// don't load texture data on dedicated server, as there is no renderer.
|
||||
// but count the wadusage for automatic precache
|
||||
texture_t *texture = mod->textures[textureIndex];
|
||||
const mip_t *mipTex = Mod_GetMipTexForTexture( bmod, textureIndex );
|
||||
const qboolean usesCustomPalette = Mod_CalcMipTexUsesCustomPalette( mod, bmod, textureIndex );
|
||||
const qboolean iswater = Mod_LooksLikeWaterTexture( mipTex->name );
|
||||
//
|
||||
// FIXME: for ENGINE_IMPROVED_LINETRACE we need to load textures on server too
|
||||
// but there is no facility for this yet
|
||||
texture = mod->textures[textureIndex];
|
||||
mipTex = Mod_GetMipTexForTexture( bmod, textureIndex );
|
||||
usesCustomPalette = Mod_CalcMipTexUsesCustomPalette( mod, bmod, textureIndex );
|
||||
|
||||
// check for multi-layered sky texture (quake1 specific)
|
||||
if( bmod->isworld && Q_strncmp( mipTex->name, "sky", 3 ) == 0 && ( mipTex->width / mipTex->height ) == 2 )
|
||||
@@ -2548,13 +2540,11 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: for ENGINE_IMPROVED_LINETRACE we need to load textures on server too
|
||||
// but there is no facility for this yet
|
||||
if( FBitSet( host.features, ENGINE_IMPROVED_LINETRACE ) && mipTex->name[0] == '{' )
|
||||
SetBits( txFlags, TF_KEEP_SOURCE ); // Paranoia2 texture alpha-tracing
|
||||
|
||||
// check if this is water to keep the source texture and expand it to RGBA (so ripple effect works)
|
||||
if( iswater )
|
||||
if( Mod_LooksLikeWaterTexture( mipTex->name ))
|
||||
SetBits( txFlags, TF_KEEP_SOURCE | TF_EXPAND_SOURCE );
|
||||
|
||||
// Texture loading order:
|
||||
@@ -2619,13 +2609,8 @@ static void Mod_LoadTextureData( model_t *mod, dbspmodel_t *bmod, int textureInd
|
||||
texture->gl_texturenum = R_GetBuiltinTexture( REF_DEFAULT_TEXTURE );
|
||||
}
|
||||
|
||||
texture->fb_texturenum = 0;
|
||||
|
||||
// Check for luma texture
|
||||
// a1ba: ignore for water because fb_texturenum will be used to store ripple texture
|
||||
if( iswater )
|
||||
return;
|
||||
|
||||
texture->fb_texturenum = 0;
|
||||
if( load_external ) // external textures will not have TF_HAS_LUMA flag because it set only from WAD images loader
|
||||
{
|
||||
if( Mod_SearchForTextureReplacement( texpath, sizeof( texpath ), mod->name, safemtname, "_luma" ))
|
||||
@@ -3467,7 +3452,7 @@ static void Mod_LoadClipnodes( model_t *mod, dbspmodel_t *bmod )
|
||||
out->children[0] = (unsigned short)in->children[0];
|
||||
out->children[1] = (unsigned short)in->children[1];
|
||||
|
||||
// aguirRe QBSP 'broken' clipnodes
|
||||
// Arguire QBSP 'broken' clipnodes
|
||||
if( out->children[0] >= bmod->numclipnodes )
|
||||
out->children[0] -= 65536;
|
||||
if( out->children[1] >= bmod->numclipnodes )
|
||||
|
||||
@@ -169,7 +169,7 @@ void Mod_LoadAliasModel( model_t *mod, const void *buffer, qboolean *loaded );
|
||||
//
|
||||
void Mod_LoadBrushModel( model_t *mod, const void *buffer, qboolean *loaded );
|
||||
qboolean Mod_TestBmodelLumps( file_t *f, const char *name, const byte *mod_base, qboolean silent, dlump_t *entities );
|
||||
int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis, qboolean phs );
|
||||
int Mod_FatPVS( const vec3_t org, float radius, byte *visbuffer, int visbytes, qboolean merge, qboolean fullvis, qboolean false );
|
||||
qboolean Mod_BoxVisible( const vec3_t mins, const vec3_t maxs, const byte *visbits );
|
||||
int Mod_CheckLump( const char *filename, const int lump, int *lumpsize );
|
||||
int Mod_ReadLump( const char *filename, const int lump, void **lumpdata, int *lumpsize );
|
||||
|
||||
@@ -382,7 +382,8 @@ static void Mod_StudioCalcRotations( int boneused[], int numbones, const byte *p
|
||||
for( j = numbones - 1; j >= 0; j-- )
|
||||
{
|
||||
i = boneused[j];
|
||||
R_StudioCalcBones( frame, s, &pbone[i], &panim[i], adj, pos[i], q[i] );
|
||||
R_StudioCalcBoneQuaternion( frame, s, &pbone[i], &panim[i], adj, q[i] );
|
||||
R_StudioCalcBonePosition( frame, s, &pbone[i], &panim[i], adj, pos[i] );
|
||||
}
|
||||
|
||||
if( pseqdesc->motiontype & STUDIO_X ) pos[pseqdesc->motionbone][0] = 0.0f;
|
||||
@@ -723,7 +724,7 @@ void Mod_StudioComputeBounds( void *buffer, vec3_t mins, vec3_t maxs, qboolean i
|
||||
{
|
||||
for( k = 0; k < pseqdesc->numframes; k++ )
|
||||
{
|
||||
R_StudioCalcBones( k, 0, &pbones[j], panim, NULL, pos, NULL );
|
||||
R_StudioCalcBonePosition( k, 0, &pbones[j], panim, NULL, pos );
|
||||
Mod_StudioBoundVertex( vert_mins, vert_maxs, &bone_count, pos );
|
||||
}
|
||||
}
|
||||
@@ -867,7 +868,7 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded )
|
||||
mod->type = mod_studio;
|
||||
|
||||
phdr = R_StudioLoadHeader( mod, buffer );
|
||||
if( !phdr || phdr->length < sizeof( studiohdr_t )) // garbage value in length
|
||||
if( !phdr )
|
||||
return; // bad model
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
|
||||
@@ -258,7 +258,7 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
|
||||
{
|
||||
char tempname[MAX_QPATH];
|
||||
fs_offset_t length = 0;
|
||||
qboolean loaded, loaded2 = false;
|
||||
qboolean loaded;
|
||||
byte *buf;
|
||||
model_info_t *p;
|
||||
|
||||
@@ -279,7 +279,7 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
|
||||
|
||||
buf = FS_LoadFile( tempname, &length, false );
|
||||
|
||||
if( !buf || length < sizeof( uint ))
|
||||
if( !buf )
|
||||
{
|
||||
memset( mod, 0, sizeof( model_t ));
|
||||
|
||||
@@ -329,12 +329,11 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
|
||||
// let the server.dll load custom data
|
||||
svgame.physFuncs.Mod_ProcessUserData( mod, true, buf );
|
||||
}
|
||||
loaded2 = true;
|
||||
}
|
||||
#if !XASH_DEDICATED
|
||||
else
|
||||
{
|
||||
loaded2 = ref.dllFuncs.Mod_ProcessRenderData( mod, true, buf );
|
||||
loaded = ref.dllFuncs.Mod_ProcessRenderData( mod, true, buf );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -346,7 +345,7 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
|
||||
hdr->pposeverts = NULL;
|
||||
}
|
||||
|
||||
if( !loaded || !loaded2 )
|
||||
if( !loaded )
|
||||
{
|
||||
Mod_FreeModel( mod );
|
||||
Mem_Free( buf );
|
||||
@@ -611,41 +610,3 @@ void Mod_NeedCRC( const char *name, qboolean needCRC )
|
||||
if( needCRC ) SetBits( p->flags, FCRC_SHOULD_CHECKSUM );
|
||||
else ClearBits( p->flags, FCRC_SHOULD_CHECKSUM );
|
||||
}
|
||||
|
||||
#if XASH_ENGINE_TESTS
|
||||
|
||||
static const uint8_t *fuzz_data;
|
||||
static size_t fuzz_size;
|
||||
|
||||
static byte *Fuzz_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly )
|
||||
{
|
||||
byte *buf = Mem_Malloc( host.mempool, fuzz_size );
|
||||
memcpy( buf, fuzz_data, fuzz_size );
|
||||
*filesizeptr = fuzz_size;
|
||||
return buf;
|
||||
}
|
||||
|
||||
int EXPORT Fuzz_Mod_LoadModel( const uint8_t *Data, size_t Size );
|
||||
int EXPORT Fuzz_Mod_LoadModel( const uint8_t *Data, size_t Size )
|
||||
{
|
||||
model_t mod = { .name = "test", .needload = NL_NEEDS_LOADED };
|
||||
|
||||
Memory_Init();
|
||||
|
||||
host.type = HOST_DEDICATED;
|
||||
host.mempool = Mem_AllocPool( "fuzzing pool" );
|
||||
fuzz_data = Data;
|
||||
fuzz_size = Size;
|
||||
refState.draw_surfaces = NULL;
|
||||
|
||||
g_fsapi.LoadFile = Fuzz_LoadFile;
|
||||
|
||||
if( Mod_LoadModel( &mod, false ) && mod.mempool )
|
||||
Mem_FreePool( &mod.mempool );
|
||||
|
||||
Mem_FreePool( &host.mempool );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // XASH_ENGINE_TESTS
|
||||
|
||||
@@ -18,177 +18,11 @@ GNU General Public License for more details.
|
||||
#include "net_buffer.h"
|
||||
#include "xash3d_mathlib.h"
|
||||
|
||||
static const uint32_t BitWriteMasks[32][32] =
|
||||
{ {
|
||||
0xfffffffe, 0xfffffffc, 0xfffffff8, 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80, 0xffffff00,
|
||||
0xfffffe00, 0xfffffc00, 0xfffff800, 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000, 0xffff0000,
|
||||
0xfffe0000, 0xfffc0000, 0xfff80000, 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, 0xff000000,
|
||||
0xfe000000, 0xfc000000, 0xf8000000, 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000, 0x00000000,
|
||||
}, {
|
||||
0xfffffffd, 0xfffffff9, 0xfffffff1, 0xffffffe1, 0xffffffc1, 0xffffff81, 0xffffff01, 0xfffffe01,
|
||||
0xfffffc01, 0xfffff801, 0xfffff001, 0xffffe001, 0xffffc001, 0xffff8001, 0xffff0001, 0xfffe0001,
|
||||
0xfffc0001, 0xfff80001, 0xfff00001, 0xffe00001, 0xffc00001, 0xff800001, 0xff000001, 0xfe000001,
|
||||
0xfc000001, 0xf8000001, 0xf0000001, 0xe0000001, 0xc0000001, 0x80000001, 0x00000001, 0x00000001,
|
||||
}, {
|
||||
0xfffffffb, 0xfffffff3, 0xffffffe3, 0xffffffc3, 0xffffff83, 0xffffff03, 0xfffffe03, 0xfffffc03,
|
||||
0xfffff803, 0xfffff003, 0xffffe003, 0xffffc003, 0xffff8003, 0xffff0003, 0xfffe0003, 0xfffc0003,
|
||||
0xfff80003, 0xfff00003, 0xffe00003, 0xffc00003, 0xff800003, 0xff000003, 0xfe000003, 0xfc000003,
|
||||
0xf8000003, 0xf0000003, 0xe0000003, 0xc0000003, 0x80000003, 0x00000003, 0x00000003, 0x00000003,
|
||||
}, {
|
||||
0xfffffff7, 0xffffffe7, 0xffffffc7, 0xffffff87, 0xffffff07, 0xfffffe07, 0xfffffc07, 0xfffff807,
|
||||
0xfffff007, 0xffffe007, 0xffffc007, 0xffff8007, 0xffff0007, 0xfffe0007, 0xfffc0007, 0xfff80007,
|
||||
0xfff00007, 0xffe00007, 0xffc00007, 0xff800007, 0xff000007, 0xfe000007, 0xfc000007, 0xf8000007,
|
||||
0xf0000007, 0xe0000007, 0xc0000007, 0x80000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007,
|
||||
}, {
|
||||
0xffffffef, 0xffffffcf, 0xffffff8f, 0xffffff0f, 0xfffffe0f, 0xfffffc0f, 0xfffff80f, 0xfffff00f,
|
||||
0xffffe00f, 0xffffc00f, 0xffff800f, 0xffff000f, 0xfffe000f, 0xfffc000f, 0xfff8000f, 0xfff0000f,
|
||||
0xffe0000f, 0xffc0000f, 0xff80000f, 0xff00000f, 0xfe00000f, 0xfc00000f, 0xf800000f, 0xf000000f,
|
||||
0xe000000f, 0xc000000f, 0x8000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f,
|
||||
}, {
|
||||
0xffffffdf, 0xffffff9f, 0xffffff1f, 0xfffffe1f, 0xfffffc1f, 0xfffff81f, 0xfffff01f, 0xffffe01f,
|
||||
0xffffc01f, 0xffff801f, 0xffff001f, 0xfffe001f, 0xfffc001f, 0xfff8001f, 0xfff0001f, 0xffe0001f,
|
||||
0xffc0001f, 0xff80001f, 0xff00001f, 0xfe00001f, 0xfc00001f, 0xf800001f, 0xf000001f, 0xe000001f,
|
||||
0xc000001f, 0x8000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f,
|
||||
}, {
|
||||
0xffffffbf, 0xffffff3f, 0xfffffe3f, 0xfffffc3f, 0xfffff83f, 0xfffff03f, 0xffffe03f, 0xffffc03f,
|
||||
0xffff803f, 0xffff003f, 0xfffe003f, 0xfffc003f, 0xfff8003f, 0xfff0003f, 0xffe0003f, 0xffc0003f,
|
||||
0xff80003f, 0xff00003f, 0xfe00003f, 0xfc00003f, 0xf800003f, 0xf000003f, 0xe000003f, 0xc000003f,
|
||||
0x8000003f, 0x0000003f, 0x0000003f, 0x0000003f, 0x0000003f, 0x0000003f, 0x0000003f, 0x0000003f,
|
||||
}, {
|
||||
0xffffff7f, 0xfffffe7f, 0xfffffc7f, 0xfffff87f, 0xfffff07f, 0xffffe07f, 0xffffc07f, 0xffff807f,
|
||||
0xffff007f, 0xfffe007f, 0xfffc007f, 0xfff8007f, 0xfff0007f, 0xffe0007f, 0xffc0007f, 0xff80007f,
|
||||
0xff00007f, 0xfe00007f, 0xfc00007f, 0xf800007f, 0xf000007f, 0xe000007f, 0xc000007f, 0x8000007f,
|
||||
0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f,
|
||||
}, {
|
||||
0xfffffeff, 0xfffffcff, 0xfffff8ff, 0xfffff0ff, 0xffffe0ff, 0xffffc0ff, 0xffff80ff, 0xffff00ff,
|
||||
0xfffe00ff, 0xfffc00ff, 0xfff800ff, 0xfff000ff, 0xffe000ff, 0xffc000ff, 0xff8000ff, 0xff0000ff,
|
||||
0xfe0000ff, 0xfc0000ff, 0xf80000ff, 0xf00000ff, 0xe00000ff, 0xc00000ff, 0x800000ff, 0x000000ff,
|
||||
0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff,
|
||||
}, {
|
||||
0xfffffdff, 0xfffff9ff, 0xfffff1ff, 0xffffe1ff, 0xffffc1ff, 0xffff81ff, 0xffff01ff, 0xfffe01ff,
|
||||
0xfffc01ff, 0xfff801ff, 0xfff001ff, 0xffe001ff, 0xffc001ff, 0xff8001ff, 0xff0001ff, 0xfe0001ff,
|
||||
0xfc0001ff, 0xf80001ff, 0xf00001ff, 0xe00001ff, 0xc00001ff, 0x800001ff, 0x000001ff, 0x000001ff,
|
||||
0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff, 0x000001ff,
|
||||
}, {
|
||||
0xfffffbff, 0xfffff3ff, 0xffffe3ff, 0xffffc3ff, 0xffff83ff, 0xffff03ff, 0xfffe03ff, 0xfffc03ff,
|
||||
0xfff803ff, 0xfff003ff, 0xffe003ff, 0xffc003ff, 0xff8003ff, 0xff0003ff, 0xfe0003ff, 0xfc0003ff,
|
||||
0xf80003ff, 0xf00003ff, 0xe00003ff, 0xc00003ff, 0x800003ff, 0x000003ff, 0x000003ff, 0x000003ff,
|
||||
0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff, 0x000003ff,
|
||||
}, {
|
||||
0xfffff7ff, 0xffffe7ff, 0xffffc7ff, 0xffff87ff, 0xffff07ff, 0xfffe07ff, 0xfffc07ff, 0xfff807ff,
|
||||
0xfff007ff, 0xffe007ff, 0xffc007ff, 0xff8007ff, 0xff0007ff, 0xfe0007ff, 0xfc0007ff, 0xf80007ff,
|
||||
0xf00007ff, 0xe00007ff, 0xc00007ff, 0x800007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff,
|
||||
0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff, 0x000007ff,
|
||||
}, {
|
||||
0xffffefff, 0xffffcfff, 0xffff8fff, 0xffff0fff, 0xfffe0fff, 0xfffc0fff, 0xfff80fff, 0xfff00fff,
|
||||
0xffe00fff, 0xffc00fff, 0xff800fff, 0xff000fff, 0xfe000fff, 0xfc000fff, 0xf8000fff, 0xf0000fff,
|
||||
0xe0000fff, 0xc0000fff, 0x80000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff,
|
||||
0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff, 0x00000fff,
|
||||
}, {
|
||||
0xffffdfff, 0xffff9fff, 0xffff1fff, 0xfffe1fff, 0xfffc1fff, 0xfff81fff, 0xfff01fff, 0xffe01fff,
|
||||
0xffc01fff, 0xff801fff, 0xff001fff, 0xfe001fff, 0xfc001fff, 0xf8001fff, 0xf0001fff, 0xe0001fff,
|
||||
0xc0001fff, 0x80001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff,
|
||||
0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff, 0x00001fff,
|
||||
}, {
|
||||
0xffffbfff, 0xffff3fff, 0xfffe3fff, 0xfffc3fff, 0xfff83fff, 0xfff03fff, 0xffe03fff, 0xffc03fff,
|
||||
0xff803fff, 0xff003fff, 0xfe003fff, 0xfc003fff, 0xf8003fff, 0xf0003fff, 0xe0003fff, 0xc0003fff,
|
||||
0x80003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff,
|
||||
0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff, 0x00003fff,
|
||||
}, {
|
||||
0xffff7fff, 0xfffe7fff, 0xfffc7fff, 0xfff87fff, 0xfff07fff, 0xffe07fff, 0xffc07fff, 0xff807fff,
|
||||
0xff007fff, 0xfe007fff, 0xfc007fff, 0xf8007fff, 0xf0007fff, 0xe0007fff, 0xc0007fff, 0x80007fff,
|
||||
0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff,
|
||||
0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff, 0x00007fff,
|
||||
}, {
|
||||
0xfffeffff, 0xfffcffff, 0xfff8ffff, 0xfff0ffff, 0xffe0ffff, 0xffc0ffff, 0xff80ffff, 0xff00ffff,
|
||||
0xfe00ffff, 0xfc00ffff, 0xf800ffff, 0xf000ffff, 0xe000ffff, 0xc000ffff, 0x8000ffff, 0x0000ffff,
|
||||
0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff,
|
||||
0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff,
|
||||
}, {
|
||||
0xfffdffff, 0xfff9ffff, 0xfff1ffff, 0xffe1ffff, 0xffc1ffff, 0xff81ffff, 0xff01ffff, 0xfe01ffff,
|
||||
0xfc01ffff, 0xf801ffff, 0xf001ffff, 0xe001ffff, 0xc001ffff, 0x8001ffff, 0x0001ffff, 0x0001ffff,
|
||||
0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff,
|
||||
0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff, 0x0001ffff,
|
||||
}, {
|
||||
0xfffbffff, 0xfff3ffff, 0xffe3ffff, 0xffc3ffff, 0xff83ffff, 0xff03ffff, 0xfe03ffff, 0xfc03ffff,
|
||||
0xf803ffff, 0xf003ffff, 0xe003ffff, 0xc003ffff, 0x8003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff,
|
||||
0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff,
|
||||
0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff,
|
||||
}, {
|
||||
0xfff7ffff, 0xffe7ffff, 0xffc7ffff, 0xff87ffff, 0xff07ffff, 0xfe07ffff, 0xfc07ffff, 0xf807ffff,
|
||||
0xf007ffff, 0xe007ffff, 0xc007ffff, 0x8007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff,
|
||||
0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff,
|
||||
0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff, 0x0007ffff,
|
||||
}, {
|
||||
0xffefffff, 0xffcfffff, 0xff8fffff, 0xff0fffff, 0xfe0fffff, 0xfc0fffff, 0xf80fffff, 0xf00fffff,
|
||||
0xe00fffff, 0xc00fffff, 0x800fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff,
|
||||
0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff,
|
||||
0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff, 0x000fffff,
|
||||
}, {
|
||||
0xffdfffff, 0xff9fffff, 0xff1fffff, 0xfe1fffff, 0xfc1fffff, 0xf81fffff, 0xf01fffff, 0xe01fffff,
|
||||
0xc01fffff, 0x801fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff,
|
||||
0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff,
|
||||
0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff, 0x001fffff,
|
||||
}, {
|
||||
0xffbfffff, 0xff3fffff, 0xfe3fffff, 0xfc3fffff, 0xf83fffff, 0xf03fffff, 0xe03fffff, 0xc03fffff,
|
||||
0x803fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff,
|
||||
0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff,
|
||||
0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff, 0x003fffff,
|
||||
}, {
|
||||
0xff7fffff, 0xfe7fffff, 0xfc7fffff, 0xf87fffff, 0xf07fffff, 0xe07fffff, 0xc07fffff, 0x807fffff,
|
||||
0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff,
|
||||
0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff,
|
||||
0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff, 0x007fffff,
|
||||
}, {
|
||||
0xfeffffff, 0xfcffffff, 0xf8ffffff, 0xf0ffffff, 0xe0ffffff, 0xc0ffffff, 0x80ffffff, 0x00ffffff,
|
||||
0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff,
|
||||
0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff,
|
||||
0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff,
|
||||
}, {
|
||||
0xfdffffff, 0xf9ffffff, 0xf1ffffff, 0xe1ffffff, 0xc1ffffff, 0x81ffffff, 0x01ffffff, 0x01ffffff,
|
||||
0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
|
||||
0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
|
||||
0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff, 0x01ffffff,
|
||||
}, {
|
||||
0xfbffffff, 0xf3ffffff, 0xe3ffffff, 0xc3ffffff, 0x83ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
|
||||
0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
|
||||
0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
|
||||
0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff, 0x03ffffff,
|
||||
}, {
|
||||
0xf7ffffff, 0xe7ffffff, 0xc7ffffff, 0x87ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff,
|
||||
0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff,
|
||||
0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff,
|
||||
0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff, 0x07ffffff,
|
||||
}, {
|
||||
0xefffffff, 0xcfffffff, 0x8fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff,
|
||||
0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff,
|
||||
0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff,
|
||||
0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff, 0x0fffffff,
|
||||
}, {
|
||||
0xdfffffff, 0x9fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff,
|
||||
0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff,
|
||||
0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff,
|
||||
0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff, 0x1fffffff,
|
||||
}, {
|
||||
0xbfffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff,
|
||||
0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff,
|
||||
0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff,
|
||||
0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff,
|
||||
}, {
|
||||
0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
|
||||
0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
|
||||
0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
|
||||
0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
|
||||
} };
|
||||
|
||||
static const uint32_t ExtraMasks[32] =
|
||||
{
|
||||
0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
|
||||
0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
|
||||
0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
|
||||
0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
|
||||
};
|
||||
|
||||
// precalculated bit masks for WriteUBitLong.
|
||||
// Using these tables instead of doing the calculations
|
||||
// gives a 33% speedup in WriteUBitLong.
|
||||
static uint32_t BitWriteMasks[32][33];
|
||||
static uint32_t ExtraMasks[32];
|
||||
const char *const svc_strings[svc_lastmsg+1] =
|
||||
{
|
||||
"svc_bad",
|
||||
@@ -298,41 +132,65 @@ const char *const svc_quake_strings[svc_lastmsg+1] =
|
||||
[svc_fog] = "svc_quake_fog",
|
||||
};
|
||||
|
||||
void MSG_InitMasks( void )
|
||||
{
|
||||
uint startbit, endbit;
|
||||
uint maskBit, nBitsLeft;
|
||||
|
||||
for( startbit = 0; startbit < 32; startbit++ )
|
||||
{
|
||||
for( nBitsLeft = 0; nBitsLeft < 33; nBitsLeft++ )
|
||||
{
|
||||
endbit = startbit + nBitsLeft;
|
||||
|
||||
BitWriteMasks[startbit][nBitsLeft] = (uint)BIT( startbit ) - 1;
|
||||
if( endbit < 32 ) BitWriteMasks[startbit][nBitsLeft] |= ~((uint)BIT( endbit ) - 1 );
|
||||
}
|
||||
}
|
||||
|
||||
for( maskBit = 0; maskBit < 32; maskBit++ )
|
||||
ExtraMasks[maskBit] = (uint)BIT( maskBit ) - 1;
|
||||
}
|
||||
|
||||
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.
|
||||
uint32_t iCurBitMasked;
|
||||
int nBitsWritten;
|
||||
|
||||
Assert( numbits >= 1 && numbits <= 32 );
|
||||
Assert( numbits >= 0 && numbits <= 32 );
|
||||
|
||||
// bounds checking..
|
||||
if( MSG_Overflow( sb, numbits ))
|
||||
if(( sb->iCurBit + numbits ) > sb->nDataBits )
|
||||
{
|
||||
sb->bOverflow = true;
|
||||
sb->iCurBit = sb->nDataBits;
|
||||
return;
|
||||
}
|
||||
|
||||
iCurBitMasked = iCurBit & 31;
|
||||
((uint32_t *)sb->pData)[iDWord] &= BitWriteMasks[iCurBitMasked][nBitsLeft-1];
|
||||
((uint32_t *)sb->pData)[iDWord] |= curData << iCurBitMasked;
|
||||
|
||||
// did it span a dword?
|
||||
nBitsWritten = 32 - iCurBitMasked;
|
||||
|
||||
if( nBitsWritten < nBitsLeft )
|
||||
else
|
||||
{
|
||||
nBitsLeft -= nBitsWritten;
|
||||
iCurBit += nBitsWritten;
|
||||
curData >>= nBitsWritten;
|
||||
int nBitsLeft = numbits;
|
||||
int iCurBit = sb->iCurBit;
|
||||
uint iDWord = iCurBit >> 5; // Mask in a dword.
|
||||
uint32_t iCurBitMasked;
|
||||
int nBitsWritten;
|
||||
|
||||
Assert(( iDWord * 4 + sizeof( int )) <= (uint)MSG_GetMaxBytes( sb ));
|
||||
|
||||
iCurBitMasked = iCurBit & 31;
|
||||
((uint32_t *)sb->pData)[iDWord+1] &= BitWriteMasks[iCurBitMasked][nBitsLeft-1];
|
||||
((uint32_t *)sb->pData)[iDWord+1] |= 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;
|
||||
|
||||
if( nBitsWritten < nBitsLeft )
|
||||
{
|
||||
nBitsLeft -= nBitsWritten;
|
||||
iCurBit += nBitsWritten;
|
||||
curData >>= nBitsWritten;
|
||||
|
||||
iCurBitMasked = iCurBit & 31;
|
||||
((uint32_t *)sb->pData)[iDWord+1] &= BitWriteMasks[iCurBitMasked][nBitsLeft];
|
||||
((uint32_t *)sb->pData)[iDWord+1] |= curData << iCurBitMasked;
|
||||
}
|
||||
sb->iCurBit += numbits;
|
||||
}
|
||||
sb->iCurBit += numbits;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -380,7 +238,7 @@ qboolean MSG_WriteBits( sizebuf_t *sb, const void *pData, int nBits )
|
||||
int nBitsLeft = nBits;
|
||||
|
||||
// get output dword-aligned.
|
||||
while((( uintptr_t )pOut & 3 ) != 0 && nBitsLeft >= 8 )
|
||||
while((( uint32_t )pOut & 3 ) != 0 && nBitsLeft >= 8 )
|
||||
{
|
||||
MSG_WriteUBitLong( sb, *pOut, 8 );
|
||||
|
||||
@@ -417,14 +275,16 @@ qboolean MSG_WriteBits( sizebuf_t *sb, const void *pData, int nBits )
|
||||
|
||||
void MSG_WriteBitAngle( sizebuf_t *sb, float fAngle, int numbits )
|
||||
{
|
||||
const uint shift = ( 1 << numbits );
|
||||
const uint mask = shift - 1;
|
||||
uint mask, shift;
|
||||
int d;
|
||||
|
||||
// clamp the angle before receiving
|
||||
fAngle = fmod( fAngle, 360.0f );
|
||||
if( fAngle < 0 ) fAngle += 360.0f;
|
||||
|
||||
shift = ( 1 << numbits );
|
||||
mask = shift - 1;
|
||||
|
||||
d = (int)(( fAngle * shift ) / 360.0f );
|
||||
d &= mask;
|
||||
|
||||
@@ -578,8 +438,9 @@ uint MSG_ReadUBitLong( sizebuf_t *sb, int numbits )
|
||||
return 0; // end of message
|
||||
}
|
||||
|
||||
if( MSG_Overflow( sb, numbits ))
|
||||
if(( sb->iCurBit + numbits ) > sb->nDataBits )
|
||||
{
|
||||
sb->bOverflow = true;
|
||||
sb->iCurBit = sb->nDataBits;
|
||||
return 0;
|
||||
}
|
||||
@@ -618,7 +479,7 @@ qboolean MSG_ReadBits( sizebuf_t *sb, void *pOutData, int nBits )
|
||||
int nBitsLeft = nBits;
|
||||
|
||||
// get output dword-aligned.
|
||||
while((( uintptr_t )pOut & 3) != 0 && nBitsLeft >= 8 )
|
||||
while((( uint32_t )pOut & 3) != 0 && nBitsLeft >= 8 )
|
||||
{
|
||||
*pOut = (byte)MSG_ReadUBitLong( sb, 8 );
|
||||
++pOut;
|
||||
@@ -652,9 +513,13 @@ qboolean MSG_ReadBits( sizebuf_t *sb, void *pOutData, int nBits )
|
||||
|
||||
float MSG_ReadBitAngle( sizebuf_t *sb, int numbits )
|
||||
{
|
||||
float shift = (float)( 1 << numbits );
|
||||
int i = MSG_ReadUBitLong( sb, numbits );
|
||||
float fReturn = (float)i * ( 360.0f / shift );
|
||||
float fReturn, shift;
|
||||
int i;
|
||||
|
||||
shift = (float)( 1 << numbits );
|
||||
|
||||
i = MSG_ReadUBitLong( sb, numbits );
|
||||
fReturn = (float)i * ( 360.0f / shift );
|
||||
|
||||
// clamp the finale angle
|
||||
if( fReturn < -180.0f ) fReturn += 360.0f;
|
||||
@@ -666,11 +531,11 @@ float MSG_ReadBitAngle( sizebuf_t *sb, int numbits )
|
||||
// Append numbits least significant bits from data to the current bit stream
|
||||
int MSG_ReadSBitLong( sizebuf_t *sb, int numbits )
|
||||
{
|
||||
int r;
|
||||
int r, sign;
|
||||
|
||||
if( sb->iAlternateSign )
|
||||
{
|
||||
int sign = MSG_ReadOneBit( sb );
|
||||
sign = MSG_ReadOneBit( sb );
|
||||
r = MSG_ReadUBitLong( sb, numbits - 1 );
|
||||
|
||||
if( sign )
|
||||
@@ -679,7 +544,9 @@ int MSG_ReadSBitLong( sizebuf_t *sb, int numbits )
|
||||
else
|
||||
{
|
||||
r = MSG_ReadUBitLong( sb, numbits - 1 );
|
||||
if( MSG_ReadOneBit( sb ))
|
||||
sign = MSG_ReadOneBit( sb );
|
||||
|
||||
if( sign )
|
||||
r = -( BIT( numbits - 1 ) - r );
|
||||
}
|
||||
|
||||
@@ -800,12 +667,12 @@ qboolean MSG_ReadBytes( sizebuf_t *sb, void *pOut, int nBytes )
|
||||
static char *MSG_ReadStringExt( sizebuf_t *sb, qboolean bLine )
|
||||
{
|
||||
static char string[4096];
|
||||
int l = 0;
|
||||
int l = 0, c;
|
||||
|
||||
do
|
||||
{
|
||||
// use MSG_ReadByte so -1 is out of bounds
|
||||
int c = MSG_ReadByte( sb );
|
||||
c = MSG_ReadByte( sb );
|
||||
|
||||
if( c == 0 ) break;
|
||||
else if( bLine && c == '\n' )
|
||||
@@ -873,7 +740,7 @@ static void Test_Buffer_Write( void )
|
||||
MSG_Init( &sb, __func__, testdata, sizeof( testdata ));
|
||||
TASSERT_EQi( sb.iCurBit, 0 );
|
||||
TASSERT_EQi( sb.nDataBits, sizeof( testdata ) << 3 );
|
||||
TASSERT_EQp( sb.pData, (void *)testdata );
|
||||
TASSERT_EQi( sb.pData, testdata );
|
||||
TASSERT_EQi( sb.bOverflow, false );
|
||||
|
||||
MSG_WriteBytes( &sb, "asdf", 4 );
|
||||
@@ -929,7 +796,7 @@ static void Test_Buffer_Read( void )
|
||||
MSG_StartReading( &sb, (void *)g_testbuf, -1, 0, g_testbuf_bits );
|
||||
TASSERT_EQi( sb.iCurBit, 0 );
|
||||
TASSERT_EQi( sb.nDataBits, g_testbuf_bits );
|
||||
TASSERT_EQp( sb.pData, (void *)g_testbuf );
|
||||
TASSERT_EQi( sb.pData, g_testbuf );
|
||||
TASSERT_EQi( sb.bOverflow, false );
|
||||
|
||||
MSG_ReadBytes( &sb, buf, 4 );
|
||||
@@ -998,6 +865,8 @@ static void Test_Buffer_ExciseBits( void )
|
||||
|
||||
void Test_RunBuffer( void )
|
||||
{
|
||||
MSG_InitMasks();
|
||||
|
||||
TRUN( Test_Buffer_BitByte( ));
|
||||
TRUN( Test_Buffer_Write( ));
|
||||
TRUN( Test_Buffer_Read( ));
|
||||
|
||||
@@ -193,6 +193,7 @@ static inline void MSG_StartBitWriting( sizebuf_t *sb )
|
||||
sb->iAlternateSign++;
|
||||
}
|
||||
|
||||
void MSG_InitMasks( void ); // called once at startup engine
|
||||
void MSG_ExciseBits( sizebuf_t *sb, int startbit, int bitstoremove );
|
||||
|
||||
// Bit-write functions
|
||||
|
||||