mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-06 03:54:52 +08:00
Compare commits
1 Commits
continuous
...
continuous
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a656469f12 |
19
.cirrus.yml
19
.cirrus.yml
@@ -1,10 +1,10 @@
|
||||
task:
|
||||
name: freebsd-14-amd64
|
||||
freebsd_instance:
|
||||
image_family: freebsd-14-3
|
||||
image_family: freebsd-14-2
|
||||
setup_script:
|
||||
- pkg update
|
||||
- pkg install -y pkgconf git sdl2 python freetype2 libvorbis opusfile bzip2 libbacktrace libogg libvorbis
|
||||
- pkg install -y pkgconf git sdl2 python fontconfig libvorbis opusfile bzip2 libbacktrace
|
||||
- git submodule update --init --recursive
|
||||
test_script:
|
||||
- ./scripts/cirrus/build_freebsd.sh
|
||||
@@ -12,21 +12,10 @@ task:
|
||||
task:
|
||||
name: freebsd-15-amd64
|
||||
freebsd_instance:
|
||||
image_family: freebsd-15-0-amd64-zfs
|
||||
image_family: freebsd-15-0-snap
|
||||
setup_script:
|
||||
- pkg update
|
||||
- pkg install -y pkgconf git sdl2 python freetype2 libvorbis opusfile bzip2 libbacktrace libogg libvorbis
|
||||
- pkg install -y pkgconf git sdl2 python fontconfig libvorbis opusfile bzip2 libbacktrace
|
||||
- git submodule update --init --recursive
|
||||
test_script:
|
||||
- ./scripts/cirrus/build_freebsd.sh
|
||||
|
||||
#task:
|
||||
# name: freebsd-16-amd64
|
||||
# freebsd_instance:
|
||||
# image_family: freebsd-16-0-snap
|
||||
# setup_script:
|
||||
# - pkg update
|
||||
# - pkg install -y pkgconf git sdl2 python freetype2 libvorbis opusfile bzip2 libbacktrace libogg libvorbis
|
||||
# - git submodule update --init --recursive
|
||||
# test_script:
|
||||
# - ./scripts/cirrus/build_freebsd.sh
|
||||
|
||||
55
.github/workflows/c-cpp.yml
vendored
55
.github/workflows/c-cpp.yml
vendored
@@ -21,12 +21,14 @@ jobs:
|
||||
- os: ubuntu-22.04
|
||||
targetos: linux
|
||||
targetarch: i386
|
||||
- os: ubuntu-22.04-arm
|
||||
- os: ubuntu-22.04
|
||||
targetos: linux
|
||||
targetarch: arm64
|
||||
- os: ubuntu-22.04-arm
|
||||
cross: true
|
||||
- os: ubuntu-22.04
|
||||
targetos: linux
|
||||
targetarch: armhf
|
||||
cross: true
|
||||
- os: ubuntu-24.04 # riscv64 would benefit from having latest compilers
|
||||
targetos: linux
|
||||
targetarch: riscv64
|
||||
@@ -35,6 +37,9 @@ jobs:
|
||||
targetos: linux
|
||||
targetarch: ppc64el
|
||||
cross: true
|
||||
# - os: ubuntu-aarch64-22.04
|
||||
# targetos: linux
|
||||
# targetarch: aarch64
|
||||
# - os: ubuntu-latest
|
||||
# targetos: linux
|
||||
# targetarch: e2k-8c
|
||||
@@ -61,21 +66,18 @@ jobs:
|
||||
- os: macos-14 # arm64 as per github documentation
|
||||
targetos: apple
|
||||
targetarch: arm64
|
||||
- os: macos-latest
|
||||
targetos: ios
|
||||
targetarch: arm64
|
||||
- os: macos-15-intel
|
||||
- os: macos-13 # x86 as per github documentation (will they fix it before they deprecate this version?..)
|
||||
targetos: apple
|
||||
targetarch: amd64
|
||||
env:
|
||||
SDL_VERSION: 2.32.10
|
||||
FFMPEG_VERSION: 8.1
|
||||
SDL_VERSION: 2.32.8
|
||||
FFMPEG_VERSION: 7.1
|
||||
GH_CPU_ARCH: ${{ matrix.targetarch }}
|
||||
GH_CPU_OS: ${{ matrix.targetos }}
|
||||
GH_CROSSCOMPILING: ${{ matrix.cross }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Install dependencies
|
||||
@@ -85,7 +87,7 @@ jobs:
|
||||
FWGS_PFX_PASSWORD: ${{ secrets.FWGS_PFX_PASSWORD }}
|
||||
run: bash scripts/gha/build_${{ matrix.targetos }}.sh
|
||||
- name: Upload engine (artifacts)
|
||||
uses: actions/upload-artifact@v7
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: artifact-${{ matrix.targetos }}-${{ matrix.targetarch }}
|
||||
path: artifacts/*
|
||||
@@ -97,11 +99,11 @@ jobs:
|
||||
include:
|
||||
- app: su.xash.Engine.Compat.i386
|
||||
container:
|
||||
image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-25.08
|
||||
image: ghcr.io/flathub-infra/flatpak-github-actions:freedesktop-24.08
|
||||
options: --privileged
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Build flatpak (Compat.i386)
|
||||
@@ -115,10 +117,31 @@ jobs:
|
||||
needs: [build, flatpak]
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
- name: Remove old release, fetch artifacts, repackage binaries and upload new release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BASE_BUILDNUM_DATE: "2015-04-01"
|
||||
run: bash scripts/gha/make_release.sh "Xash3D FWGS" "${{ github.ref_name }}"
|
||||
RELEASE_TAG: ${{ github.ref_name == 'master' && 'continuous' || format('continuous-{0}', github.ref_name) }}
|
||||
run: |
|
||||
gh release delete "$RELEASE_TAG" \
|
||||
--yes \
|
||||
--cleanup-tag \
|
||||
--repo "$GITHUB_REPOSITORY" || true
|
||||
gh run download "$GITHUB_RUN_ID" \
|
||||
--dir artifacts/ \
|
||||
--repo "$GITHUB_REPOSITORY"
|
||||
pushd artifacts/
|
||||
echo "Found artifacts:"
|
||||
ls
|
||||
for i in $(find -mindepth 1 -maxdepth 1 -type d); do
|
||||
mv "$i"/* .
|
||||
rm -rf "$i"
|
||||
done
|
||||
echo "Repackaged artifacts:"
|
||||
ls -R
|
||||
popd
|
||||
sleep 20s
|
||||
gh release create "$RELEASE_TAG" artifacts/* \
|
||||
--title "Xash3D FWGS Continuous ${{ github.ref_name }} Build" \
|
||||
--target $GITHUB_SHA \
|
||||
--repo "$GITHUB_REPOSITORY" \
|
||||
--prerelease
|
||||
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -318,12 +318,6 @@ build-*
|
||||
*.includes
|
||||
*.files
|
||||
|
||||
# ios
|
||||
ios/cl_dlls/*
|
||||
ios/dlls/*
|
||||
ios/*.framework
|
||||
scripts/ios/mod-build
|
||||
|
||||
# Waf
|
||||
build_current
|
||||
*waf-*/
|
||||
@@ -345,7 +339,6 @@ __pycache__
|
||||
.history/*
|
||||
.cache/*
|
||||
enc_temp_folder/
|
||||
Taskfile.yml
|
||||
|
||||
# KDevelop4
|
||||
*.kdev4
|
||||
|
||||
5
.gitmodules
vendored
5
.gitmodules
vendored
@@ -39,7 +39,4 @@
|
||||
url = https://github.com/ianlancetaylor/libbacktrace
|
||||
[submodule "3rdparty/maintui"]
|
||||
path = 3rdparty/maintui
|
||||
url = https://github.com/FWGS/xash3d-maintui.git
|
||||
[submodule "3rdparty/library_suffix"]
|
||||
path = 3rdparty/library_suffix
|
||||
url = https://github.com/FWGS/library-suffix.git
|
||||
url = https://github.com/numas13/xash3d-maintui.git
|
||||
|
||||
2
3rdparty/MultiEmulator
vendored
2
3rdparty/MultiEmulator
vendored
Submodule 3rdparty/MultiEmulator updated: 6a56b7b112...11ff077ca5
2
3rdparty/libbacktrace/libbacktrace
vendored
2
3rdparty/libbacktrace/libbacktrace
vendored
Submodule 3rdparty/libbacktrace/libbacktrace updated: b9e40069c0...793921876c
27
3rdparty/libbacktrace/wscript
vendored
27
3rdparty/libbacktrace/wscript
vendored
@@ -20,10 +20,10 @@ int main (void) {
|
||||
}'''
|
||||
|
||||
FRAGMENT_GETPAGESIZE='''#include <unistd.h>
|
||||
int main(void) { return getpagesize(); }'''
|
||||
int main(void) { return getpagesize() }'''
|
||||
|
||||
FRAGMENT_GETEXECNAME='''#include <stdlib.h>
|
||||
int main(void) { return getexecname() != 0; }'''
|
||||
int main(void) { return getexecname() != 0 }'''
|
||||
|
||||
FRAGMENT_STRNLEN='''#include <string.h>
|
||||
int main(int argc, char **argv) { return (int)strnlen(argv[0], 10); }'''
|
||||
@@ -62,7 +62,7 @@ def options(opt):
|
||||
|
||||
def configure(conf):
|
||||
# add unsupported platforms here
|
||||
if conf.env.DEST_OS in ['nswitch', 'psvita', 'dos', 'irix']:
|
||||
if conf.env.DEST_OS in ['nswitch', 'psvita', 'dos']:
|
||||
conf.env.DISABLE_LIBBACKTRACE = True
|
||||
return
|
||||
|
||||
@@ -95,7 +95,7 @@ def configure(conf):
|
||||
return {'header_name':hdr, 'msg':'... %s header' % hdr, 'mandatory':False, 'id':hdr, 'compiler': 'c'}
|
||||
|
||||
def check_frag(frag, msg, define, **kw):
|
||||
return dict({'fragment': frag, 'msg':'... %s' % msg, 'mandatory': False, 'define_name': define, 'compiler': 'c'}, **kw)
|
||||
return dict({'fragment': frag, 'msg':'... %s' % msg, 'mandatory': False, 'compiler': 'c'}, **kw)
|
||||
|
||||
conf.multicheck(
|
||||
check_header('dlfcn.h'),
|
||||
@@ -120,8 +120,8 @@ def configure(conf):
|
||||
check_frag(FRAGMENT_SYNC, ' __sync extensions', 'HAVE_SYNC_FUNCTIONS'),
|
||||
check_frag(FRAGMENT_GETPAGESIZE, ' getpagesize function', 'HAVE_DECL_GETPAGESIZE'),
|
||||
check_frag(FRAGMENT_STRNLEN, ' strnlen function', 'HAVE_DECL_STRNLEN'),
|
||||
check_frag(FRAGMENT_DL_ITERATE_PHDR % 'link.h', ' dl_iterate_phdr function in link.h', 'HAVE_DL_ITERATE_PHDR_LINK_H', after_tests=['link.h']),
|
||||
check_frag(FRAGMENT_DL_ITERATE_PHDR % 'sys/link.h', ' dl_iterate_phdr function in sys/link.h', 'HAVE_DL_ITERATE_PHDR_SYS_LINK_H', after_tests=['sys/link.h']),
|
||||
check_frag(FRAGMENT_DL_ITERATE_PHDR % 'link.h', ' dl_iterate_phdr function in link.h', 'HAVE_DL_ITERATE_PHDR', after_tests=['link.h']),
|
||||
check_frag(FRAGMENT_DL_ITERATE_PHDR % 'sys/link.h', ' dl_iterate_phdr function in sys/link.h', 'HAVE_DL_ITERATE_PHDR', after_tests=['sys/link.h']),
|
||||
check_frag(FRAGMENT_FCNTL, 'fnctl function', 'HAVE_FCNTL'),
|
||||
check_frag(FRAGMENT_GETEXECNAME, 'getexecname function','HAVE_GETEXECNAME'),
|
||||
check_frag(FRAGMENT_GETIPINFO, '_Unwind_GetIPInfo function', 'HAVE_GETIPINFO'),
|
||||
@@ -137,9 +137,6 @@ def configure(conf):
|
||||
msg='Checking for in parallel'
|
||||
)
|
||||
|
||||
if conf.is_defined('HAVE_DL_ITERATE_PHDR_LINK_H') or conf.is_defined('HAVE_DL_ITERATE_PHDR_SYS_LINK_H'):
|
||||
conf.define('HAVE_DL_ITERATE_PHDR', 1)
|
||||
|
||||
conf.env[DEFKEYS].sort()
|
||||
|
||||
conf.write_config_header()
|
||||
@@ -165,13 +162,8 @@ def build(bld):
|
||||
if bld.env.DISABLE_LIBBACKTRACE:
|
||||
return
|
||||
|
||||
sources = ['atomic.c', 'dwarf.c', 'fileline.c', 'posix.c', 'print.c', 'sort.c', 'state.c', 'backtrace.c', 'simple.c']
|
||||
|
||||
if bld.env.DEST_OS == 'win32':
|
||||
sources += ['read.c', 'alloc.c']
|
||||
else:
|
||||
# we specifically only want mmap-based allocators because calling malloc is not safe from signal handlers
|
||||
sources += ['mmap.c', 'mmapio.c']
|
||||
# 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']
|
||||
@@ -184,8 +176,7 @@ def build(bld):
|
||||
|
||||
task = bld.stlib(
|
||||
source = ['libbacktrace/' + i for i in sources],
|
||||
# while we're using upstream libbacktrace, sometimes compiler picks up it's own version that isn't built with required options
|
||||
target = 'backtrace_custom',
|
||||
target = 'backtrace',
|
||||
features = 'frandomseed' if bld.env.HAVE_FRANDOM_SEED else '',
|
||||
use = 'EXTRAFLAGS lzma z zstd',
|
||||
includes = '. libbacktrace/',
|
||||
|
||||
1
3rdparty/library_suffix
vendored
1
3rdparty/library_suffix
vendored
Submodule 3rdparty/library_suffix deleted from 2cb2a0e120
2
3rdparty/maintui
vendored
2
3rdparty/maintui
vendored
Submodule 3rdparty/maintui updated: e5f143ee33...eba8d49880
2
3rdparty/mainui
vendored
2
3rdparty/mainui
vendored
Submodule 3rdparty/mainui updated: d262e14d54...b015e45062
2
3rdparty/vgui_support
vendored
2
3rdparty/vgui_support
vendored
Submodule 3rdparty/vgui_support updated: 36219aedfc...9f2b9512cd
@@ -29,11 +29,10 @@
|
||||
|
||||
* This project uses mixed Quake's and HLSDK's C/C++ code style convention.
|
||||
* In short:
|
||||
* Use spaces in parenthesis, but not when two parentheses are consecutive.
|
||||
* Use spaces in parenthesis.
|
||||
* Only tabs for indentation.
|
||||
* Any brace must have it's own line.
|
||||
* Short blocks, if statements and loops on single line are allowed.
|
||||
* Prefer generic utilities from libpublic over rolling your own.
|
||||
* Avoid magic numbers.
|
||||
* While macros are powerful, it's better to avoid overusing them.
|
||||
* If you unsure, try to mimic code style from anywhere else of engine source code.
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
## Setting up Xash3D FWGS in Qt Creator
|
||||
|
||||
### Intro
|
||||
|
||||
Most versions of Qt Creator support using `compile_commands.json` as a project
|
||||
file and Waf supports generating this file in a compliant format. In this
|
||||
tutorial we will leverage that features.
|
||||
|
||||
The tutorial is written using Qt Creator 18.0, but I urge you to use whatever
|
||||
latest Qt Creator version is available, as it's often has important bug fixes.
|
||||
|
||||
### Step 1. Configure the build.
|
||||
|
||||
`compile_commands.json` file, as it can be guessed from it's name, contains
|
||||
every command used to invoke compiler during build. As the build process
|
||||
depends on the build configuration, we have to configure it first. I'm not
|
||||
going to get into details here, as basics of compiling Xash3D FWGS already
|
||||
explained in `README.md`, located in repository root.
|
||||
|
||||
Save the configure step command somewhere, as it's going to be used later.
|
||||
|
||||
### Step 2. Generate `compile_commands.json` file.
|
||||
|
||||
Usually, this file is located in `build` directory after a successful build.
|
||||
However, it's also possible to generate it manually by running follow command:
|
||||
|
||||
On *nix systems:
|
||||
|
||||
```
|
||||
$ ./waf clangdb
|
||||
```
|
||||
|
||||
Or on Windows:
|
||||
|
||||
```
|
||||
> waf.bat clangdb
|
||||
```
|
||||
|
||||
### Step 3. Load the project in Qt Creator.
|
||||
|
||||
To do this, you need to be sure that `Compilation Databases` plugin is enabled.
|
||||
As it's considered experimental, it probably needs to be enabled manually. It
|
||||
can be done in `Help` -> `About Plugins...`. Locate it in `Build Systems`
|
||||
category, put the checkbox and press `OK`. The IDE will ask for restart, so do
|
||||
this.
|
||||
|
||||
After IDE has been restarted, you can use `File` -> `Open File or Project...`.
|
||||
Navigate to Xash3D FWGS directory, then to `build` directory and select
|
||||
`compile_commands.json` file. If everything is done correctly, IDE will ask to
|
||||
set up the project. Press `Configure Project` button, as most options there are
|
||||
usually unapplicable to us.
|
||||
|
||||
Next IDE will show project tree, however you might not see any files. This is
|
||||
happens as Qt Creator "thinks" our project root located in `build` directory.
|
||||
Thankfully it provides a way to override this. To fix it, click with right
|
||||
mouse button on the root of project tree (it's usually called something like
|
||||
`build [master]`) and select `Change Root Directory`. In opened window choose
|
||||
Xash3D FWGS repository root and press `OK`.
|
||||
|
||||
### Step 4. Tell IDE how to build this project.
|
||||
|
||||
Open `Projects` on the left menu and choose `Build Settings` tab. You should
|
||||
see an empty configuration for build and clean steps. Press on `Add Build Step`
|
||||
button and choose `Custom Process Step`.
|
||||
|
||||
In created step you should see `Command`, `Arguments` and `Working Directory`.
|
||||
|
||||
For the command, choose the Python executable. For arguments, use configure
|
||||
command for Waf from the first step. Working directory is usually set by IDE
|
||||
to `%{buildDir}`. You need to select the upper directory, where the `waf` is
|
||||
located. To save some time, it can be specified as `%{buildDir}/../`.
|
||||
|
||||
Add another custom step, fill it with the same command and working directory.
|
||||
For arguments use `waf build`.
|
||||
|
||||
Below you should see `Clean steps`. Create a clean step the same way, fill the
|
||||
arguments and working directory as usual, for arguments use `waf clean`.
|
||||
|
||||
### Step 5. Tell IDE how to copy built binaries.
|
||||
|
||||
Now select `Deploy Settings` tab. Press `Add Deploy Step` -> `Custom Process
|
||||
Step`. Again, same command and working directory. In arguments field type:
|
||||
`waf install --destdir="<here put where Xash binaries should be copied to>"`.
|
||||
|
||||
### Step 6. Finally, set up Qt Creator to run the engine.
|
||||
|
||||
Select the `Run Settings` tab. Below you might see familiar text fields:
|
||||
`Executable`, `Command line arguments` and `Working directory`.
|
||||
|
||||
For working directory click on `Browse...` button and select the folder where
|
||||
Xash3D executable will be copied to, from previous step.
|
||||
|
||||
For executable type `./xash3d` if you're on *nix or `xash3d.exe` if you're on
|
||||
Windows. The command line arguments are the same you use to run the engine. Can
|
||||
be empty as well, but I personally use `-dev 2 -log` for extra verbosity.
|
||||
|
||||
### Outro
|
||||
|
||||
At this moment, you should be able to press `Run` button, wait until build
|
||||
finishes and see running Xash3D FWGS. On Windows to use the debugger you might
|
||||
need the `CDB` debugger and appropriate `qtcreatorcdbext` binary for debugging
|
||||
32-bit applications and a separate for 64-bit, but that's left as an exercise
|
||||
for the reader and a potential improvement for this document.
|
||||
@@ -26,12 +26,3 @@ Initial Xash3D SDL2/Linux port author, Xash3D FWGS engine maintainer, creator of
|
||||
|
||||
* [Boosty page](https://boosty.to/snmetamorph)
|
||||
* [Other donation methods](https://snmetamorph.github.io/donate)
|
||||
|
||||
## [$_Vladislav](https://github.com/Vladislav4KZ)
|
||||
|
||||
[YaPB Project](https://github.com/yapb) member, [Xash3D FWGS](https://github.com/FWGS/xash3d-fwgs) tester,
|
||||
editor of the [Official YaPB Documentation](https://github.com/yapb/docs) (in English and Russian), curator of the [YaPB Graph Database](https://github.com/yapb/graph) and author of [YaPB Waypoint/Graph Pack](https://gamebanana.com/mods/40087).
|
||||
|
||||
Also does the Russian localization of text, images (gfx/shell), as well as additional menu buttons in English used in Xash3D FWGS for various mods.
|
||||
|
||||
* [Boosty page](https://boosty.to/rasstaman1337)
|
||||
@@ -1,16 +0,0 @@
|
||||
# Addon folders in Xash3D FWGS
|
||||
|
||||
Xash3D FWGS supports both GoldSource-style addon folders and has few own. Each directory can have it's own archives that will be mounted with lower priority than directory itself.
|
||||
|
||||
Below is the mounts map, in order of precedence from least important to most important.
|
||||
|
||||
|--------------------|------|
|
||||
| Directory | Note |
|
||||
|--------------------|------|
|
||||
| `$game/downloaded` | Always added. Used to store server downloads.|
|
||||
| `$game` | This is the game directory. |
|
||||
| `$game/custom` | Always added. Used for user modifications content. |
|
||||
| `$game_hd` | Added with `fs_mount_hd` set to non-zero value. Used for high definition content, similar to GoldSrc.. |
|
||||
| `$game_addon` | Added with `fs_mount_addon` set to non-zero value. Used for user modifications content, similar to GoldSrc. |
|
||||
| `$game_lv` | Added with `fs_mount_lv` set to non-zero value. Used for low-violence content, similar to GoldSrc. |
|
||||
| `$game_$language` | Added with `fs_mount_l10n` set to non-zero value. Language is controlled with `ui_language` cvar or `-language` command line switch. Used for localization content, similar to GoldSrc. |
|
||||
@@ -1,8 +0,0 @@
|
||||
# Steam broker protocol
|
||||
`sb_connect <ip:port> <server's steam id> <secure> <challenge>` - used for obtaining auth ticket during connection to GoldSrc server
|
||||
|
||||
`sb_disconnect <ip:port> <challenge>` - used for signaling broker about disconnecting from GoldSrc server
|
||||
|
||||
`sb_gamedir <gamedir>` - used for signaling broker about game startup and for announcing started mod, so broker could choose proper AppID for Steam API initialization
|
||||
|
||||
`sb_terminate` - used for signaling broker about game shutdown, ideally broker should be terminated too (and later restarted automatically and waiting for sb_gamedir message)
|
||||
@@ -1,18 +1,15 @@
|
||||
# Support for GoldSrc network protocol
|
||||
This feature is still work-in-progress, but for now it's available for all users, and we appreciate any bug-reports and contributions around it.
|
||||
|
||||
For connecting to GoldSrc-based servers, use this command:
|
||||
```
|
||||
connect ip:port gs
|
||||
```
|
||||
|
||||
You need to use [Steam API broker](https://github.com/FWGS/steam-broker) and have purchased Half-Life 1 on your Steam account to be able to join GoldSrc servers.
|
||||
But keep in mind, there are requirement for server to be able to accept connections from Xash3D-based clients: it should use Reunion.
|
||||
Without this requirement, you will just get "Steam validation rejected" error on connecting.
|
||||
|
||||
Broker will run on your PC and will be responsible for communicating with Steam client and obtaining auth tickets.
|
||||
Also, make sure to set that broker as current ticket generator using console or edit `config.cfg` file manually:
|
||||
```
|
||||
cl_ticket_generator steam
|
||||
```
|
||||
That is because proper authorization with Steam API is not implemented in engine yet (but we have plans on it).
|
||||
|
||||
If you want to join GoldSrc servers from other device (Android/iOS or console), make sure to set proper broker IP address with `cl_steam_broker_addr` console variable. Default value assumed that broker is running on the same device as game client.
|
||||
|
||||
By the way, we encountered that some GoldSrc-based servers are recognizing Xash3D clients as "fake clients" and banning/kicking them. Maybe this problem will be
|
||||
Also, we encountered that some GoldSrc-based servers are recognizing Xash3D clients as "fake clients" and banning/kicking them. Maybe this problem will be
|
||||
solved along with better compatibility with GoldSrc behavior, but may be not - we don't know logic behind this fake client checks.
|
||||
|
||||
@@ -16,9 +16,6 @@ Mirrored on github - https://github.com/JoelTroch/am_src_rebirth
|
||||
## Battle Grounds
|
||||
Mirrored on github - https://github.com/nekonomicon/BattleGrounds
|
||||
|
||||
## Brain Bread
|
||||
Official github repository - https://github.com/IronOak-Studios/BrainBread
|
||||
|
||||
## Bubblemod
|
||||
Download page on official site(WM snapshot) - [http://www.bubblemod.org/dl_default.php](https://web.archive.org/web/20130717133158/http://www.bubblemod.org/dl_default.php)
|
||||
|
||||
@@ -53,9 +50,6 @@ Alpha 2.0 - https://www.gamers-desire.de/details/2830
|
||||
## ESHQ
|
||||
Official github repository - https://github.com/adslbarxatov/xash3d-for-ESHQ
|
||||
|
||||
## Feline
|
||||
Available on ModDB - https://www.moddb.com/mods/feline-10/downloads/feline-sdk
|
||||
|
||||
## Flat-Life
|
||||
Available on GamerLab - http://gamer-lab.com/eng/code_mods_goldsrc/Half-Life_2D_(Flat-Life)
|
||||
|
||||
@@ -70,9 +64,6 @@ Version 3.0, mirrored on github - https://github.com/nekonomicon/Go-mod30
|
||||
## GT mod
|
||||
Available on GamerLab - http://gamer-lab.com/eng/code_mods_goldsrc/GT_mod_(Polnie_ishodniki)
|
||||
|
||||
## Half-Force
|
||||
Available on ModDB - https://www.moddb.com/mods/half-force/downloads/half-force-v20-sdk
|
||||
|
||||
## Half-Life: Advanced Deathmatch
|
||||
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/hla
|
||||
|
||||
@@ -85,9 +76,6 @@ Available on ModDB - https://www.moddb.com/mods/half-life-echoes
|
||||
## Half-Life: Expanded Arsenal
|
||||
Available on ModDB - https://www.moddb.com/mods/half-life-expanded-arsenal
|
||||
|
||||
## Half-Life: Field Intensity
|
||||
Branch **field_intensity_1.7** in halflife-featureful - https://github.com/FreeSlave/halflife-featureful/tree/field_intensity_1.7
|
||||
|
||||
## Half-Life: Gravgun mod
|
||||
Branch **gravgun** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/gravgun
|
||||
|
||||
@@ -109,9 +97,6 @@ Official github repository - https://github.com/Fograin/hl-subsmod-ex
|
||||
## Half-Life: Rally
|
||||
Official gitlab repository - https://gitlab.com/hlrally/src
|
||||
|
||||
## Half-Life: RXT
|
||||
Available on ModDB - https://www.moddb.com/mods/half-life-rxt/downloads/rxt-source-code-v57
|
||||
|
||||
## Half-Life: Weapon Edition
|
||||
Available on ModDB - https://www.moddb.com/mods/half-life-weapon-edition/downloads/half-life-weapon-edition-1508-alpha-open-src
|
||||
|
||||
@@ -133,17 +118,12 @@ Official github repository - https://github.com/HeathGames/half_rats_parasomnia_
|
||||
## Half-Screwed
|
||||
Official github repository - https://github.com/desukuran/half-screwed
|
||||
|
||||
## Halo: GoldSource
|
||||
Available on ModDB - https://www.moddb.com/mods/halo-goldsrc/downloads/halo-gold-source-summer-2025-release-v10-sdk
|
||||
|
||||
## Headcrab Frenzy
|
||||
Version 1.3 on ModDB - https://www.moddb.com/mods/headcrab-frenzy/downloads/headcrab-frenzy-13-beta-source-code
|
||||
|
||||
## Heart of Evil
|
||||
Mirrored on github - https://github.com/nekonomicon/HeartOfEvil
|
||||
|
||||
Mirrored on github (Includes maps and models source files) - https://github.com/malortie/heart-of-evil-source-files
|
||||
|
||||
## Ingram Chillin' Mod
|
||||
Official SourceForge repository - https://sourceforge.net/projects/icm-hl/
|
||||
|
||||
@@ -175,9 +155,6 @@ Prealpha, mirrored on github - https://github.com/a1batross/Paranoia2_ancient
|
||||
|
||||
Version 1.51, mirrored on github - https://github.com/a1batross/Paranoia2_original
|
||||
|
||||
## Public Enemy
|
||||
Official github repository - https://github.com/IronOak-Studios/Public-Enemy
|
||||
|
||||
## Raven City
|
||||
*Unfinished mod*
|
||||
|
||||
@@ -209,9 +186,6 @@ Mirrored on code.idtech.space - https://code.idtech.space/vera/halflife-wastelan
|
||||
## Wizard Wars
|
||||
Download page on official site - http://www.thothie.com/ww/
|
||||
|
||||
## Wrong Door
|
||||
Available on ModDB - https://www.moddb.com/mods/wrong-door/downloads/wrong-door-sdk
|
||||
|
||||
## XashXT
|
||||
Mirrored on github - https://github.com/a1batross/XashXT_original
|
||||
|
||||
@@ -277,9 +251,6 @@ Reverse-engineered code of server part by s1lentq - https://github.com/s1lentq/R
|
||||
## Counter Strike Online
|
||||
CSO-like Xash3D-based mod, CSMoE - https://github.com/MoeMod/CSMoE
|
||||
|
||||
## Crack-Life
|
||||
Reverse-engineered code: branch **cracklife** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/cracklife
|
||||
|
||||
## Crack-Life: Campaign Mode
|
||||
Recreation by lostgamer aka nillerusr - https://github.com/LostGamerHL/crack_life
|
||||
|
||||
@@ -382,9 +353,6 @@ Deathmatch Quaked - https://www.moddb.com/games/deathmatch-classic/downloads/dmq
|
||||
|
||||
Branch **dmc** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/dmc
|
||||
|
||||
## Delta Particles
|
||||
Branch **delta_particles** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/delta_particles
|
||||
|
||||
## Half-Life: Echoes
|
||||
Branch **echoes** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/echoes
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ Table is sorted by status and platform.
|
||||
| PSVita | Supported | @fgsfdsfgs |
|
||||
| Switch | Supported | @fgsfdsfgs |
|
||||
| Windows | Supported | @a1batross, @SNMetamorph |
|
||||
| iOS | Supported | @ksagameng2 |
|
||||
| DOS4GW | Orphaned | N/A | Haven't been confirmed to work for a very long time
|
||||
| Haiku | Orphaned | N/A | Was added by #478 and #483
|
||||
| IRIX | Orphaned | N/A | Undone, compiles but requires big endian port
|
||||
@@ -36,3 +35,4 @@ Table is sorted by status and platform.
|
||||
| Emscripten | Old Engine | N/A |
|
||||
| 3DS | Old Engine fork | N/A | [GitHub Repository](https://github.com/masterfeizz/Xash3DS)
|
||||
| Oculus Quest | Old Engine fork | N/A | [GitHub Repository](https://github.com/DrBeef/Lambda1VR)
|
||||
| iOS | Deprecated | N/A | See GitHub issue #61
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# Xash3D FWGS protocol support
|
||||
|
||||
Xash3D FWGS currently supports four network protocols:
|
||||
* Version 49, introduced in Xash3D in around 2018.
|
||||
* Version 48, used in Xash3D FWGS 0.19 and earlier. Deprecated and to be removed in the future.
|
||||
* GoldSrc version 48, used in current GoldSource version.
|
||||
* Quake version 15, only used for demo playback for Quake Wrapper mod.
|
||||
|
||||
On the server side, we only support Xash3D 49 protocol, but bugcomp `gsmrf` mode can convert GoldSrc 48 messages into Xash3D 49 on the fly, for some mods that directly write engine internal messages.
|
||||
|
||||
In the following documents we will only cover version 49, as everything else is either not Xash3D specific or deprecated.
|
||||
@@ -1,305 +0,0 @@
|
||||
# Xash3D 49 connectionless protocol
|
||||
|
||||
Connectionless protocol defines four common message sources and destinations, they can be:
|
||||
* `S` for Server
|
||||
* `C` for Client
|
||||
* `M` for Master
|
||||
* `A` for Anything else
|
||||
|
||||
All connectionless packets have `\xff\xff\xff\xff` (32-bit integer set to all ones) in it's header. Let's go through each of possible direction in this document.
|
||||
|
||||
<!--TOC-->
|
||||
|
||||
- [Any](#any)
|
||||
- [Any to Any](#any-to-any)
|
||||
- [`A2A_NETINFO`](#a2a_netinfo)
|
||||
- [`A2A_INFO`](#a2a_info)
|
||||
- [`A2A_PING` and `A2A_GOLDSRC_PING`](#a2a_ping-and-a2a_goldsrc_ping)
|
||||
- [`A2A_ACK` and `A2A_GOLDSRC_ACK`](#a2a_ack-and-a2a_goldsrc_ack)
|
||||
- [Any to Client](#any-to-client)
|
||||
- [`A2C_PRINT` and `A2C_GOLDSRC_PRINT`](#a2c_print-and-a2c_goldsrc_print)
|
||||
- [Any to Server and Server to Any](#any-to-server-and-server-to-any)
|
||||
- [`A2S_GOLDSRC_INFO`, `A2S_GOLDSRC_RULES` and `A2S_GOLDSRC_PLAYERS` and their responses](#a2s_goldsrc_info-a2s_goldsrc_rules-and-a2s_goldsrc_players-and-their-responses)
|
||||
- [Any to Master](#any-to-master)
|
||||
- [`S2M_SCAN_REQUEST`](#s2m_scan_request)
|
||||
- [Master to Any](#master-to-any)
|
||||
- [`M2A_SERVERSLIST`](#m2a_serverslist)
|
||||
- [Master and game server](#master-and-game-server)
|
||||
- [Server to Master](#server-to-master)
|
||||
- [`S2M_HEARTBEAT`](#s2m_heartbeat)
|
||||
- [`S2M_SHUTDOWN`](#s2m_shutdown)
|
||||
- [`S2M_INFO`](#s2m_info)
|
||||
- [Master to Server](#master-to-server)
|
||||
- [`M2S_CHALLENGE`](#m2s_challenge)
|
||||
- [`M2S_NAT_CONNECT`](#m2s_nat_connect)
|
||||
- [Client and game server](#client-and-game-server)
|
||||
- [Client to Server](#client-to-server)
|
||||
- [`C2S_BANDWIDTHTEST`](#c2s_bandwidthtest)
|
||||
- [`C2S_GETCHALLENGE`](#c2s_getchallenge)
|
||||
- [`C2S_CONNECT`](#c2s_connect)
|
||||
- [Server to Client](#server-to-client)
|
||||
- [`S2C_BANDWIDTHTEST`](#s2c_bandwidthtest)
|
||||
- [`S2C_CHALLENGE`](#s2c_challenge)
|
||||
- [`S2C_CONNECTION`](#s2c_connection)
|
||||
- [`S2C_ERRORMSG`](#s2c_errormsg)
|
||||
- [`S2C_REJECT`](#s2c_reject)
|
||||
|
||||
<!--TOC-->
|
||||
|
||||
## Any
|
||||
|
||||
### Any to Any
|
||||
|
||||
#### `A2A_NETINFO`
|
||||
|
||||
Used to implement Half-Life's NetAPI.
|
||||
* Request message, in ASCII: `netinfo <version> <context> <request_id>`
|
||||
- `version` must be 49, as text.
|
||||
- `context` can be any 32-bit signed integer value, encoded as text.
|
||||
- `request_id` see `common/net_api.h`
|
||||
|
||||
* Response message, in ASCII: `netinfo <context> <request_id> <response>`
|
||||
- `context` same as in request.
|
||||
- `request_id` same as in request.
|
||||
- `response` is server's response, depending on request type. Always encoded as Quake info string.
|
||||
|
||||
Possible requests and response formats:
|
||||
* Request ID `1` will make server respond with empty response string.
|
||||
* Request ID `2` makes server respond with all server game rule cvars where the key is cvar name and the value is cvar value. One additional key `rules` with total amount of cvars is added.
|
||||
* Request ID `3` makes server respond with players list, where:
|
||||
- `p<id>name` is set to player's name
|
||||
- `p<id>frags` is set to player's kill count
|
||||
- `p<id>time` is set to player's total play time
|
||||
- `players` is total player's list.
|
||||
- Alternatively, it can respond with `neterror` set to `forbidden` if server does not wish to expose it's player list.
|
||||
* Request ID `4` makes server to respond with common game details:
|
||||
- `hostname` is server's name
|
||||
- `gamedir` is game directory name
|
||||
- `current` is total player count
|
||||
- `max` is max players limit
|
||||
- `map` is server's current level
|
||||
* On any other server will respond with `neterror` set to `undefined`
|
||||
* If protocol version doesn't match, server responds with `neterror` set to `protocol`
|
||||
|
||||
#### `A2A_INFO`
|
||||
|
||||
Used to request server's details.
|
||||
* Request message, in ASCII: `info <version>`
|
||||
- `version` must be 49, as text
|
||||
* Response message, in ASCII: `info\n<response>`
|
||||
- `response` is Quake info string, otherwise it's an error message.
|
||||
|
||||
* Response info string format:
|
||||
- `p` is set to protocol version (FWGS extension)
|
||||
- `map` is server's current level
|
||||
- `dm` set to 1 if current game mode is deathmatch otherwise 0
|
||||
- `team` set to 1 if current game mode includes teamplay otherwise 0
|
||||
- `coop` set to 1 if current game mode is cooperative otherwise 0
|
||||
- `numcl` is total player count
|
||||
- `maxcl` is max players limit
|
||||
- `gamedir` is game directory name
|
||||
- `password` set to 1 if server is protected with password otherwise 0
|
||||
- `host` is server's name
|
||||
|
||||
#### `A2A_PING` and `A2A_GOLDSRC_PING`
|
||||
|
||||
Simple ping message.
|
||||
* Request, in ASCII: `ping` or `i` in GoldSrc format
|
||||
* Response is always `A2A_ACK` or `A2A_GOLDSRC_ACK`
|
||||
|
||||
#### `A2A_ACK` and `A2A_GOLDSRC_ACK`
|
||||
|
||||
Simple ack message.
|
||||
* Request, in ASCII: `ack` or `j` in GoldSrc format
|
||||
* Response: none
|
||||
|
||||
### Any to Client
|
||||
|
||||
#### `A2C_PRINT` and `A2C_GOLDSRC_PRINT`
|
||||
|
||||
Simple print message.
|
||||
* Header: `\xff\xff\xff\xff`
|
||||
* Request, in ASCII: `print <message>` or `l<message>` in GoldSrc format.
|
||||
* Response: none
|
||||
|
||||
### Any to Server and Server to Any
|
||||
|
||||
#### `A2S_GOLDSRC_INFO`, `A2S_GOLDSRC_RULES` and `A2S_GOLDSRC_PLAYERS` and their responses
|
||||
|
||||
These match Source Engine Query messages used in GoldSrc and Source engine and implemented for compatibility with existing tools. Read documentation for them on VDC: https://developer.valvesoftware.com/wiki/Server_queries
|
||||
|
||||
### Any to Master
|
||||
|
||||
#### `S2M_SCAN_REQUEST`
|
||||
|
||||
* Request: `1<region><IP:Port>\0<info>`
|
||||
- Format of this message is loosely based on https://developer.valvesoftware.com/wiki/Master_Server_Query_Protocol
|
||||
- `info` however adds few additional fields:
|
||||
- `clver` set to engine's version
|
||||
- `nat` set to 1 to filter only servers behind NAT and tell master to notify servers about scan
|
||||
- `commit` set to engine's build commit hash
|
||||
- `branch` set to engine's build branch
|
||||
- `os` set to which operating system engine has been built
|
||||
- `arch` set to which CPU architecture engine has been built
|
||||
- `buildnum` set to engine's build number
|
||||
- `key` set to random 32-bit value formatted as hex, used to validate master responses
|
||||
* Response: `M2A_SERVERSLIST`
|
||||
|
||||
### Master to Any
|
||||
|
||||
#### `M2A_SERVERSLIST`
|
||||
|
||||
* Request: `f\xff<key><reserved><IP:Port>...`
|
||||
- `key` is random 32-bit value set in `S2M_SCAN_REQUEST`
|
||||
- `reserved` is single reserved 8-bit byte
|
||||
- Following is list of IP addresses in binary form: 6-bytes for IPv4 address + port and 18-bytes for IPv6 address + port
|
||||
- If port is 0, it means the end of list, otherwise it's the last IP used for pagination (not implemented in Xash3D)
|
||||
* Response: client doesn't make response to master server but might request `A2S_INFO` from servers
|
||||
|
||||
## Master and game server
|
||||
|
||||
### Server to Master
|
||||
|
||||
#### `S2M_HEARTBEAT`
|
||||
|
||||
Used to update game server information on the master server.
|
||||
|
||||
* Request: `q\xff<heartbeat challenge>`
|
||||
- `heartbeat challenge` is random 32-bit value, used to prevent faked/forged source IP addresses.
|
||||
* Response: `M2S_CHALLENGE`
|
||||
|
||||
#### `S2M_SHUTDOWN`
|
||||
|
||||
Used to notify master server about server shutdown, but due to security reasons must be ignored by any master implementation.
|
||||
|
||||
* Request: `\x62\x0a`
|
||||
* Response: none
|
||||
|
||||
#### `S2M_INFO`
|
||||
|
||||
Game server info response on `M2S_CHALLENGE`.
|
||||
|
||||
* Request: `0\n<info>`
|
||||
- `info` is Quake info string containing server information passed to master server. It contains following fields:
|
||||
- `protocol` is always 49
|
||||
- `challenge` is master challenge
|
||||
- `players` is total player count, without bots
|
||||
- `max` is max players limits
|
||||
- `bots` is total bot count
|
||||
- `gamedir` is set to game directory
|
||||
- `map` is server's current level
|
||||
- `type` set to `d` for dedicated or `l` for listen server
|
||||
- `password` set to `1` if server protected with password set otherwise `0`
|
||||
- `os` always `w`
|
||||
- `secure` always `0`
|
||||
- `lan` always `0`
|
||||
- `version` engine version
|
||||
- `region` always `255`
|
||||
- `product` same as `gamedir`
|
||||
- `nat` set to `1` if server is behind NAT
|
||||
* Response: none
|
||||
|
||||
### Master to Server
|
||||
|
||||
#### `M2S_CHALLENGE`
|
||||
|
||||
Master's respoonse on game server's heartbeat message.
|
||||
|
||||
* Request: `s<master challenge><heartbeat challenge>`
|
||||
- `master challenge` contains 32-bit value, used in server response to prevent faked/forged source IP addresses.
|
||||
- `heartbat challenge` cotnains 32-bit value, used in heartbeat request to prevent faked/forged source IP addresses.
|
||||
* Response: `S2M_INFO`.
|
||||
|
||||
#### `M2S_NAT_CONNECT`
|
||||
|
||||
Master server's message with client IP address and port, used in NAT punching.
|
||||
|
||||
* Request: `c <IP:Port>`
|
||||
* Response: `S2C_INFO` to a specified client address.
|
||||
|
||||
## Client and game server
|
||||
|
||||
### Client to Server
|
||||
|
||||
#### `C2S_BANDWIDTHTEST`
|
||||
|
||||
Used to figure out network MTU. The message is optional and server might choose to not implement it or respond with challenge.
|
||||
|
||||
* Request, in ASCII: `bandwidth <version> <max_size>`
|
||||
- `version` must be 49, as text.
|
||||
- `max_size` is requested maximum packet size.
|
||||
|
||||
* Possible responses:
|
||||
- `S2C_BANDWIDTHTEST`
|
||||
- `S2C_CHALLENGE`
|
||||
- `A2A_PRINT` followed by `S2C_REJECT`
|
||||
- `S2C_ERRORMSG` (as FWGS extension) followed by `A2A_PRINT` and `S2C_REJECT`.
|
||||
|
||||
#### `C2S_GETCHALLENGE`
|
||||
|
||||
Used to validate client's address to prevent faked/forged source IP addresses.
|
||||
|
||||
* Header: `\xff\xff\xff\xff`
|
||||
* Request, in ASCII: `getchallenge steam`
|
||||
- `steam` argument is optional and can be ignored by the server, as it's only kept for compatibility with similar GoldSrc 48 message.
|
||||
|
||||
* Possible responses:
|
||||
- `S2C_CHALLENGE`
|
||||
|
||||
#### `C2S_CONNECT`
|
||||
|
||||
Used to build a connection with the server.
|
||||
|
||||
* Header: `\xff\xff\xff\xff`
|
||||
* Request, in ASCII: `connect <version> <challenge> "<protinfo>" "<userinfo>"`
|
||||
- `version` must be 49, as text.
|
||||
- `challenge` must be challenge value, as text.
|
||||
- `protinfo` is a Quake info string, containing protocol extensions and other connection information.
|
||||
- `uuid` is this client's unique ID (FWGS extension) hasheed with MD5.
|
||||
- `qport` is random integer value from 1 to 65535, unique for this engine run.
|
||||
- `ext` is an integer value OR'ed with requested protocol extensions. Currently only extension is `NET_EXT_SPLITSIZE` with the value of `1`, which tells server to split messages based on `cl_dlmax` value from `userinfo`.
|
||||
- `userinfo` contains initial user info, encoded as Quake info string.
|
||||
* Possible responses:
|
||||
- `A2A_PRINT` followed by `S2C_REJECT`
|
||||
- `S2C_ERRORMSG` (as FWGS extension) followed by `A2A_PRINT` and `S2C_REJECT`.
|
||||
- `S2C_CONNECTION`
|
||||
|
||||
### Server to Client
|
||||
|
||||
#### `S2C_BANDWIDTHTEST`
|
||||
|
||||
* Request: `testpacket<crc><blob>`
|
||||
- `crc` is 32-bit CRC of `blob`
|
||||
- `blob` random data
|
||||
* There is no required response to this message
|
||||
|
||||
Total message size doesn't exceed request max size.
|
||||
|
||||
#### `S2C_CHALLENGE`
|
||||
|
||||
* Request, in ASCII: `challenge <value>`
|
||||
- `value` is challenge value that client must include in it's response
|
||||
* Response: `C2S_CONNECT`
|
||||
|
||||
#### `S2C_CONNECTION`
|
||||
|
||||
* Request, in ASCII: `client_connect <protinfo>`
|
||||
- `protinfo` is an optional Quake info string, contains following optional fields:
|
||||
- `ext` is an integer value OR'ed with allowed protocol extension. Bit fields match requested in `ext` field in `C2S_CONNECT`
|
||||
- `cheats` set to 1 if server allows cheats otherwise 0
|
||||
* Response: there is no out of band from the client but client will proceed to building netchan and switch client-server interaction to it.
|
||||
|
||||
#### `S2C_ERRORMSG`
|
||||
|
||||
Show client error message. Doesn't mean connection reject, only used for UI.
|
||||
|
||||
* Request, in ASCII: `errormsg <message>`
|
||||
- `message` contains error message
|
||||
* Response: none
|
||||
|
||||
#### `S2C_REJECT`
|
||||
|
||||
Client has been rejected in connection.
|
||||
|
||||
* Request, in ASCII: `disconnect`
|
||||
* Response: client can cope, get depressed or mentally tell server to fuck off.
|
||||
@@ -1,3 +0,0 @@
|
||||
# Xash3D 49 netchan protocol
|
||||
|
||||
TBD...
|
||||
@@ -962,57 +962,53 @@ Client: https://github.com/Velaron/cs16-client/
|
||||
|
||||
Server: https://github.com/rehlds/ReGameDLL_CS
|
||||
|
||||
15. **[Crack-Life](https://www.moddb.com/mods/crack-life/downloads/crack-life)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **cracklife** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
16. **[Crack-Life: Campaign Mode](https://www.moddb.com/mods/crack-life/downloads/crack-life-campaign-mode)**
|
||||
15. **[Crack-Life: Campaign Mode](https://www.moddb.com/mods/crack-life)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **clcampaign** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
17. **[Deathmatch Classic](https://store.steampowered.com/app/40/Deathmatch_Classic/)**
|
||||
16. **[Deathmatch Classic](https://store.steampowered.com/app/40/Deathmatch_Classic/)**
|
||||
|
||||
Steam version already supports x86 Linux.
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **dmc** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
18. **[Delta Particles](https://www.moddb.com/mods/half-life-delta)**
|
||||
17. **[Delta Particles](https://www.moddb.com/mods/half-life-delta)**
|
||||
|
||||
This mod already supports x86 Linux.
|
||||
|
||||
Support for other platforms may be available later.
|
||||
|
||||
19. **[Escape from the Darkness](https://www.moddb.com/mods/escape-from-the-darkness)**
|
||||
18. **[Escape from the Darkness](https://www.moddb.com/mods/escape-from-the-darkness)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **eftd** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
20. **[Gang Wars](https://www.moddb.com/mods/gangwars)**
|
||||
19. **[Gang Wars](https://www.moddb.com/mods/gangwars)**
|
||||
|
||||
This mod already supports x86 Linux.
|
||||
|
||||
Support for other platforms may be available later.
|
||||
|
||||
21. **[Half-Life: Blue Shift](https://store.steampowered.com/app/130/HalfLife_Blue_Shift/)**
|
||||
20. **[Half-Life: Blue Shift](https://store.steampowered.com/app/130/HalfLife_Blue_Shift/)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **bshift** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
22. **[Half-Life: Decay](https://www.moddb.com/mods/half-life-decay)**
|
||||
21. **[Half-Life: Decay](https://www.moddb.com/mods/half-life-decay)**
|
||||
|
||||
Currently, you can compile mod libraries for x86 Linux from **decay-pc** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
Support for other platforms may be available later.
|
||||
|
||||
23. **[Half-Life: Echoes](https://www.moddb.com/mods/half-life-echoes)**
|
||||
22. **[Half-Life: Echoes](https://www.moddb.com/mods/half-life-echoes)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **echoes** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
24. **[Half-Life: Field Intensity](https://www.moddb.com/mods/field-intensity)**
|
||||
23. **[Half-Life: Field Intensity](https://www.moddb.com/mods/field-intensity)**
|
||||
|
||||
This mod already supports x86 Linux.
|
||||
|
||||
Support for other platforms may be available later.
|
||||
|
||||
25. **Half-Life: Gravgun** (unfinished) by *mittorn*, *a1batross* and *Solexid*
|
||||
24. **Half-Life: Gravgun** (unfinished) by *mittorn*, *a1batross* and *Solexid*
|
||||
|
||||
*Support temporary abandoned*
|
||||
|
||||
@@ -1022,163 +1018,163 @@ Currently, MSVC is not supported, use MinGW if you need build for Windows.
|
||||
|
||||
Mod files: [1](http://mittorn.fwgs.ru/coop-entpatches/), [2](http://mittorn.fwgs.ru/ggm/), [3](https://github.com/nillerusr/gravgun-extras).
|
||||
|
||||
26. **[Half-Life: Induction 1.2](https://www.moddb.com/mods/half-life-induction)**
|
||||
25. **[Half-Life: Induction 1.2](https://www.moddb.com/mods/half-life-induction)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **induction_1.2** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
27. **[Half-Life: Invasion](https://www.moddb.com/mods/half-life-invasion)**
|
||||
26. **[Half-Life: Invasion](https://www.moddb.com/mods/half-life-invasion)**
|
||||
|
||||
This mod supports x86 Linux.
|
||||
|
||||
Support for other platforms may be available later.
|
||||
|
||||
28. **[Half-Life: Intense Force](https://www.moddb.com/downloads/intense-force)**
|
||||
27. **[Half-Life: Intense Force](https://www.moddb.com/downloads/intense-force)**
|
||||
|
||||
This mod already supports x86 Linux.
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **intense_force** branch of [halflife-featureful](https://github.com/FreeSlave/halflife-featureful).
|
||||
|
||||
29. **[Half-Life: Opposing Force](https://store.steampowered.com/app/50/HalfLife_Opposing_Force/)**
|
||||
28. **[Half-Life: Opposing Force](https://store.steampowered.com/app/50/HalfLife_Opposing_Force/)**
|
||||
|
||||
Steam version already supports x86 Linux.
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **opfor** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
30. **[Half-Life: Quest mod](https://csm.dev/threads/half-life-the-quest-mod-isxodniki.38030/)**
|
||||
29. **[Half-Life: Quest mod](https://csm.dev/threads/half-life-the-quest-mod-isxodniki.38030/)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **sci** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
31. **[Half-Life: TopDown](https://www.moddb.com/mods/half-life-top-downs)**
|
||||
30. **[Half-Life: TopDown](https://www.moddb.com/mods/half-life-top-downs)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **topdown** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
32. **[Half-Life: Urbicide](https://www.moddb.com/mods/half-life-urbicide)**
|
||||
31. **[Half-Life: Urbicide](https://www.moddb.com/mods/half-life-urbicide)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **hl_urbicide** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
33. **[Half-Life: Visitors](https://www.moddb.com/mods/half-life-visitors)**
|
||||
32. **[Half-Life: Visitors](https://www.moddb.com/mods/half-life-visitors)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **visitors** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
34. **[Half-Rats: Parasomnia](https://www.moddb.com/mods/half-rats-parasomnia/downloads/half-rats-parasomnia-v10b-steamlinux)**
|
||||
33. **[Half-Rats: Parasomnia](https://www.moddb.com/mods/half-rats-parasomnia/downloads/half-rats-parasomnia-v10b-steamlinux)**
|
||||
|
||||
This mod already supports x86 Linux.
|
||||
|
||||
Support for other platforms may be available later.
|
||||
|
||||
35. **[Half-Screwed: Death and Rebirth](https://www.moddb.com/mods/half-screwed)**
|
||||
34. **[Half-Screwed: Death and Rebirth](https://www.moddb.com/mods/half-screwed)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **half-screwed** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
36. **[Half-Secret](https://www.moddb.com/mods/half-secret)**
|
||||
35. **[Half-Secret](https://www.moddb.com/mods/half-secret)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **half-secret** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
37. **[Natural Selection](https://www.moddb.com/mods/natural-selection)**
|
||||
36. **[Natural Selection](https://www.moddb.com/mods/natural-selection)**
|
||||
|
||||
This mod already supports x86 Linux.
|
||||
|
||||
Support for other platforms may be available later.
|
||||
|
||||
38. **[Night at the Office](https://www.moddb.com/mods/night-at-the-office)**
|
||||
37. **[Night at the Office](https://www.moddb.com/mods/night-at-the-office)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **noffice** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
39. **[Paranoia](https://www.moddb.com/mods/paranoia)**
|
||||
38. **[Paranoia](https://www.moddb.com/mods/paranoia)**
|
||||
|
||||
*Support temporary abandoned*
|
||||
|
||||
[Source code](https://github.com/FWGS/paranoia_toolkit).
|
||||
|
||||
40. **[Poke646](https://poke646.com/)**
|
||||
39. **[Poke646](https://poke646.com/)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **poke646** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
41. **[Poke646: Vendetta](https://poke646.com/)**
|
||||
40. **[Poke646: Vendetta](https://poke646.com/)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **poke646_vendetta** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
42. [PrimeXT](https://snmetamorph.github.io/PrimeXT/)
|
||||
41. [PrimeXT](https://snmetamorph.github.io/PrimeXT/)
|
||||
|
||||
[Source code](https://github.com/SNMetamorph/PrimeXT)
|
||||
|
||||
43. **[Quake Remake](https://www.moddb.com/games/quake-remake)**
|
||||
42. **[Quake Remake](https://www.moddb.com/games/quake-remake)**
|
||||
|
||||
*Support was fully abandoned due Quake Wrapper release.*
|
||||
|
||||
[Actual source code](https://github.com/FWGS/quakeremake)
|
||||
|
||||
44. **[Rebellion](https://www.moddb.com/mods/rebellion1)**
|
||||
43. **[Rebellion](https://www.moddb.com/mods/rebellion1)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **rebellion** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
45. **[Residual Life](https://www.moddb.com/mods/hl-residual-life)**
|
||||
44. **[Residual Life](https://www.moddb.com/mods/hl-residual-life)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **residual_point** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
46. **[Residual Point](https://www.moddb.com/mods/hl-residual-point)**
|
||||
45. **[Residual Point](https://www.moddb.com/mods/hl-residual-point)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **residual_point** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
47. **[Ricochet](https://store.steampowered.com/app/60/Ricochet/)**
|
||||
46. **[Ricochet](https://store.steampowered.com/app/60/Ricochet/)**
|
||||
|
||||
This mod already supports x86 Linux.
|
||||
|
||||
Support for other platforms may be available later.
|
||||
|
||||
48. [Sewer](https://www.moddb.com/games/half-life/addons/sewer-beta)
|
||||
47. [Sewer](https://www.moddb.com/games/half-life/addons/sewer-beta)
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **sewer_beta** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
49. [Spirit of Half-Life 1.2](https://www.moddb.com/mods/spirit-of-half-life)
|
||||
48. [Spirit of Half-Life 1.2](https://www.moddb.com/mods/spirit-of-half-life)
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **sohl1.2** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
50. **[Swiss Cheese Halloween](https://www.moddb.com/mods/half-life-halloween-mod)**
|
||||
49. **[Swiss Cheese Halloween](https://www.moddb.com/mods/half-life-halloween-mod)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **halloween** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
51. **[Team Fortress Classic](https://store.steampowered.com/app/20/Team_Fortress_Classic/)**
|
||||
50. **[Team Fortress Classic](https://store.steampowered.com/app/20/Team_Fortress_Classic/)**
|
||||
|
||||
This mod already supports x86 Linux.
|
||||
|
||||
Currently, only source code of [client part](https://github.com/Velaron/tf15-client) is available.
|
||||
|
||||
52. **[The Gate](https://www.moddb.com/mods/the-gate)**
|
||||
51. **[The Gate](https://www.moddb.com/mods/the-gate)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **thegate** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
53. **[They Hunger: Trilogy](https://www.moddb.com/mods/they-hunger)**
|
||||
52. **[They Hunger: Trilogy](https://www.moddb.com/mods/they-hunger)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **theyhunger** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
54. **[ThreeWave CTF](https://www.moddb.com/games/deathmatch-classic/downloads/threewave-ctf)**
|
||||
53. **[ThreeWave CTF](https://www.moddb.com/games/deathmatch-classic/downloads/threewave-ctf)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **dmc** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
55. **[Times of Troubles](https://www.moddb.com/mods/times-of-troubles)**
|
||||
54. **[Times of Troubles](https://www.moddb.com/mods/times-of-troubles)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **tot** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
56. [XashXT](https://csm.dev/threads/xashxt-0-65-rev-4-release-stable.38319/)
|
||||
55. [XashXT](https://csm.dev/threads/xashxt-0-65-rev-4-release-stable.38319/)
|
||||
|
||||
*Support was fully abandoned due PrimeXT development*
|
||||
|
||||
[Source code](https://github.com/FWGS/XashXT-FWGS/)
|
||||
|
||||
57. **[X-Half-Life DeathMatch](https://www.moddb.com/mods/xdm)**
|
||||
56. **[X-Half-Life DeathMatch](https://www.moddb.com/mods/xdm)**
|
||||
|
||||
This mod already supports x86 Linux.
|
||||
|
||||
Support for other platforms may be available later.
|
||||
|
||||
58. **[Xen-Warrior](https://www.moddb.com/mods/xen-warrior)**
|
||||
57. **[Xen-Warrior](https://www.moddb.com/mods/xen-warrior)**
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **sohl1.2** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
Don't forget to enable XENWARRIOR build option!!!
|
||||
|
||||
59. [Zombie-X](https://www.moddb.com/mods/zombie-x-10-final)
|
||||
58. [Zombie-X](https://www.moddb.com/mods/zombie-x-10-final)
|
||||
|
||||
To run this mod on specific platforms you may be need to compile libraries from **zombie-x** branch of [hlsdk-portable](https://github.com/FWGS/hlsdk-portable).
|
||||
|
||||
|
||||
39
README.md
39
README.md
@@ -1,6 +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://xash.su/discord/) [](https://t.me/flyingwithgauss) \
|
||||
[](http://fwgsdiscord.mentality.rip/) [](https://t.me/flyingwithgauss) \
|
||||
[](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.
|
||||
@@ -41,12 +41,10 @@ For additional info, run Xash3D with `-help` command line key.
|
||||
1) Copy `valve` directory to a folder named `xash` in the Internal storage.
|
||||
2) Run games from within the app.
|
||||
|
||||
## Reporting issues
|
||||
## Contributing
|
||||
* Before sending an issue, check if someone already reported your issue. Make sure you're following "How To Ask Questions The Smart Way" guide by Eric Steven Raymond. Read more: http://www.catb.org/~esr/faqs/smart-questions.html.
|
||||
* Issues are accepted in both English and Russian.
|
||||
* They are only accepted if you run legally acquired product (e.g. Half-Life in Steam).
|
||||
|
||||
## Contributing code
|
||||
* Check the CONTRIBUTING.md file.
|
||||
* Before sending a PR, check if you followed our contribution guide in CONTRIBUTING.md file.
|
||||
|
||||
## 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/).
|
||||
@@ -83,11 +81,11 @@ This repository contains our fork of HLSDK and restored source code for Half-Lif
|
||||
|
||||
##### 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 SDL3-devel.i686 sdl2-compat-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 freetype-devel.i686 bzip2-devel.i686 libvorbis-devel.i686 opusfile-devel.i686 libogg-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++ SDL3-devel sdl2-compat-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 freetype-devel bzip2-devel libvorbis-devel opusfile-devel libogg-devel`.
|
||||
|
||||
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
|
||||
|
||||
@@ -100,16 +98,6 @@ This repository contains our fork of HLSDK and restored source code for Half-Lif
|
||||
|
||||
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
|
||||
|
||||
#### iOS/iPadOS
|
||||
* Install Xcode from the appstore.
|
||||
* Install [Homebrew package manager](https://brew.sh).
|
||||
|
||||
* Install build dependencies by running: `brew install python`.
|
||||
|
||||
* Clone the SDL2 repo `$ git clone --recursive https://github.com/libsdl-org/SDL.git -b SDL2` and compile the iOS framework by navigating to SDL/Xcode/SDL and opening the Xcode project.
|
||||
|
||||
* Clone this repository: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
|
||||
|
||||
### Building
|
||||
#### Windows (Visual Studio)
|
||||
0) Open command line.
|
||||
@@ -128,17 +116,4 @@ If compiling 32-bit on amd64, make sure `PKG_CONFIG_PATH` from the previous step
|
||||
3) Install: `./waf install --destdir=/path/to/any/output/directory`.
|
||||
|
||||
#### Android (Windows/Linux/macOS)
|
||||
To build you should clone [SDL](https://github.com/libsdl-org/SDL) from `SDL2` branch and [HLSDK-portable](https://github.com/FWGS/hlsdk-portable) `mobile-hacks` branch repositories to 3rdparty folder, after that you should be able to open the project in Android Studio from `android` directory or manually call Gradle to build the APK.
|
||||
|
||||
#### iOS/iPadOS (MacOS only)
|
||||
0) (optional) Examine which build options are available: `./waf --help`.
|
||||
1) Configure build: `./waf configure --ios --enable-bundled-deps --sdl2 (path/to/SDL2.framework)`, set `--ios-simulator` instead of `--ios` if you want to build for simulator.
|
||||
2) Compile `./waf build`.
|
||||
3) Navigate to `build` and copy your compiled SDL2.framework there, then add your game dylibs to `build/ios/libs/(gamedir)/(dlls/cl_dlls)`(You can also run `scripts/ios/buildhlsdk.sh` instead to automatically create an ipa with hlsdk dylibs)
|
||||
4) Run `scripts/ios/createipa.sh` to create an installable ipa
|
||||
|
||||
### Running tests
|
||||
|
||||
Tests are enabled with `--enable-tests` passed to `./waf configure` and can be run with `./waf --alltests`.
|
||||
|
||||
This builds both standalone unit tests and a separate engine test binary (`xash3d_tests`) that embeds engine-level tests. The engine test binary requires no game assets.
|
||||
You can just open the `android` folder in Android Studio and build from here, or use `gradlew` to build from command line.
|
||||
18
SECURITY.md
18
SECURITY.md
@@ -1,18 +0,0 @@
|
||||
# Xash3D FWGS Security Policy
|
||||
|
||||
## Supported versions
|
||||
|
||||
Because we don't have clear release cycle yet, support is only provided to the
|
||||
latest engine versions from `master` branch. You can use `host_ver` command in
|
||||
console to fetch detailed info about the engine build.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you discover a security vulnerability in this project, it can be reported
|
||||
privately though `Security` tab on GitHub:
|
||||
https://github.com/FWGS/xash3d-fwgs/security
|
||||
|
||||
Alternatively, you can report them publicly on the `Issues` tab:
|
||||
https://github.com/FWGS/xash3d-fwgs/issues
|
||||
|
||||
In both cases, expect a reply within approximately a week.
|
||||
@@ -1,4 +1,3 @@
|
||||
import com.android.build.api.dsl.ApplicationExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
import java.time.LocalDateTime
|
||||
import java.time.Month
|
||||
@@ -6,11 +5,12 @@ import java.time.temporal.ChronoUnit
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
}
|
||||
|
||||
extensions.configure<ApplicationExtension> {
|
||||
android {
|
||||
namespace = "su.xash.engine"
|
||||
ndkVersion = "29.0.14206865"
|
||||
ndkVersion = "28.2.13676358"
|
||||
compileSdk = 35
|
||||
|
||||
defaultConfig {
|
||||
@@ -34,7 +34,7 @@ extensions.configure<ApplicationExtension> {
|
||||
"--configuration-dir=\${ndk.buildRoot}",
|
||||
"--ndk-version=\${ndk.moduleNdkVersion}",
|
||||
"--min-sdk-version=\${ndk.minPlatform}",
|
||||
"--ndk-root=${androidComponents.sdkComponents.ndkDirectory.get()}",
|
||||
"--ndk-root=${android.ndkDirectory}",
|
||||
// shut up, fake options
|
||||
"-p:Configuration=\${ndk.variantName}",
|
||||
"-p:Platform=\${ndk.abi}"
|
||||
@@ -77,8 +77,8 @@ extensions.configure<ApplicationExtension> {
|
||||
|
||||
sourceSets {
|
||||
getByName("main") {
|
||||
assets.directories.add("../../3rdparty/extras/xash-extras")
|
||||
java.directories.add("../../3rdparty/SDL/android-project/app/src/main/java")
|
||||
assets.srcDirs("../../3rdparty/extras/xash-extras")
|
||||
java.srcDir("../../3rdparty/SDL/android-project/app/src/main/java")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,10 +29,10 @@
|
||||
<!-- Allow downloading to the external storage on Android 5.1 and older -->
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="29" />
|
||||
android:maxSdkVersion="22" />
|
||||
<uses-permission
|
||||
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||
android:maxSdkVersion="29" />
|
||||
android:maxSdkVersion="32" />
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
||||
<!-- Allow access to Bluetooth devices -->
|
||||
<!-- Currently this is just for Steam Controller support and requires setting SDL_HINT_JOYSTICK_HIDAPI_STEAM -->
|
||||
|
||||
@@ -15,9 +15,6 @@ import org.libsdl.app.SDLActivity;
|
||||
|
||||
import su.xash.engine.util.AndroidBug5497Workaround;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class XashActivity extends SDLActivity {
|
||||
private boolean mUseVolumeKeys;
|
||||
private String mPackageName;
|
||||
@@ -152,7 +149,6 @@ public class XashActivity extends SDLActivity {
|
||||
|
||||
String argv = getIntent().getStringExtra("argv");
|
||||
if (argv == null) argv = "-console -log";
|
||||
|
||||
return argv.split(" ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,36 +6,28 @@ import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import androidx.core.net.toUri
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import su.xash.engine.R
|
||||
import android.net.Uri
|
||||
import su.xash.engine.XashActivity
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.util.Arrays
|
||||
import android.util.Log
|
||||
|
||||
class Game(val ctx: Context, val basedir: File, val gameInfoFile: File) {
|
||||
|
||||
class Game(val ctx: Context, val basedir: File) {
|
||||
private var iconName = "game.ico"
|
||||
var title = "Unknown Game"
|
||||
var icon: Bitmap? = null
|
||||
var cover: Bitmap? = null
|
||||
|
||||
val mobileHacksGames = arrayOf("aom", "bdlands", "biglolly", "bshift", "caseclosed",
|
||||
"hl_urbicide", "induction", "redempt", "secret",
|
||||
"sewer_beta", "tot", "valve", "vendetta")
|
||||
|
||||
// a1ba: follow the behavior of Xash3D's game_launch.
|
||||
// for hl mods we put `valve` as game directory
|
||||
// for any other game that's not hl this string must be replaced with your
|
||||
// main game directory
|
||||
// mods always use -game command line parameter
|
||||
var defaultGameDir = "valve"
|
||||
|
||||
private val pref = ctx.getSharedPreferences(basedir.name, Context.MODE_PRIVATE)
|
||||
|
||||
init {
|
||||
parseGameInfo(gameInfoFile)
|
||||
val gameInfo = File(basedir, "gameinfo.txt")
|
||||
if (gameInfo.exists()) {
|
||||
parseGameInfo(gameInfo)
|
||||
} else {
|
||||
val libListGam = File(basedir, "liblist.gam")
|
||||
if (libListGam.exists()) parseGameInfo(libListGam)
|
||||
}
|
||||
|
||||
val iconFile = File(basedir, iconName)
|
||||
if (iconFile.exists()) {
|
||||
@@ -50,76 +42,14 @@ class Game(val ctx: Context, val basedir: File, val gameInfoFile: File) {
|
||||
}
|
||||
|
||||
fun startEngine(ctx: Context) {
|
||||
val packageNames = getPackageNamesForGameDir(basedir.name)
|
||||
var externalGame = false
|
||||
var commandLineArgs = "";
|
||||
|
||||
if (basedir.name != defaultGameDir)
|
||||
commandLineArgs += "-game ${basedir.name} "
|
||||
|
||||
if (packageNames != null) {
|
||||
if (packageNames.contains("su.xash.engine")) {
|
||||
commandLineArgs += "-dll @hl "
|
||||
} else if (packageNames.contains("su.xash.cs16client")) {
|
||||
if (pref.getBoolean("enable_yapb_bots", true)) {
|
||||
commandLineArgs += "-dll @yapb "
|
||||
}
|
||||
externalGame = true
|
||||
}
|
||||
}
|
||||
|
||||
commandLineArgs += pref.getString("arguments", "-console -log")
|
||||
|
||||
var packageName: String? = null
|
||||
var gameLibDir: String? = null
|
||||
if (externalGame && packageNames != null) {
|
||||
for (pn in packageNames) {
|
||||
gameLibDir = try {
|
||||
getGameLibDir(ctx, pn)
|
||||
} catch(e: PackageManager.NameNotFoundException) {
|
||||
null
|
||||
} catch(e: Exception) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
|
||||
if (gameLibDir != null) {
|
||||
packageName = pn
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (gameLibDir == null) {
|
||||
MaterialAlertDialogBuilder(ctx).apply {
|
||||
setTitle(R.string.game_apk_required)
|
||||
setMessage(R.string.game_apk_message)
|
||||
setPositiveButton(R.string.game_apk_install) { _, _ ->
|
||||
val intent = Intent(Intent.ACTION_VIEW,
|
||||
getDownloadPageForGameDir(basedir.name).toUri())
|
||||
ctx.startActivity(intent)
|
||||
}
|
||||
show()
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.startActivity(Intent(ctx, XashActivity::class.java).apply {
|
||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
|
||||
putExtra("gamedir", defaultGameDir)
|
||||
putExtra("argv", commandLineArgs)
|
||||
putExtra("gamedir", basedir.name)
|
||||
putExtra("argv", pref.getString("arguments", "-console -log"))
|
||||
putExtra("usevolume", pref.getBoolean("use_volume_buttons", false))
|
||||
putExtra("basedir", basedir.parent)
|
||||
|
||||
if (gameLibDir != null) {
|
||||
putExtra("gamelibdir", gameLibDir)
|
||||
}
|
||||
|
||||
if (packageName != null) {
|
||||
putExtra("package", packageName)
|
||||
}
|
||||
//.putExtra("gamelibdir", getGameLibDir(context))
|
||||
//.putExtra("package", getPackageName()) }
|
||||
})
|
||||
}
|
||||
|
||||
@@ -140,50 +70,44 @@ class Game(val ctx: Context, val basedir: File, val gameInfoFile: File) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPackageNamesForGameDir(gamedir: String): Array<String>? {
|
||||
if (gamedir.equals("cstrike", ignoreCase = true)
|
||||
|| gamedir.equals("czero", ignoreCase = true))
|
||||
return arrayOf("su.xash.cs16client.test", "su.xash.cs16client")
|
||||
|
||||
if (gamedir.equals("tfc", ignoreCase = true))
|
||||
return arrayOf("su.xash.tf15client.test", "su.xash.tf15client")
|
||||
|
||||
// mobile_hacks hlsdk-portable branch allows us to have few more mods out of the box
|
||||
if (mobileHacksGames.any { it.equals(gamedir, ignoreCase = true) })
|
||||
return arrayOf("su.xash.engine")
|
||||
|
||||
// return if (mDbEntry != null) {
|
||||
// mDbEntry.getPackageName()
|
||||
// } else null
|
||||
private fun getPackageName(): String? {
|
||||
// return if (mDbEntry != null) {
|
||||
// mDbEntry.getPackageName()
|
||||
// } else null
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getDownloadPageForGameDir(gamedir: String): String {
|
||||
if (gamedir.equals("cstrike", ignoreCase = true)
|
||||
|| gamedir.equals("czero", ignoreCase = true))
|
||||
return "https://github.com/Velaron/cs16-client/releases/download/continuous/CS16Client-Android.apk"
|
||||
|
||||
if (gamedir.equals("tfc", ignoreCase = true))
|
||||
return "https://github.com/Velaron/tf15-client/releases/download/continuous/TF15Client-Android.apk"
|
||||
|
||||
// just so we don't return null
|
||||
return "https://github.com/FWGS/xash3d-fwgs/releases/download/continuous/xash3d-fwgs-android.apk"
|
||||
}
|
||||
|
||||
private fun getGameLibDir(ctx: Context, packageName: String): String? {
|
||||
val packageInfo: PackageInfo = ctx.packageManager.getPackageInfo(packageName, 0)
|
||||
return packageInfo.applicationInfo?.nativeLibraryDir
|
||||
private fun getGameLibDir(ctx: Context): String? {
|
||||
val pkgName = getPackageName()
|
||||
if (pkgName != null) {
|
||||
val pkgInfo: PackageInfo = try {
|
||||
ctx.packageManager.getPackageInfo(pkgName, 0)
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
e.printStackTrace()
|
||||
ctx.startActivity(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW, Uri.parse("market://details?id=$pkgName")
|
||||
).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||
)
|
||||
return null
|
||||
}
|
||||
return pkgInfo.applicationInfo?.nativeLibraryDir
|
||||
}
|
||||
return ctx.applicationInfo.nativeLibraryDir
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getGames(ctx: Context, root: File): List<Game> {
|
||||
fun getGames(ctx: Context, file: File): List<Game> {
|
||||
val games = mutableListOf<Game>()
|
||||
|
||||
root.listFiles()?.forEach {
|
||||
if (it.isDirectory) {
|
||||
val subDirGameInfoFile = checkIfGamedir(it)
|
||||
if (subDirGameInfoFile != null) {
|
||||
games.add(Game(ctx, it, subDirGameInfoFile))
|
||||
if (checkIfGamedir(file)) {
|
||||
games.add(Game(ctx, file))
|
||||
} else {
|
||||
file.listFiles()?.forEach {
|
||||
if (it.isDirectory) {
|
||||
if (checkIfGamedir(it)) {
|
||||
games.add(Game(ctx, it))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -191,18 +115,24 @@ class Game(val ctx: Context, val basedir: File, val gameInfoFile: File) {
|
||||
return games
|
||||
}
|
||||
|
||||
fun checkIfGamedir(gamedir: File): File? {
|
||||
gamedir.listFiles()?.forEach {
|
||||
if (it.isFile) {
|
||||
if (it.name.equals("liblist.gam", ignoreCase = true))
|
||||
return it
|
||||
fun checkIfGamedir(file: File): Boolean {
|
||||
if (File(file, "liblist.gam").exists()) return true
|
||||
if (File(file, "gameinfo.txt").exists()) return true
|
||||
|
||||
if (it.name.equals("gameinfo.txt", ignoreCase = true))
|
||||
return it
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Intent intent = new Intent("su.xash.engine.MOD");
|
||||
// for (ResolveInfo info : context.getPackageManager()
|
||||
// .queryIntentActivities(intent, PackageManager.GET_META_DATA)) {
|
||||
// String packageName = info.activityInfo.applicationInfo.packageName;
|
||||
// String gameDir = info.activityInfo.applicationInfo.metaData.getString(
|
||||
// "su.xash.engine.gamedir");
|
||||
// Log.d(TAG, "package = " + packageName + " gamedir = " + gameDir);
|
||||
// }
|
||||
|
||||
//public void startEngine(Context context) {
|
||||
// context.startActivity(new Intent(context, XashActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP).putExtra("gamedir", getGameDir()).putExtra("argv", getArguments()).putExtra("usevolume", getVolumeState()).putExtra("gamelibdir", getGameLibDir(context)).putExtra("package", getPackageName()));
|
||||
//}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package su.xash.engine.ui.library
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
@@ -15,8 +13,7 @@ import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
@@ -28,7 +25,6 @@ import su.xash.engine.R
|
||||
import su.xash.engine.adapters.GameAdapter
|
||||
import su.xash.engine.databinding.FragmentLibraryBinding
|
||||
|
||||
|
||||
class LibraryFragment : Fragment(), MenuProvider {
|
||||
private var _binding: FragmentLibraryBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
@@ -42,85 +38,23 @@ class LibraryFragment : Fragment(), MenuProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private val requiredPermissions = arrayOf(
|
||||
Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
)
|
||||
|
||||
private val requestPermissionLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.RequestMultiplePermissions()
|
||||
) { permissions ->
|
||||
val granted = permissions.entries.all { it.value }
|
||||
if (granted) {
|
||||
libraryViewModel.reloadGames(requireContext())
|
||||
} else {
|
||||
checkStoragePermissions()
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkStoragePermissions(): Boolean {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
if (!Environment.isExternalStorageManager()) {
|
||||
MaterialAlertDialogBuilder(requireContext()).apply {
|
||||
setTitle(R.string.file_access_required)
|
||||
setMessage(R.string.file_access_message)
|
||||
setPositiveButton(R.string.open_settings) { _, _ ->
|
||||
startActivityForResult.launch(
|
||||
Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION).setData(
|
||||
Uri.fromParts("package", BuildConfig.APPLICATION_ID, null)
|
||||
)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
|
||||
MaterialAlertDialogBuilder(requireContext()).apply {
|
||||
setTitle(R.string.file_access_required)
|
||||
setMessage(R.string.file_access_message)
|
||||
setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
startActivityForResult.launch(
|
||||
Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION).setData(
|
||||
Uri.fromParts("package", BuildConfig.APPLICATION_ID, null)
|
||||
)
|
||||
}
|
||||
setNeutralButton(R.string.done_check_permissions) { dialog, _ ->
|
||||
checkStoragePermissions()
|
||||
}
|
||||
setCancelable(false)
|
||||
show()
|
||||
|
||||
return false
|
||||
)
|
||||
}
|
||||
} else {
|
||||
return true
|
||||
setCancelable(false)
|
||||
show()
|
||||
}
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
val permissionsNeeded = requiredPermissions.filter {
|
||||
ContextCompat.checkSelfPermission(
|
||||
requireContext(),
|
||||
it
|
||||
) != PackageManager.PERMISSION_GRANTED
|
||||
}.toTypedArray()
|
||||
|
||||
if (!permissionsNeeded.isEmpty()) {
|
||||
val showRationale = permissionsNeeded.any {
|
||||
ActivityCompat.shouldShowRequestPermissionRationale(requireActivity(), it)
|
||||
}
|
||||
|
||||
MaterialAlertDialogBuilder(requireContext()).apply {
|
||||
setTitle(R.string.external_storage_required)
|
||||
setMessage(R.string.external_storage_message)
|
||||
setPositiveButton(R.string.open_settings) { _, _ ->
|
||||
if (showRationale) {
|
||||
requestPermissionLauncher.launch(permissionsNeeded)
|
||||
} else {
|
||||
val intent =
|
||||
Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
|
||||
data =
|
||||
Uri.fromParts("package", requireContext().packageName, null)
|
||||
}
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
setNeutralButton(R.string.done_check_permissions) { _, _ ->
|
||||
checkStoragePermissions()
|
||||
}
|
||||
setCancelable(false)
|
||||
show()
|
||||
}
|
||||
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
@@ -173,12 +107,4 @@ class LibraryFragment : Fragment(), MenuProvider {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
if (checkStoragePermissions()) {
|
||||
libraryViewModel.reloadGames(requireContext())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import su.xash.engine.model.Game
|
||||
import su.xash.engine.util.Nomedia
|
||||
import java.io.File
|
||||
|
||||
class LibraryViewModel(application: Application) : AndroidViewModel(application) {
|
||||
@@ -40,8 +39,6 @@ class LibraryViewModel(application: Application) : AndroidViewModel(application)
|
||||
?: (Environment.getExternalStorageDirectory().absolutePath + "/xash")
|
||||
val root = File(rootPath)
|
||||
|
||||
Nomedia.ensureNomedia(root)
|
||||
|
||||
_installedGames.postValue(Game.getGames(ctx, root))
|
||||
_isReloading.postValue(false)
|
||||
}
|
||||
|
||||
@@ -20,12 +20,6 @@ class GameSettingsPreferenceFragment(val game: Game) : PreferenceFragmentCompat(
|
||||
packageList.setValueIndex(0);
|
||||
}
|
||||
|
||||
if (game.basedir.name.equals("cstrike", ignoreCase = true)
|
||||
|| game.basedir.name.equals("czero", ignoreCase = true)) {
|
||||
val enableYaPBBots = findPreference<SwitchPreferenceCompat>("enable_yapb_bots")!!
|
||||
enableYaPBBots.isVisible = true
|
||||
}
|
||||
|
||||
val separatePackages = findPreference<SwitchPreferenceCompat>("separate_libraries")!!
|
||||
val clientPackage = findPreference<ListPreference>("client_package")!!
|
||||
val serverPackage = findPreference<ListPreference>("server_package")!!
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
Nomedia.kt - ensure that .nomedia file exists in directory
|
||||
Copyright (C) 2025 Alibek Omarov
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
package su.xash.engine.util
|
||||
import java.io.File
|
||||
|
||||
object Nomedia {
|
||||
fun ensureNomedia(directory: File): Boolean {
|
||||
try {
|
||||
// ensure paths exists
|
||||
if (!directory.exists() && !directory.mkdirs()) {
|
||||
return false
|
||||
}
|
||||
|
||||
// check if it's a directory
|
||||
if (!directory.isDirectory) {
|
||||
return false
|
||||
}
|
||||
|
||||
val nomediaFile = File(directory, ".nomedia")
|
||||
|
||||
// if the .nomedia is directory, remove it
|
||||
if (nomediaFile.isDirectory) {
|
||||
// it should be empty to be deleted, but that's good
|
||||
// because this way we're not deleting something important
|
||||
// (who would stash important files in .nomedia directory though...)
|
||||
if (!nomediaFile.delete()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// it returns false if file already exists, which is fine for us
|
||||
nomediaFile.createNewFile()
|
||||
|
||||
return true
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name" translatable="false">Xash3D FWGS</string>
|
||||
<string name="library">Librería</string>
|
||||
<string name="dedicated_server">Dedicado</string>
|
||||
<string name="app_settings">Ajustes</string>
|
||||
<string name="game_settings">Ajustes del juego</string>
|
||||
<string name="game_settings_command_line">Argumentos de la línea de comandos</string>
|
||||
<string name="game_settings_volume_buttons">Usar botones de volumen en el juego</string>
|
||||
<string name="preferences_package_name">Paquete de librerías</string>
|
||||
<string name="preferences_separate_libraries">Librerías de paquetes separados</string>
|
||||
<string name="preferences_client_package">Paquete de cliente</string>
|
||||
<string name="preferences_server_package">Paquete de servidor</string>
|
||||
<string name="preferences_use_icons">Usar iconos en lugar de fondos</string>
|
||||
<string name="game_data_location">Ubicación de los datos del juego</string>
|
||||
<string name="file_access_required">Se requiere acceso a todos los archivos</string>
|
||||
<string name="file_access_message">Se requiere acceso a todos los archivos para que la aplicación funcione correctamente.</string>
|
||||
<string name="select_current_directory">Seleccionar directorio actual</string>
|
||||
<string name="external_storage_required">Se requiere acceso al almacenamiento externo</string>
|
||||
<string name="external_storage_message">Se requiere acceso al almacenamiento externo para que la aplicación funcione correctamente.</string>
|
||||
</resources>
|
||||
@@ -1,27 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name" translatable="false">Xash3D FWGS</string>
|
||||
<string name="library">Bibliothèque</string>
|
||||
<string name="dedicated_server">Dédié</string>
|
||||
<string name="app_settings">Paramètres</string>
|
||||
<string name="game_settings">Paramètres du jeu</string>
|
||||
<string name="game_settings_command_line">Arguments de ligne de commande</string>
|
||||
<string name="game_settings_volume_buttons">Utiliser les boutons de volume dans le jeu</string>
|
||||
<string name="game_settings_yapb_bots">Activer les bots YaPB (Uniquement pour CS)</string>
|
||||
<string name="preferences_package_name">Paquet de bibliothèques</string>
|
||||
<string name="preferences_separate_libraries">Bibliothèques de paquets séparés</string>
|
||||
<string name="preferences_client_package">Paquet client</string>
|
||||
<string name="preferences_server_package">Paquet serveur</string>
|
||||
<string name="preferences_use_icons">Utiliser des icônes au lieu d\'arrière-plans</string>
|
||||
<string name="game_data_location">Emplacement des données du jeu</string>
|
||||
<string name="file_access_required">L\'accès à tous les fichiers est requis</string>
|
||||
<string name="file_access_message">L\'accès à tous les fichiers est requis pour que l\'application fonctionne correctement.</string>
|
||||
<string name="select_current_directory">Sélectionner le répertoire actuel</string>
|
||||
<string name="external_storage_required">L\'accès au stockage externe est requis</string>
|
||||
<string name="external_storage_message">L\'accès au stockage externe est requis pour que l\'application fonctionne correctement.</string>
|
||||
<string name="open_settings">Ouvrir les paramètres</string>
|
||||
<string name="done_check_permissions">Terminé ! Vérifier les permissions</string>
|
||||
<string name="game_apk_required">Nécessite un APK de bibliothèques de jeu</string>
|
||||
<string name="game_apk_message">Pour lancer ce jeu, vous devez installer un APK additionnel</string>
|
||||
<string name="game_apk_install">Télécharger</string>
|
||||
</resources>
|
||||
@@ -6,15 +6,9 @@
|
||||
<string name="game_settings">Configurações do jogo</string>
|
||||
<string name="game_settings_command_line">Argumentos de linha de comando</string>
|
||||
<string name="game_settings_volume_buttons">Usar botões de volume no jogo</string>
|
||||
<string name="preferences_package_name">Pacote de bibliotecas</string>
|
||||
<string name="preferences_package_name">Bibliotecas de pacotes</string>
|
||||
<string name="preferences_separate_libraries">Bibliotecas de pacotes separados</string>
|
||||
<string name="preferences_client_package">Pacote do cliente</string>
|
||||
<string name="preferences_server_package">Pacote do servidor</string>
|
||||
<string name="preferences_use_icons">Usar ícones em vez de fundos</string>
|
||||
<string name="game_data_location">Local dos dados do jogo</string>
|
||||
<string name="file_access_required">Acesso a todos os arquivos necessário</string>
|
||||
<string name="file_access_message">É necessário acesso a todos os arquivos para que o aplicativo funcione corretamente.</string>
|
||||
<string name="select_current_directory">Selecionar diretório atual</string>
|
||||
<string name="external_storage_required">Acesso ao armazenamento externo necessário</string>
|
||||
<string name="external_storage_message">É necessário acesso ao armazenamento externo para que o aplicativo funcione corretamente.</string>
|
||||
<string name="preferences_client_package">Pacotes de Cliente</string>
|
||||
<string name="preferences_server_package">Pacotes de Servidor</string>
|
||||
<string name="preferences_use_icons">Usar ícones ao inves de imagens de fundo</string>
|
||||
</resources>
|
||||
|
||||
@@ -6,21 +6,9 @@
|
||||
<string name="game_settings">Настройки игры</string>
|
||||
<string name="game_settings_command_line">Аргументы командной строки</string>
|
||||
<string name="game_settings_volume_buttons">Использовать кнопки громкости</string>
|
||||
<string name="game_settings_yapb_bots">Включить YaPB ботов (только CS)</string>
|
||||
<string name="preferences_package_name">Пакет библиотек</string>
|
||||
<string name="preferences_separate_libraries">Библиотеки из отдельных пакетов</string>
|
||||
<string name="preferences_client_package">Пакет клиента</string>
|
||||
<string name="preferences_server_package">Пакет сервера</string>
|
||||
<string name="preferences_use_icons">Использовать иконки вместо фона</string>
|
||||
<string name="game_data_location">Расположение игровых данных</string>
|
||||
<string name="file_access_required">Требуется доступ ко всем файлам</string>
|
||||
<string name="file_access_message">Для правильной работы приложения требуется доступ ко всем файлам.</string>
|
||||
<string name="select_current_directory">Выбрать текущую директорию</string>
|
||||
<string name="external_storage_required">Требуется доступ к внешнему хранилищу</string>
|
||||
<string name="external_storage_message">Для правильной работы приложения требуется доступ к внешнему хранилищу.</string>
|
||||
<string name="open_settings">Открыть настройки</string>
|
||||
<string name="done_check_permissions">Готово! Проверить разрешения</string>
|
||||
<string name="game_apk_required">Требуется APK с игровыми библиотеками</string>
|
||||
<string name="game_apk_message">Чтобы запустить эту игру, нужно установить дополнительный APK</string>
|
||||
<string name="game_apk_install">Скачать</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="library">库</string>
|
||||
<string name="dedicated_server">专用服务器</string>
|
||||
<string name="app_settings">设置</string>
|
||||
<string name="game_settings">游戏设置</string>
|
||||
<string name="game_settings_command_line">命令行参数</string>
|
||||
<string name="game_settings_volume_buttons">在游戏中使用音量按钮</string>
|
||||
<string name="game_settings_yapb_bots">启用yapb机器人(仅限CS)</string>
|
||||
<string name="preferences_package_name">数据包</string>
|
||||
<string name="preferences_separate_libraries">来自独立包的库</string>
|
||||
<string name="preferences_client_package">客户端包</string>
|
||||
<string name="preferences_server_package">服务器包</string>
|
||||
<string name="preferences_use_icons">使用图标代替背景</string>
|
||||
<string name="game_data_location">游戏数据包路径位置</string>
|
||||
<string name="file_access_required">需要所有文件访问权限</string>
|
||||
<string name="file_access_message">应用程序需要所有文件访问权限才能正常运行</string>
|
||||
<string name="select_current_directory">选择当前目录</string>
|
||||
<string name="external_storage_required">需要外部存储访问权限</string>
|
||||
<string name="external_storage_message">应用程序需要外部存储访问权限才能正常运行</string>
|
||||
<string name="open_settings">打开设置</string>
|
||||
<string name="done_check_permissions">准备好了!检查权限</string>
|
||||
<string name="game_apk_required">需要带有游戏库的APK</string>
|
||||
<string name="game_apk_message">要运行此游戏,您需要安装额外的APK</string>
|
||||
<string name="game_apk_install">下载</string>
|
||||
</resources>
|
||||
@@ -7,7 +7,6 @@
|
||||
<string name="game_settings">Game Settings</string>
|
||||
<string name="game_settings_command_line">Command-line arguments</string>
|
||||
<string name="game_settings_volume_buttons">Use volume buttons in-game</string>
|
||||
<string name="game_settings_yapb_bots">Enable YaPB bots (CS only)</string>
|
||||
<string name="preferences_package_name">Libraries package</string>
|
||||
<string name="preferences_separate_libraries">Libraries from separate packages</string>
|
||||
<string name="preferences_client_package">Client package</string>
|
||||
@@ -17,11 +16,4 @@
|
||||
<string name="file_access_required">All-files access required</string>
|
||||
<string name="file_access_message">All-files access is required for the app to function properly.</string>
|
||||
<string name="select_current_directory">Select current directory</string>
|
||||
<string name="external_storage_required">External storage access required</string>
|
||||
<string name="external_storage_message">External storage access is required for the app to function properly.</string>
|
||||
<string name="open_settings">Open settings</string>
|
||||
<string name="done_check_permissions">Done! Check permissions</string>
|
||||
<string name="game_apk_required">Game code APK required</string>
|
||||
<string name="game_apk_message">To launch this game, you need additional APK installed</string>
|
||||
<string name="game_apk_install">Download</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<EditTextPreference
|
||||
app:defaultValue="-console -log"
|
||||
app:key="arguments"
|
||||
@@ -13,13 +12,6 @@
|
||||
app:layout="@layout/switch_preference"
|
||||
app:title="@string/game_settings_volume_buttons" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
app:key="enable_yapb_bots"
|
||||
app:layout="@layout/switch_preference"
|
||||
app:title="@string/game_settings_yapb_bots"
|
||||
app:defaultValue="true"
|
||||
app:isPreferenceVisible="false" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
app:key="separate_libraries"
|
||||
app:layout="@layout/switch_preference"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
alias(libs.plugins.android.application) apply false
|
||||
alias(libs.plugins.kotlin.android) apply false
|
||||
}
|
||||
|
||||
@@ -25,6 +25,3 @@ android.nonTransitiveRClass=true
|
||||
|
||||
# Enable verbose output for CMake
|
||||
android.native.buildOutput=verbose
|
||||
android.uniquePackageNames=false
|
||||
android.dependency.useConstraints=true
|
||||
android.r8.strictFullModeForKeepRules=false
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#This file is generated by updateDaemonJvm
|
||||
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/29ee363f71d060405f729a8f1b7f7aef/redirect
|
||||
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/ecd23fd7707c683afbcd6052998cb6a9/redirect
|
||||
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/29ee363f71d060405f729a8f1b7f7aef/redirect
|
||||
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/ecd23fd7707c683afbcd6052998cb6a9/redirect
|
||||
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/10fc3bf1ee0001078a473afe6e43cfdb/redirect
|
||||
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/658299a896470fbb3103ba3a430ee227/redirect
|
||||
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/29ee363f71d060405f729a8f1b7f7aef/redirect
|
||||
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/67a0fee3c4236b6397dcbe8575ca2011/redirect
|
||||
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/39846e8427e64a3824c13e399d7d813c/redirect
|
||||
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/932015f6361ccaead0c6d9b8717ed96e/redirect
|
||||
toolchainVendor=JETBRAINS
|
||||
toolchainVersion=21
|
||||
@@ -1,7 +1,8 @@
|
||||
[versions]
|
||||
acraHttp = "5.12.0"
|
||||
agp = "9.0.1"
|
||||
agp = "8.11.1"
|
||||
appcompat = "1.7.1"
|
||||
kotlin = "2.2.0"
|
||||
material = "1.12.0"
|
||||
navigationRuntimeKtx = "2.9.1"
|
||||
preferenceKtx = "1.2.1"
|
||||
@@ -19,3 +20,4 @@ swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout"
|
||||
|
||||
[plugins]
|
||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#Tue Jul 01 19:51:06 EEST 2025
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -11,9 +11,6 @@ pluginManagement {
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
plugins {
|
||||
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
|
||||
}
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
repositories {
|
||||
|
||||
@@ -18,20 +18,17 @@ GNU General Public License for more details.
|
||||
// video backends (XASH_VIDEO)
|
||||
#define VIDEO_NULL 0
|
||||
#define VIDEO_SDL 1
|
||||
#define VIDEO_PSP 2
|
||||
#define VIDEO_FBDEV 3
|
||||
#define VIDEO_DOS 4
|
||||
|
||||
// audio backends (XASH_SOUND)
|
||||
#define SOUND_NULL 0
|
||||
#define SOUND_SDL 1
|
||||
#define SOUND_PSP 2
|
||||
#define SOUND_ALSA 3
|
||||
|
||||
// input (XASH_INPUT)
|
||||
#define INPUT_NULL 0
|
||||
#define INPUT_SDL 1
|
||||
#define INPUT_PSP 2
|
||||
#define INPUT_EVDEV 3
|
||||
|
||||
// timer (XASH_TIMER)
|
||||
@@ -40,21 +37,18 @@ GNU General Public License for more details.
|
||||
#define TIMER_POSIX 2
|
||||
#define TIMER_WIN32 3
|
||||
#define TIMER_DOS 4
|
||||
#define TIMER_PSP 5
|
||||
|
||||
// messageboxes (XASH_MESSAGEBOX)
|
||||
#define MSGBOX_STDERR 0
|
||||
#define MSGBOX_SDL 1
|
||||
#define MSGBOX_PSP 2
|
||||
#define MSGBOX_WIN32 3
|
||||
#define MSGBOX_NSWITCH 4
|
||||
|
||||
// library loading (XASH_LIB)
|
||||
#define LIB_NULL 0
|
||||
#define LIB_POSIX 1
|
||||
#define LIB_WIN32 2
|
||||
#define LIB_NULL 0
|
||||
#define LIB_POSIX 1
|
||||
#define LIB_WIN32 2
|
||||
#define LIB_STATIC 3
|
||||
#define LIB_PSP 4
|
||||
|
||||
// movies (XASH_AVI)
|
||||
#define AVI_NULL 0
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
#ifndef BEAMDEF_H
|
||||
#define BEAMDEF_H
|
||||
|
||||
#include "xash3d_types.h"
|
||||
|
||||
#define FBEAM_STARTENTITY 0x00000001
|
||||
#define FBEAM_ENDENTITY 0x00000002
|
||||
#define FBEAM_FADEIN 0x00000004
|
||||
|
||||
344
common/bspfile.h
344
common/bspfile.h
@@ -12,12 +12,10 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef BSPFILE_H
|
||||
#define BSPFILE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "xash3d_types.h"
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
@@ -28,310 +26,288 @@ BRUSH MODELS
|
||||
*/
|
||||
|
||||
// header
|
||||
#define Q1BSP_VERSION 29 // quake1 regular version (beta is 28)
|
||||
#define HLBSP_VERSION 30 // half-life regular version
|
||||
#define QBSP2_VERSION (( 'B' << 0 ) | ( 'S' << 8 ) | ( 'P' << 16 ) | ( '2' << 24 ))
|
||||
#define Q1BSP_VERSION 29 // quake1 regular version (beta is 28)
|
||||
#define HLBSP_VERSION 30 // half-life regular version
|
||||
#define QBSP2_VERSION (('B' << 0) | ('S' << 8) | ('P' << 16) | ('2'<<24))
|
||||
|
||||
#define IDEXTRAHEADER (( 'X' << 0 ) | ( 'A' << 8 ) | ( 'S' << 16 ) | ( 'H' << 24 ))
|
||||
#define EXTRA_VERSION 4 // ver. 1 was occupied by old versions of XashXT
|
||||
// ver. 2 was occupied by old vesrions of P2:savior
|
||||
// ver. 3 was occupied by experimental versions of P2:savior change fmt
|
||||
#define IDEXTRAHEADER (('H'<<24)+('S'<<16)+('A'<<8)+'X') // little-endian "XASH"
|
||||
#define EXTRA_VERSION 4 // ver. 1 was occupied by old versions of XashXT, ver. 2 was occupied by old vesrions of P2:savior
|
||||
// ver. 3 was occupied by experimental versions of P2:savior change fmt
|
||||
|
||||
#define IDBSPXHEADER (( 'B' << 0 ) | ( 'S' << 8 ) | ( 'P' << 16 ) | ( 'X' << 24 ))
|
||||
|
||||
#define DELUXEMAP_VERSION 1
|
||||
#define IDDELUXEMAPHEADER (( 'Q' << 0 ) | ('L' << 8 ) | ( 'I' << 16 ) | ( 'T' << 24 ))
|
||||
#define DELUXEMAP_VERSION 1
|
||||
#define IDDELUXEMAPHEADER (('T'<<24)+('I'<<16)+('L'<<8)+'Q') // little-endian "QLIT"
|
||||
|
||||
// worldcraft predefined angles
|
||||
#define ANGLE_UP -1
|
||||
#define ANGLE_DOWN -2
|
||||
#define ANGLE_UP -1
|
||||
#define ANGLE_DOWN -2
|
||||
|
||||
// bmodel limits
|
||||
#define MAX_MAP_HULLS 4 // MAX_HULLS
|
||||
#define MAX_MAP_HULLS 4 // MAX_HULLS
|
||||
|
||||
#define SURF_PLANEBACK BIT( 1 ) // plane should be negated
|
||||
#define SURF_DRAWSKY BIT( 2 ) // sky surface
|
||||
#define SURF_DRAWTURB_QUADS BIT( 3 ) // all subidivided polygons are quads
|
||||
#define SURF_DRAWTURB BIT( 4 ) // warp surface
|
||||
#define SURF_DRAWTILED BIT( 5 ) // face without lighmap
|
||||
#define SURF_CONVEYOR BIT( 6 ) // scrolled texture (was SURF_DRAWBACKGROUND)
|
||||
#define SURF_UNDERWATER BIT( 7 ) // caustics
|
||||
#define SURF_TRANSPARENT BIT( 8 ) // it's a transparent texture (was SURF_DONTWARP)
|
||||
#define SURF_PLANEBACK BIT( 1 ) // plane should be negated
|
||||
#define SURF_DRAWSKY BIT( 2 ) // sky surface
|
||||
#define SURF_DRAWTURB_QUADS BIT( 3 ) // all subidivided polygons are quads
|
||||
#define SURF_DRAWTURB BIT( 4 ) // warp surface
|
||||
#define SURF_DRAWTILED BIT( 5 ) // face without lighmap
|
||||
#define SURF_CONVEYOR BIT( 6 ) // scrolled texture (was SURF_DRAWBACKGROUND)
|
||||
#define SURF_UNDERWATER BIT( 7 ) // caustics
|
||||
#define SURF_TRANSPARENT BIT( 8 ) // it's a transparent texture (was SURF_DONTWARP)
|
||||
|
||||
// lightstyle management
|
||||
#define LM_STYLES 4 // MAXLIGHTMAPS
|
||||
#define LS_NORMAL 0x00
|
||||
#define LS_UNUSED 0xFE
|
||||
#define LS_NONE 0xFF
|
||||
#define LM_STYLES 4 // MAXLIGHTMAPS
|
||||
#define LS_NORMAL 0x00
|
||||
#define LS_UNUSED 0xFE
|
||||
#define LS_NONE 0xFF
|
||||
|
||||
#define MAX_MAP_CLIPNODES_HLBSP 32767
|
||||
#define MAX_MAP_CLIPNODES_BSP2 524288
|
||||
|
||||
// these limis not using by modelloader but only for displaying 'mapstats' correctly
|
||||
#define MAX_MAP_MODELS 2048 // embedded models
|
||||
#define MAX_MAP_ENTSTRING 0x200000 // 2 Mb should be enough
|
||||
#define MAX_MAP_PLANES 131072 // can be increased without problems
|
||||
#define MAX_MAP_NODES 262144 // can be increased without problems
|
||||
#define MAX_MAP_CLIPNODES MAX_MAP_CLIPNODES_BSP2 // can be increased without problems
|
||||
#define MAX_MAP_LEAFS 131072 // CRITICAL STUFF to run ad_sepulcher!!!
|
||||
#define MAX_MAP_VERTS 524288 // can be increased without problems
|
||||
#define MAX_MAP_FACES 262144 // can be increased without problems
|
||||
#define MAX_MAP_MARKSURFACES 524288 // can be increased without problems
|
||||
#define MAX_MAP_MODELS 2048 // embedded models
|
||||
#define MAX_MAP_ENTSTRING 0x200000 // 2 Mb should be enough
|
||||
#define MAX_MAP_PLANES 131072 // can be increased without problems
|
||||
#define MAX_MAP_NODES 262144 // can be increased without problems
|
||||
#define MAX_MAP_CLIPNODES MAX_MAP_CLIPNODES_BSP2 // can be increased without problems
|
||||
#define MAX_MAP_LEAFS 131072 // CRITICAL STUFF to run ad_sepulcher!!!
|
||||
#define MAX_MAP_VERTS 524288 // can be increased without problems
|
||||
#define MAX_MAP_FACES 262144 // can be increased without problems
|
||||
#define MAX_MAP_MARKSURFACES 524288 // can be increased without problems
|
||||
|
||||
#define MAX_MAP_ENTITIES 8192 // network limit
|
||||
#define MAX_MAP_TEXINFO MAX_MAP_FACES // in theory each face may have personal texinfo
|
||||
#define MAX_MAP_EDGES 0x100000 // can be increased but not needed
|
||||
#define MAX_MAP_SURFEDGES 0x200000 // can be increased but not needed
|
||||
#define MAX_MAP_TEXTURES 2048 // can be increased but not needed
|
||||
#define MAX_MAP_MIPTEX 0x2000000 // 32 Mb internal textures data
|
||||
#define MAX_MAP_LIGHTING 0x2000000 // 32 Mb lightmap raw data (can contain deluxemaps)
|
||||
#define MAX_MAP_VISIBILITY 0x1000000 // 16 Mb visdata
|
||||
#define MAX_MAP_FACEINFO 8192 // can be increased but not needed
|
||||
#define MAX_MAP_ENTITIES 8192 // network limit
|
||||
#define MAX_MAP_TEXINFO MAX_MAP_FACES // in theory each face may have personal texinfo
|
||||
#define MAX_MAP_EDGES 0x100000 // can be increased but not needs
|
||||
#define MAX_MAP_SURFEDGES 0x200000 // can be increased but not needs
|
||||
#define MAX_MAP_TEXTURES 2048 // can be increased but not needs
|
||||
#define MAX_MAP_MIPTEX 0x2000000 // 32 Mb internal textures data
|
||||
#define MAX_MAP_LIGHTING 0x2000000 // 32 Mb lightmap raw data (can contain deluxemaps)
|
||||
#define MAX_MAP_VISIBILITY 0x1000000 // 16 Mb visdata
|
||||
#define MAX_MAP_FACEINFO 8192 // can be increased but not needs
|
||||
|
||||
// quake lump ordering
|
||||
enum
|
||||
{
|
||||
LUMP_ENTITIES = 0,
|
||||
LUMP_PLANES = 1,
|
||||
LUMP_TEXTURES = 2, // internal textures
|
||||
LUMP_VERTEXES = 3,
|
||||
LUMP_VISIBILITY = 4,
|
||||
LUMP_NODES = 5,
|
||||
LUMP_TEXINFO = 6,
|
||||
LUMP_FACES = 7,
|
||||
LUMP_LIGHTING = 8,
|
||||
LUMP_CLIPNODES = 9,
|
||||
LUMP_LEAFS = 10,
|
||||
LUMP_MARKSURFACES = 11,
|
||||
LUMP_EDGES = 12,
|
||||
LUMP_SURFEDGES = 13,
|
||||
LUMP_MODELS = 14, // internal submodels
|
||||
HEADER_LUMPS = 15,
|
||||
};
|
||||
#define LUMP_ENTITIES 0
|
||||
#define LUMP_PLANES 1
|
||||
#define LUMP_TEXTURES 2 // internal textures
|
||||
#define LUMP_VERTEXES 3
|
||||
#define LUMP_VISIBILITY 4
|
||||
#define LUMP_NODES 5
|
||||
#define LUMP_TEXINFO 6
|
||||
#define LUMP_FACES 7
|
||||
#define LUMP_LIGHTING 8
|
||||
#define LUMP_CLIPNODES 9
|
||||
#define LUMP_LEAFS 10
|
||||
#define LUMP_MARKSURFACES 11
|
||||
#define LUMP_EDGES 12
|
||||
#define LUMP_SURFEDGES 13
|
||||
#define LUMP_MODELS 14 // internal submodels
|
||||
#define HEADER_LUMPS 15
|
||||
|
||||
// extra lump ordering
|
||||
enum
|
||||
{
|
||||
LUMP_LIGHTVECS = 0, // deluxemap data
|
||||
LUMP_FACEINFO = 1, // landscape and lightmap resolution info
|
||||
LUMP_CUBEMAPS = 2, // cubemap description
|
||||
LUMP_VERTNORMALS = 3, // phong shaded vertex normals
|
||||
LUMP_LEAF_LIGHTING = 4, // store vertex lighting for statics
|
||||
LUMP_WORLDLIGHTS = 5, // list of all the virtual and real lights (used to relight models in-game)
|
||||
LUMP_COLLISION = 6, // physics engine collision hull dump (userdata)
|
||||
LUMP_AINODEGRAPH = 7, // node graph that stored into the bsp (userdata)
|
||||
LUMP_SHADOWMAP = 8, // contains shadow map for direct light
|
||||
LUMP_VERTEX_LIGHT = 9, // store vertex lighting for statics
|
||||
LUMP_UNUSED0 = 10, // one lump reserved for me
|
||||
LUMP_UNUSED1 = 11, // one lump reserved for me
|
||||
EXTRA_LUMPS = 12, // count of the extra lumps
|
||||
};
|
||||
#define LUMP_LIGHTVECS 0 // deluxemap data
|
||||
#define LUMP_FACEINFO 1 // landscape and lightmap resolution info
|
||||
#define LUMP_CUBEMAPS 2 // cubemap description
|
||||
#define LUMP_VERTNORMALS 3 // phong shaded vertex normals
|
||||
#define LUMP_LEAF_LIGHTING 4 // store vertex lighting for statics
|
||||
#define LUMP_WORLDLIGHTS 5 // list of all the virtual and real lights (used to relight models in-game)
|
||||
#define LUMP_COLLISION 6 // physics engine collision hull dump (userdata)
|
||||
#define LUMP_AINODEGRAPH 7 // node graph that stored into the bsp (userdata)
|
||||
#define LUMP_SHADOWMAP 8 // contains shadow map for direct light
|
||||
#define LUMP_VERTEX_LIGHT 9 // store vertex lighting for statics
|
||||
#define LUMP_UNUSED0 10 // one lump reserved for me
|
||||
#define LUMP_UNUSED1 11 // one lump reserved for me
|
||||
#define EXTRA_LUMPS 12 // count of the extra lumps
|
||||
|
||||
// texture flags
|
||||
#define TEX_SPECIAL BIT( 0 ) // sky or slime, no lightmap or 256 subdivision
|
||||
#define TEX_WORLD_LUXELS BIT( 1 ) // alternative lightmap matrix will be used (luxels per world units instead of luxels per texels)
|
||||
#define TEX_AXIAL_LUXELS BIT( 2 ) // force world luxels to axial positive scales
|
||||
#define TEX_EXTRA_LIGHTMAP BIT( 3 ) // bsp31 legacy - using 8 texels per luxel instead of 16 texels per luxel
|
||||
#define TEX_SCROLL BIT( 6 ) // Doom special FX
|
||||
#define TEX_SPECIAL BIT( 0 ) // sky or slime, no lightmap or 256 subdivision
|
||||
#define TEX_WORLD_LUXELS BIT( 1 ) // alternative lightmap matrix will be used (luxels per world units instead of luxels per texels)
|
||||
#define TEX_AXIAL_LUXELS BIT( 2 ) // force world luxels to axial positive scales
|
||||
#define TEX_EXTRA_LIGHTMAP BIT( 3 ) // bsp31 legacy - using 8 texels per luxel instead of 16 texels per luxel
|
||||
#define TEX_SCROLL BIT( 6 ) // Doom special FX
|
||||
|
||||
#define IsLiquidContents( cnt ) ( cnt == CONTENTS_WATER || cnt == CONTENTS_SLIME || cnt == CONTENTS_LAVA )
|
||||
|
||||
// ambient sound types
|
||||
enum
|
||||
{
|
||||
AMBIENT_WATER = 0, // waterfall
|
||||
AMBIENT_SKY, // wind
|
||||
AMBIENT_SLIME, // never used in quake
|
||||
AMBIENT_LAVA, // never used in quake
|
||||
NUM_AMBIENTS, // automatic ambient sounds
|
||||
AMBIENT_WATER = 0, // waterfall
|
||||
AMBIENT_SKY, // wind
|
||||
AMBIENT_SLIME, // never used in quake
|
||||
AMBIENT_LAVA, // never used in quake
|
||||
NUM_AMBIENTS, // automatic ambient sounds
|
||||
};
|
||||
|
||||
//
|
||||
// BSP File Structures
|
||||
//
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t fileofs;
|
||||
int32_t filelen;
|
||||
int fileofs;
|
||||
int filelen;
|
||||
} dlump_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t version;
|
||||
dlump_t lumps[HEADER_LUMPS];
|
||||
int version;
|
||||
dlump_t lumps[HEADER_LUMPS];
|
||||
} dheader_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t id; // must be little endian XASH
|
||||
int32_t version;
|
||||
dlump_t lumps[EXTRA_LUMPS];
|
||||
int id; // must be little endian XASH
|
||||
int version;
|
||||
dlump_t lumps[EXTRA_LUMPS];
|
||||
} dextrahdr_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char lumpname[24]; // up to 23 chars, zero-padded
|
||||
int32_t fileofs;
|
||||
int32_t filelen;
|
||||
} dbspx_lump_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t id; // must be little endian BSPX
|
||||
int32_t numlumps;
|
||||
dbspx_lump_t lumps[];
|
||||
} dbspx_hdr_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
vec3_t origin; // for sounds or lights
|
||||
int32_t headnode[MAX_MAP_HULLS];
|
||||
int32_t visleafs; // not including the solid leaf 0
|
||||
int32_t firstface;
|
||||
int32_t numfaces;
|
||||
vec3_t mins;
|
||||
vec3_t maxs;
|
||||
vec3_t origin; // for sounds or lights
|
||||
int headnode[MAX_MAP_HULLS];
|
||||
int visleafs; // not including the solid leaf 0
|
||||
int firstface;
|
||||
int numfaces;
|
||||
} dmodel_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t nummiptex;
|
||||
int32_t dataofs[4]; // [nummiptex]
|
||||
int nummiptex;
|
||||
int dataofs[4]; // [nummiptex]
|
||||
} dmiptexlump_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t point;
|
||||
vec3_t point;
|
||||
} dvertex_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
int32_t type; // PLANE_X - PLANE_ANYZ ?
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
int type; // PLANE_X - PLANE_ANYZ ?
|
||||
} dplane_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t planenum;
|
||||
int16_t children[2]; // negative numbers are -(leafs + 1), not nodes
|
||||
int16_t mins[3]; // for sphere culling
|
||||
int16_t maxs[3];
|
||||
uint16_t firstface;
|
||||
uint16_t numfaces; // counting both sides
|
||||
int planenum;
|
||||
short children[2]; // negative numbers are -(leafs + 1), not nodes
|
||||
short mins[3]; // for sphere culling
|
||||
short maxs[3];
|
||||
word firstface;
|
||||
word numfaces; // counting both sides
|
||||
} dnode_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t planenum;
|
||||
int32_t children[2]; // negative numbers are -(leafs+1), not nodes
|
||||
float mins[3]; // for sphere culling
|
||||
float maxs[3];
|
||||
int32_t firstface;
|
||||
int32_t numfaces; // counting both sides
|
||||
int planenum;
|
||||
int children[2]; // negative numbers are -(leafs+1), not nodes
|
||||
float mins[3]; // for sphere culling
|
||||
float maxs[3];
|
||||
int firstface;
|
||||
int numfaces; // counting both sides
|
||||
} dnode32_t;
|
||||
|
||||
// leaf 0 is the generic CONTENTS_SOLID leaf, used for all solid areas
|
||||
// all other leafs need visibility info
|
||||
typedef struct
|
||||
{
|
||||
int32_t contents;
|
||||
int32_t visofs; // -1 = no visibility info
|
||||
int contents;
|
||||
int visofs; // -1 = no visibility info
|
||||
|
||||
int16_t mins[3]; // for frustum culling
|
||||
int16_t maxs[3];
|
||||
uint16_t firstmarksurface;
|
||||
uint16_t nummarksurfaces;
|
||||
short mins[3]; // for frustum culling
|
||||
short maxs[3];
|
||||
word firstmarksurface;
|
||||
word nummarksurfaces;
|
||||
|
||||
// automatic ambient sounds
|
||||
uint8_t ambient_level[NUM_AMBIENTS]; // ambient sound level (0 - 255)
|
||||
byte ambient_level[NUM_AMBIENTS]; // ambient sound level (0 - 255)
|
||||
} dleaf_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t contents;
|
||||
int32_t visofs; // -1 = no visibility info
|
||||
int contents;
|
||||
int visofs; // -1 = no visibility info
|
||||
|
||||
float mins[3]; // for frustum culling
|
||||
float maxs[3];
|
||||
float mins[3]; // for frustum culling
|
||||
float maxs[3];
|
||||
|
||||
int32_t firstmarksurface;
|
||||
int32_t nummarksurfaces;
|
||||
int firstmarksurface;
|
||||
int nummarksurfaces;
|
||||
|
||||
uint8_t ambient_level[NUM_AMBIENTS];
|
||||
byte ambient_level[NUM_AMBIENTS];
|
||||
} dleaf32_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t planenum;
|
||||
int16_t children[2]; // negative numbers are contents
|
||||
int planenum;
|
||||
short children[2]; // negative numbers are contents
|
||||
} dclipnode_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t planenum;
|
||||
int32_t children[2]; // negative numbers are contents
|
||||
int planenum;
|
||||
int children[2]; // negative numbers are contents
|
||||
} dclipnode32_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float vecs[2][4]; // texmatrix [s/t][xyz offset]
|
||||
int32_t miptex;
|
||||
int16_t flags;
|
||||
int16_t faceinfo; // -1 no face info otherwise dfaceinfo_t
|
||||
float vecs[2][4]; // texmatrix [s/t][xyz offset]
|
||||
int miptex;
|
||||
short flags;
|
||||
short faceinfo; // -1 no face info otherwise dfaceinfo_t
|
||||
} dtexinfo_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char landname[16]; // name of decsription in mapname_land.txt
|
||||
uint16_t texture_step; // default is 16, pixels\luxels ratio
|
||||
uint16_t max_extent; // default is 16, subdivision step ((texture_step * max_extent) - texture_step)
|
||||
int16_t groupid; // to determine equal landscapes from various groups, -1 - no group
|
||||
char landname[16]; // name of decsription in mapname_land.txt
|
||||
unsigned short texture_step; // default is 16, pixels\luxels ratio
|
||||
unsigned short max_extent; // default is 16, subdivision step ((texture_step * max_extent) - texture_step)
|
||||
short groupid; // to determine equal landscapes from various groups, -1 - no group
|
||||
} dfaceinfo_t;
|
||||
|
||||
typedef uint16_t dmarkface_t; // leaf marksurfaces indexes
|
||||
typedef int32_t dmarkface32_t; // leaf marksurfaces indexes
|
||||
typedef word dmarkface_t; // leaf marksurfaces indexes
|
||||
typedef int dmarkface32_t; // leaf marksurfaces indexes
|
||||
|
||||
typedef int32_t dsurfedge_t; // map surfedges
|
||||
typedef int dsurfedge_t; // map surfedges
|
||||
|
||||
// NOTE: that edge 0 is never used, because negative edge nums
|
||||
// are used for counterclockwise use of the edge in a face
|
||||
typedef struct
|
||||
{
|
||||
uint16_t v[2]; // vertex numbers
|
||||
word v[2]; // vertex numbers
|
||||
} dedge_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t v[2]; // vertex numbers
|
||||
int v[2]; // vertex numbers
|
||||
} dedge32_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t planenum;
|
||||
int16_t side;
|
||||
word planenum;
|
||||
short side;
|
||||
|
||||
int32_t firstedge; // we must support > 64k edges
|
||||
int16_t numedges;
|
||||
int16_t texinfo;
|
||||
int firstedge; // we must support > 64k edges
|
||||
short numedges;
|
||||
short texinfo;
|
||||
|
||||
// lighting info
|
||||
uint8_t styles[LM_STYLES];
|
||||
int32_t lightofs; // start of [numstyles*surfsize] samples
|
||||
byte styles[LM_STYLES];
|
||||
int lightofs; // start of [numstyles*surfsize] samples
|
||||
} dface_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t planenum;
|
||||
int32_t side;
|
||||
int planenum;
|
||||
int side;
|
||||
|
||||
int32_t firstedge; // we must support > 64k edges
|
||||
int32_t numedges;
|
||||
int32_t texinfo;
|
||||
int firstedge; // we must support > 64k edges
|
||||
int numedges;
|
||||
int texinfo;
|
||||
|
||||
// lighting info
|
||||
uint8_t styles[LM_STYLES];
|
||||
int32_t lightofs; // start of [numstyles*surfsize] samples
|
||||
byte styles[LM_STYLES];
|
||||
int lightofs; // start of [numstyles*surfsize] samples
|
||||
} dface32_t;
|
||||
|
||||
#endif // BSPFILE_H
|
||||
#endif//BSPFILE_H
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
#ifndef CL_ENTITY_H
|
||||
#define CL_ENTITY_H
|
||||
|
||||
#include "const.h"
|
||||
|
||||
typedef struct efrag_s
|
||||
{
|
||||
struct mleaf_s *leaf;
|
||||
|
||||
@@ -1,23 +1,4 @@
|
||||
/*
|
||||
com_image.h - image definitions common between client and server
|
||||
Copyright (C) 2007 Uncle Mike
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef COM_IMAGE_H
|
||||
#define COM_IMAGE_H
|
||||
|
||||
#include "xash3d_types.h"
|
||||
|
||||
#pragma once
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
@@ -27,9 +8,21 @@ typically expanded to rgba buffer
|
||||
NOTE: number at end of pixelformat name it's a total bitscount e.g. PF_RGB_24 == PF_RGB_888
|
||||
========================================================================
|
||||
*/
|
||||
#define ImageRAW( type ) ( type >= PF_RGBA_32 && type <= PF_LUMINANCE )
|
||||
#define ImageCompressed( type ) ( type >= PF_DXT1 && type <= PF_KTX2_RAW )
|
||||
#define ImageBigEndian( type ) ( type == PF_BGRA_32 || type == PF_BGR_24 )
|
||||
#define ImageRAW( type ) (type == PF_RGBA_32 || type == PF_BGRA_32 || type == PF_RGB_24 || type == PF_BGR_24 || type == PF_LUMINANCE)
|
||||
#define ImageCompressed( type ) \
|
||||
( type == PF_DXT1 \
|
||||
|| type == PF_DXT3 \
|
||||
|| type == PF_DXT5 \
|
||||
|| type == PF_ATI2 \
|
||||
|| type == PF_BC4_SIGNED \
|
||||
|| type == PF_BC4_UNSIGNED \
|
||||
|| type == PF_BC5_SIGNED \
|
||||
|| type == PF_BC5_UNSIGNED \
|
||||
|| type == PF_BC6H_SIGNED \
|
||||
|| type == PF_BC6H_UNSIGNED \
|
||||
|| type == PF_BC7_UNORM \
|
||||
|| type == PF_BC7_SRGB \
|
||||
|| type == PF_KTX2_RAW )
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -57,20 +50,11 @@ typedef enum
|
||||
PF_TOTALCOUNT, // must be last
|
||||
} pixformat_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RF_COMPRESSED,
|
||||
RF_RGBA,
|
||||
RF_BGRA,
|
||||
RF_BGR,
|
||||
RF_LUMINANCE
|
||||
} rawformat_t;
|
||||
|
||||
typedef struct bpc_desc_s
|
||||
{
|
||||
int format; // pixelformat
|
||||
char name[16]; // used for debug
|
||||
rawformat_t rawformat;
|
||||
uint glFormat; // RGBA format
|
||||
int bpp; // channels (e.g. rgb = 3, rgba = 4)
|
||||
} bpc_desc_t;
|
||||
|
||||
@@ -86,8 +70,6 @@ typedef enum
|
||||
IL_OVERVIEW = BIT(6), // overview required some unque operations
|
||||
IL_LOAD_PLAYER_DECAL = BIT(7), // special mode for player decals
|
||||
IL_KTX2_RAW = BIT(8), // renderer can consume raw KTX2 files (e.g. ref_vk)
|
||||
IL_ALLOW_WAD3_LUMA = BIT(9), // allow usage of luma textures in wad3 (tilde textures)
|
||||
IL_HOST_ENDIAN = BIT(10), // buffer is already in host endian, skip byte-swapping
|
||||
} ilFlags_t;
|
||||
|
||||
// goes into rgbdata_t->encode
|
||||
@@ -117,8 +99,6 @@ typedef enum
|
||||
IMAGE_MULTILAYER = BIT(8), // to differentiate from 3D texture
|
||||
IMAGE_ONEBIT_ALPHA = BIT(9), // binary alpha
|
||||
IMAGE_QUAKEPAL = BIT(10), // image has quake1 palette
|
||||
IMAGE_PREMULTIPLIED = BIT(11),
|
||||
IMAGE_PLAYERDECAL = BIT(12), // loaded with IL_LOAD_PLAYER_DECAL (custom player spray)
|
||||
|
||||
// Image_Process manipulation flags
|
||||
IMAGE_FLIP_X = BIT(16), // flip the image by width
|
||||
@@ -152,4 +132,3 @@ typedef struct rgbdata_s
|
||||
size_t size; // for bounds checking
|
||||
} rgbdata_t;
|
||||
|
||||
#endif//COM_IMAGE_H
|
||||
|
||||
@@ -16,11 +16,9 @@ GNU General Public License for more details.
|
||||
#ifndef COM_MODEL_H
|
||||
#define COM_MODEL_H
|
||||
|
||||
#include "const.h"
|
||||
#include "xash3d_types.h"
|
||||
#include "bspfile.h" // we need some declarations from it
|
||||
|
||||
#include "xash3d_mathlib.h" // mplane_t
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
@@ -48,6 +46,15 @@ typedef enum
|
||||
mod_studio
|
||||
} modtype_t;
|
||||
|
||||
typedef struct mplane_s
|
||||
{
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
byte type; // for fast side tests
|
||||
byte signbits; // signx + (signy<<1) + (signz<<1)
|
||||
byte pad[2];
|
||||
} mplane_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t position;
|
||||
@@ -612,9 +619,9 @@ static inline mnode_t *node_child( const mnode_t *n, int side, const model_t *mo
|
||||
}
|
||||
}
|
||||
|
||||
return n->children_[side ? 1 : 0];
|
||||
return n->children_[side];
|
||||
#else
|
||||
return n->children_[side ? 1 : 0];
|
||||
return n->children_[side];
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -723,6 +723,8 @@ enum
|
||||
typedef int func_t;
|
||||
typedef int string_t;
|
||||
|
||||
typedef unsigned short word;
|
||||
|
||||
#include "xash3d_types.h"
|
||||
|
||||
typedef struct
|
||||
@@ -735,6 +737,11 @@ typedef struct
|
||||
unsigned r, g, b, a;
|
||||
} colorVec;
|
||||
|
||||
typedef struct link_s
|
||||
{
|
||||
struct link_s *prev, *next;
|
||||
} link_t;
|
||||
|
||||
typedef struct edict_s edict_t;
|
||||
|
||||
typedef struct
|
||||
|
||||
@@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#ifndef CVAR
|
||||
#define CVAR
|
||||
|
||||
#include <stdint.h>
|
||||
#include STDINT_H
|
||||
#include "xash3d_types.h"
|
||||
|
||||
/*
|
||||
|
||||
@@ -26,44 +26,68 @@ SETUP BACKENDS DEFINITIONS
|
||||
|
||||
===================================================================
|
||||
*/
|
||||
//
|
||||
// when compiling client, we need to pick video, audio and input implementations
|
||||
//
|
||||
#if !XASH_DEDICATED // when compiling client, we need to pick video, audio and input implementations
|
||||
#if XASH_SDL // we are building with SDL
|
||||
#define XASH_VIDEO VIDEO_SDL
|
||||
#define XASH_INPUT INPUT_SDL
|
||||
#define XASH_SOUND SOUND_SDL
|
||||
#elif XASH_LINUX // we are building for Linux without SDL, only framebuffer is supported for now
|
||||
#define XASH_VIDEO VIDEO_FBDEV
|
||||
#define XASH_INPUT INPUT_EVDEV
|
||||
#define XASH_SOUND SOUND_ALSA
|
||||
#if !XASH_DEDICATED
|
||||
#if XASH_SDL
|
||||
// we are building using libSDL
|
||||
#ifndef XASH_VIDEO
|
||||
#define XASH_VIDEO VIDEO_SDL
|
||||
#endif // XASH_VIDEO
|
||||
|
||||
#ifndef XASH_INPUT
|
||||
#define XASH_INPUT INPUT_SDL
|
||||
#endif // XASH_INPUT
|
||||
|
||||
#ifndef XASH_SOUND
|
||||
#define XASH_SOUND SOUND_SDL
|
||||
#endif // XASH_SOUND
|
||||
|
||||
#if XASH_SDL == 2
|
||||
#ifndef XASH_TIMER
|
||||
#define XASH_TIMER TIMER_SDL
|
||||
#endif // XASH_TIMER
|
||||
|
||||
#ifndef XASH_MESSAGEBOX
|
||||
#if !XASH_NSWITCH // SDL2 messageboxes not available
|
||||
#define XASH_MESSAGEBOX MSGBOX_SDL
|
||||
#endif
|
||||
#endif // XASH_MESSAGEBOX
|
||||
#endif
|
||||
#elif XASH_LINUX
|
||||
// we are building for Linux without SDL2, can draw only to framebuffer yet
|
||||
#ifndef XASH_VIDEO
|
||||
#define XASH_VIDEO VIDEO_FBDEV
|
||||
#endif // XASH_VIDEO
|
||||
|
||||
#ifndef XASH_INPUT
|
||||
#define XASH_INPUT INPUT_EVDEV
|
||||
#endif // XASH_INPUT
|
||||
|
||||
#ifndef XASH_SOUND
|
||||
#define XASH_SOUND SOUND_ALSA
|
||||
#endif // XASH_SOUND
|
||||
|
||||
#define XASH_USE_EVDEV 1
|
||||
#elif XASH_DOS4GW
|
||||
#define XASH_VIDEO VIDEO_DOS
|
||||
#define XASH_REDUCE_FD 1 // usually only 10-20 fds available
|
||||
#elif XASH_PSP
|
||||
#define XASH_VIDEO VIDEO_PSP
|
||||
#define XASH_INPUT INPUT_PSP
|
||||
#define XASH_SOUND SOUND_PSP
|
||||
#define XASH_REDUCE_FD 1
|
||||
#define XASH_NO_TOUCH 1
|
||||
#define XASH_NO_ZIP 1
|
||||
#ifndef XASH_VIDEO
|
||||
#define XASH_VIDEO VIDEO_DOS
|
||||
#endif
|
||||
#ifndef XASH_TIMER
|
||||
#define XASH_TIMER TIMER_DOS
|
||||
#endif
|
||||
|
||||
// usually only 10-20 fds availiable
|
||||
#define XASH_REDUCE_FD
|
||||
#endif
|
||||
#endif // !XASH_DEDICATED
|
||||
#endif // XASH_DEDICATED
|
||||
|
||||
//
|
||||
// select messagebox implementation
|
||||
//
|
||||
#ifndef XASH_MESSAGEBOX
|
||||
#if XASH_SDL >= 2 && !XASH_NSWITCH // SDL2 messageboxes are not available on NSW
|
||||
#define XASH_MESSAGEBOX MSGBOX_SDL
|
||||
#elif XASH_WIN32
|
||||
#if XASH_WIN32
|
||||
#define XASH_MESSAGEBOX MSGBOX_WIN32
|
||||
#elif XASH_NSWITCH
|
||||
#define XASH_MESSAGEBOX MSGBOX_NSWITCH
|
||||
#elif XASH_PSP
|
||||
#define XASH_MESSAGEBOX MSGBOX_PSP
|
||||
#else // !XASH_WIN32
|
||||
#define XASH_MESSAGEBOX MSGBOX_STDERR
|
||||
#endif // !XASH_WIN32
|
||||
@@ -73,14 +97,8 @@ SETUP BACKENDS DEFINITIONS
|
||||
// no timer - no xash
|
||||
//
|
||||
#ifndef XASH_TIMER
|
||||
#if XASH_SDL >= 2
|
||||
#define XASH_TIMER TIMER_SDL
|
||||
#elif XASH_WIN32
|
||||
#if XASH_WIN32
|
||||
#define XASH_TIMER TIMER_WIN32
|
||||
#elif XASH_DOS4GW
|
||||
#define XASH_TIMER TIMER_DOS
|
||||
#elif XASH_PSP
|
||||
#define XASH_TIMER TIMER_PSP
|
||||
#else // !XASH_WIN32
|
||||
#define XASH_TIMER TIMER_POSIX
|
||||
#endif // !XASH_WIN32
|
||||
@@ -97,16 +115,14 @@ SETUP BACKENDS DEFINITIONS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if XASH_PSP
|
||||
#define XASH_PSP LIB_PSP
|
||||
#elif defined( XASH_STATIC_LIBS )
|
||||
#define XASH_LIB LIB_STATIC
|
||||
#define XASH_INTERNAL_GAMELIBS
|
||||
#define XASH_ALLOW_SAVERESTORE_OFFSETS
|
||||
#ifdef XASH_STATIC_LIBS
|
||||
#define XASH_LIB LIB_STATIC
|
||||
#define XASH_INTERNAL_GAMELIBS
|
||||
#define XASH_ALLOW_SAVERESTORE_OFFSETS
|
||||
#elif XASH_WIN32
|
||||
#define XASH_LIB LIB_WIN32
|
||||
#define XASH_LIB LIB_WIN32
|
||||
#elif XASH_POSIX
|
||||
#define XASH_LIB LIB_POSIX
|
||||
#define XASH_LIB LIB_POSIX
|
||||
#endif
|
||||
|
||||
//
|
||||
@@ -133,11 +149,7 @@ Default build-depended cvar and constant values
|
||||
*/
|
||||
|
||||
// Platform overrides
|
||||
#if XASH_WIN32
|
||||
// set up windowed by default on Windows to avoid problems with
|
||||
// Xbox Game Bar
|
||||
#define DEFAULT_FULLSCREEN "0"
|
||||
#elif XASH_NSWITCH
|
||||
#if XASH_NSWITCH
|
||||
#define DEFAULT_TOUCH_ENABLE "1"
|
||||
#define DEFAULT_M_IGNORE "1"
|
||||
#define DEFAULT_MODE_WIDTH 1280
|
||||
@@ -156,6 +168,12 @@ Default build-depended cvar and constant values
|
||||
#define DEFAULT_M_IGNORE "1"
|
||||
#endif // !XASH_MOBILE_PLATFORM && !XASH_NSWITCH
|
||||
|
||||
#if XASH_IOS
|
||||
// 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
|
||||
#endif // XASH_IOS
|
||||
|
||||
// Defaults
|
||||
#ifndef DEFAULT_TOUCH_ENABLE
|
||||
#define DEFAULT_TOUCH_ENABLE "0"
|
||||
@@ -178,28 +196,11 @@ Default build-depended cvar and constant values
|
||||
#endif // DEFAULT_ALLOWCONSOLE
|
||||
|
||||
#ifndef DEFAULT_FULLSCREEN
|
||||
#define DEFAULT_FULLSCREEN "2" // must be a string
|
||||
#define DEFAULT_FULLSCREEN "1" // must be a string
|
||||
#endif // DEFAULT_FULLSCREEN
|
||||
|
||||
#ifndef DEFAULT_MAX_EDICTS
|
||||
#define DEFAULT_MAX_EDICTS 1200 // was 900 before HL25
|
||||
#endif // DEFAULT_MAX_EDICTS
|
||||
|
||||
|
||||
#ifndef DEFAULT_ACCELERATED_RENDERER
|
||||
#if XASH_PSP
|
||||
#define DEFAULT_ACCELERATED_RENDERER "gu"
|
||||
#elif XASH_MOBILE_PLATFORM
|
||||
#define DEFAULT_ACCELERATED_RENDERER "gles1"
|
||||
#elif XASH_IOS
|
||||
#define DEFAULT_ACCELERATED_RENDERER "gles2"
|
||||
#else // !XASH_MOBILE_PLATFORM
|
||||
#define DEFAULT_ACCELERATED_RENDERER "gl"
|
||||
#endif // !XASH_MOBILE_PLATFORM
|
||||
#endif // DEFAULT_ACCELERATED_RENDERER
|
||||
|
||||
#ifndef DEFAULT_SOFTWARE_RENDERER
|
||||
#define DEFAULT_SOFTWARE_RENDERER "soft" // mittorn's ref_soft
|
||||
#endif // DEFAULT_SOFTWARE_RENDERER
|
||||
|
||||
#endif // DEFAULTS_H
|
||||
|
||||
31
common/dlight.h
Normal file
31
common/dlight.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
|
||||
#ifndef DLIGHT_H
|
||||
#define DLIGHT_H
|
||||
|
||||
typedef struct dlight_s
|
||||
{
|
||||
vec3_t origin;
|
||||
float radius;
|
||||
color24 color;
|
||||
float die; // stop lighting after this time
|
||||
float decay; // drop this each second
|
||||
float minlight; // don't add when contributing less
|
||||
int key;
|
||||
qboolean dark; // subtracts light instead of adding
|
||||
} dlight_t;
|
||||
|
||||
#endif//DLIGHT_H
|
||||
59
common/hltv.h
Normal file
59
common/hltv.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
|
||||
#ifndef HLTV_H
|
||||
#define HLTV_H
|
||||
|
||||
#define TYPE_CLIENT 0 // client is a normal HL client (default)
|
||||
#define TYPE_PROXY 1 // client is another proxy
|
||||
#define TYPE_COMMENTATOR 3 // client is a commentator
|
||||
#define TYPE_DEMO 4 // client is a demo file
|
||||
|
||||
// sub commands of svc_hltv:
|
||||
#define HLTV_ACTIVE 0 // tells client that he's an spectator and will get director commands
|
||||
#define HLTV_STATUS 1 // send status infos about proxy
|
||||
#define HLTV_LISTEN 2 // tell client to listen to a multicast stream
|
||||
|
||||
// sub commands of svc_director:
|
||||
#define DRC_CMD_NONE 0 // NULL director command
|
||||
#define DRC_CMD_START 1 // start director mode
|
||||
#define DRC_CMD_EVENT 2 // informs about director command
|
||||
#define DRC_CMD_MODE 3 // switches camera modes
|
||||
#define DRC_CMD_CAMERA 4 // sets camera registers
|
||||
#define DRC_CMD_TIMESCALE 5 // sets time scale
|
||||
#define DRC_CMD_MESSAGE 6 // send HUD centerprint
|
||||
#define DRC_CMD_SOUND 7 // plays a particular sound
|
||||
#define DRC_CMD_STATUS 8 // status info about broadcast
|
||||
#define DRC_CMD_BANNER 9 // banner file name for HLTV gui
|
||||
#define DRC_CMD_FADE 10 // send screen fade command
|
||||
#define DRC_CMD_SHAKE 11 // send screen shake command
|
||||
#define DRC_CMD_STUFFTEXT 12 // like the normal svc_stufftext but as director command
|
||||
|
||||
#define DRC_CMD_LAST 12
|
||||
|
||||
// HLTV_EVENT event flags
|
||||
#define DRC_FLAG_PRIO_MASK 0x0F // priorities between 0 and 15 (15 most important)
|
||||
#define DRC_FLAG_SIDE (1<<4) //
|
||||
#define DRC_FLAG_DRAMATIC (1<<5) // is a dramatic scene
|
||||
#define DRC_FLAG_SLOWMOTION (1<<6) // would look good in SloMo
|
||||
#define DRC_FLAG_FACEPLAYER (1<<7) // player is doning something (reload/defuse bomb etc)
|
||||
#define DRC_FLAG_INTRO (1<<8) // is a introduction scene
|
||||
#define DRC_FLAG_FINAL (1<<9) // is a final scene
|
||||
#define DRC_FLAG_NO_RANDOM (1<<10) // don't randomize event data
|
||||
|
||||
#define MAX_DIRECTOR_CMD_PARAMETERS 4
|
||||
#define MAX_DIRECTOR_CMD_STRING 128
|
||||
|
||||
#endif//HLTV_H
|
||||
35
common/kbutton.h
Normal file
35
common/kbutton.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
#ifndef KBUTTON_H
|
||||
#define KBUTTON_H
|
||||
|
||||
// a1ba: copied from WinQuake/client.h
|
||||
//
|
||||
// cl_input
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
int down[2]; // key nums holding it down
|
||||
int state; // low bit is down state
|
||||
} kbutton_t;
|
||||
|
||||
STATIC_CHECK_SIZEOF( kbutton_t, 12, 12 );
|
||||
|
||||
#endif // KBUTTON_H
|
||||
@@ -16,8 +16,6 @@ GNU General Public License for more details.
|
||||
#ifndef LIGHTSTYLE_H
|
||||
#define LIGHTSTYLE_H
|
||||
|
||||
#include "xash3d_types.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char pattern[256];
|
||||
|
||||
95
common/mathlib.h
Normal file
95
common/mathlib.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
// mathlib.h
|
||||
|
||||
#include <math.h>
|
||||
|
||||
typedef float vec_t;
|
||||
typedef vec_t vec2_t[2];
|
||||
typedef vec_t vec3_t[3];
|
||||
typedef vec_t vec4_t[4]; // x,y,z,w
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
|
||||
#endif
|
||||
|
||||
struct mplane_s;
|
||||
|
||||
extern vec3_t vec3_origin;
|
||||
extern int nanmask;
|
||||
|
||||
#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
|
||||
|
||||
#ifndef VECTOR_H
|
||||
#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
|
||||
#endif
|
||||
|
||||
#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}
|
||||
#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];}
|
||||
#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];}
|
||||
#define VectorClear(a) {(a)[0]=0.0;(a)[1]=0.0;(a)[2]=0.0;}
|
||||
|
||||
void VectorMA (const vec3_t veca, float scale, const vec3_t vecb, vec3_t vecc);
|
||||
|
||||
vec_t _DotProduct (vec3_t v1, vec3_t v2);
|
||||
void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out);
|
||||
void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out);
|
||||
void _VectorCopy (vec3_t in, vec3_t out);
|
||||
|
||||
int VectorCompare (const vec3_t v1, const vec3_t v2);
|
||||
float Length (const vec3_t v);
|
||||
void CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross);
|
||||
float VectorNormalize (vec3_t v); // returns vector length
|
||||
void VectorInverse (vec3_t v);
|
||||
void VectorScale (const vec3_t in, vec_t scale, vec3_t out);
|
||||
|
||||
void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]);
|
||||
void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]);
|
||||
|
||||
void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
|
||||
void AngleVectorsTranspose (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
|
||||
#define AngleIVectors AngleVectorsTranspose
|
||||
|
||||
void AngleMatrix (const vec3_t angles, float (*matrix)[4] );
|
||||
void AngleIMatrix (const vec3_t angles, float (*matrix)[4] );
|
||||
void VectorTransform (const vec3_t in1, float in2[3][4], vec3_t out);
|
||||
|
||||
void NormalizeAngles( vec3_t angles );
|
||||
void InterpolateAngles( vec3_t start, vec3_t end, vec3_t output, float frac );
|
||||
float AngleBetweenVectors( const vec3_t v1, const vec3_t v2 );
|
||||
|
||||
void VectorMatrix( vec3_t forward, vec3_t right, vec3_t up);
|
||||
void VectorAngles( const vec3_t forward, vec3_t angles );
|
||||
|
||||
int InvertMatrix( const float * m, float *out );
|
||||
|
||||
int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane);
|
||||
float anglemod(float a);
|
||||
|
||||
#define BOX_ON_PLANE_SIDE(emins, emaxs, p) \
|
||||
(((p)->type < 3)? \
|
||||
( \
|
||||
((p)->dist <= (emins)[(p)->type])? \
|
||||
1 \
|
||||
: \
|
||||
( \
|
||||
((p)->dist >= (emaxs)[(p)->type])?\
|
||||
2 \
|
||||
: \
|
||||
3 \
|
||||
) \
|
||||
) \
|
||||
: \
|
||||
BoxOnPlaneSide( (emins), (emaxs), (p)))
|
||||
@@ -27,7 +27,7 @@
|
||||
// Set this flag for things like broadcast requests, etc. where the engine should not
|
||||
// kill the request hook after receiving the first response
|
||||
#define FNETAPI_MULTIPLE_RESPONSE ( 1<<0 )
|
||||
// 1<<1 is reserved for deprecated xash3d-fwgs extension
|
||||
#define FNETAPI_LEGACY_PROTOCOL ( 1<<1 ) // xash3d-fwgs extension
|
||||
|
||||
struct net_response_s;
|
||||
typedef void (*net_api_response_func_t) ( struct net_response_s *response );
|
||||
|
||||
@@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#ifndef NET_ADR_H
|
||||
#define NET_ADR_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include STDINT_H
|
||||
|
||||
// net.h -- quake's interface to the networking layer
|
||||
// a1ba: copied from Quake-2/qcommon/qcommon.h and modified to support IPv6
|
||||
|
||||
53
common/particledef.h
Normal file
53
common/particledef.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
|
||||
#ifndef PARTICLEDEF_H
|
||||
#define PARTICLEDEF_H
|
||||
|
||||
typedef enum
|
||||
{
|
||||
pt_static,
|
||||
pt_grav,
|
||||
pt_slowgrav,
|
||||
pt_fire,
|
||||
pt_explode,
|
||||
pt_explode2,
|
||||
pt_blob,
|
||||
pt_blob2,
|
||||
pt_vox_slowgrav,
|
||||
pt_vox_grav,
|
||||
pt_clientcustom // Must have callback function specified
|
||||
} ptype_t;
|
||||
|
||||
typedef struct particle_s
|
||||
{
|
||||
vec3_t org;
|
||||
short color;
|
||||
short packedColor;
|
||||
struct particle_s *next;
|
||||
vec3_t vel;
|
||||
float ramp;
|
||||
float die;
|
||||
ptype_t type;
|
||||
void (*deathfunc)( struct particle_s *particle );
|
||||
|
||||
// for pt_clientcusttom, we'll call this function each frame
|
||||
void (*callback)( struct particle_s *particle, float frametime );
|
||||
|
||||
// For deathfunc, etc.
|
||||
unsigned char context;
|
||||
} particle_t;
|
||||
|
||||
#endif//PARTICLEDEF_H
|
||||
@@ -1,86 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 1996-1997 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef QW_PMOVE_H
|
||||
#define QW_PMOVE_H
|
||||
|
||||
// a1ba: from QW's client/pmove.h
|
||||
// and modified to keep binary compatibility with
|
||||
// goldsrc base structs and xash extensions
|
||||
typedef struct pmplane_s
|
||||
{
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
} pmplane_t;
|
||||
|
||||
STATIC_CHECK_SIZEOF( pmplane_t, 16, 16 );
|
||||
|
||||
typedef struct pmtrace_s
|
||||
{
|
||||
qboolean allsolid; // if true, plane is not valid
|
||||
qboolean startsolid; // if true, the initial point was in a solid area
|
||||
qboolean inopen, inwater;
|
||||
float fraction; // time completed, 1.0 = didn't hit anything
|
||||
vec3_t endpos; // final position
|
||||
pmplane_t plane; // surface normal at impact
|
||||
int ent; // entity the surface is on
|
||||
vec3_t deltavelocity;
|
||||
int hitgroup;
|
||||
} pmtrace_t;
|
||||
|
||||
STATIC_CHECK_SIZEOF( pmtrace_t, 68, 68 );
|
||||
|
||||
typedef struct movevars_s
|
||||
{
|
||||
float gravity;
|
||||
float stopspeed;
|
||||
float maxspeed;
|
||||
float spectatormaxspeed;
|
||||
float accelerate;
|
||||
float airaccelerate;
|
||||
float wateraccelerate;
|
||||
float friction;
|
||||
float edgefriction; // goldsrc binary compat
|
||||
float waterfriction;
|
||||
float entgravity;
|
||||
|
||||
// goldsrc additions
|
||||
float bounce;
|
||||
float stepsize;
|
||||
float maxvelocity;
|
||||
float zmax;
|
||||
float waveHeight;
|
||||
qboolean footsteps;
|
||||
char skyName[32];
|
||||
float rollangle;
|
||||
float rollspeed;
|
||||
vec3_t skycolor;
|
||||
vec3_t skyvec;
|
||||
|
||||
// xash extensions
|
||||
int features;
|
||||
int fog_settings;
|
||||
float wateralpha;
|
||||
vec3_t skydir; // unused
|
||||
float skyangle; // unused
|
||||
} movevars_t;
|
||||
|
||||
STATIC_CHECK_SIZEOF( movevars_t, 160, 160 );
|
||||
|
||||
#endif // QW_PMOVE_H
|
||||
41
common/pmtrace.h
Normal file
41
common/pmtrace.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
|
||||
#ifndef PM_TRACE_H
|
||||
#define PM_TRACE_H
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
} pmplane_t;
|
||||
|
||||
typedef struct pmtrace_s pmtrace_t;
|
||||
|
||||
struct pmtrace_s
|
||||
{
|
||||
qboolean allsolid; // if true, plane is not valid
|
||||
qboolean startsolid; // if true, the initial point was in a solid area
|
||||
qboolean inopen, inwater; // End point is in empty space or in water
|
||||
float fraction; // time completed, 1.0 = didn't hit anything
|
||||
vec3_t endpos; // final position
|
||||
pmplane_t plane; // surface normal at impact
|
||||
int ent; // entity at impact
|
||||
vec3_t deltavelocity; // Change in player's velocity caused by impact.
|
||||
// Only run on server.
|
||||
int hitgroup;
|
||||
};
|
||||
|
||||
#endif//PM_TRACE_H
|
||||
114
common/port.h
114
common/port.h
@@ -17,54 +17,76 @@ GNU General Public License for more details.
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
#include "build.h"
|
||||
|
||||
#if !XASH_WIN32
|
||||
#if XASH_APPLE
|
||||
#include <sys/syslimits.h>
|
||||
#define OS_LIB_EXT "dylib"
|
||||
#define OPEN_COMMAND "open"
|
||||
#elif XASH_EMSCRIPTEN
|
||||
#define OS_LIB_EXT "wasm"
|
||||
#define OPEN_COMMAND "???"
|
||||
#else
|
||||
#define OS_LIB_EXT "so"
|
||||
#define OPEN_COMMAND "xdg-open"
|
||||
#endif
|
||||
#define OS_LIB_PREFIX "lib"
|
||||
#define VGUI_SUPPORT_DLL "libvgui_support." OS_LIB_EXT
|
||||
|
||||
// Windows-specific
|
||||
#define __cdecl
|
||||
#define __stdcall
|
||||
#define _inline static inline
|
||||
|
||||
#if XASH_POSIX
|
||||
#include <unistd.h>
|
||||
#if XASH_NSWITCH
|
||||
#define SOLDER_LIBDL_COMPAT
|
||||
#include <solder.h>
|
||||
#elif XASH_PSVITA
|
||||
#define VRTLD_LIBDL_COMPAT
|
||||
#include <vrtld.h>
|
||||
#define O_BINARY 0
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#define HAVE_DUP
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
#define O_TEXT 0
|
||||
#define _mkdir( x ) mkdir( x, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH )
|
||||
#endif
|
||||
|
||||
typedef void* HANDLE;
|
||||
typedef void* HINSTANCE;
|
||||
|
||||
typedef struct tagPOINT
|
||||
{
|
||||
int x, y;
|
||||
} POINT;
|
||||
#else // WIN32
|
||||
#define open _open
|
||||
#define read _read
|
||||
#define alloca _alloca
|
||||
|
||||
#define HSPRITE WINAPI_HSPRITE
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#undef HSPRITE
|
||||
|
||||
#define OS_LIB_PREFIX ""
|
||||
#define OS_LIB_EXT "dll"
|
||||
#define VGUI_SUPPORT_DLL "../vgui_support." OS_LIB_EXT
|
||||
#define HAVE_DUP
|
||||
#endif //WIN32
|
||||
|
||||
#ifndef XASH_LOW_MEMORY
|
||||
#define XASH_LOW_MEMORY 0
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include "build.h"
|
||||
|
||||
#if XASH_POSIX
|
||||
#include <unistd.h>
|
||||
#define OS_LIB_PREFIX "lib"
|
||||
#endif
|
||||
|
||||
#if XASH_APPLE
|
||||
#include <sys/syslimits.h>
|
||||
#define OS_LIB_EXT "dylib"
|
||||
#define OPEN_COMMAND "open"
|
||||
#elif XASH_POSIX
|
||||
#define OS_LIB_EXT "so"
|
||||
#define OPEN_COMMAND "xdg-open"
|
||||
#elif XASH_WIN32
|
||||
#define HSPRITE WINAPI_HSPRITE
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define VC_EXTRALEAN
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif // NOMINMAX
|
||||
|
||||
#include <windows.h>
|
||||
#undef HSPRITE
|
||||
#define open _open
|
||||
#define read _read
|
||||
|
||||
#ifndef alloca
|
||||
#define alloca _alloca
|
||||
#endif // alloca
|
||||
|
||||
#define OS_LIB_PREFIX ""
|
||||
#define OS_LIB_EXT "dll"
|
||||
#define OPEN_COMMAND "open"
|
||||
#elif XASH_PSP
|
||||
#define OS_LIB_EXT "prx"
|
||||
#endif
|
||||
|
||||
#if !XASH_WIN32
|
||||
typedef void *HINSTANCE;
|
||||
typedef struct tagPOINT { int x, y; } POINT; // one nasty function in cdll_int.h needs it
|
||||
#endif // !XASH_WIN32
|
||||
|
||||
#ifndef XASH_LOW_MEMORY
|
||||
#define XASH_LOW_MEMORY 0
|
||||
#endif
|
||||
|
||||
#endif // PORT_H
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// client.h -- primary header for client
|
||||
|
||||
#ifndef QUAKE_CLIENT_H
|
||||
#define QUAKE_CLIENT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "xash3d_types.h"
|
||||
|
||||
// Definitions originally taken from Quake, modified for binary compatibility
|
||||
|
||||
typedef struct usercmd_s
|
||||
{
|
||||
int16_t lerp_msec; // added in HL
|
||||
int8_t msec; // added in QW
|
||||
uint8_t pad1;
|
||||
vec3_t viewangles;
|
||||
|
||||
// intended velocities
|
||||
float forwardmove;
|
||||
float sidemove;
|
||||
float upmove;
|
||||
uint8_t lightlevel;
|
||||
uint8_t pad2;
|
||||
uint16_t buttons; // added in QW
|
||||
uint8_t impulse;
|
||||
|
||||
// added in HL
|
||||
uint8_t weaponselect;
|
||||
uint8_t pad3[2];
|
||||
|
||||
// unused HL impact stuff, left for modders
|
||||
// TODO: document how to use them in delta encoding
|
||||
int32_t reserved[4];
|
||||
} usercmd_t;
|
||||
|
||||
STATIC_CHECK_SIZEOF( usercmd_t, 52, 52 );
|
||||
|
||||
typedef struct dlight_s
|
||||
{
|
||||
vec3_t origin;
|
||||
float radius;
|
||||
struct
|
||||
{
|
||||
uint8_t r, g, b;
|
||||
} color;
|
||||
float die; // stop lighting after this time
|
||||
float decay; // drop this each second
|
||||
float minlight; // don't add when contributing less
|
||||
int key; // so entities can reuse same entry
|
||||
qboolean dark; // subtracts light instead of adding
|
||||
} dlight_t;
|
||||
|
||||
STATIC_CHECK_SIZEOF( dlight_t, 40, 40 );
|
||||
|
||||
//
|
||||
// cl_input
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
int down[2]; // key nums holding it down
|
||||
int state; // low bit is down state
|
||||
} kbutton_t;
|
||||
|
||||
STATIC_CHECK_SIZEOF( kbutton_t, 12, 12 );
|
||||
|
||||
typedef enum {
|
||||
// Quake defined types
|
||||
pt_static, pt_grav, pt_slowgrav, pt_fire, pt_explode, pt_explode2, pt_blob, pt_blob2,
|
||||
|
||||
// added in HL
|
||||
pt_4x_slowgrav, // 4 times faster than pt_slowgrav
|
||||
pt_8x_slowgrav, // 8 times faster than pt_slowgrav
|
||||
pt_custom, // will call think function from particle
|
||||
} ptype_t;
|
||||
|
||||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
typedef struct particle_s
|
||||
{
|
||||
// driver-usable fields
|
||||
vec3_t org;
|
||||
short color; // in HL color is defnied by palette
|
||||
short unused; // not used in hw
|
||||
|
||||
// drivers never touch the following fields
|
||||
struct particle_s *next;
|
||||
vec3_t vel;
|
||||
float ramp;
|
||||
float die;
|
||||
ptype_t type;
|
||||
|
||||
// HL added fields
|
||||
void (*on_die)( struct particle_s *p );
|
||||
void (*think)( struct particle_s *p, float frametime );
|
||||
unsigned char userdata;
|
||||
} particle_t;
|
||||
|
||||
STATIC_CHECK_SIZEOF( particle_t, 56, 72 );
|
||||
|
||||
#endif // QUAKE_CLIENT_H
|
||||
@@ -16,13 +16,23 @@
|
||||
#ifndef R_EFX_H
|
||||
#define R_EFX_H
|
||||
|
||||
// particle_t
|
||||
#if !defined( PARTICLEDEFH )
|
||||
#include "particledef.h"
|
||||
#endif
|
||||
|
||||
// BEAM
|
||||
#if !defined( BEAMDEF_H )
|
||||
#if !defined( BEAMDEFH )
|
||||
#include "beamdef.h"
|
||||
#endif
|
||||
|
||||
// dlight_t
|
||||
#if !defined ( DLIGHTH )
|
||||
#include "dlight.h"
|
||||
#endif
|
||||
|
||||
// cl_entity_t
|
||||
#if !defined( CL_ENTITY_H )
|
||||
#if !defined( CL_ENTITYH )
|
||||
#include "cl_entity.h"
|
||||
#endif
|
||||
|
||||
@@ -104,9 +114,7 @@ typedef struct tempent_s
|
||||
// baseline.angles - angle velocity
|
||||
} TEMPENTITY;
|
||||
|
||||
typedef struct particle_s particle_t;
|
||||
typedef struct efx_api_s efx_api_t;
|
||||
struct dlight_s;
|
||||
|
||||
struct efx_api_s
|
||||
{
|
||||
@@ -174,8 +182,8 @@ struct efx_api_s
|
||||
BEAM *(*R_BeamLightning)( float *start, float *end, int modelIndex, float life, float width, float amplitude, float brightness, float speed );
|
||||
BEAM *(*R_BeamPoints)( float *start, float *end, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b );
|
||||
BEAM *(*R_BeamRing)( int startEnt, int endEnt, int modelIndex, float life, float width, float amplitude, float brightness, float speed, int startFrame, float framerate, float r, float g, float b );
|
||||
struct dlight_s *(*CL_AllocDlight)( int key );
|
||||
struct dlight_s *(*CL_AllocElight)( int key );
|
||||
dlight_t *(*CL_AllocDlight)( int key );
|
||||
dlight_t *(*CL_AllocElight)( int key );
|
||||
TEMPENTITY *(*CL_TempEntAlloc)( const float *org, struct model_s *model );
|
||||
TEMPENTITY *(*CL_TempEntAllocNoModel)( const float *org );
|
||||
TEMPENTITY *(*CL_TempEntAllocHigh)( const float *org, struct model_s *model );
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
#ifndef REF_PARAMS_H
|
||||
#define REF_PARAMS_H
|
||||
|
||||
#include "xash3d_types.h"
|
||||
|
||||
typedef struct ref_params_s
|
||||
{
|
||||
// output
|
||||
|
||||
@@ -16,8 +16,8 @@ GNU General Public License for more details.
|
||||
#ifndef RENDER_API_H
|
||||
#define RENDER_API_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "lightstyle.h"
|
||||
#include "dlight.h"
|
||||
|
||||
#define CL_RENDER_INTERFACE_VERSION 37 // Xash3D 1.0
|
||||
#define MAX_STUDIO_DECALS 4096 // + unused space of BSP decals
|
||||
@@ -101,7 +101,7 @@ typedef enum
|
||||
TF_TEXTURE_3D = (1<<20), // this is GL_TEXTURE_3D
|
||||
TF_ATLAS_PAGE = (1<<21), // bit who indicate lightmap page or deluxemap page
|
||||
TF_ALPHACONTRAST = (1<<22), // special texture mode for A2C
|
||||
TF_PREMULTIPLIED = (1<<23), // RGBA was stored premultiplied (HL gradient / indexalpha)
|
||||
// reserved
|
||||
// reserved
|
||||
TF_IMG_UPLOADED = (1<<25), // this is set for first time when called glTexImage, otherwise it will be call glTexSubImage
|
||||
TF_ARB_FLOAT = (1<<26), // float textures
|
||||
@@ -175,7 +175,6 @@ enum movie_parms_e
|
||||
|
||||
struct movie_state_s;
|
||||
struct ref_viewpass_s;
|
||||
struct dlight_s;
|
||||
|
||||
typedef struct render_api_s
|
||||
{
|
||||
@@ -184,8 +183,8 @@ typedef struct render_api_s
|
||||
void (*GetDetailScaleForTexture)( int texture, float *xScale, float *yScale );
|
||||
void (*GetExtraParmsForTexture)( int texture, byte *red, byte *green, byte *blue, byte *alpha );
|
||||
lightstyle_t* (*GetLightStyle)( int number );
|
||||
struct dlight_s* (*GetDynamicLight)( int number );
|
||||
struct dlight_s* (*GetEntityLight)( int number );
|
||||
dlight_t* (*GetDynamicLight)( int number );
|
||||
dlight_t* (*GetEntityLight)( int number );
|
||||
byte (*LightToTexGamma)( byte color ); // software gamma support
|
||||
float (*GetFrameTime)( void );
|
||||
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
/*
|
||||
sound_api.h - Xash3D extension for client sound interface
|
||||
Copyright (C) 2026 Xash3D FWGS Developers
|
||||
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
#ifndef SOUND_API_H
|
||||
#define SOUND_API_H
|
||||
|
||||
#include "xash3d_types.h"
|
||||
|
||||
// Experimental implementation, backward compatibility is not guaranteed.
|
||||
#define CL_SOUND_INTERFACE_VERSION 1
|
||||
|
||||
#define FL_VOXWORD_IN_CACHE BIT( 0 ) // if set, it was loaded prior and shouldn't be freed
|
||||
|
||||
#define FL_CHAN_USE_LOOP BIT( 0 ) // don't loop default and local sounds
|
||||
#define FL_CHAN_STATIC_SOUND BIT( 1 ) // use origin instead of fetching entnum's origin
|
||||
#define FL_CHAN_LOCAL_SOUND BIT( 2 ) // it's a local menu sound (not looped, not paused)
|
||||
#define FL_CHAN_SENTENCE_FINISHED BIT( 4 ) // if set, finished playing sentence
|
||||
#define FL_CHAN_FINISHED BIT( 5 ) // if set, finished playing single word
|
||||
|
||||
typedef int sound_t;
|
||||
|
||||
typedef struct portable_samplepair_s
|
||||
{
|
||||
int left;
|
||||
int right;
|
||||
} portable_samplepair_t;
|
||||
|
||||
typedef struct sfx_s
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
wavdata_t *cache;
|
||||
|
||||
int servercount;
|
||||
uint hashValue;
|
||||
struct sfx_s *hashNext;
|
||||
} sfx_t;
|
||||
|
||||
typedef struct voxword_s
|
||||
{
|
||||
sfx_t *sfx;
|
||||
uint16_t volume; // volume percent
|
||||
uint16_t pitch; // pitch shift percent (keep large for extra chipmunk fun)
|
||||
uint8_t timecompress; // percent of skipped data (speeds up playback without pitch shift)
|
||||
uint8_t start; // percent at which playback starts
|
||||
uint8_t end; // percent at which playback ends
|
||||
uint8_t flags;
|
||||
} voxword_t;
|
||||
|
||||
typedef struct channel_s
|
||||
{
|
||||
char name[16]; // keep sentence name
|
||||
sfx_t *sfx; // sfx number
|
||||
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
float dist_mult; // distance multiplier (attenuation/clipK)
|
||||
|
||||
int entchannel; // sound channel (CHAN_STREAM, CHAN_VOICE, etc.)
|
||||
uint flags;
|
||||
short entnum; // entity soundsource
|
||||
short master_vol; // 0-255 master volume
|
||||
short leftvol; // 0-255 left volume
|
||||
short rightvol; // 0-255 right volume
|
||||
short basePitch; // base pitch percent (100% is normal pitch playback)
|
||||
byte word_index;
|
||||
|
||||
// HACKHACK: count when this channel became inaudible
|
||||
// to not free it when it could be respatialized soon
|
||||
#define MAX_CHANNEL_INAUDIBLE_TIME 0.1f
|
||||
float inauduble_free_time;
|
||||
|
||||
double sample;
|
||||
double forced_end;
|
||||
wavdata_t *data;
|
||||
voxword_t *words; // dynamically allocated, (num_words + 1) entries, null sfx terminates
|
||||
|
||||
uintptr_t engine_reserved[8]; // only for engine developers
|
||||
uintptr_t game_reserved[8]; // free space for game developers
|
||||
} channel_t;
|
||||
|
||||
typedef struct rawchan_s
|
||||
{
|
||||
short entnum;
|
||||
short master_vol;
|
||||
short leftvol; // 0-255 left volume
|
||||
short rightvol; // 0-255 right volume
|
||||
float dist_mult; // distance multiplier (attenuation/clipK)
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
volatile uint s_rawend;
|
||||
float oldtime; // catch time jumps
|
||||
|
||||
uintptr_t engine_reserved[8]; // only for engine developers
|
||||
uintptr_t game_reserved[8]; // free space for game developers
|
||||
|
||||
size_t max_samples; // buffer length
|
||||
portable_samplepair_t rawsamples[]; // variable sized
|
||||
} rawchan_t;
|
||||
|
||||
typedef struct snd_format_s
|
||||
{
|
||||
uint speed;
|
||||
byte width;
|
||||
byte channels;
|
||||
} snd_format_t;
|
||||
|
||||
typedef struct snd_globals_s
|
||||
{
|
||||
// dma
|
||||
const char *backend_name;
|
||||
byte *buffer;
|
||||
snd_format_t format;
|
||||
qboolean initialized; // sound engine is active
|
||||
int samples; // mono samples in buffer
|
||||
int samplepos; // in mono samples
|
||||
|
||||
int paintedtime; // total samples that have been mixed at speed
|
||||
int soundtime; // total samples that have been played out to hardware at dma speed
|
||||
|
||||
// listener (client, camera, etc)
|
||||
vec3_t origin;
|
||||
vec3_t forward, right, up;
|
||||
int entnum;
|
||||
qboolean streaming; // playing AVI-file
|
||||
qboolean stream_paused; // pause only background track
|
||||
|
||||
// SoundAPI shared pointers
|
||||
channel_t *const channels;
|
||||
int max_channels;
|
||||
int total_channels;
|
||||
rawchan_t **const raw_channels;
|
||||
int max_raw_channels;
|
||||
sound_t ambient_sfx[NUM_AMBIENTS];
|
||||
qboolean have_ambient_sfx;
|
||||
} snd_globals_t;
|
||||
|
||||
typedef struct voice_audio_info_s
|
||||
{
|
||||
uint width;
|
||||
uint samplerate;
|
||||
uint frame_size; // in samples
|
||||
} voice_audio_info_t;
|
||||
|
||||
// API from engine to client (client calls these)
|
||||
typedef struct sound_api_s
|
||||
{
|
||||
qboolean (*CL_GetEntitySpatialization)( channel_t *ch );
|
||||
sfx_t* (*S_GetSfxByHandle)( sound_t handle );
|
||||
// Voice extensions
|
||||
void (*pfnS_RawEntSamples)( int entnum, uint samples, uint rate, word width, word channels, const byte *data, int snd_vol, float attn );
|
||||
void (*pfnSND_ForceInitMouth)( int entnum );
|
||||
voice_audio_info_t (*pfnVoice_GetAudioInfo)( void );
|
||||
} sound_api_t;
|
||||
|
||||
// Callbacks from client to engine (engine calls these when custom sound is active)
|
||||
typedef struct sound_interface_s
|
||||
{
|
||||
int version;
|
||||
|
||||
qboolean (*pfnS_Init)( snd_globals_t *globals );
|
||||
void (*pfnS_Shutdown)( void );
|
||||
void (*pfnS_UpdateSound)( void );
|
||||
/* Full paint: endtime (sample pairs), dma buffer, paintedtime in/out. Client does mix + transfer to dma.buffer. */
|
||||
void (*pfnS_PaintChannels)( int endtime );
|
||||
void (*pfnS_UpdateChannel)( int ch_idx, const channel_t *ch, sound_t handle ); // ch=NULL -> channel freed
|
||||
void (*pfnS_UpdateRawChannel)( int raw_idx, rawchan_t *ch ); // ch=NULL -> channel freed
|
||||
void (*pfnS_Spatialize)( channel_t *ch );
|
||||
void (*pfnS_FreeSound)( sfx_t *sfx, sound_t handle );
|
||||
} sound_interface_t;
|
||||
|
||||
#endif // SOUND_API_H
|
||||
39
common/usercmd.h
Normal file
39
common/usercmd.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/***
|
||||
*
|
||||
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
||||
*
|
||||
* This product contains software technology licensed from Id
|
||||
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Use, distribution, and modification of this source code and/or resulting
|
||||
* object code is restricted to non-commercial enhancements to products from
|
||||
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||
* without written permission from Valve LLC.
|
||||
*
|
||||
****/
|
||||
|
||||
#ifndef USERCMD_H
|
||||
#define USERCMD_H
|
||||
|
||||
typedef struct usercmd_s
|
||||
{
|
||||
short lerp_msec; // Interpolation time on client
|
||||
byte msec; // Duration in ms of command
|
||||
vec3_t viewangles; // Command view angles
|
||||
|
||||
// intended velocities
|
||||
float forwardmove; // Forward velocity
|
||||
float sidemove; // Sideways velocity
|
||||
float upmove; // Upward velocity
|
||||
byte lightlevel; // Light level at spot where we are standing.
|
||||
unsigned short buttons; // Attack and move buttons
|
||||
byte impulse; // Impulse command issued
|
||||
byte weaponselect; // Current weapon id
|
||||
|
||||
// Experimental player impact stuff.
|
||||
int impact_index;
|
||||
vec3_t impact_position;
|
||||
} usercmd_t;
|
||||
|
||||
#endif//USERCMD_H
|
||||
@@ -2,28 +2,23 @@
|
||||
#ifndef XASH_TYPES_H
|
||||
#define XASH_TYPES_H
|
||||
|
||||
#include <wchar.h> // off_t
|
||||
#include <sys/types.h> // off_t
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include "build.h"
|
||||
#include "port.h"
|
||||
|
||||
#define MAX_STRING 256 // generic string
|
||||
#define MAX_VA_STRING 1024 // compatibility macro
|
||||
#define MAX_SYSPATH 1024 // system filepath
|
||||
#define MAX_OSPATH 260 // max length of a filesystem pathname
|
||||
#define CS_SIZE 64 // size of one config string
|
||||
#define CS_TIME 16 // size of time string
|
||||
|
||||
// platform-specific alignment for types, to not break ABI
|
||||
#if XASH_PSP
|
||||
#define MAYBE_ALIGNED( x ) __attribute__(( aligned( 16 )))
|
||||
#if XASH_IRIX
|
||||
#include <port.h>
|
||||
#endif
|
||||
|
||||
#if !defined( MAYBE_ALIGNED )
|
||||
#define MAYBE_ALIGNED( x )
|
||||
#endif // !defined( MAYBE_ALIGNED )
|
||||
#if XASH_WIN32
|
||||
#include <wchar.h> // off_t
|
||||
#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;
|
||||
@@ -31,30 +26,13 @@ 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] MAYBE_ALIGNED( 16 );
|
||||
typedef vec_t quat_t[4] MAYBE_ALIGNED( 16 );
|
||||
typedef byte rgba_t[4]; // unsigned byte colorpack
|
||||
typedef byte rgb_t[3]; // unsigned byte colorpack
|
||||
typedef vec_t matrix3x4[3][4] MAYBE_ALIGNED( 16 );
|
||||
typedef vec_t matrix4x4[4][4] MAYBE_ALIGNED( 16 );
|
||||
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 uint16_t word;
|
||||
typedef uint32_t dword;
|
||||
typedef char string[MAX_STRING];
|
||||
typedef off_t fs_offset_t;
|
||||
#if XASH_WIN32
|
||||
typedef int fs_size_t; // return type of _read, _write funcs
|
||||
#else // !XASH_WIN32
|
||||
typedef ssize_t fs_size_t;
|
||||
#endif // !XASH_WIN32
|
||||
typedef unsigned int uint;
|
||||
typedef void *(*pfnCreateInterface_t)( const char *, int * );
|
||||
|
||||
// Quake definition
|
||||
typedef struct link_s
|
||||
{
|
||||
struct link_s *prev, *next;
|
||||
} link_t;
|
||||
|
||||
#undef true
|
||||
#undef false
|
||||
@@ -65,77 +43,95 @@ enum { false, true };
|
||||
#endif
|
||||
typedef int qboolean;
|
||||
|
||||
#if XASH_LOW_MEMORY == 1 || XASH_PSP
|
||||
#define MAX_QPATH 48
|
||||
#define MAX_MODS 16
|
||||
#elif XASH_LOW_MEMORY == 2
|
||||
#define MAX_QPATH 32 // should be enough for singleplayer
|
||||
#define MAX_MODS 4
|
||||
#else // !XASH_LOW_MEMORY
|
||||
#define MAX_QPATH 64
|
||||
#define MAX_MODS 512
|
||||
#endif // !XASH_LOW_MEMORY
|
||||
#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
|
||||
|
||||
#define BIT( n ) ( 1U << ( n ))
|
||||
#define BIT64( n ) ( 1ULL << ( n ))
|
||||
#define BIT( n ) ( 1U << ( n ))
|
||||
#define BIT64( n ) ( 1ULL << ( n ))
|
||||
|
||||
#define SetBits( bit_vector, bits ) (( bit_vector ) |= ( bits ))
|
||||
#define ClearBits( bit_vector, bits ) (( bit_vector ) &= ~( bits ))
|
||||
#define FBitSet( bit_vector, bits ) (( bit_vector ) & ( bits ))
|
||||
#define SetBits( iBitVector, bits ) ((iBitVector) = (iBitVector) | (bits))
|
||||
#define ClearBits( iBitVector, bits ) ((iBitVector) = (iBitVector) & ~(bits))
|
||||
#define FBitSet( iBitVector, bit ) ((iBitVector) & (bit))
|
||||
|
||||
#ifndef __cplusplus
|
||||
#ifdef NULL
|
||||
#undef NULL
|
||||
#endif
|
||||
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
// color strings
|
||||
#define IsColorString( p ) (( p ) && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' )
|
||||
#define ColorIndex( c ) ((( c ) - '0' ) & 7 )
|
||||
#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 ))
|
||||
#define GAME_EXPORT __attribute__(( force_align_arg_pointer ))
|
||||
#else // !defined( __i386__ )
|
||||
#define EXPORT __attribute__(( visibility ( "default" )))
|
||||
#endif // !defined( __i386__ )
|
||||
#else
|
||||
#define EXPORT __attribute__(( visibility ( "default" )))
|
||||
#define GAME_EXPORT
|
||||
#endif
|
||||
|
||||
#define MALLOC __attribute__(( malloc ))
|
||||
|
||||
// added in GCC 11
|
||||
#if __GNUC__ >= 11
|
||||
// might want to set noclone due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116893
|
||||
// but it's easier to not force mismatched-dealloc to error yet
|
||||
#define MALLOC_LIKE( x, y ) __attribute__(( malloc( x, y )))
|
||||
#else
|
||||
#define MALLOC_LIKE( x, y ) __attribute__(( malloc ))
|
||||
#endif
|
||||
|
||||
#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 RETURNS_NONNULL
|
||||
#define MALLOC_LIKE( x, y ) MALLOC
|
||||
#endif
|
||||
#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
|
||||
#else
|
||||
#define PFN_RETURNS_NONNULL RETURNS_NONNULL
|
||||
#endif
|
||||
#define FORMAT_CHECK( x ) __attribute__(( format( printf, x, x + 1 )))
|
||||
#define ALLOC_CHECK( x ) __attribute__(( alloc_size( x )))
|
||||
#define NO_ASAN __attribute__(( no_sanitize( "address" )))
|
||||
#define WARN_UNUSED_RESULT __attribute__(( warn_unused_result ))
|
||||
#define RENAME_SYMBOL( x ) asm( x )
|
||||
#if !defined( offsetof )
|
||||
#define offsetof( s, m ) __builtin_offsetof( s, m )
|
||||
#endif // !defined( offsetof )
|
||||
#elif defined( _MSC_VER )
|
||||
#define EXPORT __declspec( dllexport )
|
||||
#else
|
||||
#if defined( _MSC_VER )
|
||||
#define EXPORT __declspec( dllexport )
|
||||
#define NO_ASAN __declspec( no_sanitize_address )
|
||||
#else
|
||||
#define EXPORT
|
||||
#define NO_ASAN
|
||||
#endif
|
||||
#define GAME_EXPORT
|
||||
#define NORETURN
|
||||
#define NONNULL
|
||||
#define RETURNS_NONNULL
|
||||
#define PFN_RETURNS_NONNULL
|
||||
#define FORMAT_CHECK( x )
|
||||
#define ALLOC_CHECK( x )
|
||||
#define RENAME_SYMBOL( x )
|
||||
#define MALLOC
|
||||
#define MALLOC_LIKE( x, y )
|
||||
#define WARN_UNUSED_RESULT
|
||||
#endif
|
||||
|
||||
#ifdef ARRAYSIZE
|
||||
#undef ARRAYSIZE
|
||||
#endif // ARRAYSIZE
|
||||
#if defined( __has_feature )
|
||||
#if __has_feature( address_sanitizer )
|
||||
#define USE_ASAN 1
|
||||
#endif // __has_feature
|
||||
#endif // defined( __has_feature )
|
||||
|
||||
#define ARRAYSIZE( p ) ( sizeof(( p ))/ sizeof(( p )[0] ))
|
||||
|
||||
#if defined( __SANITIZE_ADDRESS__ )
|
||||
#define USE_ASAN 1
|
||||
|
||||
#if defined( __GNUC__ )
|
||||
#define NO_ASAN __attribute__(( no_sanitize( "address" )))
|
||||
#elif defined( _MSC_VER )
|
||||
#define NO_ASAN __declspec( no_sanitize_address )
|
||||
#endif
|
||||
#if !defined( USE_ASAN ) && defined( __SANITIZE_ADDRESS__ )
|
||||
#define USE_ASAN 1
|
||||
#endif
|
||||
|
||||
#if __GNUC__ >= 3
|
||||
@@ -148,73 +144,11 @@ typedef int qboolean;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined( __cplusplus ) && __STDC_VERSION__ >= 199101L // not C++ and C99 or newer
|
||||
#define XASH_RESTRICT restrict
|
||||
#elif _MSC_VER || __GNUC__ || __clang__ // compiler-specific extensions
|
||||
#define XASH_RESTRICT __restrict
|
||||
#endif
|
||||
|
||||
#if !defined( EXPORT )
|
||||
#define EXPORT
|
||||
#endif // !defined( EXPORT )
|
||||
|
||||
#if !defined( GAME_EXPORT )
|
||||
#define GAME_EXPORT
|
||||
#endif // !defined( GAME_EXPORT )
|
||||
|
||||
#if !defined( MALLOC_LIKE )
|
||||
#define MALLOC_LIKE( x, y )
|
||||
#endif // !defined MALLOC_LIKE
|
||||
|
||||
#if !defined( NO_ASAN )
|
||||
#define NO_ASAN
|
||||
#endif // !defined( NO_ASAN )
|
||||
|
||||
#if !defined( RETURNS_NONNULL )
|
||||
#define RETURNS_NONNULL
|
||||
#endif // !defined( RETURNS_NONNULL )
|
||||
|
||||
#if !defined( PFN_RETURNS_NONNULL )
|
||||
#define PFN_RETURNS_NONNULL
|
||||
#endif // !defined( PFN_RETURNS_NONNULL )
|
||||
|
||||
#if !defined( NORETURN )
|
||||
#define NORETURN
|
||||
#endif // !defined( NORETURN )
|
||||
|
||||
#if !defined( NONNULL )
|
||||
#define NONNULL
|
||||
#endif // !defined( NONNULL )
|
||||
|
||||
#if !defined( FORMAT_CHECK )
|
||||
#define FORMAT_CHECK( x )
|
||||
#endif // !defined( FORMAT_CHECK )
|
||||
|
||||
#if !defined( ALLOC_CHECK )
|
||||
#define ALLOC_CHECK( x )
|
||||
#endif // !defined( ALLOC_CHECK )
|
||||
|
||||
#if !defined( WARN_UNUSED_RESULT )
|
||||
#define WARN_UNUSED_RESULT
|
||||
#endif // !defined( WARN_UNUSED_RESULT )
|
||||
|
||||
#if !defined( RENAME_SYMBOL )
|
||||
#define RENAME_SYMBOL( x )
|
||||
#endif // !defined( RENAME_SYMBOL )
|
||||
|
||||
#if !defined( unlikely ) || !defined( likely )
|
||||
#define unlikely( x ) ( x )
|
||||
#define likely( x ) ( x )
|
||||
#endif // !defined( unlikely ) || !defined( likely )
|
||||
|
||||
#if !defined( XASH_RESTRICT )
|
||||
#define XASH_RESTRICT
|
||||
#endif
|
||||
|
||||
#if !defined( offsetof )
|
||||
#define offsetof( s, m ) (size_t)&(((s *)0)->m )
|
||||
#endif // !defined( offsetof )
|
||||
|
||||
#if __STDC_VERSION__ >= 202311L || __cplusplus >= 201103L // C23 or C++ static_assert is a keyword
|
||||
#define STATIC_ASSERT_( ignore, x, y ) static_assert( x, y )
|
||||
#define STATIC_ASSERT static_assert
|
||||
@@ -231,41 +165,75 @@ typedef int qboolean;
|
||||
|
||||
// at least, statically check size of some public structures
|
||||
#if XASH_64BIT
|
||||
#define STATIC_CHECK_SIZEOF( type, size32, size64 ) \
|
||||
STATIC_ASSERT( sizeof( type ) == size64, #type " unexpected size" )
|
||||
#define STATIC_CHECK_SIZEOF( type, size32, size64 ) \
|
||||
STATIC_ASSERT( sizeof( type ) == size64, #type " unexpected size" )
|
||||
#else
|
||||
#define STATIC_CHECK_SIZEOF( type, size32, size64 ) \
|
||||
STATIC_ASSERT( sizeof( type ) == size32, #type " unexpected size" )
|
||||
#define STATIC_CHECK_SIZEOF( type, size32, size64 ) \
|
||||
STATIC_ASSERT( sizeof( type ) == size32, #type " unexpected size" )
|
||||
#endif
|
||||
|
||||
#define Swap32( x ) (((uint32_t)((( x ) & 255 ) << 24 )) + ((uint32_t)(((( x ) >> 8 ) & 255 ) << 16 )) + ((uint32_t)((( x ) >> 16 ) & 255 ) << 8 ) + ((( x ) >> 24 ) & 255 ))
|
||||
#define Swap16( x ) ((uint16_t)((((uint16_t)( x ) >> 8 ) & 255 ) + (((uint16_t)( x ) & 255 ) << 8 )))
|
||||
#define Swap32Store( x ) ( x = Swap32( x ))
|
||||
#define Swap16Store( x ) ( x = Swap16( x ))
|
||||
|
||||
#define LittleFourCC( a, b, c, d ) (((uint32_t)( d ) << 24 ) | ((uint32_t)( c ) << 16 ) | ((uint32_t)( b ) << 8 ) | (uint32_t)( a ))
|
||||
#define BigFourCC( a, b, c, d ) (((uint32_t)( a ) << 24 ) | ((uint32_t)( b ) << 16 ) | ((uint32_t)( c ) << 8 ) | (uint32_t)( d ))
|
||||
|
||||
#if XASH_BIG_ENDIAN
|
||||
#define LittleLong( x ) Swap32( x )
|
||||
#define LittleShort( x ) Swap16( x )
|
||||
#define LittleLongSW( x ) Swap32Store( x )
|
||||
#define LittleShortSW( x ) Swap16Store( x )
|
||||
#define LittleFloat( x ) SwapFloat( x )
|
||||
#define BigLong( x ) ( x )
|
||||
#define BigShort( x ) ( x )
|
||||
#define BigFloat( x ) ( x )
|
||||
#define HostFourCC( a, b, c, d ) BigFourCC( a, b, c, d )
|
||||
#if !defined( __cplusplus ) && __STDC_VERSION__ >= 199101L // not C++ and C99 or newer
|
||||
#define XASH_RESTRICT restrict
|
||||
#elif _MSC_VER || __GNUC__ || __clang__ // compiler-specific extensions
|
||||
#define XASH_RESTRICT __restrict
|
||||
#else
|
||||
#define LittleLong( x ) ( x )
|
||||
#define LittleShort( x ) ( x )
|
||||
#define LittleFloat( x ) ( x )
|
||||
#define LittleLongSW( x )
|
||||
#define LittleShortSW( x )
|
||||
#define BigLong( x ) Swap32( x )
|
||||
#define BigShort( x ) Swap16( x )
|
||||
#define BigFloat( x ) SwapFloat( x )
|
||||
#define HostFourCC( a, b, c, d ) LittleFourCC( a, b, c, d )
|
||||
#define XASH_RESTRICT // nothing
|
||||
#endif
|
||||
|
||||
#ifdef XASH_BIG_ENDIAN
|
||||
#define LittleLong(x) (((int)(((x)&255)<<24)) + ((int)((((x)>>8)&255)<<16)) + ((int)(((x)>>16)&255)<<8) + (((x) >> 24)&255))
|
||||
#define LittleLongSW(x) (x = LittleLong(x) )
|
||||
#define LittleShort(x) ((short)( (((short)(x) >> 8) & 255) + (((short)(x) & 255) << 8)))
|
||||
#define LittleShortSW(x) (x = LittleShort(x) )
|
||||
_inline float LittleFloat( float f )
|
||||
{
|
||||
union
|
||||
{
|
||||
float f;
|
||||
unsigned char b[4];
|
||||
} dat1, dat2;
|
||||
|
||||
dat1.f = f;
|
||||
dat2.b[0] = dat1.b[3];
|
||||
dat2.b[1] = dat1.b[2];
|
||||
dat2.b[2] = dat1.b[1];
|
||||
dat2.b[3] = dat1.b[0];
|
||||
|
||||
return dat2.f;
|
||||
}
|
||||
#else
|
||||
#define LittleLong(x) (x)
|
||||
#define LittleLongSW(x)
|
||||
#define LittleShort(x) (x)
|
||||
#define LittleShortSW(x)
|
||||
#define LittleFloat(x) (x)
|
||||
#endif
|
||||
|
||||
|
||||
typedef unsigned int dword;
|
||||
typedef unsigned int uint;
|
||||
typedef char string[MAX_STRING];
|
||||
typedef off_t fs_offset_t;
|
||||
#if XASH_WIN32
|
||||
typedef int fs_size_t; // return type of _read, _write funcs
|
||||
#else /* !XASH_WIN32 */
|
||||
typedef ssize_t fs_size_t;
|
||||
#endif /* !XASH_WIN32 */
|
||||
|
||||
typedef void *(*pfnCreateInterface_t)( const char *, int * );
|
||||
|
||||
// config strings are a general means of communication from
|
||||
// the server to all connected clients.
|
||||
// each config string can be at most CS_SIZE characters.
|
||||
#if XASH_LOW_MEMORY == 0
|
||||
#define MAX_QPATH 64 // max length of a game pathname
|
||||
#elif XASH_LOW_MEMORY == 2
|
||||
#define MAX_QPATH 32 // should be enough for singleplayer
|
||||
#elif XASH_LOW_MEMORY == 1
|
||||
#define MAX_QPATH 48
|
||||
#endif
|
||||
#define MAX_OSPATH 260 // max length of a filesystem pathname
|
||||
#define CS_SIZE 64 // size of one config string
|
||||
#define CS_TIME 16 // size of time string
|
||||
|
||||
#endif // XASH_TYPES_H
|
||||
|
||||
@@ -17,10 +17,8 @@
|
||||
#define ALIAS_H
|
||||
|
||||
#include "build.h"
|
||||
#include <stdint.h>
|
||||
#include STDINT_H
|
||||
#include "synctype.h"
|
||||
#include "xash3d_types.h"
|
||||
#include "com_model.h"
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
@@ -23,12 +23,6 @@ struct mstudioevent_s;
|
||||
struct engine_studio_api_s;
|
||||
struct r_studio_interface_s;
|
||||
|
||||
struct sound_api_s;
|
||||
struct sound_interface_s;
|
||||
|
||||
typedef struct sound_api_s sound_api_t;
|
||||
typedef struct sound_interface_s sound_interface_t;
|
||||
|
||||
// NOTE: ordering is important!
|
||||
typedef struct cldll_func_s
|
||||
{
|
||||
@@ -80,9 +74,6 @@ typedef struct cldll_func_s
|
||||
int (*pfnTouchEvent)( int type, int fingerID, float x, float y, float dx, float dy );
|
||||
void (*pfnMoveEvent)( float forwardmove, float sidemove );
|
||||
void (*pfnLookEvent)( float relyaw, float relpitch );
|
||||
// Sound API
|
||||
int (*pfnGetSoundInterface)( int version, const sound_api_t *api, sound_interface_t *callback );
|
||||
int (*pfnVoice_StartChannel)( int samples, byte *data, int entnum );
|
||||
} cldll_func_t;
|
||||
|
||||
#endif//CDLL_EXP_H
|
||||
|
||||
@@ -25,6 +25,7 @@ qboolean AVI_GetVideoInfo( movie_state_t *Avi, int *xres, int *yres, float *dura
|
||||
qboolean AVI_HaveAudioTrack( const movie_state_t *Avi );
|
||||
void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audio, int quiet );
|
||||
movie_state_t *AVI_LoadVideo( const char *filename, qboolean load_audio );
|
||||
int AVI_TimeToSoundPosition( movie_state_t *Avi, int time );
|
||||
void AVI_CloseVideo( movie_state_t *Avi );
|
||||
qboolean AVI_IsActive( movie_state_t *Avi );
|
||||
void AVI_FreeVideo( movie_state_t *Avi );
|
||||
|
||||
@@ -23,6 +23,7 @@ static qboolean avi_initialized;
|
||||
static poolhandle_t avi_mempool;
|
||||
|
||||
#if XASH_AVI == AVI_FFMPEG
|
||||
#define XASH_FFMPEG_DLOPEN 1
|
||||
#include "avi_ffmpeg.h"
|
||||
|
||||
struct movie_state_s
|
||||
@@ -221,6 +222,11 @@ int AVI_GetVideoFrameNumber( movie_state_t *Avi, float time )
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AVI_TimeToSoundPosition( movie_state_t *Avi, int time )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
qboolean AVI_GetVideoInfo( movie_state_t *Avi, int *xres, int *yres, float *duration )
|
||||
{
|
||||
if( !Avi->active )
|
||||
@@ -255,9 +261,9 @@ static void AVI_StreamAudio( movie_state_t *Avi )
|
||||
rawchan_t *ch = NULL;
|
||||
|
||||
// keep the same semantics, when S_RAW_SOUND_SOUNDTRACK doesn't play if S_StartStreaming wasn't enabled
|
||||
qboolean disable_stream = Avi->entnum == S_RAW_SOUND_SOUNDTRACK ? !snd.streaming : false;
|
||||
qboolean disable_stream = Avi->entnum == S_RAW_SOUND_SOUNDTRACK ? !s_listener.streaming : false;
|
||||
|
||||
if( !snd.initialized || disable_stream || cl.paused || !Avi->cached_audio )
|
||||
if( !dma.initialized || disable_stream || s_listener.paused || !Avi->cached_audio )
|
||||
return;
|
||||
|
||||
ch = S_FindRawChannel( Avi->entnum, true );
|
||||
@@ -268,14 +274,14 @@ static void AVI_StreamAudio( movie_state_t *Avi )
|
||||
ch->master_vol = Avi->volume;
|
||||
ch->dist_mult = (Avi->attn / SND_CLIP_DISTANCE);
|
||||
|
||||
if( ch->s_rawend < snd.soundtime )
|
||||
ch->s_rawend = snd.soundtime;
|
||||
if( ch->s_rawend < soundtime )
|
||||
ch->s_rawend = soundtime;
|
||||
|
||||
while( ch->s_rawend < snd.soundtime + ch->max_samples )
|
||||
while( ch->s_rawend < soundtime + ch->max_samples )
|
||||
{
|
||||
size_t copy;
|
||||
|
||||
buffer_samples = ch->max_samples - (ch->s_rawend - snd.soundtime);
|
||||
buffer_samples = ch->max_samples - (ch->s_rawend - soundtime);
|
||||
|
||||
file_samples = buffer_samples * ((float)Avi->rate / SOUND_DMA_SPEED);
|
||||
if( file_samples <= 1 ) return; // no more samples need
|
||||
@@ -349,10 +355,6 @@ qboolean AVI_Think( movie_state_t *Avi )
|
||||
qboolean decoded = false;
|
||||
qboolean flushing = false;
|
||||
qboolean redraw = false;
|
||||
|
||||
if( !Avi->video_ctx )
|
||||
return false;
|
||||
|
||||
const double timebase = (double)Avi->video_ctx->pkt_timebase.den / Avi->video_ctx->pkt_timebase.num;
|
||||
int64_t curtime = round( Platform_DoubleTime() * timebase );
|
||||
|
||||
@@ -382,7 +384,7 @@ qboolean AVI_Think( movie_state_t *Avi )
|
||||
|
||||
if(( res = pav_read_frame( Avi->fmt_ctx, Avi->pkt )) >= 0 )
|
||||
{
|
||||
if( Avi->pkt->stream_index == Avi->audio_stream && Avi->audio_ctx )
|
||||
if( Avi->pkt->stream_index == Avi->audio_stream )
|
||||
{
|
||||
res = pavcodec_send_packet( Avi->audio_ctx, Avi->pkt );
|
||||
if( res < 0 )
|
||||
@@ -444,16 +446,13 @@ qboolean AVI_Think( movie_state_t *Avi )
|
||||
|
||||
if( Avi->texture == 0 )
|
||||
{
|
||||
int cinTexture = SCR_GetCinematicTexture();
|
||||
int w = Avi->w >= 0 ? Avi->w : refState.width;
|
||||
int h = Avi->h >= 0 ? Avi->h : refState.height;
|
||||
|
||||
if( redraw )
|
||||
ref.dllFuncs.GL_UpdateTexture( cinTexture, Avi->xres, Avi->yres, Avi->xres, Avi->yres, Avi->dst, PF_BGRA_32 );
|
||||
ref.dllFuncs.R_DrawStretchPic( Avi->x, Avi->y, w, h, 0, 0, 1, 1, cinTexture );
|
||||
ref.dllFuncs.R_DrawStretchRaw( Avi->x, Avi->y, w, h, Avi->xres, Avi->yres, Avi->dst, redraw );
|
||||
}
|
||||
else if( redraw && Avi->texture > 0 )
|
||||
ref.dllFuncs.GL_UpdateTexture( Avi->texture, Avi->xres, Avi->yres, Avi->w, Avi->h, Avi->dst, PF_BGRA_32 );
|
||||
ref.dllFuncs.AVI_UploadRawFrame( Avi->texture, Avi->xres, Avi->yres, Avi->w, Avi->h, Avi->dst );
|
||||
|
||||
if( flushing && !decoded )
|
||||
return false; // probably hit an EOF
|
||||
@@ -843,6 +842,11 @@ void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audi
|
||||
;
|
||||
}
|
||||
|
||||
int AVI_TimeToSoundPosition( movie_state_t *Avi, int time )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AVI_CloseVideo( movie_state_t *Avi )
|
||||
{
|
||||
;
|
||||
|
||||
@@ -26,101 +26,35 @@ GNU General Public License for more details.
|
||||
|
||||
#if XASH_FFMPEG_DLOPEN
|
||||
|
||||
// using typeof gives more resilience to function declaration changes
|
||||
// but it's only available in GCC and standardized in C23
|
||||
#if defined(__GNUC__) || __STDC_VERSION__ >= 202311L
|
||||
|
||||
#define SUPPORTED_AVU_VERSION_MAJOR LIBAVUTIL_VERSION_MAJOR
|
||||
#define SUPPORTED_AVF_VERSION_MAJOR LIBAVFORMAT_VERSION_MAJOR
|
||||
#define SUPPORTED_AVC_VERSION_MAJOR LIBAVCODEC_VERSION_MAJOR
|
||||
#define SUPPORTED_SWR_VERSION_MAJOR LIBSWRESAMPLE_VERSION_MAJOR
|
||||
#define SUPPORTED_SWS_VERSION_MAJOR LIBSWSCALE_VERSION_MAJOR
|
||||
|
||||
#define F( func ) \
|
||||
typedef typeof( func ) func##_t; \
|
||||
func##_t *p##func
|
||||
|
||||
// libavutil
|
||||
F( avutil_version );
|
||||
F( av_frame_alloc );
|
||||
F( av_frame_free );
|
||||
F( av_frame_ref );
|
||||
F( av_frame_unref );
|
||||
F( av_strerror );
|
||||
F( av_free );
|
||||
F( av_get_bytes_per_sample );
|
||||
F( av_get_media_type_string );
|
||||
F( av_image_alloc );
|
||||
|
||||
// libavformat
|
||||
F( avformat_version );
|
||||
F( av_find_best_stream );
|
||||
F( av_read_frame );
|
||||
F( av_seek_frame );
|
||||
F( avformat_close_input );
|
||||
F( avformat_find_stream_info );
|
||||
F( avformat_open_input );
|
||||
|
||||
// libavcodec
|
||||
F( avcodec_version );
|
||||
F( av_packet_alloc );
|
||||
F( av_packet_free );
|
||||
F( av_packet_unref );
|
||||
F( avcodec_alloc_context3 );
|
||||
F( avcodec_find_decoder );
|
||||
F( avcodec_flush_buffers );
|
||||
F( avcodec_free_context );
|
||||
F( avcodec_open2 );
|
||||
F( avcodec_parameters_to_context );
|
||||
F( avcodec_receive_frame );
|
||||
F( avcodec_send_packet );
|
||||
|
||||
// libswresample
|
||||
F( swresample_version );
|
||||
F( swr_alloc_set_opts2 );
|
||||
F( swr_convert );
|
||||
F( swr_free );
|
||||
F( swr_init );
|
||||
|
||||
// libswscale
|
||||
F( swscale_version );
|
||||
F( sws_freeContext );
|
||||
F( sws_getContext );
|
||||
F( sws_scale );
|
||||
|
||||
#undef F
|
||||
|
||||
#else // !defined(__GNUC__) && __STDC_VERSION__ < 202311L
|
||||
|
||||
// the following symbols were taken from ffmpeg public headers
|
||||
// on each major ffmpeg uprgade, they must be validated
|
||||
// ffmpeg guarantees API and ABI compatibility between major versions
|
||||
// so complain if this gets compiled against unsupported yet version
|
||||
// the same check will be done in runtime to ensure compatibility
|
||||
#define SUPPORTED_AVU_VERSION_MAJOR 60
|
||||
#define SUPPORTED_AVF_VERSION_MAJOR 62
|
||||
#define SUPPORTED_AVC_VERSION_MAJOR 62
|
||||
#define SUPPORTED_SWR_VERSION_MAJOR 6
|
||||
#define SUPPORTED_SWS_VERSION_MAJOR 9
|
||||
#define SUPPORTED_AVU_VERSION_MAJOR 59
|
||||
#define SUPPORTED_AVF_VERSION_MAJOR 61
|
||||
#define SUPPORTED_AVC_VERSION_MAJOR 61
|
||||
#define SUPPORTED_SWR_VERSION_MAJOR 5
|
||||
#define SUPPORTED_SWS_VERSION_MAJOR 8
|
||||
|
||||
#if SUPPORTED_AVU_VERSION_MAJOR != LIBAVUTIL_VERSION_MAJOR
|
||||
#error "unsupported libavutil version"
|
||||
#error
|
||||
#endif
|
||||
|
||||
#if SUPPORTED_AVF_VERSION_MAJOR != LIBAVFORMAT_VERSION_MAJOR
|
||||
#error "unsupported libavformat version"
|
||||
#error
|
||||
#endif
|
||||
|
||||
#if SUPPORTED_AVC_VERSION_MAJOR != LIBAVCODEC_VERSION_MAJOR
|
||||
#error "unsupported libavcodec version"
|
||||
#error
|
||||
#endif
|
||||
|
||||
#if SUPPORTED_SWR_VERSION_MAJOR != LIBSWRESAMPLE_VERSION_MAJOR
|
||||
#error "unsupported libswresample version"
|
||||
#error
|
||||
#endif
|
||||
|
||||
#if SUPPORTED_SWS_VERSION_MAJOR != LIBSWSCALE_VERSION_MAJOR
|
||||
#error "unsupported libswscale version"
|
||||
#error
|
||||
#endif
|
||||
|
||||
// libavutil
|
||||
@@ -171,8 +105,6 @@ void (*psws_freeContext)( struct SwsContext *swsContext );
|
||||
struct SwsContext *(*psws_getContext)( int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param );
|
||||
int (*psws_scale)( struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[] );
|
||||
|
||||
#endif // defined(__GNUC__) || __STDC_VERSION__ >= 202311L
|
||||
|
||||
#else // !XASH_FFMPEG_DLOPEN
|
||||
|
||||
#define SUPPORTED_AVU_VERSION_MAJOR LIBAVUTIL_VERSION_MAJOR
|
||||
@@ -184,9 +116,8 @@ int (*psws_scale)( struct SwsContext *c, const uint8_t *const srcS
|
||||
// libavutil
|
||||
#define pavutil_version avutil_version
|
||||
#define pav_frame_alloc av_frame_alloc
|
||||
#define pav_frame_free av_frame_free
|
||||
#define pav_frame_ref av_frame_ref
|
||||
#define pav_frame_unref av_frame_unref
|
||||
#define pav_frame_unref av_Frame_unref
|
||||
#define pav_strerror av_strerror
|
||||
#define pav_free av_free
|
||||
#define pav_get_bytes_per_sample av_get_bytes_per_sample
|
||||
|
||||
@@ -97,17 +97,7 @@ void CL_PlayCDTrack_f( void )
|
||||
if( Q_isdigit( pszTrack ))
|
||||
{
|
||||
track = bound( 1, Q_atoi( Cmd_Argv( 2 )), MAX_CDTRACKS );
|
||||
|
||||
// a1ba: some maps contain cd track set in worldspawn
|
||||
// forcibly stopping music on changelevel
|
||||
//
|
||||
// server notifies us about this in sv_client.c SV_PutClientInServer
|
||||
// through "cd loop" command
|
||||
//
|
||||
// however, it could be set to a track that doesn't contain music data (in CD terms)
|
||||
// so we catch it here and music will carry over changelevels
|
||||
if( !COM_StringEmpty( clgame.cdtracks[track-1] ))
|
||||
S_StartBackgroundTrack( clgame.cdtracks[track-1], clgame.cdtracks[track-1], 0, false );
|
||||
S_StartBackgroundTrack( clgame.cdtracks[track-1], clgame.cdtracks[track-1], 0, false );
|
||||
}
|
||||
else S_StartBackgroundTrack( pszTrack, pszTrack, 0, true );
|
||||
paused = false;
|
||||
@@ -146,13 +136,10 @@ void CL_PlayCDTrack_f( void )
|
||||
}
|
||||
else if( !Q_stricmp( command, "info" ))
|
||||
{
|
||||
int maxTrack = 0;
|
||||
int i, maxTrack;
|
||||
|
||||
for( int i = 0; i < MAX_CDTRACKS; i++ )
|
||||
{
|
||||
if( !COM_StringEmpty( clgame.cdtracks[i] ) )
|
||||
maxTrack++;
|
||||
}
|
||||
for( maxTrack = i = 0; i < MAX_CDTRACKS; i++ )
|
||||
if( COM_CheckStringEmpty( clgame.cdtracks[i] ) ) maxTrack++;
|
||||
|
||||
Con_Printf( "%u tracks\n", maxTrack );
|
||||
if( track )
|
||||
|
||||
@@ -16,8 +16,10 @@ GNU General Public License for more details.
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "net_encode.h"
|
||||
#include "particledef.h"
|
||||
#include "cl_tent.h"
|
||||
#include "shake.h"
|
||||
#include "hltv.h"
|
||||
#include "input.h"
|
||||
|
||||
#define MSG_COUNT 32 // last 32 messages parsed
|
||||
@@ -55,6 +57,9 @@ const char *CL_MsgInfo( int cmd )
|
||||
case PROTO_CURRENT:
|
||||
svc_string = svc_strings[cmd];
|
||||
break;
|
||||
case PROTO_LEGACY:
|
||||
svc_string = svc_legacy_strings[cmd];
|
||||
break;
|
||||
case PROTO_QUAKE:
|
||||
svc_string = svc_quake_strings[cmd];
|
||||
break;
|
||||
@@ -144,11 +149,7 @@ static void CL_WriteErrorMessage( int current_count, sizebuf_t *msg )
|
||||
file_t *fp;
|
||||
|
||||
fp = FS_Open( buffer_file, "wb", false );
|
||||
if( !fp )
|
||||
{
|
||||
Con_Printf( S_ERROR "%s: can't open %s for write\n", __func__, buffer_file );
|
||||
return;
|
||||
}
|
||||
if( !fp ) return;
|
||||
|
||||
FS_Write( fp, &cls.starting_count, sizeof( int ));
|
||||
FS_Write( fp, ¤t_count, sizeof( int ));
|
||||
|
||||
@@ -117,6 +117,8 @@ static int CL_GetDemoNetProtocol( connprotocol_t proto )
|
||||
{
|
||||
case PROTO_CURRENT:
|
||||
return PROTOCOL_VERSION;
|
||||
case PROTO_LEGACY:
|
||||
return PROTOCOL_LEGACY_VERSION;
|
||||
case PROTO_QUAKE:
|
||||
return PROTOCOL_VERSION_QUAKE;
|
||||
case PROTO_GOLDSRC:
|
||||
@@ -132,6 +134,8 @@ static connprotocol_t CL_GetProtocolFromDemo( int net_protocol )
|
||||
{
|
||||
case PROTOCOL_VERSION:
|
||||
return PROTO_CURRENT;
|
||||
case PROTOCOL_LEGACY_VERSION:
|
||||
return PROTO_LEGACY;
|
||||
case PROTOCOL_VERSION_QUAKE:
|
||||
return PROTO_QUAKE;
|
||||
case PROTOCOL_GOLDSRC_VERSION_DEMO:
|
||||
@@ -1213,7 +1217,7 @@ void CL_StopPlayback( void )
|
||||
else
|
||||
{
|
||||
// let game known about demo state
|
||||
Cvar_DirectFullSet( &cl_background, "0", FCVAR_READ_ONLY );
|
||||
Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
|
||||
cls.state = ca_disconnected;
|
||||
memset( &cls.serveradr, 0, sizeof( cls.serveradr ) );
|
||||
cls.set_lastdemo = false;
|
||||
@@ -1260,7 +1264,8 @@ int GAME_EXPORT CL_GetDemoComment( const char *demoname, char *comment )
|
||||
return false;
|
||||
}
|
||||
|
||||
if( demohdr.net_protocol != PROTOCOL_VERSION ||
|
||||
if(( demohdr.net_protocol != PROTOCOL_VERSION &&
|
||||
demohdr.net_protocol != PROTOCOL_LEGACY_VERSION ) ||
|
||||
demohdr.dem_protocol != DEMO_PROTOCOL )
|
||||
{
|
||||
FS_Close( demfile );
|
||||
@@ -1475,10 +1480,10 @@ static qboolean CL_ParseDemoHeader( const char *callee, const char *filename, fi
|
||||
return false;
|
||||
}
|
||||
|
||||
if( hdr->net_protocol != PROTOCOL_VERSION && hdr->net_protocol != PROTOCOL_GOLDSRC_VERSION_DEMO )
|
||||
if( hdr->net_protocol != PROTOCOL_VERSION && hdr->net_protocol != PROTOCOL_LEGACY_VERSION && hdr->net_protocol != PROTOCOL_GOLDSRC_VERSION_DEMO )
|
||||
{
|
||||
Con_Printf( S_ERROR "%s: net protocol outdated (%i should be %i or %i)\n",
|
||||
callee, hdr->net_protocol, PROTOCOL_VERSION, PROTOCOL_GOLDSRC_VERSION );
|
||||
callee, hdr->net_protocol, PROTOCOL_VERSION, PROTOCOL_LEGACY_VERSION );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -200,15 +200,15 @@ particle_t * GAME_EXPORT R_AllocParticle( void (*callback)( particle_t*, float )
|
||||
p->type = pt_static;
|
||||
VectorClear( p->vel );
|
||||
VectorClear( p->org );
|
||||
p->unused = 0;
|
||||
p->packedColor = 0;
|
||||
p->die = cl.time;
|
||||
p->color = 0;
|
||||
p->ramp = 0;
|
||||
|
||||
if( callback )
|
||||
{
|
||||
p->type = pt_custom;
|
||||
p->think = callback;
|
||||
p->type = pt_clientcustom;
|
||||
p->callback = callback;
|
||||
}
|
||||
|
||||
return p;
|
||||
@@ -254,7 +254,7 @@ static particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life
|
||||
p->die = cl.time + life;
|
||||
p->ramp = tracerlength.value;
|
||||
p->color = TRACER_COLORINDEX_DEFAULT; // select custom color
|
||||
p->unused = 255; // alpha
|
||||
p->packedColor = 255; // alpha
|
||||
|
||||
return p;
|
||||
}
|
||||
@@ -849,31 +849,6 @@ BEAM * GAME_EXPORT R_BeamEnts( int startEnt, int endEnt, int modelIndex, float l
|
||||
return pbeam;
|
||||
}
|
||||
|
||||
static qboolean R_BeamVisible( const vec3_t start, const vec3_t end )
|
||||
{
|
||||
vec3_t mins, maxs;
|
||||
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
if( start[i] < end[i] )
|
||||
{
|
||||
mins[i] = start[i];
|
||||
maxs[i] = end[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
mins[i] = end[i];
|
||||
maxs[i] = start[i];
|
||||
}
|
||||
|
||||
// don't let it be zero sized
|
||||
if( mins[i] == maxs[i] )
|
||||
maxs[i] += 1.0f;
|
||||
}
|
||||
|
||||
return Mod_BoxVisible( mins, maxs, ref.dllFuncs.Mod_GetCurrentVis( ));
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
R_BeamPoints
|
||||
@@ -886,7 +861,7 @@ BEAM * GAME_EXPORT R_BeamPoints( vec3_t start, vec3_t end, int modelIndex, float
|
||||
{
|
||||
BEAM *pbeam;
|
||||
|
||||
if( life != 0 && !R_BeamVisible( start, end ))
|
||||
if( life != 0 && ref.dllFuncs.R_BeamCull( start, end, true ))
|
||||
return NULL;
|
||||
|
||||
pbeam = R_BeamAlloc();
|
||||
@@ -1143,7 +1118,7 @@ void GAME_EXPORT R_ParticleExplosion2( const vec3_t org, int colorStart, int col
|
||||
|
||||
p->die = cl.time + 0.3f;
|
||||
p->color = colorStart + ( colorMod % colorLength );
|
||||
p->unused = packedColor;
|
||||
p->packedColor = packedColor;
|
||||
colorMod++;
|
||||
|
||||
p->type = pt_blob;
|
||||
@@ -1175,7 +1150,7 @@ void GAME_EXPORT R_BlobExplosion( const vec3_t org )
|
||||
if( !p ) return;
|
||||
|
||||
p->die = cl.time + COM_RandomFloat( 1.0f, 1.4f );
|
||||
p->unused = packedColor;
|
||||
p->packedColor = packedColor;
|
||||
|
||||
if( i & 1 )
|
||||
{
|
||||
@@ -1239,8 +1214,8 @@ particle spray
|
||||
void GAME_EXPORT R_Blood( const vec3_t org, const vec3_t ndir, int pcolor, int speed )
|
||||
{
|
||||
vec3_t pos, dir, vec;
|
||||
float pspeed = speed * 3.0f;
|
||||
int i, j;
|
||||
int pspeed = speed * 3;
|
||||
particle_t *p;
|
||||
|
||||
VectorNormalize2( ndir, dir );
|
||||
@@ -1250,20 +1225,18 @@ void GAME_EXPORT R_Blood( const vec3_t org, const vec3_t ndir, int pcolor, int s
|
||||
VectorAddScalar( org, COM_RandomFloat( -3.0f, 3.0f ), pos );
|
||||
VectorAddScalar( dir, COM_RandomFloat( -0.06f, 0.06f ), vec );
|
||||
|
||||
for( j = 0; j < 8; j++ )
|
||||
for( j = 0; j < 7; j++ )
|
||||
{
|
||||
p = R_AllocParticle( NULL );
|
||||
if( !p ) return;
|
||||
|
||||
p->die = cl.time + 1.5f;
|
||||
p->color = pcolor + COM_RandomLong( 0, 9 );
|
||||
p->type = pt_8x_slowgrav;
|
||||
p->type = pt_vox_grav;
|
||||
|
||||
VectorAddScalar( pos, COM_RandomFloat( -1.0f, 1.0f ), p->org );
|
||||
VectorScale( vec, pspeed, p->vel );
|
||||
}
|
||||
|
||||
pspeed -= speed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1290,7 +1263,7 @@ void GAME_EXPORT R_BloodStream( const vec3_t org, const vec3_t ndir, int pcolor,
|
||||
if( !p ) return;
|
||||
|
||||
p->die = cl.time + 2.0f;
|
||||
p->type = pt_8x_slowgrav;
|
||||
p->type = pt_vox_grav;
|
||||
p->color = pcolor + COM_RandomLong( 0, 9 );
|
||||
|
||||
VectorCopy( org, p->org );
|
||||
@@ -1311,7 +1284,7 @@ void GAME_EXPORT R_BloodStream( const vec3_t org, const vec3_t ndir, int pcolor,
|
||||
|
||||
p->die = cl.time + 3.0f;
|
||||
p->color = pcolor + COM_RandomLong( 0, 9 );
|
||||
p->type = pt_4x_slowgrav;
|
||||
p->type = pt_vox_slowgrav;
|
||||
|
||||
VectorCopy( org, p->org );
|
||||
VectorCopy( dir, p->vel );
|
||||
@@ -1333,9 +1306,12 @@ void GAME_EXPORT R_BloodStream( const vec3_t org, const vec3_t ndir, int pcolor,
|
||||
|
||||
p->die = cl.time + 3.0f;
|
||||
p->color = pcolor + COM_RandomLong( 0, 9 );
|
||||
p->type = pt_4x_slowgrav;
|
||||
p->type = pt_vox_slowgrav;
|
||||
|
||||
p->org[0] = org[0] + COM_RandomFloat( -1.0f, 1.0f );
|
||||
p->org[1] = org[1] + COM_RandomFloat( -1.0f, 1.0f );
|
||||
p->org[2] = org[2] + COM_RandomFloat( -1.0f, 1.0f );
|
||||
|
||||
VectorAddScalar( org, COM_RandomFloat( -1.0f, 1.0f ), p->org );
|
||||
VectorCopy( dir, p->vel );
|
||||
p->vel[2] -= arc;
|
||||
|
||||
@@ -1922,8 +1898,8 @@ void GAME_EXPORT R_UserTracerParticle( float *org, float *vel, float life, int c
|
||||
|
||||
if(( p = R_AllocTracer( org, vel, life )) != NULL )
|
||||
{
|
||||
p->userdata = deathcontext;
|
||||
p->on_die = deathfunc;
|
||||
p->context = deathcontext;
|
||||
p->deathfunc = deathfunc;
|
||||
p->color = colorIndex;
|
||||
p->ramp = length;
|
||||
}
|
||||
@@ -2020,9 +1996,9 @@ void R_FreeDeadParticles( particle_t **ppparticles )
|
||||
kill = *ppparticles;
|
||||
if( kill && kill->die < cl.time )
|
||||
{
|
||||
if( kill->on_die )
|
||||
kill->on_die( kill );
|
||||
kill->on_die = NULL;
|
||||
if( kill->deathfunc )
|
||||
kill->deathfunc( kill );
|
||||
kill->deathfunc = NULL;
|
||||
*ppparticles = kill->next;
|
||||
kill->next = cl_free_particles;
|
||||
cl_free_particles = kill;
|
||||
@@ -2039,9 +2015,9 @@ void R_FreeDeadParticles( particle_t **ppparticles )
|
||||
kill = p->next;
|
||||
if( kill && kill->die < cl.time )
|
||||
{
|
||||
if( kill->on_die )
|
||||
kill->on_die( kill );
|
||||
kill->on_die = NULL;
|
||||
if( kill->deathfunc )
|
||||
kill->deathfunc( kill );
|
||||
kill->deathfunc = NULL;
|
||||
p->next = kill->next;
|
||||
kill->next = cl_free_particles;
|
||||
cl_free_particles = kill;
|
||||
@@ -2178,7 +2154,7 @@ void CL_ThinkParticle( double frametime, particle_t *p )
|
||||
float grav = frametime * clgame.movevars.gravity * 0.05f;
|
||||
|
||||
|
||||
if( p->type != pt_custom )
|
||||
if( p->type != pt_clientcustom )
|
||||
{
|
||||
// update position.
|
||||
VectorMA( p->org, frametime, p->vel, p->org );
|
||||
@@ -2209,7 +2185,7 @@ void CL_ThinkParticle( double frametime, particle_t *p )
|
||||
p->vel[2] -= grav;
|
||||
break;
|
||||
case pt_blob:
|
||||
if( p->unused == 255 )
|
||||
if( p->packedColor == 255 )
|
||||
{
|
||||
// normal blob explosion
|
||||
VectorMA( p->vel, dvel, p->vel, p->vel );
|
||||
@@ -2218,7 +2194,7 @@ void CL_ThinkParticle( double frametime, particle_t *p )
|
||||
}
|
||||
// intentionally fallthrough
|
||||
case pt_blob2:
|
||||
if( p->unused == 255 )
|
||||
if( p->packedColor == 255 )
|
||||
{
|
||||
// normal blob explosion
|
||||
p->vel[0] -= p->vel[0] * dvel;
|
||||
@@ -2241,15 +2217,15 @@ void CL_ThinkParticle( double frametime, particle_t *p )
|
||||
case pt_slowgrav:
|
||||
p->vel[2] -= grav;
|
||||
break;
|
||||
case pt_8x_slowgrav:
|
||||
case pt_vox_grav:
|
||||
p->vel[2] -= grav * 8.0f;
|
||||
break;
|
||||
case pt_4x_slowgrav:
|
||||
case pt_vox_slowgrav:
|
||||
p->vel[2] -= grav * 4.0f;
|
||||
break;
|
||||
case pt_custom:
|
||||
if( p->think )
|
||||
p->think( p, frametime );
|
||||
case pt_clientcustom:
|
||||
if( p->callback )
|
||||
p->callback( p, frametime );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ word CL_EventIndex( const char *name )
|
||||
{
|
||||
word i;
|
||||
|
||||
if( COM_StringEmptyOrNULL( name ))
|
||||
if( !COM_CheckString( name ))
|
||||
return 0;
|
||||
|
||||
for( i = 1; i < MAX_EVENTS && cl.event_precache[i][0]; i++ )
|
||||
@@ -436,8 +436,9 @@ void CL_ParseEvent( sizebuf_t *msg, connprotocol_t proto )
|
||||
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
entity_bits = MAX_GOLDSRC_ENTITY_BITS;
|
||||
else
|
||||
entity_bits = MAX_ENTITY_BITS;
|
||||
else if( proto == PROTO_LEGACY )
|
||||
entity_bits = MAX_LEGACY_ENTITY_BITS;
|
||||
else entity_bits = MAX_ENTITY_BITS;
|
||||
|
||||
// parse events queue
|
||||
for( i = 0 ; i < num_events; i++ )
|
||||
|
||||
@@ -17,20 +17,6 @@ GNU General Public License for more details.
|
||||
#include "filesystem.h"
|
||||
#include "client.h"
|
||||
#include "qfont.h"
|
||||
#include "swaplib.h"
|
||||
|
||||
le_struct_begin( charinfo_swap )
|
||||
le_struct_field( charinfo, startoffset )
|
||||
le_struct_field( charinfo, charwidth )
|
||||
le_struct_end();
|
||||
|
||||
le_struct_begin( qfont_swap )
|
||||
le_struct_field( qfont_t, width )
|
||||
le_struct_field( qfont_t, height )
|
||||
le_struct_field( qfont_t, rowcount )
|
||||
le_struct_field( qfont_t, rowheight )
|
||||
le_struct_array_child( qfont_t, fontinfo, charinfo_swap, NUM_GLYPHS )
|
||||
le_struct_end();
|
||||
|
||||
qboolean CL_FixedFont( cl_font_t *font )
|
||||
{
|
||||
@@ -82,11 +68,6 @@ void CL_SetFontRendermode( cl_font_t *font )
|
||||
ref.dllFuncs.GL_SetRenderMode( CL_FontRenderMode( font->rendermode ));
|
||||
}
|
||||
|
||||
void CL_SetFontColor( cl_font_t *font, const rgba_t color )
|
||||
{
|
||||
ref.dllFuncs.Color4ub( color[0], color[1], color[2], color[3] );
|
||||
}
|
||||
|
||||
qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, convar_t *rendermode, uint texFlags )
|
||||
{
|
||||
int font_width, i;
|
||||
@@ -144,7 +125,6 @@ qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font, float
|
||||
}
|
||||
|
||||
memcpy( &src, pfile, sizeof( src ));
|
||||
le_struct_swap( qfont_swap, &src );
|
||||
Mem_Free( pfile );
|
||||
|
||||
font->hFontTexture = CL_LoadFontTexture( fontname, texFlags, &font_width );
|
||||
@@ -183,7 +163,7 @@ void CL_FreeFont( cl_font_t *font )
|
||||
|
||||
static int CL_CalcTabStop( const cl_font_t *font, int x )
|
||||
{
|
||||
int space = font->charWidths['0'];
|
||||
int space = font->charWidths[' '];
|
||||
int tab = space * 6; // 6 spaces
|
||||
int stop = tab - x % tab;
|
||||
|
||||
@@ -242,9 +222,10 @@ int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_
|
||||
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
|
||||
CL_SetFontRendermode( font );
|
||||
|
||||
if( !FBitSet( flags, FONT_DRAW_NOCOLOR ))
|
||||
CL_SetFontColor( font, color );
|
||||
|
||||
// don't apply color to fixed fonts it's already colored
|
||||
if( font->type != FONT_FIXED || REF_GET_PARM( PARM_TEX_GLFORMAT, font->hFontTexture ) == 0x8045 ) // GL_LUMINANCE8_ALPHA8
|
||||
ref.dllFuncs.Color4ub( color[0], color[1], color[2], color[3] );
|
||||
else ref.dllFuncs.Color4ub( 255, 255, 255, color[3] );
|
||||
ref.dllFuncs.R_DrawStretchPic( x, y, w, h, s1, t1, s2, t2, font->hFontTexture );
|
||||
|
||||
return font->charWidths[number];
|
||||
@@ -252,6 +233,7 @@ int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_
|
||||
|
||||
int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_t *font, int flags )
|
||||
{
|
||||
rgba_t current_color;
|
||||
int draw_len = 0;
|
||||
|
||||
if( !font || !font->valid )
|
||||
@@ -263,9 +245,7 @@ int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_
|
||||
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
|
||||
CL_SetFontRendermode( font );
|
||||
|
||||
CL_SetFontColor( font, color );
|
||||
|
||||
SetBits( flags, FONT_DRAW_NOCOLOR | FONT_DRAW_NORENDERMODE );
|
||||
Vector4Copy( color, current_color );
|
||||
|
||||
while( *s )
|
||||
{
|
||||
@@ -284,7 +264,7 @@ int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_
|
||||
}
|
||||
|
||||
if( FBitSet( flags, FONT_DRAW_RESETCOLORONLF ))
|
||||
CL_SetFontColor( font, color );
|
||||
Vector4Copy( color, current_color );
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -292,14 +272,14 @@ int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_
|
||||
{
|
||||
// don't copy alpha
|
||||
if( !FBitSet( flags, FONT_DRAW_FORCECOL ))
|
||||
CL_SetFontColor( font, g_color_table[ColorIndex(*( s + 1 ))] );
|
||||
VectorCopy( g_color_table[ColorIndex(*( s + 1 ))], current_color );
|
||||
|
||||
s += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip setting rendermode, it was changed for this string already
|
||||
draw_len += CL_DrawCharacter( x + draw_len, y, (byte)*s, NULL, font, flags );
|
||||
draw_len += CL_DrawCharacter( x + draw_len, y, (byte)*s, current_color, font, flags | FONT_DRAW_NORENDERMODE );
|
||||
|
||||
s++;
|
||||
}
|
||||
@@ -344,7 +324,7 @@ void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height,
|
||||
if( width )
|
||||
*width = 0;
|
||||
|
||||
if( COM_StringEmptyOrNULL( s ))
|
||||
if( !COM_CheckString( s ))
|
||||
return;
|
||||
|
||||
if( FBitSet( flags, FONT_DRAW_UTF8 ))
|
||||
|
||||
@@ -20,6 +20,7 @@ GNU General Public License for more details.
|
||||
#include "pm_local.h"
|
||||
#include "cl_tent.h"
|
||||
#include "studio.h"
|
||||
#include "dlight.h"
|
||||
#include "sound.h"
|
||||
#include "input.h"
|
||||
|
||||
@@ -156,6 +157,13 @@ static qboolean CL_EntityCustomLerp( cl_entity_t *e )
|
||||
case MOVETYPE_FLY:
|
||||
case MOVETYPE_COMPOUND:
|
||||
return false;
|
||||
|
||||
// ABSOLUTELY STUPID HACK TO ALLOW MONSTERS
|
||||
// INTERPOLATION IN GRAVGUNMOD COOP
|
||||
// MUST BE REMOVED ONCE WE REMOVE 48 PROTO SUPPORT
|
||||
case MOVETYPE_TOSS:
|
||||
if( cls.legacymode == PROTO_LEGACY && e->model && e->model->type == mod_studio )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -310,21 +318,6 @@ static void CL_ProcessEntityUpdate( cl_entity_t *ent )
|
||||
if( FBitSet( ent->curstate.entityType, ENTITY_NORMAL ))
|
||||
COM_NormalizeAngles( ent->curstate.angles );
|
||||
|
||||
// a1ba: follow entities are sent with null origin, grab their aiment origin here
|
||||
//
|
||||
// null origin leads to triggered entity teleport check and subsequent reset of position history
|
||||
// and empty position history doesn't allow entity to render correctly
|
||||
//
|
||||
// it's probably should be done somewhere else, as goldsrc doesn't do this here
|
||||
// it has MoveAiments function but it's called after LinkPacketEntities :shrug:
|
||||
if( ent->curstate.movetype == MOVETYPE_FOLLOW && VectorIsNull( ent->curstate.origin ) && ent->curstate.aiment )
|
||||
{
|
||||
cl_entity_t *aiment = CL_GetEntityByIndex( ent->curstate.aiment );
|
||||
|
||||
if( aiment )
|
||||
VectorCopy( aiment->origin, ent->curstate.origin );
|
||||
}
|
||||
|
||||
parametric = ent->curstate.starttime != 0.0f && ent->curstate.impacttime != 0.0f;
|
||||
|
||||
// allow interpolation on bmodels too
|
||||
@@ -660,9 +653,18 @@ FRAME PARSING
|
||||
*/
|
||||
static qboolean CL_ParseEntityNumFromPacket( sizebuf_t *msg, int *newnum, connprotocol_t proto )
|
||||
{
|
||||
*newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
|
||||
if( *newnum == LAST_EDICT )
|
||||
return false;
|
||||
if( proto == PROTO_LEGACY )
|
||||
{
|
||||
*newnum = MSG_ReadWord( msg );
|
||||
if( *newnum == 0 )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
|
||||
if( *newnum == LAST_EDICT )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -829,7 +831,9 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
||||
CL_WriteDemoJumpTime();
|
||||
|
||||
// sentinel count. save it for debug checking
|
||||
count = MSG_ReadUBitLong( msg, MAX_VISIBLE_PACKET_BITS ) + 1;
|
||||
if( proto == PROTO_LEGACY )
|
||||
count = MSG_ReadWord( msg );
|
||||
else count = MSG_ReadUBitLong( msg, MAX_VISIBLE_PACKET_BITS ) + 1;
|
||||
|
||||
newframe = &cl.frames[cl.parsecountmod];
|
||||
|
||||
@@ -981,8 +985,15 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
|
||||
if( !draw_player )
|
||||
return false;
|
||||
|
||||
if( !ref.dllFuncs.R_AddEntity( ent, entityType ))
|
||||
if( entityType == ET_BEAM )
|
||||
{
|
||||
ref.dllFuncs.CL_AddCustomBeam( ent );
|
||||
return true;
|
||||
}
|
||||
else if( !ref.dllFuncs.R_AddEntity( ent, entityType ))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// because pTemp->entity.curstate.effects
|
||||
// is already occupied by FTENT_FLICKER
|
||||
@@ -1235,6 +1246,16 @@ static void CL_LinkPacketEntities( frame_t *frame )
|
||||
if( !CL_InterpolateModel( ent ))
|
||||
continue;
|
||||
}
|
||||
#if 0
|
||||
// ABSOLUTELY STUPID HACK TO ALLOW MONSTERS
|
||||
// INTERPOLATION IN GRAVGUNMOD COOP
|
||||
// MUST BE REMOVED ONCE WE REMOVE 48 PROTO SUPPORT
|
||||
else if( cls.legacymode == PROTO_LEGACY && ent->model->type == mod_studio && ent->curstate.movetype == MOVETYPE_TOSS )
|
||||
{
|
||||
if( !CL_InterpolateModel( ent ))
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
// no interpolation right now
|
||||
@@ -1374,7 +1395,7 @@ qboolean CL_GetEntitySpatialization( channel_t *ch )
|
||||
|
||||
if( ch->entnum == 0 )
|
||||
{
|
||||
SetBits( ch->flags, FL_CHAN_STATIC_SOUND );
|
||||
ch->staticsound = true;
|
||||
return true; // static sound
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,6 @@ GNU General Public License for more details.
|
||||
#include "client.h"
|
||||
#include "const.h"
|
||||
#include "triangleapi.h"
|
||||
#include "r_studioint.h"
|
||||
#include "mod_local.h"
|
||||
#include "r_efx.h"
|
||||
#include "demo_api.h"
|
||||
#include "ivoicetweak.h"
|
||||
@@ -39,20 +37,11 @@ GNU General Public License for more details.
|
||||
#include "platform/platform.h"
|
||||
|
||||
#define MAX_LINELENGTH 80
|
||||
#define TEXT_MSGNAME "TextMessage"
|
||||
#define MAX_TEXTCHANNELS 8 // must be power of two (GoldSrc uses 4 channels)
|
||||
#define TEXT_MSGNAME "TextMessage%i"
|
||||
|
||||
static char cl_textbuffer[MAX_TEXTCHANNELS][2048];
|
||||
client_textmessage_t cl_textmessage[MAX_TEXTCHANNELS] =
|
||||
{
|
||||
{ .pName = "TextMessage0", .pMessage = cl_textbuffer[0] },
|
||||
{ .pName = "TextMessage1", .pMessage = cl_textbuffer[1] },
|
||||
{ .pName = "TextMessage2", .pMessage = cl_textbuffer[2] },
|
||||
{ .pName = "TextMessage3", .pMessage = cl_textbuffer[3] },
|
||||
{ .pName = "TextMessage4", .pMessage = cl_textbuffer[4] },
|
||||
{ .pName = "TextMessage5", .pMessage = cl_textbuffer[5] },
|
||||
{ .pName = "TextMessage6", .pMessage = cl_textbuffer[6] },
|
||||
{ .pName = "TextMessage7", .pMessage = cl_textbuffer[7] },
|
||||
};
|
||||
static client_textmessage_t cl_textmessage[MAX_TEXTCHANNELS];
|
||||
|
||||
static const dllfunc_t cdll_exports[] =
|
||||
{
|
||||
@@ -107,8 +96,6 @@ static const dllfunc_t cdll_new_exports[] = // allowed only in SDK 2.3 and high
|
||||
{ "IN_ClientTouchEvent", (void **)&clgame.dllFuncs.pfnTouchEvent}, // Xash3D FWGS ext
|
||||
{ "IN_ClientMoveEvent", (void **)&clgame.dllFuncs.pfnMoveEvent}, // Xash3D FWGS ext
|
||||
{ "IN_ClientLookEvent", (void **)&clgame.dllFuncs.pfnLookEvent}, // Xash3D FWGS ext
|
||||
{ "HUD_GetSoundInterface", (void **)&clgame.dllFuncs.pfnGetSoundInterface }, // Xash3D FWGS ext
|
||||
{ "Voice_StartChannel", (void **)&clgame.dllFuncs.pfnVoice_StartChannel }, // Xash3D FWGS ext
|
||||
};
|
||||
|
||||
static void pfnSPR_DrawHoles( int frame, int x, int y, const wrect_t *prc );
|
||||
@@ -125,11 +112,7 @@ static void CL_CreatePlaylist( const char *filename )
|
||||
file_t *f;
|
||||
|
||||
f = FS_Open( filename, "w", false );
|
||||
if( !f )
|
||||
{
|
||||
Con_Printf( S_ERROR "%s: can't open %s for write\n", __func__, filename );
|
||||
return;
|
||||
}
|
||||
if( !f ) return;
|
||||
|
||||
// make standard cdaudio playlist
|
||||
FS_Print( f, "blank\n" ); // #1
|
||||
@@ -192,13 +175,7 @@ static void CL_InitCDAudio( const char *filename )
|
||||
while(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) != NULL )
|
||||
{
|
||||
if( !Q_stricmp( token, "blank" ))
|
||||
{
|
||||
clgame.cdtracks[c][0] = '\0';
|
||||
}
|
||||
else if( token[0] == '/' ) // allow custom path
|
||||
{
|
||||
Q_strncpy( clgame.cdtracks[c], &token[1], sizeof( clgame.cdtracks[c] ));
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( clgame.cdtracks[c], sizeof( clgame.cdtracks[c] ),
|
||||
@@ -289,7 +266,7 @@ void CL_CenterPrint( const char *text, float y )
|
||||
{
|
||||
cl_font_t *font = Con_GetCurFont();
|
||||
|
||||
if( COM_StringEmptyOrNULL( text ) || !font || !font->valid )
|
||||
if( !COM_CheckString( text ) || !font || !font->valid )
|
||||
return;
|
||||
|
||||
clgame.centerPrint.totalWidth = 0;
|
||||
@@ -376,13 +353,13 @@ static void SPR_DrawGeneric( int frame, float x, float y, float width, float hei
|
||||
int w, h;
|
||||
|
||||
// assume we get sizes from image
|
||||
R_GetSpriteParms( &w, &h, NULL, frame, clgame.ds.pSprite );
|
||||
ref.dllFuncs.R_GetSpriteParms( &w, &h, NULL, frame, clgame.ds.pSprite );
|
||||
|
||||
width = w;
|
||||
height = h;
|
||||
}
|
||||
|
||||
texnum = R_GetSpriteTexture( clgame.ds.pSprite, frame );
|
||||
texnum = ref.dllFuncs.R_GetSpriteTexture( clgame.ds.pSprite, frame );
|
||||
|
||||
if( prc )
|
||||
{
|
||||
@@ -452,7 +429,6 @@ void CL_DrawCenterPrint( void )
|
||||
|
||||
CL_DrawCharacterLen( font, 0, NULL, &charHeight );
|
||||
CL_SetFontRendermode( font );
|
||||
CL_SetFontColor( font, colorDefault );
|
||||
for( i = 0; i < clgame.centerPrint.lines; i++ )
|
||||
{
|
||||
lineLength = 0;
|
||||
@@ -482,7 +458,7 @@ void CL_DrawCenterPrint( void )
|
||||
for( j = 0; j < lineLength; j++ )
|
||||
{
|
||||
if( x >= 0 && y >= 0 && x <= refState.width )
|
||||
x += CL_DrawCharacter( x, y, line[j], NULL, font, FONT_DRAW_HUD | FONT_DRAW_NORENDERMODE | FONT_DRAW_NOCOLOR );
|
||||
x += CL_DrawCharacter( x, y, line[j], colorDefault, font, FONT_DRAW_HUD | FONT_DRAW_NORENDERMODE );
|
||||
}
|
||||
y += charHeight;
|
||||
}
|
||||
@@ -579,18 +555,31 @@ and hold them into permament memory pool
|
||||
*/
|
||||
static void CL_InitTitles( const char *filename )
|
||||
{
|
||||
fs_offset_t fileSize;
|
||||
byte *pMemFile;
|
||||
int i;
|
||||
|
||||
// initialize text messages (game_text)
|
||||
for( i = 0; i < MAX_TEXTCHANNELS; i++ )
|
||||
{
|
||||
char name[MAX_VA_STRING];
|
||||
|
||||
Q_snprintf( name, sizeof( name ), TEXT_MSGNAME, i );
|
||||
|
||||
cl_textmessage[i].pName = copystringpool( clgame.mempool, name );
|
||||
cl_textmessage[i].pMessage = cl_textbuffer[i];
|
||||
}
|
||||
|
||||
// clear out any old data that's sitting around.
|
||||
Mem_Free( clgame.titles );
|
||||
if( clgame.titles ) Mem_Free( clgame.titles );
|
||||
|
||||
clgame.titles = NULL;
|
||||
clgame.numTitles = 0;
|
||||
|
||||
fs_offset_t fileSize = 0;
|
||||
char *pMemFile = (char *)FS_LoadFile( filename, &fileSize, false );
|
||||
if( !pMemFile )
|
||||
return;
|
||||
pMemFile = FS_LoadFile( filename, &fileSize, false );
|
||||
if( !pMemFile ) return;
|
||||
|
||||
clgame.titles = CL_TextMessageParse( clgame.mempool, pMemFile, fileSize, &clgame.numTitles );
|
||||
CL_TextMessageParse( pMemFile, fileSize );
|
||||
Mem_Free( pMemFile );
|
||||
}
|
||||
|
||||
@@ -603,10 +592,8 @@ Template to show hud messages
|
||||
*/
|
||||
void CL_HudMessage( const char *pMessage )
|
||||
{
|
||||
if( COM_StringEmptyOrNULL( pMessage ))
|
||||
return;
|
||||
|
||||
CL_DispatchUserMessage( "HudText", Q_strlen( pMessage ) + 1, (void *)pMessage );
|
||||
if( !COM_CheckString( pMessage )) return;
|
||||
CL_DispatchUserMessage( "HudText", Q_strlen( pMessage ), (void *)pMessage );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -659,6 +646,54 @@ void CL_ParseTextMessage( sizebuf_t *msg )
|
||||
CL_HudMessage( text->pName );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_ParseFinaleCutscene
|
||||
|
||||
show display finale or cutscene message
|
||||
================
|
||||
*/
|
||||
void CL_ParseFinaleCutscene( sizebuf_t *msg, int level )
|
||||
{
|
||||
static int msgindex = 0;
|
||||
client_textmessage_t *text;
|
||||
int channel;
|
||||
|
||||
cl.intermission = level;
|
||||
|
||||
channel = msgindex;
|
||||
msgindex = (msgindex + 1) & (MAX_TEXTCHANNELS - 1);
|
||||
|
||||
// grab message channel
|
||||
text = &cl_textmessage[channel];
|
||||
|
||||
// NOTE: svc_finale and svc_cutscene has a
|
||||
// predefined settings like Quake-style
|
||||
text->x = -1.0f;
|
||||
text->y = 0.15f;
|
||||
text->effect = 2; // scan out effect
|
||||
text->r1 = 245;
|
||||
text->g1 = 245;
|
||||
text->b1 = 245;
|
||||
text->a1 = 0; // unused
|
||||
text->r2 = 0;
|
||||
text->g2 = 0;
|
||||
text->b2 = 0;
|
||||
text->a2 = 0;
|
||||
text->fadein = 0.15f;
|
||||
text->fadeout = 0.0f;
|
||||
text->holdtime = 99999.0f;
|
||||
text->fxtime = 0.0f;
|
||||
|
||||
// to prevent grab too long messages
|
||||
Q_strncpy( (char *)text->pMessage, MSG_ReadString( msg ), 2048 );
|
||||
|
||||
if( *text->pMessage == '\0' )
|
||||
return; // no real text
|
||||
|
||||
CL_HudMessage( text->pName );
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_GetMaxlients
|
||||
@@ -1075,12 +1110,7 @@ void CL_ClearSpriteTextures( void )
|
||||
int i;
|
||||
|
||||
for( i = 1; i < MAX_CLIENT_SPRITES; i++ )
|
||||
{
|
||||
if( clgame.sprites[i].needload == NL_UNREFERENCED )
|
||||
continue;
|
||||
|
||||
clgame.sprites[i].needload = NL_FREE_UNUSED;
|
||||
}
|
||||
clgame.sprites[i].needload = NL_UNREFERENCED;
|
||||
}
|
||||
|
||||
// it's a Valve default value for LoadMapSprite (probably must be power of two)
|
||||
@@ -1251,8 +1281,8 @@ static qboolean CL_LoadHudSprite( const char *szSpriteName, model_t *m_pSprite,
|
||||
Mod_LoadMapSprite( m_pSprite, buf, size, &loaded );
|
||||
else
|
||||
{
|
||||
Mod_LoadSpriteModel( m_pSprite, buf, size, &loaded );
|
||||
ref.dllFuncs.Mod_ProcessRenderData( m_pSprite, true, buf, size );
|
||||
Mod_LoadSpriteModel( m_pSprite, buf, &loaded );
|
||||
ref.dllFuncs.Mod_ProcessRenderData( m_pSprite, true, buf );
|
||||
}
|
||||
|
||||
Mem_Free( buf );
|
||||
@@ -1282,7 +1312,7 @@ static model_t *CL_LoadSpriteModel( const char *filename, uint type, uint texFla
|
||||
model_t *mod;
|
||||
int i, start;
|
||||
|
||||
if( COM_StringEmptyOrNULL( filename ))
|
||||
if( !COM_CheckString( filename ))
|
||||
{
|
||||
Con_Reportf( S_ERROR "%s: bad name!\n", __func__ );
|
||||
return NULL;
|
||||
@@ -1314,7 +1344,7 @@ static model_t *CL_LoadSpriteModel( const char *filename, uint type, uint texFla
|
||||
|
||||
for( i = 0, mod = &clgame.sprites[start]; i < MAX_CLIENT_SPRITES / 2; i++, mod++ )
|
||||
{
|
||||
if( mod->needload == NL_UNREFERENCED )
|
||||
if( !mod->name[0] )
|
||||
break; // this is a valid spot
|
||||
}
|
||||
|
||||
@@ -1426,7 +1456,7 @@ int EXPORT pfnSPR_Frames( HSPRITE hPic )
|
||||
{
|
||||
int numFrames = 0;
|
||||
|
||||
R_GetSpriteParms( NULL, NULL, &numFrames, 0, CL_GetSpritePointer( hPic ));
|
||||
ref.dllFuncs.R_GetSpriteParms( NULL, NULL, &numFrames, 0, CL_GetSpritePointer( hPic ));
|
||||
|
||||
return numFrames;
|
||||
}
|
||||
@@ -1441,7 +1471,7 @@ static int GAME_EXPORT pfnSPR_Height( HSPRITE hPic, int frame )
|
||||
{
|
||||
int sprHeight = 0;
|
||||
|
||||
R_GetSpriteParms( NULL, &sprHeight, NULL, frame, CL_GetSpritePointer( hPic ));
|
||||
ref.dllFuncs.R_GetSpriteParms( NULL, &sprHeight, NULL, frame, CL_GetSpritePointer( hPic ));
|
||||
|
||||
return sprHeight;
|
||||
}
|
||||
@@ -1456,7 +1486,7 @@ static int GAME_EXPORT pfnSPR_Width( HSPRITE hPic, int frame )
|
||||
{
|
||||
int sprWidth = 0;
|
||||
|
||||
R_GetSpriteParms( &sprWidth, NULL, NULL, frame, CL_GetSpritePointer( hPic ));
|
||||
ref.dllFuncs.R_GetSpriteParms( &sprWidth, NULL, NULL, frame, CL_GetSpritePointer( hPic ));
|
||||
|
||||
return sprWidth;
|
||||
}
|
||||
@@ -1801,7 +1831,7 @@ pfnServerCmd
|
||||
*/
|
||||
static int GAME_EXPORT pfnServerCmd( const char *szCmdString )
|
||||
{
|
||||
if( COM_StringEmptyOrNULL( szCmdString ))
|
||||
if( !COM_CheckString( szCmdString ))
|
||||
return 0;
|
||||
|
||||
// just like the client typed "cmd xxxxx" at the console
|
||||
@@ -1819,7 +1849,7 @@ pfnClientCmd
|
||||
*/
|
||||
static int GAME_EXPORT pfnClientCmd( const char *szCmdString )
|
||||
{
|
||||
if( COM_StringEmptyOrNULL( szCmdString ))
|
||||
if( !COM_CheckString( szCmdString ))
|
||||
return 0;
|
||||
|
||||
if( cls.initialized )
|
||||
@@ -1844,7 +1874,7 @@ pfnFilteredClientCmd
|
||||
*/
|
||||
static int GAME_EXPORT pfnFilteredClientCmd( const char *szCmdString )
|
||||
{
|
||||
if( COM_StringEmptyOrNULL( szCmdString ))
|
||||
if( !COM_CheckString( szCmdString ))
|
||||
return 0;
|
||||
|
||||
// a1ba:
|
||||
@@ -1932,12 +1962,13 @@ client_textmessage_t *CL_TextMessageGet( const char *pName )
|
||||
int i;
|
||||
|
||||
// first check internal messages
|
||||
if( Q_strlen( pName ) == sizeof( TEXT_MSGNAME ) // including the digit
|
||||
&& !Q_strncmp( pName, TEXT_MSGNAME, sizeof( TEXT_MSGNAME ) - 1 ))
|
||||
for( i = 0; i < MAX_TEXTCHANNELS; i++ )
|
||||
{
|
||||
i = pName[sizeof( TEXT_MSGNAME ) - 1] - '0';
|
||||
char name[MAX_VA_STRING];
|
||||
|
||||
if( i >= 0 && i < MAX_TEXTCHANNELS )
|
||||
Q_snprintf( name, sizeof( name ), TEXT_MSGNAME, i );
|
||||
|
||||
if( !Q_strcmp( pName, name ))
|
||||
return cl_textmessage + i;
|
||||
}
|
||||
|
||||
@@ -2025,7 +2056,7 @@ prints directly into console (can skip notify)
|
||||
*/
|
||||
static void GAME_EXPORT pfnConsolePrint( const char *string )
|
||||
{
|
||||
if( COM_StringEmptyOrNULL( string ))
|
||||
if( !COM_CheckString( string ))
|
||||
return;
|
||||
|
||||
// WON GoldSrc behavior
|
||||
@@ -2175,7 +2206,7 @@ pfnGetViewModel
|
||||
|
||||
=============
|
||||
*/
|
||||
static cl_entity_t *GAME_EXPORT CL_GetViewModel( void )
|
||||
static cl_entity_t* GAME_EXPORT CL_GetViewModel( void )
|
||||
{
|
||||
return &clgame.viewent;
|
||||
}
|
||||
@@ -2397,7 +2428,7 @@ static int GAME_EXPORT CL_FindModelIndex( const char *m )
|
||||
char filepath[MAX_QPATH];
|
||||
int i;
|
||||
|
||||
if( COM_StringEmptyOrNULL( m ))
|
||||
if( !COM_CheckString( m ))
|
||||
return 0;
|
||||
|
||||
Q_strncpy( filepath, m, sizeof( filepath ));
|
||||
@@ -2698,7 +2729,7 @@ static const char *pfnGetLevelName( void )
|
||||
// a1ba: don't return maps/.bsp if no map is loaded yet
|
||||
// in GoldSrc this is handled by cl.levelname field but we don't have it
|
||||
// so emulate this behavior here
|
||||
if( cls.state >= ca_connected && !COM_StringEmpty( clgame.mapname ))
|
||||
if( cls.state >= ca_connected && COM_CheckStringEmpty( clgame.mapname ))
|
||||
Q_snprintf( mapname, sizeof( mapname ), "maps/%s.bsp", clgame.mapname );
|
||||
else mapname[0] = '\0'; // not in game
|
||||
|
||||
@@ -2769,7 +2800,7 @@ static int GAME_EXPORT COM_ExpandFilename( const char *fileName, char *nameOutBu
|
||||
{
|
||||
char result[MAX_SYSPATH];
|
||||
|
||||
if( COM_StringEmptyOrNULL( fileName ) || !nameOutBuffer || nameOutBufferSize <= 0 )
|
||||
if( !COM_CheckString( fileName ) || !nameOutBuffer || nameOutBufferSize <= 0 )
|
||||
return 0;
|
||||
|
||||
// filename examples:
|
||||
@@ -2882,7 +2913,7 @@ pfnServerCmdUnreliable
|
||||
*/
|
||||
static int GAME_EXPORT pfnServerCmdUnreliable( char *szCmdString )
|
||||
{
|
||||
if( COM_StringEmptyOrNULL( szCmdString ))
|
||||
if( !COM_CheckString( szCmdString ))
|
||||
return 0;
|
||||
|
||||
MSG_BeginClientCmd( &cls.datagram, clc_stringcmd );
|
||||
@@ -2899,15 +2930,10 @@ pfnGetMousePos
|
||||
*/
|
||||
static void GAME_EXPORT pfnGetMousePos( struct tagPOINT *ppt )
|
||||
{
|
||||
int x, y;
|
||||
|
||||
if( !ppt )
|
||||
return;
|
||||
|
||||
Platform_GetMousePos( &x, &y );
|
||||
|
||||
ppt->x = x;
|
||||
ppt->y = y;
|
||||
Platform_GetMousePos( &ppt->x, &ppt->y );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3176,8 +3202,7 @@ handle colon separately
|
||||
*/
|
||||
static char *pfnParseFile( char *data, char *token )
|
||||
{
|
||||
// GoldSrc uses 1024 byte tokens
|
||||
return COM_ParseFileSafe( data, token, 1024, PFILE_HANDLECOLON, NULL, NULL );
|
||||
return COM_ParseFileSafe( data, token, PFILE_TOKEN_MAX_LENGTH, PFILE_HANDLECOLON, NULL, NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3326,7 +3351,7 @@ int TriSpriteTexture( model_t *pSpriteModel, int frame )
|
||||
{
|
||||
int gl_texturenum;
|
||||
|
||||
if(( gl_texturenum = R_GetSpriteTexture( pSpriteModel, frame )) <= 0 )
|
||||
if(( gl_texturenum = ref.dllFuncs.R_GetSpriteTexture( pSpriteModel, frame )) <= 0 )
|
||||
return 0;
|
||||
|
||||
ref.dllFuncs.GL_Bind( XASH_TEXTURE0, gl_texturenum );
|
||||
@@ -3456,7 +3481,7 @@ static void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags,
|
||||
nr->flags = flags;
|
||||
|
||||
// local servers request
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, nr->resp.remote_address, A2A_NETINFO" %i %i %i", PROTOCOL_VERSION, context, request );
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, nr->resp.remote_address, A2A_NETINFO" %i %i %i", FBitSet( flags, FNETAPI_LEGACY_PROTOCOL ) ? PROTOCOL_LEGACY_VERSION : PROTOCOL_VERSION, context, request );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3919,7 +3944,7 @@ void CL_UnloadProgs( void )
|
||||
if( GI->internal_vgui_support )
|
||||
VGui_Shutdown();
|
||||
|
||||
Cvar_DirectFullSet( &cl_background, "0", FCVAR_READ_ONLY );
|
||||
Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
|
||||
Cvar_FullSet( "host_clientloaded", "0", FCVAR_READ_ONLY );
|
||||
|
||||
Cvar_Unlink( FCVAR_CLIENTDLL );
|
||||
@@ -3931,76 +3956,12 @@ void CL_UnloadProgs( void )
|
||||
memset( &clgame, 0, sizeof( clgame ));
|
||||
}
|
||||
|
||||
static model_t *pfnStudio_Mod_ForName( const char *name, int crash )
|
||||
{
|
||||
return Mod_ForName( name, crash, false );
|
||||
}
|
||||
|
||||
static void *pfnStudio_Mod_Extradata( model_t *mod )
|
||||
{
|
||||
return Mod_StudioExtradata( mod );
|
||||
}
|
||||
|
||||
static void pfnStudio_GetAliasScale( float *x, float *y )
|
||||
{
|
||||
if( x ) *x = 1.0f;
|
||||
if( y ) *y = 1.0f;
|
||||
}
|
||||
|
||||
static float ***pfnStudio_GetAliasTransform( void )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static model_t *pfnStudio_GetChromeSprite( void )
|
||||
{
|
||||
return cl_sprite_shell;
|
||||
}
|
||||
|
||||
static int pfnStudio_IsHardware( void )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static engine_studio_api_t gStudioAPI =
|
||||
{
|
||||
.Mem_Calloc = Mod_Calloc,
|
||||
.Cache_Check = Mod_CacheCheck,
|
||||
.LoadCacheFile = Mod_LoadCacheFile,
|
||||
.Mod_ForName = pfnStudio_Mod_ForName,
|
||||
.Mod_Extradata = pfnStudio_Mod_Extradata,
|
||||
.GetModelByIndex = CL_ModelHandle,
|
||||
.GetCvar = pfnCVarGetPointer,
|
||||
.GetChromeSprite = pfnStudio_GetChromeSprite,
|
||||
.GetAliasScale = pfnStudio_GetAliasScale,
|
||||
.StudioGetAliasTransform = pfnStudio_GetAliasTransform,
|
||||
.GetViewEntity = CL_GetViewModel,
|
||||
.IsHardware = pfnStudio_IsHardware,
|
||||
};
|
||||
|
||||
static void CL_InitStudioAPI( void )
|
||||
{
|
||||
static r_studio_interface_t gDefaultStudioDraw;
|
||||
r_studio_interface_t *pStudioDraw;
|
||||
|
||||
if( !ref.dllFuncs.R_StudioFillAPI( &gStudioAPI, &gDefaultStudioDraw ))
|
||||
return;
|
||||
|
||||
pStudioDraw = &gDefaultStudioDraw;
|
||||
|
||||
if( clgame.dllFuncs.pfnGetStudioModelInterface )
|
||||
clgame.dllFuncs.pfnGetStudioModelInterface( STUDIO_INTERFACE_VERSION, &pStudioDraw, &gStudioAPI );
|
||||
|
||||
ref.dllFuncs.R_StudioSetDrawInterface( pStudioDraw );
|
||||
}
|
||||
|
||||
qboolean CL_LoadProgs( const char *name )
|
||||
{
|
||||
static playermove_t gpMove;
|
||||
CL_EXPORT_FUNCS GetClientAPI; // single export
|
||||
qboolean valid_single_export = false;
|
||||
qboolean missed_exports = false;
|
||||
qboolean try_internal_vgui_support = GI->internal_vgui_support;
|
||||
int i;
|
||||
|
||||
if( clgame.hInstance ) CL_UnloadProgs();
|
||||
@@ -4021,10 +3982,10 @@ qboolean CL_LoadProgs( const char *name )
|
||||
|
||||
// NOTE: important stuff!
|
||||
// vgui must startup BEFORE loading client.dll to avoid get error ERROR_NOACESS during LoadLibrary
|
||||
if( !try_internal_vgui_support && VGui_LoadProgs( NULL ))
|
||||
if( !GI->internal_vgui_support && VGui_LoadProgs( NULL ))
|
||||
VGui_Startup( refState.width, refState.height );
|
||||
else
|
||||
try_internal_vgui_support = true; // we failed to load vgui_support, but let's probe client.dll for support anyway
|
||||
GI->internal_vgui_support = true; // we failed to load vgui_support, but let's probe client.dll for support anyway
|
||||
|
||||
clgame.hInstance = COM_LoadLibrary( name, false, false );
|
||||
|
||||
@@ -4032,21 +3993,21 @@ qboolean CL_LoadProgs( const char *name )
|
||||
return false;
|
||||
|
||||
// delayed vgui initialization for internal support
|
||||
if( try_internal_vgui_support && VGui_LoadProgs( clgame.hInstance ))
|
||||
if( GI->internal_vgui_support && VGui_LoadProgs( clgame.hInstance ))
|
||||
VGui_Startup( refState.width, refState.height );
|
||||
|
||||
// clear exports
|
||||
ClearExports( cdll_exports, ARRAYSIZE( cdll_exports ));
|
||||
|
||||
// trying to get single export
|
||||
if(( GetClientAPI = COM_GetProcAddress( clgame.hInstance, "GetClientAPI" )) != NULL )
|
||||
if(( GetClientAPI = (void *)COM_GetProcAddress( clgame.hInstance, "GetClientAPI" )) != NULL )
|
||||
{
|
||||
Con_Reportf( "%s: found single callback export\n", __func__ );
|
||||
|
||||
// trying to fill interface now
|
||||
GetClientAPI( &clgame.dllFuncs );
|
||||
}
|
||||
else if(( GetClientAPI = COM_GetProcAddress( clgame.hInstance, "F" )) != NULL )
|
||||
else if(( GetClientAPI = (void *)COM_GetProcAddress( clgame.hInstance, "F" )) != NULL )
|
||||
{
|
||||
Con_Reportf( "%s: found single callback export (secured client dlls)\n", __func__ );
|
||||
|
||||
@@ -4060,7 +4021,7 @@ qboolean CL_LoadProgs( const char *name )
|
||||
for( i = 0; i < ARRAYSIZE( cdll_exports ); i++ )
|
||||
{
|
||||
if( *(cdll_exports[i].func) != NULL )
|
||||
continue; // already got through 'F' or 'GetClientAPI'
|
||||
continue; // already gott through 'F' or 'GetClientAPI'
|
||||
|
||||
// functions are cleared before all the extensions are evaluated
|
||||
if(( *(cdll_exports[i].func) = (void *)COM_GetProcAddress( clgame.hInstance, cdll_exports[i].name )) == NULL )
|
||||
@@ -4074,11 +4035,6 @@ qboolean CL_LoadProgs( const char *name )
|
||||
|
||||
if( missed_exports )
|
||||
{
|
||||
if( clgame.dllFuncs.pfnInit && clgame.dllFuncs.pfnRedraw && clgame.dllFuncs.pfnReset && clgame.dllFuncs.pfnUpdateClientData && clgame.dllFuncs.pfnVidInit && clgame.dllFuncs.pfnInitialize )
|
||||
COM_PushLibraryError( "missing essential exports; outdated DLL!!!" );
|
||||
else
|
||||
COM_PushLibraryError( "missing essential exports" );
|
||||
|
||||
COM_FreeLibrary( clgame.hInstance );
|
||||
clgame.hInstance = NULL;
|
||||
return false;
|
||||
@@ -4101,7 +4057,6 @@ qboolean CL_LoadProgs( const char *name )
|
||||
|
||||
if( !clgame.dllFuncs.pfnInitialize( &gEngfuncs, CLDLL_INTERFACE_VERSION ))
|
||||
{
|
||||
COM_PushLibraryError( "can't init client API" );
|
||||
COM_FreeLibrary( clgame.hInstance );
|
||||
Con_Reportf( "%s: can't init client API\n", __func__ );
|
||||
clgame.hInstance = NULL;
|
||||
@@ -4115,14 +4070,14 @@ qboolean CL_LoadProgs( const char *name )
|
||||
|
||||
CL_InitCDAudio( "media/cdaudio.txt" );
|
||||
CL_InitTitles( "titles.txt" );
|
||||
CL_InitParticles( );
|
||||
CL_InitViewBeams( );
|
||||
CL_InitTempEnts( );
|
||||
CL_InitParticles ();
|
||||
CL_InitViewBeams ();
|
||||
CL_InitTempEnts ();
|
||||
|
||||
if( !R_InitRenderAPI( )) // Xash3D extension
|
||||
if( !R_InitRenderAPI()) // Xash3D extension
|
||||
Con_Reportf( S_WARN "%s: couldn't get render API\n", __func__ );
|
||||
|
||||
if( !Mobile_Init( )) // Xash3D FWGS extension: mobile interface
|
||||
if( !Mobile_Init() ) // Xash3D FWGS extension: mobile interface
|
||||
Con_Reportf( S_WARN "%s: couldn't get mobility API\n", __func__ );
|
||||
|
||||
CL_InitEdicts( cl.maxclients ); // initailize local player and world
|
||||
@@ -4131,7 +4086,7 @@ qboolean CL_LoadProgs( const char *name )
|
||||
// initialize game
|
||||
clgame.dllFuncs.pfnInit();
|
||||
|
||||
CL_InitStudioAPI();
|
||||
ref.dllFuncs.CL_InitStudioAPI();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -37,11 +37,8 @@ void UI_UpdateMenu( float realtime )
|
||||
{
|
||||
if( !gameui.hInstance ) return;
|
||||
|
||||
// don't draw menu over console
|
||||
if( cls.key_dest == key_console ) return;
|
||||
|
||||
// if some deferred cmds is waiting
|
||||
if( UI_IsVisible() && !COM_StringEmptyOrNULL( host.deferred_cmd ))
|
||||
if( UI_IsVisible() && COM_CheckString( host.deferred_cmd ))
|
||||
{
|
||||
Cbuf_AddText( host.deferred_cmd );
|
||||
host.deferred_cmd[0] = '\0';
|
||||
@@ -202,6 +199,24 @@ void UI_ShowConnectionWarning( void )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
UI_ShowConnectionWarning
|
||||
|
||||
show update dialog
|
||||
=================
|
||||
*/
|
||||
void UI_ShowUpdateDialog( qboolean preferStore )
|
||||
{
|
||||
if( gameui.dllFuncs2.pfnShowUpdateDialog )
|
||||
{
|
||||
gameui.dllFuncs2.pfnShowUpdateDialog( preferStore );
|
||||
}
|
||||
|
||||
Con_Printf( S_WARN "This version is not supported anymore. To continue, install latest engine version\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
UI_ShowConnectionWarning
|
||||
@@ -499,7 +514,7 @@ static HIMAGE GAME_EXPORT pfnPIC_Load( const char *szPicName, const byte *image_
|
||||
{
|
||||
HIMAGE tx;
|
||||
|
||||
if( COM_StringEmptyOrNULL( szPicName ))
|
||||
if( !COM_CheckString( szPicName ))
|
||||
{
|
||||
Con_Reportf( S_ERROR "%s: refusing to load image with empty name\n", __func__ );
|
||||
return 0;
|
||||
@@ -695,9 +710,7 @@ pfnPlaySound
|
||||
*/
|
||||
static void GAME_EXPORT pfnPlaySound( const char *szSound )
|
||||
{
|
||||
if( COM_StringEmptyOrNULL( szSound ))
|
||||
return;
|
||||
|
||||
if( !COM_CheckString( szSound )) return;
|
||||
S_StartLocalSound( szSound, VOL_NORM, false );
|
||||
}
|
||||
|
||||
@@ -982,7 +995,7 @@ pfnGetFilesList
|
||||
release prev search on a next call
|
||||
=========
|
||||
*/
|
||||
char **GAME_EXPORT CL_GetFilesList( const char *pattern, int *numFiles, int gamedironly )
|
||||
static char ** GAME_EXPORT pfnGetFilesList( const char *pattern, int *numFiles, int gamedironly )
|
||||
{
|
||||
static search_t *t = NULL;
|
||||
|
||||
@@ -1083,9 +1096,6 @@ UI_ShellExecute
|
||||
*/
|
||||
static void GAME_EXPORT UI_ShellExecute( const char *path, const char *parms, int shouldExit )
|
||||
{
|
||||
if( !Q_strcmp( path, GENERIC_UPDATE_PAGE ) || !Q_strcmp( path, PLATFORM_UPDATE_PAGE ))
|
||||
path = DEFAULT_UPDATE_PAGE;
|
||||
|
||||
Platform_ShellExecute( path, parms );
|
||||
|
||||
if( shouldExit )
|
||||
@@ -1222,7 +1232,7 @@ static const ui_enginefuncs_t gEngfuncs =
|
||||
pfnMemFree,
|
||||
pfnGetOldGameInfo,
|
||||
pfnGetGamesList,
|
||||
CL_GetFilesList,
|
||||
pfnGetFilesList,
|
||||
SV_GetSaveComment,
|
||||
CL_GetDemoComment,
|
||||
pfnCheckGameDll,
|
||||
@@ -1344,6 +1354,7 @@ qboolean UI_LoadProgs( void )
|
||||
UITEXTAPI GiveTextApi;
|
||||
MENUAPI GetMenuAPI;
|
||||
string dllpath;
|
||||
int i;
|
||||
|
||||
if( gameui.hInstance ) UI_UnloadProgs();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,7 @@ GNU General Public License for more details.
|
||||
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "kbutton.h"
|
||||
|
||||
#if XASH_LOW_MEMORY == 0
|
||||
#define NET_TIMINGS 1024
|
||||
@@ -171,7 +172,7 @@ get frame data info, like chokes, packet losses, also update graph, packet and c
|
||||
static void NetGraph_GetFrameData( float *latency, int *latency_count )
|
||||
{
|
||||
int i, choke_count = 0, loss_count = 0;
|
||||
double newtime = Platform_DoubleTime();
|
||||
double newtime = Sys_DoubleTime();
|
||||
static double nexttime = 0;
|
||||
float loss, choke;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
633
engine/client/cl_parse_48.c
Normal file
633
engine/client/cl_parse_48.c
Normal file
@@ -0,0 +1,633 @@
|
||||
/*
|
||||
cl_parse.c - parse a message received from the server
|
||||
Copyright (C) 2008 Uncle Mike
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "net_encode.h"
|
||||
#include "particledef.h"
|
||||
#include "cl_tent.h"
|
||||
#include "shake.h"
|
||||
#include "hltv.h"
|
||||
#include "input.h"
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ParseStaticEntity
|
||||
|
||||
static client entity
|
||||
==================
|
||||
*/
|
||||
static void CL_LegacyParseStaticEntity( sizebuf_t *msg )
|
||||
{
|
||||
int i;
|
||||
entity_state_t state = { 0 };
|
||||
cl_entity_t *ent;
|
||||
|
||||
if( !clgame.static_entities )
|
||||
clgame.static_entities = Mem_Calloc( clgame.mempool, sizeof( cl_entity_t ) * MAX_STATIC_ENTITIES );
|
||||
|
||||
state.modelindex = MSG_ReadShort( msg );
|
||||
state.sequence = MSG_ReadByte( msg );
|
||||
state.frame = MSG_ReadByte( msg );
|
||||
state.colormap = MSG_ReadWord( msg );
|
||||
state.skin = MSG_ReadByte( msg );
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
state.origin[i] = MSG_ReadCoord( msg );
|
||||
state.angles[i] = MSG_ReadBitAngle( msg, 16 );
|
||||
}
|
||||
|
||||
state.rendermode = MSG_ReadByte( msg );
|
||||
|
||||
if( state.rendermode != kRenderNormal )
|
||||
{
|
||||
state.renderamt = MSG_ReadByte( msg );
|
||||
state.rendercolor.r = MSG_ReadByte( msg );
|
||||
state.rendercolor.g = MSG_ReadByte( msg );
|
||||
state.rendercolor.b = MSG_ReadByte( msg );
|
||||
state.renderfx = MSG_ReadByte( msg );
|
||||
}
|
||||
|
||||
i = clgame.numStatics;
|
||||
if( i >= MAX_STATIC_ENTITIES )
|
||||
{
|
||||
Con_Printf( S_ERROR "MAX_STATIC_ENTITIES limit exceeded!\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
ent = &clgame.static_entities[i];
|
||||
clgame.numStatics++;
|
||||
|
||||
// all states are same
|
||||
ent->baseline = ent->curstate = ent->prevstate = state;
|
||||
ent->index = 0; // static entities doesn't has the numbers
|
||||
|
||||
// statics may be respawned in game e.g. for demo recording
|
||||
if( cls.state == ca_connected || cls.state == ca_validate )
|
||||
ent->trivial_accept = INVALID_HANDLE;
|
||||
|
||||
// setup the new static entity
|
||||
VectorCopy( ent->curstate.origin, ent->origin );
|
||||
VectorCopy( ent->curstate.angles, ent->angles );
|
||||
ent->model = CL_ModelHandle( state.modelindex );
|
||||
ent->curstate.framerate = 1.0f;
|
||||
CL_ResetLatchedVars( ent, true );
|
||||
|
||||
if( ent->curstate.rendermode == kRenderNormal && ent->model != NULL )
|
||||
{
|
||||
// auto 'solid' faces
|
||||
if( FBitSet( ent->model->flags, MODEL_TRANSPARENT ) && Host_IsQuakeCompatible( ))
|
||||
{
|
||||
ent->curstate.rendermode = kRenderTransAlpha;
|
||||
ent->curstate.renderamt = 255;
|
||||
}
|
||||
}
|
||||
|
||||
R_AddEfrags( ent ); // add link
|
||||
}
|
||||
|
||||
static void CL_LegacyParseSoundPacket( sizebuf_t *msg, qboolean is_ambient )
|
||||
{
|
||||
vec3_t pos;
|
||||
int chan, sound;
|
||||
float volume, attn;
|
||||
int flags, pitch, entnum;
|
||||
sound_t handle = 0;
|
||||
|
||||
flags = MSG_ReadWord( msg );
|
||||
if( flags & SND_LEGACY_LARGE_INDEX )
|
||||
{
|
||||
sound = MSG_ReadWord( msg );
|
||||
flags &= ~SND_LEGACY_LARGE_INDEX;
|
||||
}
|
||||
else
|
||||
sound = MSG_ReadByte( msg );
|
||||
chan = MSG_ReadByte( msg );
|
||||
|
||||
if( FBitSet( flags, SND_VOLUME ))
|
||||
volume = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
else volume = VOL_NORM;
|
||||
|
||||
if( FBitSet( flags, SND_ATTENUATION ))
|
||||
attn = (float)MSG_ReadByte( msg ) / 64.0f;
|
||||
else attn = ATTN_NONE;
|
||||
|
||||
if( FBitSet( flags, SND_PITCH ))
|
||||
pitch = MSG_ReadByte( msg );
|
||||
else pitch = PITCH_NORM;
|
||||
|
||||
// entity reletive
|
||||
entnum = MSG_ReadWord( msg );
|
||||
|
||||
// positioned in space
|
||||
MSG_ReadVec3Coord( msg, pos );
|
||||
|
||||
if( FBitSet( flags, SND_SENTENCE ))
|
||||
{
|
||||
char sentenceName[32];
|
||||
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
|
||||
handle = S_RegisterSound( sentenceName );
|
||||
}
|
||||
else handle = cl.sound_index[sound]; // see precached sound
|
||||
|
||||
if( !cl.audio_prepped )
|
||||
return; // too early
|
||||
|
||||
// g-cont. sound and ambient sound have only difference with channel
|
||||
if( is_ambient )
|
||||
{
|
||||
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StartSound( pos, entnum, chan, handle, volume, attn, pitch, flags );
|
||||
}
|
||||
}
|
||||
/*
|
||||
================
|
||||
CL_PrecacheSound
|
||||
|
||||
prceache sound from server
|
||||
================
|
||||
*/
|
||||
static void CL_LegacyPrecacheSound( sizebuf_t *msg )
|
||||
{
|
||||
int soundIndex;
|
||||
|
||||
soundIndex = MSG_ReadUBitLong( msg, MAX_SOUND_BITS );
|
||||
|
||||
if( soundIndex < 0 || soundIndex >= MAX_SOUNDS )
|
||||
Host_Error( "%s: bad soundindex %i\n", __func__, soundIndex );
|
||||
|
||||
Q_strncpy( cl.sound_precache[soundIndex], MSG_ReadString( msg ), sizeof( cl.sound_precache[0] ));
|
||||
|
||||
// when we loading map all resources is precached sequentially
|
||||
//if( !cl.audio_prepped ) return;
|
||||
|
||||
cl.sound_index[soundIndex] = S_RegisterSound( cl.sound_precache[soundIndex] );
|
||||
}
|
||||
|
||||
static void CL_LegacyPrecacheModel( sizebuf_t *msg )
|
||||
{
|
||||
int modelIndex;
|
||||
string model;
|
||||
|
||||
modelIndex = MSG_ReadUBitLong( msg, MAX_LEGACY_MODEL_BITS );
|
||||
|
||||
if( modelIndex < 0 || modelIndex >= MAX_MODELS )
|
||||
Host_Error( "%s: bad modelindex %i\n", __func__, modelIndex );
|
||||
|
||||
Q_strncpy( model, MSG_ReadString( msg ), sizeof( model ));
|
||||
//Q_strncpy( cl.model_precache[modelIndex], BF_ReadString( msg ), sizeof( cl.model_precache[0] ));
|
||||
|
||||
// when we loading map all resources is precached sequentially
|
||||
//if( !cl.video_prepped ) return;
|
||||
if( modelIndex == 1 && !cl.worldmodel )
|
||||
{
|
||||
CL_ClearWorld ();
|
||||
|
||||
cl.models[modelIndex] = cl.worldmodel = Mod_LoadWorld( model, true );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
//Mod_RegisterModel( cl.model_precache[modelIndex], modelIndex );
|
||||
|
||||
cl.models[modelIndex] = Mod_ForName( model, false, false );
|
||||
cl.nummodels = Q_max( cl.nummodels, modelIndex );
|
||||
}
|
||||
|
||||
static void CL_LegacyPrecacheEvent( sizebuf_t *msg )
|
||||
{
|
||||
int eventIndex;
|
||||
|
||||
eventIndex = MSG_ReadUBitLong( msg, MAX_EVENT_BITS );
|
||||
|
||||
if( eventIndex < 0 || eventIndex >= MAX_EVENTS )
|
||||
Host_Error( "%s: bad eventindex %i\n", __func__, eventIndex );
|
||||
|
||||
Q_strncpy( cl.event_precache[eventIndex], MSG_ReadString( msg ), sizeof( cl.event_precache[0] ));
|
||||
|
||||
// can be set now
|
||||
CL_SetEventIndex( cl.event_precache[eventIndex], eventIndex );
|
||||
}
|
||||
|
||||
#if XASH_LOW_MEMORY == 0
|
||||
#define MAX_LEGACY_RESOURCES 2048
|
||||
#elif XASH_LOW_MEMORY == 2
|
||||
#define MAX_LEGACY_RESOURCES 1
|
||||
#elif XASH_LOW_MEMORY == 1
|
||||
#define MAX_LEGACY_RESOURCES 512
|
||||
#endif
|
||||
/*
|
||||
==============
|
||||
CL_ParseResourceList
|
||||
|
||||
==============
|
||||
*/
|
||||
static void CL_LegacyParseResourceList( sizebuf_t *msg )
|
||||
{
|
||||
int i = 0;
|
||||
static struct
|
||||
{
|
||||
int rescount;
|
||||
int restype[MAX_LEGACY_RESOURCES];
|
||||
char resnames[MAX_LEGACY_RESOURCES][MAX_QPATH];
|
||||
} reslist;
|
||||
|
||||
memset( &reslist, 0, sizeof( reslist ));
|
||||
reslist.rescount = MSG_ReadWord( msg ) - 1;
|
||||
|
||||
if( reslist.rescount > MAX_LEGACY_RESOURCES )
|
||||
Host_Error( "MAX_RESOURCES reached\n" );
|
||||
|
||||
for( i = 0; i < reslist.rescount; i++ )
|
||||
{
|
||||
reslist.restype[i] = MSG_ReadWord( msg );
|
||||
Q_strncpy( reslist.resnames[i], MSG_ReadString( msg ), sizeof( reslist.resnames[i] ));
|
||||
}
|
||||
|
||||
if( cls.demoplayback )
|
||||
return;
|
||||
|
||||
if( !cl_allow_download.value )
|
||||
{
|
||||
Con_DPrintf( "Refusing new resource, cl_allowdownload set to 0\n" );
|
||||
reslist.rescount = 0;
|
||||
}
|
||||
|
||||
if( cls.state == ca_active && !cl_download_ingame.value )
|
||||
{
|
||||
Con_DPrintf( "Refusing new resource, cl_download_ingame set to 0\n" );
|
||||
reslist.rescount = 0;
|
||||
}
|
||||
|
||||
HTTP_ResetProcessState();
|
||||
|
||||
host.downloadcount = 0;
|
||||
|
||||
for( i = 0; i < reslist.rescount; i++ )
|
||||
{
|
||||
char soundpath[MAX_VA_STRING];
|
||||
const char *path;
|
||||
|
||||
if( reslist.restype[i] == t_sound )
|
||||
{
|
||||
Q_snprintf( soundpath, sizeof( soundpath ), DEFAULT_SOUNDPATH "%s", reslist.resnames[i] );
|
||||
|
||||
path = soundpath;
|
||||
}
|
||||
else path = reslist.resnames[i];
|
||||
|
||||
if( FS_FileExists( path, false ))
|
||||
continue; // already exists
|
||||
|
||||
host.downloadcount++;
|
||||
HTTP_AddDownload( path, -1, true, NULL );
|
||||
}
|
||||
|
||||
if( !host.downloadcount )
|
||||
{
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_WriteString( &cls.netchan.message, "continueloading" );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_ParseLegacyServerMessage
|
||||
|
||||
dispatch messages
|
||||
=====================
|
||||
*/
|
||||
void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||
{
|
||||
size_t bufStart, playerbytes;
|
||||
int cmd;
|
||||
int old_background;
|
||||
const char *s;
|
||||
|
||||
// parse the message
|
||||
while( 1 )
|
||||
{
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
{
|
||||
Host_Error( "%s: overflow!\n", __func__ );
|
||||
return;
|
||||
}
|
||||
|
||||
// mark start position
|
||||
bufStart = MSG_GetNumBytesRead( msg );
|
||||
|
||||
// end of message (align bits)
|
||||
if( MSG_GetNumBitsLeft( msg ) < 8 )
|
||||
break;
|
||||
|
||||
cmd = MSG_ReadServerCmd( msg );
|
||||
|
||||
// record command for debugging spew on parse problem
|
||||
CL_Parse_RecordCommand( cmd, bufStart );
|
||||
|
||||
if( CL_ParseCommonDLLMessage( msg, PROTO_LEGACY, cmd, bufStart ))
|
||||
continue;
|
||||
|
||||
// other commands
|
||||
switch( cmd )
|
||||
{
|
||||
case svc_bad:
|
||||
Host_Error( "svc_bad\n" );
|
||||
break;
|
||||
case svc_nop:
|
||||
// this does nothing
|
||||
break;
|
||||
case svc_disconnect:
|
||||
CL_Drop ();
|
||||
Host_AbortCurrentFrame ();
|
||||
break;
|
||||
case svc_legacy_event:
|
||||
CL_ParseEvent( msg, PROTO_LEGACY );
|
||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_legacy_changing:
|
||||
old_background = cl.background;
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
{
|
||||
int maxclients = cl.maxclients;
|
||||
|
||||
// we can only changelevel in singleplayer
|
||||
// and singleplayer always runs in current protocol
|
||||
// cls.changelevel = true;
|
||||
S_StopAllSounds( true );
|
||||
|
||||
Con_Printf( "Server changing, reconnecting\n" );
|
||||
|
||||
if( cls.demoplayback )
|
||||
{
|
||||
SCR_BeginLoadingPlaque( cl.background );
|
||||
cls.changedemo = true;
|
||||
}
|
||||
|
||||
CL_ClearState( );
|
||||
|
||||
// a1ba: need to restore cl.maxclients because engine chooses
|
||||
// frame backups count depending on this value
|
||||
// In general, it's incorrect to call CL_InitEdicts right after
|
||||
// CL_ClearState because of this bug. Some time later this logic
|
||||
// should be re-done.
|
||||
CL_InitEdicts( maxclients ); // re-arrange edicts
|
||||
}
|
||||
else Con_Printf( "Server disconnected, reconnecting\n" );
|
||||
|
||||
if( cls.demoplayback )
|
||||
{
|
||||
cl.background = (cls.demonum != -1) ? true : false;
|
||||
cls.state = ca_connected;
|
||||
}
|
||||
else
|
||||
{
|
||||
// g-cont. local client skip the challenge
|
||||
if( SV_Active( ))
|
||||
cls.state = ca_disconnected;
|
||||
else cls.state = ca_connecting;
|
||||
cl.background = old_background;
|
||||
cls.connect_time = MAX_HEARTBEAT;
|
||||
cls.connect_retry = 0;
|
||||
}
|
||||
break;
|
||||
case svc_setview:
|
||||
CL_ParseViewEntity( msg );
|
||||
break;
|
||||
case svc_sound:
|
||||
CL_LegacyParseSoundPacket( msg, false );
|
||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_legacy_ambientsound:
|
||||
CL_LegacyParseSoundPacket( msg, true );
|
||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
|
||||
break;
|
||||
case svc_time:
|
||||
CL_ParseServerTime( msg, PROTO_LEGACY );
|
||||
break;
|
||||
case svc_print:
|
||||
Con_Printf( "%s", MSG_ReadString( msg ));
|
||||
break;
|
||||
case svc_stufftext:
|
||||
s = MSG_ReadString( msg );
|
||||
if( cl_trace_stufftext.value )
|
||||
{
|
||||
size_t len = Q_strlen( s );
|
||||
Con_Printf( "Stufftext: %s%c", s, len && s[len-1] == '\n' ? '\0' : '\n' );
|
||||
}
|
||||
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
// disable Cry Of Fear antisave protection
|
||||
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
|
||||
break; // too early
|
||||
#endif
|
||||
Cbuf_AddFilteredText( s );
|
||||
break;
|
||||
case svc_setangle:
|
||||
CL_ParseSetAngle( msg );
|
||||
break;
|
||||
case svc_serverdata:
|
||||
Cbuf_Execute(); // make sure any stuffed commands are done
|
||||
CL_ParseServerData( msg, PROTO_LEGACY );
|
||||
break;
|
||||
case svc_lightstyle:
|
||||
CL_ParseLightStyle( msg, PROTO_LEGACY );
|
||||
break;
|
||||
case svc_updateuserinfo:
|
||||
CL_UpdateUserinfo( msg, PROTO_LEGACY );
|
||||
break;
|
||||
case svc_deltatable:
|
||||
Delta_ParseTableField( msg );
|
||||
break;
|
||||
case svc_clientdata:
|
||||
CL_ParseClientData( msg, PROTO_LEGACY );
|
||||
cl.frames[cl.parsecountmod].graphdata.client += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_resource:
|
||||
CL_ParseResource( msg );
|
||||
break;
|
||||
case svc_pings:
|
||||
CL_UpdateUserPings( msg );
|
||||
break;
|
||||
case svc_particle:
|
||||
CL_ParseParticles( msg, PROTO_LEGACY );
|
||||
break;
|
||||
case svc_restoresound:
|
||||
Con_Printf( S_ERROR "%s: svc_restoresound: implement me!\n", __func__ );
|
||||
break;
|
||||
case svc_spawnstatic:
|
||||
CL_LegacyParseStaticEntity( msg );
|
||||
break;
|
||||
case svc_event_reliable:
|
||||
CL_ParseReliableEvent( msg, PROTO_LEGACY );
|
||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_spawnbaseline:
|
||||
CL_ParseBaseline( msg, PROTO_LEGACY );
|
||||
break;
|
||||
case svc_setpause:
|
||||
cl.paused = ( MSG_ReadOneBit( msg ) != 0 );
|
||||
break;
|
||||
case svc_signonnum:
|
||||
CL_ParseSignon( msg, PROTO_LEGACY );
|
||||
break;
|
||||
case svc_centerprint:
|
||||
CL_CenterPrint( MSG_ReadString( msg ), 0.25f );
|
||||
break;
|
||||
case svc_legacy_modelindex:
|
||||
CL_LegacyPrecacheModel( msg );
|
||||
break;
|
||||
case svc_legacy_soundindex:
|
||||
CL_LegacyPrecacheSound( msg );
|
||||
break;
|
||||
case svc_restore:
|
||||
CL_ParseRestore( msg );
|
||||
break;
|
||||
case svc_legacy_eventindex:
|
||||
CL_LegacyPrecacheEvent(msg);
|
||||
break;
|
||||
case svc_bspdecal:
|
||||
CL_ParseStaticDecal( msg );
|
||||
break;
|
||||
case svc_addangle:
|
||||
CL_ParseAddAngle( msg );
|
||||
break;
|
||||
case svc_usermessage:
|
||||
CL_RegisterUserMessage( msg, PROTO_LEGACY );
|
||||
break;
|
||||
case svc_packetentities:
|
||||
playerbytes = CL_ParsePacketEntities( msg, false, PROTO_LEGACY );
|
||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||
break;
|
||||
case svc_deltapacketentities:
|
||||
playerbytes = CL_ParsePacketEntities( msg, true, PROTO_LEGACY );
|
||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||
break;
|
||||
case svc_legacy_chokecount:
|
||||
{
|
||||
int i, j;
|
||||
i = MSG_ReadByte( msg );
|
||||
j = cls.netchan.incoming_acknowledged - 1;
|
||||
for( ; i > 0 && j > cls.netchan.outgoing_sequence - CL_UPDATE_BACKUP; j-- )
|
||||
{
|
||||
if( cl.frames[j & CL_UPDATE_MASK].receivedtime != -3.0 )
|
||||
{
|
||||
cl.frames[j & CL_UPDATE_MASK].choked = true;
|
||||
cl.frames[j & CL_UPDATE_MASK].receivedtime = -2.0;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
//cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = true;
|
||||
//cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].receivedtime = -2.0;
|
||||
break;
|
||||
case svc_resourcelist:
|
||||
CL_LegacyParseResourceList( msg );
|
||||
break;
|
||||
case svc_deltamovevars:
|
||||
CL_ParseMovevars( msg );
|
||||
break;
|
||||
case svc_resourcerequest:
|
||||
CL_ParseResourceRequest( msg );
|
||||
break;
|
||||
case svc_customization:
|
||||
CL_ParseCustomization( msg );
|
||||
break;
|
||||
case svc_crosshairangle:
|
||||
CL_ParseCrosshairAngle( msg );
|
||||
break;
|
||||
case svc_soundfade:
|
||||
CL_ParseSoundFade( msg );
|
||||
break;
|
||||
case svc_filetxferfailed:
|
||||
CL_ParseFileTransferFailed( msg );
|
||||
break;
|
||||
case svc_hltv:
|
||||
CL_ParseHLTV( msg );
|
||||
break;
|
||||
case svc_resourcelocation:
|
||||
CL_ParseResLocation( msg );
|
||||
break;
|
||||
case svc_querycvarvalue:
|
||||
CL_ParseCvarValue( msg, false, PROTO_LEGACY );
|
||||
break;
|
||||
case svc_querycvarvalue2:
|
||||
CL_ParseCvarValue( msg, true, PROTO_LEGACY );
|
||||
break;
|
||||
default:
|
||||
CL_ParseUserMessage( msg, cmd, PROTO_LEGACY );
|
||||
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CL_LegacyPrecache_f( void )
|
||||
{
|
||||
int spawncount, i;
|
||||
model_t *mod;
|
||||
|
||||
if( cls.legacymode != PROTO_LEGACY )
|
||||
return;
|
||||
|
||||
spawncount = Q_atoi( Cmd_Argv( 1 ));
|
||||
|
||||
Con_Printf( "Setting up renderer...\n" );
|
||||
|
||||
// load tempent sprites (glowshell, muzzleflashes etc)
|
||||
CL_LoadClientSprites ();
|
||||
|
||||
// invalidate all decal indexes
|
||||
memset( cl.decal_index, 0, sizeof( cl.decal_index ));
|
||||
cl.video_prepped = true;
|
||||
cl.audio_prepped = true;
|
||||
if( clgame.entities )
|
||||
clgame.entities->model = cl.worldmodel;
|
||||
|
||||
// load skybox
|
||||
R_SetupSky( clgame.movevars.skyName );
|
||||
|
||||
// tell rendering system we have a new set of models.
|
||||
ref.dllFuncs.R_NewMap ();
|
||||
|
||||
CL_SetupOverviewParams();
|
||||
|
||||
// release unused SpriteTextures
|
||||
for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ )
|
||||
{
|
||||
if( mod->needload == NL_UNREFERENCED && COM_CheckString( mod->name ))
|
||||
Mod_FreeModel( mod );
|
||||
}
|
||||
|
||||
// Mod_FreeUnused ();
|
||||
|
||||
if( host_developer.value <= DEV_NONE )
|
||||
Con_ClearNotify(); // clear any lines of console text
|
||||
|
||||
// done with all resources, issue prespawn command.
|
||||
// Include server count in case server disconnects and changes level during d/l
|
||||
MSG_BeginClientCmd( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_WriteStringf( &cls.netchan.message, "begin %i", spawncount );
|
||||
cls.signon = SIGNONS - 1;
|
||||
}
|
||||
@@ -16,8 +16,10 @@ GNU General Public License for more details.
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "net_encode.h"
|
||||
#include "particledef.h"
|
||||
#include "cl_tent.h"
|
||||
#include "shake.h"
|
||||
#include "hltv.h"
|
||||
#include "input.h"
|
||||
#include "server.h"
|
||||
|
||||
@@ -26,11 +28,18 @@ static void CL_ParseExtraInfo( sizebuf_t *msg )
|
||||
string clientfallback;
|
||||
|
||||
Q_strncpy( clientfallback, MSG_ReadString( msg ), sizeof( clientfallback ));
|
||||
if( !COM_StringEmpty( clientfallback ))
|
||||
if( COM_CheckStringEmpty( clientfallback ))
|
||||
Con_Reportf( S_ERROR "%s: TODO: add fallback directory %s!\n", __func__, clientfallback );
|
||||
|
||||
cls.allow_cheats = MSG_ReadByte( msg ) ? true : false;
|
||||
CL_SetCheatState( cl.maxclients > 1, cls.allow_cheats );
|
||||
if( MSG_ReadByte( msg ))
|
||||
{
|
||||
Cvar_FullSet( "sv_cheats", "1", FCVAR_READ_ONLY | FCVAR_SERVER );
|
||||
}
|
||||
else
|
||||
{
|
||||
Cvar_SetCheatState();
|
||||
Cvar_FullSet( "sv_cheats", "0", FCVAR_READ_ONLY | FCVAR_SERVER );
|
||||
}
|
||||
}
|
||||
|
||||
static void CL_ParseNewMovevars( sizebuf_t *msg )
|
||||
@@ -56,12 +65,12 @@ static void CL_ParseNewMovevars( sizebuf_t *msg )
|
||||
clgame.movevars.footsteps = MSG_ReadByte( msg );
|
||||
clgame.movevars.rollangle = MSG_ReadFloat( msg );
|
||||
clgame.movevars.rollspeed = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skycolor[0] = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skycolor[1] = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skycolor[2] = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skyvec[0] = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skyvec[1] = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skyvec[2] = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skycolor_r = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skycolor_g = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skycolor_b = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skyvec_x = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skyvec_y = MSG_ReadFloat( msg );
|
||||
clgame.movevars.skyvec_z = MSG_ReadFloat( msg );
|
||||
|
||||
Q_strncpy( clgame.movevars.skyName, MSG_ReadString( msg ), sizeof( clgame.movevars.skyName ));
|
||||
|
||||
@@ -204,7 +213,6 @@ static void CL_DeltaEntityGS( const delta_header_t *hdr, sizebuf_t *msg, frame_t
|
||||
qboolean newent = from == NULL;
|
||||
int pack = frame->num_entities;
|
||||
qboolean has_update = msg != NULL;
|
||||
static entity_state_t nullent;
|
||||
|
||||
// alloc next slot to store update
|
||||
to = &cls.packet_entities[cls.next_client_entities % cls.num_client_entities];
|
||||
@@ -232,17 +240,7 @@ static void CL_DeltaEntityGS( const delta_header_t *hdr, sizebuf_t *msg, frame_t
|
||||
if( hdr->instanced )
|
||||
from = &cl.instanced_baseline[hdr->instanced_baseline_index];
|
||||
else if( hdr->offset != 0 )
|
||||
{
|
||||
// FIXME: the usage of `offset` is incorrect here as the entities might
|
||||
// not be ordered in cls.packet_entities the same way as on server
|
||||
// catch the error, print the scary message and fix it up to nullent
|
||||
if( cls.next_client_entities - hdr->offset < 0 )
|
||||
{
|
||||
Con_Printf( S_ERROR "%s: prevented delta-ing from invalid entity (%d - %d < 0)\n", __func__, cls.next_client_entities, hdr->offset );
|
||||
from = &nullent;
|
||||
}
|
||||
else from = &cls.packet_entities[(cls.next_client_entities - hdr->offset ) % cls.num_client_entities];
|
||||
}
|
||||
from = &cls.packet_entities[(cls.next_client_entities - hdr->offset) % cls.num_client_entities];
|
||||
else
|
||||
from = &ent->baseline;
|
||||
}
|
||||
@@ -476,7 +474,7 @@ static void CL_ParseSoundPacketGS( sizebuf_t *msg )
|
||||
|
||||
chan = MSG_ReadUBitLong( msg, 3 );
|
||||
entnum = MSG_ReadUBitLong( msg, MAX_GOLDSRC_ENTITY_BITS );
|
||||
if( FBitSet( flags, SND_GOLDSRC_LARGE_INDEX ))
|
||||
if( FBitSet( flags, SND_LEGACY_LARGE_INDEX ))
|
||||
sound = MSG_ReadWord( msg );
|
||||
else sound = MSG_ReadByte( msg );
|
||||
MSG_ReadGSBitVec3Coord( msg, pos );
|
||||
@@ -487,7 +485,7 @@ static void CL_ParseSoundPacketGS( sizebuf_t *msg )
|
||||
|
||||
MSG_EndBitWriting( msg );
|
||||
|
||||
ClearBits( flags, SND_GOLDSRC_LARGE_INDEX );
|
||||
ClearBits( flags, SND_LEGACY_LARGE_INDEX );
|
||||
|
||||
if( FBitSet( flags, SND_SENTENCE ))
|
||||
{
|
||||
@@ -514,26 +512,17 @@ static void CL_ParseSoundPacketGS( sizebuf_t *msg )
|
||||
static void CL_ParseSpawnStaticSound( sizebuf_t *msg )
|
||||
{
|
||||
vec3_t pos;
|
||||
int sound, entnum, pitch, flags;
|
||||
int handle, entnum, pitch, flags;
|
||||
float volume, attn;
|
||||
sound_t handle = 0;
|
||||
|
||||
MSG_ReadVec3Coord( msg, pos );
|
||||
sound = MSG_ReadShort( msg );
|
||||
handle = MSG_ReadShort( msg );
|
||||
volume = MSG_ReadByte( msg ) * ( 1.0f / 255.0f );
|
||||
attn = MSG_ReadByte( msg ) * ( 1.0f / 64.0f );
|
||||
entnum = MSG_ReadShort( msg );
|
||||
pitch = MSG_ReadByte( msg );
|
||||
flags = MSG_ReadByte( msg );
|
||||
|
||||
if( FBitSet( flags, SND_SENTENCE ))
|
||||
{
|
||||
char sentenceName[32];
|
||||
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
|
||||
handle = S_RegisterSound( sentenceName );
|
||||
}
|
||||
else handle = cl.sound_index[sound]; // see precached sound
|
||||
|
||||
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
|
||||
}
|
||||
|
||||
@@ -578,18 +567,25 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
||||
// record command for debugging spew on parse problem
|
||||
CL_Parse_RecordCommand( cmd, bufStart );
|
||||
|
||||
if( CL_ParseCommonMessage( msg, PROTO_GOLDSRC, cmd, bufStart ))
|
||||
continue;
|
||||
|
||||
if( CL_ParseCommonHLMessage( msg, PROTO_GOLDSRC, cmd, bufStart ))
|
||||
if( CL_ParseCommonDLLMessage( msg, PROTO_GOLDSRC, cmd, bufStart ))
|
||||
continue;
|
||||
|
||||
// other commands
|
||||
switch( cmd )
|
||||
{
|
||||
case svc_bad:
|
||||
Host_Error( "svc_bad\n" );
|
||||
break;
|
||||
case svc_nop:
|
||||
case svc_spawnstatic:
|
||||
case svc_goldsrc_damage:
|
||||
case svc_goldsrc_killedmonster:
|
||||
case svc_goldsrc_foundsecret:
|
||||
// this does nothing
|
||||
break;
|
||||
case svc_disconnect:
|
||||
s = MSG_ReadString( msg );
|
||||
if( !COM_StringEmpty( s ))
|
||||
if( COM_CheckStringEmpty( s ))
|
||||
Con_Printf( "Server issued disconnect. Reason: %s\n", s );
|
||||
CL_Drop ();
|
||||
Host_AbortCurrentFrame ();
|
||||
@@ -605,10 +601,47 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
||||
if( param1 != PROTOCOL_GOLDSRC_VERSION )
|
||||
Host_Error( "Server use invalid protocol (%i should be %i)\n", param1, PROTOCOL_GOLDSRC_VERSION );
|
||||
break;
|
||||
case svc_setview:
|
||||
CL_ParseViewEntity( msg );
|
||||
break;
|
||||
case svc_sound:
|
||||
CL_ParseSoundPacketGS( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_time:
|
||||
CL_ParseServerTime( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_print:
|
||||
Con_Printf( "%s", MSG_ReadString( msg ));
|
||||
break;
|
||||
case svc_stufftext:
|
||||
s = MSG_ReadString( msg );
|
||||
if( cl_trace_stufftext.value )
|
||||
{
|
||||
size_t len = Q_strlen( s );
|
||||
Con_Printf( "Stufftext: %s%c", s, len && s[len-1] == '\n' ? '\0' : '\n' );
|
||||
}
|
||||
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
// disable Cry Of Fear antisave protection
|
||||
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
|
||||
break; // too early
|
||||
#endif
|
||||
Cbuf_AddFilteredText( s );
|
||||
break;
|
||||
case svc_setangle:
|
||||
CL_ParseSetAngle( msg );
|
||||
break;
|
||||
case svc_serverdata:
|
||||
Cbuf_Execute(); // make sure any stuffed commands are done
|
||||
CL_ParseServerData( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_lightstyle:
|
||||
CL_ParseLightStyle( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_updateuserinfo:
|
||||
CL_UpdateUserinfo( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_deltatable:
|
||||
Delta_ParseTableField_GS( msg );
|
||||
break;
|
||||
@@ -628,9 +661,8 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
||||
CL_UpdateUserPings( msg );
|
||||
MSG_EndBitWriting( msg );
|
||||
break;
|
||||
case svc_goldsrc_damage:
|
||||
case svc_spawnstatic:
|
||||
// this does nothing
|
||||
case svc_particle:
|
||||
CL_ParseParticles( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_event_reliable:
|
||||
MSG_StartBitWriting( msg );
|
||||
@@ -646,18 +678,35 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
||||
case svc_setpause:
|
||||
cl.paused = ( MSG_ReadByte( msg ) != 0 );
|
||||
break;
|
||||
case svc_goldsrc_killedmonster:
|
||||
case svc_goldsrc_foundsecret:
|
||||
// this does nothing
|
||||
case svc_signonnum:
|
||||
CL_ParseSignon( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_centerprint:
|
||||
CL_CenterPrint( MSG_ReadString( msg ), 0.25f );
|
||||
break;
|
||||
case svc_goldsrc_spawnstaticsound:
|
||||
CL_ParseSpawnStaticSound( msg );
|
||||
break;
|
||||
case svc_finale:
|
||||
CL_ParseFinaleCutscene( msg, 2 );
|
||||
break;
|
||||
case svc_restore:
|
||||
CL_ParseRestore( msg );
|
||||
break;
|
||||
case svc_cutscene:
|
||||
CL_ParseFinaleCutscene( msg, 3 );
|
||||
break;
|
||||
case svc_goldsrc_decalname:
|
||||
param1 = MSG_ReadByte( msg );
|
||||
s = MSG_ReadString( msg );
|
||||
Q_strncpy( host.draw_decals[param1], s, sizeof( host.draw_decals[param1] ));
|
||||
break;
|
||||
case svc_addangle:
|
||||
CL_ParseAddAngle( msg );
|
||||
break;
|
||||
case svc_usermessage:
|
||||
CL_RegisterUserMessage( msg, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_packetentities:
|
||||
playerbytes = CL_ParsePacketEntitiesGS( msg, false );
|
||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||
@@ -668,6 +717,10 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||
break;
|
||||
case svc_choke:
|
||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = true;
|
||||
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].receivedtime = -2.0;
|
||||
break;
|
||||
case svc_resourcelist:
|
||||
MSG_StartBitWriting( msg );
|
||||
CL_ParseResourceList( msg, PROTO_GOLDSRC );
|
||||
@@ -676,6 +729,34 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
||||
case svc_deltamovevars:
|
||||
CL_ParseNewMovevars( msg );
|
||||
break;
|
||||
case svc_resourcerequest:
|
||||
CL_ParseResourceRequest( msg );
|
||||
break;
|
||||
case svc_customization:
|
||||
CL_ParseCustomization( msg );
|
||||
break;
|
||||
case svc_crosshairangle:
|
||||
CL_ParseCrosshairAngle( msg );
|
||||
break;
|
||||
case svc_soundfade:
|
||||
CL_ParseSoundFade( msg );
|
||||
break;
|
||||
case svc_filetxferfailed:
|
||||
CL_ParseFileTransferFailed( msg );
|
||||
break;
|
||||
case svc_hltv:
|
||||
CL_ParseHLTV( msg );
|
||||
break;
|
||||
case svc_voiceinit:
|
||||
CL_ParseVoiceInit( msg );
|
||||
break;
|
||||
case svc_voicedata:
|
||||
CL_ParseVoiceData( msg, PROTO_GOLDSRC );
|
||||
cl.frames[cl.parsecountmod].graphdata.voicebytes += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_resourcelocation:
|
||||
CL_ParseResLocation( msg );
|
||||
break;
|
||||
case svc_goldsrc_sendextrainfo:
|
||||
CL_ParseExtraInfo( msg );
|
||||
break;
|
||||
@@ -685,8 +766,17 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
||||
Con_Reportf( S_ERROR "%s: svc_goldsrc_timescale: implement me!\n", __func__ );
|
||||
MSG_ReadFloat( msg );
|
||||
break;
|
||||
case svc_querycvarvalue:
|
||||
CL_ParseCvarValue( msg, false, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_querycvarvalue2:
|
||||
CL_ParseCvarValue( msg, true, PROTO_GOLDSRC );
|
||||
break;
|
||||
case svc_exec:
|
||||
CL_ParseExec( msg );
|
||||
break;
|
||||
default:
|
||||
CL_ParseUserMessage( msg, cmd, PROTO_GOLDSRC );
|
||||
CL_ParseUserMessage( msg, cmd, PROTO_LEGACY );
|
||||
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
}
|
||||
@@ -18,6 +18,7 @@ GNU General Public License for more details.
|
||||
#include "const.h"
|
||||
#include "cl_tent.h"
|
||||
#include "pm_local.h"
|
||||
#include "particledef.h"
|
||||
#include "studio.h"
|
||||
|
||||
#define MAX_FORWARD 6 // forward probes for set idealpitch
|
||||
@@ -775,7 +776,7 @@ void CL_InitClientMove( void )
|
||||
clgame.pmove->COM_FileSize = COM_FileSize;
|
||||
clgame.pmove->COM_LoadFile = COM_LoadFile;
|
||||
clgame.pmove->COM_FreeFile = COM_FreeFile;
|
||||
clgame.pmove->memfgets = Q_memfgets;
|
||||
clgame.pmove->memfgets = COM_MemFgets;
|
||||
clgame.pmove->PM_PlaySound = pfnPlaySound;
|
||||
clgame.pmove->PM_TraceTexture = PM_CL_TraceTexture;
|
||||
clgame.pmove->PM_PlaybackEventFull = pfnPlaybackEventFull;
|
||||
@@ -826,6 +827,7 @@ static void CL_SetupPMove( playermove_t *pmove, const local_state_t *from, const
|
||||
pmove->flFallVelocity = ps->flFallVelocity;
|
||||
pmove->flSwimTime = (float)cd->flSwimTime;
|
||||
VectorCopy( cd->punchangle, pmove->punchangle );
|
||||
pmove->flNextPrimaryAttack = 0.0f; // not used by PM_ code
|
||||
pmove->effects = ps->effects;
|
||||
pmove->flags = cd->flags;
|
||||
pmove->gravity = ps->gravity;
|
||||
@@ -1009,11 +1011,6 @@ void CL_PredictMovement( qboolean repredicting )
|
||||
if(( cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged ) >= CL_UPDATE_MASK )
|
||||
return;
|
||||
|
||||
// goldsrc checks for intermission here, so it technically allows sending commands
|
||||
// during intermission but completely disables any client updates, predicted or not
|
||||
if( cl.intermission )
|
||||
return;
|
||||
|
||||
// this is the last frame received from the server
|
||||
frame = &cl.frames[cl.parsecountmod];
|
||||
|
||||
@@ -1101,7 +1098,7 @@ void CL_PredictMovement( qboolean repredicting )
|
||||
|
||||
// now interpolate some fraction of the final frame
|
||||
if( to_cmd->senttime != from_cmd->senttime )
|
||||
f = bound( 0.0, ( host.realtime - from_cmd->senttime ) / ( to_cmd->senttime - from_cmd->senttime ), 1.0 );
|
||||
f = bound( 0.0, (host.realtime - from_cmd->senttime) / (to_cmd->senttime - from_cmd->senttime) * 0.1, 1.0 );
|
||||
else f = 0.0;
|
||||
|
||||
if( CL_PlayerTeleported( from, to ))
|
||||
@@ -16,10 +16,11 @@ GNU General Public License for more details.
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "net_encode.h"
|
||||
#include "particledef.h"
|
||||
#include "cl_tent.h"
|
||||
#include "shake.h"
|
||||
#include "hltv.h"
|
||||
#include "input.h"
|
||||
#include "base_cmd.h"
|
||||
|
||||
enum {
|
||||
STAT_HEALTH = 0,
|
||||
@@ -187,7 +188,7 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
||||
int i;
|
||||
|
||||
Con_Reportf( "Serverdata packet received.\n" );
|
||||
cls.timestart = Platform_DoubleTime();
|
||||
cls.timestart = Sys_DoubleTime();
|
||||
|
||||
cls.demowaiting = false; // server is changed
|
||||
|
||||
@@ -213,7 +214,6 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
||||
clgame.maxEntities = bound( 600, clgame.maxEntities, MAX_EDICTS );
|
||||
clgame.maxModels = MAX_MODELS;
|
||||
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), sizeof( clgame.maptitle ));
|
||||
Host_ValidateEngineFeatures( ENGINE_FEATURES_MASK, ENGINE_QUAKE_COMPATIBLE );
|
||||
|
||||
// Re-init hud video, especially if we changed game directories
|
||||
clgame.dllFuncs.pfnVidInit();
|
||||
@@ -239,8 +239,9 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
||||
}
|
||||
else Cvar_DirectSet( &r_decals, NULL );
|
||||
|
||||
// tell the game parts about background state
|
||||
Cvar_DirectFullSet( &cl_background, cl.background ? "1" : "0", FCVAR_READ_ONLY );
|
||||
if( cl.background ) // tell the game parts about background state
|
||||
Cvar_FullSet( "cl_background", "1", FCVAR_READ_ONLY );
|
||||
else Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
|
||||
|
||||
S_StopBackgroundTrack ();
|
||||
|
||||
@@ -266,7 +267,7 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
||||
{
|
||||
pResName = MSG_ReadString( msg );
|
||||
|
||||
if( COM_StringEmptyOrNULL( pResName ))
|
||||
if( !COM_CheckString( pResName ))
|
||||
break; // end of list
|
||||
|
||||
pResource = Mem_Calloc( cls.mempool, sizeof( resource_t ));
|
||||
@@ -284,7 +285,7 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
||||
{
|
||||
pResName = MSG_ReadString( msg );
|
||||
|
||||
if( COM_StringEmptyOrNULL( pResName ))
|
||||
if( !COM_CheckString( pResName ))
|
||||
break; // end of list
|
||||
|
||||
pResource = Mem_Calloc( cls.mempool, sizeof( resource_t ));
|
||||
@@ -839,7 +840,7 @@ static void CL_QuakeExecStuff( void )
|
||||
int argc = 0;
|
||||
|
||||
// check if no commands this frame
|
||||
if( COM_StringEmptyOrNULL( text ))
|
||||
if( !COM_CheckString( text ))
|
||||
return;
|
||||
|
||||
while( 1 )
|
||||
@@ -866,13 +867,7 @@ static void CL_QuakeExecStuff( void )
|
||||
if( argc == 0 )
|
||||
{
|
||||
// debug: find all missed commands and cvars to add them into QWrap
|
||||
cmdalias_t *alias;
|
||||
cmd_t *cmd;
|
||||
convar_t *cvar;
|
||||
|
||||
BaseCmd_FindAll( token, &cmd, &alias, &cvar );
|
||||
|
||||
if( !cvar && !cmd )
|
||||
if( !Cvar_Exists( token ) && !Cmd_Exists( token ))
|
||||
Con_Printf( S_WARN "'%s' is not exist\n", token );
|
||||
// else Msg( "cmd: %s\n", token );
|
||||
|
||||
@@ -930,12 +925,12 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
||||
// record command for debugging spew on parse problem
|
||||
CL_Parse_RecordCommand( cmd, bufStart );
|
||||
|
||||
if( CL_ParseCommonMessage( msg, PROTO_QUAKE, cmd, bufStart ))
|
||||
continue;
|
||||
|
||||
// other commands
|
||||
switch( cmd )
|
||||
{
|
||||
case svc_nop:
|
||||
// this does nothing
|
||||
break;
|
||||
case svc_disconnect:
|
||||
CL_DemoCompleted ();
|
||||
break;
|
||||
@@ -947,6 +942,9 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
||||
if( param1 != PROTOCOL_VERSION_QUAKE )
|
||||
Host_Error( "Server is protocol %i instead of %i\n", param1, PROTOCOL_VERSION_QUAKE );
|
||||
break;
|
||||
case svc_setview:
|
||||
CL_ParseViewEntity( msg );
|
||||
break;
|
||||
case svc_sound:
|
||||
CL_ParseQuakeSound( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
@@ -971,6 +969,9 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
||||
Cbuf_Execute(); // make sure any stuffed commands are done
|
||||
CL_ParseQuakeServerInfo( msg );
|
||||
break;
|
||||
case svc_lightstyle:
|
||||
CL_ParseLightStyle( msg, PROTO_QUAKE );
|
||||
break;
|
||||
case svc_updatename:
|
||||
param1 = MSG_ReadByte( msg );
|
||||
Q_strncpy( cl.players[param1].name, MSG_ReadString( msg ), sizeof( cl.players[0].name ));
|
||||
@@ -1023,7 +1024,8 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
||||
CL_ParseQuakeSignon( msg );
|
||||
break;
|
||||
case svc_centerprint:
|
||||
CL_HudMessage( MSG_ReadString( msg ));
|
||||
str = MSG_ReadString( msg );
|
||||
CL_DispatchUserMessage( "HudText", Q_strlen( str ), (void *)str );
|
||||
break;
|
||||
case svc_killedmonster:
|
||||
CL_DispatchQuakeMessage( "KillMonster" ); // just an event
|
||||
@@ -1034,6 +1036,12 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
||||
case svc_spawnstaticsound:
|
||||
CL_ParseQuakeStaticSound( msg );
|
||||
break;
|
||||
case svc_intermission:
|
||||
cl.intermission = 1;
|
||||
break;
|
||||
case svc_finale:
|
||||
CL_ParseFinaleCutscene( msg, 2 );
|
||||
break;
|
||||
case svc_cdtrack:
|
||||
param1 = MSG_ReadByte( msg );
|
||||
param1 = bound( 0, param1, MAX_CDTRACKS - 1 ); // tracknum
|
||||
@@ -1046,12 +1054,15 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
||||
case svc_sellscreen:
|
||||
Cmd_ExecuteString( "help" ); // open quake menu
|
||||
break;
|
||||
case svc_showlmp:
|
||||
CL_ParseNehahraShowLMP( msg );
|
||||
case svc_cutscene:
|
||||
CL_ParseFinaleCutscene( msg, 3 );
|
||||
break;
|
||||
case svc_hidelmp:
|
||||
CL_ParseNehahraHideLMP( msg );
|
||||
break;
|
||||
case svc_showlmp:
|
||||
CL_ParseNehahraShowLMP( msg );
|
||||
break;
|
||||
case svc_skybox:
|
||||
Q_strncpy( clgame.movevars.skyName, MSG_ReadString( msg ), sizeof( clgame.movevars.skyName ));
|
||||
break;
|
||||
@@ -356,9 +356,8 @@ static void CL_AllocRemapInfo( cl_entity_t *entity, model_t *model, int topcolor
|
||||
|
||||
if( model->type == mod_studio )
|
||||
{
|
||||
phdr = (studiohdr_t *)model->cache.data;
|
||||
if( !phdr )
|
||||
return; // bad model?
|
||||
phdr = (studiohdr_t *)Mod_StudioExtradata( model );
|
||||
if( !phdr ) return; // bad model?
|
||||
|
||||
src = (mstudiotexture_t *)(((byte *)phdr) + phdr->textureindex);
|
||||
|
||||
@@ -397,9 +396,8 @@ static void CL_AllocRemapInfo( cl_entity_t *entity, model_t *model, int topcolor
|
||||
}
|
||||
else if( model->type == mod_alias )
|
||||
{
|
||||
ahdr = (aliashdr_t *)model->cache.data;
|
||||
if( !ahdr )
|
||||
return; // bad model?
|
||||
ahdr = (aliashdr_t *)Mod_AliasExtradata( model );
|
||||
if( !ahdr ) return; // bad model?
|
||||
|
||||
// NOTE: we must copy all the structures 'mstudiotexture_t' for easy access when model is rendering
|
||||
if( !clgame.remap_info[i] || clgame.remap_info[i]->model != model )
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user