Compare commits

..

4 Commits

Author SHA1 Message Date
Alibek Omarov
70a3ff531c ref_gl: fix texturelist output 2021-11-24 01:41:25 +03:00
Alibek Omarov
501ff944b9 ref_gl: add VERY basic 16-bit texture support(no mips, no rescale, no filters), as an example to ref_vk dev 2021-11-23 04:12:30 +03:00
Alibek Omarov
f16641b606 engine: imagelib: add 16-bit PNG load support 2021-11-23 04:03:07 +03:00
Alibek Omarov
f045103abb engine: imagelib: add common definitions for 16-bit images 2021-11-23 03:58:47 +03:00
428 changed files with 30402 additions and 42944 deletions

View File

@@ -1,27 +0,0 @@
image: alpine/latest
packages:
- build-base
- sdl2-dev
- freetype-dev
- fontconfig-dev
- opus-dev
sources:
- https://git.sr.ht/~a1batross/xash3d-fwgs
tasks:
- client: |
cd xash3d-fwgs
./waf configure -8 --enable-tests --enable-engine-tests build install --destdir=bin
- server: |
cd xash3d-fwgs
./waf configure --reconfigure --dedicated build install --destdir=bin
- run-tests: |
cd xash3d-fwgs/bin
export SDL_VIDEODRIVER=wayland
./xash3d -runtests
./xash -runtests
rm -rf valve/gameinfo.txt test_*
- package: |
cd xash3d-fwgs/bin
tar -cjvf xash3d-fwgs-alpine-amd64.tar.bz2 *
artifacts:
- xash3d-fwgs/bin/xash3d-fwgs-alpine-amd64.tar.bz2

View File

@@ -1,30 +0,0 @@
image: debian/sid
arch: amd64
packages:
- build-essential
- python-is-python3
- libsdl2-dev
- libfreetype-dev
- libfontconfig-dev
- libopus-dev
sources:
- https://git.sr.ht/~a1batross/xash3d-fwgs
tasks:
- client: |
cd xash3d-fwgs
./waf configure -8 --enable-tests --enable-engine-tests build install --destdir=bin
- server: |
cd xash3d-fwgs
./waf configure --reconfigure --dedicated build install --destdir=bin
- run-tests: |
cd xash3d-fwgs/bin
export SDL_VIDEODRIVER=wayland
./xash3d -runtests
./xash -runtests
rm -rf valve/gameinfo.txt test_*
- package: |
cd xash3d-fwgs/bin
tar -cjvf xash3d-fwgs-debian-arm64.tar.bz2 *
artifacts:
- xash3d-fwgs/bin/xash3d-fwgs-debian-arm64.tar.bz2

View File

@@ -1,29 +0,0 @@
image: debian/sid
packages:
- build-essential
- python-is-python3
- libsdl2-dev
- libfreetype-dev
- libfontconfig-dev
- libopus-dev
sources:
- https://git.sr.ht/~a1batross/xash3d-fwgs
tasks:
- client: |
cd xash3d-fwgs
./waf configure -8 --enable-tests --enable-engine-tests build install --destdir=bin
- server: |
cd xash3d-fwgs
./waf configure --reconfigure --dedicated build install --destdir=bin
- run-tests: |
cd xash3d-fwgs/bin
export SDL_VIDEODRIVER=wayland
./xash3d -runtests
./xash -runtests
rm -rf valve/gameinfo.txt test_*
- package: |
cd xash3d-fwgs/bin
tar -cjvf xash3d-fwgs-debian-amd64.tar.bz2 *
artifacts:
- xash3d-fwgs/bin/xash3d-fwgs-debian-amd64.tar.bz2

View File

@@ -1,29 +0,0 @@
image: freebsd/latest
packages:
- lang/python
- devel/pkgconf
- devel/sdl20
- print/freetype2
- x11-fonts/fontconfig
- audio/opus
sources:
- https://git.sr.ht/~a1batross/xash3d-fwgs
tasks:
- client: |
cd xash3d-fwgs
./waf configure --enable-tests --enable-engine-tests build install --destdir=bin
- server: |
cd xash3d-fwgs
./waf configure --reconfigure --dedicated build install --destdir=bin
- run-tests: |
cd xash3d-fwgs/bin
export SDL_VIDEODRIVER=wayland
./xash3d -runtests
./xash -runtests
rm -rf valve/gameinfo.txt test_*
- package: |
cd xash3d-fwgs/bin
tar -cjvf xash3d-fwgs-freebsd-amd64.tar.bz2 *
artifacts:
- xash3d-fwgs/bin/xash3d-fwgs-freebsd-amd64.tar.bz2

View File

@@ -1,29 +0,0 @@
image: netbsd/latest
packages:
- python311
- SDL2
- freetype2
- fontconfig
- libopus
- pkgconf
sources:
- https://git.sr.ht/~a1batross/xash3d-fwgs
tasks:
- client: |
cd xash3d-fwgs
python3.11 waf configure --enable-tests --enable-engine-tests build install --destdir=bin
- server: |
cd xash3d-fwgs
python3.11 waf configure --reconfigure --dedicated build install --destdir=bin
- run-tests: |
cd xash3d-fwgs/bin
export SDL_VIDEODRIVER=wayland
./xash3d -runtests
./xash -runtests
rm -rf valve/gameinfo.txt test_*
- package: |
cd xash3d-fwgs/bin
tar -cjvf xash3d-fwgs-netbsd-amd64.tar.bz2 *
artifacts:
- xash3d-fwgs/bin/xash3d-fwgs-netbsd-amd64.tar.bz2

View File

@@ -1,26 +0,0 @@
image: openbsd/latest
packages:
- python3
- sdl2
- opus
sources:
- https://git.sr.ht/~a1batross/xash3d-fwgs
tasks:
- client: |
cd xash3d-fwgs
python3 waf configure --enable-tests --enable-engine-tests build install --destdir=bin
- server: |
cd xash3d-fwgs
python3 waf configure --reconfigure --dedicated build install --destdir=bin
- run-tests: |
cd xash3d-fwgs/bin
export SDL_VIDEODRIVER=wayland
./xash3d -runtests
./xash -runtests
rm -rf valve/gameinfo.txt test_*
- package: |
cd xash3d-fwgs/bin
tar -cjvf xash3d-fwgs-openbsd-amd64.tar.bz2 *
artifacts:
- xash3d-fwgs/bin/xash3d-fwgs-openbsd-amd64.tar.bz2

View File

@@ -1,47 +1,34 @@
task:
# Seems packages for it were removed from the mirrors
# name: freebsd-12-amd64
# freebsd_instance:
# image_family: freebsd-12-4
# setup_script:
# - pkg update
# - pkg install -y pkgconf git sdl2 python fontconfig opus
# - git submodule update --init --recursive
# test_script:
# - ./scripts/cirrus/build_freebsd.sh dedicated
# - ./scripts/cirrus/build_freebsd.sh full
name: freebsd-11-amd64
freebsd_instance:
image_family: freebsd-11-4
setup_script:
- pkg update
- pkg install -y git sdl2 python
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated
- ./scripts/cirrus/build_freebsd.sh full
task:
name: freebsd-12-amd64
freebsd_instance:
image_family: freebsd-12-2
setup_script:
- pkg update
- pkg install -y git sdl2 python
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated
- ./scripts/cirrus/build_freebsd.sh full
task:
name: freebsd-13-amd64
freebsd_instance:
image_family: freebsd-13-2
image_family: freebsd-13-0-snap
setup_script:
- pkg update
- pkg install -y pkgconf git sdl2 python fontconfig opus
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated
- ./scripts/cirrus/build_freebsd.sh full
task:
name: freebsd-14-amd64
freebsd_instance:
image_family: freebsd-14-0-snap
setup_script:
- pkg update
- pkg install -y pkgconf git sdl2 python fontconfig opus
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated
- ./scripts/cirrus/build_freebsd.sh full
task:
name: freebsd-15-amd64
freebsd_instance:
image_family: freebsd-15-0-snap
setup_script:
- pkg update
- pkg install -y pkgconf git sdl2 python fontconfig opus
- pkg install -y git sdl2 python
- git submodule update --init --recursive
test_script:
- ./scripts/cirrus/build_freebsd.sh dedicated

View File

@@ -1,11 +1,6 @@
name: Build & Deploy Engine
on: [push, pull_request]
jobs:
# cleanup:
# runs-on: self-hosted
# steps:
# - name: Cleanup
# run: rm -rf .* || true
build:
runs-on: ${{ matrix.os }}
continue-on-error: true
@@ -13,116 +8,63 @@ jobs:
fail-fast: false
matrix:
include:
# Linux build specifically want oldest Ubuntu as possible
# to be crossdistribution compatible, otherwise use ubuntu-latest
- os: ubuntu-20.04
- os: ubuntu-18.04
targetos: linux
targetarch: amd64
- os: ubuntu-20.04
- os: ubuntu-18.04
targetos: linux
targetarch: i386
# - os: ubuntu-aarch64-20.04
# targetos: linux
# targetarch: aarch64
# - os: ubuntu-20.04
# targetos: android
# targetarch: 32
# - os: ubuntu-20.04
# targetos: android
# targetarch: 64
- os: ubuntu-18.04
targetos: android
targetarch: 32
- os: ubuntu-18.04
targetos: android
targetarch: 64
# - os: ubuntu-20.04
# targetos: motomagx
# targetarch: armv6
- os: ubuntu-18.04
targetos: motomagx
targetarch: armv6
- os: ubuntu-latest
targetos: nswitch
targetarch: arm64
- os: ubuntu-latest
targetos: psvita
targetarch: armv7hf
- os: windows-latest
targetos: win32
targetarch: amd64
- os: windows-2019 # always use the oldest possible for 32-bit because of older compilers, and better support of certain legacy OSes
- os: windows-latest
targetos: win32
targetarch: i386
env:
SDL_VERSION: 2.28.5
SDL_VERSION: 2.0.14
GH_CPU_ARCH: ${{ matrix.targetarch }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ANDROID_SDK_TOOLS_VER: 4333796
ANDROID_NDK_VER: r10e
UPLOADTOOL_ISPRERELEASE: true
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v2
with:
submodules: recursive
- name: Checkout xash-extras
uses: actions/checkout@v2
with:
repository: FWGS/xash-extras
path: xash-extras
- name: Install dependencies
run: bash scripts/gha/deps_${{ matrix.targetos }}.sh
- name: Build engine
run: bash scripts/gha/build_${{ matrix.targetos }}.sh
- name: Upload engine (artifacts)
uses: actions/upload-artifact@v3
with:
name: artifact-${{ matrix.targetos }}-${{ matrix.targetarch }}
path: artifacts/*
flatpak:
name: "Flatpak"
runs-on: ubuntu-latest
strategy:
matrix:
include:
- app: su.xash.Engine.Compat.i386
container:
image: bilelmoussaoui/flatpak-github-actions:freedesktop-22.08
options: --privileged
steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive
- name: Build flatpak (Compat.i386)
uses: FWGS/flatpak-github-actions/flatpak-builder@v6.1
with:
bundle: ${{ matrix.app }}.flatpak
manifest-path: scripts/flatpak/${{ matrix.app }}.yml
- name: Upload engine (artifacts)
uses: actions/upload-artifact@v3
with:
name: artifact-${{ matrix.targetos }}-${{ matrix.targetarch }}
path: artifacts/*
release:
name: "Upload releases"
runs-on: ubuntu-latest
needs: [build, flatpak]
if: ${{ github.event_name == 'push' }}
steps:
- name: Remove old release
uses: FWGS/delete-tag-and-release@v0.2.1-dev
with:
tag_name: ${{ github.ref_name == 'master' && 'continuous' || format('continuous-{0}', github.ref_name) }}
delete_release: true
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Fetch artifacts
uses: actions/download-artifact@v3.0.1
with:
path: artifacts/
- name: Repackage binaries and allow GitHub to process removed release for few seconds
run: |
cd artifacts/
for i in artifact-* su.xash.Engine.*; do
mv "$i"/* .
rm -rf "$i"
done
ls -R .
cd ../
sleep 20s
- name: Upload new release
uses: FWGS/action-gh-release@v0.1.15
with:
name: Xash3D FWGS Continuous ${{ github.ref_name }} Build
tag_name: ${{ github.ref_name == 'master' && 'continuous' || format('continuous-{0}', github.ref_name) }}
prerelease: true
token: ${{ secrets.GITHUB_TOKEN }}
files: artifacts/*
draft: false
- name: Upload engine (android)
if: matrix.targetos == 'android'
run: bash scripts/continious_upload.sh xashdroid-${{ matrix.targetarch }}.apk
- name: Upload engine (motomagx)
if: matrix.targetos == 'motomagx'
run: bash scripts/continious_upload.sh xash3d-fwgs-magx.7z
- name: Upload engine (linux)
if: matrix.targetos == 'linux'
run: bash scripts/continious_upload.sh xash3d-fwgs-${{ matrix.targetarch }}.AppImage xashds-linux-${{ matrix.targetarch }}
- name: Upload engine (windows)
if: matrix.targetos == 'win32'
run: bash scripts/continious_upload.sh xash3d-fwgs-win32-${{ matrix.targetarch }}.7z

7
.gitignore vendored
View File

@@ -60,7 +60,6 @@ Makefile.dep
ALL_BUILD.*
INSTALL.*
ZERO_CHECK.*
CMakeLists.txt
# Visual Studio
*.obj
@@ -332,8 +331,4 @@ __pycache__
.vscode/*
*.code-workspace
.history/*
.cache/*
enc_temp_folder/
# KDevelop4
*.kdev4
.cache/*

20
.gitmodules vendored
View File

@@ -1,21 +1,15 @@
[submodule "mainui"]
path = 3rdparty/mainui
path = mainui
url = https://github.com/FWGS/mainui_cpp
[submodule "ref_gl/nanogl"]
path = 3rdparty/nanogl
path = ref_gl/nanogl
url = https://github.com/FWGS/nanogl
[submodule "ref_gl/gl-wes-v2"]
path = 3rdparty/gl-wes-v2
path = ref_gl/gl-wes-v2
url = https://github.com/FWGS/gl-wes-v2
[submodule "vgui-dev"]
path = vgui-dev
url = https://github.com/FWGS/vgui-dev
[submodule "ref_gl/gl4es"]
path = 3rdparty/gl4es/gl4es
path = ref_gl/gl4es
url = https://github.com/ptitSeb/gl4es
[submodule "vgui_support"]
path = 3rdparty/vgui_support
url = https://github.com/FWGS/vgui_support
[submodule "opus"]
path = 3rdparty/opus/opus
url = https://github.com/xiph/opus
[submodule "3rdparty/xash-extras"]
path = 3rdparty/extras/xash-extras
url = https://github.com/FWGS/xash-extras

35
.travis.yml Normal file
View File

@@ -0,0 +1,35 @@
language: c
compiler: gcc
sudo: false
env:
global:
- SDL_VERSION=2.0.14
git:
depth: 50
submodules: true
os: linux
arch:
- aarch64
- ppc64le
- s390x
addons:
apt:
update: true
packages:
- libx11-dev
- libxext-dev
- x11-utils
- libgl1-mesa-dev
- libasound-dev
- libstdc++6
- libfuse2
- unzip
before_script:
- sh scripts/travis/deps_common.sh
- sh scripts/travis/deps_${TRAVIS_OS_NAME}.sh
script:
- sh scripts/travis/build_${TRAVIS_OS_NAME}.sh
after_script:
- ccache --show-stats
- sh scripts/continious_upload.sh xash3d-fwgs-${ARCH}.tar.xz xashds-linux-${ARCH}

View File

@@ -1,29 +0,0 @@
#! /usr/bin/env python
# encoding: utf-8
import os
def options(opt):
pass
def configure(conf):
if not conf.path.find_dir('xash-extras'):
conf.fatal('Can\'t find xash-extras submodule.')
return
conf.load('zip')
def build(bld):
srcdir = bld.path.find_dir('xash-extras')
if bld.env.DEST_OS in ['android']:
install_path = bld.env.PREFIX
else:
install_path = os.path.join(bld.env.SHAREDIR, bld.env.GAMEDIR)
bld(features='zip',
name = 'extras.pk3',
files = srcdir.ant_glob('**/*'),
relative_to = srcdir,
compresslevel = 0,
install_path = install_path)

1
3rdparty/gl-wes-v2 vendored

Submodule 3rdparty/gl-wes-v2 deleted from 2d9b5afe10

Submodule 3rdparty/gl4es/gl4es deleted from 5226f5f937

View File

@@ -1,24 +0,0 @@
#! /usr/bin/env python
# encoding: utf-8
import os
def options(opt):
pass
def configure(conf):
if not conf.path.find_dir('gl4es') or not conf.path.find_dir('gl4es/src'):
conf.fatal('Can\'t find gl4es submodule. Run `git submodule update --init --recursive`.')
return
def build(bld):
gl4es_srcdir = bld.path.find_node('gl4es/src')
bld.stlib(source = gl4es_srcdir.ant_glob(['gl/*.c', 'gl/*/*.c', 'glx/hardext.c']),
target = 'gl4es',
features = 'c',
includes = ['gl4es/src', 'gl4es/src/gl', 'gl4es/src/glx', 'gl4es/include'],
defines = ['NOX11', 'NO_GBM', 'NO_INIT_CONSTRUCTOR', 'DEFAULT_ES=2', 'NOEGL', 'NO_LOADER', 'STATICLIB'],
cflags = ['-w', '-fvisibility=hidden', '-std=gnu99'],
subsystem = bld.env.MSVC_SUBSYSTEM,
export_includes = '.')

1
3rdparty/mainui vendored

Submodule 3rdparty/mainui deleted from de4402e86b

1
3rdparty/nanogl vendored

Submodule 3rdparty/nanogl deleted from 76393a8fde

1
3rdparty/opus/opus vendored

Submodule 3rdparty/opus/opus deleted from 8cf872a186

40
3rdparty/opus/wscript vendored
View File

@@ -1,40 +0,0 @@
#! /usr/bin/env python
# encoding: utf-8
import os
def options(opt):
pass
def configure(conf):
if not conf.path.find_dir('opus') or not conf.path.find_dir('opus/src'):
conf.fatal('Can\'t find opus submodule. Run `git submodule update --init --recursive`.')
return
# TODO: ARM/x86 intrinsics detection
# TODO: maybe call autotools/cmake/meson instead?
def build(bld):
sources = bld.path.ant_glob([
'opus/src/*.c',
'opus/celt/*.c',
'opus/silk/*.c',
'opus/silk/float/*.c'
], excl = [
'opus/src/repacketizer_demo.c',
'opus/src/opus_demo.c',
'opus/src/opus_compare.c',
'opus/celt/opus_custom_demo.c'
])
includes = ['opus/include/', 'opus/celt/', 'opus/silk/', 'opus/silk/float/']
defines = ['USE_ALLOCA', 'OPUS_BUILD', 'FLOAT_APPROX', 'PACKAGE_VERSION="1.3.1"', 'CUSTOM_MODES']
bld.stlib(
source = sources,
target = 'opus',
features = 'c',
includes = includes,
defines = defines,
subsystem = bld.env.MSVC_SUBSYSTEM,
export_includes = ['opus/include/']
)

Submodule 3rdparty/vgui_support deleted from a2a7b9073f

View File

@@ -1,17 +0,0 @@
# Bug-compatibility in Xash3D FWGS
Xash3D FWGS has special mode for games that rely on original engine bugs.
In this mode, we emulate the behaviour of selected functions that may help running mods relying on engine bugs, but enabling them by default may break majority of other games.
At this time, we only have implemented GoldSrc bug-compatibility. It can be enabled with `-bugcomp` command line switch.
## GoldSrc bug-compatibility
### Emulated bugs
* `pfnPEntityOfEntIndex` in GoldSrc returns NULL for last player due to incorrect player index comparison
### Games and mods that require this
* Counter-Strike: Condition Zero - Deleted Scenes

View File

@@ -1,9 +0,0 @@
# Cross-compiling for Windows with Wine
This can be useful to test engine in Wine without using virtual machines or dual-booting to Windows.
0. Clone and install https://github.com/mstorsjo/msvc-wine (you can skip CMake part)
1. Set environment variable MSVC_WINE_PATH to the path to installed MSVC toolchain
2. Pre-load wine: `wineserver -k; wineserver -p; wine64 wineboot`
3. Run `./waf configure -T <build-type> --enable-wine-msvc --sdl2=../SDL2_VC`. Configuration step will take more time than usual.
4. .. other typical steps to build from console ...

View File

@@ -1,10 +0,0 @@
# Debugging your mod using minidump files (Windows only)
Minidump files is awesome instrument for debugging your mod after it's being released, or for catch specific crashes which are presented only in one specific configuration, but doesn't happens in other configurations or even on developer machine. It contains a lot of information useful for debugging, and therefore it size is not so small: around hundreds or even thousands of megabytes. But this is not a problem, since minidump files compresses very effectively using common algorithms.
There are short algorithm, explaining how to use this debugging instrument:
1. User starts your mod with `-minidumps` startup parameter
2. Finally, crash happened on user's machine, and minidump file being written. This file has `.mdmp` extension and located in same folder, where mod folder located
3. User packs this minidump file to .zip/.7z archive, and somehow sends it to developer
4. Developer just opens minidump file in Visual Studio, then a virtual debugging session is opened and now reasons of crash is pretty easy to detect: you can see call stack, local function variables and global variables, information about exception and a lot of other information
You can find more information about minidumps in this [awesome article](https://learn.microsoft.com/en-us/windows/win32/dxtecharts/crash-dump-analysis?source=recommendations#writing-a-minidump).

View File

@@ -1,24 +0,0 @@
# Developers donation page
On this page you can find links where you can support each developer individually, who has provided public sponsorship information.
### [a1batross](https://github.com/a1batross)
* Initial Xash3D SDL2/Linux port author, Xash3D FWGS engine maintainer, creator of non-commercial Flying With Gauss organization.
* Boosty page: https://boosty.to/a1ba
### [nekonomicon](https://github.com/nekonomicon)
* [hlsdk-portable](https://github.com/FWGS/hlsdk-portable), [mdldec](../utils/mdldec), [opensource-mods.md](opensource-mods.md) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=nekonomicon) (*BSD/clang port, PNG support, etc).
* Boosty page: https://boosty.to/nekonomicon
### [Velaron](https://github.com/Velaron)
* [cs16-client](https://github.com/Velaron/cs16-client) & [tf15-client](https://github.com/Velaron/tf15-client) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=Velaron) (Android port, voice chat, etc).
* BuyMeACoffee page: https://www.buymeacoffee.com/velaron
### [SNMetamorph](https://github.com/SNMetamorph)
* [PrimeXT](https://github.com/SNMetamorph/PrimeXT) & [GoldSrc Monitor](https://github.com/SNMetamorph/goldsrc-monitor) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=SNMetamorph) (Windows port, voice chat, etc).
* BTC: `16GAzK3qei5AwBW7sggXp3yNcFHBtdpxXj`
* ETH (ERC20): `0xb580eeca9756e3881f9d6d026e28db28eb72a383`
* USDT (ERC20): `0xb580eeca9756e3881f9d6d026e28db28eb72a383`
* USDC (ERC20): `0xb580eeca9756e3881f9d6d026e28db28eb72a383`

View File

@@ -1,150 +0,0 @@
# There are few new commands availiable in xash3d fork:
## Commands:
### ent_create
Create entity with specified classname and key/values
`ent_create <classname> <key> <value> <key> <value> ...`
for example:
`ent_create monster_zombie targetname zomb1`
after creating entity, ent_last_xxx cvars are set to new entity and ent_last_cb called, look at ent_getvars description
### ent_fire
Make some actions on entity
`ent_fire <pattern> <command> <args>`
Availiavle commands:
* Set fields (Only set entity field, does not call any functions):
* health
* gravity
* movetype
* solid
* rendermode
* rendercolor (vector)
* renderfx
* renderamt
* hullmin (vector)
* hullmax (vector)
* Actions
* rename: set entity targetname
* settarget: set entity target (only targetnames)
* setmodel: set entity model (does not update)
* set: set key/value by server library
* See game FGD to get list.
* command takes two arguments
* touch: touch entity by current player.
* use: use entity by current player.
* movehere: place entity in player fov.
* drop2floor: place entity to nearest floor surface
* moveup: move entity to 25 units up
* moveup (value): move by y axis relatively to specified value
* Flags (Set/clear specified flag bit, arg is bit number):
* setflag
* clearflag
* setspawnflag
* clearspawnflag
### ent_info
Print information about entity by identificator
`ent_info <identificator>`
### ent_getvars
Set client cvars containing entity information (useful for [[Scripting]]) and call ent_last_cb
`ent_getvars <identificator>`
These cvars are set:
```
ent_last_name
ent_last_num
ent_last_inst
ent_last_origin
ent_last_class
```
### ent_list
Print short information about antities, filtered by pattern
`ent_list <pattern>`
## Syntax description
### \<identificator\>
* !cross: entity under aim
* Instance code: !\<number\>_\<seria\l>
* set by ent_getvars command
* Entity index
* targetname pattern
### \<pattern\>
Pattern is like identificator, but may filter many entities by classname
### (vector)
used by ent_fire command. vector means three float values, entered without quotes
### key/value
All entities parameters may be set by specifiing key and value strings.
Originally, this mechanizm is used in map/bsp format, but it can be used in enttools too.
Keys and values are passed to server library and processed by entity keyvalue function, setting edict and entity owns parameters.
If value contains spaces, it must be put in quotes:
`ent_fire !cross set origin "0 0 0"`
## Using with scripting
ent_create and ent_getvars commands are setting cvars on client
It can be used with ent_last_cb alias that is executed after setting cvars.
Simple example:
```
ent_create weapon_c4
alias ent_last_cb "ent_fire \$ent_last_inst use"
```
Use weapon_c4 after creating it.
Note that you cannot use many dfferent callbacks at the same time.
You can set entity name by by pattern and create special script, contatning all callbacks.
Example:
example.cfg
```
alias ent_last_cb exec entity_cb.cfg
ent create \<class\> targetname my_ent1_$name
ent_create \<class\> targetname my_ent2_$name
```
entity_cb.cfg
```
if $ent_last_name == my_ent1_$name
:(ent1 actions)
if $ent_last_name == my_ent2_$name
:(ent2 actions)
```
Note that scripting cannot be blocking. You cannot wait for server answer and continue. But you can use small scripts, connected with ent_last_cb command. The best usage is user interaction. You can add touch buttons to screen or call user command menu actions by callbacks.
## Server side
To enable entity tools on server, set sv_enttools_enable to 1
To change maximum number of entities, touched by ent_fire, change sv_enttools_maxfire to required number.
To enable actions on players, set sv_enttools_players to 1.
To enable entity tools for player by nickname, set sv_enttools_godplayer to nickname. Useful to temporary enable from rcon.
To prevent crash on some actions, set host_mapdesign_fatal to 0

View File

@@ -1,8 +0,0 @@
# Expanded structures that used by engine and mods
To make porting and developing mods on 64-bit platforms less painful, we decided to expand size of several structures.
This information important in case you are using codebase like XashXT, Paranoia 2: Savior and want to compile your mod for platform with 64-bit pointer size: you should replace old definitions with new ones, otherwise your mod will not work with Xash3D FWGS (typically, it's just crashing when starting map).
| Structure name | Locates in file | Original size on 64-bit | Current size on 64-bit |
|----------------|-----------------|-------------------------|------------------------|
|`mfaceinfo_t` | `common/com_model.h` | 176 bytes | 304 bytes |
|`decal_s` | `common/com_model.h` | 72 bytes | 88 bytes |
|`mextrasurf_t` | `common/com_model.h` | 376 bytes | 504 bytes |

View File

@@ -31,14 +31,11 @@ Issue #0. Inconsistency between ABI and Q_buildarch.\
Resolution: Change Q_buildarch return value to use Debian-styled architectures list: https://www.debian.org/ports/, which includes a special naming for big/little-endian and hard/soft-float ARM.
Issue #1: Build-system integration.\
Resolution: implemented as [LibraryNaming.cmake](https://github.com/FWGS/hlsdk-portable/blob/master/cmake/LibraryNaming.cmake) and [library_naming.py](https://github.com/FWGS/hlsdk-portable/blob/master/scripts/waifulib/library_naming.py) extensions, see
Resolution: implemented as [LibraryNaming.cmake](https://github.com/FWGS/hlsdk-xash3d/blob/master/cmake/LibraryNaming.cmake) and [library_naming.py](https://github.com/FWGS/hlsdk-xash3d/blob/master/scripts/waifulib/library_naming.py) extensions, see
Issue #2(related to #0): Which ARM flavours we actually need to handle?\
Resolution: Little-endian only, as there is no known big-endian ARM platforms in the wild.
Architecture is coded this way:
* ```armvxy```, where `x` is ARM instruction set level and `y` is hard-float ABI presence: `hf` where hard float ABI used, otherwise `l`.
Issue #3: Some mods (like The Specialists, Tyrian, ...) already apply suffixes _i386, _i686 to the gamedll path:\
Resolution: On x86 on **Win/Lin/Mac**, don't change anything. Otherwise, strip the _i?86 part and follow the usual scheme.
See discussion: https://github.com/FWGS/xash3d-fwgs/issues/39

View File

@@ -1,22 +0,0 @@
## Looping MP3 extension
It is now possible to loop MP3 file in Xash3D FWGS by adding a custom text tag with `LOOP_START` or `LOOPSTART` in description and time point (in raw samples) in value.
### Example with foobar2000
1. Open Foobar2000
2. Add your .mp3 file to playlist
3. Right click to newly added file and select Properties
4. In Metadata tab, at the bottom of the table, select "+add new"
5. In newly added line replace `<60>input field name<6D>` with `LOOP_START` (without any symbols).
6. Press Tab and enter loop time point in raw samples. For example, `0` will replay sound file from beginning to end indefinitely.
### Possible alternatives
1. Classic WAV files looping. HQ WAV files can take too much disk space, and recommended software supporting cue points is paid, outdated and can't run on modern systems. (Although there is alternative that's proven to work with idTech-based engines called LoopAuditioneer.)
2. Vorbis looping through comment. Engine doesn't support Vorbis but this extension was highly inspired by this hack.
### Known bugs and limitations
1. At this time using MP3 as SFX requires complete decoding. This can cause noticeable stutters, so keep MP3 file length in mind.
2. We deliberately only support modern ID3v2.3 and ID3v2.4 tags. Using ID3v1 is not possible.

View File

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

View File

@@ -1,40 +1,7 @@
# Self-made port
## Compatibility with RISC architectures
### Unaligned access
Unaligned access on **i386** causes only performance penalty, but on **RISC** it can cause unstable work.
For HLSDK at least you need such patches in util.cpp:
- https://github.com/FWGS/halflife/commit/7bfefe86e35d67867ae7af830ac1fc38f2908360
- https://github.com/FWGS/hlsdk-portable/commit/617d75545f2ecb9b2d46cc30728dc37c9eb6d35e
### Signed chars
`char` type defined as **signed** for **x86** and as **unsigned** for **arm**.
And sometimes such difference can break logic.
As a solution you can use `signed char` type in code directly or use `-fsigned-char` option for gcc/clang compilers.
For HLSDK at least you need such [fix](https://github.com/FWGS/hlsdk-portable/commit/1ca34fcb4381682bd517612b530db22a1354a795) in nodes.cpp/.h.
## Compatibility with 64bit architectures
You need list of patches for Studio Model Render, MAKE_STRING macro and nodes:
- https://github.com/FWGS/hlsdk-portable/commit/d287ed446332e615ab5fb25ca81b99fa14d18a73
- https://github.com/FWGS/hlsdk-portable/commit/3bce17e3a04f8af10a927a07ceb8ab0f09152ec4
- https://github.com/FWGS/hlsdk-portable/commit/9ebfc981773ec4c7a89ffe52d9c249e1fbef9634
- https://github.com/FWGS/hlsdk-portable/commit/00833188dab87ef5746286479ba5aeb9d83b4a0c
- https://github.com/FWGS/hlsdk-portable/commit/4661b5c1a5245b27a5532745c11e44b5540e4172
- https://github.com/FWGS/hlsdk-portable/commit/2b61380146b1d58a8c465f0e312c061b12bda115
- https://github.com/FWGS/hlsdk-portable/commit/8ef6cb2427ee16a763103bd3f315f38e2f01cfe2
## Mobility API
Xash3D FWGS has special extended interface in `mobility_int.h` which adds some new features like vibration on mobile platforms.
## Porting server-side code
# Server porting
Original valve's server code was compatible with linux and gcc 2.x.
Newer gcc versions have restriction which breaks build.
Now, to make it building with gcc 4.x+ or clang, you need to do following:
Now, to make it building with gcc 4.x, you need do following:
* Go to cbase.h and redefine macros as following
```
#define SetThink( a ) m_pfnThink = static_cast <void (CBaseEntity::*)(void)> (&a)
@@ -51,60 +18,58 @@ Now, to make it building with gcc 4.x+ or clang, you need to do following:
* Replace all SetThink(NULL), SetTouch(NULL), setUse(NULL) and SetBlocked(NULL) by ResetThink(), ResetTouch(), ResetUse() and ResetBlocked()
* Sometimes you may need to add #include <ctype.h> if functions tolower or isspace are missing
## Porting client-side code
# Client porting
## VGUI library
Valve's client uses vgui library which is available only on x86 systems and has big amount of mistakes in headers. The best and simplest way of porting is removing VGUI dependency at all.
Most singleplayer mods don't really use VGUI at all. It is used in multiplayer only to show score table and MOTD window
## Porting
### First strategy: full port
#### Basic port (Stage 1)
* First, remove all files and headers which use vgui (contains "vgui" in file name).
* After that, try to build it and remove vgui includes.
* Remove all gViewPort usings.
* Remove all CVoiceManager usings (xash3d does not support voice)
* Redefine all DLLEXPORT defines as empty field (Place it under _WIN32 macro if you want to keep windows compatibility).
* Remove hud_servers.cpp and Servers_Init/Servers_Shutdown from hud.cpp.
* Remove hud_servers.cpp and Servers_Init/Servers_Shutdown from hud.cpp
* Fix CAPS filenames in includes (like STDIO.H, replace by stdio.h).
* Replace broken macros as DECLARE_MESSAGE, DECLARE_COMMAND by fixed examples from our hlsdk-portable port (cl_util.h).
* Add ctype.h where is needed (tolower, isspace functions).
* Add string.h where is needed (memcpy, strcpy, etc).
* Use in_defs.h from hlsdk-portable.
* Add input_xash3d.cpp from hlsdk-portable project to fix input.
* Replace broken macros as DECLARE_MESSAGE, DECLARE_COMMAND by fixed examples from our hlsdk-xash3d port (cl_util.h)
* Add ctype.h where it is need (tolower, isspace functions)
* Add string.h where it is need (memcpy, strcpy, etc)
* Use in_defs.h from hlsdk_client
* Add scoreboard_stub.cpp and input_stub.cpp from hlsdk-xash3d to fix linking.
Now your client should be able to build and work correctly. Add input_xash3d.cpp from hlsdk-xash3d project to fix input.
Now your client should be able to build and work correctly.
#### Multiplayer fix (Stage 2)
Look at hlsdk-xash3d project.
# Porting mod to hlsdk-portable
Look at changes which was made.
Main changes are:
* Add MOTD.cpp, scoreboard.cpp and input_xash3d.cpp
* Add missing functions to hud_redraw.cpp, hud.cpp and tri.cpp, fix class defination in hud.h
* Remove duplicate functions from hud.cpp and HOOK_MESSAGE's for it
* Remove +showscores/-showscores hooks from input.h
* Fix cl_util.h
If there are not too much changes (for example, only some weapons was added), add these changes in hlsdk-portable.
### Second way: move mod to hlsdk-xash3d
Look at changes you made in client.
You can use diff with original HLSDK and apply it as patch to hlsdk-portable.
If there are not much changes (for example, only some weapons was add), add these changes in hlsdk-xash3d.
You may use diff with original HLSDK you used and apply it as patch to hlsdk-xash3d.
```
NOTE: Many an old mods was made on HLSDK 2.0-2.1 and some rare mods on HLSDK 1.0.
So you need to have different versions of HLSDK to make diffs.
Plus different Spirit of Half-Life versions if mod was made on it.
Also, weapons in old HLSDK versions does not use client weapon prediction system and you may be need to port standart half-life weapons to server side.
```
Files must have same line endings (use dos2unix on all files).
We recommend to enable ignoring space changes in diff.
I recommend to enable ignoring space changes in diff.
### Writing Makefiles
Move all new files to separate directories.
Use Makefile from hlsdk-xash3d as Makefile example.
# Possible replacements for non-portable external dependencies
1. If mod uses **fmod.dll** or **base.dll** to play mp3/ogg on client-side or to precache sounds on server-side, you can replace it with:
- [pfnPrimeMusicStream](https://github.com/FWGS/hlsdk-portable/blob/master/engine/cdll_int.h#L293=) engine callback;
- [miniaudio](https://github.com/mackron/miniaudio);
- [phonon](https://community.kde.org/Phonon).
Get .c and .cpp file lists from Visual Studio project and fill SRCS and SRCS_C variables to Makefile.
2. If mod uses **OpenGL**, porting code to Xash3D render interface is recommended.
3. If mod uses **cg.dll**, you can try to port code to [NVFX](https://github.com/tlorach/nvFX).
4. If mod uses detours, comment code or try to find replacement somehow by yourself.
# Additional recommendations
1. If mod uses STL, you can replace it with [MiniUTL](https://github.com/FWGS/MiniUTL).
2. Avoid to use dynamic casts to make small size binaries.
3. Avoid to use exceptions to make small size binaries.
# Writing build scripts
Use wscript/CMakeLists.txt files from hlsdk-portable as build scripts example.
Get .c and .cpp file lists from Visual Studio project.
Add missing include dirs.
Remove all files containing vgui in name from list, add missing include dirs.
Do same for Android.mk if you are building for android.

View File

@@ -7,5 +7,6 @@
|Counter Strike: Condition Zero |The latest steam release |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|Counter Strike: Condition Zero - Deleted scenes |The latest steam release |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|Day of Defeat |The latest steam release |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|Sven-Coop |5.0+ |Uses custom GoldSrc engine |
|Sven-Coop |5.0+ |Uses filesystem_stdio library which xash3d does not support |filesystem_stdio replacement already was made: https://github.com/FWGS/filesystem_stdio_xash
|XDM |3.0.4.0 | |

View File

@@ -17,9 +17,7 @@ Mirrored on github - https://github.com/JoelTroch/am_src_rebirth
Mirrored on github - https://github.com/nekonomicon/BattleGrounds
## Bubblemod
Download page on official site(WM snapshot) - [http://www.bubblemod.org/dl_default.php](https://web.archive.org/web/20130717133158/http://www.bubblemod.org/dl_default.php)
Mirrored on github - https://github.com/HLSources/BubbleMod
Download page on official site - http://www.bubblemod.org/dl_default.php
## Chicken Fortress
Official github repository - https://github.com/CKFDevPowered/CKF3Alpha
@@ -27,11 +25,6 @@ Official github repository - https://github.com/CKFDevPowered/CKF3Alpha
## Cold Ice
Version 1.9 is available on ModDB - https://www.moddb.com/mods/cold-ice/downloads/cold-ice-sdk
Version 1.9 mirrored on github - https://github.com/solidi/hl-mods/tree/master/ci
## Cold Ice Ressurection
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/cir
## Cthulhu
Uploaded to github by Oleg Cherkasky - https://github.com/gunrunners-paradise/Cthulhu-HLmod-SDK
@@ -45,36 +38,25 @@ Official github repository - https://github.com/adslbarxatov/xash3d-for-ESHQ
Available on GamerLab - http://gamer-lab.com/eng/code_mods_goldsrc/Half-Life_2D_(Flat-Life)
## Gang Wars
Mirrored on github - https://github.com/nekonomicon/gw1.45src
Mirrored on github - https://github.com/hammermaps/gw1.45src
## Go-mod
Versions 2.0 and 3.0, available in mod archives on ModDB - https://www.moddb.com/mods/go-mod/downloads
Version 3.0, mirrored on github - https://github.com/nekonomicon/Go-mod30
## GT mod
Available on GamerLab - http://gamer-lab.com/eng/code_mods_goldsrc/GT_mod_(Polnie_ishodniki)
## Half-Life: Advanced Deathmatch
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/hla
## Half-Life: Decay
Mirrored on github(PC Port) - https://github.com/hoaxer/Half-Life-Decay
## Half-Life: Echoes
Available on ModDB - https://www.moddb.com/mods/half-life-echoes
Download link on dropbox - https://www.dropbox.com/s/s6j8gtegn10wgvj/dlls.zip?dl=1
## Half-Life: Expanded Arsenal
Available on ModDB - https://www.moddb.com/mods/half-life-expanded-arsenal
## Half-Life: Gravgun mod
Branch **gravgun** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/gravgun
Branch **gravgun** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/gravgun
## Half-Life: Invasion
Official github repository - https://github.com/jlecorre/hlinvasion
## Half-Life: Pong
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/pong
official github repository - https://github.com/jlecorre/hlinvasion
## Half-Life: Quest Mode
Available on cs-mapping.com.ua - https://old.cs-mapping.com.ua/forum/showthread.php?t=38030
@@ -85,9 +67,6 @@ Official gitlab repository - https://gitlab.com/Sockman/hltopdown
## Half-Life: Update
Official github repository - https://github.com/Fograin/hl-subsmod-ex
## Half-Life: Rally
Official gitlab repository - https://gitlab.com/hlrally/src
## Half-Life: Weapon Edition
Available on ModDB - https://www.moddb.com/mods/half-life-weapon-edition/downloads/half-life-weapon-edition-1508-alpha-open-src
@@ -113,7 +92,7 @@ Official github repository - https://github.com/desukuran/half-screwed
Version 1.3 on ModDB - https://www.moddb.com/mods/headcrab-frenzy/downloads/headcrab-frenzy-13-beta-source-code
## Heart of Evil
Mirrored on github - https://github.com/nekonomicon/HeartOfEvil
Available on ModDB - https://www.moddb.com/mods/heart-of-evil/downloads/heart-of-evil-dlls-source-code
## Ingram Chillin' Mod
Official SourceForge repository - https://sourceforge.net/projects/icm-hl/
@@ -130,11 +109,22 @@ Official github repository - https://github.com/unknownworlds/NS
## Overturn
Available in mod archive on ModDB - https://www.moddb.com/mods/overturn
## Oz Deathmatch
Mirrored on github - https://github.com/nekonomicon/OZDM
## Spirit of Half-Life
[Logic&Trick's](https://github.com/LogicAndTrick) mirror - https://files.logic-and-trick.com/#/Half-Life/Mods/Spirit%20of%20Half-Life
## Threewave CTF
*Unfinished mod by Valve Software*
Available in Valve's Half-Life repository with Deathmatch Classic sources - https://github.com/ValveSoftware/halflife/tree/master/dmc
## Trinity Render
Available on ModDB: https://www.moddb.com/mods/half-life-episode-two/downloads/trinity-rendering-engine-v308f
## Tyrian: Ground Assault
Available on ModDB: https://www.moddb.com/mods/tyriangroundassault/downloads/tyrianga-v1-0-src
## Paranoia
Available on ModDB - https://www.moddb.com/mods/paranoia/downloads/paranoia-toolkit
Available on ModDB: https://www.moddb.com/mods/paranoia/downloads/paranoia-toolkit
## Paranoia 2: The Savior
Prealpha, mirrored on github - https://github.com/a1batross/Paranoia2_ancient
@@ -149,37 +139,12 @@ Was found on HLFX - http://hlfx.ru/forum/showthread.php?s=2c892dfc52f72be52a89c3
## Ricochet
Available in Valve's Half-Life repository - https://github.com/ValveSoftware/halflife/tree/master/ricochet
## Spirit of Half-Life
[Logic&Trick's](https://github.com/LogicAndTrick) mirror - https://files.logic-and-trick.com/#/Half-Life/Mods/Spirit%20of%20Half-Life
## The Wastes
Version 1.5: mirrored on code.idtech.space - https://code.idtech.space/vera/halflife-thewastes-sdk
## Threewave CTF
*Unfinished mod by Valve Software*
Available in Valve's Half-Life repository with Deathmatch Classic sources - https://github.com/ValveSoftware/halflife/tree/master/dmc
## Trinity Render
Available on ModDB - https://www.moddb.com/mods/half-life-episode-two/downloads/trinity-rendering-engine-v308f
## Tyrian: Ground Assault
Available on ModDB - https://www.moddb.com/mods/tyriangroundassault/downloads/tyrianga-v1-0-src
## Wasteland
Mirrored on code.idtech.space - https://code.idtech.space/vera/halflife-wasteland-sdk
## Wizard Wars
Download page on official site - http://www.thothie.com/ww/
## XashXT
Mirrored on github - https://github.com/a1batross/XashXT_original
## Xen-Warrior
*Source code is a part of Spirit of Half-Life 1.0-1.2 under XENWARRIOR macro*
[Logic&Trick's](https://github.com/LogicAndTrick) mirror - https://files.logic-and-trick.com/#/Half-Life/Mods/Spirit%20of%20Half-Life
## Zombie-X
Available in mod archive on ModDB - https://www.moddb.com/mods/zombie-x-10-final/downloads/zombie-x-10-dle-beta6-last-version
@@ -190,45 +155,45 @@ Mirrored on github - https://github.com/ZXCmod/ZXCmod
# Reimplementation
## Absolute Redemption
Branch **redempt** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/redempt
Branch **redempt** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/redempt
## Adrenaline Gamer
OpenAG by YaLTeR - https://github.com/YaLTeR/OpenAG
## Afraid of Monsters
malortie's recreation - https://github.com/malortie/hl-aom
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-aom
Branch **aom** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/aom
Branch **aom** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/aom
## Afraid of Monsters: Director's cut
Reverse-engineered code: branch **aomdc** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/aomdc
Reverse-engineered code, branch **aomdc** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/aomdc
## Azure Sheep
malortie's recreation - https://github.com/malortie/hl-asheep
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-asheep
Reverse-engineered code: branch **asheep** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/asheep
Reverse-engineered code, branch **asheep** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/asheep
## Big Lolly
malortie's recreation - https://github.com/malortie/hl-biglolly
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-biglolly
Branch **biglolly** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/biglolly
Branch **biglolly** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/biglolly
## Black Ops
malortie's recreation - https://github.com/malortie/hl-blackops
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-blackops
Branch **blackops** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/blackops
Branch **blackops** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/blackops
## Bloody Pizza: Vendetta
Branch **caseclosed** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/caseclosed
Branch **caseclosed** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/caseclosed
## Case Closed
Branch **caseclosed** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/caseclosed
Branch **caseclosed** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/caseclosed
## Cleaner's Adventures
Branch **CAd** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/CAd
Branch **CAd** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/CAd
## Counter Strike
Reverse-engineered code of client part by a1batross - https://github.com/Velaron/cs16-client
Reverse-engineered code of client part by a1batross - https://github.com/FWGS/cs16-client/tree/v1.32
Reverse-engineered code of server part by nagist - https://github.com/nagist/cs16nd
@@ -240,141 +205,117 @@ CSO-like Xash3D-based mod, CSMoE - https://github.com/MoeMod/CSMoE
## Crack-Life: Campaign Mode
Recreation by lostgamer aka nillerusr - https://github.com/LostGamerHL/crack_life
Reverse-engineered code: branch **clcampaign** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/clcampaign
## Escape from the Darkness
malortie's recreation - https://github.com/malortie/hl-eftd
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-eftd
Reverse-engineered code: branch **eftd** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/eftd
## Half-Life: Black Guard
*This mod uses dlls from Cleaner's Adventures*
Branch **CAd** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/CAd
Reverse-engineered code, branch **eftd** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/eftd
## Half-Life: Blue Shift
Unkle Mike's recreation - https://hlfx.ru/forum/showthread.php?s=&threadid=5253
Reverse-engineered code: branch **bshift** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/bshift
Reverse-engineered code, branch **bshift** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/bshift
## Half-Life: Induction
Branch **induction** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/induction
Branch **induction** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/induction
## Half-Life: Opposing Force
Recreation by lostgamer aka nillerusr - https://github.com/LostGamerHL/hlsdk-xash3d
Reverse-engineered code: clean branch **opfor** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/opfor
Reverse-engineered code, clean branch **opfor** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/opfor
Spirit of Half Life: Opposing-Force Edition - https://github.com/Hammermaps-DEV/SOHL-V1.9-Opposing-Force-Edition
## Half-Life: Rebellion
Reverse-engineered code: branch **rebellion** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/rebellion
## Half-Life: Urbicide
Branch **hl_urbicide** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/hl_urbicide
Reverse-engineered code, branch **rebellion** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/rebellion
## Half-Life: Visitors
malortie's recreation - https://github.com/malortie/hl-visitors
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-visitors
Reverse-engineered code: branch **visitors** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/visitors
Reverse-engineered code, branch **visitors** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/visitors
## Half-Secret
Branch **half-secret** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/half-secret
Branch **half-secret** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/half-secret
## Night at the Office
malortie's recreation - https://github.com/malortie/hl-nato
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-noffice
Branch **noffice** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/noffice
Branch **noffice** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/noffice
## Poke 646
malortie's recreation - https://github.com/malortie/hl-poke646
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-poke646
Reverse-engineered code: branch **poke646** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/poke646
Reverse-engineered code, branch **poke646** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/poke646
## Poke 646: Vendetta
malortie's recreation - https://github.com/malortie/hl-poke646-vendetta
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-poke646
Reverse-engineered code: branch **poke646_vendetta** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/poke646_vendetta
Reverse-engineered code, branch **poke646_vendetta** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/poke646_vendetta
## Residual Life
Reverse-engineered code: branch **residual_point** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/residual_point
Reverse-engineered code, branch **residual_point** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/residual_point
## Residual Point
Reverse-engineered code: branch **residual_point** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/residual_point
## Sewer Beta
Branch **sewer_beta** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/sewer_beta
Reverse-engineered code, branch **residual_point** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/residual_point
## Team Fortress Classic
Reverse-engineered code by Velaron - https://github.com/Velaron/tf15-client
## The Gate
malortie's recreation - https://github.com/malortie/hl-thegate
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-TheGate
Reverse-engineered code: branch **thegate** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/thegate
Reverse-engineered code, branch **thegate** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/thegate
## They Hunger
malortie's recreation - https://github.com/malortie/hl-theyhunger
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-Hunger
Reverse-engineered code: branch **theyhunger** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/theyhunger
Reverse-engineered code, branch **theyhunger** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/theyhunger
They Hunger: Tactical - https://www.moddb.com/mods/they-hunger-tactical/downloads/tht-source-code-documentation
## Times of Troubles
malortie's recreation - https://github.com/malortie/hl-tot
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-tot
Branch **tot** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/tot
Branch **tot** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/tot
# Derived work
## Adrenaline Gamer
Branch **aghl** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/aghl
Branch **aghl** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/aghl
## Bubblemod
Branch **bubblemod** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/bubblemod
Branch **bubblemod** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/bubblemod
## Deathmatch Classic
Deathmatch Classic: Adrenaline Gamer Edition - https://github.com/martinwebrant/agmod/tree/master/src/dmc
Deathmatch Quaked - https://www.moddb.com/games/deathmatch-classic/downloads/dmq2
Branch **dmc** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/dmc
Branch **dmc** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/dmc
## Half-Life: Echoes
Branch **echoes** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/echoes
Branch **echoes** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/echoes
## Half-Life: Invasion
Port to HLSDK 2.4 by malortie - https://github.com/malortie/hl-invasion
Port to HLSDK 2.4 by malortie - https://github.com/malortie/halflife/tree/mod-hl-invasion
Port to Linux by fmoraw - https://github.com/fmoraw/hlinvasion
Branch **invasion** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/invasion
## Half-Life: Top-Down
Branch **hltopdown** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/hltopdown
Branch **hltopdown** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/hltopdown
## Half-Screwed
Branch **half-screwed** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/half-screwed
Branch **half-screwed** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/half-screwed
## Natural Selection
Port to Linux - https://github.com/fmoraw/NS
## Spirit of Half-Life
Version 1.2: branch **sohl1.2** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/sohl1.2
## Swiss Cheese Halloween 2002
Just more playable version by malortie - https://github.com/malortie/hl-shall
Just more playable version by malortie - https://github.com/malortie/halflife/tree/mod-hl-halloween
Branch **halloween** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/halloween
## The Wastes
Version 1.5: Port to Linux - https://git.mentality.rip/a1batross/halflife-thewastes-sdk
Branch **halloween** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/halloween
## Threewave CTF
Branch **dmc** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/dmc
## Xen-Warrior
Branch **sohl1.2** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/sohl1.2
Branch **dmc** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/dmc
## Zombie-X
Branch **zombie-x** in hlsdk-portable - https://github.com/FWGS/hlsdk-portable/tree/zombie-x
Branch **zombie-x** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/zombie-x

View File

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

View File

@@ -1,49 +0,0 @@
## PlayStation Vita port
### Prerequisites
1. Make sure your PSVita is [set up to run homebrew applications](https://vita.hacks.guide/).
2. Install [kubridge](https://github.com/TheOfficialFloW/kubridge/releases/) by copying `kubridge.suprx` to your taiHEN plugins folder (usually `ux0:/tai`) and add it to your `config.txt`, for example:
```
*KERNEL
ux0:tai/kubridge.skprx
```
3. Install `libshacccg.suprx` by following [this guide](https://cimmerian.gitbook.io/vita-troubleshooting-guide/shader-compiler/extract-libshacccg.suprx).
### Installation
1. If you have an old vitaXash3D install, remove it.
2. Get `xash3d-fwgs-psvita.7z` from the latest [automatic build](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous).
3. Install `xash.vpk` from the 7z archive onto your PSVita.
4. Copy the `data` directory from the 7z archive to the root of your PSVita's SD card.
5. Copy the valve folder and any other mod folders from your Half-Life install to `ux0:/data/xash3d/` (you can use other mountpoints instead of `ux0`). **Do not overwrite anything.**
### Build instructions
1. Install [VitaSDK](https://vitasdk.org/).
2. Build and install [vitaGL](https://github.com/Rinnegatamante/vitaGL):
```
git clone https://github.com/Rinnegatamante/vitaGL.git
make -C vitaGL NO_TEX_COMBINER=1 HAVE_UNFLIPPED_FBOS=1 HAVE_PTHREAD=1 SINGLE_THREADED_GC=1 MATH_SPEEDHACK=1 DRAW_SPEEDHACK=1 HAVE_CUSTOM_HEAP=1 -j2 install
```
3. Build and install [vita-rtld](https://github.com/fgsfdsfgs/vita-rtld):
```
git clone https://github.com/fgsfdsfgs/vita-rtld.git && cd vita-rtld
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j2 install
```
4. Build and install [this SDL2 fork](https://github.com/Northfear/SDL) with vitaGL integration:
```
git clone https://github.com/Northfear/SDL.git && cd SDL
mkdir build && cd build
cmake -DCMAKE_TOOLCHAIN_FILE=${VITASDK}/share/vita.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DVIDEO_VITA_VGL=ON ..
make -j2 install
```
5. Use `waf`:
```
./waf configure -T release --psvita
./waf build
```
6. Copy all the resulting `.so` files into a single folder:
```
./waf install --destdir=xash3d
```
7. `xash.vpk` is located in `build/engine/`.

View File

@@ -46,7 +46,7 @@ For mappacks - place *.bsp files to **valve/maps** folder, *.wad files to **valv
16. [Betrayal](http://www.moddb.com/mods/betrayal) (this mod has inner bugs; set **gl_allow_mirrors** to **0** to prevent drops of game's perfomance in some areas)
17. [Between Two Worlds](https://www.runthinkshootlive.com/posts/between-two-worlds/)
18. [Black Mesa Energy Testing Chamber](http://twhl.info/competitions.php?results=17)
19. [Black Mesa Sideline](https://www.moddb.com/mods/black-mesa-sideline) (set **gl_allow_mirrors** to **0** to prevent drops of game's perfomance in some areas)
19. [Black Mesa Sideline](http://www.isolated-design.de/half-life-mods/black-mesa-sideline/) (set **gl_allow_mirrors** to **0** to prevent drops of game's perfomance in some areas)
20. [BlackMesa 2007( Black Mesa Missions 2007 )](http://www.moddb.com/addons/blackmesa-2007)
21. [Blood and Bones](https://www.runthinkshootlive.com/posts/blood-and-bones/)
22. Boom (Huknenn) v1.0 & [HL Boom: Gold Edition v1.1](http://www.moddb.com/mods/boom)
@@ -103,8 +103,8 @@ For mappacks - place *.bsp files to **valve/maps** folder, *.wad files to **valv
72. [Freeman](https://www.runthinkshootlive.com/posts/freeman/)
73. [Freeman's Escape](http://www.moddb.com/mods/freeman-escape-french) (2 maps by *JiggZ*)
74. [Freeman's Fight](https://www.runthinkshootlive.com/posts/freemans-fight/)
75. [Freeman's Return](https://www.moddb.com/games/half-life/addons/freemans-return-v12)
76. [Freeman's Return 2](https://www.moddb.com/games/half-life/addons/freemans-return-2-v11)
75. [Freeman's Return](http://jpmaps.wz.cz/epizody.htm)
76. [Freeman's Return 2](http://jpmaps.wz.cz/epizody.htm)
77. [Freeman's Revenge](https://www.runthinkshootlive.com/posts/freemans-revenge/)
78. [Freeman's Tomb( The Crypt )](http://twhl.info/vault.php?map=3787)
79. [G-Invasion v2.5](http://www.moddb.com/mods/g-man-invasion) aka G-Man Invasion (there is an inner crash bug on final titles: some text lines are too long and cannot be properly displayed)
@@ -129,7 +129,7 @@ For mappacks - place *.bsp files to **valve/maps** folder, *.wad files to **valv
96. [Haunted](https://www.runthinkshootlive.com/posts/haunted/) (set **sv_validate_changelevel** to **0** to avoid a problem with level change between maps **pagan7** and **pagan8**)
97. [Hazardous Materials: Episode 1 & 2](http://www.moddb.com/mods/half-life-hazardous-materials)
98. [Hazardous-Course 2](http://www.moddb.com/mods/hazardous-course-2)
99. [Help Wanted](https://www.moddb.com/games/half-life/addons/help-wanted)
99. [Help Wanted](http://maps.mrsucko.org/work/)
100. [Hidden Evil v1.01](https://www.runthinkshootlive.com/posts/hidden-evil/)
101. [High Speed](http://www.moddb.com/games/half-life/addons/high-speed-english-version)
102. [hlife_hotdog_compo26](http://twhl.info/vault.php?map=5181)
@@ -155,7 +155,7 @@ For mappacks - place *.bsp files to **valve/maps** folder, *.wad files to **valv
122. [Mario Keys](http://www.moddb.com/mods/mario-keys)
123. [McBeth](https://www.runthinkshootlive.com/posts/mcbeth/)
124. [Medieval World](http://www.moddb.com/mods/medieval-world)
125. [Mel Soaring 2: Star Rancor](https://www.moddb.com/addons/mel-soaring-2-star-rancor)
125. [Mel Soaring 2: Star Rancor](http://www.etherealhell.com/etherealhell/index.php/my-levels/half-life)
126. [MINIMICUS](http://twhl.info/vault.php?map=163)
127. [Mission Failed](http://www.moddb.com/mods/mission-failed)
128. [Mission MC Poker](http://www.moddb.com/mods/half-life-mission-mc-poker)
@@ -176,7 +176,7 @@ For mappacks - place *.bsp files to **valve/maps** folder, *.wad files to **valv
143. [Operation: Nova](http://www.moddb.com/mods/half-life-operation-nova) (there is an inner bug with an M60 machinegun on a map with Osprey: it can be activated and used if you are staying in front of it, not behind it)
144. [Optimum Fear](https://www.fileplanet.com/7472/0/fileinfo/Optimum-Fear)
145. [Outrun](http://www.moddb.com/mods/outrun)
146. [Outwards (Day One)](https://drive.google.com/file/d/1mjQ8wUazYbwTq9Ocg0Vs0raq4avbTRne/view?usp=sharing)
146. [Outwards (Day One)](http://www.visgi.info/maps/)
147. [Overhaul Pack](http://www.moddb.com/mods/half-life-overhaul-pack) (Just HD pack for Half-Life)
148. [P.I.Z.D.E.C.](https://www.runthinkshootlive.com/posts/pizdec/)
149. [pagoda](http://www.moddb.com/mods/pagoda1)
@@ -184,7 +184,7 @@ For mappacks - place *.bsp files to **valve/maps** folder, *.wad files to **valv
151. [Phobos IV](http://www.moddb.com/mods/phobos-iv)
152. [Pimp My Car](https://www.runthinkshootlive.com/posts/pimp-my-car/) (there is an inner issue with incorrect responses of buttons on combination locks)
153. [Point Blank Stackdeath Complex](https://www.runthinkshootlive.com/posts/half-life-point-blank-stackdeath-complex/)
154. [Prisoner Escaped](https://www.moddb.com/mods/prisoner-escaped-1-2)
154. [Prisoner Escaped](http://four0four.org/downloads/maps/)
155. [Prisoner of Event](http://wp.vondur.net/?page_id=40)
156. [Prisoner of War](https://www.runthinkshootlive.com/posts/prisoner-of-war/)
157. [Project Quantum Leap](http://www.moddb.com/mods/project-quantum-leap)
@@ -282,7 +282,7 @@ For mappacks - place *.bsp files to **valve/maps** folder, *.wad files to **valv
6. [Catacombs: Part 1](https://www.runthinkshootlive.com/posts/catacombs/)
7. [Cro-man's Office Mappack](http://twhl.info/vault.php?map=5547)
8. [Half-Life Episode Two Demo Alpha v1.0](http://hl.loess.ru/?mod=451)
9. [Hazardous-Course (first version of Hazardous-Course 2)](https://drive.google.com/file/d/16djJZSpNWKyScSxSyMqX-u_S-2i400rl/view?usp=sharing)
9. [Hazardous-Course (first version of Hazardous-Course 2)](http://www.richmans-maps.ch.vu/) (link dead!)
10. [High Tech v0.2](http://hl.loess.ru/?mod=499)
11. [HL Shadows, Part 1](https://www.fileplanet.com/7466/0/fileinfo/'HL-Shadows',-Part-1)
12. [HLNewEnd](http://twhl.info/vault.php?map=2275)
@@ -305,11 +305,11 @@ For mappacks - place *.bsp files to **valve/maps** folder, *.wad files to **valv
29. [Shortcut v1.0 Beta](https://www.runthinkshootlive.com/posts/shortcut/)
30. [Stoka](https://www.ceskemody.cz/mapy.php?lng=1&clanek=222&razeni_hra=1&pn=stoka)
31. [Striker's Compo 26](http://twhl.info/vault.php?map=5190) (buggy)
32. [Technology Test 2](https://drive.google.com/file/d/1LfldzsMIN5j07bgtNkfY5v0Xl0S9de_G/view?usp=sharing)
32. [Technology Test 2](http://www.richmans-maps.ch.vu/) (link dead!)
33. [The Gate Playable Demo](https://www.fileplanet.com/116347/110000/fileinfo/The-Gate-Playable-Demo)
34. [They are Back](https://www.runthinkshootlive.com/posts/they-are-back/)
35. [Tiefseelabor( Deep Sea Laboratory )](https://www.runthinkshootlive.com/posts/deep-sea-laboratory/)
36. [Time-Shift](https://drive.google.com/file/d/1pK1s-2SIlSMQHVRPMLdC_94wTa__8_DX/view?usp=sharing)
36. [Time-Shift](http://www.richmans-maps.ch.vu/) (link dead!)
37. [Train Single Beta](https://cs-mapping.com.ua/forum/showthread.php?t=36394) (Remove **gfx.wad** from **TrainSingle** folder)
38. [WAR: The Killer Beta 0.1](http://www.moddb.com/mods/war)
39. [White Force Beta( Residual Point prototype )](http://www.moddb.com/mods/hl-residual-point/downloads/white-force-beta-2002)
@@ -379,7 +379,7 @@ Mods:
5. [Half-Life Baby v1.4](http://www.moddb.com/games/half-life/addons/half-life-baby) (it's an unfinished but playable mod; after installing of the mod open **liblist.gam** or **gameinfo.txt** file in the mod's folder and correct the line **gamedll "..\hlbaby\dlls\hl.dll"** for **gamedll "dlls\hl.dll"**, otherwise you'll not be able to start a game)
6. [Half-Secret](http://www.moddb.com/mods/half-secret) (this mod has custom **weapon_snark** code)
7. [Induction](http://www.moddb.com/mods/half-life-induction) (this mod has new item - **item_flashlight**)
8. [Lost in Black Mesa(first version without HLFX)](https://drive.google.com/file/d/1bEnm_AxJs-ly8hTEZIQBw_v2BsXdSiGa/view?usp=sharing)
8. [Lost in Black Mesa(first version without HLFX)](http://half-life.ru/forum/showthread.php?threadid=13959)
9. [Soldier](http://www.moddb.com/mods/half-life-soldier)
10. [Solo Operations](http://www.moddb.com/mods/solo-operations)
11. [The Blood v1.1](http://hl.loess.ru/?mods=&search=The+Blood) (there are some inner bugs in the mod, but they don't interfere with a game progress)
@@ -440,7 +440,7 @@ Mods:
51. [Data-base](https://www.runthinkshootlive.com/posts/database/)
52. [de_dust2_azabetfeN](https://cs-mapping.com.ua/forum/showthread.php?t=36394) (remove **cl_dlls** & **dlls** folders from inside of mod's directory before you start the game)
53. [De-railed](http://twhl.info/competitions.php?results=7)
54. [Dead Shift Beta](http://www.moddb.com/mods/dead-shift) - [Demo 1](https://www.gamewatcher.com/mods/half-life-mod/dead-shift-1-0-beta) & [Demo 2](https://drive.google.com/file/d/1uHvr8xONogTTNOy-8X6G4ehFV6Eawvbq/view?usp=sharing)
54. [Dead Shift Beta](http://www.moddb.com/mods/dead-shift) - [Demo 1](https://www.gamewatcher.com/mods/half-life-mod/dead-shift-1-0-beta) & [Demo 2](https://www.gamefront.com/files/13532512) (3rd link dead!)
55. [Deep](http://twhl.info/vault.php?map=1669)
56. [Desert Attack](http://fyzzer.narod.ru/index.html)
57. [Desert Combat Demo](https://www.fileplanet.com/190487/190000/fileinfo/Half-Life---Desert-Combat-Mod) (despite a big file size there's only one small unfinished map)
@@ -469,7 +469,7 @@ Mods:
80. [Extinct Lifeform Hunt](https://www.fileplanet.com/13501/10000/fileinfo/Extinct-Lifeform-Hunt)
81. [Facility](http://twhl.info/vault.php?map=5482)
82. [Facility Escape](http://twhl.info/vault.php?map=3673)
83. [Fallout](http://www.thewall.de/forum/thread/hl1-sp-48h-mapping-contest/64975.4.html) (map by *simb*) (link dead!)
83. [Fallout](http://www.thewall.de/forum/thread/hl1-sp-48h-mapping-contest/64975.4.html) (map by *simb*)
84. [Final Assault](http://twhl.info/vault.php?map=4500)
85. [Flat](http://hl.loess.ru/?mods=&search=Flat)
86. [Freeman's Allegiance](https://www.runthinkshootlive.com/posts/freemans-allegiance/)
@@ -498,8 +498,8 @@ Mods:
109. [Hospital](https://gamebanana.com/maps/167446) (you need to edit **liblist.gam** file in the mod's folder - delete *gamedll & type* strings from it before you start to play)
110. [Hostage](https://www.runthinkshootlive.com/posts/hostage-2/)
111. [House](http://www.artpeter.net/Data/HalfLife/Hl.php)
112. [Impulse 101 Fun - The Train](https://drive.google.com/file/d/1jAuMCCmREH0mfAEAscqaG8FQGa2uNknb/view?usp=sharing) (map from *TWHL* by *Archie* aka *The Hunter*)
113. [In America](https://drive.google.com/file/d/1gOC8zfnUvBxRy8Rr8juNiUNbLYjoZpnn/view?usp=sharing)
112. [Impulse 101 Fun - The Train](http://web.archive.org/web/20070305075816/http://www.twhl.co.za/mapvault/2817.zip) (map from *TWHL* by *Archie* aka *The Hunter*)
113. [In America](http://www.lambda-force.org/load/half_life/karty/half_life_in_america/18-1-0-476)
114. [In the Kitchen](http://twhl.info/vault.php?map=4314)
115. [Infiltration](https://www.fileplanet.com/7467/0/fileinfo/Infiltration)
116. [Interactivity & Lots of Entities](http://twhl.info/vault.php?map=5744) (link dead!)
@@ -668,7 +668,7 @@ Mods:
279. [X-treme Violence](http://www.moddb.com/mods/x-treme-violence)
280. [XargoL's Entry for Vassy's Compo](http://twhl.info/vault.php?map=769)
281. [Xen Again](https://www.fileplanet.com/9132/0/fileinfo/XEN-AGAIN)
282. [Xen World](http://www.lambda-force.org/load/half_life/karty/half_life_xen_world/18-1-0-481) (link dead!)
282. [Xen World](http://www.lambda-force.org/load/half_life/karty/half_life_xen_world/18-1-0-481)
283. [XUnil](https://www.fileplanet.com/7883/0/fileinfo/XUNIL)
284. [Zeeba-G's TWHL Compo 26 Entry](http://twhl.info/competitions.php?results=26)
285. [Zombies!](https://gamebanana.com/maps/160812)
@@ -694,7 +694,7 @@ For Linux and OS X you must download crossbuild from [here](http://www.moddb.com
2. [Big Scientists](http://www.moddb.com/mods/big-scientists)
3. [Black Silla Assault DEMO v1.2](http://www.moddb.com/mods/black-silla-assault)
4. [Blbej Den](http://www.moddb.com/mods/blbej-den)
5. [Cold Experiment v1](https://www.moddb.com/games/half-life/addons/cold-experiment) (you will need some files from SoHL to play it properly; download SoHL 1.2, extract files and copy following folders into **coldexv1** folder: cl_dlls, dlls, models, sprites)
5. [Cold Experiment v1](http://jpmaps.wz.cz/epizody.htm) (you will need some files from SoHL to play it properly; download SoHL 1.2, extract files and copy following folders into **coldexv1** folder: cl_dlls, dlls, models, sprites)
6. [Dead Sector v1.0a](http://www.moddb.com/mods/dead-sector)
7. [Death Is Dead](http://www.moddb.com/games/half-life/addons/death-is-dead) (there is a fog-related inner bug at the first map)
8. [Escape from Black Mesa Alpha](http://www.moddb.com/mods/escape-from-black-mesa)
@@ -710,9 +710,9 @@ For Linux and OS X you must download crossbuild from [here](http://www.moddb.com
18. [Santa's Revenge](http://twhl.info/vault.php?map=4332) (set **fps_max** to **60** to avoid an inner problem of the last map with final scripted sequence, otherwise the mod can not be finished properly)
19. [Sector 6](https://www.moddb.com/mods/sector-6/)
20. [Space Prisoner v1.1](http://www.moddb.com/games/half-life/addons/space-prisoner-v11) (after installing of the mod open **liblist.gam** or **gameinfo.txt** file in the mod's folder and correct the line **gamedll "..\prison\dlls\spirit.dll"** for **gamedll "dlls\spirit.dll"**, otherwise you'll not be able to start a game; there is also a scripting error on a third map of the mod, so you'll be forced to use **noclip** to pass around bugged place)
21. [Terrorist Attack 2](https://www.moddb.com/games/half-life/addons/terrorist-attack-2)
21. [Terrorist Attack 2](http://terroristattack.wz.cz/mody.html) (link dead!)
22. [Timeline III: The Heart of Darkness](http://www.moddb.com/mods/timeline-series)
23. [Underground 2 Demo](https://www.moddb.com/games/half-life/addons/underground-2-demo)
23. [Underground 2 Demo](http://www.isolated-design.de/half-life-mods/underground-2/)
## Mods which based on modified Spirit of Half-Life 1.2 or older(Partially playable with SoHL 1.2 libraries or not playable at all)
1. [Black Death](http://www.moddb.com/mods/half-life-black-death)
@@ -825,10 +825,10 @@ Mods:
3. [Bomb Squad](http://www.snarkpit.net/index.php?s=maps&map=3471)
4. [Corruption](http://www.snarkpit.net/index.php?s=maps&map=3154)
5. [Critical Mass](http://www.moddb.com/mods/half-life-critical-mass) [C3M1 Build 1 Demo](https://www.fileplanet.com/125746/120000/fileinfo/C3M1-Build-1)
6. [EPRST!](https://www.runthinkshootlive.com/posts/ep-rst/)
6. [EPRST!](http://www.planetphillip.com/posts/ep-rst-opposing-force/) (link dead!)
7. [Firing Range](https://www.runthinkshootlive.com/posts/firing-range/)
8. [Friendly Fire](https://www.runthinkshootlive.com/posts/friendly-fire/)
9. [Guitar Star Pre-Alpha](http://gamer-lab.com/rus/mods_goldsrc/Guitar_Star_(Prealpha))
9. [Guitar Star Pre-Alpha](http://hl-lab.ru/eng/mods_goldsrc/Guitar_Star_(Prealpha)) (link dead!)
10. [J2000](https://www.runthinkshootlive.com/posts/j2000/)
11. [Killing House for OF](https://www.runthinkshootlive.com/posts/scientist-rescue-aka-cqb/)
12. [Klabautermann](https://www.runthinkshootlive.com/posts/klabautermann/) (though the map has some inner issues, it can be properly finished, just don't let the welder soldier die and don't press the fifth button until you mount a special gun in its' place)

View File

@@ -1,36 +1,42 @@
# 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" />
[![builds.sr.ht status](https://builds.sr.ht/~a1batross/xash3d-fwgs.svg)](https://builds.sr.ht/~a1batross/xash3d-fwgs?) [![GitHub Actions Status](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [![FreeBSD Build Status](https://img.shields.io/cirrus/github/FWGS/xash3d-fwgs?label=freebsd%20build)](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) [![Discord Server](https://img.shields.io/discord/355697768582610945.svg)](http://fwgsdiscord.mentality.rip/) \
[![Download Stable](https://img.shields.io/badge/download-stable-yellow)](https://github.com/FWGS/xash3d-fwgs/releases/latest) [![Download Testing](https://img.shields.io/badge/downloads-testing-orange)](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous)
# Xash3D FWGS Engine
[![GitHub Actions Status](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [![Travis CI Status](https://api.travis-ci.org/FWGS/xash3d-fwgs.svg?branch=master)](https://travis-ci.org/FWGS/xash3d-fwgs) [![FreeBSD Build Status](https://img.shields.io/cirrus/github/FWGS/xash3d-fwgs?label=freebsd%20build)](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) [![Discord Server](https://img.shields.io/discord/355697768582610945.svg)](http://discord.fwgs.ru/) \
[![Download Stable](https://img.shields.io/badge/download-stable-yellow)](https://github.com/FWGS/xash3d-fwgs/releases/latest) [![Download Testing](https://img.shields.io/badge/downloads-testing-orange)](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous)
Xash3D 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 FWGS is a fork of Xash3D Engine by Unkle Mike with extended features and crossplatform.
Xash3D FWGS is a heavily modified fork of an original [Xash3D Engine](https://www.moddb.com/engines/xash3d-engine) by Unkle Mike.
## Donate
[![Donate to FWGS button](https://img.shields.io/badge/Donate_to_FWGS-%3C3-magenta)](Documentation/donate.md) \
If you like Xash3D FWGS, consider supporting individual engine maintainers. By supporting us, you help to continue developing this game engine further. The sponsorship links are available in [documentation](Documentation/donate.md).
```
Xash3D is a game engine, aimed to provide compatibility with Half-Life Engine,
as well as to give game developers well known workflow and extend it.
Read more about Xash3D on ModDB: https://www.moddb.com/engines/xash3d-engine
```
## Fork features
* Steam Half-Life (HLSDK 2.4) support.
* Crossplatform and modern compilers support: supports Windows, Linux, BSD & Android on x86 & ARM and [many more](Documentation/ports.md).
* Better multiplayer support: multiple master servers, headless dedicated server, voice chat and IPv6 support.
* Multiple renderers support: OpenGL, GLESv1, GLESv2 and Software.
* Advanced virtual filesystem: `.pk3` and `.pk3dir` support, compatibility with GoldSrc FS module, fast case-insensitivity emulation for crossplatform.
* Mobility API: better game integration on mobile devices (vibration, touch controls)
* Different input methods: touch and gamepad in addition to mouse & keyboard.
* HLSDK 2.4 support.
* Crossplatform: supported x86 and ARM on Windows/Linux/BSD/Android. ([see docs for more info](Documentation/ports.md))
* Modern compilers support: say no more to MSVC6.
* Better multiplayer support: multiple master servers, headless dedicated server.
* Mobility API: allows better game integration on mobile devices(vibration, touch controls)
* Different input methods: touch, gamepad and classic mouse & keyboard.
* TrueType font rendering, as a part of mainui_cpp.
* External VGUI support module.
* PNG & KTX2 image format support.
* [A set of small improvements](Documentation/), without broken compatibility.
* Multiple renderers support: OpenGL, GLESv1, GLESv2, Software
* A set of small improvements, without broken compatibility.
## Planned fork features
* Virtual Reality support and game API
* Voice support
* Vulkan renderer
## Installation & Running
0) Get Xash3D FWGS binaries: you can use [testing](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous) build or you can compile engine from source code.
0) Get Xash3D binaries: you can use [testing](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous) build or you can compile engine from source code.
Choose proper build package depending on which platform you're using.
1) Copy engine binaries to some directory.
2) Copy `valve` directory from [Half-Life](https://store.steampowered.com/app/70/HalfLife/) to directory with engine binaries.
If your CPU is NOT x86 compatible or you're running 64-bit version of the engine, you may want to compile [Half-Life SDK](https://github.com/FWGS/hlsdk-portable).
This repository contains our fork of HLSDK and restored source code for some of the mods. Not all of them, of course.
You still needed to copy `valve` directory as all game resources located there.
3) Run the main executable (`xash3d.exe` or AppImage).
Also if you're using Windows: you should copy `vgui.dll` library from Half-Life directory to Xash3D directory.
As alternative, you can compile [hlsdk-xash3d](https://github.com/FWGS/hlsdk-xash3d) instead of using official Valve game binaries, but you still needed to copy `valve` directory as all game resources located in there.
3) Download [extras.pak](https://github.com/FWGS/xash-extras/releases/tag/v0.19.2) and place it to `valve` directory.
4) Run `xash3d.exe`/`xash3d.sh`/`xash3d` depending on which platform you're using.
Note: on Linux, you may need to create an sh file with the command `LD_LIBRARY_PATH=. ./xash3d`.
For additional info, run Xash3D with `-help` command line key.
@@ -45,13 +51,6 @@ We are using Waf build system. If you have some Waf-related questions, I recomme
NOTE: NEVER USE GitHub's ZIP ARCHIVES. GitHub doesn't include external dependencies we're using!
### Prerequisites
If your CPU is x86 compatible, we are building 32-bit code by default. This was done to maintain compatibility with Steam releases of Half-Life and based on it's engine games.
Even if Xash3D FWGS does support targetting 64-bit, you can't load games without recompiling them from source code!
If your CPU is NOT x86 compatible or you decided build 64-bit version of engine, you may want to compile [Half-Life SDK](https://github.com/FWGS/hlsdk-portable).
This repository contains our fork of HLSDK and restored source code for some of the mods. Not all of them, of course.
#### Windows (Visual Studio)
* Install Visual Studio.
* Install latest [Python](https://python.org) **OR** run `cinst python.install` if you have Chocolatey.
@@ -61,6 +60,10 @@ This repository contains our fork of HLSDK and restored source code for some of
* Make sure you have at least 12GB of free space to store all build-time dependencies: ~10GB for Visual Studio, 300 MB for Git, 100 MB for Python and other.
#### GNU/Linux
NOTE FOR USERS WITH X86 COMPATIBLE CPUs:
We have forced Waf to throw an error, if you're trying to build 64-bit engine. This was done for keeping compatibility with Steam releases of Half-Life and based on it's engine games.
Even if Xash3D FWGS does support targetting 64-bit, you can't load games without recompiling them from source code!
##### Debian/Ubuntu
* Enable i386 on your system, if you're compiling 32-bit engine on amd64. If not, skip this
@@ -78,15 +81,16 @@ This repository contains our fork of HLSDK and restored source code for some of
0) Open command line
1) Navigate to `xash3d-fwgs` directory.
2) Carefully examine which build options are available: `waf --help`
3) Configure build: `waf configure -T release --sdl2=c:/path/to/SDL2`
3) Configure build: `waf configure -T release --sdl2=c:/path/to/SDL2 --prefix=c:/path/to/any/output/directory`
4) Compile: `waf build`
5) Install: `waf install --destdir=c:/path/to/any/output/directory`
5) Install: `waf install`
#### Linux
If compiling 32-bit on amd64, you may need to supply `export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig` prior to running configure.
0) Examine which build options are available: `./waf --help`
1) Configure build: `./waf configure -T release`
1) Configure build: `./waf configure -T release --prefix=/path/to/any/output/directory`
(You need to pass `-8` to compile 64-bit engine on 64-bit x86 processor)
2) Compile: `./waf build`
3) Install(optional): `./waf install --destdir=/path/to/any/output/directory`
3) Install(optional): `./waf install`
Note: if compiling 32-bit on amd64, you may need to supply `export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig` prior to running configure.

View File

@@ -18,17 +18,27 @@ GNU General Public License for more details.
// video backends (XASH_VIDEO)
#define VIDEO_NULL 0
#define VIDEO_SDL 1
#define VIDEO_ANDROID 2
#define VIDEO_FBDEV 3
#define VIDEO_DOS 4
// audio backends (XASH_SOUND)
#define SOUND_NULL 0
#define SOUND_SDL 1
#define SOUND_OPENSLES 2
#define SOUND_ALSA 3
// crash handler (XASH_CRASHHANDLER)
#define CRASHHANDLER_NULL 0
#define CRASHHANDLER_UCONTEXT 1
#define CRASHHANDLER_DBGHELP 2
#define CRASHHANDLER_WIN32 3
// input (XASH_INPUT)
#define INPUT_NULL 0
#define INPUT_SDL 1
#define INPUT_ANDROID 2
#define INPUT_EVDEV 3
// timer (XASH_TIMER)
@@ -41,8 +51,9 @@ GNU General Public License for more details.
// messageboxes (XASH_MESSAGEBOX)
#define MSGBOX_STDERR 0
#define MSGBOX_SDL 1
#define MSGBOX_ANDROID 2
#define MSGBOX_WIN32 3
#define MSGBOX_NSWITCH 4
// library loading (XASH_LIB)
#define LIB_NULL 0
@@ -50,4 +61,5 @@ GNU General Public License for more details.
#define LIB_WIN32 2
#define LIB_STATIC 3
#endif /* BACKENDS_H */

View File

@@ -61,27 +61,23 @@ BRUSH MODELS
#define LS_UNUSED 0xFE
#define LS_NONE 0xFF
#define MAX_MAP_CLIPNODES_HLBSP 32767
#define MAX_MAP_CLIPNODES_BSP2 524288
// these limis not using by modelloader but only for displaying 'mapstats' correctly
#ifdef SUPPORT_BSP2_FORMAT
#define MAX_MAP_MODELS 2048 // embedded models
#define MAX_MAP_ENTSTRING 0x200000 // 2 Mb should be enough
#define MAX_MAP_PLANES 131072 // can be increased without problems
#define MAX_MAP_NODES 262144 // can be increased without problems
#define MAX_MAP_CLIPNODES MAX_MAP_CLIPNODES_BSP2 // can be increased without problems
#define MAX_MAP_CLIPNODES 524288 // can be increased without problems
#define MAX_MAP_LEAFS 131072 // CRITICAL STUFF to run ad_sepulcher!!!
#define MAX_MAP_VERTS 524288 // can be increased without problems
#define MAX_MAP_FACES 262144 // can be increased without problems
#define MAX_MAP_MARKSURFACES 524288 // can be increased without problems
#else
// increased to match PrimeXT compilers
#define MAX_MAP_MODELS 1024 // embedded models
#define MAX_MAP_MODELS 768 // embedded models
#define MAX_MAP_ENTSTRING 0x100000 // 1 Mb should be enough
#define MAX_MAP_PLANES 65536 // can be increased without problems
#define MAX_MAP_NODES 32767 // because negative shorts are leafs
#define MAX_MAP_CLIPNODES MAX_MAP_CLIPNODES_HLBSP // because negative shorts are contents
#define MAX_MAP_CLIPNODES 32767 // because negative shorts are contents
#define MAX_MAP_LEAFS 32767 // signed short limit
#define MAX_MAP_VERTS 65535 // unsigned short limit
#define MAX_MAP_FACES 65535 // unsigned short limit

View File

@@ -9,20 +9,8 @@ NOTE: number at end of pixelformat name it's a total bitscount e.g. PF_RGB_24 ==
========================================================================
*/
#define ImageRAW( type ) (type == PF_RGBA_32 || type == PF_BGRA_32 || type == PF_RGB_24 || type == PF_BGR_24 || type == PF_LUMINANCE)
#define ImageCompressed( type ) \
( type == PF_DXT1 \
|| type == PF_DXT3 \
|| type == PF_DXT5 \
|| type == PF_ATI2 \
|| type == PF_BC4_SIGNED \
|| type == PF_BC4_UNSIGNED \
|| type == PF_BC5_SIGNED \
|| type == PF_BC5_UNSIGNED \
|| type == PF_BC6H_SIGNED \
|| type == PF_BC6H_UNSIGNED \
|| type == PF_BC7_UNORM \
|| type == PF_BC7_SRGB \
|| type == PF_KTX2_RAW )
#define ImageDXT( type ) (type == PF_DXT1 || type == PF_DXT3 || type == PF_DXT5 || type == PF_ATI2)
#define Image16( type ) (type == PF_RGBA_64 || type == PF_RGB_48)
typedef enum
{
@@ -34,19 +22,12 @@ typedef enum
PF_RGB_24, // uncompressed dds or another 24-bit image
PF_BGR_24, // big-endian RGB (MacOS)
PF_LUMINANCE,
PF_DXT1, // s3tc DXT1/BC1 format
PF_DXT3, // s3tc DXT3/BC2 format
PF_DXT5, // s3tc DXT5/BC3 format
PF_ATI2, // latc ATI2N/BC5 format
PF_BC4_SIGNED,
PF_BC4_UNSIGNED,
PF_BC5_SIGNED,
PF_BC5_UNSIGNED,
PF_BC6H_SIGNED, // bptc BC6H signed FP16 format
PF_BC6H_UNSIGNED, // bptc BC6H unsigned FP16 format
PF_BC7_UNORM, // bptc BC7 format
PF_BC7_SRGB,
PF_KTX2_RAW, // Raw KTX2 data, used for yet unsupported KTX2 subformats
PF_DXT1, // s3tc DXT1 format
PF_DXT3, // s3tc DXT3 format
PF_DXT5, // s3tc DXT5 format
PF_ATI2, // latc ATI2N format
PF_RGBA_64, // 16-bit RGBA
PF_RGB_48, // 16-bit RGB
PF_TOTALCOUNT, // must be last
} pixformat_t;
@@ -68,8 +49,6 @@ typedef enum
IL_DDS_HARDWARE = BIT(4), // DXT compression is support
IL_LOAD_DECAL = BIT(5), // special mode for load gradient decals
IL_OVERVIEW = BIT(6), // overview required some unque operations
IL_LOAD_PLAYER_DECAL = BIT(7), // special mode for player decals
IL_KTX2_RAW = BIT(8), // renderer can consume raw KTX2 files (e.g. ref_vk)
} ilFlags_t;
// goes into rgbdata_t->encode
@@ -106,7 +85,7 @@ typedef enum
IMAGE_ROT_90 = BIT(18), // flip from upper left corner to down right corner
IMAGE_ROT180 = IMAGE_FLIP_X|IMAGE_FLIP_Y,
IMAGE_ROT270 = IMAGE_FLIP_X|IMAGE_FLIP_Y|IMAGE_ROT_90,
// reserved
IMAGE_EMBOSS = BIT(19), // apply emboss mapping
IMAGE_RESAMPLE = BIT(20), // resample image to specified dims
// reserved
// reserved

View File

@@ -105,7 +105,7 @@ typedef struct
vec3_t mins, maxs; // terrain bounds (fill by user)
intptr_t reserved[32]; // just for future expansions or mod-makers
int reserved[32]; // just for future expansions or mod-makers
} mfaceinfo_t;
typedef struct
@@ -173,8 +173,8 @@ struct decal_s
short entityIndex; // Entity this is attached to
// Xash3D specific
vec3_t position; // location of the decal center in world space.
glpoly_t *polys; // precomputed decal vertices
intptr_t reserved[4]; // just for future expansions or mod-makers
glpoly_t *polys; // precomputed decal vertices
int reserved[4]; // just for future expansions or mod-makers
};
typedef struct mleaf_s
@@ -228,7 +228,7 @@ typedef struct mextrasurf_s
unsigned short numverts; // world->vertexes[]
int firstvertex; // fisrt look up in tr.tbn_vectors[], then acess to world->vertexes[]
intptr_t reserved[32]; // just for future expansions or mod-makers
int reserved[32]; // just for future expansions or mod-makers
} mextrasurf_t;
struct msurface_s
@@ -530,7 +530,7 @@ typedef struct
#define MAX_DEMOS 32
#define MAX_MOVIES 8
#define MAX_CDTRACKS 32
#define MAX_CLIENT_SPRITES 512 // SpriteTextures (0-256 hud, 256-512 client)
#define MAX_CLIENT_SPRITES 256 // SpriteTextures
#define MAX_EFRAGS 8192 // Arcane Dimensions required
#define MAX_REQUESTS 64

View File

@@ -717,7 +717,6 @@ enum
kRenderFxExplode, // Scale up really big!
kRenderFxGlowShell, // Glowing Shell
kRenderFxClampMinScale, // Keep this sprite from getting very small (SPRITES only!)
kRenderFxLightMultiplier,
};
typedef int func_t;
@@ -726,6 +725,7 @@ typedef int string_t;
typedef unsigned short word;
#include "xash3d_types.h"
#define Q_isspace( ch ) (ch < 32 || ch > 255)
typedef struct
{

View File

@@ -25,18 +25,14 @@
#define FCVAR_PRINTABLEONLY (1<<7) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ).
#define FCVAR_UNLOGGED (1<<8) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log
#define FCVAR_NOEXTRAWHITEPACE (1<<9) // strip trailing/leading white space from this cvar
#define FCVAR_PRIVILEGED (1<<10) // only available in privileged mode
#define FCVAR_FILTERABLE (1<<11) // filtered in unprivileged mode if cl_filterstuffcmd is 1
// Xash3D extensions
#define FCVAR_MOVEVARS (1<<10) // this cvar is a part of movevars_t struct that shared between client and server
#define FCVAR_LATCH (1<<11) // notify client what this cvar will be applied only after server restart (but don't does more nothing)
#define FCVAR_GLCONFIG (1<<12) // write it into <renderer>.cfg(see RefAPI)
#define FCVAR_CHANGED (1<<13) // set each time the cvar is changed
#define FCVAR_GAMEUIDLL (1<<14) // defined by the menu DLL
#define FCVAR_CHEAT (1<<15) // can not be changed if cheats are disabled
// a1ba: let's reuse higher bits for flags extensions from now on
#define FCVAR_LATCH (1<<30) // notify client what this cvar will be applied only after server restart (but don't does more nothing)
typedef struct cvar_s
{
char *name;

View File

@@ -47,11 +47,29 @@ SETUP BACKENDS DEFINITIONS
#endif // XASH_TIMER
#ifndef XASH_MESSAGEBOX
#if !XASH_NSWITCH // SDL2 messageboxes not available
#define XASH_MESSAGEBOX MSGBOX_SDL
#endif
#define XASH_MESSAGEBOX MSGBOX_SDL
#endif // XASH_MESSAGEBOX
#endif
#elif XASH_ANDROID
// we are building for Android platform, use Android APIs
#ifndef XASH_VIDEO
#define XASH_VIDEO VIDEO_ANDROID
#endif // XASH_VIDEO
#ifndef XASH_INPUT
#define XASH_INPUT INPUT_ANDROID
#endif // XASH_INPUT
#ifndef XASH_SOUND
#define XASH_SOUND SOUND_OPENSLES
#endif // XASH_SOUND
#ifndef XASH_MESSAGEBOX
#define XASH_MESSAGEBOX MSGBOX_ANDROID
#endif // XASH_MESSAGEBOX
#define XASH_USE_EVDEV
#define XASH_DYNAMIC_DLADDR
#elif XASH_LINUX
// we are building for Linux without SDL2, can draw only to framebuffer yet
#ifndef XASH_VIDEO
@@ -66,7 +84,7 @@ SETUP BACKENDS DEFINITIONS
#define XASH_SOUND SOUND_ALSA
#endif // XASH_SOUND
#define XASH_USE_EVDEV 1
#define XASH_USE_EVDEV
#elif XASH_DOS4GW
#ifndef XASH_VIDEO
#define XASH_VIDEO VIDEO_DOS
@@ -87,13 +105,22 @@ SETUP BACKENDS DEFINITIONS
#ifndef XASH_MESSAGEBOX
#if XASH_WIN32
#define XASH_MESSAGEBOX MSGBOX_WIN32
#elif XASH_NSWITCH
#define XASH_MESSAGEBOX MSGBOX_NSWITCH
#else // !XASH_WIN32
#define XASH_MESSAGEBOX MSGBOX_STDERR
#endif // !XASH_WIN32
#endif // XASH_MESSAGEBOX
//
// select crashhandler based on defines
//
#ifndef XASH_CRASHHANDLER
#if XASH_WIN32 && defined(DBGHELP)
#define XASH_CRASHHANDLER CRASHHANDLER_DBGHELP
#elif XASH_LINUX || XASH_BSD
#define XASH_CRASHHANDLER CRASHHANDLER_UCONTEXT
#endif // !(XASH_LINUX || XASH_BSD || XASH_WIN32)
#endif
//
// no timer - no xash
//
@@ -130,6 +157,10 @@ SETUP BACKENDS DEFINITIONS
#define XASH_INPUT INPUT_NULL
#endif // XASH_INPUT
#ifndef XASH_CRASHHANDLER
#define XASH_CRASHHANDLER CRASHHANDLER_NULL
#endif // XASH_CRASHHANDLER
/*
=========================================================================
@@ -138,59 +169,27 @@ Default build-depended cvar and constant values
=========================================================================
*/
// Platform overrides
#if XASH_NSWITCH
#define DEFAULT_TOUCH_ENABLE "0"
#define DEFAULT_M_IGNORE "1"
#define DEFAULT_MODE_WIDTH 1280
#define DEFAULT_MODE_HEIGHT 720
#define DEFAULT_ALLOWCONSOLE 1
#elif XASH_PSVITA
#define DEFAULT_TOUCH_ENABLE "0"
#define DEFAULT_M_IGNORE "1"
#define DEFAULT_MODE_WIDTH 960
#define DEFAULT_MODE_HEIGHT 544
#define DEFAULT_ALLOWCONSOLE 1
#elif XASH_ANDROID
#if XASH_MOBILE_PLATFORM
#define DEFAULT_TOUCH_ENABLE "1"
#elif XASH_MOBILE_PLATFORM
#define DEFAULT_TOUCH_ENABLE "1"
#define DEFAULT_M_IGNORE "1"
#endif // !XASH_MOBILE_PLATFORM && !XASH_NSWITCH
#define DEFAULT_M_IGNORE "1"
#else // !XASH_MOBILE_PLATFORM
#define DEFAULT_TOUCH_ENABLE "0"
#define DEFAULT_M_IGNORE "0"
#endif // !XASH_MOBILE_PLATFORM
#if XASH_ANDROID || XASH_IOS || XASH_EMSCRIPTEN
// this means that libraries are provided with engine, but not in game data
// You need add library loading code to library.c when adding new platform
#define XASH_INTERNAL_GAMELIBS
#define XASH_INTERNAL_GAMELIBS
// 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
#endif // XASH_ANDROID || XASH_IOS || XASH_EMSCRIPTEN
// Defaults
#ifndef DEFAULT_TOUCH_ENABLE
#define DEFAULT_TOUCH_ENABLE "0"
#endif // DEFAULT_TOUCH_ENABLE
#ifndef DEFAULT_M_IGNORE
#define DEFAULT_M_IGNORE "0"
#endif // DEFAULT_M_IGNORE
#ifndef DEFAULT_JOY_DEADZONE
#define DEFAULT_JOY_DEADZONE "4096"
#endif // DEFAULT_JOY_DEADZONE
// allow override for developer/debug builds
#ifndef DEFAULT_DEV
#define DEFAULT_DEV 0
#endif // DEFAULT_DEV
#ifndef DEFAULT_ALLOWCONSOLE
#define DEFAULT_ALLOWCONSOLE 0
#endif // DEFAULT_ALLOWCONSOLE
#ifndef DEFAULT_FULLSCREEN
#define DEFAULT_FULLSCREEN "1" // must be a string
#define DEFAULT_FULLSCREEN 1
#endif // DEFAULT_FULLSCREEN
#ifndef DEFAULT_MAX_EDICTS
#define DEFAULT_MAX_EDICTS 1200 // was 900 before HL25
#endif // DEFAULT_MAX_EDICTS
#endif // DEFAULTS_H

View File

@@ -25,21 +25,5 @@ GNU General Public License for more details.
#define ENGINE_COMPENSATE_QUAKE_BUG (1<<5) // compensate stupid quake bug (inverse pitch) for mods where this bug is fixed
#define ENGINE_IMPROVED_LINETRACE (1<<6) // new traceline that tracing through alphatextures
#define ENGINE_COMPUTE_STUDIO_LERP (1<<7) // enable MOVETYPE_STEP lerping back in engine
#define ENGINE_LINEAR_GAMMA_SPACE (1<<8) // disable influence of gamma/brightness cvars to textures/lightmaps, for mods with custom renderer
#define ENGINE_STEP_POSHISTORY_LERP (1U<<31) // enable MOVETYPE_STEP interpolation based on position history. Incompatible with ENGINE_COMPUTE_STUDIO_LERP!
// adjust the mask when features will be added or removed
#define ENGINE_FEATURES_MASK \
( ENGINE_WRITE_LARGE_COORD \
| ENGINE_QUAKE_COMPATIBLE \
| ENGINE_LOAD_DELUXEDATA \
| ENGINE_PHYSICS_PUSHER_EXT \
| ENGINE_LARGE_LIGHTMAPS \
| ENGINE_COMPENSATE_QUAKE_BUG \
| ENGINE_IMPROVED_LINETRACE \
| ENGINE_COMPUTE_STUDIO_LERP \
| ENGINE_LINEAR_GAMMA_SPACE \
| ENGINE_STEP_POSHISTORY_LERP )
#endif//FEATURES_H

View File

@@ -18,9 +18,6 @@ GNU General Public License for more details.
#define GFL_NOMODELS (1<<0)
#define GFL_NOSKILLS (1<<1)
#define GFL_RENDER_PICBUTTON_TEXT (1<<2)
#define GFL_HD_BACKGROUND (1<<3)
#define GFL_ANIMATED_TITLE (1<<4)
/*
========================================================================

View File

@@ -1,35 +1,18 @@
/*
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
//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============
//
// cl_input
// Purpose:
//
typedef struct
// $NoKeywords: $
//=============================================================================
#if !defined( KBUTTONH )
#define KBUTTONH
#pragma once
typedef struct kbutton_s
{
int down[2]; // key nums holding it down
int state; // low bit is down state
} kbutton_t;
STATIC_ASSERT( sizeof( kbutton_t ) == 12, "kbutton_t isn't 12 bytes!" );
#endif // KBUTTON_H
#endif // !KBUTTONH

View File

@@ -1,74 +1,37 @@
/*
Copyright (C) 1997-2001 Id Software, Inc.
/***
*
* 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.
*
****/
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.
#ifndef NETADR_H
#define NETADR_H
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 NET_ADR_H
#define NET_ADR_H
#include STDINT_H
// net.h -- quake's interface to the networking layer
// a1ba: copied from Quake-2/qcommon/qcommon.h and modified to support IPv6
#define PORT_ANY -1
typedef enum {NA_LOOPBACK = 1, NA_BROADCAST, NA_IP, NA_IPX, NA_BROADCAST_IPX, NA_IP6, NA_MULTICAST_IP6} netadrtype_t;
/*
Original Quake-2 structure:
typedef struct
typedef enum
{
netadrtype_t type;
NA_UNUSED,
NA_LOOPBACK,
NA_BROADCAST,
NA_IP,
NA_IPX,
NA_BROADCAST_IPX
} netadrtype_t;
byte ip[4];
byte ipx[10];
unsigned short port;
} netadr_t;
*/
#pragma pack( push, 1 )
typedef struct netadr_s
{
union
{
// IPv6 struct
struct
{
uint16_t type6;
uint8_t ip6[16];
};
struct
{
uint32_t type; // must be netadrtype_t but will break with short enums
union
{
uint8_t ip[4];
uint32_t ip4; // for easier conversions
};
uint8_t ipx[10];
};
};
uint16_t port;
netadrtype_t type;
unsigned char ip[4];
unsigned char ipx[10];
unsigned short port;
} netadr_t;
#pragma pack( pop )
STATIC_ASSERT( sizeof( netadr_t ) == 20, "netadr_t isn't 20 bytes!" );
#endif // NET_ADR_H
#endif//NETADR_H

View File

@@ -20,6 +20,8 @@ GNU General Public License for more details.
#include "build.h"
#if !XASH_WIN32
#if XASH_APPLE
#include <sys/syslimits.h>
#define OS_LIB_EXT "dylib"
@@ -28,44 +30,97 @@ GNU General Public License for more details.
#define OS_LIB_EXT "so"
#define OPEN_COMMAND "xdg-open"
#endif
#define OS_LIB_PREFIX "lib"
#if XASH_ANDROID
//#if defined(LOAD_HARDFP)
// #define POSTFIX "_hardfp"
//#else
#define POSTFIX
//#endif
#else
#endif
#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
#define _inline static inline
#define FORCEINLINE inline __attribute__((always_inline))
#if XASH_POSIX
#define PATH_SPLITTER "/"
#include <unistd.h>
#include <dlfcn.h>
#define O_BINARY 0 // O_BINARY is Windows extension
#define O_TEXT 0 // O_TEXT is Windows extension
// Windows functions to posix equivalent
#define _mkdir( x ) mkdir( x, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH )
#define LoadLibrary( x ) dlopen( x, RTLD_NOW )
#define GetProcAddress( x, y ) dlsym( x, y )
#define FreeLibrary( x ) dlclose( x )
#define tell( a ) lseek(a, 0, SEEK_CUR)
#define HAVE_DUP
#endif
#if XASH_DOS4GW
#define PATH_SPLITTER "\\"
#define LoadLibrary( x ) (0)
#define GetProcAddress( x, y ) (0)
#define FreeLibrary( x ) (0)
#endif
//#define MAKEWORD( a, b ) ((short int)(((unsigned char)(a))|(((short int)((unsigned char)(b)))<<8)))
#define max( a, b ) (((a) > (b)) ? (a) : (b))
#define min( a, b ) (((a) < (b)) ? (a) : (b))
/// TODO: check if we may clean this defines, it should not appear in non-platform code!
typedef unsigned char BYTE;
typedef short int WORD;
typedef unsigned int DWORD;
typedef int LONG;
typedef unsigned int ULONG;
typedef int WPARAM;
typedef unsigned int LPARAM;
typedef void* HANDLE;
typedef void* HMODULE;
typedef void* HINSTANCE;
typedef char* LPSTR;
typedef struct tagPOINT
{
int x, y;
} POINT;
#else // WIN32
#define PATH_SPLITTER "\\"
#ifdef __MINGW32__
#define _inline static inline
#define FORCEINLINE inline __attribute__((always_inline))
#else
#define FORCEINLINE __forceinline
#endif
#define open _open
#define read _read
#define alloca _alloca
// shut-up compiler warnings
#pragma warning(disable : 4244) // MIPS
#pragma warning(disable : 4018) // signed/unsigned mismatch
#pragma warning(disable : 4305) // truncation from const double to float
#pragma warning(disable : 4115) // named type definition in parentheses
#pragma warning(disable : 4100) // unreferenced formal parameter
#pragma warning(disable : 4127) // conditional expression is constant
#pragma warning(disable : 4057) // differs in indirection to slightly different base types
#pragma warning(disable : 4201) // nonstandard extension used
#pragma warning(disable : 4706) // assignment within conditional expression
#pragma warning(disable : 4054) // type cast' : from function pointer
#pragma warning(disable : 4310) // cast truncates constant value
#define HSPRITE WINAPI_HSPRITE
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
@@ -75,9 +130,13 @@ GNU General Public License for more details.
#define OS_LIB_PREFIX ""
#define OS_LIB_EXT "dll"
#define VGUI_SUPPORT_DLL "../vgui_support." OS_LIB_EXT
#ifdef XASH_64BIT
// windows NameForFunction not implemented yet
#define XASH_ALLOW_SAVERESTORE_OFFSETS
#endif
#define HAVE_DUP
#endif //WIN32
#endif //WIN32
#ifndef XASH_LOW_MEMORY
#define XASH_LOW_MEMORY 0
#endif

View File

@@ -82,7 +82,7 @@ typedef enum
TF_KEEP_SOURCE = (1<<1), // some images keep source
TF_NOFLIP_TGA = (1<<2), // Steam background completely ignore tga attribute 0x20
TF_EXPAND_SOURCE = (1<<3), // Don't keep source as 8-bit expand to RGBA
// reserved
TF_ALLOW_EMBOSS = (1<<4), // Allow emboss-mapping for this image
TF_RECTANGLE = (1<<5), // this is GL_TEXTURE_RECTANGLE
TF_CUBEMAP = (1<<6), // it's cubemap texture
TF_DEPTHMAP = (1<<7), // custom texture filter used
@@ -107,8 +107,6 @@ typedef enum
TF_ARB_FLOAT = (1<<26), // float textures
TF_NOCOMPARE = (1<<27), // disable comparing for depth textures
TF_ARB_16BIT = (1<<28), // keep image as 16-bit (not 24)
TF_MULTISAMPLE = (1<<29), // multisampling texture
TF_ALLOW_NEAREST = (1<<30), // allows toggling nearest filtering for TF_NOMIPMAP textures
} texFlags_t;
typedef enum
@@ -162,7 +160,7 @@ struct ref_viewpass_s;
typedef struct render_api_s
{
// Get renderer info (doesn't changes engine state at all)
intptr_t (*RenderGetParm)( int parm, int arg ); // generic
int (*RenderGetParm)( int parm, int arg ); // generic
void (*GetDetailScaleForTexture)( int texture, float *xScale, float *yScale );
void (*GetExtraParmsForTexture)( int texture, byte *red, byte *green, byte *blue, byte *alpha );
lightstyle_t* (*GetLightStyle)( int number );
@@ -230,7 +228,7 @@ typedef struct render_api_s
void (*R_Reserved0)( void );
// static allocations
void *(*pfnMemAlloc)( size_t cb, const char *filename, const int fileline ) ALLOC_CHECK( 1 );
void *(*pfnMemAlloc)( size_t cb, const char *filename, const int fileline );
void (*pfnMemFree)( void *mem, const char *filename, const int fileline );
// engine utils (not related with render API but placed here)

View File

@@ -1,24 +0,0 @@
/*
synctype.h -- shared synctype_t definition
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 2023 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 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 SYNCTYPE_H
#define SYNCTYPE_H
typedef enum {ST_SYNC=0, ST_RAND } synctype_t;
#endif

View File

@@ -2,19 +2,12 @@
#ifndef XASH_TYPES_H
#define XASH_TYPES_H
#include "build.h"
#if XASH_IRIX
#include <port.h>
#endif
#if XASH_WIN32
#ifdef _WIN32
#include <wchar.h> // off_t
#endif // _WIN32
#include <sys/types.h> // off_t
#include STDINT_H
#include <assert.h>
typedef unsigned char byte;
typedef int sound_t;
@@ -27,12 +20,7 @@ typedef byte rgba_t[4]; // unsigned byte colorpack
typedef byte rgb_t[3]; // unsigned byte colorpack
typedef vec_t matrix3x4[3][4];
typedef vec_t matrix4x4[4][4];
#if XASH_64BIT
typedef uint32_t poolhandle_t;
#else
typedef void* poolhandle_t;
#endif
#undef true
#undef false
@@ -50,14 +38,15 @@ typedef uint64_t longtime_t;
#define MAX_SERVERINFO_STRING 512 // server handles too many settings. expand to 1024?
#define MAX_LOCALINFO_STRING 32768 // localinfo used on server and not sended to the clients
#define MAX_SYSPATH 1024 // system filepath
#define MAX_VA_STRING 1024 // string length returned by va()
#define MAX_PRINT_MSG 8192 // how many symbols can handle single call of Con_Printf or Con_DPrintf
#define MAX_TOKEN 2048 // parse token length
#define MAX_MODS 512 // environment games that engine can keep visible
#define MAX_USERMSG_LENGTH 2048 // don't modify it's relies on a client-side definitions
#define BIT( n ) ( 1U << ( n ))
#define BIT64( n ) ( 1ULL << ( n ))
#define GAMMA ( 2.2f ) // Valve Software gamma
#define INVGAMMA ( 1.0f / 2.2f ) // back to 1.0
#define TEXGAMMA ( 0.9f ) // compensate dim textures
#define SetBits( iBitVector, bits ) ((iBitVector) = (iBitVector) | (bits))
#define ClearBits( iBitVector, bits ) ((iBitVector) = (iBitVector) & ~(bits))
#define FBitSet( iBitVector, bit ) ((iBitVector) & (bit))
@@ -75,68 +64,21 @@ typedef uint64_t longtime_t;
#define ColorIndex( c ) ((( c ) - '0' ) & 7 )
#if defined(__GNUC__)
#ifdef __i386__
#define EXPORT __attribute__ ((visibility ("default"),force_align_arg_pointer))
#define GAME_EXPORT __attribute((force_align_arg_pointer))
#else
#define EXPORT __attribute__ ((visibility ("default")))
#define GAME_EXPORT
#endif
#define _format(x) __attribute__((format(printf, x, x+1)))
#define NORETURN __attribute__((noreturn))
#define NONNULL __attribute__((nonnull))
#define ALLOC_CHECK(x) __attribute__((alloc_size(x)))
#define FORCEINLINE inline __attribute__((always_inline))
#define NOINLINE __attribute__((noinline))
#ifdef __i386__
#define EXPORT __attribute__ ((visibility ("default"),force_align_arg_pointer))
#define GAME_EXPORT __attribute((force_align_arg_pointer))
#else
#define EXPORT __attribute__ ((visibility ("default")))
#define GAME_EXPORT
#endif
#elif defined(_MSC_VER)
#define EXPORT __declspec( dllexport )
#define GAME_EXPORT
#define _format(x)
#define NORETURN
#define NONNULL
#define ALLOC_CHECK(x)
#define FORCEINLINE __forceinline
#define NOINLINE __declspec( noinline )
#define EXPORT __declspec( dllexport )
#define GAME_EXPORT
#else
#define EXPORT
#define GAME_EXPORT
#define _format(x)
#define NORETURN
#define NONNULL
#define ALLOC_CHECK(x)
#define FORCEINLINE
#define NOINLINE
#define EXPORT
#define GAME_EXPORT
#endif
#if ( __GNUC__ >= 3 )
#define unlikely(x) __builtin_expect(x, 0)
#define likely(x) __builtin_expect(x, 1)
#elif defined( __has_builtin )
#if __has_builtin( __builtin_expect )
#define unlikely(x) __builtin_expect(x, 0)
#define likely(x) __builtin_expect(x, 1)
#else
#define unlikely(x) (x)
#define likely(x) (x)
#endif
#else
#define unlikely(x) (x)
#define likely(x) (x)
#endif
#if __STDC_VERSION__ >= 202311L || __cplusplus >= 201103L // C23 or C++ static_assert is a keyword
#define STATIC_ASSERT_( ignore, x, y ) static_assert( x, y )
#define STATIC_ASSERT static_assert
#elif __STDC_VERSION__ >= 201112L // in C11 it's _Static_assert
#define STATIC_ASSERT_( ignore, x, y ) _Static_assert( x, y )
#define STATIC_ASSERT _Static_assert
#else
#define STATIC_ASSERT_( id, x, y ) extern int id[( x ) ? 1 : -1]
// need these to correctly expand the line macro
#define STATIC_ASSERT_3( line, x, y ) STATIC_ASSERT_( static_assert_ ## line, x, y )
#define STATIC_ASSERT_2( line, x, y ) STATIC_ASSERT_3( line, x, y )
#define STATIC_ASSERT( x, y ) STATIC_ASSERT_2( __LINE__, x, y )
#endif
#ifdef XASH_BIG_ENDIAN
#define LittleLong(x) (((int)(((x)&255)<<24)) + ((int)((((x)>>8)&255)<<16)) + ((int)(((x)>>16)&255)<<8) + (((x) >> 24)&255))
@@ -172,13 +114,9 @@ typedef unsigned int dword;
typedef unsigned int uint;
typedef char string[MAX_STRING];
typedef struct file_s file_t; // normal file
typedef struct wfile_s wfile_t; // wad file
typedef struct stream_s stream_t; // sound stream for background music playing
typedef off_t fs_offset_t;
#if XASH_WIN32
typedef int fs_size_t; // return type of _read, _write funcs
#else /* !XASH_WIN32 */
typedef ssize_t fs_size_t;
#endif /* !XASH_WIN32 */
typedef struct dllfunc_s
{
@@ -194,8 +132,7 @@ typedef struct dll_info_s
void *link; // hinstance of loading library
} dll_info_t;
typedef void (*setpair_t)( const char *key, const void *value, const void *buffer, void *numpairs );
typedef void *(*pfnCreateInterface_t)( const char *, int * );
typedef void (*setpair_t)( const char *key, const void *value, void *buffer, void *numpairs );
// config strings are a general means of communication from
// the server to all connected clients.

View File

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

269
contrib/mittorn/README.md Normal file
View File

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

7
contrib/mittorn/setup.sh Executable file
View File

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

73
contrib/mittorn/wscript Normal file
View File

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

View File

@@ -16,10 +16,6 @@
#ifndef ALIAS_H
#define ALIAS_H
#include "build.h"
#include STDINT_H
#include "synctype.h"
/*
==============================================================================
@@ -43,6 +39,16 @@ Alias models are position independent, so the cache manager can move them.
#define ALIAS_TRACER2 0x0040 // orange split trail + rotate
#define ALIAS_TRACER3 0x0080 // purple trail
// must match definition in sprite.h
#ifndef SYNCTYPE_T
#define SYNCTYPE_T
typedef enum
{
ST_SYNC = 0,
ST_RAND
} synctype_t;
#endif
typedef enum
{
ALIAS_SINGLE = 0,
@@ -57,42 +63,36 @@ typedef enum
typedef struct
{
int32_t ident;
int32_t version;
int ident;
int version;
vec3_t scale;
vec3_t scale_origin;
float boundingradius;
vec3_t eyeposition;
int32_t numskins;
int32_t skinwidth;
int32_t skinheight;
int32_t numverts;
int32_t numtris;
int32_t numframes;
uint32_t synctype; // was synctype_t
int32_t flags;
int numskins;
int skinwidth;
int skinheight;
int numverts;
int numtris;
int numframes;
synctype_t synctype;
int flags;
float size;
} daliashdr_t;
STATIC_ASSERT( sizeof( daliashdr_t ) == 84, "invalid daliashdr_t size" );
typedef struct
{
int32_t onseam;
int32_t s;
int32_t t;
int onseam;
int s;
int t;
} stvert_t;
STATIC_ASSERT( sizeof( stvert_t ) == 12, "invalid stvert_t size" );
typedef struct dtriangle_s
{
int32_t facesfront;
int32_t vertindex[3];
int facesfront;
int vertindex[3];
} dtriangle_t;
STATIC_ASSERT( sizeof( dtriangle_t ) == 16, "invalid dtriangle_t size" );
#define DT_FACES_FRONT 0x0010
#define ALIAS_ONSEAM 0x0020
@@ -103,50 +103,36 @@ typedef struct
char name[16]; // frame name from grabbing
} daliasframe_t;
STATIC_ASSERT( sizeof( daliasframe_t ) == 24, "invalid daliasframe_t size" );
typedef struct
{
int32_t numframes;
int numframes;
trivertex_t bboxmin; // lightnormal isn't used
trivertex_t bboxmax; // lightnormal isn't used
} daliasgroup_t;
STATIC_ASSERT( sizeof( daliasgroup_t ) == 12, "invalid daliasgrou_t size" );
typedef struct
{
int32_t numskins;
int numskins;
} daliasskingroup_t;
STATIC_ASSERT( sizeof( daliasskingroup_t ) == 4, "invalid daliasskingroup_t size" );
typedef struct
{
float interval;
} daliasinterval_t;
STATIC_ASSERT( sizeof( daliasinterval_t ) == 4, "invalid daliasinterval_t size" );
typedef struct
{
float interval;
} daliasskininterval_t;
STATIC_ASSERT( sizeof( daliasskininterval_t ) == 4, "invalid daliasskininterval_t size" );
typedef struct
{
uint32_t type; // was aliasframetype_t
aliasframetype_t type;
} daliasframetype_t;
STATIC_ASSERT( sizeof( daliasframetype_t ) == 4, "invalid daliasframetype_t size" );
typedef struct
{
uint32_t type; // was aliasskintype_t
aliasskintype_t type;
} daliasskintype_t;
STATIC_ASSERT( sizeof( daliasskintype_t ) == 4, "invalid daliasskintype_t size" );
#endif//ALIAS_H

View File

@@ -1,181 +1,177 @@
/*
Copyright (C) 1996-1997 Id Software, Inc.
/***
*
* 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.
*
****/
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.
*/
{-0.525731, 0.000000, 0.850651},
{-0.442863, 0.238856, 0.864188},
{-0.295242, 0.000000, 0.955423},
{-0.309017, 0.500000, 0.809017},
{-0.162460, 0.262866, 0.951056},
{0.000000, 0.000000, 1.000000},
{0.000000, 0.850651, 0.525731},
{-0.147621, 0.716567, 0.681718},
{0.147621, 0.716567, 0.681718},
{0.000000, 0.525731, 0.850651},
{0.309017, 0.500000, 0.809017},
{0.525731, 0.000000, 0.850651},
{0.295242, 0.000000, 0.955423},
{0.442863, 0.238856, 0.864188},
{0.162460, 0.262866, 0.951056},
{-0.681718, 0.147621, 0.716567},
{-0.809017, 0.309017, 0.500000},
{-0.587785, 0.425325, 0.688191},
{-0.850651, 0.525731, 0.000000},
{-0.864188, 0.442863, 0.238856},
{-0.716567, 0.681718, 0.147621},
{-0.688191, 0.587785, 0.425325},
{-0.500000, 0.809017, 0.309017},
{-0.238856, 0.864188, 0.442863},
{-0.425325, 0.688191, 0.587785},
{-0.716567, 0.681718, -0.147621},
{-0.500000, 0.809017, -0.309017},
{-0.525731, 0.850651, 0.000000},
{0.000000, 0.850651, -0.525731},
{-0.238856, 0.864188, -0.442863},
{0.000000, 0.955423, -0.295242},
{-0.262866, 0.951056, -0.162460},
{0.000000, 1.000000, 0.000000},
{0.000000, 0.955423, 0.295242},
{-0.262866, 0.951056, 0.162460},
{0.238856, 0.864188, 0.442863},
{0.262866, 0.951056, 0.162460},
{0.500000, 0.809017, 0.309017},
{0.238856, 0.864188, -0.442863},
{0.262866, 0.951056, -0.162460},
{0.500000, 0.809017, -0.309017},
{0.850651, 0.525731, 0.000000},
{0.716567, 0.681718, 0.147621},
{0.716567, 0.681718, -0.147621},
{0.525731, 0.850651, 0.000000},
{0.425325, 0.688191, 0.587785},
{0.864188, 0.442863, 0.238856},
{0.688191, 0.587785, 0.425325},
{0.809017, 0.309017, 0.500000},
{0.681718, 0.147621, 0.716567},
{0.587785, 0.425325, 0.688191},
{0.955423, 0.295242, 0.000000},
{1.000000, 0.000000, 0.000000},
{0.951056, 0.162460, 0.262866},
{0.850651, -0.525731, 0.000000},
{0.955423, -0.295242, 0.000000},
{0.864188, -0.442863, 0.238856},
{0.951056, -0.162460, 0.262866},
{0.809017, -0.309017, 0.500000},
{0.681718, -0.147621, 0.716567},
{0.850651, 0.000000, 0.525731},
{0.864188, 0.442863, -0.238856},
{0.809017, 0.309017, -0.500000},
{0.951056, 0.162460, -0.262866},
{0.525731, 0.000000, -0.850651},
{0.681718, 0.147621, -0.716567},
{0.681718, -0.147621, -0.716567},
{0.850651, 0.000000, -0.525731},
{0.809017, -0.309017, -0.500000},
{0.864188, -0.442863, -0.238856},
{0.951056, -0.162460, -0.262866},
{0.147621, 0.716567, -0.681718},
{0.309017, 0.500000, -0.809017},
{0.425325, 0.688191, -0.587785},
{0.442863, 0.238856, -0.864188},
{0.587785, 0.425325, -0.688191},
{0.688191, 0.587785, -0.425325},
{-0.147621, 0.716567, -0.681718},
{-0.309017, 0.500000, -0.809017},
{0.000000, 0.525731, -0.850651},
{-0.525731, 0.000000, -0.850651},
{-0.442863, 0.238856, -0.864188},
{-0.295242, 0.000000, -0.955423},
{-0.162460, 0.262866, -0.951056},
{0.000000, 0.000000, -1.000000},
{0.295242, 0.000000, -0.955423},
{0.162460, 0.262866, -0.951056},
{-0.442863, -0.238856, -0.864188},
{-0.309017, -0.500000, -0.809017},
{-0.162460, -0.262866, -0.951056},
{0.000000, -0.850651, -0.525731},
{-0.147621, -0.716567, -0.681718},
{0.147621, -0.716567, -0.681718},
{0.000000, -0.525731, -0.850651},
{0.309017, -0.500000, -0.809017},
{0.442863, -0.238856, -0.864188},
{0.162460, -0.262866, -0.951056},
{0.238856, -0.864188, -0.442863},
{0.500000, -0.809017, -0.309017},
{0.425325, -0.688191, -0.587785},
{0.716567, -0.681718, -0.147621},
{0.688191, -0.587785, -0.425325},
{0.587785, -0.425325, -0.688191},
{0.000000, -0.955423, -0.295242},
{0.000000, -1.000000, 0.000000},
{0.262866, -0.951056, -0.162460},
{0.000000, -0.850651, 0.525731},
{0.000000, -0.955423, 0.295242},
{0.238856, -0.864188, 0.442863},
{0.262866, -0.951056, 0.162460},
{0.500000, -0.809017, 0.309017},
{0.716567, -0.681718, 0.147621},
{0.525731, -0.850651, 0.000000},
{-0.238856, -0.864188, -0.442863},
{-0.500000, -0.809017, -0.309017},
{-0.262866, -0.951056, -0.162460},
{-0.850651, -0.525731, 0.000000},
{-0.716567, -0.681718, -0.147621},
{-0.716567, -0.681718, 0.147621},
{-0.525731, -0.850651, 0.000000},
{-0.500000, -0.809017, 0.309017},
{-0.238856, -0.864188, 0.442863},
{-0.262866, -0.951056, 0.162460},
{-0.864188, -0.442863, 0.238856},
{-0.809017, -0.309017, 0.500000},
{-0.688191, -0.587785, 0.425325},
{-0.681718, -0.147621, 0.716567},
{-0.442863, -0.238856, 0.864188},
{-0.587785, -0.425325, 0.688191},
{-0.309017, -0.500000, 0.809017},
{-0.147621, -0.716567, 0.681718},
{-0.425325, -0.688191, 0.587785},
{-0.162460, -0.262866, 0.951056},
{0.442863, -0.238856, 0.864188},
{0.162460, -0.262866, 0.951056},
{0.309017, -0.500000, 0.809017},
{0.147621, -0.716567, 0.681718},
{0.000000, -0.525731, 0.850651},
{0.425325, -0.688191, 0.587785},
{0.587785, -0.425325, 0.688191},
{0.688191, -0.587785, 0.425325},
{-0.955423, 0.295242, 0.000000},
{-0.951056, 0.162460, 0.262866},
{-1.000000, 0.000000, 0.000000},
{-0.850651, 0.000000, 0.525731},
{-0.955423, -0.295242, 0.000000},
{-0.951056, -0.162460, 0.262866},
{-0.864188, 0.442863, -0.238856},
{-0.951056, 0.162460, -0.262866},
{-0.809017, 0.309017, -0.500000},
{-0.864188, -0.442863, -0.238856},
{-0.951056, -0.162460, -0.262866},
{-0.809017, -0.309017, -0.500000},
{-0.681718, 0.147621, -0.716567},
{-0.681718, -0.147621, -0.716567},
{-0.850651, 0.000000, -0.525731},
{-0.688191, 0.587785, -0.425325},
{-0.587785, 0.425325, -0.688191},
{-0.425325, 0.688191, -0.587785},
{-0.425325, -0.688191, -0.587785},
{-0.587785, -0.425325, -0.688191},
{-0.688191, -0.587785, -0.425325},
{-0.525731, 0.000000, 0.850651},
{-0.442863, 0.238856, 0.864188},
{-0.295242, 0.000000, 0.955423},
{-0.309017, 0.500000, 0.809017},
{-0.162460, 0.262866, 0.951056},
{0.000000, 0.000000, 1.000000},
{0.000000, 0.850651, 0.525731},
{-0.147621, 0.716567, 0.681718},
{0.147621, 0.716567, 0.681718},
{0.000000, 0.525731, 0.850651},
{0.309017, 0.500000, 0.809017},
{0.525731, 0.000000, 0.850651},
{0.295242, 0.000000, 0.955423},
{0.442863, 0.238856, 0.864188},
{0.162460, 0.262866, 0.951056},
{-0.681718, 0.147621, 0.716567},
{-0.809017, 0.309017, 0.500000},
{-0.587785, 0.425325, 0.688191},
{-0.850651, 0.525731, 0.000000},
{-0.864188, 0.442863, 0.238856},
{-0.716567, 0.681718, 0.147621},
{-0.688191, 0.587785, 0.425325},
{-0.500000, 0.809017, 0.309017},
{-0.238856, 0.864188, 0.442863},
{-0.425325, 0.688191, 0.587785},
{-0.716567, 0.681718, -0.147621},
{-0.500000, 0.809017, -0.309017},
{-0.525731, 0.850651, 0.000000},
{0.000000, 0.850651, -0.525731},
{-0.238856, 0.864188, -0.442863},
{0.000000, 0.955423, -0.295242},
{-0.262866, 0.951056, -0.162460},
{0.000000, 1.000000, 0.000000},
{0.000000, 0.955423, 0.295242},
{-0.262866, 0.951056, 0.162460},
{0.238856, 0.864188, 0.442863},
{0.262866, 0.951056, 0.162460},
{0.500000, 0.809017, 0.309017},
{0.238856, 0.864188, -0.442863},
{0.262866, 0.951056, -0.162460},
{0.500000, 0.809017, -0.309017},
{0.850651, 0.525731, 0.000000},
{0.716567, 0.681718, 0.147621},
{0.716567, 0.681718, -0.147621},
{0.525731, 0.850651, 0.000000},
{0.425325, 0.688191, 0.587785},
{0.864188, 0.442863, 0.238856},
{0.688191, 0.587785, 0.425325},
{0.809017, 0.309017, 0.500000},
{0.681718, 0.147621, 0.716567},
{0.587785, 0.425325, 0.688191},
{0.955423, 0.295242, 0.000000},
{1.000000, 0.000000, 0.000000},
{0.951056, 0.162460, 0.262866},
{0.850651, -0.525731, 0.000000},
{0.955423, -0.295242, 0.000000},
{0.864188, -0.442863, 0.238856},
{0.951056, -0.162460, 0.262866},
{0.809017, -0.309017, 0.500000},
{0.681718, -0.147621, 0.716567},
{0.850651, 0.000000, 0.525731},
{0.864188, 0.442863, -0.238856},
{0.809017, 0.309017, -0.500000},
{0.951056, 0.162460, -0.262866},
{0.525731, 0.000000, -0.850651},
{0.681718, 0.147621, -0.716567},
{0.681718, -0.147621, -0.716567},
{0.850651, 0.000000, -0.525731},
{0.809017, -0.309017, -0.500000},
{0.864188, -0.442863, -0.238856},
{0.951056, -0.162460, -0.262866},
{0.147621, 0.716567, -0.681718},
{0.309017, 0.500000, -0.809017},
{0.425325, 0.688191, -0.587785},
{0.442863, 0.238856, -0.864188},
{0.587785, 0.425325, -0.688191},
{0.688191, 0.587785, -0.425325},
{-0.147621, 0.716567, -0.681718},
{-0.309017, 0.500000, -0.809017},
{0.000000, 0.525731, -0.850651},
{-0.525731, 0.000000, -0.850651},
{-0.442863, 0.238856, -0.864188},
{-0.295242, 0.000000, -0.955423},
{-0.162460, 0.262866, -0.951056},
{0.000000, 0.000000, -1.000000},
{0.295242, 0.000000, -0.955423},
{0.162460, 0.262866, -0.951056},
{-0.442863, -0.238856, -0.864188},
{-0.309017, -0.500000, -0.809017},
{-0.162460, -0.262866, -0.951056},
{0.000000, -0.850651, -0.525731},
{-0.147621, -0.716567, -0.681718},
{0.147621, -0.716567, -0.681718},
{0.000000, -0.525731, -0.850651},
{0.309017, -0.500000, -0.809017},
{0.442863, -0.238856, -0.864188},
{0.162460, -0.262866, -0.951056},
{0.238856, -0.864188, -0.442863},
{0.500000, -0.809017, -0.309017},
{0.425325, -0.688191, -0.587785},
{0.716567, -0.681718, -0.147621},
{0.688191, -0.587785, -0.425325},
{0.587785, -0.425325, -0.688191},
{0.000000, -0.955423, -0.295242},
{0.000000, -1.000000, 0.000000},
{0.262866, -0.951056, -0.162460},
{0.000000, -0.850651, 0.525731},
{0.000000, -0.955423, 0.295242},
{0.238856, -0.864188, 0.442863},
{0.262866, -0.951056, 0.162460},
{0.500000, -0.809017, 0.309017},
{0.716567, -0.681718, 0.147621},
{0.525731, -0.850651, 0.000000},
{-0.238856, -0.864188, -0.442863},
{-0.500000, -0.809017, -0.309017},
{-0.262866, -0.951056, -0.162460},
{-0.850651, -0.525731, 0.000000},
{-0.716567, -0.681718, -0.147621},
{-0.716567, -0.681718, 0.147621},
{-0.525731, -0.850651, 0.000000},
{-0.500000, -0.809017, 0.309017},
{-0.238856, -0.864188, 0.442863},
{-0.262866, -0.951056, 0.162460},
{-0.864188, -0.442863, 0.238856},
{-0.809017, -0.309017, 0.500000},
{-0.688191, -0.587785, 0.425325},
{-0.681718, -0.147621, 0.716567},
{-0.442863, -0.238856, 0.864188},
{-0.587785, -0.425325, 0.688191},
{-0.309017, -0.500000, 0.809017},
{-0.147621, -0.716567, 0.681718},
{-0.425325, -0.688191, 0.587785},
{-0.162460, -0.262866, 0.951056},
{0.442863, -0.238856, 0.864188},
{0.162460, -0.262866, 0.951056},
{0.309017, -0.500000, 0.809017},
{0.147621, -0.716567, 0.681718},
{0.000000, -0.525731, 0.850651},
{0.425325, -0.688191, 0.587785},
{0.587785, -0.425325, 0.688191},
{0.688191, -0.587785, 0.425325},
{-0.955423, 0.295242, 0.000000},
{-0.951056, 0.162460, 0.262866},
{-1.000000, 0.000000, 0.000000},
{-0.850651, 0.000000, 0.525731},
{-0.955423, -0.295242, 0.000000},
{-0.951056, -0.162460, 0.262866},
{-0.864188, 0.442863, -0.238856},
{-0.951056, 0.162460, -0.262866},
{-0.809017, 0.309017, -0.500000},
{-0.864188, -0.442863, -0.238856},
{-0.951056, -0.162460, -0.262866},
{-0.809017, -0.309017, -0.500000},
{-0.681718, 0.147621, -0.716567},
{-0.681718, -0.147621, -0.716567},
{-0.850651, 0.000000, -0.525731},
{-0.688191, 0.587785, -0.425325},
{-0.587785, 0.425325, -0.688191},
{-0.425325, 0.688191, -0.587785},
{-0.425325, -0.688191, -0.587785},
{-0.587785, -0.425325, -0.688191},
{-0.688191, -0.587785, -0.425325},

View File

@@ -27,6 +27,7 @@ int AVI_GetAudioChunk( movie_state_t *Avi, char *audiodata, int offset, int leng
void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audio, int quiet );
movie_state_t *AVI_LoadVideo( const char *filename, qboolean load_audio );
int AVI_TimeToSoundPosition( movie_state_t *Avi, int time );
int AVI_GetVideoFrameCount( movie_state_t *Avi );
void AVI_CloseVideo( movie_state_t *Avi );
qboolean AVI_IsActive( movie_state_t *Avi );
void AVI_FreeVideo( movie_state_t *Avi );

View File

@@ -57,6 +57,11 @@ int AVI_TimeToSoundPosition( movie_state_t *Avi, int time )
return 0;
}
int AVI_GetVideoFrameCount( movie_state_t *Avi )
{
return 0;
}
void AVI_CloseVideo( movie_state_t *Avi )
{
;

View File

@@ -1,6 +1,5 @@
/*
avi_win.c - playing AVI files (based on original AVIKit code, Win32 version)
Copyright (c) 2003-2004, Ruari O'Sullivan
Copyright (C) 2010 Uncle Mike
This program is free software: you can redistribute it and/or modify
@@ -64,7 +63,7 @@ static int (_stdcall *pAVIStreamTimeToSample)( PAVISTREAM pavi, LONG lTime );
static void* (_stdcall *pAVIStreamGetFrame)( PGETFRAME pg, LONG lPos );
static int (_stdcall *pAVIStreamGetFrameClose)( PGETFRAME pg );
static dword (_stdcall *pAVIStreamRelease)( PAVISTREAM pavi );
static int (_stdcall *pAVIFileOpenW)( PAVIFILE *ppfile, LPCWSTR szFile, UINT uMode, LPCLSID lpHandler );
static int (_stdcall *pAVIFileOpen)( PAVIFILE *ppfile, LPCSTR szFile, UINT uMode, LPCLSID lpHandler );
static int (_stdcall *pAVIFileGetStream)( PAVIFILE pfile, PAVISTREAM *ppavi, DWORD fccType, LONG lParam );
static int (_stdcall *pAVIStreamReadFormat)( PAVISTREAM pavi, LONG lPos,LPVOID lpFormat, LONG *lpcbFormat );
static int (_stdcall *pAVIStreamStart)( PAVISTREAM pavi );
@@ -77,7 +76,7 @@ static dllfunc_t avifile_funcs[] =
{ "AVIFileExit", (void **) &pAVIFileExit },
{ "AVIFileGetStream", (void **) &pAVIFileGetStream },
{ "AVIFileInit", (void **) &pAVIFileInit },
{ "AVIFileOpenW", (void **) &pAVIFileOpenW },
{ "AVIFileOpenA", (void **) &pAVIFileOpen },
{ "AVIFileRelease", (void **) &pAVIFileRelease },
{ "AVIStreamGetFrame", (void **) &pAVIStreamGetFrame },
{ "AVIStreamGetFrameClose", (void **) &pAVIStreamGetFrameClose },
@@ -279,6 +278,14 @@ int AVI_GetVideoFrameNumber( movie_state_t *Avi, float time )
return (time * Avi->video_fps);
}
int AVI_GetVideoFrameCount( movie_state_t *Avi )
{
if( !Avi->active )
return 0;
return Avi->video_frames;
}
int AVI_TimeToSoundPosition( movie_state_t *Avi, int time )
{
if( !Avi->active || !Avi->audio_stream )
@@ -486,7 +493,6 @@ void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audi
AVISTREAMINFO stream_info;
int opened_streams = 0;
LONG hr;
wchar_t pathBuffer[MAX_PATH];
// default state: non-working.
Avi->active = false;
@@ -495,15 +501,8 @@ void AVI_OpenVideo( movie_state_t *Avi, const char *filename, qboolean load_audi
// can't load Video For Windows :-(
if( !avi_initialized ) return;
// convert to wide char
if( MultiByteToWideChar( CP_UTF8, 0, filename, -1, pathBuffer, ARRAYSIZE( pathBuffer )) <= 0 )
{
Con_DPrintf( S_ERROR "filename buffer limit exceeded\n" );
return;
}
// load the AVI
hr = pAVIFileOpenW( &Avi->pfile, pathBuffer, OF_SHARE_DENY_WRITE, 0L );
hr = pAVIFileOpen( &Avi->pfile, filename, OF_SHARE_DENY_WRITE, 0L );
if( hr != 0 ) // error opening AVI:
{
@@ -658,7 +657,7 @@ movie_state_t *AVI_LoadVideo( const char *filename, qboolean load_audio )
// open cinematic
Q_snprintf( path, sizeof( path ), "media/%s", filename );
COM_DefaultExtension( path, ".avi", sizeof( path ));
COM_DefaultExtension( path, ".avi" );
fullpath = FS_GetDiskPath( path, false );
if( FS_FileExists( path, false ) && !fullpath )

View File

@@ -85,12 +85,6 @@ void CL_PlayCDTrack_f( void )
paused = false;
looped = false;
}
else if( !Q_stricmp( command, "playfile" ))
{
S_StartBackgroundTrack( pszTrack, NULL, 0, true );
paused = false;
looped = false;
}
else if( !Q_stricmp( command, "loop" ))
{
if( Q_isdigit( pszTrack ))
@@ -102,12 +96,6 @@ void CL_PlayCDTrack_f( void )
paused = false;
looped = true;
}
else if( !Q_stricmp( command, "loopfile" ))
{
S_StartBackgroundTrack( pszTrack, pszTrack, 0, true );
paused = false;
looped = true;
}
else if( !Q_stricmp( command, "pause" ))
{
S_StreamSetPause( true );
@@ -157,12 +145,36 @@ void CL_PlayCDTrack_f( void )
CL_ScreenshotGetName
==================
*/
static qboolean CL_ScreenshotGetName( const char *fmt, int lastnum, char *filename, size_t size )
qboolean CL_ScreenshotGetName( int lastnum, char *filename )
{
if( lastnum < 0 || lastnum > 9999 )
{
Con_Printf( S_ERROR "unable to write screenshot\n" );
return false;
}
return Q_snprintf( filename, size, fmt, clgame.mapname, lastnum ) > 0;
Q_sprintf( filename, "scrshots/%s_shot%04d.png", clgame.mapname, lastnum );
return true;
}
/*
==================
CL_SnapshotGetName
==================
*/
qboolean CL_SnapshotGetName( int lastnum, char *filename )
{
if( lastnum < 0 || lastnum > 9999 )
{
Con_Printf( S_ERROR "unable to write snapshot\n" );
FS_AllowDirectPaths( false );
return false;
}
Q_sprintf( filename, "../%s_%04d.png", clgame.mapname, lastnum );
return true;
}
/*
@@ -172,6 +184,127 @@ static qboolean CL_ScreenshotGetName( const char *fmt, int lastnum, char *filena
==============================================================================
*/
/*
==================
CL_ScreenShot_f
normal screenshot
==================
*/
void CL_ScreenShot_f( void )
{
int i;
string checkname;
if( CL_IsDevOverviewMode() == 1 )
{
// special case for write overview image and script file
Q_snprintf( cls.shotname, sizeof( cls.shotname ), "overviews/%s.bmp", clgame.mapname );
cls.scrshot_action = scrshot_mapshot; // build new frame for mapshot
}
else
{
// scan for a free filename
for( i = 0; i < 9999; i++ )
{
if( !CL_ScreenshotGetName( i, checkname ))
return; // no namespace
if( !FS_FileExists( checkname, false ))
break;
}
Q_strncpy( cls.shotname, checkname, sizeof( cls.shotname ));
cls.scrshot_action = scrshot_normal; // build new frame for screenshot
}
cls.envshot_vieworg = NULL; // no custom view
cls.envshot_viewsize = 0;
}
/*
==================
CL_SnapShot_f
save screenshots into root dir
==================
*/
void CL_SnapShot_f( void )
{
int i;
string checkname;
if( CL_IsDevOverviewMode() == 1 )
{
// special case for write overview image and script file
Q_snprintf( cls.shotname, sizeof( cls.shotname ), "overviews/%s.bmp", clgame.mapname );
cls.scrshot_action = scrshot_mapshot; // build new frame for mapshot
}
else
{
FS_AllowDirectPaths( true );
// scan for a free filename
for( i = 0; i < 9999; i++ )
{
if( !CL_SnapshotGetName( i, checkname ))
return; // no namespace
if( !FS_FileExists( checkname, false ))
break;
}
FS_AllowDirectPaths( false );
Q_strncpy( cls.shotname, checkname, sizeof( cls.shotname ));
cls.scrshot_action = scrshot_snapshot; // build new frame for screenshot
}
cls.envshot_vieworg = NULL; // no custom view
cls.envshot_viewsize = 0;
}
/*
==================
CL_EnvShot_f
cubemap view
==================
*/
void CL_EnvShot_f( void )
{
if( Cmd_Argc() < 2 )
{
Con_Printf( S_USAGE "envshot <shotname>\n" );
return;
}
Q_sprintf( cls.shotname, "gfx/env/%s", Cmd_Argv( 1 ));
cls.scrshot_action = scrshot_envshot; // build new frame for envshot
cls.envshot_vieworg = NULL; // no custom view
cls.envshot_viewsize = 0;
}
/*
==================
CL_SkyShot_f
skybox view
==================
*/
void CL_SkyShot_f( void )
{
if( Cmd_Argc() < 2 )
{
Con_Printf( S_USAGE "skyshot <shotname>\n" );
return;
}
Q_sprintf( cls.shotname, "gfx/env/%s", Cmd_Argv( 1 ));
cls.scrshot_action = scrshot_skyshot; // build new frame for skyshot
cls.envshot_vieworg = NULL; // no custom view
cls.envshot_viewsize = 0;
}
/*
==================
CL_LevelShot_f
@@ -190,8 +323,7 @@ void CL_LevelShot_f( void )
// check for exist
if( cls.demoplayback && ( cls.demonum != -1 ))
{
Q_snprintf( cls.shotname, sizeof( cls.shotname ),
"levelshots/%s_%s.bmp", cls.demoname, refState.wideScreen ? "16x9" : "4x3" );
Q_sprintf( cls.shotname, "levelshots/%s_%s.bmp", cls.demoname, refState.wideScreen ? "16x9" : "4x3" );
Q_snprintf( filename, sizeof( filename ), "%s.dem", cls.demoname );
// make sure what levelshot is newer than demo
@@ -200,8 +332,7 @@ void CL_LevelShot_f( void )
}
else
{
Q_snprintf( cls.shotname, sizeof( cls.shotname ),
"levelshots/%s_%s.bmp", clgame.mapname, refState.wideScreen ? "16x9" : "4x3" );
Q_sprintf( cls.shotname, "levelshots/%s_%s.bmp", clgame.mapname, refState.wideScreen ? "16x9" : "4x3" );
// make sure what levelshot is newer than bsp
ft1 = FS_FileTime( cl.worldmodel->name, false );
@@ -214,100 +345,23 @@ void CL_LevelShot_f( void )
else cls.scrshot_action = scrshot_inactive; // disable - not needs
}
static scrshot_t CL_GetScreenshotTypeFromString( const char *string )
/*
==================
CL_SaveShot_f
mini-pic in loadgame menu
==================
*/
void CL_SaveShot_f( void )
{
if( !Q_stricmp( string, "snapshot" ))
return scrshot_snapshot;
if( !Q_stricmp( string, "screenshot" ))
return scrshot_normal;
if( !Q_stricmp( string, "saveshot" ))
return scrshot_savegame;
if( !Q_stricmp( string, "envshot" ))
return scrshot_envshot;
if( !Q_stricmp( string, "skyshot" ))
return scrshot_skyshot;
return scrshot_inactive;
}
void CL_GenericShot_f( void )
{
const char *argv0 = Cmd_Argv( 0 );
scrshot_t type;
type = CL_GetScreenshotTypeFromString( argv0 );
if( type == scrshot_normal || type == scrshot_snapshot )
if( Cmd_Argc() < 2 )
{
if( CL_IsDevOverviewMode() == 1 )
type = scrshot_mapshot;
}
else
{
if( Cmd_Argc() < 2 )
{
Con_Printf( S_USAGE "%s <shotname>\n", argv0 );
return;
}
Con_Printf( S_USAGE "saveshot <savename>\n" );
return;
}
switch( type )
{
case scrshot_envshot:
case scrshot_skyshot:
Q_snprintf( cls.shotname, sizeof( cls.shotname ), "gfx/env/%s", Cmd_Argv( 1 ));
break;
case scrshot_savegame:
Q_snprintf( cls.shotname, sizeof( cls.shotname ), DEFAULT_SAVE_DIRECTORY "%s.bmp", Cmd_Argv( 1 ));
break;
case scrshot_mapshot:
Q_snprintf( cls.shotname, sizeof( cls.shotname ), "overviews/%s.bmp", clgame.mapname );
break;
case scrshot_normal:
case scrshot_snapshot:
{
const char *fmt;
string checkname;
int i;
if( type == scrshot_snapshot )
{
fmt = "../%s_%04d.png";
FS_AllowDirectPaths( true );
}
else fmt = "scrshots/%s_shot%04d.png";
for( i = 0; i < 9999; i++ )
{
if( !CL_ScreenshotGetName( fmt, i, checkname, sizeof( checkname )))
{
Con_Printf( S_ERROR "unable to write %s\n", argv0 );
FS_AllowDirectPaths( false );
return;
}
if( !FS_FileExists( checkname, true ))
break;
}
FS_AllowDirectPaths( false );
Q_strncpy( cls.shotname, checkname, sizeof( cls.shotname ));
break;
}
case scrshot_inactive:
case scrshot_plaque:
default:
return; // shouldn't happen
}
cls.scrshot_action = type; // build new frame for saveshot
cls.envshot_vieworg = NULL;
cls.envshot_viewsize = 0;
Q_sprintf( cls.shotname, DEFAULT_SAVE_DIRECTORY "%s.bmp", Cmd_Argv( 1 ));
cls.scrshot_action = scrshot_savegame; // build new frame for saveshot
}
/*

View File

@@ -78,7 +78,7 @@ qboolean CL_CheckFile( sizebuf_t *msg, resource_t *pResource )
}
MSG_BeginClientCmd( msg, clc_stringcmd );
MSG_WriteStringf( msg, "dlfile %s", filepath );
MSG_WriteString( msg, va( "dlfile %s", filepath ));
host.downloadcount++;
return false;
@@ -106,7 +106,7 @@ void CL_RemoveFromResourceList( resource_t *pResource )
if( pResource->pPrev == NULL || pResource->pNext == NULL )
Host_Error( "mislinked resource in CL_RemoveFromResourceList\n" );
if( pResource->pNext == pResource || pResource->pPrev == pResource )
if ( pResource->pNext == pResource || pResource->pPrev == pResource )
Host_Error( "attempt to free last entry in list.\n" );
pResource->pPrev->pNext = pResource->pNext;
@@ -127,7 +127,7 @@ void CL_MoveToOnHandList( resource_t *pResource )
CL_AddToResourceList( pResource, &cl.resourcesonhand );
}
static void CL_ClearResourceList( resource_t *pList )
void CL_ClearResourceList( resource_t *pList )
{
resource_t *p, *n;

View File

@@ -25,6 +25,70 @@ GNU General Public License for more details.
#define MSG_COUNT 32 // last 32 messages parsed
#define MSG_MASK (MSG_COUNT - 1)
const char *svc_strings[svc_lastmsg+1] =
{
"svc_bad",
"svc_nop",
"svc_disconnect",
"svc_event",
"svc_changing",
"svc_setview",
"svc_sound",
"svc_time",
"svc_print",
"svc_stufftext",
"svc_setangle",
"svc_serverdata",
"svc_lightstyle",
"svc_updateuserinfo",
"svc_deltatable",
"svc_clientdata",
"svc_resource",
"svc_pings",
"svc_particle",
"svc_restoresound",
"svc_spawnstatic",
"svc_event_reliable",
"svc_spawnbaseline",
"svc_temp_entity",
"svc_setpause",
"svc_signonnum",
"svc_centerprint",
"svc_unused27",
"svc_unused28",
"svc_unused29",
"svc_intermission",
"svc_finale",
"svc_cdtrack",
"svc_restore",
"svc_cutscene",
"svc_weaponanim",
"svc_bspdecal",
"svc_roomtype",
"svc_addangle",
"svc_usermessage",
"svc_packetentities",
"svc_deltapacketentities",
"svc_choke",
"svc_resourcelist",
"svc_deltamovevars",
"svc_resourcerequest",
"svc_customization",
"svc_crosshairangle",
"svc_soundfade",
"svc_filetxferfailed",
"svc_hltv",
"svc_director",
"svc_voiceinit",
"svc_voicedata",
"svc_deltapacketbones",
"svc_unused55",
"svc_resourcelocation",
"svc_querycvarvalue",
"svc_querycvarvalue2",
"svc_exec",
};
typedef struct
{
int command;
@@ -45,7 +109,7 @@ const char *CL_MsgInfo( int cmd )
{
static string sz;
Q_strncpy( sz, "???", sizeof( sz ));
Q_strcpy( sz, "???" );
if( cmd >= 0 && cmd <= svc_lastmsg )
{

View File

@@ -107,8 +107,6 @@ struct
int angle_position;
} demo;
static qboolean CL_NextDemo( void );
/*
====================
CL_StartupDemoHeader
@@ -158,7 +156,7 @@ CL_GetDemoRecordClock
write time while demo is recording
====================
*/
static float CL_GetDemoRecordClock( void )
float CL_GetDemoRecordClock( void )
{
return cl.mtime[0];
}
@@ -170,7 +168,7 @@ CL_GetDemoPlaybackClock
overwrite host.realtime
====================
*/
static float CL_GetDemoPlaybackClock( void )
float CL_GetDemoPlaybackClock( void )
{
return host.realtime + host.frametime;
}
@@ -196,7 +194,7 @@ CL_WriteDemoCmdHeader
Writes the demo command header and time-delta
====================
*/
static void CL_WriteDemoCmdHeader( byte cmd, file_t *file )
void CL_WriteDemoCmdHeader( byte cmd, file_t *file )
{
float dt;
@@ -269,7 +267,7 @@ Save state of cls.netchan sequences
so that we can play the demo correctly.
====================
*/
static void CL_WriteDemoSequence( file_t *file )
void CL_WriteDemoSequence( file_t *file )
{
Assert( file != NULL );
@@ -350,7 +348,7 @@ CL_WriteDemoHeader
Write demo header
====================
*/
static void CL_WriteDemoHeader( const char *name )
void CL_WriteDemoHeader( const char *name )
{
int copysize;
int savepos;
@@ -374,7 +372,7 @@ static void CL_WriteDemoHeader( const char *name )
demo.header.id = IDEMOHEADER;
demo.header.dem_protocol = DEMO_PROTOCOL;
demo.header.net_protocol = cls.legacymode ? PROTOCOL_LEGACY_VERSION : PROTOCOL_VERSION;
demo.header.host_fps = host_maxfps.value ? bound( MIN_FPS, host_maxfps.value, MAX_FPS ) : MAX_FPS;
demo.header.host_fps = bound( MIN_FPS, host_maxfps->value, MAX_FPS );
Q_strncpy( demo.header.mapname, clgame.mapname, sizeof( demo.header.mapname ));
Q_strncpy( demo.header.comment, clgame.maptitle, sizeof( demo.header.comment ));
Q_strncpy( demo.header.gamedir, FS_Gamedir(), sizeof( demo.header.gamedir ));
@@ -438,7 +436,7 @@ CL_StopRecord
finish recording demo
=================
*/
static void CL_StopRecord( void )
void CL_StopRecord( void )
{
int i, curpos;
float stoptime;
@@ -520,26 +518,14 @@ CL_ReadDemoCmdHeader
read the demo command
=================
*/
static qboolean CL_ReadDemoCmdHeader( byte *cmd, float *dt )
void CL_ReadDemoCmdHeader( byte *cmd, float *dt )
{
// read the command
// HACKHACK: skip NOPs
do
{
FS_Read( cls.demofile, cmd, sizeof( byte ));
} while( *cmd == dem_unknown );
if( *cmd > dem_lastcmd )
{
Con_Printf( S_ERROR "Demo cmd %d > %d, file offset = %d\n", *cmd, dem_lastcmd, (int)FS_Tell( cls.demofile ));
CL_DemoCompleted();
return false;
}
FS_Read( cls.demofile, cmd, sizeof( byte ));
Assert( *cmd >= 1 && *cmd <= dem_lastcmd );
// read the timestamp
FS_Read( cls.demofile, dt, sizeof( float ));
return true;
}
/*
@@ -550,7 +536,7 @@ read the demo usercmd for predicting
and smooth movement during playback the demo
=================
*/
static void CL_ReadDemoUserCmd( qboolean discard )
void CL_ReadDemoUserCmd( qboolean discard )
{
byte data[1024];
int cmdnumber;
@@ -572,9 +558,6 @@ static void CL_ReadDemoUserCmd( qboolean discard )
memset( &nullcmd, 0, sizeof( nullcmd ));
MSG_Init( &buf, "UserCmd", data, sizeof( data ));
// a1ba: I have no proper explanation why
cmdnumber++;
pcmd = &cl.commands[cmdnumber & CL_UPDATE_MASK];
pcmd->processedfuncs = false;
pcmd->senttime = 0.0f;
@@ -615,7 +598,7 @@ CL_ReadDemoSequence
read netchan sequences
=================
*/
static void CL_ReadDemoSequence( qboolean discard )
void CL_ReadDemoSequence( qboolean discard )
{
int incoming_sequence;
int incoming_acknowledged;
@@ -649,17 +632,15 @@ static void CL_ReadDemoSequence( qboolean discard )
CL_DemoStartPlayback
=================
*/
static void CL_DemoStartPlayback( int mode )
void CL_DemoStartPlayback( int mode )
{
if( cls.changedemo )
{
int maxclients = cl.maxclients;
S_StopAllSounds( true );
SCR_BeginLoadingPlaque( false );
CL_ClearState( );
CL_InitEdicts( maxclients ); // re-arrange edicts
CL_ClearState ();
CL_InitEdicts (); // re-arrange edicts
}
else
{
@@ -694,7 +675,7 @@ static void CL_DemoStartPlayback( int mode )
CL_DemoAborted
=================
*/
static void CL_DemoAborted( void )
void CL_DemoAborted( void )
{
if( cls.demofile )
FS_Close( cls.demofile );
@@ -705,7 +686,7 @@ static void CL_DemoAborted( void )
cls.demofile = NULL;
cls.demonum = -1;
Cvar_DirectSet( &v_dark, "0" );
Cvar_SetValue( "v_dark", 0.0f );
}
/*
@@ -723,7 +704,7 @@ void CL_DemoCompleted( void )
if( !CL_NextDemo() && !cls.changedemo )
UI_SetActiveMenu( true );
Cvar_DirectSet( &v_dark, "0" );
Cvar_SetValue( "v_dark", 0.0f );
}
/*
@@ -734,7 +715,7 @@ returns true on success, false on failure
g-cont. probably captain obvious mode is ON
=================
*/
static qboolean CL_DemoMoveToNextSection( void )
qboolean CL_DemoMoveToNextSection( void )
{
if( ++demo.entryIndex >= demo.directory.numentries )
{
@@ -756,7 +737,7 @@ static qboolean CL_DemoMoveToNextSection( void )
return true;
}
static qboolean CL_ReadRawNetworkData( byte *buffer, size_t *length )
qboolean CL_ReadRawNetworkData( byte *buffer, size_t *length )
{
int msglen = 0;
@@ -807,7 +788,7 @@ CL_DemoReadMessageQuake
reads demo data and write it to client
=================
*/
static qboolean CL_DemoReadMessageQuake( byte *buffer, size_t *length )
qboolean CL_DemoReadMessageQuake( byte *buffer, size_t *length )
{
vec3_t viewangles;
int msglen = 0;
@@ -907,7 +888,7 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length )
qboolean swallowmessages = true;
static int tdlastdemoframe = 0;
byte *userbuf = NULL;
size_t size = 0;
size_t size;
byte cmd;
if( !cls.demofile )
@@ -932,8 +913,7 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length )
if( !cls.demofile ) break;
curpos = FS_Tell( cls.demofile );
if( !CL_ReadDemoCmdHeader( &cmd, &demo.timestamp ))
return false;
CL_ReadDemoCmdHeader( &cmd, &demo.timestamp );
fElapsedTime = CL_GetDemoPlaybackClock() - demo.starttime;
if( !cls.timedemo ) bSkipMessage = ((demo.timestamp - cl_serverframetime()) >= fElapsedTime) ? true : false;
@@ -1022,7 +1002,7 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length )
return CL_ReadRawNetworkData( buffer, length );
}
static void CL_DemoFindInterpolatedViewAngles( float t, float *frac, demoangle_t **prev, demoangle_t **next )
void CL_DemoFindInterpolatedViewAngles( float t, float *frac, demoangle_t **prev, demoangle_t **next )
{
int i, i0, i1, imod;
float at;
@@ -1117,7 +1097,7 @@ CL_FinishTimeDemo
show stats
==============
*/
static void CL_FinishTimeDemo( void )
void CL_FinishTimeDemo( void )
{
int frames;
double time;
@@ -1129,10 +1109,7 @@ static void CL_FinishTimeDemo( void )
time = host.realtime - cls.td_starttime;
if( !time ) time = 1.0;
Con_Printf( "timedemo result: %i frames %5.3f seconds %5.3f fps\n", frames, time, frames / time );
if( Sys_CheckParm( "-timedemo" ))
CL_Quit_f();
Con_Printf( "%i frames %5.3f seconds %5.3f fps\n", frames, time, frames / time );
}
/*
@@ -1266,7 +1243,7 @@ CL_NextDemo
Called when a demo finishes
==================
*/
static qboolean CL_NextDemo( void )
qboolean CL_NextDemo( void )
{
char str[MAX_QPATH];
@@ -1316,7 +1293,7 @@ void CL_CheckStartupDemos( void )
}
// run demos loop in background mode
Cvar_DirectSet( &v_dark, "1" );
Cvar_SetValue( "v_dark", 1.0f );
cls.demos_pending = false;
cls.demonum = 0;
CL_NextDemo ();
@@ -1327,16 +1304,16 @@ void CL_CheckStartupDemos( void )
CL_DemoGetName
==================
*/
static void CL_DemoGetName( int lastnum, char *filename, size_t size )
static void CL_DemoGetName( int lastnum, char *filename )
{
if( lastnum < 0 || lastnum > 9999 )
{
// bound
Q_strncpy( filename, "demo9999", size );
Q_strcpy( filename, "demo9999" );
return;
}
Q_snprintf( filename, size, "demo%04d", lastnum );
Q_sprintf( filename, "demo%04d", lastnum );
}
/*
@@ -1390,10 +1367,8 @@ void CL_Record_f( void )
// scan for a free filename
for( n = 0; n < 10000; n++ )
{
CL_DemoGetName( n, demoname, sizeof( demoname ));
Q_snprintf( demopath, sizeof( demopath ), "%s.dem", demoname );
if( !FS_FileExists( demopath, true ))
CL_DemoGetName( n, demoname );
if( !FS_FileExists( va( "%s.dem", demoname ), true ))
break;
}
@@ -1406,7 +1381,7 @@ void CL_Record_f( void )
else Q_strncpy( demoname, name, sizeof( demoname ));
// open the demo file
Q_snprintf( demopath, sizeof( demopath ), "%s.dem", demoname );
Q_sprintf( demopath, "%s.dem", demoname );
// make sure that old demo is removed
if( FS_FileExists( demopath, false ))
@@ -1433,7 +1408,7 @@ void CL_PlayDemo_f( void )
if( Cmd_Argc() < 2 )
{
Con_Printf( S_USAGE "%s <demoname>\n", Cmd_Argv( 0 ));
Con_Printf( S_USAGE "playdemo <demoname>\n" );
return;
}
@@ -1480,7 +1455,7 @@ void CL_PlayDemo_f( void )
{
int c, neg = false;
demo.header.host_fps = host_maxfps.value;
demo.header.host_fps = host_maxfps->value;
while(( c = FS_Getc( cls.demofile )) != '\n' )
{
@@ -1560,6 +1535,12 @@ timedemo <demoname>
*/
void CL_TimeDemo_f( void )
{
if( Cmd_Argc() != 2 )
{
Con_Printf( S_USAGE "timedemo <demoname>\n" );
return;
}
CL_PlayDemo_f ();
// cls.td_starttime will be grabbed at the second frame of the demo, so

View File

@@ -33,6 +33,46 @@ static mnode_t *r_pefragtopnode;
static vec3_t r_emins, r_emaxs;
static cl_entity_t *r_addent;
/*
================
R_RemoveEfrags
Call when removing an object from the world or moving it to another position
================
*/
void R_RemoveEfrags( cl_entity_t *ent )
{
efrag_t *ef, *old, *walk, **prev;
ef = ent->efrag;
while( ef )
{
prev = &ef->leaf->efrags;
while( 1 )
{
walk = *prev;
if( !walk ) break;
if( walk == ef )
{
// remove this fragment
*prev = ef->leafnext;
break;
}
else prev = &walk->leafnext;
}
old = ef;
ef = ef->entnext;
// put it on the free list
old->entnext = clgame.free_efrags;
clgame.free_efrags = old;
}
ent->efrag = NULL;
}
/*
===================
R_SplitEntityOnNode
@@ -148,6 +188,8 @@ void R_StoreEfrags( efrag_t **ppefrag, int framecount )
case mod_brush:
case mod_studio:
case mod_sprite:
pent = pefrag->entity;
if( pent->visframe != framecount )
{
if( CL_AddVisibleEntity( pent, ET_FRAGMENTED ))

View File

@@ -6,7 +6,7 @@
#include "r_efx.h"
#include "cl_tent.h"
#include "pm_local.h"
#define PART_SIZE Q_max( 0.5f, cl_draw_particles.value )
#define PART_SIZE Q_max( 0.5f, cl_draw_particles->value )
/*
==============================================================
@@ -21,9 +21,9 @@ static int ramp2[8] = { 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66 };
static int ramp3[6] = { 0x6d, 0x6b, 6, 5, 4, 3 };
static int gSparkRamp[9] = { 0xfe, 0xfd, 0xfc, 0x6f, 0x6e, 0x6d, 0x6c, 0x67, 0x60 };
static CVAR_DEFINE_AUTO( tracerspeed, "6000", 0, "tracer speed" );
static CVAR_DEFINE_AUTO( tracerlength, "0.8", 0, "tracer length factor" );
static CVAR_DEFINE_AUTO( traceroffset, "30", 0, "tracer starting offset" );
convar_t *tracerspeed;
convar_t *tracerlength;
convar_t *traceroffset;
particle_t *cl_active_particles;
particle_t *cl_active_tracers;
@@ -46,7 +46,7 @@ short GAME_EXPORT R_LookupColor( byte r, byte g, byte b )
float rf, gf, bf;
bestdiff = 999999;
best = -1;
best = 65535;
for( i = 0; i < 256; i++ )
{
@@ -100,9 +100,9 @@ void CL_InitParticles( void )
cl_avelocities[i][2] = COM_RandomFloat( 0.0f, 2.55f );
}
Cvar_RegisterVariable( &tracerspeed );
Cvar_RegisterVariable( &tracerlength );
Cvar_RegisterVariable( &traceroffset );
tracerspeed = Cvar_Get( "tracerspeed", "6000", 0, "tracer speed" );
tracerlength = Cvar_Get( "tracerlength", "0.8", 0, "tracer length factor" );
traceroffset = Cvar_Get( "traceroffset", "30", 0, "tracer starting offset" );
}
/*
@@ -140,6 +140,26 @@ void CL_FreeParticles( void )
cl_particles = NULL;
}
/*
================
CL_FreeParticle
move particle to freelist
================
*/
void CL_FreeParticle( particle_t *p )
{
if( p->deathfunc )
{
// call right the deathfunc before die
p->deathfunc( p );
p->deathfunc = NULL;
}
p->next = cl_free_particles;
cl_free_particles = p;
}
/*
================
CL_AllocParticleFast
@@ -171,11 +191,11 @@ particle_t * GAME_EXPORT R_AllocParticle( void (*callback)( particle_t*, float )
{
particle_t *p;
if( !cl_draw_particles.value )
if( !cl_draw_particles->value )
return NULL;
// never alloc particles when we not in game
if( cl_clientframetime() == 0.0 ) return NULL;
// if( tr.frametime == 0.0 ) return NULL;
if( !cl_free_particles )
{
@@ -218,15 +238,15 @@ R_AllocTracer
can return NULL if particles is out
================
*/
static particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life )
particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life )
{
particle_t *p;
if( !cl_draw_tracers.value )
if( !cl_draw_tracers->value )
return NULL;
// never alloc particles when we not in game
if( cl_clientframetime() == 0.0 ) return NULL;
//if( tr.frametime == 0.0 ) return NULL;
if( !cl_free_particles )
{
@@ -249,7 +269,7 @@ static particle_t *R_AllocTracer( const vec3_t org, const vec3_t vel, float life
VectorCopy( org, p->org );
VectorCopy( vel, p->vel );
p->die = cl.time + life;
p->ramp = tracerlength.value;
p->ramp = tracerlength->value;
p->color = 4; // select custom color
p->packedColor = 255; // alpha
@@ -300,7 +320,7 @@ R_BeamAlloc
==============
*/
static BEAM *R_BeamAlloc( void )
BEAM *R_BeamAlloc( void )
{
BEAM *pBeam;
@@ -323,7 +343,7 @@ R_BeamFree
==============
*/
static void R_BeamFree( BEAM *pBeam )
void R_BeamFree( BEAM *pBeam )
{
// free particles that have died off.
R_FreeDeadParticles( &pBeam->particles );
@@ -605,7 +625,7 @@ CL_BeamAttemptToDie
Check for expired beams
==============
*/
static qboolean CL_BeamAttemptToDie( BEAM *pBeam )
qboolean CL_BeamAttemptToDie( BEAM *pBeam )
{
Assert( pBeam != NULL );
@@ -663,46 +683,42 @@ void CL_ParseViewBeam( sizebuf_t *msg, int beamType )
switch( beamType )
{
case TE_BEAMPOINTS:
case TE_BEAMENTPOINT:
case TE_BEAMENTS:
if( beamType == TE_BEAMENTS )
{
startEnt = MSG_ReadShort( msg );
endEnt = MSG_ReadShort( msg );
}
else
{
if( beamType == TE_BEAMENTPOINT )
{
startEnt = MSG_ReadShort( msg );
}
else
{
start[0] = MSG_ReadCoord( msg );
start[1] = MSG_ReadCoord( msg );
start[2] = MSG_ReadCoord( msg );
}
end[0] = MSG_ReadCoord( msg );
end[1] = MSG_ReadCoord( msg );
end[2] = MSG_ReadCoord( msg );
}
start[0] = MSG_ReadCoord( msg );
start[1] = MSG_ReadCoord( msg );
start[2] = MSG_ReadCoord( msg );
end[0] = MSG_ReadCoord( msg );
end[1] = MSG_ReadCoord( msg );
end[2] = MSG_ReadCoord( msg );
modelIndex = MSG_ReadShort( msg );
startFrame = MSG_ReadByte( msg );
frameRate = (float)MSG_ReadByte( msg ) * 0.1f;
life = (float)MSG_ReadByte( msg ) * 0.1f;
width = (float)MSG_ReadByte( msg ) * 0.1f;
noise = (float)MSG_ReadByte( msg ) * 0.01f;
frameRate = (float)MSG_ReadByte( msg );
life = (float)(MSG_ReadByte( msg ) * 0.1f);
width = (float)(MSG_ReadByte( msg ) * 0.1f);
noise = (float)(MSG_ReadByte( msg ) * 0.01f);
r = (float)MSG_ReadByte( msg ) / 255.0f;
g = (float)MSG_ReadByte( msg ) / 255.0f;
b = (float)MSG_ReadByte( msg ) / 255.0f;
a = (float)MSG_ReadByte( msg ) / 255.0f;
speed = (float)MSG_ReadByte( msg ) * 0.1f;
if( beamType == TE_BEAMENTS )
R_BeamEnts( startEnt, endEnt, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
else if( beamType == TE_BEAMENTPOINT )
R_BeamEntPoint( startEnt, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
else
R_BeamPoints( start, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
speed = (float)(MSG_ReadByte( msg ) * 0.1f);
R_BeamPoints( start, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
break;
case TE_BEAMENTPOINT:
startEnt = MSG_ReadShort( msg );
end[0] = MSG_ReadCoord( msg );
end[1] = MSG_ReadCoord( msg );
end[2] = MSG_ReadCoord( msg );
modelIndex = MSG_ReadShort( msg );
startFrame = MSG_ReadByte( msg );
frameRate = (float)MSG_ReadByte( msg );
life = (float)(MSG_ReadByte( msg ) * 0.1f);
width = (float)(MSG_ReadByte( msg ) * 0.1f);
noise = (float)(MSG_ReadByte( msg ) * 0.01f);
r = (float)MSG_ReadByte( msg ) / 255.0f;
g = (float)MSG_ReadByte( msg ) / 255.0f;
b = (float)MSG_ReadByte( msg ) / 255.0f;
a = (float)MSG_ReadByte( msg ) / 255.0f;
speed = (float)(MSG_ReadByte( msg ) * 0.1f);
R_BeamEntPoint( startEnt, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
break;
case TE_LIGHTNING:
start[0] = MSG_ReadCoord( msg );
@@ -711,11 +727,27 @@ void CL_ParseViewBeam( sizebuf_t *msg, int beamType )
end[0] = MSG_ReadCoord( msg );
end[1] = MSG_ReadCoord( msg );
end[2] = MSG_ReadCoord( msg );
life = (float)MSG_ReadByte( msg ) * 0.1f;
width = (float)MSG_ReadByte( msg ) * 0.1f;
noise = (float)MSG_ReadByte( msg ) * 0.01f;
life = (float)(MSG_ReadByte( msg ) * 0.1f);
width = (float)(MSG_ReadByte( msg ) * 0.1f);
noise = (float)(MSG_ReadByte( msg ) * 0.01f);
modelIndex = MSG_ReadShort( msg );
R_BeamLightning( start, end, modelIndex, life, width, noise, 0.6f, 3.5f );
R_BeamLightning( start, end, modelIndex, life, width, noise, 0.6F, 3.5f );
break;
case TE_BEAMENTS:
startEnt = MSG_ReadShort( msg );
endEnt = MSG_ReadShort( msg );
modelIndex = MSG_ReadShort( msg );
startFrame = MSG_ReadByte( msg );
frameRate = (float)(MSG_ReadByte( msg ) * 0.1f);
life = (float)(MSG_ReadByte( msg ) * 0.1f);
width = (float)(MSG_ReadByte( msg ) * 0.1f);
noise = (float)(MSG_ReadByte( msg ) * 0.01f);
r = (float)MSG_ReadByte( msg ) / 255.0f;
g = (float)MSG_ReadByte( msg ) / 255.0f;
b = (float)MSG_ReadByte( msg ) / 255.0f;
a = (float)MSG_ReadByte( msg ) / 255.0f;
speed = (float)(MSG_ReadByte( msg ) * 0.1f);
R_BeamEnts( startEnt, endEnt, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
break;
case TE_BEAM:
break;
@@ -741,21 +773,21 @@ void CL_ParseViewBeam( sizebuf_t *msg, int beamType )
end[2] = MSG_ReadCoord( msg );
modelIndex = MSG_ReadShort( msg );
startFrame = MSG_ReadByte( msg );
frameRate = (float)MSG_ReadByte( msg ) * 0.1f;
life = (float)MSG_ReadByte( msg ) * 0.1f;
width = (float)MSG_ReadByte( msg );
noise = (float)MSG_ReadByte( msg ) * 0.01f;
frameRate = (float)(MSG_ReadByte( msg ));
life = (float)(MSG_ReadByte( msg ) * 0.1f);
width = (float)(MSG_ReadByte( msg ));
noise = (float)(MSG_ReadByte( msg ) * 0.1f);
r = (float)MSG_ReadByte( msg ) / 255.0f;
g = (float)MSG_ReadByte( msg ) / 255.0f;
b = (float)MSG_ReadByte( msg ) / 255.0f;
a = (float)MSG_ReadByte( msg ) / 255.0f;
speed = (float)MSG_ReadByte( msg ) * 0.1f;
speed = (float)(MSG_ReadByte( msg ) / 0.1f);
R_BeamCirclePoints( beamType, start, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
break;
case TE_BEAMFOLLOW:
startEnt = MSG_ReadShort( msg );
modelIndex = MSG_ReadShort( msg );
life = (float)MSG_ReadByte( msg ) * 0.1f;
life = (float)(MSG_ReadByte( msg ) * 0.1f);
width = (float)MSG_ReadByte( msg );
r = (float)MSG_ReadByte( msg ) / 255.0f;
g = (float)MSG_ReadByte( msg ) / 255.0f;
@@ -768,15 +800,15 @@ void CL_ParseViewBeam( sizebuf_t *msg, int beamType )
endEnt = MSG_ReadShort( msg );
modelIndex = MSG_ReadShort( msg );
startFrame = MSG_ReadByte( msg );
frameRate = (float)MSG_ReadByte( msg ) * 0.1f;
life = (float)MSG_ReadByte( msg ) * 0.1f;
width = (float)MSG_ReadByte( msg ) * 0.1f;
noise = (float)MSG_ReadByte( msg ) * 0.01f;
frameRate = (float)MSG_ReadByte( msg );
life = (float)(MSG_ReadByte( msg ) * 0.1f);
width = (float)(MSG_ReadByte( msg ) * 0.1f);
noise = (float)(MSG_ReadByte( msg ) * 0.01f);
r = (float)MSG_ReadByte( msg ) / 255.0f;
g = (float)MSG_ReadByte( msg ) / 255.0f;
b = (float)MSG_ReadByte( msg ) / 255.0f;
a = (float)MSG_ReadByte( msg ) / 255.0f;
speed = (float)MSG_ReadByte( msg ) * 0.1f;
speed = (float)(MSG_ReadByte( msg ) * 0.1f);
R_BeamRing( startEnt, endEnt, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
break;
case TE_BEAMHOSE:
@@ -1091,13 +1123,9 @@ R_ParticleExplosion2
void GAME_EXPORT R_ParticleExplosion2( const vec3_t org, int colorStart, int colorLength )
{
int i, j;
int colorMod = 0, packedColor;
int colorMod = 0;
particle_t *p;
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
packedColor = 255; // use old code for blob particles
else packedColor = 0;
for( i = 0; i < 512; i++ )
{
p = R_AllocParticle( NULL );
@@ -1105,7 +1133,7 @@ void GAME_EXPORT R_ParticleExplosion2( const vec3_t org, int colorStart, int col
p->die = cl.time + 0.3f;
p->color = colorStart + ( colorMod % colorLength );
p->packedColor = packedColor;
p->packedColor = 255; // use old code for blob particles
colorMod++;
p->type = pt_blob;
@@ -1127,19 +1155,15 @@ R_BlobExplosion
void GAME_EXPORT R_BlobExplosion( const vec3_t org )
{
particle_t *p;
int i, j, packedColor;
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
packedColor = 255; // use old code for blob particles
else packedColor = 0;
int i, j;
for( i = 0; i < 1024; i++ )
{
p = R_AllocParticle( NULL );
if( !p ) return;
p->die = cl.time + COM_RandomFloat( 1.0f, 1.4f );
p->packedColor = packedColor;
p->die = cl.time + COM_RandomFloat( 2.0f, 2.4f );
p->packedColor = 255; // use old code for blob particles
if( i & 1 )
{
@@ -1236,15 +1260,12 @@ R_BloodStream
particle spray 2
===============
*/
void GAME_EXPORT R_BloodStream( const vec3_t org, const vec3_t ndir, int pcolor, int speed )
void GAME_EXPORT R_BloodStream( const vec3_t org, const vec3_t dir, int pcolor, int speed )
{
particle_t *p;
int i, j;
float arc;
int accel = speed; // must be integer due to bug in GoldSrc
vec3_t dir;
VectorNormalize2( ndir, dir );
float accel = speed;
for( arc = 0.05f, i = 0; i < 100; i++ )
{
@@ -1807,14 +1828,14 @@ void GAME_EXPORT R_TracerEffect( const vec3_t start, const vec3_t end )
float len, speed;
float offset;
speed = Q_max( tracerspeed.value, 3.0f );
speed = Q_max( tracerspeed->value, 3.0f );
VectorSubtract( end, start, dir );
len = VectorLength( dir );
if( len == 0.0f ) return;
VectorScale( dir, 1.0f / len, dir ); // normalize
offset = COM_RandomFloat( -10.0f, 9.0f ) + traceroffset.value;
offset = COM_RandomFloat( -10.0f, 9.0f ) + traceroffset->value;
VectorScale( dir, offset, vel );
VectorAdd( start, vel, pos );
VectorScale( dir, speed, vel );
@@ -2040,7 +2061,7 @@ void CL_ReadPointFile_f( void )
else Con_Printf( "map %s has no leaks!\n", clgame.mapname );
}
static void CL_FreeDeadBeams( void )
void CL_FreeDeadBeams( void )
{
BEAM *pBeam, *pNext, *pPrev = NULL;
// draw temporary entity beams
@@ -2070,16 +2091,16 @@ static void CL_FreeDeadBeams( void )
void CL_DrawEFX( float time, qboolean fTrans )
{
CL_FreeDeadBeams();
if( cl_draw_beams.value )
if( CVAR_TO_BOOL( cl_draw_beams ))
ref.dllFuncs.CL_DrawBeams( fTrans, cl_active_beams );
if( fTrans )
{
R_FreeDeadParticles( &cl_active_particles );
if( cl_draw_particles.value )
if( CVAR_TO_BOOL( cl_draw_particles ))
ref.dllFuncs.CL_DrawParticles( time, cl_active_particles, PART_SIZE );
R_FreeDeadParticles( &cl_active_tracers );
if( cl_draw_tracers.value )
if( CVAR_TO_BOOL( cl_draw_tracers ))
ref.dllFuncs.CL_DrawTracers( time, cl_active_tracers );
}
}

View File

@@ -40,7 +40,7 @@ CL_CalcPlayerVelocity
compute velocity for a given client
=============
*/
static void CL_CalcPlayerVelocity( int idx, vec3_t velocity )
void CL_CalcPlayerVelocity( int idx, vec3_t velocity )
{
clientdata_t *pcd;
vec3_t delta;
@@ -78,13 +78,13 @@ CL_DescribeEvent
=============
*/
static void CL_DescribeEvent( event_info_t *ei, int slot )
void CL_DescribeEvent( event_info_t *ei, int slot )
{
int idx = (slot & 63) * 2;
con_nprint_t info;
string origin_str = { 0 }; //, angles_str = { 0 };
if( !cl_showevents.value )
if( !cl_showevents->value )
return;
info.time_to_live = 1.0f;
@@ -158,7 +158,7 @@ CL_EventIndex
*/
word CL_EventIndex( const char *name )
{
word i;
int i;
if( !COM_CheckString( name ))
return 0;
@@ -202,7 +202,7 @@ CL_FireEvent
=============
*/
static qboolean CL_FireEvent( event_info_t *ei, int slot )
qboolean CL_FireEvent( event_info_t *ei, int slot )
{
cl_user_event_t *ev;
const char *name;
@@ -225,18 +225,6 @@ static qboolean CL_FireEvent( event_info_t *ei, int slot )
if( ev->index == ei->index )
{
name = cl.event_precache[ei->index];
if( cl_trace_events.value )
{
Con_Printf( "^3EVENT %s AT %.2f %.2f %.2f\n" // event name
"\t%.2f %.2f %i %i %s %s\n", // bool params
name, ei->args.origin[0], ei->args.origin[1], ei->args.origin[2],
ei->args.fparam1, ei->args.fparam2,
ei->args.iparam1, ei->args.iparam2,
ei->args.bparam1 ? "TRUE" : "FALSE", ei->args.bparam2 ? "TRUE" : "FALSE" );
}
if( ev->func )
{
CL_DescribeEvent( ei, slot );
@@ -244,6 +232,7 @@ static qboolean CL_FireEvent( event_info_t *ei, int slot )
return true;
}
name = cl.event_precache[ei->index];
Con_Reportf( S_ERROR "CL_FireEvent: %s not hooked\n", name );
break;
}
@@ -292,7 +281,7 @@ CL_FindEvent
find first empty event
=============
*/
static event_info_t *CL_FindEmptyEvent( void )
event_info_t *CL_FindEmptyEvent( void )
{
int i;
event_state_t *es;
@@ -320,7 +309,7 @@ CL_FindEvent
replace only unreliable events
=============
*/
static event_info_t *CL_FindUnreliableEvent( void )
event_info_t *CL_FindUnreliableEvent( void )
{
event_state_t *es;
event_info_t *ei;
@@ -350,7 +339,7 @@ CL_QueueEvent
=============
*/
static void CL_QueueEvent( int flags, int index, float delay, event_args_t *args )
void CL_QueueEvent( int flags, int index, float delay, event_args_t *args )
{
event_info_t *ei;
@@ -495,7 +484,7 @@ void GAME_EXPORT CL_PlaybackEvent( int flags, const edict_t *pInvoker, word even
return;
// first check event for out of bounds
if( eventindex < 1 || eventindex >= MAX_EVENTS )
if( eventindex < 1 || eventindex > MAX_EVENTS )
{
Con_DPrintf( S_ERROR "CL_PlaybackEvent: invalid eventindex %i\n", eventindex );
return;

View File

@@ -1,348 +0,0 @@
/*
cl_font.c - bare bones engine font manager
Copyright (C) 2023 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.
*/
#include "common.h"
#include "filesystem.h"
#include "client.h"
#include "qfont.h"
qboolean CL_FixedFont( cl_font_t *font )
{
return font && font->valid && font->type == FONT_FIXED;
}
static int CL_LoadFontTexture( const char *fontname, uint texFlags, int *width )
{
int font_width;
int tex;
if( !g_fsapi.FileExists( fontname, false ))
return 0;
tex = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, texFlags );
if( !tex )
return 0;
font_width = REF_GET_PARM( PARM_TEX_WIDTH, tex );
if( !font_width )
{
ref.dllFuncs.GL_FreeTexture( tex );
return 0;
}
*width = font_width;
return tex;
}
qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, int rendermode, uint texFlags )
{
int font_width, i;
if( font->valid )
return true; // already loaded
font->hFontTexture = CL_LoadFontTexture( fontname, texFlags, &font_width );
if( !font->hFontTexture )
return false;
font->type = FONT_FIXED;
font->valid = true;
font->scale = scale;
font->rendermode = rendermode;
font->charHeight = Q_rint( font_width / 16 * scale );
for( i = 0; i < ARRAYSIZE( font->fontRc ); i++ )
{
font->fontRc[i].left = ( i * font_width / 16 ) % font_width;
font->fontRc[i].right = font->fontRc[i].left + font_width / 16;
font->fontRc[i].top = ( i / 16 ) * ( font_width / 16 );
font->fontRc[i].bottom = font->fontRc[i].top + font_width / 16;
font->charWidths[i] = Q_rint( font_width / 16 * scale );
}
return true;
}
qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font, float scale, int rendermode, uint texFlags )
{
fs_offset_t length;
qfont_t src;
byte *pfile;
int font_width, i;
if( font->valid )
return true;
pfile = g_fsapi.LoadFile( fontname, &length, false );
if( !pfile )
return false;
if( length < sizeof( src ))
{
Mem_Free( pfile );
return false;
}
memcpy( &src, pfile, sizeof( src ));
Mem_Free( pfile );
font->hFontTexture = CL_LoadFontTexture( fontname, texFlags, &font_width );
if( !font->hFontTexture )
return false;
font->type = FONT_VARIABLE;
font->valid = true;
font->scale = scale;
font->rendermode = rendermode;
font->charHeight = Q_rint( src.rowheight * scale );
for( i = 0; i < ARRAYSIZE( font->fontRc ); i++ )
{
const charinfo *ci = &src.fontinfo[i];
font->fontRc[i].left = (word)ci->startoffset % font_width;
font->fontRc[i].right = font->fontRc[i].left + ci->charwidth;
font->fontRc[i].top = (word)ci->startoffset / font_width;
font->fontRc[i].bottom = font->fontRc[i].top + src.rowheight;
font->charWidths[i] = Q_rint( src.fontinfo[i].charwidth * scale );
}
return true;
}
void CL_FreeFont( cl_font_t *font )
{
if( !font || !font->valid )
return;
ref.dllFuncs.GL_FreeTexture( font->hFontTexture );
memset( font, 0, sizeof( *font ));
}
static int CL_CalcTabStop( const cl_font_t *font, int x )
{
int space = font->charWidths[' '];
int tab = space * 6; // 6 spaces
int stop = tab - x % tab;
if( stop < space )
return tab * 2 - x % tab; // select next
return stop;
}
int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *font, int flags )
{
wrect_t *rc;
float w, h;
float s1, t1, s2, t2, half = 0.5f;
int texw, texh;
if( !font || !font->valid || y < -font->charHeight )
return 0;
// check if printable
if( number <= 32 )
{
if( number == ' ' )
return font->charWidths[' '];
else if( number == '\t' )
return CL_CalcTabStop( font, x );
return 0;
}
if( FBitSet( flags, FONT_DRAW_UTF8 ))
number = Con_UtfProcessChar( number & 255 );
else number &= 255;
if( !number || !font->charWidths[number])
return 0;
R_GetTextureParms( &texw, &texh, font->hFontTexture );
if( !texw || !texh )
return font->charWidths[number];
rc = &font->fontRc[number];
if( font->scale <= 1.0f || REF_GET_PARM( PARM_TEX_FILTERING, font->hFontTexture ))
half = 0;
s1 = ((float)rc->left + half ) / texw;
t1 = ((float)rc->top + half ) / texh;
s2 = ((float)rc->right - half ) / texw;
t2 = ((float)rc->bottom - half ) / texh;
w = ( rc->right - rc->left ) * font->scale;
h = ( rc->bottom - rc->top ) * font->scale;
if( FBitSet( flags, FONT_DRAW_HUD ))
SPR_AdjustSize( &x, &y, &w, &h );
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
ref.dllFuncs.GL_SetRenderMode( font->rendermode );
// don't apply color to fixed fonts it's already colored
if( font->type != FONT_FIXED || REF_GET_PARM( PARM_TEX_GLFORMAT, font->hFontTexture ) == 0x8045 ) // GL_LUMINANCE8_ALPHA8
ref.dllFuncs.Color4ub( color[0], color[1], color[2], color[3] );
else ref.dllFuncs.Color4ub( 255, 255, 255, color[3] );
ref.dllFuncs.R_DrawStretchPic( x, y, w, h, s1, t1, s2, t2, font->hFontTexture );
return font->charWidths[number];
}
int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *font, int flags )
{
rgba_t current_color;
int draw_len = 0;
if( !font || !font->valid )
return 0;
if( FBitSet( flags, FONT_DRAW_UTF8 ))
Con_UtfProcessChar( 0 ); // clear utf state
if( !FBitSet( flags, FONT_DRAW_NORENDERMODE ))
ref.dllFuncs.GL_SetRenderMode( font->rendermode );
Vector4Copy( color, current_color );
while( *s )
{
if( *s == '\n' )
{
s++;
if( !*s )
break;
// some client functions ignore newlines
if( !FBitSet( flags, FONT_DRAW_NOLF ))
{
draw_len = 0;
y += font->charHeight;
}
if( FBitSet( flags, FONT_DRAW_RESETCOLORONLF ))
Vector4Copy( color, current_color );
continue;
}
if( IsColorString( s ))
{
// don't copy alpha
if( !FBitSet( flags, FONT_DRAW_FORCECOL ))
VectorCopy( g_color_table[ColorIndex(*( s + 1 ))], current_color );
s += 2;
continue;
}
// skip setting rendermode, it was changed for this string already
draw_len += CL_DrawCharacter( x + draw_len, y, (byte)*s, current_color, font, flags | FONT_DRAW_NORENDERMODE );
s++;
}
return draw_len;
}
int CL_DrawStringf( cl_font_t *font, float x, float y, rgba_t color, int flags, const char *fmt, ... )
{
va_list va;
char buf[MAX_VA_STRING];
va_start( va, fmt );
Q_vsnprintf( buf, sizeof( buf ), fmt, va );
va_end( va );
return CL_DrawString( x, y, buf, color, font, flags );
}
void CL_DrawCharacterLen( cl_font_t *font, int number, int *width, int *height )
{
if( !font || !font->valid ) return;
if( width )
{
if( number == '\t' )
*width = CL_CalcTabStop( font, 0 ); // at least return max tabstop
else *width = font->charWidths[number & 255];
}
if( height ) *height = font->charHeight;
}
void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height, int flags )
{
int draw_len = 0;
if( !font || !font->valid )
return;
if( height )
*height = font->charHeight;
if( width )
*width = 0;
if( !COM_CheckString( s ))
return;
if( FBitSet( flags, FONT_DRAW_UTF8 ))
Con_UtfProcessChar( 0 ); // reset utf state
while( *s )
{
int number;
if( *s == '\n' )
{
// BUG: no check for end string here
// but high chances somebody's relying on this
s++;
draw_len = 0;
if( !FBitSet( flags, FONT_DRAW_NOLF ))
{
if( height )
*height += font->charHeight;
}
continue;
}
else if( *s == '\t' )
{
draw_len += CL_CalcTabStop( font, 0 ); // at least return max tabstop
s++;
continue;
}
if( IsColorString( s ))
{
s += 2;
continue;
}
if( FBitSet( flags, FONT_DRAW_UTF8 ))
number = Con_UtfProcessChar( (byte)*s );
else number = (byte)*s;
if( number )
{
draw_len += font->charWidths[number];
if( draw_len > *width )
*width = draw_len;
}
s++;
}
}

View File

@@ -24,7 +24,7 @@ GNU General Public License for more details.
#include "sound.h"
#include "input.h"
// #define STUDIO_INTERPOLATION_FIX
#define STUDIO_INTERPOLATION_FIX
/*
==================
@@ -52,30 +52,16 @@ CL_UpdatePositions
Store another position into interpolation circular buffer
==================
*/
static void CL_UpdatePositions( cl_entity_t *ent )
void CL_UpdatePositions( cl_entity_t *ent )
{
position_history_t *ph, *prev;
prev = &ent->ph[ent->current_position];
position_history_t *ph;
ent->current_position = (ent->current_position + 1) & HISTORY_MASK;
ph = &ent->ph[ent->current_position];
VectorCopy( ent->curstate.origin, ph->origin );
VectorCopy( ent->curstate.angles, ph->angles );
ph->animtime = ent->curstate.animtime;
// a1ba: for some reason, this sometimes still may happen
// at this time, I'm not sure whether this bug happens in delta readwrite code
// or server just decides to go backwards and really sends these values
if( ph->animtime < prev->animtime )
{
// try to deduce real animtime by looking up the difference between
// server messages (cl.mtime is never modified ny the interpolation code)
float diff = Q_max( 0, ent->curstate.msg_time - ent->prevstate.msg_time );
ph->animtime = prev->animtime + diff;
}
ph->animtime = ent->curstate.animtime; // !!!
}
/*
@@ -85,7 +71,7 @@ CL_ResetPositions
Interpolation init or reset after teleporting
==================
*/
static void CL_ResetPositions( cl_entity_t *ent )
void CL_ResetPositions( cl_entity_t *ent )
{
position_history_t store;
@@ -107,7 +93,7 @@ check for instant movement in case
we don't want interpolate this
==================
*/
static qboolean CL_EntityTeleported( cl_entity_t *ent )
qboolean CL_EntityTeleported( cl_entity_t *ent )
{
float len, maxlen;
vec3_t delta;
@@ -128,7 +114,7 @@ CL_CompareTimestamps
round-off floating errors
==================
*/
static qboolean CL_CompareTimestamps( float t1, float t2 )
qboolean CL_CompareTimestamps( float t1, float t2 )
{
int iTime1 = t1 * 1000;
int iTime2 = t2 * 1000;
@@ -143,9 +129,9 @@ CL_EntityIgnoreLerp
some ents will be ignore lerping
==================
*/
static qboolean CL_EntityIgnoreLerp( cl_entity_t *e )
qboolean CL_EntityIgnoreLerp( cl_entity_t *e )
{
if( cl_nointerp.value > 0.f )
if( cl_nointerp->value > 0.f )
return true;
if( e->model && e->model->type == mod_alias )
@@ -160,7 +146,7 @@ CL_EntityCustomLerp
==================
*/
static qboolean CL_EntityCustomLerp( cl_entity_t *e )
qboolean CL_EntityCustomLerp( cl_entity_t *e )
{
switch( e->curstate.movetype )
{
@@ -170,13 +156,6 @@ static qboolean CL_EntityCustomLerp( cl_entity_t *e )
case MOVETYPE_FLY:
case MOVETYPE_COMPOUND:
return false;
// ABSOLUTELY STUPID HACK TO ALLOW MONSTERS
// INTERPOLATION IN GRAVGUNMOD COOP
// MUST BE REMOVED ONCE WE REMOVE 48 PROTO SUPPORT
case MOVETYPE_TOSS:
if( cls.legacymode && e->model && e->model->type == mod_studio )
return false;
}
return true;
@@ -189,7 +168,7 @@ CL_ParametricMove
check for parametrical moved entities
==================
*/
static qboolean CL_ParametricMove( cl_entity_t *ent )
qboolean CL_ParametricMove( cl_entity_t *ent )
{
float frac, dt, t;
vec3_t delta;
@@ -226,7 +205,7 @@ CL_UpdateLatchedVars
====================
*/
static void CL_UpdateLatchedVars( cl_entity_t *ent )
void CL_UpdateLatchedVars( cl_entity_t *ent )
{
if( !ent->model || ( ent->model->type != mod_alias && ent->model->type != mod_studio ))
return; // below fields used only for alias and studio interpolation
@@ -240,7 +219,7 @@ static void CL_UpdateLatchedVars( cl_entity_t *ent )
if( ent->curstate.sequence != ent->prevstate.sequence )
{
memcpy( ent->latched.prevseqblending, ent->prevstate.blending, sizeof( ent->latched.prevseqblending ));
memcpy( ent->prevstate.blending, ent->latched.prevseqblending, sizeof( ent->prevstate.blending ));
ent->latched.prevsequence = ent->prevstate.sequence;
ent->latched.sequencetime = ent->curstate.animtime;
}
@@ -259,7 +238,7 @@ CL_GetStudioEstimatedFrame
====================
*/
static float CL_GetStudioEstimatedFrame( cl_entity_t *ent )
float CL_GetStudioEstimatedFrame( cl_entity_t *ent )
{
studiohdr_t *pstudiohdr;
mstudioseqdesc_t *pseqdesc;
@@ -273,7 +252,7 @@ static float CL_GetStudioEstimatedFrame( cl_entity_t *ent )
{
sequence = bound( 0, ent->curstate.sequence, pstudiohdr->numseq - 1 );
pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + sequence;
return ref.dllFuncs.R_StudioEstimateFrame( ent, pseqdesc, cl.time );
return ref.dllFuncs.R_StudioEstimateFrame( ent, pseqdesc );
}
}
@@ -321,7 +300,7 @@ CL_ProcessEntityUpdate
apply changes since new frame received
==================
*/
static void CL_ProcessEntityUpdate( cl_entity_t *ent )
void CL_ProcessEntityUpdate( cl_entity_t *ent )
{
qboolean parametric;
@@ -331,7 +310,7 @@ static void CL_ProcessEntityUpdate( cl_entity_t *ent )
if( FBitSet( ent->curstate.entityType, ENTITY_NORMAL ))
COM_NormalizeAngles( ent->curstate.angles );
parametric = ent->curstate.starttime != 0.0f && ent->curstate.impacttime != 0.0f;
parametric = CL_ParametricMove( ent );
// allow interpolation on bmodels too
if( ent->model && ent->model->type == mod_brush )
@@ -367,10 +346,11 @@ CL_FindInterpolationUpdates
find two timestamps
==================
*/
static qboolean CL_FindInterpolationUpdates( cl_entity_t *ent, double targettime, position_history_t **ph0, position_history_t **ph1 )
qboolean CL_FindInterpolationUpdates( cl_entity_t *ent, float targettime, position_history_t **ph0, position_history_t **ph1 )
{
qboolean extrapolate = true;
uint i, i0, i1, imod;
int i, i0, i1, imod;
float at;
imod = ent->current_position;
i0 = (imod - 0) & HISTORY_MASK; // curpos (lerp end)
@@ -378,10 +358,8 @@ static qboolean CL_FindInterpolationUpdates( cl_entity_t *ent, double targettime
for( i = 1; i < HISTORY_MAX - 1; i++ )
{
double at = ent->ph[( imod - i ) & HISTORY_MASK].animtime;
if( at == 0.0f )
break;
at = ent->ph[( imod - i ) & HISTORY_MASK].animtime;
if( at == 0.0f ) break;
if( targettime > at )
{
@@ -406,14 +384,15 @@ CL_PureOrigin
non-local players interpolation
==================
*/
static void CL_PureOrigin( cl_entity_t *ent, double t, vec3_t outorigin, vec3_t outangles )
void CL_PureOrigin( cl_entity_t *ent, float t, vec3_t outorigin, vec3_t outangles )
{
double t1, t0, frac;
qboolean extrapolate;
float t1, t0, frac;
position_history_t *ph0, *ph1;
vec3_t delta;
// NOTE: ph0 is next, ph1 is a prev
CL_FindInterpolationUpdates( ent, t, &ph0, &ph1 );
extrapolate = CL_FindInterpolationUpdates( ent, t, &ph0, &ph1 );
if ( !ph0 || !ph1 )
return;
@@ -421,17 +400,17 @@ static void CL_PureOrigin( cl_entity_t *ent, double t, vec3_t outorigin, vec3_t
t0 = ph0->animtime;
t1 = ph1->animtime;
if( t0 != 0.0 )
if( t0 != 0.0f )
{
vec4_t q, q1, q2;
VectorSubtract( ph0->origin, ph1->origin, delta );
if( !Q_equal( t0, t1 ))
if( t0 != t1 )
frac = ( t - t1 ) / ( t0 - t1 );
else frac = 1.0;
else frac = 1.0f;
frac = bound( 0.0, frac, 1.2 );
frac = bound( 0.0f, frac, 1.2f );
VectorMA( ph1->origin, frac, delta, outorigin );
@@ -455,11 +434,11 @@ CL_InterpolateModel
non-players interpolation
==================
*/
static int CL_InterpolateModel( cl_entity_t *e )
int CL_InterpolateModel( cl_entity_t *e )
{
position_history_t *ph0 = NULL, *ph1 = NULL;
vec3_t origin, angles, delta;
double t, t1, t2, frac;
float t, t1, t2, frac;
vec4_t q, q1, q2;
VectorCopy( e->curstate.origin, e->origin );
@@ -482,13 +461,13 @@ static int CL_InterpolateModel( cl_entity_t *e )
if( cl.maxclients <= 1 )
return 1;
if( e->model->type == mod_brush && !cl_bmodelinterp.value )
if( e->model->type == mod_brush && !cl_bmodelinterp->value )
return 1;
if( cl.local.moving && cl.local.onground == e->index )
return 1;
t = cl.time - cl_interp.value;
t = cl.time - cl_interp->value;
CL_FindInterpolationUpdates( e, t, &ph0, &ph1 );
if( ph0 == NULL || ph1 == NULL )
@@ -507,7 +486,7 @@ static int CL_InterpolateModel( cl_entity_t *e )
return 0;
}
if( Q_equal( t2, t1 ))
if( t2 == t1 )
{
VectorCopy( ph0->origin, e->origin );
VectorCopy( ph0->angles, e->angles );
@@ -545,15 +524,15 @@ interpolate non-local clients
*/
void CL_ComputePlayerOrigin( cl_entity_t *ent )
{
double targettime;
float targettime;
vec4_t q, q1, q2;
vec3_t origin;
vec3_t angles;
if( !ent->player )
if( !ent->player || ent->index == ( cl.playernum + 1 ))
return;
if( cl_nointerp.value > 0.f )
if( cl_nointerp->value > 0.f )
{
VectorCopy( ent->curstate.angles, ent->angles );
VectorCopy( ent->curstate.origin, ent->origin );
@@ -571,7 +550,7 @@ void CL_ComputePlayerOrigin( cl_entity_t *ent )
return;
}
targettime = cl.time - cl_interp.value;
targettime = cl.time - cl_interp->value;
CL_PureOrigin( ent, targettime, origin, angles );
VectorCopy( angles, ent->angles );
@@ -585,7 +564,7 @@ CL_ProcessPlayerState
process player states after the new packet has received
=================
*/
static void CL_ProcessPlayerState( int playerindex, entity_state_t *state )
void CL_ProcessPlayerState( int playerindex, entity_state_t *state )
{
entity_state_t *ps;
@@ -605,7 +584,7 @@ reset latched state if this frame entity was teleported
or just EF_NOINTERP was set
=================
*/
static void CL_ResetLatchedState( int pnum, frame_t *frame, cl_entity_t *ent )
void CL_ResetLatchedState( int pnum, frame_t *frame, cl_entity_t *ent )
{
if( CHECKVISBIT( frame->flags, pnum ))
{
@@ -670,24 +649,6 @@ FRAME PARSING
=========================================================================
*/
static qboolean CL_ParseEntityNumFromPacket( sizebuf_t *msg, int *newnum )
{
if( cls.legacymode )
{
*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;
}
/*
=================
CL_FlushEntityPacket
@@ -695,7 +656,7 @@ CL_FlushEntityPacket
Read and ignore whole entity packet.
=================
*/
static void CL_FlushEntityPacket( sizebuf_t *msg )
void CL_FlushEntityPacket( sizebuf_t *msg )
{
int newnum;
entity_state_t from, to;
@@ -708,8 +669,8 @@ static void CL_FlushEntityPacket( sizebuf_t *msg )
// read it all, but ignore it
while( 1 )
{
if( !CL_ParseEntityNumFromPacket( msg, &newnum ))
break; // done
newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
if( newnum == LAST_EDICT ) break; // done
if( MSG_CheckOverflow( msg ))
Host_Error( "CL_FlushEntityPacket: overflow\n" );
@@ -725,7 +686,7 @@ CL_DeltaEntity
processing delta update
=================
*/
static void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t *old, qboolean has_update )
void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t *old, qboolean has_update )
{
cl_entity_t *ent;
entity_state_t *state;
@@ -881,12 +842,21 @@ int CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta )
while( 1 )
{
if( !CL_ParseEntityNumFromPacket( msg, &newnum ))
break; // done
int lastedict;
if( cls.legacymode )
{
newnum = MSG_ReadWord( msg );
lastedict = 0;
}
else
{
newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
lastedict = LAST_EDICT;
}
if( newnum == lastedict ) break; // end of packet entities
if( MSG_CheckOverflow( msg ))
Host_Error( "CL_ParsePacketEntities: overflow\n" );
player = CL_IsPlayerIndex( newnum );
while( oldnum < newnum )
@@ -995,25 +965,9 @@ all the visible entities should pass this filter
*/
qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
{
qboolean draw_player = true;
if( !ent || !ent->model )
return false;
// don't add the player in firstperson mode
if( RP_LOCALCLIENT( ent ))
{
cl.local.apply_effects = true;
if( !CL_IsThirdPerson( ) && ( ent->index == cl.viewentity ))
{
// we don't draw player in default renderer in firstperson mode
// but let the client.dll know about player entity anyway
// for use in custom renderers
draw_player = false;
}
}
// check for adding this entity
if( !clgame.dllFuncs.pfnAddEntity( entityType, ent, ent->model->name ))
{
@@ -1023,7 +977,8 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
return false;
}
if( !draw_player )
// don't add the player in firstperson mode
if( RP_LOCALCLIENT( ent ) && !CL_IsThirdPerson( ) && ( ent->index == cl.viewentity ))
return false;
if( entityType == ET_BEAM )
@@ -1038,8 +993,12 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
// because pTemp->entity.curstate.effects
// is already occupied by FTENT_FLICKER
if( entityType != ET_TEMPENTITY && !RP_LOCALCLIENT( ent ) )
if( entityType != ET_TEMPENTITY )
{
// no reason to do it twice
if( RP_LOCALCLIENT( ent ))
cl.local.apply_effects = false;
// apply client-side effects
CL_AddEntityEffects( ent );
@@ -1057,7 +1016,7 @@ CL_LinkCustomEntity
Add server beam to draw list
=============
*/
static void CL_LinkCustomEntity( cl_entity_t *ent, entity_state_t *state )
void CL_LinkCustomEntity( cl_entity_t *ent, entity_state_t *state )
{
ent->curstate.movetype = state->modelindex; // !!!
@@ -1080,7 +1039,7 @@ Create visible entities in the correct position
for all current players
=============
*/
static void CL_LinkPlayers( frame_t *frame )
void CL_LinkPlayers( frame_t *frame )
{
entity_state_t *state;
cl_entity_t *ent;
@@ -1091,6 +1050,7 @@ static void CL_LinkPlayers( frame_t *frame )
// apply muzzleflash to weaponmodel
if( ent && FBitSet( ent->curstate.effects, EF_MUZZLEFLASH ))
SetBits( clgame.viewent.curstate.effects, EF_MUZZLEFLASH );
cl.local.apply_effects = true;
// check all the clients but add only visible
for( i = 0, state = frame->playerstate; i < MAX_CLIENTS; i++, state++ )
@@ -1129,9 +1089,6 @@ static void CL_LinkPlayers( frame_t *frame )
if ( i == cl.playernum )
{
// using interpolation only for local player angles
CL_ComputePlayerOrigin( ent );
if( cls.demoplayback == DEMO_QUAKE1 )
VectorLerp( ent->prevstate.origin, cl.lerpFrac, ent->curstate.origin, cl.simorg );
VectorCopy( cl.simorg, ent->origin );
@@ -1163,7 +1120,7 @@ CL_LinkPacketEntities
===============
*/
static void CL_LinkPacketEntities( frame_t *frame )
void CL_LinkPacketEntities( frame_t *frame )
{
cl_entity_t *ent;
entity_state_t *state;
@@ -1228,33 +1185,17 @@ static void CL_LinkPacketEntities( frame_t *frame )
#else
if( ent->lastmove >= cl.time )
{
float at = ent->curstate.animtime;
CL_ResetLatchedVars( ent, true );
if( cl_fixmodelinterpolationartifacts.value )
ent->latched.prevanimtime = ent->curstate.animtime = at;
VectorCopy( ent->curstate.origin, ent->latched.prevorigin );
VectorCopy( ent->curstate.angles, ent->latched.prevangles );
if( !FBitSet( host.features, ENGINE_COMPUTE_STUDIO_LERP ))
{
// disable step interpolation in client.dll
ent->curstate.movetype = MOVETYPE_NONE;
}
// disable step interpolation in client.dll
ent->curstate.movetype = MOVETYPE_NONE;
}
else
{
if( FBitSet( host.features, ENGINE_COMPUTE_STUDIO_LERP ))
{
interpolate = true;
}
else
{
// restore step interpolation in client.dll
ent->curstate.movetype = MOVETYPE_STEP;
}
// restore step interpolation in client.dll
ent->curstate.movetype = MOVETYPE_STEP;
}
#endif
}
@@ -1279,24 +1220,11 @@ static void CL_LinkPacketEntities( frame_t *frame )
if ( !CL_InterpolateModel( ent ))
continue;
}
// a1ba: in GoldSrc this is done for cstrike and czero
// but let modders use this as an engine feature
else if( FBitSet( host.features, ENGINE_STEP_POSHISTORY_LERP ) &&
ent->curstate.movetype == MOVETYPE_STEP && !NET_IsLocalAddress( cls.netchan.remote_address ))
else if( ent->curstate.movetype == MOVETYPE_STEP && !NET_IsLocalAddress( cls.netchan.remote_address ))
{
if( !CL_InterpolateModel( ent ))
continue;
}
#if 0
// ABSOLUTELY STUPID HACK TO ALLOW MONSTERS
// INTERPOLATION IN GRAVGUNMOD COOP
// MUST BE REMOVED ONCE WE REMOVE 48 PROTO SUPPORT
else if( cls.legacymode && ent->model->type == mod_studio && ent->curstate.movetype == MOVETYPE_TOSS )
{
if( !CL_InterpolateModel( ent ))
continue;
}
#endif
else
{
// no interpolation right now
@@ -1492,3 +1420,9 @@ qboolean CL_GetMovieSpatialization( rawchan_t *ch )
return true;
}
void CL_ExtraUpdate( void )
{
clgame.dllFuncs.IN_Accumulate();
S_ExtraUpdate();
}

File diff suppressed because it is too large Load Diff

View File

@@ -309,7 +309,7 @@ static void GAME_EXPORT UI_DrawLogo( const char *filename, float x, float y, flo
// run cinematic if not
Q_snprintf( path, sizeof( path ), "media/%s", filename );
COM_DefaultExtension( path, ".avi", sizeof( path ));
COM_DefaultExtension( path, ".avi" );
fullpath = FS_GetDiskPath( path, false );
if( FS_FileExists( path, false ) && !fullpath )
@@ -414,15 +414,57 @@ static void UI_ConvertGameInfo( GAMEINFO *out, gameinfo_t *in )
out->gamemode = in->gamemode;
if( in->nomodels )
SetBits( out->flags, GFL_NOMODELS );
out->flags |= GFL_NOMODELS;
if( in->noskills )
SetBits( out->flags, GFL_NOSKILLS );
if( in->render_picbutton_text )
SetBits( out->flags, GFL_RENDER_PICBUTTON_TEXT );
if( in->hd_background )
SetBits( out->flags, GFL_HD_BACKGROUND );
if( in->animated_title )
SetBits( out->flags, GFL_ANIMATED_TITLE );
out->flags |= GFL_NOSKILLS;
}
static qboolean PIC_Scissor( float *x, float *y, float *width, float *height, float *u0, float *v0, float *u1, float *v1 )
{
float dudx, dvdy;
// clip sub rect to sprite
if(( width == 0 ) || ( height == 0 ))
return false;
if( *x + *width <= gameui.ds.scissor_x )
return false;
if( *x >= gameui.ds.scissor_x + gameui.ds.scissor_width )
return false;
if( *y + *height <= gameui.ds.scissor_y )
return false;
if( *y >= gameui.ds.scissor_y + gameui.ds.scissor_height )
return false;
dudx = (*u1 - *u0) / *width;
dvdy = (*v1 - *v0) / *height;
if( *x < gameui.ds.scissor_x )
{
*u0 += (gameui.ds.scissor_x - *x) * dudx;
*width -= gameui.ds.scissor_x - *x;
*x = gameui.ds.scissor_x;
}
if( *x + *width > gameui.ds.scissor_x + gameui.ds.scissor_width )
{
*u1 -= (*x + *width - (gameui.ds.scissor_x + gameui.ds.scissor_width)) * dudx;
*width = gameui.ds.scissor_x + gameui.ds.scissor_width - *x;
}
if( *y < gameui.ds.scissor_y )
{
*v0 += (gameui.ds.scissor_y - *y) * dvdy;
*height -= gameui.ds.scissor_y - *y;
*y = gameui.ds.scissor_y;
}
if( *y + *height > gameui.ds.scissor_y + gameui.ds.scissor_height )
{
*v1 -= (*y + *height - (gameui.ds.scissor_y + gameui.ds.scissor_height)) * dvdy;
*height = gameui.ds.scissor_y + gameui.ds.scissor_height - *y;
}
return true;
}
/*
@@ -443,10 +485,10 @@ static void PIC_DrawGeneric( float x, float y, float width, float height, const
if( prc )
{
// calc user-defined rectangle
s1 = prc->left / (float)w;
t1 = prc->top / (float)h;
s2 = prc->right / (float)w;
t2 = prc->bottom / (float)h;
s1 = (float)prc->left / (float)w;
t1 = (float)prc->top / (float)h;
s2 = (float)prc->right / (float)w;
t2 = (float)prc->bottom / (float)h;
if( width == -1 && height == -1 )
{
@@ -467,9 +509,10 @@ static void PIC_DrawGeneric( float x, float y, float width, float height, const
}
// pass scissor test if supposed
if( !CL_Scissor( &gameui.ds.scissor, &x, &y, &width, &height, &s1, &t1, &s2, &t2 ))
if( gameui.ds.scissor_test && !PIC_Scissor( &x, &y, &width, &height, &s1, &t1, &s2, &t2 ))
return;
PicAdjustSize( &x, &y, &width, &height );
ref.dllFuncs.R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, gameui.ds.gl_texturenum );
ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
}
@@ -542,7 +585,7 @@ pfnPIC_Set
=========
*/
static void GAME_EXPORT pfnPIC_Set( HIMAGE hPic, int r, int g, int b, int a )
void GAME_EXPORT pfnPIC_Set( HIMAGE hPic, int r, int g, int b, int a )
{
gameui.ds.gl_texturenum = hPic;
r = bound( 0, r, 255 );
@@ -558,7 +601,7 @@ pfnPIC_Draw
=========
*/
static void GAME_EXPORT pfnPIC_Draw( int x, int y, int width, int height, const wrect_t *prc )
void GAME_EXPORT pfnPIC_Draw( int x, int y, int width, int height, const wrect_t *prc )
{
ref.dllFuncs.GL_SetRenderMode( kRenderNormal );
PIC_DrawGeneric( x, y, width, height, prc );
@@ -570,7 +613,7 @@ pfnPIC_DrawTrans
=========
*/
static void GAME_EXPORT pfnPIC_DrawTrans( int x, int y, int width, int height, const wrect_t *prc )
void GAME_EXPORT pfnPIC_DrawTrans( int x, int y, int width, int height, const wrect_t *prc )
{
ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture );
PIC_DrawGeneric( x, y, width, height, prc );
@@ -582,7 +625,7 @@ pfnPIC_DrawHoles
=========
*/
static void GAME_EXPORT pfnPIC_DrawHoles( int x, int y, int width, int height, const wrect_t *prc )
void GAME_EXPORT pfnPIC_DrawHoles( int x, int y, int width, int height, const wrect_t *prc )
{
ref.dllFuncs.GL_SetRenderMode( kRenderTransAlpha );
PIC_DrawGeneric( x, y, width, height, prc );
@@ -594,7 +637,7 @@ pfnPIC_DrawAdditive
=========
*/
static void GAME_EXPORT pfnPIC_DrawAdditive( int x, int y, int width, int height, const wrect_t *prc )
void GAME_EXPORT pfnPIC_DrawAdditive( int x, int y, int width, int height, const wrect_t *prc )
{
ref.dllFuncs.GL_SetRenderMode( kRenderTransAdd );
PIC_DrawGeneric( x, y, width, height, prc );
@@ -614,7 +657,11 @@ static void GAME_EXPORT pfnPIC_EnableScissor( int x, int y, int width, int heigh
width = bound( 0, width, gameui.globals->scrWidth - x );
height = bound( 0, height, gameui.globals->scrHeight - y );
CL_EnableScissor( &gameui.ds.scissor, x, y, width, height );
gameui.ds.scissor_x = x;
gameui.ds.scissor_width = width;
gameui.ds.scissor_y = y;
gameui.ds.scissor_height = height;
gameui.ds.scissor_test = true;
}
/*
@@ -625,7 +672,11 @@ pfnPIC_DisableScissor
*/
static void GAME_EXPORT pfnPIC_DisableScissor( void )
{
CL_DisableScissor( &gameui.ds.scissor );
gameui.ds.scissor_x = 0;
gameui.ds.scissor_width = 0;
gameui.ds.scissor_y = 0;
gameui.ds.scissor_height = 0;
gameui.ds.scissor_test = false;
}
/*
@@ -646,17 +697,6 @@ static void GAME_EXPORT pfnFillRGBA( int x, int y, int width, int height, int r,
ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
}
/*
=============
pfnCvar_RegisterVariable
=============
*/
static cvar_t *GAME_EXPORT pfnCvar_RegisterGameUIVariable( const char *szName, const char *szValue, int flags )
{
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_GAMEUIDLL, Cvar_BuildAutoDescription( szName, flags|FCVAR_GAMEUIDLL ));
}
/*
=============
pfnClientCmd
@@ -724,7 +764,7 @@ static void GAME_EXPORT pfnDrawCharacter( int ix, int iy, int iwidth, int iheigh
t2 = t1 + size;
// pass scissor test if supposed
if( !CL_Scissor( &gameui.ds.scissor, &x, &y, &width, &height, &s1, &t1, &s2, &t2 ))
if( gameui.ds.scissor_test && !PIC_Scissor( &x, &y, &width, &height, &s1, &t1, &s2, &t2 ))
return;
ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture );
@@ -853,7 +893,7 @@ send client connect
*/
static void GAME_EXPORT pfnClientJoin( const netadr_t adr )
{
Cbuf_AddTextf( "connect %s\n", NET_AdrToString( adr ));
Cbuf_AddText( va( "connect %s\n", NET_AdrToString( adr )));
}
/*
@@ -938,7 +978,7 @@ pfnGetGamesList
*/
static GAMEINFO ** GAME_EXPORT pfnGetGamesList( int *numGames )
{
if( numGames ) *numGames = FI->numgames;
if( numGames ) *numGames = SI.numgames;
return gameui.modsInfo;
}
@@ -984,23 +1024,30 @@ pfnCheckGameDll
=========
*/
static int GAME_EXPORT pfnCheckGameDll( void )
int GAME_EXPORT pfnCheckGameDll( void )
{
#ifdef XASH_INTERNAL_GAMELIBS
return true;
#else
string dllpath;
void *hInst;
#if TARGET_OS_IPHONE
// loading server library drains too many ram
// so 512MB iPod Touch cannot even connect to
// to servers in cstrike
return true;
#endif
if( svgame.hInstance )
return true;
COM_GetCommonLibraryPath( LIBRARY_SERVER, dllpath, sizeof( dllpath ));
if( FS_FileExists( dllpath, false ))
if(( hInst = COM_LoadLibrary( dllpath, true, false )) != NULL )
{
COM_FreeLibrary( hInst ); // don't increase linker's reference counter
return true;
}
Con_Reportf( S_WARN "Could not load server library: %s\n", COM_GetLibraryError() );
return false;
#endif
}
/*
@@ -1011,7 +1058,10 @@ pfnChangeInstance
*/
static void GAME_EXPORT pfnChangeInstance( const char *newInstance, const char *szFinalMessage )
{
Con_Reportf( S_ERROR "ChangeInstance menu call is deprecated!\n" );
if( !szFinalMessage ) szFinalMessage = "";
if( !newInstance || !*newInstance ) return;
Host_NewInstance( newInstance, szFinalMessage );
}
/*
@@ -1068,35 +1118,6 @@ static char *pfnParseFile( char *buf, char *token )
return COM_ParseFile( buf, token, INT_MAX );
}
/*
=============
pfnFileExists
legacy wrapper
=============
*/
static int pfnFileExists( const char *path, int gamedironly )
{
return FS_FileExists( path, gamedironly );
}
/*
=============
pfnDelete
legacy wrapper
=============
*/
static int pfnDelete( const char *path )
{
return FS_Delete( path );
}
static void GAME_EXPORT pfnCon_DefaultColor( int r, int g, int b )
{
Con_DefaultColor( r, g, b, true );
}
// engine callbacks
static ui_enginefuncs_t gEngfuncs =
{
@@ -1136,14 +1157,14 @@ static ui_enginefuncs_t gEngfuncs =
UI_DrawConsoleString,
UI_DrawSetTextColor,
Con_DrawStringLen,
pfnCon_DefaultColor,
Con_DefaultColor,
pfnGetPlayerModel,
pfnSetPlayerModel,
pfnClearScene,
pfnRenderScene,
pfnAddEntity,
Host_Error,
pfnFileExists,
FS_FileExists,
pfnGetGameDir,
Cmd_CheckMapsList,
CL_Active,
@@ -1182,7 +1203,7 @@ static ui_enginefuncs_t gEngfuncs =
COM_CompareFileTime,
VID_GetModeString,
(void*)COM_SaveFile,
pfnDelete
(void*)FS_Delete
};
static void pfnEnableTextInput( int enable )
@@ -1204,11 +1225,6 @@ static int pfnGetRenderers( unsigned int num, char *shortName, size_t size1, cha
return 1;
}
static char *pfnParseFileSafe( char *data, char *buf, const int size, unsigned int flags, int *len )
{
return COM_ParseFileSafe( data, buf, size, flags, len, NULL );
}
static ui_extendedfuncs_t gExtendedfuncs =
{
pfnEnableTextInput,
@@ -1217,9 +1233,7 @@ static ui_extendedfuncs_t gExtendedfuncs =
Con_UtfMoveRight,
pfnGetRenderers,
Sys_DoubleTime,
pfnParseFileSafe,
NET_AdrToString,
NET_CompareAdrSort,
_COM_ParseFileSafe
};
void UI_UnloadProgs( void )
@@ -1231,12 +1245,12 @@ void UI_UnloadProgs( void )
Cvar_FullSet( "host_gameuiloaded", "0", FCVAR_READ_ONLY );
Cvar_Unlink( FCVAR_GAMEUIDLL );
Cmd_Unlink( CMD_GAMEUIDLL );
COM_FreeLibrary( gameui.hInstance );
Mem_FreePool( &gameui.mempool );
memset( &gameui, 0, sizeof( gameui ));
Cvar_Unlink( FCVAR_GAMEUIDLL );
Cmd_Unlink( CMD_GAMEUIDLL );
}
qboolean UI_LoadProgs( void )
@@ -1339,13 +1353,13 @@ qboolean UI_LoadProgs( void )
Cvar_FullSet( "host_gameuiloaded", "1", FCVAR_READ_ONLY );
// setup gameinfo
for( i = 0; i < FI->numgames; i++ )
for( i = 0; i < SI.numgames; i++ )
{
gameui.modsInfo[i] = Mem_Calloc( gameui.mempool, sizeof( GAMEINFO ));
UI_ConvertGameInfo( gameui.modsInfo[i], FI->games[i] );
UI_ConvertGameInfo( gameui.modsInfo[i], SI.games[i] );
}
UI_ConvertGameInfo( &gameui.gameInfo, FI->GameInfo ); // current gameinfo
UI_ConvertGameInfo( &gameui.gameInfo, SI.GameInfo ); // current gameinfo
// setup globals
gameui.globals->developer = host.allow_console;

File diff suppressed because it is too large Load Diff

View File

@@ -20,17 +20,14 @@ GNU General Public License for more details.
#include "input.h"
#include "platform/platform.h"
static mobile_engfuncs_t *gMobileEngfuncs;
mobile_engfuncs_t *gMobileEngfuncs;
static CVAR_DEFINE_AUTO( vibration_length, "1.0", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "vibration length" );
static CVAR_DEFINE_AUTO( vibration_enable, "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "enable vibration" );
static cl_font_t g_scaled_font;
static float g_font_scale;
convar_t *vibration_length;
convar_t *vibration_enable;
static void pfnVibrate( float life, char flags )
{
if( !vibration_enable.value )
if( !vibration_enable->value )
return;
if( life < 0.0f )
@@ -42,7 +39,7 @@ static void pfnVibrate( float life, char flags )
//Con_Reportf( "Vibrate: %f %d\n", life, flags );
// here goes platform-specific backends
Platform_Vibrate( life * vibration_length.value, flags );
Platform_Vibrate( life * vibration_length->value, flags );
}
static void Vibrate_f( void )
@@ -63,44 +60,39 @@ static void pfnEnableTextInput( int enable )
static int pfnDrawScaledCharacter( int x, int y, int number, int r, int g, int b, float scale )
{
// this call is very ineffective and possibly broken!
rgba_t color = { r, g, b, 255 };
int flags = FONT_DRAW_HUD;
int width = clgame.scrInfo.charWidths[number] * scale * hud_scale->value;
int height = clgame.scrInfo.iCharHeight * scale * hud_scale->value;
if( hud_utf8.value )
SetBits( flags, FONT_DRAW_UTF8 );
if( !cls.creditsFont.valid )
return 0;
if( fabs( g_font_scale - scale ) > 0.1f ||
g_scaled_font.hFontTexture != cls.creditsFont.hFontTexture )
{
int i;
x *= hud_scale->value;
y *= hud_scale->value;
g_scaled_font = cls.creditsFont;
g_scaled_font.scale *= scale;
g_scaled_font.charHeight *= scale;
for( i = 0; i < ARRAYSIZE( g_scaled_font.charWidths ); i++ )
g_scaled_font.charWidths[i] *= scale;
number &= 255;
number = Con_UtfProcessChar( number );
g_font_scale = scale;
}
if( number < 32 )
return 0;
return CL_DrawCharacter( x, y, number, color, &g_scaled_font, flags );
if( y < -height )
return 0;
pfnPIC_Set( cls.creditsFont.hFontTexture, r, g, b, 255 );
pfnPIC_DrawAdditive( x, y, width, height, &cls.creditsFont.fontRc[number] );
return width;
}
static void pfnTouch_HideButtons( const char *name, byte state )
static void *pfnGetNativeObject( const char *obj )
{
Touch_HideButtons( name, state, true );
if( !obj )
return NULL;
// Backend should consider that obj is case-sensitive
return Platform_GetNativeObject( obj );
}
static void pfnTouch_RemoveButton( const char *name )
{
Touch_RemoveButton( name, true );
}
static char *pfnParseFileSafe( char *data, char *buf, const int size, unsigned int flags, int *len )
{
return COM_ParseFileSafe( data, buf, size, flags, len, NULL );
}
static mobile_engfuncs_t gpMobileEngfuncs =
{
@@ -109,15 +101,15 @@ static mobile_engfuncs_t gpMobileEngfuncs =
pfnEnableTextInput,
Touch_AddClientButton,
Touch_AddDefaultButton,
pfnTouch_HideButtons,
pfnTouch_RemoveButton,
Touch_SetClientOnly,
Touch_HideButtons,
Touch_RemoveButton,
(void*)Touch_SetClientOnly,
Touch_ResetDefaultButtons,
pfnDrawScaledCharacter,
Sys_Warn,
Sys_GetNativeObject,
pfnGetNativeObject,
ID_SetCustomClientID,
pfnParseFileSafe
_COM_ParseFileSafe
};
qboolean Mobile_Init( void )
@@ -133,8 +125,8 @@ qboolean Mobile_Init( void )
success = true;
Cmd_AddCommand( "vibrate", (xcommand_t)Vibrate_f, "Vibrate for specified time");
Cvar_RegisterVariable( &vibration_length );
Cvar_RegisterVariable( &vibration_enable );
vibration_length = Cvar_Get( "vibration_length", "1.0", FCVAR_ARCHIVE, "Vibration length");
vibration_enable = Cvar_Get( "vibration_enable", "1", FCVAR_ARCHIVE, "Enable vibration");
return success;
}

View File

@@ -33,12 +33,12 @@ GNU General Public License for more details.
#define NETGRAPH_NET_COLORS 5
#define NUM_LATENCY_SAMPLES 8
CVAR_DEFINE_AUTO( net_graph, "0", FCVAR_ARCHIVE, "draw network usage graph" );
static CVAR_DEFINE_AUTO( net_graphpos, "1", FCVAR_ARCHIVE, "network usage graph position" );
static CVAR_DEFINE_AUTO( net_scale, "5", FCVAR_ARCHIVE, "network usage graph scale level" );
static CVAR_DEFINE_AUTO( net_graphwidth, "192", FCVAR_ARCHIVE, "network usage graph width" );
static CVAR_DEFINE_AUTO( net_graphheight, "64", FCVAR_ARCHIVE, "network usage graph height" );
static CVAR_DEFINE_AUTO( net_graphsolid, "1", FCVAR_ARCHIVE, "fill segments in network usage graph" );
convar_t *net_graph;
static convar_t *net_graphpos;
static convar_t *net_graphwidth;
static convar_t *net_graphheight;
static convar_t *net_graphsolid;
static convar_t *net_scale;
static struct packet_latency_t
{
@@ -158,7 +158,6 @@ static void NetGraph_InitColors( void )
f = (float)(i - hfrac) / (float)(NETGRAPH_LERP_HEIGHT - hfrac );
VectorMA( mincolor[1], f, dc[1], netcolors[NETGRAPH_NET_COLORS + i] );
}
netcolors[NETGRAPH_NET_COLORS + i][3] = 255;
}
}
@@ -211,7 +210,7 @@ static void NetGraph_GetFrameData( float *latency, int *latency_count )
else
{
int frame_latency = Q_min( 1.0f, f->latency );
p->latency = (( frame_latency + 0.1f ) / 1.1f ) * ( net_graphheight.value - NETGRAPH_LERP_HEIGHT - 2 );
p->latency = (( frame_latency + 0.1f ) / 1.1f ) * ( net_graphheight->value - NETGRAPH_LERP_HEIGHT - 2 );
if( i > cls.netchan.incoming_sequence - NUM_LATENCY_SAMPLES )
{
@@ -260,7 +259,7 @@ static void NetGraph_DrawTimes( wrect_t rect, int x, int w )
for( a = 0; a < w; a++ )
{
i = ( cls.netchan.outgoing_sequence - a ) & NET_TIMINGS_MASK;
h = Q_min(( netstat_cmdinfo[i].cmd_lerp / 3.0f ) * NETGRAPH_LERP_HEIGHT, net_graphheight.value * 0.7f);
h = ( netstat_cmdinfo[i].cmd_lerp / 3.0f ) * NETGRAPH_LERP_HEIGHT;
fill.left = x + w - a - 1;
fill.right = fill.bottom = 1;
@@ -273,7 +272,7 @@ static void NetGraph_DrawTimes( wrect_t rect, int x, int w )
h -= extrap_point;
fill.top -= extrap_point;
if( !net_graphsolid.value )
if( !net_graphsolid->value )
{
fill.top -= (h - 1);
start = (h - 1);
@@ -281,10 +280,7 @@ static void NetGraph_DrawTimes( wrect_t rect, int x, int w )
for( j = start; j < h; j++ )
{
int color = NETGRAPH_NET_COLORS + j + extrap_point;
color = Q_min( color, ARRAYSIZE( netcolors ) - 1 );
NetGraph_DrawRect( &fill, netcolors[color] );
NetGraph_DrawRect( &fill, netcolors[NETGRAPH_NET_COLORS + j + extrap_point] );
fill.top--;
}
}
@@ -295,15 +291,12 @@ static void NetGraph_DrawTimes( wrect_t rect, int x, int w )
fill.top -= h;
h = extrap_point - h;
if( !net_graphsolid.value )
if( !net_graphsolid->value )
h = 1;
for( j = 0; j < h; j++ )
{
int color = NETGRAPH_NET_COLORS + j + oldh;
color = Q_min( color, ARRAYSIZE( netcolors ) - 1 );
NetGraph_DrawRect( &fill, netcolors[color] );
NetGraph_DrawRect( &fill, netcolors[NETGRAPH_NET_COLORS + j + oldh] );
fill.top--;
}
}
@@ -334,7 +327,7 @@ NetGraph_DrawHatches
*/
static void NetGraph_DrawHatches( int x, int y )
{
int ystep = (int)( 10.0f / net_scale.value );
int ystep = (int)( 10.0f / net_scale->value );
byte colorminor[4] = { 0, 63, 63, 200 };
byte color[4] = { 0, 200, 0, 255 };
wrect_t hatch = { x, 4, y, 1 };
@@ -342,9 +335,9 @@ static void NetGraph_DrawHatches( int x, int y )
ystep = Q_max( ystep, 1 );
for( starty = hatch.top; hatch.top > 0 && ((starty - hatch.top) * net_scale.value < (maxmsgbytes + 50)); hatch.top -= ystep )
for( starty = hatch.top; hatch.top > 0 && ((starty - hatch.top) * net_scale->value < (maxmsgbytes + 50)); hatch.top -= ystep )
{
if(!((int)((starty - hatch.top) * net_scale.value ) % 50 ))
if(!((int)((starty - hatch.top) * net_scale->value ) % 50 ))
{
NetGraph_DrawRect( &hatch, color );
}
@@ -364,20 +357,19 @@ NetGraph_DrawTextFields
static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int count, float avg, int packet_loss, int packet_choke, int graphtype )
{
static int lastout;
cl_font_t *font = Con_GetFont( 0 );
rgba_t colors = { 0.9 * 255, 0.9 * 255, 0.7 * 255, 255 };
int ptx = Q_max( x + w - NETGRAPH_LERP_HEIGHT - 1, 1 );
int pty = Q_max( rect.top + rect.bottom - NETGRAPH_LERP_HEIGHT - 3, 1 );
int out, i = ( cls.netchan.outgoing_sequence - 1 ) & NET_TIMINGS_MASK;
int j = cls.netchan.incoming_sequence & NET_TIMINGS_MASK;
int last_y = y - net_graphheight.value;
int last_y = y - net_graphheight->value;
if( count > 0 )
{
avg = avg / (float)( count - ( host.frametime * FRAMERATE_AVG_FRAC ));
if( cl_updaterate.value > 0.0f )
avg -= 1000.0f / cl_updaterate.value;
if( cl_updaterate->value > 0.0f )
avg -= 1000.0f / cl_updaterate->value;
// can't be below zero
avg = Q_max( 0.0f, avg );
@@ -386,17 +378,16 @@ static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int coun
// move rolling average
framerate = FRAMERATE_AVG_FRAC * host.frametime + ( 1.0f - FRAMERATE_AVG_FRAC ) * framerate;
ref.dllFuncs.GL_SetRenderMode( font->rendermode );
Con_SetFont( 0 );
if( framerate > 0.0f )
{
y -= net_graphheight.value;
y -= net_graphheight->value;
CL_DrawStringf( font, x, y, colors, FONT_DRAW_NORENDERMODE, "%.1f fps" , 1.0f / framerate);
Con_DrawString( x, y, va( "%.1f fps" , 1.0f / framerate ), colors );
if( avg > 1.0f )
CL_DrawStringf( font, x + 75, y, colors, FONT_DRAW_NORENDERMODE, "%i ms" , (int)avg );
Con_DrawString( x + 75, y, va( "%i ms" , (int)avg ), colors );
y += 15;
@@ -404,12 +395,10 @@ static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int coun
if( !out ) out = lastout;
else lastout = out;
CL_DrawStringf( font, x, y, colors, FONT_DRAW_NORENDERMODE,
"in : %i %.2f kb/s", netstat_graph[j].msgbytes, cls.netchan.flow[FLOW_INCOMING].avgkbytespersec );
Con_DrawString( x, y, va( "in : %i %.2f k/s", netstat_graph[j].msgbytes, cls.netchan.flow[FLOW_INCOMING].avgkbytespersec ), colors );
y += 15;
CL_DrawStringf( font, x, y, colors, FONT_DRAW_NORENDERMODE,
"out: %i %.2f kb/s", out, cls.netchan.flow[FLOW_OUTGOING].avgkbytespersec );
Con_DrawString( x, y, va( "out: %i %.2f k/s", out, cls.netchan.flow[FLOW_OUTGOING].avgkbytespersec ), colors );
y += 15;
if( graphtype > 2 )
@@ -417,14 +406,16 @@ static void NetGraph_DrawTextFields( int x, int y, int w, wrect_t rect, int coun
int loss = (int)(( packet_loss + PACKETLOSS_AVG_FRAC ) - 0.01f );
int choke = (int)(( packet_choke + PACKETCHOKE_AVG_FRAC ) - 0.01f );
CL_DrawStringf( font, x, y, colors, FONT_DRAW_NORENDERMODE, "loss: %i choke: %i", loss, choke );
Con_DrawString( x, y, va( "loss: %i choke: %i", loss, choke ), colors );
}
}
if( graphtype < 3 )
CL_DrawStringf( font, ptx, pty, colors, FONT_DRAW_NORENDERMODE, "%i/s", (int)cl_cmdrate.value );
Con_DrawString( ptx, pty, va( "%i/s", (int)cl_cmdrate->value ), colors );
CL_DrawStringf( font, ptx, last_y, colors, FONT_DRAW_NORENDERMODE, "%i/s" , (int)cl_updaterate.value );
Con_DrawString( ptx, last_y, va( "%i/s" , (int)cl_updaterate->value ), colors );
Con_RestoreFont();
}
/*
@@ -435,12 +426,12 @@ NetGraph_DrawDataSegment
*/
static int NetGraph_DrawDataSegment( wrect_t *fill, int bytes, byte r, byte g, byte b, byte a )
{
float h = bytes / net_scale.value;
float h = bytes / net_scale->value;
byte colors[4] = { r, g, b, a };
fill->top -= (int)h;
if( net_graphsolid.value )
if( net_graphsolid->value )
fill->bottom = (int)h;
else fill->bottom = 1;
@@ -498,7 +489,7 @@ NetGraph_DrawDataUsage
static void NetGraph_DrawDataUsage( int x, int y, int w, int graphtype )
{
int a, i, h, lastvalidh = 0, ping;
int pingheight = net_graphheight.value - NETGRAPH_LERP_HEIGHT - 2;
int pingheight = net_graphheight->value - NETGRAPH_LERP_HEIGHT - 2;
wrect_t fill = { 0 };
byte color[4];
@@ -554,7 +545,7 @@ static void NetGraph_DrawDataUsage( int x, int y, int w, int graphtype )
continue;
color[0] = color[1] = color[2] = color[3] = 255;
fill.top = y - net_graphheight.value - 1;
fill.top = y - net_graphheight->value - 1;
fill.bottom = 1;
if( NetGraph_AtEdge( a, w ))
@@ -589,7 +580,7 @@ static void NetGraph_DrawDataUsage( int x, int y, int w, int graphtype )
if( !NetGraph_DrawDataSegment( &fill, netstat_graph[i].voicebytes, 255, 255, 255, 255 ))
continue;
fill.top = y - net_graphheight.value - 1;
fill.top = y - net_graphheight->value - 1;
fill.bottom = 1;
fill.top -= 2;
@@ -598,7 +589,7 @@ static void NetGraph_DrawDataUsage( int x, int y, int w, int graphtype )
}
if( graphtype >= 2 )
NetGraph_DrawHatches( x, y - net_graphheight.value - 1 );
NetGraph_DrawHatches( x, y - net_graphheight->value - 1 );
}
/*
@@ -613,18 +604,18 @@ static void NetGraph_GetScreenPos( wrect_t *rect, int *w, int *x, int *y )
rect->right = refState.width;
rect->bottom = refState.height;
*w = Q_min( NET_TIMINGS, net_graphwidth.value );
*w = Q_min( NET_TIMINGS, net_graphwidth->value );
if( rect->right < *w + 10 )
*w = rect->right - 10;
// detect x and y position
switch( (int)net_graphpos.value )
switch( (int)net_graphpos->value )
{
case 1: // right sided
*x = rect->left + rect->right - 5 - *w;
break;
case 2: // center
*x = ( rect->left + ( rect->right - 10 - *w )) / 2;
*x = rect->left + ( rect->right - 10 - *w ) / 2;
break;
default: // left sided
*x = rect->left + 5;
@@ -661,16 +652,16 @@ void SCR_DrawNetGraph( void )
{
graphtype = 2;
}
else if( net_graph.value != 0.0f )
else if( net_graph->value != 0.0f )
{
graphtype = (int)net_graph.value;
graphtype = (int)net_graph->value;
}
else
{
return;
}
if( net_scale.value <= 0 )
if( net_scale->value <= 0 )
Cvar_SetValue( "net_scale", 0.1f );
NetGraph_GetScreenPos( &rect, &w, &x, &y );
@@ -681,7 +672,7 @@ void SCR_DrawNetGraph( void )
if( graphtype < 3 )
{
ref.dllFuncs.GL_SetRenderMode( kRenderTransColor );
ref.dllFuncs.GL_SetRenderMode( kRenderTransAdd );
ref.dllFuncs.GL_Bind( XASH_TEXTURE0, R_GetBuiltinTexture( REF_WHITE_TEXTURE ) );
ref.dllFuncs.Begin( TRI_QUADS ); // draw all the fills as a long solid sequence of quads for speedup reasons
@@ -697,12 +688,12 @@ void SCR_DrawNetGraph( void )
void CL_InitNetgraph( void )
{
Cvar_RegisterVariable( &net_graph );
Cvar_RegisterVariable( &net_graphpos );
Cvar_RegisterVariable( &net_scale );
Cvar_RegisterVariable( &net_graphwidth );
Cvar_RegisterVariable( &net_graphheight );
Cvar_RegisterVariable( &net_graphsolid );
net_graph = Cvar_Get( "net_graph", "0", FCVAR_ARCHIVE, "draw network usage graph" );
net_graphpos = Cvar_Get( "net_graphpos", "1", FCVAR_ARCHIVE, "network usage graph position" );
net_scale = Cvar_Get( "net_scale", "5", FCVAR_ARCHIVE, "network usage graph scale level" );
net_graphwidth = Cvar_Get( "net_graphwidth", "192", FCVAR_ARCHIVE, "network usage graph width" );
net_graphheight = Cvar_Get( "net_graphheight", "64", FCVAR_ARCHIVE, "network usage graph height" );
net_graphsolid = Cvar_Get( "net_graphsolid", "1", FCVAR_ARCHIVE, "fill segments in network usage graph" );
packet_loss = packet_choke = 0.0;
NetGraph_InitColors();

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -26,6 +26,20 @@ GNU General Public License for more details.
#define MIN_PREDICTION_EPSILON 0.5f // complain if error is > this and we have cl_showerror set
#define MAX_PREDICTION_ERROR 64.0f // above this is assumed to be a teleport, don't smooth, etc.
/*
=============
CL_ClearPhysEnts
=============
*/
void CL_ClearPhysEnts( void )
{
clgame.pmove->numtouch = 0;
clgame.pmove->numvisent = 0;
clgame.pmove->nummoveent = 0;
clgame.pmove->numphysent = 0;
}
/*
=============
CL_PushPMStates
@@ -54,6 +68,31 @@ void GAME_EXPORT CL_PopPMStates( void )
clgame.pushed = false;
}
/*
=============
CL_PushTraceBounds
=============
*/
void GAME_EXPORT CL_PushTraceBounds( int hullnum, const float *mins, const float *maxs )
{
hullnum = bound( 0, hullnum, 3 );
VectorCopy( mins, clgame.pmove->player_mins[hullnum] );
VectorCopy( maxs, clgame.pmove->player_maxs[hullnum] );
}
/*
=============
CL_PopTraceBounds
=============
*/
void GAME_EXPORT CL_PopTraceBounds( void )
{
memcpy( clgame.pmove->player_mins, host.player_mins, sizeof( host.player_mins ));
memcpy( clgame.pmove->player_maxs, host.player_maxs, sizeof( host.player_maxs ));
}
/*
===============
CL_IsPredicted
@@ -61,7 +100,7 @@ CL_IsPredicted
*/
qboolean CL_IsPredicted( void )
{
if( cl_nopred.value || cl.intermission )
if( cl_nopred->value || cl.intermission )
return false;
// never predict the quake demos
@@ -158,7 +197,7 @@ void CL_SetIdealPitch( void )
}
if( steps < 2 ) return;
cl.local.idealpitch = -dir * cl_idealpitchscale.value;
cl.local.idealpitch = -dir * cl_idealpitchscale->value;
}
/*
@@ -169,7 +208,7 @@ check for instant movement in case
we don't want interpolate this
==================
*/
static qboolean CL_PlayerTeleported( local_state_t *from, local_state_t *to )
qboolean CL_PlayerTeleported( local_state_t *from, local_state_t *to )
{
int len, maxlen;
vec3_t delta;
@@ -209,7 +248,7 @@ void CL_CheckPredictionError( void )
// save the prediction error for interpolation
if( dist > MAX_PREDICTION_ERROR )
{
if( cl_showerror.value && host_developer.value )
if( cl_showerror->value && host_developer.value )
Con_NPrintf( 10 + ( ++pos & 3 ), "^3player teleported:^7 %.3f units\n", dist );
// a teleport or something or gamepaused
@@ -217,7 +256,7 @@ void CL_CheckPredictionError( void )
}
else
{
if( cl_showerror.value && dist > MIN_PREDICTION_EPSILON && host_developer.value )
if( cl_showerror->value && dist > MIN_PREDICTION_EPSILON && host_developer.value )
Con_NPrintf( 10 + ( ++pos & 3 ), "^1prediction error:^7 %.3f units\n", dist );
VectorCopy( cl.frames[cmd].playerstate[cl.playernum].origin, cl.local.predicted_origins[frame] );
@@ -228,7 +267,7 @@ void CL_CheckPredictionError( void )
// GoldSrc checks for singleplayer
// we would check for local server
if( dist > MIN_CORRECTION_DISTANCE && !SV_Active() )
cls.correction_time = cl_smoothtime.value;
cls.correction_time = cl_smoothtime->value;
}
}
@@ -392,7 +431,7 @@ CL_AddLinksToPmove
collect solid entities
====================
*/
static void CL_AddLinksToPmove( frame_t *frame )
void CL_AddLinksToPmove( frame_t *frame )
{
entity_state_t *state;
model_t *model;
@@ -508,7 +547,7 @@ void GAME_EXPORT CL_SetSolidPlayers( int playernum )
physent_t *pe;
int i;
if( !cl_solid_players.value )
if( !cl_solid_players->value )
return;
for( i = 0; i < MAX_CLIENTS; i++ )
@@ -662,6 +701,11 @@ cl_entity_t *CL_GetWaterEntity( const float *rgflPos )
return CL_GetEntityByIndex( entnum );
}
int GAME_EXPORT CL_TestLine( const vec3_t start, const vec3_t end, int flags )
{
return PM_TestLineExt( clgame.pmove, clgame.pmove->physents, clgame.pmove->numphysent, start, end, flags );
}
static int GAME_EXPORT pfnTestPlayerPosition( float *pos, pmtrace_t *ptrace )
{
return PM_TestPlayerPosition( clgame.pmove, pos, ptrace, NULL );
@@ -669,7 +713,33 @@ static int GAME_EXPORT pfnTestPlayerPosition( float *pos, pmtrace_t *ptrace )
static void GAME_EXPORT pfnStuckTouch( int hitent, pmtrace_t *tr )
{
PM_StuckTouch( clgame.pmove, hitent, tr );
int i;
for( i = 0; i < clgame.pmove->numtouch; i++ )
{
if( clgame.pmove->touchindex[i].ent == hitent )
return;
}
if( clgame.pmove->numtouch >= MAX_PHYSENTS )
return;
VectorCopy( clgame.pmove->velocity, tr->deltavelocity );
tr->ent = hitent;
clgame.pmove->touchindex[clgame.pmove->numtouch++] = *tr;
}
static int GAME_EXPORT pfnPointContents( float *p, int *truecontents )
{
int cont, truecont;
truecont = cont = PM_PointContents( clgame.pmove, p );
if( truecontents ) *truecontents = truecont;
if( cont <= CONTENTS_CURRENT_0 && cont >= CONTENTS_CURRENT_DOWN )
cont = CONTENTS_WATER;
return cont;
}
static int GAME_EXPORT pfnTruePointContents( float *p )
@@ -677,19 +747,99 @@ static int GAME_EXPORT pfnTruePointContents( float *p )
return PM_TruePointContents( clgame.pmove, p );
}
static int GAME_EXPORT pfnHullPointContents( struct hull_s *hull, int num, float *p )
{
return PM_HullPointContents( hull, num, p );
}
static pmtrace_t GAME_EXPORT pfnPlayerTrace( float *start, float *end, int traceFlags, int ignore_pe )
{
return PM_PlayerTraceExt( clgame.pmove, start, end, traceFlags, clgame.pmove->numphysent, clgame.pmove->physents, ignore_pe, NULL );
}
static void *pfnHullForBsp( physent_t *pe, float *offset )
pmtrace_t *PM_TraceLine( float *start, float *end, int flags, int usehull, int ignore_pe )
{
static pmtrace_t tr;
int old_usehull;
old_usehull = clgame.pmove->usehull;
clgame.pmove->usehull = usehull;
switch( flags )
{
case PM_TRACELINE_PHYSENTSONLY:
tr = PM_PlayerTraceExt( clgame.pmove, start, end, 0, clgame.pmove->numphysent, clgame.pmove->physents, ignore_pe, NULL );
break;
case PM_TRACELINE_ANYVISIBLE:
tr = PM_PlayerTraceExt( clgame.pmove, start, end, 0, clgame.pmove->numvisent, clgame.pmove->visents, ignore_pe, NULL );
break;
}
clgame.pmove->usehull = old_usehull;
return &tr;
}
static hull_t *pfnHullForBsp( physent_t *pe, float *offset )
{
return PM_HullForBsp( pe, clgame.pmove, offset );
}
static float GAME_EXPORT pfnTraceModel( physent_t *pe, float *start, float *end, trace_t *trace )
{
return PM_TraceModel( clgame.pmove, pe, start, end, trace );
int old_usehull;
vec3_t start_l, end_l;
vec3_t offset, temp;
qboolean rotated;
matrix4x4 matrix;
hull_t *hull;
old_usehull = clgame.pmove->usehull;
clgame.pmove->usehull = 2;
hull = PM_HullForBsp( pe, clgame.pmove, offset );
clgame.pmove->usehull = old_usehull;
if( pe->solid == SOLID_BSP && !VectorIsNull( pe->angles ))
rotated = true;
else rotated = false;
if( rotated )
{
Matrix4x4_CreateFromEntity( matrix, pe->angles, offset, 1.0f );
Matrix4x4_VectorITransform( matrix, start, start_l );
Matrix4x4_VectorITransform( matrix, end, end_l );
}
else
{
VectorSubtract( start, offset, start_l );
VectorSubtract( end, offset, end_l );
}
PM_RecursiveHullCheck( hull, hull->firstclipnode, 0, 1, start_l, end_l, (pmtrace_t *)trace );
trace->ent = NULL;
if( rotated )
{
VectorCopy( trace->plane.normal, temp );
Matrix4x4_TransformPositivePlane( matrix, temp, trace->plane.dist, trace->plane.normal, &trace->plane.dist );
}
VectorLerp( start, trace->fraction, end, trace->endpos );
return trace->fraction;
}
static const char *pfnTraceTexture( int ground, float *vstart, float *vend )
{
physent_t *pe;
if( ground < 0 || ground >= clgame.pmove->numphysent )
return NULL; // bad ground
pe = &clgame.pmove->physents[ground];
return PM_TraceTexture( pe, vstart, vend );
}
static void GAME_EXPORT pfnPlaySound( int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch )
@@ -718,7 +868,25 @@ static int GAME_EXPORT pfnTestPlayerPositionEx( float *pos, pmtrace_t *ptrace, p
static pmtrace_t *pfnTraceLineEx( float *start, float *end, int flags, int usehull, pfnIgnore pmFilter )
{
return PM_TraceLineEx( clgame.pmove, start, end, flags, usehull, pmFilter );
static pmtrace_t tr;
int old_usehull;
old_usehull = clgame.pmove->usehull;
clgame.pmove->usehull = usehull;
switch( flags )
{
case PM_TRACELINE_PHYSENTSONLY:
tr = PM_PlayerTraceExt( clgame.pmove, start, end, 0, clgame.pmove->numphysent, clgame.pmove->physents, -1, pmFilter );
break;
case PM_TRACELINE_ANYVISIBLE:
tr = PM_PlayerTraceExt( clgame.pmove, start, end, 0, clgame.pmove->numvisent, clgame.pmove->visents, -1, pmFilter );
break;
}
clgame.pmove->usehull = old_usehull;
return &tr;
}
/*
@@ -758,23 +926,23 @@ void CL_InitClientMove( void )
clgame.pmove->Con_Printf = Con_Printf;
clgame.pmove->Sys_FloatTime = Sys_DoubleTime;
clgame.pmove->PM_StuckTouch = pfnStuckTouch;
clgame.pmove->PM_PointContents = (void*)PM_CL_PointContents;
clgame.pmove->PM_PointContents = pfnPointContents;
clgame.pmove->PM_TruePointContents = pfnTruePointContents;
clgame.pmove->PM_HullPointContents = (void*)PM_HullPointContents;
clgame.pmove->PM_HullPointContents = pfnHullPointContents;
clgame.pmove->PM_PlayerTrace = pfnPlayerTrace;
clgame.pmove->PM_TraceLine = PM_CL_TraceLine;
clgame.pmove->PM_TraceLine = PM_TraceLine;
clgame.pmove->RandomLong = COM_RandomLong;
clgame.pmove->RandomFloat = COM_RandomFloat;
clgame.pmove->PM_GetModelType = pfnGetModelType;
clgame.pmove->PM_GetModelBounds = pfnGetModelBounds;
clgame.pmove->PM_HullForBsp = pfnHullForBsp;
clgame.pmove->PM_HullForBsp = (void*)pfnHullForBsp;
clgame.pmove->PM_TraceModel = pfnTraceModel;
clgame.pmove->COM_FileSize = COM_FileSize;
clgame.pmove->COM_LoadFile = COM_LoadFile;
clgame.pmove->COM_FreeFile = COM_FreeFile;
clgame.pmove->memfgets = COM_MemFgets;
clgame.pmove->PM_PlaySound = pfnPlaySound;
clgame.pmove->PM_TraceTexture = PM_CL_TraceTexture;
clgame.pmove->PM_TraceTexture = pfnTraceTexture;
clgame.pmove->PM_PlaybackEventFull = pfnPlaybackEventFull;
clgame.pmove->PM_PlayerTraceEx = pfnPlayerTraceEx;
clgame.pmove->PM_TestPlayerPositionEx = pfnTestPlayerPositionEx;
@@ -785,36 +953,26 @@ void CL_InitClientMove( void )
clgame.dllFuncs.pfnPlayerMoveInit( clgame.pmove );
}
static void CL_SetupPMove( playermove_t *pmove, const local_state_t *from, const usercmd_t *ucmd, qboolean runfuncs, double time )
static void PM_CheckMovingGround( clientdata_t *cd, entity_state_t *state, float frametime )
{
const entity_state_t *ps;
const clientdata_t *cd;
if(!( cd->flags & FL_BASEVELOCITY ))
{
// apply momentum (add in half of the previous frame of velocity first)
VectorMA( cd->velocity, 1.0f + (frametime * 0.5f), state->basevelocity, cd->velocity );
VectorClear( state->basevelocity );
}
cd->flags &= ~FL_BASEVELOCITY;
}
void CL_SetupPMove( playermove_t *pmove, local_state_t *from, usercmd_t *ucmd, qboolean runfuncs, double time )
{
entity_state_t *ps;
clientdata_t *cd;
ps = &from->playerstate;
cd = &from->client;
pmove->player_index = ps->number - 1;
// a1ba: workaround bug on old protocol where the server refuse to send
// our local player in delta. cl.playernum, in theory, must be equal
// to our local player index anyway
// this might not be a real solution, since everything else will be bogus
// but we need to properly run prediction and avoid potential memory
// corruption
// either debug this, or remove when old protocol will be dropped!!!
if( pmove->player_index < 0 )
{
if( cls.legacymode )
{
pmove->player_index = bound( 0, cl.playernum, cl.maxclients - 1 );
}
else
{
// if this happens, record a demo and send it to a1ba
Host_Error( "%s: ps->number == %d\n", __func__, ps->number );
}
}
pmove->multiplayer = (cl.maxclients > 1);
pmove->runfuncs = runfuncs;
pmove->time = time * 1000.0f;
@@ -826,21 +984,22 @@ static void CL_SetupPMove( playermove_t *pmove, const local_state_t *from, const
VectorCopy( ps->basevelocity, pmove->basevelocity );
VectorCopy( cd->view_ofs, pmove->view_ofs );
VectorClear( pmove->movedir );
pmove->flDuckTime = (float)cd->flDuckTime;
pmove->flDuckTime = cd->flDuckTime;
pmove->bInDuck = cd->bInDuck;
pmove->usehull = ps->usehull;
pmove->flTimeStepSound = cd->flTimeStepSound;
pmove->iStepLeft = ps->iStepLeft;
pmove->flFallVelocity = ps->flFallVelocity;
pmove->flSwimTime = (float)cd->flSwimTime;
pmove->flSwimTime = cd->flSwimTime;
VectorCopy( cd->punchangle, pmove->punchangle );
pmove->flSwimTime = cd->flSwimTime;
pmove->flNextPrimaryAttack = 0.0f; // not used by PM_ code
pmove->effects = ps->effects;
pmove->flags = cd->flags;
pmove->gravity = ps->gravity;
pmove->friction = ps->friction;
pmove->oldbuttons = ps->oldbuttons;
pmove->waterjumptime = (float)cd->waterjumptime;
pmove->waterjumptime = cd->waterjumptime;
pmove->dead = (cl.local.health <= 0);
pmove->deadflag = cd->deadflag;
pmove->spectator = (cls.spectator != 0);
@@ -867,7 +1026,7 @@ static void CL_SetupPMove( playermove_t *pmove, const local_state_t *from, const
Q_strncpy( pmove->physinfo, cls.physinfo, MAX_INFO_STRING );
}
static const void CL_FinishPMove( const playermove_t *pmove, local_state_t *to )
void CL_FinishPMove( playermove_t *pmove, local_state_t *to )
{
entity_state_t *ps;
clientdata_t *cd;
@@ -878,7 +1037,7 @@ static const void CL_FinishPMove( const playermove_t *pmove, local_state_t *to )
cd->flags = pmove->flags;
cd->bInDuck = pmove->bInDuck;
cd->flTimeStepSound = pmove->flTimeStepSound;
cd->flDuckTime = (int)pmove->flDuckTime;
cd->flDuckTime = pmove->flDuckTime;
cd->flSwimTime = (int)pmove->flSwimTime;
cd->waterjumptime = (int)pmove->waterjumptime;
cd->watertype = pmove->watertype;
@@ -891,7 +1050,7 @@ static const void CL_FinishPMove( const playermove_t *pmove, local_state_t *to )
VectorCopy( pmove->angles, ps->angles );
VectorCopy( pmove->basevelocity, ps->basevelocity );
VectorCopy( pmove->punchangle, cd->punchangle );
ps->oldbuttons = (uint)pmove->cmd.buttons;
ps->oldbuttons = pmove->cmd.buttons;
ps->friction = pmove->friction;
ps->movetype = pmove->movetype;
ps->onground = pmove->onground;
@@ -920,7 +1079,7 @@ CL_RunUsercmd
Runs prediction code for user cmd
=================
*/
static void CL_RunUsercmd( local_state_t *from, local_state_t *to, usercmd_t *u, qboolean runfuncs, double *time, unsigned int random_seed )
void CL_RunUsercmd( local_state_t *from, local_state_t *to, usercmd_t *u, qboolean runfuncs, double *time, unsigned int random_seed )
{
usercmd_t cmd;
@@ -999,9 +1158,13 @@ void CL_PredictMovement( qboolean repredicting )
{
runcmd_t *to_cmd = NULL, *from_cmd;
local_state_t *from = NULL, *to = NULL;
frame_t *frame = NULL;
uint current_command;
uint current_command_mod;
frame_t *frame = NULL;
uint i, stoppoint;
qboolean runfuncs;
double f = 1.0;
cl_entity_t *ent;
double time;
if( cls.state != ca_active || cls.spectator )
@@ -1012,7 +1175,7 @@ void CL_PredictMovement( qboolean repredicting )
CL_SetUpPlayerPrediction( false, false );
if( !cl.validsequence )
if( cls.state != ca_active || !cl.validsequence )
return;
if(( cls.netchan.outgoing_sequence - cls.netchan.incoming_acknowledged ) >= CL_UPDATE_MASK )
@@ -1053,10 +1216,6 @@ void CL_PredictMovement( qboolean repredicting )
for( i = 1; i < CL_UPDATE_MASK && cls.netchan.incoming_acknowledged + i < cls.netchan.outgoing_sequence + stoppoint; i++ )
{
uint current_command;
uint current_command_mod;
qboolean runfuncs;
current_command = cls.netchan.incoming_acknowledged + i;
current_command_mod = current_command & CL_UPDATE_MASK;
@@ -1096,7 +1255,7 @@ void CL_PredictMovement( qboolean repredicting )
cl.local.onground = frame->playerstate[cl.playernum].onground;
else cl.local.onground = -1;
if( !repredicting || !cl_lw.value )
if( !repredicting || !CVAR_TO_BOOL( cl_lw ))
cl.local.viewmodel = to->client.viewmodel;
cl.local.repredicting = false;
cl.local.moving = false;
@@ -1128,12 +1287,12 @@ void CL_PredictMovement( qboolean repredicting )
cl.local.waterlevel = to->client.waterlevel;
cl.local.usehull = to->playerstate.usehull;
if( !repredicting || !cl_lw.value )
if( !repredicting || !CVAR_TO_BOOL( cl_lw ))
cl.local.viewmodel = to->client.viewmodel;
if( FBitSet( to->client.flags, FL_ONGROUND ))
{
cl_entity_t *ent = CL_GetEntityByIndex( cl.local.lastground );
ent = CL_GetEntityByIndex( cl.local.lastground );
cl.local.onground = cl.local.lastground;
cl.local.moving = false;
@@ -1155,27 +1314,27 @@ void CL_PredictMovement( qboolean repredicting )
else
{
cl.local.onground = -1;
cl.local.moving = false;
cl.local.moving = 0;
}
if( cls.correction_time > 0 && !cl_nosmooth.value && cl_smoothtime.value )
if( cls.correction_time > 0 && !cl_nosmooth->value && cl_smoothtime->value )
{
vec3_t delta;
float frac;
vec3_t delta;
float frac;
// only decay timer once per frame
if( !repredicting )
cls.correction_time -= host.frametime;
// Make sure smoothtime is postive
if( cl_smoothtime.value <= 0.0f )
Cvar_DirectSet( &cl_smoothtime, "0.1" );
if( cl_smoothtime->value <= 0.0f )
Cvar_DirectSet( cl_smoothtime, "0.1" );
// Clamp from 0 to cl_smoothtime.value
cls.correction_time = bound( 0.0, cls.correction_time, cl_smoothtime.value );
cls.correction_time = bound( 0.0, cls.correction_time, cl_smoothtime->value );
// Compute backward interpolation fraction along full correction
frac = 1.0f - cls.correction_time / cl_smoothtime.value;
frac = 1.0f - cls.correction_time / cl_smoothtime->value;
// Determine how much error we still have to make up for
VectorSubtract( cl.simorg, cl.local.lastorigin, delta );

View File

@@ -232,10 +232,14 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
// loading user settings
CSCR_LoadDefaultCVars( "user.scr" );
if( r_decals.value > mp_decals.value )
Cvar_DirectSet( &r_decals, mp_decals.string );
if( r_decals->value > mp_decals.value )
Cvar_SetValue( "r_decals", mp_decals.value );
}
else Cvar_DirectSet( &r_decals, NULL );
else Cvar_Reset( "r_decals" );
// re-init mouse
if( cl.background )
host.mouse_visible = false;
if( cl.background ) // tell the game parts about background state
Cvar_FullSet( "cl_background", "1", FCVAR_READ_ONLY );
@@ -258,7 +262,7 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
Q_strncpy( gameui.globals->maptitle, clgame.maptitle, sizeof( gameui.globals->maptitle ));
if( !cls.changelevel && !cls.changedemo )
CL_InitEdicts( cl.maxclients ); // re-arrange edicts
CL_InitEdicts (); // re-arrange edicts
// Quake just have a large packet of initialization data
for( i = 1; i < MAX_MODELS; i++ )
@@ -302,9 +306,9 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
else Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, refState.wideScreen ? "16x9" : "4x3" ));
Cvar_SetValue( "scr_loading", 0.0f ); // reset progress bar
if(( cl_allow_levelshots.value && !cls.changelevel ) || cl.background )
if(( cl_allow_levelshots->value && !cls.changelevel ) || cl.background )
{
if( !FS_FileExists( va( "%s.bmp", cl_levelshot_name.string ), true ))
if( !FS_FileExists( va( "%s.bmp", cl_levelshot_name->string ), true ))
Cvar_Set( "cl_levelshot_name", "*black" ); // render a black screen
cls.scrshot_request = scrshot_plaque; // request levelshot even if exist (check filetime)
}
@@ -414,7 +418,7 @@ If an entities model or origin changes from frame to frame, it must be
relinked. Other attributes can change without relinking.
==================
*/
static void CL_ParseQuakeEntityData( sizebuf_t *msg, int bits )
void CL_ParseQuakeEntityData( sizebuf_t *msg, int bits )
{
int i, newnum, pack;
qboolean forcelink;
@@ -565,7 +569,7 @@ CL_ParseQuakeParticles
==================
*/
static void CL_ParseQuakeParticle( sizebuf_t *msg )
void CL_ParseQuakeParticle( sizebuf_t *msg )
{
int count, color;
vec3_t org, dir;
@@ -587,7 +591,7 @@ CL_ParseQuakeStaticSound
===================
*/
static void CL_ParseQuakeStaticSound( sizebuf_t *msg )
void CL_ParseQuakeStaticSound( sizebuf_t *msg )
{
int sound_num;
float vol, attn;
@@ -694,13 +698,17 @@ static void CL_ParseQuakeBaseline( sizebuf_t *msg )
cl_entity_t *ent;
int newnum;
memset( &state, 0, sizeof( state ));
newnum = MSG_ReadWord( msg ); // entnum
if( newnum >= clgame.maxEntities )
Host_Error( "CL_AllocEdict: no free edicts\n" );
ent = CL_EDICT_NUM( newnum );
memset( &ent->prevstate, 0, sizeof( ent->prevstate ));
ent->index = newnum;
// parse baseline
memset( &state, 0, sizeof( state ));
state.modelindex = MSG_ReadByte( msg );
state.frame = MSG_ReadByte( msg );
state.colormap = MSG_ReadByte( msg );
@@ -711,10 +719,8 @@ static void CL_ParseQuakeBaseline( sizebuf_t *msg )
state.angles[1] = MSG_ReadAngle( msg );
state.origin[2] = MSG_ReadCoord( msg );
state.angles[2] = MSG_ReadAngle( msg );
ent = CL_EDICT_NUM( newnum );
ent->index = newnum;
ent->player = CL_IsPlayerIndex( newnum );
memcpy( &ent->baseline, &state, sizeof( entity_state_t ));
memcpy( &ent->prevstate, &state, sizeof( entity_state_t ));
}
@@ -816,12 +822,9 @@ CL_QuakeStuffText
==================
*/
static void CL_QuakeStuffText( const char *text )
void CL_QuakeStuffText( const char *text )
{
Q_strncat( cmd_buf, text, sizeof( cmd_buf ));
// a1ba: didn't filtered, anyway quake protocol
// only supported for demos, not network games
Cbuf_AddText( text );
}
@@ -831,7 +834,7 @@ CL_QuakeExecStuff
==================
*/
static void CL_QuakeExecStuff( void )
void CL_QuakeExecStuff( void )
{
char *text = cmd_buf;
char token[256];
@@ -858,7 +861,7 @@ static void CL_QuakeExecStuff( void )
if( !*text ) break;
text = COM_ParseFileSafe( text, token, sizeof( token ), PFILE_IGNOREBRACKET, NULL, NULL );
text = _COM_ParseFileSafe( text, token, sizeof( token ), PFILE_IGNOREBRACKET, NULL );
if( !text ) break;

View File

@@ -41,24 +41,11 @@ CL_CmpStudioTextures
return true if equal
====================
*/
static qboolean CL_CmpStudioTextures( int numtexs, mstudiotexture_t *p1, remap_info_t *remap )
qboolean CL_CmpStudioTextures( int numtexs, mstudiotexture_t *p1, mstudiotexture_t *p2 )
{
int i;
mstudiotexture_t *p2;
if( !p1 ) // no textures
return false;
if( !remap ) // current model has no remap
return false;
if( !remap->textures ) // shouldn't happen, just in case
return false;
if( numtexs != remap->numtextures ) // amount of textures differs, it's a different model
return false;
p2 = remap->ptexture;
if( !p1 || !p2 ) return false;
for( i = 0; i < numtexs; i++, p1++, p2++ )
{
@@ -78,7 +65,7 @@ CL_CreateRawTextureFromPixels
Convert texture_t struct into mstudiotexture_t prototype
====================
*/
static byte *CL_CreateRawTextureFromPixels( texture_t *tx, size_t *size, int topcolor, int bottomcolor )
byte *CL_CreateRawTextureFromPixels( texture_t *tx, size_t *size, int topcolor, int bottomcolor )
{
static mstudiotexture_t pin;
byte *pal;
@@ -111,7 +98,7 @@ CL_DuplicateTexture
Dupliacte texture with remap pixels
====================
*/
static void CL_DuplicateTexture( cl_entity_t *entity, model_t *model, mstudiotexture_t *ptexture, int topcolor, int bottomcolor )
void CL_DuplicateTexture( cl_entity_t *entity, model_t *model, mstudiotexture_t *ptexture, int topcolor, int bottomcolor )
{
const char *name;
texture_t *tx = NULL;
@@ -154,7 +141,7 @@ CL_UpdateStudioTexture
Update texture top and bottom colors
====================
*/
static void CL_UpdateStudioTexture( cl_entity_t *entity, mstudiotexture_t *ptexture, int topcolor, int bottomcolor )
void CL_UpdateStudioTexture( cl_entity_t *entity, mstudiotexture_t *ptexture, int topcolor, int bottomcolor )
{
rgbdata_t *pic;
texture_t *tx = NULL;
@@ -170,7 +157,7 @@ static void CL_UpdateStudioTexture( cl_entity_t *entity, mstudiotexture_t *ptext
// build name of original texture
Q_strncpy( mdlname, entity->model->name, sizeof( mdlname ));
COM_FileBase( ptexture->name, name, sizeof( name ));
COM_FileBase( ptexture->name, name );
COM_StripExtension( mdlname );
Q_snprintf( texname, sizeof( texname ), "#%s/%s.mdl", mdlname, name );
@@ -215,7 +202,7 @@ CL_UpdateAliasTexture
Update texture top and bottom colors
====================
*/
static void CL_UpdateAliasTexture( cl_entity_t *entity, unsigned short *texture, int skinnum, int topcolor, int bottomcolor )
void CL_UpdateAliasTexture( cl_entity_t *entity, unsigned short *texture, int skinnum, int topcolor, int bottomcolor )
{
char texname[MAX_QPATH];
rgbdata_t skin, *pic;
@@ -247,68 +234,6 @@ static void CL_UpdateAliasTexture( cl_entity_t *entity, unsigned short *texture,
ref.dllFuncs.GL_ProcessTexture( *texture, -1.0f, topcolor, bottomcolor );
}
/*
====================
CL_FreeRemapInfo
Release remap info per entity
====================
*/
static void CL_FreeRemapInfo( remap_info_t *info )
{
int i;
Assert( info != NULL );
// release all colormap texture copies
for( i = 0; i < info->numtextures; i++ )
{
if( info->ptexture != NULL )
{
if( FBitSet( info->ptexture[i].flags, STUDIO_NF_COLORMAP ))
ref.dllFuncs.GL_FreeTexture( info->ptexture[i].index );
}
if( info->textures[i] != 0 )
ref.dllFuncs.GL_FreeTexture( info->textures[i] );
}
Mem_Free( info ); // release struct
}
/*
====================
CL_UpdateRemapInfo
Update all remaps per entity
====================
*/
static void CL_UpdateRemapInfo( cl_entity_t *entity, int topcolor, int bottomcolor )
{
remap_info_t *info;
int i;
i = ( entity == &clgame.viewent ) ? clgame.maxEntities : entity->curstate.number;
info = clgame.remap_info[i];
if( !info ) return; // no remap info
if( info->topcolor == topcolor && info->bottomcolor == bottomcolor )
return; // values is valid
for( i = 0; i < info->numtextures; i++ )
{
if( info->ptexture != NULL )
{
if( FBitSet( info->ptexture[i].flags, STUDIO_NF_COLORMAP ))
CL_UpdateStudioTexture( entity, &info->ptexture[i], topcolor, bottomcolor );
}
else CL_UpdateAliasTexture( entity, &info->textures[i], i, topcolor, bottomcolor );
}
info->topcolor = topcolor;
info->bottomcolor = bottomcolor;
}
/*
====================
CL_AllocRemapInfo
@@ -317,7 +242,7 @@ Allocate new remap info per entity
and make copy of remap textures
====================
*/
static void CL_AllocRemapInfo( cl_entity_t *entity, model_t *model, int topcolor, int bottomcolor )
void CL_AllocRemapInfo( cl_entity_t *entity, model_t *model, int topcolor, int bottomcolor )
{
remap_info_t *info;
studiohdr_t *phdr;
@@ -357,9 +282,10 @@ static void CL_AllocRemapInfo( cl_entity_t *entity, model_t *model, int topcolor
if( !phdr ) return; // bad model?
src = (mstudiotexture_t *)(((byte *)phdr) + phdr->textureindex);
dst = (clgame.remap_info[i] ? clgame.remap_info[i]->ptexture : NULL);
// NOTE: we must copy all the structures 'mstudiotexture_t' for easy access when model is rendering
if( !CL_CmpStudioTextures( phdr->numtextures, src, clgame.remap_info[i] ) || clgame.remap_info[i]->model != model )
if( !CL_CmpStudioTextures( phdr->numtextures, src, dst ) || clgame.remap_info[i]->model != model )
{
// this code catches studiomodel change with another studiomodel with remap textures
// e.g. playermodel 'barney' with playermodel 'gordon'
@@ -424,6 +350,68 @@ static void CL_AllocRemapInfo( cl_entity_t *entity, model_t *model, int topcolor
info->model = model;
}
/*
====================
CL_UpdateRemapInfo
Update all remaps per entity
====================
*/
void CL_UpdateRemapInfo( cl_entity_t *entity, int topcolor, int bottomcolor )
{
remap_info_t *info;
int i;
i = ( entity == &clgame.viewent ) ? clgame.maxEntities : entity->curstate.number;
info = clgame.remap_info[i];
if( !info ) return; // no remap info
if( info->topcolor == topcolor && info->bottomcolor == bottomcolor )
return; // values is valid
for( i = 0; i < info->numtextures; i++ )
{
if( info->ptexture != NULL )
{
if( FBitSet( info->ptexture[i].flags, STUDIO_NF_COLORMAP ))
CL_UpdateStudioTexture( entity, &info->ptexture[i], topcolor, bottomcolor );
}
else CL_UpdateAliasTexture( entity, &info->textures[i], i, topcolor, bottomcolor );
}
info->topcolor = topcolor;
info->bottomcolor = bottomcolor;
}
/*
====================
CL_FreeRemapInfo
Release remap info per entity
====================
*/
void CL_FreeRemapInfo( remap_info_t *info )
{
int i;
Assert( info != NULL );
// release all colormap texture copies
for( i = 0; i < info->numtextures; i++ )
{
if( info->ptexture != NULL )
{
if( FBitSet( info->ptexture[i].flags, STUDIO_NF_COLORMAP ))
ref.dllFuncs.GL_FreeTexture( info->ptexture[i].index );
}
if( info->textures[i] != 0 )
ref.dllFuncs.GL_FreeTexture( info->textures[i] );
}
Mem_Free( info ); // release struct
}
/*
====================
CL_ClearAllRemaps
@@ -446,21 +434,3 @@ void CL_ClearAllRemaps( void )
}
clgame.remap_info = NULL;
}
/*
=============
CL_EntitySetRemapColors
=============
*/
qboolean CL_EntitySetRemapColors( cl_entity_t *e, model_t *mod, int top, int bottom )
{
CL_AllocRemapInfo( e, mod, top, bottom );
if( CL_GetRemapInfoForEntity( e ))
{
CL_UpdateRemapInfo( e, top, bottom );
return true;
}
return false;
}

View File

@@ -117,7 +117,7 @@ static void R_EnvShot( const float *vieworg, const char *name, qboolean skyshot,
else cls.scrshot_action = scrshot_envshot;
// catch negative values
cls.envshot_viewsize = Q_max( 0, shotsize );
cls.envshot_viewsize = max( 0, shotsize );
}
/*
@@ -126,14 +126,14 @@ CL_GenericHandle
=============
*/
static const char *CL_GenericHandle( int fileindex )
const char *CL_GenericHandle( int fileindex )
{
if( fileindex < 0 || fileindex >= MAX_CUSTOM )
return 0;
return cl.files_precache[fileindex];
}
intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRef )
int CL_RenderGetParm( const int parm, const int arg, const qboolean checkRef )
{
switch( parm )
{
@@ -142,6 +142,8 @@ intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRe
return 1;
#endif
return 0;
case PARM_SKY_SPHERE:
return FBitSet( world.flags, FWORLD_SKYSPHERE ) && !FBitSet( world.flags, FWORLD_CUSTOM_SKYBOX );
case PARAM_GAMEPAUSED:
return cl.paused;
case PARM_CLIENT_INGAME:
@@ -159,17 +161,9 @@ intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRe
case PARM_WATER_ALPHA:
return FBitSet( world.flags, FWORLD_WATERALPHA );
case PARM_DELUXEDATA:
return (intptr_t)world.deluxedata;
return *(int *)&world.deluxedata;
case PARM_SHADOWDATA:
return (intptr_t)world.shadowdata;
case PARM_FULLSCREEN:
return refState.fullScreen;
case PARM_WIDESCREEN:
return refState.wideScreen;
case PARM_SCREEN_WIDTH:
return refState.width;
case PARM_SCREEN_HEIGHT:
return refState.height;
return *(int *)&world.shadowdata;
default:
// indicates call from client.dll
if( checkRef )
@@ -185,36 +179,32 @@ intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRe
return CL_IsThirdPerson();
case PARM_QUAKE_COMPATIBLE:
return Host_IsQuakeCompatible();
case PARM_PLAYER_INDEX:
return cl.playernum + 1;
case PARM_VIEWENT_INDEX:
return cl.viewentity;
case PARM_CONNSTATE:
return (int)cls.state;
case PARM_PLAYING_DEMO:
return cls.demoplayback;
case PARM_WATER_LEVEL:
return cl.local.waterlevel;
case PARM_MAX_CLIENTS:
return cl.maxclients;
case PARM_LOCAL_HEALTH:
return cl.local.health;
case PARM_LOCAL_GAME:
return Host_IsLocalGame();
case PARM_NUMENTITIES:
return pfnNumberOfEntities();
case PARM_GET_CLIENT_PTR:
return (intptr_t)&cl.time; // with the offset
case PARM_GET_HOST_PTR:
return (intptr_t)&host.realtime; // with the offset
case PARM_GET_WORLD_PTR:
return (intptr_t)&world;
case PARM_GET_MOVEVARS_PTR:
return (intptr_t)&clgame.movevars;
case PARM_GET_PALETTE_PTR:
return (intptr_t)&clgame.palette;
case PARM_GET_VIEWENT_PTR:
return (intptr_t)&clgame.viewent;
case PARM_NUMMODELS:
return cl.nummodels;
}
}
return 0;
}
static intptr_t pfnRenderGetParm( int parm, int arg )
static int pfnRenderGetParm( int parm, int arg )
{
return CL_RenderGetParm( parm, arg, true );
}

View File

@@ -20,18 +20,18 @@ GNU General Public License for more details.
#include "input.h"
#include "library.h"
CVAR_DEFINE_AUTO( scr_centertime, "2.5", 0, "centerprint hold time" );
CVAR_DEFINE_AUTO( scr_loading, "0", 0, "loading bar progress" );
CVAR_DEFINE_AUTO( scr_download, "-1", 0, "downloading bar progress" );
CVAR_DEFINE( scr_viewsize, "viewsize", "120", FCVAR_ARCHIVE, "screen size (quake only)" );
CVAR_DEFINE_AUTO( cl_testlights, "0", 0, "test dynamic lights" );
CVAR_DEFINE( cl_allow_levelshots, "allow_levelshots", "0", FCVAR_ARCHIVE, "allow engine to use indivdual levelshots instead of 'loading' image" );
CVAR_DEFINE_AUTO( cl_levelshot_name, "*black", 0, "contains path to current levelshot" );
static CVAR_DEFINE_AUTO( cl_envshot_size, "256", FCVAR_ARCHIVE, "envshot size of cube side" );
CVAR_DEFINE_AUTO( v_dark, "0", 0, "starts level from dark screen" );
static CVAR_DEFINE_AUTO( net_speeds, "0", FCVAR_ARCHIVE, "show network packets" );
static CVAR_DEFINE_AUTO( cl_showfps, "0", FCVAR_ARCHIVE, "show client fps" );
static CVAR_DEFINE_AUTO( cl_showpos, "0", FCVAR_ARCHIVE, "show local player position and velocity" );
convar_t *scr_centertime;
convar_t *scr_loading;
convar_t *scr_download;
convar_t *scr_viewsize;
convar_t *cl_testlights;
convar_t *cl_allow_levelshots;
convar_t *cl_levelshot_name;
static convar_t *cl_envshot_size;
convar_t *v_dark;
static convar_t *net_speeds;
static convar_t *cl_showfps;
static convar_t *cl_showpos;
typedef struct
{
@@ -59,7 +59,7 @@ void SCR_DrawFPS( int height )
char fpsstring[64];
int offset;
if( cls.state != ca_active || !cl_showfps.value || cl.background )
if( cls.state != ca_active || !cl_showfps->value || cl.background )
return;
switch( cls.scrshot_action )
@@ -95,7 +95,7 @@ void SCR_DrawFPS( int height )
if( curfps < minfps ) minfps = curfps;
if( curfps > maxfps ) maxfps = curfps;
if( cl_showfps.value == 2 )
if( cl_showfps->value == 2 )
Q_snprintf( fpsstring, sizeof( fpsstring ), "fps: ^1%4i min, ^3%4i cur, ^2%4i max", minfps, curfps, maxfps );
else Q_snprintf( fpsstring, sizeof( fpsstring ), "%4i fps", curfps );
MakeRGBA( color, 255, 255, 255, 255 );
@@ -119,7 +119,7 @@ void SCR_DrawPos( void )
cl_entity_t *ent;
rgba_t color;
if( cls.state != ca_active || !cl_showpos.value || cl.background )
if( cls.state != ca_active || !cl_showpos->value || cl.background )
return;
ent = CL_GetLocalPlayer();
@@ -150,7 +150,8 @@ same as r_speeds but for network channel
void SCR_NetSpeeds( void )
{
static char msg[MAX_SYSPATH];
int x, y;
int x, y, height;
char *p, *start, *end;
float time = cl.mtime[0];
static int min_svfps = 100;
static int max_svfps = 0;
@@ -159,12 +160,11 @@ void SCR_NetSpeeds( void )
static int max_clfps = 0;
int cur_clfps = 0;
rgba_t color;
cl_font_t *font = Con_GetCurFont();
if( !host.allow_console )
return;
if( !net_speeds.value || cls.state != ca_active )
if( !net_speeds->value || cls.state != ca_active )
return;
// prevent to get too big values at max
@@ -196,11 +196,25 @@ void SCR_NetSpeeds( void )
Q_memprint( cls.netchan.total_sended )
);
x = refState.width - 320 * font->scale;
x = refState.width - 320;
y = 384;
Con_DrawStringLen( NULL, NULL, &height );
MakeRGBA( color, 255, 255, 255, 255 );
CL_DrawString( x, y, msg, color, font, FONT_DRAW_RESETCOLORONLF );
p = start = msg;
do
{
end = Q_strchr( p, '\n' );
if( end ) msg[end-start] = '\0';
Con_DrawString( x, y, p, color );
y += height;
if( end ) p = end + 1;
else break;
} while( 1 );
}
/*
@@ -217,15 +231,31 @@ void SCR_RSpeeds( void )
if( ref.dllFuncs.R_SpeedsMessage( msg, sizeof( msg )))
{
int x, y;
int x, y, height;
char *p, *start, *end;
rgba_t color;
cl_font_t *font = Con_GetCurFont();
x = refState.width - 340 * font->scale;
x = refState.width - 340;
y = 64;
Con_DrawStringLen( NULL, NULL, &height );
MakeRGBA( color, 255, 255, 255, 255 );
CL_DrawString( x, y, msg, color, font, FONT_DRAW_RESETCOLORONLF );
p = start = msg;
do
{
end = Q_strchr( p, '\n' );
if( end ) msg[end-start] = '\0';
Con_DrawString( x, y, p, color );
y += height;
// handle '\n\n'
if( *p == '\n' )
y += height;
if( end ) p = end + 1;
else break;
} while( 1 );
}
}
@@ -252,7 +282,7 @@ VID_WriteOverviewScript
Create overview script file
===============
*/
static void VID_WriteOverviewScript( void )
void VID_WriteOverviewScript( void )
{
ref_overview_t *ov = &clgame.overView;
string filename;
@@ -290,9 +320,7 @@ void SCR_MakeScreenShot( void )
if( cls.envshot_viewsize > 0 )
viewsize = cls.envshot_viewsize;
else viewsize = cl_envshot_size.value;
V_CheckGamma();
else viewsize = cl_envshot_size->value;
switch( cls.scrshot_action )
{
@@ -344,11 +372,11 @@ void SCR_MakeScreenShot( void )
SCR_DrawPlaque
================
*/
static void SCR_DrawPlaque( void )
void SCR_DrawPlaque( void )
{
if(( cl_allow_levelshots.value && !cls.changelevel ) || cl.background )
if(( cl_allow_levelshots->value && !cls.changelevel ) || cl.background )
{
int levelshot = ref.dllFuncs.GL_LoadTexture( cl_levelshot_name.string, NULL, 0, TF_IMAGE );
int levelshot = ref.dllFuncs.GL_LoadTexture( cl_levelshot_name->string, NULL, 0, TF_IMAGE );
ref.dllFuncs.GL_SetRenderMode( kRenderNormal );
ref.dllFuncs.R_DrawStretchPic( 0, 0, refState.width, refState.height, 0, 0, 1, 1, levelshot );
if( !cl.background ) CL_DrawHUD( CL_LOADING );
@@ -368,7 +396,7 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
cl.video_prepped = false;
if( !Host_IsDedicated() )
oldclear = gl_clear.value;
oldclear = gl_clear->value;
if( CL_IsInMenu( ) && !cls.changedemo && !is_background )
{
@@ -384,16 +412,17 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
return;
if( !Host_IsDedicated() )
gl_clear.value = 0.0f;
gl_clear->value = 0.0f;
if( is_background ) IN_MouseSavePos( );
cls.draw_changelevel = !is_background;
SCR_UpdateScreen();
cls.disable_screen = host.realtime;
cls.disable_servercount = cl.servercount;
cl.background = is_background; // set right state before svc_serverdata is came
if( !Host_IsDedicated() )
gl_clear.value = oldclear;
gl_clear->value = oldclear;
// SNDDMA_LockSound();
}
@@ -415,7 +444,7 @@ void SCR_EndLoadingPlaque( void )
SCR_AddDirtyPoint
=================
*/
static void SCR_AddDirtyPoint( int x, int y )
void SCR_AddDirtyPoint( int x, int y )
{
if( x < scr_dirty.x1 ) scr_dirty.x1 = x;
if( x > scr_dirty.x2 ) scr_dirty.x2 = x;
@@ -444,7 +473,7 @@ void SCR_TileClear( void )
int i, top, bottom, left, right;
dirty_t clear;
if( scr_viewsize.value >= 120 )
if( scr_viewsize->value >= 120 )
return; // full screen rendering
// erase rect will be the union of the past three frames
@@ -549,6 +578,77 @@ void SCR_UpdateScreen( void )
V_PostRender();
}
qboolean SCR_LoadFixedWidthFont( const char *fontname )
{
int i, fontWidth;
if( cls.creditsFont.valid )
return true; // already loaded
if( !FS_FileExists( fontname, false ))
return false;
cls.creditsFont.hFontTexture = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, TF_IMAGE|TF_KEEP_SOURCE );
R_GetTextureParms( &fontWidth, NULL, cls.creditsFont.hFontTexture );
cls.creditsFont.charHeight = clgame.scrInfo.iCharHeight = fontWidth / 16;
cls.creditsFont.type = FONT_FIXED;
cls.creditsFont.valid = true;
// build fixed rectangles
for( i = 0; i < 256; i++ )
{
cls.creditsFont.fontRc[i].left = (i * (fontWidth / 16)) % fontWidth;
cls.creditsFont.fontRc[i].right = cls.creditsFont.fontRc[i].left + fontWidth / 16;
cls.creditsFont.fontRc[i].top = (i / 16) * (fontWidth / 16);
cls.creditsFont.fontRc[i].bottom = cls.creditsFont.fontRc[i].top + fontWidth / 16;
cls.creditsFont.charWidths[i] = clgame.scrInfo.charWidths[i] = fontWidth / 16;
}
return true;
}
qboolean SCR_LoadVariableWidthFont( const char *fontname )
{
int i, fontWidth;
byte *buffer;
fs_offset_t length;
qfont_t *src;
if( cls.creditsFont.valid )
return true; // already loaded
if( !FS_FileExists( fontname, false ))
return false;
cls.creditsFont.hFontTexture = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, TF_IMAGE );
R_GetTextureParms( &fontWidth, NULL, cls.creditsFont.hFontTexture );
// half-life font with variable chars witdh
buffer = FS_LoadFile( fontname, &length, false );
// setup creditsfont
if( buffer && length >= sizeof( qfont_t ))
{
src = (qfont_t *)buffer;
cls.creditsFont.charHeight = clgame.scrInfo.iCharHeight = src->rowheight;
cls.creditsFont.type = FONT_VARIABLE;
// build rectangles
for( i = 0; i < 256; i++ )
{
cls.creditsFont.fontRc[i].left = (word)src->fontinfo[i].startoffset % fontWidth;
cls.creditsFont.fontRc[i].right = cls.creditsFont.fontRc[i].left + src->fontinfo[i].charwidth;
cls.creditsFont.fontRc[i].top = (word)src->fontinfo[i].startoffset / fontWidth;
cls.creditsFont.fontRc[i].bottom = cls.creditsFont.fontRc[i].top + src->rowheight;
cls.creditsFont.charWidths[i] = clgame.scrInfo.charWidths[i] = src->fontinfo[i].charwidth;
}
cls.creditsFont.valid = true;
}
if( buffer ) Mem_Free( buffer );
return true;
}
/*
================
SCR_LoadCreditsFont
@@ -558,41 +658,22 @@ INTERNAL RESOURCE
*/
void SCR_LoadCreditsFont( void )
{
cl_font_t *const font = &cls.creditsFont;
qboolean success = false;
float scale = hud_fontscale.value;
dword crc = 0;
const char *path = "gfx/creditsfont.fnt";
dword crc;
// replace default gfx.wad textures by current charset's font
if( !CRC32_File( &crc, "gfx.wad" ) || crc == 0x49eb9f16 )
{
string charsetFnt;
if( Q_snprintf( charsetFnt, sizeof( charsetFnt ),
"creditsfont_%s.fnt", Cvar_VariableString( "con_charset" )) > 0 )
{
if( FS_FileExists( charsetFnt, false ))
success = Con_LoadVariableWidthFont( charsetFnt, font, scale, kRenderTransAdd, TF_FONT );
}
const char *path2 = va("creditsfont_%s.fnt", Cvar_VariableString( "con_charset" ) );
if( FS_FileExists( path2, false ) )
path = path2;
}
if( !success )
success = Con_LoadVariableWidthFont( "gfx/creditsfont.fnt", font, scale, kRenderTransAdd, TF_FONT );
if( !success )
success = Con_LoadFixedWidthFont( "gfx/conchars", font, scale, kRenderTransAdd, TF_FONT );
// copy font size for client.dll
if( success )
if( !SCR_LoadVariableWidthFont( path ))
{
int i;
clgame.scrInfo.iCharHeight = cls.creditsFont.charHeight;
for( i = 0; i < ARRAYSIZE( cls.creditsFont.charWidths ); i++ )
clgame.scrInfo.charWidths[i] = cls.creditsFont.charWidths[i];
if( !SCR_LoadFixedWidthFont( "gfx/conchars" ))
Con_DPrintf( S_ERROR "failed to load HUD font\n" );
}
else Con_DPrintf( S_ERROR "failed to load HUD font\n" );
}
/*
@@ -602,7 +683,7 @@ SCR_InstallParticlePalette
INTERNAL RESOURCE
================
*/
static void SCR_InstallParticlePalette( void )
void SCR_InstallParticlePalette( void )
{
rgbdata_t *pic;
int i;
@@ -648,21 +729,21 @@ void SCR_RegisterTextures( void )
// register gfx.wad images
if( FS_FileExists( "gfx/paused.lmp", false ))
cls.pauseIcon = ref.dllFuncs.GL_LoadTexture( "gfx/paused.lmp", NULL, 0, TF_IMAGE|TF_ALLOW_NEAREST );
cls.pauseIcon = ref.dllFuncs.GL_LoadTexture( "gfx/paused.lmp", NULL, 0, TF_IMAGE );
else if( FS_FileExists( "gfx/pause.lmp", false ))
cls.pauseIcon = ref.dllFuncs.GL_LoadTexture( "gfx/pause.lmp", NULL, 0, TF_IMAGE|TF_ALLOW_NEAREST );
cls.pauseIcon = ref.dllFuncs.GL_LoadTexture( "gfx/pause.lmp", NULL, 0, TF_IMAGE );
if( FS_FileExists( "gfx/lambda.lmp", false ))
{
if( cl_allow_levelshots.value )
cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE|TF_ALLOW_NEAREST );
else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE|TF_ALLOW_NEAREST );
if( cl_allow_levelshots->value )
cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE );
else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/lambda.lmp", NULL, 0, TF_IMAGE );
}
else if( FS_FileExists( "gfx/loading.lmp", false ))
{
if( cl_allow_levelshots.value )
cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE|TF_ALLOW_NEAREST );
else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE|TF_ALLOW_NEAREST );
if( cl_allow_levelshots->value )
cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE|TF_LUMINANCE );
else cls.loadingBar = ref.dllFuncs.GL_LoadTexture( "gfx/loading.lmp", NULL, 0, TF_IMAGE );
}
cls.tileImage = ref.dllFuncs.GL_LoadTexture( "gfx/backtile.lmp", NULL, 0, TF_NOMIPMAP );
@@ -675,9 +756,9 @@ SCR_SizeUp_f
Keybinding command
=================
*/
static void SCR_SizeUp_f( void )
void SCR_SizeUp_f( void )
{
Cvar_SetValue( "viewsize", Q_min( scr_viewsize.value + 10, 120 ));
Cvar_SetValue( "viewsize", Q_min( scr_viewsize->value + 10, 120 ));
}
@@ -688,9 +769,9 @@ SCR_SizeDown_f
Keybinding command
=================
*/
static void SCR_SizeDown_f( void )
void SCR_SizeDown_f( void )
{
Cvar_SetValue( "viewsize", Q_max( scr_viewsize.value - 10, 30 ));
Cvar_SetValue( "viewsize", Q_max( scr_viewsize->value - 10, 30 ));
}
/*
@@ -714,11 +795,7 @@ void SCR_VidInit( void )
gameui.globals->scrHeight = refState.height;
}
// notify vgui about screen size change
if( clgame.hInstance )
{
VGui_Startup( refState.width, refState.height );
}
VGui_Startup( NULL, refState.width, refState.height ); // initialized already, so pass NULL
CL_ClearSpriteTextures(); // now all hud sprites are invalid
@@ -728,7 +805,6 @@ void SCR_VidInit( void )
// restart console size
Con_VidInit ();
Touch_NotifyResize();
}
/*
@@ -740,18 +816,18 @@ void SCR_Init( void )
{
if( scr_init ) return;
Cvar_RegisterVariable( &scr_centertime );
Cvar_RegisterVariable( &cl_levelshot_name );
Cvar_RegisterVariable( &cl_allow_levelshots );
Cvar_RegisterVariable( &scr_loading );
Cvar_RegisterVariable( &scr_download );
Cvar_RegisterVariable( &cl_testlights );
Cvar_RegisterVariable( &cl_envshot_size );
Cvar_RegisterVariable( &v_dark );
Cvar_RegisterVariable( &scr_viewsize );
Cvar_RegisterVariable( &net_speeds );
Cvar_RegisterVariable( &cl_showfps );
Cvar_RegisterVariable( &cl_showpos );
scr_centertime = Cvar_Get( "scr_centertime", "2.5", 0, "centerprint hold time" );
cl_levelshot_name = Cvar_Get( "cl_levelshot_name", "*black", 0, "contains path to current levelshot" );
cl_allow_levelshots = Cvar_Get( "allow_levelshots", "0", FCVAR_ARCHIVE, "allow engine to use indivdual levelshots instead of 'loading' image" );
scr_loading = Cvar_Get( "scr_loading", "0", 0, "loading bar progress" );
scr_download = Cvar_Get( "scr_download", "-1", 0, "downloading bar progress" );
cl_testlights = Cvar_Get( "cl_testlights", "0", 0, "test dynamic lights" );
cl_envshot_size = Cvar_Get( "cl_envshot_size", "256", FCVAR_ARCHIVE, "envshot size of cube side" );
v_dark = Cvar_Get( "v_dark", "0", 0, "starts level from dark screen" );
scr_viewsize = Cvar_Get( "viewsize", "120", FCVAR_ARCHIVE, "screen size" );
net_speeds = Cvar_Get( "net_speeds", "0", FCVAR_ARCHIVE, "show network packets" );
cl_showfps = Cvar_Get( "cl_showfps", "1", FCVAR_ARCHIVE, "show client fps" );
cl_showpos = Cvar_Get( "cl_showpos", "0", FCVAR_ARCHIVE, "show local player position and velocity" );
// register our commands
Cmd_AddCommand( "skyname", CL_SetSky_f, "set new skybox by basename" );

View File

@@ -1,463 +0,0 @@
/*
cl_securedstub.c - secured client dll stub
Copyright (C) 2022 FWGS
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"
typedef struct cldll_func_src_s
{
int (*pfnInitialize)( cl_enginefunc_t *pEnginefuncs, int iVersion );
void (*pfnInit)( void );
int (*pfnVidInit)( void );
int (*pfnRedraw)( float flTime, int intermission );
int (*pfnUpdateClientData)( client_data_t *cdata, float flTime );
void (*pfnReset)( void );
void (*pfnPlayerMove)( struct playermove_s *ppmove, int server );
void (*pfnPlayerMoveInit)( struct playermove_s *ppmove );
char (*pfnPlayerMoveTexture)( char *name );
void (*IN_ActivateMouse)( void );
void (*IN_DeactivateMouse)( void );
void (*IN_MouseEvent)( int mstate );
void (*IN_ClearStates)( void );
void (*IN_Accumulate)( void );
void (*CL_CreateMove)( float frametime, struct usercmd_s *cmd, int active );
int (*CL_IsThirdPerson)( void );
void (*CL_CameraOffset)( float *ofs ); // unused
void *(*KB_Find)( const char *name );
void (*CAM_Think)( void ); // camera stuff
void (*pfnCalcRefdef)( ref_params_t *pparams );
int (*pfnAddEntity)( int type, cl_entity_t *ent, const char *modelname );
void (*pfnCreateEntities)( void );
void (*pfnDrawNormalTriangles)( void );
void (*pfnDrawTransparentTriangles)( void );
void (*pfnStudioEvent)( const struct mstudioevent_s *event, const cl_entity_t *entity );
void (*pfnPostRunCmd)( struct local_state_s *from, struct local_state_s *to, usercmd_t *cmd, int runfuncs, double time, unsigned int random_seed );
void (*pfnShutdown)( void );
void (*pfnTxferLocalOverrides)( entity_state_t *state, const clientdata_t *client );
void (*pfnProcessPlayerState)( entity_state_t *dst, const entity_state_t *src );
void (*pfnTxferPredictionData)( entity_state_t *ps, const entity_state_t *pps, clientdata_t *pcd, const clientdata_t *ppcd, weapon_data_t *wd, const weapon_data_t *pwd );
void (*pfnDemo_ReadBuffer)( int size, byte *buffer );
int (*pfnConnectionlessPacket)( const struct netadr_s *net_from, const char *args, char *buffer, int *size );
int (*pfnGetHullBounds)( int hullnumber, float *mins, float *maxs );
void (*pfnFrame)( double time );
int (*pfnKey_Event)( int eventcode, int keynum, const char *pszCurrentBinding );
void (*pfnTempEntUpdate)( double frametime, double client_time, double cl_gravity, struct tempent_s **ppTempEntFree, struct tempent_s **ppTempEntActive, int ( *Callback_AddVisibleEntity )( cl_entity_t *pEntity ), void ( *Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ));
cl_entity_t *(*pfnGetUserEntity)( int index );
void (*pfnVoiceStatus)( int entindex, qboolean bTalking );
void (*pfnDirectorMessage)( int iSize, void *pbuf );
int (*pfnGetStudioModelInterface)( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio );
void (*pfnChatInputPosition)( int *x, int *y );
int (*pfnGetPlayerTeam)( int iPlayer );
void *(*pfnClientFactory)( void );
} cldll_func_src_t;
typedef struct cldll_func_dst_s
{
void (*pfnInitialize)( cl_enginefunc_t **pEnginefuncs, int *iVersion );
void (*pfnInit)( void );
void (*pfnVidInit)( void );
void (*pfnRedraw)( float *flTime, int *intermission );
void (*pfnUpdateClientData)( client_data_t **cdata, float *flTime );
void (*pfnReset)( void );
void (*pfnPlayerMove)( struct playermove_s **ppmove, int *server );
void (*pfnPlayerMoveInit)( struct playermove_s **ppmove );
void (*pfnPlayerMoveTexture)( char **name );
void (*IN_ActivateMouse)( void );
void (*IN_DeactivateMouse)( void );
void (*IN_MouseEvent)( int *mstate );
void (*IN_ClearStates)( void );
void (*IN_Accumulate)( void );
void (*CL_CreateMove)( float *frametime, struct usercmd_s **cmd, int *active );
void (*CL_IsThirdPerson)( void );
void (*CL_CameraOffset)( float **ofs );
void (*KB_Find)( const char **name );
void (*CAM_Think)( void );
void (*pfnCalcRefdef)( ref_params_t **pparams );
void (*pfnAddEntity)( int *type, cl_entity_t **ent, const char **modelname );
void (*pfnCreateEntities)( void );
void (*pfnDrawNormalTriangles)( void );
void (*pfnDrawTransparentTriangles)( void );
void (*pfnStudioEvent)( const struct mstudioevent_s **event, const cl_entity_t **entity );
void (*pfnPostRunCmd)( struct local_state_s **from, struct local_state_s **to, usercmd_t **cmd, int *runfuncs, double *time, unsigned int *random_seed );
void (*pfnShutdown)( void );
void (*pfnTxferLocalOverrides)( entity_state_t **state, const clientdata_t **client );
void (*pfnProcessPlayerState)( entity_state_t **dst, const entity_state_t **src );
void (*pfnTxferPredictionData)( entity_state_t **ps, const entity_state_t **pps, clientdata_t **pcd, const clientdata_t **ppcd, weapon_data_t **wd, const weapon_data_t **pwd );
void (*pfnDemo_ReadBuffer)( int *size, byte **buffer );
void (*pfnConnectionlessPacket)( const struct netadr_s **net_from, const char **args, char **buffer, int **size );
void (*pfnGetHullBounds)( int *hullnumber, float **mins, float **maxs );
void (*pfnFrame)( double *time );
void (*pfnKey_Event)( int *eventcode, int *keynum, const char **pszCurrentBinding );
void (*pfnTempEntUpdate)( double *frametime, double *client_time, double *cl_gravity, struct tempent_s ***ppTempEntFree, struct tempent_s ***ppTempEntActive, int ( **Callback_AddVisibleEntity )( cl_entity_t *pEntity ), void ( **Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ));
void (*pfnGetUserEntity)( int *index );
void (*pfnVoiceStatus)( int *entindex, qboolean *bTalking );
void (*pfnDirectorMessage)( int *iSize, void **pbuf );
void (*pfnGetStudioModelInterface)( int *version, struct r_studio_interface_s ***ppinterface, struct engine_studio_api_s **pstudio );
void (*pfnChatInputPosition)( int **x, int **y );
void (*pfnGetPlayerTeam)( int *iPlayer );
} cldll_func_dst_t;
struct cl_enginefunc_dst_s;
struct modshelpers_s;
struct modchelpers_s;
struct engdata_s;
typedef struct modfuncs_s
{
void (*m_pfnLoadMod)( char *pchModule );
void (*m_pfnCloseMod)( void );
int (*m_pfnNCall)( int ijump, int cnArg, ... );
void (*m_pfnGetClDstAddrs)( cldll_func_dst_t *pcldstAddrs );
void (*m_pfnGetEngDstAddrs)( struct cl_enginefunc_dst_s *pengdstAddrs );
void (*m_pfnModuleLoaded)( void );
void (*m_pfnProcessOutgoingNet)( struct netchan_s *pchan, struct sizebuf_s *psizebuf );
qboolean (*m_pfnProcessIncomingNet)( struct netchan_s *pchan, struct sizebuf_s *psizebuf );
void (*m_pfnTextureLoad)( char *pszName, int dxWidth, int dyHeight, char *pbData );
void (*m_pfnModelLoad)( struct model_s *pmodel, void *pvBuf );
void (*m_pfnFrameBegin)( void );
void (*m_pfnFrameRender1)( void );
void (*m_pfnFrameRender2)( void );
void (*m_pfnSetModSHelpers)( struct modshelpers_s *pmodshelpers );
void (*m_pfnSetModCHelpers)( struct modchelpers_s *pmodchelpers );
void (*m_pfnSetEngData)( struct engdata_s *pengdata );
int m_nVersion;
void (*m_pfnConnectClient)( int iPlayer );
void (*m_pfnRecordIP)( unsigned int pnIP );
void (*m_pfnPlayerStatus)( unsigned char *pbData, int cbData );
void (*m_pfnSetEngineVersion)( int nVersion );
int m_nVoid2;
int m_nVoid3;
int m_nVoid4;
int m_nVoid5;
int m_nVoid6;
int m_nVoid7;
int m_nVoid8;
int m_nVoid9;
} modfuncs_t;
static void DstInitialize( cl_enginefunc_t **pEnginefuncs, int *iVersion )
{
// stub
}
static void DstInit( void )
{
// stub
}
static void DstVidInit( void )
{
// stub
}
static void DstRedraw( float *flTime, int *intermission )
{
// stub
}
static void DstUpdateClientData( client_data_t **cdata, float *flTime )
{
// stub
}
static void DstReset( void )
{
// stub
}
static void DstPlayerMove( struct playermove_s **ppmove, int *server )
{
// stub
}
static void DstPlayerMoveInit( struct playermove_s **ppmove )
{
// stub
}
static void DstPlayerMoveTexture( char **name )
{
// stub
}
static void DstIN_ActivateMouse( void )
{
// stub
}
static void DstIN_DeactivateMouse( void )
{
// stub
}
static void DstIN_MouseEvent( int *mstate )
{
// stub
}
static void DstIN_ClearStates( void )
{
// stub
}
static void DstIN_Accumulate( void )
{
// stub
}
static void DstCL_CreateMove( float *frametime, struct usercmd_s **cmd, int *active )
{
// stub
}
static void DstCL_IsThirdPerson( void )
{
// stub
}
static void DstCL_CameraOffset( float **ofs )
{
// stub
}
static void DstKB_Find( const char **name )
{
// stub
}
static void DstCAM_Think( void )
{
// stub
}
static void DstCalcRefdef( ref_params_t **pparams )
{
// stub
}
static void DstAddEntity( int *type, cl_entity_t **ent, const char **modelname )
{
// stub
}
static void DstCreateEntities( void )
{
// stub
}
static void DstDrawNormalTriangles( void )
{
// stub
}
static void DstDrawTransparentTriangles( void )
{
// stub
}
static void DstStudioEvent( const struct mstudioevent_s **event, const cl_entity_t **entity )
{
// stub
}
static void DstPostRunCmd( struct local_state_s **from, struct local_state_s **to, usercmd_t **cmd, int *runfuncs, double *time, unsigned int *random_seed )
{
// stub
}
static void DstShutdown( void )
{
// stub
}
static void DstTxferLocalOverrides( entity_state_t **state, const clientdata_t **client )
{
// stub
}
static void DstProcessPlayerState( entity_state_t **dst, const entity_state_t **src )
{
// stub
}
static void DstTxferPredictionData( entity_state_t **ps, const entity_state_t **pps, clientdata_t **pcd, const clientdata_t **ppcd, weapon_data_t **wd, const weapon_data_t **pwd )
{
// stub
}
static void DstDemo_ReadBuffer( int *size, byte **buffer )
{
// stub
}
static void DstConnectionlessPacket( const struct netadr_s **net_from, const char **args, char **buffer, int **size )
{
// stub
}
static void DstGetHullBounds( int *hullnumber, float **mins, float **maxs )
{
// stub
}
static void DstFrame( double *time )
{
// stub
}
static void DstKey_Event( int *eventcode, int *keynum, const char **pszCurrentBinding )
{
// stub
}
static void DstTempEntUpdate( double *frametime, double *client_time, double *cl_gravity, struct tempent_s ***ppTempEntFree, struct tempent_s ***ppTempEntActive, int ( **Callback_AddVisibleEntity )( cl_entity_t *pEntity ), void ( **Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ) )
{
// stub
}
static void DstGetUserEntity( int *index )
{
// stub
}
static void DstVoiceStatus( int *entindex, qboolean *bTalking )
{
// stub
}
static void DstDirectorMessage( int *iSize, void **pbuf )
{
// stub
}
static void DstGetStudioModelInterface( int *version, struct r_studio_interface_s ***ppinterface, struct engine_studio_api_s **pstudio )
{
// stub
}
static void DstChatInputPosition( int **x, int **y )
{
// stub
}
static void DstGetPlayerTeam( int *iPlayer )
{
// stub
}
static cldll_func_dst_t cldllFuncDst =
{
DstInitialize,
DstInit,
DstVidInit,
DstRedraw,
DstUpdateClientData,
DstReset,
DstPlayerMove,
DstPlayerMoveInit,
DstPlayerMoveTexture,
DstIN_ActivateMouse,
DstIN_DeactivateMouse,
DstIN_MouseEvent,
DstIN_ClearStates,
DstIN_Accumulate,
DstCL_CreateMove,
DstCL_IsThirdPerson,
DstCL_CameraOffset,
DstKB_Find,
DstCAM_Think,
DstCalcRefdef,
DstAddEntity,
DstCreateEntities,
DstDrawNormalTriangles,
DstDrawTransparentTriangles,
DstStudioEvent,
DstPostRunCmd,
DstShutdown,
DstTxferLocalOverrides,
DstProcessPlayerState,
DstTxferPredictionData,
DstDemo_ReadBuffer,
DstConnectionlessPacket,
DstGetHullBounds,
DstFrame,
DstKey_Event,
DstTempEntUpdate,
DstGetUserEntity,
DstVoiceStatus,
DstDirectorMessage,
DstGetStudioModelInterface,
DstChatInputPosition,
DstGetPlayerTeam,
};
void CL_GetSecuredClientAPI( CL_EXPORT_FUNCS F )
{
modfuncs_t modFuncs = { 0 };
// secured client dlls need these
cldll_func_src_t cldllFuncSrc =
{
(void *)&modFuncs,
NULL,
(void *)&cldllFuncDst
};
// trying to fill interface now
F( &cldllFuncSrc );
// map exports to xash's cldll_func_t
clgame.dllFuncs.pfnInitialize = cldllFuncSrc.pfnInitialize;
clgame.dllFuncs.pfnInit = cldllFuncSrc.pfnInit;
clgame.dllFuncs.pfnVidInit = cldllFuncSrc.pfnVidInit;
clgame.dllFuncs.pfnRedraw = cldllFuncSrc.pfnRedraw;
clgame.dllFuncs.pfnUpdateClientData = cldllFuncSrc.pfnUpdateClientData;
clgame.dllFuncs.pfnReset = cldllFuncSrc.pfnReset;
clgame.dllFuncs.pfnPlayerMove = cldllFuncSrc.pfnPlayerMove;
clgame.dllFuncs.pfnPlayerMoveInit = cldllFuncSrc.pfnPlayerMoveInit;
clgame.dllFuncs.pfnPlayerMoveTexture = cldllFuncSrc.pfnPlayerMoveTexture;
clgame.dllFuncs.IN_ActivateMouse = cldllFuncSrc.IN_ActivateMouse;
clgame.dllFuncs.IN_DeactivateMouse = cldllFuncSrc.IN_DeactivateMouse;
clgame.dllFuncs.IN_MouseEvent = cldllFuncSrc.IN_MouseEvent;
clgame.dllFuncs.IN_ClearStates = cldllFuncSrc.IN_ClearStates;
clgame.dllFuncs.IN_Accumulate = cldllFuncSrc.IN_Accumulate;
clgame.dllFuncs.CL_CreateMove = cldllFuncSrc.CL_CreateMove;
clgame.dllFuncs.CL_IsThirdPerson = cldllFuncSrc.CL_IsThirdPerson;
clgame.dllFuncs.CL_CameraOffset = cldllFuncSrc.CL_CameraOffset;
clgame.dllFuncs.KB_Find = cldllFuncSrc.KB_Find;
clgame.dllFuncs.CAM_Think = cldllFuncSrc.CAM_Think;
clgame.dllFuncs.pfnCalcRefdef = cldllFuncSrc.pfnCalcRefdef;
clgame.dllFuncs.pfnAddEntity = cldllFuncSrc.pfnAddEntity;
clgame.dllFuncs.pfnCreateEntities = cldllFuncSrc.pfnCreateEntities;
clgame.dllFuncs.pfnDrawNormalTriangles = cldllFuncSrc.pfnDrawNormalTriangles;
clgame.dllFuncs.pfnDrawTransparentTriangles = cldllFuncSrc.pfnDrawTransparentTriangles;
clgame.dllFuncs.pfnStudioEvent = cldllFuncSrc.pfnStudioEvent;
clgame.dllFuncs.pfnPostRunCmd = cldllFuncSrc.pfnPostRunCmd;
clgame.dllFuncs.pfnShutdown = cldllFuncSrc.pfnShutdown;
clgame.dllFuncs.pfnTxferLocalOverrides = cldllFuncSrc.pfnTxferLocalOverrides;
clgame.dllFuncs.pfnProcessPlayerState = cldllFuncSrc.pfnProcessPlayerState;
clgame.dllFuncs.pfnTxferPredictionData = cldllFuncSrc.pfnTxferPredictionData;
clgame.dllFuncs.pfnDemo_ReadBuffer = cldllFuncSrc.pfnDemo_ReadBuffer;
clgame.dllFuncs.pfnConnectionlessPacket = cldllFuncSrc.pfnConnectionlessPacket;
clgame.dllFuncs.pfnGetHullBounds = cldllFuncSrc.pfnGetHullBounds;
clgame.dllFuncs.pfnFrame = cldllFuncSrc.pfnFrame;
clgame.dllFuncs.pfnKey_Event = cldllFuncSrc.pfnKey_Event;
clgame.dllFuncs.pfnTempEntUpdate = cldllFuncSrc.pfnTempEntUpdate;
clgame.dllFuncs.pfnGetUserEntity = cldllFuncSrc.pfnGetUserEntity;
clgame.dllFuncs.pfnVoiceStatus = cldllFuncSrc.pfnVoiceStatus;
clgame.dllFuncs.pfnDirectorMessage = cldllFuncSrc.pfnDirectorMessage;
clgame.dllFuncs.pfnGetStudioModelInterface = cldllFuncSrc.pfnGetStudioModelInterface;
clgame.dllFuncs.pfnChatInputPosition = cldllFuncSrc.pfnChatInputPosition;
}

View File

@@ -87,8 +87,6 @@ const char *cl_explode_sounds[] =
"weapons/explode5.wav",
};
static void CL_PlayerDecal( int playerIndex, int textureIndex, int entityIndex, float *pos );
/*
================
CL_LoadClientSprites
@@ -257,7 +255,7 @@ CL_PrepareTEnt
set default values
==============
*/
static void CL_PrepareTEnt( TEMPENTITY *pTemp, model_t *pmodel )
void CL_PrepareTEnt( TEMPENTITY *pTemp, model_t *pmodel )
{
int frameCount = 0;
int modelIndex = 0;
@@ -298,7 +296,7 @@ CL_TempEntPlaySound
play collide sound
==============
*/
static void CL_TempEntPlaySound( TEMPENTITY *pTemp, float damp )
void CL_TempEntPlaySound( TEMPENTITY *pTemp, float damp )
{
float fvol;
char soundname[32];
@@ -363,8 +361,8 @@ static void CL_TempEntPlaySound( TEMPENTITY *pTemp, float damp )
sound_t handle;
if( isshellcasing )
fvol *= Q_min( 1.0f, ((float)zvel) / 350.0f );
else fvol *= Q_min( 1.0f, ((float)zvel) / 450.0f );
fvol *= min ( 1.0f, ((float)zvel) / 350.0f );
else fvol *= min ( 1.0f, ((float)zvel) / 450.0f );
if( !COM_RandomLong( 0, 3 ) && !isshellcasing )
pitch = COM_RandomLong( 95, 105 );
@@ -382,7 +380,7 @@ CL_TEntAddEntity
add entity to renderlist
==============
*/
static int CL_TempEntAddEntity( cl_entity_t *pEntity )
int CL_TempEntAddEntity( cl_entity_t *pEntity )
{
vec3_t mins, maxs;
@@ -434,7 +432,7 @@ CL_TEntAddEntity
free the first low priority tempent it finds.
==============
*/
static qboolean CL_FreeLowPriorityTempEnt( void )
qboolean CL_FreeLowPriorityTempEnt( void )
{
TEMPENTITY *pActive = cl_active_tents;
TEMPENTITY *pPrev = NULL;
@@ -1039,7 +1037,7 @@ void GAME_EXPORT R_BreakModel( const vec3_t pos, const vec3_t size, const vec3_t
vecSpot[1] = pos[1] + COM_RandomFloat( -0.5f, 0.5f ) * size[1];
vecSpot[2] = pos[2] + COM_RandomFloat( -0.5f, 0.5f ) * size[2];
if( PM_CL_PointContents( vecSpot, NULL ) != CONTENTS_SOLID )
if( CL_PointContents( vecSpot ) != CONTENTS_SOLID )
break; // valid spot
}
@@ -1247,28 +1245,37 @@ apply params for exploding sprite
*/
void GAME_EXPORT R_Sprite_Explode( TEMPENTITY *pTemp, float scale, int flags )
{
qboolean noadditive, drawalpha, rotate;
if( !pTemp ) return;
if( !pTemp )
return;
if( FBitSet( flags, TE_EXPLFLAG_NOADDITIVE ))
{
// solid sprite
pTemp->entity.curstate.rendermode = kRenderNormal;
pTemp->entity.curstate.renderamt = 255;
}
else if( FBitSet( flags, TE_EXPLFLAG_DRAWALPHA ))
{
// alpha sprite (came from hl2)
pTemp->entity.curstate.rendermode = kRenderTransAlpha;
pTemp->entity.curstate.renderamt = 180;
}
else
{
// additive sprite
pTemp->entity.curstate.rendermode = kRenderTransAdd;
pTemp->entity.curstate.renderamt = 180;
}
noadditive = FBitSet( flags, TE_EXPLFLAG_NOADDITIVE );
drawalpha = FBitSet( flags, TE_EXPLFLAG_DRAWALPHA );
rotate = FBitSet( flags, TE_EXPLFLAG_ROTATE );
if( FBitSet( flags, TE_EXPLFLAG_ROTATE ))
{
// came from hl2
pTemp->entity.angles[2] = COM_RandomLong( 0, 360 );
}
pTemp->entity.curstate.renderfx = kRenderFxNone;
pTemp->entity.baseline.origin[2] = 8;
pTemp->entity.origin[2] += 10;
pTemp->entity.curstate.scale = scale;
pTemp->entity.baseline.origin[2] = 8.0f;
pTemp->entity.origin[2] = pTemp->entity.origin[2] + 10.0f;
if( rotate )
pTemp->entity.angles[2] = COM_RandomFloat( 0.0, 360.0f );
pTemp->entity.curstate.rendermode = noadditive ? kRenderNormal :
drawalpha ? kRenderTransAlpha : kRenderTransAdd;
pTemp->entity.curstate.renderamt = noadditive ? 0xff : 0xb4;
pTemp->entity.curstate.renderfx = 0;
pTemp->entity.curstate.rendercolor.r = 0;
pTemp->entity.curstate.rendercolor.g = 0;
pTemp->entity.curstate.rendercolor.b = 0;
}
/*
@@ -1475,6 +1482,7 @@ void GAME_EXPORT R_FunnelSprite( const vec3_t org, int modelIndex, int reverse )
pTemp->entity.baseline.angles[2] = COM_RandomFloat( -100.0f, 100.0f );
pTemp->entity.curstate.framerate = COM_RandomFloat( 0.1f, 0.4f );
pTemp->flags = FTENT_ROTATE|FTENT_FADEOUT;
pTemp->entity.curstate.framerate = 10;
vel = dest[2] / 8.0f;
if( vel < 64.0f ) vel = 64.0f;
@@ -1507,18 +1515,17 @@ R_RicochetSound
Make a random ricochet sound
==============
*/
static void R_RicochetSound_( const vec3_t pos, int sound )
{
sound_t handle;
handle = S_RegisterSound( cl_ricochet_sounds[sound] );
S_StartSound( pos, 0, CHAN_AUTO, handle, VOL_NORM, 1.0, 100, 0 );
}
void GAME_EXPORT R_RicochetSound( const vec3_t pos )
{
R_RicochetSound_( pos, COM_RandomLong( 0, 4 ));
int iPitch = COM_RandomLong( 90, 105 );
float fvol = COM_RandomFloat( 0.7f, 0.9f );
char soundpath[32];
sound_t handle;
Q_strncpy( soundpath, cl_ricochet_sounds[COM_RandomLong( 0, 4 )], sizeof( soundpath ) );
handle = S_RegisterSound( soundpath );
S_StartSound( pos, 0, CHAN_AUTO, handle, fvol, ATTN_NORM, iPitch, 0 );
}
/*
@@ -1649,7 +1656,7 @@ void GAME_EXPORT R_Explosion( vec3_t pos, int model, float scale, float framerat
dl->color.g = 250;
dl->color.b = 150;
dl->die = cl.time + 0.01f;
dl->decay = 800;
dl->decay = 80;
// red glow
dl = CL_AllocDlight( 0 );
@@ -1897,7 +1904,7 @@ handle temp-entity messages
void CL_ParseTempEntity( sizebuf_t *msg )
{
sizebuf_t buf;
byte pbuf[2048];
byte pbuf[256];
int iSize;
int type, color, count, flags;
int decalIndex, modelIndex, entityIndex;
@@ -1908,7 +1915,6 @@ void CL_ParseTempEntity( sizebuf_t *msg )
TEMPENTITY *pTemp;
cl_entity_t *pEnt;
dlight_t *dl;
sound_t hSound;
if( cls.legacymode )
iSize = MSG_ReadByte( msg );
@@ -1916,10 +1922,6 @@ void CL_ParseTempEntity( sizebuf_t *msg )
decalIndex = modelIndex = entityIndex = 0;
// this will probably be fatal anyway
if( iSize > sizeof( pbuf ))
Con_Printf( S_ERROR "%s: Temp buffer overflow!\n", __FUNCTION__ );
// parse user message into buffer
MSG_ReadBytes( msg, pbuf, iSize );
@@ -1967,9 +1969,6 @@ void CL_ParseTempEntity( sizebuf_t *msg )
pos[1] = MSG_ReadCoord( &buf );
pos[2] = MSG_ReadCoord( &buf );
R_BlobExplosion( pos );
hSound = S_RegisterSound( cl_explode_sounds[0] );
S_StartSound( pos, -1, CHAN_AUTO, hSound, VOL_NORM, 1.0f, PITCH_NORM, 0 );
break;
case TE_SMOKE:
pos[0] = MSG_ReadCoord( &buf );
@@ -2015,46 +2014,15 @@ void CL_ParseTempEntity( sizebuf_t *msg )
color = MSG_ReadByte( &buf );
count = MSG_ReadByte( &buf );
R_ParticleExplosion2( pos, color, count );
dl = CL_AllocDlight( 0 );
VectorCopy( pos, dl->origin );
dl->radius = 350;
dl->die = cl.time + 0.5;
dl->decay = 300;
hSound = S_RegisterSound( cl_explode_sounds[0] );
S_StartSound( pos, -1, CHAN_AUTO, hSound, VOL_NORM, 0.6f, PITCH_NORM, 0 );
break;
case TE_BSPDECAL:
case TE_DECAL:
case TE_WORLDDECAL:
case TE_WORLDDECALHIGH:
case TE_DECALHIGH:
pos[0] = MSG_ReadCoord( &buf );
pos[1] = MSG_ReadCoord( &buf );
pos[2] = MSG_ReadCoord( &buf );
if( type == TE_BSPDECAL )
{
decalIndex = MSG_ReadShort( &buf );
entityIndex = MSG_ReadShort( &buf );
if( entityIndex )
modelIndex = MSG_ReadShort( &buf );
else modelIndex = 0;
}
else
{
decalIndex = MSG_ReadByte( &buf );
if( type == TE_DECALHIGH || type == TE_WORLDDECALHIGH )
decalIndex += 256;
if( type == TE_DECALHIGH || type == TE_DECAL )
entityIndex = MSG_ReadShort( &buf );
else entityIndex = 0;
pEnt = CL_GetEntityByIndex( entityIndex );
modelIndex = pEnt->curstate.modelindex;
}
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, modelIndex, pos, type == TE_BSPDECAL ? FDECAL_PERMANENT : 0 );
decalIndex = MSG_ReadShort( &buf );
entityIndex = MSG_ReadShort( &buf );
if( entityIndex ) modelIndex = MSG_ReadShort( &buf );
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, modelIndex, pos, FDECAL_PERMANENT );
break;
case TE_IMPLOSION:
pos[0] = MSG_ReadCoord( &buf );
@@ -2074,12 +2042,10 @@ void CL_ParseTempEntity( sizebuf_t *msg )
pos2[2] = MSG_ReadCoord( &buf );
modelIndex = MSG_ReadShort( &buf );
count = MSG_ReadByte( &buf );
life = (float)MSG_ReadByte( &buf ) * 0.1f;
scale = (float)MSG_ReadByte( &buf );
if( !scale ) scale = 1.0f;
else scale *= 0.1f;
vel = (float)MSG_ReadByte( &buf ) * 10;
random = (float)MSG_ReadByte( &buf ) * 10;
life = (float)(MSG_ReadByte( &buf ) * 0.1f);
scale = (float)(MSG_ReadByte( &buf ) * 0.1f);
vel = (float)MSG_ReadByte( &buf );
random = (float)MSG_ReadByte( &buf );
R_Sprite_Trail( type, pos, pos2, modelIndex, count, life, scale, random, 255, vel );
break;
case TE_SPRITE:
@@ -2087,23 +2053,36 @@ void CL_ParseTempEntity( sizebuf_t *msg )
pos[1] = MSG_ReadCoord( &buf );
pos[2] = MSG_ReadCoord( &buf );
modelIndex = MSG_ReadShort( &buf );
scale = (float)MSG_ReadByte( &buf ) * 0.1f;
brightness = (float)MSG_ReadByte( &buf ) / 255.0f;
scale = (float)(MSG_ReadByte( &buf ) * 0.1f);
brightness = (float)MSG_ReadByte( &buf );
R_TempSprite( pos, vec3_origin, scale, modelIndex,
kRenderTransAdd, kRenderFxNone, brightness, 0.0, FTENT_SPRANIMATE );
if(( pTemp = R_DefaultSprite( pos, modelIndex, 0 )) != NULL )
{
pTemp->entity.curstate.scale = scale;
pTemp->entity.baseline.renderamt = brightness;
pTemp->entity.curstate.renderamt = brightness;
pTemp->entity.curstate.rendermode = kRenderTransAdd;
}
break;
case TE_GLOWSPRITE:
pos[0] = MSG_ReadCoord( &buf );
pos[1] = MSG_ReadCoord( &buf );
pos[2] = MSG_ReadCoord( &buf );
modelIndex = MSG_ReadShort( &buf );
life = (float)MSG_ReadByte( &buf ) * 0.1f;
scale = (float)MSG_ReadByte( &buf ) * 0.1f;
brightness = (float)MSG_ReadByte( &buf ) / 255.0f;
life = (float)(MSG_ReadByte( &buf ) * 0.1f);
scale = (float)(MSG_ReadByte( &buf ) * 0.1f);
brightness = (float)MSG_ReadByte( &buf );
R_TempSprite( pos, vec3_origin, scale, modelIndex,
kRenderGlow, kRenderFxNoDissipation, brightness, life, FTENT_FADEOUT );
if(( pTemp = R_DefaultSprite( pos, modelIndex, 0 )) != NULL )
{
pTemp->entity.curstate.scale = scale;
pTemp->entity.curstate.rendermode = kRenderGlow;
pTemp->entity.curstate.renderfx = kRenderFxNoDissipation;
pTemp->entity.baseline.renderamt = brightness;
pTemp->entity.curstate.renderamt = brightness;
pTemp->flags = FTENT_FADEOUT;
pTemp->die = cl.time + life;
}
break;
case TE_STREAK_SPLASH:
pos[0] = MSG_ReadCoord( &buf );
@@ -2193,6 +2172,23 @@ void CL_ParseTempEntity( sizebuf_t *msg )
pos2[2] = MSG_ReadCoord( &buf );
R_ShowLine( pos, pos2 );
break;
case TE_DECAL:
case TE_DECALHIGH:
case TE_WORLDDECAL:
case TE_WORLDDECALHIGH:
pos[0] = MSG_ReadCoord( &buf );
pos[1] = MSG_ReadCoord( &buf );
pos[2] = MSG_ReadCoord( &buf );
decalIndex = MSG_ReadByte( &buf );
if( type == TE_DECAL || type == TE_DECALHIGH )
entityIndex = MSG_ReadShort( &buf );
else entityIndex = 0;
if( type == TE_DECALHIGH || type == TE_WORLDDECALHIGH )
decalIndex += 256;
pEnt = CL_GetEntityByIndex( entityIndex );
if( pEnt ) modelIndex = pEnt->curstate.modelindex;
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, modelIndex, pos, 0 );
break;
case TE_FIZZ:
entityIndex = MSG_ReadShort( &buf );
modelIndex = MSG_ReadShort( &buf );
@@ -2248,11 +2244,10 @@ void CL_ParseTempEntity( sizebuf_t *msg )
pos[2] = MSG_ReadCoord( &buf );
entityIndex = MSG_ReadShort( &buf );
decalIndex = MSG_ReadByte( &buf );
pEnt = CL_GetEntityByIndex( entityIndex );
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, 0, pos, 0 );
R_BulletImpactParticles( pos );
flags = COM_RandomLong( 0, 0x7fff );
if( flags < 0x3fff )
R_RicochetSound_( pos, flags % 5 );
R_RicochetSound( pos );
break;
case TE_SPRAY:
case TE_SPRITE_SPRAY:
@@ -2398,7 +2393,7 @@ void CL_ParseTempEntity( sizebuf_t *msg )
// throw warning
if( MSG_CheckOverflow( &buf ))
Con_DPrintf( S_WARN "ParseTempEntity: overflow TE message %i\n", type );
Con_DPrintf( S_WARN "ParseTempEntity: overflow TE message\n" );
}
@@ -2416,7 +2411,7 @@ LIGHT STYLE MANAGEMENT
CL_ClearLightStyles
================
*/
static void CL_ClearLightStyles( void )
void CL_ClearLightStyles( void )
{
memset( cl.lightstyles, 0, sizeof( cl.lightstyles ));
}
@@ -2474,7 +2469,7 @@ dlight_t cl_elights[MAX_ELIGHTS];
CL_ClearDlights
================
*/
static void CL_ClearDlights( void )
void CL_ClearDlights( void )
{
memset( cl_dlights, 0, sizeof( cl_dlights ));
memset( cl_elights, 0, sizeof( cl_elights ));
@@ -2626,12 +2621,12 @@ CL_UpdateFlashlight
update client flashlight
================
*/
static void CL_UpdateFlashlight( cl_entity_t *ent )
void CL_UpdateFlashlight( cl_entity_t *ent )
{
vec3_t forward, view_ofs;
vec3_t vecSrc, vecEnd;
float falloff;
pmtrace_t trace;
pmtrace_t *trace;
cl_entity_t *hit;
dlight_t *dl;
@@ -2662,65 +2657,32 @@ static void CL_UpdateFlashlight( cl_entity_t *ent )
VectorAdd( ent->origin, view_ofs, vecSrc );
VectorMA( vecSrc, FLASHLIGHT_DISTANCE, forward, vecEnd );
trace = CL_TraceLine( vecSrc, vecEnd, PM_STUDIO_BOX );
trace = CL_VisTraceLine( vecSrc, vecEnd, PM_STUDIO_BOX );
// update flashlight endpos
dl = CL_AllocDlight( ent->index );
#if 1
hit = CL_GetEntityByIndex( clgame.pmove->physents[trace.ent].info );
hit = CL_GetEntityByIndex( clgame.pmove->visents[trace->ent].info );
if( hit && hit->model && ( hit->model->type == mod_alias || hit->model->type == mod_studio ))
VectorCopy( hit->origin, dl->origin );
else VectorCopy( trace.endpos, dl->origin );
else VectorCopy( trace->endpos, dl->origin );
#else
VectorCopy( trace->endpos, dl->origin );
#endif
// compute falloff
falloff = trace.fraction * FLASHLIGHT_DISTANCE;
falloff = trace->fraction * FLASHLIGHT_DISTANCE;
if( falloff < 500.0f ) falloff = 1.0f;
else falloff = 500.0f / falloff;
falloff *= falloff;
// apply brigthness to dlight
dl->color.r = dl->color.g = dl->color.b = bound( 0, falloff * 255, 255 );
dl->color.r = bound( 0, falloff * 255, 255 );
dl->color.g = bound( 0, falloff * 255, 255 );
dl->color.b = bound( 0, falloff * 255, 255 );
dl->die = cl.time + 0.01f; // die on next frame
dl->radius = 80;
}
static void R_EntityDimlight( cl_entity_t *ent, int key )
{
dlight_t *dl = CL_AllocDlight( key );
VectorCopy( ent->origin, dl->origin );
dl->color.r = dl->color.g = dl->color.b = 100;
dl->radius = COM_RandomFloat( 200.0f, 231.0f );
dl->die = cl.time + 0.001;
}
static void R_EntityLight( cl_entity_t *ent, int key )
{
dlight_t *dl = CL_AllocDlight( key );
VectorCopy( ent->origin, dl->origin );
dl->color.r = dl->color.g = dl->color.b = 100;
dl->radius = 200;
dl->die = cl.time + 0.001;
R_RocketFlare( ent->origin );
}
static void R_EntityBrightlight( cl_entity_t *ent, int key, int radius )
{
dlight_t *dl = CL_AllocDlight( key );
VectorCopy( ent->origin, dl->origin );
dl->origin[2] += 16.0f;
dl->color.r = dl->color.g = dl->color.b = 250;
if( !radius )
dl->radius = COM_RandomFloat( 400.0f, 431.0f );
else dl->radius = 400;
dl->die = cl.time + 0.001;
}
/*
================
CL_AddEntityEffects
@@ -2730,41 +2692,50 @@ apply various effects to entity origin or attachment
*/
void CL_AddEntityEffects( cl_entity_t *ent )
{
// players have special set of effects, from CL_LinkPlayers
if( ent->player && ent->index != cl.viewentity )
{
if( FBitSet( ent->curstate.effects, EF_BRIGHTLIGHT ))
R_EntityBrightlight( ent, ent->index /* 4 in GoldSrc */, 0 );
// yellow flies effect 'monster stuck in the wall'
if( FBitSet( ent->curstate.effects, EF_BRIGHTFIELD ))
R_EntityParticles( ent );
if( FBitSet( ent->curstate.effects, EF_DIMLIGHT ))
R_EntityDimlight( ent, ent->index /* 4 in GoldSrc */ );
}
else if( RP_LOCALCLIENT( ent ))
if( FBitSet( ent->curstate.effects, EF_DIMLIGHT ))
{
// from CL_PlayerFlashlight
if( FBitSet( ent->curstate.effects, EF_BRIGHTLIGHT ))
R_EntityBrightlight( ent, ent->index /* 1 in GoldSrc */, 400 );
else if( FBitSet( ent->curstate.effects, EF_DIMLIGHT ))
if( ent->player && !Host_IsQuakeCompatible( ))
{
CL_UpdateFlashlight( ent );
}
else
{
dlight_t *dl = CL_AllocDlight( ent->index );
dl->color.r = dl->color.g = dl->color.b = 100;
dl->radius = COM_RandomFloat( 200, 231 );
VectorCopy( ent->origin, dl->origin );
dl->die = cl.time + 0.001;
}
}
else
if( FBitSet( ent->curstate.effects, EF_BRIGHTLIGHT ))
{
// from CL_LinkPacketEntities
if( FBitSet( ent->curstate.effects, EF_BRIGHTFIELD ))
R_EntityParticles( ent );
dlight_t *dl = CL_AllocDlight( ent->index );
dl->color.r = dl->color.g = dl->color.b = 250;
if( ent->player ) dl->radius = 400; // don't flickering
else dl->radius = COM_RandomFloat( 400, 431 );
VectorCopy( ent->origin, dl->origin );
dl->die = cl.time + 0.001;
dl->origin[2] += 16.0f;
}
if( FBitSet( ent->curstate.effects, EF_BRIGHTLIGHT ))
R_EntityBrightlight( ent, ent->index, 0 );
if( FBitSet( ent->curstate.effects, EF_DIMLIGHT ))
R_EntityDimlight( ent, ent->index );
if( FBitSet( ent->curstate.effects, EF_LIGHT ))
R_EntityLight( ent, ent->curstate.number );
// add light effect
if( FBitSet( ent->curstate.effects, EF_LIGHT ))
{
dlight_t *dl = CL_AllocDlight( ent->index );
dl->color.r = dl->color.g = dl->color.b = 100;
VectorCopy( ent->origin, dl->origin );
R_RocketFlare( ent->origin );
dl->die = cl.time + 0.001;
dl->radius = 200;
}
// studio models are handle muzzleflashes difference
if( FBitSet( ent->curstate.effects, EF_MUZZLEFLASH ) && ent->model && ent->model->type == mod_alias )
if( FBitSet( ent->curstate.effects, EF_MUZZLEFLASH ) && Mod_AliasExtradata( ent->model ))
{
dlight_t *dl = CL_AllocDlight( ent->index );
vec3_t fv;
@@ -2793,11 +2764,15 @@ void CL_AddModelEffects( cl_entity_t *ent )
vec3_t neworigin;
vec3_t oldorigin;
if( !ent->model || ent->player )
return;
if( !ent->model ) return;
if( ent->model->type != mod_alias && ent->model->type != mod_studio )
return;
switch( ent->model->type )
{
case mod_alias:
case mod_studio:
break;
default: return;
}
if( cls.demoplayback == DEMO_QUAKE1 )
{
@@ -2817,15 +2792,19 @@ void CL_AddModelEffects( cl_entity_t *ent )
if( FBitSet( ent->model->flags, STUDIO_GIB ))
R_RocketTrail( oldorigin, neworigin, 2 );
else if( FBitSet( ent->model->flags, STUDIO_ZOMGIB ))
if( FBitSet( ent->model->flags, STUDIO_ZOMGIB ))
R_RocketTrail( oldorigin, neworigin, 4 );
else if( FBitSet( ent->model->flags, STUDIO_TRACER ))
if( FBitSet( ent->model->flags, STUDIO_TRACER ))
R_RocketTrail( oldorigin, neworigin, 3 );
else if( FBitSet( ent->model->flags, STUDIO_TRACER2 ))
if( FBitSet( ent->model->flags, STUDIO_TRACER2 ))
R_RocketTrail( oldorigin, neworigin, 5 );
else if( FBitSet( ent->model->flags, STUDIO_ROCKET ))
if( FBitSet( ent->model->flags, STUDIO_ROCKET ))
{
dlight_t *dl = CL_AllocDlight( ent->curstate.number );
dlight_t *dl = CL_AllocDlight( ent->index );
dl->color.r = dl->color.g = dl->color.b = 200;
VectorCopy( ent->origin, dl->origin );
@@ -2839,9 +2818,11 @@ void CL_AddModelEffects( cl_entity_t *ent )
R_RocketTrail( oldorigin, neworigin, 0 );
}
else if( FBitSet( ent->model->flags, STUDIO_GRENADE ))
if( FBitSet( ent->model->flags, STUDIO_GRENADE ))
R_RocketTrail( oldorigin, neworigin, 1 );
else if( FBitSet( ent->model->flags, STUDIO_TRACER3 ))
if( FBitSet( ent->model->flags, STUDIO_TRACER3 ))
R_RocketTrail( oldorigin, neworigin, 6 );
}
@@ -2859,10 +2840,10 @@ void CL_TestLights( void )
float f, r;
dlight_t *dl;
if( !cl_testlights.value )
if( !CVAR_TO_BOOL( cl_testlights ))
return;
numLights = bound( 1, cl_testlights.value, MAX_DLIGHTS );
numLights = bound( 1, cl_testlights->value, MAX_DLIGHTS );
AngleVectors( cl.viewangles, forward, right, NULL );
for( i = 0; i < numLights; i++ )
@@ -2921,7 +2902,7 @@ CL_PlayerDecal
spray custom colored decal (clan logo etc)
===============
*/
static void CL_PlayerDecal( int playernum, int customIndex, int entityIndex, float *pos )
void CL_PlayerDecal( int playernum, int customIndex, int entityIndex, float *pos )
{
int textureIndex = 0;
customization_t *pCust = NULL;
@@ -2933,17 +2914,9 @@ static void CL_PlayerDecal( int playernum, int customIndex, int entityIndex, flo
{
if( FBitSet( pCust->resource.ucFlags, RES_CUSTOM ) && pCust->resource.type == t_decal && pCust->bTranslated )
{
if( !pCust->nUserData1 )
if( !pCust->nUserData1 && pCust->pInfo != NULL )
{
int sprayTextureIndex;
char decalname[MAX_VA_STRING];
Q_snprintf( decalname, sizeof( decalname ), "player%dlogo%d", playernum, customIndex );
sprayTextureIndex = ref.dllFuncs.GL_FindTexture( decalname );
if( sprayTextureIndex != 0 )
{
ref.dllFuncs.GL_FreeTexture( sprayTextureIndex );
}
const char *decalname = va( "player%dlogo%d", playernum, customIndex );
pCust->nUserData1 = GL_LoadTextureInternal( decalname, pCust->pInfo, TF_DECAL );
}
textureIndex = pCust->nUserData1;

View File

@@ -81,6 +81,7 @@ void R_DebugParticle( const vec3_t pos, byte r, byte g, byte b );
void R_RicochetSound( const vec3_t pos );
struct dlight_s *CL_AllocDlight( int key );
struct dlight_s *CL_AllocElight( int key );
void CL_UpdateFlashlight( cl_entity_t *pEnt );
void CL_AddEntityEffects( cl_entity_t *ent );
void CL_AddModelEffects( cl_entity_t *ent );
void CL_DecalShoot( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags );

View File

@@ -68,7 +68,7 @@ qboolean SCR_NextMovie( void )
return true;
}
static void SCR_CreateStartupVids( void )
void SCR_CreateStartupVids( void )
{
file_t *f;
@@ -202,13 +202,14 @@ SCR_PlayCinematic
*/
qboolean SCR_PlayCinematic( const char *arg )
{
string path;
const char *fullpath;
fullpath = FS_GetDiskPath( arg, false );
if( FS_FileExists( arg, false ) && !fullpath )
{
Con_Printf( S_ERROR "Couldn't load %s from packfile. Please extract it\n", arg );
Con_Printf( S_ERROR "Couldn't load %s from packfile. Please extract it\n", path );
return false;
}

View File

@@ -29,45 +29,36 @@ V_CalcViewRect
calc frame rectangle (Quake1 style)
===============
*/
static void V_CalcViewRect( void )
void V_CalcViewRect( void )
{
qboolean full = false;
int sb_lines;
float size;
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
{
// intermission is always full screen
if( cl.intermission ) size = 120.0f;
else size = scr_viewsize.value;
// intermission is always full screen
if( cl.intermission ) size = 120.0f;
else size = scr_viewsize->value;
if( size >= 120.0f )
sb_lines = 0; // no status bar at all
else if( size >= 110.0f )
sb_lines = 24; // no inventory
else sb_lines = 48;
if( size >= 120.0f )
sb_lines = 0; // no status bar at all
else if( size >= 110.0f )
sb_lines = 24; // no inventory
else sb_lines = 48;
if( scr_viewsize.value >= 100.0f )
{
full = true;
size = 100.0f;
}
else size = scr_viewsize.value;
if( cl.intermission )
{
size = 100.0f;
sb_lines = 0;
full = true;
}
size /= 100.0f;
}
else
if( scr_viewsize->value >= 100.0f )
{
full = true;
sb_lines = 0;
size = 1.0f;
size = 100.0f;
}
else size = scr_viewsize->value;
if( cl.intermission )
{
size = 100.0f;
sb_lines = 0;
full = true;
}
size /= 100.0f;
clgame.viewport[2] = refState.width * size;
clgame.viewport[3] = refState.height * size;
@@ -88,7 +79,7 @@ static void V_CalcViewRect( void )
V_SetupViewModel
===============
*/
static void V_SetupViewModel( void )
void V_SetupViewModel( void )
{
cl_entity_t *view = &clgame.viewent;
player_info_t *info = &cl.players[cl.playernum];
@@ -118,7 +109,7 @@ static void V_SetupViewModel( void )
V_SetRefParams
===============
*/
static void V_SetRefParams( ref_params_t *fd )
void V_SetRefParams( ref_params_t *fd )
{
memset( fd, 0, sizeof( ref_params_t ));
@@ -144,7 +135,7 @@ static void V_SetRefParams( ref_params_t *fd )
VectorCopy( cl.viewangles, fd->cl_viewangles );
fd->health = cl.local.health;
VectorCopy( cl.crosshairangle, fd->crosshairangle );
fd->viewsize = scr_viewsize.value;
fd->viewsize = scr_viewsize->value;
VectorCopy( cl.punchangle, fd->punchangle );
fd->maxclients = cl.maxclients;
@@ -182,7 +173,7 @@ V_MergeOverviewRefdef
merge refdef with overview settings
===============
*/
static void V_RefApplyOverview( ref_viewpass_t *rvp )
void V_RefApplyOverview( ref_viewpass_t *rvp )
{
ref_overview_t *ov = &clgame.overView;
float aspect;
@@ -229,59 +220,12 @@ static void V_RefApplyOverview( ref_viewpass_t *rvp )
ref.dllFuncs.GL_OrthoBounds( mins, maxs );
}
/*
====================
V_CalcFov
====================
*/
static float V_CalcFov( float *fov_x, float width, float height )
{
float x, half_fov_y;
if( *fov_x < 1.0f || *fov_x > 179.0f )
*fov_x = 90.0f; // default value
x = width / tan( DEG2RAD( *fov_x ) * 0.5f );
half_fov_y = atan( height / x );
return RAD2DEG( half_fov_y ) * 2;
}
/*
====================
V_AdjustFov
====================
*/
static void V_AdjustFov( float *fov_x, float *fov_y, float width, float height, qboolean lock_x )
{
float x, y;
if( width * 3 == 4 * height || width * 4 == height * 5 )
{
// 4:3 or 5:4 ratio
return;
}
if( lock_x )
{
*fov_y = 2 * atan((width * 3) / (height * 4) * tan( *fov_y * M_PI_F / 360.0f * 0.5f )) * 360 / M_PI_F;
return;
}
y = V_CalcFov( fov_x, 640, 480 );
x = *fov_x;
*fov_x = V_CalcFov( &y, height, width );
if( *fov_x < x ) *fov_x = x;
else *fov_y = y;
}
/*
=============
V_GetRefParams
=============
*/
static void V_GetRefParams( ref_params_t *fd, ref_viewpass_t *rvp )
void V_GetRefParams( ref_params_t *fd, ref_viewpass_t *rvp )
{
// part1: deniable updates
VectorCopy( fd->simvel, cl.simvel );
@@ -311,7 +255,7 @@ static void V_GetRefParams( ref_params_t *fd, ref_viewpass_t *rvp )
rvp->fov_y = V_CalcFov( &rvp->fov_x, clgame.viewport[2], clgame.viewport[3] );
// adjust FOV for widescreen
if( refState.wideScreen && r_adjust_fov.value )
if( refState.wideScreen && r_adjust_fov->value )
V_AdjustFov( &rvp->fov_x, &rvp->fov_y, clgame.viewport[2], clgame.viewport[3], false );
rvp->flags = 0;
@@ -333,13 +277,16 @@ qboolean V_PreRender( void )
if( !ref.initialized )
return false;
if( host.status == HOST_NOFOCUS )
return false;
if( host.status == HOST_SLEEP )
return false;
// if the screen is disabled (loading plaque is up)
if( cls.disable_screen )
{
if(( host.realtime - cls.disable_screen ) > cl_timeout.value )
if(( host.realtime - cls.disable_screen ) > cl_timeout->value )
{
Con_Reportf( "V_PreRender: loading plaque timed out\n" );
cls.disable_screen = 0.0f;
@@ -347,8 +294,6 @@ qboolean V_PreRender( void )
return false;
}
V_CheckGamma();
ref.dllFuncs.R_BeginFrame( !cl.paused && ( cls.state == ca_active ));
GL_UpdateSwapInterval( );
@@ -366,13 +311,11 @@ V_RenderView
*/
void V_RenderView( void )
{
// HACKHACK: make ref params static
// not really critical but allows client.dll to take address of refdef and don't trigger ASan
static ref_params_t rp;
ref_params_t rp;
ref_viewpass_t rvp;
int viewnum = 0;
if( !cl.video_prepped || ( !ui_renderworld.value && UI_IsVisible() && !cl.background ))
if( !cl.video_prepped || ( !ui_renderworld->value && UI_IsVisible() && !cl.background ))
return; // still loading
V_CalcViewRect (); // compute viewport rectangle
@@ -408,14 +351,14 @@ void V_RenderView( void )
#define NODE_INTERVAL_X(x) (x * 16.0f)
#define NODE_INTERVAL_Y(x) (x * 16.0f)
static void R_DrawLeafNode( float x, float y, float scale )
void R_DrawLeafNode( float x, float y, float scale )
{
float downScale = scale * 0.25f;// * POINT_SIZE;
ref.dllFuncs.R_DrawStretchPic( x - downScale * 0.5f, y - downScale * 0.5f, downScale, downScale, 0, 0, 1, 1, R_GetBuiltinTexture( REF_PARTICLE_TEXTURE ) );
}
static void R_DrawNodeConnection( float x, float y, float x2, float y2 )
void R_DrawNodeConnection( float x, float y, float x2, float y2 )
{
ref.dllFuncs.Begin( TRI_LINES );
ref.dllFuncs.Vertex3f( x, y, 0 );
@@ -423,7 +366,7 @@ static void R_DrawNodeConnection( float x, float y, float x2, float y2 )
ref.dllFuncs.End( );
}
static void R_ShowTree_r( mnode_t *node, float x, float y, float scale, int shownodes, mleaf_t *viewleaf )
void R_ShowTree_r( mnode_t *node, float x, float y, float scale, int shownodes, mleaf_t *viewleaf )
{
float downScale = scale * 0.8f;
@@ -470,13 +413,13 @@ static void R_ShowTree_r( mnode_t *node, float x, float y, float scale, int show
world.recursion_level--;
}
static void R_ShowTree( void )
void R_ShowTree( void )
{
float x = (float)((refState.width - (int)POINT_SIZE) >> 1);
float y = NODE_INTERVAL_Y(1.0f);
mleaf_t *viewleaf;
if( !cl.worldmodel || !r_showtree.value )
if( !cl.worldmodel || !CVAR_TO_BOOL( r_showtree ))
return;
world.recursion_level = 0;
@@ -551,6 +494,5 @@ void V_PostRender( void )
SCR_MakeScreenShot();
ref.dllFuncs.R_AllowFog( true );
Platform_SetTimer( 0.0f );
ref.dllFuncs.R_EndFrame();
}

View File

@@ -33,7 +33,6 @@ GNU General Public License for more details.
#include "net_api.h"
#include "world.h"
#include "ref_common.h"
#include "voice.h"
// client sprite types
#define SPR_CLIENT 0 // client sprite for temp-entities or user-textures
@@ -108,6 +107,7 @@ extern int CL_UPDATE_BACKUP;
#define MIN_UPDATERATE 10.0f
#define MAX_UPDATERATE 102.0f
#define MIN_EX_INTERP 0.005f
#define MAX_EX_INTERP 0.1f
#define CL_MIN_RESEND_TIME 1.5f // mininum time gap (in seconds) before a subsequent connection request is sent.
@@ -138,7 +138,7 @@ typedef struct
int light_level;
int waterlevel;
int usehull;
qboolean moving;
int moving;
int pushmsec;
int weapons;
float maxspeed;
@@ -174,26 +174,6 @@ typedef struct
// at every server map change
typedef struct
{
// ==== shared through RefAPI's ref_client_t ====
double time; // this is the time value that the client
// is rendering at. always <= cls.realtime
// a lerp point for other data
double oldtime; // previous cl.time, time-oldtime is used
// to decay light values and smooth step ups
int viewentity;
// server state information
int playernum;
int maxclients;
int nummodels;
model_t *models[MAX_MODELS+1]; // precached models (plus sentinel slot)
qboolean paused;
vec3_t simorg; // predicted origin
// ==== shared through RefAPI's ref_client_t ===
int servercount; // server identification for prespawns
int validsequence; // this is the sequence number of the last good
// world snapshot/update we got. If this is 0, we can't
@@ -203,6 +183,7 @@ typedef struct
qboolean video_prepped; // false if on new level or new ref dll
qboolean audio_prepped; // false if on new level or new snd dll
qboolean paused;
int delta_sequence; // acknowledged sequence number
@@ -224,7 +205,12 @@ typedef struct
runcmd_t commands[MULTIPLAYER_BACKUP]; // each mesage will send several old cmds
local_state_t predicted_frames[MULTIPLAYER_BACKUP]; // local client state
double timedelta; // floating delta between two updates
double time; // this is the time value that the client
// is rendering at. always <= cls.realtime
// a lerp point for other data
double oldtime; // previous cl.time, time-oldtime is used
// to decay light values and smooth step ups
float timedelta; // floating delta between two updates
char serverinfo[MAX_SERVERINFO_STRING];
player_info_t players[MAX_CLIENTS]; // collected info about all other players include himself
@@ -237,6 +223,7 @@ typedef struct
// player final info
usercmd_t *cmd; // cl.commands[outgoing_sequence].cmd
int viewentity;
vec3_t viewangles;
vec3_t viewheight;
vec3_t punchangle;
@@ -249,9 +236,14 @@ typedef struct
float addangletotal;
float prevaddangletotal;
// predicted velocity
// predicted origin and velocity
vec3_t simorg;
vec3_t simvel;
// server state information
int playernum;
int maxclients;
entity_state_t instanced_baseline[MAX_CUSTOM_BASELINES];
int instanced_baseline_count;
@@ -259,6 +251,8 @@ typedef struct
char event_precache[MAX_EVENTS][MAX_QPATH];
char files_precache[MAX_CUSTOM][MAX_QPATH];
lightstyle_t lightstyles[MAX_LIGHTSTYLES];
model_t *models[MAX_MODELS+1]; // precached models (plus sentinel slot)
int nummodels;
int numfiles;
consistency_t consistency_list[MAX_MODELS];
@@ -324,45 +318,32 @@ typedef struct
pfnEventHook func; // user-defined function
} cl_user_event_t;
#define FONT_FIXED 0
#define FONT_VARIABLE 1
#define FONT_DRAW_HUD BIT( 0 ) // pass to drawing function to apply hud_scale
#define FONT_DRAW_UTF8 BIT( 1 ) // call UtfProcessChar
#define FONT_DRAW_FORCECOL BIT( 2 ) // ignore colorcodes
#define FONT_DRAW_NORENDERMODE BIT( 3 ) // ignore font's default rendermode
#define FONT_DRAW_NOLF BIT( 4 ) // ignore \n
#define FONT_DRAW_RESETCOLORONLF BIT( 5 ) // yet another flag to simulate consecutive Con_DrawString calls...
#define FONT_FIXED 0
#define FONT_VARIABLE 1
typedef struct
{
int hFontTexture; // handle to texture
wrect_t fontRc[256]; // tex coords
float scale; // scale factor
byte charWidths[256]; // scaled widths
int charHeight; // scaled height
int type; // fixed width font or variable
int rendermode; // default rendermode
qboolean valid; // all rectangles are valid
int hFontTexture; // handle to texture
wrect_t fontRc[256]; // rectangles
byte charWidths[256];
int charHeight;
int type;
qboolean valid; // all rectangles are valid
} cl_font_t;
typedef struct scissor_state_s
{
int x;
int y;
int width;
int height;
qboolean test;
} scissor_state_t;
typedef struct
{
// scissor test
scissor_state_t scissor;
// temp handle
const model_t *pSprite; // pointer to current SpriteTexture
// scissor test
int scissor_x;
int scissor_y;
int scissor_width;
int scissor_height;
qboolean scissor_test;
qboolean adjust_size; // allow to adjust scale for fonts
int renderMode; // override kRenderMode from TriAPI
TRICULLSTYLE cullMode; // override CULL FACE from TriAPI
@@ -389,11 +370,15 @@ typedef struct cl_predicted_player_s
typedef struct
{
// scissor test
scissor_state_t scissor;
int gl_texturenum; // this is a real texnum
// scissor test
int scissor_x;
int scissor_y;
int scissor_width;
int scissor_height;
qboolean scissor_test;
// holds text color
rgba_t textColor;
} gameui_draw_t;
@@ -428,6 +413,13 @@ typedef struct
float applied_angle;
} screen_shake_t;
typedef enum
{
NET_REQUEST_CANCEL = 0, // request was cancelled for some reasons
NET_REQUEST_GAMEUI, // called from GameUI
NET_REQUEST_CLIENT, // called from Client
} net_request_type_t;
typedef struct
{
net_response_t resp;
@@ -473,7 +465,7 @@ typedef struct
string cdtracks[MAX_CDTRACKS]; // 32 cd-tracks read from cdaudio.txt
model_t sprites[MAX_CLIENT_SPRITES]; // hud&client spritetexturesz
model_t sprites[MAX_CLIENT_SPRITES]; // client spritetextures
int viewport[4]; // viewport sizes
client_draw_t ds; // draw2d stuff (hud, weaponmenu etc)
@@ -489,7 +481,9 @@ typedef struct
client_textmessage_t *titles; // title messages, not network messages
int numTitles;
net_request_type_t request_type; // filter the requests
net_request_t net_requests[MAX_REQUESTS]; // no reason to keep more
net_request_t *master_request; // queued master request
efrag_t *free_efrags; // linked efrags
cl_entity_t viewent; // viewmodel
@@ -533,6 +527,9 @@ typedef struct
float disable_screen; // showing loading plaque between levels
// or changing rendering dlls
// if time gets > 30 seconds ahead, break it
int disable_servercount; // when we receive a frame and cl.servercount
// > cls.disable_servercount, clear disable_screen
qboolean draw_changelevel; // draw changelevel image 'Loading...'
keydest_t key_dest;
@@ -623,14 +620,13 @@ typedef struct
file_t *demofile;
file_t *demoheader; // contain demo startup info in case we record a demo on this level
qboolean internetservers_wait; // internetservers is waiting for dns request
qboolean internetservers_pending; // if true, clean master server pings
uint32_t internetservers_key; // compare key to validate master server reply
char internetservers_query[512]; // cached query
uint32_t internetservers_query_len;
qboolean internetservers_pending; // internetservers is waiting for dns request
// legacy mode support
qboolean legacymode; // one-way 48 protocol compatibility
netadr_t legacyserver;
netadr_t legacyservers[MAX_LEGACY_SERVERS];
int legacyservercount;
int extensions;
netadr_t serveradr;
@@ -658,53 +654,51 @@ extern convar_t cl_logocolor;
extern convar_t cl_allow_download;
extern convar_t cl_allow_upload;
extern convar_t cl_download_ingame;
extern convar_t cl_nopred;
extern convar_t cl_timeout;
extern convar_t cl_nodelta;
extern convar_t cl_interp;
extern convar_t cl_nointerp;
extern convar_t cl_showerror;
extern convar_t cl_nosmooth;
extern convar_t cl_smoothtime;
extern convar_t cl_crosshair;
extern convar_t cl_testlights;
extern convar_t cl_cmdrate;
extern convar_t cl_updaterate;
extern convar_t cl_solid_players;
extern convar_t cl_idealpitchscale;
extern convar_t cl_allow_levelshots;
extern convar_t cl_lightstyle_lerping;
extern convar_t cl_draw_particles;
extern convar_t cl_draw_tracers;
extern convar_t cl_levelshot_name;
extern convar_t cl_draw_beams;
extern convar_t cl_clockreset;
extern convar_t cl_fixtimerate;
extern convar_t hud_fontscale;
extern convar_t hud_scale;
extern convar_t hud_scale_minimal_width;
extern convar_t r_showtextures;
extern convar_t cl_bmodelinterp;
extern convar_t cl_lw; // local weapons
extern convar_t cl_charset;
extern convar_t cl_trace_messages;
extern convar_t cl_trace_events;
extern convar_t hud_utf8;
extern convar_t cl_showevents;
extern convar_t scr_centertime;
extern convar_t scr_viewsize;
extern convar_t scr_loading;
extern convar_t v_dark; // start from dark
extern convar_t net_graph;
extern convar_t rate;
extern convar_t m_ignore;
extern convar_t r_showtree;
extern convar_t ui_renderworld;
extern convar_t cl_fixmodelinterpolationartifacts;
extern convar_t *cl_nopred;
extern convar_t *cl_timeout;
extern convar_t *cl_nodelta;
extern convar_t *cl_interp;
extern convar_t *cl_nointerp;
extern convar_t *cl_showerror;
extern convar_t *cl_nosmooth;
extern convar_t *cl_smoothtime;
extern convar_t *cl_crosshair;
extern convar_t *cl_testlights;
extern convar_t *cl_cmdrate;
extern convar_t *cl_updaterate;
extern convar_t *cl_solid_players;
extern convar_t *cl_idealpitchscale;
extern convar_t *cl_allow_levelshots;
extern convar_t *cl_lightstyle_lerping;
extern convar_t *cl_draw_particles;
extern convar_t *cl_draw_tracers;
extern convar_t *cl_levelshot_name;
extern convar_t *cl_draw_beams;
extern convar_t *cl_clockreset;
extern convar_t *cl_fixtimerate;
extern convar_t *hud_scale;
extern convar_t *gl_showtextures;
extern convar_t *cl_bmodelinterp;
extern convar_t *cl_righthand;
extern convar_t *cl_lw; // local weapons
extern convar_t *cl_charset;
extern convar_t *cl_trace_messages;
extern convar_t *hud_utf8;
extern convar_t *cl_showevents;
extern convar_t *scr_centertime;
extern convar_t *scr_viewsize;
extern convar_t *scr_loading;
extern convar_t *v_dark; // start from dark
extern convar_t *net_graph;
extern convar_t *rate;
extern convar_t *m_ignore;
extern convar_t *r_showtree;
extern convar_t *ui_renderworld;
//=============================================================================
void CL_SetLightstyle( int style, const char* s, float f );
void CL_RunLightStyles( void );
void CL_DecayLights( void );
dlight_t *CL_GetDynamicLight( int number );
dlight_t *CL_GetEntityLight( int number );
@@ -714,9 +708,13 @@ dlight_t *CL_GetEntityLight( int number );
//
// cl_cmds.c
//
void CL_Quit_f( void );
void CL_GenericShot_f( void );
void CL_Quit_f( void ) NORETURN;
void CL_ScreenShot_f( void );
void CL_SnapShot_f( void );
void CL_PlayCDTrack_f( void );
void CL_EnvShot_f( void );
void CL_SkyShot_f( void );
void CL_SaveShot_f( void );
void CL_LevelShot_f( void );
void CL_SetSky_f( void );
void SCR_Viewpos_f( void );
@@ -737,6 +735,8 @@ void CL_ClearResourceLists( void );
void CL_Parse_Debug( qboolean enable );
void CL_Parse_RecordCommand( int cmd, int startoffset );
void CL_ResetFrame( frame_t *frame );
void CL_WriteMessageHistory( void );
const char *CL_MsgInfo( int cmd );
//
// cl_efx.c
@@ -747,6 +747,7 @@ void CL_Particle( const vec3_t org, int color, float life, int zpos, int zvel );
// cl_main.c
//
void CL_Init( void );
void CL_SendCommand( void );
void CL_Disconnect_f( void );
void CL_ProcessFile( qboolean successfully_received, const char *filename );
void CL_WriteUsercmd( sizebuf_t *msg, int from, int to );
@@ -755,6 +756,7 @@ qboolean CL_PrecacheResources( void );
void CL_SetupOverviewParams( void );
void CL_UpdateFrameLerp( void );
int CL_IsDevOverviewMode( void );
void CL_PingServers_f( void );
void CL_SignonReply( void );
void CL_ClearState( void );
@@ -772,6 +774,8 @@ void CL_CheckStartupDemos( void );
void CL_WriteDemoJumpTime( void );
void CL_CloseDemoHeader( void );
void CL_DemoCompleted( void );
void CL_StopPlayback( void );
void CL_StopRecord( void );
void CL_PlayDemo_f( void );
void CL_TimeDemo_f( void );
void CL_StartDemos_f( void );
@@ -779,7 +783,6 @@ void CL_Demos_f( void );
void CL_DeleteDemo_f( void );
void CL_Record_f( void );
void CL_Stop_f( void );
int CL_GetDemoComment( const char *demoname, char *comment );
//
// cl_events.c
@@ -787,60 +790,57 @@ int CL_GetDemoComment( const char *demoname, char *comment );
void CL_ParseEvent( sizebuf_t *msg );
void CL_ParseReliableEvent( sizebuf_t *msg );
void CL_SetEventIndex( const char *szEvName, int ev_index );
void CL_QueueEvent( int flags, int index, float delay, event_args_t *args );
void CL_PlaybackEvent( int flags, const edict_t *pInvoker, word eventindex, float delay, float *origin,
float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 );
void CL_RegisterEvent( int lastnum, const char *szEvName, pfnEventHook func );
void CL_BatchResourceRequest( qboolean initialize );
int CL_EstimateNeededResources( void );
void CL_ResetEvent( event_info_t *ei );
word CL_EventIndex( const char *name );
void CL_FireEvents( void );
//
// cl_font.c
//
qboolean CL_FixedFont( cl_font_t *font );
qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float scale, int rendermode, uint texFlags );
qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font, float scale, int rendermode, uint texFlags );
void CL_FreeFont( cl_font_t *font );
int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *font, int flags );
int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *font, int flags );
void CL_DrawCharacterLen( cl_font_t *font, int number, int *width, int *height );
void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height, int flags );
int CL_DrawStringf( cl_font_t *font, float x, float y, rgba_t color, int flags, const char *fmt, ... ) _format( 6 );
//
// cl_game.c
//
void CL_UnloadProgs( void );
qboolean CL_LoadProgs( const char *name );
void CL_ParseUserMessage( sizebuf_t *msg, int svc_num );
void CL_LinkUserMessage( char *pszName, const int svc_num, int iSize );
void CL_ParseFinaleCutscene( sizebuf_t *msg, int level );
void CL_ParseTextMessage( sizebuf_t *msg );
void CL_DrawHUD( int state );
void CL_InitEdicts( int maxclients );
void CL_InitEdicts( void );
void CL_FreeEdicts( void );
void CL_ClearWorld( void );
void CL_DrawCenterPrint( void );
void CL_ClearSpriteTextures( void );
void CL_FreeEntity( cl_entity_t *pEdict );
void CL_CenterPrint( const char *text, float y );
void CL_TextMessageParse( byte *pMemFile, int fileSize );
client_textmessage_t *CL_TextMessageGet( const char *pName );
int pfnDecalIndexFromName( const char *szDecalName );
int pfnIndexFromTrace( struct pmtrace_s *pTrace );
model_t *CL_ModelHandle( int modelindex );
void NetAPI_CancelAllRequests( void );
int CL_FindModelIndex( const char *m );
cl_entity_t *CL_GetLocalPlayer( void );
model_t *CL_LoadClientSprite( const char *filename );
model_t *CL_LoadModel( const char *modelname, int *index );
HSPRITE EXPORT pfnSPR_Load( const char *szPicName );
HSPRITE pfnSPR_LoadExt( const char *szPicName, uint texFlags );
void SPR_AdjustSize( float *x, float *y, float *w, float *h );
void PicAdjustSize( float *x, float *y, float *w, float *h );
int CL_GetScreenInfo( SCREENINFO *pscrinfo );
pmtrace_t *PM_CL_TraceLine( float *start, float *end, int flags, int usehull, int ignore_pe );
const char *PM_CL_TraceTexture( int ground, float *vstart, float *vend );
int PM_CL_PointContents( const float *p, int *truecontents );
void CL_FillRGBA( int x, int y, int width, int height, int r, int g, int b, int a );
void CL_PlayerTrace( float *start, float *end, int traceFlags, int ignore_pe, pmtrace_t *tr );
void CL_PlayerTraceExt( float *start, float *end, int traceFlags, int (*pfnIgnore)( physent_t *pe ), pmtrace_t *tr );
void CL_SetTraceHull( int hull );
void CL_GetMousePosition( int *mx, int *my ); // TODO: move to input
cl_entity_t* CL_GetViewModel( void );
void pfnGetScreenFade( struct screenfade_s *fade );
physent_t *pfnGetPhysent( int idx );
struct msurface_s *pfnTraceSurface( int ground, float *vstart, float *vend );
movevars_t *pfnGetMoveVars( void );
void CL_EnableScissor( scissor_state_t *scissor, int x, int y, int width, int height );
void CL_DisableScissor( scissor_state_t *scissor );
qboolean CL_Scissor( const scissor_state_t *scissor, float *x, float *y, float *width, float *height, float *u0, float *v0, float *u1, float *v1 );
struct cl_entity_s *CL_GetEntityByIndex( int index );
_inline cl_entity_t *CL_EDICT_NUM( int n )
{
@@ -860,49 +860,17 @@ _inline cl_entity_t *CL_EDICT_NUM( int n )
//
// cl_parse.c
//
void CL_ParseSetAngle( sizebuf_t *msg );
void CL_ParseServerData( sizebuf_t *msg, qboolean legacy );
void CL_ParseLightStyle( sizebuf_t *msg );
void CL_UpdateUserinfo( sizebuf_t *msg, qboolean legacy );
void CL_ParseResource( sizebuf_t *msg );
void CL_ParseClientData( sizebuf_t *msg );
void CL_UpdateUserPings( sizebuf_t *msg );
void CL_ParseParticles( sizebuf_t *msg );
void CL_ParseRestoreSoundPacket( sizebuf_t *msg );
void CL_ParseBaseline( sizebuf_t *msg, qboolean legacy );
void CL_ParseSignon( sizebuf_t *msg );
void CL_ParseRestore( sizebuf_t *msg );
void CL_ParseStaticDecal( sizebuf_t *msg );
void CL_ParseAddAngle( sizebuf_t *msg );
void CL_RegisterUserMessage( sizebuf_t *msg );
void CL_ParseMovevars( sizebuf_t *msg );
void CL_ParseResourceRequest( sizebuf_t *msg );
void CL_ParseCustomization( sizebuf_t *msg );
void CL_ParseCrosshairAngle( sizebuf_t *msg );
void CL_ParseSoundFade( sizebuf_t *msg );
void CL_ParseFileTransferFailed( sizebuf_t *msg );
void CL_ParseHLTV( sizebuf_t *msg );
void CL_ParseDirector( sizebuf_t *msg );
void CL_ParseResLocation( sizebuf_t *msg );
void CL_ParseCvarValue( sizebuf_t *msg, const qboolean ext );
void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message );
void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message );
void CL_LegacyPrecache_f( void );
void CL_ParseTempEntity( sizebuf_t *msg );
void CL_StartResourceDownloading( const char *pszMessage, qboolean bCustom );
qboolean CL_DispatchUserMessage( const char *pszName, int iSize, void *pbuf );
qboolean CL_RequestMissingResources( void );
void CL_RegisterResources ( sizebuf_t *msg );
void CL_ParseViewEntity( sizebuf_t *msg );
void CL_ParseServerTime( sizebuf_t *msg );
void CL_ParseUserMessage( sizebuf_t *msg, int svc_num );
void CL_ParseFinaleCutscene( sizebuf_t *msg, int level );
void CL_ParseTextMessage( sizebuf_t *msg );
void CL_BatchResourceRequest( qboolean initialize );
int CL_EstimateNeededResources( void );
//
// cl_parse_48.c
//
void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message );
void CL_LegacyPrecache_f( void );
//
// cl_scrn.c
@@ -910,6 +878,8 @@ void CL_LegacyPrecache_f( void );
void SCR_VidInit( void );
void SCR_TileClear( void );
void SCR_DirtyScreen( void );
void SCR_AddDirtyPoint( int x, int y );
void SCR_InstallParticlePalette( void );
void SCR_EndLoadingPlaque( void );
void SCR_RegisterTextures( void );
void SCR_LoadCreditsFont( void );
@@ -945,17 +915,23 @@ void CL_InitClientMove( void );
void CL_PredictMovement( qboolean repredicting );
void CL_CheckPredictionError( void );
qboolean CL_IsPredicted( void );
int CL_TruePointContents( const vec3_t p );
int CL_PointContents( const vec3_t p );
int CL_WaterEntity( const float *rgflPos );
cl_entity_t *CL_GetWaterEntity( const float *rgflPos );
void CL_SetupPMove( playermove_t *pmove, local_state_t *from, usercmd_t *ucmd, qboolean runfuncs, double time );
int CL_TestLine( const vec3_t start, const vec3_t end, int flags );
pmtrace_t *CL_VisTraceLine( vec3_t start, vec3_t end, int flags );
pmtrace_t CL_TraceLine( vec3_t start, vec3_t end, int flags );
void CL_PushTraceBounds( int hullnum, const float *mins, const float *maxs );
void CL_PopTraceBounds( void );
void CL_MoveSpectatorCamera( void );
void CL_SetLastUpdate( void );
void CL_RedoPrediction( void );
void CL_ClearPhysEnts( void );
void CL_PushPMStates( void );
void CL_PopPMStates( void );
void CL_SetUpPlayerPrediction( int dopred, int bIncludeLocalClient );
void CL_SetIdealPitch( void );
//
// cl_qparse.c
@@ -972,24 +948,28 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType );
void CL_ResetLatchedVars( cl_entity_t *ent, qboolean full_reset );
qboolean CL_GetEntitySpatialization( struct channel_s *ch );
qboolean CL_GetMovieSpatialization( struct rawchan_s *ch );
void CL_ProcessPlayerState( int playerindex, entity_state_t *state );
void CL_ComputePlayerOrigin( cl_entity_t *clent );
void CL_ProcessPacket( frame_t *frame );
void CL_MoveThirdpersonCamera( void );
qboolean CL_IsPlayerIndex( int idx );
void CL_SetIdealPitch( void );
void CL_EmitEntities( void );
//
// cl_remap.c
//
remap_info_t *CL_GetRemapInfoForEntity( cl_entity_t *e );
qboolean CL_EntitySetRemapColors( cl_entity_t *e, model_t *mod, int top, int bottom );
void CL_AllocRemapInfo( cl_entity_t *entity, model_t *model, int topcolor, int bottomcolor );
void CL_FreeRemapInfo( remap_info_t *info );
void CL_UpdateRemapInfo( cl_entity_t *ent, int topcolor, int bottomcolor );
void CL_ClearAllRemaps( void );
//
// cl_render.c
//
qboolean R_InitRenderAPI( void );
intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRef );
int CL_RenderGetParm( const int parm, const int arg, const qboolean checkRef );
lightstyle_t *CL_GetLightStyle( int number );
int R_FatPVS( const vec3_t org, float radius, byte *visbuffer, qboolean merge, qboolean fullvis );
const ref_overview_t *GL_GetOverviewParms( void );
@@ -999,17 +979,19 @@ const ref_overview_t *GL_GetOverviewParms( void );
//
void R_StoreEfrags( efrag_t **ppefrag, int framecount );
void R_AddEfrags( cl_entity_t *ent );
void R_RemoveEfrags( cl_entity_t *ent );
//
// cl_tent.c
//
struct particle_s;
int CL_AddEntity( int entityType, cl_entity_t *pEnt );
void CL_WeaponAnim( int iAnim, int body );
void CL_ClearEffects( void );
void CL_ClearEfrags( void );
void CL_TestLights( void );
void CL_FireCustomDecal( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags, float scale );
void CL_DecalShoot( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags );
void CL_PlayerDecal( int playerIndex, int textureIndex, int entityIndex, float *pos );
void R_FreeDeadParticles( struct particle_s **ppparticles );
void CL_AddClientResource( const char *filename, int type );
void CL_AddClientResources( void );
@@ -1031,11 +1013,12 @@ void CL_ReadPointFile_f( void );
void CL_DrawEFX( float time, qboolean fTrans );
void CL_ThinkParticle( double frametime, particle_t *p );
void CL_ReadLineFile_f( void );
void CL_RunLightStyles( void );
//
// console.c
//
extern convar_t con_fontsize;
extern convar_t *con_fontsize;
int Con_Visible( void );
qboolean Con_FixedFont( void );
void Con_VidInit( void );
@@ -1050,23 +1033,28 @@ int Con_UtfProcessChar( int in );
int Con_UtfProcessCharForce( int in );
int Con_UtfMoveLeft( char *str, int pos );
int Con_UtfMoveRight( char *str, int pos, int length );
void Con_DefaultColor( int r, int g, int b, qboolean gameui );
cl_font_t *Con_GetCurFont( void );
cl_font_t *Con_GetFont( int num );
void Con_DrawStringLen( const char *pText, int *length, int *height );
int Con_DrawString( int x, int y, const char *string, rgba_t setColor );
int Con_DrawCharacter( int x, int y, int number, rgba_t color );
void Con_DrawCharacterLen( int number, int *width, int *height );
int Con_DrawString( int x, int y, const char *string, rgba_t setColor ); // legacy, use cl_font.c
void GAME_EXPORT Con_DrawStringLen( const char *pText, int *length, int *height ); // legacy, use cl_font.c
void Con_DefaultColor( int r, int g, int b );
void Con_InvalidateFonts( void );
void Con_SetFont( int fontNum );
void Con_CharEvent( int key );
void Con_RestoreFont( void );
void Key_Console( int key );
void Key_Message( int key );
void Con_FastClose( void );
void Con_Bottom( void );
void Con_Top( void );
void Con_PageDown( int lines );
void Con_PageUp( int lines );
void Con_LoadHistory( void );
//
// s_main.c
//
void S_StreamRawSamples( int samples, int rate, int width, int channels, const byte *data );
void S_StreamAviSamples( void *Avi, int entnum, float fvol, float attn, float synctime );
void S_StartBackgroundTrack( const char *intro, const char *loop, int position, qboolean fullpath );
void S_StopBackgroundTrack( void );
@@ -1113,6 +1101,11 @@ void UI_ConnectionProgress_Precache( void );
void UI_ConnectionProgress_Connect( const char *server );
void UI_ConnectionProgress_ChangeLevel( void );
void UI_ConnectionProgress_ParseServerInfo( const char *server );
void pfnPIC_Set( HIMAGE hPic, int r, int g, int b, int a );
void pfnPIC_Draw( int x, int y, int width, int height, const wrect_t *prc );
void pfnPIC_DrawTrans( int x, int y, int width, int height, const wrect_t *prc );
void pfnPIC_DrawHoles( int x, int y, int width, int height, const wrect_t *prc );
void pfnPIC_DrawAdditive( int x, int y, int width, int height, const wrect_t *prc );
//
// cl_mobile.c
@@ -1120,11 +1113,6 @@ void UI_ConnectionProgress_ParseServerInfo( const char *server );
qboolean Mobile_Init( void );
void Mobile_Shutdown( void );
//
// cl_securedstub.c
//
void CL_GetSecuredClientAPI( CL_EXPORT_FUNCS F );
//
// cl_video.c
//
@@ -1142,6 +1130,7 @@ void CL_PlayVideo_f( void );
// keys.c
//
int Key_IsDown( int keynum );
const char *Key_IsBind( int keynum );
void Key_Event( int key, int down );
void Key_Init( void );
void Key_WriteBindings( file_t *f );

File diff suppressed because it is too large Load Diff

View File

@@ -1,425 +0,0 @@
/*
gamma.c - gamma routines
Copyright (C) 2011 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 "xash3d_mathlib.h"
#include "enginefeatures.h"
//-----------------------------------------------------------------------------
// Gamma conversion support
//-----------------------------------------------------------------------------
static byte texgammatable[256];
static uint lightgammatable[1024];
static uint lineargammatable[1024];
static uint screengammatable[1024];
static CVAR_DEFINE( v_direct, "direct", "0.9", 0, "direct studio lighting" );
static CVAR_DEFINE( v_texgamma, "texgamma", "2.0", 0, "texgamma amount" );
static CVAR_DEFINE( v_lightgamma, "lightgamma", "2.5", 0, "lightgamma amount" );
static CVAR_DEFINE( v_brightness, "brightness", "0.0", FCVAR_ARCHIVE, "brightness factor" );
static CVAR_DEFINE( v_gamma, "gamma", "2.5", FCVAR_ARCHIVE, "gamma amount" );
static void BuildGammaTable( const float gamma, const float brightness, const float texgamma, const float lightgamma )
{
float g1, g2, g3;
int i;
if( gamma != 0.0 )
g1 = 1.0 / gamma;
else g1 = 0.4;
g2 = g1 * texgamma;
if( brightness <= 0.0 )
g3 = 0.125;
else if( brightness <= 1.0 )
g3 = 0.125 - brightness * brightness * 0.075;
else
g3 = 0.05;
for( i = 0; i < 256; i++ )
{
double d = pow( i / 255.0, (double)g2 );
int inf = d * 255.0;
texgammatable[i] = bound( 0, inf, 255 );
}
for( i = 0; i < 1024; i++ )
{
double d;
float f = pow( i / 1023.0, (double)lightgamma );
int inf;
if( brightness > 1.0 )
f *= brightness;
if( f <= g3 )
f = ( f / g3 ) * 0.125;
else
f = (( f - g3 ) / ( 1.0 - g3 )) * 0.875 + 0.125;
d = pow( (double)f, (double)g1 ); // do not remove the cast, or tests fail
inf = d * 1023.0;
lightgammatable[i] = bound( 0, inf, 1023 );
// do these calculations in the same loop...
lineargammatable[i] = pow( i / 1023.0, (double)gamma ) * 1023.0;
screengammatable[i] = pow( i / 1023.0, 1.0 / gamma ) * 1023.0;
}
}
static void V_ValidateGammaCvars( void )
{
if( v_gamma.value < 1.8f )
Cvar_DirectSet( &v_gamma, "1.8" );
else if( v_gamma.value > 3.0f )
Cvar_DirectSet( &v_gamma, "3" );
if( v_texgamma.value < 1.8f )
Cvar_DirectSet( &v_texgamma, "1.8" );
else if( v_texgamma.value > 3.0f )
Cvar_DirectSet( &v_texgamma, "3" );
if( v_lightgamma.value < 1.8f )
Cvar_DirectSet( &v_lightgamma, "1.8" );
else if( v_lightgamma.value > 3.0f )
Cvar_DirectSet( &v_lightgamma, "3" );
if( v_brightness.value < 0.0f )
Cvar_DirectSet( &v_brightness, "0" );
else if( v_brightness.value > 2.0f )
Cvar_DirectSet( &v_brightness, "2" );
}
void V_CheckGamma( void )
{
static qboolean dirty = false;
qboolean notify_refdll = false;
// because these cvars were defined as archive
// but wasn't doing anything useful
// reset them into default values
// this might be removed after a while
if( v_direct.value == 1.0f || v_lightgamma.value == 1.0f )
{
Cvar_DirectSet( &v_direct, "0.9" );
Cvar_DirectSet( &v_lightgamma, "2.5" );
}
if( cls.scrshot_action == scrshot_envshot || cls.scrshot_action == scrshot_skyshot )
{
dirty = true; // force recalculate next normal frame
BuildGammaTable( 1.8f, 0.0f, 2.0f, 2.5f );
if( ref.initialized )
ref.dllFuncs.R_GammaChanged( true );
return;
}
if( dirty || FBitSet( v_texgamma.flags|v_lightgamma.flags|v_brightness.flags|v_gamma.flags, FCVAR_CHANGED ))
{
V_ValidateGammaCvars();
dirty = false;
BuildGammaTable( v_gamma.value, v_brightness.value, v_texgamma.value, v_lightgamma.value );
// force refdll to recalculate lightmaps
notify_refdll = true;
// unfortunately, recalculating textures isn't possible yet
ClearBits( v_texgamma.flags, FCVAR_CHANGED );
ClearBits( v_lightgamma.flags, FCVAR_CHANGED );
ClearBits( v_brightness.flags, FCVAR_CHANGED );
ClearBits( v_gamma.flags, FCVAR_CHANGED );
}
if( notify_refdll && ref.initialized )
ref.dllFuncs.R_GammaChanged( false );
}
void V_Init( void )
{
Cvar_RegisterVariable( &v_texgamma );
Cvar_RegisterVariable( &v_lightgamma );
Cvar_RegisterVariable( &v_brightness );
Cvar_RegisterVariable( &v_gamma );
Cvar_RegisterVariable( &v_direct );
// force gamma init
SetBits( v_gamma.flags, FCVAR_CHANGED );
V_CheckGamma();
}
byte TextureToGamma( byte b )
{
if( FBitSet( host.features, ENGINE_LINEAR_GAMMA_SPACE ))
return b;
return texgammatable[b];
}
byte LightToTexGamma( byte b )
{
if( FBitSet( host.features, ENGINE_LINEAR_GAMMA_SPACE ))
return b;
// 255 << 2 is 1020, impossible to overflow
return lightgammatable[b << 2] >> 2;
}
uint LightToTexGammaEx( uint b )
{
if( FBitSet( host.features, ENGINE_LINEAR_GAMMA_SPACE ))
return b;
if( unlikely( b > ARRAYSIZE( lightgammatable )))
return 0;
return lightgammatable[b];
}
uint ScreenGammaTable( uint b )
{
if( FBitSet( host.features, ENGINE_LINEAR_GAMMA_SPACE ))
return b;
if( unlikely( b > ARRAYSIZE( screengammatable )))
return 0;
return screengammatable[b];
}
uint LinearGammaTable( uint b )
{
if( FBitSet( host.features, ENGINE_LINEAR_GAMMA_SPACE ))
return b;
if( unlikely( b > ARRAYSIZE( lineargammatable )))
return 0;
return lineargammatable[b];
}
#if XASH_ENGINE_TESTS
#include "tests.h"
typedef struct precomputed_gamma_tables_s
{
float gamma;
float brightness;
float texgamma;
float lightgamma;
byte texgammatable[256];
int lightgammatable[1024];
int lineargammatable[1024];
int screengammatable[1024];
} precomputed_gamma_tables_t;
// put at the end of the file, to not confuse Qt Creator's parser
precomputed_gamma_tables_t *Test_GetGammaTables( int i );
static void Test_PrecomputedGammaTables( void )
{
precomputed_gamma_tables_t *data;
int i = 0;
while(( data = Test_GetGammaTables( i )))
{
int j;
BuildGammaTable( data->gamma, data->brightness, data->texgamma, data->lightgamma );
for( j = 0; j < 1024; j++ )
{
if( j < 256 )
{
TASSERT_EQi( texgammatable[j], data->texgammatable[j] );
}
TASSERT_EQi( lightgammatable[j], data->lightgammatable[j] );
TASSERT_EQi( lineargammatable[j], data->lineargammatable[j] );
TASSERT_EQi( screengammatable[j], data->screengammatable[j] );
}
i++;
}
}
void Test_RunGamma( void )
{
TRUN( Test_PrecomputedGammaTables() );
}
precomputed_gamma_tables_t *Test_GetGammaTables( int i )
{
static precomputed_gamma_tables_t precomputed_data[] = {
{
.gamma = 2.5,
.brightness = 0.0,
.texgamma = 2.0,
.lightgamma = 2.5,
.texgammatable = {
0, 3, 5, 7, 9, 10, 12, 14, 15, 17, 19, 20, 22, 23, 25, 26, 27, 29, 30, 31, 33, 34, 35, 37, 38, 39, 41, 42, 43, 44, 46, 47, 48, 49, 50, 52, 53, 54, 55, 56, 57, 59, 60, 61, 62, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 79, 80, 81, 82, 83, 84,
85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 132, 133, 134, 135, 136, 137, 138,
139, 140, 141, 142, 143, 144, 145, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 165, 166, 167, 168, 169, 170, 171, 172, 172, 173, 174, 175, 176, 177, 178, 179, 180, 180, 181, 182, 183, 184, 185,
186, 186, 187, 188, 189, 190, 191, 192, 192, 193, 194, 195, 196, 197, 198, 198, 199, 200, 201, 202, 203, 204, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 214, 214, 215, 216, 217, 218, 219, 219, 220, 221, 222, 223, 224, 224, 225, 226, 227, 228, 229,
229, 230, 231, 232, 233, 233, 234, 235, 236, 237, 238, 238, 239, 240, 241, 242, 242, 243, 244, 245, 246, 246, 247, 248, 249, 250, 250, 251, 252, 253, 254, 255
},
.lightgammatable = {
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279,
280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331,
332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 343, 343, 344, 345, 346, 347, 348, 349, 350, 351, 353, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 376, 376, 377, 379, 379, 380, 381, 382, 383,
384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435,
436, 437, 438, 439, 440, 441, 442, 443, 444, 446, 446, 447, 449, 449, 450, 451, 452, 453, 455, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 468, 469, 470, 470, 472, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487,
488, 489, 490, 491, 493, 493, 494, 495, 496, 498, 498, 499, 500, 502, 502, 503, 504, 505, 507, 508, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 520, 521, 521, 522, 523, 524, 525, 526, 527, 528, 530, 530, 531, 532, 533, 534, 536, 536, 537, 538, 539,
540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 552, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 564, 564, 565, 566, 567, 568, 570, 571, 571, 572, 573, 574, 576, 576, 577, 578, 579, 580, 581, 583, 583, 584, 585, 586, 587, 588, 590, 591, 591,
593, 593, 594, 596, 596, 597, 598, 600, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 611, 611, 612, 613, 615, 615, 616, 618, 618, 620, 621, 621, 622, 624, 625, 626, 627, 627, 628, 629, 630, 632, 633, 633, 634, 635, 636, 638, 638, 639, 641, 642, 643, 643,
644, 645, 646, 648, 648, 650, 651, 651, 652, 654, 655, 656, 656, 658, 658, 660, 660, 662, 662, 664, 664, 665, 666, 668, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 682, 682, 683, 684, 685, 686, 687, 688, 690, 690, 691, 692, 693, 695, 696,
696, 697, 698, 699, 700, 701, 702, 703, 705, 706, 706, 707, 708, 709, 710, 711, 712, 713, 715, 716, 716, 717, 718, 719, 721, 721, 722, 724, 724, 725, 727, 727, 728, 729, 730, 731, 733, 733, 734, 735, 736, 737, 738, 740, 740, 741, 743, 744, 744, 745, 747, 747,
748, 749, 750, 752, 753, 753, 755, 755, 757, 757, 758, 759, 760, 761, 762, 764, 764, 766, 766, 767, 769, 770, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 782, 783, 784, 784, 785, 786, 788, 789, 790, 791, 792, 792, 794, 794, 796, 796, 797, 799, 800,
801, 801, 802, 803, 804, 805, 806, 807, 809, 810, 810, 811, 813, 813, 815, 815, 816, 817, 819, 819, 820, 822, 823, 823, 824, 825, 826, 827, 829, 829, 830, 832, 832, 833, 835, 835, 837, 837, 839, 840, 840, 841, 842, 843, 844, 845, 847, 847, 849, 849, 850, 851,
852, 854, 854, 856, 856, 857, 859, 859, 860, 861, 862, 864, 864, 865, 867, 867, 868, 870, 870, 872, 872, 874, 875, 875, 876, 877, 879, 880, 881, 881, 882, 883, 885, 885, 886, 887, 888, 890, 891, 891, 893, 893, 894, 895, 897, 898, 899, 900, 901, 902, 902, 903,
904, 905, 907, 907, 908, 910, 910, 911, 912, 914, 914, 915, 917, 918, 919, 920, 921, 922, 922, 923, 925, 925, 926, 927, 928, 930, 931, 932, 932, 933, 935, 936, 936, 937, 939, 940, 940, 942, 942, 944, 944, 946, 947, 948, 949, 949, 950, 952, 952, 953, 955, 956,
957, 958, 959, 959, 960, 962, 962, 964, 965, 965, 967, 967, 969, 970, 971, 972, 973, 973, 975, 975, 976, 977, 978, 979, 980, 982, 982, 984, 984, 986, 986, 988, 988, 990, 991, 992, 993, 993, 994, 995, 996, 998, 999, 999, 1000, 1002, 1002, 1004, 1005, 1005,
1006, 1007, 1008, 1010, 1011, 1011, 1013, 1014, 1015, 1016, 1017, 1018, 1018, 1019, 1020, 1021, 1023
},
.lineargammatable = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11,
11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 25, 25,
25, 25, 26, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 46, 46, 46,
47, 47, 48, 48, 48, 49, 49, 50, 50, 50, 51, 51, 52, 52, 52, 53, 53, 54, 54, 55, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 60, 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 75, 75, 76, 76,
77, 77, 78, 78, 79, 79, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 86, 86, 87, 87, 88, 88, 89, 90, 90, 91, 91, 92, 92, 93, 94, 94, 95, 95, 96, 97, 97, 98, 99, 99, 100, 100, 101, 102, 102, 103, 104, 104, 105, 105, 106, 107, 107, 108, 109, 109, 110, 111, 111, 112,
113, 113, 114, 115, 115, 116, 117, 117, 118, 119, 119, 120, 121, 122, 122, 123, 124, 124, 125, 126, 126, 127, 128, 129, 129, 130, 131, 132, 132, 133, 134, 134, 135, 136, 137, 137, 138, 139, 140, 140, 141, 142, 143, 144, 144, 145, 146, 147, 147, 148, 149, 150,
151, 151, 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 164, 164, 165, 166, 167, 168, 169, 169, 170, 171, 172, 173, 174, 175, 176, 176, 177, 178, 179, 180, 181, 182, 183, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 193, 194,
195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
247, 248, 249, 250, 251, 252, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 265, 266, 267, 268, 269, 270, 271, 272, 274, 275, 276, 277, 278, 279, 280, 282, 283, 284, 285, 286, 287, 289, 290, 291, 292, 293, 294, 296, 297, 298, 299, 300, 302, 303, 304, 305,
306, 308, 309, 310, 311, 312, 314, 315, 316, 317, 319, 320, 321, 322, 324, 325, 326, 327, 329, 330, 331, 333, 334, 335, 336, 338, 339, 340, 342, 343, 344, 345, 347, 348, 349, 351, 352, 353, 355, 356, 357, 359, 360, 361, 363, 364, 365, 367, 368, 369, 371, 372,
373, 375, 376, 378, 379, 380, 382, 383, 384, 386, 387, 389, 390, 391, 393, 394, 396, 397, 399, 400, 401, 403, 404, 406, 407, 409, 410, 411, 413, 414, 416, 417, 419, 420, 422, 423, 425, 426, 428, 429, 431, 432, 434, 435, 437, 438, 440, 441, 443, 444, 446, 447,
449, 450, 452, 453, 455, 456, 458, 459, 461, 462, 464, 466, 467, 469, 470, 472, 473, 475, 477, 478, 480, 481, 483, 485, 486, 488, 489, 491, 493, 494, 496, 497, 499, 501, 502, 504, 506, 507, 509, 511, 512, 514, 515, 517, 519, 520, 522, 524, 525, 527, 529, 531,
532, 534, 536, 537, 539, 541, 542, 544, 546, 548, 549, 551, 553, 554, 556, 558, 560, 561, 563, 565, 567, 568, 570, 572, 574, 575, 577, 579, 581, 583, 584, 586, 588, 590, 592, 593, 595, 597, 599, 601, 602, 604, 606, 608, 610, 612, 613, 615, 617, 619, 621, 623,
625, 626, 628, 630, 632, 634, 636, 638, 639, 641, 643, 645, 647, 649, 651, 653, 655, 657, 659, 660, 662, 664, 666, 668, 670, 672, 674, 676, 678, 680, 682, 684, 686, 688, 690, 692, 694, 696, 698, 700, 702, 704, 706, 708, 710, 712, 714, 716, 718, 720, 722, 724,
726, 728, 730, 732, 734, 736, 738, 740, 742, 744, 746, 748, 750, 753, 755, 757, 759, 761, 763, 765, 767, 769, 771, 773, 776, 778, 780, 782, 784, 786, 788, 791, 793, 795, 797, 799, 801, 803, 806, 808, 810, 812, 814, 816, 819, 821, 823, 825, 827, 830, 832, 834,
836, 839, 841, 843, 845, 847, 850, 852, 854, 856, 859, 861, 863, 865, 868, 870, 872, 874, 877, 879, 881, 884, 886, 888, 890, 893, 895, 897, 900, 902, 904, 907, 909, 911, 914, 916, 918, 921, 923, 925, 928, 930, 932, 935, 937, 940, 942, 944, 947, 949, 952, 954,
956, 959, 961, 964, 966, 968, 971, 973, 976, 978, 981, 983, 985, 988, 990, 993, 995, 998, 1000, 1003, 1005, 1008, 1010, 1013, 1015, 1018, 1020, 1023
},
.screengammatable = {
0, 63, 84, 99, 111, 121, 130, 139, 146, 154, 160, 166, 172, 178, 183, 188, 193, 198, 203, 207, 212, 216, 220, 224, 228, 231, 235, 239, 242, 245, 249, 252, 255, 259, 262, 265, 268, 271, 274, 276, 279, 282, 285, 287, 290, 293, 295, 298, 300, 303, 305, 308,
310, 313, 315, 317, 320, 322, 324, 326, 328, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351, 353, 355, 357, 359, 361, 363, 365, 367, 369, 370, 372, 374, 376, 378, 379, 381, 383, 385, 386, 388, 390, 392, 393, 395, 397, 398, 400, 401, 403, 405, 406, 408,
409, 411, 413, 414, 416, 417, 419, 420, 422, 423, 425, 426, 428, 429, 431, 432, 434, 435, 436, 438, 439, 441, 442, 444, 445, 446, 448, 449, 450, 452, 453, 455, 456, 457, 459, 460, 461, 463, 464, 465, 466, 468, 469, 470, 472, 473, 474, 475, 477, 478, 479, 480,
482, 483, 484, 485, 487, 488, 489, 490, 491, 493, 494, 495, 496, 497, 499, 500, 501, 502, 503, 504, 505, 507, 508, 509, 510, 511, 512, 513, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539,
540, 541, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 585, 586, 587, 588, 589, 590,
591, 592, 593, 594, 595, 595, 596, 597, 598, 599, 600, 601, 602, 603, 603, 604, 605, 606, 607, 608, 609, 610, 610, 611, 612, 613, 614, 615, 616, 616, 617, 618, 619, 620, 621, 622, 622, 623, 624, 625, 626, 627, 627, 628, 629, 630, 631, 632, 632, 633, 634, 635,
636, 637, 637, 638, 639, 640, 641, 641, 642, 643, 644, 645, 645, 646, 647, 648, 649, 649, 650, 651, 652, 652, 653, 654, 655, 656, 656, 657, 658, 659, 659, 660, 661, 662, 663, 663, 664, 665, 666, 666, 667, 668, 669, 669, 670, 671, 672, 672, 673, 674, 675, 675,
676, 677, 678, 678, 679, 680, 681, 681, 682, 683, 684, 684, 685, 686, 686, 687, 688, 689, 689, 690, 691, 692, 692, 693, 694, 694, 695, 696, 697, 697, 698, 699, 699, 700, 701, 701, 702, 703, 704, 704, 705, 706, 706, 707, 708, 708, 709, 710, 711, 711, 712, 713,
713, 714, 715, 715, 716, 717, 717, 718, 719, 719, 720, 721, 721, 722, 723, 723, 724, 725, 725, 726, 727, 727, 728, 729, 729, 730, 731, 731, 732, 733, 733, 734, 735, 735, 736, 737, 737, 738, 739, 739, 740, 741, 741, 742, 743, 743, 744, 745, 745, 746, 746, 747,
748, 748, 749, 750, 750, 751, 752, 752, 753, 753, 754, 755, 755, 756, 757, 757, 758, 758, 759, 760, 760, 761, 762, 762, 763, 763, 764, 765, 765, 766, 767, 767, 768, 768, 769, 770, 770, 771, 771, 772, 773, 773, 774, 774, 775, 776, 776, 777, 778, 778, 779, 779,
780, 781, 781, 782, 782, 783, 784, 784, 785, 785, 786, 786, 787, 788, 788, 789, 789, 790, 791, 791, 792, 792, 793, 794, 794, 795, 795, 796, 796, 797, 798, 798, 799, 799, 800, 801, 801, 802, 802, 803, 803, 804, 805, 805, 806, 806, 807, 807, 808, 809, 809, 810,
810, 811, 811, 812, 813, 813, 814, 814, 815, 815, 816, 816, 817, 818, 818, 819, 819, 820, 820, 821, 821, 822, 823, 823, 824, 824, 825, 825, 826, 826, 827, 828, 828, 829, 829, 830, 830, 831, 831, 832, 832, 833, 834, 834, 835, 835, 836, 836, 837, 837, 838, 838,
839, 839, 840, 841, 841, 842, 842, 843, 843, 844, 844, 845, 845, 846, 846, 847, 848, 848, 849, 849, 850, 850, 851, 851, 852, 852, 853, 853, 854, 854, 855, 855, 856, 856, 857, 857, 858, 859, 859, 860, 860, 861, 861, 862, 862, 863, 863, 864, 864, 865, 865, 866,
866, 867, 867, 868, 868, 869, 869, 870, 870, 871, 871, 872, 872, 873, 873, 874, 874, 875, 875, 876, 876, 877, 877, 878, 878, 879, 879, 880, 880, 881, 881, 882, 882, 883, 883, 884, 884, 885, 885, 886, 886, 887, 887, 888, 888, 889, 889, 890, 890, 891, 891, 892,
892, 893, 893, 894, 894, 895, 895, 896, 896, 897, 897, 898, 898, 899, 899, 900, 900, 901, 901, 902, 902, 903, 903, 904, 904, 904, 905, 905, 906, 906, 907, 907, 908, 908, 909, 909, 910, 910, 911, 911, 912, 912, 913, 913, 914, 914, 915, 915, 915, 916, 916, 917,
917, 918, 918, 919, 919, 920, 920, 921, 921, 922, 922, 922, 923, 923, 924, 924, 925, 925, 926, 926, 927, 927, 928, 928, 929, 929, 929, 930, 930, 931, 931, 932, 932, 933, 933, 934, 934, 935, 935, 935, 936, 936, 937, 937, 938, 938, 939, 939, 940, 940, 940, 941,
941, 942, 942, 943, 943, 944, 944, 944, 945, 945, 946, 946, 947, 947, 948, 948, 949, 949, 949, 950, 950, 951, 951, 952, 952, 953, 953, 953, 954, 954, 955, 955, 956, 956, 957, 957, 957, 958, 958, 959, 959, 960, 960, 961, 961, 961, 962, 962, 963, 963, 964, 964,
964, 965, 965, 966, 966, 967, 967, 968, 968, 968, 969, 969, 970, 970, 971, 971, 971, 972, 972, 973, 973, 974, 974, 974, 975, 975, 976, 976, 977, 977, 977, 978, 978, 979, 979, 980, 980, 980, 981, 981, 982, 982, 983, 983, 983, 984, 984, 985, 985, 986, 986, 986,
987, 987, 988, 988, 988, 989, 989, 990, 990, 991, 991, 991, 992, 992, 993, 993, 993, 994, 994, 995, 995, 996, 996, 996, 997, 997, 998, 998, 998, 999, 999, 1000, 1000, 1001, 1001, 1001, 1002, 1002, 1003, 1003, 1003, 1004, 1004, 1005, 1005, 1005, 1006, 1006,
1007, 1007, 1008, 1008, 1008, 1009, 1009, 1010, 1010, 1010, 1011, 1011, 1012, 1012, 1012, 1013, 1013, 1014, 1014, 1014, 1015, 1015, 1016, 1016, 1016, 1017, 1017, 1018, 1018, 1018, 1019, 1019, 1020, 1020, 1020, 1021, 1021, 1022, 1022, 1023
},
}, {
.gamma = 2.2,
.brightness = 1.0,
.texgamma = 2.2,
.lightgamma = 2.4,
.texgammatable = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227,
228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
},
.lightgammatable = {
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 39, 40, 41, 42, 43, 45, 46, 47, 48, 50, 51, 52, 53, 55, 56, 57, 58, 60, 61, 62, 63, 65, 66, 67, 69, 70, 71, 72, 74, 75, 76,
78, 79, 80, 81, 83, 84, 85, 87, 88, 89, 91, 92, 93, 94, 96, 97, 98, 100, 101, 102, 104, 105, 106, 108, 109, 110, 112, 113, 114, 116, 117, 118, 120, 121, 122, 124, 125, 126, 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 147, 148, 149,
151, 152, 153, 155, 156, 157, 159, 160, 162, 163, 164, 166, 167, 168, 170, 171, 173, 174, 175, 177, 178, 179, 181, 182, 184, 185, 186, 188, 189, 191, 192, 193, 195, 196, 198, 199, 200, 202, 203, 204, 206, 207, 209, 210, 211, 213, 214, 216, 217, 219, 220, 221,
223, 224, 226, 227, 228, 230, 231, 233, 234, 235, 237, 238, 240, 241, 243, 244, 245, 247, 248, 250, 251, 252, 254, 255, 257, 258, 260, 261, 262, 264, 265, 267, 268, 270, 271, 272, 274, 275, 277, 278, 280, 281, 282, 284, 285, 287, 288, 290, 291, 293, 294, 295,
297, 298, 300, 301, 303, 304, 306, 307, 308, 310, 311, 313, 314, 316, 317, 319, 320, 321, 323, 324, 326, 327, 329, 330, 332, 333, 335, 336, 337, 339, 340, 342, 343, 345, 346, 348, 349, 351, 352, 354, 355, 356, 358, 359, 361, 362, 364, 365, 367, 368, 370, 371,
373, 374, 376, 377, 378, 380, 381, 383, 384, 386, 387, 389, 390, 392, 393, 395, 396, 397, 398, 398, 399, 399, 400, 401, 401, 402, 402, 403, 403, 404, 404, 405, 406, 406, 407, 407, 408, 408, 409, 410, 410, 411, 411, 412, 413, 413, 414, 414, 415, 416, 416, 417,
417, 418, 419, 419, 420, 420, 421, 422, 422, 423, 423, 424, 425, 425, 426, 427, 427, 428, 428, 429, 430, 430, 431, 432, 432, 433, 433, 434, 435, 435, 436, 437, 437, 438, 439, 439, 440, 441, 441, 442, 443, 443, 444, 445, 445, 446, 447, 447, 448, 449, 449, 450,
451, 451, 452, 453, 453, 454, 455, 455, 456, 457, 457, 458, 459, 459, 460, 461, 461, 462, 463, 464, 464, 465, 466, 466, 467, 468, 468, 469, 470, 471, 471, 472, 473, 473, 474, 475, 476, 476, 477, 478, 478, 479, 480, 481, 481, 482, 483, 483, 484, 485, 486, 486,
487, 488, 489, 489, 490, 491, 492, 492, 493, 494, 495, 495, 496, 497, 498, 498, 499, 500, 501, 501, 502, 503, 504, 504, 505, 506, 507, 507, 508, 509, 510, 510, 511, 512, 513, 513, 514, 515, 516, 517, 517, 518, 519, 520, 520, 521, 522, 523, 524, 524, 525, 526,
527, 527, 528, 529, 530, 531, 531, 532, 533, 534, 535, 535, 536, 537, 538, 538, 539, 540, 541, 542, 542, 543, 544, 545, 546, 546, 547, 548, 549, 550, 550, 551, 552, 553, 554, 555, 555, 556, 557, 558, 559, 559, 560, 561, 562, 563, 564, 564, 565, 566, 567, 568,
568, 569, 570, 571, 572, 573, 573, 574, 575, 576, 577, 578, 578, 579, 580, 581, 582, 583, 583, 584, 585, 586, 587, 588, 588, 589, 590, 591, 592, 593, 593, 594, 595, 596, 597, 598, 599, 599, 600, 601, 602, 603, 604, 605, 605, 606, 607, 608, 609, 610, 611, 611,
612, 613, 614, 615, 616, 617, 617, 618, 619, 620, 621, 622, 623, 623, 624, 625, 626, 627, 628, 629, 629, 630, 631, 632, 633, 634, 635, 636, 636, 637, 638, 639, 640, 641, 642, 643, 643, 644, 645, 646, 647, 648, 649, 650, 651, 651, 652, 653, 654, 655, 656, 657,
658, 658, 659, 660, 661, 662, 663, 664, 665, 666, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 703,
704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 749, 750, 751,
752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 795, 796, 797, 798, 799, 800,
801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850,
851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 900,
901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952,
953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002,
1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1023
},
.lineargammatable = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4,
4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17,
17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, 35, 36,
36, 36, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 42, 42, 42, 43, 43, 44, 44, 44, 45, 45, 46, 46, 46, 47, 47, 48, 48, 48, 49, 49, 50, 50, 51, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 61, 62, 62, 63,
63, 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80, 81, 82, 82, 83, 83, 84, 84, 85, 86, 86, 87, 87, 88, 88, 89, 90, 90, 91, 91, 92, 93, 93, 94, 94, 95, 96, 96, 97, 97, 98, 99,
99, 100, 100, 101, 102, 102, 103, 104, 104, 105, 105, 106, 107, 107, 108, 109, 109, 110, 111, 111, 112, 113, 113, 114, 115, 115, 116, 117, 117, 118, 119, 119, 120, 121, 121, 122, 123, 123, 124, 125, 126, 126, 127, 128, 128, 129, 130, 131, 131, 132, 133, 133,
134, 135, 136, 136, 137, 138, 139, 139, 140, 141, 142, 142, 143, 144, 145, 145, 146, 147, 148, 148, 149, 150, 151, 151, 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167, 168, 169, 170, 171, 172, 172, 173, 174,
175, 176, 177, 177, 178, 179, 180, 181, 182, 183, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 193, 194, 195, 196, 197, 198, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
222, 223, 224, 225, 226, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273,
274, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 288, 289, 290, 291, 292, 293, 294, 295, 296, 298, 299, 300, 301, 302, 303, 304, 305, 307, 308, 309, 310, 311, 312, 313, 315, 316, 317, 318, 319, 320, 322, 323, 324, 325, 326, 328, 329, 330, 331, 332,
333, 335, 336, 337, 338, 339, 341, 342, 343, 344, 346, 347, 348, 349, 350, 352, 353, 354, 355, 357, 358, 359, 360, 362, 363, 364, 365, 367, 368, 369, 370, 372, 373, 374, 375, 377, 378, 379, 381, 382, 383, 384, 386, 387, 388, 390, 391, 392, 393, 395, 396, 397,
399, 400, 401, 403, 404, 405, 407, 408, 409, 411, 412, 413, 415, 416, 417, 419, 420, 421, 423, 424, 426, 427, 428, 430, 431, 432, 434, 435, 437, 438, 439, 441, 442, 443, 445, 446, 448, 449, 450, 452, 453, 455, 456, 458, 459, 460, 462, 463, 465, 466, 468, 469,
470, 472, 473, 475, 476, 478, 479, 481, 482, 483, 485, 486, 488, 489, 491, 492, 494, 495, 497, 498, 500, 501, 503, 504, 506, 507, 509, 510, 512, 513, 515, 516, 518, 519, 521, 522, 524, 525, 527, 528, 530, 532, 533, 535, 536, 538, 539, 541, 542, 544, 545, 547,
549, 550, 552, 553, 555, 556, 558, 560, 561, 563, 564, 566, 568, 569, 571, 572, 574, 576, 577, 579, 580, 582, 584, 585, 587, 589, 590, 592, 593, 595, 597, 598, 600, 602, 603, 605, 607, 608, 610, 612, 613, 615, 617, 618, 620, 622, 623, 625, 627, 628, 630, 632,
633, 635, 637, 639, 640, 642, 644, 645, 647, 649, 650, 652, 654, 656, 657, 659, 661, 663, 664, 666, 668, 670, 671, 673, 675, 677, 678, 680, 682, 684, 685, 687, 689, 691, 692, 694, 696, 698, 700, 701, 703, 705, 707, 709, 710, 712, 714, 716, 718, 719, 721, 723,
725, 727, 729, 730, 732, 734, 736, 738, 740, 741, 743, 745, 747, 749, 751, 753, 754, 756, 758, 760, 762, 764, 766, 767, 769, 771, 773, 775, 777, 779, 781, 783, 785, 786, 788, 790, 792, 794, 796, 798, 800, 802, 804, 806, 808, 809, 811, 813, 815, 817, 819, 821,
823, 825, 827, 829, 831, 833, 835, 837, 839, 841, 843, 845, 847, 849, 851, 853, 855, 857, 859, 861, 863, 865, 867, 869, 871, 873, 875, 877, 879, 881, 883, 885, 887, 889, 891, 893, 895, 897, 899, 901, 903, 905, 907, 910, 912, 914, 916, 918, 920, 922, 924, 926,
928, 930, 932, 934, 937, 939, 941, 943, 945, 947, 949, 951, 953, 956, 958, 960, 962, 964, 966, 968, 970, 973, 975, 977, 979, 981, 983, 985, 988, 990, 992, 994, 996, 998, 1001, 1003, 1005, 1007, 1009, 1012, 1014, 1016, 1018, 1020, 1023
},
.screengammatable = {
0, 43, 60, 72, 82, 91, 98, 106, 112, 118, 124, 130, 135, 140, 145, 150, 154, 158, 163, 167, 171, 174, 178, 182, 185, 189, 192, 196, 199, 202, 205, 208, 211, 214, 217, 220, 223, 226, 228, 231, 234, 237, 239, 242, 244, 247, 249, 252, 254, 257, 259, 261,
264, 266, 268, 270, 273, 275, 277, 279, 281, 283, 286, 288, 290, 292, 294, 296, 298, 300, 302, 304, 306, 308, 310, 311, 313, 315, 317, 319, 321, 323, 324, 326, 328, 330, 331, 333, 335, 337, 338, 340, 342, 343, 345, 347, 348, 350, 352, 353, 355, 357, 358, 360,
361, 363, 365, 366, 368, 369, 371, 372, 374, 375, 377, 378, 380, 381, 383, 384, 386, 387, 389, 390, 392, 393, 394, 396, 397, 399, 400, 401, 403, 404, 406, 407, 408, 410, 411, 412, 414, 415, 416, 418, 419, 420, 422, 423, 424, 426, 427, 428, 430, 431, 432, 433,
435, 436, 437, 438, 440, 441, 442, 443, 445, 446, 447, 448, 450, 451, 452, 453, 454, 456, 457, 458, 459, 460, 462, 463, 464, 465, 466, 467, 469, 470, 471, 472, 473, 474, 475, 477, 478, 479, 480, 481, 482, 483, 484, 486, 487, 488, 489, 490, 491, 492, 493, 494,
495, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 545, 546, 547,
548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 583, 584, 585, 586, 587, 588, 589, 590, 591, 591, 592, 593, 594, 595,
596, 597, 598, 598, 599, 600, 601, 602, 603, 604, 604, 605, 606, 607, 608, 609, 609, 610, 611, 612, 613, 614, 615, 615, 616, 617, 618, 619, 620, 620, 621, 622, 623, 624, 624, 625, 626, 627, 628, 629, 629, 630, 631, 632, 633, 633, 634, 635, 636, 637, 637, 638,
639, 640, 641, 641, 642, 643, 644, 645, 645, 646, 647, 648, 649, 649, 650, 651, 652, 652, 653, 654, 655, 656, 656, 657, 658, 659, 659, 660, 661, 662, 663, 663, 664, 665, 666, 666, 667, 668, 669, 669, 670, 671, 672, 672, 673, 674, 675, 675, 676, 677, 678, 678,
679, 680, 681, 681, 682, 683, 684, 684, 685, 686, 686, 687, 688, 689, 689, 690, 691, 692, 692, 693, 694, 694, 695, 696, 697, 697, 698, 699, 700, 700, 701, 702, 702, 703, 704, 705, 705, 706, 707, 707, 708, 709, 709, 710, 711, 712, 712, 713, 714, 714, 715, 716,
716, 717, 718, 719, 719, 720, 721, 721, 722, 723, 723, 724, 725, 725, 726, 727, 728, 728, 729, 730, 730, 731, 732, 732, 733, 734, 734, 735, 736, 736, 737, 738, 738, 739, 740, 740, 741, 742, 742, 743, 744, 744, 745, 746, 746, 747, 748, 748, 749, 750, 750, 751,
752, 752, 753, 754, 754, 755, 756, 756, 757, 758, 758, 759, 759, 760, 761, 761, 762, 763, 763, 764, 765, 765, 766, 767, 767, 768, 769, 769, 770, 770, 771, 772, 772, 773, 774, 774, 775, 776, 776, 777, 777, 778, 779, 779, 780, 781, 781, 782, 782, 783, 784, 784,
785, 786, 786, 787, 787, 788, 789, 789, 790, 791, 791, 792, 792, 793, 794, 794, 795, 795, 796, 797, 797, 798, 799, 799, 800, 800, 801, 802, 802, 803, 803, 804, 805, 805, 806, 806, 807, 808, 808, 809, 809, 810, 811, 811, 812, 812, 813, 814, 814, 815, 815, 816,
817, 817, 818, 818, 819, 820, 820, 821, 821, 822, 823, 823, 824, 824, 825, 825, 826, 827, 827, 828, 828, 829, 830, 830, 831, 831, 832, 833, 833, 834, 834, 835, 835, 836, 837, 837, 838, 838, 839, 839, 840, 841, 841, 842, 842, 843, 843, 844, 845, 845, 846, 846,
847, 847, 848, 849, 849, 850, 850, 851, 851, 852, 853, 853, 854, 854, 855, 855, 856, 857, 857, 858, 858, 859, 859, 860, 860, 861, 862, 862, 863, 863, 864, 864, 865, 865, 866, 867, 867, 868, 868, 869, 869, 870, 870, 871, 872, 872, 873, 873, 874, 874, 875, 875,
876, 876, 877, 878, 878, 879, 879, 880, 880, 881, 881, 882, 882, 883, 884, 884, 885, 885, 886, 886, 887, 887, 888, 888, 889, 889, 890, 891, 891, 892, 892, 893, 893, 894, 894, 895, 895, 896, 896, 897, 898, 898, 899, 899, 900, 900, 901, 901, 902, 902, 903, 903,
904, 904, 905, 905, 906, 906, 907, 908, 908, 909, 909, 910, 910, 911, 911, 912, 912, 913, 913, 914, 914, 915, 915, 916, 916, 917, 917, 918, 918, 919, 920, 920, 921, 921, 922, 922, 923, 923, 924, 924, 925, 925, 926, 926, 927, 927, 928, 928, 929, 929, 930, 930,
931, 931, 932, 932, 933, 933, 934, 934, 935, 935, 936, 936, 937, 937, 938, 938, 939, 939, 940, 940, 941, 941, 942, 942, 943, 943, 944, 944, 945, 945, 946, 946, 947, 947, 948, 948, 949, 949, 950, 950, 951, 951, 952, 952, 953, 953, 954, 954, 955, 955, 956, 956,
957, 957, 958, 958, 959, 959, 960, 960, 961, 961, 962, 962, 963, 963, 964, 964, 965, 965, 966, 966, 967, 967, 968, 968, 969, 969, 969, 970, 970, 971, 971, 972, 972, 973, 973, 974, 974, 975, 975, 976, 976, 977, 977, 978, 978, 979, 979, 980, 980, 981, 981, 982,
982, 982, 983, 983, 984, 984, 985, 985, 986, 986, 987, 987, 988, 988, 989, 989, 990, 990, 991, 991, 991, 992, 992, 993, 993, 994, 994, 995, 995, 996, 996, 997, 997, 998, 998, 999, 999, 999, 1000, 1000, 1001, 1001, 1002, 1002, 1003, 1003, 1004, 1004, 1005,
1005, 1006, 1006, 1006, 1007, 1007, 1008, 1008, 1009, 1009, 1010, 1010, 1011, 1011, 1012, 1012, 1012, 1013, 1013, 1014, 1014, 1015, 1015, 1016, 1016, 1017, 1017, 1017, 1018, 1018, 1019, 1019, 1020, 1020, 1021, 1021, 1022, 1022, 1023
},
}
};
if( i < 0 || i >= ARRAYSIZE( precomputed_data ))
return NULL;
return &precomputed_data[i];
}
#endif

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,7 @@ GNU General Public License for more details.
#include "client.h"
#include "vgui_draw.h"
#if XASH_SDL
#ifdef XASH_SDL
#include <SDL.h>
#endif
@@ -30,21 +30,23 @@ qboolean in_mouseinitialized;
qboolean in_mouse_suspended;
POINT in_lastvalidpos;
qboolean in_mouse_savedpos;
static int in_mstate = 0;
static struct inputstate_s
{
float lastpitch, lastyaw;
} inputstate;
CVAR_DEFINE_AUTO( m_pitch, "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse pitch value" );
CVAR_DEFINE_AUTO( m_yaw, "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse yaw value" );
CVAR_DEFINE_AUTO( m_ignore, DEFAULT_M_IGNORE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "ignore mouse events" );
static CVAR_DEFINE_AUTO( look_filter, "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "filter look events making it smoother" );
static CVAR_DEFINE_AUTO( m_rawinput, "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable mouse raw input" );
extern convar_t *vid_fullscreen;
convar_t *m_enginemouse;
convar_t *m_pitch;
convar_t *m_yaw;
static CVAR_DEFINE_AUTO( cl_forwardspeed, "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default forward move speed" );
static CVAR_DEFINE_AUTO( cl_backspeed, "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default back move speed" );
static CVAR_DEFINE_AUTO( cl_sidespeed, "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default side move speed" );
convar_t *m_enginesens;
convar_t *m_ignore;
convar_t *cl_forwardspeed;
convar_t *cl_sidespeed;
convar_t *cl_backspeed;
convar_t *look_filter;
convar_t *m_rawinput;
/*
================
@@ -57,10 +59,10 @@ uint IN_CollectInputDevices( void )
{
uint ret = 0;
if( !m_ignore.value ) // no way to check is mouse connected, so use cvar only
if( !m_ignore->value ) // no way to check is mouse connected, so use cvar only
ret |= INPUT_DEVICE_MOUSE;
if( touch_enable.value )
if( CVAR_TO_BOOL(touch_enable) )
ret |= INPUT_DEVICE_TOUCH;
if( Joy_IsActive() ) // connected or enabled
@@ -85,19 +87,19 @@ player is connected to the server
*/
void IN_LockInputDevices( qboolean lock )
{
extern convar_t joy_enable; // private to input system
extern convar_t *joy_enable; // private to input system
if( lock )
{
SetBits( m_ignore.flags, FCVAR_READ_ONLY );
SetBits( joy_enable.flags, FCVAR_READ_ONLY );
SetBits( touch_enable.flags, FCVAR_READ_ONLY );
SetBits( m_ignore->flags, FCVAR_READ_ONLY );
SetBits( joy_enable->flags, FCVAR_READ_ONLY );
SetBits( touch_enable->flags, FCVAR_READ_ONLY );
}
else
{
ClearBits( m_ignore.flags, FCVAR_READ_ONLY );
ClearBits( joy_enable.flags, FCVAR_READ_ONLY );
ClearBits( touch_enable.flags, FCVAR_READ_ONLY );
ClearBits( m_ignore->flags, FCVAR_READ_ONLY );
ClearBits( joy_enable->flags, FCVAR_READ_ONLY );
ClearBits( touch_enable->flags, FCVAR_READ_ONLY );
}
}
@@ -107,14 +109,16 @@ void IN_LockInputDevices( qboolean lock )
IN_StartupMouse
===========
*/
static void IN_StartupMouse( void )
void IN_StartupMouse( void )
{
Cvar_RegisterVariable( &m_ignore );
m_ignore = Cvar_Get( "m_ignore", DEFAULT_M_IGNORE, FCVAR_ARCHIVE , "ignore mouse events" );
Cvar_RegisterVariable( &m_pitch );
Cvar_RegisterVariable( &m_yaw );
Cvar_RegisterVariable( &look_filter );
Cvar_RegisterVariable( &m_rawinput );
m_enginemouse = Cvar_Get( "m_enginemouse", "0", FCVAR_ARCHIVE, "read mouse events in engine instead of client" );
m_enginesens = Cvar_Get( "m_enginesens", "0.3", FCVAR_ARCHIVE, "mouse sensitivity, when m_enginemouse enabled" );
m_pitch = Cvar_Get( "m_pitch", "0.022", FCVAR_ARCHIVE, "mouse pitch value" );
m_yaw = Cvar_Get( "m_yaw", "0.022", FCVAR_ARCHIVE, "mouse yaw value" );
look_filter = Cvar_Get( "look_filter", "0", FCVAR_ARCHIVE, "filter look events making it smoother" );
m_rawinput = Cvar_Get( "m_rawinput", "1", FCVAR_ARCHIVE, "enable mouse raw input" );
// You can use -nomouse argument to prevent using mouse from client
// -noenginemouse will disable all mouse input
@@ -123,9 +127,21 @@ static void IN_StartupMouse( void )
in_mouseinitialized = true;
}
static void IN_ActivateCursor( void )
{
if( cls.key_dest == key_menu )
{
#ifdef XASH_SDL
SDL_SetCursor( in_mousecursor );
#endif
}
}
void GAME_EXPORT IN_SetCursor( void *hCursor )
{
// stub
in_mousecursor = hCursor;
IN_ActivateCursor();
}
/*
@@ -170,104 +186,67 @@ Called when key_dest is changed
*/
void IN_ToggleClientMouse( int newstate, int oldstate )
{
if( newstate == oldstate )
return;
if( newstate == oldstate ) return;
// since SetCursorType controls cursor visibility
// execute it first, and then check mouse grab state
if( newstate == key_menu || newstate == key_console )
if( oldstate == key_game )
{
Platform_SetCursorType( dc_arrow );
if( cls.initialized )
clgame.dllFuncs.IN_DeactivateMouse();
}
else if( newstate == key_game )
{
// reset mouse pos, so cancel effect in game
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
if( CVAR_TO_BOOL( touch_enable ) )
{
SDL_SetRelativeMouseMode( SDL_FALSE );
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
}
else
#endif
{
Platform_SetMousePos( host.window_center_x, host.window_center_y );
#if XASH_SDL
SDL_SetWindowGrab( host.hWnd, SDL_TRUE );
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
if ( clgame.dllFuncs.pfnLookEvent || ( clgame.client_dll_uses_sdl && CVAR_TO_BOOL( m_rawinput ) ) )
{
SDL_SetRelativeMouseMode( SDL_TRUE );
}
#endif
#endif // XASH_SDL
}
if( cls.initialized )
clgame.dllFuncs.IN_ActivateMouse();
}
#if XASH_USE_EVDEV
if( ( newstate == key_menu || newstate == key_console || newstate == key_message ) && ( !CL_IsBackgroundMap() || CL_IsBackgroundDemo( )))
{
#ifdef XASH_SDL
SDL_SetWindowGrab(host.hWnd, SDL_FALSE);
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
if ( clgame.dllFuncs.pfnLookEvent || ( clgame.client_dll_uses_sdl && CVAR_TO_BOOL( m_rawinput ) ) )
{
SDL_SetRelativeMouseMode( SDL_FALSE );
}
#endif
#endif // XASH_SDL
#if XASH_ANDROID
Android_ShowMouse( true );
#endif
#ifdef XASH_USE_EVDEV
Evdev_SetGrab( false );
#endif
}
else
{
Platform_SetCursorType( dc_none );
#if XASH_USE_EVDEV
#if XASH_ANDROID
Android_ShowMouse( false );
#endif
#ifdef XASH_USE_EVDEV
Evdev_SetGrab( true );
#endif
}
// don't leave the user without cursor if they enabled m_ignore
if( m_ignore.value )
return;
if( oldstate == key_game )
{
IN_DeactivateMouse();
}
else if( newstate == key_game )
{
IN_ActivateMouse();
}
}
static void IN_CheckMouseState( qboolean active )
{
static qboolean s_bRawInput, s_bMouseGrab;
#if XASH_WIN32
qboolean useRawInput = ( m_rawinput.value && clgame.client_dll_uses_sdl ) || clgame.dllFuncs.pfnLookEvent != NULL;
#else
qboolean useRawInput = true; // always use SDL code
#endif
if( m_ignore.value )
return;
if( active && useRawInput && !host.mouse_visible && cls.state == ca_active )
{
if( !s_bRawInput )
{
#if XASH_SDL == 2
SDL_GetRelativeMouseState( NULL, NULL );
SDL_SetRelativeMouseMode( SDL_TRUE );
#endif
// Con_Printf( "Enable relative mode\n" );
s_bRawInput = true;
}
}
else
{
if( s_bRawInput )
{
#if XASH_SDL == 2
SDL_GetRelativeMouseState( NULL, NULL );
SDL_SetRelativeMouseMode( SDL_FALSE );
#endif
// Con_Printf( "Disable relative mode\n" );
s_bRawInput = false;
}
}
if( active && !host.mouse_visible && cls.state == ca_active )
{
if( !s_bMouseGrab )
{
#if XASH_SDL
SDL_SetWindowGrab( host.hWnd, SDL_TRUE );
#endif
// Con_Printf( "Enable grab\n" );
s_bMouseGrab = true;
}
}
else
{
if( s_bMouseGrab )
{
#if XASH_SDL
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
#endif
// Con_Printf( "Disable grab\n" );
s_bMouseGrab = false;
}
}
}
/*
@@ -277,15 +256,58 @@ IN_ActivateMouse
Called when the window gains focus or changes in some way
===========
*/
void IN_ActivateMouse( void )
void IN_ActivateMouse( qboolean force )
{
int width, height;
static int oldstate;
if( !in_mouseinitialized )
return;
IN_CheckMouseState( true );
if( clgame.dllFuncs.IN_ActivateMouse )
clgame.dllFuncs.IN_ActivateMouse();
if( CL_Active() && host.mouse_visible && !force )
return; // VGUI controls
if( cls.key_dest == key_menu && !Cvar_VariableInteger( "fullscreen" ))
{
// check for mouse leave-entering
if( !in_mouse_suspended && !UI_MouseInRect( ))
in_mouse_suspended = true;
if( oldstate != in_mouse_suspended )
{
if( in_mouse_suspended )
{
#ifdef XASH_SDL
/// TODO: Platform_ShowCursor
if( !touch_emulate )
SDL_ShowCursor( SDL_FALSE );
#endif
UI_ShowCursor( false );
}
}
oldstate = in_mouse_suspended;
if( in_mouse_suspended )
{
in_mouse_suspended = false;
in_mouseactive = false; // re-initialize mouse
UI_ShowCursor( true );
}
}
if( in_mouseactive ) return;
in_mouseactive = true;
if( UI_IsVisible( )) return;
if( cls.key_dest == key_game )
{
clgame.dllFuncs.IN_ActivateMouse();
#ifdef XASH_SDL
SDL_GetRelativeMouseState( 0, 0 ); // Reset mouse position
#endif
}
}
/*
@@ -297,43 +319,48 @@ Called when the window loses focus
*/
void IN_DeactivateMouse( void )
{
if( !in_mouseinitialized )
if( !in_mouseinitialized || !in_mouseactive )
return;
IN_CheckMouseState( false );
if( clgame.dllFuncs.IN_DeactivateMouse )
if( cls.key_dest == key_game )
{
clgame.dllFuncs.IN_DeactivateMouse();
}
in_mouseactive = false;
#ifdef XASH_SDL
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
#endif // XASH_SDL
}
/*
================
IN_MouseMove
================
*/
static void IN_MouseMove( void )
void IN_MouseMove( void )
{
int x, y;
POINT current_pos;
if( !in_mouseinitialized )
if( !in_mouseinitialized || !in_mouseactive || !UI_IsVisible( ))
return;
if( touch_emulate.value )
{
// touch emulation overrides all input
Touch_KeyEvent( 0, 0 );
return;
}
// find mouse movement
Platform_GetMousePos( &x, &y );
Platform_GetMousePos( &current_pos.x, &current_pos.y );
VGui_MouseMove( x, y );
VGui_MouseMove( current_pos.x, current_pos.y );
// HACKHACK: show cursor in UI, as mainui doesn't call
// platform-dependent SetCursor anymore
#ifdef XASH_SDL
if( UI_IsVisible() )
SDL_ShowCursor( SDL_TRUE );
#endif
// if the menu is visible, move the menu cursor
UI_MouseMove( x, y );
UI_MouseMove( current_pos.x, current_pos.y );
IN_ActivateCursor();
}
/*
@@ -341,55 +368,76 @@ static void IN_MouseMove( void )
IN_MouseEvent
===========
*/
void IN_MouseEvent( int key, int down )
void IN_MouseEvent( void )
{
if( !in_mouseinitialized )
int i;
// touch emu: handle motion
if( CVAR_TO_BOOL( touch_emulate ))
{
if( Key_IsDown( K_SHIFT ) )
Touch_KeyEvent( K_MOUSE2, 2 );
else
Touch_KeyEvent( K_MOUSE1, 2 );
}
if( !in_mouseinitialized || !in_mouseactive )
return;
if( down )
SetBits( in_mstate, BIT( key ));
else ClearBits( in_mstate, BIT( key ));
// touch emulation overrides all input
if( touch_emulate.value )
{
Touch_KeyEvent( K_MOUSE1 + key, down );
}
else if( cls.key_dest == key_game )
{
// perform button actions
VGui_MouseEvent( K_MOUSE1 + key, down );
if( m_ignore->value )
return;
// don't do Key_Event here
// client may override IN_MouseEvent
// but by default it calls back to Key_Event anyway
if( in_mouseactive )
clgame.dllFuncs.IN_MouseEvent( in_mstate );
if( cls.key_dest == key_game )
{
#if defined( XASH_SDL )
static qboolean ignore; // igonre mouse warp event
int x, y;
Platform_GetMousePos(&x, &y);
if( host.mouse_visible )
SDL_ShowCursor( SDL_TRUE );
else if( !CVAR_TO_BOOL( touch_emulate ) )
SDL_ShowCursor( SDL_FALSE );
if( x < host.window_center_x / 2 ||
y < host.window_center_y / 2 ||
x > host.window_center_x + host.window_center_x / 2 ||
y > host.window_center_y + host.window_center_y / 2 )
{
Platform_SetMousePos( host.window_center_x, host.window_center_y );
ignore = 1; // next mouse event will be mouse warp
return;
}
if ( !ignore )
{
if( !m_enginemouse->value )
{
// a1ba: mouse keys are now separated
// so pass 0 here
clgame.dllFuncs.IN_MouseEvent( 0 );
}
}
else
{
SDL_GetRelativeMouseState( 0, 0 ); // reset relative state
ignore = 0;
}
#endif
return;
}
else
{
// perform button actions
Key_Event( K_MOUSE1 + key, down );
#if XASH_SDL && !XASH_WIN32
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
SDL_SetRelativeMouseMode( SDL_FALSE );
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
SDL_ShowCursor( SDL_TRUE );
#endif // XASH_SDL && !XASH_WIN32
IN_MouseMove();
}
}
/*
==============
IN_MWheelEvent
direction is negative for wheel down, otherwise wheel up
==============
*/
void IN_MWheelEvent( int y )
{
int b = y > 0 ? K_MWHEELUP : K_MWHEELDOWN;
VGui_MWheelEvent( y );
Key_Event( b, true );
Key_Event( b, false );
}
/*
===========
IN_Shutdown
@@ -399,7 +447,7 @@ void IN_Shutdown( void )
{
IN_DeactivateMouse( );
#if XASH_USE_EVDEV
#ifdef XASH_USE_EVDEV
Evdev_Shutdown();
#endif
@@ -414,9 +462,9 @@ IN_Init
*/
void IN_Init( void )
{
Cvar_RegisterVariable( &cl_forwardspeed );
Cvar_RegisterVariable( &cl_backspeed );
Cvar_RegisterVariable( &cl_sidespeed );
cl_forwardspeed = Cvar_Get( "cl_forwardspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL, "Default forward move speed" );
cl_backspeed = Cvar_Get( "cl_backspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL, "Default back move speed" );
cl_sidespeed = Cvar_Get( "cl_sidespeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL, "Default side move speed" );
if( !Host_IsDedicated() )
{
@@ -426,7 +474,7 @@ void IN_Init( void )
Touch_Init();
#if XASH_USE_EVDEV
#ifdef XASH_USE_EVDEV
Evdev_Init();
#endif
}
@@ -453,8 +501,8 @@ static void IN_JoyAppendMove( usercmd_t *cmd, float forwardmove, float sidemove
{
static uint moveflags = T | S;
if( forwardmove ) cmd->forwardmove = forwardmove * cl_forwardspeed.value;
if( sidemove ) cmd->sidemove = sidemove * cl_sidespeed.value;
if( forwardmove ) cmd->forwardmove = forwardmove * cl_forwardspeed->value;
if( sidemove ) cmd->sidemove = sidemove * cl_sidespeed->value;
if( forwardmove )
{
@@ -523,16 +571,20 @@ static void IN_JoyAppendMove( usercmd_t *cmd, float forwardmove, float sidemove
}
}
static void IN_CollectInput( float *forward, float *side, float *pitch, float *yaw, qboolean includeMouse )
void IN_CollectInput( float *forward, float *side, float *pitch, float *yaw, qboolean includeMouse, qboolean includeSdlMouse )
{
if( includeMouse )
if( includeMouse
#if XASH_SDL
&& includeSdlMouse
#endif
)
{
float x, y;
Platform_MouseMove( &x, &y );
*pitch += y * m_pitch.value;
*yaw -= x * m_yaw.value;
*pitch += y * m_pitch->value;
*yaw -= x * m_yaw->value;
#if XASH_USE_EVDEV
#ifdef XASH_USE_EVDEV
IN_EvdevMove( yaw, pitch );
#endif
}
@@ -540,7 +592,7 @@ static void IN_CollectInput( float *forward, float *side, float *pitch, float *y
Joy_FinalizeMove( forward, side, yaw, pitch );
Touch_GetMove( forward, side, yaw, pitch );
if( look_filter.value )
if( look_filter->value )
{
*pitch = ( inputstate.lastpitch + *pitch ) / 2;
*yaw = ( inputstate.lastyaw + *yaw ) / 2;
@@ -574,7 +626,7 @@ void IN_EngineAppendMove( float frametime, void *cmd1, qboolean active )
{
float sensitivity = 1;//( (float)cl.local.scr_fov / (float)90.0f );
IN_CollectInput( &forward, &side, &pitch, &yaw, false );
IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized && !CVAR_TO_BOOL( m_ignore ), m_enginemouse->value );
IN_JoyAppendMove( cmd, forward, side );
@@ -583,36 +635,11 @@ void IN_EngineAppendMove( float frametime, void *cmd1, qboolean active )
cmd->viewangles[YAW] += yaw * sensitivity;
cmd->viewangles[PITCH] += pitch * sensitivity;
cmd->viewangles[PITCH] = bound( -90, cmd->viewangles[PITCH], 90 );
VectorCopy( cmd->viewangles, cl.viewangles );
VectorCopy(cmd->viewangles, cl.viewangles);
}
}
}
static void IN_Commands( void )
{
#if XASH_USE_EVDEV
IN_EvdevFrame();
#endif
if( clgame.dllFuncs.pfnLookEvent )
{
float forward = 0, side = 0, pitch = 0, yaw = 0;
IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized && !m_ignore.value );
if( cls.key_dest == key_game )
{
clgame.dllFuncs.pfnLookEvent( yaw, pitch );
clgame.dllFuncs.pfnMoveEvent( forward, side );
}
}
if( !in_mouseinitialized )
return;
IN_CheckMouseState( in_mouseactive );
}
/*
==================
Host_InputFrame
@@ -622,9 +649,45 @@ Called every frame, even if not generating commands
*/
void Host_InputFrame( void )
{
qboolean shutdownMouse = false;
float forward = 0, side = 0, pitch = 0, yaw = 0;
Sys_SendKeyEvents ();
IN_Commands();
#ifdef XASH_USE_EVDEV
IN_EvdevFrame();
#endif
if( clgame.dllFuncs.pfnLookEvent )
{
IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized && !CVAR_TO_BOOL( m_ignore ), true );
if( cls.key_dest == key_game )
{
clgame.dllFuncs.pfnLookEvent( yaw, pitch );
clgame.dllFuncs.pfnMoveEvent( forward, side );
}
}
if( !in_mouseinitialized )
return;
if( host.status != HOST_FRAME )
{
IN_DeactivateMouse();
return;
}
// release mouse during pause or console typeing
if( cl.paused && cls.key_dest == key_game )
shutdownMouse = true;
if( shutdownMouse && !Cvar_VariableInteger( "fullscreen" ))
{
IN_DeactivateMouse();
return;
}
IN_ActivateMouse( false );
IN_MouseMove();
}

View File

@@ -33,9 +33,8 @@ extern qboolean in_mouseinitialized;
void IN_Init( void );
void Host_InputFrame( void );
void IN_Shutdown( void );
void IN_MouseEvent( int key, int down );
void IN_MWheelEvent( int direction );
void IN_ActivateMouse( void );
void IN_MouseEvent( void );
void IN_ActivateMouse( qboolean force );
void IN_DeactivateMouse( void );
void IN_MouseSavePos( void );
void IN_MouseRestorePos( void );
@@ -46,8 +45,8 @@ uint IN_CollectInputDevices( void );
void IN_LockInputDevices( qboolean lock );
void IN_EngineAppendMove( float frametime, void *cmd, qboolean active );
extern convar_t m_yaw;
extern convar_t m_pitch;
extern convar_t *m_yaw;
extern convar_t *m_pitch;
//
// in_touch.c
//
@@ -58,13 +57,16 @@ typedef enum
event_motion
} touchEventType;
extern convar_t touch_enable;
extern convar_t touch_emulate;
extern convar_t *touch_enable;
extern convar_t *touch_emulate;
void Touch_Draw( void );
void Touch_SetClientOnly( byte state );
void Touch_RemoveButton( const char *name, qboolean privileged );
void Touch_HideButtons( const char *name, unsigned char hide, qboolean privileged );
void Touch_SetClientOnly( qboolean state );
void Touch_RemoveButton( const char *name );
void Touch_HideButtons( const char *name, unsigned char hide );
//void IN_TouchSetCommand( const char *name, const char *command );
//void IN_TouchSetTexture( const char *name, const char *texture );
//void IN_TouchSetColor( const char *name, byte *color );
void Touch_AddClientButton( const char *name, const char *texture, const char *command, float x1, float y1, float x2, float y2, byte *color, int round, float aspect, int flags );
void Touch_AddDefaultButton( const char *name, const char *texturefile, const char *command, float x1, float y1, float x2, float y2, byte *color, int round, float aspect, int flags );
void Touch_WriteConfig( void );
@@ -74,8 +76,6 @@ void Touch_GetMove( float * forward, float *side, float *yaw, float *pitch );
void Touch_ResetDefaultButtons( void );
int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy );
void Touch_KeyEvent( int key, int down );
qboolean Touch_WantVisibleCursor( void );
void Touch_NotifyResize( void );
//
// in_joy.c

View File

@@ -104,9 +104,9 @@ keyname_t keynames[] =
{"B_BUTTON", K_B_BUTTON, "+use"},
{"X_BUTTON", K_X_BUTTON, "+reload"},
{"Y_BUTTON", K_Y_BUTTON, "impulse 100"}, // Flashlight
{"BACK", K_BACK_BUTTON, "pause"}, // Menu
{"BACK", K_BACK_BUTTON, "cancelselect"}, // Menu
{"MODE", K_MODE_BUTTON, ""},
{"START", K_START_BUTTON, "escape"},
{"START", K_START_BUTTON, "pause"},
{"STICK1", K_LSTICK, "+speed"},
{"STICK2", K_RSTICK, "+duck"},
{"L1_BUTTON", K_L1_BUTTON, "+duck"},
@@ -123,13 +123,13 @@ keyname_t keynames[] =
{"JOY4" , K_JOY4 , ""},
{"C_BUTTON", K_C_BUTTON, ""},
{"Z_BUTTON", K_Z_BUTTON, ""},
{"MISC_BUTTON", K_MISC_BUTTON, ""},
{"PADDLE1", K_PADDLE1_BUTTON, ""},
{"PADDLE2", K_PADDLE2_BUTTON, ""},
{"PADDLE3", K_PADDLE3_BUTTON, ""},
{"PADDLE4", K_PADDLE4_BUTTON, ""},
{"TOUCHPAD", K_TOUCHPAD, ""},
{"AUX26", K_AUX26, ""}, // generic
{"AUX20", K_AUX20, ""}, // generic
{"AUX21", K_AUX21, ""},
{"AUX22", K_AUX22, ""},
{"AUX23", K_AUX23, ""},
{"AUX24", K_AUX24, ""},
{"AUX25", K_AUX25, ""},
{"AUX26", K_AUX26, ""},
{"AUX27", K_AUX27, ""},
{"AUX28", K_AUX28, ""},
{"AUX29", K_AUX29, ""},
@@ -144,8 +144,8 @@ keyname_t keynames[] =
static void OSK_EnableTextInput( qboolean enable, qboolean force );
static qboolean OSK_KeyEvent( int key, int down );
static CVAR_DEFINE_AUTO( osk_enable, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "enable built-in on-screen keyboard" );
static CVAR_DEFINE_AUTO( key_rotate, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "rotate arrow keys (0-3)" );
static convar_t *osk_enable;
static convar_t *key_rotate;
/*
===================
@@ -159,6 +159,18 @@ int GAME_EXPORT Key_IsDown( int keynum )
return keys[keynum].down;
}
/*
===================
Key_GetBind
===================
*/
const char *Key_IsBind( int keynum )
{
if( keynum == -1 || !keys[keynum].binding )
return NULL;
return keys[keynum].binding;
}
/*
===================
Key_StringToKeynum
@@ -332,7 +344,7 @@ int Key_GetKey( const char *pBinding )
Key_Unbind_f
===================
*/
static void Key_Unbind_f( void )
void Key_Unbind_f( void )
{
int b;
@@ -358,11 +370,11 @@ static void Key_Unbind_f( void )
Key_Unbindall_f
===================
*/
static void Key_Unbindall_f( void )
void Key_Unbindall_f( void )
{
int i;
for( i = 0; i < ARRAYSIZE( keys ); i++ )
for( i = 0; i < 256; i++ )
{
if( keys[i].binding )
Key_SetBinding( i, "" );
@@ -370,7 +382,6 @@ static void Key_Unbindall_f( void )
// set some defaults
Key_SetBinding( K_ESCAPE, "escape" );
Key_SetBinding( K_START_BUTTON, "escape" );
}
/*
@@ -378,13 +389,13 @@ static void Key_Unbindall_f( void )
Key_Reset_f
===================
*/
static void Key_Reset_f( void )
void Key_Reset_f( void )
{
keyname_t *kn;
int i;
// clear all keys first
for( i = 0; i < ARRAYSIZE( keys ); i++ )
for( i = 0; i < 256; i++ )
{
if( keys[i].binding )
Key_SetBinding( i, "" );
@@ -400,7 +411,7 @@ static void Key_Reset_f( void )
Key_Bind_f
===================
*/
static void Key_Bind_f( void )
void Key_Bind_f( void )
{
char cmd[1024];
int i, c, b;
@@ -434,8 +445,8 @@ static void Key_Bind_f( void )
for( i = 2; i < c; i++ )
{
Q_strncat( cmd, Cmd_Argv( i ), sizeof( cmd ));
if( i != ( c - 1 )) Q_strncat( cmd, " ", sizeof( cmd ));
Q_strcat( cmd, Cmd_Argv( i ));
if( i != ( c - 1 )) Q_strcat( cmd, " " );
}
Key_SetBinding( b, cmd );
@@ -451,7 +462,6 @@ Writes lines containing "bind key value"
void Key_WriteBindings( file_t *f )
{
int i;
string newCommand;
if( !f ) return;
@@ -462,8 +472,7 @@ void Key_WriteBindings( file_t *f )
if( !COM_CheckString( keys[i].binding ))
continue;
Cmd_Escape( newCommand, keys[i].binding, sizeof( newCommand ));
FS_Printf( f, "bind %s \"%s\"\n", Key_KeynumToString( i ), newCommand );
FS_Printf( f, "bind %s \"%s\"\n", Key_KeynumToString( i ), keys[i].binding );
}
}
@@ -473,7 +482,7 @@ Key_Bindlist_f
============
*/
static void Key_Bindlist_f( void )
void Key_Bindlist_f( void )
{
int i;
@@ -503,18 +512,18 @@ void Key_Init( void )
keyname_t *kn;
// register our functions
Cmd_AddRestrictedCommand( "bind", Key_Bind_f, "binds a command to the specified key in bindmap" );
Cmd_AddRestrictedCommand( "unbind", Key_Unbind_f, "removes a command on the specified key in bindmap" );
Cmd_AddRestrictedCommand( "unbindall", Key_Unbindall_f, "removes all commands from all keys in bindmap" );
Cmd_AddRestrictedCommand( "resetkeys", Key_Reset_f, "reset all keys to their default values" );
Cmd_AddCommand( "bind", Key_Bind_f, "binds a command to the specified key in bindmap" );
Cmd_AddCommand( "unbind", Key_Unbind_f, "removes a command on the specified key in bindmap" );
Cmd_AddCommand( "unbindall", Key_Unbindall_f, "removes all commands from all keys in bindmap" );
Cmd_AddCommand( "resetkeys", Key_Reset_f, "reset all keys to their default values" );
Cmd_AddCommand( "bindlist", Key_Bindlist_f, "display current key bindings" );
Cmd_AddCommand( "makehelp", Key_EnumCmds_f, "write help.txt that contains all console cvars and cmds" );
// setup default binding. "unbindall" from config.cfg will be reset it
for( kn = keynames; kn->name; kn++ ) Key_SetBinding( kn->keynum, kn->binding );
Cvar_RegisterVariable( &osk_enable );
Cvar_RegisterVariable( &key_rotate );
osk_enable = Cvar_Get( "osk_enable", "0", FCVAR_ARCHIVE, "enable built-in on-screen keyboard" );
key_rotate = Cvar_Get( "key_rotate", "0", FCVAR_ARCHIVE, "rotate arrow keys (0-3)" );
}
@@ -523,7 +532,7 @@ void Key_Init( void )
Key_AddKeyCommands
===================
*/
static void Key_AddKeyCommands( int key, const char *kb, qboolean down )
void Key_AddKeyCommands( int key, const char *kb, qboolean down )
{
char button[1024];
char *buttonPtr;
@@ -541,8 +550,8 @@ static void Key_AddKeyCommands( int key, const char *kb, qboolean down )
if( button[0] == '+' )
{
// button commands add keynum as a parm
if( down ) Q_snprintf( cmd, sizeof( cmd ), "%s %i\n", button, key );
else Q_snprintf( cmd, sizeof( cmd ), "-%s %i\n", button + 1, key );
if( down ) Q_sprintf( cmd, "%s %i\n", button, key );
else Q_sprintf( cmd, "-%s %i\n", button + 1, key );
Cbuf_AddText( cmd );
}
else if( down )
@@ -590,7 +599,7 @@ static qboolean Key_IsAllowedAutoRepeat( int key )
static int Key_Rotate( int key )
{
if( key_rotate.value == 1.0f ) // CW
if( key_rotate->value == 1.0f ) // CW
{
if( key == K_UPARROW )
key = K_LEFTARROW;
@@ -602,7 +611,7 @@ static int Key_Rotate( int key )
key = K_RIGHTARROW;
}
else if( key_rotate.value == 3.0f ) // CCW
else if( key_rotate->value == 3.0f ) // CCW
{
if( key == K_UPARROW )
key = K_RIGHTARROW;
@@ -614,7 +623,7 @@ static int Key_Rotate( int key )
key = K_LEFTARROW;
}
else if( key_rotate.value == 2.0f )
else if( key_rotate->value == 2.0f )
{
if( key == K_UPARROW )
key = K_DOWNARROW;
@@ -701,6 +710,7 @@ void GAME_EXPORT Key_Event( int key, int down )
}
VGui_KeyEvent( key, down );
Touch_KeyEvent( key, down );
// console key is hardcoded, so the user can never unbind it
if( key == '`' || key == '~' )
@@ -719,10 +729,10 @@ void GAME_EXPORT Key_Event( int key, int down )
switch( cls.key_dest )
{
case key_game:
if( r_showtextures.value )
if( CVAR_TO_BOOL( gl_showtextures ))
{
// close texture atlas
Cvar_DirectSet( &r_showtextures, "0" );
Cvar_SetValue( "r_showtextures", 0.0f );
return;
}
else if( host.mouse_visible && cls.state != ca_cinematic )
@@ -797,14 +807,14 @@ Key_EnableTextInput
*/
void Key_EnableTextInput( qboolean enable, qboolean force )
{
if( osk_enable.value )
if( CVAR_TO_BOOL( osk_enable ) )
{
OSK_EnableTextInput( enable, force );
return;
}
if( enable && ( !host.textmode || force ))
if( enable && ( !host.textmode || force ) )
Platform_EnableTextInput( true );
else if( !enable && ( host.textmode || force ))
else if( !enable )
Platform_EnableTextInput( false );
host.textmode = enable;
@@ -830,9 +840,7 @@ void GAME_EXPORT Key_SetKeyDest( int key_dest )
cls.key_dest = key_menu;
break;
case key_console:
#if !XASH_NSWITCH && !XASH_PSVITA // if we don't disable this, pops up the keyboard during load
Key_EnableTextInput( true, false );
#endif
cls.key_dest = key_console;
break;
case key_message:
@@ -995,7 +1003,7 @@ struct osk_s
static qboolean OSK_KeyEvent( int key, int down )
{
if( !osk.enable || !osk_enable.value )
if( !osk.enable || !CVAR_TO_BOOL( osk_enable ) )
return false;
if( osk.sending )
@@ -1034,7 +1042,7 @@ static qboolean OSK_KeyEvent( int key, int down )
else
osk.curlayout++;
osk.shift = true;
osk.shift = osk.curbutton.val == OSK_SHIFT;
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
break;
case OSK_BACKSPACE:
@@ -1055,7 +1063,7 @@ static qboolean OSK_KeyEvent( int key, int down )
break;
}
if( !Q_stricmp( cl_charset.string, "utf-8" ) )
if( !Q_stricmp( cl_charset->string, "utf-8" ) )
ch = (unsigned char)osk.curbutton.val;
else
ch = Con_UtfProcessCharForce( (unsigned char)osk.curbutton.val );
@@ -1139,7 +1147,7 @@ Draw button with symbol on it
*/
static void OSK_DrawSymbolButton( int symb, float x, float y, float width, float height )
{
cl_font_t *font = Con_GetCurFont();
char str[] = {symb & 255, 0};
byte color[] = { 255, 255, 255, 255 };
int x1 = x * refState.width,
y1 = y * refState.height,
@@ -1147,15 +1155,14 @@ static void OSK_DrawSymbolButton( int symb, float x, float y, float width, float
h = height * refState.height;
if( symb == osk.curbutton.val )
{
ref.dllFuncs.FillRGBABlend( x1, y1, w, h, 255, 160, 0, 100 );
}
if( !symb || symb == ' ' || (symb >= OSK_TAB && symb < OSK_SPECKEY_LAST ) )
return;
CL_DrawCharacter(
x1 + width * 0.4 * refState.width,
y1 + height * 0.4 * refState.height,
symb, color, font, 0 );
Con_DrawCharacter( x1 + 1, y1, symb, color );
}
/*
@@ -1169,11 +1176,7 @@ static void OSK_DrawSpecialButton( const char *name, float x, float y, float wid
{
byte color[] = { 0, 255, 0, 255 };
Con_DrawString(
x * refState.width + width * 0.4 * refState.width,
y * refState.height + height * 0.4 * refState.height,
name,
color );
Con_DrawString( x * refState.width, y * refState.height, name, color );
}
@@ -1190,7 +1193,7 @@ void OSK_Draw( void )
float x, y;
int i, j;
if( !osk.enable || !osk_enable.value || !osk.curbutton.val )
if( !osk.enable || !CVAR_TO_BOOL(osk_enable) || !osk.curbutton.val )
return;
// draw keyboard

View File

@@ -659,7 +659,7 @@ static void make_hull_windings( hull_t *hull, hull_model_t *model )
Con_Reportf( "%i hull polys\n", model->num_polys );
}
void Mod_InitDebugHulls( model_t *loadmodel )
void Mod_InitDebugHulls( void )
{
int i;

View File

@@ -8,40 +8,14 @@
struct ref_state_s ref;
ref_globals_t refState;
CVAR_DEFINE_AUTO( gl_vsync, "0", FCVAR_ARCHIVE, "enable vertical syncronization" );
CVAR_DEFINE_AUTO( r_showtextures, "0", FCVAR_CHEAT, "show all uploaded textures" );
CVAR_DEFINE_AUTO( r_adjust_fov, "1", FCVAR_ARCHIVE, "making FOV adjustment for wide-screens" );
CVAR_DEFINE_AUTO( r_decals, "4096", FCVAR_ARCHIVE, "sets the maximum number of decals" );
CVAR_DEFINE_AUTO( gl_msaa_samples, "0", FCVAR_GLCONFIG, "samples number for multisample anti-aliasing" );
CVAR_DEFINE_AUTO( gl_clear, "0", FCVAR_ARCHIVE, "clearing screen after each frame" );
CVAR_DEFINE_AUTO( r_showtree, "0", FCVAR_ARCHIVE, "build the graph of visible BSP tree" );
static CVAR_DEFINE_AUTO( r_refdll, "", FCVAR_RENDERINFO, "choose renderer implementation, if supported" );
static CVAR_DEFINE_AUTO( r_refdll_loaded, "", FCVAR_READ_ONLY, "currently loaded renderer" );
// there is no need to expose whole host and cl structs into the renderer
// but we still need to update timings accurately as possible
// this looks horrible but the only other option would be passing four
// time pointers and then it's looks even worse with dereferences everywhere
#define STATIC_OFFSET_CHECK( s1, s2, field, base, msg ) \
STATIC_ASSERT( offsetof( s1, field ) == offsetof( s2, field ) - offsetof( s2, base ), msg )
#define REF_CLIENT_CHECK( field ) \
STATIC_OFFSET_CHECK( ref_client_t, client_t, field, time, "broken ref_client_t offset" ); \
STATIC_ASSERT_( szchk_##__LINE__, sizeof(((ref_client_t *)0)->field ) == sizeof( cl.field ), "broken ref_client_t size" )
#define REF_HOST_CHECK( field ) \
STATIC_OFFSET_CHECK( ref_host_t, host_parm_t, field, realtime, "broken ref_client_t offset" ); \
STATIC_ASSERT_( szchk_##__LINE__, sizeof(((ref_host_t *)0)->field ) == sizeof( host.field ), "broken ref_client_t size" )
REF_CLIENT_CHECK( time );
REF_CLIENT_CHECK( oldtime );
REF_CLIENT_CHECK( viewentity );
REF_CLIENT_CHECK( playernum );
REF_CLIENT_CHECK( maxclients );
REF_CLIENT_CHECK( models );
REF_CLIENT_CHECK( paused );
REF_CLIENT_CHECK( simorg );
REF_HOST_CHECK( realtime );
REF_HOST_CHECK( frametime );
REF_HOST_CHECK( features );
convar_t *gl_vsync;
convar_t *gl_showtextures;
convar_t *r_decals;
convar_t *r_adjust_fov;
convar_t *r_showtree;
convar_t *gl_wgl_msaa_samples;
convar_t *gl_clear;
convar_t *r_refdll;
void R_GetTextureParms( int *w, int *h, int texnum )
{
@@ -67,24 +41,50 @@ void GAME_EXPORT GL_FreeImage( const char *name )
ref.dllFuncs.GL_FreeTexture( texnum );
}
void R_UpdateRefState( void )
{
refState.time = cl.time;
refState.oldtime = cl.oldtime;
refState.realtime = host.realtime;
refState.frametime = host.frametime;
}
void GL_RenderFrame( const ref_viewpass_t *rvp )
{
R_UpdateRefState();
VectorCopy( rvp->vieworigin, refState.vieworg );
VectorCopy( rvp->viewangles, refState.viewangles );
AngleVectors( refState.viewangles, refState.vforward, refState.vright, refState.vup );
ref.dllFuncs.GL_RenderFrame( rvp );
}
static intptr_t pfnEngineGetParm( int parm, int arg )
static int pfnEngineGetParm( int parm, int arg )
{
return CL_RenderGetParm( parm, arg, false ); // prevent recursion
}
static world_static_t *pfnGetWorld( void )
{
return &world;
}
static void pfnStudioEvent( const mstudioevent_t *event, const cl_entity_t *e )
{
clgame.dllFuncs.pfnStudioEvent( event, e );
}
static efrag_t* pfnGetEfragsFreeList( void )
{
return clgame.free_efrags;
}
static void pfnSetEfragsFreeList( efrag_t *list )
{
clgame.free_efrags = list;
}
static model_t *pfnGetDefaultSprite( enum ref_defaultsprite_e spr )
{
switch( spr )
@@ -109,10 +109,24 @@ static void *pfnMod_Extradata( int type, model_t *m )
return NULL;
}
static void CL_ExtraUpdate( void )
static model_t *pfnMod_GetCurrentLoadingModel( void )
{
clgame.dllFuncs.IN_Accumulate();
S_ExtraUpdate();
return loadmodel;
}
static void pfnMod_SetCurrentLoadingModel( model_t *m )
{
loadmodel = m;
}
static void pfnGetPredictedOrigin( vec3_t v )
{
VectorCopy( cl.simorg, v );
}
static color24 *pfnCL_GetPaletteColor( int color ) // clgame.palette[color]
{
return &clgame.palette[color];
}
static void pfnCL_GetScreenInfo( int *width, int *height ) // clgame.scrInfo, ptrs may be NULL
@@ -137,7 +151,7 @@ static player_info_t *pfnPlayerInfo( int index )
if( index == -1 ) // special index for menu
return &gameui.playerinfo;
if( index < 0 || index >= cl.maxclients )
if( index < 0 || index > cl.maxclients )
return NULL;
return &cl.players[index];
@@ -164,6 +178,11 @@ static int pfnGetStudioModelInterface( int version, struct r_studio_interface_s
0;
}
static poolhandle_t pfnImage_GetPool( void )
{
return host.imagepool;
}
static const bpc_desc_t *pfnImage_GetPFDesc( int idx )
{
return &PFDesc[idx];
@@ -184,10 +203,29 @@ static screenfade_t *pfnRefGetScreenFade( void )
return &clgame.fade;
}
/*
===============
R_DoResetGamma
gamma will be reset for
some type of screenshots
===============
*/
static qboolean R_DoResetGamma( void )
{
switch( cls.scrshot_action )
{
case scrshot_envshot:
case scrshot_skyshot:
return true;
default:
return false;
}
}
static qboolean R_Init_Video_( const int type )
{
host.apply_opengl_config = true;
Cbuf_AddTextf( "exec %s.cfg", ref.dllFuncs.R_GetConfigName());
Cbuf_AddText( va( "exec %s.cfg", ref.dllFuncs.R_GetConfigName()));
Cbuf_Execute();
host.apply_opengl_config = false;
@@ -204,7 +242,7 @@ static ref_api_t gEngfuncs =
Cvar_VariableString,
Cvar_SetValue,
Cvar_Set,
Cvar_RegisterVariable,
(void*)Cvar_RegisterVariable,
Cvar_FullSet,
Cmd_AddRefCommand,
@@ -228,15 +266,22 @@ static ref_api_t gEngfuncs =
Con_DrawString,
CL_DrawCenterPrint,
CL_GetLocalPlayer,
CL_GetViewModel,
CL_GetEntityByIndex,
R_BeamGetEntity,
CL_GetWaterEntity,
CL_AddVisibleEntity,
Mod_SampleSizeForFace,
Mod_BoxVisible,
pfnGetWorld,
Mod_PointInLeaf,
Mod_CreatePolygonsForHull,
R_StudioSlerpBones,
R_StudioCalcBoneQuaternion,
R_StudioCalcBonePosition,
R_StudioGetAnim,
pfnStudioEvent,
@@ -250,9 +295,14 @@ static ref_api_t gEngfuncs =
Mod_ForName,
pfnMod_Extradata,
CL_ModelHandle,
pfnMod_GetCurrentLoadingModel,
pfnMod_SetCurrentLoadingModel,
CL_EntitySetRemapColors,
CL_GetRemapInfoForEntity,
CL_AllocRemapInfo,
CL_FreeRemapInfo,
CL_UpdateRemapInfo,
CL_ExtraUpdate,
Host_Error,
@@ -260,6 +310,9 @@ static ref_api_t gEngfuncs =
COM_RandomFloat,
COM_RandomLong,
pfnRefGetScreenFade,
CL_TextMessageGet,
pfnGetPredictedOrigin,
pfnCL_GetPaletteColor,
pfnCL_GetScreenInfo,
pfnSetLocalLightLevel,
Sys_CheckParm,
@@ -281,6 +334,10 @@ static ref_api_t gEngfuncs =
COM_FreeLibrary,
COM_GetProcAddress,
FS_LoadFile,
FS_FileExists,
FS_AllowDirectPaths,
R_Init_Video_,
R_Free_Video,
@@ -293,11 +350,9 @@ static ref_api_t gEngfuncs =
SW_LockBuffer,
SW_UnlockBuffer,
BuildGammaTable,
LightToTexGamma,
LightToTexGammaEx,
TextureToGamma,
ScreenGammaTable,
LinearGammaTable,
R_DoResetGamma,
CL_GetLightStyle,
CL_GetDynamicLight,
@@ -308,9 +363,10 @@ static ref_api_t gEngfuncs =
pfnGetPhysent,
pfnTraceSurface,
PM_CL_TraceLine,
PM_TraceLine,
CL_VisTraceLine,
CL_TraceLine,
pfnGetMoveVars,
Image_AddCmdFlags,
Image_SetForceFlags,
@@ -322,13 +378,12 @@ static ref_api_t gEngfuncs =
FS_CopyImage,
FS_FreeImage,
Image_SetMDLPointer,
pfnImage_GetPool,
pfnImage_GetPFDesc,
pfnDrawNormalTriangles,
pfnDrawTransparentTriangles,
&clgame.drawFuncs,
&g_fsapi,
&clgame.drawFuncs
};
static void R_UnloadProgs( void )
@@ -340,14 +395,14 @@ static void R_UnloadProgs( void )
Cvar_FullSet( "host_refloaded", "0", FCVAR_READ_ONLY );
Cvar_Unlink( FCVAR_RENDERINFO | FCVAR_GLCONFIG );
Cmd_Unlink( CMD_REFDLL );
COM_FreeLibrary( ref.hInstance );
ref.hInstance = NULL;
memset( &refState, 0, sizeof( refState ));
memset( &ref.dllFuncs, 0, sizeof( ref.dllFuncs ));
Cvar_Unlink( FCVAR_RENDERINFO | FCVAR_GLCONFIG );
Cmd_Unlink( CMD_REFDLL );
}
static void CL_FillTriAPIFromRef( triangleapi_t *dst, const ref_interface_t *src )
@@ -403,7 +458,7 @@ static qboolean R_LoadProgs( const char *name )
// make local copy of engfuncs to prevent overwrite it with user dll
memcpy( &gpEngfuncs, &gEngfuncs, sizeof( gpEngfuncs ));
if( GetRefAPI( REF_API_VERSION, &ref.dllFuncs, &gpEngfuncs, &refState ) != REF_API_VERSION )
if( !GetRefAPI( REF_API_VERSION, &ref.dllFuncs, &gpEngfuncs, &refState ))
{
COM_FreeLibrary( ref.hInstance );
Con_Reportf( "R_LoadProgs: can't init renderer API: wrong version\n" );
@@ -473,7 +528,7 @@ static void R_GetRendererName( char *dest, size_t size, const char *opt )
else
{
// full path
Q_strncpy( dest, opt, size );
Q_strcpy( dest, opt );
}
}
@@ -492,7 +547,6 @@ static qboolean R_LoadRenderer( const char *refopt )
return false;
}
Cvar_FullSet( "r_refdll_loaded", refopt, FCVAR_READ_ONLY );
Con_Reportf( "Renderer %s initialized\n", refdll );
return true;
@@ -511,70 +565,72 @@ static void SetWidthAndHeightFromCommandLine( void )
return;
}
R_SaveVideoMode( width, height, width, height, false );
R_SaveVideoMode( width, height, width, height );
}
static void SetFullscreenModeFromCommandLine( void )
{
if( Sys_CheckParm( "-borderless" ))
Cvar_DirectSet( &vid_fullscreen, "2" );
else if( Sys_CheckParm( "-fullscreen" ))
Cvar_DirectSet( &vid_fullscreen, "1" );
else if( Sys_CheckParm( "-windowed" ))
Cvar_DirectSet( &vid_fullscreen, "0" );
#if !XASH_MOBILE_PLATFORM
if ( Sys_CheckParm("-fullscreen") )
{
Cvar_Set( "fullscreen", "1" );
}
else if ( Sys_CheckParm( "-windowed" ) )
{
Cvar_Set( "fullscreen", "0" );
}
#endif
}
static void R_CollectRendererNames( void )
void R_CollectRendererNames( void )
{
// ordering is important!
static const char *shortNames[] =
{
#if XASH_REF_GL_ENABLED
"gl",
#endif
#if XASH_REF_NANOGL_ENABLED
"gles1",
#endif
#if XASH_REF_GLWES_ENABLED
"gles2",
#endif
#if XASH_REF_GL4ES_ENABLED
"gl4es",
#endif
#if XASH_REF_GLES3COMPAT_ENABLED
"gles3compat",
#endif
#if XASH_REF_SOFT_ENABLED
"soft",
#endif
};
const char *renderers[] = DEFAULT_RENDERERS;
int i, cur;
// ordering is important here too!
static const char *readableNames[ARRAYSIZE( shortNames )] =
cur = 0;
for( i = 0; i < DEFAULT_RENDERERS_LEN; i++ )
{
#if XASH_REF_GL_ENABLED
"OpenGL",
#endif
#if XASH_REF_NANOGL_ENABLED
"GLES1 (NanoGL)",
#endif
#if XASH_REF_GLWES_ENABLED
"GLES2 (gl-wes-v2)",
#endif
#if XASH_REF_GL4ES_ENABLED
"GL4ES",
#endif
#if XASH_REF_GLES3COMPAT_ENABLED
"GLES3 (gl2_shim)"
#endif
#if XASH_REF_SOFT_ENABLED
"Software",
#endif
};
string temp;
void *dll, *pfn;
ref.numRenderers = ARRAYSIZE( shortNames );
ref.shortNames = shortNames;
ref.readableNames = readableNames;
R_GetRendererName( temp, sizeof( temp ), renderers[i] );
dll = COM_LoadLibrary( temp, false, true );
if( !dll )
{
Con_Reportf( "R_CollectRendererNames: can't load library %s: %s\n", temp, COM_GetLibraryError() );
continue;
}
pfn = COM_GetProcAddress( dll, GET_REF_API );
if( !pfn )
{
Con_Reportf( "R_CollectRendererNames: can't find API entry point in %s\n", temp );
COM_FreeLibrary( dll );
continue;
}
Q_strncpy( ref.shortNames[cur], renderers[i], sizeof( ref.shortNames[cur] ));
pfn = COM_GetProcAddress( dll, GET_REF_HUMANREADABLE_NAME );
if( !pfn ) // just in case
{
Con_Reportf( "R_CollectRendererNames: can't find GetHumanReadableName export in %s\n", temp );
Q_strncpy( ref.readableNames[cur], renderers[i], sizeof( ref.readableNames[cur] ));
}
else
{
REF_HUMANREADABLE_NAME GetHumanReadableName = (REF_HUMANREADABLE_NAME)pfn;
GetHumanReadableName( ref.readableNames[cur], sizeof( ref.readableNames[cur] ));
}
Con_Printf( "Found renderer %s: %s\n", ref.shortNames[cur], ref.readableNames[cur] );
cur++;
COM_FreeLibrary( dll );
}
ref.numRenderers = cur;
}
qboolean R_Init( void )
@@ -582,32 +638,14 @@ qboolean R_Init( void )
qboolean success = false;
string requested;
Cvar_RegisterVariable( &gl_vsync );
Cvar_RegisterVariable( &r_showtextures );
Cvar_RegisterVariable( &r_adjust_fov );
Cvar_RegisterVariable( &r_decals );
Cvar_RegisterVariable( &gl_msaa_samples );
Cvar_RegisterVariable( &gl_clear );
Cvar_RegisterVariable( &r_showtree );
Cvar_RegisterVariable( &r_refdll );
Cvar_RegisterVariable( &r_refdll_loaded );
// cvars that are expected to exist
Cvar_Get( "r_speeds", "0", FCVAR_ARCHIVE, "shows renderer speeds" );
Cvar_Get( "r_fullbright", "0", FCVAR_CHEAT, "disable lightmaps, get fullbright for entities" );
Cvar_Get( "r_norefresh", "0", 0, "disable 3D rendering (use with caution)" );
Cvar_Get( "r_dynamic", "1", FCVAR_ARCHIVE, "allow dynamic lighting (dlights, lightstyles)" );
Cvar_Get( "r_lightmap", "0", FCVAR_CHEAT, "lightmap debugging tool" );
Cvar_Get( "tracerred", "0.8", 0, "tracer red component weight ( 0 - 1.0 )" );
Cvar_Get( "tracergreen", "0.8", 0, "tracer green component weight ( 0 - 1.0 )" );
Cvar_Get( "tracerblue", "0.4", 0, "tracer blue component weight ( 0 - 1.0 )" );
Cvar_Get( "traceralpha", "0.5", 0, "tracer alpha amount ( 0 - 1.0 )" );
Cvar_Get( "r_sprite_lerping", "1", FCVAR_ARCHIVE, "enables sprite animation lerping" );
Cvar_Get( "r_sprite_lighting", "1", FCVAR_ARCHIVE, "enables sprite lighting (blood etc)" );
Cvar_Get( "r_drawviewmodel", "1", 0, "draw firstperson weapon model" );
Cvar_Get( "r_glowshellfreq", "2.2", 0, "glowing shell frequency update" );
gl_vsync = Cvar_Get( "gl_vsync", "0", FCVAR_ARCHIVE, "enable vertical syncronization" );
gl_showtextures = Cvar_Get( "r_showtextures", "0", FCVAR_CHEAT, "show all uploaded textures" );
r_adjust_fov = Cvar_Get( "r_adjust_fov", "1", FCVAR_ARCHIVE, "making FOV adjustment for wide-screens" );
r_decals = Cvar_Get( "r_decals", "4096", FCVAR_ARCHIVE, "sets the maximum number of decals" );
gl_wgl_msaa_samples = Cvar_Get( "gl_wgl_msaa_samples", "0", FCVAR_GLCONFIG, "samples number for multisample anti-aliasing" );
gl_clear = Cvar_Get( "gl_clear", "0", FCVAR_ARCHIVE, "clearing screen after each frame" );
r_showtree = Cvar_Get( "r_showtree", "0", FCVAR_ARCHIVE, "build the graph of visible BSP tree" );
r_refdll = Cvar_Get( "r_refdll", "", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "choose renderer implementation, if supported" );
// cvars that are expected to exist by client.dll
// refdll should just get pointer to them
@@ -629,34 +667,36 @@ qboolean R_Init( void )
// 1. Command line `-ref` argument.
// 2. `ref_dll` cvar.
// 3. Detected renderers in `DEFAULT_RENDERERS` order.
requested[0] = 0;
requested[0] = '\0';
if( !Sys_GetParmFromCmdLine( "-ref", requested ) && COM_CheckString( r_refdll->string ) )
// r_refdll is set to empty by default, so we can change hardcoded defaults just in case
Q_strncpy( requested, r_refdll->string, sizeof( requested ) );
if( !success && Sys_GetParmFromCmdLine( "-ref", requested ))
if ( requested[0] )
success = R_LoadRenderer( requested );
if( !success && COM_CheckString( r_refdll.string ))
{
Q_strncpy( requested, r_refdll.string, sizeof( requested ));
success = R_LoadRenderer( requested );
}
if( !success )
{
int i;
for( i = 0; i < ref.numRenderers && !success; i++ )
// cycle through renderers that we collected in CollectRendererNames
for( i = 0; i < ref.numRenderers; i++ )
{
// skip renderer that was requested but failed to load
if( !Q_strcmp( requested, ref.shortNames[i] ))
if( !Q_strcmp( requested, ref.shortNames[i] ) )
continue;
success = R_LoadRenderer( ref.shortNames[i] );
// yay, found working one
if( success )
break;
}
}
if( !success )
{
Host_Error( "Can't initialize any renderer. Check your video drivers!\n" );
Host_Error( "Can't initialize any renderer. Check your video drivers!" );
return false;
}

View File

@@ -27,10 +27,9 @@ struct ref_state_s
HINSTANCE hInstance;
ref_interface_t dllFuncs;
// depends on build configuration
int numRenderers;
const char **shortNames;
const char **readableNames;
string shortNames[DEFAULT_RENDERERS_LEN];
string readableNames[DEFAULT_RENDERERS_LEN];
};
extern struct ref_state_s ref;
@@ -46,12 +45,13 @@ void R_GetTextureParms( int *w, int *h, int texnum );
void GL_RenderFrame( const struct ref_viewpass_s *rvp );
// common engine and renderer cvars
extern convar_t r_decals;
extern convar_t r_adjust_fov;
extern convar_t gl_clear;
extern convar_t *r_decals;
extern convar_t *r_adjust_fov;
extern convar_t *gl_clear;
qboolean R_Init( void );
void R_Shutdown( void );
void R_UpdateRefState( void );
extern triangleapi_t gTriApi;

View File

@@ -1,7 +1,6 @@
/*
s_dsp.c - digital signal processing algorithms for audio FX
Copyright (C) 2009 Uncle Mike
Copyright (C) 2016-2024 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
@@ -34,6 +33,7 @@ GNU General Public License for more details.
#define MAXDLY (STEREODLY + 1)
#define MAXLP 10
#define MAXPRESETS 29
typedef struct sx_preset_s
{
@@ -79,7 +79,7 @@ typedef struct dly_s
int *lpdelayline;
} dly_t;
static const sx_preset_t rgsxpre[] =
const sx_preset_t rgsxpre[MAXPRESETS] =
{
// -------reverb-------- -------delay--------
// lp mod size refl rvblp delay feedback dlylp left
@@ -116,7 +116,7 @@ static const sx_preset_t rgsxpre[] =
// 0x0045dca8 enginegl.exe
// SHA256: 42383d32cd712e59ee2c1bd78b7ba48814e680e7026c4223e730111f34a60d66
static const sx_preset_t rgsxpre_hlalpha052[] =
const sx_preset_t rgsxpre_hlalpha052[MAXPRESETS] =
{
// -------reverb-------- -------delay--------
// lp mod size refl rvblp delay feedback dlylp left
@@ -151,50 +151,51 @@ static const sx_preset_t rgsxpre_hlalpha052[] =
{ 0.0, 0.0, 0.001, 0.999, 0.0, 0.2, 0.8, 2.0, 0.05 }, // 28
};
static const sx_preset_t *ptable = rgsxpre;
const sx_preset_t *ptable = rgsxpre;
// cvars
static CVAR_DEFINE_AUTO( dsp_off, "0", FCVAR_ARCHIVE, "disable DSP processing" );
static CVAR_DEFINE_AUTO( dsp_coeff_table, "0", FCVAR_ARCHIVE, "select DSP coefficient table: 0 for release or 1 for alpha 0.52" );
static CVAR_DEFINE_AUTO( room_type, "0", 0, "current room type preset" );
static CVAR_DEFINE( roomwater_type, "waterroom_type", "14", 0, "water room type" );
static CVAR_DEFINE( hisound, "room_hires", "2", FCVAR_ARCHIVE, "dsp quality. 1 for 22k, 2 for 44k(recommended) and 3 for 96k" );
convar_t *dsp_off; // disable dsp
convar_t *roomwater_type; // water room_type
convar_t *room_type; // current room type
convar_t *hisound; // DSP quality
// underwater/special fx modulations
static CVAR_DEFINE( sxmod_mod, "room_mod", "0", 0, "stereo amptitude modulation for room" );
static CVAR_DEFINE( sxmod_lowpass, "room_lp", "0", 0, "for water fx, lowpass for entire room" );
convar_t *sxmod_mod;
convar_t *sxmod_lowpass;
// stereo delay(no feedback)
static CVAR_DEFINE( sxste_delay, "room_left", "0", 0, "left channel delay time" );
convar_t *sxste_delay; // straight left delay
// mono reverb
static CVAR_DEFINE( sxrvb_lp, "room_rvblp", "1", 0, "reverb: low pass filtering level" );
static CVAR_DEFINE( sxrvb_feedback, "room_refl", "0", 0, "reverb: decay time" );
static CVAR_DEFINE( sxrvb_size, "room_size", "0", 0, "reverb: initial reflection size" );
convar_t *sxrvb_lp; // lowpass
convar_t *sxrvb_feedback; // reverb decay. Higher -- longer
convar_t *sxrvb_size; // room size. Higher -- larger
// mono delay
static CVAR_DEFINE( sxdly_lp, "room_dlylp", "1", 0, "mono delay: low pass filtering level" );
static CVAR_DEFINE( sxdly_feedback, "room_feedback", "0.2", 0, "mono delay: decay time" );
static CVAR_DEFINE( sxdly_delay, "room_delay", "0.8", 0, "mono delay: delay time" );
convar_t *sxdly_lp; // lowpass
convar_t *sxdly_feedback; // cycles
convar_t *sxdly_delay; // current delay in seconds
static int idsp_dma_speed;
convar_t *dsp_room; // for compability
convar_t *dsp_coeff_table; // use release or 0.52 style
int idsp_dma_speed;
int idsp_room;
static int room_typeprev;
int room_typeprev;
// routines
static int sxamodl, sxamodr; // amplitude modulation values
static int sxamodlt, sxamodrt; // modulation targets
static int sxmod1cur, sxmod2cur;
static int sxmod1, sxmod2;
static int sxhires;
int sxamodl, sxamodr; // amplitude modulation values
int sxamodlt, sxamodrt; // modulation targets
int sxmod1cur, sxmod2cur;
int sxmod1, sxmod2;
int sxhires;
static portable_samplepair_t *paintto = NULL;
portable_samplepair_t *paintto = NULL;
static dly_t rgsxdly[MAXDLY]; // stereo is last
static int rgsxlp[MAXLP];
dly_t rgsxdly[MAXDLY]; // stereo is last
int rgsxlp[MAXLP];
static void SX_Profiling_f( void );
void SX_Profiling_f( void );
/*
============
@@ -202,12 +203,14 @@ SX_ReloadRoomFX
============
*/
static void SX_ReloadRoomFX( void )
void SX_ReloadRoomFX( void )
{
SetBits( sxste_delay.flags, FCVAR_CHANGED );
SetBits( sxrvb_feedback.flags, FCVAR_CHANGED );
SetBits( sxdly_delay.flags, FCVAR_CHANGED );
SetBits( room_type.flags, FCVAR_CHANGED );
if( !dsp_room ) return; // not initialized
SetBits( sxste_delay->flags, FCVAR_CHANGED );
SetBits( sxrvb_feedback->flags, FCVAR_CHANGED );
SetBits( sxdly_delay->flags, FCVAR_CHANGED );
SetBits( room_type->flags, FCVAR_CHANGED );
}
/*
@@ -225,33 +228,36 @@ void SX_Init( void )
sxamodr = sxamodl = sxamodrt = sxamodlt = 255;
idsp_dma_speed = SOUND_11k;
Cvar_RegisterVariable( &hisound );
hisound = Cvar_Get( "room_hires", "2", FCVAR_ARCHIVE, "dsp quality. 1 for 22k, 2 for 44k(recommended) and 3 for 96k" );
sxhires = 2;
sxmod1cur = sxmod1 = 350 * ( idsp_dma_speed / SOUND_11k );
sxmod2cur = sxmod2 = 450 * ( idsp_dma_speed / SOUND_11k );
Cvar_RegisterVariable( &dsp_off );
Cvar_RegisterVariable( &dsp_coeff_table );
dsp_off = Cvar_Get( "dsp_off", "0", FCVAR_ARCHIVE, "disable DSP processing" );
dsp_coeff_table = Cvar_Get( "dsp_coeff_table", "0", FCVAR_ARCHIVE, "select DSP coefficient table: 0 for release or 1 for alpha 0.52" );
Cvar_RegisterVariable( &roomwater_type );
Cvar_RegisterVariable( &room_type );
roomwater_type = Cvar_Get( "waterroom_type", "14", 0, "water room type" );
room_type = Cvar_Get( "room_type", "0", 0, "current room type preset" );
Cvar_RegisterVariable( &sxmod_lowpass );
Cvar_RegisterVariable( &sxmod_mod );
sxmod_lowpass = Cvar_Get( "room_lp", "0", 0, "for water fx, lowpass for entire room" );
sxmod_mod = Cvar_Get( "room_mod", "0", 0, "stereo amptitude modulation for room" );
Cvar_RegisterVariable( &sxrvb_size );
Cvar_RegisterVariable( &sxrvb_feedback );
Cvar_RegisterVariable( &sxrvb_lp );
sxrvb_size = Cvar_Get( "room_size", "0", 0, "reverb: initial reflection size" );
sxrvb_feedback = Cvar_Get( "room_refl", "0", 0, "reverb: decay time" );
sxrvb_lp = Cvar_Get( "room_rvblp", "1", 0, "reverb: low pass filtering level" );
Cvar_RegisterVariable( &sxdly_delay );
Cvar_RegisterVariable( &sxdly_feedback );
Cvar_RegisterVariable( &sxdly_lp );
sxdly_delay = Cvar_Get( "room_delay", "0.8", 0, "mono delay: delay time" );
sxdly_feedback = Cvar_Get( "room_feedback", "0.2", 0, "mono delay: decay time" );
sxdly_lp = Cvar_Get( "room_dlylp", "1", 0, "mono delay: low pass filtering level" );
Cvar_RegisterVariable( &sxste_delay );
sxste_delay = Cvar_Get( "room_left", "0", 0, "left channel delay time" );
Cmd_AddCommand( "dsp_profile", SX_Profiling_f, "dsp stress-test, first argument is room_type" );
// for compability
dsp_room = room_type;
SX_ReloadRoomFX();
}
@@ -262,7 +268,7 @@ DLY_Free
Free memory allocated for DSP
===========
*/
static void DLY_Free( int idelay )
void DLY_Free( int idelay )
{
Assert( idelay >= 0 && idelay < MAXDLY );
@@ -298,7 +304,7 @@ DLY_Init
Initialize dly
===========
*/
static int DLY_Init( int idelay, float delay )
int DLY_Init( int idelay, float delay )
{
dly_t *cur;
@@ -334,7 +340,7 @@ DLY_MovePointer
Checks overflow and moves pointer
============
*/
static void DLY_MovePointer( dly_t *dly )
_inline void DLY_MovePointer( dly_t *dly )
{
if( ++dly->idelayinput >= dly->cdelaysamplesmax )
dly->idelayinput = 0;
@@ -350,12 +356,12 @@ DLY_CheckNewStereoDelayVal
Update stereo processor settings if we are in new room
=============
*/
static void DLY_CheckNewStereoDelayVal( void )
void DLY_CheckNewStereoDelayVal( void )
{
dly_t *const dly = &rgsxdly[STEREODLY];
float delay = sxste_delay.value;
float delay = sxste_delay->value;
if( !FBitSet( sxste_delay.flags, FCVAR_CHANGED ))
if( !FBitSet( sxste_delay->flags, FCVAR_CHANGED ))
return;
if( delay == 0 )
@@ -398,7 +404,7 @@ DLY_DoStereoDelay
Do stereo processing
=============
*/
static void DLY_DoStereoDelay( int count )
void DLY_DoStereoDelay( int count )
{
int delay, samplexf;
dly_t *const dly = &rgsxdly[STEREODLY];
@@ -463,12 +469,12 @@ DLY_CheckNewDelayVal
Update delay processor settings if we are in new room
=============
*/
static void DLY_CheckNewDelayVal( void )
void DLY_CheckNewDelayVal( void )
{
float delay = sxdly_delay.value;
float delay = sxdly_delay->value;
dly_t *const dly = &rgsxdly[MONODLY];
if( FBitSet( sxdly_delay.flags, FCVAR_CHANGED ))
if( FBitSet( sxdly_delay->flags, FCVAR_CHANGED ))
{
if( delay == 0 )
{
@@ -476,7 +482,7 @@ static void DLY_CheckNewDelayVal( void )
}
else
{
delay = Q_min( delay, MAX_MONO_DELAY );
delay = min( delay, MAX_MONO_DELAY );
dly->delaysamples = (int)(delay * idsp_dma_speed) << sxhires;
// init dly
@@ -498,8 +504,8 @@ static void DLY_CheckNewDelayVal( void )
}
}
dly->lp = sxdly_lp.value;
dly->delayfeedback = 255 * sxdly_feedback.value;
dly->lp = sxdly_lp->value;
dly->delayfeedback = 255 * sxdly_feedback->value;
}
/*
@@ -509,7 +515,7 @@ DLY_DoDelay
Do delay processing
=============
*/
static void DLY_DoDelay( int count )
void DLY_DoDelay( int count )
{
dly_t *const dly = &rgsxdly[MONODLY];
portable_samplepair_t *paint = paintto;
@@ -560,7 +566,7 @@ RVB_SetUpDly
Set up dly for reverb
===========
*/
static void RVB_SetUpDly( int pos, float delay, int kmod )
void RVB_SetUpDly( int pos, float delay, int kmod )
{
int samples;
@@ -596,13 +602,13 @@ RVB_CheckNewReverbVal
Update reverb settings if we are in new room
===========
*/
static void RVB_CheckNewReverbVal( void )
void RVB_CheckNewReverbVal( void )
{
dly_t *const dly1 = &rgsxdly[REVERBPOS];
dly_t *const dly2 = &rgsxdly[REVERBPOS + 1];
float delay = sxrvb_size.value;
float delay = sxrvb_size->value;
if( FBitSet( sxrvb_size.flags, FCVAR_CHANGED ))
if( FBitSet( sxrvb_size->flags, FCVAR_CHANGED ))
{
if( delay == 0.0f )
{
@@ -611,13 +617,13 @@ static void RVB_CheckNewReverbVal( void )
}
else
{
RVB_SetUpDly( REVERBPOS, sxrvb_size.value, 500 );
RVB_SetUpDly( REVERBPOS+1, sxrvb_size.value * 0.71f, 700 );
RVB_SetUpDly( REVERBPOS, sxrvb_size->value, 500 );
RVB_SetUpDly( REVERBPOS+1, sxrvb_size->value * 0.71f, 700 );
}
}
dly1->lp = dly2->lp = sxrvb_lp.value;
dly1->delayfeedback = dly2->delayfeedback = (int)(255 * sxrvb_feedback.value);
dly1->lp = dly2->lp = sxrvb_lp->value;
dly1->delayfeedback = dly2->delayfeedback = (int)(255 * sxrvb_feedback->value);
}
/*
@@ -627,7 +633,7 @@ RVB_DoReverbForOneDly
Do reverberation for one dly
===========
*/
static int RVB_DoReverbForOneDly( dly_t *dly, const int vlr, const portable_samplepair_t *samplepair )
int RVB_DoReverbForOneDly( dly_t *dly, const int vlr, const portable_samplepair_t *samplepair )
{
int delay;
int samplexf;
@@ -701,7 +707,7 @@ RVB_DoReverb
Do reverberation processing
===========
*/
static void RVB_DoReverb( int count )
void RVB_DoReverb( int count )
{
dly_t *const dly1 = &rgsxdly[REVERBPOS];
dly_t *const dly2 = &rgsxdly[REVERBPOS+1];
@@ -718,7 +724,7 @@ static void RVB_DoReverb( int count )
voutm = RVB_DoReverbForOneDly( dly1, vlr, paint );
voutm += RVB_DoReverbForOneDly( dly2, vlr, paint );
if( dsp_coeff_table.value == 1.0f )
if( dsp_coeff_table->value == 1.0f )
voutm /= 6; // alpha
else voutm = (11 * voutm) >> 6;
@@ -734,18 +740,18 @@ RVB_DoAMod
Do amplification modulation processing
===========
*/
static void RVB_DoAMod( int count )
void RVB_DoAMod( int count )
{
portable_samplepair_t *paint = paintto;
if( !sxmod_lowpass.value && !sxmod_mod.value )
if( !sxmod_lowpass->value && !sxmod_mod->value )
return;
for( ; count; count--, paint++ )
{
portable_samplepair_t res = *paint;
if( sxmod_lowpass.value )
if( sxmod_lowpass->value )
{
res.left = rgsxlp[0] + rgsxlp[1] + rgsxlp[2] + rgsxlp[3] + rgsxlp[4] + res.left;
res.right = rgsxlp[5] + rgsxlp[6] + rgsxlp[7] + rgsxlp[8] + rgsxlp[9] + res.right;
@@ -767,7 +773,7 @@ static void RVB_DoAMod( int count )
rgsxlp[8] = rgsxlp[9];
}
if( sxmod_mod.value )
if( sxmod_mod->value )
{
if( --sxmod1cur < 0 )
sxmod1cur = sxmod1;
@@ -807,9 +813,13 @@ DSP_Process
(xash dsp interface)
===========
*/
void DSP_Process( portable_samplepair_t *pbfront, int sampleCount )
void DSP_Process( int idsp, portable_samplepair_t *pbfront, int sampleCount )
{
if( dsp_off.value || !sampleCount )
if( dsp_off->value )
return;
// don't process DSP while in menu
if( cls.key_dest == key_menu || !sampleCount )
return;
// preset is already installed by CheckNewDspPresets
@@ -830,7 +840,7 @@ DSP_ClearState
*/
void DSP_ClearState( void )
{
Cvar_DirectSet( &room_type, "0" );
Cvar_SetValue( "room_type", 0.0f );
SX_ReloadRoomFX();
}
@@ -843,12 +853,12 @@ CheckNewDspPresets
*/
void CheckNewDspPresets( void )
{
if( dsp_off.value != 0.0f )
if( dsp_off->value != 0.0f )
return;
if( FBitSet( dsp_coeff_table.flags, FCVAR_CHANGED ))
if( FBitSet( dsp_coeff_table->flags, FCVAR_CHANGED ))
{
switch( (int)dsp_coeff_table.value )
switch( (int)dsp_coeff_table->value )
{
case 0: // release
ptable = rgsxpre;
@@ -864,40 +874,43 @@ void CheckNewDspPresets( void )
SX_ReloadRoomFX();
room_typeprev = -1;
ClearBits( dsp_coeff_table.flags, FCVAR_CHANGED );
ClearBits( dsp_coeff_table->flags, FCVAR_CHANGED );
}
if( s_listener.waterlevel > 2 )
idsp_room = roomwater_type.value;
else idsp_room = room_type.value;
idsp_room = roomwater_type->value;
else idsp_room = room_type->value;
// don't pass invalid presets
idsp_room = bound( 0, idsp_room, MAX_ROOM_TYPES );
idsp_room = bound( 0, idsp_room, MAXPRESETS - 1 );
if( FBitSet( hisound.flags, FCVAR_CHANGED ))
if( FBitSet( hisound->flags, FCVAR_CHANGED ))
{
sxhires = hisound.value;
ClearBits( hisound.flags, FCVAR_CHANGED );
sxhires = hisound->value;
ClearBits( hisound->flags, FCVAR_CHANGED );
}
if( idsp_room == room_typeprev && idsp_room == 0 )
return;
if( idsp_room > MAX_ROOM_TYPES )
return;
if( idsp_room != room_typeprev )
{
const sx_preset_t *cur;
cur = ptable + idsp_room;
Cvar_DirectSetValue( &sxmod_lowpass, cur->room_lp );
Cvar_DirectSetValue( &sxmod_mod, cur->room_mod );
Cvar_DirectSetValue( &sxrvb_size, cur->room_size );
Cvar_DirectSetValue( &sxrvb_feedback, cur->room_refl );
Cvar_DirectSetValue( &sxrvb_lp, cur->room_rvblp );
Cvar_DirectSetValue( &sxdly_delay, cur->room_delay );
Cvar_DirectSetValue( &sxdly_feedback, cur->room_feedback );
Cvar_DirectSetValue( &sxdly_lp, cur->room_dlylp );
Cvar_DirectSetValue( &sxste_delay, cur->room_left );
Cvar_SetValue( "room_lp", cur->room_lp );
Cvar_SetValue( "room_mod", cur->room_mod );
Cvar_SetValue( "room_size", cur->room_size );
Cvar_SetValue( "room_refl", cur->room_refl );
Cvar_SetValue( "room_rvblp", cur->room_rvblp );
Cvar_SetValue( "room_delay", cur->room_delay );
Cvar_SetValue( "room_feedback", cur->room_feedback );
Cvar_SetValue( "room_dlylp", cur->room_dlylp );
Cvar_SetValue( "room_left", cur->room_left );
}
room_typeprev = idsp_room;
@@ -906,15 +919,15 @@ void CheckNewDspPresets( void )
DLY_CheckNewDelayVal( );
DLY_CheckNewStereoDelayVal();
ClearBits( sxrvb_size.flags, FCVAR_CHANGED );
ClearBits( sxdly_delay.flags, FCVAR_CHANGED );
ClearBits( sxste_delay.flags, FCVAR_CHANGED );
ClearBits( sxrvb_size->flags, FCVAR_CHANGED );
ClearBits( sxdly_delay->flags, FCVAR_CHANGED );
ClearBits( sxste_delay->flags, FCVAR_CHANGED );
}
static void SX_Profiling_f( void )
void SX_Profiling_f( void )
{
portable_samplepair_t testbuffer[512];
float oldroom = room_type.value;
float oldroom = room_type->value;
double start, end;
int i, calls;
@@ -926,7 +939,7 @@ static void SX_Profiling_f( void )
if( Cmd_Argc() > 1 )
{
Cvar_DirectSetValue( &room_type, Q_atof( Cmd_Argv( 1 )));
Cvar_SetValue( "room_type", Q_atof( Cmd_Argv( 1 )));
SX_ReloadRoomFX();
CheckNewDspPresets(); // we just need idsp_room immediately, for message below
}
@@ -936,7 +949,7 @@ static void SX_Profiling_f( void )
start = Sys_DoubleTime();
for( calls = 10000; calls; calls-- )
{
DSP_Process( testbuffer, 512 );
DSP_Process( idsp_room, testbuffer, 512 );
}
end = Sys_DoubleTime();
@@ -944,7 +957,7 @@ static void SX_Profiling_f( void )
if( Cmd_Argc() > 1 )
{
Cvar_DirectSetValue( &room_type, oldroom );
Cvar_SetValue( "room_type", oldroom );
SX_ReloadRoomFX();
CheckNewDspPresets();
}

View File

@@ -14,7 +14,6 @@ GNU General Public License for more details.
*/
#include "common.h"
#include "client.h"
#include "sound.h"
// during registration it is possible to have more sounds
@@ -29,6 +28,7 @@ static sfx_t s_knownSfx[MAX_SFX];
static sfx_t *s_sfxHashList[MAX_SFX_HASH];
static string s_sentenceImmediateName; // keep dummy sentence name
qboolean s_registering = false;
int s_registration_sequence = 0;
/*
=================
@@ -54,7 +54,7 @@ void S_SoundList_f( void )
if( sc->loopStart >= 0 ) Con_Printf( "L" );
else Con_Printf( " " );
if( sfx->name[0] == '*' || !Q_strncmp( sfx->name, DEFAULT_SOUNDPATH, sizeof( DEFAULT_SOUNDPATH ) - 1 ))
if( sfx->name[0] == '*' )
Con_Printf( " (%2db) %s : %s\n", sc->width * 8, Q_memprint( sc->size ), sfx->name );
else Con_Printf( " (%2db) %s : " DEFAULT_SOUNDPATH "%s\n", sc->width * 8, Q_memprint( sc->size ), sfx->name );
totalSfx++;
@@ -199,7 +199,7 @@ sfx_t *S_FindName( const char *pname, int *pfInCache )
*pfInCache = ( sfx->cache != NULL ) ? true : false;
}
// prolonge registration
sfx->servercount = cl.servercount;
sfx->servercount = s_registration_sequence;
return sfx;
}
}
@@ -219,7 +219,7 @@ sfx_t *S_FindName( const char *pname, int *pfInCache )
memset( sfx, 0, sizeof( *sfx ));
if( pfInCache ) *pfInCache = false;
Q_strncpy( sfx->name, name, MAX_STRING );
sfx->servercount = cl.servercount;
sfx->servercount = s_registration_sequence;
sfx->hashValue = COM_HashKey( sfx->name, MAX_SFX_HASH );
// link it in
@@ -273,6 +273,7 @@ void S_BeginRegistration( void )
{
int i;
s_registration_sequence++;
snd_ambient = false;
// check for automatic ambient sounds
@@ -308,7 +309,7 @@ void S_EndRegistration( void )
if( !sfx->name[0] || !Q_stricmp( sfx->name, "*default" ))
continue; // don't release default sound
if( sfx->servercount != cl.servercount )
if( sfx->servercount != s_registration_sequence )
S_FreeSound( sfx ); // don't need this sound
}
@@ -348,7 +349,7 @@ sound_t S_RegisterSound( const char *name )
sfx = S_FindName( name, NULL );
if( !sfx ) return -1;
sfx->servercount = cl.servercount;
sfx->servercount = s_registration_sequence;
if( !s_registering ) S_LoadSound( sfx );
return sfx - s_knownSfx;

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