mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-06 04:05:11 +08:00
Compare commits
1 Commits
new_vgui_s
...
inotify
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc31c6588e |
106
.github/workflows/c-cpp.yml
vendored
106
.github/workflows/c-cpp.yml
vendored
@@ -13,33 +13,27 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- 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-20.04
|
||||
targetos: nswitch
|
||||
targetarch: arm64
|
||||
- os: ubuntu-20.04
|
||||
targetos: psvita
|
||||
targetarch: armv7hf
|
||||
- os: windows-latest
|
||||
targetos: win32
|
||||
targetarch: amd64
|
||||
@@ -47,80 +41,32 @@ jobs:
|
||||
targetos: win32
|
||||
targetarch: i386
|
||||
env:
|
||||
SDL_VERSION: 2.26.2
|
||||
SDL_VERSION: 2.0.14
|
||||
GH_CPU_ARCH: ${{ matrix.targetarch }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ANDROID_SDK_TOOLS_VER: 4333796
|
||||
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 (prereleases)
|
||||
run: bash scripts/continious_upload.sh artifacts/*
|
||||
- name: Upload engine (artifacts)
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v2
|
||||
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@v5
|
||||
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
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -16,6 +16,3 @@
|
||||
[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
|
||||
|
||||
29
3rdparty/extras/wscript
vendored
29
3rdparty/extras/wscript
vendored
@@ -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/extras/xash-extras
vendored
1
3rdparty/extras/xash-extras
vendored
Submodule 3rdparty/extras/xash-extras deleted from 853f633be1
2
3rdparty/gl-wes-v2
vendored
2
3rdparty/gl-wes-v2
vendored
Submodule 3rdparty/gl-wes-v2 updated: 0be6803f81...7f567393d4
2
3rdparty/gl4es/gl4es
vendored
2
3rdparty/gl4es/gl4es
vendored
Submodule 3rdparty/gl4es/gl4es updated: 277be116c1...5c28420a38
2
3rdparty/mainui
vendored
2
3rdparty/mainui
vendored
Submodule 3rdparty/mainui updated: 262128c0d1...14c0922af7
2
3rdparty/nanogl
vendored
2
3rdparty/nanogl
vendored
Submodule 3rdparty/nanogl updated: 5f2892a37e...5a22eab534
2
3rdparty/opus/opus
vendored
2
3rdparty/opus/opus
vendored
Submodule 3rdparty/opus/opus updated: 8cf872a186...997fdf54e7
2
3rdparty/vgui_support
vendored
2
3rdparty/vgui_support
vendored
Submodule 3rdparty/vgui_support updated: 27fbcbf2bf...63c134f188
@@ -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 ...
|
||||
@@ -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).
|
||||
@@ -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
|
||||
@@ -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 |
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -127,9 +127,6 @@ 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
|
||||
|
||||
|
||||
@@ -26,8 +26,7 @@ Table is sorted by status.
|
||||
| Haiku | Supported | not maintained | Was added by #478 and #483
|
||||
| DOS4GW | Supported | @mittorn |
|
||||
| GNU/Linux(mipsel) | Supported | @mittorn |
|
||||
| PSVita | Supported | @fgsfdsfgs |
|
||||
| Switch | Supported | @fgsfdsfgs |
|
||||
| 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 | @Crow_bar, @Velaron | [GitHub Repository](https://github.com/Crow-bar/xash3d-fwgs)
|
||||
| Emscripten | Old Engine | not maintained |
|
||||
|
||||
@@ -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/`.
|
||||
@@ -1,41 +0,0 @@
|
||||
# Experimental VGUI2 Support
|
||||
|
||||
Thanks to @kungfulon contributions, Xash3D FWGS now supports VGUI2.
|
||||
|
||||
VGUI2 is undocumented UI system from Source Engine that GoldSrc used in some games and it's main menu.
|
||||
|
||||
## Support status
|
||||
|
||||
Doesn't draw anything, doesn't take any input.
|
||||
|
||||
## List of games that require VGUI2 support
|
||||
|
||||
- Counter-Strike 1.6
|
||||
- Counter-Strike: Condition Zero
|
||||
- Counter-Strike: Condition Zero Deleted Scenes
|
||||
- Day of Defeat
|
||||
- Half-Life: Blue Shift
|
||||
|
||||
## How to enable VGUI2 support
|
||||
|
||||
By default, engine doesn't initialize VGUI2 to not confuse existing games and mods that use or do not use VGUI1. This support also relies on a number of proprietary libraries, that we better not redistribute, so you have to supply them yourself. Keep in mind, that these libraries are compiled only for 32-bit Windows, Linux and OSX, you shouldn't expect them running anywhere else.
|
||||
|
||||
1. Download latest Half-Life from Steam.
|
||||
2. Open local files.
|
||||
3. Copy libraries in the list below according to your platform, to folder where Xash3D searches it's libraries (usually in same folder where executable is located)
|
||||
|
||||
| Linux | Windows
|
||||
| -------- | --------
|
||||
| `chromehtml.so` | `chromehtml.dll`
|
||||
| `vgui2.so` | `vgui2.dll`
|
||||
| `libcef.so` | `libcef.dll`
|
||||
| `libtier0.so` | `tier0.dll`
|
||||
| `libvstdlib.so` | `vstdlib.dll`
|
||||
| `libsteam_api.so` | `steam_api.dll`
|
||||
|
||||
Some files must also be copied:
|
||||
- `cef_gtk.pak`
|
||||
|
||||
Additionally, on Linux other libraries must be provided. Use `ldd` tool to figure out which libraries you miss. Many of them can be pulled from Steam Runtime.
|
||||
|
||||
Do not recommend using RoDir with VGUI2 games. Many of them are broken. Steam API will crash without `steam_appid.txt` in Xash root directory.
|
||||
17
README.md
17
README.md
@@ -18,22 +18,19 @@ Read more about Xash3D on ModDB: https://www.moddb.com/engines/xash3d-engine
|
||||
* 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.
|
||||
* Multiple renderers support: OpenGL, GLESv1, GLESv2, Software.
|
||||
* Voice support.
|
||||
* External filesystem module like in GoldSrc engine.
|
||||
* External vgui support module.
|
||||
* PNG image format support.
|
||||
* Multiple renderers support: OpenGL, GLESv1, GLESv2, Software
|
||||
* A set of small improvements, without broken compatibility.
|
||||
|
||||
## Planned fork features
|
||||
* Virtual Reality support and game API.
|
||||
* Vulkan renderer.
|
||||
* 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.
|
||||
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).
|
||||
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-xash3d).
|
||||
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).
|
||||
@@ -52,10 +49,10 @@ NOTE: NEVER USE GitHub's ZIP ARCHIVES. GitHub doesn't include external dependenc
|
||||
|
||||
### 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.
|
||||
If your CPU is x86 compatible, we are building 32-bit code by default. This was dont 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!
|
||||
|
||||
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).
|
||||
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-xash3d).
|
||||
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)
|
||||
|
||||
@@ -29,6 +29,12 @@ GNU General Public License for more details.
|
||||
#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
|
||||
@@ -47,7 +53,6 @@ GNU General Public License for more details.
|
||||
#define MSGBOX_SDL 1
|
||||
#define MSGBOX_ANDROID 2
|
||||
#define MSGBOX_WIN32 3
|
||||
#define MSGBOX_NSWITCH 4
|
||||
|
||||
|
||||
// library loading (XASH_LIB)
|
||||
|
||||
@@ -61,16 +61,13 @@ 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
|
||||
@@ -81,7 +78,7 @@ BRUSH 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
|
||||
|
||||
@@ -49,7 +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
|
||||
} ilFlags_t;
|
||||
|
||||
// goes into rgbdata_t->encode
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -47,9 +47,7 @@ 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
|
||||
@@ -70,7 +68,7 @@ SETUP BACKENDS DEFINITIONS
|
||||
#define XASH_MESSAGEBOX MSGBOX_ANDROID
|
||||
#endif // XASH_MESSAGEBOX
|
||||
|
||||
#define XASH_USE_EVDEV 1
|
||||
#define XASH_USE_EVDEV
|
||||
#define XASH_DYNAMIC_DLADDR
|
||||
#elif XASH_LINUX
|
||||
// we are building for Linux without SDL2, can draw only to framebuffer yet
|
||||
@@ -86,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
|
||||
@@ -107,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
|
||||
//
|
||||
@@ -150,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
|
||||
|
||||
/*
|
||||
=========================================================================
|
||||
|
||||
@@ -158,51 +169,25 @@ 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_MOBILE_PLATFORM
|
||||
#if 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
|
||||
#endif // DEFAULT_FULLSCREEN
|
||||
|
||||
@@ -16,61 +16,22 @@
|
||||
#ifndef NETADR_H
|
||||
#define NETADR_H
|
||||
|
||||
#include "build.h"
|
||||
#include STDINT_H
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NA_UNUSED = 0,
|
||||
NA_UNUSED,
|
||||
NA_LOOPBACK,
|
||||
NA_BROADCAST,
|
||||
NA_IP,
|
||||
NA_IPX,
|
||||
NA_BROADCAST_IPX,
|
||||
NA_IP6,
|
||||
NA_MULTICAST_IP6, // all nodes multicast
|
||||
NA_BROADCAST_IPX
|
||||
} netadrtype_t;
|
||||
|
||||
// Original structure:
|
||||
// typedef struct netadr_s
|
||||
// {
|
||||
// netadrtype_t type;
|
||||
// unsigned char ip[4];
|
||||
// unsigned char ipx[10];
|
||||
// unsigned short port;
|
||||
// } netadr_t;
|
||||
|
||||
#pragma pack( push, 1 )
|
||||
typedef struct netadr_s
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t type;
|
||||
union
|
||||
{
|
||||
uint8_t ip[4];
|
||||
uint32_t ip4;
|
||||
};
|
||||
uint8_t ipx[10];
|
||||
};
|
||||
struct
|
||||
{
|
||||
#if XASH_LITTLE_ENDIAN
|
||||
uint16_t type6;
|
||||
uint8_t ip6[16];
|
||||
#elif XASH_BIG_ENDIAN
|
||||
uint8_t ip6_0[2];
|
||||
uint16_t type6;
|
||||
uint8_t ip6_2[14];
|
||||
#endif
|
||||
};
|
||||
};
|
||||
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, "invalid netadr_t size" );
|
||||
|
||||
#endif//NETADR_H
|
||||
|
||||
@@ -39,20 +39,16 @@ GNU General Public License for more details.
|
||||
|
||||
#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
|
||||
#include <dlfcn.h>
|
||||
|
||||
#define PATH_SPLITTER "/"
|
||||
#define HAVE_DUP
|
||||
|
||||
#define O_BINARY 0
|
||||
#define O_TEXT 0
|
||||
#define _mkdir( x ) mkdir( x, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH )
|
||||
#elif XASH_DOS4GW
|
||||
#define PATH_SPLITTER "\\"
|
||||
#endif
|
||||
|
||||
typedef void* HANDLE;
|
||||
@@ -63,6 +59,7 @@ GNU General Public License for more details.
|
||||
int x, y;
|
||||
} POINT;
|
||||
#else // WIN32
|
||||
#define PATH_SPLITTER "\\"
|
||||
#ifdef __MINGW32__
|
||||
#define _inline static inline
|
||||
#define FORCEINLINE inline __attribute__((always_inline))
|
||||
|
||||
@@ -161,7 +161,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 );
|
||||
|
||||
@@ -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
|
||||
@@ -4,17 +4,12 @@
|
||||
|
||||
#include "build.h"
|
||||
|
||||
#if XASH_IRIX
|
||||
#include <port.h>
|
||||
#endif
|
||||
|
||||
#if XASH_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 +22,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,7 +40,6 @@ 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
|
||||
@@ -114,11 +103,6 @@ typedef uint64_t longtime_t;
|
||||
#define likely(x) (x)
|
||||
#endif
|
||||
|
||||
#if defined( static_assert ) // C11 static_assert
|
||||
#define STATIC_ASSERT static_assert
|
||||
#else
|
||||
#define STATIC_ASSERT( x, y ) extern int _static_assert_##__LINE__[( x ) ? 1 : -1]
|
||||
#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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
;
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -145,7 +145,7 @@ void CL_PlayCDTrack_f( void )
|
||||
CL_ScreenshotGetName
|
||||
==================
|
||||
*/
|
||||
static qboolean CL_ScreenshotGetName( int lastnum, char *filename, size_t size )
|
||||
qboolean CL_ScreenshotGetName( int lastnum, char *filename )
|
||||
{
|
||||
if( lastnum < 0 || lastnum > 9999 )
|
||||
{
|
||||
@@ -153,7 +153,9 @@ static qboolean CL_ScreenshotGetName( int lastnum, char *filename, size_t size )
|
||||
return false;
|
||||
}
|
||||
|
||||
return Q_snprintf( filename, size, "scrshots/%s_shot%04d.png", clgame.mapname, lastnum ) > 0;
|
||||
Q_sprintf( filename, "scrshots/%s_shot%04d.png", clgame.mapname, lastnum );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -161,7 +163,7 @@ static qboolean CL_ScreenshotGetName( int lastnum, char *filename, size_t size )
|
||||
CL_SnapshotGetName
|
||||
==================
|
||||
*/
|
||||
static qboolean CL_SnapshotGetName( int lastnum, char *filename, size_t size )
|
||||
qboolean CL_SnapshotGetName( int lastnum, char *filename )
|
||||
{
|
||||
if( lastnum < 0 || lastnum > 9999 )
|
||||
{
|
||||
@@ -170,7 +172,9 @@ static qboolean CL_SnapshotGetName( int lastnum, char *filename, size_t size )
|
||||
return false;
|
||||
}
|
||||
|
||||
return Q_snprintf( filename, size, "../%s_%04d.png", clgame.mapname, lastnum ) > 0;
|
||||
Q_sprintf( filename, "../%s_%04d.png", clgame.mapname, lastnum );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -203,7 +207,7 @@ void CL_ScreenShot_f( void )
|
||||
// scan for a free filename
|
||||
for( i = 0; i < 9999; i++ )
|
||||
{
|
||||
if( !CL_ScreenshotGetName( i, checkname, sizeof( checkname )))
|
||||
if( !CL_ScreenshotGetName( i, checkname ))
|
||||
return; // no namespace
|
||||
|
||||
if( !FS_FileExists( checkname, false ))
|
||||
@@ -243,7 +247,7 @@ void CL_SnapShot_f( void )
|
||||
// scan for a free filename
|
||||
for( i = 0; i < 9999; i++ )
|
||||
{
|
||||
if( !CL_SnapshotGetName( i, checkname, sizeof( checkname )))
|
||||
if( !CL_SnapshotGetName( i, checkname ))
|
||||
return; // no namespace
|
||||
|
||||
if( !FS_FileExists( checkname, false ))
|
||||
@@ -274,7 +278,7 @@ void CL_EnvShot_f( void )
|
||||
return;
|
||||
}
|
||||
|
||||
Q_snprintf( cls.shotname, sizeof( cls.shotname ), "gfx/env/%s", Cmd_Argv( 1 ));
|
||||
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;
|
||||
@@ -295,7 +299,7 @@ void CL_SkyShot_f( void )
|
||||
return;
|
||||
}
|
||||
|
||||
Q_snprintf( cls.shotname, sizeof( cls.shotname ),"gfx/env/%s", Cmd_Argv( 1 ));
|
||||
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;
|
||||
@@ -319,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
|
||||
@@ -329,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 );
|
||||
@@ -358,7 +360,7 @@ void CL_SaveShot_f( void )
|
||||
return;
|
||||
}
|
||||
|
||||
Q_snprintf( cls.shotname, sizeof( cls.shotname ), DEFAULT_SAVE_DIRECTORY "%s.bmp", Cmd_Argv( 1 ));
|
||||
Q_sprintf( cls.shotname, DEFAULT_SAVE_DIRECTORY "%s.bmp", Cmd_Argv( 1 ));
|
||||
cls.scrshot_action = scrshot_savegame; // build new frame for saveshot
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -518,26 +518,14 @@ CL_ReadDemoCmdHeader
|
||||
read the demo command
|
||||
=================
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -925,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;
|
||||
@@ -1317,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.dem", size );
|
||||
Q_strcpy( filename, "demo9999" );
|
||||
return;
|
||||
}
|
||||
|
||||
Q_snprintf( filename, size, "demo%04d.dem", lastnum );
|
||||
Q_sprintf( filename, "demo%04d", lastnum );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1380,8 +1367,8 @@ void CL_Record_f( void )
|
||||
// scan for a free filename
|
||||
for( n = 0; n < 10000; n++ )
|
||||
{
|
||||
CL_DemoGetName( n, demoname, sizeof( demoname ));
|
||||
if( !FS_FileExists( demoname, true ))
|
||||
CL_DemoGetName( n, demoname );
|
||||
if( !FS_FileExists( va( "%s.dem", demoname ), true ))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1394,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 ))
|
||||
@@ -1421,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;
|
||||
}
|
||||
|
||||
@@ -1548,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,350 +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->nearest = FBitSet( texFlags, TF_NEAREST );
|
||||
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->nearest = FBitSet( texFlags, TF_NEAREST );
|
||||
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->nearest || font->scale <= 1.0f )
|
||||
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++;
|
||||
}
|
||||
}
|
||||
@@ -241,7 +241,7 @@ CL_GetStudioEstimatedFrame
|
||||
|
||||
====================
|
||||
*/
|
||||
static float CL_GetStudioEstimatedFrame( cl_entity_t *ent )
|
||||
float CL_GetStudioEstimatedFrame( cl_entity_t *ent )
|
||||
{
|
||||
studiohdr_t *pstudiohdr;
|
||||
mstudioseqdesc_t *pseqdesc;
|
||||
@@ -255,7 +255,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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -654,24 +654,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
|
||||
@@ -692,8 +674,8 @@ 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" );
|
||||
@@ -865,12 +847,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 )
|
||||
@@ -979,25 +970,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 ))
|
||||
{
|
||||
@@ -1007,8 +982,14 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !draw_player )
|
||||
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 ))
|
||||
return false;
|
||||
}
|
||||
|
||||
if( entityType == ET_BEAM )
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 )
|
||||
@@ -421,6 +421,54 @@ static void UI_ConvertGameInfo( GAMEINFO *out, gameinfo_t *in )
|
||||
out->flags |= GFL_RENDER_PICBUTTON_TEXT;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
PIC_DrawGeneric
|
||||
@@ -439,10 +487,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 )
|
||||
{
|
||||
@@ -463,9 +511,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 );
|
||||
}
|
||||
@@ -610,7 +659,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;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -621,7 +674,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;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -709,7 +766,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 );
|
||||
@@ -838,7 +895,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 )));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1205,8 +1262,7 @@ static ui_extendedfuncs_t gExtendedfuncs =
|
||||
pfnGetRenderers,
|
||||
Sys_DoubleTime,
|
||||
pfnParseFileSafe,
|
||||
NET_AdrToString,
|
||||
NET_CompareAdrSort,
|
||||
NET_AdrToString
|
||||
};
|
||||
|
||||
void UI_UnloadProgs( void )
|
||||
|
||||
@@ -22,14 +22,12 @@ GNU General Public License for more details.
|
||||
#include "vgui_draw.h"
|
||||
#include "library.h"
|
||||
#include "vid_common.h"
|
||||
#include "pm_local.h"
|
||||
#include "sequence.h"
|
||||
|
||||
#define MAX_TOTAL_CMDS 32
|
||||
#define MAX_CMD_BUFFER 8000
|
||||
#define CONNECTION_PROBLEM_TIME 15.0 // 15 seconds
|
||||
#define CL_CONNECTION_RETRIES 10
|
||||
#define CL_TEST_RETRIES_NORESPONCE 3
|
||||
#define CL_TEST_RETRIES_NORESPONCE 2
|
||||
#define CL_TEST_RETRIES 5
|
||||
|
||||
CVAR_DEFINE_AUTO( mp_decals, "300", FCVAR_ARCHIVE, "decals limit in multiplayer" );
|
||||
@@ -40,8 +38,8 @@ CVAR_DEFINE_AUTO( cl_allow_upload, "1", FCVAR_ARCHIVE, "allow to uploading resou
|
||||
CVAR_DEFINE_AUTO( cl_download_ingame, "1", FCVAR_ARCHIVE, "allow to downloading resources while client is active" );
|
||||
CVAR_DEFINE_AUTO( cl_logofile, "lambda", FCVAR_ARCHIVE, "player logo name" );
|
||||
CVAR_DEFINE_AUTO( cl_logocolor, "orange", FCVAR_ARCHIVE, "player logo color" );
|
||||
CVAR_DEFINE_AUTO( cl_logoext, "bmp", FCVAR_ARCHIVE, "temporary cvar to tell engine which logo must be packed" );
|
||||
CVAR_DEFINE_AUTO( cl_test_bandwidth, "1", FCVAR_ARCHIVE, "test network bandwith before connection" );
|
||||
convar_t *rcon_client_password;
|
||||
convar_t *rcon_address;
|
||||
convar_t *cl_timeout;
|
||||
convar_t *cl_nopred;
|
||||
@@ -58,7 +56,6 @@ convar_t *cl_nosmooth;
|
||||
convar_t *cl_smoothtime;
|
||||
convar_t *cl_clockreset;
|
||||
convar_t *cl_fixtimerate;
|
||||
convar_t *hud_fontscale;
|
||||
convar_t *hud_scale;
|
||||
convar_t *cl_solid_players;
|
||||
convar_t *cl_draw_beams;
|
||||
@@ -150,6 +147,16 @@ qboolean CL_DisableVisibility( void )
|
||||
return cls.envshot_disable_vis;
|
||||
}
|
||||
|
||||
qboolean CL_IsBackgroundDemo( void )
|
||||
{
|
||||
return ( cls.demoplayback && cls.demonum != -1 );
|
||||
}
|
||||
|
||||
qboolean CL_IsBackgroundMap( void )
|
||||
{
|
||||
return ( cl.background && !cls.demoplayback );
|
||||
}
|
||||
|
||||
char *CL_Userinfo( void )
|
||||
{
|
||||
return cls.userinfo;
|
||||
@@ -230,13 +237,15 @@ void CL_SignonReply( void )
|
||||
if( cl.proxy_redirect && !cls.spectator )
|
||||
CL_Disconnect();
|
||||
cl.proxy_redirect = false;
|
||||
|
||||
if( cls.demoplayback )
|
||||
Sequence_OnLevelLoad( clgame.mapname );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float CL_LerpInterval( void )
|
||||
{
|
||||
return Q_max( cl_interp->value, 1.f / cl_updaterate->value );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CL_LerpPoint
|
||||
@@ -247,26 +256,55 @@ should be put at.
|
||||
*/
|
||||
static float CL_LerpPoint( void )
|
||||
{
|
||||
double f = cl_serverframetime();
|
||||
double frac;
|
||||
float frac = 1.0f;
|
||||
float server_frametime = cl_serverframetime();
|
||||
|
||||
if( f == 0.0 || cls.timedemo )
|
||||
if( server_frametime == 0.0f || cls.timedemo )
|
||||
{
|
||||
double fgap = cl_clientframetime();
|
||||
cl.time = cl.mtime[0];
|
||||
|
||||
// maybe don't need for Xash demos
|
||||
if( cls.demoplayback )
|
||||
cl.oldtime = cl.mtime[0] - fgap;
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
if( cl_interp->value <= 0.001 )
|
||||
return 1.0f;
|
||||
|
||||
frac = ( cl.time - cl.mtime[0] ) / cl_interp->value;
|
||||
|
||||
if( server_frametime > 0.1f )
|
||||
{
|
||||
// dropped packet, or start of demo
|
||||
cl.mtime[1] = cl.mtime[0] - 0.1f;
|
||||
server_frametime = 0.1f;
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
g-cont: this code more suitable for singleplayer
|
||||
NOTE in multiplayer causes significant framerate stutter/jitter and
|
||||
occuring frames with zero time delta and even with negative time delta.
|
||||
game becomes more twitchy and as if without interpolation.
|
||||
*/
|
||||
frac = (cl.time - cl.mtime[1]) / f;
|
||||
if( frac < 0.0f )
|
||||
{
|
||||
if( frac < -0.01f )
|
||||
cl.time = cl.mtime[1];
|
||||
frac = 0.0f;
|
||||
}
|
||||
else if( frac > 1.0f )
|
||||
{
|
||||
if( frac > 1.01f )
|
||||
cl.time = cl.mtime[0];
|
||||
frac = 1.0f;
|
||||
}
|
||||
#else
|
||||
// for multiplayer
|
||||
if( cl_interp->value > 0.001f )
|
||||
{
|
||||
// manual lerp value (goldsrc mode)
|
||||
float td = Q_max( 0.f, cl.time - cl.mtime[0] );
|
||||
frac = td / CL_LerpInterval();
|
||||
}
|
||||
else if( server_frametime > 0.001f )
|
||||
{
|
||||
// automatic lerp (classic mode)
|
||||
frac = ( cl.time - cl.mtime[1] ) / server_frametime;
|
||||
}
|
||||
#endif
|
||||
return frac;
|
||||
}
|
||||
|
||||
@@ -308,7 +346,7 @@ Validate interpolation cvars, calc interpolation window
|
||||
void CL_ComputeClientInterpolationAmount( usercmd_t *cmd )
|
||||
{
|
||||
const float epsilon = 0.001f; // to avoid float invalid comparision
|
||||
float min_interp;
|
||||
float min_interp = MIN_EX_INTERP;
|
||||
float max_interp = MAX_EX_INTERP;
|
||||
float interpolation_time;
|
||||
|
||||
@@ -328,7 +366,7 @@ void CL_ComputeClientInterpolationAmount( usercmd_t *cmd )
|
||||
max_interp = 0.2f;
|
||||
|
||||
min_interp = 1.0f / cl_updaterate->value;
|
||||
interpolation_time = cl_interp->value * 1000.0;
|
||||
interpolation_time = CL_LerpInterval( );
|
||||
|
||||
if( (cl_interp->value + epsilon) < min_interp )
|
||||
{
|
||||
@@ -584,7 +622,7 @@ CL_CreateCmd
|
||||
*/
|
||||
void CL_CreateCmd( void )
|
||||
{
|
||||
usercmd_t nullcmd, *cmd;
|
||||
usercmd_t cmd;
|
||||
runcmd_t *pcmd;
|
||||
vec3_t angles;
|
||||
qboolean active;
|
||||
@@ -597,6 +635,7 @@ void CL_CreateCmd( void )
|
||||
// store viewangles in case it's will be freeze
|
||||
VectorCopy( cl.viewangles, angles );
|
||||
ms = bound( 1, host.frametime * 1000, 255 );
|
||||
memset( &cmd, 0, sizeof( cmd ));
|
||||
input_override = 0;
|
||||
|
||||
CL_SetSolidEntities();
|
||||
@@ -615,18 +654,12 @@ void CL_CreateCmd( void )
|
||||
pcmd->receivedtime = -1.0;
|
||||
pcmd->heldback = false;
|
||||
pcmd->sendsize = 0;
|
||||
cmd = &pcmd->cmd;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset( &nullcmd, 0, sizeof( nullcmd ));
|
||||
cmd = &nullcmd;
|
||||
}
|
||||
|
||||
active = (( cls.signon == SIGNONS ) && !cl.paused && !cls.demoplayback );
|
||||
Platform_PreCreateMove();
|
||||
clgame.dllFuncs.CL_CreateMove( host.frametime, cmd, active );
|
||||
IN_EngineAppendMove( host.frametime, cmd, active );
|
||||
clgame.dllFuncs.CL_CreateMove( host.frametime, &pcmd->cmd, active );
|
||||
IN_EngineAppendMove( host.frametime, &pcmd->cmd, active );
|
||||
|
||||
CL_PopPMStates();
|
||||
|
||||
@@ -703,22 +736,15 @@ void CL_WritePacket( void )
|
||||
|
||||
CL_ComputePacketLoss ();
|
||||
|
||||
memset( data, 0, sizeof( data ));
|
||||
MSG_Init( &buf, "ClientData", data, sizeof( data ));
|
||||
|
||||
// Determine number of backup commands to send along
|
||||
numbackup = bound( 0, cl_cmdbackup->value, cls.legacymode ? MAX_LEGACY_BACKUP_CMDS : MAX_BACKUP_COMMANDS );
|
||||
numbackup = bound( 0, cl_cmdbackup->value, MAX_BACKUP_COMMANDS );
|
||||
if( cls.state == ca_connected ) numbackup = 0;
|
||||
|
||||
// clamp cmdrate
|
||||
if( cl_cmdrate->value < 10.0f )
|
||||
{
|
||||
Cvar_SetValue( "cl_cmdrate", 10.0f );
|
||||
}
|
||||
else if( cl_cmdrate->value > 100.0f )
|
||||
{
|
||||
Cvar_SetValue( "cl_cmdrate", 100.0f );
|
||||
}
|
||||
if( cl_cmdrate->value < 0.0f ) Cvar_SetValue( "cl_cmdrate", 0.0f );
|
||||
else if( cl_cmdrate->value > 100.0f ) Cvar_SetValue( "cl_cmdrate", 100.0f );
|
||||
|
||||
// Check to see if we can actually send this command
|
||||
|
||||
@@ -748,7 +774,6 @@ void CL_WritePacket( void )
|
||||
if(( host.realtime - cls.netchan.last_received ) > CONNECTION_PROBLEM_TIME )
|
||||
{
|
||||
Con_NPrintf( 1, "^3Warning:^1 Connection Problem^7\n" );
|
||||
Con_NPrintf( 2, "^1Auto-disconnect in %.1f seconds^7", cl_timeout->value - ( host.realtime - cls.netchan.last_received ));
|
||||
cl.validsequence = 0;
|
||||
}
|
||||
}
|
||||
@@ -788,13 +813,12 @@ void CL_WritePacket( void )
|
||||
newcmds = ( cls.netchan.outgoing_sequence - cls.lastoutgoingcommand );
|
||||
|
||||
// put an upper/lower bound on this
|
||||
newcmds = bound( 0, newcmds, cls.legacymode ? MAX_LEGACY_TOTAL_CMDS: MAX_TOTAL_CMDS );
|
||||
newcmds = bound( 0, newcmds, cls.legacymode?MAX_LEGACY_TOTAL_CMDS:MAX_TOTAL_CMDS );
|
||||
if( cls.state == ca_connected ) newcmds = 0;
|
||||
|
||||
MSG_WriteByte( &buf, newcmds );
|
||||
|
||||
numcmds = newcmds + numbackup;
|
||||
|
||||
from = -1;
|
||||
|
||||
for( i = numcmds - 1; i >= 0; i-- )
|
||||
@@ -1020,12 +1044,9 @@ void CL_SendConnectPacket( void )
|
||||
input_devices = IN_CollectInputDevices();
|
||||
IN_LockInputDevices( true );
|
||||
|
||||
Cvar_SetCheatState();
|
||||
Cvar_FullSet( "sv_cheats", "0", FCVAR_READ_ONLY | FCVAR_SERVER );
|
||||
|
||||
Info_SetValueForKeyf( protinfo, "d", sizeof( protinfo ), "%d", input_devices );
|
||||
Info_SetValueForKey( protinfo, "d", va( "%d", input_devices ), sizeof( protinfo ) );
|
||||
Info_SetValueForKey( protinfo, "v", XASH_VERSION, sizeof( protinfo ) );
|
||||
Info_SetValueForKeyf( protinfo, "b", sizeof( protinfo ), "%d", Q_buildnum( ));
|
||||
Info_SetValueForKey( protinfo, "b", va( "%d", Q_buildnum() ), sizeof( protinfo ) );
|
||||
Info_SetValueForKey( protinfo, "o", Q_buildos(), sizeof( protinfo ) );
|
||||
Info_SetValueForKey( protinfo, "a", Q_buildarch(), sizeof( protinfo ) );
|
||||
}
|
||||
@@ -1059,7 +1080,7 @@ void CL_SendConnectPacket( void )
|
||||
|
||||
Info_SetValueForKey( protinfo, "uuid", key, sizeof( protinfo ));
|
||||
Info_SetValueForKey( protinfo, "qport", qport, sizeof( protinfo ));
|
||||
Info_SetValueForKeyf( protinfo, "ext", sizeof( protinfo ), "%d", extensions);
|
||||
Info_SetValueForKey( protinfo, "ext", va("%d", extensions), sizeof( protinfo ));
|
||||
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "connect %i %i \"%s\" \"%s\"\n", PROTOCOL_VERSION, cls.challenge, protinfo, cls.userinfo );
|
||||
Con_Printf( "Trying to connect by modern protocol\n" );
|
||||
@@ -1077,9 +1098,8 @@ Resend a connect message if the last one has timed out
|
||||
*/
|
||||
void CL_CheckForResend( void )
|
||||
{
|
||||
netadr_t adr;
|
||||
net_gai_state_t res;
|
||||
qboolean bandwidthTest;
|
||||
netadr_t adr;
|
||||
int res;
|
||||
|
||||
if( cls.internetservers_wait )
|
||||
CL_InternetServers_f();
|
||||
@@ -1111,13 +1131,13 @@ void CL_CheckForResend( void )
|
||||
|
||||
res = NET_StringToAdrNB( cls.servername, &adr );
|
||||
|
||||
if( res == NET_EAI_NONAME )
|
||||
if( !res )
|
||||
{
|
||||
CL_Disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
if( res == NET_EAI_AGAIN )
|
||||
if( res == 2 )
|
||||
{
|
||||
cls.connect_time = MAX_HEARTBEAT;
|
||||
return;
|
||||
@@ -1144,18 +1164,14 @@ void CL_CheckForResend( void )
|
||||
return;
|
||||
}
|
||||
|
||||
bandwidthTest = !cls.legacymode && cl_test_bandwidth.value;
|
||||
cls.serveradr = adr;
|
||||
cls.max_fragment_size = Q_min( FRAGMENT_MAX_SIZE, cls.max_fragment_size / (cls.connect_retry + 1));
|
||||
cls.max_fragment_size = Q_max( FRAGMENT_MAX_SIZE, cls.max_fragment_size >> Q_min( 1, cls.connect_retry ));
|
||||
cls.connect_time = host.realtime; // for retransmit requests
|
||||
cls.connect_retry++;
|
||||
|
||||
if( bandwidthTest )
|
||||
Con_Printf( "Connecting to %s... [retry #%i, max fragment size %i]\n", cls.servername, cls.connect_retry, cls.max_fragment_size );
|
||||
else
|
||||
Con_Printf( "Connecting to %s... [retry #%i]\n", cls.servername, cls.connect_retry );
|
||||
Con_Printf( "Connecting to %s... [retry #%i]\n", cls.servername, cls.connect_retry );
|
||||
|
||||
if( bandwidthTest )
|
||||
if( !cls.legacymode && cl_test_bandwidth.value )
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "bandwidth %i %i\n", PROTOCOL_VERSION, cls.max_fragment_size );
|
||||
else
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "getchallenge\n" );
|
||||
@@ -1180,7 +1196,7 @@ resource_t *CL_AddResource( resourcetype_t type, const char *name, int size, qbo
|
||||
|
||||
void CL_CreateResourceList( void )
|
||||
{
|
||||
char szFileName[MAX_OSPATH];
|
||||
char szFileName[MAX_OSPATH];
|
||||
byte rgucMD5_hash[16];
|
||||
resource_t *pNewResource;
|
||||
int nSize;
|
||||
@@ -1188,36 +1204,30 @@ void CL_CreateResourceList( void )
|
||||
|
||||
HPAK_FlushHostQueue();
|
||||
cl.num_resources = 0;
|
||||
|
||||
Q_snprintf( szFileName, sizeof( szFileName ), "logos/remapped.bmp" );
|
||||
memset( rgucMD5_hash, 0, sizeof( rgucMD5_hash ));
|
||||
|
||||
// sanitize cvar value
|
||||
if( Q_strcmp( cl_logoext.string, "bmp" ) &&
|
||||
Q_strcmp( cl_logoext.string, "png" ))
|
||||
Cvar_DirectSet( &cl_logoext, "bmp" );
|
||||
|
||||
Q_snprintf( szFileName, sizeof( szFileName ),
|
||||
"logos/remapped.%s", cl_logoext.string );
|
||||
fp = FS_Open( szFileName, "rb", true );
|
||||
|
||||
if( !fp )
|
||||
return;
|
||||
|
||||
MD5_HashFile( rgucMD5_hash, szFileName, NULL );
|
||||
nSize = FS_FileLength( fp );
|
||||
|
||||
if( nSize != 0 )
|
||||
if( fp )
|
||||
{
|
||||
pNewResource = CL_AddResource( t_decal, szFileName, nSize, false, 0 );
|
||||
MD5_HashFile( rgucMD5_hash, szFileName, NULL );
|
||||
nSize = FS_FileLength( fp );
|
||||
|
||||
if( pNewResource )
|
||||
if( nSize != 0 )
|
||||
{
|
||||
SetBits( pNewResource->ucFlags, RES_CUSTOM );
|
||||
memcpy( pNewResource->rgucMD5_hash, rgucMD5_hash, 16 );
|
||||
HPAK_AddLump( false, CUSTOM_RES_PATH, pNewResource, NULL, fp );
|
||||
}
|
||||
}
|
||||
pNewResource = CL_AddResource( t_decal, szFileName, nSize, false, 0 );
|
||||
|
||||
FS_Close( fp );
|
||||
if( pNewResource )
|
||||
{
|
||||
SetBits( pNewResource->ucFlags, RES_CUSTOM );
|
||||
memcpy( pNewResource->rgucMD5_hash, rgucMD5_hash, 16 );
|
||||
HPAK_AddLump( false, CUSTOM_RES_PATH, pNewResource, NULL, fp );
|
||||
}
|
||||
}
|
||||
FS_Close( fp );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1280,7 +1290,7 @@ void CL_Rcon_f( void )
|
||||
string command;
|
||||
int i;
|
||||
|
||||
if( !COM_CheckString( rcon_password.string ))
|
||||
if( !COM_CheckString( rcon_client_password->string ))
|
||||
{
|
||||
Con_Printf( "You must set 'rcon_password' before issuing an rcon command.\n" );
|
||||
return;
|
||||
@@ -1294,15 +1304,15 @@ void CL_Rcon_f( void )
|
||||
|
||||
NET_Config( true, false ); // allow remote
|
||||
|
||||
Q_strncat( message, "rcon ", sizeof( message ));
|
||||
Q_strncat( message, rcon_password.string, sizeof( message ));
|
||||
Q_strncat( message, " ", sizeof( message ) );
|
||||
Q_strcat( message, "rcon " );
|
||||
Q_strcat( message, rcon_client_password->string );
|
||||
Q_strcat( message, " " );
|
||||
|
||||
for( i = 1; i < Cmd_Argc(); i++ )
|
||||
{
|
||||
Cmd_Escape( command, Cmd_Argv( i ), sizeof( command ));
|
||||
Q_strncat( message, command, sizeof( message ));
|
||||
Q_strncat( message, " ", sizeof( message ));
|
||||
Q_strcat( message, command );
|
||||
Q_strcat( message, " " );
|
||||
}
|
||||
|
||||
if( cls.state >= ca_connected )
|
||||
@@ -1344,7 +1354,7 @@ void CL_ClearState( void )
|
||||
CL_ClearEffects ();
|
||||
CL_FreeEdicts ();
|
||||
|
||||
PM_ClearPhysEnts( clgame.pmove );
|
||||
CL_ClearPhysEnts ();
|
||||
NetAPI_CancelAllRequests();
|
||||
|
||||
// wipe the entire cl structure
|
||||
@@ -1352,7 +1362,6 @@ void CL_ClearState( void )
|
||||
MSG_Clear( &cls.netchan.message );
|
||||
memset( &clgame.fade, 0, sizeof( clgame.fade ));
|
||||
memset( &clgame.shake, 0, sizeof( clgame.shake ));
|
||||
clgame.mapname[0] = '\0';
|
||||
Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
|
||||
cl.maxclients = 1; // allow to drawing player in menu
|
||||
cl.mtime[0] = cl.mtime[1] = 1.0f; // because level starts from 1.0f second
|
||||
@@ -1562,38 +1571,11 @@ void CL_LocalServers_f( void )
|
||||
// send a broadcast packet
|
||||
adr.type = NA_BROADCAST;
|
||||
adr.port = MSG_BigShort( PORT_SERVER );
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "info %i", PROTOCOL_VERSION );
|
||||
|
||||
adr.type = NA_MULTICAST_IP6;
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, "info %i", PROTOCOL_VERSION );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_BuildMasterServerScanRequest
|
||||
=================
|
||||
*/
|
||||
size_t CL_BuildMasterServerScanRequest( char *buf, size_t size, qboolean nat )
|
||||
{
|
||||
size_t remaining;
|
||||
char *info;
|
||||
|
||||
if( unlikely( size < sizeof( MS_SCAN_REQUEST )))
|
||||
return 0;
|
||||
|
||||
Q_strncpy( buf, MS_SCAN_REQUEST, size );
|
||||
|
||||
info = buf + sizeof( MS_SCAN_REQUEST ) - 1;
|
||||
remaining = size - sizeof( MS_SCAN_REQUEST );
|
||||
|
||||
info[0] = 0;
|
||||
|
||||
Info_SetValueForKey( info, "gamedir", GI->gamefolder, remaining );
|
||||
Info_SetValueForKey( info, "clver", XASH_VERSION, remaining ); // let master know about client version
|
||||
Info_SetValueForKey( info, "nat", nat ? "1" : "0", remaining );
|
||||
|
||||
return sizeof( MS_SCAN_REQUEST ) + Q_strlen( info );
|
||||
}
|
||||
#define MS_SCAN_REQUEST "1\xFF" "0.0.0.0:0\0"
|
||||
|
||||
/*
|
||||
=================
|
||||
@@ -1602,17 +1584,18 @@ CL_InternetServers_f
|
||||
*/
|
||||
void CL_InternetServers_f( void )
|
||||
{
|
||||
char fullquery[512];
|
||||
size_t len;
|
||||
qboolean nat = cl_nat->value != 0.0f;
|
||||
|
||||
len = CL_BuildMasterServerScanRequest( fullquery, sizeof( fullquery ), nat );
|
||||
|
||||
Con_Printf( "Scanning for servers on the internet area...\n" );
|
||||
char fullquery[512] = MS_SCAN_REQUEST;
|
||||
char *info = fullquery + sizeof( MS_SCAN_REQUEST ) - 1;
|
||||
const size_t remaining = sizeof( fullquery ) - sizeof( MS_SCAN_REQUEST );
|
||||
|
||||
NET_Config( true, true ); // allow remote
|
||||
|
||||
cls.internetservers_wait = NET_SendToMasters( NS_CLIENT, len, fullquery );
|
||||
Con_Printf( "Scanning for servers on the internet area...\n" );
|
||||
Info_SetValueForKey( info, "gamedir", GI->gamefolder, remaining );
|
||||
Info_SetValueForKey( info, "clver", XASH_VERSION, remaining ); // let master know about client version
|
||||
Info_SetValueForKey( info, "nat", cl_nat->string, remaining );
|
||||
|
||||
cls.internetservers_wait = NET_SendToMasters( NS_CLIENT, sizeof( MS_SCAN_REQUEST ) + Q_strlen( info ), fullquery );
|
||||
cls.internetservers_pending = true;
|
||||
|
||||
if( !cls.internetservers_wait )
|
||||
@@ -1646,8 +1629,6 @@ void CL_Reconnect_f( void )
|
||||
|
||||
if( COM_CheckString( cls.servername ))
|
||||
{
|
||||
qboolean legacy = cls.legacymode;
|
||||
|
||||
if( cls.state >= ca_connected )
|
||||
CL_Disconnect();
|
||||
|
||||
@@ -1655,7 +1636,6 @@ void CL_Reconnect_f( void )
|
||||
cls.demonum = cls.movienum = -1; // not in the demo loop now
|
||||
cls.state = ca_connecting;
|
||||
cls.signon = 0;
|
||||
cls.legacymode = legacy; // don't change protocol
|
||||
|
||||
Con_Printf( "reconnecting...\n" );
|
||||
}
|
||||
@@ -2080,7 +2060,7 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
||||
|
||||
if( NET_CompareAdr( from, cls.legacyserver ))
|
||||
{
|
||||
Cbuf_AddTextf( "connect %s legacy\n", NET_AdrToString( from ));
|
||||
Cbuf_AddText( va( "connect %s legacy\n", NET_AdrToString( from )));
|
||||
memset( &cls.legacyserver, 0, sizeof( cls.legacyserver ));
|
||||
}
|
||||
}
|
||||
@@ -2444,18 +2424,11 @@ void CL_ProcessFile( qboolean successfully_received, const char *filename )
|
||||
{
|
||||
if( filename[0] != '!' )
|
||||
Con_Printf( "processing %s\n", filename );
|
||||
|
||||
if( !Q_strnicmp( filename, "downloaded/", 11 ))
|
||||
{
|
||||
// skip "downloaded/" part to avoid mismatch with needed resources list
|
||||
filename += 11;
|
||||
}
|
||||
}
|
||||
else if( !successfully_received )
|
||||
{
|
||||
Con_Printf( S_ERROR "server failed to transmit file '%s'\n", CL_CleanFileName( filename ));
|
||||
}
|
||||
|
||||
if( cls.legacymode )
|
||||
{
|
||||
if( host.downloadcount > 0 )
|
||||
@@ -2583,7 +2556,7 @@ void CL_ServerCommand( qboolean reliable, const char *fmt, ... )
|
||||
return;
|
||||
|
||||
va_start( argptr, fmt );
|
||||
Q_vsnprintf( string, sizeof( string ), fmt, argptr );
|
||||
Q_vsprintf( string, fmt, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
if( reliable )
|
||||
@@ -2852,11 +2825,9 @@ void CL_InitLocal( void )
|
||||
Cvar_RegisterVariable( &cl_download_ingame );
|
||||
Cvar_RegisterVariable( &cl_logofile );
|
||||
Cvar_RegisterVariable( &cl_logocolor );
|
||||
Cvar_RegisterVariable( &cl_logoext );
|
||||
Cvar_RegisterVariable( &cl_test_bandwidth );
|
||||
|
||||
Voice_RegisterCvars();
|
||||
VGui_RegisterCvars();
|
||||
|
||||
// register our variables
|
||||
cl_crosshair = Cvar_Get( "crosshair", "1", FCVAR_ARCHIVE, "show weapon chrosshair" );
|
||||
@@ -2868,6 +2839,7 @@ void CL_InitLocal( void )
|
||||
cl_charset = Cvar_Get( "cl_charset", "utf-8", FCVAR_ARCHIVE, "1-byte charset to use (iconv style)" );
|
||||
hud_utf8 = Cvar_Get( "hud_utf8", "0", FCVAR_ARCHIVE, "Use utf-8 encoding for hud text" );
|
||||
|
||||
rcon_client_password = Cvar_Get( "rcon_password", "", FCVAR_PRIVILEGED, "remote control client password" );
|
||||
rcon_address = Cvar_Get( "rcon_address", "", FCVAR_PRIVILEGED, "remote control address" );
|
||||
|
||||
cl_trace_messages = Cvar_Get( "cl_trace_messages", "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable message names tracing (good for developers)");
|
||||
@@ -2891,9 +2863,9 @@ void CL_InitLocal( void )
|
||||
|
||||
cl_nosmooth = Cvar_Get( "cl_nosmooth", "0", FCVAR_ARCHIVE, "disable smooth up stair climbing" );
|
||||
cl_nointerp = Cvar_Get( "cl_nointerp", "0", FCVAR_CLIENTDLL, "disable interpolation of entities and players" );
|
||||
cl_smoothtime = Cvar_Get( "cl_smoothtime", "0.1", FCVAR_ARCHIVE, "time to smooth up" );
|
||||
cl_smoothtime = Cvar_Get( "cl_smoothtime", "0", FCVAR_ARCHIVE, "time to smooth up" );
|
||||
cl_cmdbackup = Cvar_Get( "cl_cmdbackup", "10", FCVAR_ARCHIVE, "how many additional history commands are sent" );
|
||||
cl_cmdrate = Cvar_Get( "cl_cmdrate", "60", FCVAR_ARCHIVE, "Max number of command packets sent to server per second" );
|
||||
cl_cmdrate = Cvar_Get( "cl_cmdrate", "30", FCVAR_ARCHIVE, "Max number of command packets sent to server per second" );
|
||||
cl_draw_particles = Cvar_Get( "r_drawparticles", "1", FCVAR_CHEAT, "render particles" );
|
||||
cl_draw_tracers = Cvar_Get( "r_drawtracers", "1", FCVAR_CHEAT, "render tracers" );
|
||||
cl_draw_beams = Cvar_Get( "r_drawbeams", "1", FCVAR_CHEAT, "render beams" );
|
||||
@@ -2902,7 +2874,6 @@ void CL_InitLocal( void )
|
||||
cl_bmodelinterp = Cvar_Get( "cl_bmodelinterp", "1", FCVAR_ARCHIVE, "enable bmodel interpolation" );
|
||||
cl_clockreset = Cvar_Get( "cl_clockreset", "0.1", FCVAR_ARCHIVE, "frametime delta maximum value before reset" );
|
||||
cl_fixtimerate = Cvar_Get( "cl_fixtimerate", "7.5", FCVAR_ARCHIVE, "time in msec to client clock adjusting" );
|
||||
hud_fontscale = Cvar_Get( "hud_fontscale", "1.0", FCVAR_ARCHIVE|FCVAR_LATCH, "scale hud font texture" );
|
||||
hud_scale = Cvar_Get( "hud_scale", "0", FCVAR_ARCHIVE|FCVAR_LATCH, "scale hud at current resolution" );
|
||||
Cvar_Get( "cl_background", "0", FCVAR_READ_ONLY, "indicate what background map is running" );
|
||||
cl_showevents = Cvar_Get( "cl_showevents", "0", FCVAR_ARCHIVE, "show events playback" );
|
||||
@@ -2924,12 +2895,6 @@ void CL_InitLocal( void )
|
||||
Cmd_AddCommand ("god", NULL, "enable godmode" );
|
||||
Cmd_AddCommand ("fov", NULL, "set client field of view" );
|
||||
|
||||
Cmd_AddRestrictedCommand ("ent_list", NULL, "list entities on server" );
|
||||
Cmd_AddRestrictedCommand ("ent_fire", NULL, "fire entity command (be careful)" );
|
||||
Cmd_AddRestrictedCommand ("ent_info", NULL, "dump entity information" );
|
||||
Cmd_AddRestrictedCommand ("ent_create", NULL, "create entity with specified values (be careful)" );
|
||||
Cmd_AddRestrictedCommand ("ent_getvars", NULL, "put parameters of specified entities to client's' ent_last_* cvars" );
|
||||
|
||||
// register our commands
|
||||
Cmd_AddCommand ("pause", NULL, "pause the game (if the server allows pausing)" );
|
||||
Cmd_AddCommand ("localservers", CL_LocalServers_f, "collect info about local servers" );
|
||||
@@ -2996,12 +2961,12 @@ void CL_AdjustClock( void )
|
||||
if( fabs( cl.timedelta ) >= 0.001f )
|
||||
{
|
||||
double msec, adjust;
|
||||
double sign;
|
||||
float sign;
|
||||
|
||||
msec = ( cl.timedelta * 1000.0 );
|
||||
sign = ( msec < 0 ) ? 1.0 : -1.0;
|
||||
msec = Q_min( cl_fixtimerate->value, fabs( msec ));
|
||||
adjust = sign * ( msec / 1000.0 );
|
||||
msec = ( cl.timedelta * 1000.0f );
|
||||
sign = ( msec < 0 ) ? 1.0f : -1.0f;
|
||||
msec = fabs( msec );
|
||||
adjust = sign * ( cl_fixtimerate->value / 1000.0f );
|
||||
|
||||
if( fabs( adjust ) < fabs( cl.timedelta ))
|
||||
{
|
||||
@@ -3086,6 +3051,9 @@ void Host_ClientFrame( void )
|
||||
// catch changes video settings
|
||||
VID_CheckChanges();
|
||||
|
||||
// process VGUI
|
||||
VGui_RunFrame ();
|
||||
|
||||
// update the screen
|
||||
SCR_UpdateScreen ();
|
||||
|
||||
@@ -3118,7 +3086,6 @@ void CL_Init( void )
|
||||
VID_Init(); // init video
|
||||
S_Init(); // init sound
|
||||
Voice_Init( VOICE_DEFAULT_CODEC, 3 ); // init voice
|
||||
Sequence_Init();
|
||||
|
||||
// unreliable buffer. unsed for unreliable commands and voice stream
|
||||
MSG_Init( &cls.datagram, "cls.datagram", cls.datagram_buf, sizeof( cls.datagram_buf ));
|
||||
@@ -3162,12 +3129,9 @@ void CL_Shutdown( void )
|
||||
CL_UnloadProgs ();
|
||||
cls.initialized = false;
|
||||
|
||||
// for client-side VGUI support we use other order
|
||||
if( FI && FI->GameInfo && !FI->GameInfo->internal_vgui_support )
|
||||
VGui_Shutdown();
|
||||
VGui_Shutdown();
|
||||
|
||||
if( g_fsapi.Delete )
|
||||
g_fsapi.Delete( "demoheader.tmp" ); // remove tmp file
|
||||
FS_Delete( "demoheader.tmp" ); // remove tmp file
|
||||
SCR_FreeCinematic (); // release AVI's *after* client.dll because custom renderer may use them
|
||||
S_Shutdown ();
|
||||
R_Shutdown ();
|
||||
|
||||
@@ -25,9 +25,6 @@ mobile_engfuncs_t *gMobileEngfuncs;
|
||||
convar_t *vibration_length;
|
||||
convar_t *vibration_enable;
|
||||
|
||||
static cl_font_t g_scaled_font;
|
||||
static float g_font_scale;
|
||||
|
||||
static void pfnVibrate( float life, char flags )
|
||||
{
|
||||
if( !vibration_enable->value )
|
||||
@@ -63,28 +60,28 @@ 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 *pfnGetNativeObject( const char *obj )
|
||||
|
||||
@@ -281,10 +281,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--;
|
||||
}
|
||||
}
|
||||
@@ -300,10 +297,7 @@ static void NetGraph_DrawTimes( wrect_t rect, int x, int w )
|
||||
|
||||
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--;
|
||||
}
|
||||
}
|
||||
@@ -364,7 +358,6 @@ 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 );
|
||||
@@ -386,17 +379,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;
|
||||
|
||||
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 +396,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 kb/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 kb/s", out, cls.netchan.flow[FLOW_OUTGOING].avgkbytespersec ), colors );
|
||||
y += 15;
|
||||
|
||||
if( graphtype > 2 )
|
||||
@@ -417,14 +407,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();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -499,7 +499,7 @@ void CL_BatchResourceRequest( qboolean initialize )
|
||||
if( !FBitSet( p->ucFlags, RES_REQUESTED ))
|
||||
{
|
||||
MSG_BeginClientCmd( &msg, clc_stringcmd );
|
||||
MSG_WriteStringf( &msg, "dlfile !MD5%s", MD5_Print( p->rgucMD5_hash ));;
|
||||
MSG_WriteString( &msg, va( "dlfile !MD5%s", MD5_Print( p->rgucMD5_hash ) ) );
|
||||
SetBits( p->ucFlags, RES_REQUESTED );
|
||||
}
|
||||
break;
|
||||
@@ -587,7 +587,7 @@ int CL_EstimateNeededResources( void )
|
||||
return nTotalSize;
|
||||
}
|
||||
|
||||
static void CL_StartResourceDownloading( const char *pszMessage, qboolean bCustom )
|
||||
void CL_StartResourceDownloading( const char *pszMessage, qboolean bCustom )
|
||||
{
|
||||
resourceinfo_t ri;
|
||||
|
||||
@@ -603,8 +603,6 @@ static void CL_StartResourceDownloading( const char *pszMessage, qboolean bCusto
|
||||
}
|
||||
else
|
||||
{
|
||||
HTTP_ResetProcessState();
|
||||
|
||||
cls.state = ca_validate;
|
||||
cls.dl.custom = false;
|
||||
}
|
||||
@@ -845,76 +843,54 @@ void CL_ParseFileTransferFailed( sizebuf_t *msg )
|
||||
CL_ParseServerData
|
||||
==================
|
||||
*/
|
||||
void CL_ParseServerData( sizebuf_t *msg, qboolean legacy )
|
||||
void CL_ParseServerData( sizebuf_t *msg )
|
||||
{
|
||||
char gamefolder[MAX_QPATH];
|
||||
qboolean background;
|
||||
int i;
|
||||
|
||||
HPAK_CheckSize( CUSTOM_RES_PATH );
|
||||
|
||||
Con_Reportf( "%s packet received.\n", legacy ? "Legacy serverdata" : "Serverdata" );
|
||||
|
||||
Con_Reportf( "Serverdata packet received.\n" );
|
||||
cls.timestart = Sys_DoubleTime();
|
||||
|
||||
cls.demowaiting = false; // server is changed
|
||||
|
||||
// wipe the client_t struct
|
||||
if( !cls.changelevel && !cls.changedemo )
|
||||
CL_ClearState ();
|
||||
|
||||
// Re-init hud video, especially if we changed game directories
|
||||
clgame.dllFuncs.pfnVidInit();
|
||||
|
||||
cls.state = ca_connected;
|
||||
|
||||
// parse protocol version number
|
||||
i = MSG_ReadLong( msg );
|
||||
|
||||
if( legacy )
|
||||
{
|
||||
if( i != PROTOCOL_LEGACY_VERSION )
|
||||
Host_Error( "Server use invalid protocol (%i should be %i)\n", i, PROTOCOL_LEGACY_VERSION );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( i != PROTOCOL_VERSION )
|
||||
Host_Error( "Server use invalid protocol (%i should be %i)\n", i, PROTOCOL_VERSION );
|
||||
}
|
||||
if( i != PROTOCOL_VERSION )
|
||||
Host_Error( "Server use invalid protocol (%i should be %i)\n", i, PROTOCOL_VERSION );
|
||||
|
||||
cl.servercount = MSG_ReadLong( msg );
|
||||
cl.checksum = MSG_ReadLong( msg );
|
||||
cl.playernum = MSG_ReadByte( msg );
|
||||
cl.maxclients = MSG_ReadByte( msg );
|
||||
clgame.maxEntities = MSG_ReadWord( msg );
|
||||
if( legacy )
|
||||
{
|
||||
clgame.maxEntities = bound( MIN_LEGACY_EDICTS, clgame.maxEntities, MAX_LEGACY_EDICTS );
|
||||
clgame.maxModels = 512; // ???
|
||||
}
|
||||
else
|
||||
{
|
||||
clgame.maxEntities = bound( MIN_EDICTS, clgame.maxEntities, MAX_EDICTS );
|
||||
clgame.maxModels = MSG_ReadWord( msg );
|
||||
}
|
||||
Q_strncpy( clgame.mapname, MSG_ReadString( msg ), sizeof( clgame.mapname ));
|
||||
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), sizeof( clgame.maptitle ));
|
||||
clgame.maxEntities = bound( MIN_EDICTS, clgame.maxEntities, MAX_EDICTS );
|
||||
clgame.maxModels = MSG_ReadWord( msg );
|
||||
Q_strncpy( clgame.mapname, MSG_ReadString( msg ), MAX_STRING );
|
||||
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), MAX_STRING );
|
||||
background = MSG_ReadOneBit( msg );
|
||||
Q_strncpy( gamefolder, MSG_ReadString( msg ), sizeof( gamefolder ));
|
||||
Q_strncpy( gamefolder, MSG_ReadString( msg ), MAX_QPATH );
|
||||
host.features = (uint)MSG_ReadLong( msg );
|
||||
|
||||
if( !legacy )
|
||||
// receive the player hulls
|
||||
for( i = 0; i < MAX_MAP_HULLS * 3; i++ )
|
||||
{
|
||||
// receive the player hulls
|
||||
for( i = 0; i < MAX_MAP_HULLS * 3; i++ )
|
||||
{
|
||||
host.player_mins[i/3][i%3] = MSG_ReadChar( msg );
|
||||
host.player_maxs[i/3][i%3] = MSG_ReadChar( msg );
|
||||
}
|
||||
host.player_mins[i/3][i%3] = MSG_ReadChar( msg );
|
||||
host.player_maxs[i/3][i%3] = MSG_ReadChar( msg );
|
||||
}
|
||||
|
||||
if( clgame.maxModels > MAX_MODELS )
|
||||
Con_Printf( S_WARN "server model limit is above client model limit %i > %i\n", clgame.maxModels, MAX_MODELS );
|
||||
|
||||
// Re-init hud video, especially if we changed game directories
|
||||
clgame.dllFuncs.pfnVidInit();
|
||||
|
||||
if( Con_FixedFont( ))
|
||||
{
|
||||
// seperate the printfs so the server message can have a color
|
||||
@@ -938,7 +914,11 @@ void CL_ParseServerData( sizebuf_t *msg, qboolean legacy )
|
||||
|
||||
// set the background state
|
||||
if( cls.demoplayback && ( cls.demonum != -1 ))
|
||||
{
|
||||
// re-init mouse
|
||||
host.mouse_visible = false;
|
||||
cl.background = true;
|
||||
}
|
||||
else cl.background = background;
|
||||
|
||||
if( cl.background ) // tell the game parts about background state
|
||||
@@ -985,11 +965,8 @@ void CL_ParseServerData( sizebuf_t *msg, qboolean legacy )
|
||||
COM_ClearCustomizationList( &cl.players[i].customdata, true );
|
||||
CL_CreateCustomizationList();
|
||||
|
||||
if( !legacy )
|
||||
{
|
||||
// request resources from server
|
||||
CL_ServerCommand( true, "sendres %i\n", cl.servercount );
|
||||
}
|
||||
// request resources from server
|
||||
CL_ServerCommand( true, "sendres %i\n", cl.servercount );
|
||||
|
||||
memset( &clgame.movevars, 0, sizeof( clgame.movevars ));
|
||||
memset( &clgame.oldmovevars, 0, sizeof( clgame.oldmovevars ));
|
||||
@@ -1164,7 +1141,7 @@ void CL_ParseClientData( sizebuf_t *msg )
|
||||
CL_ParseBaseline
|
||||
==================
|
||||
*/
|
||||
void CL_ParseBaseline( sizebuf_t *msg, qboolean legacy )
|
||||
void CL_ParseBaseline( sizebuf_t *msg )
|
||||
{
|
||||
int i, newnum;
|
||||
entity_state_t nullstate;
|
||||
@@ -1177,15 +1154,8 @@ void CL_ParseBaseline( sizebuf_t *msg, qboolean legacy )
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
if( legacy )
|
||||
{
|
||||
newnum = MSG_ReadWord( msg );
|
||||
}
|
||||
else
|
||||
{
|
||||
newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
|
||||
if( newnum == LAST_EDICT ) break; // end of baselines
|
||||
}
|
||||
newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
|
||||
if( newnum == LAST_EDICT ) break; // end of baselines
|
||||
player = CL_IsPlayerIndex( newnum );
|
||||
|
||||
if( newnum >= clgame.maxEntities )
|
||||
@@ -1196,22 +1166,14 @@ void CL_ParseBaseline( sizebuf_t *msg, qboolean legacy )
|
||||
ent->index = newnum;
|
||||
|
||||
MSG_ReadDeltaEntity( msg, &ent->prevstate, &ent->baseline, newnum, player, 1.0f );
|
||||
|
||||
if( legacy )
|
||||
{
|
||||
break; // only one baseline allowed in legacy protocol
|
||||
}
|
||||
}
|
||||
|
||||
if( !legacy )
|
||||
{
|
||||
cl.instanced_baseline_count = MSG_ReadUBitLong( msg, 6 );
|
||||
cl.instanced_baseline_count = MSG_ReadUBitLong( msg, 6 );
|
||||
|
||||
for( i = 0; i < cl.instanced_baseline_count; i++ )
|
||||
{
|
||||
newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
|
||||
MSG_ReadDeltaEntity( msg, &nullstate, &cl.instanced_baseline[i], newnum, false, 1.0f );
|
||||
}
|
||||
for( i = 0; i < cl.instanced_baseline_count; i++ )
|
||||
{
|
||||
newnum = MSG_ReadUBitLong( msg, MAX_ENTITY_BITS );
|
||||
MSG_ReadDeltaEntity( msg, &nullstate, &cl.instanced_baseline[i], newnum, false, 1.0f );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1240,9 +1202,11 @@ CL_ParseSetAngle
|
||||
set the view angle to this absolute value
|
||||
================
|
||||
*/
|
||||
static void CL_ParseSetAngle( sizebuf_t *msg )
|
||||
void CL_ParseSetAngle( sizebuf_t *msg )
|
||||
{
|
||||
MSG_ReadVec3Angles( msg, cl.viewangles );
|
||||
cl.viewangles[0] = MSG_ReadBitAngle( msg, 16 );
|
||||
cl.viewangles[1] = MSG_ReadBitAngle( msg, 16 );
|
||||
cl.viewangles[2] = MSG_ReadBitAngle( msg, 16 );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1357,7 +1321,7 @@ CL_UpdateUserinfo
|
||||
collect userinfo from all players
|
||||
================
|
||||
*/
|
||||
void CL_UpdateUserinfo( sizebuf_t *msg, qboolean legacy )
|
||||
void CL_UpdateUserinfo( sizebuf_t *msg )
|
||||
{
|
||||
int slot, id;
|
||||
qboolean active;
|
||||
@@ -1368,8 +1332,7 @@ void CL_UpdateUserinfo( sizebuf_t *msg, qboolean legacy )
|
||||
if( slot >= MAX_CLIENTS )
|
||||
Host_Error( "CL_ParseServerMessage: svc_updateuserinfo >= MAX_CLIENTS\n" );
|
||||
|
||||
if( !legacy )
|
||||
id = MSG_ReadLong( msg ); // unique user ID
|
||||
id = MSG_ReadLong( msg ); // unique user ID
|
||||
player = &cl.players[slot];
|
||||
active = MSG_ReadOneBit( msg ) ? true : false;
|
||||
|
||||
@@ -1381,8 +1344,7 @@ void CL_UpdateUserinfo( sizebuf_t *msg, qboolean legacy )
|
||||
player->topcolor = Q_atoi( Info_ValueForKey( player->userinfo, "topcolor" ));
|
||||
player->bottomcolor = Q_atoi( Info_ValueForKey( player->userinfo, "bottomcolor" ));
|
||||
player->spectator = Q_atoi( Info_ValueForKey( player->userinfo, "*hltv" ));
|
||||
if( !legacy )
|
||||
MSG_ReadBytes( msg, player->hashedcdkey, sizeof( player->hashedcdkey ));
|
||||
MSG_ReadBytes( msg, player->hashedcdkey, sizeof( player->hashedcdkey ));
|
||||
|
||||
if( slot == cl.playernum ) memcpy( &gameui.playerinfo, player, sizeof( player_info_t ));
|
||||
}
|
||||
@@ -1543,42 +1505,6 @@ void CL_SendConsistencyInfo( sizebuf_t *msg )
|
||||
MSG_WriteOneBit( msg, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_StartDark
|
||||
==================
|
||||
*/
|
||||
static void CL_StartDark( void )
|
||||
{
|
||||
if( Cvar_VariableValue( "v_dark" ))
|
||||
{
|
||||
screenfade_t *sf = &clgame.fade;
|
||||
float fadetime = 5.0f;
|
||||
client_textmessage_t *title;
|
||||
|
||||
title = CL_TextMessageGet( "GAMETITLE" );
|
||||
if( Host_IsQuakeCompatible( ))
|
||||
fadetime = 1.0f;
|
||||
|
||||
if( title )
|
||||
{
|
||||
// get settings from titles.txt
|
||||
sf->fadeEnd = title->holdtime + title->fadeout;
|
||||
sf->fadeReset = title->fadeout;
|
||||
}
|
||||
else sf->fadeEnd = sf->fadeReset = fadetime;
|
||||
|
||||
sf->fadeFlags = FFADE_IN;
|
||||
sf->fader = sf->fadeg = sf->fadeb = 0;
|
||||
sf->fadealpha = 255;
|
||||
sf->fadeSpeed = (float)sf->fadealpha / sf->fadeReset;
|
||||
sf->fadeReset += cl.time;
|
||||
sf->fadeEnd += sf->fadeReset;
|
||||
|
||||
Cvar_SetValue( "v_dark", 0.0f );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_RegisterResources
|
||||
@@ -1628,9 +1554,6 @@ void CL_RegisterResources( sizebuf_t *msg )
|
||||
// tell rendering system we have a new set of models.
|
||||
ref.dllFuncs.R_NewMap ();
|
||||
|
||||
// check if this map must start from dark screen
|
||||
CL_StartDark ();
|
||||
|
||||
CL_SetupOverviewParams();
|
||||
|
||||
// release unused SpriteTextures
|
||||
@@ -1648,7 +1571,7 @@ void CL_RegisterResources( sizebuf_t *msg )
|
||||
// done with all resources, issue prespawn command.
|
||||
// Include server count in case server disconnects and changes level during d/l
|
||||
MSG_BeginClientCmd( msg, clc_stringcmd );
|
||||
MSG_WriteStringf( msg, "spawn %i", cl.servercount );
|
||||
MSG_WriteString( msg, va( "spawn %i", cl.servercount ));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1893,17 +1816,10 @@ Set screen shake
|
||||
*/
|
||||
void CL_ParseScreenShake( sizebuf_t *msg )
|
||||
{
|
||||
float amplitude = (float)(word)MSG_ReadShort( msg ) * ( 1.0f / (float)( 1 << 12 ));
|
||||
float duration = (float)(word)MSG_ReadShort( msg ) * ( 1.0f / (float)( 1 << 12 ));
|
||||
float frequency = (float)(word)MSG_ReadShort( msg ) * ( 1.0f / (float)( 1 << 8 ));
|
||||
|
||||
// don't overwrite larger existing shake
|
||||
if( amplitude > clgame.shake.amplitude )
|
||||
clgame.shake.amplitude = amplitude;
|
||||
|
||||
clgame.shake.duration = duration;
|
||||
clgame.shake.time = cl.time + clgame.shake.duration;
|
||||
clgame.shake.frequency = frequency;
|
||||
clgame.shake.amplitude = (float)(word)MSG_ReadShort( msg ) * (1.0f / (float)(1<<12));
|
||||
clgame.shake.duration = (float)(word)MSG_ReadShort( msg ) * (1.0f / (float)(1<<12));
|
||||
clgame.shake.frequency = (float)(word)MSG_ReadShort( msg ) * (1.0f / (float)(1<<8));
|
||||
clgame.shake.time = cl.time + Q_max( clgame.shake.duration, 0.01f );
|
||||
clgame.shake.next_shake = 0.0f; // apply immediately
|
||||
}
|
||||
|
||||
@@ -1923,7 +1839,7 @@ void CL_ParseScreenFade( sizebuf_t *msg )
|
||||
duration = (float)MSG_ReadWord( msg );
|
||||
holdTime = (float)MSG_ReadWord( msg );
|
||||
sf->fadeFlags = MSG_ReadShort( msg );
|
||||
flScale = FBitSet( sf->fadeFlags, FFADE_LONGFADE ) ? (1.0f / 256.0f) : (1.0f / 4096.0f);
|
||||
flScale = ( sf->fadeFlags & FFADE_LONGFADE ) ? (1.0f / 256.0f) : (1.0f / 4096.0f);
|
||||
|
||||
sf->fader = MSG_ReadByte( msg );
|
||||
sf->fadeg = MSG_ReadByte( msg );
|
||||
@@ -1936,7 +1852,7 @@ void CL_ParseScreenFade( sizebuf_t *msg )
|
||||
// calc fade speed
|
||||
if( duration > 0 )
|
||||
{
|
||||
if( FBitSet( sf->fadeFlags, FFADE_OUT ))
|
||||
if( sf->fadeFlags & FFADE_OUT )
|
||||
{
|
||||
if( sf->fadeEnd )
|
||||
{
|
||||
@@ -1944,7 +1860,6 @@ void CL_ParseScreenFade( sizebuf_t *msg )
|
||||
}
|
||||
|
||||
sf->fadeEnd += cl.time;
|
||||
sf->fadeTotalEnd = sf->fadeEnd;
|
||||
sf->fadeReset += sf->fadeEnd;
|
||||
}
|
||||
else
|
||||
@@ -2046,10 +1961,10 @@ void CL_ParseExec( sizebuf_t *msg )
|
||||
{
|
||||
Cbuf_AddText( "exec mapdefault.cfg\n" );
|
||||
|
||||
COM_FileBase( clgame.mapname, mapname, sizeof( mapname ));
|
||||
COM_FileBase( clgame.mapname, mapname );
|
||||
|
||||
if ( COM_CheckString( mapname ) )
|
||||
Cbuf_AddTextf( "exec %s.cfg\n", mapname );
|
||||
Cbuf_AddText( va( "exec %s.cfg\n", mapname ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2289,7 +2204,6 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
else cls.state = ca_connecting;
|
||||
cl.background = old_background;
|
||||
cls.connect_time = MAX_HEARTBEAT;
|
||||
cls.connect_retry = 0;
|
||||
}
|
||||
break;
|
||||
case svc_setview:
|
||||
@@ -2319,13 +2233,13 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
break;
|
||||
case svc_serverdata:
|
||||
Cbuf_Execute(); // make sure any stuffed commands are done
|
||||
CL_ParseServerData( msg, false );
|
||||
CL_ParseServerData( msg );
|
||||
break;
|
||||
case svc_lightstyle:
|
||||
CL_ParseLightStyle( msg );
|
||||
break;
|
||||
case svc_updateuserinfo:
|
||||
CL_UpdateUserinfo( msg, false );
|
||||
CL_UpdateUserinfo( msg );
|
||||
break;
|
||||
case svc_deltatable:
|
||||
Delta_ParseTableField( msg );
|
||||
@@ -2355,7 +2269,7 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_spawnbaseline:
|
||||
CL_ParseBaseline( msg, false );
|
||||
CL_ParseBaseline( msg );
|
||||
break;
|
||||
case svc_temp_entity:
|
||||
CL_ParseTempEntity( msg );
|
||||
@@ -2492,6 +2406,160 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ParseBaseline
|
||||
==================
|
||||
*/
|
||||
void CL_LegacyParseBaseline( sizebuf_t *msg )
|
||||
{
|
||||
int i, newnum;
|
||||
qboolean player;
|
||||
cl_entity_t *ent;
|
||||
|
||||
Delta_InitClient (); // finalize client delta's
|
||||
|
||||
newnum = MSG_ReadWord( msg );
|
||||
player = CL_IsPlayerIndex( newnum );
|
||||
|
||||
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;
|
||||
|
||||
MSG_ReadDeltaEntity( msg, &ent->prevstate, &ent->baseline, newnum, player, 1.0f );
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ParseServerData
|
||||
==================
|
||||
*/
|
||||
void CL_ParseLegacyServerData( sizebuf_t *msg )
|
||||
{
|
||||
string gamefolder;
|
||||
qboolean background;
|
||||
int i;
|
||||
|
||||
Con_Reportf( "Legacy serverdata packet received.\n" );
|
||||
|
||||
cls.timestart = Sys_DoubleTime();
|
||||
|
||||
cls.demowaiting = false; // server is changed
|
||||
//clgame.load_sequence++; // now all hud sprites are invalid
|
||||
|
||||
// wipe the client_t struct
|
||||
if( !cls.changelevel && !cls.changedemo )
|
||||
CL_ClearState ();
|
||||
cls.state = ca_connected;
|
||||
|
||||
// parse protocol version number
|
||||
i = MSG_ReadLong( msg );
|
||||
//cls.serverProtocol = i;
|
||||
|
||||
if( i != 48 )
|
||||
Host_Error( "Server uses invalid protocol (%i should be %i)\n", i, PROTOCOL_VERSION );
|
||||
|
||||
cl.servercount = MSG_ReadLong( msg );
|
||||
cl.checksum = MSG_ReadLong( msg );
|
||||
cl.playernum = MSG_ReadByte( msg );
|
||||
cl.maxclients = MSG_ReadByte( msg );
|
||||
clgame.maxEntities = MSG_ReadWord( msg );
|
||||
clgame.maxEntities = bound( 30, clgame.maxEntities, 4096 );
|
||||
clgame.maxModels = 512;
|
||||
Q_strncpy( clgame.mapname, MSG_ReadString( msg ), MAX_STRING );
|
||||
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), MAX_STRING );
|
||||
background = MSG_ReadOneBit( msg );
|
||||
Q_strncpy( gamefolder, MSG_ReadString( msg ), MAX_STRING );
|
||||
host.features = (uint)MSG_ReadLong( msg );
|
||||
|
||||
// Re-init hud video, especially if we changed game directories
|
||||
clgame.dllFuncs.pfnVidInit();
|
||||
|
||||
if( Con_FixedFont( ))
|
||||
{
|
||||
// seperate the printfs so the server message can have a color
|
||||
Con_Print( "\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n" );
|
||||
Con_Print( va( "%c%s\n\n", 2, clgame.maptitle ));
|
||||
}
|
||||
|
||||
// multiplayer game?
|
||||
if( cl.maxclients > 1 )
|
||||
{
|
||||
// allow console in multiplayer games
|
||||
host.allow_console = true;
|
||||
|
||||
// loading user settings
|
||||
CSCR_LoadDefaultCVars( "user.scr" );
|
||||
|
||||
if( r_decals->value > mp_decals.value )
|
||||
Cvar_SetValue( "r_decals", mp_decals.value );
|
||||
}
|
||||
else Cvar_Reset( "r_decals" );
|
||||
|
||||
// set the background state
|
||||
if( cls.demoplayback && ( cls.demonum != -1 ))
|
||||
{
|
||||
// re-init mouse
|
||||
host.mouse_visible = false;
|
||||
cl.background = true;
|
||||
}
|
||||
else cl.background = background;
|
||||
|
||||
if( cl.background ) // tell the game parts about background state
|
||||
Cvar_FullSet( "cl_background", "1", FCVAR_READ_ONLY );
|
||||
else Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
|
||||
|
||||
if( !cls.changelevel )
|
||||
{
|
||||
// continue playing if we are changing level
|
||||
S_StopBackgroundTrack ();
|
||||
}
|
||||
|
||||
if( !cls.changedemo )
|
||||
UI_SetActiveMenu( cl.background );
|
||||
else if( !cls.demoplayback )
|
||||
Key_SetKeyDest( key_menu );
|
||||
|
||||
// don't reset cursor in background mode
|
||||
if( cl.background )
|
||||
IN_MouseRestorePos();
|
||||
|
||||
// will be changed later
|
||||
cl.viewentity = cl.playernum + 1;
|
||||
gameui.globals->maxClients = cl.maxclients;
|
||||
Q_strncpy( gameui.globals->maptitle, clgame.maptitle, sizeof( gameui.globals->maptitle ));
|
||||
|
||||
if( !cls.changelevel && !cls.changedemo )
|
||||
CL_InitEdicts (); // re-arrange edicts
|
||||
|
||||
// get splash name
|
||||
if( cls.demoplayback && ( cls.demonum != -1 ))
|
||||
Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", cls.demoname, refState.wideScreen ? "16x9" : "4x3" ));
|
||||
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( !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)
|
||||
}
|
||||
|
||||
for( i = 0; i < MAX_CLIENTS; i++ )
|
||||
COM_ClearCustomizationList( &cl.players[i].customdata, true );
|
||||
CL_CreateCustomizationList();
|
||||
|
||||
memset( &clgame.movevars, 0, sizeof( clgame.movevars ));
|
||||
memset( &clgame.oldmovevars, 0, sizeof( clgame.oldmovevars ));
|
||||
memset( &clgame.centerPrint, 0, sizeof( clgame.centerPrint ));
|
||||
cl.video_prepped = false;
|
||||
cl.audio_prepped = false;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ParseStaticEntity
|
||||
@@ -2567,6 +2635,8 @@ void CL_LegacyParseStaticEntity( sizebuf_t *msg )
|
||||
R_AddEfrags( ent ); // add link
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CL_LegacyParseSoundPacket( sizebuf_t *msg, qboolean is_ambient )
|
||||
{
|
||||
vec3_t pos;
|
||||
@@ -2698,6 +2768,36 @@ void CL_LegacyPrecacheEvent( sizebuf_t *msg )
|
||||
CL_SetEventIndex( cl.event_precache[eventIndex], eventIndex );
|
||||
}
|
||||
|
||||
|
||||
void CL_LegacyUpdateUserinfo( sizebuf_t *msg )
|
||||
{
|
||||
int slot, id = 0;
|
||||
qboolean active;
|
||||
player_info_t *player;
|
||||
|
||||
slot = MSG_ReadUBitLong( msg, MAX_CLIENT_BITS );
|
||||
|
||||
if( slot >= MAX_CLIENTS )
|
||||
Host_Error( "CL_ParseServerMessage: svc_updateuserinfo >= MAX_CLIENTS\n" );
|
||||
|
||||
//id = MSG_ReadLong( msg ); // unique user ID
|
||||
player = &cl.players[slot];
|
||||
active = MSG_ReadOneBit( msg ) ? true : false;
|
||||
|
||||
if( active )
|
||||
{
|
||||
Q_strncpy( player->userinfo, MSG_ReadString( msg ), sizeof( player->userinfo ));
|
||||
Q_strncpy( player->name, Info_ValueForKey( player->userinfo, "name" ), sizeof( player->name ));
|
||||
Q_strncpy( player->model, Info_ValueForKey( player->userinfo, "model" ), sizeof( player->model ));
|
||||
player->topcolor = Q_atoi( Info_ValueForKey( player->userinfo, "topcolor" ));
|
||||
player->bottomcolor = Q_atoi( Info_ValueForKey( player->userinfo, "bottomcolor" ));
|
||||
player->spectator = Q_atoi( Info_ValueForKey( player->userinfo, "*hltv" ));
|
||||
//MSG_ReadBytes( msg, player->hashedcdkey, sizeof( player->hashedcdkey ));
|
||||
|
||||
if( slot == cl.playernum ) memcpy( &gameui.playerinfo, player, sizeof( player_info_t ));
|
||||
}
|
||||
else memset( player, 0, sizeof( *player ));
|
||||
}
|
||||
#if XASH_LOW_MEMORY == 0
|
||||
#define MAX_LEGACY_RESOURCES 2048
|
||||
#elif XASH_LOW_MEMORY == 2
|
||||
@@ -2714,14 +2814,15 @@ CL_ParseResourceList
|
||||
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 )
|
||||
@@ -2738,21 +2839,14 @@ void CL_LegacyParseResourceList( sizebuf_t *msg )
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
path = va( DEFAULT_SOUNDPATH "%s", reslist.resnames[i] );
|
||||
else path = reslist.resnames[i];
|
||||
|
||||
if( FS_FileExists( path, false ))
|
||||
@@ -2871,7 +2965,6 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
else cls.state = ca_connecting;
|
||||
cl.background = old_background;
|
||||
cls.connect_time = MAX_HEARTBEAT;
|
||||
cls.connect_retry = 0;
|
||||
}
|
||||
break;
|
||||
case svc_setview:
|
||||
@@ -2908,13 +3001,13 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
break;
|
||||
case svc_serverdata:
|
||||
Cbuf_Execute(); // make sure any stuffed commands are done
|
||||
CL_ParseServerData( msg, true );
|
||||
CL_ParseLegacyServerData( msg );
|
||||
break;
|
||||
case svc_lightstyle:
|
||||
CL_ParseLightStyle( msg );
|
||||
break;
|
||||
case svc_updateuserinfo:
|
||||
CL_UpdateUserinfo( msg, true );
|
||||
CL_LegacyUpdateUserinfo( msg );
|
||||
break;
|
||||
case svc_deltatable:
|
||||
Delta_ParseTableField( msg );
|
||||
@@ -2937,14 +3030,14 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
cl.frames[cl.parsecountmod].graphdata.sound += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_spawnstatic:
|
||||
CL_LegacyParseStaticEntity( msg );
|
||||
CL_ParseStaticEntity( 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 );
|
||||
CL_LegacyParseBaseline( msg );
|
||||
break;
|
||||
case svc_temp_entity:
|
||||
CL_ParseTempEntity( msg );
|
||||
@@ -2964,6 +3057,7 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
break;
|
||||
case svc_legacy_modelindex:
|
||||
CL_LegacyPrecacheModel( msg );
|
||||
|
||||
break;
|
||||
case svc_legacy_soundindex:
|
||||
CL_LegacyPrecacheSound( msg );
|
||||
@@ -2979,6 +3073,7 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
CL_ParseRestore( msg );
|
||||
break;
|
||||
case svc_legacy_eventindex:
|
||||
//CL_ParseFinaleCutscene( msg, 3 );
|
||||
CL_LegacyPrecacheEvent(msg);
|
||||
break;
|
||||
case svc_weaponanim:
|
||||
@@ -3134,7 +3229,7 @@ void CL_LegacyPrecache_f( void )
|
||||
// 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 );
|
||||
MSG_WriteString( &cls.netchan.message, va( "begin %i", spawncount ));
|
||||
cls.signon = SIGNONS;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -194,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;
|
||||
@@ -699,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 )
|
||||
@@ -707,19 +747,101 @@ 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;
|
||||
|
||||
PM_InitTrace( trace, end );
|
||||
|
||||
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 )
|
||||
@@ -748,7 +870,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;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -788,23 +928,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;
|
||||
@@ -815,10 +955,21 @@ 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;
|
||||
@@ -835,13 +986,13 @@ 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->flNextPrimaryAttack = 0.0f; // not used by PM_ code
|
||||
pmove->effects = ps->effects;
|
||||
@@ -849,7 +1000,7 @@ static void CL_SetupPMove( playermove_t *pmove, const local_state_t *from, const
|
||||
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);
|
||||
@@ -876,7 +1027,7 @@ static void CL_SetupPMove( playermove_t *pmove, const local_state_t *from, const
|
||||
Q_strncpy( pmove->physinfo, cls.physinfo, MAX_INFO_STRING );
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -887,7 +1038,7 @@ 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;
|
||||
@@ -900,7 +1051,7 @@ 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;
|
||||
@@ -1008,9 +1159,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 )
|
||||
@@ -1021,7 +1176,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 )
|
||||
@@ -1062,10 +1217,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;
|
||||
|
||||
@@ -1142,7 +1293,7 @@ void CL_PredictMovement( qboolean repredicting )
|
||||
|
||||
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;
|
||||
|
||||
@@ -1164,13 +1315,13 @@ 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 )
|
||||
{
|
||||
vec3_t delta;
|
||||
float frac;
|
||||
vec3_t delta;
|
||||
float frac;
|
||||
|
||||
// only decay timer once per frame
|
||||
if( !repredicting )
|
||||
|
||||
@@ -237,6 +237,10 @@ static void CL_ParseQuakeServerInfo( sizebuf_t *msg )
|
||||
}
|
||||
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 );
|
||||
else Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
|
||||
|
||||
@@ -157,7 +157,7 @@ void CL_UpdateStudioTexture( cl_entity_t *entity, mstudiotexture_t *ptexture, in
|
||||
|
||||
// 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 );
|
||||
|
||||
@@ -133,7 +133,7 @@ const char *CL_GenericHandle( int fileindex )
|
||||
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 )
|
||||
{
|
||||
@@ -161,9 +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;
|
||||
return *(int *)&world.shadowdata;
|
||||
default:
|
||||
// indicates call from client.dll
|
||||
if( checkRef )
|
||||
@@ -204,7 +204,7 @@ intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRe
|
||||
return 0;
|
||||
}
|
||||
|
||||
static intptr_t pfnRenderGetParm( int parm, int arg )
|
||||
static int pfnRenderGetParm( int parm, int arg )
|
||||
{
|
||||
return CL_RenderGetParm( parm, arg, true );
|
||||
}
|
||||
|
||||
@@ -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,7 +160,6 @@ 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;
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,6 +577,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
|
||||
@@ -556,41 +657,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" );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -698,6 +780,7 @@ SCR_VidInit
|
||||
*/
|
||||
void SCR_VidInit( void )
|
||||
{
|
||||
string libpath;
|
||||
if( !ref.initialized ) // don't call VidInit too soon
|
||||
return;
|
||||
|
||||
@@ -712,13 +795,8 @@ void SCR_VidInit( void )
|
||||
gameui.globals->scrHeight = refState.height;
|
||||
}
|
||||
|
||||
// notify vgui about screen size change
|
||||
if( clgame.hInstance )
|
||||
{
|
||||
// do not pass client pointer, we do not want to
|
||||
// re-initialize vgui2
|
||||
VGui_Startup( NULL, refState.width, refState.height );
|
||||
}
|
||||
COM_GetCommonLibraryPath( LIBRARY_CLIENT, libpath, sizeof( libpath ));
|
||||
VGui_Startup( libpath, refState.width, refState.height );
|
||||
|
||||
CL_ClearSpriteTextures(); // now all hud sprites are invalid
|
||||
|
||||
@@ -749,7 +827,7 @@ void SCR_Init( void )
|
||||
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", "0", FCVAR_ARCHIVE, "show client fps" );
|
||||
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
|
||||
|
||||
@@ -405,15 +405,12 @@ static cldll_func_dst_t cldllFuncDst =
|
||||
|
||||
void CL_GetSecuredClientAPI( CL_EXPORT_FUNCS F )
|
||||
{
|
||||
cldll_func_src_t cldllFuncSrc = { 0 };
|
||||
modfuncs_t modFuncs = { 0 };
|
||||
|
||||
// secured client dlls need these
|
||||
cldll_func_src_t cldllFuncSrc =
|
||||
{
|
||||
(void *)&modFuncs,
|
||||
NULL,
|
||||
(void *)&cldllFuncDst
|
||||
};
|
||||
*(cldll_func_dst_t **)&cldllFuncSrc.pfnVidInit = &cldllFuncDst;
|
||||
*(modfuncs_t **)&cldllFuncSrc.pfnInitialize = &modFuncs;
|
||||
|
||||
// trying to fill interface now
|
||||
F( &cldllFuncSrc );
|
||||
|
||||
@@ -1037,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
|
||||
}
|
||||
|
||||
@@ -1245,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;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2919,15 +2928,7 @@ void CL_PlayerDecal( int playernum, int customIndex, int entityIndex, float *pos
|
||||
{
|
||||
if( !pCust->nUserData1 )
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -209,7 +209,7 @@ qboolean SCR_PlayCinematic( const char *arg )
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -229,53 +229,6 @@ 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
|
||||
|
||||
@@ -108,6 +108,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 +139,7 @@ typedef struct
|
||||
int light_level;
|
||||
int waterlevel;
|
||||
int usehull;
|
||||
qboolean moving;
|
||||
int moving;
|
||||
int pushmsec;
|
||||
int weapons;
|
||||
float maxspeed;
|
||||
@@ -210,7 +211,7 @@ typedef struct
|
||||
// a lerp point for other data
|
||||
double oldtime; // previous cl.time, time-oldtime is used
|
||||
// to decay light values and smooth step ups
|
||||
double timedelta; // floating delta between two updates
|
||||
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
|
||||
@@ -318,46 +319,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 nearest; // nearest filtering enabled
|
||||
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
|
||||
|
||||
@@ -384,11 +371,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;
|
||||
@@ -681,7 +672,6 @@ 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 *gl_showtextures;
|
||||
extern convar_t *cl_bmodelinterp;
|
||||
@@ -764,7 +754,6 @@ int CL_IsDevOverviewMode( void );
|
||||
void CL_PingServers_f( void );
|
||||
void CL_SignonReply( void );
|
||||
void CL_ClearState( void );
|
||||
size_t CL_BuildMasterServerScanRequest( char *buf, size_t size, qboolean nat );
|
||||
|
||||
//
|
||||
// cl_demo.c
|
||||
@@ -806,20 +795,6 @@ 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
|
||||
//
|
||||
@@ -835,6 +810,7 @@ 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 );
|
||||
@@ -848,15 +824,11 @@ 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 SPR_AdjustTexCoords( float width, float height, float *s1, float *t1, float *s2, float *t2 );
|
||||
void PicAdjustSize( float *x, float *y, float *w, float *h );
|
||||
int CL_GetScreenInfo( SCREENINFO *pscrinfo );
|
||||
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 );
|
||||
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_SetTraceHull( int hull );
|
||||
void CL_GetMousePosition( int *mx, int *my ); // TODO: move to input
|
||||
cl_entity_t* CL_GetViewModel( void );
|
||||
@@ -864,9 +836,6 @@ 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 );
|
||||
|
||||
_inline cl_entity_t *CL_EDICT_NUM( int n )
|
||||
{
|
||||
@@ -891,6 +860,7 @@ 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 );
|
||||
@@ -941,8 +911,10 @@ 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 );
|
||||
@@ -951,6 +923,7 @@ 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 );
|
||||
@@ -991,7 +964,7 @@ 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 );
|
||||
@@ -1001,6 +974,7 @@ 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
|
||||
//
|
||||
@@ -1054,13 +1028,13 @@ 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_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 );
|
||||
void Con_DefaultColor( int r, int g, int b );
|
||||
void Con_InvalidateFonts( void );
|
||||
cl_font_t *Con_GetCurFont( void );
|
||||
cl_font_t *Con_GetFont( int num );
|
||||
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_SetFont( int fontNum );
|
||||
void Con_CharEvent( int key );
|
||||
void Con_RestoreFont( void );
|
||||
void Key_Console( int key );
|
||||
@@ -1155,6 +1129,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 );
|
||||
|
||||
@@ -116,7 +116,7 @@ typedef struct
|
||||
|
||||
// console fonts
|
||||
cl_font_t chars[CON_NUMFONTS];// fonts.wad/font1.fnt
|
||||
cl_font_t *curFont;
|
||||
cl_font_t *curFont, *lastUsedFont;
|
||||
|
||||
// console input
|
||||
field_t input;
|
||||
@@ -213,6 +213,37 @@ void Con_ClearTyping( void )
|
||||
Cmd_AutoCompleteClear();
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Con_StringLength
|
||||
|
||||
skipped color prefixes
|
||||
============
|
||||
*/
|
||||
int Con_StringLength( const char *string )
|
||||
{
|
||||
int len;
|
||||
const char *p;
|
||||
|
||||
if( !string ) return 0;
|
||||
|
||||
len = 0;
|
||||
p = string;
|
||||
|
||||
while( *p )
|
||||
{
|
||||
if( IsColorString( p ))
|
||||
{
|
||||
p += 2;
|
||||
continue;
|
||||
}
|
||||
len++;
|
||||
p++;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Con_MessageMode_f
|
||||
@@ -524,9 +555,89 @@ Con_FixedFont
|
||||
*/
|
||||
qboolean Con_FixedFont( void )
|
||||
{
|
||||
return CL_FixedFont( con.curFont );
|
||||
if( con.curFont && con.curFont->valid && con.curFont->type == FONT_FIXED )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font )
|
||||
{
|
||||
int i, fontWidth;
|
||||
|
||||
if( font->valid )
|
||||
return true; // already loaded
|
||||
|
||||
if( !FS_FileExists( fontname, false ))
|
||||
return false;
|
||||
|
||||
// keep source to print directly into conback image
|
||||
font->hFontTexture = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, TF_FONT|TF_KEEP_SOURCE );
|
||||
R_GetTextureParms( &fontWidth, NULL, font->hFontTexture );
|
||||
|
||||
if( font->hFontTexture && fontWidth != 0 )
|
||||
{
|
||||
font->charHeight = fontWidth / 16 * con_fontscale->value;
|
||||
font->type = FONT_FIXED;
|
||||
|
||||
// build fixed rectangles
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
font->fontRc[i].left = (i * (fontWidth / 16)) % fontWidth;
|
||||
font->fontRc[i].right = font->fontRc[i].left + fontWidth / 16;
|
||||
font->fontRc[i].top = (i / 16) * (fontWidth / 16);
|
||||
font->fontRc[i].bottom = font->fontRc[i].top + fontWidth / 16;
|
||||
font->charWidths[i] = fontWidth / 16 * con_fontscale->value;
|
||||
}
|
||||
font->valid = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font )
|
||||
{
|
||||
int i, fontWidth;
|
||||
byte *buffer;
|
||||
fs_offset_t length;
|
||||
qfont_t *src;
|
||||
|
||||
if( font->valid )
|
||||
return true; // already loaded
|
||||
|
||||
if( !FS_FileExists( fontname, false ))
|
||||
return false;
|
||||
|
||||
font->hFontTexture = ref.dllFuncs.GL_LoadTexture( fontname, NULL, 0, TF_FONT|TF_NEAREST );
|
||||
R_GetTextureParms( &fontWidth, NULL, font->hFontTexture );
|
||||
|
||||
// setup consolefont
|
||||
if( font->hFontTexture && fontWidth != 0 )
|
||||
{
|
||||
// half-life font with variable chars witdh
|
||||
buffer = FS_LoadFile( fontname, &length, false );
|
||||
|
||||
if( buffer && length >= sizeof( qfont_t ))
|
||||
{
|
||||
src = (qfont_t *)buffer;
|
||||
font->charHeight = src->rowheight * con_fontscale->value;
|
||||
font->type = FONT_VARIABLE;
|
||||
|
||||
// build rectangles
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
font->fontRc[i].left = (word)src->fontinfo[i].startoffset % fontWidth;
|
||||
font->fontRc[i].right = font->fontRc[i].left + src->fontinfo[i].charwidth;
|
||||
font->fontRc[i].top = (word)src->fontinfo[i].startoffset / fontWidth;
|
||||
font->fontRc[i].bottom = font->fontRc[i].top + src->rowheight;
|
||||
font->charWidths[i] = src->fontinfo[i].charwidth * con_fontscale->value;
|
||||
}
|
||||
font->valid = true;
|
||||
}
|
||||
if( buffer ) Mem_Free( buffer );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
@@ -537,46 +648,32 @@ INTERNAL RESOURCE
|
||||
*/
|
||||
static void Con_LoadConsoleFont( int fontNumber, cl_font_t *font )
|
||||
{
|
||||
qboolean success = false;
|
||||
float scale = con_fontscale->value;
|
||||
const char *path = NULL;
|
||||
dword crc = 0;
|
||||
|
||||
if( font->valid )
|
||||
return; // already loaded
|
||||
if( font->valid ) return; // already loaded
|
||||
|
||||
// replace default fonts.wad textures by current charset's font
|
||||
if( !CRC32_File( &crc, "fonts.wad" ) || crc == 0x3c0a0029 )
|
||||
{
|
||||
const char *path2 = va("font%i_%s.fnt", fontNumber, Cvar_VariableString( "con_charset" ) );
|
||||
if( FS_FileExists( path2, false ) )
|
||||
path = path2;
|
||||
}
|
||||
|
||||
// loading conchars
|
||||
if( Sys_CheckParm( "-oldfont" ))
|
||||
{
|
||||
success = Con_LoadVariableWidthFont( "gfx/conchars.fnt", font, scale, kRenderTransTexture, TF_FONT|TF_NEAREST );
|
||||
}
|
||||
Con_LoadVariableWidthFont( "gfx/conchars.fnt", font );
|
||||
else
|
||||
{
|
||||
string path;
|
||||
dword crc = 0;
|
||||
if( !path )
|
||||
path = va( "fonts/font%i", fontNumber );
|
||||
|
||||
// replace default fonts.wad textures by current charset's font
|
||||
if( !CRC32_File( &crc, "fonts.wad" ) || crc == 0x3c0a0029 )
|
||||
{
|
||||
if( Q_snprintf( path, sizeof( path ),
|
||||
"font%i_%s.fnt", fontNumber, Cvar_VariableString( "con_charset" )) > 0 )
|
||||
{
|
||||
success = Con_LoadVariableWidthFont( path, font, scale, kRenderTransTexture, TF_FONT|TF_NEAREST );
|
||||
}
|
||||
}
|
||||
|
||||
if( !success )
|
||||
{
|
||||
Q_snprintf( path, sizeof( path ), "fonts/font%i", fontNumber );
|
||||
success = Con_LoadVariableWidthFont( path, font, scale, kRenderTransTexture, TF_FONT|TF_NEAREST );
|
||||
}
|
||||
Con_LoadVariableWidthFont( path, font );
|
||||
}
|
||||
|
||||
if( !success )
|
||||
{
|
||||
// quake fixed font as fallback
|
||||
// keep source to print directly into conback image
|
||||
if( !Con_LoadFixedWidthFont( "gfx/conchars", font, scale, kRenderTransTexture, TF_FONT|TF_KEEP_SOURCE ))
|
||||
Con_DPrintf( S_ERROR "failed to load console font\n" );
|
||||
}
|
||||
// quake fixed font as fallback
|
||||
if( !font->valid ) Con_LoadFixedWidthFont( "gfx/conchars", font );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -605,7 +702,7 @@ static void Con_LoadConchars( void )
|
||||
fontSize = CON_NUMFONTS - 1;
|
||||
|
||||
// sets the current font
|
||||
con.curFont = &con.chars[fontSize];
|
||||
con.lastUsedFont = con.curFont = &con.chars[fontSize];
|
||||
}
|
||||
|
||||
// CP1251 table
|
||||
@@ -778,25 +875,129 @@ static void Con_DrawCharToConback( int num, const byte *conchars, byte *dest )
|
||||
|
||||
/*
|
||||
====================
|
||||
Con_GetFont
|
||||
Con_TextAdjustSize
|
||||
|
||||
draw charcters routine
|
||||
====================
|
||||
*/
|
||||
cl_font_t *Con_GetFont( int num )
|
||||
static void Con_TextAdjustSize( int *x, int *y, int *w, int *h )
|
||||
{
|
||||
num = bound( 0, num, CON_NUMFONTS - 1 );
|
||||
return &con.chars[num];
|
||||
float xscale, yscale;
|
||||
|
||||
if( !x && !y && !w && !h ) return;
|
||||
|
||||
// scale for screen sizes
|
||||
xscale = (float)refState.width / (float)clgame.scrInfo.iWidth;
|
||||
yscale = (float)refState.height / (float)clgame.scrInfo.iHeight;
|
||||
|
||||
if( x ) *x *= xscale;
|
||||
if( y ) *y *= yscale;
|
||||
if( w ) *w *= xscale;
|
||||
if( h ) *h *= yscale;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
Con_GetCurFont
|
||||
Con_DrawGenericChar
|
||||
|
||||
draw console single character
|
||||
====================
|
||||
*/
|
||||
cl_font_t *Con_GetCurFont( void )
|
||||
static int Con_DrawGenericChar( int x, int y, int number, rgba_t color )
|
||||
{
|
||||
return con.curFont;
|
||||
int width, height;
|
||||
float s1, t1, s2, t2;
|
||||
wrect_t *rc;
|
||||
|
||||
number &= 255;
|
||||
|
||||
if( !con.curFont || !con.curFont->valid )
|
||||
return 0;
|
||||
|
||||
number = Con_UtfProcessChar( number );
|
||||
if( !number )
|
||||
return 0;
|
||||
|
||||
if( y < -con.curFont->charHeight )
|
||||
return 0;
|
||||
|
||||
rc = &con.curFont->fontRc[number];
|
||||
R_GetTextureParms( &width, &height, con.curFont->hFontTexture );
|
||||
|
||||
if( !width || !height )
|
||||
return con.curFont->charWidths[number];
|
||||
|
||||
// don't apply color to fixed fonts it's already colored
|
||||
if( con.curFont->type != FONT_FIXED || REF_GET_PARM( PARM_TEX_GLFORMAT, con.curFont->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] );
|
||||
|
||||
// calc rectangle
|
||||
s1 = (float)rc->left / width;
|
||||
t1 = (float)rc->top / height;
|
||||
s2 = (float)rc->right / width;
|
||||
t2 = (float)rc->bottom / height;
|
||||
width = ( rc->right - rc->left ) * con_fontscale->value;
|
||||
height = ( rc->bottom - rc->top ) * con_fontscale->value;
|
||||
|
||||
if( clgame.ds.adjust_size )
|
||||
Con_TextAdjustSize( &x, &y, &width, &height );
|
||||
ref.dllFuncs.R_DrawStretchPic( x, y, width, height, s1, t1, s2, t2, con.curFont->hFontTexture );
|
||||
ref.dllFuncs.Color4ub( 255, 255, 255, 255 ); // don't forget reset color
|
||||
|
||||
return con.curFont->charWidths[number];
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
Con_SetFont
|
||||
|
||||
choose font size
|
||||
====================
|
||||
*/
|
||||
void Con_SetFont( int fontNum )
|
||||
{
|
||||
fontNum = bound( 0, fontNum, CON_NUMFONTS - 1 );
|
||||
con.curFont = &con.chars[fontNum];
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
Con_RestoreFont
|
||||
|
||||
restore auto-selected console font
|
||||
(that based on screen resolution)
|
||||
====================
|
||||
*/
|
||||
void Con_RestoreFont( void )
|
||||
{
|
||||
con.curFont = con.lastUsedFont;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
Con_DrawCharacter
|
||||
|
||||
client version of routine
|
||||
====================
|
||||
*/
|
||||
int Con_DrawCharacter( int x, int y, int number, rgba_t color )
|
||||
{
|
||||
ref.dllFuncs.GL_SetRenderMode( kRenderTransTexture );
|
||||
return Con_DrawGenericChar( x, y, number, color );
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
Con_DrawCharacterLen
|
||||
|
||||
returns character sizes in screen pixels
|
||||
====================
|
||||
*/
|
||||
void Con_DrawCharacterLen( int number, int *width, int *height )
|
||||
{
|
||||
if( width && con.curFont ) *width = con.curFont->charWidths[number];
|
||||
if( height && con.curFont ) *height = con.curFont->charHeight;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -808,7 +1009,105 @@ compute string width and height in screen pixels
|
||||
*/
|
||||
void GAME_EXPORT Con_DrawStringLen( const char *pText, int *length, int *height )
|
||||
{
|
||||
return CL_DrawStringLen( con.curFont, pText, length, height, FONT_DRAW_UTF8 );
|
||||
int curLength = 0;
|
||||
|
||||
if( !con.curFont )
|
||||
return;
|
||||
if( height )
|
||||
*height = con.curFont->charHeight;
|
||||
if (!length)
|
||||
return;
|
||||
|
||||
*length = 0;
|
||||
|
||||
while( *pText )
|
||||
{
|
||||
byte c = *pText;
|
||||
|
||||
if( *pText == '\n' )
|
||||
{
|
||||
pText++;
|
||||
curLength = 0;
|
||||
}
|
||||
|
||||
// skip color strings they are not drawing
|
||||
if( IsColorString( pText ))
|
||||
{
|
||||
pText += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Convert to unicode
|
||||
c = Con_UtfProcessChar( c );
|
||||
|
||||
if( c )
|
||||
curLength += con.curFont->charWidths[c];
|
||||
|
||||
pText++;
|
||||
|
||||
if( curLength > *length )
|
||||
*length = curLength;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Con_DrawString
|
||||
|
||||
Draws a multi-colored string, optionally forcing
|
||||
to a fixed color.
|
||||
==================
|
||||
*/
|
||||
int Con_DrawGenericString( int x, int y, const char *string, rgba_t setColor, qboolean forceColor, int hideChar )
|
||||
{
|
||||
rgba_t color;
|
||||
int drawLen = 0;
|
||||
int numDraws = 0;
|
||||
const char *s;
|
||||
|
||||
if( !con.curFont ) return 0; // no font set
|
||||
|
||||
Con_UtfProcessChar( 0 );
|
||||
|
||||
// draw the colored text
|
||||
memcpy( color, setColor, sizeof( color ));
|
||||
s = string;
|
||||
|
||||
while( *s )
|
||||
{
|
||||
if( *s == '\n' )
|
||||
{
|
||||
s++;
|
||||
if( !*s ) break; // at end the string
|
||||
drawLen = 0; // begin new row
|
||||
y += con.curFont->charHeight;
|
||||
}
|
||||
|
||||
if( IsColorString( s ))
|
||||
{
|
||||
if( !forceColor )
|
||||
{
|
||||
memcpy( color, g_color_table[ColorIndex(*(s+1))], sizeof( color ));
|
||||
color[3] = setColor[3];
|
||||
}
|
||||
|
||||
s += 2;
|
||||
numDraws++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// hide char for overstrike mode
|
||||
if( hideChar == numDraws )
|
||||
drawLen += con.curFont->charWidths[*s];
|
||||
else drawLen += Con_DrawCharacter( x + drawLen, y, *s, color );
|
||||
|
||||
numDraws++;
|
||||
s++;
|
||||
}
|
||||
|
||||
ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
|
||||
return drawLen;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -820,9 +1119,10 @@ client version of routine
|
||||
*/
|
||||
int Con_DrawString( int x, int y, const char *string, rgba_t setColor )
|
||||
{
|
||||
return CL_DrawString( x, y, string, setColor, con.curFont, FONT_DRAW_UTF8 );
|
||||
return Con_DrawGenericString( x, y, string, setColor, false, -1 );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Con_Init
|
||||
@@ -1199,7 +1499,7 @@ void Field_KeyDownEvent( field_t *edit, int key )
|
||||
return;
|
||||
}
|
||||
|
||||
if( key == K_BACKSPACE || key == K_X_BUTTON )
|
||||
if( key == K_BACKSPACE )
|
||||
{
|
||||
if( edit->cursor > 0 )
|
||||
{
|
||||
@@ -1211,7 +1511,7 @@ void Field_KeyDownEvent( field_t *edit, int key )
|
||||
return;
|
||||
}
|
||||
|
||||
if( key == K_RIGHTARROW || key == K_DPAD_RIGHT )
|
||||
if( key == K_RIGHTARROW )
|
||||
{
|
||||
if( edit->cursor < len ) edit->cursor = Con_UtfMoveRight( edit->buffer, edit->cursor, edit->widthInChars );
|
||||
if( edit->cursor >= edit->scroll + edit->widthInChars && edit->cursor <= len )
|
||||
@@ -1219,7 +1519,7 @@ void Field_KeyDownEvent( field_t *edit, int key )
|
||||
return;
|
||||
}
|
||||
|
||||
if( key == K_LEFTARROW || key == K_DPAD_LEFT )
|
||||
if( key == K_LEFTARROW )
|
||||
{
|
||||
if( edit->cursor > 0 ) edit->cursor = Con_UtfMoveLeft( edit->buffer, edit->cursor );
|
||||
if( edit->cursor < edit->scroll ) edit->scroll--;
|
||||
@@ -1314,7 +1614,7 @@ Field_DrawInputLine
|
||||
void Field_DrawInputLine( int x, int y, field_t *edit )
|
||||
{
|
||||
int len, cursorChar;
|
||||
int drawLen;
|
||||
int drawLen, hideChar = -1;
|
||||
int prestep, curPos;
|
||||
char str[MAX_SYSPATH];
|
||||
byte *colorDefault;
|
||||
@@ -1351,23 +1651,35 @@ void Field_DrawInputLine( int x, int y, field_t *edit )
|
||||
// save char for overstrike
|
||||
cursorChar = str[edit->cursor - prestep];
|
||||
|
||||
if( host.key_overstrike && cursorChar && !((int)( host.realtime * 4 ) & 1 ))
|
||||
hideChar = edit->cursor - prestep; // skip this char
|
||||
|
||||
// draw it
|
||||
CL_DrawString( x, y, str, colorDefault, con.curFont, FONT_DRAW_UTF8 );
|
||||
Con_DrawGenericString( x, y, str, colorDefault, false, hideChar );
|
||||
|
||||
// draw the cursor
|
||||
if((int)( host.realtime * 4 ) & 1 ) return; // off blink
|
||||
|
||||
// calc cursor position
|
||||
str[edit->cursor - prestep] = 0;
|
||||
CL_DrawStringLen( con.curFont, str, &curPos, NULL, FONT_DRAW_UTF8 );
|
||||
Con_DrawStringLen( str, &curPos, NULL );
|
||||
Con_UtfProcessChar( 0 );
|
||||
|
||||
if( host.key_overstrike )
|
||||
if( host.key_overstrike && cursorChar )
|
||||
{
|
||||
CL_DrawCharacter( x + curPos, y, '|', colorDefault, con.curFont, 0 );
|
||||
// overstrike cursor
|
||||
#if 0
|
||||
pglEnable( GL_BLEND );
|
||||
pglDisable( GL_ALPHA_TEST );
|
||||
pglBlendFunc( GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA );
|
||||
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
#endif
|
||||
Con_DrawGenericChar( x + curPos, y, cursorChar, colorDefault );
|
||||
}
|
||||
else
|
||||
{
|
||||
CL_DrawCharacter( x + curPos, y, '_', colorDefault, con.curFont, 0 );
|
||||
Con_UtfProcessChar( 0 );
|
||||
Con_DrawCharacter( x + curPos, y, '_', colorDefault );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1481,10 +1793,6 @@ static void Con_SaveHistory( con_history_t *self )
|
||||
int historyStart = self->next - CON_HISTORY, i;
|
||||
file_t *f;
|
||||
|
||||
// do not save history if nothing was executed
|
||||
if( self->next == 0 )
|
||||
return;
|
||||
|
||||
if( historyStart < 0 )
|
||||
historyStart = 0;
|
||||
|
||||
@@ -1520,8 +1828,8 @@ void Key_Console( int key )
|
||||
return;
|
||||
}
|
||||
|
||||
// enter or A finish the line
|
||||
if( key == K_ENTER || key == K_KP_ENTER || key == K_A_BUTTON )
|
||||
// enter finishes the line
|
||||
if( key == K_ENTER || key == K_KP_ENTER )
|
||||
{
|
||||
// backslash text are commands, else chat
|
||||
if( con.input.buffer[0] == '\\' || con.input.buffer[0] == '/' )
|
||||
@@ -1548,7 +1856,7 @@ void Key_Console( int key )
|
||||
}
|
||||
|
||||
// command completion
|
||||
if( key == K_TAB || key == K_L2_BUTTON )
|
||||
if( key == K_TAB )
|
||||
{
|
||||
Con_CompleteCommand( &con.input );
|
||||
Con_Bottom();
|
||||
@@ -1569,13 +1877,13 @@ void Key_Console( int key )
|
||||
}
|
||||
|
||||
// console scrolling
|
||||
if( key == K_PGUP || key == K_DPAD_UP )
|
||||
if( key == K_PGUP )
|
||||
{
|
||||
Con_PageUp( 1 );
|
||||
return;
|
||||
}
|
||||
|
||||
if( key == K_PGDN || key == K_DPAD_DOWN )
|
||||
if( key == K_PGDN )
|
||||
{
|
||||
Con_PageDown( 1 );
|
||||
return;
|
||||
@@ -1611,23 +1919,6 @@ void Key_Console( int key )
|
||||
return;
|
||||
}
|
||||
|
||||
// enable the OSK with button press
|
||||
if( key == K_Y_BUTTON )
|
||||
{
|
||||
Key_EnableTextInput( true, true );
|
||||
return;
|
||||
}
|
||||
|
||||
// exit the console by pressing MINUS on NSwitch
|
||||
// or both Back(Select)/Start buttons for everyone else
|
||||
if( key == K_BACK_BUTTON || key == K_START_BUTTON )
|
||||
{
|
||||
if( cls.state == ca_active && !cl.background )
|
||||
Key_SetKeyDest( key_game );
|
||||
else UI_SetActiveMenu( true );
|
||||
return;
|
||||
}
|
||||
|
||||
// pass to the normal editline routine
|
||||
Field_KeyDownEvent( &con.input, key );
|
||||
}
|
||||
@@ -1643,14 +1934,14 @@ void Key_Message( int key )
|
||||
{
|
||||
char buffer[MAX_SYSPATH];
|
||||
|
||||
if( key == K_ESCAPE || key == K_BACK_BUTTON )
|
||||
if( key == K_ESCAPE )
|
||||
{
|
||||
Key_SetKeyDest( key_game );
|
||||
Con_ClearField( &con.chat );
|
||||
return;
|
||||
}
|
||||
|
||||
if( key == K_ENTER || key == K_KP_ENTER || key == K_A_BUTTON )
|
||||
if( key == K_ENTER || key == K_KP_ENTER )
|
||||
{
|
||||
if( con.chat.buffer[0] && cls.state == ca_active )
|
||||
{
|
||||
@@ -1692,7 +1983,7 @@ void Con_DrawInput( int lines )
|
||||
return;
|
||||
|
||||
y = lines - ( con.curFont->charHeight * 2 );
|
||||
CL_DrawCharacter( con.curFont->charWidths[' '], y, ']', g_color_table[7], con.curFont, 0 );
|
||||
Con_DrawCharacter( con.curFont->charWidths[' '], y, ']', g_color_table[7] );
|
||||
Field_DrawInputLine( con.curFont->charWidths[' ']*2, y, &con.input );
|
||||
}
|
||||
|
||||
@@ -1705,37 +1996,30 @@ Custom debug messages
|
||||
*/
|
||||
int Con_DrawDebugLines( void )
|
||||
{
|
||||
notify_t *notify = con.notify;
|
||||
int i, count = 0;
|
||||
int defaultX;
|
||||
int y = 20;
|
||||
int fontTall;
|
||||
|
||||
if( !con.curFont || !con.curFont->valid )
|
||||
return 0;
|
||||
|
||||
defaultX = refState.width / 4;
|
||||
fontTall = con.curFont->charHeight + 1;
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( con.notify ); i++, notify++ )
|
||||
for( i = 0; i < MAX_DBG_NOTIFY; i++ )
|
||||
{
|
||||
int x, len;
|
||||
if( host.realtime < con.notify[i].expire && con.notify[i].key_dest == cls.key_dest )
|
||||
{
|
||||
int x, len;
|
||||
int fontTall = 0;
|
||||
|
||||
if( host.realtime > notify->expire )
|
||||
continue;
|
||||
Con_DrawStringLen( con.notify[i].szNotify, &len, &fontTall );
|
||||
x = refState.width - Q_max( defaultX, len ) - 10;
|
||||
fontTall += 1;
|
||||
|
||||
if( notify->key_dest != cls.key_dest )
|
||||
continue;
|
||||
if( y + fontTall > refState.height - 20 )
|
||||
return count;
|
||||
|
||||
Con_DrawStringLen( notify->szNotify, &len, NULL );
|
||||
x = refState.width - Q_max( defaultX, len ) - 10;
|
||||
|
||||
if( y + fontTall > refState.height - 20 )
|
||||
return count;
|
||||
|
||||
count++;
|
||||
y += fontTall;
|
||||
CL_DrawString( x, y, notify->szNotify, notify->color, con.curFont, FONT_DRAW_UTF8 | FONT_DRAW_NOLF );
|
||||
count++;
|
||||
y = 20 + fontTall * i;
|
||||
Con_DrawString( x, y, con.notify[i].szNotify, con.notify[i].color );
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
@@ -1764,7 +2048,7 @@ void Con_DrawDebug( void )
|
||||
}
|
||||
else
|
||||
{
|
||||
timeStart = host.realtime;
|
||||
timeStart = Sys_DoubleTime();
|
||||
}
|
||||
|
||||
if( !host.allow_console || Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" ))
|
||||
@@ -1844,11 +2128,7 @@ int Con_DrawConsoleLine( int y, int lineno )
|
||||
return 0; // this string will be shown only at notify
|
||||
|
||||
if( y >= con.curFont->charHeight )
|
||||
{
|
||||
float x = con.curFont->charWidths[' '];
|
||||
|
||||
CL_DrawString( x, y, li->start, g_color_table[7], con.curFont, FONT_DRAW_UTF8 );
|
||||
}
|
||||
Con_DrawGenericString( con.curFont->charWidths[' '], y, li->start, g_color_table[7], false, -1 );
|
||||
|
||||
return con.curFont->charHeight;
|
||||
}
|
||||
@@ -1915,15 +2195,17 @@ void Con_DrawSolidConsole( int lines )
|
||||
// draw current version
|
||||
memcpy( color, g_color_table[7], sizeof( color ));
|
||||
|
||||
Q_snprintf( curbuild, MAX_STRING, XASH_ENGINE_NAME " %i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
|
||||
Q_snprintf( curbuild, MAX_STRING, "%s %i/%s (%s-%s build %i)", XASH_ENGINE_NAME, PROTOCOL_VERSION, XASH_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
|
||||
|
||||
Con_DrawStringLen( curbuild, &stringLen, &charH );
|
||||
|
||||
start = refState.width - stringLen;
|
||||
stringLen = Con_StringLength( curbuild );
|
||||
|
||||
fraction = lines / (float)refState.height;
|
||||
color[3] = Q_min( fraction * 2.0f, 1.0f ) * 255; // fadeout version number
|
||||
|
||||
Con_DrawString( start, 0, curbuild, color );
|
||||
for( i = 0; i < stringLen; i++ )
|
||||
width += Con_DrawCharacter( start + width, 0, curbuild[i], color );
|
||||
|
||||
// draw the text
|
||||
if( CON_LINES_COUNT > 0 )
|
||||
@@ -1940,7 +2222,7 @@ void Con_DrawSolidConsole( int lines )
|
||||
|
||||
// draw red arrows to show the buffer is backscrolled
|
||||
for( x = 0; x < con.linewidth; x += 4 )
|
||||
CL_DrawCharacter( ( x + 1 ) * start, y, '^', g_color_table[1], con.curFont, 0 );
|
||||
Con_DrawCharacter(( x + 1 ) * start, y, '^', g_color_table[1] );
|
||||
y -= con.curFont->charHeight;
|
||||
}
|
||||
x = lastline;
|
||||
@@ -2043,7 +2325,7 @@ void Con_DrawVersion( void )
|
||||
{
|
||||
// draws the current build
|
||||
byte *color = g_color_table[7];
|
||||
int stringLen, charH = 0;
|
||||
int i, stringLen, width = 0, charH = 0;
|
||||
int start, height = refState.height;
|
||||
qboolean draw_version = false;
|
||||
string curbuild;
|
||||
@@ -2066,14 +2348,16 @@ void Con_DrawVersion( void )
|
||||
host.force_draw_version = false;
|
||||
|
||||
if( host.force_draw_version || draw_version )
|
||||
Q_snprintf( curbuild, MAX_STRING, XASH_ENGINE_NAME " v%i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
|
||||
else Q_snprintf( curbuild, MAX_STRING, "v%i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
|
||||
Q_snprintf( curbuild, MAX_STRING, "%s v%i/%s (%s-%s build %i)", XASH_ENGINE_NAME, PROTOCOL_VERSION, XASH_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
|
||||
else Q_snprintf( curbuild, MAX_STRING, "v%i/%s (%s-%s build %i)", PROTOCOL_VERSION, XASH_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
|
||||
|
||||
Con_DrawStringLen( curbuild, &stringLen, &charH );
|
||||
start = refState.width - stringLen * 1.05f;
|
||||
stringLen = Con_StringLength( curbuild );
|
||||
height -= charH * 1.05f;
|
||||
|
||||
Con_DrawString( start, height, curbuild, color );
|
||||
for( i = 0; i < stringLen; i++ )
|
||||
width += Con_DrawCharacter( start + width, height, curbuild[i], color );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2113,10 +2397,10 @@ void Con_RunConsole( void )
|
||||
con.vislines = con.showlines;
|
||||
}
|
||||
|
||||
if( FBitSet( con_charset->flags, FCVAR_CHANGED ) ||
|
||||
if( FBitSet( con_charset->flags, FCVAR_CHANGED ) ||
|
||||
FBitSet( con_fontscale->flags, FCVAR_CHANGED ) ||
|
||||
FBitSet( con_fontnum->flags, FCVAR_CHANGED ) ||
|
||||
FBitSet( cl_charset->flags, FCVAR_CHANGED ))
|
||||
FBitSet( cl_charset->flags, FCVAR_CHANGED ) )
|
||||
{
|
||||
// update codepage parameters
|
||||
if( !Q_stricmp( con_charset->string, "cp1251" ))
|
||||
@@ -2138,10 +2422,13 @@ void Con_RunConsole( void )
|
||||
g_utf8 = !Q_stricmp( cl_charset->string, "utf-8" );
|
||||
Con_InvalidateFonts();
|
||||
Con_LoadConchars();
|
||||
cls.creditsFont.valid = false;
|
||||
SCR_LoadCreditsFont();
|
||||
ClearBits( con_charset->flags, FCVAR_CHANGED );
|
||||
ClearBits( con_fontnum->flags, FCVAR_CHANGED );
|
||||
ClearBits( con_fontscale->flags, FCVAR_CHANGED );
|
||||
ClearBits( cl_charset->flags, FCVAR_CHANGED );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2276,10 +2563,8 @@ Con_InvalidateFonts
|
||||
*/
|
||||
void Con_InvalidateFonts( void )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < ARRAYSIZE( con.chars ); i++ )
|
||||
CL_FreeFont( &con.chars[i] );
|
||||
con.curFont = NULL;
|
||||
memset( con.chars, 0, sizeof( con.chars ));
|
||||
con.curFont = con.lastUsedFont = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -44,7 +44,6 @@ 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;
|
||||
convar_t *joy_enable;
|
||||
static convar_t *joy_pitch;
|
||||
static convar_t *joy_yaw;
|
||||
@@ -245,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 )
|
||||
@@ -394,10 +393,10 @@ void Joy_Init( void )
|
||||
joy_forward_key_threshold = Cvar_Get( "joy_forward_key_threshold", "24576", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "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
|
||||
joy_side_deadzone = Cvar_Get( "joy_side_deadzone", DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "side axis deadzone. Value from 0 to 32767" );
|
||||
joy_forward_deadzone = Cvar_Get( "joy_forward_deadzone", DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "forward axis deadzone. Value from 0 to 32767");
|
||||
joy_pitch_deadzone = Cvar_Get( "joy_pitch_deadzone", DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "pitch axis deadzone. Value from 0 to 32767");
|
||||
joy_yaw_deadzone = Cvar_Get( "joy_yaw_deadzone", DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "yaw axis deadzone. Value from 0 to 32767" );
|
||||
joy_side_deadzone = Cvar_Get( "joy_side_deadzone", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "side axis deadzone. Value from 0 to 32767" );
|
||||
joy_forward_deadzone = Cvar_Get( "joy_forward_deadzone", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "forward axis deadzone. Value from 0 to 32767");
|
||||
joy_pitch_deadzone = Cvar_Get( "joy_pitch_deadzone", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "pitch axis deadzone. Value from 0 to 32767");
|
||||
joy_yaw_deadzone = Cvar_Get( "joy_yaw_deadzone", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "yaw axis deadzone. Value from 0 to 32767" );
|
||||
|
||||
joy_axis_binding = Cvar_Get( "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" );
|
||||
@@ -408,17 +407,13 @@ void Joy_Init( void )
|
||||
|
||||
joy_enable = Cvar_Get( "joy_enable", "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "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;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -430,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 );
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ typedef struct touchbuttonlist_s
|
||||
touch_button_t *last;
|
||||
} touchbuttonlist_t;
|
||||
|
||||
static struct touch_s
|
||||
struct touch_s
|
||||
{
|
||||
qboolean initialized;
|
||||
qboolean config_loaded;
|
||||
@@ -151,6 +151,7 @@ convar_t *touch_exp_mult;
|
||||
convar_t *touch_grid_enable;
|
||||
convar_t *touch_grid_count;
|
||||
convar_t *touch_config_file;
|
||||
convar_t *touch_enable;
|
||||
convar_t *touch_in_menu;
|
||||
convar_t *touch_joy_radius;
|
||||
convar_t *touch_dpad_radius;
|
||||
@@ -161,9 +162,7 @@ convar_t *touch_highlight_b;
|
||||
convar_t *touch_highlight_a;
|
||||
convar_t *touch_precise_amount;
|
||||
convar_t *touch_joy_texture;
|
||||
|
||||
CVAR_DEFINE_AUTO( touch_enable, DEFAULT_TOUCH_ENABLE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable touch controls" );
|
||||
CVAR_DEFINE_AUTO( touch_emulate, "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "emulate touch with mouse" );
|
||||
convar_t *touch_emulate;
|
||||
|
||||
// code looks smaller with it
|
||||
#define B(x) (button->x)
|
||||
@@ -215,74 +214,6 @@ static inline int Touch_ExportButtonToConfig( file_t *f, touch_button_t *button,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Touch_DumpConfig
|
||||
|
||||
Dump config to file
|
||||
=================
|
||||
*/
|
||||
qboolean Touch_DumpConfig( const char *name, const char *profilename )
|
||||
{
|
||||
file_t *f;
|
||||
touch_button_t *button;
|
||||
|
||||
f = FS_Open( name, "w", true );
|
||||
|
||||
if( !f )
|
||||
{
|
||||
Con_Printf( S_ERROR "Couldn't write %s.\n", name );
|
||||
return false;
|
||||
}
|
||||
|
||||
FS_Printf( f, "//=======================================================================\n");
|
||||
FS_Printf( f, "//\tCopyright FWGS & XashXT group %s (c)\n", Q_timestamp( TIME_YEAR_ONLY ));
|
||||
FS_Printf( f, "//\t\t\ttouchscreen config\n" );
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
FS_Printf( f, "\ntouch_config_file \"%s\"\n", profilename );
|
||||
FS_Printf( f, "\n// touch cvars\n" );
|
||||
FS_Printf( f, "\n// sensitivity settings\n" );
|
||||
FS_Printf( f, "touch_pitch \"%f\"\n", touch_pitch->value );
|
||||
FS_Printf( f, "touch_yaw \"%f\"\n", touch_yaw->value );
|
||||
FS_Printf( f, "touch_forwardzone \"%f\"\n", touch_forwardzone->value );
|
||||
FS_Printf( f, "touch_sidezone \"%f\"\n", touch_sidezone->value );
|
||||
FS_Printf( f, "touch_nonlinear_look \"%d\"\n", CVAR_TO_BOOL(touch_nonlinear_look));
|
||||
FS_Printf( f, "touch_pow_factor \"%f\"\n", touch_pow_factor->value );
|
||||
FS_Printf( f, "touch_pow_mult \"%f\"\n", touch_pow_mult->value );
|
||||
FS_Printf( f, "touch_exp_mult \"%f\"\n", touch_exp_mult->value );
|
||||
FS_Printf( f, "\n// grid settings\n" );
|
||||
FS_Printf( f, "touch_grid_count \"%d\"\n", (int)touch_grid_count->value );
|
||||
FS_Printf( f, "touch_grid_enable \"%d\"\n", CVAR_TO_BOOL(touch_grid_enable));
|
||||
FS_Printf( f, "\n// global overstroke (width, r, g, b, a)\n" );
|
||||
FS_Printf( f, "touch_set_stroke %d %d %d %d %d\n", touch.swidth, touch.scolor[0], touch.scolor[1], touch.scolor[2], touch.scolor[3] );
|
||||
FS_Printf( f, "\n// highlight when pressed\n" );
|
||||
FS_Printf( f, "touch_highlight_r \"%f\"\n", touch_highlight_r->value );
|
||||
FS_Printf( f, "touch_highlight_g \"%f\"\n", touch_highlight_g->value );
|
||||
FS_Printf( f, "touch_highlight_b \"%f\"\n", touch_highlight_b->value );
|
||||
FS_Printf( f, "touch_highlight_a \"%f\"\n", touch_highlight_a->value );
|
||||
FS_Printf( f, "\n// _joy and _dpad options\n" );
|
||||
FS_Printf( f, "touch_dpad_radius \"%f\"\n", touch_dpad_radius->value );
|
||||
FS_Printf( f, "touch_joy_radius \"%f\"\n", touch_joy_radius->value );
|
||||
FS_Printf( f, "\n// how much slowdown when Precise Look button pressed\n" );
|
||||
FS_Printf( f, "touch_precise_amount \"%f\"\n", touch_precise_amount->value );
|
||||
FS_Printf( f, "\n// enable/disable move indicator\n" );
|
||||
FS_Printf( f, "touch_move_indicator \"%f\"\n", touch_move_indicator->value );
|
||||
|
||||
FS_Printf( f, "\n// reset menu state when execing config\n" );
|
||||
FS_Printf( f, "touch_setclientonly 0\n" );
|
||||
FS_Printf( f, "\n// touch buttons\n" );
|
||||
FS_Printf( f, "touch_removeall\n" );
|
||||
|
||||
for( button = touch.list_user.first; button; button = button->next )
|
||||
{
|
||||
Touch_ExportButtonToConfig( f, button, false );
|
||||
}
|
||||
|
||||
FS_Close( f );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Touch_WriteConfig
|
||||
@@ -306,14 +237,61 @@ void Touch_WriteConfig( void )
|
||||
Q_snprintf( newconfigfile, sizeof( newconfigfile ), "%s.new", touch_config_file->string );
|
||||
Q_snprintf( oldconfigfile, sizeof( oldconfigfile ), "%s.bak", touch_config_file->string );
|
||||
|
||||
if( Touch_DumpConfig( newconfigfile, touch_config_file->string ))
|
||||
f = FS_Open( newconfigfile, "w", true );
|
||||
if( f )
|
||||
{
|
||||
touch_button_t *button;
|
||||
FS_Printf( f, "//=======================================================================\n");
|
||||
FS_Printf( f, "//\tCopyright FWGS & XashXT group %s (c)\n", Q_timestamp( TIME_YEAR_ONLY ));
|
||||
FS_Printf( f, "//\t\t\ttouchscreen config\n" );
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
FS_Printf( f, "\ntouch_config_file \"%s\"\n", touch_config_file->string );
|
||||
FS_Printf( f, "\n// touch cvars\n" );
|
||||
FS_Printf( f, "\n// sensitivity settings\n" );
|
||||
FS_Printf( f, "touch_pitch \"%f\"\n", touch_pitch->value );
|
||||
FS_Printf( f, "touch_yaw \"%f\"\n", touch_yaw->value );
|
||||
FS_Printf( f, "touch_forwardzone \"%f\"\n", touch_forwardzone->value );
|
||||
FS_Printf( f, "touch_sidezone \"%f\"\n", touch_sidezone->value );
|
||||
FS_Printf( f, "touch_nonlinear_look \"%d\"\n", CVAR_TO_BOOL(touch_nonlinear_look));
|
||||
FS_Printf( f, "touch_pow_factor \"%f\"\n", touch_pow_factor->value );
|
||||
FS_Printf( f, "touch_pow_mult \"%f\"\n", touch_pow_mult->value );
|
||||
FS_Printf( f, "touch_exp_mult \"%f\"\n", touch_exp_mult->value );
|
||||
FS_Printf( f, "\n// grid settings\n" );
|
||||
FS_Printf( f, "touch_grid_count \"%d\"\n", (int)touch_grid_count->value );
|
||||
FS_Printf( f, "touch_grid_enable \"%d\"\n", CVAR_TO_BOOL(touch_grid_enable));
|
||||
FS_Printf( f, "\n// global overstroke (width, r, g, b, a)\n" );
|
||||
FS_Printf( f, "touch_set_stroke %d %d %d %d %d\n", touch.swidth, touch.scolor[0], touch.scolor[1], touch.scolor[2], touch.scolor[3] );
|
||||
FS_Printf( f, "\n// highlight when pressed\n" );
|
||||
FS_Printf( f, "touch_highlight_r \"%f\"\n", touch_highlight_r->value );
|
||||
FS_Printf( f, "touch_highlight_g \"%f\"\n", touch_highlight_g->value );
|
||||
FS_Printf( f, "touch_highlight_b \"%f\"\n", touch_highlight_b->value );
|
||||
FS_Printf( f, "touch_highlight_a \"%f\"\n", touch_highlight_a->value );
|
||||
FS_Printf( f, "\n// _joy and _dpad options\n" );
|
||||
FS_Printf( f, "touch_dpad_radius \"%f\"\n", touch_dpad_radius->value );
|
||||
FS_Printf( f, "touch_joy_radius \"%f\"\n", touch_joy_radius->value );
|
||||
FS_Printf( f, "\n// how much slowdown when Precise Look button pressed\n" );
|
||||
FS_Printf( f, "touch_precise_amount \"%f\"\n", touch_precise_amount->value );
|
||||
FS_Printf( f, "\n// enable/disable move indicator\n" );
|
||||
FS_Printf( f, "touch_move_indicator \"%f\"\n", touch_move_indicator->value );
|
||||
|
||||
FS_Printf( f, "\n// reset menu state when execing config\n" );
|
||||
FS_Printf( f, "touch_setclientonly 0\n" );
|
||||
FS_Printf( f, "\n// touch buttons\n" );
|
||||
FS_Printf( f, "touch_removeall\n" );
|
||||
|
||||
for( button = touch.list_user.first; button; button = button->next )
|
||||
{
|
||||
Touch_ExportButtonToConfig( f, button, false );
|
||||
}
|
||||
|
||||
FS_Close( f );
|
||||
|
||||
FS_Delete( oldconfigfile );
|
||||
FS_Rename( touch_config_file->string, oldconfigfile );
|
||||
|
||||
FS_Delete( touch_config_file->string );
|
||||
FS_Rename( newconfigfile, touch_config_file->string );
|
||||
}
|
||||
else Con_Printf( S_ERROR "Couldn't write %s.\n", touch_config_file->string );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -325,8 +303,8 @@ export current touch configuration into profile
|
||||
*/
|
||||
static void Touch_ExportConfig_f( void )
|
||||
{
|
||||
file_t *f;
|
||||
const char *name;
|
||||
string profilename, profilebase;
|
||||
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
@@ -338,15 +316,65 @@ static void Touch_ExportConfig_f( void )
|
||||
|
||||
name = Cmd_Argv( 1 );
|
||||
|
||||
if( Q_strstr( name, "touch_presets/" ))
|
||||
Con_Reportf( "Exporting config to %s\n", name );
|
||||
f = FS_Open( name, "w", true );
|
||||
if( f )
|
||||
{
|
||||
COM_FileBase( name, profilebase, sizeof( profilebase ));
|
||||
Q_snprintf( profilename, sizeof( profilebase ), "touch_profiles/%s (copy).cfg", profilebase );
|
||||
}
|
||||
else Q_strncpy( profilename, name, sizeof( profilename ));
|
||||
string profilename, profilebase;
|
||||
touch_button_t *button;
|
||||
|
||||
Con_Reportf( "Exporting config to \"%s\", profile name \"%s\"\n", name, profilename );
|
||||
Touch_DumpConfig( name, profilename );
|
||||
if( Q_strstr( name, "touch_presets/" ) )
|
||||
{
|
||||
COM_FileBase( name, profilebase );
|
||||
Q_snprintf( profilename, sizeof( profilebase ), "touch_profiles/%s (copy).cfg", profilebase );
|
||||
}
|
||||
else Q_strncpy( profilename, name, sizeof( profilename ));
|
||||
FS_Printf( f, "//=======================================================================\n");
|
||||
FS_Printf( f, "//\tCopyright FWGS & XashXT group %s (c)\n", Q_timestamp( TIME_YEAR_ONLY ));
|
||||
FS_Printf( f, "//\t\t\ttouchscreen preset\n" );
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
FS_Printf( f, "\ntouch_config_file \"%s\"\n", profilename );
|
||||
FS_Printf( f, "\n// touch cvars\n" );
|
||||
FS_Printf( f, "\n// sensitivity settings\n" );
|
||||
FS_Printf( f, "touch_pitch \"%f\"\n", touch_pitch->value );
|
||||
FS_Printf( f, "touch_yaw \"%f\"\n", touch_yaw->value );
|
||||
FS_Printf( f, "touch_forwardzone \"%f\"\n", touch_forwardzone->value );
|
||||
FS_Printf( f, "touch_sidezone \"%f\"\n", touch_sidezone->value );
|
||||
FS_Printf( f, "touch_nonlinear_look \"%d\"\n", CVAR_TO_BOOL(touch_nonlinear_look) );
|
||||
FS_Printf( f, "touch_pow_factor \"%f\"\n", touch_pow_factor->value );
|
||||
FS_Printf( f, "touch_pow_mult \"%f\"\n", touch_pow_mult->value );
|
||||
FS_Printf( f, "touch_exp_mult \"%f\"\n", touch_exp_mult->value );
|
||||
FS_Printf( f, "\n// grid settings\n" );
|
||||
FS_Printf( f, "touch_grid_count \"%d\"\n", (int)touch_grid_count->value );
|
||||
FS_Printf( f, "touch_grid_enable \"%d\"\n", CVAR_TO_BOOL(touch_grid_enable) );
|
||||
FS_Printf( f, "\n// global overstroke (width, r, g, b, a)\n" );
|
||||
FS_Printf( f, "touch_set_stroke %d %d %d %d %d\n", touch.swidth, touch.scolor[0], touch.scolor[1], touch.scolor[2], touch.scolor[3] );
|
||||
FS_Printf( f, "\n// highlight when pressed\n" );
|
||||
FS_Printf( f, "touch_highlight_r \"%f\"\n", touch_highlight_r->value );
|
||||
FS_Printf( f, "touch_highlight_g \"%f\"\n", touch_highlight_g->value );
|
||||
FS_Printf( f, "touch_highlight_b \"%f\"\n", touch_highlight_b->value );
|
||||
FS_Printf( f, "touch_highlight_a \"%f\"\n", touch_highlight_a->value );
|
||||
FS_Printf( f, "\n// _joy and _dpad options\n" );
|
||||
FS_Printf( f, "touch_dpad_radius \"%f\"\n", touch_dpad_radius->value );
|
||||
FS_Printf( f, "touch_joy_radius \"%f\"\n", touch_joy_radius->value );
|
||||
FS_Printf( f, "\n// how much slowdown when Precise Look button pressed\n" );
|
||||
FS_Printf( f, "touch_precise_amount \"%f\"\n", touch_precise_amount->value );
|
||||
FS_Printf( f, "\n// enable/disable move indicator\n" );
|
||||
FS_Printf( f, "touch_move_indicator \"%f\"\n", touch_move_indicator->value );
|
||||
|
||||
FS_Printf( f, "\n// reset menu state when execing config\n" );
|
||||
FS_Printf( f, "touch_setclientonly 0\n" );
|
||||
FS_Printf( f, "\n// touch buttons\n" );
|
||||
FS_Printf( f, "touch_removeall\n" );
|
||||
for( button = touch.list_user.first; button; button = button->next )
|
||||
{
|
||||
Touch_ExportButtonToConfig( f, button, true );
|
||||
}
|
||||
FS_Printf( f, "\n// round button coordinates to grid\n" );
|
||||
FS_Printf( f, "touch_roundall\n" );
|
||||
FS_Close( f );
|
||||
}
|
||||
else Con_Printf( S_ERROR "Couldn't write %s.\n", name );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -469,8 +497,8 @@ static touch_button_t *Touch_FindFirst( touchbuttonlist_t *list, const char *nam
|
||||
|
||||
void Touch_SetClientOnly( byte state )
|
||||
{
|
||||
// TODO: fix clash with vgui cursors
|
||||
touch.clientonly = state;
|
||||
host.mouse_visible = state;
|
||||
|
||||
touch.move_finger = touch.look_finger = -1;
|
||||
touch.forward = touch.side = 0;
|
||||
@@ -737,7 +765,7 @@ static void Touch_ReloadConfig_f( void )
|
||||
touch.edit = touch.selection = NULL;
|
||||
touch.resize_finger = touch.move_finger = touch.look_finger = touch.wheel_finger = -1;
|
||||
|
||||
Cbuf_AddTextf( "exec %s\n", touch_config_file->string );
|
||||
Cbuf_AddText( va("exec %s\n", touch_config_file->string ) );
|
||||
}
|
||||
|
||||
static touch_button_t *Touch_AddButton( touchbuttonlist_t *list,
|
||||
@@ -1016,18 +1044,18 @@ void Touch_Init( void )
|
||||
Touch_AddDefaultButton( "jump", "touch_default/jump", "+jump", 0.880000, 0.227228, 1.000000, 0.454457, color, 2, 1, 0 );
|
||||
Touch_AddDefaultButton( "attack", "touch_default/shoot", "+attack", 0.760000, 0.530200, 0.880000, 0.757428, color, 2, 1, 0 );
|
||||
Touch_AddDefaultButton( "attack2", "touch_default/shoot_alt", "+attack2", 0.760000, 0.302971, 0.880000, 0.530200, color, 2, 1, 0 );
|
||||
Touch_AddDefaultButton( "loadquick", "touch_default/load", "loadquick", 0.680000, 0.000000, 0.760000, 0.151486, color, 2, 1, 16 );
|
||||
Touch_AddDefaultButton( "savequick", "touch_default/save", "savequick", 0.760000, 0.000000, 0.840000, 0.151486, color, 2, 1, 16 );
|
||||
Touch_AddDefaultButton( "messagemode", "touch_default/keyboard", "messagemode", 0.760000, 0.000000, 0.840000, 0.151486, color, 2, 1, 8 );
|
||||
Touch_AddDefaultButton( "loadquick", "touch_default/load", "loadquick", 0.760000, 0.000000, 0.840000, 0.151486, color, 2, 1, 16 );
|
||||
Touch_AddDefaultButton( "savequick", "touch_default/save", "savequick", 0.840000, 0.000000, 0.920000, 0.151486, color, 2, 1, 16 );
|
||||
Touch_AddDefaultButton( "messagemode", "touch_default/keyboard", "messagemode", 0.840000, 0.000000, 0.920000, 0.151486, color, 2, 1, 8 );
|
||||
Touch_AddDefaultButton( "reload", "touch_default/reload", "+reload", 0.000000, 0.302971, 0.120000, 0.530200, color, 2, 1, 0 );
|
||||
Touch_AddDefaultButton( "flashlight", "touch_default/flash_light_filled", "impulse 100", 0.920000, 0.000000, 1.000000, 0.151486, color, 2, 1, 0 );
|
||||
Touch_AddDefaultButton( "scores", "touch_default/map", "+showscores", 0.680000, 0.000000, 0.760000, 0.151486, color, 2, 1, 8 );
|
||||
Touch_AddDefaultButton( "scores", "touch_default/map", "+showscores", 0.760000, 0.000000, 0.840000, 0.151486, color, 2, 1, 8 );
|
||||
Touch_AddDefaultButton( "show_numbers", "touch_default/show_weapons", "exec touch_default/numbers.cfg", 0.440000, 0.833171, 0.520000, 0.984656, color, 2, 1, 0 );
|
||||
Touch_AddDefaultButton( "duck", "touch_default/crouch", "+duck", 0.880000, 0.757428, 1.000000, 0.984656, color, 2, 1, 0 );
|
||||
Touch_AddDefaultButton( "tduck", "touch_default/tduck", ";+duck", 0.560000, 0.833171, 0.620000, 0.946785, color, 2, 1, 0 );
|
||||
Touch_AddDefaultButton( "edit", "touch_default/settings", "touch_enableedit", 0.420000, 0.000000, 0.500000, 0.151486, color, 2, 1, 32 );
|
||||
Touch_AddDefaultButton( "menu", "touch_default/menu", "escape", 0.000000, 0.833171, 0.080000, 0.984656, color, 2, 1, 0 );
|
||||
Touch_AddDefaultButton( "spray", "touch_default/spray", "impulse 201", 0.840000, 0.000000, 0.920000, 0.151486, color, 2, 1, 0 );
|
||||
|
||||
|
||||
Cmd_AddCommand( "touch_addbutton", Touch_AddButton_f, "add native touch button" );
|
||||
Cmd_AddCommand( "touch_removebutton", IN_TouchRemoveButton_f, "remove native touch button" );
|
||||
@@ -1081,16 +1109,11 @@ void Touch_Init( void )
|
||||
touch_joy_texture = Cvar_Get( "touch_joy_texture", "touch_default/joy", FCVAR_FILTERABLE, "texture for move indicator");
|
||||
|
||||
// input devices cvar
|
||||
Cvar_RegisterVariable( &touch_enable );
|
||||
Cvar_RegisterVariable( &touch_emulate );
|
||||
touch_enable = Cvar_Get( "touch_enable", DEFAULT_TOUCH_ENABLE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable touch controls" );
|
||||
touch_emulate = Cvar_Get( "touch_emulate", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "emulate touch with mouse" );
|
||||
|
||||
// TODO: touch platform
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 10 )
|
||||
SDL_SetHint( SDL_HINT_MOUSE_TOUCH_EVENTS, "0" );
|
||||
SDL_SetHint( SDL_HINT_TOUCH_MOUSE_EVENTS, "0" );
|
||||
#else
|
||||
SDL_SetHint( SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1" );
|
||||
#endif
|
||||
/// TODO: touch sdl platform
|
||||
// SDL_SetHint( SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1" );
|
||||
|
||||
touch.initialized = true;
|
||||
}
|
||||
@@ -1110,14 +1133,8 @@ static void Touch_InitConfig( void )
|
||||
/// TODO: hud font
|
||||
//pfnGetScreenInfo( NULL ); //HACK: update hud screen parameters like iHeight
|
||||
if( FS_FileExists( touch_config_file->string, true ) )
|
||||
{
|
||||
Cbuf_AddTextf( "exec \"%s\"\n", touch_config_file->string );
|
||||
Cbuf_Execute();
|
||||
}
|
||||
else
|
||||
{
|
||||
Touch_LoadDefaults_f();
|
||||
}
|
||||
Cbuf_AddText( va( "exec \"%s\"\n", touch_config_file->string ) );
|
||||
else Touch_LoadDefaults_f( );
|
||||
|
||||
Touch_InitEditor();
|
||||
touch.joytexture = ref.dllFuncs.GL_LoadTexture( touch_joy_texture->string, NULL, 0, TF_NOMIPMAP );
|
||||
@@ -1355,7 +1372,7 @@ void Touch_Draw( void )
|
||||
{
|
||||
touch_button_t *button;
|
||||
|
||||
if( !touch.initialized || ( !touch_enable.value && !touch.clientonly ))
|
||||
if( !touch.initialized || (!CVAR_TO_BOOL(touch_enable) && !touch.clientonly) )
|
||||
return;
|
||||
|
||||
Touch_InitConfig();
|
||||
@@ -1498,9 +1515,9 @@ static void Touch_EditMove( touchEventType type, int fingerID, float x, float y,
|
||||
touch.hidebutton->flags &= ~TOUCH_FL_HIDE;
|
||||
|
||||
if( FBitSet( button->flags, TOUCH_FL_HIDE ))
|
||||
Q_strncpy( touch.hidebutton->texturefile, "touch_default/edit_show", sizeof( touch.hidebutton->texturefile ));
|
||||
Q_strcpy( touch.hidebutton->texturefile, "touch_default/edit_show" );
|
||||
else
|
||||
Q_strncpy( touch.hidebutton->texturefile, "touch_default/edit_hide", sizeof( touch.hidebutton->texturefile ));
|
||||
Q_strcpy( touch.hidebutton->texturefile, "touch_default/edit_hide" );
|
||||
}
|
||||
}
|
||||
if( type == event_motion ) // shutdown button move
|
||||
@@ -1949,15 +1966,15 @@ static int Touch_ControlsEvent( touchEventType type, int fingerID, float x, floa
|
||||
|
||||
int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy )
|
||||
{
|
||||
|
||||
// simulate menu mouse click
|
||||
if( cls.key_dest != key_game && !CVAR_TO_BOOL( touch_in_menu ))
|
||||
if( cls.key_dest != key_game && !CVAR_TO_BOOL(touch_in_menu) )
|
||||
{
|
||||
touch.move_finger = touch.resize_finger = touch.look_finger = -1;
|
||||
// Hack for keyboard, hope it help
|
||||
if( cls.key_dest == key_console || cls.key_dest == key_message )
|
||||
{
|
||||
if ( type == event_down ) // don't pop it again on event_up
|
||||
Key_EnableTextInput( true, true );
|
||||
Key_EnableTextInput( true, true );
|
||||
if( cls.key_dest == key_console )
|
||||
{
|
||||
static float y1 = 0;
|
||||
@@ -1994,20 +2011,25 @@ int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx
|
||||
{
|
||||
VGui_MouseMove( TO_SCRN_X(x), TO_SCRN_Y(y) );
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case event_down:
|
||||
VGui_MouseEvent( K_MOUSE1, 1 );
|
||||
break;
|
||||
case event_up:
|
||||
VGui_MouseEvent( K_MOUSE1, 0 );
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
if( type != event_motion )
|
||||
VGui_KeyEvent( K_MOUSE1, type == event_down ? 1 : 0 );
|
||||
|
||||
// allow scoreboard scroll
|
||||
if( host.mouse_visible && type == event_motion )
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( !touch.initialized || ( !touch_enable.value && !touch.clientonly ))
|
||||
if( !touch.initialized || (!CVAR_TO_BOOL(touch_enable) && !touch.clientonly) )
|
||||
{
|
||||
#if 0
|
||||
if( type == event_down )
|
||||
Key_Event( K_MOUSE1, true );
|
||||
if( type == event_up )
|
||||
Key_Event( K_MOUSE1, false );
|
||||
Android_AddMove( dx * (float)refState.width, dy * (float)refState.height );
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( clgame.dllFuncs.pfnTouchEvent && clgame.dllFuncs.pfnTouchEvent( type, fingerID, x, y, dx, dy ) )
|
||||
return true;
|
||||
@@ -2026,65 +2048,35 @@ void Touch_GetMove( float *forward, float *side, float *yaw, float *pitch )
|
||||
|
||||
void Touch_KeyEvent( int key, int down )
|
||||
{
|
||||
static float lx, ly;
|
||||
static int kidNamedFinger = -1;
|
||||
touchEventType event;
|
||||
int xi, yi;
|
||||
float x, y;
|
||||
int finger, xi, yi;
|
||||
static float lx, ly;
|
||||
|
||||
if( !touch_emulate.value )
|
||||
if( !CVAR_TO_BOOL(touch_emulate) )
|
||||
{
|
||||
if( touch_enable.value )
|
||||
if( CVAR_TO_BOOL(touch_enable) )
|
||||
return;
|
||||
|
||||
if( !touch.clientonly )
|
||||
return;
|
||||
}
|
||||
|
||||
if( !key )
|
||||
{
|
||||
if( kidNamedFinger < 0 )
|
||||
return;
|
||||
|
||||
finger = kidNamedFinger;
|
||||
event = event_motion;
|
||||
}
|
||||
else
|
||||
{
|
||||
finger = key == K_MOUSE1 ? 0 : 1;
|
||||
if( down )
|
||||
{
|
||||
event = event_down;
|
||||
kidNamedFinger = finger;
|
||||
}
|
||||
else
|
||||
{
|
||||
event = event_up;
|
||||
kidNamedFinger = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// don't deactivate mouse in game
|
||||
// checking a case when mouse and touchscreen
|
||||
// can be used simultaneously
|
||||
Platform_SetCursorType( dc_arrow );
|
||||
Platform_GetMousePos( &xi, &yi );
|
||||
|
||||
x = xi / SCR_W;
|
||||
y = yi / SCR_H;
|
||||
x = xi/SCR_W;
|
||||
y = yi/SCR_H;
|
||||
|
||||
Con_DPrintf( "event %d %.2f %.2f %.2f %.2f\n",
|
||||
event, x, y, x - lx, y - ly );
|
||||
if( cls.key_dest == key_menu && down < 2 && key == K_MOUSE1 )
|
||||
{
|
||||
UI_MouseMove( xi, yi );
|
||||
UI_KeyEvent( key, down );
|
||||
}
|
||||
|
||||
IN_TouchEvent( event, finger, x, y, x - lx, y - ly );
|
||||
|
||||
lx = x;
|
||||
ly = y;
|
||||
}
|
||||
|
||||
qboolean Touch_WantVisibleCursor( void )
|
||||
{
|
||||
return ( touch_enable.value && touch_emulate.value ) || touch.clientonly;
|
||||
if( down == 1 )
|
||||
Touch_ControlsEvent( event_down, key == K_MOUSE1?0:1, x, y, 0, 0 );
|
||||
else
|
||||
Touch_ControlsEvent( down? event_motion: event_up, key == K_MOUSE1?0:1, x, y, x-lx, y-ly );
|
||||
lx = x, ly = y;
|
||||
}
|
||||
|
||||
void Touch_Shutdown( void )
|
||||
|
||||
@@ -47,6 +47,8 @@ convar_t *cl_backspeed;
|
||||
convar_t *look_filter;
|
||||
convar_t *m_rawinput;
|
||||
|
||||
static qboolean s_bRawInput, s_bMouseGrab;
|
||||
|
||||
/*
|
||||
================
|
||||
IN_CollectInputDevices
|
||||
@@ -61,7 +63,7 @@ uint IN_CollectInputDevices( void )
|
||||
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
|
||||
@@ -92,13 +94,13 @@ void IN_LockInputDevices( qboolean lock )
|
||||
{
|
||||
SetBits( m_ignore->flags, FCVAR_READ_ONLY );
|
||||
SetBits( joy_enable->flags, FCVAR_READ_ONLY );
|
||||
SetBits( touch_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( touch_enable->flags, FCVAR_READ_ONLY );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,33 +173,7 @@ Called when key_dest is changed
|
||||
*/
|
||||
void IN_ToggleClientMouse( int newstate, int oldstate )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
Platform_SetCursorType( dc_arrow );
|
||||
|
||||
#if XASH_ANDROID
|
||||
Android_ShowMouse( true );
|
||||
#endif
|
||||
#if XASH_USE_EVDEV
|
||||
Evdev_SetGrab( false );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
Platform_SetCursorType( dc_none );
|
||||
|
||||
#if XASH_ANDROID
|
||||
Android_ShowMouse( false );
|
||||
#endif
|
||||
#if XASH_USE_EVDEV
|
||||
Evdev_SetGrab( true );
|
||||
#endif
|
||||
}
|
||||
if( newstate == oldstate ) return;
|
||||
|
||||
if( oldstate == key_game )
|
||||
{
|
||||
@@ -207,14 +183,31 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
|
||||
{
|
||||
IN_ActivateMouse();
|
||||
}
|
||||
|
||||
if( ( newstate == key_menu || newstate == key_console || newstate == key_message ) && ( !CL_IsBackgroundMap() || CL_IsBackgroundDemo( )))
|
||||
{
|
||||
#if XASH_ANDROID
|
||||
Android_ShowMouse( true );
|
||||
#endif
|
||||
#ifdef XASH_USE_EVDEV
|
||||
Evdev_SetGrab( false );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if XASH_ANDROID
|
||||
Android_ShowMouse( false );
|
||||
#endif
|
||||
#ifdef XASH_USE_EVDEV
|
||||
Evdev_SetGrab( true );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void IN_CheckMouseState( qboolean active )
|
||||
{
|
||||
static qboolean s_bRawInput, s_bMouseGrab;
|
||||
|
||||
#if XASH_WIN32
|
||||
qboolean useRawInput = ( CVAR_TO_BOOL( m_rawinput ) && clgame.client_dll_uses_sdl ) || clgame.dllFuncs.pfnLookEvent != NULL;
|
||||
qboolean useRawInput = CVAR_TO_BOOL( m_rawinput ) && clgame.client_dll_uses_sdl || clgame.dllFuncs.pfnLookEvent;
|
||||
#else
|
||||
qboolean useRawInput = true; // always use SDL code
|
||||
#endif
|
||||
@@ -315,25 +308,25 @@ IN_MouseMove
|
||||
*/
|
||||
void IN_MouseMove( void )
|
||||
{
|
||||
int x, y;
|
||||
POINT current_pos;
|
||||
|
||||
if( !in_mouseinitialized )
|
||||
return;
|
||||
|
||||
if( touch_emulate.value )
|
||||
{
|
||||
// touch emulation overrides all input
|
||||
Touch_KeyEvent( 0, 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
// find mouse movement
|
||||
Platform_GetMousePos( &x, &y );
|
||||
Platform_GetMousePos( ¤t_pos.x, ¤t_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
|
||||
#if 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 );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -343,6 +336,8 @@ IN_MouseEvent
|
||||
*/
|
||||
void IN_MouseEvent( int key, int down )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( !in_mouseinitialized )
|
||||
return;
|
||||
|
||||
@@ -350,15 +345,10 @@ void IN_MouseEvent( int key, int 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 )
|
||||
if( cls.key_dest == key_game )
|
||||
{
|
||||
// perform button actions
|
||||
VGui_MouseEvent( K_MOUSE1 + key, down );
|
||||
VGui_KeyEvent( K_MOUSE1 + key, down );
|
||||
|
||||
// don't do Key_Event here
|
||||
// client may override IN_MouseEvent
|
||||
@@ -373,23 +363,6 @@ void IN_MouseEvent( int key, int down )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
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 +372,7 @@ void IN_Shutdown( void )
|
||||
{
|
||||
IN_DeactivateMouse( );
|
||||
|
||||
#if XASH_USE_EVDEV
|
||||
#ifdef XASH_USE_EVDEV
|
||||
Evdev_Shutdown();
|
||||
#endif
|
||||
|
||||
@@ -426,7 +399,7 @@ void IN_Init( void )
|
||||
|
||||
Touch_Init();
|
||||
|
||||
#if XASH_USE_EVDEV
|
||||
#ifdef XASH_USE_EVDEV
|
||||
Evdev_Init();
|
||||
#endif
|
||||
}
|
||||
@@ -532,7 +505,7 @@ static void IN_CollectInput( float *forward, float *side, float *pitch, float *y
|
||||
*pitch += y * m_pitch->value;
|
||||
*yaw -= x * m_yaw->value;
|
||||
|
||||
#if XASH_USE_EVDEV
|
||||
#ifdef XASH_USE_EVDEV
|
||||
IN_EvdevMove( yaw, pitch );
|
||||
#endif
|
||||
}
|
||||
@@ -590,7 +563,7 @@ void IN_EngineAppendMove( float frametime, void *cmd1, qboolean active )
|
||||
|
||||
void IN_Commands( void )
|
||||
{
|
||||
#if XASH_USE_EVDEV
|
||||
#ifdef XASH_USE_EVDEV
|
||||
IN_EvdevFrame();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ 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_DeactivateMouse( void );
|
||||
void IN_MouseSavePos( void );
|
||||
@@ -58,8 +57,8 @@ 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 );
|
||||
@@ -74,7 +73,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 );
|
||||
|
||||
//
|
||||
// in_joy.c
|
||||
|
||||
@@ -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, ""},
|
||||
@@ -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
|
||||
@@ -362,7 +374,7 @@ 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 @@ void Key_Unbindall_f( void )
|
||||
|
||||
// set some defaults
|
||||
Key_SetBinding( K_ESCAPE, "escape" );
|
||||
Key_SetBinding( K_START_BUTTON, "escape" );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -384,7 +395,7 @@ void Key_Reset_f( void )
|
||||
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, "" );
|
||||
@@ -434,8 +445,8 @@ 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 );
|
||||
@@ -541,8 +552,8 @@ 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 )
|
||||
@@ -701,6 +712,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 == '~' )
|
||||
@@ -830,9 +842,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:
|
||||
@@ -1139,7 +1149,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 +1157,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 +1178,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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -55,11 +55,12 @@ void GL_RenderFrame( const ref_viewpass_t *rvp )
|
||||
|
||||
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
|
||||
}
|
||||
@@ -74,6 +75,16 @@ 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 )
|
||||
@@ -214,7 +225,7 @@ static qboolean R_DoResetGamma( void )
|
||||
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;
|
||||
|
||||
@@ -268,6 +279,9 @@ static ref_api_t gEngfuncs =
|
||||
Mod_PointInLeaf,
|
||||
Mod_CreatePolygonsForHull,
|
||||
|
||||
R_StudioSlerpBones,
|
||||
R_StudioCalcBoneQuaternion,
|
||||
R_StudioCalcBonePosition,
|
||||
R_StudioGetAnim,
|
||||
pfnStudioEvent,
|
||||
|
||||
@@ -345,7 +359,7 @@ static ref_api_t gEngfuncs =
|
||||
|
||||
pfnGetPhysent,
|
||||
pfnTraceSurface,
|
||||
PM_CL_TraceLine,
|
||||
PM_TraceLine,
|
||||
CL_VisTraceLine,
|
||||
CL_TraceLine,
|
||||
pfnGetMoveVars,
|
||||
@@ -512,7 +526,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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -555,62 +569,66 @@ static void SetWidthAndHeightFromCommandLine( void )
|
||||
static void SetFullscreenModeFromCommandLine( void )
|
||||
{
|
||||
#if !XASH_MOBILE_PLATFORM
|
||||
if( Sys_CheckParm( "-fullscreen" ))
|
||||
if ( Sys_CheckParm("-fullscreen") )
|
||||
{
|
||||
Cvar_Set( "fullscreen", "1" );
|
||||
}
|
||||
else if( Sys_CheckParm( "-windowed" ))
|
||||
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_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_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 )
|
||||
@@ -625,7 +643,7 @@ qboolean R_Init( void )
|
||||
gl_msaa_samples = Cvar_Get( "gl_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, "choose renderer implementation, if supported" );
|
||||
r_refdll = Cvar_Get( "r_refdll", "", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "choose renderer implementation, if supported" );
|
||||
|
||||
// cvars that are expected to exist
|
||||
Cvar_Get( "r_speeds", "0", FCVAR_ARCHIVE, "shows renderer speeds" );
|
||||
@@ -664,28 +682,30 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -159,7 +159,7 @@ void S_UpdateSoundFade( void )
|
||||
}
|
||||
|
||||
// spline it.
|
||||
f = -( cos( M_PI * f ) - 1 ) / 2;
|
||||
f = SimpleSpline( f );
|
||||
f = bound( 0.0f, f, 1.0f );
|
||||
|
||||
soundfade.percent = soundfade.initial_percent * f;
|
||||
@@ -197,65 +197,6 @@ qboolean SND_FStreamIsPlaying( sfx_t *sfx )
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SND_GetChannelTimeLeft
|
||||
|
||||
TODO: this function needs to be removed after whole sound subsystem rewrite
|
||||
=================
|
||||
*/
|
||||
static int SND_GetChannelTimeLeft( const channel_t *ch )
|
||||
{
|
||||
int remaining;
|
||||
|
||||
if( ch->pMixer.finished || !ch->sfx || !ch->sfx->cache )
|
||||
return 0;
|
||||
|
||||
if( ch->isSentence ) // sentences are special, count all remaining words
|
||||
{
|
||||
int i;
|
||||
|
||||
if( !ch->currentWord )
|
||||
return 0;
|
||||
|
||||
// current word
|
||||
remaining = ch->currentWord->forcedEndSample - ch->currentWord->sample;
|
||||
|
||||
// here we count all remaining words, stopping if no sfx or sound file is available
|
||||
// see VOX_LoadWord
|
||||
for( i = ch->wordIndex + 1; i < ARRAYSIZE( ch->words ); i++ )
|
||||
{
|
||||
wavdata_t *sc;
|
||||
int end;
|
||||
|
||||
// don't continue with broken sentences
|
||||
if( !ch->words[i].sfx )
|
||||
break;
|
||||
|
||||
if( !( sc = S_LoadSound( ch->words[i].sfx )))
|
||||
break;
|
||||
|
||||
end = ch->words[i].end;
|
||||
|
||||
if( end )
|
||||
remaining += sc->samples * 0.01f * end;
|
||||
else remaining += sc->samples;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int curpos;
|
||||
int samples;
|
||||
|
||||
// handle position looping
|
||||
samples = ch->sfx->cache->samples;
|
||||
curpos = S_ConvertLoopedPosition( ch->sfx->cache, ch->pMixer.sample, ch->use_loop );
|
||||
remaining = bound( 0, samples - curpos, samples );
|
||||
}
|
||||
|
||||
return remaining;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SND_PickDynamicChannel
|
||||
@@ -305,7 +246,11 @@ channel_t *SND_PickDynamicChannel( int entnum, int channel, sfx_t *sfx, qboolean
|
||||
continue;
|
||||
|
||||
// try to pick the sound with the least amount of data left to play
|
||||
timeleft = SND_GetChannelTimeLeft( ch );
|
||||
timeleft = 0;
|
||||
if( ch->sfx )
|
||||
{
|
||||
timeleft = 1; // ch->end - paintedtime
|
||||
}
|
||||
|
||||
if( timeleft < life_left )
|
||||
{
|
||||
@@ -1292,6 +1237,36 @@ void S_StreamAviSamples( void *Avi, int entnum, float fvol, float attn, float sy
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
S_GetRawSamplesLength
|
||||
===================
|
||||
*/
|
||||
uint S_GetRawSamplesLength( int entnum )
|
||||
{
|
||||
rawchan_t *ch;
|
||||
|
||||
if( !( ch = S_FindRawChannel( entnum, false )))
|
||||
return 0;
|
||||
|
||||
return ch->s_rawend <= paintedtime ? 0 : (float)(ch->s_rawend - paintedtime) * DMA_MSEC_PER_SAMPLE;
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
S_ClearRawChannel
|
||||
===================
|
||||
*/
|
||||
void S_ClearRawChannel( int entnum )
|
||||
{
|
||||
rawchan_t *ch;
|
||||
|
||||
if( !( ch = S_FindRawChannel( entnum, false )))
|
||||
return;
|
||||
|
||||
ch->s_rawend = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
S_FreeIdleRawChannels
|
||||
@@ -1812,12 +1787,8 @@ void S_Music_f( void )
|
||||
|
||||
for( i = 0; i < 2; i++ )
|
||||
{
|
||||
char intro_path[MAX_VA_STRING];
|
||||
char main_path[MAX_VA_STRING];
|
||||
char track_path[MAX_VA_STRING];
|
||||
|
||||
Q_snprintf( intro_path, sizeof( intro_path ), "media/%s.%s", intro, ext[i] );
|
||||
Q_snprintf( main_path, sizeof( main_path ), "media/%s.%s", main, ext[i] );
|
||||
const char *intro_path = va( "media/%s.%s", intro, ext[i] );
|
||||
const char *main_path = va( "media/%s.%s", main, ext[i] );
|
||||
|
||||
if( FS_FileExists( intro_path, false ) && FS_FileExists( main_path, false ))
|
||||
{
|
||||
@@ -1825,10 +1796,7 @@ void S_Music_f( void )
|
||||
S_StartBackgroundTrack( intro, main, 0, false );
|
||||
break;
|
||||
}
|
||||
|
||||
Q_snprintf( track_path, sizeof( track_path ), "media/%s.%s", track, ext[i] );
|
||||
|
||||
if( FS_FileExists( track_path, false ))
|
||||
else if( FS_FileExists( va( "media/%s.%s", track, ext[i] ), false ))
|
||||
{
|
||||
// single non-looped theme
|
||||
S_StartBackgroundTrack( track, NULL, 0, false );
|
||||
|
||||
@@ -117,6 +117,13 @@ _inline void MIX_ActivatePaintbuffer( int ipaintbuffer )
|
||||
paintbuffers[ipaintbuffer].factive = true;
|
||||
}
|
||||
|
||||
// don't mix into this paintbuffer
|
||||
_inline void MIX_DeactivatePaintbuffer( int ipaintbuffer )
|
||||
{
|
||||
Assert( ipaintbuffer < CPAINTBUFFERS );
|
||||
paintbuffers[ipaintbuffer].factive = false;
|
||||
}
|
||||
|
||||
_inline void MIX_SetCurrentPaintbuffer( int ipaintbuffer )
|
||||
{
|
||||
Assert( ipaintbuffer < CPAINTBUFFERS );
|
||||
@@ -162,6 +169,12 @@ _inline void MIX_ResetPaintbufferFilterCounters( void )
|
||||
paintbuffers[i].ifilter = FILTERTYPE_NONE;
|
||||
}
|
||||
|
||||
_inline void MIX_ResetPaintbufferFilterCounter( int ipaintbuffer )
|
||||
{
|
||||
Assert( ipaintbuffer < CPAINTBUFFERS );
|
||||
paintbuffers[ipaintbuffer].ifilter = 0;
|
||||
}
|
||||
|
||||
// return pointer to front paintbuffer pbuf, given index
|
||||
_inline portable_samplepair_t *MIX_GetPFrontFromIPaint( int ipaintbuffer )
|
||||
{
|
||||
@@ -608,7 +621,7 @@ void MIX_MixChannelsToPaintbuffer( int endtime, int rate, int outputRate )
|
||||
|
||||
ch->pitch *= ( sys_timescale.value + 1 ) / 2;
|
||||
|
||||
if( CL_GetEntityByIndex( ch->entnum ) && ( ch->entchannel == CHAN_VOICE || ch->entchannel == CHAN_STREAM ))
|
||||
if( CL_GetEntityByIndex( ch->entnum ) && ( ch->entchannel == CHAN_VOICE ))
|
||||
{
|
||||
if( pSource->width == 1 )
|
||||
SND_MoveMouth8( ch, pSource, sampleCount );
|
||||
@@ -884,13 +897,43 @@ void S_MixUpsample( int sampleCount, int filtertype )
|
||||
ppaint->ifilter++;
|
||||
}
|
||||
|
||||
void MIX_MixStreamBuffer( int end )
|
||||
{
|
||||
portable_samplepair_t *pbuf;
|
||||
rawchan_t *ch;
|
||||
|
||||
pbuf = MIX_GetPFrontFromIPaint( ISTREAMBUFFER );
|
||||
ch = S_FindRawChannel( S_RAW_SOUND_BACKGROUNDTRACK, false );
|
||||
|
||||
// clear the paint buffer
|
||||
if( s_listener.paused || !ch || ch->s_rawend < paintedtime )
|
||||
{
|
||||
memset( pbuf, 0, (end - paintedtime) * sizeof( portable_samplepair_t ));
|
||||
}
|
||||
else
|
||||
{
|
||||
int i, stop;
|
||||
|
||||
// copy from the streaming sound source
|
||||
stop = (end < ch->s_rawend) ? end : ch->s_rawend;
|
||||
|
||||
for( i = paintedtime; i < stop; i++ )
|
||||
{
|
||||
pbuf[i-paintedtime].left = ( ch->rawsamples[i & ( ch->max_samples - 1 )].left * ch->leftvol ) >> 8;
|
||||
pbuf[i-paintedtime].right = ( ch->rawsamples[i & ( ch->max_samples - 1 )].right * ch->rightvol ) >> 8;
|
||||
}
|
||||
|
||||
for( ; i < end; i++ )
|
||||
pbuf[i-paintedtime].left = pbuf[i-paintedtime].right = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MIX_MixRawSamplesBuffer( int end )
|
||||
{
|
||||
portable_samplepair_t *pbuf, *roombuf, *streambuf;
|
||||
portable_samplepair_t *pbuf;
|
||||
uint i, j, stop;
|
||||
|
||||
roombuf = MIX_GetPFrontFromIPaint( IROOMBUFFER );
|
||||
streambuf = MIX_GetPFrontFromIPaint( ISTREAMBUFFER );
|
||||
pbuf = MIX_GetCurrentPaintbufferPtr()->pbuf;
|
||||
|
||||
if( s_listener.paused ) return;
|
||||
|
||||
@@ -898,19 +941,16 @@ void MIX_MixRawSamplesBuffer( int end )
|
||||
for( i = 0; i < MAX_RAW_CHANNELS; i++ )
|
||||
{
|
||||
// copy from the streaming sound source
|
||||
rawchan_t *ch = raw_channels[i];
|
||||
qboolean stream;
|
||||
rawchan_t *ch = raw_channels[i];
|
||||
|
||||
if( !ch )
|
||||
// background track should be mixing into another buffer
|
||||
if( !ch || ch->entnum == S_RAW_SOUND_BACKGROUNDTRACK )
|
||||
continue;
|
||||
|
||||
// not audible
|
||||
if( !ch->leftvol && !ch->rightvol )
|
||||
continue;
|
||||
|
||||
stream = ch->entnum == S_RAW_SOUND_BACKGROUNDTRACK || CL_IsPlayerIndex( ch->entnum );
|
||||
pbuf = stream ? streambuf : roombuf;
|
||||
|
||||
stop = (end < ch->s_rawend) ? end : ch->s_rawend;
|
||||
|
||||
for( j = paintedtime; j < stop; j++ )
|
||||
@@ -919,7 +959,7 @@ void MIX_MixRawSamplesBuffer( int end )
|
||||
pbuf[j-paintedtime].right += ( ch->rawsamples[j & ( ch->max_samples - 1 )].right * ch->rightvol ) >> 8;
|
||||
}
|
||||
|
||||
if( ch->entnum > 0 )
|
||||
if ( ch->entnum > 0 )
|
||||
SND_MoveMouthRaw( ch, &ch->rawsamples[paintedtime & ( ch->max_samples - 1 )], stop - paintedtime );
|
||||
}
|
||||
}
|
||||
@@ -930,6 +970,9 @@ void MIX_MixRawSamplesBuffer( int end )
|
||||
// caller also remixes all into final IPAINTBUFFER output.
|
||||
void MIX_UpsampleAllPaintbuffers( int end, int count )
|
||||
{
|
||||
// process stream buffer
|
||||
MIX_MixStreamBuffer( end );
|
||||
|
||||
// 11khz sounds are mixed into 3 buffers based on distance from listener, and facing direction
|
||||
// These buffers are facing, facingaway, room
|
||||
// These 3 mixed buffers are then each upsampled to 22khz.
|
||||
@@ -971,6 +1014,7 @@ void MIX_UpsampleAllPaintbuffers( int end, int count )
|
||||
#endif
|
||||
|
||||
// mix raw samples from the video streams
|
||||
MIX_SetCurrentPaintbuffer( IROOMBUFFER );
|
||||
MIX_MixRawSamplesBuffer( end );
|
||||
|
||||
MIX_DeactivateAllPaintbuffers();
|
||||
|
||||
@@ -24,7 +24,17 @@ void SND_InitMouth( int entnum, int entchannel )
|
||||
{
|
||||
if(( entchannel == CHAN_VOICE || entchannel == CHAN_STREAM ) && entnum > 0 )
|
||||
{
|
||||
SND_ForceInitMouth( entnum );
|
||||
cl_entity_t *clientEntity;
|
||||
|
||||
// init mouth movement vars
|
||||
clientEntity = CL_GetEntityByIndex( entnum );
|
||||
|
||||
if( clientEntity )
|
||||
{
|
||||
clientEntity->mouth.mouthopen = 0;
|
||||
clientEntity->mouth.sndcount = 0;
|
||||
clientEntity->mouth.sndavg = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +42,15 @@ void SND_CloseMouth( channel_t *ch )
|
||||
{
|
||||
if( ch->entchannel == CHAN_VOICE || ch->entchannel == CHAN_STREAM )
|
||||
{
|
||||
SND_ForceCloseMouth( ch->entnum );
|
||||
cl_entity_t *clientEntity;
|
||||
|
||||
clientEntity = CL_GetEntityByIndex( ch->entnum );
|
||||
|
||||
if( clientEntity )
|
||||
{
|
||||
// shut mouth
|
||||
clientEntity->mouth.mouthopen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +157,7 @@ void SND_ForceInitMouth( int entnum )
|
||||
|
||||
clientEntity = CL_GetEntityByIndex( entnum );
|
||||
|
||||
if( clientEntity )
|
||||
if ( clientEntity )
|
||||
{
|
||||
clientEntity->mouth.mouthopen = 0;
|
||||
clientEntity->mouth.sndavg = 0;
|
||||
@@ -153,7 +171,7 @@ void SND_ForceCloseMouth( int entnum )
|
||||
|
||||
clientEntity = CL_GetEntityByIndex( entnum );
|
||||
|
||||
if( clientEntity )
|
||||
if ( clientEntity )
|
||||
clientEntity->mouth.mouthopen = 0;
|
||||
}
|
||||
|
||||
@@ -196,4 +214,4 @@ void SND_MoveMouthRaw( rawchan_t *ch, portable_samplepair_t *pData, int count )
|
||||
pMouth->sndavg = 0;
|
||||
pMouth->sndcount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ void S_StartBackgroundTrack( const char *introTrack, const char *mainTrack, int
|
||||
else Q_strncpy( s_bgTrack.loopName, mainTrack, sizeof( s_bgTrack.loopName ));
|
||||
|
||||
// open stream
|
||||
s_bgTrack.stream = FS_OpenStream( introTrack );
|
||||
s_bgTrack.stream = FS_OpenStream( va( "media/%s", introTrack ));
|
||||
Q_strncpy( s_bgTrack.current, introTrack, sizeof( s_bgTrack.current ));
|
||||
memset( &musicfade, 0, sizeof( musicfade )); // clear any soundfade
|
||||
s_bgTrack.source = cls.key_dest;
|
||||
@@ -242,7 +242,7 @@ void S_StreamBackgroundTrack( void )
|
||||
if( s_bgTrack.loopName[0] )
|
||||
{
|
||||
FS_FreeStream( s_bgTrack.stream );
|
||||
s_bgTrack.stream = FS_OpenStream( s_bgTrack.loopName );
|
||||
s_bgTrack.stream = FS_OpenStream( va( "media/%s", s_bgTrack.loopName ));
|
||||
Q_strncpy( s_bgTrack.current, s_bgTrack.loopName, sizeof( s_bgTrack.current ));
|
||||
|
||||
if( !s_bgTrack.stream ) return;
|
||||
|
||||
@@ -142,7 +142,7 @@ static const char *VOX_GetDirectory( char *szpath, const char *psz, int nsize )
|
||||
|
||||
if( !p )
|
||||
{
|
||||
Q_strncpy( szpath, "vox/", nsize );
|
||||
Q_strcpy( szpath, "vox/" );
|
||||
return psz;
|
||||
}
|
||||
|
||||
@@ -176,7 +176,6 @@ static const char *VOX_LookupString( const char *pszin )
|
||||
i = Q_atoi( pszin + 1 );
|
||||
if(( sentenceEntry = Sequence_GetSentenceByIndex( i )))
|
||||
return sentenceEntry->data;
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -276,6 +276,8 @@ void S_RawEntSamples( int entnum, uint samples, uint rate, word width, word chan
|
||||
void S_RawSamples( uint samples, uint rate, word width, word channels, const byte *data, int entnum );
|
||||
void S_StopSound( int entnum, int channel, const char *soundname );
|
||||
void S_UpdateFrame( struct ref_viewpass_s *rvp );
|
||||
uint S_GetRawSamplesLength( int entnum );
|
||||
void S_ClearRawChannel( int entnum );
|
||||
void S_StopAllSounds( qboolean ambient );
|
||||
void S_FreeSounds( void );
|
||||
|
||||
@@ -304,7 +306,6 @@ void S_FadeMusicVolume( float fadePercent );
|
||||
//
|
||||
int S_ZeroCrossingAfter( wavdata_t *pWaveData, int sample );
|
||||
int S_ZeroCrossingBefore( wavdata_t *pWaveData, int sample );
|
||||
int S_ConvertLoopedPosition( wavdata_t *pSource, int samplePosition, qboolean use_loop );
|
||||
int S_GetOutputData( wavdata_t *pSource, void **pData, int samplePosition, int sampleCount, qboolean use_loop );
|
||||
void S_SetSampleStart( channel_t *pChan, wavdata_t *pSource, int newPosition );
|
||||
void S_SetSampleEnd( channel_t *pChan, wavdata_t *pSource, int newEndPosition );
|
||||
|
||||
@@ -218,7 +218,6 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
|
||||
client_textmessage_t textMessages[MAX_MESSAGES];
|
||||
int i, nameHeapSize, textHeapSize, messageSize, nameOffset;
|
||||
int messageCount, lastNamePos;
|
||||
size_t textHeapSizeRemaining;
|
||||
|
||||
lastNamePos = 0;
|
||||
lineNumber = 0;
|
||||
@@ -253,7 +252,7 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
|
||||
Con_Reportf( "TextMessage: unexpected '}' found, line %d\n", lineNumber );
|
||||
return;
|
||||
}
|
||||
Q_strncpy( currentName, trim, sizeof( currentName ));
|
||||
Q_strcpy( currentName, trim );
|
||||
break;
|
||||
case MSGFILE_TEXT:
|
||||
if( IsEndOfText( trim ))
|
||||
@@ -267,7 +266,7 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
|
||||
return;
|
||||
}
|
||||
|
||||
Q_strncpy( nameHeap + lastNamePos, currentName, sizeof( nameHeap ) - lastNamePos );
|
||||
Q_strcpy( nameHeap + lastNamePos, currentName );
|
||||
|
||||
// terminate text in-place in the memory file
|
||||
// (it's temporary memory that will be deleted)
|
||||
@@ -330,20 +329,15 @@ void CL_TextMessageParse( byte *pMemFile, int fileSize )
|
||||
|
||||
|
||||
// copy text & fixup pointers
|
||||
textHeapSizeRemaining = textHeapSize;
|
||||
pCurrentText = pNameHeap + nameHeapSize;
|
||||
|
||||
for( i = 0; i < messageCount; i++ )
|
||||
{
|
||||
size_t currentTextSize = Q_strlen( clgame.titles[i].pMessage ) + 1;
|
||||
|
||||
clgame.titles[i].pName = pNameHeap; // adjust name pointer (parallel buffer)
|
||||
Q_strncpy( pCurrentText, clgame.titles[i].pMessage, textHeapSizeRemaining ); // copy text over
|
||||
Q_strcpy( pCurrentText, clgame.titles[i].pMessage ); // copy text over
|
||||
clgame.titles[i].pMessage = pCurrentText;
|
||||
|
||||
pNameHeap += Q_strlen( pNameHeap ) + 1;
|
||||
pCurrentText += currentTextSize;
|
||||
textHeapSizeRemaining -= currentTextSize;
|
||||
pCurrentText += Q_strlen( pCurrentText ) + 1;
|
||||
}
|
||||
|
||||
if(( pCurrentText - (char *)clgame.titles ) != ( textHeapSize + nameHeapSize + messageSize ))
|
||||
|
||||
@@ -23,77 +23,54 @@ GNU General Public License for more details.
|
||||
#include "input.h"
|
||||
#include "platform/platform.h"
|
||||
|
||||
CVAR_DEFINE_AUTO( vgui_utf8, "0", FCVAR_ARCHIVE, "enable utf-8 support for vgui text" );
|
||||
static enum VGUI_KeyCode s_pVirtualKeyTrans[256];
|
||||
static VGUI_DefaultCursor s_currentCursor;
|
||||
static HINSTANCE s_pVGuiSupport; // vgui_support library
|
||||
static convar_t *vgui_utf8 = NULL;
|
||||
|
||||
static void GAME_EXPORT *VGUI_EngineMalloc( size_t size );
|
||||
static void GAME_EXPORT VGUI_GetMousePos( int *, int * );
|
||||
static void GAME_EXPORT VGUI_CursorSelect( VGUI_DefaultCursor );
|
||||
static byte GAME_EXPORT VGUI_GetColor( int, int );
|
||||
static int GAME_EXPORT VGUI_UtfProcessChar( int in );
|
||||
static qboolean GAME_EXPORT VGUI_IsInGame( void );
|
||||
|
||||
static struct
|
||||
{
|
||||
qboolean initialized;
|
||||
vgui_support_interface_t dllFuncs;
|
||||
VGUI_DefaultCursor cursor;
|
||||
|
||||
HINSTANCE hInstance;
|
||||
|
||||
enum VGUI_KeyCode virtualKeyTrans[256];
|
||||
} vgui =
|
||||
{
|
||||
false,
|
||||
{ 0 }, // not initialized yet
|
||||
-1
|
||||
};
|
||||
|
||||
static void GAME_EXPORT *VGUI_EngineMalloc( size_t size )
|
||||
void GAME_EXPORT *VGUI_EngineMalloc(size_t size)
|
||||
{
|
||||
return Z_Malloc( size );
|
||||
}
|
||||
|
||||
static qboolean GAME_EXPORT VGUI_IsInGame( void )
|
||||
qboolean GAME_EXPORT VGUI_IsInGame( void )
|
||||
{
|
||||
return cls.state == ca_active && cls.key_dest == key_game;
|
||||
}
|
||||
|
||||
static void GAME_EXPORT VGUI_GetMousePos( int *_x, int *_y )
|
||||
void GAME_EXPORT VGUI_GetMousePos( int *_x, int *_y )
|
||||
{
|
||||
float xscale = (float)refState.width / (float)clgame.scrInfo.iWidth;
|
||||
float yscale = (float)refState.height / (float)clgame.scrInfo.iHeight;
|
||||
int x, y;
|
||||
|
||||
Platform_GetMousePos( &x, &y );
|
||||
*_x = x / xscale;
|
||||
*_y = y / yscale;
|
||||
*_x = x / xscale, *_y = y / yscale;
|
||||
}
|
||||
|
||||
static void GAME_EXPORT VGUI_CursorSelect( VGUI_DefaultCursor cursor )
|
||||
void GAME_EXPORT VGUI_CursorSelect( VGUI_DefaultCursor cursor )
|
||||
{
|
||||
if( vgui.cursor != cursor )
|
||||
Platform_SetCursorType( cursor );
|
||||
Platform_SetCursorType( cursor );
|
||||
s_currentCursor = cursor;
|
||||
}
|
||||
|
||||
static byte GAME_EXPORT VGUI_GetColor( int i, int j )
|
||||
byte GAME_EXPORT VGUI_GetColor( int i, int j)
|
||||
{
|
||||
return g_color_table[i][j];
|
||||
}
|
||||
|
||||
static int GAME_EXPORT VGUI_UtfProcessChar( int in )
|
||||
// Define and initialize vgui API
|
||||
int GAME_EXPORT VGUI_UtfProcessChar( int in )
|
||||
{
|
||||
if( vgui_utf8.value )
|
||||
if( CVAR_TO_BOOL( vgui_utf8 ))
|
||||
return Con_UtfProcessCharForce( in );
|
||||
return in;
|
||||
else
|
||||
return in;
|
||||
}
|
||||
|
||||
qboolean VGui_IsActive( void )
|
||||
{
|
||||
return vgui.initialized;
|
||||
}
|
||||
|
||||
static vgui_support_api_t gEngfuncs =
|
||||
vguiapi_t vgui =
|
||||
{
|
||||
false, // Not initialized yet
|
||||
NULL, // VGUI_DrawInit,
|
||||
NULL, // VGUI_DrawShutdown,
|
||||
NULL, // VGUI_SetupDrawingText,
|
||||
@@ -111,18 +88,28 @@ static vgui_support_api_t gEngfuncs =
|
||||
VGUI_CursorSelect,
|
||||
VGUI_GetColor,
|
||||
VGUI_IsInGame,
|
||||
Key_EnableTextInput,
|
||||
NULL,
|
||||
VGUI_GetMousePos,
|
||||
VGUI_UtfProcessChar,
|
||||
Platform_GetClipboardText,
|
||||
Platform_SetClipboardText,
|
||||
Platform_GetKeyModifiers,
|
||||
COM_LoadLibrary,
|
||||
COM_FreeLibrary,
|
||||
COM_GetProcAddress,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void VGui_FillAPIFromRef( vgui_support_api_t *to, const ref_interface_t *from )
|
||||
qboolean VGui_IsActive( void )
|
||||
{
|
||||
return vgui.initialized;
|
||||
}
|
||||
|
||||
void VGui_FillAPIFromRef( vguiapi_t *to, const ref_interface_t *from )
|
||||
{
|
||||
to->DrawInit = from->VGUI_DrawInit;
|
||||
to->DrawShutdown = from->VGUI_DrawShutdown;
|
||||
@@ -139,184 +126,141 @@ static void VGui_FillAPIFromRef( vgui_support_api_t *to, const ref_interface_t *
|
||||
to->GenerateTexture = from->VGUI_GenerateTexture;
|
||||
}
|
||||
|
||||
void VGui_RegisterCvars( void )
|
||||
{
|
||||
Cvar_RegisterVariable( &vgui_utf8 );
|
||||
}
|
||||
|
||||
static HINSTANCE VGui_LoadSupportLibrary( void )
|
||||
{
|
||||
string vguiloader;
|
||||
string vguilib;
|
||||
HINSTANCE hInstance;
|
||||
|
||||
// HACKHACK: try to load path from custom path
|
||||
// to support having different versions of VGUI
|
||||
if( Sys_GetParmFromCmdLine( "-vguilib", vguilib ) && !COM_LoadLibrary( vguilib, false, false ))
|
||||
{
|
||||
Con_Reportf( S_WARN "VGUI preloading failed. Default library will be used! Reason: %s", COM_GetLibraryError());
|
||||
}
|
||||
|
||||
if( !Sys_GetParmFromCmdLine( "-vguiloader", vguiloader ))
|
||||
{
|
||||
Q_strncpy( vguiloader, VGUI_SUPPORT_DLL, sizeof( vguiloader ));
|
||||
}
|
||||
|
||||
hInstance = COM_LoadLibrary( vguiloader, false, false );
|
||||
|
||||
if( !hInstance )
|
||||
{
|
||||
if( FS_FileExists( vguiloader, false ))
|
||||
Con_Reportf( S_ERROR "Failed to load vgui_support library: %s\n", COM_GetLibraryError() );
|
||||
else Con_Reportf( "vgui_support: not found\n" );
|
||||
}
|
||||
|
||||
return hInstance;
|
||||
}
|
||||
|
||||
static qboolean VGui_ProbeNewAPI( HINSTANCE hInstance,
|
||||
vgui_support_interface_t *iface, const vgui_support_api_t *api )
|
||||
{
|
||||
const int version = VGUI_SUPPORT_API_VERSION;
|
||||
static vgui_support_api_t localapi;
|
||||
VGUISUPPORTAPI F;
|
||||
|
||||
F = COM_GetProcAddress( hInstance, GET_VGUI_SUPPORT_API );
|
||||
|
||||
if( !F )
|
||||
return false;
|
||||
|
||||
// keep local temporary copy, do not let vgui_support to mess up here
|
||||
memcpy( &localapi, api, sizeof( localapi ));
|
||||
|
||||
if( F( version, iface, &localapi ) != version )
|
||||
return false;
|
||||
|
||||
Con_Reportf( "vgui_support: initialized new API\n" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static qboolean VGui_ProbeOldAPI( HINSTANCE hInstance,
|
||||
vgui_support_interface_t *iface, const vgui_support_api_t *api,
|
||||
qboolean client )
|
||||
{
|
||||
static legacy_vguiapi_t localapi;
|
||||
LEGACY_VGUISUPPORTAPI F;
|
||||
|
||||
F = COM_GetProcAddress( hInstance, client ? LEGACY_CLIENT_GET_VGUI_SUPPORT_API : LEGACY_GET_VGUI_SUPPORT_API );
|
||||
|
||||
if( !F )
|
||||
return false;
|
||||
|
||||
memset( &localapi, 0, sizeof( localapi ));
|
||||
localapi.DrawInit = api->DrawInit;
|
||||
localapi.DrawShutdown = api->DrawShutdown;
|
||||
localapi.SetupDrawingText = api->SetupDrawingText;
|
||||
localapi.SetupDrawingRect = api->SetupDrawingRect;
|
||||
localapi.SetupDrawingImage = api->SetupDrawingImage;
|
||||
localapi.BindTexture = api->BindTexture;
|
||||
localapi.EnableTexture = api->EnableTexture;
|
||||
localapi.CreateTexture = api->CreateTexture;
|
||||
localapi.UploadTexture = api->UploadTexture;
|
||||
localapi.UploadTextureBlock = api->UploadTextureBlock;
|
||||
localapi.DrawQuad = api->DrawQuad;
|
||||
localapi.GetTextureSizes = api->GetTextureSizes;
|
||||
localapi.GenerateTexture = api->GenerateTexture;
|
||||
localapi.EngineMalloc = api->EngineMalloc;
|
||||
localapi.CursorSelect = api->CursorSelect;
|
||||
localapi.GetColor = api->GetColor;
|
||||
localapi.IsInGame = api->IsInGame;
|
||||
localapi.EnableTextInput = api->EnableTextInput;
|
||||
localapi.GetCursorPos = api->GetCursorPos;
|
||||
localapi.ProcessUtfChar = api->ProcessUtfChar;
|
||||
localapi.GetClipboardText = api->GetClipboardText;
|
||||
localapi.SetClipboardText = api->SetClipboardText;
|
||||
localapi.GetKeyModifiers = api->GetKeyModifiers;
|
||||
|
||||
F( &localapi );
|
||||
|
||||
localapi.initialized = true;
|
||||
|
||||
iface->Startup = localapi.Startup;
|
||||
iface->Shutdown = localapi.Shutdown;
|
||||
iface->GetPanel = localapi.GetPanel;
|
||||
iface->Paint = localapi.Paint;
|
||||
iface->Mouse = localapi.Mouse;
|
||||
iface->Key = localapi.Key;
|
||||
iface->MouseMove = localapi.MouseMove;
|
||||
iface->TextInput = localapi.TextInput;
|
||||
|
||||
Con_Reportf( "vgui_support: initialized legacy API in %s module\n", client ? "client" : "support" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
qboolean VGui_LoadProgs( HINSTANCE hInstance )
|
||||
{
|
||||
LEGACY_VGUISUPPORTAPI F;
|
||||
qboolean client = hInstance != NULL;
|
||||
|
||||
// not loading interface from client.dll, load vgui_support.dll instead
|
||||
if( !client )
|
||||
{
|
||||
hInstance = vgui.hInstance = VGui_LoadSupportLibrary();
|
||||
|
||||
if( !hInstance )
|
||||
return false;
|
||||
}
|
||||
|
||||
// prepare api funcs
|
||||
VGui_FillAPIFromRef( &gEngfuncs, &ref.dllFuncs );
|
||||
|
||||
// try new API first
|
||||
if( !VGui_ProbeNewAPI( vgui.hInstance, &vgui.dllFuncs, &gEngfuncs ))
|
||||
{
|
||||
// try legacy API next
|
||||
if( !VGui_ProbeOldAPI( vgui.hInstance, &vgui.dllFuncs, &gEngfuncs, client ))
|
||||
{
|
||||
Con_Reportf( S_ERROR "Failed to find VGUI support API entry point in %s module\n", client ? "client" : "support" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
vgui.initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
VGui_Startup
|
||||
|
||||
Load vgui_support library and call VGui_Startup
|
||||
================
|
||||
*/
|
||||
void VGui_Startup( HINSTANCE clientInstance, int width, int height )
|
||||
void VGui_Startup( const char *clientlib, int width, int height )
|
||||
{
|
||||
// vgui not initialized from both support and client modules, skip
|
||||
if( !vgui.initialized )
|
||||
static qboolean failed = false;
|
||||
|
||||
void (*F) ( vguiapi_t * );
|
||||
char vguiloader[256];
|
||||
char vguilib[256];
|
||||
|
||||
vguiloader[0] = vguilib[0] = '\0';
|
||||
|
||||
if( failed )
|
||||
return;
|
||||
|
||||
height = Q_max( 480, height );
|
||||
|
||||
if( width <= 640 ) width = 640;
|
||||
else if( width <= 800 ) width = 800;
|
||||
else if( width <= 1024 ) width = 1024;
|
||||
else if( width <= 1152 ) width = 1152;
|
||||
else if( width <= 1280 ) width = 1280;
|
||||
else if( width <= 1600 ) width = 1600;
|
||||
|
||||
if( !clientInstance )
|
||||
if( !vgui.initialized )
|
||||
{
|
||||
if( vgui.dllFuncs.Startup )
|
||||
vgui.dllFuncs.Startup( width, height );
|
||||
vgui_utf8 = Cvar_Get( "vgui_utf8", "0", FCVAR_ARCHIVE, "enable utf-8 support for vgui text" );
|
||||
|
||||
VGui_FillAPIFromRef( &vgui, &ref.dllFuncs );
|
||||
|
||||
s_pVGuiSupport = COM_LoadLibrary( clientlib, false, false );
|
||||
|
||||
if( s_pVGuiSupport )
|
||||
{
|
||||
F = COM_GetProcAddress( s_pVGuiSupport, "InitVGUISupportAPI" );
|
||||
if( F )
|
||||
{
|
||||
F( &vgui );
|
||||
vgui.initialized = true;
|
||||
Con_Reportf( "vgui_support: found internal client support\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
COM_FreeLibrary( s_pVGuiSupport );
|
||||
}
|
||||
}
|
||||
|
||||
if( !vgui.initialized )
|
||||
{
|
||||
// HACKHACK: load vgui with correct path first if specified.
|
||||
// it will be reused while resolving vgui support and client deps
|
||||
if( Sys_GetParmFromCmdLine( "-vguilib", vguilib ))
|
||||
{
|
||||
if( Q_strstr( vguilib, ".dll" ))
|
||||
Q_strncpy( vguiloader, "vgui_support.dll", 256 );
|
||||
else
|
||||
Q_strncpy( vguiloader, VGUI_SUPPORT_DLL, 256 );
|
||||
|
||||
if( !COM_LoadLibrary( vguilib, false, false ))
|
||||
Con_Reportf( S_WARN "VGUI preloading failed. Default library will be used! Reason: %s\n", COM_GetLibraryError() );
|
||||
}
|
||||
|
||||
if( Q_strstr( clientlib, ".dll" ))
|
||||
Q_strncpy( vguiloader, "vgui_support.dll", 256 );
|
||||
|
||||
if( !vguiloader[0] && !Sys_GetParmFromCmdLine( "-vguiloader", vguiloader ))
|
||||
Q_strncpy( vguiloader, VGUI_SUPPORT_DLL, 256 );
|
||||
|
||||
s_pVGuiSupport = COM_LoadLibrary( vguiloader, false, false );
|
||||
|
||||
if( !s_pVGuiSupport )
|
||||
{
|
||||
s_pVGuiSupport = COM_LoadLibrary( va( "../%s", vguiloader ), false, false );
|
||||
}
|
||||
|
||||
if( !s_pVGuiSupport )
|
||||
{
|
||||
if( FS_FileExists( vguiloader, false ))
|
||||
{
|
||||
Con_Reportf( S_ERROR "Failed to load vgui_support library: %s\n", COM_GetLibraryError() );
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Reportf( "vgui_support: not found\n" );
|
||||
}
|
||||
failed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
F = COM_GetProcAddress( s_pVGuiSupport, "InitAPI" );
|
||||
if( F )
|
||||
{
|
||||
F( &vgui );
|
||||
vgui.initialized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Reportf( S_ERROR "Failed to find vgui_support library entry point!\n" );
|
||||
failed = true;
|
||||
COM_FreeLibrary( s_pVGuiSupport );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if( height < 480 )
|
||||
height = 480;
|
||||
|
||||
if( width <= 640 )
|
||||
width = 640;
|
||||
else if( width <= 800 )
|
||||
width = 800;
|
||||
else if( width <= 1024 )
|
||||
width = 1024;
|
||||
else if( width <= 1152 )
|
||||
width = 1152;
|
||||
else if( width <= 1280 )
|
||||
width = 1280;
|
||||
else if( width <= 1600 )
|
||||
width = 1600;
|
||||
#ifdef XASH_DLL_LOADER
|
||||
else if ( Q_strstr( vguiloader, ".dll" ) )
|
||||
width = 1600;
|
||||
#endif
|
||||
|
||||
|
||||
if( vgui.initialized )
|
||||
{
|
||||
if( vgui.dllFuncs.ClientStartup )
|
||||
vgui.dllFuncs.ClientStartup( clientInstance, width, height );
|
||||
//host.mouse_visible = true;
|
||||
vgui.Startup( width, height );
|
||||
}
|
||||
else if ( COM_CheckString( clientlib ) )
|
||||
{
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
VGui_Shutdown
|
||||
@@ -326,223 +270,214 @@ Unload vgui_support library and call VGui_Shutdown
|
||||
*/
|
||||
void VGui_Shutdown( void )
|
||||
{
|
||||
if( vgui.dllFuncs.Shutdown )
|
||||
vgui.dllFuncs.Shutdown();
|
||||
if( vgui.Shutdown )
|
||||
vgui.Shutdown();
|
||||
|
||||
if( vgui.hInstance )
|
||||
COM_FreeLibrary( vgui.hInstance );
|
||||
if( s_pVGuiSupport )
|
||||
COM_FreeLibrary( s_pVGuiSupport );
|
||||
s_pVGuiSupport = NULL;
|
||||
|
||||
vgui.hInstance = NULL;
|
||||
vgui.initialized = false;
|
||||
}
|
||||
|
||||
|
||||
static void VGUI_InitKeyTranslationTable( void )
|
||||
void VGUI_InitKeyTranslationTable( void )
|
||||
{
|
||||
static qboolean initialized = false;
|
||||
static qboolean bInitted = false;
|
||||
|
||||
if( initialized ) return;
|
||||
|
||||
initialized = true;
|
||||
if( bInitted )
|
||||
return;
|
||||
bInitted = true;
|
||||
|
||||
// set virtual key translation table
|
||||
memset( vgui.virtualKeyTrans, -1, sizeof( vgui.virtualKeyTrans ) );
|
||||
memset( s_pVirtualKeyTrans, -1, sizeof( s_pVirtualKeyTrans ) );
|
||||
|
||||
// TODO: engine keys are not enough here!
|
||||
// make crossplatform way to pass SDL keys here
|
||||
s_pVirtualKeyTrans['0'] = KEY_0;
|
||||
s_pVirtualKeyTrans['1'] = KEY_1;
|
||||
s_pVirtualKeyTrans['2'] = KEY_2;
|
||||
s_pVirtualKeyTrans['3'] = KEY_3;
|
||||
s_pVirtualKeyTrans['4'] = KEY_4;
|
||||
s_pVirtualKeyTrans['5'] = KEY_5;
|
||||
s_pVirtualKeyTrans['6'] = KEY_6;
|
||||
s_pVirtualKeyTrans['7'] = KEY_7;
|
||||
s_pVirtualKeyTrans['8'] = KEY_8;
|
||||
s_pVirtualKeyTrans['9'] = KEY_9;
|
||||
s_pVirtualKeyTrans['A'] = s_pVirtualKeyTrans['a'] = KEY_A;
|
||||
s_pVirtualKeyTrans['B'] = s_pVirtualKeyTrans['b'] = KEY_B;
|
||||
s_pVirtualKeyTrans['C'] = s_pVirtualKeyTrans['c'] = KEY_C;
|
||||
s_pVirtualKeyTrans['D'] = s_pVirtualKeyTrans['d'] = KEY_D;
|
||||
s_pVirtualKeyTrans['E'] = s_pVirtualKeyTrans['e'] = KEY_E;
|
||||
s_pVirtualKeyTrans['F'] = s_pVirtualKeyTrans['f'] = KEY_F;
|
||||
s_pVirtualKeyTrans['G'] = s_pVirtualKeyTrans['g'] = KEY_G;
|
||||
s_pVirtualKeyTrans['H'] = s_pVirtualKeyTrans['h'] = KEY_H;
|
||||
s_pVirtualKeyTrans['I'] = s_pVirtualKeyTrans['i'] = KEY_I;
|
||||
s_pVirtualKeyTrans['J'] = s_pVirtualKeyTrans['j'] = KEY_J;
|
||||
s_pVirtualKeyTrans['K'] = s_pVirtualKeyTrans['k'] = KEY_K;
|
||||
s_pVirtualKeyTrans['L'] = s_pVirtualKeyTrans['l'] = KEY_L;
|
||||
s_pVirtualKeyTrans['M'] = s_pVirtualKeyTrans['m'] = KEY_M;
|
||||
s_pVirtualKeyTrans['N'] = s_pVirtualKeyTrans['n'] = KEY_N;
|
||||
s_pVirtualKeyTrans['O'] = s_pVirtualKeyTrans['o'] = KEY_O;
|
||||
s_pVirtualKeyTrans['P'] = s_pVirtualKeyTrans['p'] = KEY_P;
|
||||
s_pVirtualKeyTrans['Q'] = s_pVirtualKeyTrans['q'] = KEY_Q;
|
||||
s_pVirtualKeyTrans['R'] = s_pVirtualKeyTrans['r'] = KEY_R;
|
||||
s_pVirtualKeyTrans['S'] = s_pVirtualKeyTrans['s'] = KEY_S;
|
||||
s_pVirtualKeyTrans['T'] = s_pVirtualKeyTrans['t'] = KEY_T;
|
||||
s_pVirtualKeyTrans['U'] = s_pVirtualKeyTrans['u'] = KEY_U;
|
||||
s_pVirtualKeyTrans['V'] = s_pVirtualKeyTrans['v'] = KEY_V;
|
||||
s_pVirtualKeyTrans['W'] = s_pVirtualKeyTrans['w'] = KEY_W;
|
||||
s_pVirtualKeyTrans['X'] = s_pVirtualKeyTrans['x'] = KEY_X;
|
||||
s_pVirtualKeyTrans['Y'] = s_pVirtualKeyTrans['y'] = KEY_Y;
|
||||
s_pVirtualKeyTrans['Z'] = s_pVirtualKeyTrans['z'] = KEY_Z;
|
||||
|
||||
vgui.virtualKeyTrans['0'] = KEY_0;
|
||||
vgui.virtualKeyTrans['1'] = KEY_1;
|
||||
vgui.virtualKeyTrans['2'] = KEY_2;
|
||||
vgui.virtualKeyTrans['3'] = KEY_3;
|
||||
vgui.virtualKeyTrans['4'] = KEY_4;
|
||||
vgui.virtualKeyTrans['5'] = KEY_5;
|
||||
vgui.virtualKeyTrans['6'] = KEY_6;
|
||||
vgui.virtualKeyTrans['7'] = KEY_7;
|
||||
vgui.virtualKeyTrans['8'] = KEY_8;
|
||||
vgui.virtualKeyTrans['9'] = KEY_9;
|
||||
vgui.virtualKeyTrans['A'] = vgui.virtualKeyTrans['a'] = KEY_A;
|
||||
vgui.virtualKeyTrans['B'] = vgui.virtualKeyTrans['b'] = KEY_B;
|
||||
vgui.virtualKeyTrans['C'] = vgui.virtualKeyTrans['c'] = KEY_C;
|
||||
vgui.virtualKeyTrans['D'] = vgui.virtualKeyTrans['d'] = KEY_D;
|
||||
vgui.virtualKeyTrans['E'] = vgui.virtualKeyTrans['e'] = KEY_E;
|
||||
vgui.virtualKeyTrans['F'] = vgui.virtualKeyTrans['f'] = KEY_F;
|
||||
vgui.virtualKeyTrans['G'] = vgui.virtualKeyTrans['g'] = KEY_G;
|
||||
vgui.virtualKeyTrans['H'] = vgui.virtualKeyTrans['h'] = KEY_H;
|
||||
vgui.virtualKeyTrans['I'] = vgui.virtualKeyTrans['i'] = KEY_I;
|
||||
vgui.virtualKeyTrans['J'] = vgui.virtualKeyTrans['j'] = KEY_J;
|
||||
vgui.virtualKeyTrans['K'] = vgui.virtualKeyTrans['k'] = KEY_K;
|
||||
vgui.virtualKeyTrans['L'] = vgui.virtualKeyTrans['l'] = KEY_L;
|
||||
vgui.virtualKeyTrans['M'] = vgui.virtualKeyTrans['m'] = KEY_M;
|
||||
vgui.virtualKeyTrans['N'] = vgui.virtualKeyTrans['n'] = KEY_N;
|
||||
vgui.virtualKeyTrans['O'] = vgui.virtualKeyTrans['o'] = KEY_O;
|
||||
vgui.virtualKeyTrans['P'] = vgui.virtualKeyTrans['p'] = KEY_P;
|
||||
vgui.virtualKeyTrans['Q'] = vgui.virtualKeyTrans['q'] = KEY_Q;
|
||||
vgui.virtualKeyTrans['R'] = vgui.virtualKeyTrans['r'] = KEY_R;
|
||||
vgui.virtualKeyTrans['S'] = vgui.virtualKeyTrans['s'] = KEY_S;
|
||||
vgui.virtualKeyTrans['T'] = vgui.virtualKeyTrans['t'] = KEY_T;
|
||||
vgui.virtualKeyTrans['U'] = vgui.virtualKeyTrans['u'] = KEY_U;
|
||||
vgui.virtualKeyTrans['V'] = vgui.virtualKeyTrans['v'] = KEY_V;
|
||||
vgui.virtualKeyTrans['W'] = vgui.virtualKeyTrans['w'] = KEY_W;
|
||||
vgui.virtualKeyTrans['X'] = vgui.virtualKeyTrans['x'] = KEY_X;
|
||||
vgui.virtualKeyTrans['Y'] = vgui.virtualKeyTrans['y'] = KEY_Y;
|
||||
vgui.virtualKeyTrans['Z'] = vgui.virtualKeyTrans['z'] = KEY_Z;
|
||||
|
||||
vgui.virtualKeyTrans[K_KP_5 - 5] = KEY_PAD_0;
|
||||
vgui.virtualKeyTrans[K_KP_5 - 4] = KEY_PAD_1;
|
||||
vgui.virtualKeyTrans[K_KP_5 - 3] = KEY_PAD_2;
|
||||
vgui.virtualKeyTrans[K_KP_5 - 2] = KEY_PAD_3;
|
||||
vgui.virtualKeyTrans[K_KP_5 - 1] = KEY_PAD_4;
|
||||
vgui.virtualKeyTrans[K_KP_5 - 0] = KEY_PAD_5;
|
||||
vgui.virtualKeyTrans[K_KP_5 + 1] = KEY_PAD_6;
|
||||
vgui.virtualKeyTrans[K_KP_5 + 2] = KEY_PAD_7;
|
||||
vgui.virtualKeyTrans[K_KP_5 + 3] = KEY_PAD_8;
|
||||
vgui.virtualKeyTrans[K_KP_5 + 4] = KEY_PAD_9;
|
||||
vgui.virtualKeyTrans[K_KP_SLASH] = KEY_PAD_DIVIDE;
|
||||
vgui.virtualKeyTrans['*'] = KEY_PAD_MULTIPLY;
|
||||
vgui.virtualKeyTrans[K_KP_MINUS] = KEY_PAD_MINUS;
|
||||
vgui.virtualKeyTrans[K_KP_PLUS] = KEY_PAD_PLUS;
|
||||
vgui.virtualKeyTrans[K_KP_ENTER] = KEY_PAD_ENTER;
|
||||
vgui.virtualKeyTrans[K_KP_NUMLOCK] = KEY_NUMLOCK;
|
||||
vgui.virtualKeyTrans['['] = KEY_LBRACKET;
|
||||
vgui.virtualKeyTrans[']'] = KEY_RBRACKET;
|
||||
vgui.virtualKeyTrans[';'] = KEY_SEMICOLON;
|
||||
vgui.virtualKeyTrans['`'] = KEY_BACKQUOTE;
|
||||
vgui.virtualKeyTrans[','] = KEY_COMMA;
|
||||
vgui.virtualKeyTrans['.'] = KEY_PERIOD;
|
||||
vgui.virtualKeyTrans['-'] = KEY_MINUS;
|
||||
vgui.virtualKeyTrans['='] = KEY_EQUAL;
|
||||
vgui.virtualKeyTrans['/'] = KEY_SLASH;
|
||||
vgui.virtualKeyTrans['\\'] = KEY_BACKSLASH;
|
||||
vgui.virtualKeyTrans['\''] = KEY_APOSTROPHE;
|
||||
vgui.virtualKeyTrans[K_TAB] = KEY_TAB;
|
||||
vgui.virtualKeyTrans[K_ENTER] = KEY_ENTER;
|
||||
vgui.virtualKeyTrans[K_SPACE] = KEY_SPACE;
|
||||
vgui.virtualKeyTrans[K_CAPSLOCK] = KEY_CAPSLOCK;
|
||||
vgui.virtualKeyTrans[K_BACKSPACE] = KEY_BACKSPACE;
|
||||
vgui.virtualKeyTrans[K_ESCAPE] = KEY_ESCAPE;
|
||||
vgui.virtualKeyTrans[K_INS] = KEY_INSERT;
|
||||
vgui.virtualKeyTrans[K_DEL] = KEY_DELETE;
|
||||
vgui.virtualKeyTrans[K_HOME] = KEY_HOME;
|
||||
vgui.virtualKeyTrans[K_END] = KEY_END;
|
||||
vgui.virtualKeyTrans[K_PGUP] = KEY_PAGEUP;
|
||||
vgui.virtualKeyTrans[K_PGDN] = KEY_PAGEDOWN;
|
||||
vgui.virtualKeyTrans[K_PAUSE] = KEY_BREAK;
|
||||
vgui.virtualKeyTrans[K_SHIFT] = KEY_LSHIFT; // SHIFT -> left SHIFT
|
||||
vgui.virtualKeyTrans[K_ALT] = KEY_LALT; // ALT -> left ALT
|
||||
vgui.virtualKeyTrans[K_CTRL] = KEY_LCONTROL; // CTRL -> left CTRL
|
||||
vgui.virtualKeyTrans[K_WIN] = KEY_LWIN;
|
||||
vgui.virtualKeyTrans[K_UPARROW] = KEY_UP;
|
||||
vgui.virtualKeyTrans[K_LEFTARROW] = KEY_LEFT;
|
||||
vgui.virtualKeyTrans[K_DOWNARROW] = KEY_DOWN;
|
||||
vgui.virtualKeyTrans[K_RIGHTARROW] = KEY_RIGHT;
|
||||
vgui.virtualKeyTrans[K_F1] = KEY_F1;
|
||||
vgui.virtualKeyTrans[K_F2] = KEY_F2;
|
||||
vgui.virtualKeyTrans[K_F3] = KEY_F3;
|
||||
vgui.virtualKeyTrans[K_F4] = KEY_F4;
|
||||
vgui.virtualKeyTrans[K_F5] = KEY_F5;
|
||||
vgui.virtualKeyTrans[K_F6] = KEY_F6;
|
||||
vgui.virtualKeyTrans[K_F7] = KEY_F7;
|
||||
vgui.virtualKeyTrans[K_F8] = KEY_F8;
|
||||
vgui.virtualKeyTrans[K_F9] = KEY_F9;
|
||||
vgui.virtualKeyTrans[K_F10] = KEY_F10;
|
||||
vgui.virtualKeyTrans[K_F11] = KEY_F11;
|
||||
vgui.virtualKeyTrans[K_F12] = KEY_F12;
|
||||
s_pVirtualKeyTrans[K_KP_5 - 5] = KEY_PAD_0;
|
||||
s_pVirtualKeyTrans[K_KP_5 - 4] = KEY_PAD_1;
|
||||
s_pVirtualKeyTrans[K_KP_5 - 3] = KEY_PAD_2;
|
||||
s_pVirtualKeyTrans[K_KP_5 - 2] = KEY_PAD_3;
|
||||
s_pVirtualKeyTrans[K_KP_5 - 1] = KEY_PAD_4;
|
||||
s_pVirtualKeyTrans[K_KP_5 - 0] = KEY_PAD_5;
|
||||
s_pVirtualKeyTrans[K_KP_5 + 1] = KEY_PAD_6;
|
||||
s_pVirtualKeyTrans[K_KP_5 + 2] = KEY_PAD_7;
|
||||
s_pVirtualKeyTrans[K_KP_5 + 3] = KEY_PAD_8;
|
||||
s_pVirtualKeyTrans[K_KP_5 + 4] = KEY_PAD_9;
|
||||
s_pVirtualKeyTrans[K_KP_SLASH] = KEY_PAD_DIVIDE;
|
||||
s_pVirtualKeyTrans['*'] = KEY_PAD_MULTIPLY;
|
||||
s_pVirtualKeyTrans[K_KP_MINUS] = KEY_PAD_MINUS;
|
||||
s_pVirtualKeyTrans[K_KP_PLUS] = KEY_PAD_PLUS;
|
||||
s_pVirtualKeyTrans[K_KP_ENTER] = KEY_PAD_ENTER;
|
||||
//s_pVirtualKeyTrans[K_KP_DECIMAL] = KEY_PAD_DECIMAL;
|
||||
s_pVirtualKeyTrans['['] = KEY_LBRACKET;
|
||||
s_pVirtualKeyTrans[']'] = KEY_RBRACKET;
|
||||
s_pVirtualKeyTrans[';'] = KEY_SEMICOLON;
|
||||
s_pVirtualKeyTrans['\''] = KEY_APOSTROPHE;
|
||||
s_pVirtualKeyTrans['`'] = KEY_BACKQUOTE;
|
||||
s_pVirtualKeyTrans[','] = KEY_COMMA;
|
||||
s_pVirtualKeyTrans['.'] = KEY_PERIOD;
|
||||
s_pVirtualKeyTrans[K_KP_SLASH] = KEY_SLASH;
|
||||
s_pVirtualKeyTrans['\\'] = KEY_BACKSLASH;
|
||||
s_pVirtualKeyTrans['-'] = KEY_MINUS;
|
||||
s_pVirtualKeyTrans['='] = KEY_EQUAL;
|
||||
s_pVirtualKeyTrans[K_ENTER] = KEY_ENTER;
|
||||
s_pVirtualKeyTrans[K_SPACE] = KEY_SPACE;
|
||||
s_pVirtualKeyTrans[K_BACKSPACE] = KEY_BACKSPACE;
|
||||
s_pVirtualKeyTrans[K_TAB] = KEY_TAB;
|
||||
s_pVirtualKeyTrans[K_CAPSLOCK] = KEY_CAPSLOCK;
|
||||
s_pVirtualKeyTrans[K_KP_NUMLOCK] = KEY_NUMLOCK;
|
||||
s_pVirtualKeyTrans[K_ESCAPE] = KEY_ESCAPE;
|
||||
//s_pVirtualKeyTrans[K_KP_SCROLLLOCK] = KEY_SCROLLLOCK;
|
||||
s_pVirtualKeyTrans[K_INS] = KEY_INSERT;
|
||||
s_pVirtualKeyTrans[K_DEL] = KEY_DELETE;
|
||||
s_pVirtualKeyTrans[K_HOME] = KEY_HOME;
|
||||
s_pVirtualKeyTrans[K_END] = KEY_END;
|
||||
s_pVirtualKeyTrans[K_PGUP] = KEY_PAGEUP;
|
||||
s_pVirtualKeyTrans[K_PGDN] = KEY_PAGEDOWN;
|
||||
s_pVirtualKeyTrans[K_PAUSE] = KEY_BREAK;
|
||||
//s_pVirtualKeyTrans[K_SHIFT] = KEY_RSHIFT;
|
||||
s_pVirtualKeyTrans[K_SHIFT] = KEY_LSHIFT; // SHIFT -> left SHIFT
|
||||
//s_pVirtualKeyTrans[SDLK_RALT] = KEY_RALT;
|
||||
s_pVirtualKeyTrans[K_ALT] = KEY_LALT; // ALT -> left ALT
|
||||
//s_pVirtualKeyTrans[SDLK_RCTRL] = KEY_RCONTROL;
|
||||
s_pVirtualKeyTrans[K_CTRL] = KEY_LCONTROL; // CTRL -> left CTRL
|
||||
s_pVirtualKeyTrans[K_WIN] = KEY_LWIN;
|
||||
//s_pVirtualKeyTrans[SDLK_APPLICATION] = KEY_RWIN;
|
||||
//s_pVirtualKeyTrans[K_WIN] = KEY_APP;
|
||||
s_pVirtualKeyTrans[K_UPARROW] = KEY_UP;
|
||||
s_pVirtualKeyTrans[K_LEFTARROW] = KEY_LEFT;
|
||||
s_pVirtualKeyTrans[K_DOWNARROW] = KEY_DOWN;
|
||||
s_pVirtualKeyTrans[K_RIGHTARROW] = KEY_RIGHT;
|
||||
s_pVirtualKeyTrans[K_F1] = KEY_F1;
|
||||
s_pVirtualKeyTrans[K_F2] = KEY_F2;
|
||||
s_pVirtualKeyTrans[K_F3] = KEY_F3;
|
||||
s_pVirtualKeyTrans[K_F4] = KEY_F4;
|
||||
s_pVirtualKeyTrans[K_F5] = KEY_F5;
|
||||
s_pVirtualKeyTrans[K_F6] = KEY_F6;
|
||||
s_pVirtualKeyTrans[K_F7] = KEY_F7;
|
||||
s_pVirtualKeyTrans[K_F8] = KEY_F8;
|
||||
s_pVirtualKeyTrans[K_F9] = KEY_F9;
|
||||
s_pVirtualKeyTrans[K_F10] = KEY_F10;
|
||||
s_pVirtualKeyTrans[K_F11] = KEY_F11;
|
||||
s_pVirtualKeyTrans[K_F12] = KEY_F12;
|
||||
}
|
||||
|
||||
static enum VGUI_KeyCode VGUI_MapKey( int keyCode )
|
||||
enum VGUI_KeyCode VGUI_MapKey( int keyCode )
|
||||
{
|
||||
VGUI_InitKeyTranslationTable();
|
||||
|
||||
if( keyCode >= 0 && keyCode < ARRAYSIZE( vgui.virtualKeyTrans ))
|
||||
return vgui.virtualKeyTrans[keyCode];
|
||||
|
||||
return (enum VGUI_KeyCode)-1;
|
||||
}
|
||||
|
||||
void VGui_MouseEvent( int key, int clicks )
|
||||
{
|
||||
enum VGUI_MouseAction mact;
|
||||
enum VGUI_MouseCode code;
|
||||
|
||||
if( !vgui.dllFuncs.Mouse )
|
||||
return;
|
||||
|
||||
switch( key )
|
||||
if( keyCode < 0 || keyCode >= (int)sizeof( s_pVirtualKeyTrans ) / (int)sizeof( s_pVirtualKeyTrans[0] ))
|
||||
{
|
||||
case K_MOUSE1: code = MOUSE_LEFT; break;
|
||||
case K_MOUSE2: code = MOUSE_RIGHT; break;
|
||||
case K_MOUSE3: code = MOUSE_MIDDLE; break;
|
||||
default: return;
|
||||
//Assert( false );
|
||||
return (enum VGUI_KeyCode)-1;
|
||||
}
|
||||
|
||||
if( clicks >= 2 )
|
||||
mact = MA_DOUBLE;
|
||||
else if( clicks == 1 )
|
||||
mact = MA_PRESSED;
|
||||
else
|
||||
mact = MA_RELEASED;
|
||||
|
||||
vgui.dllFuncs.Mouse( mact, code );
|
||||
}
|
||||
|
||||
void VGui_MWheelEvent( int y )
|
||||
{
|
||||
if( !vgui.dllFuncs.Mouse )
|
||||
return;
|
||||
|
||||
vgui.dllFuncs.Mouse( MA_WHEEL, y );
|
||||
{
|
||||
return s_pVirtualKeyTrans[keyCode];
|
||||
}
|
||||
}
|
||||
|
||||
void VGui_KeyEvent( int key, int down )
|
||||
{
|
||||
enum VGUI_KeyCode code;
|
||||
|
||||
if( !vgui.dllFuncs.Key )
|
||||
if( !vgui.initialized )
|
||||
return;
|
||||
|
||||
if(( code = VGUI_MapKey( key )) < 0 )
|
||||
return;
|
||||
|
||||
if( down )
|
||||
switch( key )
|
||||
{
|
||||
vgui.dllFuncs.Key( KA_PRESSED, code );
|
||||
vgui.dllFuncs.Key( KA_TYPED, code );
|
||||
case K_MOUSE1:
|
||||
if( down && host.mouse_visible ) {
|
||||
Key_EnableTextInput(true, false);
|
||||
}
|
||||
vgui.Mouse( down ? MA_PRESSED : MA_RELEASED, MOUSE_LEFT );
|
||||
return;
|
||||
case K_MOUSE2:
|
||||
vgui.Mouse( down ? MA_PRESSED : MA_RELEASED, MOUSE_RIGHT );
|
||||
return;
|
||||
case K_MOUSE3:
|
||||
vgui.Mouse( down ? MA_PRESSED : MA_RELEASED, MOUSE_MIDDLE );
|
||||
return;
|
||||
case K_MWHEELDOWN:
|
||||
vgui.Mouse( MA_WHEEL, 1 );
|
||||
return;
|
||||
case K_MWHEELUP:
|
||||
vgui.Mouse( MA_WHEEL, -1 );
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else vgui.dllFuncs.Key( KA_RELEASED, code );
|
||||
|
||||
if( down == 2 )
|
||||
vgui.Key( KA_TYPED, VGUI_MapKey( key ) );
|
||||
else
|
||||
vgui.Key( down?KA_PRESSED:KA_RELEASED, VGUI_MapKey( key ) );
|
||||
//Msg("VGui_KeyEvent %d %d %d\n", key, VGUI_MapKey( key ), down );
|
||||
}
|
||||
|
||||
void VGui_MouseMove( int x, int y )
|
||||
{
|
||||
if( vgui.dllFuncs.MouseMove )
|
||||
{
|
||||
float xscale = (float)refState.width / (float)clgame.scrInfo.iWidth;
|
||||
float yscale = (float)refState.height / (float)clgame.scrInfo.iHeight;
|
||||
vgui.dllFuncs.MouseMove( x / xscale, y / yscale );
|
||||
}
|
||||
float xscale = (float)refState.width / (float)clgame.scrInfo.iWidth;
|
||||
float yscale = (float)refState.height / (float)clgame.scrInfo.iHeight;
|
||||
if( vgui.initialized )
|
||||
vgui.MouseMove( x / xscale, y / yscale );
|
||||
}
|
||||
|
||||
void VGui_Paint( void )
|
||||
{
|
||||
if( vgui.dllFuncs.Paint )
|
||||
vgui.dllFuncs.Paint();
|
||||
if( vgui.initialized )
|
||||
vgui.Paint();
|
||||
}
|
||||
|
||||
void VGui_UpdateInternalCursorState( VGUI_DefaultCursor cursorType )
|
||||
void VGui_RunFrame( void )
|
||||
{
|
||||
vgui.cursor = cursorType;
|
||||
//stub
|
||||
}
|
||||
|
||||
|
||||
void *GAME_EXPORT VGui_GetPanel( void )
|
||||
{
|
||||
if( vgui.dllFuncs.GetPanel )
|
||||
return vgui.dllFuncs.GetPanel();
|
||||
if( vgui.initialized )
|
||||
return vgui.GetPanel();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void VGui_ReportTextInput( const char *text )
|
||||
{
|
||||
if( vgui.dllFuncs.TextInput )
|
||||
vgui.dllFuncs.TextInput( text );
|
||||
if ( vgui.initialized )
|
||||
vgui.TextInput( text );
|
||||
}
|
||||
|
||||
|
||||
@@ -16,22 +16,25 @@ GNU General Public License for more details.
|
||||
#ifndef VGUI_DRAW_H
|
||||
#define VGUI_DRAW_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "port.h"
|
||||
|
||||
//
|
||||
// vgui_draw.c
|
||||
//
|
||||
void VGui_RegisterCvars( void );
|
||||
qboolean VGui_LoadProgs( HINSTANCE hInstance );
|
||||
void VGui_Startup( HINSTANCE clientInstance, int width, int height );
|
||||
void VGui_Startup( const char *clientlib, int width, int height );
|
||||
void VGui_Shutdown( void );
|
||||
void VGui_Paint( void );
|
||||
void VGui_RunFrame( void );
|
||||
void VGui_MouseEvent( int key, int clicks );
|
||||
void VGui_MWheelEvent( int y );
|
||||
void VGui_KeyEvent( int key, int down );
|
||||
void VGui_MouseMove( int x, int y );
|
||||
qboolean VGui_IsActive( void );
|
||||
void *VGui_GetPanel( void );
|
||||
void VGui_ReportTextInput( const char *text );
|
||||
void VGui_UpdateInternalCursorState( VGUI_DefaultCursor cursorType );
|
||||
|
||||
#endif // VGUI_DRAW_H
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif//VGUI_DRAW_H
|
||||
|
||||
@@ -21,6 +21,7 @@ GNU General Public License for more details.
|
||||
#include "platform/platform.h"
|
||||
|
||||
#define WINDOW_NAME XASH_ENGINE_NAME " Window" // Half-Life
|
||||
convar_t *vid_displayfrequency;
|
||||
convar_t *vid_fullscreen;
|
||||
convar_t *vid_mode;
|
||||
convar_t *vid_brightness;
|
||||
@@ -66,30 +67,19 @@ void VID_InitDefaultResolution( void )
|
||||
R_SaveVideoMode
|
||||
=================
|
||||
*/
|
||||
void R_SaveVideoMode( int w, int h, int render_w, int render_h )
|
||||
void R_SaveVideoMode( int w, int h , int render_w, int render_h )
|
||||
{
|
||||
if( !w || !h || !render_w || !render_h )
|
||||
{
|
||||
host.renderinfo_changed = false;
|
||||
return;
|
||||
}
|
||||
|
||||
host.window_center_x = w / 2;
|
||||
host.window_center_y = h / 2;
|
||||
|
||||
Cvar_SetValue( "width", w );
|
||||
Cvar_SetValue( "height", h );
|
||||
|
||||
// immediately drop changed state or we may trigger
|
||||
// video subsystem to reapply settings
|
||||
host.renderinfo_changed = false;
|
||||
|
||||
if( refState.width == render_w && refState.height == render_h )
|
||||
return;
|
||||
|
||||
refState.width = render_w;
|
||||
refState.height = render_h;
|
||||
|
||||
host.renderinfo_changed = false;
|
||||
|
||||
// check for 4:3 or 5:4
|
||||
if( render_w * 3 != render_h * 4 && render_w * 4 != render_h * 5 )
|
||||
refState.wideScreen = true;
|
||||
@@ -186,11 +176,12 @@ void VID_Init( void )
|
||||
Cvar_Get( "width", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen width" );
|
||||
Cvar_Get( "height", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "screen height" );
|
||||
|
||||
window_xpos = Cvar_Get( "_window_xpos", "-1", FCVAR_RENDERINFO, "window position by horizontal" );
|
||||
window_ypos = Cvar_Get( "_window_ypos", "-1", FCVAR_RENDERINFO, "window position by vertical" );
|
||||
window_xpos = Cvar_Get( "_window_xpos", "130", FCVAR_RENDERINFO, "window position by horizontal" );
|
||||
window_ypos = Cvar_Get( "_window_ypos", "48", FCVAR_RENDERINFO, "window position by vertical" );
|
||||
|
||||
vid_gamma = Cvar_Get( "gamma", "2.5", FCVAR_ARCHIVE, "gamma amount" );
|
||||
vid_brightness = Cvar_Get( "brightness", "0.0", FCVAR_ARCHIVE, "brightness factor" );
|
||||
vid_displayfrequency = Cvar_Get ( "vid_displayfrequency", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "fullscreen refresh rate" );
|
||||
vid_fullscreen = Cvar_Get( "fullscreen", "0", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable fullscreen mode" );
|
||||
vid_mode = Cvar_Get( "vid_mode", "0", FCVAR_RENDERINFO, "current video mode index (used just for storage)" );
|
||||
vid_highdpi = Cvar_Get( "vid_highdpi", "1", FCVAR_RENDERINFO|FCVAR_VIDRESTART, "enable High-DPI mode" );
|
||||
|
||||
@@ -31,6 +31,7 @@ extern glwstate_t glw_state;
|
||||
#define VID_MIN_WIDTH 320
|
||||
|
||||
extern convar_t *vid_fullscreen;
|
||||
extern convar_t *vid_displayfrequency;
|
||||
extern convar_t *vid_highdpi;
|
||||
extern convar_t *vid_rotate;
|
||||
extern convar_t *vid_scale;
|
||||
|
||||
@@ -159,11 +159,9 @@ static uint Voice_GetOpusCompressedData( byte *out, uint maxsize, uint *frames )
|
||||
if( voice.input_file )
|
||||
{
|
||||
uint numbytes;
|
||||
double updateInterval, curtime = Sys_DoubleTime();
|
||||
|
||||
updateInterval = curtime - voice.start_time;
|
||||
voice.start_time = curtime;
|
||||
double updateInterval;
|
||||
|
||||
updateInterval = cl.mtime[0] - cl.mtime[1];
|
||||
numbytes = updateInterval * voice.samplerate * voice.width * VOICE_PCM_CHANNELS;
|
||||
numbytes = Q_min( numbytes, voice.input_file->size - voice.input_file_pos );
|
||||
numbytes = Q_min( numbytes, sizeof( voice.input_buffer ) - voice.input_buffer_pos );
|
||||
|
||||
@@ -17,20 +17,10 @@ GNU General Public License for more details.
|
||||
#include "base_cmd.h"
|
||||
#include "cdll_int.h"
|
||||
|
||||
// TODO: use another hash function, as COM_HashKey depends on string length
|
||||
#define HASH_SIZE 128 // 128 * 4 * 4 == 2048 bytes
|
||||
|
||||
typedef struct base_command_hashmap_s
|
||||
{
|
||||
base_command_t *basecmd; // base command: cvar, alias or command
|
||||
const char *name; // key for searching
|
||||
base_command_type_e type; // type for faster searching
|
||||
struct base_command_hashmap_s *next;
|
||||
} base_command_hashmap_t;
|
||||
|
||||
static base_command_hashmap_t *hashed_cmds[HASH_SIZE];
|
||||
|
||||
#define BaseCmd_HashKey( x ) COM_HashKey( name, HASH_SIZE )
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_FindInBucket
|
||||
@@ -38,7 +28,7 @@ BaseCmd_FindInBucket
|
||||
Find base command in bucket
|
||||
============
|
||||
*/
|
||||
static base_command_hashmap_t *BaseCmd_FindInBucket( base_command_hashmap_t *bucket, base_command_type_e type, const char *name )
|
||||
base_command_hashmap_t *BaseCmd_FindInBucket( base_command_hashmap_t *bucket, base_command_type_e type, const char *name )
|
||||
{
|
||||
base_command_hashmap_t *i = bucket;
|
||||
for( ; i && ( i->type != type || Q_stricmp( name, i->name ) ); // filter out
|
||||
@@ -54,9 +44,9 @@ BaseCmd_GetBucket
|
||||
Get bucket which contain basecmd by given name
|
||||
============
|
||||
*/
|
||||
static base_command_hashmap_t *BaseCmd_GetBucket( const char *name )
|
||||
base_command_hashmap_t *BaseCmd_GetBucket( const char *name )
|
||||
{
|
||||
return hashed_cmds[ BaseCmd_HashKey( name ) ];
|
||||
return hashed_cmds[ COM_HashKey( name, HASH_SIZE ) ];
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -83,7 +73,7 @@ BaseCmd_Find
|
||||
Find every type of base command and write into arguments
|
||||
============
|
||||
*/
|
||||
void BaseCmd_FindAll( const char *name, base_command_t **cmd, base_command_t **alias, base_command_t **cvar )
|
||||
void BaseCmd_FindAll(const char *name, base_command_t **cmd, base_command_t **alias, base_command_t **cvar)
|
||||
{
|
||||
base_command_hashmap_t *base = BaseCmd_GetBucket( name );
|
||||
base_command_hashmap_t *i = base;
|
||||
@@ -111,6 +101,7 @@ void BaseCmd_FindAll( const char *name, base_command_t **cmd, base_command_t **a
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -122,23 +113,41 @@ Add new typed base command to hashmap
|
||||
*/
|
||||
void BaseCmd_Insert( base_command_type_e type, base_command_t *basecmd, const char *name )
|
||||
{
|
||||
base_command_hashmap_t *elem, *cur, *find;
|
||||
uint hash = BaseCmd_HashKey( name );
|
||||
uint hash = COM_HashKey( name, HASH_SIZE );
|
||||
base_command_hashmap_t *elem;
|
||||
|
||||
elem = Z_Malloc( sizeof( base_command_hashmap_t ) );
|
||||
elem->basecmd = basecmd;
|
||||
elem->type = type;
|
||||
elem->name = name;
|
||||
elem->next = hashed_cmds[hash];
|
||||
hashed_cmds[hash] = elem;
|
||||
}
|
||||
|
||||
// link the variable in alphanumerical order
|
||||
for( cur = NULL, find = hashed_cmds[hash];
|
||||
find && Q_strcmp( find->name, elem->name ) < 0;
|
||||
cur = find, find = find->next );
|
||||
/*
|
||||
============
|
||||
BaseCmd_Replace
|
||||
|
||||
if( cur ) cur->next = elem;
|
||||
else hashed_cmds[hash] = elem;
|
||||
Used in case, when basecmd has been registered, but gamedll wants to register it's own
|
||||
============
|
||||
*/
|
||||
qboolean BaseCmd_Replace( base_command_type_e type, base_command_t *basecmd, const char *name )
|
||||
{
|
||||
base_command_hashmap_t *i = BaseCmd_GetBucket( name );
|
||||
|
||||
elem->next = find;
|
||||
for( ; i && ( i->type != type || Q_stricmp( name, i->name ) ) ; // filter out
|
||||
i = i->next );
|
||||
|
||||
if( !i )
|
||||
{
|
||||
Con_Reportf( S_ERROR "BaseCmd_Replace: couldn't find %s\n", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
i->basecmd = basecmd;
|
||||
i->name = name; // may be freed after
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -150,7 +159,7 @@ Remove base command from hashmap
|
||||
*/
|
||||
void BaseCmd_Remove( base_command_type_e type, const char *name )
|
||||
{
|
||||
uint hash = BaseCmd_HashKey( name );
|
||||
uint hash = COM_HashKey( name, HASH_SIZE );
|
||||
base_command_hashmap_t *i, *prev;
|
||||
|
||||
for( prev = NULL, i = hashed_cmds[hash]; i &&
|
||||
@@ -212,27 +221,23 @@ void BaseCmd_Stats_f( void )
|
||||
|
||||
if( len > maxsize )
|
||||
maxsize = len;
|
||||
|
||||
}
|
||||
|
||||
Con_Printf( "min length: %d, max length: %d, empty: %d\n", minsize, maxsize, empty );
|
||||
Con_Printf( "Base command stats:\n");
|
||||
Con_Printf( "Bucket minimal length: %d\n", minsize );
|
||||
Con_Printf( "Bucket maximum length: %d\n", maxsize );
|
||||
Con_Printf( "Empty buckets: %d\n", empty );
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
qboolean valid;
|
||||
int lookups;
|
||||
} basecmd_test_stats_t;
|
||||
|
||||
static void BaseCmd_CheckCvars( const char *key, const char *value, const void *unused, void *ptr )
|
||||
{
|
||||
basecmd_test_stats_t *stats = ptr;
|
||||
base_command_t *v = BaseCmd_Find( HM_CVAR, key );
|
||||
qboolean *invalid = ptr;
|
||||
|
||||
stats->lookups++;
|
||||
if( !BaseCmd_Find( HM_CVAR, key ))
|
||||
if( !v )
|
||||
{
|
||||
Con_Printf( "Cvar %s is missing in basecmd\n", key );
|
||||
stats->valid = false;
|
||||
*invalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,51 +250,38 @@ testing order matches cbuf execute
|
||||
*/
|
||||
void BaseCmd_Test_f( void )
|
||||
{
|
||||
basecmd_test_stats_t stats;
|
||||
double start, end, dt;
|
||||
int i;
|
||||
void *cmd;
|
||||
cmdalias_t *a;
|
||||
qboolean invalid = false;
|
||||
|
||||
stats.valid = true;
|
||||
stats.lookups = 0;
|
||||
|
||||
start = Sys_DoubleTime() * 1000;
|
||||
|
||||
for( i = 0; i < 1000; i++ )
|
||||
// Cmd_LookupCmds don't allows to check alias, so just iterate
|
||||
for( a = Cmd_AliasGetList(); a; a = a->next )
|
||||
{
|
||||
cmdalias_t *a;
|
||||
void *cmd;
|
||||
base_command_t *v = BaseCmd_Find( HM_CMDALIAS, a->name );
|
||||
|
||||
// Cmd_LookupCmds don't allows to check alias, so just iterate
|
||||
for( a = Cmd_AliasGetList(); a; a = a->next, stats.lookups++ )
|
||||
if( !v )
|
||||
{
|
||||
if( !BaseCmd_Find( HM_CMDALIAS, a->name ))
|
||||
{
|
||||
Con_Printf( "Alias %s is missing in basecmd\n", a->name );
|
||||
stats.valid = false;
|
||||
}
|
||||
Con_Printf( "Alias %s is missing in basecmd\n", a->name );
|
||||
invalid = true;
|
||||
}
|
||||
|
||||
for( cmd = Cmd_GetFirstFunctionHandle(); cmd;
|
||||
cmd = Cmd_GetNextFunctionHandle( cmd ), stats.lookups++ )
|
||||
{
|
||||
if( !BaseCmd_Find( HM_CMD, Cmd_GetName( cmd )))
|
||||
{
|
||||
Con_Printf( "Command %s is missing in basecmd\n", Cmd_GetName( cmd ));
|
||||
stats.valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
Cvar_LookupVars( 0, NULL, &stats.valid, (setpair_t)BaseCmd_CheckCvars );
|
||||
}
|
||||
|
||||
end = Sys_DoubleTime() * 1000;
|
||||
for( cmd = Cmd_GetFirstFunctionHandle(); cmd;
|
||||
cmd = Cmd_GetNextFunctionHandle( cmd ) )
|
||||
{
|
||||
base_command_t *v = BaseCmd_Find( HM_CMD, Cmd_GetName( cmd ) );
|
||||
|
||||
dt = end - start;
|
||||
if( !v )
|
||||
{
|
||||
Con_Printf( "Command %s is missing in basecmd\n", Cmd_GetName( cmd ) );
|
||||
invalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !stats.valid )
|
||||
Cvar_LookupVars( 0, NULL, &invalid, (setpair_t)BaseCmd_CheckCvars );
|
||||
|
||||
if( !invalid )
|
||||
{
|
||||
Con_Printf( "BaseCmd is valid\n" );
|
||||
|
||||
Con_Printf( "Test took %.3f ms, %d lookups, %.3f us/lookup\n", dt, stats.lookups, dt / stats.lookups * 1000 );
|
||||
|
||||
BaseCmd_Stats_f();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ GNU General Public License for more details.
|
||||
#ifndef BASE_CMD_H
|
||||
#define BASE_CMD_H
|
||||
|
||||
// TODO: Find cases when command hashmap works incorrect
|
||||
// and maybe disable it
|
||||
#define XASH_HASHED_VARS
|
||||
|
||||
#ifdef XASH_HASHED_VARS
|
||||
@@ -31,13 +33,23 @@ typedef enum base_command_type
|
||||
|
||||
typedef void base_command_t;
|
||||
|
||||
typedef struct base_command_hashmap_s
|
||||
{
|
||||
base_command_t *basecmd; // base command: cvar, alias or command
|
||||
const char *name; // key for searching
|
||||
base_command_type_e type; // type for faster searching
|
||||
struct base_command_hashmap_s *next;
|
||||
} base_command_hashmap_t;
|
||||
|
||||
|
||||
void BaseCmd_Init( void );
|
||||
base_command_hashmap_t *BaseCmd_GetBucket( const char *name );
|
||||
base_command_hashmap_t *BaseCmd_FindInBucket( base_command_hashmap_t *bucket, base_command_type_e type, const char *name );
|
||||
base_command_t *BaseCmd_Find( base_command_type_e type, const char *name );
|
||||
void BaseCmd_FindAll( const char *name,
|
||||
base_command_t **cmd, base_command_t **alias, base_command_t **cvar );
|
||||
void BaseCmd_Insert ( base_command_type_e type, base_command_t *basecmd, const char *name );
|
||||
qboolean BaseCmd_Replace( base_command_type_e type, base_command_t *basecmd, const char *name ); // only if same name
|
||||
void BaseCmd_Remove ( base_command_type_e type, const char *name );
|
||||
void BaseCmd_Stats_f( void ); // to be registered later
|
||||
void BaseCmd_Test_f( void ); // to be registered later
|
||||
|
||||
@@ -120,18 +120,6 @@ void Cbuf_AddText( const char *text )
|
||||
Cbuf_AddTextToBuffer( &cmd_text, text );
|
||||
}
|
||||
|
||||
void Cbuf_AddTextf( 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 );
|
||||
|
||||
Cbuf_AddText( buf );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cbuf_AddFilteredText
|
||||
@@ -996,7 +984,7 @@ static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPr
|
||||
cmd_condlevel = 0;
|
||||
|
||||
// cvar value substitution
|
||||
if( CVAR_TO_BOOL( cmd_scripting ) && isPrivileged )
|
||||
if( CVAR_TO_BOOL( cmd_scripting ))
|
||||
{
|
||||
while( *text )
|
||||
{
|
||||
@@ -1162,13 +1150,13 @@ void Cmd_ForwardToServer( void )
|
||||
str[0] = 0;
|
||||
if( Q_stricmp( Cmd_Argv( 0 ), "cmd" ))
|
||||
{
|
||||
Q_strncat( str, Cmd_Argv( 0 ), sizeof( str ));
|
||||
Q_strncat( str, " ", sizeof( str ));
|
||||
Q_strcat( str, Cmd_Argv( 0 ));
|
||||
Q_strcat( str, " " );
|
||||
}
|
||||
|
||||
if( Cmd_Argc() > 1 )
|
||||
Q_strncat( str, Cmd_Args( ), sizeof( str ));
|
||||
else Q_strncat( str, "\n", sizeof( str ));
|
||||
Q_strcat( str, Cmd_Args( ));
|
||||
else Q_strcat( str, "\n" );
|
||||
|
||||
MSG_WriteString( &cls.netchan.message, str );
|
||||
}
|
||||
@@ -1266,21 +1254,21 @@ static void Cmd_Apropos_f( void )
|
||||
cmdalias_t *alias;
|
||||
const char *partial;
|
||||
int count = 0;
|
||||
char buf[MAX_VA_STRING];
|
||||
qboolean ispattern;
|
||||
|
||||
if( Cmd_Argc() < 2 )
|
||||
if( Cmd_Argc() > 1 )
|
||||
{
|
||||
partial = Cmd_Args();
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg( "apropos what?\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
partial = Cmd_Args();
|
||||
|
||||
if( !Q_strpbrk( partial, "*?" ))
|
||||
{
|
||||
Q_snprintf( buf, sizeof( buf ), "*%s*", partial );
|
||||
partial = buf;
|
||||
}
|
||||
ispattern = partial && Q_strpbrk( partial, "*?" );
|
||||
if( !ispattern )
|
||||
partial = va( "*%s*", partial );
|
||||
|
||||
for( var = (convar_t*)Cvar_GetList(); var; var = var->next )
|
||||
{
|
||||
@@ -1407,8 +1395,8 @@ void Cmd_Init( void )
|
||||
#endif // XASH_DEDICATED
|
||||
Cmd_AddRestrictedCommand( "alias", Cmd_Alias_f, "create a script function. Without arguments show the list of all alias" );
|
||||
Cmd_AddRestrictedCommand( "unalias", Cmd_UnAlias_f, "remove a script function" );
|
||||
Cmd_AddRestrictedCommand( "if", Cmd_If_f, "compare and set condition bits" );
|
||||
Cmd_AddRestrictedCommand( "else", Cmd_Else_f, "invert condition bit" );
|
||||
Cmd_AddCommand( "if", Cmd_If_f, "compare and set condition bits" );
|
||||
Cmd_AddCommand( "else", Cmd_Else_f, "invert condition bit" );
|
||||
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
Cmd_AddCommand( "basecmd_stats", BaseCmd_Stats_f, "print info about basecmd usage" );
|
||||
|
||||
@@ -21,7 +21,6 @@ GNU General Public License for more details.
|
||||
#define S_WARN "^3Warning:^7 "
|
||||
#define S_ERROR "^1Error:^7 "
|
||||
#define S_USAGE "Usage: "
|
||||
#define S_USAGE_INDENT " "
|
||||
|
||||
#define S_OPENGL_NOTE "^2OpenGL Note:^7 "
|
||||
#define S_OPENGL_WARN "^3OpenGL Warning:^7 "
|
||||
@@ -68,4 +67,8 @@ GNU General Public License for more details.
|
||||
#define XASH_VERSION "0.20" // engine current version
|
||||
#define XASH_COMPAT_VERSION "0.99" // version we are based on
|
||||
|
||||
// renderers order is important, software is always a last chance fallback
|
||||
#define DEFAULT_RENDERERS { "gl", "gles1", "gles2", "gl4es", "soft" }
|
||||
#define DEFAULT_RENDERERS_LEN 5
|
||||
|
||||
#endif//COM_STRINGS_H
|
||||
|
||||
@@ -151,30 +151,6 @@ int GAME_EXPORT COM_RandomLong( int lLow, int lHigh )
|
||||
return lLow + (n % x);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
va
|
||||
|
||||
does a varargs printf into a temp buffer,
|
||||
so I don't need to have varargs versions
|
||||
of all text functions.
|
||||
============
|
||||
*/
|
||||
char *va( const char *format, ... )
|
||||
{
|
||||
va_list argptr;
|
||||
static char string[16][MAX_VA_STRING], *s;
|
||||
static int stringindex = 0;
|
||||
|
||||
s = string[stringindex];
|
||||
stringindex = (stringindex + 1) & 15;
|
||||
va_start( argptr, format );
|
||||
Q_vsnprintf( s, sizeof( string[0] ), format, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
@@ -553,6 +529,7 @@ This doesn't search in the pak file.
|
||||
*/
|
||||
int GAME_EXPORT COM_ExpandFilename( const char *fileName, char *nameOutBuffer, int nameOutBufferSize )
|
||||
{
|
||||
const char *path;
|
||||
char result[MAX_SYSPATH];
|
||||
|
||||
if( !COM_CheckString( fileName ) || !nameOutBuffer || nameOutBufferSize <= 0 )
|
||||
@@ -561,8 +538,10 @@ int GAME_EXPORT COM_ExpandFilename( const char *fileName, char *nameOutBuffer, i
|
||||
// filename examples:
|
||||
// media\sierra.avi - D:\Xash3D\valve\media\sierra.avi
|
||||
// models\barney.mdl - D:\Xash3D\bshift\models\barney.mdl
|
||||
if( g_fsapi.GetFullDiskPath( result, sizeof( result ), fileName, false ))
|
||||
if(( path = FS_GetDiskPath( fileName, false )) != NULL )
|
||||
{
|
||||
Q_sprintf( result, "%s/%s", host.rootdir, path );
|
||||
|
||||
// check for enough room
|
||||
if( Q_strlen( result ) > nameOutBufferSize )
|
||||
return 0;
|
||||
@@ -897,7 +876,9 @@ cvar_t *pfnCvar_RegisterClientVariable( const char *szName, const char *szValue,
|
||||
if( !Q_stricmp( szName, "motdfile" ))
|
||||
flags |= FCVAR_PRIVILEGED;
|
||||
|
||||
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_CLIENTDLL, Cvar_BuildAutoDescription( szName, flags|FCVAR_CLIENTDLL ));
|
||||
if( FBitSet( flags, FCVAR_GLCONFIG ))
|
||||
return (cvar_t *)Cvar_Get( szName, szValue, flags, va( CVAR_GLCONFIG_DESCRIPTION, szName ));
|
||||
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_CLIENTDLL, Cvar_BuildAutoDescription( flags|FCVAR_CLIENTDLL ));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -908,7 +889,9 @@ pfnCvar_RegisterVariable
|
||||
*/
|
||||
cvar_t *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 ));
|
||||
if( FBitSet( flags, FCVAR_GLCONFIG ))
|
||||
return (cvar_t *)Cvar_Get( szName, szValue, flags, va( CVAR_GLCONFIG_DESCRIPTION, szName ));
|
||||
return (cvar_t *)Cvar_Get( szName, szValue, flags|FCVAR_GAMEUIDLL, Cvar_BuildAutoDescription( flags|FCVAR_GAMEUIDLL ));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1003,7 +986,7 @@ pfnGetGameDir
|
||||
void GAME_EXPORT pfnGetGameDir( char *szGetGameDir )
|
||||
{
|
||||
if( !szGetGameDir ) return;
|
||||
Q_strncpy( szGetGameDir, GI->gamefolder, sizeof( GI->gamefolder ));
|
||||
Q_strcpy( szGetGameDir, GI->gamefolder );
|
||||
}
|
||||
|
||||
qboolean COM_IsSafeFileToDownload( const char *filename )
|
||||
@@ -1050,32 +1033,15 @@ qboolean COM_IsSafeFileToDownload( const char *filename )
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *COM_GetResourceTypeName( resourcetype_t restype )
|
||||
{
|
||||
switch( restype )
|
||||
{
|
||||
case t_decal: return "decal";
|
||||
case t_eventscript: return "eventscript";
|
||||
case t_generic: return "generic";
|
||||
case t_model: return "model";
|
||||
case t_skin: return "skin";
|
||||
case t_sound: return "sound";
|
||||
case t_world: return "world";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
char *_copystring( poolhandle_t mempool, const char *s, const char *filename, int fileline )
|
||||
{
|
||||
size_t size;
|
||||
char *b;
|
||||
|
||||
if( !s ) return NULL;
|
||||
if( !mempool ) mempool = host.mempool;
|
||||
|
||||
size = Q_strlen( s ) + 1;
|
||||
b = _Mem_Alloc( mempool, size, false, filename, fileline );
|
||||
Q_strncpy( b, s, size );
|
||||
b = _Mem_Alloc( mempool, Q_strlen( s ) + 1, false, filename, fileline );
|
||||
Q_strcpy( b, s );
|
||||
|
||||
return b;
|
||||
}
|
||||
@@ -1100,6 +1066,7 @@ void *GAME_EXPORT pfnSequenceGet( const char *fileName, const char *entryName )
|
||||
{
|
||||
Msg( "Sequence_Get: file %s, entry %s\n", fileName, entryName );
|
||||
|
||||
|
||||
return Sequence_Get( fileName, entryName );
|
||||
}
|
||||
|
||||
|
||||
@@ -159,13 +159,13 @@ extern convar_t *scr_download;
|
||||
extern convar_t *cmd_scripting;
|
||||
extern convar_t *sv_maxclients;
|
||||
extern convar_t *cl_allow_levelshots;
|
||||
extern convar_t *vid_displayfrequency;
|
||||
extern convar_t host_developer;
|
||||
extern convar_t *host_limitlocal;
|
||||
extern convar_t *host_framerate;
|
||||
extern convar_t *host_maxfps;
|
||||
extern convar_t sys_timescale;
|
||||
extern convar_t cl_filterstuffcmd;
|
||||
extern convar_t rcon_password;
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
@@ -358,13 +358,14 @@ typedef struct host_parm_s
|
||||
qboolean allow_cheats; // this host will allow cheating
|
||||
qboolean con_showalways; // show console always (developer and dedicated)
|
||||
qboolean change_game; // initialize when game is changed
|
||||
qboolean mouse_visible; // vgui override cursor control (never change outside Platform_SetCursorType!)
|
||||
qboolean mouse_visible; // vgui override cursor control
|
||||
qboolean shutdown_issued; // engine is shutting down
|
||||
qboolean force_draw_version; // used when fraps is loaded
|
||||
float force_draw_version_time;
|
||||
qboolean apply_game_config; // when true apply only to game cvars and ignore all other commands
|
||||
qboolean apply_opengl_config;// when true apply only to opengl cvars and ignore all other commands
|
||||
qboolean config_executed; // a bit who indicated was config.cfg already executed e.g. from valve.rc
|
||||
int sv_cvars_restored; // count of restored server cvars
|
||||
qboolean crashed; // set to true if crashed
|
||||
qboolean daemonized;
|
||||
qboolean enabledll;
|
||||
@@ -393,11 +394,6 @@ typedef struct host_parm_s
|
||||
// bug compatibility level, for very "special" games
|
||||
bugcomp_t bugcomp;
|
||||
|
||||
// measure time to first frame
|
||||
double starttime;
|
||||
|
||||
// count of sleeps can be inserted between frames
|
||||
double pureframetime;
|
||||
} host_parm_t;
|
||||
|
||||
extern host_parm_t host;
|
||||
@@ -425,7 +421,6 @@ void FS_Shutdown( void );
|
||||
void Cbuf_Init( void );
|
||||
void Cbuf_Clear( void );
|
||||
void Cbuf_AddText( const char *text );
|
||||
void Cbuf_AddTextf( const char *text, ... ) _format( 1 );
|
||||
void Cbuf_AddFilteredText( const char *text );
|
||||
void Cbuf_InsertText( const char *text );
|
||||
void Cbuf_ExecStuffCmds( void );
|
||||
@@ -566,7 +561,6 @@ int FS_GetStreamPos( stream_t *stream );
|
||||
void FS_FreeStream( stream_t *stream );
|
||||
qboolean Sound_Process( wavdata_t **wav, int rate, int width, uint flags );
|
||||
uint Sound_GetApproxWavePlayLen( const char *filepath );
|
||||
qboolean Sound_SupportedFileFormat( const char *fileext );
|
||||
|
||||
//
|
||||
// host.c
|
||||
@@ -638,7 +632,6 @@ void COM_HexConvert( const char *pszInput, int nInputLength, byte *pOutput );
|
||||
int COM_SaveFile( const char *filename, const void *data, int len );
|
||||
byte* COM_LoadFileForMe( const char *filename, int *pLength );
|
||||
qboolean COM_IsSafeFileToDownload( const char *filename );
|
||||
const char *COM_GetResourceTypeName( resourcetype_t restype );
|
||||
cvar_t *pfnCVarGetPointer( const char *szVarName );
|
||||
int pfnDrawConsoleString( int x, int y, char *string );
|
||||
void pfnDrawSetTextColor( float r, float g, float b );
|
||||
@@ -746,6 +739,7 @@ char *CL_Userinfo( void );
|
||||
void CL_LegacyUpdateInfo( void );
|
||||
void CL_CharEvent( int key );
|
||||
qboolean CL_DisableVisibility( void );
|
||||
int CL_PointContents( const vec3_t point );
|
||||
byte *COM_LoadFile( const char *filename, int usehunk, int *pLength );
|
||||
int CL_GetDemoComment( const char *demoname, char *comment );
|
||||
void COM_AddAppDirectoryToSearchPath( const char *pszBaseDir, const char *appName );
|
||||
@@ -754,6 +748,7 @@ struct cmd_s *Cmd_GetFirstFunctionHandle( void );
|
||||
struct cmd_s *Cmd_GetNextFunctionHandle( struct cmd_s *cmd );
|
||||
struct cmdalias_s *Cmd_AliasGetList( void );
|
||||
const char *Cmd_GetName( struct cmd_s *cmd );
|
||||
struct pmtrace_s *PM_TraceLine( float *start, float *end, int flags, int usehull, int ignore_pe );
|
||||
void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float attn, int flags, int pitch );
|
||||
void SV_StartMusic( const char *curtrack, const char *looptrack, int position );
|
||||
void SV_CreateDecal( sizebuf_t *msg, const float *origin, int decalIndex, int entityIndex, int modelIndex, int flags, float scale );
|
||||
@@ -780,6 +775,8 @@ int SV_GetMaxClients( void );
|
||||
qboolean CL_IsRecordDemo( void );
|
||||
qboolean CL_IsTimeDemo( void );
|
||||
qboolean CL_IsPlaybackDemo( void );
|
||||
qboolean CL_IsBackgroundDemo( void );
|
||||
qboolean CL_IsBackgroundMap( void );
|
||||
qboolean SV_Initialized( void );
|
||||
qboolean CL_LoadProgs( const char *name );
|
||||
void CL_ProcessFile( qboolean successfully_received, const char *filename );
|
||||
@@ -819,7 +816,6 @@ const char *Info_ValueForKey( const char *s, const char *key );
|
||||
void Info_RemovePrefixedKeys( char *start, char prefix );
|
||||
qboolean Info_RemoveKey( char *s, const char *key );
|
||||
qboolean Info_SetValueForKey( char *s, const char *key, const char *value, int maxsize );
|
||||
qboolean Info_SetValueForKeyf( char *s, const char *key, int maxsize, const char *format, ... ) _format( 4 );
|
||||
qboolean Info_SetValueForStarKey( char *s, const char *key, const char *value, int maxsize );
|
||||
qboolean Info_IsValid( const char *s );
|
||||
void Info_WriteVars( file_t *f );
|
||||
@@ -845,7 +841,6 @@ void COM_NormalizeAngles( vec3_t angles );
|
||||
int COM_FileSize( const char *filename );
|
||||
void COM_FreeFile( void *buffer );
|
||||
int COM_CompareFileTime( const char *filename1, const char *filename2, int *iCompare );
|
||||
char *va( const char *format, ... ) _format( 1 );
|
||||
|
||||
// soundlib shared exports
|
||||
qboolean S_Init( void );
|
||||
@@ -858,6 +853,7 @@ void S_StopAllSounds( qboolean ambient );
|
||||
// gamma routines
|
||||
void BuildGammaTable( float gamma, float brightness );
|
||||
byte LightToTexGamma( byte b );
|
||||
byte TextureToGamma( byte b );
|
||||
|
||||
//
|
||||
// identification.c
|
||||
@@ -873,10 +869,6 @@ void NET_InitMasters( void );
|
||||
void NET_SaveMasters( void );
|
||||
qboolean NET_SendToMasters( netsrc_t sock, size_t len, const void *data );
|
||||
qboolean NET_IsMasterAdr( netadr_t adr );
|
||||
void NET_MasterHeartbeat( void );
|
||||
void NET_MasterClear( void );
|
||||
void NET_MasterShutdown( void );
|
||||
qboolean NET_GetMaster( netadr_t from, uint *challenge, double *last_heartbeat );
|
||||
|
||||
#ifdef REF_DLL
|
||||
#error "common.h in ref_dll"
|
||||
|
||||
@@ -80,9 +80,8 @@ int Cmd_ListMaps( search_t *t, char *lastmapname, size_t len )
|
||||
|
||||
if( f )
|
||||
{
|
||||
dheader_t *header;
|
||||
dheader_t *header;
|
||||
dextrahdr_t *hdrext;
|
||||
dlump_t entities;
|
||||
|
||||
memset( buf, 0, sizeof( buf ));
|
||||
FS_Read( f, buf, sizeof( buf ));
|
||||
@@ -90,10 +89,10 @@ int Cmd_ListMaps( search_t *t, char *lastmapname, size_t len )
|
||||
ver = header->version;
|
||||
|
||||
// check all the lumps and some other errors
|
||||
if( Mod_TestBmodelLumps( f, t->filenames[i], buf, true, &entities ))
|
||||
if( Mod_TestBmodelLumps( t->filenames[i], buf, true ))
|
||||
{
|
||||
lumpofs = entities.fileofs;
|
||||
lumplen = entities.filelen;
|
||||
lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
|
||||
lumplen = header->lumps[LUMP_ENTITIES].filelen;
|
||||
ver = header->version;
|
||||
}
|
||||
|
||||
@@ -101,7 +100,8 @@ int Cmd_ListMaps( search_t *t, char *lastmapname, size_t len )
|
||||
if( hdrext->id == IDEXTRAHEADER ) version = hdrext->version;
|
||||
|
||||
Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename ));
|
||||
COM_ReplaceExtension( entfilename, ".ent", sizeof( entfilename ));
|
||||
COM_StripExtension( entfilename );
|
||||
COM_DefaultExtension( entfilename, ".ent" );
|
||||
ents = (char *)FS_LoadFile( entfilename, NULL, true );
|
||||
|
||||
if( !ents && lumplen >= 10 )
|
||||
@@ -145,7 +145,7 @@ int Cmd_ListMaps( search_t *t, char *lastmapname, size_t len )
|
||||
}
|
||||
|
||||
if( f ) FS_Close(f);
|
||||
COM_FileBase( t->filenames[i], mapname, sizeof( mapname ));
|
||||
COM_FileBase( t->filenames[i], mapname );
|
||||
|
||||
switch( ver )
|
||||
{
|
||||
@@ -193,7 +193,7 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
|
||||
t = FS_Search( va( "maps/%s*.bsp", s ), true, con_gamemaps->value );
|
||||
if( !t ) return false;
|
||||
|
||||
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
|
||||
COM_FileBase( t->filenames[0], matchbuf );
|
||||
if( completedname && length )
|
||||
Q_strncpy( completedname, matchbuf, length );
|
||||
if( t->numfilenames == 1 ) return true;
|
||||
@@ -230,7 +230,7 @@ qboolean Cmd_GetDemoList( const char *s, char *completedname, int length )
|
||||
t = FS_Search( va( "%s*.dem", s ), true, true );
|
||||
if( !t ) return false;
|
||||
|
||||
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
|
||||
COM_FileBase( t->filenames[0], matchbuf );
|
||||
if( completedname && length )
|
||||
Q_strncpy( completedname, matchbuf, length );
|
||||
if( t->numfilenames == 1 ) return true;
|
||||
@@ -240,7 +240,7 @@ qboolean Cmd_GetDemoList( const char *s, char *completedname, int length )
|
||||
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "dem" ))
|
||||
continue;
|
||||
|
||||
COM_FileBase( t->filenames[i], matchbuf, sizeof( matchbuf ));
|
||||
COM_FileBase( t->filenames[i], matchbuf );
|
||||
Con_Printf( "%16s\n", matchbuf );
|
||||
numdems++;
|
||||
}
|
||||
@@ -276,7 +276,7 @@ qboolean Cmd_GetMovieList( const char *s, char *completedname, int length )
|
||||
t = FS_Search( va( "media/%s*.avi", s ), true, false );
|
||||
if( !t ) return false;
|
||||
|
||||
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
|
||||
COM_FileBase( t->filenames[0], matchbuf );
|
||||
if( completedname && length )
|
||||
Q_strncpy( completedname, matchbuf, length );
|
||||
if( t->numfilenames == 1 ) return true;
|
||||
@@ -286,7 +286,7 @@ qboolean Cmd_GetMovieList( const char *s, char *completedname, int length )
|
||||
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "avi" ))
|
||||
continue;
|
||||
|
||||
COM_FileBase( t->filenames[i], matchbuf, sizeof( matchbuf ));
|
||||
COM_FileBase( t->filenames[i], matchbuf );
|
||||
Con_Printf( "%16s\n", matchbuf );
|
||||
nummovies++;
|
||||
}
|
||||
@@ -323,7 +323,7 @@ qboolean Cmd_GetMusicList( const char *s, char *completedname, int length )
|
||||
t = FS_Search( va( "media/%s*.*", s ), true, false );
|
||||
if( !t ) return false;
|
||||
|
||||
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
|
||||
COM_FileBase( t->filenames[0], matchbuf );
|
||||
if( completedname && length )
|
||||
Q_strncpy( completedname, matchbuf, length );
|
||||
if( t->numfilenames == 1 ) return true;
|
||||
@@ -335,7 +335,7 @@ qboolean Cmd_GetMusicList( const char *s, char *completedname, int length )
|
||||
if( Q_stricmp( ext, "wav" ) && Q_stricmp( ext, "mp3" ))
|
||||
continue;
|
||||
|
||||
COM_FileBase( t->filenames[i], matchbuf, sizeof( matchbuf ));
|
||||
COM_FileBase( t->filenames[i], matchbuf );
|
||||
Con_Printf( "%16s\n", matchbuf );
|
||||
numtracks++;
|
||||
}
|
||||
@@ -368,10 +368,10 @@ qboolean Cmd_GetSavesList( const char *s, char *completedname, int length )
|
||||
string matchbuf;
|
||||
int i, numsaves;
|
||||
|
||||
t = FS_Search( va( DEFAULT_SAVE_DIRECTORY "%s*.sav", s ), true, true ); // lookup only in gamedir
|
||||
t = FS_Search( va( "%s%s*.sav", DEFAULT_SAVE_DIRECTORY, s ), true, true ); // lookup only in gamedir
|
||||
if( !t ) return false;
|
||||
|
||||
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
|
||||
COM_FileBase( t->filenames[0], matchbuf );
|
||||
if( completedname && length )
|
||||
Q_strncpy( completedname, matchbuf, length );
|
||||
if( t->numfilenames == 1 ) return true;
|
||||
@@ -381,7 +381,7 @@ qboolean Cmd_GetSavesList( const char *s, char *completedname, int length )
|
||||
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "sav" ))
|
||||
continue;
|
||||
|
||||
COM_FileBase( t->filenames[i], matchbuf, sizeof( matchbuf ));
|
||||
COM_FileBase( t->filenames[i], matchbuf );
|
||||
Con_Printf( "%16s\n", matchbuf );
|
||||
numsaves++;
|
||||
}
|
||||
@@ -418,7 +418,7 @@ qboolean Cmd_GetConfigList( const char *s, char *completedname, int length )
|
||||
t = FS_Search( va( "%s*.cfg", s ), true, false );
|
||||
if( !t ) return false;
|
||||
|
||||
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
|
||||
COM_FileBase( t->filenames[0], matchbuf );
|
||||
if( completedname && length )
|
||||
Q_strncpy( completedname, matchbuf, length );
|
||||
if( t->numfilenames == 1 ) return true;
|
||||
@@ -428,7 +428,7 @@ qboolean Cmd_GetConfigList( const char *s, char *completedname, int length )
|
||||
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "cfg" ))
|
||||
continue;
|
||||
|
||||
COM_FileBase( t->filenames[i], matchbuf, sizeof( matchbuf ));
|
||||
COM_FileBase( t->filenames[i], matchbuf );
|
||||
Con_Printf( "%16s\n", matchbuf );
|
||||
numconfigs++;
|
||||
}
|
||||
@@ -518,7 +518,7 @@ qboolean Cmd_GetItemsList( const char *s, char *completedname, int length )
|
||||
t = FS_Search( va( "%s/%s*.txt", clgame.itemspath, s ), true, false );
|
||||
if( !t ) return false;
|
||||
|
||||
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
|
||||
COM_FileBase( t->filenames[0], matchbuf );
|
||||
if( completedname && length )
|
||||
Q_strncpy( completedname, matchbuf, length );
|
||||
if( t->numfilenames == 1 ) return true;
|
||||
@@ -528,7 +528,7 @@ qboolean Cmd_GetItemsList( const char *s, char *completedname, int length )
|
||||
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "txt" ))
|
||||
continue;
|
||||
|
||||
COM_FileBase( t->filenames[i], matchbuf, sizeof( matchbuf ));
|
||||
COM_FileBase( t->filenames[i], matchbuf );
|
||||
Con_Printf( "%16s\n", matchbuf );
|
||||
numitems++;
|
||||
}
|
||||
@@ -570,7 +570,7 @@ qboolean Cmd_GetKeysList( const char *s, char *completedname, int length )
|
||||
const char *keyname = Key_KeynumToString( i );
|
||||
|
||||
if(( *s == '*' ) || !Q_strnicmp( keyname, s, len))
|
||||
Q_strncpy( keys[numkeys++], keyname, sizeof( keys[0] ));
|
||||
Q_strcpy( keys[numkeys++], keyname );
|
||||
}
|
||||
|
||||
if( !numkeys ) return false;
|
||||
@@ -710,7 +710,7 @@ qboolean Cmd_GetCustomList( const char *s, char *completedname, int length )
|
||||
t = FS_Search( va( "%s*.hpk", s ), true, false );
|
||||
if( !t ) return false;
|
||||
|
||||
COM_FileBase( t->filenames[0], matchbuf, sizeof( matchbuf ));
|
||||
COM_FileBase( t->filenames[0], matchbuf );
|
||||
if( completedname && length )
|
||||
Q_strncpy( completedname, matchbuf, length );
|
||||
if( t->numfilenames == 1 ) return true;
|
||||
@@ -720,7 +720,7 @@ qboolean Cmd_GetCustomList( const char *s, char *completedname, int length )
|
||||
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "hpk" ))
|
||||
continue;
|
||||
|
||||
COM_FileBase( t->filenames[i], matchbuf, sizeof( matchbuf ));
|
||||
COM_FileBase( t->filenames[i], matchbuf );
|
||||
Con_Printf( "%16s\n", matchbuf );
|
||||
numitems++;
|
||||
}
|
||||
@@ -764,7 +764,7 @@ qboolean Cmd_GetGamesList( const char *s, char *completedname, int length )
|
||||
for( i = 0, numgamedirs = 0; i < FI->numgames; i++ )
|
||||
{
|
||||
if(( *s == '*' ) || !Q_strnicmp( FI->games[i]->gamefolder, s, len))
|
||||
Q_strncpy( gamedirs[numgamedirs++], FI->games[i]->gamefolder, sizeof( gamedirs[0] ));
|
||||
Q_strcpy( gamedirs[numgamedirs++], FI->games[i]->gamefolder );
|
||||
}
|
||||
|
||||
if( !numgamedirs ) return false;
|
||||
@@ -825,7 +825,7 @@ qboolean Cmd_GetCDList( const char *s, char *completedname, int length )
|
||||
for( i = 0, numcdcommands = 0; i < 8; i++ )
|
||||
{
|
||||
if(( *s == '*' ) || !Q_strnicmp( cd_command[i], s, len))
|
||||
Q_strncpy( cdcommands[numcdcommands++], cd_command[i], sizeof( cdcommands[0] ));
|
||||
Q_strcpy( cdcommands[numcdcommands++], cd_command[i] );
|
||||
}
|
||||
|
||||
if( !numcdcommands ) return false;
|
||||
@@ -860,7 +860,6 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
|
||||
byte buf[MAX_SYSPATH];
|
||||
string mpfilter;
|
||||
char *buffer;
|
||||
size_t buffersize;
|
||||
string result;
|
||||
int i, size;
|
||||
search_t *t;
|
||||
@@ -883,8 +882,7 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
|
||||
return false;
|
||||
}
|
||||
|
||||
buffersize = t->numfilenames * 2 * sizeof( result );
|
||||
buffer = Mem_Calloc( host.mempool, buffersize );
|
||||
buffer = Mem_Calloc( host.mempool, t->numfilenames * 2 * sizeof( result ));
|
||||
use_filter = COM_CheckStringEmpty( GI->mp_filter ) ? true : false;
|
||||
|
||||
for( i = 0; i < t->numfilenames; i++ )
|
||||
@@ -900,31 +898,31 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
|
||||
continue;
|
||||
|
||||
f = FS_Open( t->filenames[i], "rb", onlyingamedir );
|
||||
COM_FileBase( t->filenames[i], mapname, sizeof( mapname ));
|
||||
COM_FileBase( t->filenames[i], mapname );
|
||||
|
||||
if( f )
|
||||
{
|
||||
int num_spawnpoints = 0;
|
||||
dheader_t *header;
|
||||
dlump_t entities;
|
||||
|
||||
memset( buf, 0, MAX_SYSPATH );
|
||||
FS_Read( f, buf, MAX_SYSPATH );
|
||||
header = (dheader_t *)buf;
|
||||
|
||||
// check all the lumps and some other errors
|
||||
if( !Mod_TestBmodelLumps( f, t->filenames[i], buf, true, &entities ))
|
||||
if( !Mod_TestBmodelLumps( t->filenames[i], buf, true ))
|
||||
{
|
||||
FS_Close( f );
|
||||
continue;
|
||||
}
|
||||
|
||||
// after call Mod_TestBmodelLumps we gurantee what map is valid
|
||||
lumpofs = entities.fileofs;
|
||||
lumplen = entities.filelen;
|
||||
lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
|
||||
lumplen = header->lumps[LUMP_ENTITIES].filelen;
|
||||
|
||||
Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename ));
|
||||
COM_ReplaceExtension( entfilename, ".ent", sizeof( entfilename ));
|
||||
COM_StripExtension( entfilename );
|
||||
COM_DefaultExtension( entfilename, ".ent" );
|
||||
ents = (char *)FS_LoadFile( entfilename, NULL, true );
|
||||
|
||||
if( !ents && lumplen >= 10 )
|
||||
@@ -969,8 +967,8 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
|
||||
if( num_spawnpoints )
|
||||
{
|
||||
// format: mapname "maptitle"\n
|
||||
Q_snprintf( result, sizeof( result ), "%s \"%s\"\n", mapname, message );
|
||||
Q_strncat( buffer, result, buffersize ); // add new string
|
||||
Q_sprintf( result, "%s \"%s\"\n", mapname, message );
|
||||
Q_strcat( buffer, result ); // add new string
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1029,7 +1027,6 @@ autocomplete_list_t cmd_list[] =
|
||||
{ "play", 1, Cmd_GetSoundList },
|
||||
{ "map", 1, Cmd_GetMapList },
|
||||
{ "cd", 1, Cmd_GetCDList },
|
||||
{ "mp3", 1, Cmd_GetCDList },
|
||||
{ NULL }, // termiantor
|
||||
};
|
||||
|
||||
@@ -1042,14 +1039,10 @@ compare first argument with string
|
||||
*/
|
||||
static qboolean Cmd_CheckName( const char *name )
|
||||
{
|
||||
const char *p = Cmd_Argv( 0 );
|
||||
|
||||
if( !Q_stricmp( p, name ))
|
||||
if( !Q_stricmp( Cmd_Argv( 0 ), name ))
|
||||
return true;
|
||||
|
||||
if( p[0] == '\\' && !Q_stricmp( &p[1], name ))
|
||||
if( !Q_stricmp( Cmd_Argv( 0 ), va( "\\%s", name )))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1331,9 +1324,8 @@ static void Cmd_WriteHelp(const char *name, const char *unused, const char *desc
|
||||
{
|
||||
int length;
|
||||
|
||||
if( !COM_CheckString( desc ))
|
||||
if( !desc || !Q_strcmp( desc, "" ))
|
||||
return; // ignore fantom cmds
|
||||
|
||||
if( name[0] == '+' || name[0] == '-' )
|
||||
return; // key bindings
|
||||
|
||||
@@ -1362,6 +1354,7 @@ void Host_FinalizeConfig( file_t *f, const char *config )
|
||||
FS_Close( f );
|
||||
FS_Delete( backup );
|
||||
FS_Rename( config, backup );
|
||||
FS_Delete( config );
|
||||
FS_Rename( newcfg, config );
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,7 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
|
||||
@@ -25,16 +23,15 @@ Sys_Crash
|
||||
Crash handler, called from system
|
||||
================
|
||||
*/
|
||||
#if XASH_WIN32
|
||||
#if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP || XASH_CRASHHANDLER == CRASHHANDLER_WIN32
|
||||
|
||||
#if DBGHELP
|
||||
#if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP
|
||||
|
||||
#pragma comment( lib, "dbghelp" )
|
||||
|
||||
#include <winnt.h>
|
||||
#include <dbghelp.h>
|
||||
#include <psapi.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifndef XASH_SDL
|
||||
typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
|
||||
@@ -190,65 +187,7 @@ static void Sys_StackTrace( PEXCEPTION_POINTERS pInfo )
|
||||
|
||||
SymCleanup( process );
|
||||
}
|
||||
|
||||
static void Sys_GetProcessName( char *processName, size_t bufferSize )
|
||||
{
|
||||
char fullpath[MAX_PATH];
|
||||
|
||||
GetModuleBaseName( GetCurrentProcess(), NULL, fullpath, sizeof( fullpath ) - 1 );
|
||||
COM_FileBase( fullpath, processName, bufferSize );
|
||||
}
|
||||
|
||||
static void Sys_GetMinidumpFileName( const char *processName, char *mdmpFileName, size_t bufferSize )
|
||||
{
|
||||
time_t currentUtcTime = time( NULL );
|
||||
struct tm *currentLocalTime = localtime( ¤tUtcTime );
|
||||
|
||||
Q_snprintf( mdmpFileName, bufferSize, "%s_%s_crash_%d%.2d%.2d_%.2d%.2d%.2d.mdmp",
|
||||
processName,
|
||||
Q_buildcommit(),
|
||||
currentLocalTime->tm_year + 1900,
|
||||
currentLocalTime->tm_mon + 1,
|
||||
currentLocalTime->tm_mday,
|
||||
currentLocalTime->tm_hour,
|
||||
currentLocalTime->tm_min,
|
||||
currentLocalTime->tm_sec);
|
||||
}
|
||||
|
||||
static qboolean Sys_WriteMinidump(PEXCEPTION_POINTERS exceptionInfo, MINIDUMP_TYPE minidumpType)
|
||||
{
|
||||
HRESULT errorCode;
|
||||
string processName;
|
||||
string mdmpFileName;
|
||||
MINIDUMP_EXCEPTION_INFORMATION minidumpInfo;
|
||||
|
||||
Sys_GetProcessName( processName, sizeof( processName ));
|
||||
Sys_GetMinidumpFileName( processName, mdmpFileName, sizeof( mdmpFileName ));
|
||||
|
||||
SetLastError( NOERROR );
|
||||
HANDLE fileHandle = CreateFile(
|
||||
mdmpFileName, GENERIC_WRITE, FILE_SHARE_WRITE,
|
||||
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
errorCode = HRESULT_FROM_WIN32( GetLastError( ));
|
||||
if( !SUCCEEDED( errorCode )) {
|
||||
CloseHandle( fileHandle );
|
||||
return false;
|
||||
}
|
||||
|
||||
minidumpInfo.ThreadId = GetCurrentThreadId();
|
||||
minidumpInfo.ExceptionPointers = exceptionInfo;
|
||||
minidumpInfo.ClientPointers = FALSE;
|
||||
|
||||
qboolean status = MiniDumpWriteDump(
|
||||
GetCurrentProcess(), GetCurrentProcessId(), fileHandle,
|
||||
minidumpType, &minidumpInfo, NULL, NULL);
|
||||
|
||||
CloseHandle( fileHandle );
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* DBGHELP */
|
||||
#endif /* XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP */
|
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER oldFilter;
|
||||
static long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
|
||||
@@ -259,7 +198,7 @@ static long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
|
||||
// check to avoid recursive call
|
||||
host.crashed = true;
|
||||
|
||||
#if DBGHELP
|
||||
#if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP
|
||||
Sys_StackTrace( pInfo );
|
||||
#else
|
||||
Sys_Warn( "Sys_Crash: call %p at address %p", pInfo->ExceptionRecord->ExceptionAddress, pInfo->ExceptionRecord->ExceptionCode );
|
||||
@@ -269,26 +208,6 @@ static long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
|
||||
CL_Crashed(); // tell client about crash
|
||||
else host.status = HOST_CRASHED;
|
||||
|
||||
#if DBGHELP
|
||||
if( Sys_CheckParm( "-minidumps" ))
|
||||
{
|
||||
int minidumpFlags = (
|
||||
MiniDumpWithDataSegs |
|
||||
MiniDumpWithCodeSegs |
|
||||
MiniDumpWithHandleData |
|
||||
MiniDumpWithFullMemory |
|
||||
MiniDumpWithFullMemoryInfo |
|
||||
MiniDumpWithIndirectlyReferencedMemory |
|
||||
MiniDumpWithThreadInfo |
|
||||
MiniDumpWithModuleHeaders);
|
||||
|
||||
if( !Sys_WriteMinidump( pInfo, (MINIDUMP_TYPE)minidumpFlags )) {
|
||||
// fallback method, create minidump with minimal info in it
|
||||
Sys_WriteMinidump( pInfo, MiniDumpWithDataSegs );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( host_developer.value <= 0 )
|
||||
{
|
||||
// no reason to call debugger in release build - just exit
|
||||
@@ -318,21 +237,21 @@ void Sys_RestoreCrashHandler( void )
|
||||
if( oldFilter ) SetUnhandledExceptionFilter( oldFilter );
|
||||
}
|
||||
|
||||
#elif XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX
|
||||
#elif XASH_CRASHHANDLER == CRASHHANDLER_UCONTEXT
|
||||
// Posix signal handler
|
||||
#include <ucontext.h>
|
||||
#include <signal.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "library.h"
|
||||
|
||||
#define STACK_BACKTRACE_STR "Stack backtrace:\n"
|
||||
#define STACK_DUMP_STR "Stack dump:\n"
|
||||
#if XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX
|
||||
#define HAVE_UCONTEXT_H 1
|
||||
#endif
|
||||
|
||||
#define STACK_BACKTRACE_STR_LEN ( sizeof( STACK_BACKTRACE_STR ) - 1 )
|
||||
#define STACK_DUMP_STR_LEN ( sizeof( STACK_DUMP_STR ) - 1 )
|
||||
#define ALIGN( x, y ) (((uintptr_t) ( x ) + (( y ) - 1 )) & ~(( y ) - 1 ))
|
||||
#ifdef HAVE_UCONTEXT_H
|
||||
#include <ucontext.h>
|
||||
#endif
|
||||
|
||||
static struct sigaction oldFilter;
|
||||
#include <signal.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#ifdef XASH_DYNAMIC_DLADDR
|
||||
static int d_dladdr( void *sym, Dl_info *info )
|
||||
@@ -363,18 +282,28 @@ static int Sys_PrintFrame( char *buf, int len, int i, void *addr )
|
||||
if( dlinfo.dli_sname )
|
||||
return Q_snprintf( buf, len, "%2d: %p <%s+%lu> (%s)\n", i, addr, dlinfo.dli_sname,
|
||||
(unsigned long)addr - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname ); // print symbol, module and address
|
||||
|
||||
return Q_snprintf( buf, len, "%2d: %p (%s)\n", i, addr, dlinfo.dli_fname ); // print module and address
|
||||
else
|
||||
return Q_snprintf( buf, len, "%2d: %p (%s)\n", i, addr, dlinfo.dli_fname ); // print module and address
|
||||
}
|
||||
|
||||
return Q_snprintf( buf, len, "%2d: %p\n", i, addr ); // print only address
|
||||
else
|
||||
return Q_snprintf( buf, len, "%2d: %p\n", i, addr ); // print only address
|
||||
}
|
||||
|
||||
struct sigaction oldFilter;
|
||||
|
||||
#define STACK_BACKTRACE_STR "Stack backtrace:\n"
|
||||
#define STACK_DUMP_STR "Stack dump:\n"
|
||||
|
||||
#define STACK_BACKTRACE_STR_LEN (sizeof( STACK_BACKTRACE_STR ) - 1)
|
||||
#define STACK_DUMP_STR_LEN (sizeof( STACK_DUMP_STR ) - 1)
|
||||
#define ALIGN( x, y ) (((uintptr_t) (x) + ((y)-1)) & ~((y)-1))
|
||||
|
||||
static void Sys_Crash( int signal, siginfo_t *si, void *context)
|
||||
{
|
||||
void *pc = NULL, **bp = NULL, **sp = NULL; // this must be set for every OS!
|
||||
char message[8192];
|
||||
int len, logfd, i = 0;
|
||||
size_t pagesize;
|
||||
|
||||
#if XASH_OPENBSD
|
||||
struct sigcontext *ucontext = (struct sigcontext*)context;
|
||||
@@ -429,10 +358,10 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
|
||||
#endif
|
||||
|
||||
// safe actions first, stack and memory may be corrupted
|
||||
len = Q_snprintf( message, sizeof( message ), "Ver: " XASH_ENGINE_NAME " " XASH_VERSION " (build %i-%s, %s-%s)\n",
|
||||
Q_buildnum(), Q_buildcommit(), Q_buildos(), Q_buildarch() );
|
||||
len = Q_snprintf( message, sizeof( message ), "Ver: %s %s (build %i-%s, %s-%s)\n",
|
||||
XASH_ENGINE_NAME, XASH_VERSION, Q_buildnum(), Q_buildcommit(), Q_buildos(), Q_buildarch() );
|
||||
|
||||
#if !XASH_FREEBSD && !XASH_NETBSD && !XASH_OPENBSD
|
||||
#if !XASH_BSD
|
||||
len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p %p\n", signal, si->si_errno, si->si_code, si->si_addr, si->si_ptr );
|
||||
#else
|
||||
len += Q_snprintf( message + len, sizeof( message ) - len, "Crash: signal %d errno %d with code %d at %p\n", signal, si->si_errno, si->si_code, si->si_addr );
|
||||
@@ -451,7 +380,6 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
|
||||
if( pc && bp && sp )
|
||||
{
|
||||
size_t pagesize = sysconf( _SC_PAGESIZE );
|
||||
|
||||
// try to print backtrace
|
||||
write( STDERR_FILENO, STACK_BACKTRACE_STR, STACK_BACKTRACE_STR_LEN );
|
||||
write( logfd, STACK_BACKTRACE_STR, STACK_BACKTRACE_STR_LEN );
|
||||
@@ -519,7 +447,7 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
|
||||
|
||||
void Sys_SetupCrashHandler( void )
|
||||
{
|
||||
struct sigaction act = { 0 };
|
||||
struct sigaction act;
|
||||
act.sa_sigaction = Sys_Crash;
|
||||
act.sa_flags = SA_SIGINFO | SA_ONSTACK;
|
||||
sigaction( SIGSEGV, &act, &oldFilter );
|
||||
@@ -536,7 +464,7 @@ void Sys_RestoreCrashHandler( void )
|
||||
sigaction( SIGILL, &oldFilter, NULL );
|
||||
}
|
||||
|
||||
#else
|
||||
#elif XASH_CRASHHANDLER == CRASHHANDLER_NULL
|
||||
|
||||
void Sys_SetupCrashHandler( void )
|
||||
{
|
||||
|
||||
@@ -17,23 +17,9 @@ GNU General Public License for more details.
|
||||
#include "custom.h"
|
||||
#include "ref_common.h"
|
||||
|
||||
static rgbdata_t *CustomDecal_LoadImage( const char *path, void *raw, int size )
|
||||
qboolean CustomDecal_Validate( void *raw, int nFileSize )
|
||||
{
|
||||
const char *testname;
|
||||
|
||||
// this way we limit file types
|
||||
if( !Q_stricmp( COM_FileExtension( path ), "png" ))
|
||||
testname = "#logo.png";
|
||||
else testname = "#logo.bmp";
|
||||
|
||||
Image_SetForceFlags( IL_LOAD_PLAYER_DECAL );
|
||||
|
||||
return FS_LoadImage( testname, raw, size );
|
||||
}
|
||||
|
||||
static qboolean CustomDecal_Validate( const char *path, void *raw, int nFileSize )
|
||||
{
|
||||
rgbdata_t *test = CustomDecal_LoadImage( path, raw, nFileSize );
|
||||
rgbdata_t *test = FS_LoadImage( "#logo.bmp", raw, nFileSize );
|
||||
|
||||
if( test )
|
||||
{
|
||||
@@ -111,25 +97,21 @@ qboolean COM_CreateCustomization( customization_t *pListHead, resource_t *pResou
|
||||
{
|
||||
pCust->resource.playernum = playernumber;
|
||||
|
||||
if( CustomDecal_Validate( pResource->szFileName, pCust->pBuffer, pResource->nDownloadSize ))
|
||||
if( CustomDecal_Validate( pCust->pBuffer, pResource->nDownloadSize ))
|
||||
{
|
||||
if( !FBitSet( flags, FCUST_IGNOREINIT ))
|
||||
{
|
||||
if( pResource->nDownloadSize >= (1 * 1024) && pResource->nDownloadSize <= ( 128 * 1024 ))
|
||||
if( pResource->nDownloadSize >= (1 * 1024) && pResource->nDownloadSize <= ( 16 * 1024 ))
|
||||
{
|
||||
pCust->bTranslated = true;
|
||||
pCust->nUserData1 = 0;
|
||||
pCust->nUserData2 = 1;
|
||||
|
||||
if( !FBitSet( flags, FCUST_WIPEDATA ))
|
||||
pCust->pInfo = CustomDecal_LoadImage( pResource->szFileName, pCust->pBuffer, pCust->resource.nDownloadSize );
|
||||
pCust->pInfo = FS_LoadImage( "#logo.bmp", pCust->pBuffer, pCust->resource.nDownloadSize );
|
||||
else pCust->pInfo = NULL;
|
||||
if( nLumps ) *nLumps = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf( S_WARN "Ignoring custom decal \"%s\": wrong size (%i bytes)\n", pResource->szFileName, pResource->nDownloadSize );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,34 +21,7 @@ GNU General Public License for more details.
|
||||
convar_t *cvar_vars = NULL; // head of list
|
||||
convar_t *cmd_scripting;
|
||||
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
typedef struct cvar_filter_quirks_s
|
||||
{
|
||||
const char *gamedir; // gamedir to enable for
|
||||
const char *cvars; // list of cvars should be excluded from filter
|
||||
} cvar_filter_quirks_t;
|
||||
|
||||
static cvar_filter_quirks_t cvar_filter_quirks[] =
|
||||
{
|
||||
// EXAMPLE:
|
||||
//{
|
||||
// "valve",
|
||||
// "test;test1;test100"
|
||||
//},
|
||||
{
|
||||
"ricochet",
|
||||
"r_drawviewmodel",
|
||||
},
|
||||
{
|
||||
"dod",
|
||||
"cl_dodmusic" // Day of Defeat Beta 1.3 cvar
|
||||
},
|
||||
};
|
||||
|
||||
static cvar_filter_quirks_t *cvar_active_filter_quirks = NULL;
|
||||
#endif
|
||||
|
||||
CVAR_DEFINE_AUTO( cl_filterstuffcmd, "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "filter commands coming from server" );
|
||||
CVAR_DEFINE_AUTO( cl_filterstuffcmd, "0", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "filter commands coming from server" );
|
||||
|
||||
/*
|
||||
============
|
||||
@@ -99,16 +72,10 @@ Cvar_BuildAutoDescription
|
||||
build cvar auto description that based on the setup flags
|
||||
============
|
||||
*/
|
||||
const char *Cvar_BuildAutoDescription( const char *szName, int flags )
|
||||
const char *Cvar_BuildAutoDescription( int flags )
|
||||
{
|
||||
static char desc[256];
|
||||
|
||||
if( FBitSet( flags, FCVAR_GLCONFIG ))
|
||||
{
|
||||
Q_snprintf( desc, sizeof( desc ), CVAR_GLCONFIG_DESCRIPTION, szName );
|
||||
return desc;
|
||||
}
|
||||
|
||||
desc[0] = '\0';
|
||||
|
||||
if( FBitSet( flags, FCVAR_EXTDLL ))
|
||||
@@ -253,24 +220,6 @@ const char *Cvar_ValidateString( convar_t *var, const char *value )
|
||||
return pszValue;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_ValidateVarName
|
||||
============
|
||||
*/
|
||||
static qboolean Cvar_ValidateVarName( const char *s, qboolean isvalue )
|
||||
{
|
||||
if( !s )
|
||||
return false;
|
||||
if( Q_strchr( s, '\\' ) && !isvalue )
|
||||
return false;
|
||||
if( Q_strchr( s, '\"' ))
|
||||
return false;
|
||||
if( Q_strchr( s, ';' ) && !isvalue )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_UnlinkVar
|
||||
@@ -419,7 +368,7 @@ convar_t *Cvar_Get( const char *name, const char *value, int flags, const char *
|
||||
// which executed from the config file. So we don't need to
|
||||
// change value here: we *already* have actual value from config.
|
||||
// in other cases we need to rewrite them
|
||||
if( COM_CheckStringEmpty( var->desc ))
|
||||
if( Q_strcmp( var->desc, "" ))
|
||||
{
|
||||
// directly set value
|
||||
freestring( var->string );
|
||||
@@ -479,23 +428,6 @@ convar_t *Cvar_Get( const char *name, const char *value, int flags, const char *
|
||||
return var;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_Getf
|
||||
============
|
||||
*/
|
||||
convar_t *Cvar_Getf( const char *var_name, int flags, const char *description, const char *format, ... )
|
||||
{
|
||||
char value[MAX_VA_STRING];
|
||||
va_list args;
|
||||
|
||||
va_start( args, format );
|
||||
Q_vsnprintf( value, sizeof( value ), format, args );
|
||||
va_end( args );
|
||||
|
||||
return Cvar_Get( var_name, value, flags, description );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_RegisterVariable
|
||||
@@ -563,113 +495,6 @@ void Cvar_RegisterVariable( convar_t *var )
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_Set2
|
||||
============
|
||||
*/
|
||||
static convar_t *Cvar_Set2( const char *var_name, const char *value )
|
||||
{
|
||||
convar_t *var;
|
||||
const char *pszValue;
|
||||
qboolean dll_variable = false;
|
||||
qboolean force = false;
|
||||
|
||||
if( !Cvar_ValidateVarName( var_name, false ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Invalid cvar name string: %s\n", var_name );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
var = Cvar_FindVar( var_name );
|
||||
if( !var )
|
||||
{
|
||||
// if cvar not found, create it
|
||||
return Cvar_Get( var_name, value, FCVAR_USER_CREATED, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !Cmd_CurrentCommandIsPrivileged( ))
|
||||
{
|
||||
if( FBitSet( var->flags, FCVAR_PRIVILEGED ))
|
||||
{
|
||||
Con_Printf( "%s is priveleged.\n", var->name );
|
||||
return var;
|
||||
}
|
||||
|
||||
if( cl_filterstuffcmd.value > 0.0f && FBitSet( var->flags, FCVAR_FILTERABLE ))
|
||||
{
|
||||
Con_Printf( "%s is filterable.\n", var->name );
|
||||
return var;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// use this check to prevent acessing for unexisting fields
|
||||
// for cvar_t: latched_string, description, etc
|
||||
dll_variable = FBitSet( var->flags, FCVAR_EXTDLL );
|
||||
|
||||
// check value
|
||||
if( !value )
|
||||
{
|
||||
if( !FBitSet( var->flags, FCVAR_EXTENDED|FCVAR_ALLOCATED ))
|
||||
{
|
||||
Con_Printf( "%s has no default value and can't be reset.\n", var->name );
|
||||
return var;
|
||||
}
|
||||
|
||||
if( dll_variable )
|
||||
value = "0";
|
||||
else
|
||||
value = var->def_string; // reset to default value
|
||||
}
|
||||
|
||||
if( !Q_strcmp( value, var->string ))
|
||||
return var;
|
||||
|
||||
// any latched values not allowed for game cvars
|
||||
if( dll_variable )
|
||||
force = true;
|
||||
|
||||
if( !force )
|
||||
{
|
||||
if( FBitSet( var->flags, FCVAR_READ_ONLY ))
|
||||
{
|
||||
Con_Printf( "%s is read-only.\n", var->name );
|
||||
return var;
|
||||
}
|
||||
|
||||
if( FBitSet( var->flags, FCVAR_CHEAT ) && !host.allow_cheats )
|
||||
{
|
||||
Con_Printf( "%s is cheat protected.\n", var->name );
|
||||
return var;
|
||||
}
|
||||
|
||||
// just tell user about deferred changes
|
||||
if( FBitSet( var->flags, FCVAR_LATCH ) && ( SV_Active() || CL_Active( )))
|
||||
Con_Printf( "%s will be changed upon restarting.\n", var->name );
|
||||
}
|
||||
|
||||
pszValue = Cvar_ValidateString( var, value );
|
||||
|
||||
// nothing to change
|
||||
if( !Q_strcmp( pszValue, var->string ))
|
||||
return var;
|
||||
|
||||
// fill it cls.userinfo, svs.serverinfo
|
||||
if( !Cvar_UpdateInfo( var, pszValue, true ))
|
||||
return var;
|
||||
|
||||
// and finally changed the cvar itself
|
||||
freestring( var->string );
|
||||
var->string = copystring( pszValue );
|
||||
var->value = Q_atof( var->string );
|
||||
|
||||
// tell engine about changes
|
||||
Cvar_Changed( var );
|
||||
return var;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_DirectSet
|
||||
@@ -952,39 +777,6 @@ static qboolean Cvar_ShouldSetCvar( convar_t *v, qboolean isPrivileged )
|
||||
if( cl_filterstuffcmd.value <= 0.0f )
|
||||
return true;
|
||||
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
// check if game-specific filter exceptions should be applied
|
||||
// TODO: for cmd exceptions, make generic function
|
||||
if( cvar_active_filter_quirks )
|
||||
{
|
||||
const char *cur, *next;
|
||||
|
||||
cur = cvar_active_filter_quirks->cvars;
|
||||
next = Q_strchr( cur, ';' );
|
||||
|
||||
// TODO: implement Q_strchrnul
|
||||
while( cur && *cur )
|
||||
{
|
||||
size_t len = next ? next - cur : Q_strlen( cur );
|
||||
|
||||
// found, quit
|
||||
if( !Q_strnicmp( cur, v->name, len ))
|
||||
return true;
|
||||
|
||||
if( next )
|
||||
{
|
||||
cur = next + 1;
|
||||
next = Q_strchr( cur, ';' );
|
||||
}
|
||||
else
|
||||
{
|
||||
// stop
|
||||
cur = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( FBitSet( v->flags, FCVAR_FILTERABLE ))
|
||||
return false;
|
||||
|
||||
@@ -1048,6 +840,8 @@ qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged )
|
||||
else
|
||||
{
|
||||
Cvar_DirectSet( v, Cmd_Argv( 1 ));
|
||||
if( host.apply_game_config )
|
||||
host.sv_cvars_restored++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1090,41 +884,7 @@ void Cvar_Toggle_f( void )
|
||||
|
||||
v = !Cvar_VariableInteger( Cmd_Argv( 1 ));
|
||||
|
||||
Cvar_Set( Cmd_Argv( 1 ), v ? "1" : "0" );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_Set_f
|
||||
|
||||
Allows setting and defining of arbitrary cvars from console, even if they
|
||||
weren't declared in C code.
|
||||
============
|
||||
*/
|
||||
void Cvar_Set_f( void )
|
||||
{
|
||||
int i, c, l = 0, len;
|
||||
char combined[MAX_CMD_TOKENS];
|
||||
|
||||
c = Cmd_Argc();
|
||||
if( c < 3 )
|
||||
{
|
||||
Msg( S_USAGE "set <variable> <value>\n" );
|
||||
return;
|
||||
}
|
||||
combined[0] = 0;
|
||||
|
||||
for( i = 2; i < c; i++ )
|
||||
{
|
||||
len = Q_strlen( Cmd_Argv(i) + 1 );
|
||||
if( l + len >= MAX_CMD_TOKENS - 2 )
|
||||
break;
|
||||
Q_strncat( combined, Cmd_Argv( i ), sizeof( combined ));
|
||||
if( i != c-1 ) Q_strncat( combined, " ", sizeof( combined ));
|
||||
l += len;
|
||||
}
|
||||
|
||||
Cvar_Set2( Cmd_Argv( 1 ), combined );
|
||||
Cvar_Set( Cmd_Argv( 1 ), va( "%i", v ));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1172,6 +932,7 @@ void Cvar_List_f( void )
|
||||
{
|
||||
convar_t *var;
|
||||
const char *match = NULL;
|
||||
char *value;
|
||||
int count = 0;
|
||||
size_t matchlen = 0;
|
||||
|
||||
@@ -1183,8 +944,6 @@ void Cvar_List_f( void )
|
||||
|
||||
for( var = cvar_vars; var; var = var->next )
|
||||
{
|
||||
char value[MAX_VA_STRING];
|
||||
|
||||
if( var->name[0] == '@' )
|
||||
continue; // never shows system cvars
|
||||
|
||||
@@ -1192,12 +951,12 @@ void Cvar_List_f( void )
|
||||
continue;
|
||||
|
||||
if( Q_colorstr( var->string ))
|
||||
Q_snprintf( value, sizeof( value ), "\"%s\"", var->string );
|
||||
else Q_snprintf( value, sizeof( value ), "\"^2%s^7\"", var->string );
|
||||
value = va( "\"%s\"", var->string );
|
||||
else value = va( "\"^2%s^7\"", var->string );
|
||||
|
||||
if( FBitSet( var->flags, FCVAR_EXTENDED|FCVAR_ALLOCATED ))
|
||||
Con_Printf( " %-*s %s ^3%s^7\n", 32, var->name, value, var->desc );
|
||||
else Con_Printf( " %-*s %s ^3%s^7\n", 32, var->name, value, Cvar_BuildAutoDescription( var->name, var->flags ));
|
||||
else Con_Printf( " %-*s %s ^3%s^7\n", 32, var->name, value, Cvar_BuildAutoDescription( var->flags ));
|
||||
|
||||
count++;
|
||||
}
|
||||
@@ -1239,37 +998,16 @@ Reads in all archived cvars
|
||||
void Cvar_Init( void )
|
||||
{
|
||||
cvar_vars = NULL;
|
||||
cvar_active_filter_quirks = NULL;
|
||||
cmd_scripting = Cvar_Get( "cmd_scripting", "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED, "enable simple condition checking and variable operations" );
|
||||
Cvar_RegisterVariable( &host_developer ); // early registering for dev
|
||||
Cvar_RegisterVariable (&host_developer); // early registering for dev
|
||||
Cvar_RegisterVariable( &cl_filterstuffcmd );
|
||||
|
||||
Cmd_AddRestrictedCommand( "setgl", Cvar_SetGL_f, "change the value of a opengl variable" ); // OBSOLETE
|
||||
Cmd_AddRestrictedCommand( "toggle", Cvar_Toggle_f, "toggles a console variable's values (use for more info)" );
|
||||
Cmd_AddRestrictedCommand( "reset", Cvar_Reset_f, "reset any type variable to initial value" );
|
||||
Cmd_AddCommand( "set", Cvar_Set_f, "create or change the value of a console variable" );
|
||||
Cmd_AddCommand( "cvarlist", Cvar_List_f, "display all console variables beginning with the specified prefix" );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_PostFSInit
|
||||
|
||||
============
|
||||
*/
|
||||
void Cvar_PostFSInit( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( cvar_filter_quirks ); i++ )
|
||||
{
|
||||
if( !Q_stricmp( cvar_filter_quirks[i].gamedir, GI->gamefolder ))
|
||||
{
|
||||
cvar_active_filter_quirks = &cvar_filter_quirks[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if XASH_ENGINE_TESTS
|
||||
#include "tests.h"
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ typedef struct convar_s
|
||||
#define FCVAR_VIDRESTART (1<<20) // recreate the window is cvar with this flag was changed
|
||||
#define FCVAR_TEMPORARY (1<<21) // these cvars holds their values and can be unlink in any time
|
||||
#define FCVAR_MOVEVARS (1<<22) // this cvar is a part of movevars_t struct that shared between client and server
|
||||
#define FCVAR_USER_CREATED (1<<23) // created by a set command (dll's used)
|
||||
|
||||
#define CVAR_DEFINE( cv, cvname, cvstr, cvflags, cvdesc ) \
|
||||
convar_t cv = { (char*)cvname, (char*)cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, (char*)cvdesc, NULL }
|
||||
@@ -63,13 +62,12 @@ cvar_t *Cvar_GetList( void );
|
||||
convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group );
|
||||
void Cvar_RegisterVariable( convar_t *var );
|
||||
convar_t *Cvar_Get( const char *var_name, const char *value, int flags, const char *description );
|
||||
convar_t *Cvar_Getf( const char *var_name, int flags, const char *description, const char *format, ... ) _format( 4 );
|
||||
void Cvar_LookupVars( int checkbit, void *buffer, void *ptr, setpair_t callback );
|
||||
void Cvar_FullSet( const char *var_name, const char *value, int flags );
|
||||
void Cvar_DirectSet( convar_t *var, const char *value );
|
||||
void Cvar_Set( const char *var_name, const char *value );
|
||||
void Cvar_SetValue( const char *var_name, float value );
|
||||
const char *Cvar_BuildAutoDescription( const char *szName, int flags );
|
||||
const char *Cvar_BuildAutoDescription( int flags );
|
||||
float Cvar_VariableValue( const char *var_name );
|
||||
int Cvar_VariableInteger( const char *var_name );
|
||||
const char *Cvar_VariableString( const char *var_name );
|
||||
@@ -79,7 +77,6 @@ void Cvar_Reset( const char *var_name );
|
||||
void Cvar_SetCheatState( void );
|
||||
qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged );
|
||||
void Cvar_Init( void );
|
||||
void Cvar_PostFSInit( void );
|
||||
void Cvar_Unlink( int group );
|
||||
|
||||
#endif//CVAR_H
|
||||
|
||||
@@ -19,6 +19,74 @@ GNU General Public License for more details.
|
||||
|
||||
ref_globals_t refState;
|
||||
|
||||
const char *svc_strings[256] =
|
||||
{
|
||||
"svc_bad",
|
||||
"svc_nop",
|
||||
"svc_disconnect",
|
||||
"svc_changing",
|
||||
"svc_version",
|
||||
"svc_setview",
|
||||
"svc_sound",
|
||||
"svc_time",
|
||||
"svc_print",
|
||||
"svc_stufftext",
|
||||
"svc_setangle",
|
||||
"svc_serverdata",
|
||||
"svc_lightstyle",
|
||||
"svc_updateuserinfo",
|
||||
"svc_deltatable",
|
||||
"svc_clientdata",
|
||||
"svc_stopsound",
|
||||
"svc_updatepings",
|
||||
"svc_particle",
|
||||
"svc_restoresound",
|
||||
"svc_spawnstatic",
|
||||
"svc_event_reliable",
|
||||
"svc_spawnbaseline",
|
||||
"svc_temp_entity",
|
||||
"svc_setpause",
|
||||
"svc_signonnum",
|
||||
"svc_centerprint",
|
||||
"svc_event",
|
||||
"svc_soundindex",
|
||||
"svc_ambientsound",
|
||||
"svc_intermission",
|
||||
"svc_modelindex",
|
||||
"svc_cdtrack",
|
||||
"svc_serverinfo",
|
||||
"svc_eventindex",
|
||||
"svc_weaponanim",
|
||||
"svc_bspdecal",
|
||||
"svc_roomtype",
|
||||
"svc_addangle",
|
||||
"svc_usermessage",
|
||||
"svc_packetentities",
|
||||
"svc_deltapacketentities",
|
||||
"svc_chokecount",
|
||||
"svc_resourcelist",
|
||||
"svc_deltamovevars",
|
||||
"svc_customization",
|
||||
"svc_unused46",
|
||||
"svc_crosshairangle",
|
||||
"svc_soundfade",
|
||||
"svc_unused49",
|
||||
"svc_unused50",
|
||||
"svc_director",
|
||||
"svc_studiodecal",
|
||||
"svc_unused53",
|
||||
"svc_unused54",
|
||||
"svc_unused55",
|
||||
"svc_unused56",
|
||||
"svc_querycvarvalue",
|
||||
"svc_querycvarvalue2",
|
||||
"svc_exec",
|
||||
"svc_unused60",
|
||||
"svc_unused61",
|
||||
"svc_unused62",
|
||||
"svc_unused63",
|
||||
};
|
||||
|
||||
void CL_ProcessFile( qboolean successfully_received, const char *filename )
|
||||
{
|
||||
|
||||
@@ -70,6 +138,16 @@ qboolean CL_DisableVisibility( void )
|
||||
return false;
|
||||
}
|
||||
|
||||
qboolean CL_IsBackgroundDemo( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
qboolean CL_IsBackgroundMap( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void CL_Init( void )
|
||||
{
|
||||
|
||||
@@ -247,9 +325,4 @@ void CL_Crashed( void )
|
||||
{
|
||||
}
|
||||
|
||||
void CL_HudMessage( const char *pMessage )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif // XASH_DEDICATED
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
/*
|
||||
filesystem.c - game filesystem based on DP fs
|
||||
Copyright (C) 2003-2006 Mathieu Olivier
|
||||
Copyright (C) 2000-2007 DarkPlaces contributors
|
||||
Copyright (C) 2007 Uncle Mike
|
||||
Copyright (C) 2015-2023 Xash3D FWGS contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -55,11 +52,8 @@ static fs_interface_t fs_memfuncs =
|
||||
|
||||
static void FS_UnloadProgs( void )
|
||||
{
|
||||
if( fs_hInstance )
|
||||
{
|
||||
COM_FreeLibrary( fs_hInstance );
|
||||
fs_hInstance = 0;
|
||||
}
|
||||
COM_FreeLibrary( fs_hInstance );
|
||||
fs_hInstance = 0;
|
||||
}
|
||||
|
||||
#ifdef XASH_INTERNAL_GAMELIBS
|
||||
@@ -107,16 +101,25 @@ FS_Init
|
||||
*/
|
||||
void FS_Init( void )
|
||||
{
|
||||
qboolean hasBaseDir = false;
|
||||
qboolean hasGameDir = false;
|
||||
qboolean caseinsensitive = true;
|
||||
int i;
|
||||
string gamedir;
|
||||
|
||||
Cmd_AddRestrictedCommand( "fs_rescan", FS_Rescan_f, "rescan filesystem search pathes" );
|
||||
Cmd_AddRestrictedCommand( "fs_path", FS_Path_f_, "show filesystem search pathes" );
|
||||
Cmd_AddRestrictedCommand( "fs_clearpaths", FS_ClearPaths_f, "clear filesystem search pathes" );
|
||||
|
||||
#if !XASH_WIN32
|
||||
if( Sys_CheckParm( "-casesensitive" ) )
|
||||
caseinsensitive = false;
|
||||
#endif
|
||||
|
||||
if( !Sys_GetParmFromCmdLine( "-game", gamedir ))
|
||||
Q_strncpy( gamedir, SI.basedirName, sizeof( gamedir )); // gamedir == basedir
|
||||
|
||||
if( !FS_InitStdio( true, host.rootdir, SI.basedirName, gamedir, host.rodir ))
|
||||
if( !FS_InitStdio( caseinsensitive, host.rootdir, SI.basedirName, gamedir, host.rodir ))
|
||||
{
|
||||
Host_Error( "Can't init filesystem_stdio!\n" );
|
||||
return;
|
||||
@@ -136,8 +139,9 @@ FS_Shutdown
|
||||
*/
|
||||
void FS_Shutdown( void )
|
||||
{
|
||||
if( g_fsapi.ShutdownStdio )
|
||||
g_fsapi.ShutdownStdio();
|
||||
int i;
|
||||
|
||||
FS_ShutdownStdio();
|
||||
|
||||
memset( &SI, 0, sizeof( sysinfo_t ));
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ GNU General Public License for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gamma conversion support
|
||||
//-----------------------------------------------------------------------------
|
||||
static byte texgammatable[256]; // palette is sent through this to convert to screen gamma
|
||||
static byte lightgammatable[256];
|
||||
static int lineargammatable[1024];
|
||||
static int screengammatable[1024];
|
||||
@@ -59,6 +60,13 @@ void BuildGammaTable( float lightgamma, float brightness )
|
||||
lightgammatable[i] = bound( 0, inf, 255 );
|
||||
}
|
||||
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
f = 255.0f * pow(( float )i / 255.0f, TEXGAMMA );
|
||||
inf = (int)(f + 0.5f);
|
||||
texgammatable[i] = bound( 0, inf, 255 );
|
||||
}
|
||||
|
||||
for( i = 0; i < 1024; i++ )
|
||||
{
|
||||
// convert from screen gamma space to linear space
|
||||
@@ -76,3 +84,11 @@ byte LightToTexGamma( byte b )
|
||||
else
|
||||
return lightgammatable[b];
|
||||
}
|
||||
|
||||
byte TextureToGamma( byte b )
|
||||
{
|
||||
if( FBitSet( host.features, ENGINE_LINEAR_GAMMA_SPACE ))
|
||||
return b;
|
||||
else
|
||||
return texgammatable[b];
|
||||
}
|
||||
|
||||
@@ -66,102 +66,101 @@ convar_t *build, *ver;
|
||||
|
||||
void Sys_PrintUsage( void )
|
||||
{
|
||||
string version_str;
|
||||
const char *usage_str;
|
||||
|
||||
Q_snprintf( version_str, sizeof( version_str ),
|
||||
XASH_ENGINE_NAME " %i/" XASH_VERSION " (%s-%s build %i)", PROTOCOL_VERSION, Q_buildos(), Q_buildarch(), Q_buildnum( ));
|
||||
#define O(x,y) " "x" "y"\n"
|
||||
|
||||
#if XASH_WIN32
|
||||
#define XASH_EXE "(xash).exe"
|
||||
#else
|
||||
#define XASH_EXE "(xash)"
|
||||
#endif
|
||||
|
||||
#define O( x, y ) " "x" "y"\n"
|
||||
|
||||
usage_str = S_USAGE XASH_EXE " [options] [+command] [+command2 arg] ...\n"
|
||||
|
||||
"\nCommon options:\n"
|
||||
O("-dev [level] ", "set log verbosity 0-2")
|
||||
O("-log ", "write log to \"engine.log\"")
|
||||
O("-nowriteconfig ", "disable config save")
|
||||
O("-noch ", "disable crashhandler")
|
||||
#if XASH_WIN32 // !!!!
|
||||
O("-minidumps ", "enable writing minidumps when game is crashed")
|
||||
#endif
|
||||
O("-rodir <path> ", "set read-only base directory")
|
||||
O("-bugcomp ", "enable precise bug compatibility. Will break games that don't require it")
|
||||
O(" ", "Refer to engine documentation for more info")
|
||||
O("-disablehelp ", "disable this message")
|
||||
#if !XASH_DEDICATED
|
||||
O("-dedicated ", "run engine in dedicated mode")
|
||||
#endif
|
||||
|
||||
"\nNetworking options:\n"
|
||||
O("-noip ", "disable IPv4")
|
||||
O("-ip <ip> ", "set IPv4 address")
|
||||
O("-port <port> ", "set IPv4 port")
|
||||
O("-noip6 ", "disable IPv6")
|
||||
O("-ip6 <ip> ", "set IPv6 address")
|
||||
O("-port6 <port> ", "set IPv6 port")
|
||||
O("-clockwindow <cw>", "adjust clockwindow used to ignore client commands to prevent speed hacks")
|
||||
|
||||
"\nGame options:\n"
|
||||
O("-dll <path> ", "override server DLL path")
|
||||
#if !XASH_DEDICATED
|
||||
O("-clientlib <path>", "override client DLL path")
|
||||
O("-console ", "run engine with console enabled")
|
||||
O("-toconsole ", "run engine witn console open")
|
||||
O("-oldfont ", "enable unused Quake font in Half-Life")
|
||||
O("-width <n> ", "set window width")
|
||||
O("-height <n> ", "set window height")
|
||||
O("-fullscreen ", "run engine in fullscreen mode")
|
||||
O("-windowed ", "run engine in windowed mode")
|
||||
O("-ref <name> ", "use selected renderer dll")
|
||||
O("-gldebug ", "enable OpenGL debug log")
|
||||
#if XASH_WIN32
|
||||
O("-noavi ", "disable AVI support")
|
||||
O("-nointro ", "disable intro video")
|
||||
#endif
|
||||
O("-noenginejoy ", "disable engine builtin joystick support")
|
||||
O("-noenginemouse ", "disable engine builtin mouse support")
|
||||
O("-nosound ", "disable sound output")
|
||||
#endif
|
||||
|
||||
"\nPlatform-specific options:\n"
|
||||
usage_str = ""
|
||||
#if XASH_MESSAGEBOX == MSGBOX_STDERR
|
||||
"\n" // dirty hack to not have Xash Error: Usage: on same line
|
||||
#endif // XASH_MESSAGEBOX == MSGBOX_STDERR
|
||||
"Usage:\n"
|
||||
#if !XASH_MOBILE_PLATFORM
|
||||
O("-daemonize ", "run engine as a daemon")
|
||||
#endif
|
||||
#if XASH_SDL == 2
|
||||
O("-sdl_joy_old_api ","use SDL legacy joystick API")
|
||||
O("-sdl_renderer <n>","use alternative SDL_Renderer for software")
|
||||
#endif // XASH_SDL
|
||||
#if XASH_WIN32
|
||||
O("<xash>.exe [options] [+command1] [+command2 arg]","")
|
||||
#else // XASH_WIN32
|
||||
O("<xash> [options] [+command1] [+command2 arg]","")
|
||||
#endif // !XASH_WIN32
|
||||
#endif // !XASH_MOBILE_PLATFORM
|
||||
"Options:\n"
|
||||
O("-dev [level] ","set log verbosity 0-2")
|
||||
O("-log ","write log to \"engine.log\"")
|
||||
O("-nowriteconfig ","disable config save")
|
||||
|
||||
#if !XASH_WIN32
|
||||
O("-casesensitive ","disable case-insensitive FS emulation")
|
||||
#endif // !XASH_WIN32
|
||||
|
||||
#if !XASH_MOBILE_PLATFORM
|
||||
O("-daemonize ","run engine in background, dedicated only")
|
||||
#endif // !XASH_MOBILE_PLATFORM
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
O("-toconsole ","run engine witn console open")
|
||||
O("-width <n> ","set window width")
|
||||
O("-height <n> ","set window height")
|
||||
O("-oldfont ","enable unused Quake font in Half-Life")
|
||||
|
||||
#if !XASH_MOBILE_PLATFORM
|
||||
O("-fullscreen ","run engine in fullscreen mode")
|
||||
O("-windowed ","run engine in windowed mode")
|
||||
O("-dedicated ","run engine in dedicated server mode")
|
||||
#endif // XASH_MOBILE_PLATFORM
|
||||
|
||||
#if XASH_ANDROID
|
||||
O("-nativeegl ","use native egl implementation. Use if screen does not update or black")
|
||||
#endif // XASH_ANDROID
|
||||
|
||||
#if XASH_WIN32
|
||||
O("-noavi ","disable AVI support")
|
||||
O("-nointro ","disable intro video")
|
||||
#endif // XASH_WIN32
|
||||
|
||||
#if XASH_DOS
|
||||
O("-novesa ","disable vesa")
|
||||
#endif // XASH_DOS
|
||||
|
||||
#if XASH_VIDEO == VIDEO_FBDEV
|
||||
O("-fbdev <path> ","open selected framebuffer")
|
||||
O("-ttygfx ","set graphics mode in tty")
|
||||
O("-doublebuffer ","enable doublebuffering")
|
||||
#endif // XASH_VIDEO == VIDEO_FBDEV
|
||||
|
||||
#if XASH_SOUND == SOUND_ALSA
|
||||
O("-alsadev <dev> ","open selected ALSA device")
|
||||
#endif // XASH_SOUND == SOUND_ALSA
|
||||
;
|
||||
#undef O
|
||||
|
||||
// HACKHACK: pretty output in dedicated
|
||||
#if XASH_MESSAGEBOX != MSGBOX_STDERR
|
||||
Platform_MessageBox( version_str, usage_str, false );
|
||||
#else
|
||||
fprintf( stderr, "%s\n%s", version_str, usage_str );
|
||||
O("-nojoy ","disable joystick support")
|
||||
|
||||
#ifdef XASH_SDL
|
||||
O("-sdl_joy_old_api ","use SDL legacy joystick API")
|
||||
O("-sdl_renderer <n>","use alternative SDL_Renderer for software")
|
||||
#endif // XASH_SDL
|
||||
O("-nosound ","disable sound")
|
||||
O("-noenginemouse ","disable mouse completely")
|
||||
|
||||
O("-ref <name> ","use selected renderer dll")
|
||||
O("-gldebug ","enable OpenGL debug log")
|
||||
#endif // XASH_DEDICATED
|
||||
|
||||
O("-noip ","disable TCP/IP")
|
||||
O("-noch ","disable crashhandler")
|
||||
O("-disablehelp ","disable this message")
|
||||
O("-dll <path> ","override server DLL path")
|
||||
#if !XASH_DEDICATED
|
||||
O("-clientlib <path>","override client DLL path")
|
||||
#endif
|
||||
O("-rodir <path> ","set read-only base directory, experimental")
|
||||
O("-bugcomp ","enable precise bug compatibility. Will break games that don't require it")
|
||||
O(" ","Refer to engine documentation for more info")
|
||||
|
||||
Sys_Quit();
|
||||
O("-ip <ip> ","set custom ip")
|
||||
O("-port <port> ","set custom host port")
|
||||
O("-clockwindow <cw>","adjust clockwindow")
|
||||
;
|
||||
#undef O
|
||||
|
||||
Sys_Error( "%s", usage_str );
|
||||
}
|
||||
|
||||
int Host_CompareFileTime( int ft1, int ft2 )
|
||||
@@ -270,35 +269,36 @@ void Host_AbortCurrentFrame( void )
|
||||
|
||||
/*
|
||||
==================
|
||||
Host_CalcSleep
|
||||
Host_CheckSleep
|
||||
==================
|
||||
*/
|
||||
static int Host_CalcSleep( void )
|
||||
void Host_CheckSleep( void )
|
||||
{
|
||||
#ifndef XASH_DEDICATED
|
||||
// never sleep in timedemo for benchmarking purposes
|
||||
// also don't sleep with vsync for less lag
|
||||
if( CL_IsTimeDemo( ) || CVAR_TO_BOOL( gl_vsync ))
|
||||
return 0;
|
||||
#endif
|
||||
int sleeptime = host_sleeptime->value;
|
||||
|
||||
if( Host_IsDedicated() )
|
||||
{
|
||||
// let the dedicated server some sleep
|
||||
return host_sleeptime->value;
|
||||
Sys_Sleep( sleeptime );
|
||||
}
|
||||
|
||||
switch( host.status )
|
||||
else
|
||||
{
|
||||
case HOST_NOFOCUS:
|
||||
if( SV_Active() && CL_IsInGame())
|
||||
return host_sleeptime->value;
|
||||
// fallthrough
|
||||
case HOST_SLEEP:
|
||||
return 20;
|
||||
if( host.status == HOST_NOFOCUS )
|
||||
{
|
||||
if( SV_Active() && CL_IsInGame( ))
|
||||
Sys_Sleep( sleeptime ); // listenserver
|
||||
else Sys_Sleep( 20 ); // sleep 20 ms otherwise
|
||||
}
|
||||
else if( host.status == HOST_SLEEP )
|
||||
{
|
||||
// completely sleep in minimized state
|
||||
Sys_Sleep( 20 );
|
||||
}
|
||||
else
|
||||
{
|
||||
Sys_Sleep( sleeptime );
|
||||
}
|
||||
}
|
||||
|
||||
return host_sleeptime->value;
|
||||
}
|
||||
|
||||
void Host_NewInstance( const char *name, const char *finalmsg )
|
||||
@@ -346,10 +346,10 @@ void Host_ChangeGame_f( void )
|
||||
}
|
||||
else
|
||||
{
|
||||
char finalmsg[MAX_VA_STRING];
|
||||
const char *arg1 = va( "%s%s", (host.type == HOST_NORMAL) ? "" : "#", Cmd_Argv( 1 ));
|
||||
const char *arg2 = va( "change game to '%s'", FI->games[i]->title );
|
||||
|
||||
Q_snprintf( finalmsg, sizeof( finalmsg ), "change game to '%s'", FI->games[i]->title );
|
||||
Host_NewInstance( Cmd_Argv( 1 ), finalmsg );
|
||||
Host_NewInstance( arg1, arg2 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,11 +384,9 @@ void Host_Exec_f( void )
|
||||
"pyro.cfg", "spy.cfg", "engineer.cfg", "civilian.cfg"
|
||||
};
|
||||
int i;
|
||||
char temp[MAX_VA_STRING];
|
||||
qboolean allow = false;
|
||||
|
||||
Q_snprintf( temp, sizeof( temp ), "%s.cfg", clgame.mapname );
|
||||
unprivilegedWhitelist[0] = temp;
|
||||
unprivilegedWhitelist[0] = va( "%s.cfg", clgame.mapname );
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( unprivilegedWhitelist ); i++ )
|
||||
{
|
||||
@@ -415,7 +413,7 @@ void Host_Exec_f( void )
|
||||
}
|
||||
|
||||
Q_strncpy( cfgpath, arg, sizeof( cfgpath ));
|
||||
COM_DefaultExtension( cfgpath, ".cfg", sizeof( cfgpath )); // append as default
|
||||
COM_DefaultExtension( cfgpath, ".cfg" ); // append as default
|
||||
|
||||
f = FS_LoadFile( cfgpath, &len, false );
|
||||
if( !f )
|
||||
@@ -509,7 +507,7 @@ qboolean Host_RegisterDecal( const char *name, int *count )
|
||||
if( !COM_CheckString( name ))
|
||||
return 0;
|
||||
|
||||
COM_FileBase( name, shortname, sizeof( shortname ));
|
||||
COM_FileBase( name, shortname );
|
||||
|
||||
for( i = 1; i < MAX_DECALS && host.draw_decals[i][0]; i++ )
|
||||
{
|
||||
@@ -599,16 +597,24 @@ double Host_CalcFPS( void )
|
||||
}
|
||||
else if( Host_IsLocalGame( ))
|
||||
{
|
||||
if( !CVAR_TO_BOOL( gl_vsync ))
|
||||
fps = host_maxfps->value;
|
||||
fps = host_maxfps->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !CVAR_TO_BOOL( gl_vsync ))
|
||||
fps = host_maxfps->value;
|
||||
if( fps == 0.0 ) fps = MAX_FPS;
|
||||
fps = bound( MIN_FPS, fps, MAX_FPS );
|
||||
}
|
||||
|
||||
// probably left part of this condition is redundant :-)
|
||||
if( host.type != HOST_DEDICATED && Host_IsLocalGame( ) && !CL_IsTimeDemo( ))
|
||||
{
|
||||
// ajdust fps for vertical synchronization
|
||||
if( CVAR_TO_BOOL( gl_vsync ))
|
||||
{
|
||||
fps = host_maxfps->value;
|
||||
if( fps == 0.0 ) fps = MAX_FPS;
|
||||
fps = bound( MIN_FPS, fps, MAX_FPS );
|
||||
if( vid_displayfrequency->value != 0.0f )
|
||||
fps = vid_displayfrequency->value;
|
||||
else fps = 60.0; // default
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -626,53 +632,27 @@ Returns false if the time is too short to run a frame
|
||||
qboolean Host_FilterTime( float time )
|
||||
{
|
||||
static double oldtime;
|
||||
double fps, scale = sys_timescale.value;
|
||||
double fps;
|
||||
double scale = sys_timescale.value;
|
||||
|
||||
host.realtime += time * scale;
|
||||
fps = Host_CalcFPS();
|
||||
fps = Host_CalcFPS( );
|
||||
|
||||
// clamp the fps in multiplayer games
|
||||
if( fps != 0.0 )
|
||||
{
|
||||
static int sleeps;
|
||||
double targetframetime;
|
||||
int sleeptime = Host_CalcSleep();
|
||||
|
||||
// limit fps to withing tolerable range
|
||||
fps = bound( MIN_FPS, fps, MAX_FPS );
|
||||
|
||||
if( Host_IsDedicated( ))
|
||||
targetframetime = ( 1.0 / ( fps + 1.0 ));
|
||||
else targetframetime = ( 1.0 / fps );
|
||||
|
||||
if(( host.realtime - oldtime ) < targetframetime * scale )
|
||||
if( Host_IsDedicated() )
|
||||
{
|
||||
if( sleeptime > 0 && sleeps > 0 )
|
||||
{
|
||||
Sys_Sleep( sleeptime );
|
||||
sleeps--;
|
||||
}
|
||||
|
||||
return false;
|
||||
if(( host.realtime - oldtime ) < ( 1.0 / ( fps + 1.0 )) * scale)
|
||||
return false;
|
||||
}
|
||||
|
||||
if( sleeptime > 0 && sleeps <= 0 )
|
||||
else
|
||||
{
|
||||
if( host.status == HOST_FRAME )
|
||||
{
|
||||
// give few sleeps this frame with small margin
|
||||
double targetsleeptime = targetframetime - host.pureframetime * 2;
|
||||
|
||||
// don't sleep if we can't keep up with the framerate
|
||||
if( targetsleeptime > 0 )
|
||||
sleeps = targetsleeptime / ( sleeptime * 0.001 );
|
||||
else sleeps = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// always sleep at least once in minimized/nofocus state
|
||||
sleeps = 1;
|
||||
}
|
||||
if(( host.realtime - oldtime ) < ( 1.0 / fps ) * scale )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -695,17 +675,12 @@ Host_Frame
|
||||
*/
|
||||
void Host_Frame( float time )
|
||||
{
|
||||
double t1, t2;
|
||||
Host_CheckSleep();
|
||||
|
||||
// decide the simulation time
|
||||
if( !Host_FilterTime( time ))
|
||||
return;
|
||||
|
||||
t1 = Sys_DoubleTime();
|
||||
|
||||
if( host.framecount == 0 )
|
||||
Con_DPrintf( "Time to first frame: %.3f seconds\n", t1 - host.starttime );
|
||||
|
||||
Host_InputFrame (); // input frame
|
||||
Host_ClientBegin (); // begin client
|
||||
Host_GetCommands (); // dedicated in
|
||||
@@ -713,10 +688,6 @@ void Host_Frame( float time )
|
||||
Host_ClientFrame (); // client frame
|
||||
HTTP_Run(); // both server and client
|
||||
|
||||
t2 = Sys_DoubleTime();
|
||||
|
||||
host.pureframetime = t2 - t1;
|
||||
|
||||
host.framecount++;
|
||||
}
|
||||
|
||||
@@ -732,8 +703,17 @@ void GAME_EXPORT Host_Error( const char *error, ... )
|
||||
static qboolean recursive = false;
|
||||
va_list argptr;
|
||||
|
||||
if( host.mouse_visible && !CL_IsInMenu( ))
|
||||
{
|
||||
// hide VGUI mouse
|
||||
#ifdef XASH_SDL
|
||||
SDL_ShowCursor( 0 );
|
||||
#endif
|
||||
host.mouse_visible = false;
|
||||
}
|
||||
|
||||
va_start( argptr, error );
|
||||
Q_vsnprintf( hosterror1, sizeof( hosterror1 ), error, argptr );
|
||||
Q_vsprintf( hosterror1, error, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
CL_WriteMessageHistory (); // before Q_error call
|
||||
@@ -769,7 +749,7 @@ void GAME_EXPORT Host_Error( const char *error, ... )
|
||||
recursive = true;
|
||||
Q_strncpy( hosterror2, hosterror1, MAX_SYSPATH );
|
||||
host.errorframe = host.framecount; // to avoid multply calls per frame
|
||||
Q_snprintf( host.finalmsg, sizeof( host.finalmsg ), "Server crashed: %s", hosterror1 );
|
||||
Q_sprintf( host.finalmsg, "Server crashed: %s", hosterror1 );
|
||||
|
||||
// clearing cmd buffer to prevent execute any commands
|
||||
COM_InitHostState();
|
||||
@@ -829,7 +809,7 @@ void Host_Userconfigd_f( void )
|
||||
|
||||
for( i = 0; i < t->numfilenames; i++ )
|
||||
{
|
||||
Cbuf_AddTextf( "exec %s\n", t->filenames[i] );
|
||||
Cbuf_AddText( va("exec %s\n", t->filenames[i] ) );
|
||||
}
|
||||
|
||||
Mem_Free( t );
|
||||
@@ -842,15 +822,18 @@ static void Host_RunTests( int stage )
|
||||
{
|
||||
case 0: // early engine load
|
||||
memset( &tests_stats, 0, sizeof( tests_stats ));
|
||||
TEST_LIST_0;
|
||||
Test_RunLibCommon();
|
||||
Test_RunCommon();
|
||||
Test_RunCmd();
|
||||
Test_RunCvar();
|
||||
#if !XASH_DEDICATED
|
||||
TEST_LIST_0_CLIENT;
|
||||
Test_RunCon();
|
||||
#endif /* XASH_DEDICATED */
|
||||
break;
|
||||
case 1: // after FS load
|
||||
TEST_LIST_1;
|
||||
Test_RunImagelib();
|
||||
#if !XASH_DEDICATED
|
||||
TEST_LIST_1_CLIENT;
|
||||
Test_RunVOX();
|
||||
#endif
|
||||
Msg( "Done! %d passed, %d failed\n", tests_stats.passed, tests_stats.failed );
|
||||
Sys_Quit();
|
||||
@@ -897,11 +880,9 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha
|
||||
|
||||
host.mempool = Mem_AllocPool( "Zone Engine" );
|
||||
|
||||
host.allow_console = DEFAULT_ALLOWCONSOLE;
|
||||
|
||||
// HACKHACK: Quake console is always allowed
|
||||
// TODO: determine if we are running QWrap more reliable
|
||||
if( !host.allow_console && ( Sys_CheckParm( "-console" ) || !Q_stricmp( SI.exeName, "quake" )))
|
||||
if( Sys_CheckParm( "-console" ) || !Q_stricmp( SI.exeName, "quake" ))
|
||||
host.allow_console = true;
|
||||
|
||||
if( Sys_CheckParm( "-dev" ))
|
||||
@@ -1011,28 +992,22 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha
|
||||
|
||||
if( COM_CheckString( baseDir ) )
|
||||
{
|
||||
Q_strncpy( host.rootdir, baseDir, sizeof( host.rootdir ));
|
||||
Q_strncpy( host.rootdir, baseDir, sizeof(host.rootdir) );
|
||||
}
|
||||
else
|
||||
{
|
||||
#if TARGET_OS_IOS
|
||||
const char *IOS_GetDocsDir();
|
||||
Q_strncpy( host.rootdir, IOS_GetDocsDir(), sizeof(host.rootdir) );
|
||||
#elif XASH_PSVITA
|
||||
if ( !PSVita_GetBasePath( host.rootdir, sizeof( host.rootdir ) ) )
|
||||
{
|
||||
Sys_Error( "couldn't find xash3d data directory" );
|
||||
host.rootdir[0] = 0;
|
||||
}
|
||||
#elif (XASH_SDL == 2) && !XASH_NSWITCH // GetBasePath not impl'd in switch-sdl2
|
||||
#elif XASH_SDL == 2
|
||||
char *szBasePath;
|
||||
|
||||
if( !( szBasePath = SDL_GetBasePath() ) )
|
||||
Sys_Error( "couldn't determine current directory: %s", SDL_GetError() );
|
||||
Q_strncpy( host.rootdir, szBasePath, sizeof( host.rootdir ));
|
||||
Q_strncpy( host.rootdir, szBasePath, sizeof( host.rootdir ) );
|
||||
SDL_free( szBasePath );
|
||||
#else
|
||||
if( !getcwd( host.rootdir, sizeof( host.rootdir )))
|
||||
if( !getcwd( host.rootdir, sizeof(host.rootdir) ) )
|
||||
{
|
||||
Sys_Error( "couldn't determine current directory: %s", strerror( errno ) );
|
||||
host.rootdir[0] = 0;
|
||||
@@ -1040,10 +1015,6 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha
|
||||
#endif
|
||||
}
|
||||
|
||||
#if XASH_WIN32
|
||||
COM_FixSlashes( host.rootdir );
|
||||
#endif
|
||||
|
||||
len = Q_strlen( host.rootdir );
|
||||
|
||||
if( len && host.rootdir[len - 1] == '/' )
|
||||
@@ -1060,10 +1031,6 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha
|
||||
Q_strncpy( host.rodir, roDir, sizeof( host.rodir ));
|
||||
}
|
||||
|
||||
#if XASH_WIN32
|
||||
COM_FixSlashes( host.rootdir );
|
||||
#endif
|
||||
|
||||
len = Q_strlen( host.rodir );
|
||||
|
||||
if( len && host.rodir[len - 1] == '/' )
|
||||
@@ -1105,7 +1072,6 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha
|
||||
#endif
|
||||
|
||||
FS_LoadGameInfo( NULL );
|
||||
Cvar_PostFSInit();
|
||||
|
||||
if( FS_FileExists( va( "%s.rc", SI.basedirName ), false ))
|
||||
Q_strncpy( SI.rcName, SI.basedirName, sizeof( SI.rcName )); // e.g. valve.rc
|
||||
@@ -1151,8 +1117,6 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
{
|
||||
static double oldtime, newtime;
|
||||
|
||||
host.starttime = Sys_DoubleTime();
|
||||
|
||||
pChangeGame = func; // may be NULL
|
||||
|
||||
Host_InitCommon( argc, argv, progname, bChangeGame );
|
||||
@@ -1175,10 +1139,10 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
con_gamemaps = Cvar_Get( "con_mapfilter", "1", FCVAR_ARCHIVE, "when true show only maps in game folder" );
|
||||
Cvar_RegisterVariable( &sys_timescale );
|
||||
|
||||
build = Cvar_Getf( "buildnum", FCVAR_READ_ONLY, "returns a current build number", "%i", Q_buildnum_compat());
|
||||
ver = Cvar_Getf( "ver", FCVAR_READ_ONLY, "shows an engine version", "%i/%s (hw build %i)", PROTOCOL_VERSION, XASH_COMPAT_VERSION, Q_buildnum_compat());
|
||||
Cvar_Getf( "host_ver", FCVAR_READ_ONLY, "detailed info about this build", "%i " XASH_VERSION " %s %s %s", Q_buildnum(), Q_buildos(), Q_buildarch(), Q_buildcommit());
|
||||
Cvar_Getf( "host_lowmemorymode", FCVAR_READ_ONLY, "indicates if engine compiled for low RAM consumption (0 - normal, 1 - low engine limits, 2 - low protocol limits)", "%i", XASH_LOW_MEMORY );
|
||||
build = Cvar_Get( "buildnum", va( "%i", Q_buildnum_compat()), FCVAR_READ_ONLY, "returns a current build number" );
|
||||
ver = Cvar_Get( "ver", va( "%i/%s (hw build %i)", PROTOCOL_VERSION, XASH_COMPAT_VERSION, Q_buildnum_compat()), FCVAR_READ_ONLY, "shows an engine version" );
|
||||
Cvar_Get( "host_ver", va( "%i %s %s %s %s", Q_buildnum(), XASH_VERSION, Q_buildos(), Q_buildarch(), Q_buildcommit() ), FCVAR_READ_ONLY, "detailed info about this build" );
|
||||
Cvar_Get( "host_lowmemorymode", va( "%i", XASH_LOW_MEMORY ), FCVAR_READ_ONLY, "indicates if engine compiled for low RAM consumption (0 - normal, 1 - low engine limits, 2 - low protocol limits)" );
|
||||
|
||||
Mod_Init();
|
||||
NET_Init();
|
||||
@@ -1213,8 +1177,6 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
}
|
||||
else Cmd_AddRestrictedCommand( "minimize", Host_Minimize_f, "minimize main window to tray" );
|
||||
|
||||
HPAK_CheckIntegrity( CUSTOM_RES_PATH );
|
||||
|
||||
host.errorframe = 0;
|
||||
|
||||
// post initializations
|
||||
@@ -1225,7 +1187,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
Wcon_ShowConsole( false ); // hide console
|
||||
#endif
|
||||
// execute startup config and cmdline
|
||||
Cbuf_AddTextf( "exec %s.rc\n", SI.rcName );
|
||||
Cbuf_AddText( va( "exec %s.rc\n", SI.rcName ));
|
||||
Cbuf_Execute();
|
||||
if( !host.config_executed )
|
||||
{
|
||||
@@ -1248,18 +1210,12 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
|
||||
oldtime = Sys_DoubleTime() - 0.1;
|
||||
|
||||
if( Host_IsDedicated( ))
|
||||
if( Host_IsDedicated() && GameState->nextstate == STATE_RUNFRAME )
|
||||
{
|
||||
// in dedicated server input system can't set HOST_FRAME status
|
||||
// so set it here as we're finished initializing
|
||||
host.status = HOST_FRAME;
|
||||
|
||||
if( GameState->nextstate == STATE_RUNFRAME )
|
||||
Con_Printf( "Type 'map <mapname>' to start game... (TAB-autocomplete is working too)\n" );
|
||||
|
||||
// execute server.cfg after commandline
|
||||
// so we have a chance to set servercfgfile
|
||||
Cbuf_AddTextf( "exec %s\n", Cvar_VariableString( "servercfgfile" ));
|
||||
Con_Printf( "Type 'map <mapname>' to start game... (TAB-autocomplete is working too)\n" );
|
||||
Cbuf_AddText( va( "exec %s\n", Cvar_VariableString( "servercfgfile" )));
|
||||
Cbuf_Execute();
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@ GNU General Public License for more details.
|
||||
#include "hpak.h"
|
||||
|
||||
#define HPAK_MAX_ENTRIES 0x8000
|
||||
#define HPAK_ENTRY_MIN_SIZE (512)
|
||||
#define HPAK_ENTRY_MAX_SIZE (128 * 1024)
|
||||
#define HPAK_MIN_SIZE (1 * 1024)
|
||||
#define HPAK_MAX_SIZE (128 * 1024)
|
||||
|
||||
typedef struct hash_pack_queue_s
|
||||
{
|
||||
@@ -29,10 +29,10 @@ typedef struct hash_pack_queue_s
|
||||
struct hash_pack_queue_s *next;
|
||||
} hash_pack_queue_t;
|
||||
|
||||
static CVAR_DEFINE_AUTO( hpk_maxsize, "4", FCVAR_ARCHIVE, "set limit by size for all HPK-files ( 0 - unlimited )" );
|
||||
static hash_pack_queue_t *gp_hpak_queue = NULL;
|
||||
static hpak_header_t hash_pack_header;
|
||||
static hpak_info_t hash_pack_info;
|
||||
convar_t *hpk_maxsize;
|
||||
hash_pack_queue_t *gp_hpak_queue = NULL;
|
||||
hpak_header_t hash_pack_header;
|
||||
hpak_info_t hash_pack_info;
|
||||
|
||||
const char *HPAK_TypeFromIndex( int type )
|
||||
{
|
||||
@@ -49,18 +49,6 @@ const char *HPAK_TypeFromIndex( int type )
|
||||
return "?";
|
||||
}
|
||||
|
||||
static inline void HPAK_ResourceToCompat( dresource_t *dest, resource_t *src )
|
||||
{
|
||||
memcpy( dest, src, sizeof( *dest ));
|
||||
dest->pNext = dest->pPrev = 0xDEADBEEF;
|
||||
}
|
||||
|
||||
static inline void HPAK_ResourceFromCompat( resource_t *dest, dresource_t *src )
|
||||
{
|
||||
memcpy( dest, src, sizeof( *src ));
|
||||
dest->pNext = dest->pPrev = (void*)0xDEADBEEF;
|
||||
}
|
||||
|
||||
static void HPAK_AddToQueue( const char *name, resource_t *pResource, void *data, file_t *f )
|
||||
{
|
||||
hash_pack_queue_t *p;
|
||||
@@ -109,11 +97,11 @@ void HPAK_CreatePak( const char *filename, resource_t *pResource, byte *pData, f
|
||||
return;
|
||||
|
||||
Q_strncpy( pakname, filename, sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk", sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk" );
|
||||
|
||||
Con_Printf( "creating HPAK %s.\n", pakname );
|
||||
|
||||
fout = FS_Open( pakname, "wb", true );
|
||||
fout = FS_Open( pakname, "wb", false );
|
||||
if( !fout )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "HPAK_CreatePak: can't write %s.\n", pakname );
|
||||
@@ -157,7 +145,7 @@ void HPAK_CreatePak( const char *filename, resource_t *pResource, byte *pData, f
|
||||
|
||||
hash_pack_info.count = 1;
|
||||
hash_pack_info.entries = Z_Malloc( sizeof( hpak_lump_t ));
|
||||
HPAK_ResourceToCompat( &hash_pack_info.entries[0].resource, pResource );
|
||||
hash_pack_info.entries[0].resource = *pResource;
|
||||
hash_pack_info.entries[0].filepos = FS_Tell( fout );
|
||||
hash_pack_info.entries[0].disksize = pResource->nDownloadSize;
|
||||
|
||||
@@ -193,7 +181,7 @@ static qboolean HPAK_FindResource( hpak_info_t *hpk, byte *hash, resource_t *pRe
|
||||
if( !memcmp( hpk->entries[i].resource.rgucMD5_hash, hash, 16 ))
|
||||
{
|
||||
if( pResource )
|
||||
HPAK_ResourceFromCompat( pResource, &hpk->entries[i].resource );
|
||||
*pResource = hpk->entries[i].resource;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -215,7 +203,7 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource,
|
||||
if( pData == NULL && pFile == NULL )
|
||||
return;
|
||||
|
||||
if( pResource->nDownloadSize < HPAK_ENTRY_MIN_SIZE || pResource->nDownloadSize > HPAK_ENTRY_MAX_SIZE )
|
||||
if( pResource->nDownloadSize < HPAK_MIN_SIZE || pResource->nDownloadSize > HPAK_MAX_SIZE )
|
||||
{
|
||||
Con_Printf( S_ERROR "%s: invalid size %s\n", name, Q_pretifymem( pResource->nDownloadSize, 2 ));
|
||||
return;
|
||||
@@ -225,7 +213,7 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource,
|
||||
memset( &ctx, 0, sizeof( MD5Context_t ));
|
||||
MD5Init( &ctx );
|
||||
|
||||
if( !pData )
|
||||
if( pData == NULL )
|
||||
{
|
||||
byte *temp;
|
||||
|
||||
@@ -257,9 +245,9 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource,
|
||||
}
|
||||
|
||||
Q_strncpy( srcname, name, sizeof( srcname ));
|
||||
COM_ReplaceExtension( srcname, ".hpk", sizeof( srcname ));
|
||||
COM_ReplaceExtension( srcname, ".hpk" );
|
||||
|
||||
file_src = FS_Open( srcname, "rb", true );
|
||||
file_src = FS_Open( srcname, "rb", false );
|
||||
|
||||
if( !file_src )
|
||||
{
|
||||
@@ -269,9 +257,9 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource,
|
||||
}
|
||||
|
||||
Q_strncpy( dstname, srcname, sizeof( dstname ));
|
||||
COM_ReplaceExtension( dstname, ".hp2", sizeof( dstname ));
|
||||
COM_ReplaceExtension( dstname, ".hp2" );
|
||||
|
||||
file_dst = FS_Open( dstname, "wb", true );
|
||||
file_dst = FS_Open( dstname, "wb", false );
|
||||
|
||||
if( !file_dst )
|
||||
{
|
||||
@@ -324,12 +312,11 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource,
|
||||
// make a new container
|
||||
dstpak.count = srcpak.count + 1;
|
||||
dstpak.entries = Z_Malloc( sizeof( hpak_lump_t ) * dstpak.count );
|
||||
memcpy( dstpak.entries, srcpak.entries, sizeof( hpak_lump_t ) * srcpak.count );
|
||||
memcpy( dstpak.entries, srcpak.entries, srcpak.count );
|
||||
|
||||
// check is there are entry with same hash
|
||||
for( i = 0; i < srcpak.count; i++ )
|
||||
{
|
||||
if( memcmp( md5, srcpak.entries[i].resource.rgucMD5_hash, 16 ) == 0 )
|
||||
if( memcmp( md5, srcpak.entries[i].resource.rgucMD5_hash, 16 ))
|
||||
{
|
||||
pCurrentEntry = &dstpak.entries[i];
|
||||
|
||||
@@ -343,14 +330,12 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource,
|
||||
|
||||
memset( pCurrentEntry, 0, sizeof( hpak_lump_t ));
|
||||
FS_Seek( file_dst, hash_pack_header.infotableofs, SEEK_SET );
|
||||
HPAK_ResourceToCompat( &pCurrentEntry->resource, pResource );
|
||||
pCurrentEntry->resource = *pResource;
|
||||
pCurrentEntry->filepos = FS_Tell( file_dst );
|
||||
pCurrentEntry->disksize = pResource->nDownloadSize;
|
||||
|
||||
if( !pData )
|
||||
FS_FileCopy( file_dst, pFile, pCurrentEntry->disksize );
|
||||
else
|
||||
FS_Write( file_dst, pData, pCurrentEntry->disksize );
|
||||
if( !pData ) FS_FileCopy( file_dst, file_src, pCurrentEntry->disksize );
|
||||
else FS_Write( file_dst, pData, pCurrentEntry->disksize );
|
||||
|
||||
hash_pack_header.infotableofs = FS_Tell( file_dst );
|
||||
FS_Write( file_dst, &dstpak.count, sizeof( dstpak.count ));
|
||||
@@ -376,7 +361,7 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource,
|
||||
FS_Rename( dstname, srcname );
|
||||
}
|
||||
|
||||
static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean delete )
|
||||
static qboolean HPAK_Validate( const char *filename, qboolean quiet )
|
||||
{
|
||||
file_t *f;
|
||||
hpak_lump_t *dataDir;
|
||||
@@ -385,7 +370,7 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
|
||||
int i, num_lumps;
|
||||
MD5Context_t MD5_Hash;
|
||||
string pakname;
|
||||
dresource_t *pRes;
|
||||
resource_t *pRes;
|
||||
byte md5[16];
|
||||
|
||||
if( quiet ) HPAK_FlushHostQueue();
|
||||
@@ -395,9 +380,9 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
|
||||
return true;
|
||||
|
||||
Q_strncpy( pakname, filename, sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk", sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk" );
|
||||
|
||||
f = FS_Open( pakname, "rb", true );
|
||||
f = FS_Open( pakname, "rb", false );
|
||||
if( !f )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Couldn't find %s.\n", pakname );
|
||||
@@ -411,7 +396,6 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
|
||||
{
|
||||
Con_DPrintf( S_ERROR "HPAK_ValidatePak: %s does not have a valid HPAK header.\n", pakname );
|
||||
FS_Close( f );
|
||||
if( delete ) FS_Delete( pakname );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -422,7 +406,6 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
|
||||
{
|
||||
Con_DPrintf( S_ERROR "HPAK_ValidatePak: %s has too many lumps %u.\n", pakname, num_lumps );
|
||||
FS_Close( f );
|
||||
if( delete ) FS_Delete( pakname );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -435,13 +418,12 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
|
||||
|
||||
for( i = 0; i < num_lumps; i++ )
|
||||
{
|
||||
if( dataDir[i].disksize < HPAK_ENTRY_MIN_SIZE || dataDir[i].disksize > HPAK_ENTRY_MAX_SIZE )
|
||||
if( dataDir[i].disksize < 1 || dataDir[i].disksize > 131071 )
|
||||
{
|
||||
// odd max size
|
||||
Con_DPrintf( S_ERROR "HPAK_ValidatePak: lump %i has invalid size %s\n", i, Q_pretifymem( dataDir[i].disksize, 2 ));
|
||||
Mem_Free( dataDir );
|
||||
FS_Close( f );
|
||||
if( delete ) FS_Delete( pakname );
|
||||
FS_Close(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -456,11 +438,8 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
|
||||
|
||||
pRes = &dataDir[i].resource;
|
||||
|
||||
if( !quiet )
|
||||
{
|
||||
Con_Printf( "%i: %s %s %s: ", i, HPAK_TypeFromIndex( pRes->type ),
|
||||
Q_pretifymem( pRes->nDownloadSize, 2 ), pRes->szFileName );
|
||||
}
|
||||
Con_Printf( "%i: %s %s %s: ", i, HPAK_TypeFromIndex( pRes->type ),
|
||||
Q_pretifymem( pRes->nDownloadSize, 2 ), pRes->szFileName );
|
||||
|
||||
if( memcmp( md5, pRes->rgucMD5_hash, 0x10 ))
|
||||
{
|
||||
@@ -470,7 +449,6 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
|
||||
Mem_Free( dataPak );
|
||||
Mem_Free( dataDir );
|
||||
FS_Close( f );
|
||||
if( delete ) FS_Delete( pakname );
|
||||
return false;
|
||||
}
|
||||
else Con_DPrintf( S_ERROR "failed\n" );
|
||||
@@ -489,6 +467,11 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
|
||||
return true;
|
||||
}
|
||||
|
||||
void HPAK_ValidatePak( const char *filename )
|
||||
{
|
||||
HPAK_Validate( filename, true );
|
||||
}
|
||||
|
||||
void HPAK_CheckIntegrity( const char *filename )
|
||||
{
|
||||
string pakname;
|
||||
@@ -497,9 +480,9 @@ void HPAK_CheckIntegrity( const char *filename )
|
||||
return;
|
||||
|
||||
Q_strncpy( pakname, filename, sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk", sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk" );
|
||||
|
||||
HPAK_Validate( pakname, true, true );
|
||||
HPAK_ValidatePak( pakname );
|
||||
}
|
||||
|
||||
void HPAK_CheckSize( const char *filename )
|
||||
@@ -507,19 +490,19 @@ void HPAK_CheckSize( const char *filename )
|
||||
string pakname;
|
||||
int maxsize;
|
||||
|
||||
maxsize = hpk_maxsize.value;
|
||||
maxsize = hpk_maxsize->value;
|
||||
if( maxsize <= 0 ) return;
|
||||
|
||||
if( !COM_CheckString( filename ) )
|
||||
return;
|
||||
|
||||
Q_strncpy( pakname, filename, sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk", sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk" );
|
||||
|
||||
if( FS_FileSize( pakname, false ) > ( maxsize * 1048576 ))
|
||||
if( FS_FileSize( pakname, false ) > ( maxsize * 1000000 ))
|
||||
{
|
||||
Con_Printf( "Server: Size of %s > %f MB, deleting.\n", filename, hpk_maxsize.value );
|
||||
Log_Printf( "Server: Size of %s > %f MB, deleting.\n", filename, hpk_maxsize.value );
|
||||
Con_Printf( "Server: Size of %s > %f MB, deleting.\n", filename, hpk_maxsize->value );
|
||||
Log_Printf( "Server: Size of %s > %f MB, deleting.\n", filename, hpk_maxsize->value );
|
||||
FS_Delete( filename );
|
||||
}
|
||||
}
|
||||
@@ -547,9 +530,9 @@ qboolean HPAK_ResourceForHash( const char *filename, byte *hash, resource_t *pRe
|
||||
}
|
||||
|
||||
Q_strncpy( pakname, filename, sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk", sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk" );
|
||||
|
||||
f = FS_Open( pakname, "rb", true );
|
||||
f = FS_Open( pakname, "rb", false );
|
||||
if( !f ) return false;
|
||||
|
||||
FS_Read( f, &header, sizeof( header ));
|
||||
@@ -595,9 +578,9 @@ static qboolean HPAK_ResourceForIndex( const char *filename, int index, resource
|
||||
return false;
|
||||
|
||||
Q_strncpy( pakname, filename, sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk", sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk" );
|
||||
|
||||
f = FS_Open( pakname, "rb", true );
|
||||
f = FS_Open( pakname, "rb", false );
|
||||
if( !f )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "couldn't open %s.\n", pakname );
|
||||
@@ -638,7 +621,7 @@ static qboolean HPAK_ResourceForIndex( const char *filename, int index, resource
|
||||
|
||||
directory.entries = Z_Malloc( sizeof( hpak_lump_t ) * directory.count );
|
||||
FS_Read( f, directory.entries, sizeof( hpak_lump_t ) * directory.count );
|
||||
HPAK_ResourceFromCompat( pResource, &directory.entries[index-1].resource );
|
||||
*pResource = directory.entries[index-1].resource;
|
||||
Z_Free( directory.entries );
|
||||
FS_Close( f );
|
||||
|
||||
@@ -664,7 +647,7 @@ qboolean HPAK_GetDataPointer( const char *filename, resource_t *pResource, byte
|
||||
|
||||
for( p = gp_hpak_queue; p != NULL; p = p->next )
|
||||
{
|
||||
if( !Q_stricmp( p->name, filename ) && !memcmp( p->resource.rgucMD5_hash, pResource->rgucMD5_hash, 16 ))
|
||||
if( !Q_stricmp(p->name, filename ) && !memcmp( p->resource.rgucMD5_hash, pResource->rgucMD5_hash, 16 ))
|
||||
{
|
||||
if( buffer )
|
||||
{
|
||||
@@ -681,9 +664,9 @@ qboolean HPAK_GetDataPointer( const char *filename, resource_t *pResource, byte
|
||||
}
|
||||
|
||||
Q_strncpy( pakname, filename, sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk", sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk" );
|
||||
|
||||
f = FS_Open( pakname, "rb", true );
|
||||
f = FS_Open( pakname, "rb", false );
|
||||
if( !f ) return false;
|
||||
|
||||
FS_Read( f, &header, sizeof( header ));
|
||||
@@ -719,13 +702,11 @@ qboolean HPAK_GetDataPointer( const char *filename, resource_t *pResource, byte
|
||||
{
|
||||
entry = &directory.entries[i];
|
||||
|
||||
if( entry->filepos > 0 &&
|
||||
entry->disksize > 0 &&
|
||||
!memcmp( entry->resource.rgucMD5_hash, pResource->rgucMD5_hash, 16 ))
|
||||
if( !memcmp( entry->resource.rgucMD5_hash, pResource->rgucMD5_hash, 16 ))
|
||||
{
|
||||
FS_Seek( f, entry->filepos, SEEK_SET );
|
||||
|
||||
if( buffer )
|
||||
if( buffer && entry->disksize > 0 )
|
||||
{
|
||||
tmpbuf = Z_Malloc( entry->disksize );
|
||||
FS_Read( f, tmpbuf, entry->disksize );
|
||||
@@ -764,9 +745,9 @@ void HPAK_RemoveLump( const char *name, resource_t *pResource )
|
||||
HPAK_FlushHostQueue();
|
||||
|
||||
Q_strncpy( read_path, name, sizeof( read_path ));
|
||||
COM_ReplaceExtension( read_path, ".hpk", sizeof( read_path ));
|
||||
COM_ReplaceExtension( read_path, ".hpk" );
|
||||
|
||||
file_src = FS_Open( read_path, "rb", true );
|
||||
file_src = FS_Open( read_path, "rb", false );
|
||||
if( !file_src )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s couldn't open.\n", read_path );
|
||||
@@ -774,8 +755,8 @@ void HPAK_RemoveLump( const char *name, resource_t *pResource )
|
||||
}
|
||||
|
||||
Q_strncpy( save_path, read_path, sizeof( save_path ));
|
||||
COM_ReplaceExtension( save_path, ".hp2", sizeof( save_path ));
|
||||
file_dst = FS_Open( save_path, "wb", true );
|
||||
COM_ReplaceExtension( save_path, ".hp2" );
|
||||
file_dst = FS_Open( save_path, "wb", false );
|
||||
|
||||
if( !file_dst )
|
||||
{
|
||||
@@ -893,10 +874,10 @@ void HPAK_List_f( void )
|
||||
HPAK_FlushHostQueue();
|
||||
|
||||
Q_strncpy( pakname, Cmd_Argv( 1 ), sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk", sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk" );
|
||||
Con_Printf( "Contents for %s.\n", pakname );
|
||||
|
||||
f = FS_Open( pakname, "rb", true );
|
||||
f = FS_Open( pakname, "rb", false );
|
||||
if( !f )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "couldn't open %s.\n", pakname );
|
||||
@@ -938,7 +919,7 @@ void HPAK_List_f( void )
|
||||
for( nCurrent = 0; nCurrent < directory.count; nCurrent++ )
|
||||
{
|
||||
entry = &directory.entries[nCurrent];
|
||||
COM_FileBase( entry->resource.szFileName, lumpname, sizeof( lumpname ));
|
||||
COM_FileBase( entry->resource.szFileName, lumpname );
|
||||
type = HPAK_TypeFromIndex( entry->resource.type );
|
||||
size = Q_memprint( entry->resource.nDownloadSize );
|
||||
|
||||
@@ -984,10 +965,10 @@ void HPAK_Extract_f( void )
|
||||
HPAK_FlushHostQueue();
|
||||
|
||||
Q_strncpy( pakname, Cmd_Argv( 1 ), sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk", sizeof( pakname ));
|
||||
COM_ReplaceExtension( pakname, ".hpk" );
|
||||
Con_Printf( "Contents for %s.\n", pakname );
|
||||
|
||||
f = FS_Open( pakname, "rb", true );
|
||||
f = FS_Open( pakname, "rb", false );
|
||||
if( !f )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "couldn't open %s.\n", pakname );
|
||||
@@ -1033,13 +1014,13 @@ void HPAK_Extract_f( void )
|
||||
if( nIndex != -1 && nIndex != nCurrent )
|
||||
continue;
|
||||
|
||||
COM_FileBase( entry->resource.szFileName, lumpname, sizeof( lumpname ) );
|
||||
COM_FileBase( entry->resource.szFileName, lumpname );
|
||||
type = HPAK_TypeFromIndex( entry->resource.type );
|
||||
size = Q_memprint( entry->resource.nDownloadSize );
|
||||
|
||||
Con_Printf( "Extracting %i: %10s %s %s\n", nCurrent + 1, type, size, lumpname );
|
||||
|
||||
if( entry->disksize < HPAK_ENTRY_MIN_SIZE || entry->disksize > HPAK_ENTRY_MAX_SIZE )
|
||||
if( entry->disksize <= 0 || entry->disksize >= HPAK_MAX_SIZE )
|
||||
{
|
||||
Con_DPrintf( S_WARN "Unable to extract data, size invalid: %s\n", Q_memprint( entry->disksize ));
|
||||
continue;
|
||||
@@ -1091,7 +1072,7 @@ void HPAK_Validate_f( void )
|
||||
return;
|
||||
}
|
||||
|
||||
HPAK_Validate( Cmd_Argv( 1 ), false, false );
|
||||
HPAK_Validate( Cmd_Argv( 1 ), false );
|
||||
}
|
||||
|
||||
void HPAK_Init( void )
|
||||
@@ -1100,7 +1081,7 @@ void HPAK_Init( void )
|
||||
Cmd_AddRestrictedCommand( "hpkremove", HPAK_Remove_f, "remove specified file from HPK-file" );
|
||||
Cmd_AddRestrictedCommand( "hpkval", HPAK_Validate_f, "validate specified HPK-file" );
|
||||
Cmd_AddRestrictedCommand( "hpkextract", HPAK_Extract_f, "extract all lumps from specified HPK-file" );
|
||||
Cvar_RegisterVariable( &hpk_maxsize );
|
||||
hpk_maxsize = Cvar_Get( "hpk_maxsize", "0", FCVAR_ARCHIVE, "set limit by size for all HPK-files ( 0 - unlimited )" );
|
||||
|
||||
gp_hpak_queue = NULL;
|
||||
}
|
||||
|
||||
@@ -37,53 +37,24 @@ infotable dlumpinfo_t[dwadinfo_t->numlumps]
|
||||
#define IDHPAKHEADER (('K'<<24)+('A'<<16)+('P'<<8)+'H') // little-endian "HPAK"
|
||||
#define IDHPAK_VERSION 1
|
||||
|
||||
// a1ba: because Valve for some reason writes resource_t to file
|
||||
// I had to make it crossplatform version
|
||||
#pragma pack( push, 8 )
|
||||
typedef struct dresource_s
|
||||
{
|
||||
char szFileName[64]; /* 0 64 */
|
||||
/* --- cacheline 1 boundary (64 bytes) --- */
|
||||
resourcetype_t type; /* 64 4 */
|
||||
int nIndex; /* 68 4 */
|
||||
int nDownloadSize; /* 72 4 */
|
||||
unsigned char ucFlags; /* 76 1 */
|
||||
unsigned char rgucMD5_hash[16]; /* 77 16 */
|
||||
unsigned char playernum; /* 93 1 */
|
||||
unsigned char rguc_reserved[32]; /* 94 32 */
|
||||
|
||||
/* XXX 2 bytes hole, try to pack */
|
||||
|
||||
/* --- cacheline 2 boundary (128 bytes) --- */
|
||||
uint32_t pNext; /* 128 4 */
|
||||
uint32_t pPrev; /* 132 4 */
|
||||
|
||||
/* size: 136, cachelines: 3, members: 10 */
|
||||
/* sum members: 134, holes: 1, sum holes: 2 */
|
||||
/* last cacheline: 8 bytes */
|
||||
} dresource_t;
|
||||
#pragma pack( pop )
|
||||
|
||||
STATIC_ASSERT( sizeof( dresource_t ) == 136, "invalid dresource_t size, HPAKs won't be compatible (no custom logo in multiplayer!)" );
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident; // should be equal HPAK
|
||||
int version;
|
||||
int infotableofs;
|
||||
int ident; // should be equal HPAK
|
||||
int version;
|
||||
int infotableofs;
|
||||
} hpak_header_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
dresource_t resource;
|
||||
int filepos;
|
||||
int disksize;
|
||||
resource_t resource;
|
||||
int filepos;
|
||||
int disksize;
|
||||
} hpak_lump_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int count;
|
||||
hpak_lump_t *entries; // variable sized.
|
||||
int count;
|
||||
hpak_lump_t *entries; // variable sized.
|
||||
} hpak_info_t;
|
||||
|
||||
#endif // HPAK_H
|
||||
|
||||
@@ -35,7 +35,7 @@ static bloomfilter_t id;
|
||||
|
||||
#define bf64_mask ((1U<<6)-1)
|
||||
|
||||
static bloomfilter_t BloomFilter_Process( const char *buffer, int size )
|
||||
bloomfilter_t BloomFilter_Process( const char *buffer, int size )
|
||||
{
|
||||
dword crc32;
|
||||
bloomfilter_t value = 0;
|
||||
@@ -55,12 +55,12 @@ static bloomfilter_t BloomFilter_Process( const char *buffer, int size )
|
||||
return value;
|
||||
}
|
||||
|
||||
static bloomfilter_t BloomFilter_ProcessStr( const char *buffer )
|
||||
bloomfilter_t BloomFilter_ProcessStr( const char *buffer )
|
||||
{
|
||||
return BloomFilter_Process( buffer, Q_strlen( buffer ) );
|
||||
}
|
||||
|
||||
static uint BloomFilter_Weight( bloomfilter_t value )
|
||||
uint BloomFilter_Weight( bloomfilter_t value )
|
||||
{
|
||||
int weight = 0;
|
||||
|
||||
@@ -77,7 +77,7 @@ static uint BloomFilter_Weight( bloomfilter_t value )
|
||||
return weight;
|
||||
}
|
||||
|
||||
static qboolean BloomFilter_ContainsString( bloomfilter_t filter, const char *str )
|
||||
qboolean BloomFilter_ContainsString( bloomfilter_t filter, const char *str )
|
||||
{
|
||||
bloomfilter_t value = BloomFilter_ProcessStr( str );
|
||||
|
||||
@@ -94,9 +94,9 @@ IDENTIFICATION
|
||||
#define MAXBITS_GEN 30
|
||||
#define MAXBITS_CHECK MAXBITS_GEN + 6
|
||||
|
||||
static qboolean ID_ProcessFile( bloomfilter_t *value, const char *path );
|
||||
qboolean ID_ProcessFile( bloomfilter_t *value, const char *path );
|
||||
|
||||
static void ID_BloomFilter_f( void )
|
||||
void ID_BloomFilter_f( void )
|
||||
{
|
||||
bloomfilter_t value = 0;
|
||||
int i;
|
||||
@@ -111,7 +111,7 @@ static void ID_BloomFilter_f( void )
|
||||
// Msg( "%s: %d\n", Cmd_Argv( i ), BloomFilter_ContainsString( value, Cmd_Argv( i ) ) );
|
||||
}
|
||||
|
||||
static qboolean ID_VerifyHEX( const char *hex )
|
||||
qboolean ID_VerifyHEX( const char *hex )
|
||||
{
|
||||
uint chars = 0;
|
||||
char prev = 0;
|
||||
@@ -153,7 +153,7 @@ static qboolean ID_VerifyHEX( const char *hex )
|
||||
return false;
|
||||
}
|
||||
|
||||
static void ID_VerifyHEX_f( void )
|
||||
void ID_VerifyHEX_f( void )
|
||||
{
|
||||
if( ID_VerifyHEX( Cmd_Argv( 1 ) ) )
|
||||
Msg( "Good\n" );
|
||||
@@ -162,7 +162,7 @@ static void ID_VerifyHEX_f( void )
|
||||
}
|
||||
|
||||
#if XASH_LINUX
|
||||
static qboolean ID_ProcessCPUInfo( bloomfilter_t *value )
|
||||
qboolean ID_ProcessCPUInfo( bloomfilter_t *value )
|
||||
{
|
||||
int cpuinfofd = open( "/proc/cpuinfo", O_RDONLY );
|
||||
char buffer[1024], *pbuf, *pbuf2;
|
||||
@@ -198,7 +198,7 @@ static qboolean ID_ProcessCPUInfo( bloomfilter_t *value )
|
||||
return true;
|
||||
}
|
||||
|
||||
static qboolean ID_ValidateNetDevice( const char *dev )
|
||||
qboolean ID_ValidateNetDevice( const char *dev )
|
||||
{
|
||||
const char *prefix = "/sys/class/net";
|
||||
byte *pfile;
|
||||
@@ -226,7 +226,7 @@ static qboolean ID_ValidateNetDevice( const char *dev )
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ID_ProcessNetDevices( bloomfilter_t *value )
|
||||
int ID_ProcessNetDevices( bloomfilter_t *value )
|
||||
{
|
||||
const char *prefix = "/sys/class/net";
|
||||
DIR *dir;
|
||||
@@ -250,7 +250,7 @@ static int ID_ProcessNetDevices( bloomfilter_t *value )
|
||||
return count;
|
||||
}
|
||||
|
||||
static int ID_CheckNetDevices( bloomfilter_t value )
|
||||
int ID_CheckNetDevices( bloomfilter_t value )
|
||||
{
|
||||
const char *prefix = "/sys/class/net";
|
||||
|
||||
@@ -278,7 +278,7 @@ static int ID_CheckNetDevices( bloomfilter_t value )
|
||||
return count;
|
||||
}
|
||||
|
||||
static void ID_TestCPUInfo_f( void )
|
||||
void ID_TestCPUInfo_f( void )
|
||||
{
|
||||
bloomfilter_t value = 0;
|
||||
|
||||
@@ -290,7 +290,7 @@ static void ID_TestCPUInfo_f( void )
|
||||
|
||||
#endif
|
||||
|
||||
static qboolean ID_ProcessFile( bloomfilter_t *value, const char *path )
|
||||
qboolean ID_ProcessFile( bloomfilter_t *value, const char *path )
|
||||
{
|
||||
int fd = open( path, O_RDONLY );
|
||||
char buffer[256];
|
||||
@@ -317,7 +317,7 @@ static qboolean ID_ProcessFile( bloomfilter_t *value, const char *path )
|
||||
}
|
||||
|
||||
#if !XASH_WIN32
|
||||
static int ID_ProcessFiles( bloomfilter_t *value, const char *prefix, const char *postfix )
|
||||
int ID_ProcessFiles( bloomfilter_t *value, const char *prefix, const char *postfix )
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
@@ -337,7 +337,7 @@ static int ID_ProcessFiles( bloomfilter_t *value, const char *prefix, const char
|
||||
return count;
|
||||
}
|
||||
|
||||
static int ID_CheckFiles( bloomfilter_t value, const char *prefix, const char *postfix )
|
||||
int ID_CheckFiles( bloomfilter_t value, const char *prefix, const char *postfix )
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
@@ -360,7 +360,7 @@ static int ID_CheckFiles( bloomfilter_t value, const char *prefix, const char *p
|
||||
return count;
|
||||
}
|
||||
#else
|
||||
static int ID_GetKeyData( HKEY hRootKey, char *subKey, char *value, LPBYTE data, DWORD cbData )
|
||||
int ID_GetKeyData( HKEY hRootKey, char *subKey, char *value, LPBYTE data, DWORD cbData )
|
||||
{
|
||||
HKEY hKey;
|
||||
|
||||
@@ -376,7 +376,7 @@ static int ID_GetKeyData( HKEY hRootKey, char *subKey, char *value, LPBYTE data,
|
||||
RegCloseKey( hKey );
|
||||
return 1;
|
||||
}
|
||||
static int ID_SetKeyData( HKEY hRootKey, char *subKey, DWORD dwType, char *value, LPBYTE data, DWORD cbData)
|
||||
int ID_SetKeyData( HKEY hRootKey, char *subKey, DWORD dwType, char *value, LPBYTE data, DWORD cbData)
|
||||
{
|
||||
HKEY hKey;
|
||||
if( RegCreateKey( hRootKey, subKey, &hKey ) != ERROR_SUCCESS )
|
||||
@@ -394,7 +394,7 @@ static int ID_SetKeyData( HKEY hRootKey, char *subKey, DWORD dwType, char *value
|
||||
|
||||
#define BUFSIZE 4096
|
||||
|
||||
static int ID_RunWMIC(char *buffer, const char *cmdline)
|
||||
int ID_RunWMIC(char *buffer, const char *cmdline)
|
||||
{
|
||||
HANDLE g_IN_Rd = NULL;
|
||||
HANDLE g_IN_Wr = NULL;
|
||||
@@ -438,7 +438,7 @@ static int ID_RunWMIC(char *buffer, const char *cmdline)
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
static int ID_ProcessWMIC( bloomfilter_t *value, const char *cmdline )
|
||||
int ID_ProcessWMIC( bloomfilter_t *value, const char *cmdline )
|
||||
{
|
||||
char buffer[BUFSIZE], token[BUFSIZE], *pbuf;
|
||||
int count = 0;
|
||||
@@ -458,7 +458,7 @@ static int ID_ProcessWMIC( bloomfilter_t *value, const char *cmdline )
|
||||
return count;
|
||||
}
|
||||
|
||||
static int ID_CheckWMIC( bloomfilter_t value, const char *cmdline )
|
||||
int ID_CheckWMIC( bloomfilter_t value, const char *cmdline )
|
||||
{
|
||||
char buffer[BUFSIZE], token[BUFSIZE], *pbuf;
|
||||
int count = 0;
|
||||
@@ -486,7 +486,7 @@ static int ID_CheckWMIC( bloomfilter_t value, const char *cmdline )
|
||||
char *IOS_GetUDID( void );
|
||||
#endif
|
||||
|
||||
static bloomfilter_t ID_GenerateRawId( void )
|
||||
bloomfilter_t ID_GenerateRawId( void )
|
||||
{
|
||||
bloomfilter_t value = 0;
|
||||
int count = 0;
|
||||
@@ -519,7 +519,7 @@ static bloomfilter_t ID_GenerateRawId( void )
|
||||
return value;
|
||||
}
|
||||
|
||||
static uint ID_CheckRawId( bloomfilter_t filter )
|
||||
uint ID_CheckRawId( bloomfilter_t filter )
|
||||
{
|
||||
bloomfilter_t value = 0;
|
||||
int count = 0;
|
||||
@@ -563,7 +563,7 @@ static uint ID_CheckRawId( bloomfilter_t filter )
|
||||
#define SYSTEM_XOR_MASK 0x10331c2dce4c91db
|
||||
#define GAME_XOR_MASK 0x7ffc48fbac1711f1
|
||||
|
||||
static void ID_Check( void )
|
||||
void ID_Check( void )
|
||||
{
|
||||
uint weight = BloomFilter_Weight( id );
|
||||
uint mincount = weight >> 2;
|
||||
@@ -677,7 +677,7 @@ void ID_Init( void )
|
||||
MD5Final( (byte*)md5, &hash );
|
||||
|
||||
for( i = 0; i < 16; i++ )
|
||||
Q_snprintf( &id_md5[i*2], sizeof( id_md5 ) - i * 2, "%02hhx", md5[i] );
|
||||
Q_sprintf( &id_md5[i*2], "%02hhx", md5[i] );
|
||||
|
||||
#if XASH_ANDROID && !XASH_DEDICATED
|
||||
Android_SaveID( va("%016llX", id^SYSTEM_XOR_MASK ) );
|
||||
|
||||
@@ -91,7 +91,7 @@ typedef struct imglib_s
|
||||
// global parms
|
||||
rgba_t fogParams; // some water textures has info about underwater fog
|
||||
|
||||
int hint; // hint for some loaders
|
||||
image_hint_t hint; // hint for some loaders
|
||||
byte *tempbuffer; // for convert operations
|
||||
int cmd_flags; // global imglib flags
|
||||
int force_flags; // override cmd_flags
|
||||
@@ -103,8 +103,6 @@ typedef struct imglib_s
|
||||
#define IMAGE_MAXHEIGHT 8192
|
||||
#define LUMP_MAXWIDTH 1024 // WorldCraft limits
|
||||
#define LUMP_MAXHEIGHT 1024
|
||||
#define PLDECAL_MAXWIDTH 512
|
||||
#define PLDECAL_MAXHEIGHT 512
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -173,6 +171,7 @@ rgbdata_t *Image_Quantize( rgbdata_t *pic );
|
||||
// img_utils.c
|
||||
//
|
||||
void Image_Reset( void );
|
||||
rgbdata_t *ImagePack( void );
|
||||
byte *Image_Copy( size_t size );
|
||||
void Image_CopyParms( rgbdata_t *src );
|
||||
qboolean Image_ValidSize( const char *name );
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user