mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 19:45:05 +08:00
Compare commits
20 Commits
gha-arm
...
continuous
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aa02f54536 | ||
|
|
ac162b33e9 | ||
|
|
54091b0875 | ||
|
|
0b65f87bb1 | ||
|
|
2553f376ae | ||
|
|
4e6babbd4d | ||
|
|
f7db736340 | ||
|
|
d038162903 | ||
|
|
99f33fb406 | ||
|
|
27c851f071 | ||
|
|
09f3998cda | ||
|
|
4c159015e4 | ||
|
|
35b63ca647 | ||
|
|
4a4086e27c | ||
|
|
b3c2e5568d | ||
|
|
232a3163ff | ||
|
|
aacdde1522 | ||
|
|
54d737fe3e | ||
|
|
b43105f13d | ||
|
|
6661ec3090 |
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
|
||||
|
||||
53
.github/workflows/c-cpp.yml
vendored
53
.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
|
||||
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
13
3rdparty/libbacktrace/wscript
vendored
13
3rdparty/libbacktrace/wscript
vendored
@@ -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'),
|
||||
@@ -162,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']
|
||||
|
||||
1
3rdparty/library_suffix
vendored
1
3rdparty/library_suffix
vendored
Submodule 3rdparty/library_suffix deleted from 5b670f638b
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: e198199f6c...c62ab29356
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. |
|
||||
@@ -42,6 +42,3 @@ Issue #3: Some mods (like The Specialists, Tyrian, ...) already apply suffixes _
|
||||
Resolution: On x86 on **Win/Lin/Mac**, don't change anything. Otherwise, strip the _i?86 part and follow the usual scheme.
|
||||
|
||||
See discussion: https://github.com/FWGS/xash3d-fwgs/issues/39
|
||||
|
||||
Issue #4: When distributing game libraries on Android inside an APK, they couldn't be loaded.
|
||||
Resolution: Enable `useLegacyPackaging` option in build.gradle, when distributing games in APK. Always force game libraries to have `lib` prefix on Android, regardless if they are packaged in APK or not..
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
filename.ext - do not include this file, only copy the header
|
||||
Copyright (C) 2015-2025 Xash3D FWGS contributors
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
@@ -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 client dylibs to `build/ios/cl_dlls` and any other dylibs to `build/ios/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 {
|
||||
@@ -23,7 +23,7 @@ extensions.configure<ApplicationExtension> {
|
||||
externalNativeBuild {
|
||||
val engineRoot = projectDir.parentFile.parent
|
||||
|
||||
experimentalProperties["ninja.abiFilters"] = setOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
|
||||
experimentalProperties["ninja.abiFilters"] = setOf("armeabi-v7a", "arm64-v8a")
|
||||
experimentalProperties["ninja.path"] = File(engineRoot, "wscript").path
|
||||
experimentalProperties["ninja.configure"] = "run-python"
|
||||
experimentalProperties["ninja.arguments"] = setOf(
|
||||
@@ -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}"
|
||||
@@ -62,23 +62,20 @@ extensions.configure<ApplicationExtension> {
|
||||
abortOnError = false
|
||||
}
|
||||
|
||||
/*
|
||||
androidResources {
|
||||
noCompress += ""
|
||||
}
|
||||
*/
|
||||
|
||||
packaging {
|
||||
jniLibs {
|
||||
keepDebugSymbols.add("**/*.so")
|
||||
useLegacyPackaging = true
|
||||
}
|
||||
}
|
||||
|
||||
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 -->
|
||||
@@ -57,8 +57,7 @@
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher"
|
||||
android:theme="@style/Theme.App"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:requestLegacyExternalStorage="true">
|
||||
android:usesCleartextTraffic="true">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true">
|
||||
@@ -81,9 +80,4 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="su.xash.engine.MOD" />
|
||||
</intent>
|
||||
</queries>
|
||||
</manifest>
|
||||
|
||||
@@ -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,7 +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)
|
||||
} ilFlags_t;
|
||||
|
||||
// goes into rgbdata_t->encode
|
||||
@@ -149,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;
|
||||
|
||||
@@ -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,115 +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
|
||||
|
||||
// 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
|
||||
@@ -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 );
|
||||
|
||||
|
||||
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,36 +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 ))
|
||||
#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 XASH_RESTRICT // nothing
|
||||
#endif
|
||||
|
||||
#ifdef 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 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 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 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"
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
@@ -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 )
|
||||
@@ -257,7 +263,7 @@ static void AVI_StreamAudio( movie_state_t *Avi )
|
||||
// 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 ? !s_listener.streaming : false;
|
||||
|
||||
if( !dma.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 );
|
||||
@@ -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 )
|
||||
@@ -840,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 )
|
||||
{
|
||||
;
|
||||
|
||||
@@ -38,23 +38,23 @@ GNU General Public License for more details.
|
||||
#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
|
||||
@@ -116,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;
|
||||
}
|
||||
@@ -1118,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;
|
||||
@@ -1150,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 )
|
||||
{
|
||||
@@ -1232,7 +1232,7 @@ void GAME_EXPORT R_Blood( const vec3_t org, const vec3_t ndir, int pcolor, int s
|
||||
|
||||
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 );
|
||||
@@ -1263,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 );
|
||||
@@ -1284,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 );
|
||||
@@ -1306,7 +1306,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;
|
||||
|
||||
p->org[0] = org[0] + COM_RandomFloat( -1.0f, 1.0f );
|
||||
p->org[1] = org[1] + COM_RandomFloat( -1.0f, 1.0f );
|
||||
@@ -1898,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;
|
||||
}
|
||||
@@ -1996,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;
|
||||
@@ -2015,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;
|
||||
@@ -2154,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 );
|
||||
@@ -2185,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 );
|
||||
@@ -2194,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;
|
||||
@@ -2217,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++ )
|
||||
|
||||
@@ -68,15 +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 )
|
||||
{
|
||||
// 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] );
|
||||
}
|
||||
|
||||
qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, convar_t *rendermode, uint texFlags )
|
||||
{
|
||||
int font_width, i;
|
||||
@@ -172,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;
|
||||
|
||||
@@ -231,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];
|
||||
@@ -241,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 )
|
||||
@@ -252,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 )
|
||||
{
|
||||
@@ -273,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;
|
||||
}
|
||||
|
||||
@@ -281,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++;
|
||||
}
|
||||
@@ -333,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];
|
||||
|
||||
@@ -1242,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
|
||||
|
||||
@@ -112,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
|
||||
@@ -270,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;
|
||||
@@ -433,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;
|
||||
@@ -463,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;
|
||||
}
|
||||
@@ -584,7 +579,7 @@ static void CL_InitTitles( const char *filename )
|
||||
pMemFile = FS_LoadFile( filename, &fileSize, false );
|
||||
if( !pMemFile ) return;
|
||||
|
||||
clgame.titles = CL_TextMessageParse( clgame.mempool, (char *)pMemFile, fileSize, &clgame.numTitles );
|
||||
CL_TextMessageParse( pMemFile, fileSize );
|
||||
Mem_Free( pMemFile );
|
||||
}
|
||||
|
||||
@@ -597,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 );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1117,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)
|
||||
@@ -1293,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 );
|
||||
@@ -1324,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;
|
||||
@@ -1356,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
|
||||
}
|
||||
|
||||
@@ -1843,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
|
||||
@@ -1861,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 )
|
||||
@@ -1886,7 +1874,7 @@ pfnFilteredClientCmd
|
||||
*/
|
||||
static int GAME_EXPORT pfnFilteredClientCmd( const char *szCmdString )
|
||||
{
|
||||
if( COM_StringEmptyOrNULL( szCmdString ))
|
||||
if( !COM_CheckString( szCmdString ))
|
||||
return 0;
|
||||
|
||||
// a1ba:
|
||||
@@ -2068,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
|
||||
@@ -2440,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 ));
|
||||
@@ -2741,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
|
||||
|
||||
@@ -2812,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:
|
||||
@@ -2925,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 );
|
||||
@@ -2942,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 );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3219,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 );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3499,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 );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3962,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 );
|
||||
@@ -3980,7 +3962,6 @@ qboolean CL_LoadProgs( const char *name )
|
||||
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();
|
||||
@@ -4001,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 );
|
||||
|
||||
@@ -4012,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__ );
|
||||
|
||||
@@ -4040,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 )
|
||||
@@ -4054,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;
|
||||
@@ -4081,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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -16,11 +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 "eiface.h"
|
||||
|
||||
#if XASH_LOW_MEMORY != 2
|
||||
int CL_UPDATE_BACKUP = SINGLEPLAYER_BACKUP;
|
||||
#endif
|
||||
@@ -57,14 +57,13 @@ CL_ParseSoundPacket
|
||||
|
||||
==================
|
||||
*/
|
||||
static void CL_ParseSoundPacket( sizebuf_t *msg, qboolean restore )
|
||||
static void CL_ParseSoundPacket( sizebuf_t *msg )
|
||||
{
|
||||
vec3_t pos;
|
||||
int chan, sound;
|
||||
float volume, attn;
|
||||
int flags, pitch, entnum, wordIndex = 0;
|
||||
int flags, pitch, entnum;
|
||||
sound_t handle = 0;
|
||||
double samplePos = 0, forcedEnd = 0;
|
||||
|
||||
flags = MSG_ReadUBitLong( msg, MAX_SND_FLAGS_BITS );
|
||||
sound = MSG_ReadUBitLong( msg, MAX_SOUND_BITS );
|
||||
@@ -100,24 +99,80 @@ static void CL_ParseSoundPacket( sizebuf_t *msg, qboolean restore )
|
||||
}
|
||||
else handle = cl.sound_index[sound]; // see precached sound
|
||||
|
||||
if( restore )
|
||||
{
|
||||
wordIndex = MSG_ReadByte( msg );
|
||||
if( !cl.audio_prepped )
|
||||
return; // too early
|
||||
|
||||
// 16 bytes here
|
||||
MSG_ReadBytes( msg, &samplePos, sizeof( samplePos ));
|
||||
MSG_ReadBytes( msg, &forcedEnd, sizeof( forcedEnd ));
|
||||
// g-cont. sound and ambient sound have only difference with channel
|
||||
if( chan == CHAN_STATIC )
|
||||
{
|
||||
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StartSound( pos, entnum, chan, handle, volume, attn, pitch, flags );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ParseRestoreSoundPacket
|
||||
|
||||
==================
|
||||
*/
|
||||
void CL_ParseRestoreSoundPacket( sizebuf_t *msg )
|
||||
{
|
||||
vec3_t pos;
|
||||
int chan, sound;
|
||||
float volume, attn;
|
||||
int flags, pitch, entnum;
|
||||
double samplePos, forcedEnd;
|
||||
int wordIndex;
|
||||
sound_t handle = 0;
|
||||
|
||||
flags = MSG_ReadUBitLong( msg, MAX_SND_FLAGS_BITS );
|
||||
sound = MSG_ReadUBitLong( msg, MAX_SOUND_BITS );
|
||||
chan = MSG_ReadUBitLong( msg, MAX_SND_CHAN_BITS );
|
||||
|
||||
if( flags & SND_VOLUME )
|
||||
volume = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
else volume = VOL_NORM;
|
||||
|
||||
if( flags & SND_ATTENUATION )
|
||||
attn = (float)MSG_ReadByte( msg ) / 64.0f;
|
||||
else attn = ATTN_NONE;
|
||||
|
||||
if( flags & SND_PITCH )
|
||||
pitch = MSG_ReadByte( msg );
|
||||
else pitch = PITCH_NORM;
|
||||
|
||||
// entity reletive
|
||||
entnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
|
||||
|
||||
// positioned in space
|
||||
MSG_ReadVec3Coord( msg, pos );
|
||||
|
||||
if( flags & SND_SENTENCE )
|
||||
{
|
||||
char sentenceName[32];
|
||||
|
||||
if( flags & SND_SEQUENCE )
|
||||
Q_snprintf( sentenceName, sizeof( sentenceName ), "!#%i", sound + MAX_SOUNDS_NONSENTENCE );
|
||||
else Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
|
||||
|
||||
handle = S_RegisterSound( sentenceName );
|
||||
}
|
||||
else handle = cl.sound_index[sound]; // see precached sound
|
||||
|
||||
wordIndex = MSG_ReadByte( msg );
|
||||
|
||||
// 16 bytes here
|
||||
MSG_ReadBytes( msg, &samplePos, sizeof( samplePos ));
|
||||
MSG_ReadBytes( msg, &forcedEnd, sizeof( forcedEnd ));
|
||||
|
||||
if( !cl.audio_prepped )
|
||||
return; // too early
|
||||
|
||||
if( restore )
|
||||
S_RestoreSound( pos, entnum, chan, handle, volume, attn, pitch, flags, samplePos, forcedEnd, wordIndex );
|
||||
else if( chan == CHAN_STATIC )
|
||||
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
|
||||
else
|
||||
S_StartSound( pos, entnum, chan, handle, volume, attn, pitch, flags );
|
||||
S_RestoreSound( pos, entnum, chan, handle, volume, attn, pitch, flags, samplePos, forcedEnd, wordIndex );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -364,12 +419,15 @@ CL_ParseSoundFade
|
||||
*/
|
||||
void CL_ParseSoundFade( sizebuf_t *msg )
|
||||
{
|
||||
int fade_percent = MSG_ReadByte( msg );
|
||||
int hold_time = MSG_ReadByte( msg );
|
||||
int fade_out_seconds = MSG_ReadByte( msg );
|
||||
int fade_in_seconds = MSG_ReadByte( msg );
|
||||
float fadePercent, fadeOutSeconds;
|
||||
float holdTime, fadeInSeconds;
|
||||
|
||||
S_SoundFade( fade_percent, hold_time, fade_out_seconds, fade_in_seconds );
|
||||
fadePercent = (float)MSG_ReadByte( msg );
|
||||
holdTime = (float)MSG_ReadByte( msg );
|
||||
fadeOutSeconds = (float)MSG_ReadByte( msg );
|
||||
fadeInSeconds = (float)MSG_ReadByte( msg );
|
||||
|
||||
S_FadeClientVolume( fadePercent, fadeOutSeconds, holdTime, fadeInSeconds );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -540,7 +598,7 @@ static void CL_StartResourceDownloading( const char *pszMessage, qboolean bCusto
|
||||
{
|
||||
resourceinfo_t ri;
|
||||
|
||||
if( !COM_StringEmptyOrNULL( pszMessage ))
|
||||
if( COM_CheckString( pszMessage ))
|
||||
Con_DPrintf( "%s", pszMessage );
|
||||
|
||||
cls.dl.nTotalSize = COM_SizeofResourceList( &cl.resourcesneeded, &ri );
|
||||
@@ -802,11 +860,16 @@ void CL_ParseServerData( sizebuf_t *msg, connprotocol_t proto )
|
||||
string mapfile;
|
||||
qboolean background;
|
||||
int i, required_version;
|
||||
uint32_t mapCRC;
|
||||
|
||||
HPAK_CheckSize( hpk_custom_file.string );
|
||||
|
||||
switch( proto )
|
||||
{
|
||||
case PROTO_LEGACY:
|
||||
required_version = PROTOCOL_LEGACY_VERSION;
|
||||
Con_Reportf( "Legacy serverdata packet received.\n" );
|
||||
break;
|
||||
case PROTO_GOLDSRC:
|
||||
required_version = PROTOCOL_GOLDSRC_VERSION;
|
||||
Con_Reportf( "GoldSrc serverdata packet received.\n" );
|
||||
@@ -817,7 +880,7 @@ void CL_ParseServerData( sizebuf_t *msg, connprotocol_t proto )
|
||||
break;
|
||||
}
|
||||
|
||||
cls.timestart = Platform_DoubleTime();
|
||||
cls.timestart = Sys_DoubleTime();
|
||||
cls.demowaiting = false; // server is changed
|
||||
|
||||
// wipe the client_t struct
|
||||
@@ -854,7 +917,7 @@ void CL_ParseServerData( sizebuf_t *msg, connprotocol_t proto )
|
||||
COM_StripExtension( clgame.mapname );
|
||||
|
||||
s = MSG_ReadString( msg );
|
||||
if( !COM_StringEmpty( s ))
|
||||
if( COM_CheckStringEmpty( s ))
|
||||
Con_Printf( "Server map cycle: %s\n", s ); // VALVEWHY?
|
||||
|
||||
if( MSG_ReadByte( msg ))
|
||||
@@ -862,7 +925,7 @@ void CL_ParseServerData( sizebuf_t *msg, connprotocol_t proto )
|
||||
|
||||
background = false;
|
||||
clgame.maxEntities = GI->max_edicts + (( cl.maxclients - 1 ) * 15 );
|
||||
clgame.maxEntities = Q_min( clgame.maxEntities, MAX_GOLDSRC_EDICTS );
|
||||
clgame.maxEntities = bound( MIN_LEGACY_EDICTS, clgame.maxEntities, MAX_GOLDSRC_EDICTS );
|
||||
clgame.maxModels = 512; // ???
|
||||
Q_strncpy( clgame.maptitle, clgame.mapname, sizeof( clgame.maptitle ));
|
||||
|
||||
@@ -870,22 +933,37 @@ void CL_ParseServerData( sizebuf_t *msg, connprotocol_t proto )
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t mask;
|
||||
|
||||
cl.playernum = MSG_ReadByte( msg );
|
||||
cl.maxclients = MSG_ReadByte( msg );
|
||||
clgame.maxEntities = MSG_ReadWord( msg );
|
||||
clgame.maxEntities = bound( MIN_EDICTS, clgame.maxEntities, MAX_EDICTS );
|
||||
clgame.maxModels = MSG_ReadWord( msg );
|
||||
if( proto == PROTO_LEGACY )
|
||||
{
|
||||
clgame.maxEntities = bound( MIN_LEGACY_EDICTS, clgame.maxEntities, MAX_LEGACY_EDICTS );
|
||||
clgame.maxModels = 512; // ???
|
||||
mask = ENGINE_LEGACY_FEATURES_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
clgame.maxEntities = bound( MIN_EDICTS, clgame.maxEntities, MAX_EDICTS );
|
||||
clgame.maxModels = MSG_ReadWord( msg );
|
||||
mask = ENGINE_FEATURES_MASK;
|
||||
}
|
||||
Q_strncpy( clgame.mapname, MSG_ReadString( msg ), sizeof( clgame.mapname ));
|
||||
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), sizeof( clgame.maptitle ));
|
||||
background = MSG_ReadOneBit( msg );
|
||||
Q_strncpy( gamefolder, MSG_ReadString( msg ), sizeof( gamefolder ));
|
||||
Host_ValidateEngineFeatures( ENGINE_FEATURES_MASK, MSG_ReadDword( msg ));
|
||||
Host_ValidateEngineFeatures( mask, MSG_ReadDword( msg ));
|
||||
|
||||
// receive the player hulls
|
||||
for( i = 0; i < MAX_MAP_HULLS * 3; i++ )
|
||||
if( proto != PROTO_LEGACY )
|
||||
{
|
||||
host.player_mins[i/3][i%3] = MSG_ReadChar( msg );
|
||||
host.player_maxs[i/3][i%3] = MSG_ReadChar( msg );
|
||||
// receive the player hulls
|
||||
for( i = 0; i < MAX_MAP_HULLS * 3; i++ )
|
||||
{
|
||||
host.player_mins[i/3][i%3] = MSG_ReadChar( msg );
|
||||
host.player_maxs[i/3][i%3] = MSG_ReadChar( msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -925,17 +1003,14 @@ void CL_ParseServerData( sizebuf_t *msg, connprotocol_t proto )
|
||||
}
|
||||
else Cvar_DirectSet( &r_decals, NULL );
|
||||
|
||||
// for GoldSrc, it's handled by svc_goldsrc_sendextrainfo
|
||||
if( proto != PROTO_GOLDSRC )
|
||||
CL_SetCheatState( cl.maxclients > 1, cls.allow_cheats );
|
||||
|
||||
// set the background state
|
||||
if( cls.demoplayback && ( cls.demonum != -1 ))
|
||||
cl.background = true;
|
||||
else cl.background = background;
|
||||
|
||||
// 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 );
|
||||
|
||||
if( !cls.changelevel )
|
||||
{
|
||||
@@ -982,7 +1057,7 @@ void CL_ParseServerData( sizebuf_t *msg, connprotocol_t proto )
|
||||
{
|
||||
CL_ServerCommand( true, "sendres" );
|
||||
}
|
||||
else
|
||||
else if( proto != PROTO_LEGACY )
|
||||
{
|
||||
CL_ServerCommand( true, "sendres %i\n", cl.servercount );
|
||||
}
|
||||
@@ -1143,7 +1218,7 @@ void CL_ParseClientData( sizebuf_t *msg, connprotocol_t proto )
|
||||
if( !MSG_ReadOneBit( msg )) break;
|
||||
|
||||
// read the weapon idx
|
||||
idx = MSG_ReadUBitLong( msg, MAX_WEAPON_BITS );
|
||||
idx = MSG_ReadUBitLong( msg, proto == PROTO_LEGACY ? MAX_LEGACY_WEAPON_BITS : MAX_WEAPON_BITS );
|
||||
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
Delta_ReadGSFields( msg, DT_WEAPONDATA_T, &from_wd[idx], &to_wd[idx], cl.mtime[0] );
|
||||
@@ -1176,7 +1251,11 @@ void CL_ParseBaseline( sizebuf_t *msg, connprotocol_t proto )
|
||||
qboolean player;
|
||||
int newnum;
|
||||
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
if( proto == PROTO_LEGACY )
|
||||
{
|
||||
newnum = MSG_ReadWord( msg );
|
||||
}
|
||||
else if( proto == PROTO_GOLDSRC )
|
||||
{
|
||||
uint value = MSG_ReadWord( msg );
|
||||
|
||||
@@ -1213,18 +1292,26 @@ void CL_ParseBaseline( sizebuf_t *msg, connprotocol_t proto )
|
||||
ent->baseline.entityType = type;
|
||||
}
|
||||
else MSG_ReadDeltaEntity( msg, &nullstate, &ent->baseline, newnum, player, 1.0f );
|
||||
|
||||
if( proto == PROTO_LEGACY )
|
||||
break; // only one baseline allowed in legacy protocol
|
||||
}
|
||||
|
||||
cl.instanced_baseline_count = MSG_ReadUBitLong( msg, 6 );
|
||||
|
||||
for( int i = 0; i < cl.instanced_baseline_count; i++ )
|
||||
if( proto != PROTO_LEGACY )
|
||||
{
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
Delta_ReadGSFields( msg, DT_ENTITY_STATE_T, &nullstate, &cl.instanced_baseline[i], 1.0f );
|
||||
else
|
||||
int i;
|
||||
|
||||
cl.instanced_baseline_count = MSG_ReadUBitLong( msg, 6 );
|
||||
|
||||
for( i = 0; i < cl.instanced_baseline_count; i++ )
|
||||
{
|
||||
int newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
|
||||
MSG_ReadDeltaEntity( msg, &nullstate, &cl.instanced_baseline[i], newnum, false, 1.0f );
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
Delta_ReadGSFields( msg, DT_ENTITY_STATE_T, &nullstate, &cl.instanced_baseline[i], 1.0f );
|
||||
else
|
||||
{
|
||||
int newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
|
||||
MSG_ReadDeltaEntity( msg, &nullstate, &cl.instanced_baseline[i], newnum, false, 1.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1344,7 +1431,7 @@ void CL_RegisterUserMessage( sizebuf_t *msg, connprotocol_t proto )
|
||||
int size;
|
||||
int svc_num = MSG_ReadByte( msg );
|
||||
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
if( proto == PROTO_LEGACY || proto == PROTO_GOLDSRC )
|
||||
{
|
||||
size = MSG_ReadByte( msg );
|
||||
if( size == UINT8_MAX )
|
||||
@@ -1387,6 +1474,12 @@ void CL_UpdateUserinfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
id = MSG_ReadLong( msg );
|
||||
active = true;
|
||||
}
|
||||
else if( proto == PROTO_LEGACY )
|
||||
{
|
||||
slot = MSG_ReadUBitLong( msg, MAX_CLIENT_BITS );
|
||||
id = 0; // bogus
|
||||
active = MSG_ReadOneBit( msg ) ? true : false;
|
||||
}
|
||||
else
|
||||
{
|
||||
slot = MSG_ReadUBitLong( msg, MAX_CLIENT_BITS );
|
||||
@@ -1407,9 +1500,10 @@ void CL_UpdateUserinfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
player->topcolor = Q_atoi( Info_ValueForKey( player->userinfo, "topcolor" ));
|
||||
player->bottomcolor = Q_atoi( Info_ValueForKey( player->userinfo, "bottomcolor" ));
|
||||
player->spectator = Q_atoi( Info_ValueForKey( player->userinfo, "*hltv" ));
|
||||
MSG_ReadBytes( msg, player->hashedcdkey, sizeof( player->hashedcdkey ));
|
||||
if( proto != PROTO_LEGACY )
|
||||
MSG_ReadBytes( msg, player->hashedcdkey, sizeof( player->hashedcdkey ));
|
||||
|
||||
if( proto == PROTO_GOLDSRC && ( COM_StringEmpty( player->userinfo ) || COM_StringEmpty( player->name )))
|
||||
if( proto == PROTO_GOLDSRC && ( !COM_CheckStringEmpty( player->userinfo ) || !COM_CheckStringEmpty( player->name )))
|
||||
active = false;
|
||||
|
||||
if( active && slot == cl.playernum )
|
||||
@@ -1539,11 +1633,13 @@ static const char *CL_CheckTypeToString( int check_type )
|
||||
|
||||
static void CL_SendConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
{
|
||||
qboolean user_changed_diskfile;
|
||||
vec3_t mins, maxs;
|
||||
string filename;
|
||||
byte md5[16] = { 0 };
|
||||
int pos;
|
||||
qboolean user_changed_diskfile;
|
||||
vec3_t mins, maxs;
|
||||
string filename;
|
||||
CRC32_t crcFile;
|
||||
byte md5[16] = { 0 };
|
||||
consistency_t *pc;
|
||||
int i, pos;
|
||||
|
||||
if( !cl.need_force_consistency_response )
|
||||
return;
|
||||
@@ -1559,10 +1655,11 @@ static void CL_SendConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
|
||||
FS_AllowDirectPaths( true );
|
||||
|
||||
for( int i = 0; i < cl.num_consistency; i++ )
|
||||
for( i = 0; i < cl.num_consistency; i++ )
|
||||
{
|
||||
qboolean have_file = true;
|
||||
consistency_t *pc = &cl.consistency_list[i];
|
||||
|
||||
pc = &cl.consistency_list[i];
|
||||
|
||||
user_changed_diskfile = false;
|
||||
MSG_WriteOneBit( msg, 1 );
|
||||
@@ -1577,7 +1674,6 @@ static void CL_SendConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
|
||||
if( Q_strstr( filename, "models/" ) && have_file )
|
||||
{
|
||||
uint32_t crcFile;
|
||||
CRC32_Init( &crcFile );
|
||||
CRC32_File( &crcFile, filename );
|
||||
crcFile = CRC32_Final( crcFile );
|
||||
@@ -1746,7 +1842,7 @@ void CL_RegisterResources( sizebuf_t *msg, connprotocol_t proto )
|
||||
// release unused SpriteTextures
|
||||
for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ )
|
||||
{
|
||||
if( mod->needload == NL_FREE_UNUSED )
|
||||
if( mod->needload == NL_UNREFERENCED && COM_CheckString( mod->name ))
|
||||
Mod_FreeModel( mod );
|
||||
}
|
||||
|
||||
@@ -1922,14 +2018,10 @@ void CL_ParseVoiceData( sizebuf_t *msg, connprotocol_t proto )
|
||||
if ( idx <= 0 || idx > cl.maxclients )
|
||||
return;
|
||||
|
||||
// must notify client.dll about server ack'ing our local client voice data
|
||||
if( idx == cl.playernum + 1 )
|
||||
Voice_LoopbackAck();
|
||||
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
{
|
||||
size = MSG_ReadShort( msg );
|
||||
if( size > VOICE_MAX_GS_DATA_SIZE )
|
||||
if ( size > VOICE_MAX_GS_DATA_SIZE )
|
||||
{
|
||||
Con_Printf( S_ERROR "Voice data size is too large: %d bytes (max: %d)\n", size, VOICE_MAX_GS_DATA_SIZE );
|
||||
return;
|
||||
@@ -1939,7 +2031,7 @@ void CL_ParseVoiceData( sizebuf_t *msg, connprotocol_t proto )
|
||||
{
|
||||
frames = MSG_ReadByte( msg );
|
||||
size = MSG_ReadShort( msg );
|
||||
if( size > VOICE_MAX_DATA_SIZE )
|
||||
if (size > VOICE_MAX_DATA_SIZE )
|
||||
{
|
||||
Con_Printf( S_ERROR "Voice data size is too large: %d bytes (max: %d)\n", size, VOICE_MAX_DATA_SIZE );
|
||||
return;
|
||||
@@ -1987,8 +2079,6 @@ CL_ParseHLTV
|
||||
|
||||
spectator message (hltv)
|
||||
sended from game.dll
|
||||
|
||||
normal client ignores any of HLTV messages
|
||||
==============
|
||||
*/
|
||||
void CL_ParseHLTV( sizebuf_t *msg )
|
||||
@@ -2000,16 +2090,21 @@ void CL_ParseHLTV( sizebuf_t *msg )
|
||||
cls.spectator = true;
|
||||
break;
|
||||
case HLTV_STATUS:
|
||||
MSG_ReadLong( msg );
|
||||
MSG_ReadShort( msg );
|
||||
MSG_ReadWord( msg );
|
||||
MSG_ReadLong( msg );
|
||||
MSG_ReadLong( msg );
|
||||
MSG_ReadWord( msg );
|
||||
MSG_ReadLong( msg );
|
||||
MSG_ReadShort( msg );
|
||||
MSG_ReadWord( msg );
|
||||
MSG_ReadLong( msg );
|
||||
MSG_ReadLong( msg );
|
||||
MSG_ReadWord( msg );
|
||||
break;
|
||||
case HLTV_LISTEN:
|
||||
cls.signon = SIGNONS;
|
||||
#if 1
|
||||
MSG_ReadString( msg );
|
||||
#else
|
||||
NET_StringToAdr( MSG_ReadString( msg ), &cls.hltv_listen_address );
|
||||
NET_JoinGroup( cls.netchan.sock, cls.hltv_listen_address );
|
||||
#endif
|
||||
SCR_EndLoadingPlaque();
|
||||
break;
|
||||
default:
|
||||
@@ -2151,6 +2246,10 @@ void CL_ParseCvarValue( sizebuf_t *msg, const qboolean ext, const connprotocol_t
|
||||
else
|
||||
response = cvar->string;
|
||||
}
|
||||
else if( proto == PROTO_LEGACY )
|
||||
{
|
||||
response = "Not Found";
|
||||
}
|
||||
else
|
||||
{
|
||||
response = "Bad CVAR request";
|
||||
@@ -2203,20 +2302,20 @@ void CL_ParseExec( sizebuf_t *msg )
|
||||
|
||||
is_class = MSG_ReadByte( msg );
|
||||
|
||||
if( is_class )
|
||||
if ( is_class )
|
||||
{
|
||||
class_idx = MSG_ReadByte( msg );
|
||||
|
||||
if( class_idx >= 0 && class_idx <= 11 && !Q_stricmp( GI->gamefolder, "tfc" ) )
|
||||
if ( class_idx >= 0 && class_idx <= 11 && !Q_stricmp( GI->gamefolder, "tfc" ) )
|
||||
Cbuf_AddText( class_cfgs[class_idx] );
|
||||
}
|
||||
else if( !Q_stricmp( GI->gamefolder, "tfc" ) )
|
||||
else if ( !Q_stricmp( GI->gamefolder, "tfc" ) )
|
||||
{
|
||||
Cbuf_AddText( "exec mapdefault.cfg\n" );
|
||||
|
||||
COM_FileBase( clgame.mapname, mapname, sizeof( mapname ));
|
||||
|
||||
if( !COM_StringEmptyOrNULL( mapname ) )
|
||||
if ( COM_CheckString( mapname ) )
|
||||
Cbuf_AddTextf( "exec %s.cfg\n", mapname );
|
||||
}
|
||||
}
|
||||
@@ -2232,7 +2331,7 @@ qboolean CL_DispatchUserMessage( const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( COM_StringEmptyOrNULL( pszName ))
|
||||
if( !COM_CheckString( pszName ))
|
||||
return false;
|
||||
|
||||
for( i = 0; i < MAX_USER_MESSAGES; i++ )
|
||||
@@ -2307,7 +2406,7 @@ void CL_ParseUserMessage( sizebuf_t *msg, int svc_num, connprotocol_t proto )
|
||||
// message with variable sizes receive an actual size as first byte
|
||||
if( iSize == -1 )
|
||||
{
|
||||
if( proto == PROTO_GOLDSRC )
|
||||
if( proto == PROTO_GOLDSRC || proto == PROTO_LEGACY )
|
||||
iSize = MSG_ReadByte( msg );
|
||||
else iSize = MSG_ReadWord( msg );
|
||||
}
|
||||
@@ -2493,7 +2592,6 @@ void CL_ParseServerMessage( sizebuf_t *msg )
|
||||
else cls.state = ca_connecting;
|
||||
cl.background = old_background;
|
||||
cls.connect_time = MAX_HEARTBEAT;
|
||||
memset( &cls.bandwidth_test, 0, sizeof( cls.bandwidth_test ));
|
||||
cls.connect_retry = 0;
|
||||
}
|
||||
break;
|
||||
@@ -2501,7 +2599,7 @@ void CL_ParseServerMessage( sizebuf_t *msg )
|
||||
CL_ParseViewEntity( msg );
|
||||
break;
|
||||
case svc_sound:
|
||||
CL_ParseSoundPacket( msg, false );
|
||||
CL_ParseSoundPacket( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_time:
|
||||
@@ -2556,7 +2654,7 @@ void CL_ParseServerMessage( sizebuf_t *msg )
|
||||
CL_ParseParticles( msg, PROTO_CURRENT );
|
||||
break;
|
||||
case svc_restoresound:
|
||||
CL_ParseSoundPacket( msg, true );
|
||||
CL_ParseRestoreSoundPacket( msg );
|
||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_spawnstatic:
|
||||
|
||||
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 ))
|
||||
{
|
||||
@@ -587,7 +585,7 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
||||
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 ();
|
||||
@@ -778,7 +776,7 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
||||
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
|
||||
|
||||
@@ -238,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 ();
|
||||
|
||||
@@ -265,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 ));
|
||||
@@ -283,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 ));
|
||||
@@ -838,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 )
|
||||
@@ -865,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 );
|
||||
|
||||
@@ -1029,7 +1025,7 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
||||
break;
|
||||
case svc_centerprint:
|
||||
str = MSG_ReadString( msg );
|
||||
CL_DispatchUserMessage( "HudText", Q_strlen( str ) + 1, (void *)str );
|
||||
CL_DispatchUserMessage( "HudText", Q_strlen( str ), (void *)str );
|
||||
break;
|
||||
case svc_killedmonster:
|
||||
CL_DispatchQuakeMessage( "KillMonster" ); // just an event
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -45,6 +45,30 @@ static void R_Mem_Free( void *mem, const char *filename, const int fileline )
|
||||
_Mem_Free( mem, filename, fileline );
|
||||
}
|
||||
|
||||
/*
|
||||
=========
|
||||
pfnGetFilesList
|
||||
|
||||
=========
|
||||
*/
|
||||
static char **pfnGetFilesList( const char *pattern, int *numFiles, int gamedironly )
|
||||
{
|
||||
static search_t *t = NULL;
|
||||
|
||||
if( t ) Mem_Free( t ); // release prev search
|
||||
|
||||
t = FS_Search( pattern, true, gamedironly );
|
||||
|
||||
if( !t )
|
||||
{
|
||||
if( numFiles ) *numFiles = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( numFiles ) *numFiles = t->numfilenames;
|
||||
return t->filenames;
|
||||
}
|
||||
|
||||
static uint pfnFileBufferCRC32( const void *buffer, const int length )
|
||||
{
|
||||
uint modelCRC = 0;
|
||||
@@ -67,7 +91,7 @@ static void R_EnvShot( const float *vieworg, const char *name, qboolean skyshot,
|
||||
{
|
||||
static vec3_t viewPoint;
|
||||
|
||||
if( COM_StringEmptyOrNULL( name ))
|
||||
if( !COM_CheckString( name ))
|
||||
return;
|
||||
|
||||
if( cls.scrshot_action != scrshot_inactive )
|
||||
@@ -136,7 +160,7 @@ intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRe
|
||||
case PARM_SHADOWDATA:
|
||||
return (intptr_t)world.shadowdata;
|
||||
case PARM_FULLSCREEN:
|
||||
return refState.window_mode == WINDOW_MODE_BORDERLESS || refState.window_mode == WINDOW_MODE_FULLSCREEN;
|
||||
return refState.fullScreen;
|
||||
case PARM_WIDESCREEN:
|
||||
return refState.wideScreen;
|
||||
case PARM_SCREEN_WIDTH:
|
||||
@@ -272,14 +296,14 @@ static render_api_t gRenderAPI =
|
||||
NULL,
|
||||
R_Mem_Alloc,
|
||||
R_Mem_Free,
|
||||
CL_GetFilesList,
|
||||
pfnGetFilesList,
|
||||
pfnFileBufferCRC32,
|
||||
pfnCompareFileTime,
|
||||
Host_Error,
|
||||
(void*)CL_ModelHandle,
|
||||
Sys_FloatTime,
|
||||
pfnTime,
|
||||
Cvar_Set,
|
||||
S_MusicFade,
|
||||
S_FadeMusicVolume,
|
||||
COM_SetRandomSeed,
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user