mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-06 04:05:11 +08:00
Compare commits
1 Commits
continuous
...
continuous
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a656469f12 |
19
.cirrus.yml
19
.cirrus.yml
@@ -1,10 +1,10 @@
|
|||||||
task:
|
task:
|
||||||
name: freebsd-14-amd64
|
name: freebsd-14-amd64
|
||||||
freebsd_instance:
|
freebsd_instance:
|
||||||
image_family: freebsd-14-3
|
image_family: freebsd-14-2
|
||||||
setup_script:
|
setup_script:
|
||||||
- pkg update
|
- 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
|
- git submodule update --init --recursive
|
||||||
test_script:
|
test_script:
|
||||||
- ./scripts/cirrus/build_freebsd.sh
|
- ./scripts/cirrus/build_freebsd.sh
|
||||||
@@ -12,21 +12,10 @@ task:
|
|||||||
task:
|
task:
|
||||||
name: freebsd-15-amd64
|
name: freebsd-15-amd64
|
||||||
freebsd_instance:
|
freebsd_instance:
|
||||||
image_family: freebsd-15-0-amd64-zfs
|
image_family: freebsd-15-0-snap
|
||||||
setup_script:
|
setup_script:
|
||||||
- pkg update
|
- 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
|
- git submodule update --init --recursive
|
||||||
test_script:
|
test_script:
|
||||||
- ./scripts/cirrus/build_freebsd.sh
|
- ./scripts/cirrus/build_freebsd.sh
|
||||||
|
|
||||||
#task:
|
|
||||||
# name: freebsd-16-amd64
|
|
||||||
# freebsd_instance:
|
|
||||||
# image_family: freebsd-16-0-snap
|
|
||||||
# setup_script:
|
|
||||||
# - pkg update
|
|
||||||
# - pkg install -y pkgconf git sdl2 python freetype2 libvorbis opusfile bzip2 libbacktrace libogg libvorbis
|
|
||||||
# - git submodule update --init --recursive
|
|
||||||
# test_script:
|
|
||||||
# - ./scripts/cirrus/build_freebsd.sh
|
|
||||||
|
|||||||
55
.github/workflows/c-cpp.yml
vendored
55
.github/workflows/c-cpp.yml
vendored
@@ -21,12 +21,14 @@ jobs:
|
|||||||
- os: ubuntu-22.04
|
- os: ubuntu-22.04
|
||||||
targetos: linux
|
targetos: linux
|
||||||
targetarch: i386
|
targetarch: i386
|
||||||
- os: ubuntu-22.04-arm
|
- os: ubuntu-22.04
|
||||||
targetos: linux
|
targetos: linux
|
||||||
targetarch: arm64
|
targetarch: arm64
|
||||||
- os: ubuntu-22.04-arm
|
cross: true
|
||||||
|
- os: ubuntu-22.04
|
||||||
targetos: linux
|
targetos: linux
|
||||||
targetarch: armhf
|
targetarch: armhf
|
||||||
|
cross: true
|
||||||
- os: ubuntu-24.04 # riscv64 would benefit from having latest compilers
|
- os: ubuntu-24.04 # riscv64 would benefit from having latest compilers
|
||||||
targetos: linux
|
targetos: linux
|
||||||
targetarch: riscv64
|
targetarch: riscv64
|
||||||
@@ -35,6 +37,9 @@ jobs:
|
|||||||
targetos: linux
|
targetos: linux
|
||||||
targetarch: ppc64el
|
targetarch: ppc64el
|
||||||
cross: true
|
cross: true
|
||||||
|
# - os: ubuntu-aarch64-22.04
|
||||||
|
# targetos: linux
|
||||||
|
# targetarch: aarch64
|
||||||
# - os: ubuntu-latest
|
# - os: ubuntu-latest
|
||||||
# targetos: linux
|
# targetos: linux
|
||||||
# targetarch: e2k-8c
|
# targetarch: e2k-8c
|
||||||
@@ -61,21 +66,18 @@ jobs:
|
|||||||
- os: macos-14 # arm64 as per github documentation
|
- os: macos-14 # arm64 as per github documentation
|
||||||
targetos: apple
|
targetos: apple
|
||||||
targetarch: arm64
|
targetarch: arm64
|
||||||
- os: macos-latest
|
- os: macos-13 # x86 as per github documentation (will they fix it before they deprecate this version?..)
|
||||||
targetos: ios
|
|
||||||
targetarch: arm64
|
|
||||||
- os: macos-15-intel
|
|
||||||
targetos: apple
|
targetos: apple
|
||||||
targetarch: amd64
|
targetarch: amd64
|
||||||
env:
|
env:
|
||||||
SDL_VERSION: 2.32.10
|
SDL_VERSION: 2.32.8
|
||||||
FFMPEG_VERSION: 8.1
|
FFMPEG_VERSION: 7.1
|
||||||
GH_CPU_ARCH: ${{ matrix.targetarch }}
|
GH_CPU_ARCH: ${{ matrix.targetarch }}
|
||||||
GH_CPU_OS: ${{ matrix.targetos }}
|
GH_CPU_OS: ${{ matrix.targetos }}
|
||||||
GH_CROSSCOMPILING: ${{ matrix.cross }}
|
GH_CROSSCOMPILING: ${{ matrix.cross }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
@@ -85,7 +87,7 @@ jobs:
|
|||||||
FWGS_PFX_PASSWORD: ${{ secrets.FWGS_PFX_PASSWORD }}
|
FWGS_PFX_PASSWORD: ${{ secrets.FWGS_PFX_PASSWORD }}
|
||||||
run: bash scripts/gha/build_${{ matrix.targetos }}.sh
|
run: bash scripts/gha/build_${{ matrix.targetos }}.sh
|
||||||
- name: Upload engine (artifacts)
|
- name: Upload engine (artifacts)
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: artifact-${{ matrix.targetos }}-${{ matrix.targetarch }}
|
name: artifact-${{ matrix.targetos }}-${{ matrix.targetarch }}
|
||||||
path: artifacts/*
|
path: artifacts/*
|
||||||
@@ -97,11 +99,11 @@ jobs:
|
|||||||
include:
|
include:
|
||||||
- app: su.xash.Engine.Compat.i386
|
- app: su.xash.Engine.Compat.i386
|
||||||
container:
|
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
|
options: --privileged
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v6
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Build flatpak (Compat.i386)
|
- name: Build flatpak (Compat.i386)
|
||||||
@@ -115,10 +117,31 @@ jobs:
|
|||||||
needs: [build, flatpak]
|
needs: [build, flatpak]
|
||||||
if: ${{ github.event_name == 'push' }}
|
if: ${{ github.event_name == 'push' }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
- name: Remove old release, fetch artifacts, repackage binaries and upload new release
|
- name: Remove old release, fetch artifacts, repackage binaries and upload new release
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
BASE_BUILDNUM_DATE: "2015-04-01"
|
RELEASE_TAG: ${{ github.ref_name == 'master' && 'continuous' || format('continuous-{0}', github.ref_name) }}
|
||||||
run: bash scripts/gha/make_release.sh "Xash3D FWGS" "${{ 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
|
*.includes
|
||||||
*.files
|
*.files
|
||||||
|
|
||||||
# ios
|
|
||||||
ios/cl_dlls/*
|
|
||||||
ios/dlls/*
|
|
||||||
ios/*.framework
|
|
||||||
scripts/ios/mod-build
|
|
||||||
|
|
||||||
# Waf
|
# Waf
|
||||||
build_current
|
build_current
|
||||||
*waf-*/
|
*waf-*/
|
||||||
@@ -345,7 +339,6 @@ __pycache__
|
|||||||
.history/*
|
.history/*
|
||||||
.cache/*
|
.cache/*
|
||||||
enc_temp_folder/
|
enc_temp_folder/
|
||||||
Taskfile.yml
|
|
||||||
|
|
||||||
# KDevelop4
|
# KDevelop4
|
||||||
*.kdev4
|
*.kdev4
|
||||||
|
|||||||
5
.gitmodules
vendored
5
.gitmodules
vendored
@@ -39,7 +39,4 @@
|
|||||||
url = https://github.com/ianlancetaylor/libbacktrace
|
url = https://github.com/ianlancetaylor/libbacktrace
|
||||||
[submodule "3rdparty/maintui"]
|
[submodule "3rdparty/maintui"]
|
||||||
path = 3rdparty/maintui
|
path = 3rdparty/maintui
|
||||||
url = https://github.com/FWGS/xash3d-maintui.git
|
url = https://github.com/numas13/xash3d-maintui.git
|
||||||
[submodule "3rdparty/library_suffix"]
|
|
||||||
path = 3rdparty/library_suffix
|
|
||||||
url = https://github.com/FWGS/library-suffix.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):
|
def configure(conf):
|
||||||
# add unsupported platforms here
|
# 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
|
conf.env.DISABLE_LIBBACKTRACE = True
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ def configure(conf):
|
|||||||
return {'header_name':hdr, 'msg':'... %s header' % hdr, 'mandatory':False, 'id':hdr, 'compiler': 'c'}
|
return {'header_name':hdr, 'msg':'... %s header' % hdr, 'mandatory':False, 'id':hdr, 'compiler': 'c'}
|
||||||
|
|
||||||
def check_frag(frag, msg, define, **kw):
|
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(
|
conf.multicheck(
|
||||||
check_header('dlfcn.h'),
|
check_header('dlfcn.h'),
|
||||||
@@ -162,13 +162,8 @@ def build(bld):
|
|||||||
if bld.env.DISABLE_LIBBACKTRACE:
|
if bld.env.DISABLE_LIBBACKTRACE:
|
||||||
return
|
return
|
||||||
|
|
||||||
sources = ['atomic.c', 'dwarf.c', 'fileline.c', 'posix.c', 'print.c', 'sort.c', 'state.c', 'backtrace.c', 'simple.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_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']
|
|
||||||
|
|
||||||
if bld.env.DEST_BINFMT == 'pe':
|
if bld.env.DEST_BINFMT == 'pe':
|
||||||
sources += ['pecoff.c']
|
sources += ['pecoff.c']
|
||||||
|
|||||||
1
3rdparty/library_suffix
vendored
1
3rdparty/library_suffix
vendored
Submodule 3rdparty/library_suffix deleted from 6e14ae31e8
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: af2b5abdde...b015e45062
2
3rdparty/vgui_support
vendored
2
3rdparty/vgui_support
vendored
Submodule 3rdparty/vgui_support updated: 36219aedfc...9f2b9512cd
@@ -29,11 +29,10 @@
|
|||||||
|
|
||||||
* This project uses mixed Quake's and HLSDK's C/C++ code style convention.
|
* This project uses mixed Quake's and HLSDK's C/C++ code style convention.
|
||||||
* In short:
|
* In short:
|
||||||
* Use spaces in parenthesis, but not when two parentheses are consecutive.
|
* Use spaces in parenthesis.
|
||||||
* Only tabs for indentation.
|
* Only tabs for indentation.
|
||||||
* Any brace must have it's own line.
|
* Any brace must have it's own line.
|
||||||
* Short blocks, if statements and loops on single line are allowed.
|
* Short blocks, if statements and loops on single line are allowed.
|
||||||
* Prefer generic utilities from libpublic over rolling your own.
|
|
||||||
* Avoid magic numbers.
|
* Avoid magic numbers.
|
||||||
* While macros are powerful, it's better to avoid overusing them.
|
* 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.
|
* 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)
|
* [Boosty page](https://boosty.to/snmetamorph)
|
||||||
* [Other donation methods](https://snmetamorph.github.io/donate)
|
* [Other donation methods](https://snmetamorph.github.io/donate)
|
||||||
|
|
||||||
## [$_Vladislav](https://github.com/Vladislav4KZ)
|
|
||||||
|
|
||||||
[YaPB Project](https://github.com/yapb) member, [Xash3D FWGS](https://github.com/FWGS/xash3d-fwgs) tester,
|
|
||||||
editor of the [Official YaPB Documentation](https://github.com/yapb/docs) (in English and Russian), curator of the [YaPB Graph Database](https://github.com/yapb/graph) and author of [YaPB Waypoint/Graph Pack](https://gamebanana.com/mods/40087).
|
|
||||||
|
|
||||||
Also does the Russian localization of text, images (gfx/shell), as well as additional menu buttons in English used in Xash3D FWGS for various mods.
|
|
||||||
|
|
||||||
* [Boosty page](https://boosty.to/rasstaman1337)
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
# Addon folders in Xash3D FWGS
|
|
||||||
|
|
||||||
Xash3D FWGS supports both GoldSource-style addon folders and has few own. Each directory can have it's own archives that will be mounted with lower priority than directory itself.
|
|
||||||
|
|
||||||
Below is the mounts map, in order of precedence from least important to most important.
|
|
||||||
|
|
||||||
|--------------------|------|
|
|
||||||
| Directory | Note |
|
|
||||||
|--------------------|------|
|
|
||||||
| `$game/downloaded` | Always added. Used to store server downloads.|
|
|
||||||
| `$game` | This is the game directory. |
|
|
||||||
| `$game/custom` | Always added. Used for user modifications content. |
|
|
||||||
| `$game_hd` | Added with `fs_mount_hd` set to non-zero value. Used for high definition content, similar to GoldSrc.. |
|
|
||||||
| `$game_addon` | Added with `fs_mount_addon` set to non-zero value. Used for user modifications content, similar to GoldSrc. |
|
|
||||||
| `$game_lv` | Added with `fs_mount_lv` set to non-zero value. Used for low-violence content, similar to GoldSrc. |
|
|
||||||
| `$game_$language` | Added with `fs_mount_l10n` set to non-zero value. Language is controlled with `ui_language` cvar or `-language` command line switch. Used for localization content, similar to GoldSrc. |
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
# Steam broker protocol
|
|
||||||
`sb_connect <ip:port> <server's steam id> <secure> <challenge>` - used for obtaining auth ticket during connection to GoldSrc server
|
|
||||||
|
|
||||||
`sb_disconnect <ip:port> <challenge>` - used for signaling broker about disconnecting from GoldSrc server
|
|
||||||
|
|
||||||
`sb_gamedir <gamedir>` - used for signaling broker about game startup and for announcing started mod, so broker could choose proper AppID for Steam API initialization
|
|
||||||
|
|
||||||
`sb_terminate` - used for signaling broker about game shutdown, ideally broker should be terminated too (and later restarted automatically and waiting for sb_gamedir message)
|
|
||||||
@@ -1,18 +1,15 @@
|
|||||||
# Support for GoldSrc network protocol
|
# 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:
|
For connecting to GoldSrc-based servers, use this command:
|
||||||
```
|
```
|
||||||
connect ip:port gs
|
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.
|
That is because proper authorization with Steam API is not implemented in engine yet (but we have plans on it).
|
||||||
Also, make sure to set that broker as current ticket generator using console or edit `config.cfg` file manually:
|
|
||||||
```
|
|
||||||
cl_ticket_generator steam
|
|
||||||
```
|
|
||||||
|
|
||||||
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.
|
Also, we encountered that some GoldSrc-based servers are recognizing Xash3D clients as "fake clients" and banning/kicking them. Maybe this problem will be
|
||||||
|
|
||||||
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
|
|
||||||
solved along with better compatibility with GoldSrc behavior, but may be not - we don't know logic behind this fake client checks.
|
solved along with better compatibility with GoldSrc behavior, but may be not - we don't know logic behind this fake client checks.
|
||||||
|
|||||||
@@ -16,9 +16,6 @@ Mirrored on github - https://github.com/JoelTroch/am_src_rebirth
|
|||||||
## Battle Grounds
|
## Battle Grounds
|
||||||
Mirrored on github - https://github.com/nekonomicon/BattleGrounds
|
Mirrored on github - https://github.com/nekonomicon/BattleGrounds
|
||||||
|
|
||||||
## Brain Bread
|
|
||||||
Official github repository - https://github.com/IronOak-Studios/BrainBread
|
|
||||||
|
|
||||||
## Bubblemod
|
## 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)
|
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
|
## ESHQ
|
||||||
Official github repository - https://github.com/adslbarxatov/xash3d-for-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
|
## Flat-Life
|
||||||
Available on GamerLab - http://gamer-lab.com/eng/code_mods_goldsrc/Half-Life_2D_(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
|
## GT mod
|
||||||
Available on GamerLab - http://gamer-lab.com/eng/code_mods_goldsrc/GT_mod_(Polnie_ishodniki)
|
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
|
## Half-Life: Advanced Deathmatch
|
||||||
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/hla
|
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
|
## Half-Life: Expanded Arsenal
|
||||||
Available on ModDB - https://www.moddb.com/mods/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
|
## Half-Life: Gravgun mod
|
||||||
Branch **gravgun** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/gravgun
|
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
|
## Half-Life: Rally
|
||||||
Official gitlab repository - https://gitlab.com/hlrally/src
|
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
|
## 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
|
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
|
## Half-Screwed
|
||||||
Official github repository - https://github.com/desukuran/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
|
## Headcrab Frenzy
|
||||||
Version 1.3 on ModDB - https://www.moddb.com/mods/headcrab-frenzy/downloads/headcrab-frenzy-13-beta-source-code
|
Version 1.3 on ModDB - https://www.moddb.com/mods/headcrab-frenzy/downloads/headcrab-frenzy-13-beta-source-code
|
||||||
|
|
||||||
## Heart of Evil
|
## Heart of Evil
|
||||||
Mirrored on github - https://github.com/nekonomicon/HeartOfEvil
|
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
|
## Ingram Chillin' Mod
|
||||||
Official SourceForge repository - https://sourceforge.net/projects/icm-hl/
|
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
|
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
|
## Raven City
|
||||||
*Unfinished mod*
|
*Unfinished mod*
|
||||||
|
|
||||||
@@ -209,9 +186,6 @@ Mirrored on code.idtech.space - https://code.idtech.space/vera/halflife-wastelan
|
|||||||
## Wizard Wars
|
## Wizard Wars
|
||||||
Download page on official site - http://www.thothie.com/ww/
|
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
|
## XashXT
|
||||||
Mirrored on github - https://github.com/a1batross/XashXT_original
|
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
|
## Counter Strike Online
|
||||||
CSO-like Xash3D-based mod, CSMoE - https://github.com/MoeMod/CSMoE
|
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
|
## Crack-Life: Campaign Mode
|
||||||
Recreation by lostgamer aka nillerusr - https://github.com/LostGamerHL/crack_life
|
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
|
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
|
## Half-Life: Echoes
|
||||||
Branch **echoes** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/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 |
|
| PSVita | Supported | @fgsfdsfgs |
|
||||||
| Switch | Supported | @fgsfdsfgs |
|
| Switch | Supported | @fgsfdsfgs |
|
||||||
| Windows | Supported | @a1batross, @SNMetamorph |
|
| Windows | Supported | @a1batross, @SNMetamorph |
|
||||||
| iOS | Supported | @ksagameng2 |
|
|
||||||
| DOS4GW | Orphaned | N/A | Haven't been confirmed to work for a very long time
|
| 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
|
| Haiku | Orphaned | N/A | Was added by #478 and #483
|
||||||
| IRIX | Orphaned | N/A | Undone, compiles but requires big endian port
|
| 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 |
|
| Emscripten | Old Engine | N/A |
|
||||||
| 3DS | Old Engine fork | N/A | [GitHub Repository](https://github.com/masterfeizz/Xash3DS)
|
| 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)
|
| 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
|
Server: https://github.com/rehlds/ReGameDLL_CS
|
||||||
|
|
||||||
15. **[Crack-Life](https://www.moddb.com/mods/crack-life/downloads/crack-life)**
|
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 **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)**
|
|
||||||
|
|
||||||
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).
|
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.
|
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).
|
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.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
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).
|
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.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
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).
|
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).
|
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.
|
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).
|
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.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
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*
|
*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).
|
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).
|
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.
|
This mod supports x86 Linux.
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
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.
|
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).
|
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.
|
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).
|
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).
|
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).
|
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).
|
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).
|
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.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
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).
|
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).
|
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.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
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).
|
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*
|
*Support temporary abandoned*
|
||||||
|
|
||||||
[Source code](https://github.com/FWGS/paranoia_toolkit).
|
[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).
|
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).
|
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)
|
[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.*
|
*Support was fully abandoned due Quake Wrapper release.*
|
||||||
|
|
||||||
[Actual source code](https://github.com/FWGS/quakeremake)
|
[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).
|
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).
|
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).
|
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.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
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).
|
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).
|
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).
|
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.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
Currently, only source code of [client part](https://github.com/Velaron/tf15-client) is available.
|
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).
|
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).
|
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).
|
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).
|
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*
|
*Support was fully abandoned due PrimeXT development*
|
||||||
|
|
||||||
[Source code](https://github.com/FWGS/XashXT-FWGS/)
|
[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.
|
This mod already supports x86 Linux.
|
||||||
|
|
||||||
Support for other platforms may be available later.
|
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).
|
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!!!
|
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).
|
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" />
|
# 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) \
|
[](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)
|
[](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.
|
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.
|
1) Copy `valve` directory to a folder named `xash` in the Internal storage.
|
||||||
2) Run games from within the app.
|
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.
|
* Issues are accepted in both English and Russian.
|
||||||
* They are only accepted if you run legally acquired product (e.g. Half-Life in Steam).
|
* Before sending a PR, check if you followed our contribution guide in CONTRIBUTING.md file.
|
||||||
|
|
||||||
## Contributing code
|
|
||||||
* Check the CONTRIBUTING.md file.
|
|
||||||
|
|
||||||
## Build instructions
|
## 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/).
|
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
|
##### RedHat/Fedora
|
||||||
* Only for 32-bit engine on 64-bit x86 operating system:
|
* 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`.
|
* 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:
|
* 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`.
|
* 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`.
|
* 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
|
### Building
|
||||||
#### Windows (Visual Studio)
|
#### Windows (Visual Studio)
|
||||||
0) Open command line.
|
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`.
|
3) Install: `./waf install --destdir=/path/to/any/output/directory`.
|
||||||
|
|
||||||
#### Android (Windows/Linux/macOS)
|
#### 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.
|
You can just open the `android` folder in Android Studio and build from here, or use `gradlew` to build from command line.
|
||||||
|
|
||||||
#### iOS/iPadOS (MacOS only)
|
|
||||||
0) (optional) Examine which build options are available: `./waf --help`.
|
|
||||||
1) Configure build: `./waf configure --ios --enable-bundled-deps --sdl2 (path/to/SDL2.framework)`, set `--ios-simulator` instead of `--ios` if you want to build for simulator.
|
|
||||||
2) Compile `./waf build`.
|
|
||||||
3) Navigate to `build` and copy your compiled SDL2.framework there, then add your game dylibs to `build/ios/libs/(gamedir)/(dlls/cl_dlls)`(You can also run `scripts/ios/buildhlsdk.sh` instead to automatically create an ipa with hlsdk dylibs)
|
|
||||||
4) Run `scripts/ios/createipa.sh` to create an installable ipa
|
|
||||||
|
|
||||||
### Running tests
|
|
||||||
|
|
||||||
Tests are enabled with `--enable-tests` passed to `./waf configure` and can be run with `./waf --alltests`.
|
|
||||||
|
|
||||||
This builds both standalone unit tests and a separate engine test binary (`xash3d_tests`) that embeds engine-level tests. The engine test binary requires no game assets.
|
|
||||||
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 org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.time.Month
|
import java.time.Month
|
||||||
@@ -6,11 +5,12 @@ import java.time.temporal.ChronoUnit
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.android.application)
|
alias(libs.plugins.android.application)
|
||||||
|
alias(libs.plugins.kotlin.android)
|
||||||
}
|
}
|
||||||
|
|
||||||
extensions.configure<ApplicationExtension> {
|
android {
|
||||||
namespace = "su.xash.engine"
|
namespace = "su.xash.engine"
|
||||||
ndkVersion = "29.0.14206865"
|
ndkVersion = "28.2.13676358"
|
||||||
compileSdk = 35
|
compileSdk = 35
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
@@ -34,7 +34,7 @@ extensions.configure<ApplicationExtension> {
|
|||||||
"--configuration-dir=\${ndk.buildRoot}",
|
"--configuration-dir=\${ndk.buildRoot}",
|
||||||
"--ndk-version=\${ndk.moduleNdkVersion}",
|
"--ndk-version=\${ndk.moduleNdkVersion}",
|
||||||
"--min-sdk-version=\${ndk.minPlatform}",
|
"--min-sdk-version=\${ndk.minPlatform}",
|
||||||
"--ndk-root=${androidComponents.sdkComponents.ndkDirectory.get()}",
|
"--ndk-root=${android.ndkDirectory}",
|
||||||
// shut up, fake options
|
// shut up, fake options
|
||||||
"-p:Configuration=\${ndk.variantName}",
|
"-p:Configuration=\${ndk.variantName}",
|
||||||
"-p:Platform=\${ndk.abi}"
|
"-p:Platform=\${ndk.abi}"
|
||||||
@@ -77,8 +77,8 @@ extensions.configure<ApplicationExtension> {
|
|||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
getByName("main") {
|
getByName("main") {
|
||||||
assets.directories.add("../../3rdparty/extras/xash-extras")
|
assets.srcDirs("../../3rdparty/extras/xash-extras")
|
||||||
java.directories.add("../../3rdparty/SDL/android-project/app/src/main/java")
|
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 -->
|
<!-- Allow downloading to the external storage on Android 5.1 and older -->
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||||
android:maxSdkVersion="29" />
|
android:maxSdkVersion="22" />
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||||
android:maxSdkVersion="29" />
|
android:maxSdkVersion="32" />
|
||||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
||||||
<!-- Allow access to Bluetooth devices -->
|
<!-- Allow access to Bluetooth devices -->
|
||||||
<!-- Currently this is just for Steam Controller support and requires setting SDL_HINT_JOYSTICK_HIDAPI_STEAM -->
|
<!-- Currently this is just for Steam Controller support and requires setting SDL_HINT_JOYSTICK_HIDAPI_STEAM -->
|
||||||
|
|||||||
@@ -15,9 +15,6 @@ import org.libsdl.app.SDLActivity;
|
|||||||
|
|
||||||
import su.xash.engine.util.AndroidBug5497Workaround;
|
import su.xash.engine.util.AndroidBug5497Workaround;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class XashActivity extends SDLActivity {
|
public class XashActivity extends SDLActivity {
|
||||||
private boolean mUseVolumeKeys;
|
private boolean mUseVolumeKeys;
|
||||||
private String mPackageName;
|
private String mPackageName;
|
||||||
@@ -152,7 +149,6 @@ public class XashActivity extends SDLActivity {
|
|||||||
|
|
||||||
String argv = getIntent().getStringExtra("argv");
|
String argv = getIntent().getStringExtra("argv");
|
||||||
if (argv == null) argv = "-console -log";
|
if (argv == null) argv = "-console -log";
|
||||||
|
|
||||||
return argv.split(" ");
|
return argv.split(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,36 +6,28 @@ import android.content.pm.PackageInfo
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import androidx.core.net.toUri
|
import android.net.Uri
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import su.xash.engine.R
|
|
||||||
import su.xash.engine.XashActivity
|
import su.xash.engine.XashActivity
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
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"
|
private var iconName = "game.ico"
|
||||||
var title = "Unknown Game"
|
var title = "Unknown Game"
|
||||||
var icon: Bitmap? = null
|
var icon: Bitmap? = null
|
||||||
var cover: 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)
|
private val pref = ctx.getSharedPreferences(basedir.name, Context.MODE_PRIVATE)
|
||||||
|
|
||||||
init {
|
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)
|
val iconFile = File(basedir, iconName)
|
||||||
if (iconFile.exists()) {
|
if (iconFile.exists()) {
|
||||||
@@ -50,76 +42,14 @@ class Game(val ctx: Context, val basedir: File, val gameInfoFile: File) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun startEngine(ctx: Context) {
|
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 {
|
ctx.startActivity(Intent(ctx, XashActivity::class.java).apply {
|
||||||
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||||
|
putExtra("gamedir", basedir.name)
|
||||||
putExtra("gamedir", defaultGameDir)
|
putExtra("argv", pref.getString("arguments", "-console -log"))
|
||||||
putExtra("argv", commandLineArgs)
|
|
||||||
putExtra("usevolume", pref.getBoolean("use_volume_buttons", false))
|
putExtra("usevolume", pref.getBoolean("use_volume_buttons", false))
|
||||||
putExtra("basedir", basedir.parent)
|
putExtra("basedir", basedir.parent)
|
||||||
|
//.putExtra("gamelibdir", getGameLibDir(context))
|
||||||
if (gameLibDir != null) {
|
//.putExtra("package", getPackageName()) }
|
||||||
putExtra("gamelibdir", gameLibDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (packageName != null) {
|
|
||||||
putExtra("package", packageName)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,50 +70,44 @@ class Game(val ctx: Context, val basedir: File, val gameInfoFile: File) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getPackageNamesForGameDir(gamedir: String): Array<String>? {
|
private fun getPackageName(): String? {
|
||||||
if (gamedir.equals("cstrike", ignoreCase = true)
|
// return if (mDbEntry != null) {
|
||||||
|| gamedir.equals("czero", ignoreCase = true))
|
// mDbEntry.getPackageName()
|
||||||
return arrayOf("su.xash.cs16client.test", "su.xash.cs16client")
|
// } else null
|
||||||
|
|
||||||
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
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getDownloadPageForGameDir(gamedir: String): String {
|
private fun getGameLibDir(ctx: Context): String? {
|
||||||
if (gamedir.equals("cstrike", ignoreCase = true)
|
val pkgName = getPackageName()
|
||||||
|| gamedir.equals("czero", ignoreCase = true))
|
if (pkgName != null) {
|
||||||
return "https://github.com/Velaron/cs16-client/releases/download/continuous/CS16Client-Android.apk"
|
val pkgInfo: PackageInfo = try {
|
||||||
|
ctx.packageManager.getPackageInfo(pkgName, 0)
|
||||||
if (gamedir.equals("tfc", ignoreCase = true))
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
return "https://github.com/Velaron/tf15-client/releases/download/continuous/TF15Client-Android.apk"
|
e.printStackTrace()
|
||||||
|
ctx.startActivity(
|
||||||
// just so we don't return null
|
Intent(
|
||||||
return "https://github.com/FWGS/xash3d-fwgs/releases/download/continuous/xash3d-fwgs-android.apk"
|
Intent.ACTION_VIEW, Uri.parse("market://details?id=$pkgName")
|
||||||
}
|
).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
|
||||||
|
)
|
||||||
private fun getGameLibDir(ctx: Context, packageName: String): String? {
|
return null
|
||||||
val packageInfo: PackageInfo = ctx.packageManager.getPackageInfo(packageName, 0)
|
}
|
||||||
return packageInfo.applicationInfo?.nativeLibraryDir
|
return pkgInfo.applicationInfo?.nativeLibraryDir
|
||||||
|
}
|
||||||
|
return ctx.applicationInfo.nativeLibraryDir
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun getGames(ctx: Context, root: File): List<Game> {
|
fun getGames(ctx: Context, file: File): List<Game> {
|
||||||
val games = mutableListOf<Game>()
|
val games = mutableListOf<Game>()
|
||||||
|
|
||||||
root.listFiles()?.forEach {
|
if (checkIfGamedir(file)) {
|
||||||
if (it.isDirectory) {
|
games.add(Game(ctx, file))
|
||||||
val subDirGameInfoFile = checkIfGamedir(it)
|
} else {
|
||||||
if (subDirGameInfoFile != null) {
|
file.listFiles()?.forEach {
|
||||||
games.add(Game(ctx, it, subDirGameInfoFile))
|
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
|
return games
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkIfGamedir(gamedir: File): File? {
|
fun checkIfGamedir(file: File): Boolean {
|
||||||
gamedir.listFiles()?.forEach {
|
if (File(file, "liblist.gam").exists()) return true
|
||||||
if (it.isFile) {
|
if (File(file, "gameinfo.txt").exists()) return true
|
||||||
if (it.name.equals("liblist.gam", ignoreCase = true))
|
|
||||||
return it
|
|
||||||
|
|
||||||
if (it.name.equals("gameinfo.txt", ignoreCase = true))
|
return false
|
||||||
return it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
package su.xash.engine.ui.library
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -15,8 +13,7 @@ import android.view.MenuItem
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.core.view.MenuProvider
|
import androidx.core.view.MenuProvider
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
@@ -28,7 +25,6 @@ import su.xash.engine.R
|
|||||||
import su.xash.engine.adapters.GameAdapter
|
import su.xash.engine.adapters.GameAdapter
|
||||||
import su.xash.engine.databinding.FragmentLibraryBinding
|
import su.xash.engine.databinding.FragmentLibraryBinding
|
||||||
|
|
||||||
|
|
||||||
class LibraryFragment : Fragment(), MenuProvider {
|
class LibraryFragment : Fragment(), MenuProvider {
|
||||||
private var _binding: FragmentLibraryBinding? = null
|
private var _binding: FragmentLibraryBinding? = null
|
||||||
private val binding get() = _binding!!
|
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 {
|
private fun checkStoragePermissions(): Boolean {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
|
||||||
if (!Environment.isExternalStorageManager()) {
|
MaterialAlertDialogBuilder(requireContext()).apply {
|
||||||
MaterialAlertDialogBuilder(requireContext()).apply {
|
setTitle(R.string.file_access_required)
|
||||||
setTitle(R.string.file_access_required)
|
setMessage(R.string.file_access_message)
|
||||||
setMessage(R.string.file_access_message)
|
setPositiveButton(android.R.string.ok) { _, _ ->
|
||||||
setPositiveButton(R.string.open_settings) { _, _ ->
|
startActivityForResult.launch(
|
||||||
startActivityForResult.launch(
|
Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION).setData(
|
||||||
Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION).setData(
|
Uri.fromParts("package", BuildConfig.APPLICATION_ID, null)
|
||||||
Uri.fromParts("package", BuildConfig.APPLICATION_ID, null)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
setNeutralButton(R.string.done_check_permissions) { dialog, _ ->
|
|
||||||
checkStoragePermissions()
|
|
||||||
}
|
|
||||||
setCancelable(false)
|
|
||||||
show()
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
} else {
|
setCancelable(false)
|
||||||
return true
|
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()) {
|
return false
|
||||||
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
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -173,12 +107,4 @@ class LibraryFragment : Fragment(), MenuProvider {
|
|||||||
|
|
||||||
return false
|
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.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import su.xash.engine.model.Game
|
import su.xash.engine.model.Game
|
||||||
import su.xash.engine.util.Nomedia
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class LibraryViewModel(application: Application) : AndroidViewModel(application) {
|
class LibraryViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
@@ -40,8 +39,6 @@ class LibraryViewModel(application: Application) : AndroidViewModel(application)
|
|||||||
?: (Environment.getExternalStorageDirectory().absolutePath + "/xash")
|
?: (Environment.getExternalStorageDirectory().absolutePath + "/xash")
|
||||||
val root = File(rootPath)
|
val root = File(rootPath)
|
||||||
|
|
||||||
Nomedia.ensureNomedia(root)
|
|
||||||
|
|
||||||
_installedGames.postValue(Game.getGames(ctx, root))
|
_installedGames.postValue(Game.getGames(ctx, root))
|
||||||
_isReloading.postValue(false)
|
_isReloading.postValue(false)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,6 @@ class GameSettingsPreferenceFragment(val game: Game) : PreferenceFragmentCompat(
|
|||||||
packageList.setValueIndex(0);
|
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 separatePackages = findPreference<SwitchPreferenceCompat>("separate_libraries")!!
|
||||||
val clientPackage = findPreference<ListPreference>("client_package")!!
|
val clientPackage = findPreference<ListPreference>("client_package")!!
|
||||||
val serverPackage = findPreference<ListPreference>("server_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">Configurações do jogo</string>
|
||||||
<string name="game_settings_command_line">Argumentos de linha de comando</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="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_separate_libraries">Bibliotecas de pacotes separados</string>
|
||||||
<string name="preferences_client_package">Pacote do cliente</string>
|
<string name="preferences_client_package">Pacotes de Cliente</string>
|
||||||
<string name="preferences_server_package">Pacote do servidor</string>
|
<string name="preferences_server_package">Pacotes de Servidor</string>
|
||||||
<string name="preferences_use_icons">Usar ícones em vez de fundos</string>
|
<string name="preferences_use_icons">Usar ícones ao inves de imagens de fundo</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>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -6,21 +6,9 @@
|
|||||||
<string name="game_settings">Настройки игры</string>
|
<string name="game_settings">Настройки игры</string>
|
||||||
<string name="game_settings_command_line">Аргументы командной строки</string>
|
<string name="game_settings_command_line">Аргументы командной строки</string>
|
||||||
<string name="game_settings_volume_buttons">Использовать кнопки громкости</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_package_name">Пакет библиотек</string>
|
||||||
<string name="preferences_separate_libraries">Библиотеки из отдельных пакетов</string>
|
<string name="preferences_separate_libraries">Библиотеки из отдельных пакетов</string>
|
||||||
<string name="preferences_client_package">Пакет клиента</string>
|
<string name="preferences_client_package">Пакет клиента</string>
|
||||||
<string name="preferences_server_package">Пакет сервера</string>
|
<string name="preferences_server_package">Пакет сервера</string>
|
||||||
<string name="preferences_use_icons">Использовать иконки вместо фона</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>
|
</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">Game Settings</string>
|
||||||
<string name="game_settings_command_line">Command-line arguments</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_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_package_name">Libraries package</string>
|
||||||
<string name="preferences_separate_libraries">Libraries from separate packages</string>
|
<string name="preferences_separate_libraries">Libraries from separate packages</string>
|
||||||
<string name="preferences_client_package">Client package</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_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="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="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>
|
</resources>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
app:defaultValue="-console -log"
|
app:defaultValue="-console -log"
|
||||||
app:key="arguments"
|
app:key="arguments"
|
||||||
@@ -13,13 +12,6 @@
|
|||||||
app:layout="@layout/switch_preference"
|
app:layout="@layout/switch_preference"
|
||||||
app:title="@string/game_settings_volume_buttons" />
|
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
|
<SwitchPreferenceCompat
|
||||||
app:key="separate_libraries"
|
app:key="separate_libraries"
|
||||||
app:layout="@layout/switch_preference"
|
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.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.android.application) apply false
|
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
|
# Enable verbose output for CMake
|
||||||
android.native.buildOutput=verbose
|
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]
|
[versions]
|
||||||
acraHttp = "5.12.0"
|
acraHttp = "5.12.0"
|
||||||
agp = "9.0.1"
|
agp = "8.11.1"
|
||||||
appcompat = "1.7.1"
|
appcompat = "1.7.1"
|
||||||
|
kotlin = "2.2.0"
|
||||||
material = "1.12.0"
|
material = "1.12.0"
|
||||||
navigationRuntimeKtx = "2.9.1"
|
navigationRuntimeKtx = "2.9.1"
|
||||||
preferenceKtx = "1.2.1"
|
preferenceKtx = "1.2.1"
|
||||||
@@ -19,3 +20,4 @@ swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout"
|
|||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
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
|
#Tue Jul 01 19:51:06 EEST 2025
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
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
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
@@ -11,9 +11,6 @@ pluginManagement {
|
|||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
plugins {
|
|
||||||
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
|
|
||||||
}
|
|
||||||
dependencyResolutionManagement {
|
dependencyResolutionManagement {
|
||||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
@@ -18,20 +18,17 @@ GNU General Public License for more details.
|
|||||||
// video backends (XASH_VIDEO)
|
// video backends (XASH_VIDEO)
|
||||||
#define VIDEO_NULL 0
|
#define VIDEO_NULL 0
|
||||||
#define VIDEO_SDL 1
|
#define VIDEO_SDL 1
|
||||||
#define VIDEO_PSP 2
|
|
||||||
#define VIDEO_FBDEV 3
|
#define VIDEO_FBDEV 3
|
||||||
#define VIDEO_DOS 4
|
#define VIDEO_DOS 4
|
||||||
|
|
||||||
// audio backends (XASH_SOUND)
|
// audio backends (XASH_SOUND)
|
||||||
#define SOUND_NULL 0
|
#define SOUND_NULL 0
|
||||||
#define SOUND_SDL 1
|
#define SOUND_SDL 1
|
||||||
#define SOUND_PSP 2
|
|
||||||
#define SOUND_ALSA 3
|
#define SOUND_ALSA 3
|
||||||
|
|
||||||
// input (XASH_INPUT)
|
// input (XASH_INPUT)
|
||||||
#define INPUT_NULL 0
|
#define INPUT_NULL 0
|
||||||
#define INPUT_SDL 1
|
#define INPUT_SDL 1
|
||||||
#define INPUT_PSP 2
|
|
||||||
#define INPUT_EVDEV 3
|
#define INPUT_EVDEV 3
|
||||||
|
|
||||||
// timer (XASH_TIMER)
|
// timer (XASH_TIMER)
|
||||||
@@ -40,21 +37,18 @@ GNU General Public License for more details.
|
|||||||
#define TIMER_POSIX 2
|
#define TIMER_POSIX 2
|
||||||
#define TIMER_WIN32 3
|
#define TIMER_WIN32 3
|
||||||
#define TIMER_DOS 4
|
#define TIMER_DOS 4
|
||||||
#define TIMER_PSP 5
|
|
||||||
|
|
||||||
// messageboxes (XASH_MESSAGEBOX)
|
// messageboxes (XASH_MESSAGEBOX)
|
||||||
#define MSGBOX_STDERR 0
|
#define MSGBOX_STDERR 0
|
||||||
#define MSGBOX_SDL 1
|
#define MSGBOX_SDL 1
|
||||||
#define MSGBOX_PSP 2
|
|
||||||
#define MSGBOX_WIN32 3
|
#define MSGBOX_WIN32 3
|
||||||
#define MSGBOX_NSWITCH 4
|
#define MSGBOX_NSWITCH 4
|
||||||
|
|
||||||
// library loading (XASH_LIB)
|
// library loading (XASH_LIB)
|
||||||
#define LIB_NULL 0
|
#define LIB_NULL 0
|
||||||
#define LIB_POSIX 1
|
#define LIB_POSIX 1
|
||||||
#define LIB_WIN32 2
|
#define LIB_WIN32 2
|
||||||
#define LIB_STATIC 3
|
#define LIB_STATIC 3
|
||||||
#define LIB_PSP 4
|
|
||||||
|
|
||||||
// movies (XASH_AVI)
|
// movies (XASH_AVI)
|
||||||
#define AVI_NULL 0
|
#define AVI_NULL 0
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
#ifndef BEAMDEF_H
|
#ifndef BEAMDEF_H
|
||||||
#define BEAMDEF_H
|
#define BEAMDEF_H
|
||||||
|
|
||||||
#include "xash3d_types.h"
|
|
||||||
|
|
||||||
#define FBEAM_STARTENTITY 0x00000001
|
#define FBEAM_STARTENTITY 0x00000001
|
||||||
#define FBEAM_ENDENTITY 0x00000002
|
#define FBEAM_ENDENTITY 0x00000002
|
||||||
#define FBEAM_FADEIN 0x00000004
|
#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
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef BSPFILE_H
|
#ifndef BSPFILE_H
|
||||||
#define BSPFILE_H
|
#define BSPFILE_H
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "xash3d_types.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
@@ -28,310 +26,288 @@ BRUSH MODELS
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// header
|
// header
|
||||||
#define Q1BSP_VERSION 29 // quake1 regular version (beta is 28)
|
#define Q1BSP_VERSION 29 // quake1 regular version (beta is 28)
|
||||||
#define HLBSP_VERSION 30 // half-life regular version
|
#define HLBSP_VERSION 30 // half-life regular version
|
||||||
#define QBSP2_VERSION (( 'B' << 0 ) | ( 'S' << 8 ) | ( 'P' << 16 ) | ( '2' << 24 ))
|
#define QBSP2_VERSION (('B' << 0) | ('S' << 8) | ('P' << 16) | ('2'<<24))
|
||||||
|
|
||||||
#define IDEXTRAHEADER (( 'X' << 0 ) | ( 'A' << 8 ) | ( 'S' << 16 ) | ( 'H' << 24 ))
|
#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
|
#define EXTRA_VERSION 4 // ver. 1 was occupied by old versions of XashXT, ver. 2 was occupied by old vesrions of P2:savior
|
||||||
// ver. 2 was occupied by old vesrions of P2:savior
|
// ver. 3 was occupied by experimental versions of P2:savior change fmt
|
||||||
// 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 (('T'<<24)+('I'<<16)+('L'<<8)+'Q') // little-endian "QLIT"
|
||||||
#define DELUXEMAP_VERSION 1
|
|
||||||
#define IDDELUXEMAPHEADER (( 'Q' << 0 ) | ('L' << 8 ) | ( 'I' << 16 ) | ( 'T' << 24 ))
|
|
||||||
|
|
||||||
// worldcraft predefined angles
|
// worldcraft predefined angles
|
||||||
#define ANGLE_UP -1
|
#define ANGLE_UP -1
|
||||||
#define ANGLE_DOWN -2
|
#define ANGLE_DOWN -2
|
||||||
|
|
||||||
// bmodel limits
|
// 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_PLANEBACK BIT( 1 ) // plane should be negated
|
||||||
#define SURF_DRAWSKY BIT( 2 ) // sky surface
|
#define SURF_DRAWSKY BIT( 2 ) // sky surface
|
||||||
#define SURF_DRAWTURB_QUADS BIT( 3 ) // all subidivided polygons are quads
|
#define SURF_DRAWTURB_QUADS BIT( 3 ) // all subidivided polygons are quads
|
||||||
#define SURF_DRAWTURB BIT( 4 ) // warp surface
|
#define SURF_DRAWTURB BIT( 4 ) // warp surface
|
||||||
#define SURF_DRAWTILED BIT( 5 ) // face without lighmap
|
#define SURF_DRAWTILED BIT( 5 ) // face without lighmap
|
||||||
#define SURF_CONVEYOR BIT( 6 ) // scrolled texture (was SURF_DRAWBACKGROUND)
|
#define SURF_CONVEYOR BIT( 6 ) // scrolled texture (was SURF_DRAWBACKGROUND)
|
||||||
#define SURF_UNDERWATER BIT( 7 ) // caustics
|
#define SURF_UNDERWATER BIT( 7 ) // caustics
|
||||||
#define SURF_TRANSPARENT BIT( 8 ) // it's a transparent texture (was SURF_DONTWARP)
|
#define SURF_TRANSPARENT BIT( 8 ) // it's a transparent texture (was SURF_DONTWARP)
|
||||||
|
|
||||||
// lightstyle management
|
// lightstyle management
|
||||||
#define LM_STYLES 4 // MAXLIGHTMAPS
|
#define LM_STYLES 4 // MAXLIGHTMAPS
|
||||||
#define LS_NORMAL 0x00
|
#define LS_NORMAL 0x00
|
||||||
#define LS_UNUSED 0xFE
|
#define LS_UNUSED 0xFE
|
||||||
#define LS_NONE 0xFF
|
#define LS_NONE 0xFF
|
||||||
|
|
||||||
#define MAX_MAP_CLIPNODES_HLBSP 32767
|
#define MAX_MAP_CLIPNODES_HLBSP 32767
|
||||||
#define MAX_MAP_CLIPNODES_BSP2 524288
|
#define MAX_MAP_CLIPNODES_BSP2 524288
|
||||||
|
|
||||||
// these limis not using by modelloader but only for displaying 'mapstats' correctly
|
// these limis not using by modelloader but only for displaying 'mapstats' correctly
|
||||||
#define MAX_MAP_MODELS 2048 // embedded models
|
#define MAX_MAP_MODELS 2048 // embedded models
|
||||||
#define MAX_MAP_ENTSTRING 0x200000 // 2 Mb should be enough
|
#define MAX_MAP_ENTSTRING 0x200000 // 2 Mb should be enough
|
||||||
#define MAX_MAP_PLANES 131072 // can be increased without problems
|
#define MAX_MAP_PLANES 131072 // can be increased without problems
|
||||||
#define MAX_MAP_NODES 262144 // 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_CLIPNODES MAX_MAP_CLIPNODES_BSP2 // can be increased without problems
|
||||||
#define MAX_MAP_LEAFS 131072 // CRITICAL STUFF to run ad_sepulcher!!!
|
#define MAX_MAP_LEAFS 131072 // CRITICAL STUFF to run ad_sepulcher!!!
|
||||||
#define MAX_MAP_VERTS 524288 // can be increased without problems
|
#define MAX_MAP_VERTS 524288 // can be increased without problems
|
||||||
#define MAX_MAP_FACES 262144 // 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_MARKSURFACES 524288 // can be increased without problems
|
||||||
|
|
||||||
#define MAX_MAP_ENTITIES 8192 // network limit
|
#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_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_EDGES 0x100000 // can be increased but not needs
|
||||||
#define MAX_MAP_SURFEDGES 0x200000 // can be increased but not needed
|
#define MAX_MAP_SURFEDGES 0x200000 // can be increased but not needs
|
||||||
#define MAX_MAP_TEXTURES 2048 // can be increased but not needed
|
#define MAX_MAP_TEXTURES 2048 // can be increased but not needs
|
||||||
#define MAX_MAP_MIPTEX 0x2000000 // 32 Mb internal textures data
|
#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_LIGHTING 0x2000000 // 32 Mb lightmap raw data (can contain deluxemaps)
|
||||||
#define MAX_MAP_VISIBILITY 0x1000000 // 16 Mb visdata
|
#define MAX_MAP_VISIBILITY 0x1000000 // 16 Mb visdata
|
||||||
#define MAX_MAP_FACEINFO 8192 // can be increased but not needed
|
#define MAX_MAP_FACEINFO 8192 // can be increased but not needs
|
||||||
|
|
||||||
// quake lump ordering
|
// quake lump ordering
|
||||||
enum
|
#define LUMP_ENTITIES 0
|
||||||
{
|
#define LUMP_PLANES 1
|
||||||
LUMP_ENTITIES = 0,
|
#define LUMP_TEXTURES 2 // internal textures
|
||||||
LUMP_PLANES = 1,
|
#define LUMP_VERTEXES 3
|
||||||
LUMP_TEXTURES = 2, // internal textures
|
#define LUMP_VISIBILITY 4
|
||||||
LUMP_VERTEXES = 3,
|
#define LUMP_NODES 5
|
||||||
LUMP_VISIBILITY = 4,
|
#define LUMP_TEXINFO 6
|
||||||
LUMP_NODES = 5,
|
#define LUMP_FACES 7
|
||||||
LUMP_TEXINFO = 6,
|
#define LUMP_LIGHTING 8
|
||||||
LUMP_FACES = 7,
|
#define LUMP_CLIPNODES 9
|
||||||
LUMP_LIGHTING = 8,
|
#define LUMP_LEAFS 10
|
||||||
LUMP_CLIPNODES = 9,
|
#define LUMP_MARKSURFACES 11
|
||||||
LUMP_LEAFS = 10,
|
#define LUMP_EDGES 12
|
||||||
LUMP_MARKSURFACES = 11,
|
#define LUMP_SURFEDGES 13
|
||||||
LUMP_EDGES = 12,
|
#define LUMP_MODELS 14 // internal submodels
|
||||||
LUMP_SURFEDGES = 13,
|
#define HEADER_LUMPS 15
|
||||||
LUMP_MODELS = 14, // internal submodels
|
|
||||||
HEADER_LUMPS = 15,
|
|
||||||
};
|
|
||||||
|
|
||||||
// extra lump ordering
|
// extra lump ordering
|
||||||
enum
|
#define LUMP_LIGHTVECS 0 // deluxemap data
|
||||||
{
|
#define LUMP_FACEINFO 1 // landscape and lightmap resolution info
|
||||||
LUMP_LIGHTVECS = 0, // deluxemap data
|
#define LUMP_CUBEMAPS 2 // cubemap description
|
||||||
LUMP_FACEINFO = 1, // landscape and lightmap resolution info
|
#define LUMP_VERTNORMALS 3 // phong shaded vertex normals
|
||||||
LUMP_CUBEMAPS = 2, // cubemap description
|
#define LUMP_LEAF_LIGHTING 4 // store vertex lighting for statics
|
||||||
LUMP_VERTNORMALS = 3, // phong shaded vertex normals
|
#define LUMP_WORLDLIGHTS 5 // list of all the virtual and real lights (used to relight models in-game)
|
||||||
LUMP_LEAF_LIGHTING = 4, // store vertex lighting for statics
|
#define LUMP_COLLISION 6 // physics engine collision hull dump (userdata)
|
||||||
LUMP_WORLDLIGHTS = 5, // list of all the virtual and real lights (used to relight models in-game)
|
#define LUMP_AINODEGRAPH 7 // node graph that stored into the bsp (userdata)
|
||||||
LUMP_COLLISION = 6, // physics engine collision hull dump (userdata)
|
#define LUMP_SHADOWMAP 8 // contains shadow map for direct light
|
||||||
LUMP_AINODEGRAPH = 7, // node graph that stored into the bsp (userdata)
|
#define LUMP_VERTEX_LIGHT 9 // store vertex lighting for statics
|
||||||
LUMP_SHADOWMAP = 8, // contains shadow map for direct light
|
#define LUMP_UNUSED0 10 // one lump reserved for me
|
||||||
LUMP_VERTEX_LIGHT = 9, // store vertex lighting for statics
|
#define LUMP_UNUSED1 11 // one lump reserved for me
|
||||||
LUMP_UNUSED0 = 10, // one lump reserved for me
|
#define EXTRA_LUMPS 12 // count of the extra lumps
|
||||||
LUMP_UNUSED1 = 11, // one lump reserved for me
|
|
||||||
EXTRA_LUMPS = 12, // count of the extra lumps
|
|
||||||
};
|
|
||||||
|
|
||||||
// texture flags
|
// texture flags
|
||||||
#define TEX_SPECIAL BIT( 0 ) // sky or slime, no lightmap or 256 subdivision
|
#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_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_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_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_SCROLL BIT( 6 ) // Doom special FX
|
||||||
|
|
||||||
#define IsLiquidContents( cnt ) ( cnt == CONTENTS_WATER || cnt == CONTENTS_SLIME || cnt == CONTENTS_LAVA )
|
#define IsLiquidContents( cnt ) ( cnt == CONTENTS_WATER || cnt == CONTENTS_SLIME || cnt == CONTENTS_LAVA )
|
||||||
|
|
||||||
// ambient sound types
|
// ambient sound types
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
AMBIENT_WATER = 0, // waterfall
|
AMBIENT_WATER = 0, // waterfall
|
||||||
AMBIENT_SKY, // wind
|
AMBIENT_SKY, // wind
|
||||||
AMBIENT_SLIME, // never used in quake
|
AMBIENT_SLIME, // never used in quake
|
||||||
AMBIENT_LAVA, // never used in quake
|
AMBIENT_LAVA, // never used in quake
|
||||||
NUM_AMBIENTS, // automatic ambient sounds
|
NUM_AMBIENTS, // automatic ambient sounds
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// BSP File Structures
|
// BSP File Structures
|
||||||
//
|
//
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int32_t fileofs;
|
int fileofs;
|
||||||
int32_t filelen;
|
int filelen;
|
||||||
} dlump_t;
|
} dlump_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int32_t version;
|
int version;
|
||||||
dlump_t lumps[HEADER_LUMPS];
|
dlump_t lumps[HEADER_LUMPS];
|
||||||
} dheader_t;
|
} dheader_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int32_t id; // must be little endian XASH
|
int id; // must be little endian XASH
|
||||||
int32_t version;
|
int version;
|
||||||
dlump_t lumps[EXTRA_LUMPS];
|
dlump_t lumps[EXTRA_LUMPS];
|
||||||
} dextrahdr_t;
|
} dextrahdr_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char lumpname[24]; // up to 23 chars, zero-padded
|
vec3_t mins;
|
||||||
int32_t fileofs;
|
vec3_t maxs;
|
||||||
int32_t filelen;
|
vec3_t origin; // for sounds or lights
|
||||||
} dbspx_lump_t;
|
int headnode[MAX_MAP_HULLS];
|
||||||
|
int visleafs; // not including the solid leaf 0
|
||||||
typedef struct
|
int firstface;
|
||||||
{
|
int numfaces;
|
||||||
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;
|
|
||||||
} dmodel_t;
|
} dmodel_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int32_t nummiptex;
|
int nummiptex;
|
||||||
int32_t dataofs[4]; // [nummiptex]
|
int dataofs[4]; // [nummiptex]
|
||||||
} dmiptexlump_t;
|
} dmiptexlump_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
vec3_t point;
|
vec3_t point;
|
||||||
} dvertex_t;
|
} dvertex_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
vec3_t normal;
|
vec3_t normal;
|
||||||
float dist;
|
float dist;
|
||||||
int32_t type; // PLANE_X - PLANE_ANYZ ?
|
int type; // PLANE_X - PLANE_ANYZ ?
|
||||||
} dplane_t;
|
} dplane_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int32_t planenum;
|
int planenum;
|
||||||
int16_t children[2]; // negative numbers are -(leafs + 1), not nodes
|
short children[2]; // negative numbers are -(leafs + 1), not nodes
|
||||||
int16_t mins[3]; // for sphere culling
|
short mins[3]; // for sphere culling
|
||||||
int16_t maxs[3];
|
short maxs[3];
|
||||||
uint16_t firstface;
|
word firstface;
|
||||||
uint16_t numfaces; // counting both sides
|
word numfaces; // counting both sides
|
||||||
} dnode_t;
|
} dnode_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int32_t planenum;
|
int planenum;
|
||||||
int32_t children[2]; // negative numbers are -(leafs+1), not nodes
|
int children[2]; // negative numbers are -(leafs+1), not nodes
|
||||||
float mins[3]; // for sphere culling
|
float mins[3]; // for sphere culling
|
||||||
float maxs[3];
|
float maxs[3];
|
||||||
int32_t firstface;
|
int firstface;
|
||||||
int32_t numfaces; // counting both sides
|
int numfaces; // counting both sides
|
||||||
} dnode32_t;
|
} dnode32_t;
|
||||||
|
|
||||||
// leaf 0 is the generic CONTENTS_SOLID leaf, used for all solid areas
|
// leaf 0 is the generic CONTENTS_SOLID leaf, used for all solid areas
|
||||||
// all other leafs need visibility info
|
// all other leafs need visibility info
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int32_t contents;
|
int contents;
|
||||||
int32_t visofs; // -1 = no visibility info
|
int visofs; // -1 = no visibility info
|
||||||
|
|
||||||
int16_t mins[3]; // for frustum culling
|
short mins[3]; // for frustum culling
|
||||||
int16_t maxs[3];
|
short maxs[3];
|
||||||
uint16_t firstmarksurface;
|
word firstmarksurface;
|
||||||
uint16_t nummarksurfaces;
|
word nummarksurfaces;
|
||||||
|
|
||||||
// automatic ambient sounds
|
// 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;
|
} dleaf_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int32_t contents;
|
int contents;
|
||||||
int32_t visofs; // -1 = no visibility info
|
int visofs; // -1 = no visibility info
|
||||||
|
|
||||||
float mins[3]; // for frustum culling
|
float mins[3]; // for frustum culling
|
||||||
float maxs[3];
|
float maxs[3];
|
||||||
|
|
||||||
int32_t firstmarksurface;
|
int firstmarksurface;
|
||||||
int32_t nummarksurfaces;
|
int nummarksurfaces;
|
||||||
|
|
||||||
uint8_t ambient_level[NUM_AMBIENTS];
|
byte ambient_level[NUM_AMBIENTS];
|
||||||
} dleaf32_t;
|
} dleaf32_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int32_t planenum;
|
int planenum;
|
||||||
int16_t children[2]; // negative numbers are contents
|
short children[2]; // negative numbers are contents
|
||||||
} dclipnode_t;
|
} dclipnode_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int32_t planenum;
|
int planenum;
|
||||||
int32_t children[2]; // negative numbers are contents
|
int children[2]; // negative numbers are contents
|
||||||
} dclipnode32_t;
|
} dclipnode32_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
float vecs[2][4]; // texmatrix [s/t][xyz offset]
|
float vecs[2][4]; // texmatrix [s/t][xyz offset]
|
||||||
int32_t miptex;
|
int miptex;
|
||||||
int16_t flags;
|
short flags;
|
||||||
int16_t faceinfo; // -1 no face info otherwise dfaceinfo_t
|
short faceinfo; // -1 no face info otherwise dfaceinfo_t
|
||||||
} dtexinfo_t;
|
} dtexinfo_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char landname[16]; // name of decsription in mapname_land.txt
|
char landname[16]; // name of decsription in mapname_land.txt
|
||||||
uint16_t texture_step; // default is 16, pixels\luxels ratio
|
unsigned short texture_step; // default is 16, pixels\luxels ratio
|
||||||
uint16_t max_extent; // default is 16, subdivision step ((texture_step * max_extent) - texture_step)
|
unsigned short 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
|
short groupid; // to determine equal landscapes from various groups, -1 - no group
|
||||||
} dfaceinfo_t;
|
} dfaceinfo_t;
|
||||||
|
|
||||||
typedef uint16_t dmarkface_t; // leaf marksurfaces indexes
|
typedef word dmarkface_t; // leaf marksurfaces indexes
|
||||||
typedef int32_t dmarkface32_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
|
// NOTE: that edge 0 is never used, because negative edge nums
|
||||||
// are used for counterclockwise use of the edge in a face
|
// are used for counterclockwise use of the edge in a face
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint16_t v[2]; // vertex numbers
|
word v[2]; // vertex numbers
|
||||||
} dedge_t;
|
} dedge_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int32_t v[2]; // vertex numbers
|
int v[2]; // vertex numbers
|
||||||
} dedge32_t;
|
} dedge32_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint16_t planenum;
|
word planenum;
|
||||||
int16_t side;
|
short side;
|
||||||
|
|
||||||
int32_t firstedge; // we must support > 64k edges
|
int firstedge; // we must support > 64k edges
|
||||||
int16_t numedges;
|
short numedges;
|
||||||
int16_t texinfo;
|
short texinfo;
|
||||||
|
|
||||||
// lighting info
|
// lighting info
|
||||||
uint8_t styles[LM_STYLES];
|
byte styles[LM_STYLES];
|
||||||
int32_t lightofs; // start of [numstyles*surfsize] samples
|
int lightofs; // start of [numstyles*surfsize] samples
|
||||||
} dface_t;
|
} dface_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int32_t planenum;
|
int planenum;
|
||||||
int32_t side;
|
int side;
|
||||||
|
|
||||||
int32_t firstedge; // we must support > 64k edges
|
int firstedge; // we must support > 64k edges
|
||||||
int32_t numedges;
|
int numedges;
|
||||||
int32_t texinfo;
|
int texinfo;
|
||||||
|
|
||||||
// lighting info
|
// lighting info
|
||||||
uint8_t styles[LM_STYLES];
|
byte styles[LM_STYLES];
|
||||||
int32_t lightofs; // start of [numstyles*surfsize] samples
|
int lightofs; // start of [numstyles*surfsize] samples
|
||||||
} dface32_t;
|
} dface32_t;
|
||||||
|
|
||||||
#endif // BSPFILE_H
|
#endif//BSPFILE_H
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
#ifndef CL_ENTITY_H
|
#ifndef CL_ENTITY_H
|
||||||
#define CL_ENTITY_H
|
#define CL_ENTITY_H
|
||||||
|
|
||||||
#include "const.h"
|
|
||||||
|
|
||||||
typedef struct efrag_s
|
typedef struct efrag_s
|
||||||
{
|
{
|
||||||
struct mleaf_s *leaf;
|
struct mleaf_s *leaf;
|
||||||
|
|||||||
@@ -1,23 +1,4 @@
|
|||||||
/*
|
#pragma once
|
||||||
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"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
========================================================================
|
========================================================================
|
||||||
|
|
||||||
@@ -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
|
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 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_KTX2_RAW )
|
#define ImageCompressed( type ) \
|
||||||
#define ImageBigEndian( type ) ( type == PF_BGRA_32 || type == PF_BGR_24 )
|
( 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
|
typedef enum
|
||||||
{
|
{
|
||||||
@@ -57,20 +50,11 @@ typedef enum
|
|||||||
PF_TOTALCOUNT, // must be last
|
PF_TOTALCOUNT, // must be last
|
||||||
} pixformat_t;
|
} pixformat_t;
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
RF_COMPRESSED,
|
|
||||||
RF_RGBA,
|
|
||||||
RF_BGRA,
|
|
||||||
RF_BGR,
|
|
||||||
RF_LUMINANCE
|
|
||||||
} rawformat_t;
|
|
||||||
|
|
||||||
typedef struct bpc_desc_s
|
typedef struct bpc_desc_s
|
||||||
{
|
{
|
||||||
int format; // pixelformat
|
int format; // pixelformat
|
||||||
char name[16]; // used for debug
|
char name[16]; // used for debug
|
||||||
rawformat_t rawformat;
|
uint glFormat; // RGBA format
|
||||||
int bpp; // channels (e.g. rgb = 3, rgba = 4)
|
int bpp; // channels (e.g. rgb = 3, rgba = 4)
|
||||||
} bpc_desc_t;
|
} bpc_desc_t;
|
||||||
|
|
||||||
@@ -86,7 +70,6 @@ typedef enum
|
|||||||
IL_OVERVIEW = BIT(6), // overview required some unque operations
|
IL_OVERVIEW = BIT(6), // overview required some unque operations
|
||||||
IL_LOAD_PLAYER_DECAL = BIT(7), // special mode for player decals
|
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_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;
|
} ilFlags_t;
|
||||||
|
|
||||||
// goes into rgbdata_t->encode
|
// goes into rgbdata_t->encode
|
||||||
@@ -116,8 +99,6 @@ typedef enum
|
|||||||
IMAGE_MULTILAYER = BIT(8), // to differentiate from 3D texture
|
IMAGE_MULTILAYER = BIT(8), // to differentiate from 3D texture
|
||||||
IMAGE_ONEBIT_ALPHA = BIT(9), // binary alpha
|
IMAGE_ONEBIT_ALPHA = BIT(9), // binary alpha
|
||||||
IMAGE_QUAKEPAL = BIT(10), // image has quake1 palette
|
IMAGE_QUAKEPAL = BIT(10), // image has quake1 palette
|
||||||
IMAGE_PREMULTIPLIED = BIT(11),
|
|
||||||
IMAGE_PLAYERDECAL = BIT(12), // loaded with IL_LOAD_PLAYER_DECAL (custom player spray)
|
|
||||||
|
|
||||||
// Image_Process manipulation flags
|
// Image_Process manipulation flags
|
||||||
IMAGE_FLIP_X = BIT(16), // flip the image by width
|
IMAGE_FLIP_X = BIT(16), // flip the image by width
|
||||||
@@ -151,4 +132,3 @@ typedef struct rgbdata_s
|
|||||||
size_t size; // for bounds checking
|
size_t size; // for bounds checking
|
||||||
} rgbdata_t;
|
} rgbdata_t;
|
||||||
|
|
||||||
#endif//COM_IMAGE_H
|
|
||||||
|
|||||||
@@ -16,11 +16,9 @@ GNU General Public License for more details.
|
|||||||
#ifndef COM_MODEL_H
|
#ifndef COM_MODEL_H
|
||||||
#define COM_MODEL_H
|
#define COM_MODEL_H
|
||||||
|
|
||||||
#include "const.h"
|
#include "xash3d_types.h"
|
||||||
#include "bspfile.h" // we need some declarations from it
|
#include "bspfile.h" // we need some declarations from it
|
||||||
|
|
||||||
#include "xash3d_mathlib.h" // mplane_t
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|
||||||
@@ -48,6 +46,15 @@ typedef enum
|
|||||||
mod_studio
|
mod_studio
|
||||||
} modtype_t;
|
} 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
|
typedef struct
|
||||||
{
|
{
|
||||||
vec3_t position;
|
vec3_t position;
|
||||||
@@ -612,9 +619,9 @@ static inline mnode_t *node_child( const mnode_t *n, int side, const model_t *mo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return n->children_[side ? 1 : 0];
|
return n->children_[side];
|
||||||
#else
|
#else
|
||||||
return n->children_[side ? 1 : 0];
|
return n->children_[side];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -723,6 +723,8 @@ enum
|
|||||||
typedef int func_t;
|
typedef int func_t;
|
||||||
typedef int string_t;
|
typedef int string_t;
|
||||||
|
|
||||||
|
typedef unsigned short word;
|
||||||
|
|
||||||
#include "xash3d_types.h"
|
#include "xash3d_types.h"
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -735,6 +737,11 @@ typedef struct
|
|||||||
unsigned r, g, b, a;
|
unsigned r, g, b, a;
|
||||||
} colorVec;
|
} colorVec;
|
||||||
|
|
||||||
|
typedef struct link_s
|
||||||
|
{
|
||||||
|
struct link_s *prev, *next;
|
||||||
|
} link_t;
|
||||||
|
|
||||||
typedef struct edict_s edict_t;
|
typedef struct edict_s edict_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||||||
#ifndef CVAR
|
#ifndef CVAR
|
||||||
#define CVAR
|
#define CVAR
|
||||||
|
|
||||||
#include <stdint.h>
|
#include STDINT_H
|
||||||
#include "xash3d_types.h"
|
#include "xash3d_types.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -26,44 +26,68 @@ SETUP BACKENDS DEFINITIONS
|
|||||||
|
|
||||||
===================================================================
|
===================================================================
|
||||||
*/
|
*/
|
||||||
//
|
#if !XASH_DEDICATED
|
||||||
// when compiling client, we need to pick video, audio and input implementations
|
#if XASH_SDL
|
||||||
//
|
// we are building using libSDL
|
||||||
#if !XASH_DEDICATED // when compiling client, we need to pick video, audio and input implementations
|
#ifndef XASH_VIDEO
|
||||||
#if XASH_SDL // we are building with SDL
|
#define XASH_VIDEO VIDEO_SDL
|
||||||
#define XASH_VIDEO VIDEO_SDL
|
#endif // XASH_VIDEO
|
||||||
#define XASH_INPUT INPUT_SDL
|
|
||||||
#define XASH_SOUND SOUND_SDL
|
#ifndef XASH_INPUT
|
||||||
#elif XASH_LINUX // we are building for Linux without SDL, only framebuffer is supported for now
|
#define XASH_INPUT INPUT_SDL
|
||||||
#define XASH_VIDEO VIDEO_FBDEV
|
#endif // XASH_INPUT
|
||||||
#define XASH_INPUT INPUT_EVDEV
|
|
||||||
#define XASH_SOUND SOUND_ALSA
|
#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
|
#define XASH_USE_EVDEV 1
|
||||||
#elif XASH_DOS4GW
|
#elif XASH_DOS4GW
|
||||||
#define XASH_VIDEO VIDEO_DOS
|
#ifndef XASH_VIDEO
|
||||||
#define XASH_REDUCE_FD 1 // usually only 10-20 fds available
|
#define XASH_VIDEO VIDEO_DOS
|
||||||
#elif XASH_PSP
|
#endif
|
||||||
#define XASH_VIDEO VIDEO_PSP
|
#ifndef XASH_TIMER
|
||||||
#define XASH_INPUT INPUT_PSP
|
#define XASH_TIMER TIMER_DOS
|
||||||
#define XASH_SOUND SOUND_PSP
|
#endif
|
||||||
#define XASH_REDUCE_FD 1
|
|
||||||
#define XASH_NO_TOUCH 1
|
// usually only 10-20 fds availiable
|
||||||
#define XASH_NO_ZIP 1
|
#define XASH_REDUCE_FD
|
||||||
#endif
|
#endif
|
||||||
#endif // !XASH_DEDICATED
|
#endif // XASH_DEDICATED
|
||||||
|
|
||||||
//
|
//
|
||||||
// select messagebox implementation
|
// select messagebox implementation
|
||||||
//
|
//
|
||||||
#ifndef XASH_MESSAGEBOX
|
#ifndef XASH_MESSAGEBOX
|
||||||
#if XASH_SDL >= 2 && !XASH_NSWITCH // SDL2 messageboxes are not available on NSW
|
#if XASH_WIN32
|
||||||
#define XASH_MESSAGEBOX MSGBOX_SDL
|
|
||||||
#elif XASH_WIN32
|
|
||||||
#define XASH_MESSAGEBOX MSGBOX_WIN32
|
#define XASH_MESSAGEBOX MSGBOX_WIN32
|
||||||
#elif XASH_NSWITCH
|
#elif XASH_NSWITCH
|
||||||
#define XASH_MESSAGEBOX MSGBOX_NSWITCH
|
#define XASH_MESSAGEBOX MSGBOX_NSWITCH
|
||||||
#elif XASH_PSP
|
|
||||||
#define XASH_MESSAGEBOX MSGBOX_PSP
|
|
||||||
#else // !XASH_WIN32
|
#else // !XASH_WIN32
|
||||||
#define XASH_MESSAGEBOX MSGBOX_STDERR
|
#define XASH_MESSAGEBOX MSGBOX_STDERR
|
||||||
#endif // !XASH_WIN32
|
#endif // !XASH_WIN32
|
||||||
@@ -73,14 +97,8 @@ SETUP BACKENDS DEFINITIONS
|
|||||||
// no timer - no xash
|
// no timer - no xash
|
||||||
//
|
//
|
||||||
#ifndef XASH_TIMER
|
#ifndef XASH_TIMER
|
||||||
#if XASH_SDL >= 2
|
#if XASH_WIN32
|
||||||
#define XASH_TIMER TIMER_SDL
|
|
||||||
#elif XASH_WIN32
|
|
||||||
#define XASH_TIMER TIMER_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
|
#else // !XASH_WIN32
|
||||||
#define XASH_TIMER TIMER_POSIX
|
#define XASH_TIMER TIMER_POSIX
|
||||||
#endif // !XASH_WIN32
|
#endif // !XASH_WIN32
|
||||||
@@ -97,16 +115,14 @@ SETUP BACKENDS DEFINITIONS
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if XASH_PSP
|
#ifdef XASH_STATIC_LIBS
|
||||||
#define XASH_PSP LIB_PSP
|
#define XASH_LIB LIB_STATIC
|
||||||
#elif defined( XASH_STATIC_LIBS )
|
#define XASH_INTERNAL_GAMELIBS
|
||||||
#define XASH_LIB LIB_STATIC
|
#define XASH_ALLOW_SAVERESTORE_OFFSETS
|
||||||
#define XASH_INTERNAL_GAMELIBS
|
|
||||||
#define XASH_ALLOW_SAVERESTORE_OFFSETS
|
|
||||||
#elif XASH_WIN32
|
#elif XASH_WIN32
|
||||||
#define XASH_LIB LIB_WIN32
|
#define XASH_LIB LIB_WIN32
|
||||||
#elif XASH_POSIX
|
#elif XASH_POSIX
|
||||||
#define XASH_LIB LIB_POSIX
|
#define XASH_LIB LIB_POSIX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -133,11 +149,7 @@ Default build-depended cvar and constant values
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Platform overrides
|
// Platform overrides
|
||||||
#if XASH_WIN32
|
#if XASH_NSWITCH
|
||||||
// set up windowed by default on Windows to avoid problems with
|
|
||||||
// Xbox Game Bar
|
|
||||||
#define DEFAULT_FULLSCREEN "0"
|
|
||||||
#elif XASH_NSWITCH
|
|
||||||
#define DEFAULT_TOUCH_ENABLE "1"
|
#define DEFAULT_TOUCH_ENABLE "1"
|
||||||
#define DEFAULT_M_IGNORE "1"
|
#define DEFAULT_M_IGNORE "1"
|
||||||
#define DEFAULT_MODE_WIDTH 1280
|
#define DEFAULT_MODE_WIDTH 1280
|
||||||
@@ -156,6 +168,12 @@ Default build-depended cvar and constant values
|
|||||||
#define DEFAULT_M_IGNORE "1"
|
#define DEFAULT_M_IGNORE "1"
|
||||||
#endif // !XASH_MOBILE_PLATFORM && !XASH_NSWITCH
|
#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
|
// Defaults
|
||||||
#ifndef DEFAULT_TOUCH_ENABLE
|
#ifndef DEFAULT_TOUCH_ENABLE
|
||||||
#define DEFAULT_TOUCH_ENABLE "0"
|
#define DEFAULT_TOUCH_ENABLE "0"
|
||||||
@@ -178,28 +196,11 @@ Default build-depended cvar and constant values
|
|||||||
#endif // DEFAULT_ALLOWCONSOLE
|
#endif // DEFAULT_ALLOWCONSOLE
|
||||||
|
|
||||||
#ifndef DEFAULT_FULLSCREEN
|
#ifndef DEFAULT_FULLSCREEN
|
||||||
#define DEFAULT_FULLSCREEN "2" // must be a string
|
#define DEFAULT_FULLSCREEN "1" // must be a string
|
||||||
#endif // DEFAULT_FULLSCREEN
|
#endif // DEFAULT_FULLSCREEN
|
||||||
|
|
||||||
#ifndef DEFAULT_MAX_EDICTS
|
#ifndef DEFAULT_MAX_EDICTS
|
||||||
#define DEFAULT_MAX_EDICTS 1200 // was 900 before HL25
|
#define DEFAULT_MAX_EDICTS 1200 // was 900 before HL25
|
||||||
#endif // DEFAULT_MAX_EDICTS
|
#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
|
#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
|
#ifndef LIGHTSTYLE_H
|
||||||
#define LIGHTSTYLE_H
|
#define LIGHTSTYLE_H
|
||||||
|
|
||||||
#include "xash3d_types.h"
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char pattern[256];
|
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
|
// Set this flag for things like broadcast requests, etc. where the engine should not
|
||||||
// kill the request hook after receiving the first response
|
// kill the request hook after receiving the first response
|
||||||
#define FNETAPI_MULTIPLE_RESPONSE ( 1<<0 )
|
#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;
|
struct net_response_s;
|
||||||
typedef void (*net_api_response_func_t) ( struct net_response_s *response );
|
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
|
#ifndef NET_ADR_H
|
||||||
#define NET_ADR_H
|
#define NET_ADR_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include STDINT_H
|
||||||
|
|
||||||
// net.h -- quake's interface to the networking layer
|
// net.h -- quake's interface to the networking layer
|
||||||
// a1ba: copied from Quake-2/qcommon/qcommon.h and modified to support IPv6
|
// 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
|
#ifndef PORT_H
|
||||||
#define 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 <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.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
|
#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
|
#ifndef R_EFX_H
|
||||||
#define R_EFX_H
|
#define R_EFX_H
|
||||||
|
|
||||||
|
// particle_t
|
||||||
|
#if !defined( PARTICLEDEFH )
|
||||||
|
#include "particledef.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// BEAM
|
// BEAM
|
||||||
#if !defined( BEAMDEF_H )
|
#if !defined( BEAMDEFH )
|
||||||
#include "beamdef.h"
|
#include "beamdef.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// dlight_t
|
||||||
|
#if !defined ( DLIGHTH )
|
||||||
|
#include "dlight.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// cl_entity_t
|
// cl_entity_t
|
||||||
#if !defined( CL_ENTITY_H )
|
#if !defined( CL_ENTITYH )
|
||||||
#include "cl_entity.h"
|
#include "cl_entity.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -104,9 +114,7 @@ typedef struct tempent_s
|
|||||||
// baseline.angles - angle velocity
|
// baseline.angles - angle velocity
|
||||||
} TEMPENTITY;
|
} TEMPENTITY;
|
||||||
|
|
||||||
typedef struct particle_s particle_t;
|
|
||||||
typedef struct efx_api_s efx_api_t;
|
typedef struct efx_api_s efx_api_t;
|
||||||
struct dlight_s;
|
|
||||||
|
|
||||||
struct efx_api_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_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_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 );
|
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 );
|
dlight_t *(*CL_AllocDlight)( int key );
|
||||||
struct dlight_s *(*CL_AllocElight)( int key );
|
dlight_t *(*CL_AllocElight)( int key );
|
||||||
TEMPENTITY *(*CL_TempEntAlloc)( const float *org, struct model_s *model );
|
TEMPENTITY *(*CL_TempEntAlloc)( const float *org, struct model_s *model );
|
||||||
TEMPENTITY *(*CL_TempEntAllocNoModel)( const float *org );
|
TEMPENTITY *(*CL_TempEntAllocNoModel)( const float *org );
|
||||||
TEMPENTITY *(*CL_TempEntAllocHigh)( const float *org, struct model_s *model );
|
TEMPENTITY *(*CL_TempEntAllocHigh)( const float *org, struct model_s *model );
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
#ifndef REF_PARAMS_H
|
#ifndef REF_PARAMS_H
|
||||||
#define REF_PARAMS_H
|
#define REF_PARAMS_H
|
||||||
|
|
||||||
#include "xash3d_types.h"
|
|
||||||
|
|
||||||
typedef struct ref_params_s
|
typedef struct ref_params_s
|
||||||
{
|
{
|
||||||
// output
|
// output
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ GNU General Public License for more details.
|
|||||||
#ifndef RENDER_API_H
|
#ifndef RENDER_API_H
|
||||||
#define RENDER_API_H
|
#define RENDER_API_H
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "lightstyle.h"
|
#include "lightstyle.h"
|
||||||
|
#include "dlight.h"
|
||||||
|
|
||||||
#define CL_RENDER_INTERFACE_VERSION 37 // Xash3D 1.0
|
#define CL_RENDER_INTERFACE_VERSION 37 // Xash3D 1.0
|
||||||
#define MAX_STUDIO_DECALS 4096 // + unused space of BSP decals
|
#define MAX_STUDIO_DECALS 4096 // + unused space of BSP decals
|
||||||
@@ -101,7 +101,7 @@ typedef enum
|
|||||||
TF_TEXTURE_3D = (1<<20), // this is GL_TEXTURE_3D
|
TF_TEXTURE_3D = (1<<20), // this is GL_TEXTURE_3D
|
||||||
TF_ATLAS_PAGE = (1<<21), // bit who indicate lightmap page or deluxemap page
|
TF_ATLAS_PAGE = (1<<21), // bit who indicate lightmap page or deluxemap page
|
||||||
TF_ALPHACONTRAST = (1<<22), // special texture mode for A2C
|
TF_ALPHACONTRAST = (1<<22), // special texture mode for A2C
|
||||||
TF_PREMULTIPLIED = (1<<23), // RGBA was stored premultiplied (HL gradient / indexalpha)
|
// reserved
|
||||||
// reserved
|
// reserved
|
||||||
TF_IMG_UPLOADED = (1<<25), // this is set for first time when called glTexImage, otherwise it will be call glTexSubImage
|
TF_IMG_UPLOADED = (1<<25), // this is set for first time when called glTexImage, otherwise it will be call glTexSubImage
|
||||||
TF_ARB_FLOAT = (1<<26), // float textures
|
TF_ARB_FLOAT = (1<<26), // float textures
|
||||||
@@ -175,7 +175,6 @@ enum movie_parms_e
|
|||||||
|
|
||||||
struct movie_state_s;
|
struct movie_state_s;
|
||||||
struct ref_viewpass_s;
|
struct ref_viewpass_s;
|
||||||
struct dlight_s;
|
|
||||||
|
|
||||||
typedef struct render_api_s
|
typedef struct render_api_s
|
||||||
{
|
{
|
||||||
@@ -184,8 +183,8 @@ typedef struct render_api_s
|
|||||||
void (*GetDetailScaleForTexture)( int texture, float *xScale, float *yScale );
|
void (*GetDetailScaleForTexture)( int texture, float *xScale, float *yScale );
|
||||||
void (*GetExtraParmsForTexture)( int texture, byte *red, byte *green, byte *blue, byte *alpha );
|
void (*GetExtraParmsForTexture)( int texture, byte *red, byte *green, byte *blue, byte *alpha );
|
||||||
lightstyle_t* (*GetLightStyle)( int number );
|
lightstyle_t* (*GetLightStyle)( int number );
|
||||||
struct dlight_s* (*GetDynamicLight)( int number );
|
dlight_t* (*GetDynamicLight)( int number );
|
||||||
struct dlight_s* (*GetEntityLight)( int number );
|
dlight_t* (*GetEntityLight)( int number );
|
||||||
byte (*LightToTexGamma)( byte color ); // software gamma support
|
byte (*LightToTexGamma)( byte color ); // software gamma support
|
||||||
float (*GetFrameTime)( void );
|
float (*GetFrameTime)( void );
|
||||||
|
|
||||||
|
|||||||
@@ -1,196 +0,0 @@
|
|||||||
/*
|
|
||||||
sound_api.h - Xash3D extension for client sound interface
|
|
||||||
Copyright (C) 2026 Xash3D FWGS Developers
|
|
||||||
|
|
||||||
This is free and unencumbered software released into the public domain.
|
|
||||||
|
|
||||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
||||||
distribute this software, either in source code form or as a compiled
|
|
||||||
binary, for any purpose, commercial or non-commercial, and by any
|
|
||||||
means.
|
|
||||||
|
|
||||||
In jurisdictions that recognize copyright laws, the author or authors
|
|
||||||
of this software dedicate any and all copyright interest in the
|
|
||||||
software to the public domain. We make this dedication for the benefit
|
|
||||||
of the public at large and to the detriment of our heirs and
|
|
||||||
successors. We intend this dedication to be an overt act of
|
|
||||||
relinquishment in perpetuity of all present and future rights to this
|
|
||||||
software under copyright law.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
||||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
For more information, please refer to <http://unlicense.org/>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SOUND_API_H
|
|
||||||
#define SOUND_API_H
|
|
||||||
|
|
||||||
#include "xash3d_types.h"
|
|
||||||
|
|
||||||
// Experimental implementation, backward compatibility is not guaranteed.
|
|
||||||
#define CL_SOUND_INTERFACE_VERSION 1
|
|
||||||
|
|
||||||
#define FL_VOXWORD_IN_CACHE BIT( 0 ) // if set, it was loaded prior and shouldn't be freed
|
|
||||||
|
|
||||||
#define FL_CHAN_USE_LOOP BIT( 0 ) // don't loop default and local sounds
|
|
||||||
#define FL_CHAN_STATIC_SOUND BIT( 1 ) // use origin instead of fetching entnum's origin
|
|
||||||
#define FL_CHAN_LOCAL_SOUND BIT( 2 ) // it's a local menu sound (not looped, not paused)
|
|
||||||
#define FL_CHAN_SENTENCE_FINISHED BIT( 4 ) // if set, finished playing sentence
|
|
||||||
#define FL_CHAN_FINISHED BIT( 5 ) // if set, finished playing single word
|
|
||||||
|
|
||||||
typedef int sound_t;
|
|
||||||
|
|
||||||
typedef struct portable_samplepair_s
|
|
||||||
{
|
|
||||||
int left;
|
|
||||||
int right;
|
|
||||||
} portable_samplepair_t;
|
|
||||||
|
|
||||||
typedef struct sfx_s
|
|
||||||
{
|
|
||||||
char name[MAX_QPATH];
|
|
||||||
wavdata_t *cache;
|
|
||||||
|
|
||||||
int servercount;
|
|
||||||
uint hashValue;
|
|
||||||
struct sfx_s *hashNext;
|
|
||||||
} sfx_t;
|
|
||||||
|
|
||||||
typedef struct voxword_s
|
|
||||||
{
|
|
||||||
sfx_t *sfx;
|
|
||||||
uint16_t volume; // volume percent
|
|
||||||
uint16_t pitch; // pitch shift percent (keep large for extra chipmunk fun)
|
|
||||||
uint8_t timecompress; // percent of skipped data (speeds up playback without pitch shift)
|
|
||||||
uint8_t start; // percent at which playback starts
|
|
||||||
uint8_t end; // percent at which playback ends
|
|
||||||
uint8_t flags;
|
|
||||||
} voxword_t;
|
|
||||||
|
|
||||||
typedef struct channel_s
|
|
||||||
{
|
|
||||||
char name[16]; // keep sentence name
|
|
||||||
sfx_t *sfx; // sfx number
|
|
||||||
|
|
||||||
vec3_t origin; // only use if fixed_origin is set
|
|
||||||
float dist_mult; // distance multiplier (attenuation/clipK)
|
|
||||||
|
|
||||||
int entchannel; // sound channel (CHAN_STREAM, CHAN_VOICE, etc.)
|
|
||||||
uint flags;
|
|
||||||
short entnum; // entity soundsource
|
|
||||||
short master_vol; // 0-255 master volume
|
|
||||||
short leftvol; // 0-255 left volume
|
|
||||||
short rightvol; // 0-255 right volume
|
|
||||||
short basePitch; // base pitch percent (100% is normal pitch playback)
|
|
||||||
byte word_index;
|
|
||||||
|
|
||||||
// HACKHACK: count when this channel became inaudible
|
|
||||||
// to not free it when it could be respatialized soon
|
|
||||||
#define MAX_CHANNEL_INAUDIBLE_TIME 0.1f
|
|
||||||
float inauduble_free_time;
|
|
||||||
|
|
||||||
double sample;
|
|
||||||
double forced_end;
|
|
||||||
wavdata_t *data;
|
|
||||||
voxword_t *words; // dynamically allocated, (num_words + 1) entries, null sfx terminates
|
|
||||||
|
|
||||||
uintptr_t engine_reserved[8]; // only for engine developers
|
|
||||||
uintptr_t game_reserved[8]; // free space for game developers
|
|
||||||
} channel_t;
|
|
||||||
|
|
||||||
typedef struct rawchan_s
|
|
||||||
{
|
|
||||||
short entnum;
|
|
||||||
short master_vol;
|
|
||||||
short leftvol; // 0-255 left volume
|
|
||||||
short rightvol; // 0-255 right volume
|
|
||||||
float dist_mult; // distance multiplier (attenuation/clipK)
|
|
||||||
vec3_t origin; // only use if fixed_origin is set
|
|
||||||
volatile uint s_rawend;
|
|
||||||
float oldtime; // catch time jumps
|
|
||||||
|
|
||||||
uintptr_t engine_reserved[8]; // only for engine developers
|
|
||||||
uintptr_t game_reserved[8]; // free space for game developers
|
|
||||||
|
|
||||||
size_t max_samples; // buffer length
|
|
||||||
portable_samplepair_t rawsamples[]; // variable sized
|
|
||||||
} rawchan_t;
|
|
||||||
|
|
||||||
typedef struct snd_format_s
|
|
||||||
{
|
|
||||||
uint speed;
|
|
||||||
byte width;
|
|
||||||
byte channels;
|
|
||||||
} snd_format_t;
|
|
||||||
|
|
||||||
typedef struct snd_globals_s
|
|
||||||
{
|
|
||||||
// dma
|
|
||||||
const char *backend_name;
|
|
||||||
byte *buffer;
|
|
||||||
snd_format_t format;
|
|
||||||
qboolean initialized; // sound engine is active
|
|
||||||
int samples; // mono samples in buffer
|
|
||||||
int samplepos; // in mono samples
|
|
||||||
|
|
||||||
int paintedtime; // total samples that have been mixed at speed
|
|
||||||
int soundtime; // total samples that have been played out to hardware at dma speed
|
|
||||||
|
|
||||||
// listener (client, camera, etc)
|
|
||||||
vec3_t origin;
|
|
||||||
vec3_t forward, right, up;
|
|
||||||
int entnum;
|
|
||||||
qboolean streaming; // playing AVI-file
|
|
||||||
qboolean stream_paused; // pause only background track
|
|
||||||
|
|
||||||
// SoundAPI shared pointers
|
|
||||||
channel_t *const channels;
|
|
||||||
int max_channels;
|
|
||||||
int total_channels;
|
|
||||||
rawchan_t **const raw_channels;
|
|
||||||
int max_raw_channels;
|
|
||||||
sound_t ambient_sfx[NUM_AMBIENTS];
|
|
||||||
qboolean have_ambient_sfx;
|
|
||||||
} snd_globals_t;
|
|
||||||
|
|
||||||
typedef struct voice_audio_info_s
|
|
||||||
{
|
|
||||||
uint width;
|
|
||||||
uint samplerate;
|
|
||||||
uint frame_size; // in samples
|
|
||||||
} voice_audio_info_t;
|
|
||||||
|
|
||||||
// API from engine to client (client calls these)
|
|
||||||
typedef struct sound_api_s
|
|
||||||
{
|
|
||||||
qboolean (*CL_GetEntitySpatialization)( channel_t *ch );
|
|
||||||
sfx_t* (*S_GetSfxByHandle)( sound_t handle );
|
|
||||||
// Voice extensions
|
|
||||||
void (*pfnS_RawEntSamples)( int entnum, uint samples, uint rate, word width, word channels, const byte *data, int snd_vol, float attn );
|
|
||||||
void (*pfnSND_ForceInitMouth)( int entnum );
|
|
||||||
voice_audio_info_t (*pfnVoice_GetAudioInfo)( void );
|
|
||||||
} sound_api_t;
|
|
||||||
|
|
||||||
// Callbacks from client to engine (engine calls these when custom sound is active)
|
|
||||||
typedef struct sound_interface_s
|
|
||||||
{
|
|
||||||
int version;
|
|
||||||
|
|
||||||
qboolean (*pfnS_Init)( snd_globals_t *globals );
|
|
||||||
void (*pfnS_Shutdown)( void );
|
|
||||||
void (*pfnS_UpdateSound)( void );
|
|
||||||
/* Full paint: endtime (sample pairs), dma buffer, paintedtime in/out. Client does mix + transfer to dma.buffer. */
|
|
||||||
void (*pfnS_PaintChannels)( int endtime );
|
|
||||||
void (*pfnS_UpdateChannel)( int ch_idx, const channel_t *ch, sound_t handle ); // ch=NULL -> channel freed
|
|
||||||
void (*pfnS_UpdateRawChannel)( int raw_idx, rawchan_t *ch ); // ch=NULL -> channel freed
|
|
||||||
void (*pfnS_Spatialize)( channel_t *ch );
|
|
||||||
void (*pfnS_FreeSound)( sfx_t *sfx, sound_t handle );
|
|
||||||
} sound_interface_t;
|
|
||||||
|
|
||||||
#endif // SOUND_API_H
|
|
||||||
39
common/usercmd.h
Normal file
39
common/usercmd.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/***
|
||||||
|
*
|
||||||
|
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
|
||||||
|
*
|
||||||
|
* This product contains software technology licensed from Id
|
||||||
|
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use, distribution, and modification of this source code and/or resulting
|
||||||
|
* object code is restricted to non-commercial enhancements to products from
|
||||||
|
* Valve LLC. All other use, distribution, or modification is prohibited
|
||||||
|
* without written permission from Valve LLC.
|
||||||
|
*
|
||||||
|
****/
|
||||||
|
|
||||||
|
#ifndef USERCMD_H
|
||||||
|
#define USERCMD_H
|
||||||
|
|
||||||
|
typedef struct usercmd_s
|
||||||
|
{
|
||||||
|
short lerp_msec; // Interpolation time on client
|
||||||
|
byte msec; // Duration in ms of command
|
||||||
|
vec3_t viewangles; // Command view angles
|
||||||
|
|
||||||
|
// intended velocities
|
||||||
|
float forwardmove; // Forward velocity
|
||||||
|
float sidemove; // Sideways velocity
|
||||||
|
float upmove; // Upward velocity
|
||||||
|
byte lightlevel; // Light level at spot where we are standing.
|
||||||
|
unsigned short buttons; // Attack and move buttons
|
||||||
|
byte impulse; // Impulse command issued
|
||||||
|
byte weaponselect; // Current weapon id
|
||||||
|
|
||||||
|
// Experimental player impact stuff.
|
||||||
|
int impact_index;
|
||||||
|
vec3_t impact_position;
|
||||||
|
} usercmd_t;
|
||||||
|
|
||||||
|
#endif//USERCMD_H
|
||||||
@@ -2,28 +2,23 @@
|
|||||||
#ifndef XASH_TYPES_H
|
#ifndef XASH_TYPES_H
|
||||||
#define 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 "build.h"
|
||||||
#include "port.h"
|
|
||||||
|
|
||||||
#define MAX_STRING 256 // generic string
|
#if XASH_IRIX
|
||||||
#define MAX_VA_STRING 1024 // compatibility macro
|
#include <port.h>
|
||||||
#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 )))
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined( MAYBE_ALIGNED )
|
#if XASH_WIN32
|
||||||
#define MAYBE_ALIGNED( x )
|
#include <wchar.h> // off_t
|
||||||
#endif // !defined( MAYBE_ALIGNED )
|
#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 uint8_t byte;
|
||||||
typedef float vec_t;
|
typedef float vec_t;
|
||||||
@@ -31,30 +26,13 @@ typedef vec_t vec2_t[2];
|
|||||||
#ifndef vec3_t // SDK renames it to Vector
|
#ifndef vec3_t // SDK renames it to Vector
|
||||||
typedef vec_t vec3_t[3];
|
typedef vec_t vec3_t[3];
|
||||||
#endif
|
#endif
|
||||||
typedef vec_t vec4_t[4] MAYBE_ALIGNED( 16 );
|
typedef vec_t vec4_t[4];
|
||||||
typedef vec_t quat_t[4] MAYBE_ALIGNED( 16 );
|
typedef vec_t quat_t[4];
|
||||||
typedef byte rgba_t[4]; // unsigned byte colorpack
|
typedef byte rgba_t[4]; // unsigned byte colorpack
|
||||||
typedef byte rgb_t[3]; // unsigned byte colorpack
|
typedef byte rgb_t[3]; // unsigned byte colorpack
|
||||||
typedef vec_t matrix3x4[3][4] MAYBE_ALIGNED( 16 );
|
typedef vec_t matrix3x4[3][4];
|
||||||
typedef vec_t matrix4x4[4][4] MAYBE_ALIGNED( 16 );
|
typedef vec_t matrix4x4[4][4];
|
||||||
typedef uint32_t poolhandle_t;
|
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 true
|
||||||
#undef false
|
#undef false
|
||||||
@@ -65,77 +43,95 @@ enum { false, true };
|
|||||||
#endif
|
#endif
|
||||||
typedef int qboolean;
|
typedef int qboolean;
|
||||||
|
|
||||||
#if XASH_LOW_MEMORY == 1 || XASH_PSP
|
#define MAX_STRING 256 // generic string
|
||||||
#define MAX_QPATH 48
|
#define MAX_VA_STRING 1024 // compatibility macro
|
||||||
#define MAX_MODS 16
|
#define MAX_SYSPATH 1024 // system filepath
|
||||||
#elif XASH_LOW_MEMORY == 2
|
#define MAX_MODS 512 // environment games that engine can keep visible
|
||||||
#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 BIT( n ) ( 1U << ( n ))
|
#define BIT( n ) ( 1U << ( n ))
|
||||||
#define BIT64( n ) ( 1ULL << ( n ))
|
#define BIT64( n ) ( 1ULL << ( n ))
|
||||||
|
|
||||||
#define SetBits( bit_vector, bits ) (( bit_vector ) |= ( bits ))
|
#define SetBits( iBitVector, bits ) ((iBitVector) = (iBitVector) | (bits))
|
||||||
#define ClearBits( bit_vector, bits ) (( bit_vector ) &= ~( bits ))
|
#define ClearBits( iBitVector, bits ) ((iBitVector) = (iBitVector) & ~(bits))
|
||||||
#define FBitSet( bit_vector, bits ) (( bit_vector ) & ( bits ))
|
#define FBitSet( iBitVector, bit ) ((iBitVector) & (bit))
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#ifdef NULL
|
||||||
|
#undef NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NULL ((void *)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
// color strings
|
// color strings
|
||||||
#define IsColorString( p ) (( p ) && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' )
|
#define IsColorString( p ) ( p && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' )
|
||||||
#define ColorIndex( c ) ((( c ) - '0' ) & 7 )
|
#define ColorIndex( c ) ((( c ) - '0' ) & 7 )
|
||||||
|
|
||||||
|
#undef EXPORT
|
||||||
|
|
||||||
#if defined( __GNUC__ )
|
#if defined( __GNUC__ )
|
||||||
#if defined( __i386__ )
|
#if defined( __i386__ )
|
||||||
#define EXPORT __attribute__(( visibility( "default" ), force_align_arg_pointer ))
|
#define EXPORT __attribute__(( visibility( "default" ), force_align_arg_pointer ))
|
||||||
#define GAME_EXPORT __attribute__(( force_align_arg_pointer ))
|
#define GAME_EXPORT __attribute__(( force_align_arg_pointer ))
|
||||||
#else // !defined( __i386__ )
|
#else
|
||||||
#define EXPORT __attribute__(( visibility ( "default" )))
|
#define EXPORT __attribute__(( visibility ( "default" )))
|
||||||
#endif // !defined( __i386__ )
|
#define GAME_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MALLOC __attribute__(( malloc ))
|
||||||
|
|
||||||
|
// added in GCC 11
|
||||||
#if __GNUC__ >= 11
|
#if __GNUC__ >= 11
|
||||||
// might want to set noclone due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116893
|
// 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
|
// but it's easier to not force mismatched-dealloc to error yet
|
||||||
#define MALLOC_LIKE( x, y ) __attribute__(( malloc( x, y )))
|
#define MALLOC_LIKE( x, y ) __attribute__(( malloc( x, y )))
|
||||||
#else
|
#else
|
||||||
#define MALLOC_LIKE( x, y ) __attribute__(( malloc ))
|
#define MALLOC_LIKE( x, y ) 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
|
|
||||||
#endif
|
#endif
|
||||||
#define NORETURN __attribute__(( noreturn ))
|
#define NORETURN __attribute__(( noreturn ))
|
||||||
#define NONNULL __attribute__(( nonnull ))
|
#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 FORMAT_CHECK( x ) __attribute__(( format( printf, x, x + 1 )))
|
||||||
#define ALLOC_CHECK( x ) __attribute__(( alloc_size( x )))
|
#define ALLOC_CHECK( x ) __attribute__(( alloc_size( x )))
|
||||||
|
#define NO_ASAN __attribute__(( no_sanitize( "address" )))
|
||||||
#define WARN_UNUSED_RESULT __attribute__(( warn_unused_result ))
|
#define WARN_UNUSED_RESULT __attribute__(( warn_unused_result ))
|
||||||
#define RENAME_SYMBOL( x ) asm( x )
|
#define RENAME_SYMBOL( x ) asm( x )
|
||||||
#if !defined( offsetof )
|
#else
|
||||||
#define offsetof( s, m ) __builtin_offsetof( s, m )
|
#if defined( _MSC_VER )
|
||||||
#endif // !defined( offsetof )
|
#define EXPORT __declspec( dllexport )
|
||||||
#elif defined( _MSC_VER )
|
#define NO_ASAN __declspec( no_sanitize_address )
|
||||||
#define EXPORT __declspec( dllexport )
|
#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
|
#endif
|
||||||
|
|
||||||
#ifdef ARRAYSIZE
|
#if defined( __has_feature )
|
||||||
#undef ARRAYSIZE
|
#if __has_feature( address_sanitizer )
|
||||||
#endif // ARRAYSIZE
|
#define USE_ASAN 1
|
||||||
|
#endif // __has_feature
|
||||||
|
#endif // defined( __has_feature )
|
||||||
|
|
||||||
#define ARRAYSIZE( p ) ( sizeof(( p ))/ sizeof(( p )[0] ))
|
#if !defined( USE_ASAN ) && defined( __SANITIZE_ADDRESS__ )
|
||||||
|
#define USE_ASAN 1
|
||||||
#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
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __GNUC__ >= 3
|
#if __GNUC__ >= 3
|
||||||
@@ -148,73 +144,11 @@ typedef int qboolean;
|
|||||||
#endif
|
#endif
|
||||||
#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 )
|
#if !defined( unlikely ) || !defined( likely )
|
||||||
#define unlikely( x ) ( x )
|
#define unlikely( x ) ( x )
|
||||||
#define likely( x ) ( x )
|
#define likely( x ) ( x )
|
||||||
#endif // !defined( unlikely ) || !defined( likely )
|
|
||||||
|
|
||||||
#if !defined( XASH_RESTRICT )
|
|
||||||
#define XASH_RESTRICT
|
|
||||||
#endif
|
#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
|
#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_( ignore, x, y ) static_assert( x, y )
|
||||||
#define STATIC_ASSERT static_assert
|
#define STATIC_ASSERT static_assert
|
||||||
@@ -231,36 +165,75 @@ typedef int qboolean;
|
|||||||
|
|
||||||
// at least, statically check size of some public structures
|
// at least, statically check size of some public structures
|
||||||
#if XASH_64BIT
|
#if XASH_64BIT
|
||||||
#define STATIC_CHECK_SIZEOF( type, size32, size64 ) \
|
#define STATIC_CHECK_SIZEOF( type, size32, size64 ) \
|
||||||
STATIC_ASSERT( sizeof( type ) == size64, #type " unexpected size" )
|
STATIC_ASSERT( sizeof( type ) == size64, #type " unexpected size" )
|
||||||
#else
|
#else
|
||||||
#define STATIC_CHECK_SIZEOF( type, size32, size64 ) \
|
#define STATIC_CHECK_SIZEOF( type, size32, size64 ) \
|
||||||
STATIC_ASSERT( sizeof( type ) == size32, #type " unexpected size" )
|
STATIC_ASSERT( sizeof( type ) == size32, #type " unexpected size" )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define Swap32( x ) (((uint32_t)((( x ) & 255 ) << 24 )) + ((uint32_t)(((( x ) >> 8 ) & 255 ) << 16 )) + ((uint32_t)((( x ) >> 16 ) & 255 ) << 8 ) + ((( x ) >> 24 ) & 255 ))
|
#if !defined( __cplusplus ) && __STDC_VERSION__ >= 199101L // not C++ and C99 or newer
|
||||||
#define Swap16( x ) ((uint16_t)((((uint16_t)( x ) >> 8 ) & 255 ) + (((uint16_t)( x ) & 255 ) << 8 )))
|
#define XASH_RESTRICT restrict
|
||||||
#define Swap32Store( x ) ( x = Swap32( x ))
|
#elif _MSC_VER || __GNUC__ || __clang__ // compiler-specific extensions
|
||||||
#define Swap16Store( x ) ( x = Swap16( x ))
|
#define XASH_RESTRICT __restrict
|
||||||
|
#else
|
||||||
|
#define XASH_RESTRICT // nothing
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef XASH_BIG_ENDIAN
|
#ifdef XASH_BIG_ENDIAN
|
||||||
#define LittleLong( x ) Swap32( x )
|
#define LittleLong(x) (((int)(((x)&255)<<24)) + ((int)((((x)>>8)&255)<<16)) + ((int)(((x)>>16)&255)<<8) + (((x) >> 24)&255))
|
||||||
#define LittleShort( x ) Swap16( x )
|
#define LittleLongSW(x) (x = LittleLong(x) )
|
||||||
#define LittleLongSW( x ) Swap32Store( x )
|
#define LittleShort(x) ((short)( (((short)(x) >> 8) & 255) + (((short)(x) & 255) << 8)))
|
||||||
#define LittleShortSW( x ) Swap16Store( x )
|
#define LittleShortSW(x) (x = LittleShort(x) )
|
||||||
#define LittleFloat( x ) SwapFloat( x )
|
_inline float LittleFloat( float f )
|
||||||
#define BigLong( x ) ( x )
|
{
|
||||||
#define BigShort( x ) ( x )
|
union
|
||||||
#define BigFloat( x ) ( x )
|
{
|
||||||
|
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
|
#else
|
||||||
#define LittleLong( x ) ( x )
|
#define LittleLong(x) (x)
|
||||||
#define LittleShort( x ) ( x )
|
#define LittleLongSW(x)
|
||||||
#define LittleFloat( x ) ( x )
|
#define LittleShort(x) (x)
|
||||||
#define LittleLongSW( x )
|
#define LittleShortSW(x)
|
||||||
#define LittleShortSW( x )
|
#define LittleFloat(x) (x)
|
||||||
#define BigLong( x ) Swap32( x )
|
|
||||||
#define BigShort( x ) Swap16( x )
|
|
||||||
#define BigFloat( x ) SwapFloat( x )
|
|
||||||
#endif
|
#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
|
#endif // XASH_TYPES_H
|
||||||
|
|||||||
@@ -17,10 +17,8 @@
|
|||||||
#define ALIAS_H
|
#define ALIAS_H
|
||||||
|
|
||||||
#include "build.h"
|
#include "build.h"
|
||||||
#include <stdint.h>
|
#include STDINT_H
|
||||||
#include "synctype.h"
|
#include "synctype.h"
|
||||||
#include "xash3d_types.h"
|
|
||||||
#include "com_model.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
|||||||
@@ -23,12 +23,6 @@ struct mstudioevent_s;
|
|||||||
struct engine_studio_api_s;
|
struct engine_studio_api_s;
|
||||||
struct r_studio_interface_s;
|
struct r_studio_interface_s;
|
||||||
|
|
||||||
struct sound_api_s;
|
|
||||||
struct sound_interface_s;
|
|
||||||
|
|
||||||
typedef struct sound_api_s sound_api_t;
|
|
||||||
typedef struct sound_interface_s sound_interface_t;
|
|
||||||
|
|
||||||
// NOTE: ordering is important!
|
// NOTE: ordering is important!
|
||||||
typedef struct cldll_func_s
|
typedef struct cldll_func_s
|
||||||
{
|
{
|
||||||
@@ -80,9 +74,6 @@ typedef struct cldll_func_s
|
|||||||
int (*pfnTouchEvent)( int type, int fingerID, float x, float y, float dx, float dy );
|
int (*pfnTouchEvent)( int type, int fingerID, float x, float y, float dx, float dy );
|
||||||
void (*pfnMoveEvent)( float forwardmove, float sidemove );
|
void (*pfnMoveEvent)( float forwardmove, float sidemove );
|
||||||
void (*pfnLookEvent)( float relyaw, float relpitch );
|
void (*pfnLookEvent)( float relyaw, float relpitch );
|
||||||
// Sound API
|
|
||||||
int (*pfnGetSoundInterface)( int version, const sound_api_t *api, sound_interface_t *callback );
|
|
||||||
int (*pfnVoice_StartChannel)( int samples, byte *data, int entnum );
|
|
||||||
} cldll_func_t;
|
} cldll_func_t;
|
||||||
|
|
||||||
#endif//CDLL_EXP_H
|
#endif//CDLL_EXP_H
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ qboolean AVI_GetVideoInfo( movie_state_t *Avi, int *xres, int *yres, float *dura
|
|||||||
qboolean AVI_HaveAudioTrack( const movie_state_t *Avi );
|
qboolean AVI_HaveAudioTrack( const movie_state_t *Avi );
|
||||||
void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audio, int quiet );
|
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 );
|
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 );
|
void AVI_CloseVideo( movie_state_t *Avi );
|
||||||
qboolean AVI_IsActive( movie_state_t *Avi );
|
qboolean AVI_IsActive( movie_state_t *Avi );
|
||||||
void AVI_FreeVideo( movie_state_t *Avi );
|
void AVI_FreeVideo( movie_state_t *Avi );
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ static qboolean avi_initialized;
|
|||||||
static poolhandle_t avi_mempool;
|
static poolhandle_t avi_mempool;
|
||||||
|
|
||||||
#if XASH_AVI == AVI_FFMPEG
|
#if XASH_AVI == AVI_FFMPEG
|
||||||
|
#define XASH_FFMPEG_DLOPEN 1
|
||||||
#include "avi_ffmpeg.h"
|
#include "avi_ffmpeg.h"
|
||||||
|
|
||||||
struct movie_state_s
|
struct movie_state_s
|
||||||
@@ -221,6 +222,11 @@ int AVI_GetVideoFrameNumber( movie_state_t *Avi, float time )
|
|||||||
return 0;
|
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 )
|
qboolean AVI_GetVideoInfo( movie_state_t *Avi, int *xres, int *yres, float *duration )
|
||||||
{
|
{
|
||||||
if( !Avi->active )
|
if( !Avi->active )
|
||||||
@@ -255,9 +261,9 @@ static void AVI_StreamAudio( movie_state_t *Avi )
|
|||||||
rawchan_t *ch = NULL;
|
rawchan_t *ch = NULL;
|
||||||
|
|
||||||
// keep the same semantics, when S_RAW_SOUND_SOUNDTRACK doesn't play if S_StartStreaming wasn't enabled
|
// keep the same semantics, when S_RAW_SOUND_SOUNDTRACK doesn't play if S_StartStreaming wasn't enabled
|
||||||
qboolean disable_stream = Avi->entnum == S_RAW_SOUND_SOUNDTRACK ? !snd.streaming : false;
|
qboolean disable_stream = Avi->entnum == S_RAW_SOUND_SOUNDTRACK ? !s_listener.streaming : false;
|
||||||
|
|
||||||
if( !snd.initialized || disable_stream || cl.paused || !Avi->cached_audio )
|
if( !dma.initialized || disable_stream || s_listener.paused || !Avi->cached_audio )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ch = S_FindRawChannel( Avi->entnum, true );
|
ch = S_FindRawChannel( Avi->entnum, true );
|
||||||
@@ -268,14 +274,14 @@ static void AVI_StreamAudio( movie_state_t *Avi )
|
|||||||
ch->master_vol = Avi->volume;
|
ch->master_vol = Avi->volume;
|
||||||
ch->dist_mult = (Avi->attn / SND_CLIP_DISTANCE);
|
ch->dist_mult = (Avi->attn / SND_CLIP_DISTANCE);
|
||||||
|
|
||||||
if( ch->s_rawend < snd.soundtime )
|
if( ch->s_rawend < soundtime )
|
||||||
ch->s_rawend = snd.soundtime;
|
ch->s_rawend = soundtime;
|
||||||
|
|
||||||
while( ch->s_rawend < snd.soundtime + ch->max_samples )
|
while( ch->s_rawend < soundtime + ch->max_samples )
|
||||||
{
|
{
|
||||||
size_t copy;
|
size_t copy;
|
||||||
|
|
||||||
buffer_samples = ch->max_samples - (ch->s_rawend - snd.soundtime);
|
buffer_samples = ch->max_samples - (ch->s_rawend - soundtime);
|
||||||
|
|
||||||
file_samples = buffer_samples * ((float)Avi->rate / SOUND_DMA_SPEED);
|
file_samples = buffer_samples * ((float)Avi->rate / SOUND_DMA_SPEED);
|
||||||
if( file_samples <= 1 ) return; // no more samples need
|
if( file_samples <= 1 ) return; // no more samples need
|
||||||
@@ -349,10 +355,6 @@ qboolean AVI_Think( movie_state_t *Avi )
|
|||||||
qboolean decoded = false;
|
qboolean decoded = false;
|
||||||
qboolean flushing = false;
|
qboolean flushing = false;
|
||||||
qboolean redraw = 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;
|
const double timebase = (double)Avi->video_ctx->pkt_timebase.den / Avi->video_ctx->pkt_timebase.num;
|
||||||
int64_t curtime = round( Platform_DoubleTime() * timebase );
|
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(( 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 );
|
res = pavcodec_send_packet( Avi->audio_ctx, Avi->pkt );
|
||||||
if( res < 0 )
|
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 )
|
void AVI_CloseVideo( movie_state_t *Avi )
|
||||||
{
|
{
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -26,101 +26,35 @@ GNU General Public License for more details.
|
|||||||
|
|
||||||
#if XASH_FFMPEG_DLOPEN
|
#if XASH_FFMPEG_DLOPEN
|
||||||
|
|
||||||
// using typeof gives more resilience to function declaration changes
|
|
||||||
// but it's only available in GCC and standardized in C23
|
|
||||||
#if defined(__GNUC__) || __STDC_VERSION__ >= 202311L
|
|
||||||
|
|
||||||
#define SUPPORTED_AVU_VERSION_MAJOR LIBAVUTIL_VERSION_MAJOR
|
|
||||||
#define SUPPORTED_AVF_VERSION_MAJOR LIBAVFORMAT_VERSION_MAJOR
|
|
||||||
#define SUPPORTED_AVC_VERSION_MAJOR LIBAVCODEC_VERSION_MAJOR
|
|
||||||
#define SUPPORTED_SWR_VERSION_MAJOR LIBSWRESAMPLE_VERSION_MAJOR
|
|
||||||
#define SUPPORTED_SWS_VERSION_MAJOR LIBSWSCALE_VERSION_MAJOR
|
|
||||||
|
|
||||||
#define F( func ) \
|
|
||||||
typedef typeof( func ) func##_t; \
|
|
||||||
func##_t *p##func
|
|
||||||
|
|
||||||
// libavutil
|
|
||||||
F( avutil_version );
|
|
||||||
F( av_frame_alloc );
|
|
||||||
F( av_frame_free );
|
|
||||||
F( av_frame_ref );
|
|
||||||
F( av_frame_unref );
|
|
||||||
F( av_strerror );
|
|
||||||
F( av_free );
|
|
||||||
F( av_get_bytes_per_sample );
|
|
||||||
F( av_get_media_type_string );
|
|
||||||
F( av_image_alloc );
|
|
||||||
|
|
||||||
// libavformat
|
|
||||||
F( avformat_version );
|
|
||||||
F( av_find_best_stream );
|
|
||||||
F( av_read_frame );
|
|
||||||
F( av_seek_frame );
|
|
||||||
F( avformat_close_input );
|
|
||||||
F( avformat_find_stream_info );
|
|
||||||
F( avformat_open_input );
|
|
||||||
|
|
||||||
// libavcodec
|
|
||||||
F( avcodec_version );
|
|
||||||
F( av_packet_alloc );
|
|
||||||
F( av_packet_free );
|
|
||||||
F( av_packet_unref );
|
|
||||||
F( avcodec_alloc_context3 );
|
|
||||||
F( avcodec_find_decoder );
|
|
||||||
F( avcodec_flush_buffers );
|
|
||||||
F( avcodec_free_context );
|
|
||||||
F( avcodec_open2 );
|
|
||||||
F( avcodec_parameters_to_context );
|
|
||||||
F( avcodec_receive_frame );
|
|
||||||
F( avcodec_send_packet );
|
|
||||||
|
|
||||||
// libswresample
|
|
||||||
F( swresample_version );
|
|
||||||
F( swr_alloc_set_opts2 );
|
|
||||||
F( swr_convert );
|
|
||||||
F( swr_free );
|
|
||||||
F( swr_init );
|
|
||||||
|
|
||||||
// libswscale
|
|
||||||
F( swscale_version );
|
|
||||||
F( sws_freeContext );
|
|
||||||
F( sws_getContext );
|
|
||||||
F( sws_scale );
|
|
||||||
|
|
||||||
#undef F
|
|
||||||
|
|
||||||
#else // !defined(__GNUC__) && __STDC_VERSION__ < 202311L
|
|
||||||
|
|
||||||
// the following symbols were taken from ffmpeg public headers
|
// the following symbols were taken from ffmpeg public headers
|
||||||
// on each major ffmpeg uprgade, they must be validated
|
// on each major ffmpeg uprgade, they must be validated
|
||||||
// ffmpeg guarantees API and ABI compatibility between major versions
|
// ffmpeg guarantees API and ABI compatibility between major versions
|
||||||
// so complain if this gets compiled against unsupported yet version
|
// so complain if this gets compiled against unsupported yet version
|
||||||
// the same check will be done in runtime to ensure compatibility
|
// the same check will be done in runtime to ensure compatibility
|
||||||
#define SUPPORTED_AVU_VERSION_MAJOR 60
|
#define SUPPORTED_AVU_VERSION_MAJOR 59
|
||||||
#define SUPPORTED_AVF_VERSION_MAJOR 62
|
#define SUPPORTED_AVF_VERSION_MAJOR 61
|
||||||
#define SUPPORTED_AVC_VERSION_MAJOR 62
|
#define SUPPORTED_AVC_VERSION_MAJOR 61
|
||||||
#define SUPPORTED_SWR_VERSION_MAJOR 6
|
#define SUPPORTED_SWR_VERSION_MAJOR 5
|
||||||
#define SUPPORTED_SWS_VERSION_MAJOR 9
|
#define SUPPORTED_SWS_VERSION_MAJOR 8
|
||||||
|
|
||||||
#if SUPPORTED_AVU_VERSION_MAJOR != LIBAVUTIL_VERSION_MAJOR
|
#if SUPPORTED_AVU_VERSION_MAJOR != LIBAVUTIL_VERSION_MAJOR
|
||||||
#error "unsupported libavutil version"
|
#error
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SUPPORTED_AVF_VERSION_MAJOR != LIBAVFORMAT_VERSION_MAJOR
|
#if SUPPORTED_AVF_VERSION_MAJOR != LIBAVFORMAT_VERSION_MAJOR
|
||||||
#error "unsupported libavformat version"
|
#error
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SUPPORTED_AVC_VERSION_MAJOR != LIBAVCODEC_VERSION_MAJOR
|
#if SUPPORTED_AVC_VERSION_MAJOR != LIBAVCODEC_VERSION_MAJOR
|
||||||
#error "unsupported libavcodec version"
|
#error
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SUPPORTED_SWR_VERSION_MAJOR != LIBSWRESAMPLE_VERSION_MAJOR
|
#if SUPPORTED_SWR_VERSION_MAJOR != LIBSWRESAMPLE_VERSION_MAJOR
|
||||||
#error "unsupported libswresample version"
|
#error
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SUPPORTED_SWS_VERSION_MAJOR != LIBSWSCALE_VERSION_MAJOR
|
#if SUPPORTED_SWS_VERSION_MAJOR != LIBSWSCALE_VERSION_MAJOR
|
||||||
#error "unsupported libswscale version"
|
#error
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// libavutil
|
// libavutil
|
||||||
@@ -171,8 +105,6 @@ void (*psws_freeContext)( struct SwsContext *swsContext );
|
|||||||
struct SwsContext *(*psws_getContext)( int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param );
|
struct SwsContext *(*psws_getContext)( int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param );
|
||||||
int (*psws_scale)( struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[] );
|
int (*psws_scale)( struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[] );
|
||||||
|
|
||||||
#endif // defined(__GNUC__) || __STDC_VERSION__ >= 202311L
|
|
||||||
|
|
||||||
#else // !XASH_FFMPEG_DLOPEN
|
#else // !XASH_FFMPEG_DLOPEN
|
||||||
|
|
||||||
#define SUPPORTED_AVU_VERSION_MAJOR LIBAVUTIL_VERSION_MAJOR
|
#define SUPPORTED_AVU_VERSION_MAJOR LIBAVUTIL_VERSION_MAJOR
|
||||||
@@ -184,9 +116,8 @@ int (*psws_scale)( struct SwsContext *c, const uint8_t *const srcS
|
|||||||
// libavutil
|
// libavutil
|
||||||
#define pavutil_version avutil_version
|
#define pavutil_version avutil_version
|
||||||
#define pav_frame_alloc av_frame_alloc
|
#define pav_frame_alloc av_frame_alloc
|
||||||
#define pav_frame_free av_frame_free
|
|
||||||
#define pav_frame_ref av_frame_ref
|
#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_strerror av_strerror
|
||||||
#define pav_free av_free
|
#define pav_free av_free
|
||||||
#define pav_get_bytes_per_sample av_get_bytes_per_sample
|
#define pav_get_bytes_per_sample av_get_bytes_per_sample
|
||||||
|
|||||||
@@ -97,17 +97,7 @@ void CL_PlayCDTrack_f( void )
|
|||||||
if( Q_isdigit( pszTrack ))
|
if( Q_isdigit( pszTrack ))
|
||||||
{
|
{
|
||||||
track = bound( 1, Q_atoi( Cmd_Argv( 2 )), MAX_CDTRACKS );
|
track = bound( 1, Q_atoi( Cmd_Argv( 2 )), MAX_CDTRACKS );
|
||||||
|
S_StartBackgroundTrack( clgame.cdtracks[track-1], clgame.cdtracks[track-1], 0, false );
|
||||||
// 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 );
|
|
||||||
}
|
}
|
||||||
else S_StartBackgroundTrack( pszTrack, pszTrack, 0, true );
|
else S_StartBackgroundTrack( pszTrack, pszTrack, 0, true );
|
||||||
paused = false;
|
paused = false;
|
||||||
@@ -146,13 +136,10 @@ void CL_PlayCDTrack_f( void )
|
|||||||
}
|
}
|
||||||
else if( !Q_stricmp( command, "info" ))
|
else if( !Q_stricmp( command, "info" ))
|
||||||
{
|
{
|
||||||
int maxTrack = 0;
|
int i, maxTrack;
|
||||||
|
|
||||||
for( int i = 0; i < MAX_CDTRACKS; i++ )
|
for( maxTrack = i = 0; i < MAX_CDTRACKS; i++ )
|
||||||
{
|
if( COM_CheckStringEmpty( clgame.cdtracks[i] ) ) maxTrack++;
|
||||||
if( !COM_StringEmpty( clgame.cdtracks[i] ) )
|
|
||||||
maxTrack++;
|
|
||||||
}
|
|
||||||
|
|
||||||
Con_Printf( "%u tracks\n", maxTrack );
|
Con_Printf( "%u tracks\n", maxTrack );
|
||||||
if( track )
|
if( track )
|
||||||
|
|||||||
@@ -16,8 +16,10 @@ GNU General Public License for more details.
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "net_encode.h"
|
#include "net_encode.h"
|
||||||
|
#include "particledef.h"
|
||||||
#include "cl_tent.h"
|
#include "cl_tent.h"
|
||||||
#include "shake.h"
|
#include "shake.h"
|
||||||
|
#include "hltv.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
#define MSG_COUNT 32 // last 32 messages parsed
|
#define MSG_COUNT 32 // last 32 messages parsed
|
||||||
@@ -55,6 +57,9 @@ const char *CL_MsgInfo( int cmd )
|
|||||||
case PROTO_CURRENT:
|
case PROTO_CURRENT:
|
||||||
svc_string = svc_strings[cmd];
|
svc_string = svc_strings[cmd];
|
||||||
break;
|
break;
|
||||||
|
case PROTO_LEGACY:
|
||||||
|
svc_string = svc_legacy_strings[cmd];
|
||||||
|
break;
|
||||||
case PROTO_QUAKE:
|
case PROTO_QUAKE:
|
||||||
svc_string = svc_quake_strings[cmd];
|
svc_string = svc_quake_strings[cmd];
|
||||||
break;
|
break;
|
||||||
@@ -144,11 +149,7 @@ static void CL_WriteErrorMessage( int current_count, sizebuf_t *msg )
|
|||||||
file_t *fp;
|
file_t *fp;
|
||||||
|
|
||||||
fp = FS_Open( buffer_file, "wb", false );
|
fp = FS_Open( buffer_file, "wb", false );
|
||||||
if( !fp )
|
if( !fp ) return;
|
||||||
{
|
|
||||||
Con_Printf( S_ERROR "%s: can't open %s for write\n", __func__, buffer_file );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
FS_Write( fp, &cls.starting_count, sizeof( int ));
|
FS_Write( fp, &cls.starting_count, sizeof( int ));
|
||||||
FS_Write( fp, ¤t_count, sizeof( int ));
|
FS_Write( fp, ¤t_count, sizeof( int ));
|
||||||
|
|||||||
@@ -117,6 +117,8 @@ static int CL_GetDemoNetProtocol( connprotocol_t proto )
|
|||||||
{
|
{
|
||||||
case PROTO_CURRENT:
|
case PROTO_CURRENT:
|
||||||
return PROTOCOL_VERSION;
|
return PROTOCOL_VERSION;
|
||||||
|
case PROTO_LEGACY:
|
||||||
|
return PROTOCOL_LEGACY_VERSION;
|
||||||
case PROTO_QUAKE:
|
case PROTO_QUAKE:
|
||||||
return PROTOCOL_VERSION_QUAKE;
|
return PROTOCOL_VERSION_QUAKE;
|
||||||
case PROTO_GOLDSRC:
|
case PROTO_GOLDSRC:
|
||||||
@@ -132,6 +134,8 @@ static connprotocol_t CL_GetProtocolFromDemo( int net_protocol )
|
|||||||
{
|
{
|
||||||
case PROTOCOL_VERSION:
|
case PROTOCOL_VERSION:
|
||||||
return PROTO_CURRENT;
|
return PROTO_CURRENT;
|
||||||
|
case PROTOCOL_LEGACY_VERSION:
|
||||||
|
return PROTO_LEGACY;
|
||||||
case PROTOCOL_VERSION_QUAKE:
|
case PROTOCOL_VERSION_QUAKE:
|
||||||
return PROTO_QUAKE;
|
return PROTO_QUAKE;
|
||||||
case PROTOCOL_GOLDSRC_VERSION_DEMO:
|
case PROTOCOL_GOLDSRC_VERSION_DEMO:
|
||||||
@@ -1213,7 +1217,7 @@ void CL_StopPlayback( void )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// let game known about demo state
|
// 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;
|
cls.state = ca_disconnected;
|
||||||
memset( &cls.serveradr, 0, sizeof( cls.serveradr ) );
|
memset( &cls.serveradr, 0, sizeof( cls.serveradr ) );
|
||||||
cls.set_lastdemo = false;
|
cls.set_lastdemo = false;
|
||||||
@@ -1260,7 +1264,8 @@ int GAME_EXPORT CL_GetDemoComment( const char *demoname, char *comment )
|
|||||||
return false;
|
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 )
|
demohdr.dem_protocol != DEMO_PROTOCOL )
|
||||||
{
|
{
|
||||||
FS_Close( demfile );
|
FS_Close( demfile );
|
||||||
@@ -1475,10 +1480,10 @@ static qboolean CL_ParseDemoHeader( const char *callee, const char *filename, fi
|
|||||||
return false;
|
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",
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -200,15 +200,15 @@ particle_t * GAME_EXPORT R_AllocParticle( void (*callback)( particle_t*, float )
|
|||||||
p->type = pt_static;
|
p->type = pt_static;
|
||||||
VectorClear( p->vel );
|
VectorClear( p->vel );
|
||||||
VectorClear( p->org );
|
VectorClear( p->org );
|
||||||
p->unused = 0;
|
p->packedColor = 0;
|
||||||
p->die = cl.time;
|
p->die = cl.time;
|
||||||
p->color = 0;
|
p->color = 0;
|
||||||
p->ramp = 0;
|
p->ramp = 0;
|
||||||
|
|
||||||
if( callback )
|
if( callback )
|
||||||
{
|
{
|
||||||
p->type = pt_custom;
|
p->type = pt_clientcustom;
|
||||||
p->think = callback;
|
p->callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
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->die = cl.time + life;
|
||||||
p->ramp = tracerlength.value;
|
p->ramp = tracerlength.value;
|
||||||
p->color = TRACER_COLORINDEX_DEFAULT; // select custom color
|
p->color = TRACER_COLORINDEX_DEFAULT; // select custom color
|
||||||
p->unused = 255; // alpha
|
p->packedColor = 255; // alpha
|
||||||
|
|
||||||
return p;
|
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->die = cl.time + 0.3f;
|
||||||
p->color = colorStart + ( colorMod % colorLength );
|
p->color = colorStart + ( colorMod % colorLength );
|
||||||
p->unused = packedColor;
|
p->packedColor = packedColor;
|
||||||
colorMod++;
|
colorMod++;
|
||||||
|
|
||||||
p->type = pt_blob;
|
p->type = pt_blob;
|
||||||
@@ -1150,7 +1150,7 @@ void GAME_EXPORT R_BlobExplosion( const vec3_t org )
|
|||||||
if( !p ) return;
|
if( !p ) return;
|
||||||
|
|
||||||
p->die = cl.time + COM_RandomFloat( 1.0f, 1.4f );
|
p->die = cl.time + COM_RandomFloat( 1.0f, 1.4f );
|
||||||
p->unused = packedColor;
|
p->packedColor = packedColor;
|
||||||
|
|
||||||
if( i & 1 )
|
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->die = cl.time + 1.5f;
|
||||||
p->color = pcolor + COM_RandomLong( 0, 9 );
|
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 );
|
VectorAddScalar( pos, COM_RandomFloat( -1.0f, 1.0f ), p->org );
|
||||||
VectorScale( vec, pspeed, p->vel );
|
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;
|
if( !p ) return;
|
||||||
|
|
||||||
p->die = cl.time + 2.0f;
|
p->die = cl.time + 2.0f;
|
||||||
p->type = pt_8x_slowgrav;
|
p->type = pt_vox_grav;
|
||||||
p->color = pcolor + COM_RandomLong( 0, 9 );
|
p->color = pcolor + COM_RandomLong( 0, 9 );
|
||||||
|
|
||||||
VectorCopy( org, p->org );
|
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->die = cl.time + 3.0f;
|
||||||
p->color = pcolor + COM_RandomLong( 0, 9 );
|
p->color = pcolor + COM_RandomLong( 0, 9 );
|
||||||
p->type = pt_4x_slowgrav;
|
p->type = pt_vox_slowgrav;
|
||||||
|
|
||||||
VectorCopy( org, p->org );
|
VectorCopy( org, p->org );
|
||||||
VectorCopy( dir, p->vel );
|
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->die = cl.time + 3.0f;
|
||||||
p->color = pcolor + COM_RandomLong( 0, 9 );
|
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[0] = org[0] + COM_RandomFloat( -1.0f, 1.0f );
|
||||||
p->org[1] = org[1] + 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 )
|
if(( p = R_AllocTracer( org, vel, life )) != NULL )
|
||||||
{
|
{
|
||||||
p->userdata = deathcontext;
|
p->context = deathcontext;
|
||||||
p->on_die = deathfunc;
|
p->deathfunc = deathfunc;
|
||||||
p->color = colorIndex;
|
p->color = colorIndex;
|
||||||
p->ramp = length;
|
p->ramp = length;
|
||||||
}
|
}
|
||||||
@@ -1996,9 +1996,9 @@ void R_FreeDeadParticles( particle_t **ppparticles )
|
|||||||
kill = *ppparticles;
|
kill = *ppparticles;
|
||||||
if( kill && kill->die < cl.time )
|
if( kill && kill->die < cl.time )
|
||||||
{
|
{
|
||||||
if( kill->on_die )
|
if( kill->deathfunc )
|
||||||
kill->on_die( kill );
|
kill->deathfunc( kill );
|
||||||
kill->on_die = NULL;
|
kill->deathfunc = NULL;
|
||||||
*ppparticles = kill->next;
|
*ppparticles = kill->next;
|
||||||
kill->next = cl_free_particles;
|
kill->next = cl_free_particles;
|
||||||
cl_free_particles = kill;
|
cl_free_particles = kill;
|
||||||
@@ -2015,9 +2015,9 @@ void R_FreeDeadParticles( particle_t **ppparticles )
|
|||||||
kill = p->next;
|
kill = p->next;
|
||||||
if( kill && kill->die < cl.time )
|
if( kill && kill->die < cl.time )
|
||||||
{
|
{
|
||||||
if( kill->on_die )
|
if( kill->deathfunc )
|
||||||
kill->on_die( kill );
|
kill->deathfunc( kill );
|
||||||
kill->on_die = NULL;
|
kill->deathfunc = NULL;
|
||||||
p->next = kill->next;
|
p->next = kill->next;
|
||||||
kill->next = cl_free_particles;
|
kill->next = cl_free_particles;
|
||||||
cl_free_particles = kill;
|
cl_free_particles = kill;
|
||||||
@@ -2154,7 +2154,7 @@ void CL_ThinkParticle( double frametime, particle_t *p )
|
|||||||
float grav = frametime * clgame.movevars.gravity * 0.05f;
|
float grav = frametime * clgame.movevars.gravity * 0.05f;
|
||||||
|
|
||||||
|
|
||||||
if( p->type != pt_custom )
|
if( p->type != pt_clientcustom )
|
||||||
{
|
{
|
||||||
// update position.
|
// update position.
|
||||||
VectorMA( p->org, frametime, p->vel, p->org );
|
VectorMA( p->org, frametime, p->vel, p->org );
|
||||||
@@ -2185,7 +2185,7 @@ void CL_ThinkParticle( double frametime, particle_t *p )
|
|||||||
p->vel[2] -= grav;
|
p->vel[2] -= grav;
|
||||||
break;
|
break;
|
||||||
case pt_blob:
|
case pt_blob:
|
||||||
if( p->unused == 255 )
|
if( p->packedColor == 255 )
|
||||||
{
|
{
|
||||||
// normal blob explosion
|
// normal blob explosion
|
||||||
VectorMA( p->vel, dvel, p->vel, p->vel );
|
VectorMA( p->vel, dvel, p->vel, p->vel );
|
||||||
@@ -2194,7 +2194,7 @@ void CL_ThinkParticle( double frametime, particle_t *p )
|
|||||||
}
|
}
|
||||||
// intentionally fallthrough
|
// intentionally fallthrough
|
||||||
case pt_blob2:
|
case pt_blob2:
|
||||||
if( p->unused == 255 )
|
if( p->packedColor == 255 )
|
||||||
{
|
{
|
||||||
// normal blob explosion
|
// normal blob explosion
|
||||||
p->vel[0] -= p->vel[0] * dvel;
|
p->vel[0] -= p->vel[0] * dvel;
|
||||||
@@ -2217,15 +2217,15 @@ void CL_ThinkParticle( double frametime, particle_t *p )
|
|||||||
case pt_slowgrav:
|
case pt_slowgrav:
|
||||||
p->vel[2] -= grav;
|
p->vel[2] -= grav;
|
||||||
break;
|
break;
|
||||||
case pt_8x_slowgrav:
|
case pt_vox_grav:
|
||||||
p->vel[2] -= grav * 8.0f;
|
p->vel[2] -= grav * 8.0f;
|
||||||
break;
|
break;
|
||||||
case pt_4x_slowgrav:
|
case pt_vox_slowgrav:
|
||||||
p->vel[2] -= grav * 4.0f;
|
p->vel[2] -= grav * 4.0f;
|
||||||
break;
|
break;
|
||||||
case pt_custom:
|
case pt_clientcustom:
|
||||||
if( p->think )
|
if( p->callback )
|
||||||
p->think( p, frametime );
|
p->callback( p, frametime );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ word CL_EventIndex( const char *name )
|
|||||||
{
|
{
|
||||||
word i;
|
word i;
|
||||||
|
|
||||||
if( COM_StringEmptyOrNULL( name ))
|
if( !COM_CheckString( name ))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for( i = 1; i < MAX_EVENTS && cl.event_precache[i][0]; i++ )
|
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 )
|
if( proto == PROTO_GOLDSRC )
|
||||||
entity_bits = MAX_GOLDSRC_ENTITY_BITS;
|
entity_bits = MAX_GOLDSRC_ENTITY_BITS;
|
||||||
else
|
else if( proto == PROTO_LEGACY )
|
||||||
entity_bits = MAX_ENTITY_BITS;
|
entity_bits = MAX_LEGACY_ENTITY_BITS;
|
||||||
|
else entity_bits = MAX_ENTITY_BITS;
|
||||||
|
|
||||||
// parse events queue
|
// parse events queue
|
||||||
for( i = 0 ; i < num_events; i++ )
|
for( i = 0 ; i < num_events; i++ )
|
||||||
|
|||||||
@@ -68,11 +68,6 @@ void CL_SetFontRendermode( cl_font_t *font )
|
|||||||
ref.dllFuncs.GL_SetRenderMode( CL_FontRenderMode( font->rendermode ));
|
ref.dllFuncs.GL_SetRenderMode( CL_FontRenderMode( font->rendermode ));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CL_SetFontColor( cl_font_t *font, const rgba_t color )
|
|
||||||
{
|
|
||||||
ref.dllFuncs.Color4ub( color[0], color[1], color[2], color[3] );
|
|
||||||
}
|
|
||||||
|
|
||||||
qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, convar_t *rendermode, uint texFlags )
|
qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, convar_t *rendermode, uint texFlags )
|
||||||
{
|
{
|
||||||
int font_width, i;
|
int font_width, i;
|
||||||
@@ -168,7 +163,7 @@ void CL_FreeFont( cl_font_t *font )
|
|||||||
|
|
||||||
static int CL_CalcTabStop( const cl_font_t *font, int x )
|
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 tab = space * 6; // 6 spaces
|
||||||
int stop = tab - x % tab;
|
int stop = tab - x % tab;
|
||||||
|
|
||||||
@@ -227,9 +222,10 @@ int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_
|
|||||||
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
|
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
|
||||||
CL_SetFontRendermode( font );
|
CL_SetFontRendermode( font );
|
||||||
|
|
||||||
if( !FBitSet( flags, FONT_DRAW_NOCOLOR ))
|
// don't apply color to fixed fonts it's already colored
|
||||||
CL_SetFontColor( font, color );
|
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 );
|
ref.dllFuncs.R_DrawStretchPic( x, y, w, h, s1, t1, s2, t2, font->hFontTexture );
|
||||||
|
|
||||||
return font->charWidths[number];
|
return font->charWidths[number];
|
||||||
@@ -237,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 )
|
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;
|
int draw_len = 0;
|
||||||
|
|
||||||
if( !font || !font->valid )
|
if( !font || !font->valid )
|
||||||
@@ -248,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 ))
|
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
|
||||||
CL_SetFontRendermode( font );
|
CL_SetFontRendermode( font );
|
||||||
|
|
||||||
CL_SetFontColor( font, color );
|
Vector4Copy( color, current_color );
|
||||||
|
|
||||||
SetBits( flags, FONT_DRAW_NOCOLOR | FONT_DRAW_NORENDERMODE );
|
|
||||||
|
|
||||||
while( *s )
|
while( *s )
|
||||||
{
|
{
|
||||||
@@ -269,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 ))
|
if( FBitSet( flags, FONT_DRAW_RESETCOLORONLF ))
|
||||||
CL_SetFontColor( font, color );
|
Vector4Copy( color, current_color );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,14 +272,14 @@ int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_
|
|||||||
{
|
{
|
||||||
// don't copy alpha
|
// don't copy alpha
|
||||||
if( !FBitSet( flags, FONT_DRAW_FORCECOL ))
|
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;
|
s += 2;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip setting rendermode, it was changed for this string already
|
// 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++;
|
s++;
|
||||||
}
|
}
|
||||||
@@ -329,7 +324,7 @@ void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height,
|
|||||||
if( width )
|
if( width )
|
||||||
*width = 0;
|
*width = 0;
|
||||||
|
|
||||||
if( COM_StringEmptyOrNULL( s ))
|
if( !COM_CheckString( s ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( FBitSet( flags, FONT_DRAW_UTF8 ))
|
if( FBitSet( flags, FONT_DRAW_UTF8 ))
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ GNU General Public License for more details.
|
|||||||
#include "pm_local.h"
|
#include "pm_local.h"
|
||||||
#include "cl_tent.h"
|
#include "cl_tent.h"
|
||||||
#include "studio.h"
|
#include "studio.h"
|
||||||
|
#include "dlight.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
|
|
||||||
@@ -156,6 +157,13 @@ static qboolean CL_EntityCustomLerp( cl_entity_t *e )
|
|||||||
case MOVETYPE_FLY:
|
case MOVETYPE_FLY:
|
||||||
case MOVETYPE_COMPOUND:
|
case MOVETYPE_COMPOUND:
|
||||||
return false;
|
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;
|
return true;
|
||||||
@@ -310,21 +318,6 @@ static void CL_ProcessEntityUpdate( cl_entity_t *ent )
|
|||||||
if( FBitSet( ent->curstate.entityType, ENTITY_NORMAL ))
|
if( FBitSet( ent->curstate.entityType, ENTITY_NORMAL ))
|
||||||
COM_NormalizeAngles( ent->curstate.angles );
|
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;
|
parametric = ent->curstate.starttime != 0.0f && ent->curstate.impacttime != 0.0f;
|
||||||
|
|
||||||
// allow interpolation on bmodels too
|
// allow interpolation on bmodels too
|
||||||
@@ -660,9 +653,18 @@ FRAME PARSING
|
|||||||
*/
|
*/
|
||||||
static qboolean CL_ParseEntityNumFromPacket( sizebuf_t *msg, int *newnum, connprotocol_t proto )
|
static qboolean CL_ParseEntityNumFromPacket( sizebuf_t *msg, int *newnum, connprotocol_t proto )
|
||||||
{
|
{
|
||||||
*newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
|
if( proto == PROTO_LEGACY )
|
||||||
if( *newnum == LAST_EDICT )
|
{
|
||||||
return false;
|
*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;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -829,7 +831,9 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta, connprotocol_t proto
|
|||||||
CL_WriteDemoJumpTime();
|
CL_WriteDemoJumpTime();
|
||||||
|
|
||||||
// sentinel count. save it for debug checking
|
// 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];
|
newframe = &cl.frames[cl.parsecountmod];
|
||||||
|
|
||||||
@@ -981,8 +985,15 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
|
|||||||
if( !draw_player )
|
if( !draw_player )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( !ref.dllFuncs.R_AddEntity( ent, entityType ))
|
if( entityType == ET_BEAM )
|
||||||
|
{
|
||||||
|
ref.dllFuncs.CL_AddCustomBeam( ent );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if( !ref.dllFuncs.R_AddEntity( ent, entityType ))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// because pTemp->entity.curstate.effects
|
// because pTemp->entity.curstate.effects
|
||||||
// is already occupied by FTENT_FLICKER
|
// is already occupied by FTENT_FLICKER
|
||||||
@@ -1235,6 +1246,16 @@ static void CL_LinkPacketEntities( frame_t *frame )
|
|||||||
if( !CL_InterpolateModel( ent ))
|
if( !CL_InterpolateModel( ent ))
|
||||||
continue;
|
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
|
else
|
||||||
{
|
{
|
||||||
// no interpolation right now
|
// no interpolation right now
|
||||||
@@ -1374,7 +1395,7 @@ qboolean CL_GetEntitySpatialization( channel_t *ch )
|
|||||||
|
|
||||||
if( ch->entnum == 0 )
|
if( ch->entnum == 0 )
|
||||||
{
|
{
|
||||||
SetBits( ch->flags, FL_CHAN_STATIC_SOUND );
|
ch->staticsound = true;
|
||||||
return true; // static sound
|
return true; // static sound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,20 +37,11 @@ GNU General Public License for more details.
|
|||||||
#include "platform/platform.h"
|
#include "platform/platform.h"
|
||||||
|
|
||||||
#define MAX_LINELENGTH 80
|
#define MAX_LINELENGTH 80
|
||||||
#define TEXT_MSGNAME "TextMessage"
|
#define MAX_TEXTCHANNELS 8 // must be power of two (GoldSrc uses 4 channels)
|
||||||
|
#define TEXT_MSGNAME "TextMessage%i"
|
||||||
|
|
||||||
static char cl_textbuffer[MAX_TEXTCHANNELS][2048];
|
static char cl_textbuffer[MAX_TEXTCHANNELS][2048];
|
||||||
client_textmessage_t cl_textmessage[MAX_TEXTCHANNELS] =
|
static client_textmessage_t cl_textmessage[MAX_TEXTCHANNELS];
|
||||||
{
|
|
||||||
{ .pName = "TextMessage0", .pMessage = cl_textbuffer[0] },
|
|
||||||
{ .pName = "TextMessage1", .pMessage = cl_textbuffer[1] },
|
|
||||||
{ .pName = "TextMessage2", .pMessage = cl_textbuffer[2] },
|
|
||||||
{ .pName = "TextMessage3", .pMessage = cl_textbuffer[3] },
|
|
||||||
{ .pName = "TextMessage4", .pMessage = cl_textbuffer[4] },
|
|
||||||
{ .pName = "TextMessage5", .pMessage = cl_textbuffer[5] },
|
|
||||||
{ .pName = "TextMessage6", .pMessage = cl_textbuffer[6] },
|
|
||||||
{ .pName = "TextMessage7", .pMessage = cl_textbuffer[7] },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const dllfunc_t cdll_exports[] =
|
static const dllfunc_t cdll_exports[] =
|
||||||
{
|
{
|
||||||
@@ -105,8 +96,6 @@ static const dllfunc_t cdll_new_exports[] = // allowed only in SDK 2.3 and high
|
|||||||
{ "IN_ClientTouchEvent", (void **)&clgame.dllFuncs.pfnTouchEvent}, // Xash3D FWGS ext
|
{ "IN_ClientTouchEvent", (void **)&clgame.dllFuncs.pfnTouchEvent}, // Xash3D FWGS ext
|
||||||
{ "IN_ClientMoveEvent", (void **)&clgame.dllFuncs.pfnMoveEvent}, // Xash3D FWGS ext
|
{ "IN_ClientMoveEvent", (void **)&clgame.dllFuncs.pfnMoveEvent}, // Xash3D FWGS ext
|
||||||
{ "IN_ClientLookEvent", (void **)&clgame.dllFuncs.pfnLookEvent}, // Xash3D FWGS ext
|
{ "IN_ClientLookEvent", (void **)&clgame.dllFuncs.pfnLookEvent}, // Xash3D FWGS ext
|
||||||
{ "HUD_GetSoundInterface", (void **)&clgame.dllFuncs.pfnGetSoundInterface }, // Xash3D FWGS ext
|
|
||||||
{ "Voice_StartChannel", (void **)&clgame.dllFuncs.pfnVoice_StartChannel }, // Xash3D FWGS ext
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pfnSPR_DrawHoles( int frame, int x, int y, const wrect_t *prc );
|
static void pfnSPR_DrawHoles( int frame, int x, int y, const wrect_t *prc );
|
||||||
@@ -123,11 +112,7 @@ static void CL_CreatePlaylist( const char *filename )
|
|||||||
file_t *f;
|
file_t *f;
|
||||||
|
|
||||||
f = FS_Open( filename, "w", false );
|
f = FS_Open( filename, "w", false );
|
||||||
if( !f )
|
if( !f ) return;
|
||||||
{
|
|
||||||
Con_Printf( S_ERROR "%s: can't open %s for write\n", __func__, filename );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// make standard cdaudio playlist
|
// make standard cdaudio playlist
|
||||||
FS_Print( f, "blank\n" ); // #1
|
FS_Print( f, "blank\n" ); // #1
|
||||||
@@ -190,13 +175,7 @@ static void CL_InitCDAudio( const char *filename )
|
|||||||
while(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) != NULL )
|
while(( pfile = COM_ParseFile( pfile, token, sizeof( token ))) != NULL )
|
||||||
{
|
{
|
||||||
if( !Q_stricmp( token, "blank" ))
|
if( !Q_stricmp( token, "blank" ))
|
||||||
{
|
|
||||||
clgame.cdtracks[c][0] = '\0';
|
clgame.cdtracks[c][0] = '\0';
|
||||||
}
|
|
||||||
else if( token[0] == '/' ) // allow custom path
|
|
||||||
{
|
|
||||||
Q_strncpy( clgame.cdtracks[c], &token[1], sizeof( clgame.cdtracks[c] ));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Q_snprintf( clgame.cdtracks[c], sizeof( clgame.cdtracks[c] ),
|
Q_snprintf( clgame.cdtracks[c], sizeof( clgame.cdtracks[c] ),
|
||||||
@@ -287,7 +266,7 @@ void CL_CenterPrint( const char *text, float y )
|
|||||||
{
|
{
|
||||||
cl_font_t *font = Con_GetCurFont();
|
cl_font_t *font = Con_GetCurFont();
|
||||||
|
|
||||||
if( COM_StringEmptyOrNULL( text ) || !font || !font->valid )
|
if( !COM_CheckString( text ) || !font || !font->valid )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clgame.centerPrint.totalWidth = 0;
|
clgame.centerPrint.totalWidth = 0;
|
||||||
@@ -374,13 +353,13 @@ static void SPR_DrawGeneric( int frame, float x, float y, float width, float hei
|
|||||||
int w, h;
|
int w, h;
|
||||||
|
|
||||||
// assume we get sizes from image
|
// assume we get sizes from image
|
||||||
R_GetSpriteParms( &w, &h, NULL, frame, clgame.ds.pSprite );
|
ref.dllFuncs.R_GetSpriteParms( &w, &h, NULL, frame, clgame.ds.pSprite );
|
||||||
|
|
||||||
width = w;
|
width = w;
|
||||||
height = h;
|
height = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
texnum = R_GetSpriteTexture( clgame.ds.pSprite, frame );
|
texnum = ref.dllFuncs.R_GetSpriteTexture( clgame.ds.pSprite, frame );
|
||||||
|
|
||||||
if( prc )
|
if( prc )
|
||||||
{
|
{
|
||||||
@@ -450,7 +429,6 @@ void CL_DrawCenterPrint( void )
|
|||||||
|
|
||||||
CL_DrawCharacterLen( font, 0, NULL, &charHeight );
|
CL_DrawCharacterLen( font, 0, NULL, &charHeight );
|
||||||
CL_SetFontRendermode( font );
|
CL_SetFontRendermode( font );
|
||||||
CL_SetFontColor( font, colorDefault );
|
|
||||||
for( i = 0; i < clgame.centerPrint.lines; i++ )
|
for( i = 0; i < clgame.centerPrint.lines; i++ )
|
||||||
{
|
{
|
||||||
lineLength = 0;
|
lineLength = 0;
|
||||||
@@ -480,7 +458,7 @@ void CL_DrawCenterPrint( void )
|
|||||||
for( j = 0; j < lineLength; j++ )
|
for( j = 0; j < lineLength; j++ )
|
||||||
{
|
{
|
||||||
if( x >= 0 && y >= 0 && x <= refState.width )
|
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;
|
y += charHeight;
|
||||||
}
|
}
|
||||||
@@ -577,18 +555,31 @@ and hold them into permament memory pool
|
|||||||
*/
|
*/
|
||||||
static void CL_InitTitles( const char *filename )
|
static void CL_InitTitles( const char *filename )
|
||||||
{
|
{
|
||||||
|
fs_offset_t fileSize;
|
||||||
|
byte *pMemFile;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// initialize text messages (game_text)
|
||||||
|
for( i = 0; i < MAX_TEXTCHANNELS; i++ )
|
||||||
|
{
|
||||||
|
char name[MAX_VA_STRING];
|
||||||
|
|
||||||
|
Q_snprintf( name, sizeof( name ), TEXT_MSGNAME, i );
|
||||||
|
|
||||||
|
cl_textmessage[i].pName = copystringpool( clgame.mempool, name );
|
||||||
|
cl_textmessage[i].pMessage = cl_textbuffer[i];
|
||||||
|
}
|
||||||
|
|
||||||
// clear out any old data that's sitting around.
|
// clear out any old data that's sitting around.
|
||||||
Mem_Free( clgame.titles );
|
if( clgame.titles ) Mem_Free( clgame.titles );
|
||||||
|
|
||||||
clgame.titles = NULL;
|
clgame.titles = NULL;
|
||||||
clgame.numTitles = 0;
|
clgame.numTitles = 0;
|
||||||
|
|
||||||
fs_offset_t fileSize = 0;
|
pMemFile = FS_LoadFile( filename, &fileSize, false );
|
||||||
char *pMemFile = (char *)FS_LoadFile( filename, &fileSize, false );
|
if( !pMemFile ) return;
|
||||||
if( !pMemFile )
|
|
||||||
return;
|
|
||||||
|
|
||||||
clgame.titles = CL_TextMessageParse( clgame.mempool, pMemFile, fileSize, &clgame.numTitles );
|
CL_TextMessageParse( pMemFile, fileSize );
|
||||||
Mem_Free( pMemFile );
|
Mem_Free( pMemFile );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -601,10 +592,8 @@ Template to show hud messages
|
|||||||
*/
|
*/
|
||||||
void CL_HudMessage( const char *pMessage )
|
void CL_HudMessage( const char *pMessage )
|
||||||
{
|
{
|
||||||
if( COM_StringEmptyOrNULL( pMessage ))
|
if( !COM_CheckString( pMessage )) return;
|
||||||
return;
|
CL_DispatchUserMessage( "HudText", Q_strlen( pMessage ), (void *)pMessage );
|
||||||
|
|
||||||
CL_DispatchUserMessage( "HudText", Q_strlen( pMessage ) + 1, (void *)pMessage );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -657,6 +646,54 @@ void CL_ParseTextMessage( sizebuf_t *msg )
|
|||||||
CL_HudMessage( text->pName );
|
CL_HudMessage( text->pName );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
CL_ParseFinaleCutscene
|
||||||
|
|
||||||
|
show display finale or cutscene message
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
void CL_ParseFinaleCutscene( sizebuf_t *msg, int level )
|
||||||
|
{
|
||||||
|
static int msgindex = 0;
|
||||||
|
client_textmessage_t *text;
|
||||||
|
int channel;
|
||||||
|
|
||||||
|
cl.intermission = level;
|
||||||
|
|
||||||
|
channel = msgindex;
|
||||||
|
msgindex = (msgindex + 1) & (MAX_TEXTCHANNELS - 1);
|
||||||
|
|
||||||
|
// grab message channel
|
||||||
|
text = &cl_textmessage[channel];
|
||||||
|
|
||||||
|
// NOTE: svc_finale and svc_cutscene has a
|
||||||
|
// predefined settings like Quake-style
|
||||||
|
text->x = -1.0f;
|
||||||
|
text->y = 0.15f;
|
||||||
|
text->effect = 2; // scan out effect
|
||||||
|
text->r1 = 245;
|
||||||
|
text->g1 = 245;
|
||||||
|
text->b1 = 245;
|
||||||
|
text->a1 = 0; // unused
|
||||||
|
text->r2 = 0;
|
||||||
|
text->g2 = 0;
|
||||||
|
text->b2 = 0;
|
||||||
|
text->a2 = 0;
|
||||||
|
text->fadein = 0.15f;
|
||||||
|
text->fadeout = 0.0f;
|
||||||
|
text->holdtime = 99999.0f;
|
||||||
|
text->fxtime = 0.0f;
|
||||||
|
|
||||||
|
// to prevent grab too long messages
|
||||||
|
Q_strncpy( (char *)text->pMessage, MSG_ReadString( msg ), 2048 );
|
||||||
|
|
||||||
|
if( *text->pMessage == '\0' )
|
||||||
|
return; // no real text
|
||||||
|
|
||||||
|
CL_HudMessage( text->pName );
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
====================
|
====================
|
||||||
CL_GetMaxlients
|
CL_GetMaxlients
|
||||||
@@ -1073,12 +1110,7 @@ void CL_ClearSpriteTextures( void )
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for( i = 1; i < MAX_CLIENT_SPRITES; i++ )
|
for( i = 1; i < MAX_CLIENT_SPRITES; i++ )
|
||||||
{
|
clgame.sprites[i].needload = NL_UNREFERENCED;
|
||||||
if( clgame.sprites[i].needload == NL_UNREFERENCED )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
clgame.sprites[i].needload = NL_FREE_UNUSED;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// it's a Valve default value for LoadMapSprite (probably must be power of two)
|
// it's a Valve default value for LoadMapSprite (probably must be power of two)
|
||||||
@@ -1249,8 +1281,8 @@ static qboolean CL_LoadHudSprite( const char *szSpriteName, model_t *m_pSprite,
|
|||||||
Mod_LoadMapSprite( m_pSprite, buf, size, &loaded );
|
Mod_LoadMapSprite( m_pSprite, buf, size, &loaded );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Mod_LoadSpriteModel( m_pSprite, buf, size, &loaded );
|
Mod_LoadSpriteModel( m_pSprite, buf, &loaded );
|
||||||
ref.dllFuncs.Mod_ProcessRenderData( m_pSprite, true, buf, size );
|
ref.dllFuncs.Mod_ProcessRenderData( m_pSprite, true, buf );
|
||||||
}
|
}
|
||||||
|
|
||||||
Mem_Free( buf );
|
Mem_Free( buf );
|
||||||
@@ -1280,7 +1312,7 @@ static model_t *CL_LoadSpriteModel( const char *filename, uint type, uint texFla
|
|||||||
model_t *mod;
|
model_t *mod;
|
||||||
int i, start;
|
int i, start;
|
||||||
|
|
||||||
if( COM_StringEmptyOrNULL( filename ))
|
if( !COM_CheckString( filename ))
|
||||||
{
|
{
|
||||||
Con_Reportf( S_ERROR "%s: bad name!\n", __func__ );
|
Con_Reportf( S_ERROR "%s: bad name!\n", __func__ );
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1312,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++ )
|
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
|
break; // this is a valid spot
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1424,7 +1456,7 @@ int EXPORT pfnSPR_Frames( HSPRITE hPic )
|
|||||||
{
|
{
|
||||||
int numFrames = 0;
|
int numFrames = 0;
|
||||||
|
|
||||||
R_GetSpriteParms( NULL, NULL, &numFrames, 0, CL_GetSpritePointer( hPic ));
|
ref.dllFuncs.R_GetSpriteParms( NULL, NULL, &numFrames, 0, CL_GetSpritePointer( hPic ));
|
||||||
|
|
||||||
return numFrames;
|
return numFrames;
|
||||||
}
|
}
|
||||||
@@ -1439,7 +1471,7 @@ static int GAME_EXPORT pfnSPR_Height( HSPRITE hPic, int frame )
|
|||||||
{
|
{
|
||||||
int sprHeight = 0;
|
int sprHeight = 0;
|
||||||
|
|
||||||
R_GetSpriteParms( NULL, &sprHeight, NULL, frame, CL_GetSpritePointer( hPic ));
|
ref.dllFuncs.R_GetSpriteParms( NULL, &sprHeight, NULL, frame, CL_GetSpritePointer( hPic ));
|
||||||
|
|
||||||
return sprHeight;
|
return sprHeight;
|
||||||
}
|
}
|
||||||
@@ -1454,7 +1486,7 @@ static int GAME_EXPORT pfnSPR_Width( HSPRITE hPic, int frame )
|
|||||||
{
|
{
|
||||||
int sprWidth = 0;
|
int sprWidth = 0;
|
||||||
|
|
||||||
R_GetSpriteParms( &sprWidth, NULL, NULL, frame, CL_GetSpritePointer( hPic ));
|
ref.dllFuncs.R_GetSpriteParms( &sprWidth, NULL, NULL, frame, CL_GetSpritePointer( hPic ));
|
||||||
|
|
||||||
return sprWidth;
|
return sprWidth;
|
||||||
}
|
}
|
||||||
@@ -1799,7 +1831,7 @@ pfnServerCmd
|
|||||||
*/
|
*/
|
||||||
static int GAME_EXPORT pfnServerCmd( const char *szCmdString )
|
static int GAME_EXPORT pfnServerCmd( const char *szCmdString )
|
||||||
{
|
{
|
||||||
if( COM_StringEmptyOrNULL( szCmdString ))
|
if( !COM_CheckString( szCmdString ))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// just like the client typed "cmd xxxxx" at the console
|
// just like the client typed "cmd xxxxx" at the console
|
||||||
@@ -1817,7 +1849,7 @@ pfnClientCmd
|
|||||||
*/
|
*/
|
||||||
static int GAME_EXPORT pfnClientCmd( const char *szCmdString )
|
static int GAME_EXPORT pfnClientCmd( const char *szCmdString )
|
||||||
{
|
{
|
||||||
if( COM_StringEmptyOrNULL( szCmdString ))
|
if( !COM_CheckString( szCmdString ))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if( cls.initialized )
|
if( cls.initialized )
|
||||||
@@ -1842,7 +1874,7 @@ pfnFilteredClientCmd
|
|||||||
*/
|
*/
|
||||||
static int GAME_EXPORT pfnFilteredClientCmd( const char *szCmdString )
|
static int GAME_EXPORT pfnFilteredClientCmd( const char *szCmdString )
|
||||||
{
|
{
|
||||||
if( COM_StringEmptyOrNULL( szCmdString ))
|
if( !COM_CheckString( szCmdString ))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// a1ba:
|
// a1ba:
|
||||||
@@ -1930,12 +1962,13 @@ client_textmessage_t *CL_TextMessageGet( const char *pName )
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
// first check internal messages
|
// first check internal messages
|
||||||
if( Q_strlen( pName ) == sizeof( TEXT_MSGNAME ) // including the digit
|
for( i = 0; i < MAX_TEXTCHANNELS; i++ )
|
||||||
&& !Q_strncmp( pName, TEXT_MSGNAME, sizeof( TEXT_MSGNAME ) - 1 ))
|
|
||||||
{
|
{
|
||||||
i = pName[sizeof( TEXT_MSGNAME ) - 1] - '0';
|
char name[MAX_VA_STRING];
|
||||||
|
|
||||||
if( i >= 0 && i < MAX_TEXTCHANNELS )
|
Q_snprintf( name, sizeof( name ), TEXT_MSGNAME, i );
|
||||||
|
|
||||||
|
if( !Q_strcmp( pName, name ))
|
||||||
return cl_textmessage + i;
|
return cl_textmessage + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2023,7 +2056,7 @@ prints directly into console (can skip notify)
|
|||||||
*/
|
*/
|
||||||
static void GAME_EXPORT pfnConsolePrint( const char *string )
|
static void GAME_EXPORT pfnConsolePrint( const char *string )
|
||||||
{
|
{
|
||||||
if( COM_StringEmptyOrNULL( string ))
|
if( !COM_CheckString( string ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// WON GoldSrc behavior
|
// WON GoldSrc behavior
|
||||||
@@ -2395,7 +2428,7 @@ static int GAME_EXPORT CL_FindModelIndex( const char *m )
|
|||||||
char filepath[MAX_QPATH];
|
char filepath[MAX_QPATH];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if( COM_StringEmptyOrNULL( m ))
|
if( !COM_CheckString( m ))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
Q_strncpy( filepath, m, sizeof( filepath ));
|
Q_strncpy( filepath, m, sizeof( filepath ));
|
||||||
@@ -2696,7 +2729,7 @@ static const char *pfnGetLevelName( void )
|
|||||||
// a1ba: don't return maps/.bsp if no map is loaded yet
|
// 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
|
// in GoldSrc this is handled by cl.levelname field but we don't have it
|
||||||
// so emulate this behavior here
|
// 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 );
|
Q_snprintf( mapname, sizeof( mapname ), "maps/%s.bsp", clgame.mapname );
|
||||||
else mapname[0] = '\0'; // not in game
|
else mapname[0] = '\0'; // not in game
|
||||||
|
|
||||||
@@ -2767,7 +2800,7 @@ static int GAME_EXPORT COM_ExpandFilename( const char *fileName, char *nameOutBu
|
|||||||
{
|
{
|
||||||
char result[MAX_SYSPATH];
|
char result[MAX_SYSPATH];
|
||||||
|
|
||||||
if( COM_StringEmptyOrNULL( fileName ) || !nameOutBuffer || nameOutBufferSize <= 0 )
|
if( !COM_CheckString( fileName ) || !nameOutBuffer || nameOutBufferSize <= 0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// filename examples:
|
// filename examples:
|
||||||
@@ -2880,7 +2913,7 @@ pfnServerCmdUnreliable
|
|||||||
*/
|
*/
|
||||||
static int GAME_EXPORT pfnServerCmdUnreliable( char *szCmdString )
|
static int GAME_EXPORT pfnServerCmdUnreliable( char *szCmdString )
|
||||||
{
|
{
|
||||||
if( COM_StringEmptyOrNULL( szCmdString ))
|
if( !COM_CheckString( szCmdString ))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
MSG_BeginClientCmd( &cls.datagram, clc_stringcmd );
|
MSG_BeginClientCmd( &cls.datagram, clc_stringcmd );
|
||||||
@@ -2897,15 +2930,10 @@ pfnGetMousePos
|
|||||||
*/
|
*/
|
||||||
static void GAME_EXPORT pfnGetMousePos( struct tagPOINT *ppt )
|
static void GAME_EXPORT pfnGetMousePos( struct tagPOINT *ppt )
|
||||||
{
|
{
|
||||||
int x, y;
|
|
||||||
|
|
||||||
if( !ppt )
|
if( !ppt )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Platform_GetMousePos( &x, &y );
|
Platform_GetMousePos( &ppt->x, &ppt->y );
|
||||||
|
|
||||||
ppt->x = x;
|
|
||||||
ppt->y = y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3174,8 +3202,7 @@ handle colon separately
|
|||||||
*/
|
*/
|
||||||
static char *pfnParseFile( char *data, char *token )
|
static char *pfnParseFile( char *data, char *token )
|
||||||
{
|
{
|
||||||
// GoldSrc uses 1024 byte tokens
|
return COM_ParseFileSafe( data, token, PFILE_TOKEN_MAX_LENGTH, PFILE_HANDLECOLON, NULL, NULL );
|
||||||
return COM_ParseFileSafe( data, token, 1024, PFILE_HANDLECOLON, NULL, NULL );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3324,7 +3351,7 @@ int TriSpriteTexture( model_t *pSpriteModel, int frame )
|
|||||||
{
|
{
|
||||||
int gl_texturenum;
|
int gl_texturenum;
|
||||||
|
|
||||||
if(( gl_texturenum = R_GetSpriteTexture( pSpriteModel, frame )) <= 0 )
|
if(( gl_texturenum = ref.dllFuncs.R_GetSpriteTexture( pSpriteModel, frame )) <= 0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ref.dllFuncs.GL_Bind( XASH_TEXTURE0, gl_texturenum );
|
ref.dllFuncs.GL_Bind( XASH_TEXTURE0, gl_texturenum );
|
||||||
@@ -3454,7 +3481,7 @@ static void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags,
|
|||||||
nr->flags = flags;
|
nr->flags = flags;
|
||||||
|
|
||||||
// local servers request
|
// 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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3917,7 +3944,7 @@ void CL_UnloadProgs( void )
|
|||||||
if( GI->internal_vgui_support )
|
if( GI->internal_vgui_support )
|
||||||
VGui_Shutdown();
|
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_FullSet( "host_clientloaded", "0", FCVAR_READ_ONLY );
|
||||||
|
|
||||||
Cvar_Unlink( FCVAR_CLIENTDLL );
|
Cvar_Unlink( FCVAR_CLIENTDLL );
|
||||||
@@ -3935,7 +3962,6 @@ qboolean CL_LoadProgs( const char *name )
|
|||||||
CL_EXPORT_FUNCS GetClientAPI; // single export
|
CL_EXPORT_FUNCS GetClientAPI; // single export
|
||||||
qboolean valid_single_export = false;
|
qboolean valid_single_export = false;
|
||||||
qboolean missed_exports = false;
|
qboolean missed_exports = false;
|
||||||
qboolean try_internal_vgui_support = GI->internal_vgui_support;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if( clgame.hInstance ) CL_UnloadProgs();
|
if( clgame.hInstance ) CL_UnloadProgs();
|
||||||
@@ -3956,10 +3982,10 @@ qboolean CL_LoadProgs( const char *name )
|
|||||||
|
|
||||||
// NOTE: important stuff!
|
// NOTE: important stuff!
|
||||||
// vgui must startup BEFORE loading client.dll to avoid get error ERROR_NOACESS during LoadLibrary
|
// 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 );
|
VGui_Startup( refState.width, refState.height );
|
||||||
else
|
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 );
|
clgame.hInstance = COM_LoadLibrary( name, false, false );
|
||||||
|
|
||||||
@@ -3967,21 +3993,21 @@ qboolean CL_LoadProgs( const char *name )
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// delayed vgui initialization for internal support
|
// 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 );
|
VGui_Startup( refState.width, refState.height );
|
||||||
|
|
||||||
// clear exports
|
// clear exports
|
||||||
ClearExports( cdll_exports, ARRAYSIZE( cdll_exports ));
|
ClearExports( cdll_exports, ARRAYSIZE( cdll_exports ));
|
||||||
|
|
||||||
// trying to get single export
|
// 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__ );
|
Con_Reportf( "%s: found single callback export\n", __func__ );
|
||||||
|
|
||||||
// trying to fill interface now
|
// trying to fill interface now
|
||||||
GetClientAPI( &clgame.dllFuncs );
|
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__ );
|
Con_Reportf( "%s: found single callback export (secured client dlls)\n", __func__ );
|
||||||
|
|
||||||
@@ -3995,7 +4021,7 @@ qboolean CL_LoadProgs( const char *name )
|
|||||||
for( i = 0; i < ARRAYSIZE( cdll_exports ); i++ )
|
for( i = 0; i < ARRAYSIZE( cdll_exports ); i++ )
|
||||||
{
|
{
|
||||||
if( *(cdll_exports[i].func) != NULL )
|
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
|
// functions are cleared before all the extensions are evaluated
|
||||||
if(( *(cdll_exports[i].func) = (void *)COM_GetProcAddress( clgame.hInstance, cdll_exports[i].name )) == NULL )
|
if(( *(cdll_exports[i].func) = (void *)COM_GetProcAddress( clgame.hInstance, cdll_exports[i].name )) == NULL )
|
||||||
@@ -4009,11 +4035,6 @@ qboolean CL_LoadProgs( const char *name )
|
|||||||
|
|
||||||
if( missed_exports )
|
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 );
|
COM_FreeLibrary( clgame.hInstance );
|
||||||
clgame.hInstance = NULL;
|
clgame.hInstance = NULL;
|
||||||
return false;
|
return false;
|
||||||
@@ -4036,7 +4057,6 @@ qboolean CL_LoadProgs( const char *name )
|
|||||||
|
|
||||||
if( !clgame.dllFuncs.pfnInitialize( &gEngfuncs, CLDLL_INTERFACE_VERSION ))
|
if( !clgame.dllFuncs.pfnInitialize( &gEngfuncs, CLDLL_INTERFACE_VERSION ))
|
||||||
{
|
{
|
||||||
COM_PushLibraryError( "can't init client API" );
|
|
||||||
COM_FreeLibrary( clgame.hInstance );
|
COM_FreeLibrary( clgame.hInstance );
|
||||||
Con_Reportf( "%s: can't init client API\n", __func__ );
|
Con_Reportf( "%s: can't init client API\n", __func__ );
|
||||||
clgame.hInstance = NULL;
|
clgame.hInstance = NULL;
|
||||||
@@ -4050,14 +4070,14 @@ qboolean CL_LoadProgs( const char *name )
|
|||||||
|
|
||||||
CL_InitCDAudio( "media/cdaudio.txt" );
|
CL_InitCDAudio( "media/cdaudio.txt" );
|
||||||
CL_InitTitles( "titles.txt" );
|
CL_InitTitles( "titles.txt" );
|
||||||
CL_InitParticles( );
|
CL_InitParticles ();
|
||||||
CL_InitViewBeams( );
|
CL_InitViewBeams ();
|
||||||
CL_InitTempEnts( );
|
CL_InitTempEnts ();
|
||||||
|
|
||||||
if( !R_InitRenderAPI( )) // Xash3D extension
|
if( !R_InitRenderAPI()) // Xash3D extension
|
||||||
Con_Reportf( S_WARN "%s: couldn't get render API\n", __func__ );
|
Con_Reportf( S_WARN "%s: couldn't get render API\n", __func__ );
|
||||||
|
|
||||||
if( !Mobile_Init( )) // Xash3D FWGS extension: mobile interface
|
if( !Mobile_Init() ) // Xash3D FWGS extension: mobile interface
|
||||||
Con_Reportf( S_WARN "%s: couldn't get mobility API\n", __func__ );
|
Con_Reportf( S_WARN "%s: couldn't get mobility API\n", __func__ );
|
||||||
|
|
||||||
CL_InitEdicts( cl.maxclients ); // initailize local player and world
|
CL_InitEdicts( cl.maxclients ); // initailize local player and world
|
||||||
|
|||||||
@@ -37,11 +37,8 @@ void UI_UpdateMenu( float realtime )
|
|||||||
{
|
{
|
||||||
if( !gameui.hInstance ) return;
|
if( !gameui.hInstance ) return;
|
||||||
|
|
||||||
// don't draw menu over console
|
|
||||||
if( cls.key_dest == key_console ) return;
|
|
||||||
|
|
||||||
// if some deferred cmds is waiting
|
// 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 );
|
Cbuf_AddText( host.deferred_cmd );
|
||||||
host.deferred_cmd[0] = '\0';
|
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
|
UI_ShowConnectionWarning
|
||||||
@@ -499,7 +514,7 @@ static HIMAGE GAME_EXPORT pfnPIC_Load( const char *szPicName, const byte *image_
|
|||||||
{
|
{
|
||||||
HIMAGE tx;
|
HIMAGE tx;
|
||||||
|
|
||||||
if( COM_StringEmptyOrNULL( szPicName ))
|
if( !COM_CheckString( szPicName ))
|
||||||
{
|
{
|
||||||
Con_Reportf( S_ERROR "%s: refusing to load image with empty name\n", __func__ );
|
Con_Reportf( S_ERROR "%s: refusing to load image with empty name\n", __func__ );
|
||||||
return 0;
|
return 0;
|
||||||
@@ -695,9 +710,7 @@ pfnPlaySound
|
|||||||
*/
|
*/
|
||||||
static void GAME_EXPORT pfnPlaySound( const char *szSound )
|
static void GAME_EXPORT pfnPlaySound( const char *szSound )
|
||||||
{
|
{
|
||||||
if( COM_StringEmptyOrNULL( szSound ))
|
if( !COM_CheckString( szSound )) return;
|
||||||
return;
|
|
||||||
|
|
||||||
S_StartLocalSound( szSound, VOL_NORM, false );
|
S_StartLocalSound( szSound, VOL_NORM, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -982,7 +995,7 @@ pfnGetFilesList
|
|||||||
release prev search on a next call
|
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;
|
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 )
|
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 );
|
Platform_ShellExecute( path, parms );
|
||||||
|
|
||||||
if( shouldExit )
|
if( shouldExit )
|
||||||
@@ -1222,7 +1232,7 @@ static const ui_enginefuncs_t gEngfuncs =
|
|||||||
pfnMemFree,
|
pfnMemFree,
|
||||||
pfnGetOldGameInfo,
|
pfnGetOldGameInfo,
|
||||||
pfnGetGamesList,
|
pfnGetGamesList,
|
||||||
CL_GetFilesList,
|
pfnGetFilesList,
|
||||||
SV_GetSaveComment,
|
SV_GetSaveComment,
|
||||||
CL_GetDemoComment,
|
CL_GetDemoComment,
|
||||||
pfnCheckGameDll,
|
pfnCheckGameDll,
|
||||||
@@ -1344,6 +1354,7 @@ qboolean UI_LoadProgs( void )
|
|||||||
UITEXTAPI GiveTextApi;
|
UITEXTAPI GiveTextApi;
|
||||||
MENUAPI GetMenuAPI;
|
MENUAPI GetMenuAPI;
|
||||||
string dllpath;
|
string dllpath;
|
||||||
|
int i;
|
||||||
|
|
||||||
if( gameui.hInstance ) UI_UnloadProgs();
|
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 "common.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
#include "kbutton.h"
|
||||||
|
|
||||||
#if XASH_LOW_MEMORY == 0
|
#if XASH_LOW_MEMORY == 0
|
||||||
#define NET_TIMINGS 1024
|
#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 )
|
static void NetGraph_GetFrameData( float *latency, int *latency_count )
|
||||||
{
|
{
|
||||||
int i, choke_count = 0, loss_count = 0;
|
int i, choke_count = 0, loss_count = 0;
|
||||||
double newtime = Platform_DoubleTime();
|
double newtime = Sys_DoubleTime();
|
||||||
static double nexttime = 0;
|
static double nexttime = 0;
|
||||||
float loss, choke;
|
float loss, choke;
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
633
engine/client/cl_parse_48.c
Normal file
633
engine/client/cl_parse_48.c
Normal file
@@ -0,0 +1,633 @@
|
|||||||
|
/*
|
||||||
|
cl_parse.c - parse a message received from the server
|
||||||
|
Copyright (C) 2008 Uncle Mike
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "client.h"
|
||||||
|
#include "net_encode.h"
|
||||||
|
#include "particledef.h"
|
||||||
|
#include "cl_tent.h"
|
||||||
|
#include "shake.h"
|
||||||
|
#include "hltv.h"
|
||||||
|
#include "input.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
CL_ParseStaticEntity
|
||||||
|
|
||||||
|
static client entity
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
static void CL_LegacyParseStaticEntity( sizebuf_t *msg )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
entity_state_t state = { 0 };
|
||||||
|
cl_entity_t *ent;
|
||||||
|
|
||||||
|
if( !clgame.static_entities )
|
||||||
|
clgame.static_entities = Mem_Calloc( clgame.mempool, sizeof( cl_entity_t ) * MAX_STATIC_ENTITIES );
|
||||||
|
|
||||||
|
state.modelindex = MSG_ReadShort( msg );
|
||||||
|
state.sequence = MSG_ReadByte( msg );
|
||||||
|
state.frame = MSG_ReadByte( msg );
|
||||||
|
state.colormap = MSG_ReadWord( msg );
|
||||||
|
state.skin = MSG_ReadByte( msg );
|
||||||
|
|
||||||
|
for( i = 0; i < 3; i++ )
|
||||||
|
{
|
||||||
|
state.origin[i] = MSG_ReadCoord( msg );
|
||||||
|
state.angles[i] = MSG_ReadBitAngle( msg, 16 );
|
||||||
|
}
|
||||||
|
|
||||||
|
state.rendermode = MSG_ReadByte( msg );
|
||||||
|
|
||||||
|
if( state.rendermode != kRenderNormal )
|
||||||
|
{
|
||||||
|
state.renderamt = MSG_ReadByte( msg );
|
||||||
|
state.rendercolor.r = MSG_ReadByte( msg );
|
||||||
|
state.rendercolor.g = MSG_ReadByte( msg );
|
||||||
|
state.rendercolor.b = MSG_ReadByte( msg );
|
||||||
|
state.renderfx = MSG_ReadByte( msg );
|
||||||
|
}
|
||||||
|
|
||||||
|
i = clgame.numStatics;
|
||||||
|
if( i >= MAX_STATIC_ENTITIES )
|
||||||
|
{
|
||||||
|
Con_Printf( S_ERROR "MAX_STATIC_ENTITIES limit exceeded!\n" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ent = &clgame.static_entities[i];
|
||||||
|
clgame.numStatics++;
|
||||||
|
|
||||||
|
// all states are same
|
||||||
|
ent->baseline = ent->curstate = ent->prevstate = state;
|
||||||
|
ent->index = 0; // static entities doesn't has the numbers
|
||||||
|
|
||||||
|
// statics may be respawned in game e.g. for demo recording
|
||||||
|
if( cls.state == ca_connected || cls.state == ca_validate )
|
||||||
|
ent->trivial_accept = INVALID_HANDLE;
|
||||||
|
|
||||||
|
// setup the new static entity
|
||||||
|
VectorCopy( ent->curstate.origin, ent->origin );
|
||||||
|
VectorCopy( ent->curstate.angles, ent->angles );
|
||||||
|
ent->model = CL_ModelHandle( state.modelindex );
|
||||||
|
ent->curstate.framerate = 1.0f;
|
||||||
|
CL_ResetLatchedVars( ent, true );
|
||||||
|
|
||||||
|
if( ent->curstate.rendermode == kRenderNormal && ent->model != NULL )
|
||||||
|
{
|
||||||
|
// auto 'solid' faces
|
||||||
|
if( FBitSet( ent->model->flags, MODEL_TRANSPARENT ) && Host_IsQuakeCompatible( ))
|
||||||
|
{
|
||||||
|
ent->curstate.rendermode = kRenderTransAlpha;
|
||||||
|
ent->curstate.renderamt = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
R_AddEfrags( ent ); // add link
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CL_LegacyParseSoundPacket( sizebuf_t *msg, qboolean is_ambient )
|
||||||
|
{
|
||||||
|
vec3_t pos;
|
||||||
|
int chan, sound;
|
||||||
|
float volume, attn;
|
||||||
|
int flags, pitch, entnum;
|
||||||
|
sound_t handle = 0;
|
||||||
|
|
||||||
|
flags = MSG_ReadWord( msg );
|
||||||
|
if( flags & SND_LEGACY_LARGE_INDEX )
|
||||||
|
{
|
||||||
|
sound = MSG_ReadWord( msg );
|
||||||
|
flags &= ~SND_LEGACY_LARGE_INDEX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sound = MSG_ReadByte( msg );
|
||||||
|
chan = MSG_ReadByte( msg );
|
||||||
|
|
||||||
|
if( FBitSet( flags, SND_VOLUME ))
|
||||||
|
volume = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||||
|
else volume = VOL_NORM;
|
||||||
|
|
||||||
|
if( FBitSet( flags, SND_ATTENUATION ))
|
||||||
|
attn = (float)MSG_ReadByte( msg ) / 64.0f;
|
||||||
|
else attn = ATTN_NONE;
|
||||||
|
|
||||||
|
if( FBitSet( flags, SND_PITCH ))
|
||||||
|
pitch = MSG_ReadByte( msg );
|
||||||
|
else pitch = PITCH_NORM;
|
||||||
|
|
||||||
|
// entity reletive
|
||||||
|
entnum = MSG_ReadWord( msg );
|
||||||
|
|
||||||
|
// positioned in space
|
||||||
|
MSG_ReadVec3Coord( msg, pos );
|
||||||
|
|
||||||
|
if( FBitSet( flags, SND_SENTENCE ))
|
||||||
|
{
|
||||||
|
char sentenceName[32];
|
||||||
|
Q_snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
|
||||||
|
handle = S_RegisterSound( sentenceName );
|
||||||
|
}
|
||||||
|
else handle = cl.sound_index[sound]; // see precached sound
|
||||||
|
|
||||||
|
if( !cl.audio_prepped )
|
||||||
|
return; // too early
|
||||||
|
|
||||||
|
// g-cont. sound and ambient sound have only difference with channel
|
||||||
|
if( is_ambient )
|
||||||
|
{
|
||||||
|
S_AmbientSound( pos, entnum, handle, volume, attn, pitch, flags );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
S_StartSound( pos, entnum, chan, handle, volume, attn, pitch, flags );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
================
|
||||||
|
CL_PrecacheSound
|
||||||
|
|
||||||
|
prceache sound from server
|
||||||
|
================
|
||||||
|
*/
|
||||||
|
static void CL_LegacyPrecacheSound( sizebuf_t *msg )
|
||||||
|
{
|
||||||
|
int soundIndex;
|
||||||
|
|
||||||
|
soundIndex = MSG_ReadUBitLong( msg, MAX_SOUND_BITS );
|
||||||
|
|
||||||
|
if( soundIndex < 0 || soundIndex >= MAX_SOUNDS )
|
||||||
|
Host_Error( "%s: bad soundindex %i\n", __func__, soundIndex );
|
||||||
|
|
||||||
|
Q_strncpy( cl.sound_precache[soundIndex], MSG_ReadString( msg ), sizeof( cl.sound_precache[0] ));
|
||||||
|
|
||||||
|
// when we loading map all resources is precached sequentially
|
||||||
|
//if( !cl.audio_prepped ) return;
|
||||||
|
|
||||||
|
cl.sound_index[soundIndex] = S_RegisterSound( cl.sound_precache[soundIndex] );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CL_LegacyPrecacheModel( sizebuf_t *msg )
|
||||||
|
{
|
||||||
|
int modelIndex;
|
||||||
|
string model;
|
||||||
|
|
||||||
|
modelIndex = MSG_ReadUBitLong( msg, MAX_LEGACY_MODEL_BITS );
|
||||||
|
|
||||||
|
if( modelIndex < 0 || modelIndex >= MAX_MODELS )
|
||||||
|
Host_Error( "%s: bad modelindex %i\n", __func__, modelIndex );
|
||||||
|
|
||||||
|
Q_strncpy( model, MSG_ReadString( msg ), sizeof( model ));
|
||||||
|
//Q_strncpy( cl.model_precache[modelIndex], BF_ReadString( msg ), sizeof( cl.model_precache[0] ));
|
||||||
|
|
||||||
|
// when we loading map all resources is precached sequentially
|
||||||
|
//if( !cl.video_prepped ) return;
|
||||||
|
if( modelIndex == 1 && !cl.worldmodel )
|
||||||
|
{
|
||||||
|
CL_ClearWorld ();
|
||||||
|
|
||||||
|
cl.models[modelIndex] = cl.worldmodel = Mod_LoadWorld( model, true );
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Mod_RegisterModel( cl.model_precache[modelIndex], modelIndex );
|
||||||
|
|
||||||
|
cl.models[modelIndex] = Mod_ForName( model, false, false );
|
||||||
|
cl.nummodels = Q_max( cl.nummodels, modelIndex );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void CL_LegacyPrecacheEvent( sizebuf_t *msg )
|
||||||
|
{
|
||||||
|
int eventIndex;
|
||||||
|
|
||||||
|
eventIndex = MSG_ReadUBitLong( msg, MAX_EVENT_BITS );
|
||||||
|
|
||||||
|
if( eventIndex < 0 || eventIndex >= MAX_EVENTS )
|
||||||
|
Host_Error( "%s: bad eventindex %i\n", __func__, eventIndex );
|
||||||
|
|
||||||
|
Q_strncpy( cl.event_precache[eventIndex], MSG_ReadString( msg ), sizeof( cl.event_precache[0] ));
|
||||||
|
|
||||||
|
// can be set now
|
||||||
|
CL_SetEventIndex( cl.event_precache[eventIndex], eventIndex );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if XASH_LOW_MEMORY == 0
|
||||||
|
#define MAX_LEGACY_RESOURCES 2048
|
||||||
|
#elif XASH_LOW_MEMORY == 2
|
||||||
|
#define MAX_LEGACY_RESOURCES 1
|
||||||
|
#elif XASH_LOW_MEMORY == 1
|
||||||
|
#define MAX_LEGACY_RESOURCES 512
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
==============
|
||||||
|
CL_ParseResourceList
|
||||||
|
|
||||||
|
==============
|
||||||
|
*/
|
||||||
|
static void CL_LegacyParseResourceList( sizebuf_t *msg )
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
int rescount;
|
||||||
|
int restype[MAX_LEGACY_RESOURCES];
|
||||||
|
char resnames[MAX_LEGACY_RESOURCES][MAX_QPATH];
|
||||||
|
} reslist;
|
||||||
|
|
||||||
|
memset( &reslist, 0, sizeof( reslist ));
|
||||||
|
reslist.rescount = MSG_ReadWord( msg ) - 1;
|
||||||
|
|
||||||
|
if( reslist.rescount > MAX_LEGACY_RESOURCES )
|
||||||
|
Host_Error( "MAX_RESOURCES reached\n" );
|
||||||
|
|
||||||
|
for( i = 0; i < reslist.rescount; i++ )
|
||||||
|
{
|
||||||
|
reslist.restype[i] = MSG_ReadWord( msg );
|
||||||
|
Q_strncpy( reslist.resnames[i], MSG_ReadString( msg ), sizeof( reslist.resnames[i] ));
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cls.demoplayback )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( !cl_allow_download.value )
|
||||||
|
{
|
||||||
|
Con_DPrintf( "Refusing new resource, cl_allowdownload set to 0\n" );
|
||||||
|
reslist.rescount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cls.state == ca_active && !cl_download_ingame.value )
|
||||||
|
{
|
||||||
|
Con_DPrintf( "Refusing new resource, cl_download_ingame set to 0\n" );
|
||||||
|
reslist.rescount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
HTTP_ResetProcessState();
|
||||||
|
|
||||||
|
host.downloadcount = 0;
|
||||||
|
|
||||||
|
for( i = 0; i < reslist.rescount; i++ )
|
||||||
|
{
|
||||||
|
char soundpath[MAX_VA_STRING];
|
||||||
|
const char *path;
|
||||||
|
|
||||||
|
if( reslist.restype[i] == t_sound )
|
||||||
|
{
|
||||||
|
Q_snprintf( soundpath, sizeof( soundpath ), DEFAULT_SOUNDPATH "%s", reslist.resnames[i] );
|
||||||
|
|
||||||
|
path = soundpath;
|
||||||
|
}
|
||||||
|
else path = reslist.resnames[i];
|
||||||
|
|
||||||
|
if( FS_FileExists( path, false ))
|
||||||
|
continue; // already exists
|
||||||
|
|
||||||
|
host.downloadcount++;
|
||||||
|
HTTP_AddDownload( path, -1, true, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !host.downloadcount )
|
||||||
|
{
|
||||||
|
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||||
|
MSG_WriteString( &cls.netchan.message, "continueloading" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=====================
|
||||||
|
CL_ParseLegacyServerMessage
|
||||||
|
|
||||||
|
dispatch messages
|
||||||
|
=====================
|
||||||
|
*/
|
||||||
|
void CL_ParseLegacyServerMessage( sizebuf_t *msg )
|
||||||
|
{
|
||||||
|
size_t bufStart, playerbytes;
|
||||||
|
int cmd;
|
||||||
|
int old_background;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
// parse the message
|
||||||
|
while( 1 )
|
||||||
|
{
|
||||||
|
if( MSG_CheckOverflow( msg ))
|
||||||
|
{
|
||||||
|
Host_Error( "%s: overflow!\n", __func__ );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark start position
|
||||||
|
bufStart = MSG_GetNumBytesRead( msg );
|
||||||
|
|
||||||
|
// end of message (align bits)
|
||||||
|
if( MSG_GetNumBitsLeft( msg ) < 8 )
|
||||||
|
break;
|
||||||
|
|
||||||
|
cmd = MSG_ReadServerCmd( msg );
|
||||||
|
|
||||||
|
// record command for debugging spew on parse problem
|
||||||
|
CL_Parse_RecordCommand( cmd, bufStart );
|
||||||
|
|
||||||
|
if( CL_ParseCommonDLLMessage( msg, PROTO_LEGACY, cmd, bufStart ))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// other commands
|
||||||
|
switch( cmd )
|
||||||
|
{
|
||||||
|
case svc_bad:
|
||||||
|
Host_Error( "svc_bad\n" );
|
||||||
|
break;
|
||||||
|
case svc_nop:
|
||||||
|
// this does nothing
|
||||||
|
break;
|
||||||
|
case svc_disconnect:
|
||||||
|
CL_Drop ();
|
||||||
|
Host_AbortCurrentFrame ();
|
||||||
|
break;
|
||||||
|
case svc_legacy_event:
|
||||||
|
CL_ParseEvent( msg, PROTO_LEGACY );
|
||||||
|
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||||
|
break;
|
||||||
|
case svc_legacy_changing:
|
||||||
|
old_background = cl.background;
|
||||||
|
if( MSG_ReadOneBit( msg ))
|
||||||
|
{
|
||||||
|
int maxclients = cl.maxclients;
|
||||||
|
|
||||||
|
// we can only changelevel in singleplayer
|
||||||
|
// and singleplayer always runs in current protocol
|
||||||
|
// cls.changelevel = true;
|
||||||
|
S_StopAllSounds( true );
|
||||||
|
|
||||||
|
Con_Printf( "Server changing, reconnecting\n" );
|
||||||
|
|
||||||
|
if( cls.demoplayback )
|
||||||
|
{
|
||||||
|
SCR_BeginLoadingPlaque( cl.background );
|
||||||
|
cls.changedemo = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CL_ClearState( );
|
||||||
|
|
||||||
|
// a1ba: need to restore cl.maxclients because engine chooses
|
||||||
|
// frame backups count depending on this value
|
||||||
|
// In general, it's incorrect to call CL_InitEdicts right after
|
||||||
|
// CL_ClearState because of this bug. Some time later this logic
|
||||||
|
// should be re-done.
|
||||||
|
CL_InitEdicts( maxclients ); // re-arrange edicts
|
||||||
|
}
|
||||||
|
else Con_Printf( "Server disconnected, reconnecting\n" );
|
||||||
|
|
||||||
|
if( cls.demoplayback )
|
||||||
|
{
|
||||||
|
cl.background = (cls.demonum != -1) ? true : false;
|
||||||
|
cls.state = ca_connected;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// g-cont. local client skip the challenge
|
||||||
|
if( SV_Active( ))
|
||||||
|
cls.state = ca_disconnected;
|
||||||
|
else cls.state = ca_connecting;
|
||||||
|
cl.background = old_background;
|
||||||
|
cls.connect_time = MAX_HEARTBEAT;
|
||||||
|
cls.connect_retry = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case svc_setview:
|
||||||
|
CL_ParseViewEntity( msg );
|
||||||
|
break;
|
||||||
|
case svc_sound:
|
||||||
|
CL_LegacyParseSoundPacket( msg, false );
|
||||||
|
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||||
|
break;
|
||||||
|
case svc_legacy_ambientsound:
|
||||||
|
CL_LegacyParseSoundPacket( msg, true );
|
||||||
|
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case svc_time:
|
||||||
|
CL_ParseServerTime( msg, PROTO_LEGACY );
|
||||||
|
break;
|
||||||
|
case svc_print:
|
||||||
|
Con_Printf( "%s", MSG_ReadString( msg ));
|
||||||
|
break;
|
||||||
|
case svc_stufftext:
|
||||||
|
s = MSG_ReadString( msg );
|
||||||
|
if( cl_trace_stufftext.value )
|
||||||
|
{
|
||||||
|
size_t len = Q_strlen( s );
|
||||||
|
Con_Printf( "Stufftext: %s%c", s, len && s[len-1] == '\n' ? '\0' : '\n' );
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HACKS_RELATED_HLMODS
|
||||||
|
// disable Cry Of Fear antisave protection
|
||||||
|
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
|
||||||
|
break; // too early
|
||||||
|
#endif
|
||||||
|
Cbuf_AddFilteredText( s );
|
||||||
|
break;
|
||||||
|
case svc_setangle:
|
||||||
|
CL_ParseSetAngle( msg );
|
||||||
|
break;
|
||||||
|
case svc_serverdata:
|
||||||
|
Cbuf_Execute(); // make sure any stuffed commands are done
|
||||||
|
CL_ParseServerData( msg, PROTO_LEGACY );
|
||||||
|
break;
|
||||||
|
case svc_lightstyle:
|
||||||
|
CL_ParseLightStyle( msg, PROTO_LEGACY );
|
||||||
|
break;
|
||||||
|
case svc_updateuserinfo:
|
||||||
|
CL_UpdateUserinfo( msg, PROTO_LEGACY );
|
||||||
|
break;
|
||||||
|
case svc_deltatable:
|
||||||
|
Delta_ParseTableField( msg );
|
||||||
|
break;
|
||||||
|
case svc_clientdata:
|
||||||
|
CL_ParseClientData( msg, PROTO_LEGACY );
|
||||||
|
cl.frames[cl.parsecountmod].graphdata.client += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||||
|
break;
|
||||||
|
case svc_resource:
|
||||||
|
CL_ParseResource( msg );
|
||||||
|
break;
|
||||||
|
case svc_pings:
|
||||||
|
CL_UpdateUserPings( msg );
|
||||||
|
break;
|
||||||
|
case svc_particle:
|
||||||
|
CL_ParseParticles( msg, PROTO_LEGACY );
|
||||||
|
break;
|
||||||
|
case svc_restoresound:
|
||||||
|
Con_Printf( S_ERROR "%s: svc_restoresound: implement me!\n", __func__ );
|
||||||
|
break;
|
||||||
|
case svc_spawnstatic:
|
||||||
|
CL_LegacyParseStaticEntity( msg );
|
||||||
|
break;
|
||||||
|
case svc_event_reliable:
|
||||||
|
CL_ParseReliableEvent( msg, PROTO_LEGACY );
|
||||||
|
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||||
|
break;
|
||||||
|
case svc_spawnbaseline:
|
||||||
|
CL_ParseBaseline( msg, PROTO_LEGACY );
|
||||||
|
break;
|
||||||
|
case svc_setpause:
|
||||||
|
cl.paused = ( MSG_ReadOneBit( msg ) != 0 );
|
||||||
|
break;
|
||||||
|
case svc_signonnum:
|
||||||
|
CL_ParseSignon( msg, PROTO_LEGACY );
|
||||||
|
break;
|
||||||
|
case svc_centerprint:
|
||||||
|
CL_CenterPrint( MSG_ReadString( msg ), 0.25f );
|
||||||
|
break;
|
||||||
|
case svc_legacy_modelindex:
|
||||||
|
CL_LegacyPrecacheModel( msg );
|
||||||
|
break;
|
||||||
|
case svc_legacy_soundindex:
|
||||||
|
CL_LegacyPrecacheSound( msg );
|
||||||
|
break;
|
||||||
|
case svc_restore:
|
||||||
|
CL_ParseRestore( msg );
|
||||||
|
break;
|
||||||
|
case svc_legacy_eventindex:
|
||||||
|
CL_LegacyPrecacheEvent(msg);
|
||||||
|
break;
|
||||||
|
case svc_bspdecal:
|
||||||
|
CL_ParseStaticDecal( msg );
|
||||||
|
break;
|
||||||
|
case svc_addangle:
|
||||||
|
CL_ParseAddAngle( msg );
|
||||||
|
break;
|
||||||
|
case svc_usermessage:
|
||||||
|
CL_RegisterUserMessage( msg, PROTO_LEGACY );
|
||||||
|
break;
|
||||||
|
case svc_packetentities:
|
||||||
|
playerbytes = CL_ParsePacketEntities( msg, false, PROTO_LEGACY );
|
||||||
|
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||||
|
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||||
|
break;
|
||||||
|
case svc_deltapacketentities:
|
||||||
|
playerbytes = CL_ParsePacketEntities( msg, true, PROTO_LEGACY );
|
||||||
|
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||||
|
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||||
|
break;
|
||||||
|
case svc_legacy_chokecount:
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
i = MSG_ReadByte( msg );
|
||||||
|
j = cls.netchan.incoming_acknowledged - 1;
|
||||||
|
for( ; i > 0 && j > cls.netchan.outgoing_sequence - CL_UPDATE_BACKUP; j-- )
|
||||||
|
{
|
||||||
|
if( cl.frames[j & CL_UPDATE_MASK].receivedtime != -3.0 )
|
||||||
|
{
|
||||||
|
cl.frames[j & CL_UPDATE_MASK].choked = true;
|
||||||
|
cl.frames[j & CL_UPDATE_MASK].receivedtime = -2.0;
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = true;
|
||||||
|
//cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].receivedtime = -2.0;
|
||||||
|
break;
|
||||||
|
case svc_resourcelist:
|
||||||
|
CL_LegacyParseResourceList( msg );
|
||||||
|
break;
|
||||||
|
case svc_deltamovevars:
|
||||||
|
CL_ParseMovevars( msg );
|
||||||
|
break;
|
||||||
|
case svc_resourcerequest:
|
||||||
|
CL_ParseResourceRequest( msg );
|
||||||
|
break;
|
||||||
|
case svc_customization:
|
||||||
|
CL_ParseCustomization( msg );
|
||||||
|
break;
|
||||||
|
case svc_crosshairangle:
|
||||||
|
CL_ParseCrosshairAngle( msg );
|
||||||
|
break;
|
||||||
|
case svc_soundfade:
|
||||||
|
CL_ParseSoundFade( msg );
|
||||||
|
break;
|
||||||
|
case svc_filetxferfailed:
|
||||||
|
CL_ParseFileTransferFailed( msg );
|
||||||
|
break;
|
||||||
|
case svc_hltv:
|
||||||
|
CL_ParseHLTV( msg );
|
||||||
|
break;
|
||||||
|
case svc_resourcelocation:
|
||||||
|
CL_ParseResLocation( msg );
|
||||||
|
break;
|
||||||
|
case svc_querycvarvalue:
|
||||||
|
CL_ParseCvarValue( msg, false, PROTO_LEGACY );
|
||||||
|
break;
|
||||||
|
case svc_querycvarvalue2:
|
||||||
|
CL_ParseCvarValue( msg, true, PROTO_LEGACY );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CL_ParseUserMessage( msg, cmd, PROTO_LEGACY );
|
||||||
|
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CL_LegacyPrecache_f( void )
|
||||||
|
{
|
||||||
|
int spawncount, i;
|
||||||
|
model_t *mod;
|
||||||
|
|
||||||
|
if( cls.legacymode != PROTO_LEGACY )
|
||||||
|
return;
|
||||||
|
|
||||||
|
spawncount = Q_atoi( Cmd_Argv( 1 ));
|
||||||
|
|
||||||
|
Con_Printf( "Setting up renderer...\n" );
|
||||||
|
|
||||||
|
// load tempent sprites (glowshell, muzzleflashes etc)
|
||||||
|
CL_LoadClientSprites ();
|
||||||
|
|
||||||
|
// invalidate all decal indexes
|
||||||
|
memset( cl.decal_index, 0, sizeof( cl.decal_index ));
|
||||||
|
cl.video_prepped = true;
|
||||||
|
cl.audio_prepped = true;
|
||||||
|
if( clgame.entities )
|
||||||
|
clgame.entities->model = cl.worldmodel;
|
||||||
|
|
||||||
|
// load skybox
|
||||||
|
R_SetupSky( clgame.movevars.skyName );
|
||||||
|
|
||||||
|
// tell rendering system we have a new set of models.
|
||||||
|
ref.dllFuncs.R_NewMap ();
|
||||||
|
|
||||||
|
CL_SetupOverviewParams();
|
||||||
|
|
||||||
|
// release unused SpriteTextures
|
||||||
|
for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ )
|
||||||
|
{
|
||||||
|
if( mod->needload == NL_UNREFERENCED && COM_CheckString( mod->name ))
|
||||||
|
Mod_FreeModel( mod );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mod_FreeUnused ();
|
||||||
|
|
||||||
|
if( host_developer.value <= DEV_NONE )
|
||||||
|
Con_ClearNotify(); // clear any lines of console text
|
||||||
|
|
||||||
|
// done with all resources, issue prespawn command.
|
||||||
|
// Include server count in case server disconnects and changes level during d/l
|
||||||
|
MSG_BeginClientCmd( &cls.netchan.message, clc_stringcmd );
|
||||||
|
MSG_WriteStringf( &cls.netchan.message, "begin %i", spawncount );
|
||||||
|
cls.signon = SIGNONS - 1;
|
||||||
|
}
|
||||||
@@ -16,8 +16,10 @@ GNU General Public License for more details.
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "net_encode.h"
|
#include "net_encode.h"
|
||||||
|
#include "particledef.h"
|
||||||
#include "cl_tent.h"
|
#include "cl_tent.h"
|
||||||
#include "shake.h"
|
#include "shake.h"
|
||||||
|
#include "hltv.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
|
|
||||||
@@ -26,11 +28,18 @@ static void CL_ParseExtraInfo( sizebuf_t *msg )
|
|||||||
string clientfallback;
|
string clientfallback;
|
||||||
|
|
||||||
Q_strncpy( clientfallback, MSG_ReadString( msg ), sizeof( 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 );
|
Con_Reportf( S_ERROR "%s: TODO: add fallback directory %s!\n", __func__, clientfallback );
|
||||||
|
|
||||||
cls.allow_cheats = MSG_ReadByte( msg ) ? true : false;
|
if( MSG_ReadByte( msg ))
|
||||||
CL_SetCheatState( cl.maxclients > 1, cls.allow_cheats );
|
{
|
||||||
|
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 )
|
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.footsteps = MSG_ReadByte( msg );
|
||||||
clgame.movevars.rollangle = MSG_ReadFloat( msg );
|
clgame.movevars.rollangle = MSG_ReadFloat( msg );
|
||||||
clgame.movevars.rollspeed = MSG_ReadFloat( msg );
|
clgame.movevars.rollspeed = MSG_ReadFloat( msg );
|
||||||
clgame.movevars.skycolor[0] = MSG_ReadFloat( msg );
|
clgame.movevars.skycolor_r = MSG_ReadFloat( msg );
|
||||||
clgame.movevars.skycolor[1] = MSG_ReadFloat( msg );
|
clgame.movevars.skycolor_g = MSG_ReadFloat( msg );
|
||||||
clgame.movevars.skycolor[2] = MSG_ReadFloat( msg );
|
clgame.movevars.skycolor_b = MSG_ReadFloat( msg );
|
||||||
clgame.movevars.skyvec[0] = MSG_ReadFloat( msg );
|
clgame.movevars.skyvec_x = MSG_ReadFloat( msg );
|
||||||
clgame.movevars.skyvec[1] = MSG_ReadFloat( msg );
|
clgame.movevars.skyvec_y = MSG_ReadFloat( msg );
|
||||||
clgame.movevars.skyvec[2] = MSG_ReadFloat( msg );
|
clgame.movevars.skyvec_z = MSG_ReadFloat( msg );
|
||||||
|
|
||||||
Q_strncpy( clgame.movevars.skyName, MSG_ReadString( msg ), sizeof( clgame.movevars.skyName ));
|
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;
|
qboolean newent = from == NULL;
|
||||||
int pack = frame->num_entities;
|
int pack = frame->num_entities;
|
||||||
qboolean has_update = msg != NULL;
|
qboolean has_update = msg != NULL;
|
||||||
static entity_state_t nullent;
|
|
||||||
|
|
||||||
// alloc next slot to store update
|
// alloc next slot to store update
|
||||||
to = &cls.packet_entities[cls.next_client_entities % cls.num_client_entities];
|
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 )
|
if( hdr->instanced )
|
||||||
from = &cl.instanced_baseline[hdr->instanced_baseline_index];
|
from = &cl.instanced_baseline[hdr->instanced_baseline_index];
|
||||||
else if( hdr->offset != 0 )
|
else if( hdr->offset != 0 )
|
||||||
{
|
from = &cls.packet_entities[(cls.next_client_entities - hdr->offset) % cls.num_client_entities];
|
||||||
// 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];
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
from = &ent->baseline;
|
from = &ent->baseline;
|
||||||
}
|
}
|
||||||
@@ -476,7 +474,7 @@ static void CL_ParseSoundPacketGS( sizebuf_t *msg )
|
|||||||
|
|
||||||
chan = MSG_ReadUBitLong( msg, 3 );
|
chan = MSG_ReadUBitLong( msg, 3 );
|
||||||
entnum = MSG_ReadUBitLong( msg, MAX_GOLDSRC_ENTITY_BITS );
|
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 );
|
sound = MSG_ReadWord( msg );
|
||||||
else sound = MSG_ReadByte( msg );
|
else sound = MSG_ReadByte( msg );
|
||||||
MSG_ReadGSBitVec3Coord( msg, pos );
|
MSG_ReadGSBitVec3Coord( msg, pos );
|
||||||
@@ -487,7 +485,7 @@ static void CL_ParseSoundPacketGS( sizebuf_t *msg )
|
|||||||
|
|
||||||
MSG_EndBitWriting( msg );
|
MSG_EndBitWriting( msg );
|
||||||
|
|
||||||
ClearBits( flags, SND_GOLDSRC_LARGE_INDEX );
|
ClearBits( flags, SND_LEGACY_LARGE_INDEX );
|
||||||
|
|
||||||
if( FBitSet( flags, SND_SENTENCE ))
|
if( FBitSet( flags, SND_SENTENCE ))
|
||||||
{
|
{
|
||||||
@@ -569,18 +567,25 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
|||||||
// record command for debugging spew on parse problem
|
// record command for debugging spew on parse problem
|
||||||
CL_Parse_RecordCommand( cmd, bufStart );
|
CL_Parse_RecordCommand( cmd, bufStart );
|
||||||
|
|
||||||
if( CL_ParseCommonMessage( msg, PROTO_GOLDSRC, cmd, bufStart ))
|
if( CL_ParseCommonDLLMessage( msg, PROTO_GOLDSRC, cmd, bufStart ))
|
||||||
continue;
|
|
||||||
|
|
||||||
if( CL_ParseCommonHLMessage( msg, PROTO_GOLDSRC, cmd, bufStart ))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// other commands
|
// other commands
|
||||||
switch( cmd )
|
switch( cmd )
|
||||||
{
|
{
|
||||||
|
case svc_bad:
|
||||||
|
Host_Error( "svc_bad\n" );
|
||||||
|
break;
|
||||||
|
case svc_nop:
|
||||||
|
case svc_spawnstatic:
|
||||||
|
case svc_goldsrc_damage:
|
||||||
|
case svc_goldsrc_killedmonster:
|
||||||
|
case svc_goldsrc_foundsecret:
|
||||||
|
// this does nothing
|
||||||
|
break;
|
||||||
case svc_disconnect:
|
case svc_disconnect:
|
||||||
s = MSG_ReadString( msg );
|
s = MSG_ReadString( msg );
|
||||||
if( !COM_StringEmpty( s ))
|
if( COM_CheckStringEmpty( s ))
|
||||||
Con_Printf( "Server issued disconnect. Reason: %s\n", s );
|
Con_Printf( "Server issued disconnect. Reason: %s\n", s );
|
||||||
CL_Drop ();
|
CL_Drop ();
|
||||||
Host_AbortCurrentFrame ();
|
Host_AbortCurrentFrame ();
|
||||||
@@ -596,10 +601,47 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
|||||||
if( param1 != PROTOCOL_GOLDSRC_VERSION )
|
if( param1 != PROTOCOL_GOLDSRC_VERSION )
|
||||||
Host_Error( "Server use invalid protocol (%i should be %i)\n", param1, PROTOCOL_GOLDSRC_VERSION );
|
Host_Error( "Server use invalid protocol (%i should be %i)\n", param1, PROTOCOL_GOLDSRC_VERSION );
|
||||||
break;
|
break;
|
||||||
|
case svc_setview:
|
||||||
|
CL_ParseViewEntity( msg );
|
||||||
|
break;
|
||||||
case svc_sound:
|
case svc_sound:
|
||||||
CL_ParseSoundPacketGS( msg );
|
CL_ParseSoundPacketGS( msg );
|
||||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||||
break;
|
break;
|
||||||
|
case svc_time:
|
||||||
|
CL_ParseServerTime( msg, PROTO_GOLDSRC );
|
||||||
|
break;
|
||||||
|
case svc_print:
|
||||||
|
Con_Printf( "%s", MSG_ReadString( msg ));
|
||||||
|
break;
|
||||||
|
case svc_stufftext:
|
||||||
|
s = MSG_ReadString( msg );
|
||||||
|
if( cl_trace_stufftext.value )
|
||||||
|
{
|
||||||
|
size_t len = Q_strlen( s );
|
||||||
|
Con_Printf( "Stufftext: %s%c", s, len && s[len-1] == '\n' ? '\0' : '\n' );
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HACKS_RELATED_HLMODS
|
||||||
|
// disable Cry Of Fear antisave protection
|
||||||
|
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
|
||||||
|
break; // too early
|
||||||
|
#endif
|
||||||
|
Cbuf_AddFilteredText( s );
|
||||||
|
break;
|
||||||
|
case svc_setangle:
|
||||||
|
CL_ParseSetAngle( msg );
|
||||||
|
break;
|
||||||
|
case svc_serverdata:
|
||||||
|
Cbuf_Execute(); // make sure any stuffed commands are done
|
||||||
|
CL_ParseServerData( msg, PROTO_GOLDSRC );
|
||||||
|
break;
|
||||||
|
case svc_lightstyle:
|
||||||
|
CL_ParseLightStyle( msg, PROTO_GOLDSRC );
|
||||||
|
break;
|
||||||
|
case svc_updateuserinfo:
|
||||||
|
CL_UpdateUserinfo( msg, PROTO_GOLDSRC );
|
||||||
|
break;
|
||||||
case svc_deltatable:
|
case svc_deltatable:
|
||||||
Delta_ParseTableField_GS( msg );
|
Delta_ParseTableField_GS( msg );
|
||||||
break;
|
break;
|
||||||
@@ -619,9 +661,8 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
|||||||
CL_UpdateUserPings( msg );
|
CL_UpdateUserPings( msg );
|
||||||
MSG_EndBitWriting( msg );
|
MSG_EndBitWriting( msg );
|
||||||
break;
|
break;
|
||||||
case svc_goldsrc_damage:
|
case svc_particle:
|
||||||
case svc_spawnstatic:
|
CL_ParseParticles( msg, PROTO_GOLDSRC );
|
||||||
// this does nothing
|
|
||||||
break;
|
break;
|
||||||
case svc_event_reliable:
|
case svc_event_reliable:
|
||||||
MSG_StartBitWriting( msg );
|
MSG_StartBitWriting( msg );
|
||||||
@@ -637,18 +678,35 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
|||||||
case svc_setpause:
|
case svc_setpause:
|
||||||
cl.paused = ( MSG_ReadByte( msg ) != 0 );
|
cl.paused = ( MSG_ReadByte( msg ) != 0 );
|
||||||
break;
|
break;
|
||||||
case svc_goldsrc_killedmonster:
|
case svc_signonnum:
|
||||||
case svc_goldsrc_foundsecret:
|
CL_ParseSignon( msg, PROTO_GOLDSRC );
|
||||||
// this does nothing
|
break;
|
||||||
|
case svc_centerprint:
|
||||||
|
CL_CenterPrint( MSG_ReadString( msg ), 0.25f );
|
||||||
break;
|
break;
|
||||||
case svc_goldsrc_spawnstaticsound:
|
case svc_goldsrc_spawnstaticsound:
|
||||||
CL_ParseSpawnStaticSound( msg );
|
CL_ParseSpawnStaticSound( msg );
|
||||||
break;
|
break;
|
||||||
|
case svc_finale:
|
||||||
|
CL_ParseFinaleCutscene( msg, 2 );
|
||||||
|
break;
|
||||||
|
case svc_restore:
|
||||||
|
CL_ParseRestore( msg );
|
||||||
|
break;
|
||||||
|
case svc_cutscene:
|
||||||
|
CL_ParseFinaleCutscene( msg, 3 );
|
||||||
|
break;
|
||||||
case svc_goldsrc_decalname:
|
case svc_goldsrc_decalname:
|
||||||
param1 = MSG_ReadByte( msg );
|
param1 = MSG_ReadByte( msg );
|
||||||
s = MSG_ReadString( msg );
|
s = MSG_ReadString( msg );
|
||||||
Q_strncpy( host.draw_decals[param1], s, sizeof( host.draw_decals[param1] ));
|
Q_strncpy( host.draw_decals[param1], s, sizeof( host.draw_decals[param1] ));
|
||||||
break;
|
break;
|
||||||
|
case svc_addangle:
|
||||||
|
CL_ParseAddAngle( msg );
|
||||||
|
break;
|
||||||
|
case svc_usermessage:
|
||||||
|
CL_RegisterUserMessage( msg, PROTO_GOLDSRC );
|
||||||
|
break;
|
||||||
case svc_packetentities:
|
case svc_packetentities:
|
||||||
playerbytes = CL_ParsePacketEntitiesGS( msg, false );
|
playerbytes = CL_ParsePacketEntitiesGS( msg, false );
|
||||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||||
@@ -659,6 +717,10 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
|||||||
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
cl.frames[cl.parsecountmod].graphdata.players += playerbytes;
|
||||||
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
cl.frames[cl.parsecountmod].graphdata.entities += MSG_GetNumBytesRead( msg ) - bufStart - playerbytes;
|
||||||
break;
|
break;
|
||||||
|
case svc_choke:
|
||||||
|
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].choked = true;
|
||||||
|
cl.frames[cls.netchan.incoming_sequence & CL_UPDATE_MASK].receivedtime = -2.0;
|
||||||
|
break;
|
||||||
case svc_resourcelist:
|
case svc_resourcelist:
|
||||||
MSG_StartBitWriting( msg );
|
MSG_StartBitWriting( msg );
|
||||||
CL_ParseResourceList( msg, PROTO_GOLDSRC );
|
CL_ParseResourceList( msg, PROTO_GOLDSRC );
|
||||||
@@ -667,6 +729,34 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
|||||||
case svc_deltamovevars:
|
case svc_deltamovevars:
|
||||||
CL_ParseNewMovevars( msg );
|
CL_ParseNewMovevars( msg );
|
||||||
break;
|
break;
|
||||||
|
case svc_resourcerequest:
|
||||||
|
CL_ParseResourceRequest( msg );
|
||||||
|
break;
|
||||||
|
case svc_customization:
|
||||||
|
CL_ParseCustomization( msg );
|
||||||
|
break;
|
||||||
|
case svc_crosshairangle:
|
||||||
|
CL_ParseCrosshairAngle( msg );
|
||||||
|
break;
|
||||||
|
case svc_soundfade:
|
||||||
|
CL_ParseSoundFade( msg );
|
||||||
|
break;
|
||||||
|
case svc_filetxferfailed:
|
||||||
|
CL_ParseFileTransferFailed( msg );
|
||||||
|
break;
|
||||||
|
case svc_hltv:
|
||||||
|
CL_ParseHLTV( msg );
|
||||||
|
break;
|
||||||
|
case svc_voiceinit:
|
||||||
|
CL_ParseVoiceInit( msg );
|
||||||
|
break;
|
||||||
|
case svc_voicedata:
|
||||||
|
CL_ParseVoiceData( msg, PROTO_GOLDSRC );
|
||||||
|
cl.frames[cl.parsecountmod].graphdata.voicebytes += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||||
|
break;
|
||||||
|
case svc_resourcelocation:
|
||||||
|
CL_ParseResLocation( msg );
|
||||||
|
break;
|
||||||
case svc_goldsrc_sendextrainfo:
|
case svc_goldsrc_sendextrainfo:
|
||||||
CL_ParseExtraInfo( msg );
|
CL_ParseExtraInfo( msg );
|
||||||
break;
|
break;
|
||||||
@@ -676,8 +766,17 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
|||||||
Con_Reportf( S_ERROR "%s: svc_goldsrc_timescale: implement me!\n", __func__ );
|
Con_Reportf( S_ERROR "%s: svc_goldsrc_timescale: implement me!\n", __func__ );
|
||||||
MSG_ReadFloat( msg );
|
MSG_ReadFloat( msg );
|
||||||
break;
|
break;
|
||||||
|
case svc_querycvarvalue:
|
||||||
|
CL_ParseCvarValue( msg, false, PROTO_GOLDSRC );
|
||||||
|
break;
|
||||||
|
case svc_querycvarvalue2:
|
||||||
|
CL_ParseCvarValue( msg, true, PROTO_GOLDSRC );
|
||||||
|
break;
|
||||||
|
case svc_exec:
|
||||||
|
CL_ParseExec( msg );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
CL_ParseUserMessage( msg, cmd, PROTO_GOLDSRC );
|
CL_ParseUserMessage( msg, cmd, PROTO_LEGACY );
|
||||||
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;
|
cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ GNU General Public License for more details.
|
|||||||
#include "const.h"
|
#include "const.h"
|
||||||
#include "cl_tent.h"
|
#include "cl_tent.h"
|
||||||
#include "pm_local.h"
|
#include "pm_local.h"
|
||||||
|
#include "particledef.h"
|
||||||
#include "studio.h"
|
#include "studio.h"
|
||||||
|
|
||||||
#define MAX_FORWARD 6 // forward probes for set idealpitch
|
#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_FileSize = COM_FileSize;
|
||||||
clgame.pmove->COM_LoadFile = COM_LoadFile;
|
clgame.pmove->COM_LoadFile = COM_LoadFile;
|
||||||
clgame.pmove->COM_FreeFile = COM_FreeFile;
|
clgame.pmove->COM_FreeFile = COM_FreeFile;
|
||||||
clgame.pmove->memfgets = Q_memfgets;
|
clgame.pmove->memfgets = COM_MemFgets;
|
||||||
clgame.pmove->PM_PlaySound = pfnPlaySound;
|
clgame.pmove->PM_PlaySound = pfnPlaySound;
|
||||||
clgame.pmove->PM_TraceTexture = PM_CL_TraceTexture;
|
clgame.pmove->PM_TraceTexture = PM_CL_TraceTexture;
|
||||||
clgame.pmove->PM_PlaybackEventFull = pfnPlaybackEventFull;
|
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->flFallVelocity = ps->flFallVelocity;
|
||||||
pmove->flSwimTime = (float)cd->flSwimTime;
|
pmove->flSwimTime = (float)cd->flSwimTime;
|
||||||
VectorCopy( cd->punchangle, pmove->punchangle );
|
VectorCopy( cd->punchangle, pmove->punchangle );
|
||||||
|
pmove->flNextPrimaryAttack = 0.0f; // not used by PM_ code
|
||||||
pmove->effects = ps->effects;
|
pmove->effects = ps->effects;
|
||||||
pmove->flags = cd->flags;
|
pmove->flags = cd->flags;
|
||||||
pmove->gravity = ps->gravity;
|
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 )
|
if(( cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged ) >= CL_UPDATE_MASK )
|
||||||
return;
|
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
|
// this is the last frame received from the server
|
||||||
frame = &cl.frames[cl.parsecountmod];
|
frame = &cl.frames[cl.parsecountmod];
|
||||||
|
|
||||||
@@ -1101,7 +1098,7 @@ void CL_PredictMovement( qboolean repredicting )
|
|||||||
|
|
||||||
// now interpolate some fraction of the final frame
|
// now interpolate some fraction of the final frame
|
||||||
if( to_cmd->senttime != from_cmd->senttime )
|
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;
|
else f = 0.0;
|
||||||
|
|
||||||
if( CL_PlayerTeleported( from, to ))
|
if( CL_PlayerTeleported( from, to ))
|
||||||
|
|||||||
@@ -16,10 +16,11 @@ GNU General Public License for more details.
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "net_encode.h"
|
#include "net_encode.h"
|
||||||
|
#include "particledef.h"
|
||||||
#include "cl_tent.h"
|
#include "cl_tent.h"
|
||||||
#include "shake.h"
|
#include "shake.h"
|
||||||
|
#include "hltv.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "base_cmd.h"
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
STAT_HEALTH = 0,
|
STAT_HEALTH = 0,
|
||||||
@@ -187,7 +188,7 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
Con_Reportf( "Serverdata packet received.\n" );
|
Con_Reportf( "Serverdata packet received.\n" );
|
||||||
cls.timestart = Platform_DoubleTime();
|
cls.timestart = Sys_DoubleTime();
|
||||||
|
|
||||||
cls.demowaiting = false; // server is changed
|
cls.demowaiting = false; // server is changed
|
||||||
|
|
||||||
@@ -213,7 +214,6 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
|||||||
clgame.maxEntities = bound( 600, clgame.maxEntities, MAX_EDICTS );
|
clgame.maxEntities = bound( 600, clgame.maxEntities, MAX_EDICTS );
|
||||||
clgame.maxModels = MAX_MODELS;
|
clgame.maxModels = MAX_MODELS;
|
||||||
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), sizeof( clgame.maptitle ));
|
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), sizeof( clgame.maptitle ));
|
||||||
Host_ValidateEngineFeatures( ENGINE_FEATURES_MASK, ENGINE_QUAKE_COMPATIBLE );
|
|
||||||
|
|
||||||
// Re-init hud video, especially if we changed game directories
|
// Re-init hud video, especially if we changed game directories
|
||||||
clgame.dllFuncs.pfnVidInit();
|
clgame.dllFuncs.pfnVidInit();
|
||||||
@@ -239,8 +239,9 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
|||||||
}
|
}
|
||||||
else Cvar_DirectSet( &r_decals, NULL );
|
else Cvar_DirectSet( &r_decals, NULL );
|
||||||
|
|
||||||
// tell the game parts about background state
|
if( cl.background ) // tell the game parts about background state
|
||||||
Cvar_DirectFullSet( &cl_background, cl.background ? "1" : "0", FCVAR_READ_ONLY );
|
Cvar_FullSet( "cl_background", "1", FCVAR_READ_ONLY );
|
||||||
|
else Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
|
||||||
|
|
||||||
S_StopBackgroundTrack ();
|
S_StopBackgroundTrack ();
|
||||||
|
|
||||||
@@ -266,7 +267,7 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
|||||||
{
|
{
|
||||||
pResName = MSG_ReadString( msg );
|
pResName = MSG_ReadString( msg );
|
||||||
|
|
||||||
if( COM_StringEmptyOrNULL( pResName ))
|
if( !COM_CheckString( pResName ))
|
||||||
break; // end of list
|
break; // end of list
|
||||||
|
|
||||||
pResource = Mem_Calloc( cls.mempool, sizeof( resource_t ));
|
pResource = Mem_Calloc( cls.mempool, sizeof( resource_t ));
|
||||||
@@ -284,7 +285,7 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
|||||||
{
|
{
|
||||||
pResName = MSG_ReadString( msg );
|
pResName = MSG_ReadString( msg );
|
||||||
|
|
||||||
if( COM_StringEmptyOrNULL( pResName ))
|
if( !COM_CheckString( pResName ))
|
||||||
break; // end of list
|
break; // end of list
|
||||||
|
|
||||||
pResource = Mem_Calloc( cls.mempool, sizeof( resource_t ));
|
pResource = Mem_Calloc( cls.mempool, sizeof( resource_t ));
|
||||||
@@ -839,7 +840,7 @@ static void CL_QuakeExecStuff( void )
|
|||||||
int argc = 0;
|
int argc = 0;
|
||||||
|
|
||||||
// check if no commands this frame
|
// check if no commands this frame
|
||||||
if( COM_StringEmptyOrNULL( text ))
|
if( !COM_CheckString( text ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while( 1 )
|
while( 1 )
|
||||||
@@ -866,13 +867,7 @@ static void CL_QuakeExecStuff( void )
|
|||||||
if( argc == 0 )
|
if( argc == 0 )
|
||||||
{
|
{
|
||||||
// debug: find all missed commands and cvars to add them into QWrap
|
// debug: find all missed commands and cvars to add them into QWrap
|
||||||
cmdalias_t *alias;
|
if( !Cvar_Exists( token ) && !Cmd_Exists( token ))
|
||||||
cmd_t *cmd;
|
|
||||||
convar_t *cvar;
|
|
||||||
|
|
||||||
BaseCmd_FindAll( token, &cmd, &alias, &cvar );
|
|
||||||
|
|
||||||
if( !cvar && !cmd )
|
|
||||||
Con_Printf( S_WARN "'%s' is not exist\n", token );
|
Con_Printf( S_WARN "'%s' is not exist\n", token );
|
||||||
// else Msg( "cmd: %s\n", token );
|
// else Msg( "cmd: %s\n", token );
|
||||||
|
|
||||||
@@ -930,12 +925,12 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
|||||||
// record command for debugging spew on parse problem
|
// record command for debugging spew on parse problem
|
||||||
CL_Parse_RecordCommand( cmd, bufStart );
|
CL_Parse_RecordCommand( cmd, bufStart );
|
||||||
|
|
||||||
if( CL_ParseCommonMessage( msg, PROTO_QUAKE, cmd, bufStart ))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// other commands
|
// other commands
|
||||||
switch( cmd )
|
switch( cmd )
|
||||||
{
|
{
|
||||||
|
case svc_nop:
|
||||||
|
// this does nothing
|
||||||
|
break;
|
||||||
case svc_disconnect:
|
case svc_disconnect:
|
||||||
CL_DemoCompleted ();
|
CL_DemoCompleted ();
|
||||||
break;
|
break;
|
||||||
@@ -947,6 +942,9 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
|||||||
if( param1 != PROTOCOL_VERSION_QUAKE )
|
if( param1 != PROTOCOL_VERSION_QUAKE )
|
||||||
Host_Error( "Server is protocol %i instead of %i\n", param1, PROTOCOL_VERSION_QUAKE );
|
Host_Error( "Server is protocol %i instead of %i\n", param1, PROTOCOL_VERSION_QUAKE );
|
||||||
break;
|
break;
|
||||||
|
case svc_setview:
|
||||||
|
CL_ParseViewEntity( msg );
|
||||||
|
break;
|
||||||
case svc_sound:
|
case svc_sound:
|
||||||
CL_ParseQuakeSound( msg );
|
CL_ParseQuakeSound( msg );
|
||||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||||
@@ -971,6 +969,9 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
|||||||
Cbuf_Execute(); // make sure any stuffed commands are done
|
Cbuf_Execute(); // make sure any stuffed commands are done
|
||||||
CL_ParseQuakeServerInfo( msg );
|
CL_ParseQuakeServerInfo( msg );
|
||||||
break;
|
break;
|
||||||
|
case svc_lightstyle:
|
||||||
|
CL_ParseLightStyle( msg, PROTO_QUAKE );
|
||||||
|
break;
|
||||||
case svc_updatename:
|
case svc_updatename:
|
||||||
param1 = MSG_ReadByte( msg );
|
param1 = MSG_ReadByte( msg );
|
||||||
Q_strncpy( cl.players[param1].name, MSG_ReadString( msg ), sizeof( cl.players[0].name ));
|
Q_strncpy( cl.players[param1].name, MSG_ReadString( msg ), sizeof( cl.players[0].name ));
|
||||||
@@ -1023,7 +1024,8 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
|||||||
CL_ParseQuakeSignon( msg );
|
CL_ParseQuakeSignon( msg );
|
||||||
break;
|
break;
|
||||||
case svc_centerprint:
|
case svc_centerprint:
|
||||||
CL_HudMessage( MSG_ReadString( msg ));
|
str = MSG_ReadString( msg );
|
||||||
|
CL_DispatchUserMessage( "HudText", Q_strlen( str ), (void *)str );
|
||||||
break;
|
break;
|
||||||
case svc_killedmonster:
|
case svc_killedmonster:
|
||||||
CL_DispatchQuakeMessage( "KillMonster" ); // just an event
|
CL_DispatchQuakeMessage( "KillMonster" ); // just an event
|
||||||
@@ -1034,6 +1036,12 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
|||||||
case svc_spawnstaticsound:
|
case svc_spawnstaticsound:
|
||||||
CL_ParseQuakeStaticSound( msg );
|
CL_ParseQuakeStaticSound( msg );
|
||||||
break;
|
break;
|
||||||
|
case svc_intermission:
|
||||||
|
cl.intermission = 1;
|
||||||
|
break;
|
||||||
|
case svc_finale:
|
||||||
|
CL_ParseFinaleCutscene( msg, 2 );
|
||||||
|
break;
|
||||||
case svc_cdtrack:
|
case svc_cdtrack:
|
||||||
param1 = MSG_ReadByte( msg );
|
param1 = MSG_ReadByte( msg );
|
||||||
param1 = bound( 0, param1, MAX_CDTRACKS - 1 ); // tracknum
|
param1 = bound( 0, param1, MAX_CDTRACKS - 1 ); // tracknum
|
||||||
@@ -1046,12 +1054,15 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
|||||||
case svc_sellscreen:
|
case svc_sellscreen:
|
||||||
Cmd_ExecuteString( "help" ); // open quake menu
|
Cmd_ExecuteString( "help" ); // open quake menu
|
||||||
break;
|
break;
|
||||||
case svc_showlmp:
|
case svc_cutscene:
|
||||||
CL_ParseNehahraShowLMP( msg );
|
CL_ParseFinaleCutscene( msg, 3 );
|
||||||
break;
|
break;
|
||||||
case svc_hidelmp:
|
case svc_hidelmp:
|
||||||
CL_ParseNehahraHideLMP( msg );
|
CL_ParseNehahraHideLMP( msg );
|
||||||
break;
|
break;
|
||||||
|
case svc_showlmp:
|
||||||
|
CL_ParseNehahraShowLMP( msg );
|
||||||
|
break;
|
||||||
case svc_skybox:
|
case svc_skybox:
|
||||||
Q_strncpy( clgame.movevars.skyName, MSG_ReadString( msg ), sizeof( clgame.movevars.skyName ));
|
Q_strncpy( clgame.movevars.skyName, MSG_ReadString( msg ), sizeof( clgame.movevars.skyName ));
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -356,9 +356,8 @@ static void CL_AllocRemapInfo( cl_entity_t *entity, model_t *model, int topcolor
|
|||||||
|
|
||||||
if( model->type == mod_studio )
|
if( model->type == mod_studio )
|
||||||
{
|
{
|
||||||
phdr = (studiohdr_t *)model->cache.data;
|
phdr = (studiohdr_t *)Mod_StudioExtradata( model );
|
||||||
if( !phdr )
|
if( !phdr ) return; // bad model?
|
||||||
return; // bad model?
|
|
||||||
|
|
||||||
src = (mstudiotexture_t *)(((byte *)phdr) + phdr->textureindex);
|
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 )
|
else if( model->type == mod_alias )
|
||||||
{
|
{
|
||||||
ahdr = (aliashdr_t *)model->cache.data;
|
ahdr = (aliashdr_t *)Mod_AliasExtradata( model );
|
||||||
if( !ahdr )
|
if( !ahdr ) return; // bad model?
|
||||||
return; // bad model?
|
|
||||||
|
|
||||||
// NOTE: we must copy all the structures 'mstudiotexture_t' for easy access when model is rendering
|
// 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 )
|
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 );
|
_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 )
|
static uint pfnFileBufferCRC32( const void *buffer, const int length )
|
||||||
{
|
{
|
||||||
uint modelCRC = 0;
|
uint modelCRC = 0;
|
||||||
@@ -67,7 +91,7 @@ static void R_EnvShot( const float *vieworg, const char *name, qboolean skyshot,
|
|||||||
{
|
{
|
||||||
static vec3_t viewPoint;
|
static vec3_t viewPoint;
|
||||||
|
|
||||||
if( COM_StringEmptyOrNULL( name ))
|
if( !COM_CheckString( name ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( cls.scrshot_action != scrshot_inactive )
|
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:
|
case PARM_SHADOWDATA:
|
||||||
return (intptr_t)world.shadowdata;
|
return (intptr_t)world.shadowdata;
|
||||||
case PARM_FULLSCREEN:
|
case PARM_FULLSCREEN:
|
||||||
return refState.window_mode == WINDOW_MODE_BORDERLESS || refState.window_mode == WINDOW_MODE_FULLSCREEN;
|
return refState.fullScreen;
|
||||||
case PARM_WIDESCREEN:
|
case PARM_WIDESCREEN:
|
||||||
return refState.wideScreen;
|
return refState.wideScreen;
|
||||||
case PARM_SCREEN_WIDTH:
|
case PARM_SCREEN_WIDTH:
|
||||||
@@ -272,14 +296,14 @@ static render_api_t gRenderAPI =
|
|||||||
NULL,
|
NULL,
|
||||||
R_Mem_Alloc,
|
R_Mem_Alloc,
|
||||||
R_Mem_Free,
|
R_Mem_Free,
|
||||||
CL_GetFilesList,
|
pfnGetFilesList,
|
||||||
pfnFileBufferCRC32,
|
pfnFileBufferCRC32,
|
||||||
pfnCompareFileTime,
|
pfnCompareFileTime,
|
||||||
Host_Error,
|
Host_Error,
|
||||||
(void*)CL_ModelHandle,
|
(void*)CL_ModelHandle,
|
||||||
Sys_FloatTime,
|
pfnTime,
|
||||||
Cvar_Set,
|
Cvar_Set,
|
||||||
S_MusicFade,
|
S_FadeMusicVolume,
|
||||||
COM_SetRandomSeed,
|
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