mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-05 03:24:56 +08:00
Compare commits
260 Commits
16bit
...
dll-leak-d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c395acad63 | ||
|
|
8eec5389fe | ||
|
|
5524aaae1e | ||
|
|
acffeb1dad | ||
|
|
6c7d57e1eb | ||
|
|
7c9f5f8ab1 | ||
|
|
6b4f55c4bf | ||
|
|
89335938c1 | ||
|
|
437630d26d | ||
|
|
341c9dae39 | ||
|
|
c10b70cb61 | ||
|
|
4c7bf1ff44 | ||
|
|
f467d0c807 | ||
|
|
a717b7fc49 | ||
|
|
07a9c4602d | ||
|
|
eeb170af22 | ||
|
|
c532c3032c | ||
|
|
ae6ad74994 | ||
|
|
f417433f59 | ||
|
|
080dc38f11 | ||
|
|
13f93412cd | ||
|
|
ca975d0168 | ||
|
|
b82d0bad7a | ||
|
|
d1de9e2802 | ||
|
|
efdf9e3599 | ||
|
|
060835cf2f | ||
|
|
74485f30d3 | ||
|
|
8dda35a128 | ||
|
|
978ec27a57 | ||
|
|
113f18cfb0 | ||
|
|
6f36edfd16 | ||
|
|
5fb4edeb36 | ||
|
|
dd29e705f8 | ||
|
|
8445567ab4 | ||
|
|
11d4cb0f1e | ||
|
|
db48d0ded7 | ||
|
|
86a777880f | ||
|
|
0d195ee6fe | ||
|
|
5e4996b119 | ||
|
|
f25254369d | ||
|
|
9ce8edcb38 | ||
|
|
33d79ddb24 | ||
|
|
52d1383f14 | ||
|
|
843c9abf9b | ||
|
|
924e895753 | ||
|
|
ac40badaa5 | ||
|
|
fd83b0dc17 | ||
|
|
5715023a0d | ||
|
|
51526948c0 | ||
|
|
10ec32e264 | ||
|
|
4fbd96d201 | ||
|
|
81b01ac561 | ||
|
|
771c359ed0 | ||
|
|
d1a5c33bf1 | ||
|
|
641f0632ef | ||
|
|
974f0787a4 | ||
|
|
87ceb0f9cb | ||
|
|
cfcd58dd78 | ||
|
|
8044d23e7f | ||
|
|
b175d6d95f | ||
|
|
d3e213aa1b | ||
|
|
26e09c240a | ||
|
|
15eb6808c4 | ||
|
|
5402e1a259 | ||
|
|
74086cc4c1 | ||
|
|
9c85d114e7 | ||
|
|
81c4acab66 | ||
|
|
6f2fda427e | ||
|
|
09b7f22cee | ||
|
|
691a305f8e | ||
|
|
66dc20dc2d | ||
|
|
92cfa2af48 | ||
|
|
9515cccb94 | ||
|
|
a7d02b8268 | ||
|
|
22815d2784 | ||
|
|
95ee88720c | ||
|
|
58dbc1ba31 | ||
|
|
d7431783d4 | ||
|
|
c8410f7e46 | ||
|
|
80e20cb55b | ||
|
|
654bac83a5 | ||
|
|
fc7fb8b62d | ||
|
|
65d624140e | ||
|
|
cd2720ba81 | ||
|
|
d2f3b1974e | ||
|
|
91742d613d | ||
|
|
fba323cf1f | ||
|
|
f67d0ffa5a | ||
|
|
a6fbf5fb74 | ||
|
|
df616b950d | ||
|
|
37cf4da136 | ||
|
|
668d528e3b | ||
|
|
12da44a3d7 | ||
|
|
51fcae8cec | ||
|
|
6473efa995 | ||
|
|
cf7852832f | ||
|
|
29ad3de78a | ||
|
|
8169c2a40b | ||
|
|
85f99c723a | ||
|
|
edc171be04 | ||
|
|
9047fe2e74 | ||
|
|
24ea8fba4b | ||
|
|
e07417aead | ||
|
|
13b36e66b3 | ||
|
|
7821f425e7 | ||
|
|
f0783ddee1 | ||
|
|
d4d39c66fb | ||
|
|
a2d8a47376 | ||
|
|
3f7773f83b | ||
|
|
18933e7981 | ||
|
|
9917cba8fc | ||
|
|
203afda053 | ||
|
|
6dbb694fdc | ||
|
|
0c26c24331 | ||
|
|
51635995a2 | ||
|
|
988183a96a | ||
|
|
d8fd0b3dcb | ||
|
|
a6b43fbfff | ||
|
|
61643585e0 | ||
|
|
75e8a51058 | ||
|
|
3a55b9cd67 | ||
|
|
89baa633c8 | ||
|
|
1bf08cc2c3 | ||
|
|
36d757c74a | ||
|
|
0891356ec5 | ||
|
|
0fa1b4f944 | ||
|
|
56103a90eb | ||
|
|
2fa964e939 | ||
|
|
0027678a56 | ||
|
|
ffea7d9729 | ||
|
|
0e286f31c5 | ||
|
|
b9cec43e2c | ||
|
|
bb84a3cb7f | ||
|
|
5aa6bfee85 | ||
|
|
204544f50f | ||
|
|
df4f21680c | ||
|
|
2c1b862654 | ||
|
|
ea5937bce0 | ||
|
|
6e4ab74694 | ||
|
|
2c74a633d0 | ||
|
|
22e770e4d4 | ||
|
|
1f26710bd0 | ||
|
|
96f35f76e1 | ||
|
|
fa37d153c8 | ||
|
|
aa5594d11f | ||
|
|
6b332eabd2 | ||
|
|
13cf909b99 | ||
|
|
606b5354e6 | ||
|
|
e29dcb4125 | ||
|
|
c3513b1615 | ||
|
|
abbd0f92a4 | ||
|
|
f9d0fba05f | ||
|
|
1ffe050205 | ||
|
|
a2f741fe8a | ||
|
|
d0a39ef492 | ||
|
|
f63d2d747f | ||
|
|
7e687b45bb | ||
|
|
284eeea3c3 | ||
|
|
01b2266b7e | ||
|
|
0714ab27b5 | ||
|
|
4ae608913b | ||
|
|
295adcf222 | ||
|
|
3351ecd754 | ||
|
|
ccf90beb7d | ||
|
|
7fbbe9f015 | ||
|
|
46fd27eb14 | ||
|
|
f1a4d66d27 | ||
|
|
c619bb4af7 | ||
|
|
210137c325 | ||
|
|
d4d79573f6 | ||
|
|
b7a32f6843 | ||
|
|
f1dabf13a1 | ||
|
|
947b94d29f | ||
|
|
f007374866 | ||
|
|
7cb06956c2 | ||
|
|
ebfa8e6ffc | ||
|
|
7869aac2e5 | ||
|
|
f3dfbc9219 | ||
|
|
4f89288ccf | ||
|
|
fb8791529e | ||
|
|
f0feb1dfbf | ||
|
|
2df27e14a8 | ||
|
|
764ef93984 | ||
|
|
d8b3ab4dcc | ||
|
|
08e72bad35 | ||
|
|
7e574ea42e | ||
|
|
0963e05716 | ||
|
|
23e2f4d0cc | ||
|
|
ca3544d559 | ||
|
|
7a0a355baf | ||
|
|
f7bf081650 | ||
|
|
a4be009ce7 | ||
|
|
d3248aad66 | ||
|
|
000c594596 | ||
|
|
960a8959d5 | ||
|
|
2604ea39c5 | ||
|
|
dc186c3cba | ||
|
|
f60112773f | ||
|
|
37aa5b1e99 | ||
|
|
aa07dab8ab | ||
|
|
ac213c22ed | ||
|
|
e0efe0aa23 | ||
|
|
29bc0392ee | ||
|
|
054765232e | ||
|
|
89425e4bf2 | ||
|
|
a777e7c80d | ||
|
|
1350fd0b52 | ||
|
|
d7db48ce4b | ||
|
|
293482fbd5 | ||
|
|
3771a1d6c5 | ||
|
|
07f1f7ded1 | ||
|
|
1cac321c00 | ||
|
|
aa7bfb4819 | ||
|
|
0c18a06946 | ||
|
|
24edcf7d9e | ||
|
|
ecddae8ee6 | ||
|
|
1ab49adbf2 | ||
|
|
28b49e00e5 | ||
|
|
1e6be598e9 | ||
|
|
155e15939b | ||
|
|
3f014fde73 | ||
|
|
66db69862f | ||
|
|
fc665527ae | ||
|
|
0c6b51fa0c | ||
|
|
c00e77c02e | ||
|
|
25c0557f7f | ||
|
|
76ea3c39a0 | ||
|
|
e67bd4811a | ||
|
|
7a215766c6 | ||
|
|
576f0a72c5 | ||
|
|
55b4597390 | ||
|
|
c64b3db6b8 | ||
|
|
67e77ca099 | ||
|
|
f726793711 | ||
|
|
1944f48516 | ||
|
|
992bcd89ef | ||
|
|
2356bc9905 | ||
|
|
9159d406e3 | ||
|
|
508eb7ab5f | ||
|
|
1de1852409 | ||
|
|
664506f79e | ||
|
|
06eb6838a9 | ||
|
|
f2a9f805b8 | ||
|
|
c6648a69ba | ||
|
|
3203d9a043 | ||
|
|
8599119c8d | ||
|
|
a3d6e7bcfe | ||
|
|
36702aafe7 | ||
|
|
b93938956e | ||
|
|
c96f10d40b | ||
|
|
8a9231628e | ||
|
|
66d66eb835 | ||
|
|
9a4dec64f9 | ||
|
|
94dc74a37f | ||
|
|
b24c1a51d3 | ||
|
|
c79a649d97 | ||
|
|
f9d1d14848 | ||
|
|
1a1d81de62 | ||
|
|
6c9321e50c | ||
|
|
c366e25a10 |
32
.cirrus.yml
32
.cirrus.yml
@@ -1,22 +1,10 @@
|
||||
task:
|
||||
name: freebsd-11-amd64
|
||||
freebsd_instance:
|
||||
image_family: freebsd-11-4
|
||||
setup_script:
|
||||
- pkg update
|
||||
- pkg install -y git sdl2 python
|
||||
- git submodule update --init --recursive
|
||||
test_script:
|
||||
- ./scripts/cirrus/build_freebsd.sh dedicated
|
||||
- ./scripts/cirrus/build_freebsd.sh full
|
||||
|
||||
task:
|
||||
name: freebsd-12-amd64
|
||||
freebsd_instance:
|
||||
image_family: freebsd-12-2
|
||||
image_family: freebsd-12-3
|
||||
setup_script:
|
||||
- pkg update
|
||||
- pkg install -y git sdl2 python
|
||||
- pkg install -y git sdl2 python fontconfig
|
||||
- git submodule update --init --recursive
|
||||
test_script:
|
||||
- ./scripts/cirrus/build_freebsd.sh dedicated
|
||||
@@ -25,10 +13,22 @@ task:
|
||||
task:
|
||||
name: freebsd-13-amd64
|
||||
freebsd_instance:
|
||||
image_family: freebsd-13-0-snap
|
||||
image_family: freebsd-13-1
|
||||
setup_script:
|
||||
- pkg update
|
||||
- pkg install -y git sdl2 python
|
||||
- pkg install -y git sdl2 python fontconfig
|
||||
- git submodule update --init --recursive
|
||||
test_script:
|
||||
- ./scripts/cirrus/build_freebsd.sh dedicated
|
||||
- ./scripts/cirrus/build_freebsd.sh full
|
||||
|
||||
task:
|
||||
name: freebsd-14-amd64
|
||||
freebsd_instance:
|
||||
image_family: freebsd-14-0-snap
|
||||
setup_script:
|
||||
- pkg update
|
||||
- pkg install -y git sdl2 python fontconfig
|
||||
- git submodule update --init --recursive
|
||||
test_script:
|
||||
- ./scripts/cirrus/build_freebsd.sh dedicated
|
||||
|
||||
28
.github/workflows/c-cpp.yml
vendored
28
.github/workflows/c-cpp.yml
vendored
@@ -1,6 +1,11 @@
|
||||
name: Build & Deploy Engine
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
# cleanup:
|
||||
# runs-on: self-hosted
|
||||
# steps:
|
||||
# - name: Cleanup
|
||||
# run: rm -rf .* || true
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: true
|
||||
@@ -14,6 +19,9 @@ jobs:
|
||||
- os: ubuntu-18.04
|
||||
targetos: linux
|
||||
targetarch: i386
|
||||
# - os: ubuntu-aarch64-20.04
|
||||
# targetos: linux
|
||||
# targetarch: aarch64
|
||||
|
||||
- os: ubuntu-18.04
|
||||
targetos: android
|
||||
@@ -37,7 +45,6 @@ jobs:
|
||||
GH_CPU_ARCH: ${{ matrix.targetarch }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
ANDROID_SDK_TOOLS_VER: 4333796
|
||||
ANDROID_NDK_VER: r10e
|
||||
UPLOADTOOL_ISPRERELEASE: true
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -56,15 +63,10 @@ jobs:
|
||||
- name: Build engine
|
||||
run: bash scripts/gha/build_${{ matrix.targetos }}.sh
|
||||
|
||||
- name: Upload engine (android)
|
||||
if: matrix.targetos == 'android'
|
||||
run: bash scripts/continious_upload.sh xashdroid-${{ matrix.targetarch }}.apk
|
||||
- name: Upload engine (motomagx)
|
||||
if: matrix.targetos == 'motomagx'
|
||||
run: bash scripts/continious_upload.sh xash3d-fwgs-magx.7z
|
||||
- name: Upload engine (linux)
|
||||
if: matrix.targetos == 'linux'
|
||||
run: bash scripts/continious_upload.sh xash3d-fwgs-${{ matrix.targetarch }}.AppImage xashds-linux-${{ matrix.targetarch }}
|
||||
- name: Upload engine (windows)
|
||||
if: matrix.targetos == 'win32'
|
||||
run: bash scripts/continious_upload.sh xash3d-fwgs-win32-${{ matrix.targetarch }}.7z
|
||||
- name: Upload engine (prereleases)
|
||||
run: bash scripts/continious_upload.sh artifacts/*
|
||||
- name: Upload engine (artifacts)
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: artifact-${{ matrix.targetos }}-${{ matrix.targetarch }}
|
||||
path: artifacts/*
|
||||
|
||||
35
.travis.yml
35
.travis.yml
@@ -1,35 +0,0 @@
|
||||
language: c
|
||||
compiler: gcc
|
||||
sudo: false
|
||||
env:
|
||||
global:
|
||||
- SDL_VERSION=2.0.14
|
||||
git:
|
||||
depth: 50
|
||||
submodules: true
|
||||
|
||||
os: linux
|
||||
arch:
|
||||
- aarch64
|
||||
- ppc64le
|
||||
- s390x
|
||||
addons:
|
||||
apt:
|
||||
update: true
|
||||
packages:
|
||||
- libx11-dev
|
||||
- libxext-dev
|
||||
- x11-utils
|
||||
- libgl1-mesa-dev
|
||||
- libasound-dev
|
||||
- libstdc++6
|
||||
- libfuse2
|
||||
- unzip
|
||||
before_script:
|
||||
- sh scripts/travis/deps_common.sh
|
||||
- sh scripts/travis/deps_${TRAVIS_OS_NAME}.sh
|
||||
script:
|
||||
- sh scripts/travis/build_${TRAVIS_OS_NAME}.sh
|
||||
after_script:
|
||||
- ccache --show-stats
|
||||
- sh scripts/continious_upload.sh xash3d-fwgs-${ARCH}.tar.xz xashds-linux-${ARCH}
|
||||
@@ -24,6 +24,10 @@ Official github repository - https://github.com/CKFDevPowered/CKF3Alpha
|
||||
|
||||
## Cold Ice
|
||||
Version 1.9 is available on ModDB - https://www.moddb.com/mods/cold-ice/downloads/cold-ice-sdk
|
||||
Version 1.9 mirrored on github - https://github.com/solidi/hl-mods/tree/master/ci
|
||||
|
||||
## Cold Ice Ressurection
|
||||
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/cir
|
||||
|
||||
## Cthulhu
|
||||
Uploaded to github by Oleg Cherkasky - https://github.com/gunrunners-paradise/Cthulhu-HLmod-SDK
|
||||
@@ -46,8 +50,14 @@ Versions 2.0 and 3.0, available in mod archives on ModDB - https://www.moddb.com
|
||||
## GT mod
|
||||
Available on GamerLab - http://gamer-lab.com/eng/code_mods_goldsrc/GT_mod_(Polnie_ishodniki)
|
||||
|
||||
## Half-Life: Advanced Deathmatch
|
||||
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/hla
|
||||
|
||||
## Half-Life: Decay
|
||||
Mirrored on github(PC Port) - https://github.com/hoaxer/Half-Life-Decay
|
||||
|
||||
## Half-Life: Echoes
|
||||
Download link on dropbox - https://www.dropbox.com/s/s6j8gtegn10wgvj/dlls.zip?dl=1
|
||||
Available on ModDB - https://www.moddb.com/mods/half-life-echoes
|
||||
|
||||
## Half-Life: Expanded Arsenal
|
||||
Available on ModDB - https://www.moddb.com/mods/half-life-expanded-arsenal
|
||||
@@ -58,6 +68,9 @@ Branch **gravgun** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/g
|
||||
## Half-Life: Invasion
|
||||
official github repository - https://github.com/jlecorre/hlinvasion
|
||||
|
||||
## Half-Life: Pong
|
||||
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/pong
|
||||
|
||||
## Half-Life: Quest Mode
|
||||
Available on cs-mapping.com.ua - https://old.cs-mapping.com.ua/forum/showthread.php?t=38030
|
||||
|
||||
@@ -161,7 +174,7 @@ Branch **redempt** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/r
|
||||
OpenAG by YaLTeR - https://github.com/YaLTeR/OpenAG
|
||||
|
||||
## Afraid of Monsters
|
||||
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-aom
|
||||
malortie's recreation - https://github.com/malortie/hl-aom
|
||||
|
||||
Branch **aom** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/aom
|
||||
|
||||
@@ -169,17 +182,17 @@ Branch **aom** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/aom
|
||||
Reverse-engineered code, branch **aomdc** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/aomdc
|
||||
|
||||
## Azure Sheep
|
||||
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-asheep
|
||||
malortie's recreation - https://github.com/malortie/hl-asheep
|
||||
|
||||
Reverse-engineered code, branch **asheep** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/asheep
|
||||
|
||||
## Big Lolly
|
||||
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-biglolly
|
||||
malortie's recreation - https://github.com/malortie/hl-biglolly
|
||||
|
||||
Branch **biglolly** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/biglolly
|
||||
|
||||
## Black Ops
|
||||
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-blackops
|
||||
malortie's recreation - https://github.com/malortie/hl-blackops
|
||||
|
||||
Branch **blackops** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/blackops
|
||||
|
||||
@@ -206,7 +219,7 @@ CSO-like Xash3D-based mod, CSMoE - https://github.com/MoeMod/CSMoE
|
||||
Recreation by lostgamer aka nillerusr - https://github.com/LostGamerHL/crack_life
|
||||
|
||||
## Escape from the Darkness
|
||||
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-eftd
|
||||
malortie's recreation - https://github.com/malortie/hl-eftd
|
||||
|
||||
Reverse-engineered code, branch **eftd** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/eftd
|
||||
|
||||
@@ -229,7 +242,7 @@ Spirit of Half Life: Opposing-Force Edition - https://github.com/Hammermaps-DEV/
|
||||
Reverse-engineered code, branch **rebellion** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/rebellion
|
||||
|
||||
## Half-Life: Visitors
|
||||
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-visitors
|
||||
malortie's recreation - https://github.com/malortie/hl-visitors
|
||||
|
||||
Reverse-engineered code, branch **visitors** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/visitors
|
||||
|
||||
@@ -237,17 +250,17 @@ Reverse-engineered code, branch **visitors** in hlsdk-xash3d - https://github.co
|
||||
Branch **half-secret** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/half-secret
|
||||
|
||||
## Night at the Office
|
||||
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-noffice
|
||||
malortie's recreation - https://github.com/malortie/hl-nato
|
||||
|
||||
Branch **noffice** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/noffice
|
||||
|
||||
## Poke 646
|
||||
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-poke646
|
||||
malortie's recreation - https://github.com/malortie/hl-poke646
|
||||
|
||||
Reverse-engineered code, branch **poke646** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/poke646
|
||||
|
||||
## Poke 646: Vendetta
|
||||
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-poke646
|
||||
malortie's recreation - https://github.com/malortie/hl-poke646-vendetta
|
||||
|
||||
Reverse-engineered code, branch **poke646_vendetta** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/poke646_vendetta
|
||||
|
||||
@@ -261,19 +274,19 @@ Reverse-engineered code, branch **residual_point** in hlsdk-xash3d - https://git
|
||||
Reverse-engineered code by Velaron - https://github.com/Velaron/tf15-client
|
||||
|
||||
## The Gate
|
||||
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-TheGate
|
||||
malortie's recreation - https://github.com/malortie/hl-thegate
|
||||
|
||||
Reverse-engineered code, branch **thegate** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/thegate
|
||||
|
||||
## They Hunger
|
||||
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-Hunger
|
||||
malortie's recreation - https://github.com/malortie/hl-theyhunger
|
||||
|
||||
Reverse-engineered code, branch **theyhunger** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/theyhunger
|
||||
|
||||
They Hunger: Tactical - https://www.moddb.com/mods/they-hunger-tactical/downloads/tht-source-code-documentation
|
||||
|
||||
## Times of Troubles
|
||||
malortie's recreation - https://github.com/malortie/halflife/tree/mod-hl-tot
|
||||
malortie's recreation - https://github.com/malortie/hl-tot
|
||||
|
||||
Branch **tot** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/tot
|
||||
|
||||
@@ -295,7 +308,7 @@ Branch **dmc** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/dmc
|
||||
Branch **echoes** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/echoes
|
||||
|
||||
## Half-Life: Invasion
|
||||
Port to HLSDK 2.4 by malortie - https://github.com/malortie/halflife/tree/mod-hl-invasion
|
||||
Port to HLSDK 2.4 by malortie - https://github.com/malortie/hl-invasion
|
||||
|
||||
Port to Linux by fmoraw - https://github.com/fmoraw/hlinvasion
|
||||
|
||||
@@ -309,7 +322,7 @@ Branch **half-screwed** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/t
|
||||
Port to Linux - https://github.com/fmoraw/NS
|
||||
|
||||
## Swiss Cheese Halloween 2002
|
||||
Just more playable version by malortie - https://github.com/malortie/halflife/tree/mod-hl-halloween
|
||||
Just more playable version by malortie - https://github.com/malortie/hl-shall
|
||||
|
||||
Branch **halloween** in hlsdk-xash3d - https://github.com/FWGS/hlsdk-xash3d/tree/halloween
|
||||
|
||||
|
||||
@@ -15,24 +15,24 @@ Status:
|
||||
|
||||
Table is sorted by status.
|
||||
|
||||
| Platform | Status | Maintainer | Note
|
||||
| -------- | ------ | ---------- | ----
|
||||
| Windows | Supported | @a1batross |
|
||||
| *BSD | Supported | @nekonomicon |
|
||||
| GNU/Linux(x86, amd64, arm) | Supported | @a1batross, @mittorn |
|
||||
| Android | Supported | @a1batross, @mittorn |
|
||||
| MotoMAGX | Supported | @a1batross |
|
||||
| GNU/Linux(elbrus) | Supported | @a1batross, @mittorn | Rare and eventual access to e2k machine
|
||||
| Haiku | Supported | not maintained | Was added by #478 and #483
|
||||
| DOS4GW | Supported | @mittorn |
|
||||
| GNU/Linux(mipsel) | Supported | @mittorn |
|
||||
| Switch | In progress | @fgsfdsfgs | [Github Repository](https://github.com/fgsfdsfgs/xash3d-fwgs/tree/switch_new)
|
||||
| Wii | In progress | Collaborative effort | [Github Repository](https://github.com/saucesaft/xash3d-wii)
|
||||
| PSP | In progress | Collaborative effort | No sources available at this moment
|
||||
| Emscripten | Old Engine | not maintained |
|
||||
| Oculus Quest | Old Engine fork | @DrBeef | [GitHub Repository](https://github.com/DrBeef/Lambda1VR)
|
||||
| PSVita | Old Engine fork | not maintained | [GitHub Repository](https://github.com/fgsfdsfgs/vitaXash3D)
|
||||
| Switch | Old Engine fork | not maintained | [GitHub Repository](https://github.com/switchports/xash3d-switch)
|
||||
| 3DS | Old Engine fork | not maintained | [GitHub Repository](https://github.com/masterfeizz/Xash3DS)
|
||||
| macOS | Deprecated | not maintained | See GitHub issue #61
|
||||
| iOS | Deprecated | not maintained | See GitHub issue #61
|
||||
| Platform | Status | Maintainer | Note
|
||||
| -------- | ------ | ---------- | ----
|
||||
| Windows | Supported | @a1batross, @SNMetamorph |
|
||||
| *BSD | Supported | @nekonomicon |
|
||||
| GNU/Linux(x86, amd64, arm) | Supported | @a1batross, @mittorn |
|
||||
| Android | Supported | @a1batross, @mittorn |
|
||||
| MotoMAGX | Supported | @a1batross |
|
||||
| GNU/Linux(elbrus) | Supported | @a1batross, @mittorn | Rare and eventual access to e2k machine
|
||||
| Haiku | Supported | not maintained | Was added by #478 and #483
|
||||
| DOS4GW | Supported | @mittorn |
|
||||
| GNU/Linux(mipsel) | Supported | @mittorn |
|
||||
| Switch | In progress | @fgsfdsfgs | [GitHub Repository](https://github.com/fgsfdsfgs/xash3d-fwgs/tree/switch_new)
|
||||
| Wii | In progress | Collaborative effort | [GitHub Repository](https://github.com/saucesaft/xash3d-wii)
|
||||
| PSP | In progress | @Crow_bar, @Velaron | [GitHub Repository](https://github.com/Crow-bar/xash3d-fwgs)
|
||||
| Emscripten | Old Engine | not maintained |
|
||||
| Oculus Quest | Old Engine fork | @DrBeef | [GitHub Repository](https://github.com/DrBeef/Lambda1VR)
|
||||
| PSVita | Old Engine fork | not maintained | [GitHub Repository](https://github.com/fgsfdsfgs/vitaXash3D)
|
||||
| Switch | Old Engine fork | not maintained | [GitHub Repository](https://github.com/switchports/xash3d-switch)
|
||||
| 3DS | Old Engine fork | not maintained | [GitHub Repository](https://github.com/masterfeizz/Xash3DS)
|
||||
| macOS | Deprecated | not maintained | See GitHub issue #61
|
||||
| iOS | Deprecated | not maintained | See GitHub issue #61
|
||||
|
||||
39
README.md
39
README.md
@@ -1,5 +1,5 @@
|
||||
# Xash3D FWGS Engine
|
||||
[](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [](https://travis-ci.org/FWGS/xash3d-fwgs) [](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) [](http://discord.fwgs.ru/) \
|
||||
[](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) [](http://fwgsdiscord.mentality.rip/) \
|
||||
[](https://github.com/FWGS/xash3d-fwgs/releases/latest) [](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous)
|
||||
|
||||
Xash3D FWGS is a fork of Xash3D Engine by Unkle Mike with extended features and crossplatform.
|
||||
@@ -27,16 +27,13 @@ Read more about Xash3D on ModDB: https://www.moddb.com/engines/xash3d-engine
|
||||
* Vulkan renderer
|
||||
|
||||
## Installation & Running
|
||||
0) Get Xash3D binaries: you can use [testing](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous) build or you can compile engine from source code.
|
||||
Choose proper build package depending on which platform you're using.
|
||||
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.
|
||||
Also if you're using Windows: you should copy `vgui.dll` library from Half-Life directory to Xash3D directory.
|
||||
As alternative, you can compile [hlsdk-xash3d](https://github.com/FWGS/hlsdk-xash3d) instead of using official Valve game binaries, but you still needed to copy `valve` directory as all game resources located in there.
|
||||
3) Download [extras.pak](https://github.com/FWGS/xash-extras/releases/tag/v0.19.2) and place it to `valve` directory.
|
||||
4) Run `xash3d.exe`/`xash3d.sh`/`xash3d` depending on which platform you're using.
|
||||
|
||||
Note: on Linux, you may need to create an sh file with the command `LD_LIBRARY_PATH=. ./xash3d`.
|
||||
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).
|
||||
|
||||
For additional info, run Xash3D with `-help` command line key.
|
||||
|
||||
@@ -51,6 +48,13 @@ We are using Waf build system. If you have some Waf-related questions, I recomme
|
||||
NOTE: NEVER USE GitHub's ZIP ARCHIVES. GitHub doesn't include external dependencies we're using!
|
||||
|
||||
### Prerequisites
|
||||
|
||||
If your CPU is x86 compatible, we are building 32-bit code by default. This was 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-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)
|
||||
* Install Visual Studio.
|
||||
* Install latest [Python](https://python.org) **OR** run `cinst python.install` if you have Chocolatey.
|
||||
@@ -60,10 +64,6 @@ NOTE: NEVER USE GitHub's ZIP ARCHIVES. GitHub doesn't include external dependenc
|
||||
* Make sure you have at least 12GB of free space to store all build-time dependencies: ~10GB for Visual Studio, 300 MB for Git, 100 MB for Python and other.
|
||||
|
||||
#### GNU/Linux
|
||||
NOTE FOR USERS WITH X86 COMPATIBLE CPUs:
|
||||
We have forced Waf to throw an error, if you're trying to build 64-bit engine. This was done for keeping compatibility with Steam releases of Half-Life and based on it's engine games.
|
||||
Even if Xash3D FWGS does support targetting 64-bit, you can't load games without recompiling them from source code!
|
||||
|
||||
##### Debian/Ubuntu
|
||||
* Enable i386 on your system, if you're compiling 32-bit engine on amd64. If not, skip this
|
||||
|
||||
@@ -81,16 +81,15 @@ Even if Xash3D FWGS does support targetting 64-bit, you can't load games without
|
||||
0) Open command line
|
||||
1) Navigate to `xash3d-fwgs` directory.
|
||||
2) Carefully examine which build options are available: `waf --help`
|
||||
3) Configure build: `waf configure -T release --sdl2=c:/path/to/SDL2 --prefix=c:/path/to/any/output/directory`
|
||||
3) Configure build: `waf configure -T release --sdl2=c:/path/to/SDL2`
|
||||
4) Compile: `waf build`
|
||||
5) Install: `waf install`
|
||||
5) Install: `waf install --destdir=c:/path/to/any/output/directory`
|
||||
|
||||
#### Linux
|
||||
If compiling 32-bit on amd64, you may need to supply `export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig` prior to running configure.
|
||||
|
||||
0) Examine which build options are available: `./waf --help`
|
||||
1) Configure build: `./waf configure -T release --prefix=/path/to/any/output/directory`
|
||||
1) Configure build: `./waf configure -T release`
|
||||
(You need to pass `-8` to compile 64-bit engine on 64-bit x86 processor)
|
||||
2) Compile: `./waf build`
|
||||
3) Install(optional): `./waf install`
|
||||
|
||||
Note: if compiling 32-bit on amd64, you may need to supply `export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig` prior to running configure.
|
||||
|
||||
3) Install(optional): `./waf install --destdir=/path/to/any/output/directory`
|
||||
|
||||
@@ -9,7 +9,7 @@ NOTE: number at end of pixelformat name it's a total bitscount e.g. PF_RGB_24 ==
|
||||
========================================================================
|
||||
*/
|
||||
#define ImageRAW( type ) (type == PF_RGBA_32 || type == PF_BGRA_32 || type == PF_RGB_24 || type == PF_BGR_24 || type == PF_LUMINANCE)
|
||||
#define ImageDXT( type ) (type == PF_DXT1 || type == PF_DXT3 || type == PF_DXT5 || type == PF_ATI2)
|
||||
#define ImageDXT( type ) (type == PF_DXT1 || type == PF_DXT3 || type == PF_DXT5 || type == PF_ATI2 || type == PF_BC6H_SIGNED || type == PF_BC6H_UNSIGNED || type == PF_BC7)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -21,10 +21,13 @@ typedef enum
|
||||
PF_RGB_24, // uncompressed dds or another 24-bit image
|
||||
PF_BGR_24, // big-endian RGB (MacOS)
|
||||
PF_LUMINANCE,
|
||||
PF_DXT1, // s3tc DXT1 format
|
||||
PF_DXT3, // s3tc DXT3 format
|
||||
PF_DXT5, // s3tc DXT5 format
|
||||
PF_ATI2, // latc ATI2N format
|
||||
PF_DXT1, // s3tc DXT1/BC1 format
|
||||
PF_DXT3, // s3tc DXT3/BC2 format
|
||||
PF_DXT5, // s3tc DXT5/BC3 format
|
||||
PF_ATI2, // latc ATI2N/BC5 format
|
||||
PF_BC6H_SIGNED, // bptc BC6H signed FP16 format
|
||||
PF_BC6H_UNSIGNED, // bptc BC6H unsigned FP16 format
|
||||
PF_BC7, // bptc BC7 format
|
||||
PF_TOTALCOUNT, // must be last
|
||||
} pixformat_t;
|
||||
|
||||
@@ -82,7 +85,7 @@ typedef enum
|
||||
IMAGE_ROT_90 = BIT(18), // flip from upper left corner to down right corner
|
||||
IMAGE_ROT180 = IMAGE_FLIP_X|IMAGE_FLIP_Y,
|
||||
IMAGE_ROT270 = IMAGE_FLIP_X|IMAGE_FLIP_Y|IMAGE_ROT_90,
|
||||
IMAGE_EMBOSS = BIT(19), // apply emboss mapping
|
||||
// reserved
|
||||
IMAGE_RESAMPLE = BIT(20), // resample image to specified dims
|
||||
// reserved
|
||||
// reserved
|
||||
|
||||
@@ -725,7 +725,6 @@ typedef int string_t;
|
||||
typedef unsigned short word;
|
||||
|
||||
#include "xash3d_types.h"
|
||||
#define Q_isspace( ch ) (ch < 32 || ch > 255)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
@@ -25,14 +25,18 @@
|
||||
#define FCVAR_PRINTABLEONLY (1<<7) // This cvar's string cannot contain unprintable characters ( e.g., used for player name etc ).
|
||||
#define FCVAR_UNLOGGED (1<<8) // If this is a FCVAR_SERVER, don't log changes to the log file / console if we are creating a log
|
||||
#define FCVAR_NOEXTRAWHITEPACE (1<<9) // strip trailing/leading white space from this cvar
|
||||
#define FCVAR_PRIVILEGED (1<<10) // only available in privileged mode
|
||||
#define FCVAR_FILTERABLE (1<<11) // filtered in unprivileged mode if cl_filterstuffcmd is 1
|
||||
|
||||
#define FCVAR_MOVEVARS (1<<10) // this cvar is a part of movevars_t struct that shared between client and server
|
||||
#define FCVAR_LATCH (1<<11) // notify client what this cvar will be applied only after server restart (but don't does more nothing)
|
||||
// Xash3D extensions
|
||||
#define FCVAR_GLCONFIG (1<<12) // write it into <renderer>.cfg(see RefAPI)
|
||||
#define FCVAR_CHANGED (1<<13) // set each time the cvar is changed
|
||||
#define FCVAR_GAMEUIDLL (1<<14) // defined by the menu DLL
|
||||
#define FCVAR_CHEAT (1<<15) // can not be changed if cheats are disabled
|
||||
|
||||
// a1ba: let's reuse higher bits for flags extensions from now on
|
||||
#define FCVAR_LATCH (1<<30) // notify client what this cvar will be applied only after server restart (but don't does more nothing)
|
||||
|
||||
typedef struct cvar_s
|
||||
{
|
||||
char *name;
|
||||
|
||||
@@ -25,5 +25,6 @@ GNU General Public License for more details.
|
||||
#define ENGINE_COMPENSATE_QUAKE_BUG (1<<5) // compensate stupid quake bug (inverse pitch) for mods where this bug is fixed
|
||||
#define ENGINE_IMPROVED_LINETRACE (1<<6) // new traceline that tracing through alphatextures
|
||||
#define ENGINE_COMPUTE_STUDIO_LERP (1<<7) // enable MOVETYPE_STEP lerping back in engine
|
||||
#define ENGINE_LINEAR_GAMMA_SPACE (1<<8) // disable influence of gamma/brightness cvars to textures/lightmaps, for mods with custom renderer
|
||||
|
||||
#endif//FEATURES_H
|
||||
|
||||
@@ -18,6 +18,7 @@ GNU General Public License for more details.
|
||||
|
||||
#define GFL_NOMODELS (1<<0)
|
||||
#define GFL_NOSKILLS (1<<1)
|
||||
#define GFL_RENDER_PICBUTTON_TEXT (1<<2)
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
@@ -20,8 +20,6 @@ GNU General Public License for more details.
|
||||
#include "build.h"
|
||||
|
||||
#if !XASH_WIN32
|
||||
|
||||
|
||||
#if XASH_APPLE
|
||||
#include <sys/syslimits.h>
|
||||
#define OS_LIB_EXT "dylib"
|
||||
@@ -30,67 +28,32 @@ GNU General Public License for more details.
|
||||
#define OS_LIB_EXT "so"
|
||||
#define OPEN_COMMAND "xdg-open"
|
||||
#endif
|
||||
|
||||
#define OS_LIB_PREFIX "lib"
|
||||
|
||||
#if XASH_ANDROID
|
||||
//#if defined(LOAD_HARDFP)
|
||||
// #define POSTFIX "_hardfp"
|
||||
//#else
|
||||
#define POSTFIX
|
||||
//#endif
|
||||
#else
|
||||
#endif
|
||||
|
||||
#define VGUI_SUPPORT_DLL "libvgui_support." OS_LIB_EXT
|
||||
|
||||
// Windows-specific
|
||||
#define __cdecl
|
||||
#define __stdcall
|
||||
|
||||
#define _inline static inline
|
||||
#define FORCEINLINE inline __attribute__((always_inline))
|
||||
|
||||
#if XASH_POSIX
|
||||
#define PATH_SPLITTER "/"
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#define O_BINARY 0 // O_BINARY is Windows extension
|
||||
#define O_TEXT 0 // O_TEXT is Windows extension
|
||||
// Windows functions to posix equivalent
|
||||
#define _mkdir( x ) mkdir( x, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH )
|
||||
#define LoadLibrary( x ) dlopen( x, RTLD_NOW )
|
||||
#define GetProcAddress( x, y ) dlsym( x, y )
|
||||
#define FreeLibrary( x ) dlclose( x )
|
||||
#define tell( a ) lseek(a, 0, SEEK_CUR)
|
||||
#define HAVE_DUP
|
||||
#endif
|
||||
#if XASH_POSIX
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#if XASH_DOS4GW
|
||||
#define PATH_SPLITTER "\\"
|
||||
#define LoadLibrary( x ) (0)
|
||||
#define GetProcAddress( x, y ) (0)
|
||||
#define FreeLibrary( x ) (0)
|
||||
#endif
|
||||
//#define MAKEWORD( a, b ) ((short int)(((unsigned char)(a))|(((short int)((unsigned char)(b)))<<8)))
|
||||
#define max( a, b ) (((a) > (b)) ? (a) : (b))
|
||||
#define min( a, b ) (((a) < (b)) ? (a) : (b))
|
||||
#define PATH_SPLITTER "/"
|
||||
#define HAVE_DUP
|
||||
|
||||
/// TODO: check if we may clean this defines, it should not appear in non-platform code!
|
||||
typedef unsigned char BYTE;
|
||||
typedef short int WORD;
|
||||
typedef unsigned int DWORD;
|
||||
typedef int LONG;
|
||||
typedef unsigned int ULONG;
|
||||
typedef int WPARAM;
|
||||
typedef unsigned int LPARAM;
|
||||
#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;
|
||||
typedef void* HMODULE;
|
||||
typedef void* HINSTANCE;
|
||||
|
||||
typedef char* LPSTR;
|
||||
|
||||
typedef struct tagPOINT
|
||||
{
|
||||
int x, y;
|
||||
@@ -108,19 +71,6 @@ GNU General Public License for more details.
|
||||
#define read _read
|
||||
#define alloca _alloca
|
||||
|
||||
// shut-up compiler warnings
|
||||
#pragma warning(disable : 4244) // MIPS
|
||||
#pragma warning(disable : 4018) // signed/unsigned mismatch
|
||||
#pragma warning(disable : 4305) // truncation from const double to float
|
||||
#pragma warning(disable : 4115) // named type definition in parentheses
|
||||
#pragma warning(disable : 4100) // unreferenced formal parameter
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#pragma warning(disable : 4057) // differs in indirection to slightly different base types
|
||||
#pragma warning(disable : 4201) // nonstandard extension used
|
||||
#pragma warning(disable : 4706) // assignment within conditional expression
|
||||
#pragma warning(disable : 4054) // type cast' : from function pointer
|
||||
#pragma warning(disable : 4310) // cast truncates constant value
|
||||
|
||||
#define HSPRITE WINAPI_HSPRITE
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <winsock2.h>
|
||||
@@ -130,13 +80,9 @@ GNU General Public License for more details.
|
||||
#define OS_LIB_PREFIX ""
|
||||
#define OS_LIB_EXT "dll"
|
||||
#define VGUI_SUPPORT_DLL "../vgui_support." OS_LIB_EXT
|
||||
#ifdef XASH_64BIT
|
||||
// windows NameForFunction not implemented yet
|
||||
#define XASH_ALLOW_SAVERESTORE_OFFSETS
|
||||
#endif
|
||||
#define HAVE_DUP
|
||||
|
||||
#endif //WIN32
|
||||
|
||||
#ifndef XASH_LOW_MEMORY
|
||||
#define XASH_LOW_MEMORY 0
|
||||
#endif
|
||||
|
||||
@@ -82,7 +82,7 @@ typedef enum
|
||||
TF_KEEP_SOURCE = (1<<1), // some images keep source
|
||||
TF_NOFLIP_TGA = (1<<2), // Steam background completely ignore tga attribute 0x20
|
||||
TF_EXPAND_SOURCE = (1<<3), // Don't keep source as 8-bit expand to RGBA
|
||||
TF_ALLOW_EMBOSS = (1<<4), // Allow emboss-mapping for this image
|
||||
// reserved
|
||||
TF_RECTANGLE = (1<<5), // this is GL_TEXTURE_RECTANGLE
|
||||
TF_CUBEMAP = (1<<6), // it's cubemap texture
|
||||
TF_DEPTHMAP = (1<<7), // custom texture filter used
|
||||
@@ -107,6 +107,7 @@ typedef enum
|
||||
TF_ARB_FLOAT = (1<<26), // float textures
|
||||
TF_NOCOMPARE = (1<<27), // disable comparing for depth textures
|
||||
TF_ARB_16BIT = (1<<28), // keep image as 16-bit (not 24)
|
||||
TF_MULTISAMPLE = (1<<29) // multisampling texture
|
||||
} texFlags_t;
|
||||
|
||||
typedef enum
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
#ifndef XASH_TYPES_H
|
||||
#define XASH_TYPES_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "build.h"
|
||||
|
||||
#if XASH_WIN32
|
||||
#include <wchar.h> // off_t
|
||||
#endif // _WIN32
|
||||
|
||||
@@ -64,19 +66,25 @@ typedef uint64_t longtime_t;
|
||||
#define ColorIndex( c ) ((( c ) - '0' ) & 7 )
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#ifdef __i386__
|
||||
#define EXPORT __attribute__ ((visibility ("default"),force_align_arg_pointer))
|
||||
#define GAME_EXPORT __attribute((force_align_arg_pointer))
|
||||
#else
|
||||
#define EXPORT __attribute__ ((visibility ("default")))
|
||||
#define GAME_EXPORT
|
||||
#endif
|
||||
#ifdef __i386__
|
||||
#define EXPORT __attribute__ ((visibility ("default"),force_align_arg_pointer))
|
||||
#define GAME_EXPORT __attribute((force_align_arg_pointer))
|
||||
#else
|
||||
#define EXPORT __attribute__ ((visibility ("default")))
|
||||
#define GAME_EXPORT
|
||||
#endif
|
||||
#define _format(x) __attribute__((format(printf, x, x+1)))
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
#elif defined(_MSC_VER)
|
||||
#define EXPORT __declspec( dllexport )
|
||||
#define GAME_EXPORT
|
||||
#define EXPORT __declspec( dllexport )
|
||||
#define GAME_EXPORT
|
||||
#define _format(x)
|
||||
#define NORETURN
|
||||
#else
|
||||
#define EXPORT
|
||||
#define GAME_EXPORT
|
||||
#define EXPORT
|
||||
#define GAME_EXPORT
|
||||
#define _format(x)
|
||||
#define NORETURN
|
||||
#endif
|
||||
|
||||
|
||||
@@ -117,6 +125,11 @@ typedef struct file_s file_t; // normal file
|
||||
typedef struct wfile_s wfile_t; // wad file
|
||||
typedef struct stream_s stream_t; // sound stream for background music playing
|
||||
typedef off_t fs_offset_t;
|
||||
#if XASH_WIN32
|
||||
typedef int fs_size_t; // return type of _read, _write funcs
|
||||
#else /* !XASH_WIN32 */
|
||||
typedef ssize_t fs_size_t;
|
||||
#endif /* !XASH_WIN32 */
|
||||
|
||||
typedef struct dllfunc_s
|
||||
{
|
||||
@@ -132,7 +145,7 @@ typedef struct dll_info_s
|
||||
void *link; // hinstance of loading library
|
||||
} dll_info_t;
|
||||
|
||||
typedef void (*setpair_t)( const char *key, const void *value, void *buffer, void *numpairs );
|
||||
typedef void (*setpair_t)( const char *key, const void *value, const void *buffer, void *numpairs );
|
||||
|
||||
// config strings are a general means of communication from
|
||||
// the server to all connected clients.
|
||||
|
||||
@@ -106,7 +106,7 @@ void CL_RemoveFromResourceList( resource_t *pResource )
|
||||
if( pResource->pPrev == NULL || pResource->pNext == NULL )
|
||||
Host_Error( "mislinked resource in CL_RemoveFromResourceList\n" );
|
||||
|
||||
if ( pResource->pNext == pResource || pResource->pPrev == pResource )
|
||||
if( pResource->pNext == pResource || pResource->pPrev == pResource )
|
||||
Host_Error( "attempt to free last entry in list.\n" );
|
||||
|
||||
pResource->pPrev->pNext = pResource->pNext;
|
||||
|
||||
@@ -188,8 +188,6 @@ void R_StoreEfrags( efrag_t **ppefrag, int framecount )
|
||||
case mod_brush:
|
||||
case mod_studio:
|
||||
case mod_sprite:
|
||||
pent = pefrag->entity;
|
||||
|
||||
if( pent->visframe != framecount )
|
||||
{
|
||||
if( CL_AddVisibleEntity( pent, ET_FRAGMENTED ))
|
||||
|
||||
@@ -46,7 +46,7 @@ short GAME_EXPORT R_LookupColor( byte r, byte g, byte b )
|
||||
float rf, gf, bf;
|
||||
|
||||
bestdiff = 999999;
|
||||
best = 65535;
|
||||
best = -1;
|
||||
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
@@ -683,42 +683,46 @@ void CL_ParseViewBeam( sizebuf_t *msg, int beamType )
|
||||
switch( beamType )
|
||||
{
|
||||
case TE_BEAMPOINTS:
|
||||
start[0] = MSG_ReadCoord( msg );
|
||||
start[1] = MSG_ReadCoord( msg );
|
||||
start[2] = MSG_ReadCoord( msg );
|
||||
end[0] = MSG_ReadCoord( msg );
|
||||
end[1] = MSG_ReadCoord( msg );
|
||||
end[2] = MSG_ReadCoord( msg );
|
||||
modelIndex = MSG_ReadShort( msg );
|
||||
startFrame = MSG_ReadByte( msg );
|
||||
frameRate = (float)MSG_ReadByte( msg );
|
||||
life = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
width = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
noise = (float)(MSG_ReadByte( msg ) * 0.01f);
|
||||
r = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
g = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
b = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
a = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
speed = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
R_BeamPoints( start, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
|
||||
break;
|
||||
case TE_BEAMENTPOINT:
|
||||
startEnt = MSG_ReadShort( msg );
|
||||
end[0] = MSG_ReadCoord( msg );
|
||||
end[1] = MSG_ReadCoord( msg );
|
||||
end[2] = MSG_ReadCoord( msg );
|
||||
case TE_BEAMENTS:
|
||||
if( beamType == TE_BEAMENTS )
|
||||
{
|
||||
startEnt = MSG_ReadShort( msg );
|
||||
endEnt = MSG_ReadShort( msg );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( beamType == TE_BEAMENTPOINT )
|
||||
{
|
||||
startEnt = MSG_ReadShort( msg );
|
||||
}
|
||||
else
|
||||
{
|
||||
start[0] = MSG_ReadCoord( msg );
|
||||
start[1] = MSG_ReadCoord( msg );
|
||||
start[2] = MSG_ReadCoord( msg );
|
||||
}
|
||||
end[0] = MSG_ReadCoord( msg );
|
||||
end[1] = MSG_ReadCoord( msg );
|
||||
end[2] = MSG_ReadCoord( msg );
|
||||
}
|
||||
modelIndex = MSG_ReadShort( msg );
|
||||
startFrame = MSG_ReadByte( msg );
|
||||
frameRate = (float)MSG_ReadByte( msg );
|
||||
life = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
width = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
noise = (float)(MSG_ReadByte( msg ) * 0.01f);
|
||||
frameRate = (float)MSG_ReadByte( msg ) * 0.1f;
|
||||
life = (float)MSG_ReadByte( msg ) * 0.1f;
|
||||
width = (float)MSG_ReadByte( msg ) * 0.1f;
|
||||
noise = (float)MSG_ReadByte( msg ) * 0.01f;
|
||||
r = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
g = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
b = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
a = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
speed = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
R_BeamEntPoint( startEnt, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
|
||||
speed = (float)MSG_ReadByte( msg ) * 0.1f;
|
||||
if( beamType == TE_BEAMENTS )
|
||||
R_BeamEnts( startEnt, endEnt, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
|
||||
else if( beamType == TE_BEAMENTPOINT )
|
||||
R_BeamEntPoint( startEnt, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
|
||||
else
|
||||
R_BeamPoints( start, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
|
||||
break;
|
||||
case TE_LIGHTNING:
|
||||
start[0] = MSG_ReadCoord( msg );
|
||||
@@ -727,27 +731,11 @@ void CL_ParseViewBeam( sizebuf_t *msg, int beamType )
|
||||
end[0] = MSG_ReadCoord( msg );
|
||||
end[1] = MSG_ReadCoord( msg );
|
||||
end[2] = MSG_ReadCoord( msg );
|
||||
life = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
width = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
noise = (float)(MSG_ReadByte( msg ) * 0.01f);
|
||||
life = (float)MSG_ReadByte( msg ) * 0.1f;
|
||||
width = (float)MSG_ReadByte( msg ) * 0.1f;
|
||||
noise = (float)MSG_ReadByte( msg ) * 0.01f;
|
||||
modelIndex = MSG_ReadShort( msg );
|
||||
R_BeamLightning( start, end, modelIndex, life, width, noise, 0.6F, 3.5f );
|
||||
break;
|
||||
case TE_BEAMENTS:
|
||||
startEnt = MSG_ReadShort( msg );
|
||||
endEnt = MSG_ReadShort( msg );
|
||||
modelIndex = MSG_ReadShort( msg );
|
||||
startFrame = MSG_ReadByte( msg );
|
||||
frameRate = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
life = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
width = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
noise = (float)(MSG_ReadByte( msg ) * 0.01f);
|
||||
r = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
g = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
b = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
a = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
speed = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
R_BeamEnts( startEnt, endEnt, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
|
||||
R_BeamLightning( start, end, modelIndex, life, width, noise, 0.6f, 3.5f );
|
||||
break;
|
||||
case TE_BEAM:
|
||||
break;
|
||||
@@ -773,21 +761,21 @@ void CL_ParseViewBeam( sizebuf_t *msg, int beamType )
|
||||
end[2] = MSG_ReadCoord( msg );
|
||||
modelIndex = MSG_ReadShort( msg );
|
||||
startFrame = MSG_ReadByte( msg );
|
||||
frameRate = (float)(MSG_ReadByte( msg ));
|
||||
life = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
width = (float)(MSG_ReadByte( msg ));
|
||||
noise = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
frameRate = (float)MSG_ReadByte( msg ) * 0.1f;
|
||||
life = (float)MSG_ReadByte( msg ) * 0.1f;
|
||||
width = (float)MSG_ReadByte( msg );
|
||||
noise = (float)MSG_ReadByte( msg ) * 0.01f;
|
||||
r = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
g = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
b = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
a = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
speed = (float)(MSG_ReadByte( msg ) / 0.1f);
|
||||
speed = (float)MSG_ReadByte( msg ) * 0.1f;
|
||||
R_BeamCirclePoints( beamType, start, end, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
|
||||
break;
|
||||
case TE_BEAMFOLLOW:
|
||||
startEnt = MSG_ReadShort( msg );
|
||||
modelIndex = MSG_ReadShort( msg );
|
||||
life = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
life = (float)MSG_ReadByte( msg ) * 0.1f;
|
||||
width = (float)MSG_ReadByte( msg );
|
||||
r = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
g = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
@@ -800,15 +788,15 @@ void CL_ParseViewBeam( sizebuf_t *msg, int beamType )
|
||||
endEnt = MSG_ReadShort( msg );
|
||||
modelIndex = MSG_ReadShort( msg );
|
||||
startFrame = MSG_ReadByte( msg );
|
||||
frameRate = (float)MSG_ReadByte( msg );
|
||||
life = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
width = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
noise = (float)(MSG_ReadByte( msg ) * 0.01f);
|
||||
frameRate = (float)MSG_ReadByte( msg ) * 0.1f;
|
||||
life = (float)MSG_ReadByte( msg ) * 0.1f;
|
||||
width = (float)MSG_ReadByte( msg ) * 0.1f;
|
||||
noise = (float)MSG_ReadByte( msg ) * 0.01f;
|
||||
r = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
g = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
b = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
a = (float)MSG_ReadByte( msg ) / 255.0f;
|
||||
speed = (float)(MSG_ReadByte( msg ) * 0.1f);
|
||||
speed = (float)MSG_ReadByte( msg ) * 0.1f;
|
||||
R_BeamRing( startEnt, endEnt, modelIndex, life, width, noise, a, speed, startFrame, frameRate, r, g, b );
|
||||
break;
|
||||
case TE_BEAMHOSE:
|
||||
@@ -1265,7 +1253,7 @@ void GAME_EXPORT R_BloodStream( const vec3_t org, const vec3_t dir, int pcolor,
|
||||
particle_t *p;
|
||||
int i, j;
|
||||
float arc;
|
||||
float accel = speed;
|
||||
int accel = speed; // must be integer due to bug in GoldSrc
|
||||
|
||||
for( arc = 0.05f, i = 0; i < 100; i++ )
|
||||
{
|
||||
|
||||
@@ -158,7 +158,7 @@ CL_EventIndex
|
||||
*/
|
||||
word CL_EventIndex( const char *name )
|
||||
{
|
||||
int i;
|
||||
word i;
|
||||
|
||||
if( !COM_CheckString( name ))
|
||||
return 0;
|
||||
@@ -484,7 +484,7 @@ void GAME_EXPORT CL_PlaybackEvent( int flags, const edict_t *pInvoker, word even
|
||||
return;
|
||||
|
||||
// first check event for out of bounds
|
||||
if( eventindex < 1 || eventindex > MAX_EVENTS )
|
||||
if( eventindex < 1 || eventindex >= MAX_EVENTS )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "CL_PlaybackEvent: invalid eventindex %i\n", eventindex );
|
||||
return;
|
||||
|
||||
@@ -58,10 +58,13 @@ void CL_UpdatePositions( cl_entity_t *ent )
|
||||
|
||||
ent->current_position = (ent->current_position + 1) & HISTORY_MASK;
|
||||
ph = &ent->ph[ent->current_position];
|
||||
|
||||
VectorCopy( ent->curstate.origin, ph->origin );
|
||||
VectorCopy( ent->curstate.angles, ph->angles );
|
||||
ph->animtime = ent->curstate.animtime; // !!!
|
||||
|
||||
if( ent->model && ent->model->type == mod_brush )
|
||||
ph->animtime = ent->curstate.animtime;
|
||||
else
|
||||
ph->animtime = cl.time;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -219,7 +222,7 @@ void CL_UpdateLatchedVars( cl_entity_t *ent )
|
||||
|
||||
if( ent->curstate.sequence != ent->prevstate.sequence )
|
||||
{
|
||||
memcpy( ent->prevstate.blending, ent->latched.prevseqblending, sizeof( ent->prevstate.blending ));
|
||||
memcpy( ent->latched.prevseqblending, ent->prevstate.blending, sizeof( ent->latched.prevseqblending ));
|
||||
ent->latched.prevsequence = ent->prevstate.sequence;
|
||||
ent->latched.sequencetime = ent->curstate.animtime;
|
||||
}
|
||||
@@ -310,7 +313,7 @@ void CL_ProcessEntityUpdate( cl_entity_t *ent )
|
||||
if( FBitSet( ent->curstate.entityType, ENTITY_NORMAL ))
|
||||
COM_NormalizeAngles( ent->curstate.angles );
|
||||
|
||||
parametric = CL_ParametricMove( ent );
|
||||
parametric = ent->curstate.starttime != 0.0f && ent->curstate.impacttime != 0.0f;
|
||||
|
||||
// allow interpolation on bmodels too
|
||||
if( ent->model && ent->model->type == mod_brush )
|
||||
@@ -349,7 +352,7 @@ find two timestamps
|
||||
qboolean CL_FindInterpolationUpdates( cl_entity_t *ent, float targettime, position_history_t **ph0, position_history_t **ph1 )
|
||||
{
|
||||
qboolean extrapolate = true;
|
||||
int i, i0, i1, imod;
|
||||
uint i, i0, i1, imod;
|
||||
float at;
|
||||
|
||||
imod = ent->current_position;
|
||||
@@ -406,7 +409,7 @@ void CL_PureOrigin( cl_entity_t *ent, float t, vec3_t outorigin, vec3_t outangle
|
||||
|
||||
VectorSubtract( ph0->origin, ph1->origin, delta );
|
||||
|
||||
if( t0 != t1 )
|
||||
if( !Q_equal( t0, t1 ))
|
||||
frac = ( t - t1 ) / ( t0 - t1 );
|
||||
else frac = 1.0f;
|
||||
|
||||
@@ -486,7 +489,9 @@ int CL_InterpolateModel( cl_entity_t *e )
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( t2 == t1 )
|
||||
// HACKHACK: workaround buggy position history animtime
|
||||
// going backward sometimes
|
||||
if( Q_equal( t2, t1 ) || t2 < t1 )
|
||||
{
|
||||
VectorCopy( ph0->origin, e->origin );
|
||||
VectorCopy( ph0->angles, e->angles );
|
||||
@@ -978,8 +983,13 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
|
||||
}
|
||||
|
||||
// don't add the player in firstperson mode
|
||||
if( RP_LOCALCLIENT( ent ) && !CL_IsThirdPerson( ) && ( ent->index == cl.viewentity ))
|
||||
return false;
|
||||
if( RP_LOCALCLIENT( ent ))
|
||||
{
|
||||
cl.local.apply_effects = true;
|
||||
|
||||
if( !CL_IsThirdPerson( ) && ( ent->index == cl.viewentity ))
|
||||
return false;
|
||||
}
|
||||
|
||||
if( entityType == ET_BEAM )
|
||||
{
|
||||
@@ -993,12 +1003,8 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
|
||||
|
||||
// because pTemp->entity.curstate.effects
|
||||
// is already occupied by FTENT_FLICKER
|
||||
if( entityType != ET_TEMPENTITY )
|
||||
if( entityType != ET_TEMPENTITY && !RP_LOCALCLIENT( ent ) )
|
||||
{
|
||||
// no reason to do it twice
|
||||
if( RP_LOCALCLIENT( ent ))
|
||||
cl.local.apply_effects = false;
|
||||
|
||||
// apply client-side effects
|
||||
CL_AddEntityEffects( ent );
|
||||
|
||||
@@ -1050,7 +1056,6 @@ void CL_LinkPlayers( frame_t *frame )
|
||||
// apply muzzleflash to weaponmodel
|
||||
if( ent && FBitSet( ent->curstate.effects, EF_MUZZLEFLASH ))
|
||||
SetBits( clgame.viewent.curstate.effects, EF_MUZZLEFLASH );
|
||||
cl.local.apply_effects = true;
|
||||
|
||||
// check all the clients but add only visible
|
||||
for( i = 0, state = frame->playerstate; i < MAX_CLIENTS; i++, state++ )
|
||||
|
||||
@@ -1744,6 +1744,29 @@ static int GAME_EXPORT pfnClientCmd( const char *szCmdString )
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
pfnFilteredClientCmd
|
||||
=============
|
||||
*/
|
||||
static int GAME_EXPORT pfnFilteredClientCmd( const char *szCmdString )
|
||||
{
|
||||
if( !COM_CheckString( szCmdString ))
|
||||
return 0;
|
||||
|
||||
// a1ba:
|
||||
// there should be stufftext validator, that checks
|
||||
// hardcoded commands and disallows them before passing to
|
||||
// filtered buffer, returning 0
|
||||
// I've replaced it by hooking potentially exploitable
|
||||
// commands and variables(motd_write, motdfile, etc) in client interfaces
|
||||
|
||||
Cbuf_AddFilteredText( szCmdString );
|
||||
Cbuf_AddFilteredText( "\n" );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
pfnGetPlayerInfo
|
||||
@@ -2276,9 +2299,9 @@ static void GAME_EXPORT pfnKillEvents( int entnum, const char *eventname )
|
||||
int i;
|
||||
event_state_t *es;
|
||||
event_info_t *ei;
|
||||
int eventIndex = CL_EventIndex( eventname );
|
||||
word eventIndex = CL_EventIndex( eventname );
|
||||
|
||||
if( eventIndex < 0 || eventIndex >= MAX_EVENTS )
|
||||
if( eventIndex >= MAX_EVENTS )
|
||||
return;
|
||||
|
||||
if( entnum < 0 || entnum > clgame.maxEntities )
|
||||
@@ -2906,15 +2929,16 @@ pfnDrawString
|
||||
*/
|
||||
static int GAME_EXPORT pfnDrawString( int x, int y, const char *str, int r, int g, int b )
|
||||
{
|
||||
int iWidth = 0;
|
||||
Con_UtfProcessChar(0);
|
||||
|
||||
// draw the string until we hit the null character or a newline character
|
||||
for ( ; *str != 0 && *str != '\n'; str++ )
|
||||
{
|
||||
x += pfnVGUI2DrawCharacterAdditive( x, y, (unsigned char)*str, r, g, b, 0 );
|
||||
iWidth += pfnVGUI2DrawCharacterAdditive( x + iWidth, y, (unsigned char)*str, r, g, b, 0 );
|
||||
}
|
||||
|
||||
return x;
|
||||
return iWidth;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2929,8 +2953,7 @@ static int GAME_EXPORT pfnDrawStringReverse( int x, int y, const char *str, int
|
||||
char *szIt;
|
||||
for( szIt = (char*)str; *szIt != 0; szIt++ )
|
||||
x -= clgame.scrInfo.charWidths[ (unsigned char) *szIt ];
|
||||
pfnDrawString( x, y, str, r, g, b );
|
||||
return x;
|
||||
return pfnDrawString( x, y, str, r, g, b );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3066,7 +3089,7 @@ char *pfnParseFile( char *data, char *token )
|
||||
{
|
||||
char *out;
|
||||
|
||||
out = _COM_ParseFileSafe( data, token, INT_MAX, PFILE_HANDLECOLON, NULL );
|
||||
out = _COM_ParseFileSafe( data, token, PFILE_TOKEN_MAX_LENGTH, PFILE_HANDLECOLON, NULL );
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -3155,16 +3178,7 @@ convert world coordinates (x,y,z) into screen (x, y)
|
||||
*/
|
||||
int TriWorldToScreen( const float *world, float *screen )
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = ref.dllFuncs.WorldToScreen( world, screen );
|
||||
|
||||
screen[0] = 0.5f * screen[0] * (float)clgame.viewport[2];
|
||||
screen[1] = -0.5f * screen[1] * (float)clgame.viewport[3];
|
||||
screen[0] += 0.5f * (float)clgame.viewport[2];
|
||||
screen[1] += 0.5f * (float)clgame.viewport[3];
|
||||
|
||||
return retval;
|
||||
return ref.dllFuncs.WorldToScreen( world, screen );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3878,10 +3892,7 @@ static cl_enginefunc_t gEngfuncs =
|
||||
pfnGetAppID,
|
||||
Cmd_AliasGetList,
|
||||
pfnVguiWrap2_GetMouseDelta,
|
||||
|
||||
// HACKHACK: added it here so it wouldn't cause overflow or segfault
|
||||
// TODO: itself client command filtering is not implemented yet
|
||||
pfnClientCmd
|
||||
pfnFilteredClientCmd
|
||||
};
|
||||
|
||||
void CL_UnloadProgs( void )
|
||||
@@ -3903,7 +3914,6 @@ void CL_UnloadProgs( void )
|
||||
Cvar_FullSet( "host_clientloaded", "0", FCVAR_READ_ONLY );
|
||||
|
||||
COM_FreeLibrary( clgame.hInstance );
|
||||
VGui_Shutdown();
|
||||
Mem_FreePool( &cls.mempool );
|
||||
Mem_FreePool( &clgame.mempool );
|
||||
memset( &clgame, 0, sizeof( clgame ));
|
||||
@@ -3947,7 +3957,7 @@ qboolean CL_LoadProgs( const char *name )
|
||||
#else
|
||||
// this doesn't mean other platforms uses SDL2 in any case
|
||||
// it just helps input code to stay platform-independent
|
||||
clgame.client_dll_uses_sdl = false;
|
||||
clgame.client_dll_uses_sdl = true;
|
||||
#endif
|
||||
|
||||
clgame.hInstance = COM_LoadLibrary( name, false, false );
|
||||
@@ -3964,7 +3974,17 @@ qboolean CL_LoadProgs( const char *name )
|
||||
|
||||
// trying to fill interface now
|
||||
GetClientAPI( &clgame.dllFuncs );
|
||||
}
|
||||
else if(( GetClientAPI = (void *)COM_GetProcAddress( clgame.hInstance, "F" )) != NULL )
|
||||
{
|
||||
Con_Reportf( "CL_LoadProgs: found single callback export (secured client dlls)\n" );
|
||||
|
||||
// trying to fill interface now
|
||||
CL_GetSecuredClientAPI( GetClientAPI );
|
||||
}
|
||||
|
||||
if ( GetClientAPI != NULL )
|
||||
{
|
||||
// check critical functions again
|
||||
for( func = cdll_exports; func && func->name; func++ )
|
||||
{
|
||||
|
||||
@@ -417,6 +417,8 @@ static void UI_ConvertGameInfo( GAMEINFO *out, gameinfo_t *in )
|
||||
out->flags |= GFL_NOMODELS;
|
||||
if( in->noskills )
|
||||
out->flags |= GFL_NOSKILLS;
|
||||
if( in->render_picbutton_text )
|
||||
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 )
|
||||
@@ -1233,7 +1235,8 @@ static ui_extendedfuncs_t gExtendedfuncs =
|
||||
Con_UtfMoveRight,
|
||||
pfnGetRenderers,
|
||||
Sys_DoubleTime,
|
||||
_COM_ParseFileSafe
|
||||
_COM_ParseFileSafe,
|
||||
NET_AdrToString
|
||||
};
|
||||
|
||||
void UI_UnloadProgs( void )
|
||||
|
||||
@@ -243,7 +243,7 @@ void CL_SignonReply( void )
|
||||
|
||||
float CL_LerpInterval( void )
|
||||
{
|
||||
return max( cl_interp->value, 1.f / cl_updaterate->value );
|
||||
return Q_max( cl_interp->value, 1.f / cl_updaterate->value );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -296,7 +296,7 @@ static float CL_LerpPoint( void )
|
||||
if( cl_interp->value > 0.001f )
|
||||
{
|
||||
// manual lerp value (goldsrc mode)
|
||||
float td = max( 0.f, cl.time - cl.mtime[0] );
|
||||
float td = Q_max( 0.f, cl.time - cl.mtime[0] );
|
||||
frac = td / CL_LerpInterval();
|
||||
}
|
||||
else if( server_frametime > 0.001f )
|
||||
@@ -528,7 +528,7 @@ qboolean CL_ProcessShowTexturesCmds( usercmd_t *cmd )
|
||||
if( released & ( IN_RIGHT|IN_MOVERIGHT ))
|
||||
Cvar_SetValue( "r_showtextures", gl_showtextures->value + 1 );
|
||||
if( released & ( IN_LEFT|IN_MOVELEFT ))
|
||||
Cvar_SetValue( "r_showtextures", max( 1, gl_showtextures->value - 1 ));
|
||||
Cvar_SetValue( "r_showtextures", Q_max( 1, gl_showtextures->value - 1 ));
|
||||
oldbuttons = cmd->buttons;
|
||||
|
||||
return true;
|
||||
@@ -1284,6 +1284,7 @@ void CL_Rcon_f( void )
|
||||
{
|
||||
char message[1024];
|
||||
netadr_t to;
|
||||
string command;
|
||||
int i;
|
||||
|
||||
if( !COM_CheckString( rcon_client_password->string ))
|
||||
@@ -1306,7 +1307,8 @@ void CL_Rcon_f( void )
|
||||
|
||||
for( i = 1; i < Cmd_Argc(); i++ )
|
||||
{
|
||||
Q_strcat( message, Cmd_Argv( i ));
|
||||
Cmd_Escape( command, Cmd_Argv( i ), sizeof( command ));
|
||||
Q_strcat( message, command );
|
||||
Q_strcat( message, " " );
|
||||
}
|
||||
|
||||
@@ -1561,7 +1563,6 @@ void CL_LocalServers_f( void )
|
||||
|
||||
Con_Printf( "Scanning for servers on the local network area...\n" );
|
||||
NET_Config( true ); // allow remote
|
||||
cls.legacyservercount = 0;
|
||||
|
||||
// send a broadcast packet
|
||||
adr.type = NA_BROADCAST;
|
||||
@@ -1589,7 +1590,6 @@ void CL_InternetServers_f( void )
|
||||
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.legacyservercount = 0;
|
||||
|
||||
cls.internetservers_wait = NET_SendToMasters( NS_CLIENT, sizeof( MS_SCAN_REQUEST ) + Q_strlen( info ), fullquery );
|
||||
cls.internetservers_pending = true;
|
||||
@@ -1720,8 +1720,6 @@ void CL_ParseStatusMessage( netadr_t from, sizebuf_t *msg )
|
||||
{
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, from, "info %i", PROTOCOL_LEGACY_VERSION );
|
||||
Con_Printf( "^1Server^7: %s, Info: %s\n", NET_AdrToString( from ), infostring );
|
||||
if( cls.legacyservercount < MAX_LEGACY_SERVERS )
|
||||
cls.legacyservers[cls.legacyservercount++] = from;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1731,14 +1729,10 @@ void CL_ParseStatusMessage( netadr_t from, sizebuf_t *msg )
|
||||
return; // unsupported proto
|
||||
}
|
||||
|
||||
for( i = 0; i < cls.legacyservercount; i++ )
|
||||
if( !COM_CheckString( Info_ValueForKey( infostring, "p" )))
|
||||
{
|
||||
if( NET_CompareAdr( cls.legacyservers[i], from ) )
|
||||
{
|
||||
Info_SetValueForKey( infostring, "legacy", "1", sizeof( infostring ) );
|
||||
Con_Print("Legacy: ");
|
||||
break;
|
||||
}
|
||||
Info_SetValueForKey( infostring, "legacy", "1", sizeof( infostring ) );
|
||||
Con_Print("Legacy: ");
|
||||
}
|
||||
|
||||
// more info about servers
|
||||
@@ -2351,11 +2345,10 @@ Replace the displayed name for some resources
|
||||
*/
|
||||
const char *CL_CleanFileName( const char *filename )
|
||||
{
|
||||
const char *pfilename = filename;
|
||||
|
||||
if( COM_CheckString( filename ) && filename[0] == '!' )
|
||||
pfilename = "customization";
|
||||
return pfilename;
|
||||
return "customization";
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
||||
@@ -2820,13 +2813,13 @@ void CL_InitLocal( void )
|
||||
cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0, "disable delta-compression for server messages" );
|
||||
cl_idealpitchscale = Cvar_Get( "cl_idealpitchscale", "0.8", 0, "how much to look up/down slopes and stairs when not using freelook" );
|
||||
cl_solid_players = Cvar_Get( "cl_solid_players", "1", 0, "Make all players not solid (can't traceline them)" );
|
||||
cl_interp = Cvar_Get( "ex_interp", "0.1", FCVAR_ARCHIVE, "Interpolate object positions starting this many seconds in past" );
|
||||
cl_interp = Cvar_Get( "ex_interp", "0.1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "Interpolate object positions starting this many seconds in past" );
|
||||
cl_timeout = Cvar_Get( "cl_timeout", "60", 0, "connect timeout (in-seconds)" );
|
||||
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", "", 0, "remote control client password" );
|
||||
rcon_address = Cvar_Get( "rcon_address", "", 0, "remote control address" );
|
||||
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)");
|
||||
|
||||
@@ -2837,7 +2830,7 @@ void CL_InitLocal( void )
|
||||
cl_updaterate = Cvar_Get( "cl_updaterate", "20", FCVAR_USERINFO|FCVAR_ARCHIVE, "refresh rate of server messages" );
|
||||
cl_dlmax = Cvar_Get( "cl_dlmax", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "max allowed outcoming fragment size" );
|
||||
cl_upmax = Cvar_Get( "cl_upmax", "1200", FCVAR_ARCHIVE, "max allowed incoming fragment size" );
|
||||
rate = Cvar_Get( "rate", "3500", FCVAR_USERINFO|FCVAR_ARCHIVE, "player network rate" );
|
||||
rate = Cvar_Get( "rate", "3500", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player network rate" );
|
||||
topcolor = Cvar_Get( "topcolor", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "player top color" );
|
||||
bottomcolor = Cvar_Get( "bottomcolor", "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "player bottom color" );
|
||||
cl_lw = Cvar_Get( "cl_lw", "1", FCVAR_ARCHIVE|FCVAR_USERINFO, "enable client weapon predicting" );
|
||||
@@ -2876,7 +2869,7 @@ void CL_InitLocal( void )
|
||||
Cmd_AddCommand ("give", NULL, "give specified item or weapon" );
|
||||
Cmd_AddCommand ("drop", NULL, "drop current/specified item or weapon" );
|
||||
Cmd_AddCommand ("gametitle", NULL, "show game logo" );
|
||||
Cmd_AddCommand( "kill", NULL, "die instantly" );
|
||||
Cmd_AddRestrictedCommand ("kill", NULL, "die instantly" );
|
||||
Cmd_AddCommand ("god", NULL, "enable godmode" );
|
||||
Cmd_AddCommand ("fov", NULL, "set client field of view" );
|
||||
Cmd_AddCommand ("log", NULL, "logging server events" );
|
||||
@@ -2889,8 +2882,8 @@ void CL_InitLocal( void )
|
||||
Cmd_AddCommand ("mp3", CL_PlayCDTrack_f, "Play mp3-track (based on virtual cd-player)" );
|
||||
Cmd_AddCommand ("waveplaylen", CL_WavePlayLen_f, "Get approximate length of wave file");
|
||||
|
||||
Cmd_AddCommand ("setinfo", CL_SetInfo_f, "examine or change the userinfo string (alias of userinfo)" );
|
||||
Cmd_AddCommand ("userinfo", CL_SetInfo_f, "examine or change the userinfo string (alias of setinfo)" );
|
||||
Cmd_AddRestrictedCommand ("setinfo", CL_SetInfo_f, "examine or change the userinfo string (alias of userinfo)" );
|
||||
Cmd_AddRestrictedCommand ("userinfo", CL_SetInfo_f, "examine or change the userinfo string (alias of setinfo)" );
|
||||
Cmd_AddCommand ("physinfo", CL_Physinfo_f, "print current client physinfo" );
|
||||
Cmd_AddCommand ("disconnect", CL_Disconnect_f, "disconnect from server" );
|
||||
Cmd_AddCommand ("record", CL_Record_f, "record a demo" );
|
||||
@@ -2909,8 +2902,8 @@ void CL_InitLocal( void )
|
||||
Cmd_AddCommand ("fullserverinfo", CL_FullServerinfo_f, "sent by server when serverinfo changes" );
|
||||
Cmd_AddCommand ("upload", CL_BeginUpload_f, "uploading file to the server" );
|
||||
|
||||
Cmd_AddCommand ("quit", CL_Quit_f, "quit from game" );
|
||||
Cmd_AddCommand ("exit", CL_Quit_f, "quit from game" );
|
||||
Cmd_AddRestrictedCommand ("quit", CL_Quit_f, "quit from game" );
|
||||
Cmd_AddRestrictedCommand ("exit", CL_Quit_f, "quit from game" );
|
||||
|
||||
Cmd_AddCommand ("screenshot", CL_ScreenShot_f, "takes a screenshot of the next rendered frame" );
|
||||
Cmd_AddCommand ("snapshot", CL_SnapShot_f, "takes a snapshot of the next rendered frame" );
|
||||
@@ -3076,7 +3069,6 @@ void CL_Init( void )
|
||||
MSG_Init( &cls.datagram, "cls.datagram", cls.datagram_buf, sizeof( cls.datagram_buf ));
|
||||
|
||||
// IN_TouchInit();
|
||||
Con_LoadHistory();
|
||||
|
||||
COM_GetCommonLibraryPath( LIBRARY_CLIENT, libpath, sizeof( libpath ));
|
||||
|
||||
@@ -3097,10 +3089,6 @@ CL_Shutdown
|
||||
*/
|
||||
void CL_Shutdown( void )
|
||||
{
|
||||
// already freed
|
||||
if( !cls.initialized ) return;
|
||||
cls.initialized = false;
|
||||
|
||||
Con_Printf( "CL_Shutdown()\n" );
|
||||
|
||||
if( !host.crashed )
|
||||
@@ -3117,6 +3105,9 @@ void CL_Shutdown( void )
|
||||
Mobile_Shutdown ();
|
||||
SCR_Shutdown ();
|
||||
CL_UnloadProgs ();
|
||||
cls.initialized = false;
|
||||
|
||||
VGui_Shutdown();
|
||||
|
||||
FS_Delete( "demoheader.tmp" ); // remove tmp file
|
||||
SCR_FreeCinematic (); // release AVI's *after* client.dll because custom renderer may use them
|
||||
@@ -3124,4 +3115,5 @@ void CL_Shutdown( void )
|
||||
R_Shutdown ();
|
||||
|
||||
Con_Shutdown ();
|
||||
|
||||
}
|
||||
|
||||
@@ -93,6 +93,15 @@ static void *pfnGetNativeObject( const char *obj )
|
||||
return Platform_GetNativeObject( obj );
|
||||
}
|
||||
|
||||
static void pfnTouch_HideButtons( const char *name, byte state )
|
||||
{
|
||||
Touch_HideButtons( name, state, true );
|
||||
}
|
||||
|
||||
static void pfnTouch_RemoveButton( const char *name )
|
||||
{
|
||||
Touch_RemoveButton( name, true );
|
||||
}
|
||||
|
||||
static mobile_engfuncs_t gpMobileEngfuncs =
|
||||
{
|
||||
@@ -101,9 +110,9 @@ static mobile_engfuncs_t gpMobileEngfuncs =
|
||||
pfnEnableTextInput,
|
||||
Touch_AddClientButton,
|
||||
Touch_AddDefaultButton,
|
||||
Touch_HideButtons,
|
||||
Touch_RemoveButton,
|
||||
(void*)Touch_SetClientOnly,
|
||||
pfnTouch_HideButtons,
|
||||
pfnTouch_RemoveButton,
|
||||
Touch_SetClientOnly,
|
||||
Touch_ResetDefaultButtons,
|
||||
pfnDrawScaledCharacter,
|
||||
Sys_Warn,
|
||||
@@ -125,8 +134,8 @@ qboolean Mobile_Init( void )
|
||||
success = true;
|
||||
|
||||
Cmd_AddCommand( "vibrate", (xcommand_t)Vibrate_f, "Vibrate for specified time");
|
||||
vibration_length = Cvar_Get( "vibration_length", "1.0", FCVAR_ARCHIVE, "Vibration length");
|
||||
vibration_enable = Cvar_Get( "vibration_enable", "1", FCVAR_ARCHIVE, "Enable vibration");
|
||||
vibration_length = Cvar_Get( "vibration_length", "1.0", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "Vibration length");
|
||||
vibration_enable = Cvar_Get( "vibration_enable", "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "Enable vibration");
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -484,6 +484,8 @@ void CL_BatchResourceRequest( qboolean initialize )
|
||||
switch( p->type )
|
||||
{
|
||||
case t_sound:
|
||||
case t_model:
|
||||
case t_eventscript:
|
||||
if( !CL_CheckFile( &msg, p ))
|
||||
break;
|
||||
CL_MoveToOnHandList( p );
|
||||
@@ -491,11 +493,6 @@ void CL_BatchResourceRequest( qboolean initialize )
|
||||
case t_skin:
|
||||
CL_MoveToOnHandList( p );
|
||||
break;
|
||||
case t_model:
|
||||
if( !CL_CheckFile( &msg, p ))
|
||||
break;
|
||||
CL_MoveToOnHandList( p );
|
||||
break;
|
||||
case t_decal:
|
||||
if( !HPAK_GetDataPointer( CUSTOM_RES_PATH, p, NULL, NULL ))
|
||||
{
|
||||
@@ -520,11 +517,6 @@ void CL_BatchResourceRequest( qboolean initialize )
|
||||
break;
|
||||
CL_MoveToOnHandList( p );
|
||||
break;
|
||||
case t_eventscript:
|
||||
if( !CL_CheckFile( &msg, p ))
|
||||
break;
|
||||
CL_MoveToOnHandList( p );
|
||||
break;
|
||||
case t_world:
|
||||
ASSERT( 0 );
|
||||
break;
|
||||
@@ -1322,30 +1314,6 @@ void CL_RegisterUserMessage( sizebuf_t *msg )
|
||||
CL_LinkUserMessage( pszName, svc_num, size );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_RegisterUserMessage
|
||||
|
||||
register new user message or update existing
|
||||
================
|
||||
*/
|
||||
/*
|
||||
void CL_LegacyRegisterUserMessage( sizebuf_t *msg )
|
||||
{
|
||||
char *pszName;
|
||||
int svc_num, size;
|
||||
|
||||
svc_num = MSG_ReadByte( msg );
|
||||
size = MSG_ReadByte( msg );
|
||||
pszName = MSG_ReadString( msg );
|
||||
|
||||
// important stuff
|
||||
if( size == 0xFF ) size = -1;
|
||||
svc_num = bound( 0, svc_num, 255 );
|
||||
|
||||
CL_LinkUserMessage( pszName, svc_num, size );
|
||||
}
|
||||
*/
|
||||
/*
|
||||
================
|
||||
CL_UpdateUserinfo
|
||||
@@ -1819,7 +1787,7 @@ void CL_ParseScreenShake( sizebuf_t *msg )
|
||||
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 + max( clgame.shake.duration, 0.01f );
|
||||
clgame.shake.time = cl.time + Q_max( clgame.shake.duration, 0.01f );
|
||||
clgame.shake.next_shake = 0.0f; // apply immediately
|
||||
}
|
||||
|
||||
@@ -1883,46 +1851,42 @@ Find the client cvar value
|
||||
and sent it back to the server
|
||||
==============
|
||||
*/
|
||||
void CL_ParseCvarValue( sizebuf_t *msg )
|
||||
void CL_ParseCvarValue( sizebuf_t *msg, const qboolean ext )
|
||||
{
|
||||
const char *cvarName = MSG_ReadString( msg );
|
||||
convar_t *cvar = Cvar_FindVar( cvarName );
|
||||
const char *cvarName, *response;
|
||||
convar_t *cvar;
|
||||
int requestID;
|
||||
|
||||
// build the answer
|
||||
MSG_BeginClientCmd( &cls.netchan.message, clc_requestcvarvalue );
|
||||
MSG_WriteString( &cls.netchan.message, cvar ? cvar->string : "Not Found" );
|
||||
}
|
||||
if( ext )
|
||||
requestID = MSG_ReadLong( msg );
|
||||
|
||||
/*
|
||||
==============
|
||||
CL_ParseCvarValue2
|
||||
|
||||
Find the client cvar value
|
||||
and sent it back to the server
|
||||
==============
|
||||
*/
|
||||
void CL_ParseCvarValue2( sizebuf_t *msg )
|
||||
{
|
||||
int requestID = MSG_ReadLong( msg );
|
||||
const char *cvarName = MSG_ReadString( msg );
|
||||
convar_t *cvar = Cvar_FindVar( cvarName );
|
||||
|
||||
// build the answer
|
||||
MSG_BeginClientCmd( &cls.netchan.message, clc_requestcvarvalue2 );
|
||||
MSG_WriteLong( &cls.netchan.message, requestID );
|
||||
MSG_WriteString( &cls.netchan.message, cvarName );
|
||||
cvarName = MSG_ReadString( msg );
|
||||
cvar = Cvar_FindVar( cvarName );
|
||||
|
||||
if( cvar )
|
||||
{
|
||||
// cheater can change value ignoring Cvar_Set so we responce incorrect value
|
||||
if( cvar->value != Q_atof( cvar->string ))
|
||||
MSG_WriteString( &cls.netchan.message, va( "%s (%g)", cvar->string, cvar->value ));
|
||||
else MSG_WriteString( &cls.netchan.message, cvar->string );
|
||||
if( cvar->flags & FCVAR_PRIVILEGED )
|
||||
response = "CVAR is privileged";
|
||||
else if( cvar->flags & FCVAR_SERVER )
|
||||
response = "CVAR is server-only";
|
||||
else if( cvar->flags & FCVAR_PROTECTED )
|
||||
response = "CVAR is protected";
|
||||
else
|
||||
response = cvar->string;
|
||||
}
|
||||
else response = "Bad CVAR request";
|
||||
|
||||
if( ext )
|
||||
{
|
||||
MSG_BeginClientCmd( &cls.netchan.message, clc_requestcvarvalue2 );
|
||||
MSG_WriteLong( &cls.netchan.message, requestID );
|
||||
MSG_WriteString( &cls.netchan.message, cvarName );
|
||||
}
|
||||
else
|
||||
{
|
||||
MSG_WriteString( &cls.netchan.message, "Not Found" );
|
||||
MSG_BeginClientCmd( &cls.netchan.message, clc_requestcvarvalue );
|
||||
}
|
||||
MSG_WriteString( &cls.netchan.message, response );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2226,11 +2190,11 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
case svc_stufftext:
|
||||
s = MSG_ReadString( msg );
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
// dsiable Cry Of Fear antisave protection
|
||||
// disable Cry Of Fear antisave protection
|
||||
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
|
||||
break; // too early
|
||||
#endif
|
||||
Cbuf_AddText( s );
|
||||
Cbuf_AddFilteredText( s );
|
||||
break;
|
||||
case svc_setangle:
|
||||
CL_ParseSetAngle( msg );
|
||||
@@ -2376,10 +2340,10 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
CL_ParseResLocation( msg );
|
||||
break;
|
||||
case svc_querycvarvalue:
|
||||
CL_ParseCvarValue( msg );
|
||||
CL_ParseCvarValue( msg, false );
|
||||
break;
|
||||
case svc_querycvarvalue2:
|
||||
CL_ParseCvarValue2( msg );
|
||||
CL_ParseCvarValue( msg, true );
|
||||
break;
|
||||
case svc_exec:
|
||||
CL_ParseExec( msg );
|
||||
@@ -2417,14 +2381,11 @@ CL_ParseBaseline
|
||||
void CL_LegacyParseBaseline( sizebuf_t *msg )
|
||||
{
|
||||
int i, newnum;
|
||||
entity_state_t nullstate;
|
||||
qboolean player;
|
||||
cl_entity_t *ent;
|
||||
|
||||
Delta_InitClient (); // finalize client delta's
|
||||
|
||||
memset( &nullstate, 0, sizeof( nullstate ));
|
||||
|
||||
newnum = MSG_ReadWord( msg );
|
||||
player = CL_IsPlayerIndex( newnum );
|
||||
|
||||
@@ -2994,13 +2955,13 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
case svc_stufftext:
|
||||
s = MSG_ReadString( msg );
|
||||
#ifdef HACKS_RELATED_HLMODS
|
||||
// dsiable Cry Of Fear antisave protection
|
||||
// disable Cry Of Fear antisave protection
|
||||
if( !Q_strnicmp( s, "disconnect", 10 ) && cls.signon != SIGNONS )
|
||||
break; // too early
|
||||
#endif
|
||||
|
||||
Con_Reportf( "Stufftext: %s", s );
|
||||
Cbuf_AddText( s );
|
||||
Cbuf_AddFilteredText( s );
|
||||
break;
|
||||
case svc_setangle:
|
||||
CL_ParseSetAngle( msg );
|
||||
@@ -3166,10 +3127,10 @@ void CL_ParseLegacyServerMessage( sizebuf_t *msg, qboolean normal_message )
|
||||
CL_ParseResLocation( msg );
|
||||
break;
|
||||
case svc_querycvarvalue:
|
||||
CL_ParseCvarValue( msg );
|
||||
CL_ParseCvarValue( msg, false );
|
||||
break;
|
||||
case svc_querycvarvalue2:
|
||||
CL_ParseCvarValue2( msg );
|
||||
CL_ParseCvarValue( msg, true );
|
||||
break;
|
||||
default:
|
||||
CL_ParseUserMessage( msg, cmd );
|
||||
|
||||
@@ -992,7 +992,6 @@ void CL_SetupPMove( playermove_t *pmove, local_state_t *from, usercmd_t *ucmd, q
|
||||
pmove->flFallVelocity = ps->flFallVelocity;
|
||||
pmove->flSwimTime = cd->flSwimTime;
|
||||
VectorCopy( cd->punchangle, pmove->punchangle );
|
||||
pmove->flSwimTime = cd->flSwimTime;
|
||||
pmove->flNextPrimaryAttack = 0.0f; // not used by PM_ code
|
||||
pmove->effects = ps->effects;
|
||||
pmove->flags = cd->flags;
|
||||
|
||||
@@ -825,6 +825,9 @@ CL_QuakeStuffText
|
||||
void CL_QuakeStuffText( const char *text )
|
||||
{
|
||||
Q_strncat( cmd_buf, text, sizeof( cmd_buf ));
|
||||
|
||||
// a1ba: didn't filtered, anyway quake protocol
|
||||
// only supported for demos, not network games
|
||||
Cbuf_AddText( text );
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ static void R_EnvShot( const float *vieworg, const char *name, qboolean skyshot,
|
||||
else cls.scrshot_action = scrshot_envshot;
|
||||
|
||||
// catch negative values
|
||||
cls.envshot_viewsize = max( 0, shotsize );
|
||||
cls.envshot_viewsize = Q_max( 0, shotsize );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -781,6 +781,7 @@ SCR_VidInit
|
||||
*/
|
||||
void SCR_VidInit( void )
|
||||
{
|
||||
string libpath;
|
||||
if( !ref.initialized ) // don't call VidInit too soon
|
||||
return;
|
||||
|
||||
@@ -795,7 +796,8 @@ void SCR_VidInit( void )
|
||||
gameui.globals->scrHeight = refState.height;
|
||||
}
|
||||
|
||||
VGui_Startup( NULL, refState.width, refState.height ); // initialized already, so pass NULL
|
||||
COM_GetCommonLibraryPath( LIBRARY_CLIENT, libpath, sizeof( libpath ));
|
||||
VGui_Startup( libpath, refState.width, refState.height );
|
||||
|
||||
CL_ClearSpriteTextures(); // now all hud sprites are invalid
|
||||
|
||||
|
||||
460
engine/client/cl_securedstub.c
Normal file
460
engine/client/cl_securedstub.c
Normal file
@@ -0,0 +1,460 @@
|
||||
/*
|
||||
cl_securedstub.c - secured client dll stub
|
||||
Copyright (C) 2022 FWGS
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
|
||||
typedef struct cldll_func_src_s
|
||||
{
|
||||
int (*pfnInitialize)( cl_enginefunc_t *pEnginefuncs, int iVersion );
|
||||
void (*pfnInit)( void );
|
||||
int (*pfnVidInit)( void );
|
||||
int (*pfnRedraw)( float flTime, int intermission );
|
||||
int (*pfnUpdateClientData)( client_data_t *cdata, float flTime );
|
||||
void (*pfnReset)( void );
|
||||
void (*pfnPlayerMove)( struct playermove_s *ppmove, int server );
|
||||
void (*pfnPlayerMoveInit)( struct playermove_s *ppmove );
|
||||
char (*pfnPlayerMoveTexture)( char *name );
|
||||
void (*IN_ActivateMouse)( void );
|
||||
void (*IN_DeactivateMouse)( void );
|
||||
void (*IN_MouseEvent)( int mstate );
|
||||
void (*IN_ClearStates)( void );
|
||||
void (*IN_Accumulate)( void );
|
||||
void (*CL_CreateMove)( float frametime, struct usercmd_s *cmd, int active );
|
||||
int (*CL_IsThirdPerson)( void );
|
||||
void (*CL_CameraOffset)( float *ofs ); // unused
|
||||
void *(*KB_Find)( const char *name );
|
||||
void (*CAM_Think)( void ); // camera stuff
|
||||
void (*pfnCalcRefdef)( ref_params_t *pparams );
|
||||
int (*pfnAddEntity)( int type, cl_entity_t *ent, const char *modelname );
|
||||
void (*pfnCreateEntities)( void );
|
||||
void (*pfnDrawNormalTriangles)( void );
|
||||
void (*pfnDrawTransparentTriangles)( void );
|
||||
void (*pfnStudioEvent)( const struct mstudioevent_s *event, const cl_entity_t *entity );
|
||||
void (*pfnPostRunCmd)( struct local_state_s *from, struct local_state_s *to, usercmd_t *cmd, int runfuncs, double time, unsigned int random_seed );
|
||||
void (*pfnShutdown)( void );
|
||||
void (*pfnTxferLocalOverrides)( entity_state_t *state, const clientdata_t *client );
|
||||
void (*pfnProcessPlayerState)( entity_state_t *dst, const entity_state_t *src );
|
||||
void (*pfnTxferPredictionData)( entity_state_t *ps, const entity_state_t *pps, clientdata_t *pcd, const clientdata_t *ppcd, weapon_data_t *wd, const weapon_data_t *pwd );
|
||||
void (*pfnDemo_ReadBuffer)( int size, byte *buffer );
|
||||
int (*pfnConnectionlessPacket)( const struct netadr_s *net_from, const char *args, char *buffer, int *size );
|
||||
int (*pfnGetHullBounds)( int hullnumber, float *mins, float *maxs );
|
||||
void (*pfnFrame)( double time );
|
||||
int (*pfnKey_Event)( int eventcode, int keynum, const char *pszCurrentBinding );
|
||||
void (*pfnTempEntUpdate)( double frametime, double client_time, double cl_gravity, struct tempent_s **ppTempEntFree, struct tempent_s **ppTempEntActive, int ( *Callback_AddVisibleEntity )( cl_entity_t *pEntity ), void ( *Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ));
|
||||
cl_entity_t *(*pfnGetUserEntity)( int index );
|
||||
void (*pfnVoiceStatus)( int entindex, qboolean bTalking );
|
||||
void (*pfnDirectorMessage)( int iSize, void *pbuf );
|
||||
int (*pfnGetStudioModelInterface)( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio );
|
||||
void (*pfnChatInputPosition)( int *x, int *y );
|
||||
int (*pfnGetPlayerTeam)( int iPlayer );
|
||||
void *(*pfnClientFactory)( void );
|
||||
} cldll_func_src_t;
|
||||
|
||||
typedef struct cldll_func_dst_s
|
||||
{
|
||||
void (*pfnInitialize)( cl_enginefunc_t **pEnginefuncs, int *iVersion );
|
||||
void (*pfnInit)( void );
|
||||
void (*pfnVidInit)( void );
|
||||
void (*pfnRedraw)( float *flTime, int *intermission );
|
||||
void (*pfnUpdateClientData)( client_data_t **cdata, float *flTime );
|
||||
void (*pfnReset)( void );
|
||||
void (*pfnPlayerMove)( struct playermove_s **ppmove, int *server );
|
||||
void (*pfnPlayerMoveInit)( struct playermove_s **ppmove );
|
||||
void (*pfnPlayerMoveTexture)( char **name );
|
||||
void (*IN_ActivateMouse)( void );
|
||||
void (*IN_DeactivateMouse)( void );
|
||||
void (*IN_MouseEvent)( int *mstate );
|
||||
void (*IN_ClearStates)( void );
|
||||
void (*IN_Accumulate)( void );
|
||||
void (*CL_CreateMove)( float *frametime, struct usercmd_s **cmd, int *active );
|
||||
void (*CL_IsThirdPerson)( void );
|
||||
void (*CL_CameraOffset)( float **ofs );
|
||||
void (*KB_Find)( const char **name );
|
||||
void (*CAM_Think)( void );
|
||||
void (*pfnCalcRefdef)( ref_params_t **pparams );
|
||||
void (*pfnAddEntity)( int *type, cl_entity_t **ent, const char **modelname );
|
||||
void (*pfnCreateEntities)( void );
|
||||
void (*pfnDrawNormalTriangles)( void );
|
||||
void (*pfnDrawTransparentTriangles)( void );
|
||||
void (*pfnStudioEvent)( const struct mstudioevent_s **event, const cl_entity_t **entity );
|
||||
void (*pfnPostRunCmd)( struct local_state_s **from, struct local_state_s **to, usercmd_t **cmd, int *runfuncs, double *time, unsigned int *random_seed );
|
||||
void (*pfnShutdown)( void );
|
||||
void (*pfnTxferLocalOverrides)( entity_state_t **state, const clientdata_t **client );
|
||||
void (*pfnProcessPlayerState)( entity_state_t **dst, const entity_state_t **src );
|
||||
void (*pfnTxferPredictionData)( entity_state_t **ps, const entity_state_t **pps, clientdata_t **pcd, const clientdata_t **ppcd, weapon_data_t **wd, const weapon_data_t **pwd );
|
||||
void (*pfnDemo_ReadBuffer)( int *size, byte **buffer );
|
||||
void (*pfnConnectionlessPacket)( const struct netadr_s **net_from, const char **args, char **buffer, int **size );
|
||||
void (*pfnGetHullBounds)( int *hullnumber, float **mins, float **maxs );
|
||||
void (*pfnFrame)( double *time );
|
||||
void (*pfnKey_Event)( int *eventcode, int *keynum, const char **pszCurrentBinding );
|
||||
void (*pfnTempEntUpdate)( double *frametime, double *client_time, double *cl_gravity, struct tempent_s ***ppTempEntFree, struct tempent_s ***ppTempEntActive, int ( **Callback_AddVisibleEntity )( cl_entity_t *pEntity ), void ( **Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ));
|
||||
void (*pfnGetUserEntity)( int *index );
|
||||
void (*pfnVoiceStatus)( int *entindex, qboolean *bTalking );
|
||||
void (*pfnDirectorMessage)( int *iSize, void **pbuf );
|
||||
void (*pfnGetStudioModelInterface)( int *version, struct r_studio_interface_s ***ppinterface, struct engine_studio_api_s **pstudio );
|
||||
void (*pfnChatInputPosition)( int **x, int **y );
|
||||
void (*pfnGetPlayerTeam)( int *iPlayer );
|
||||
} cldll_func_dst_t;
|
||||
|
||||
struct cl_enginefunc_dst_s;
|
||||
struct modshelpers_s;
|
||||
struct modchelpers_s;
|
||||
struct engdata_s;
|
||||
|
||||
typedef struct modfuncs_s
|
||||
{
|
||||
void (*m_pfnLoadMod)( char *pchModule );
|
||||
void (*m_pfnCloseMod)( void );
|
||||
int (*m_pfnNCall)( int ijump, int cnArg, ... );
|
||||
void (*m_pfnGetClDstAddrs)( cldll_func_dst_t *pcldstAddrs );
|
||||
void (*m_pfnGetEngDstAddrs)( struct cl_enginefunc_dst_s *pengdstAddrs );
|
||||
void (*m_pfnModuleLoaded)( void );
|
||||
void (*m_pfnProcessOutgoingNet)( struct netchan_s *pchan, struct sizebuf_s *psizebuf );
|
||||
qboolean (*m_pfnProcessIncomingNet)( struct netchan_s *pchan, struct sizebuf_s *psizebuf );
|
||||
void (*m_pfnTextureLoad)( char *pszName, int dxWidth, int dyHeight, char *pbData );
|
||||
void (*m_pfnModelLoad)( struct model_s *pmodel, void *pvBuf );
|
||||
void (*m_pfnFrameBegin)( void );
|
||||
void (*m_pfnFrameRender1)( void );
|
||||
void (*m_pfnFrameRender2)( void );
|
||||
void (*m_pfnSetModSHelpers)( struct modshelpers_s *pmodshelpers );
|
||||
void (*m_pfnSetModCHelpers)( struct modchelpers_s *pmodchelpers );
|
||||
void (*m_pfnSetEngData)( struct engdata_s *pengdata );
|
||||
int m_nVersion;
|
||||
void (*m_pfnConnectClient)( int iPlayer );
|
||||
void (*m_pfnRecordIP)( unsigned int pnIP );
|
||||
void (*m_pfnPlayerStatus)( unsigned char *pbData, int cbData );
|
||||
void (*m_pfnSetEngineVersion)( int nVersion );
|
||||
int m_nVoid2;
|
||||
int m_nVoid3;
|
||||
int m_nVoid4;
|
||||
int m_nVoid5;
|
||||
int m_nVoid6;
|
||||
int m_nVoid7;
|
||||
int m_nVoid8;
|
||||
int m_nVoid9;
|
||||
} modfuncs_t;
|
||||
|
||||
static void DstInitialize( cl_enginefunc_t **pEnginefuncs, int *iVersion )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstInit( void )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstVidInit( void )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstRedraw( float *flTime, int *intermission )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstUpdateClientData( client_data_t **cdata, float *flTime )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstReset( void )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstPlayerMove( struct playermove_s **ppmove, int *server )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstPlayerMoveInit( struct playermove_s **ppmove )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstPlayerMoveTexture( char **name )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstIN_ActivateMouse( void )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstIN_DeactivateMouse( void )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstIN_MouseEvent( int *mstate )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstIN_ClearStates( void )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstIN_Accumulate( void )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstCL_CreateMove( float *frametime, struct usercmd_s **cmd, int *active )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstCL_IsThirdPerson( void )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstCL_CameraOffset( float **ofs )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstKB_Find( const char **name )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstCAM_Think( void )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstCalcRefdef( ref_params_t **pparams )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstAddEntity( int *type, cl_entity_t **ent, const char **modelname )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstCreateEntities( void )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstDrawNormalTriangles( void )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstDrawTransparentTriangles( void )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstStudioEvent( const struct mstudioevent_s **event, const cl_entity_t **entity )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstPostRunCmd( struct local_state_s **from, struct local_state_s **to, usercmd_t **cmd, int *runfuncs, double *time, unsigned int *random_seed )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstShutdown( void )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstTxferLocalOverrides( entity_state_t **state, const clientdata_t **client )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstProcessPlayerState( entity_state_t **dst, const entity_state_t **src )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstTxferPredictionData( entity_state_t **ps, const entity_state_t **pps, clientdata_t **pcd, const clientdata_t **ppcd, weapon_data_t **wd, const weapon_data_t **pwd )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstDemo_ReadBuffer( int *size, byte **buffer )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstConnectionlessPacket( const struct netadr_s **net_from, const char **args, char **buffer, int **size )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstGetHullBounds( int *hullnumber, float **mins, float **maxs )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstFrame( double *time )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstKey_Event( int *eventcode, int *keynum, const char **pszCurrentBinding )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstTempEntUpdate( double *frametime, double *client_time, double *cl_gravity, struct tempent_s ***ppTempEntFree, struct tempent_s ***ppTempEntActive, int ( **Callback_AddVisibleEntity )( cl_entity_t *pEntity ), void ( **Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ) )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstGetUserEntity( int *index )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstVoiceStatus( int *entindex, qboolean *bTalking )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstDirectorMessage( int *iSize, void **pbuf )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstGetStudioModelInterface( int *version, struct r_studio_interface_s ***ppinterface, struct engine_studio_api_s **pstudio )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstChatInputPosition( int **x, int **y )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static void DstGetPlayerTeam( int *iPlayer )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
static cldll_func_dst_t cldllFuncDst =
|
||||
{
|
||||
DstInitialize,
|
||||
DstInit,
|
||||
DstVidInit,
|
||||
DstRedraw,
|
||||
DstUpdateClientData,
|
||||
DstReset,
|
||||
DstPlayerMove,
|
||||
DstPlayerMoveInit,
|
||||
DstPlayerMoveTexture,
|
||||
DstIN_ActivateMouse,
|
||||
DstIN_DeactivateMouse,
|
||||
DstIN_MouseEvent,
|
||||
DstIN_ClearStates,
|
||||
DstIN_Accumulate,
|
||||
DstCL_CreateMove,
|
||||
DstCL_IsThirdPerson,
|
||||
DstCL_CameraOffset,
|
||||
DstKB_Find,
|
||||
DstCAM_Think,
|
||||
DstCalcRefdef,
|
||||
DstAddEntity,
|
||||
DstCreateEntities,
|
||||
DstDrawNormalTriangles,
|
||||
DstDrawTransparentTriangles,
|
||||
DstStudioEvent,
|
||||
DstPostRunCmd,
|
||||
DstShutdown,
|
||||
DstTxferLocalOverrides,
|
||||
DstProcessPlayerState,
|
||||
DstTxferPredictionData,
|
||||
DstDemo_ReadBuffer,
|
||||
DstConnectionlessPacket,
|
||||
DstGetHullBounds,
|
||||
DstFrame,
|
||||
DstKey_Event,
|
||||
DstTempEntUpdate,
|
||||
DstGetUserEntity,
|
||||
DstVoiceStatus,
|
||||
DstDirectorMessage,
|
||||
DstGetStudioModelInterface,
|
||||
DstChatInputPosition,
|
||||
DstGetPlayerTeam,
|
||||
};
|
||||
|
||||
void CL_GetSecuredClientAPI( CL_EXPORT_FUNCS F )
|
||||
{
|
||||
cldll_func_src_t cldllFuncSrc = { 0 };
|
||||
modfuncs_t modFuncs = { 0 };
|
||||
|
||||
// secured client dlls need these
|
||||
*(cldll_func_dst_t **)&cldllFuncSrc.pfnVidInit = &cldllFuncDst;
|
||||
*(modfuncs_t **)&cldllFuncSrc.pfnInitialize = &modFuncs;
|
||||
|
||||
// trying to fill interface now
|
||||
F( &cldllFuncSrc );
|
||||
|
||||
// map exports to xash's cldll_func_t
|
||||
clgame.dllFuncs.pfnInitialize = cldllFuncSrc.pfnInitialize;
|
||||
clgame.dllFuncs.pfnInit = cldllFuncSrc.pfnInit;
|
||||
clgame.dllFuncs.pfnVidInit = cldllFuncSrc.pfnVidInit;
|
||||
clgame.dllFuncs.pfnRedraw = cldllFuncSrc.pfnRedraw;
|
||||
clgame.dllFuncs.pfnUpdateClientData = cldllFuncSrc.pfnUpdateClientData;
|
||||
clgame.dllFuncs.pfnReset = cldllFuncSrc.pfnReset;
|
||||
clgame.dllFuncs.pfnPlayerMove = cldllFuncSrc.pfnPlayerMove;
|
||||
clgame.dllFuncs.pfnPlayerMoveInit = cldllFuncSrc.pfnPlayerMoveInit;
|
||||
clgame.dllFuncs.pfnPlayerMoveTexture = cldllFuncSrc.pfnPlayerMoveTexture;
|
||||
clgame.dllFuncs.IN_ActivateMouse = cldllFuncSrc.IN_ActivateMouse;
|
||||
clgame.dllFuncs.IN_DeactivateMouse = cldllFuncSrc.IN_DeactivateMouse;
|
||||
clgame.dllFuncs.IN_MouseEvent = cldllFuncSrc.IN_MouseEvent;
|
||||
clgame.dllFuncs.IN_ClearStates = cldllFuncSrc.IN_ClearStates;
|
||||
clgame.dllFuncs.IN_Accumulate = cldllFuncSrc.IN_Accumulate;
|
||||
clgame.dllFuncs.CL_CreateMove = cldllFuncSrc.CL_CreateMove;
|
||||
clgame.dllFuncs.CL_IsThirdPerson = cldllFuncSrc.CL_IsThirdPerson;
|
||||
clgame.dllFuncs.CL_CameraOffset = cldllFuncSrc.CL_CameraOffset;
|
||||
clgame.dllFuncs.KB_Find = cldllFuncSrc.KB_Find;
|
||||
clgame.dllFuncs.CAM_Think = cldllFuncSrc.CAM_Think;
|
||||
clgame.dllFuncs.pfnCalcRefdef = cldllFuncSrc.pfnCalcRefdef;
|
||||
clgame.dllFuncs.pfnAddEntity = cldllFuncSrc.pfnAddEntity;
|
||||
clgame.dllFuncs.pfnCreateEntities = cldllFuncSrc.pfnCreateEntities;
|
||||
clgame.dllFuncs.pfnDrawNormalTriangles = cldllFuncSrc.pfnDrawNormalTriangles;
|
||||
clgame.dllFuncs.pfnDrawTransparentTriangles = cldllFuncSrc.pfnDrawTransparentTriangles;
|
||||
clgame.dllFuncs.pfnStudioEvent = cldllFuncSrc.pfnStudioEvent;
|
||||
clgame.dllFuncs.pfnPostRunCmd = cldllFuncSrc.pfnPostRunCmd;
|
||||
clgame.dllFuncs.pfnShutdown = cldllFuncSrc.pfnShutdown;
|
||||
clgame.dllFuncs.pfnTxferLocalOverrides = cldllFuncSrc.pfnTxferLocalOverrides;
|
||||
clgame.dllFuncs.pfnProcessPlayerState = cldllFuncSrc.pfnProcessPlayerState;
|
||||
clgame.dllFuncs.pfnTxferPredictionData = cldllFuncSrc.pfnTxferPredictionData;
|
||||
clgame.dllFuncs.pfnDemo_ReadBuffer = cldllFuncSrc.pfnDemo_ReadBuffer;
|
||||
clgame.dllFuncs.pfnConnectionlessPacket = cldllFuncSrc.pfnConnectionlessPacket;
|
||||
clgame.dllFuncs.pfnGetHullBounds = cldllFuncSrc.pfnGetHullBounds;
|
||||
clgame.dllFuncs.pfnFrame = cldllFuncSrc.pfnFrame;
|
||||
clgame.dllFuncs.pfnKey_Event = cldllFuncSrc.pfnKey_Event;
|
||||
clgame.dllFuncs.pfnTempEntUpdate = cldllFuncSrc.pfnTempEntUpdate;
|
||||
clgame.dllFuncs.pfnGetUserEntity = cldllFuncSrc.pfnGetUserEntity;
|
||||
clgame.dllFuncs.pfnVoiceStatus = cldllFuncSrc.pfnVoiceStatus;
|
||||
clgame.dllFuncs.pfnDirectorMessage = cldllFuncSrc.pfnDirectorMessage;
|
||||
clgame.dllFuncs.pfnGetStudioModelInterface = cldllFuncSrc.pfnGetStudioModelInterface;
|
||||
clgame.dllFuncs.pfnChatInputPosition = cldllFuncSrc.pfnChatInputPosition;
|
||||
}
|
||||
@@ -361,8 +361,8 @@ void CL_TempEntPlaySound( TEMPENTITY *pTemp, float damp )
|
||||
sound_t handle;
|
||||
|
||||
if( isshellcasing )
|
||||
fvol *= min ( 1.0f, ((float)zvel) / 350.0f );
|
||||
else fvol *= min ( 1.0f, ((float)zvel) / 450.0f );
|
||||
fvol *= Q_min( 1.0f, ((float)zvel) / 350.0f );
|
||||
else fvol *= Q_min( 1.0f, ((float)zvel) / 450.0f );
|
||||
|
||||
if( !COM_RandomLong( 0, 3 ) && !isshellcasing )
|
||||
pitch = COM_RandomLong( 95, 105 );
|
||||
@@ -1482,7 +1482,6 @@ void GAME_EXPORT R_FunnelSprite( const vec3_t org, int modelIndex, int reverse )
|
||||
pTemp->entity.baseline.angles[2] = COM_RandomFloat( -100.0f, 100.0f );
|
||||
pTemp->entity.curstate.framerate = COM_RandomFloat( 0.1f, 0.4f );
|
||||
pTemp->flags = FTENT_ROTATE|FTENT_FADEOUT;
|
||||
pTemp->entity.curstate.framerate = 10;
|
||||
|
||||
vel = dest[2] / 8.0f;
|
||||
if( vel < 64.0f ) vel = 64.0f;
|
||||
@@ -1515,17 +1514,18 @@ R_RicochetSound
|
||||
Make a random ricochet sound
|
||||
==============
|
||||
*/
|
||||
void GAME_EXPORT R_RicochetSound( const vec3_t pos )
|
||||
static void R_RicochetSound_( const vec3_t pos, int sound )
|
||||
{
|
||||
int iPitch = COM_RandomLong( 90, 105 );
|
||||
float fvol = COM_RandomFloat( 0.7f, 0.9f );
|
||||
char soundpath[32];
|
||||
sound_t handle;
|
||||
|
||||
Q_strncpy( soundpath, cl_ricochet_sounds[COM_RandomLong( 0, 4 )], sizeof( soundpath ) );
|
||||
handle = S_RegisterSound( soundpath );
|
||||
handle = S_RegisterSound( cl_ricochet_sounds[sound] );
|
||||
|
||||
S_StartSound( pos, 0, CHAN_AUTO, handle, fvol, ATTN_NORM, iPitch, 0 );
|
||||
S_StartSound( pos, 0, CHAN_AUTO, handle, VOL_NORM, 1.0, 100, 0 );
|
||||
}
|
||||
|
||||
void GAME_EXPORT R_RicochetSound( const vec3_t pos )
|
||||
{
|
||||
R_RicochetSound_( pos, COM_RandomLong( 0, 4 ));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1656,7 +1656,7 @@ void GAME_EXPORT R_Explosion( vec3_t pos, int model, float scale, float framerat
|
||||
dl->color.g = 250;
|
||||
dl->color.b = 150;
|
||||
dl->die = cl.time + 0.01f;
|
||||
dl->decay = 80;
|
||||
dl->decay = 800;
|
||||
|
||||
// red glow
|
||||
dl = CL_AllocDlight( 0 );
|
||||
@@ -1915,6 +1915,7 @@ void CL_ParseTempEntity( sizebuf_t *msg )
|
||||
TEMPENTITY *pTemp;
|
||||
cl_entity_t *pEnt;
|
||||
dlight_t *dl;
|
||||
sound_t hSound;
|
||||
|
||||
if( cls.legacymode )
|
||||
iSize = MSG_ReadByte( msg );
|
||||
@@ -2014,15 +2015,46 @@ void CL_ParseTempEntity( sizebuf_t *msg )
|
||||
color = MSG_ReadByte( &buf );
|
||||
count = MSG_ReadByte( &buf );
|
||||
R_ParticleExplosion2( pos, color, count );
|
||||
|
||||
dl = CL_AllocDlight( 0 );
|
||||
VectorCopy( pos, dl->origin );
|
||||
dl->radius = 350;
|
||||
dl->die = cl.time + 0.5;
|
||||
dl->decay = 300;
|
||||
|
||||
hSound = S_RegisterSound( cl_explode_sounds[0] );
|
||||
S_StartSound( pos, 0, CHAN_STATIC, hSound, VOL_NORM, 0.6f, PITCH_NORM, 0 );
|
||||
break;
|
||||
case TE_BSPDECAL:
|
||||
case TE_DECAL:
|
||||
case TE_WORLDDECAL:
|
||||
case TE_WORLDDECALHIGH:
|
||||
case TE_DECALHIGH:
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
decalIndex = MSG_ReadShort( &buf );
|
||||
entityIndex = MSG_ReadShort( &buf );
|
||||
if( entityIndex ) modelIndex = MSG_ReadShort( &buf );
|
||||
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, modelIndex, pos, FDECAL_PERMANENT );
|
||||
if( type == TE_BSPDECAL )
|
||||
{
|
||||
decalIndex = MSG_ReadShort( &buf );
|
||||
entityIndex = MSG_ReadShort( &buf );
|
||||
if( entityIndex )
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
else modelIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
decalIndex = MSG_ReadByte( &buf );
|
||||
if( type == TE_DECALHIGH || type == TE_WORLDDECALHIGH )
|
||||
decalIndex += 256;
|
||||
|
||||
if( type == TE_DECALHIGH || type == TE_DECAL )
|
||||
entityIndex = MSG_ReadShort( &buf );
|
||||
else entityIndex = 0;
|
||||
|
||||
pEnt = CL_GetEntityByIndex( entityIndex );
|
||||
modelIndex = pEnt->curstate.modelindex;
|
||||
}
|
||||
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, modelIndex, pos, type == TE_BSPDECAL ? FDECAL_PERMANENT : 0 );
|
||||
break;
|
||||
case TE_IMPLOSION:
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
@@ -2042,10 +2074,12 @@ void CL_ParseTempEntity( sizebuf_t *msg )
|
||||
pos2[2] = MSG_ReadCoord( &buf );
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
count = MSG_ReadByte( &buf );
|
||||
life = (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
scale = (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
vel = (float)MSG_ReadByte( &buf );
|
||||
random = (float)MSG_ReadByte( &buf );
|
||||
life = (float)MSG_ReadByte( &buf ) * 0.1f;
|
||||
scale = (float)MSG_ReadByte( &buf );
|
||||
if( !scale ) scale = 1.0f;
|
||||
else scale *= 0.1f;
|
||||
vel = (float)MSG_ReadByte( &buf ) * 10;
|
||||
random = (float)MSG_ReadByte( &buf ) * 10;
|
||||
R_Sprite_Trail( type, pos, pos2, modelIndex, count, life, scale, random, 255, vel );
|
||||
break;
|
||||
case TE_SPRITE:
|
||||
@@ -2053,36 +2087,23 @@ void CL_ParseTempEntity( sizebuf_t *msg )
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
scale = (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
brightness = (float)MSG_ReadByte( &buf );
|
||||
scale = (float)MSG_ReadByte( &buf ) * 0.1f;
|
||||
brightness = (float)MSG_ReadByte( &buf ) / 255.0f;
|
||||
|
||||
if(( pTemp = R_DefaultSprite( pos, modelIndex, 0 )) != NULL )
|
||||
{
|
||||
pTemp->entity.curstate.scale = scale;
|
||||
pTemp->entity.baseline.renderamt = brightness;
|
||||
pTemp->entity.curstate.renderamt = brightness;
|
||||
pTemp->entity.curstate.rendermode = kRenderTransAdd;
|
||||
}
|
||||
R_TempSprite( pos, vec3_origin, scale, modelIndex,
|
||||
kRenderTransAdd, kRenderFxNone, brightness, 0.0, FTENT_SPRANIMATE );
|
||||
break;
|
||||
case TE_GLOWSPRITE:
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
life = (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
scale = (float)(MSG_ReadByte( &buf ) * 0.1f);
|
||||
brightness = (float)MSG_ReadByte( &buf );
|
||||
life = (float)MSG_ReadByte( &buf ) * 0.1f;
|
||||
scale = (float)MSG_ReadByte( &buf ) * 0.1f;
|
||||
brightness = (float)MSG_ReadByte( &buf ) / 255.0f;
|
||||
|
||||
if(( pTemp = R_DefaultSprite( pos, modelIndex, 0 )) != NULL )
|
||||
{
|
||||
pTemp->entity.curstate.scale = scale;
|
||||
pTemp->entity.curstate.rendermode = kRenderGlow;
|
||||
pTemp->entity.curstate.renderfx = kRenderFxNoDissipation;
|
||||
pTemp->entity.baseline.renderamt = brightness;
|
||||
pTemp->entity.curstate.renderamt = brightness;
|
||||
pTemp->flags = FTENT_FADEOUT;
|
||||
pTemp->die = cl.time + life;
|
||||
}
|
||||
R_TempSprite( pos, vec3_origin, scale, modelIndex,
|
||||
kRenderGlow, kRenderFxNoDissipation, brightness, life, FTENT_FADEOUT );
|
||||
break;
|
||||
case TE_STREAK_SPLASH:
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
@@ -2172,23 +2193,6 @@ void CL_ParseTempEntity( sizebuf_t *msg )
|
||||
pos2[2] = MSG_ReadCoord( &buf );
|
||||
R_ShowLine( pos, pos2 );
|
||||
break;
|
||||
case TE_DECAL:
|
||||
case TE_DECALHIGH:
|
||||
case TE_WORLDDECAL:
|
||||
case TE_WORLDDECALHIGH:
|
||||
pos[0] = MSG_ReadCoord( &buf );
|
||||
pos[1] = MSG_ReadCoord( &buf );
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
decalIndex = MSG_ReadByte( &buf );
|
||||
if( type == TE_DECAL || type == TE_DECALHIGH )
|
||||
entityIndex = MSG_ReadShort( &buf );
|
||||
else entityIndex = 0;
|
||||
if( type == TE_DECALHIGH || type == TE_WORLDDECALHIGH )
|
||||
decalIndex += 256;
|
||||
pEnt = CL_GetEntityByIndex( entityIndex );
|
||||
if( pEnt ) modelIndex = pEnt->curstate.modelindex;
|
||||
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, modelIndex, pos, 0 );
|
||||
break;
|
||||
case TE_FIZZ:
|
||||
entityIndex = MSG_ReadShort( &buf );
|
||||
modelIndex = MSG_ReadShort( &buf );
|
||||
@@ -2244,10 +2248,11 @@ void CL_ParseTempEntity( sizebuf_t *msg )
|
||||
pos[2] = MSG_ReadCoord( &buf );
|
||||
entityIndex = MSG_ReadShort( &buf );
|
||||
decalIndex = MSG_ReadByte( &buf );
|
||||
pEnt = CL_GetEntityByIndex( entityIndex );
|
||||
CL_DecalShoot( CL_DecalIndex( decalIndex ), entityIndex, 0, pos, 0 );
|
||||
R_BulletImpactParticles( pos );
|
||||
R_RicochetSound( pos );
|
||||
flags = COM_RandomLong( 0, 0x7fff );
|
||||
if( flags < 0x3fff )
|
||||
R_RicochetSound_( pos, flags % 5 );
|
||||
break;
|
||||
case TE_SPRAY:
|
||||
case TE_SPRITE_SPRAY:
|
||||
@@ -2393,7 +2398,7 @@ void CL_ParseTempEntity( sizebuf_t *msg )
|
||||
|
||||
// throw warning
|
||||
if( MSG_CheckOverflow( &buf ))
|
||||
Con_DPrintf( S_WARN "ParseTempEntity: overflow TE message\n" );
|
||||
Con_DPrintf( S_WARN "ParseTempEntity: overflow TE message %i\n", type );
|
||||
}
|
||||
|
||||
|
||||
@@ -2693,7 +2698,7 @@ apply various effects to entity origin or attachment
|
||||
void CL_AddEntityEffects( cl_entity_t *ent )
|
||||
{
|
||||
// yellow flies effect 'monster stuck in the wall'
|
||||
if( FBitSet( ent->curstate.effects, EF_BRIGHTFIELD ))
|
||||
if( FBitSet( ent->curstate.effects, EF_BRIGHTFIELD ) && !RP_LOCALCLIENT( ent ))
|
||||
R_EntityParticles( ent );
|
||||
|
||||
if( FBitSet( ent->curstate.effects, EF_DIMLIGHT ))
|
||||
@@ -2914,7 +2919,7 @@ void CL_PlayerDecal( int playernum, int customIndex, int entityIndex, float *pos
|
||||
{
|
||||
if( FBitSet( pCust->resource.ucFlags, RES_CUSTOM ) && pCust->resource.type == t_decal && pCust->bTranslated )
|
||||
{
|
||||
if( !pCust->nUserData1 && pCust->pInfo != NULL )
|
||||
if( !pCust->nUserData1 )
|
||||
{
|
||||
const char *decalname = va( "player%dlogo%d", playernum, customIndex );
|
||||
pCust->nUserData1 = GL_LoadTextureInternal( decalname, pCust->pInfo, TF_DECAL );
|
||||
|
||||
@@ -35,30 +35,39 @@ void V_CalcViewRect( void )
|
||||
int sb_lines;
|
||||
float size;
|
||||
|
||||
// intermission is always full screen
|
||||
if( cl.intermission ) size = 120.0f;
|
||||
else size = scr_viewsize->value;
|
||||
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
{
|
||||
// intermission is always full screen
|
||||
if( cl.intermission ) size = 120.0f;
|
||||
else size = scr_viewsize->value;
|
||||
|
||||
if( size >= 120.0f )
|
||||
sb_lines = 0; // no status bar at all
|
||||
else if( size >= 110.0f )
|
||||
sb_lines = 24; // no inventory
|
||||
else sb_lines = 48;
|
||||
if( size >= 120.0f )
|
||||
sb_lines = 0; // no status bar at all
|
||||
else if( size >= 110.0f )
|
||||
sb_lines = 24; // no inventory
|
||||
else sb_lines = 48;
|
||||
|
||||
if( scr_viewsize->value >= 100.0f )
|
||||
if( scr_viewsize->value >= 100.0f )
|
||||
{
|
||||
full = true;
|
||||
size = 100.0f;
|
||||
}
|
||||
else size = scr_viewsize->value;
|
||||
|
||||
if( cl.intermission )
|
||||
{
|
||||
size = 100.0f;
|
||||
sb_lines = 0;
|
||||
full = true;
|
||||
}
|
||||
size /= 100.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
full = true;
|
||||
size = 100.0f;
|
||||
}
|
||||
else size = scr_viewsize->value;
|
||||
|
||||
if( cl.intermission )
|
||||
{
|
||||
size = 100.0f;
|
||||
sb_lines = 0;
|
||||
full = true;
|
||||
size = 1.0f;
|
||||
}
|
||||
size /= 100.0f;
|
||||
|
||||
clgame.viewport[2] = refState.width * size;
|
||||
clgame.viewport[3] = refState.height * size;
|
||||
|
||||
@@ -625,8 +625,6 @@ typedef struct
|
||||
// legacy mode support
|
||||
qboolean legacymode; // one-way 48 protocol compatibility
|
||||
netadr_t legacyserver;
|
||||
netadr_t legacyservers[MAX_LEGACY_SERVERS];
|
||||
int legacyservercount;
|
||||
int extensions;
|
||||
|
||||
netadr_t serveradr;
|
||||
@@ -679,7 +677,6 @@ extern convar_t *cl_fixtimerate;
|
||||
extern convar_t *hud_scale;
|
||||
extern convar_t *gl_showtextures;
|
||||
extern convar_t *cl_bmodelinterp;
|
||||
extern convar_t *cl_righthand;
|
||||
extern convar_t *cl_lw; // local weapons
|
||||
extern convar_t *cl_charset;
|
||||
extern convar_t *cl_trace_messages;
|
||||
@@ -1049,7 +1046,6 @@ void Con_Bottom( void );
|
||||
void Con_Top( void );
|
||||
void Con_PageDown( int lines );
|
||||
void Con_PageUp( int lines );
|
||||
void Con_LoadHistory( void );
|
||||
|
||||
//
|
||||
// s_main.c
|
||||
@@ -1113,6 +1109,11 @@ void pfnPIC_DrawAdditive( int x, int y, int width, int height, const wrect_t *pr
|
||||
qboolean Mobile_Init( void );
|
||||
void Mobile_Shutdown( void );
|
||||
|
||||
//
|
||||
// cl_securedstub.c
|
||||
//
|
||||
void CL_GetSecuredClientAPI( CL_EXPORT_FUNCS F );
|
||||
|
||||
//
|
||||
// cl_video.c
|
||||
//
|
||||
|
||||
@@ -33,6 +33,8 @@ convar_t *con_color;
|
||||
static int g_codepage = 0;
|
||||
static qboolean g_utf8 = false;
|
||||
|
||||
static qboolean g_messagemode_privileged = true;
|
||||
|
||||
#define CON_TIMES 4 // notify lines
|
||||
#define CON_MAX_TIMES 64 // notify max lines
|
||||
#define COLOR_DEFAULT '7'
|
||||
@@ -79,6 +81,14 @@ typedef struct con_lineinfo_s
|
||||
double addtime; // notify stuff
|
||||
} con_lineinfo_t;
|
||||
|
||||
typedef struct con_history_s
|
||||
{
|
||||
field_t lines[CON_HISTORY];
|
||||
field_t backup;
|
||||
int line; // the line being displayed from history buffer will be <= nextHistoryLine
|
||||
int next; // the last line in the history buffer, not masked
|
||||
} con_history_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
qboolean initialized;
|
||||
@@ -116,10 +126,8 @@ typedef struct
|
||||
string chat_cmd; // can be overrieded by user
|
||||
|
||||
// console history
|
||||
field_t historyLines[CON_HISTORY];
|
||||
int historyLine; // the line being displayed from history buffer will be <= nextHistoryLine
|
||||
int nextHistoryLine; // the last line in the history buffer, not masked
|
||||
field_t backup;
|
||||
con_history_t history;
|
||||
qboolean historyLoaded;
|
||||
|
||||
notify_t notify[MAX_DBG_NOTIFY]; // for Con_NXPrintf
|
||||
qboolean draw_notify; // true if we have NXPrint message
|
||||
@@ -133,6 +141,9 @@ static console_t con;
|
||||
void Con_ClearField( field_t *edit );
|
||||
void Field_CharEvent( field_t *edit, int ch );
|
||||
|
||||
static void Con_LoadHistory( con_history_t *self );
|
||||
static void Con_SaveHistory( con_history_t *self );
|
||||
|
||||
/*
|
||||
================
|
||||
Con_Clear_f
|
||||
@@ -196,8 +207,6 @@ Con_ClearTyping
|
||||
*/
|
||||
void Con_ClearTyping( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
Con_ClearField( &con.input );
|
||||
con.input.widthInChars = con.linewidth;
|
||||
|
||||
@@ -242,6 +251,8 @@ Con_MessageMode_f
|
||||
*/
|
||||
void Con_MessageMode_f( void )
|
||||
{
|
||||
g_messagemode_privileged = Cmd_CurrentCommandIsPrivileged();
|
||||
|
||||
if( Cmd_Argc() == 2 )
|
||||
Q_strncpy( con.chat_cmd, Cmd_Argv( 1 ), sizeof( con.chat_cmd ));
|
||||
else Q_strncpy( con.chat_cmd, "say", sizeof( con.chat_cmd ));
|
||||
@@ -256,6 +267,8 @@ Con_MessageMode2_f
|
||||
*/
|
||||
void Con_MessageMode2_f( void )
|
||||
{
|
||||
g_messagemode_privileged = Cmd_CurrentCommandIsPrivileged();
|
||||
|
||||
Q_strncpy( con.chat_cmd, "say_team", sizeof( con.chat_cmd ));
|
||||
Key_SetKeyDest( key_message );
|
||||
}
|
||||
@@ -480,7 +493,7 @@ void Con_CheckResize( void )
|
||||
con.input.widthInChars = con.linewidth;
|
||||
|
||||
for( i = 0; i < CON_HISTORY; i++ )
|
||||
con.historyLines[i].widthInChars = con.linewidth;
|
||||
con.history.lines[i].widthInChars = con.linewidth;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1056,7 +1069,7 @@ int Con_DrawGenericString( int x, int y, const char *string, rgba_t setColor, qb
|
||||
Con_UtfProcessChar( 0 );
|
||||
|
||||
// draw the colored text
|
||||
*(uint *)color = *(uint *)setColor;
|
||||
memcpy( color, setColor, sizeof( color ));
|
||||
s = string;
|
||||
|
||||
while( *s )
|
||||
@@ -1107,61 +1120,6 @@ int Con_DrawString( int x, int y, const char *string, rgba_t setColor )
|
||||
return Con_DrawGenericString( x, y, string, setColor, false, -1 );
|
||||
}
|
||||
|
||||
void Con_LoadHistory( void )
|
||||
{
|
||||
const byte *aFile = FS_LoadFile( "console_history.txt", NULL, true );
|
||||
const char *pLine = (char *)aFile, *pFile = (char *)aFile;
|
||||
int i;
|
||||
|
||||
if( !aFile )
|
||||
return;
|
||||
|
||||
while( true )
|
||||
{
|
||||
if( !*pFile )
|
||||
break;
|
||||
if( *pFile == '\n')
|
||||
{
|
||||
int len = pFile - pLine + 1;
|
||||
field_t *f;
|
||||
if( len > 255 ) len = 255;
|
||||
Con_ClearField( &con.historyLines[con.nextHistoryLine] );
|
||||
f = &con.historyLines[con.nextHistoryLine % CON_HISTORY];
|
||||
f->widthInChars = con.linewidth;
|
||||
f->cursor = len - 1;
|
||||
Q_strncpy( f->buffer, pLine, len);
|
||||
con.nextHistoryLine++;
|
||||
pLine = pFile + 1;
|
||||
}
|
||||
pFile++;
|
||||
}
|
||||
|
||||
for( i = con.nextHistoryLine; i < CON_HISTORY; i++ )
|
||||
{
|
||||
Con_ClearField( &con.historyLines[i] );
|
||||
con.historyLines[i].widthInChars = con.linewidth;
|
||||
}
|
||||
|
||||
con.historyLine = con.nextHistoryLine;
|
||||
|
||||
}
|
||||
|
||||
void Con_SaveHistory( void )
|
||||
{
|
||||
int historyStart = con.nextHistoryLine - CON_HISTORY;
|
||||
int i;
|
||||
file_t *f;
|
||||
|
||||
if( historyStart < 0 )
|
||||
historyStart = 0;
|
||||
|
||||
f = FS_Open("console_history.txt", "w", true );
|
||||
|
||||
for( i = historyStart; i < con.nextHistoryLine; i++ )
|
||||
FS_Printf( f, "%s\n", con.historyLines[i % CON_HISTORY].buffer );
|
||||
|
||||
FS_Close(f);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
@@ -1201,7 +1159,7 @@ void Con_Init( void )
|
||||
con.chat.widthInChars = con.linewidth;
|
||||
|
||||
Cmd_AddCommand( "toggleconsole", Con_ToggleConsole_f, "opens or closes the console" );
|
||||
Cmd_AddCommand( "clear", Con_Clear_f, "clear console history" );
|
||||
Cmd_AddRestrictedCommand( "clear", Con_Clear_f, "clear console history" );
|
||||
Cmd_AddCommand( "messagemode", Con_MessageMode_f, "enable message mode \"say\"" );
|
||||
Cmd_AddCommand( "messagemode2", Con_MessageMode2_f, "enable message mode \"say_team\"" );
|
||||
Cmd_AddCommand( "contimes", Con_SetTimes_f, "change number of console overlay lines (4-64)" );
|
||||
@@ -1227,7 +1185,7 @@ void Con_Shutdown( void )
|
||||
|
||||
con.buffer = NULL;
|
||||
con.lines = NULL;
|
||||
Con_SaveHistory();
|
||||
Con_SaveHistory( &con.history );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1462,11 +1420,22 @@ Con_ClearField
|
||||
*/
|
||||
void Con_ClearField( field_t *edit )
|
||||
{
|
||||
memset(edit->buffer, 0, MAX_STRING);
|
||||
memset( edit->buffer, 0, MAX_STRING );
|
||||
edit->cursor = 0;
|
||||
edit->scroll = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Field_Set
|
||||
================
|
||||
*/
|
||||
static void Field_Set( field_t *f, const char *string )
|
||||
{
|
||||
f->scroll = 0;
|
||||
f->cursor = Q_strncpy( f->buffer, string, MAX_STRING );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Field_Paste
|
||||
@@ -1486,6 +1455,18 @@ void Field_Paste( field_t *edit )
|
||||
Field_CharEvent( edit, cbd[i] );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Field_GoTo
|
||||
|
||||
=================
|
||||
*/
|
||||
static void Field_GoTo( field_t *edit, int pos )
|
||||
{
|
||||
edit->cursor = pos;
|
||||
edit->scroll = Q_max( 0, edit->cursor - edit->widthInChars );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Field_KeyDownEvent
|
||||
@@ -1538,20 +1519,20 @@ void Field_KeyDownEvent( field_t *edit, int key )
|
||||
|
||||
if( key == K_LEFTARROW )
|
||||
{
|
||||
if( edit->cursor > 0 ) edit->cursor= Con_UtfMoveLeft( edit->buffer, edit->cursor );
|
||||
if( edit->cursor > 0 ) edit->cursor = Con_UtfMoveLeft( edit->buffer, edit->cursor );
|
||||
if( edit->cursor < edit->scroll ) edit->scroll--;
|
||||
return;
|
||||
}
|
||||
|
||||
if( key == K_HOME || ( Q_tolower(key) == 'a' && Key_IsDown( K_CTRL )))
|
||||
{
|
||||
edit->cursor = 0;
|
||||
Field_GoTo( edit, 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
if( key == K_END || ( Q_tolower(key) == 'e' && Key_IsDown( K_CTRL )))
|
||||
{
|
||||
edit->cursor = len;
|
||||
Field_GoTo( edit, len );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1590,16 +1571,14 @@ void Field_CharEvent( field_t *edit, int ch )
|
||||
if( ch == 'a' - 'a' + 1 )
|
||||
{
|
||||
// ctrl-a is home
|
||||
edit->cursor = 0;
|
||||
edit->scroll = 0;
|
||||
Field_GoTo( edit, 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
if( ch == 'e' - 'a' + 1 )
|
||||
{
|
||||
// ctrl-e is end
|
||||
edit->cursor = len;
|
||||
edit->scroll = edit->cursor - edit->widthInChars;
|
||||
Field_GoTo( edit, len );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1702,12 +1681,134 @@ void Field_DrawInputLine( int x, int y, field_t *edit )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
CONSOLE HISTORY HANDLING
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
/*
|
||||
===================
|
||||
Con_HistoryUp
|
||||
|
||||
===================
|
||||
*/
|
||||
static void Con_HistoryUp( con_history_t *self, field_t *in )
|
||||
{
|
||||
if( self->line == self->next )
|
||||
self->backup = *in;
|
||||
|
||||
if(( self->next - self->line ) < CON_HISTORY )
|
||||
self->line = Q_max( 0, self->line - 1 );
|
||||
|
||||
*in = self->lines[self->line % CON_HISTORY];
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
Con_HistoryDown
|
||||
|
||||
===================
|
||||
*/
|
||||
static void Con_HistoryDown( con_history_t *self, field_t *in )
|
||||
{
|
||||
self->line = Q_min( self->next, self->line + 1 );
|
||||
if( self->line == self->next )
|
||||
*in = self->backup;
|
||||
else *in = self->lines[self->line % CON_HISTORY];
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
Con_HistoryAppend
|
||||
===================
|
||||
*/
|
||||
static void Con_HistoryAppend( con_history_t *self, field_t *from )
|
||||
{
|
||||
int prevLine = Q_max( 0, self->line - 1 );
|
||||
const char *buf = from->buffer;
|
||||
|
||||
// skip backslashes
|
||||
if( from->buffer[0] == '\\' || from->buffer[1] == '/' )
|
||||
buf++;
|
||||
|
||||
// only if non-empty
|
||||
if( !from->buffer[0] )
|
||||
return;
|
||||
|
||||
// skip empty commands
|
||||
if( Q_isspace( buf ))
|
||||
return;
|
||||
|
||||
// if not copy (don't ignore backslashes)
|
||||
if( !Q_strcmp( from->buffer, self->lines[prevLine % CON_HISTORY].buffer ))
|
||||
return;
|
||||
|
||||
self->lines[self->next % CON_HISTORY] = *from;
|
||||
self->line = ++self->next;
|
||||
}
|
||||
|
||||
static void Con_LoadHistory( con_history_t *self )
|
||||
{
|
||||
const byte *aFile = FS_LoadFile( "console_history.txt", NULL, true );
|
||||
const char *pLine, *pFile;
|
||||
int i, len;
|
||||
field_t *f;
|
||||
|
||||
if( !aFile )
|
||||
return;
|
||||
|
||||
for( pFile = pLine = (char *)aFile; *pFile; pFile++ )
|
||||
{
|
||||
if( *pFile != '\n' )
|
||||
continue;
|
||||
|
||||
Con_ClearField( &self->lines[self->next] );
|
||||
|
||||
len = Q_min( pFile - pLine + 1, sizeof( f->buffer ));
|
||||
f = &self->lines[self->next % CON_HISTORY];
|
||||
f->widthInChars = con.linewidth;
|
||||
f->cursor = len - 1;
|
||||
Q_strncpy( f->buffer, pLine, len);
|
||||
|
||||
self->next++;
|
||||
|
||||
pLine = pFile + 1;
|
||||
}
|
||||
|
||||
for( i = self->next; i < CON_HISTORY; i++ )
|
||||
{
|
||||
Con_ClearField( &self->lines[i] );
|
||||
self->lines[i].widthInChars = con.linewidth;
|
||||
}
|
||||
|
||||
self->line = self->next;
|
||||
}
|
||||
|
||||
static void Con_SaveHistory( con_history_t *self )
|
||||
{
|
||||
int historyStart = self->next - CON_HISTORY, i;
|
||||
file_t *f;
|
||||
|
||||
if( historyStart < 0 )
|
||||
historyStart = 0;
|
||||
|
||||
f = FS_Open( "console_history.txt", "w", true );
|
||||
|
||||
for( i = historyStart; i < self->next; i++ )
|
||||
FS_Printf( f, "%s\n", self->lines[i % CON_HISTORY].buffer );
|
||||
|
||||
FS_Close( f );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
CONSOLE LINE EDITING
|
||||
|
||||
==============================================================================
|
||||
=============================================================================
|
||||
*/
|
||||
/*
|
||||
====================
|
||||
@@ -1728,16 +1829,6 @@ void Key_Console( int key )
|
||||
// enter finishes the line
|
||||
if( key == K_ENTER || key == K_KP_ENTER )
|
||||
{
|
||||
// if not in the game explicitly prepent a slash if needed
|
||||
if( cls.state != ca_active && con.input.buffer[0] != '\\' && con.input.buffer[0] != '/' )
|
||||
{
|
||||
char temp[MAX_SYSPATH];
|
||||
|
||||
Q_strncpy( temp, con.input.buffer, sizeof( temp ));
|
||||
Q_sprintf( con.input.buffer, "\\%s", temp );
|
||||
con.input.cursor++;
|
||||
}
|
||||
|
||||
// backslash text are commands, else chat
|
||||
if( con.input.buffer[0] == '\\' || con.input.buffer[0] == '/' )
|
||||
Cbuf_AddText( con.input.buffer + 1 ); // skip backslash
|
||||
@@ -1748,9 +1839,7 @@ void Key_Console( int key )
|
||||
Con_Printf( ">%s\n", con.input.buffer );
|
||||
|
||||
// copy line to history buffer
|
||||
con.historyLines[con.nextHistoryLine % CON_HISTORY] = con.input;
|
||||
con.nextHistoryLine++;
|
||||
con.historyLine = con.nextHistoryLine;
|
||||
Con_HistoryAppend( &con.history, &con.input );
|
||||
|
||||
Con_ClearField( &con.input );
|
||||
con.input.widthInChars = con.linewidth;
|
||||
@@ -1775,23 +1864,13 @@ void Key_Console( int key )
|
||||
// command history (ctrl-p ctrl-n for unix style)
|
||||
if(( key == K_MWHEELUP && Key_IsDown( K_SHIFT )) || ( key == K_UPARROW ) || (( Q_tolower(key) == 'p' ) && Key_IsDown( K_CTRL )))
|
||||
{
|
||||
if( con.historyLine == con.nextHistoryLine )
|
||||
con.backup = con.input;
|
||||
if( con.nextHistoryLine - con.historyLine < CON_HISTORY && con.historyLine > 0 )
|
||||
con.historyLine--;
|
||||
con.input = con.historyLines[con.historyLine % CON_HISTORY];
|
||||
Con_HistoryUp( &con.history, &con.input );
|
||||
return;
|
||||
}
|
||||
|
||||
if(( key == K_MWHEELDOWN && Key_IsDown( K_SHIFT )) || ( key == K_DOWNARROW ) || (( Q_tolower(key) == 'n' ) && Key_IsDown( K_CTRL )))
|
||||
{
|
||||
if( con.historyLine >= con.nextHistoryLine - 1 )
|
||||
con.input = con.backup;
|
||||
else
|
||||
{
|
||||
con.historyLine++;
|
||||
con.input = con.historyLines[con.historyLine % CON_HISTORY];
|
||||
}
|
||||
Con_HistoryDown( &con.history, &con.input );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1865,7 +1944,10 @@ void Key_Message( int key )
|
||||
if( con.chat.buffer[0] && cls.state == ca_active )
|
||||
{
|
||||
Q_snprintf( buffer, sizeof( buffer ), "%s \"%s\"\n", con.chat_cmd, con.chat.buffer );
|
||||
Cbuf_AddText( buffer );
|
||||
|
||||
if( g_messagemode_privileged )
|
||||
Cbuf_AddText( buffer );
|
||||
else Cbuf_AddFilteredText( buffer );
|
||||
}
|
||||
|
||||
Key_SetKeyDest( key_game );
|
||||
@@ -2092,6 +2174,9 @@ void Con_DrawSolidConsole( int lines )
|
||||
int i, x, y;
|
||||
float fraction;
|
||||
int start;
|
||||
int stringLen, width = 0, charH;
|
||||
string curbuild;
|
||||
byte color[4];
|
||||
|
||||
if( lines <= 0 ) return;
|
||||
|
||||
@@ -2105,28 +2190,20 @@ void Con_DrawSolidConsole( int lines )
|
||||
if( !con.curFont || !host.allow_console )
|
||||
return; // nothing to draw
|
||||
|
||||
if( host.allow_console )
|
||||
{
|
||||
// draw current version
|
||||
int stringLen, width = 0, charH;
|
||||
string curbuild;
|
||||
byte color[4];
|
||||
// draw current version
|
||||
memcpy( color, g_color_table[7], sizeof( color ));
|
||||
|
||||
memcpy( color, g_color_table[7], sizeof( color ));
|
||||
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 );
|
||||
|
||||
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( ));
|
||||
fraction = lines / (float)refState.height;
|
||||
color[3] = Q_min( fraction * 2.0f, 1.0f ) * 255; // fadeout version number
|
||||
|
||||
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
|
||||
|
||||
for( i = 0; i < stringLen; i++ )
|
||||
width += Con_DrawCharacter( start + width, 0, curbuild[i], color );
|
||||
}
|
||||
for( i = 0; i < stringLen; i++ )
|
||||
width += Con_DrawCharacter( start + width, 0, curbuild[i], color );
|
||||
|
||||
// draw the text
|
||||
if( CON_LINES_COUNT > 0 )
|
||||
@@ -2163,7 +2240,7 @@ void Con_DrawSolidConsole( int lines )
|
||||
Con_DrawInput( lines );
|
||||
|
||||
y = lines - ( con.curFont->charHeight * 1.2f );
|
||||
SCR_DrawFPS( max( y, 4 )); // to avoid to hide fps counter
|
||||
SCR_DrawFPS( Q_max( y, 4 )); // to avoid to hide fps counter
|
||||
|
||||
ref.dllFuncs.Color4ub( 255, 255, 255, 255 );
|
||||
}
|
||||
@@ -2379,6 +2456,12 @@ INTERNAL RESOURCE
|
||||
*/
|
||||
void Con_VidInit( void )
|
||||
{
|
||||
if( !con.historyLoaded )
|
||||
{
|
||||
Con_LoadHistory( &con.history );
|
||||
con.historyLoaded = true;
|
||||
}
|
||||
|
||||
Con_LoadConchars();
|
||||
Con_CheckResize();
|
||||
#if XASH_LOW_MEMORY
|
||||
@@ -2414,7 +2497,6 @@ void Con_VidInit( void )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( !con.background ) // last chance - quake conback image
|
||||
{
|
||||
qboolean draw_to_console = false;
|
||||
@@ -2502,3 +2584,48 @@ void GAME_EXPORT Con_DefaultColor( int r, int g, int b )
|
||||
b = bound( 0, b, 255 );
|
||||
MakeRGBA( g_color_table[7], r, g, b, 255 );
|
||||
}
|
||||
|
||||
#if XASH_ENGINE_TESTS
|
||||
#include "tests.h"
|
||||
|
||||
static void Test_RunConHistory( void )
|
||||
{
|
||||
con_history_t hist = { 0 };
|
||||
field_t input = { 0 };
|
||||
const char *strs1[] = { "map t0a0", "quit", "wtf", "wtf", "", "nyan" };
|
||||
const char *strs2[] = { "nyan", "wtf", "quit", "map t0a0" };
|
||||
const char *testbackup = "unfinished_edit";
|
||||
int i;
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( strs1 ); i++ )
|
||||
{
|
||||
Field_Set( &input, strs1[i] );
|
||||
Con_HistoryAppend( &hist, &input );
|
||||
}
|
||||
|
||||
Field_Set( &input, testbackup );
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( strs2 ); i++ )
|
||||
{
|
||||
Con_HistoryUp( &hist, &input );
|
||||
TASSERT_STR( input.buffer, strs2[i] );
|
||||
}
|
||||
|
||||
// check for overrun
|
||||
Con_HistoryUp( &hist, &input );
|
||||
|
||||
for( i = ARRAYSIZE( strs2 ) - 1; i >= 0; i-- )
|
||||
{
|
||||
TASSERT_STR( input.buffer, strs2[i] );
|
||||
Con_HistoryDown( &hist, &input );
|
||||
}
|
||||
|
||||
TASSERT_STR( input.buffer, testbackup );
|
||||
}
|
||||
|
||||
void Test_RunCon( void )
|
||||
{
|
||||
TRUN( Test_RunConHistory() );
|
||||
}
|
||||
|
||||
#endif /* XASH_ENGINE_TESTS */
|
||||
|
||||
@@ -380,32 +380,32 @@ Main init procedure
|
||||
*/
|
||||
void Joy_Init( void )
|
||||
{
|
||||
joy_pitch = Cvar_Get( "joy_pitch", "100.0", FCVAR_ARCHIVE, "joystick pitch sensitivity" );
|
||||
joy_yaw = Cvar_Get( "joy_yaw", "100.0", FCVAR_ARCHIVE, "joystick yaw sensitivity" );
|
||||
joy_side = Cvar_Get( "joy_side", "1.0", FCVAR_ARCHIVE, "joystick side sensitivity. Values from -1.0 to 1.0" );
|
||||
joy_forward = Cvar_Get( "joy_forward", "1.0", FCVAR_ARCHIVE, "joystick forward sensitivity. Values from -1.0 to 1.0" );
|
||||
joy_pitch = Cvar_Get( "joy_pitch", "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick pitch sensitivity" );
|
||||
joy_yaw = Cvar_Get( "joy_yaw", "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick yaw sensitivity" );
|
||||
joy_side = Cvar_Get( "joy_side", "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick side sensitivity. Values from -1.0 to 1.0" );
|
||||
joy_forward = Cvar_Get( "joy_forward", "1.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick forward sensitivity. Values from -1.0 to 1.0" );
|
||||
|
||||
joy_lt_threshold = Cvar_Get( "joy_lt_threshold", "16384", FCVAR_ARCHIVE, "left trigger threshold. Value from 0 to 32767");
|
||||
joy_rt_threshold = Cvar_Get( "joy_rt_threshold", "16384", FCVAR_ARCHIVE, "right trigger threshold. Value from 0 to 32767" );
|
||||
joy_lt_threshold = Cvar_Get( "joy_lt_threshold", "16384", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "left trigger threshold. Value from 0 to 32767");
|
||||
joy_rt_threshold = Cvar_Get( "joy_rt_threshold", "16384", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "right trigger threshold. Value from 0 to 32767" );
|
||||
|
||||
// emit a key event at 75% axis move
|
||||
joy_side_key_threshold = Cvar_Get( "joy_side_key_threshold", "24576", FCVAR_ARCHIVE, "side axis key event emit threshold. Value from 0 to 32767" );
|
||||
joy_forward_key_threshold = Cvar_Get( "joy_forward_key_threshold", "24576", FCVAR_ARCHIVE, "forward axis key event emit threshold. Value from 0 to 32767");
|
||||
joy_side_key_threshold = Cvar_Get( "joy_side_key_threshold", "24576", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "side axis key event emit threshold. Value from 0 to 32767" );
|
||||
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", "0", FCVAR_ARCHIVE, "side axis deadzone. Value from 0 to 32767" );
|
||||
joy_forward_deadzone = Cvar_Get( "joy_forward_deadzone", "0", FCVAR_ARCHIVE, "forward axis deadzone. Value from 0 to 32767");
|
||||
joy_pitch_deadzone = Cvar_Get( "joy_pitch_deadzone", "0", FCVAR_ARCHIVE, "pitch axis deadzone. Value from 0 to 32767");
|
||||
joy_yaw_deadzone = Cvar_Get( "joy_yaw_deadzone", "0", FCVAR_ARCHIVE, "yaw axis deadzone. Value from 0 to 32767" );
|
||||
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, "axis hardware id to engine inner axis binding, "
|
||||
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" );
|
||||
joy_found = Cvar_Get( "joy_found", "0", FCVAR_READ_ONLY, "is joystick is connected" );
|
||||
// we doesn't loaded config.cfg yet, so this cvar is not archive.
|
||||
// change by +set joy_index in cmdline
|
||||
joy_index = Cvar_Get( "joy_index", "0", FCVAR_READ_ONLY, "current active joystick" );
|
||||
|
||||
joy_enable = Cvar_Get( "joy_enable", "1", FCVAR_ARCHIVE, "enable joystick" );
|
||||
joy_enable = Cvar_Get( "joy_enable", "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable joystick" );
|
||||
|
||||
if( Sys_CheckParm( "-nojoy" ))
|
||||
{
|
||||
|
||||
@@ -134,6 +134,9 @@ struct touch_s
|
||||
qboolean configchanged;
|
||||
} touch;
|
||||
|
||||
// private to the engine flags
|
||||
#define TOUCH_FL_UNPRIVILEGED BIT( 10 )
|
||||
|
||||
touchdefaultbutton_t g_DefaultButtons[256];
|
||||
int g_LastDefaultButton;
|
||||
|
||||
@@ -194,6 +197,8 @@ static inline int Touch_ExportButtonToConfig( file_t *f, touch_button_t *button,
|
||||
if( FBitSet( flags, TOUCH_FL_DEF_HIDE ))
|
||||
SetBits( flags, TOUCH_FL_HIDE );
|
||||
|
||||
Cmd_Escape( newCommand, B( command ), sizeof( newCommand ));
|
||||
|
||||
FS_Printf( f, "touch_addbutton \"%s\" \"%s\" \"%s\" %f %f %f %f %d %d %d %d %d",
|
||||
B(name), B(texturefile), newCommand,
|
||||
B(x1), B(y1), B(x2), B(y2),
|
||||
@@ -455,28 +460,42 @@ static void Touch_Stroke_f( void )
|
||||
MakeRGBA( touch.scolor, Q_atoi( Cmd_Argv( 2 ) ), Q_atoi( Cmd_Argv( 3 ) ), Q_atoi( Cmd_Argv( 4 ) ), Q_atoi( Cmd_Argv( 5 ) ) );
|
||||
}
|
||||
|
||||
static touch_button_t *Touch_FindButton( touchbuttonlist_t *list, const char *name )
|
||||
static touch_button_t *Touch_FindButton( touchbuttonlist_t *list, const char *name, qboolean privileged )
|
||||
{
|
||||
touch_button_t *button;
|
||||
|
||||
for( button = list->first; button; button = button->next )
|
||||
if( !Q_strncmp( button->name, name, sizeof( button->name )))
|
||||
return button;
|
||||
{
|
||||
if( !privileged && !FBitSet( button->flags, TOUCH_FL_UNPRIVILEGED ))
|
||||
continue;
|
||||
|
||||
if( Q_strncmp( button->name, name, sizeof( button->name )))
|
||||
continue;
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static touch_button_t *Touch_FindFirst( touchbuttonlist_t *list, const char *name )
|
||||
static touch_button_t *Touch_FindFirst( touchbuttonlist_t *list, const char *name, qboolean privileged )
|
||||
{
|
||||
touch_button_t *button;
|
||||
|
||||
for( button = list->first; button; button = button->next )
|
||||
{
|
||||
if( !privileged && !FBitSet( button->flags, TOUCH_FL_UNPRIVILEGED ))
|
||||
continue;
|
||||
|
||||
if(( Q_strchr( name, '*' ) && Q_stricmpext( name, button->name )) || !Q_strncmp( name, button->name, sizeof( button->name )))
|
||||
{
|
||||
return button;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Touch_SetClientOnly( qboolean state )
|
||||
void Touch_SetClientOnly( byte state )
|
||||
{
|
||||
touch.clientonly = state;
|
||||
host.mouse_visible = state;
|
||||
@@ -484,20 +503,14 @@ void Touch_SetClientOnly( qboolean state )
|
||||
touch.move_finger = touch.look_finger = -1;
|
||||
touch.forward = touch.side = 0;
|
||||
|
||||
/// TODO: touch sdl platform
|
||||
#if 0
|
||||
if( state )
|
||||
{
|
||||
SDL_SetRelativeMouseMode( SDL_FALSE );
|
||||
SDL_ShowCursor( true );
|
||||
IN_DeactivateMouse();
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_ShowCursor( false );
|
||||
SDL_GetRelativeMouseState( 0, 0 );
|
||||
IN_ActivateMouse();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void Touch_SetClientOnly_f( void )
|
||||
@@ -511,13 +524,13 @@ static void Touch_SetClientOnly_f( void )
|
||||
Touch_SetClientOnly( Q_atoi( Cmd_Argv( 1 )));
|
||||
}
|
||||
|
||||
static void Touch_RemoveButtonFromList( touchbuttonlist_t *list, const char *name )
|
||||
static void Touch_RemoveButtonFromList( touchbuttonlist_t *list, const char *name, qboolean privileged )
|
||||
{
|
||||
touch_button_t *button;
|
||||
|
||||
IN_TouchEditClear();
|
||||
|
||||
while(( button = Touch_FindFirst( &touch.list_user, name )))
|
||||
while(( button = Touch_FindFirst( &touch.list_user, name, privileged )))
|
||||
{
|
||||
if( button->prev )
|
||||
button->prev->next = button->next;
|
||||
@@ -534,9 +547,9 @@ static void Touch_RemoveButtonFromList( touchbuttonlist_t *list, const char *nam
|
||||
|
||||
}
|
||||
|
||||
void Touch_RemoveButton( const char *name )
|
||||
void Touch_RemoveButton( const char *name, qboolean privileged )
|
||||
{
|
||||
Touch_RemoveButtonFromList( &touch.list_user, name );
|
||||
Touch_RemoveButtonFromList( &touch.list_user, name, privileged );
|
||||
}
|
||||
|
||||
static void IN_TouchRemoveButton_f( void )
|
||||
@@ -547,7 +560,7 @@ static void IN_TouchRemoveButton_f( void )
|
||||
return;
|
||||
}
|
||||
|
||||
Touch_RemoveButton( Cmd_Argv( 1 ));
|
||||
Touch_RemoveButton( Cmd_Argv( 1 ), Cmd_CurrentCommandIsPrivileged());
|
||||
}
|
||||
|
||||
static void Touch_ClearList( touchbuttonlist_t *list )
|
||||
@@ -578,9 +591,9 @@ static void Touch_SetColor( touchbuttonlist_t *list, const char *name, byte *col
|
||||
}
|
||||
}
|
||||
|
||||
static void Touch_SetTexture( touchbuttonlist_t *list, const char *name, const char *texture )
|
||||
static void Touch_SetTexture( touchbuttonlist_t *list, const char *name, const char *texture, qboolean privileged )
|
||||
{
|
||||
touch_button_t *button = Touch_FindButton( list, name );
|
||||
touch_button_t *button = Touch_FindButton( list, name, privileged );
|
||||
|
||||
if( !button )
|
||||
return;
|
||||
@@ -605,12 +618,15 @@ static void Touch_SetCommand( touch_button_t *button, const char *command )
|
||||
button->type = touch_wheel;
|
||||
}
|
||||
|
||||
void Touch_HideButtons( const char *name, byte hide )
|
||||
void Touch_HideButtons( const char *name, byte hide, qboolean privileged )
|
||||
{
|
||||
touch_button_t *button;
|
||||
|
||||
for( button = touch.list_user.first; button; button = button->next)
|
||||
{
|
||||
if( !privileged && !FBitSet( button->flags, TOUCH_FL_UNPRIVILEGED ))
|
||||
continue;
|
||||
|
||||
if(( Q_strchr( name, '*' ) && Q_stricmpext( name, button->name )) || !Q_strncmp( name, button->name, sizeof( button->name )))
|
||||
{
|
||||
if( hide )
|
||||
@@ -635,7 +651,7 @@ static void Touch_Hide_f( void )
|
||||
return;
|
||||
}
|
||||
|
||||
Touch_HideButtons( Cmd_Argv( 1 ), true );
|
||||
Touch_HideButtons( Cmd_Argv( 1 ), true, Cmd_CurrentCommandIsPrivileged() );
|
||||
}
|
||||
|
||||
static void Touch_Show_f( void )
|
||||
@@ -646,14 +662,17 @@ static void Touch_Show_f( void )
|
||||
return;
|
||||
}
|
||||
|
||||
Touch_HideButtons( Cmd_Argv( 1 ), false );
|
||||
Touch_HideButtons( Cmd_Argv( 1 ), false, Cmd_CurrentCommandIsPrivileged() );
|
||||
}
|
||||
|
||||
static void Touch_FadeButtons( touchbuttonlist_t *list, const char *name, float speed, float end, float start )
|
||||
static void Touch_FadeButtons( touchbuttonlist_t *list, const char *name, float speed, float end, float start, qboolean privileged )
|
||||
{
|
||||
touch_button_t *button;
|
||||
for( button = list->first; button; button = button->next)
|
||||
{
|
||||
if( !privileged && !FBitSet( button->flags, TOUCH_FL_UNPRIVILEGED ))
|
||||
continue;
|
||||
|
||||
if(( Q_strchr( name, '*' ) && Q_stricmpext( name, button->name )) || !Q_strncmp( name, button->name, sizeof( button->name )))
|
||||
{
|
||||
if( start >= 0 )
|
||||
@@ -678,7 +697,8 @@ static void Touch_Fade_f( void )
|
||||
return;
|
||||
}
|
||||
|
||||
Touch_FadeButtons( &touch.list_user, Cmd_Argv( 1 ), Q_atof( Cmd_Argv( 2 )), Q_atof( Cmd_Argv( 3 )), start );
|
||||
Touch_FadeButtons( &touch.list_user,Cmd_Argv( 1 ), Q_atof( Cmd_Argv( 2 )), Q_atof( Cmd_Argv( 3 )),
|
||||
start, Cmd_CurrentCommandIsPrivileged() );
|
||||
}
|
||||
|
||||
static void Touch_SetColor_f( void )
|
||||
@@ -686,7 +706,7 @@ static void Touch_SetColor_f( void )
|
||||
rgba_t color;
|
||||
if( Cmd_Argc() == 6 )
|
||||
{
|
||||
MakeRGBA( color, Q_atoi( Cmd_Argv(2) ), Q_atoi( Cmd_Argv(3) ), Q_atoi( Cmd_Argv(4) ), Q_atoi( Cmd_Argv(5) ) );
|
||||
MakeRGBA( color, Q_atoi( Cmd_Argv(2) ), Q_atoi( Cmd_Argv(3) ), Q_atoi( Cmd_Argv(4) ), Q_atoi( Cmd_Argv(5) ) );
|
||||
Touch_SetColor( &touch.list_user, Cmd_Argv(1), color );
|
||||
return;
|
||||
}
|
||||
@@ -697,7 +717,7 @@ static void Touch_SetTexture_f( void )
|
||||
{
|
||||
if( Cmd_Argc() == 3 )
|
||||
{
|
||||
Touch_SetTexture( &touch.list_user, Cmd_Argv( 1 ), Cmd_Argv( 2 ) );
|
||||
Touch_SetTexture( &touch.list_user, Cmd_Argv( 1 ), Cmd_Argv( 2 ), Cmd_CurrentCommandIsPrivileged() );
|
||||
return;
|
||||
}
|
||||
Con_Printf( S_USAGE "touch_settexture <name> <file>\n" );
|
||||
@@ -707,9 +727,13 @@ static void Touch_SetFlags_f( void )
|
||||
{
|
||||
if( Cmd_Argc() == 3 )
|
||||
{
|
||||
touch_button_t *button = Touch_FindButton( &touch.list_user, Cmd_Argv( 1 ) );
|
||||
qboolean privileged = Cmd_CurrentCommandIsPrivileged();
|
||||
|
||||
touch_button_t *button = Touch_FindButton( &touch.list_user, Cmd_Argv( 1 ), privileged );
|
||||
if( button )
|
||||
button->flags = Q_atoi( Cmd_Argv( 2 ) );
|
||||
{
|
||||
button->flags = ( privileged ? 0 : TOUCH_FL_UNPRIVILEGED | TOUCH_FL_CLIENT ) | Q_atoi( Cmd_Argv( 2 ));
|
||||
}
|
||||
return;
|
||||
}
|
||||
Con_Printf( S_USAGE "touch_setflags <name> <file>\n" );
|
||||
@@ -719,7 +743,7 @@ static void Touch_SetCommand_f( void )
|
||||
{
|
||||
if( Cmd_Argc() == 3 )
|
||||
{
|
||||
touch_button_t *button = Touch_FindButton( &touch.list_user, Cmd_Argv(1) );
|
||||
touch_button_t *button = Touch_FindButton( &touch.list_user, Cmd_Argv(1), Cmd_CurrentCommandIsPrivileged() );
|
||||
|
||||
if( !button )
|
||||
Con_Printf( S_ERROR "no such button" );
|
||||
@@ -744,21 +768,24 @@ static void Touch_ReloadConfig_f( void )
|
||||
Cbuf_AddText( va("exec %s\n", touch_config_file->string ) );
|
||||
}
|
||||
|
||||
static touch_button_t *Touch_AddButton( touchbuttonlist_t *list, const char *name, const char *texture, const char *command, float x1, float y1, float x2, float y2, byte *color )
|
||||
static touch_button_t *Touch_AddButton( touchbuttonlist_t *list,
|
||||
const char *name, const char *texture, const char *command,
|
||||
float x1, float y1, float x2, float y2, byte *color,
|
||||
qboolean privileged )
|
||||
{
|
||||
touch_button_t *button = Mem_Calloc( touch.mempool, sizeof( touch_button_t ) );
|
||||
|
||||
button->texture = -1;
|
||||
Q_strncpy( button->texturefile, texture, sizeof( B( texturefile )));
|
||||
Q_strncpy( button->name, name, sizeof( B( name )));
|
||||
Touch_RemoveButtonFromList( list, name ); //replace if exist
|
||||
Touch_RemoveButtonFromList( list, name, privileged ); //replace if exist
|
||||
button->x1 = x1;
|
||||
button->y1 = y1;
|
||||
button->x2 = x2;
|
||||
button->y2 = y2;
|
||||
button->flags = privileged ? 0 : TOUCH_FL_UNPRIVILEGED | TOUCH_FL_CLIENT;
|
||||
MakeRGBA( button->color, color[0], color[1], color[2], color[3] );
|
||||
button->command[0] = 0;
|
||||
button->flags = 0;
|
||||
button->fade = 1;
|
||||
|
||||
Touch_SetCommand( button, command );
|
||||
@@ -788,7 +815,7 @@ void Touch_AddClientButton( const char *name, const char *texture, const char *c
|
||||
{
|
||||
y2 = y1 + ( x2 - x1 ) * (SCR_W/SCR_H) * aspect;
|
||||
}
|
||||
button = Touch_AddButton( &touch.list_user, name, texture, command, x1, y1, x2, y2, color );
|
||||
button = Touch_AddButton( &touch.list_user, name, texture, command, x1, y1, x2, y2, color, true );
|
||||
button->flags |= flags | TOUCH_FL_CLIENT | TOUCH_FL_NOEDIT;
|
||||
button->aspect = aspect;
|
||||
}
|
||||
@@ -815,7 +842,7 @@ static void Touch_LoadDefaults_f( void )
|
||||
}
|
||||
|
||||
IN_TouchCheckCoords( &x1, &y1, &x2, &y2 );
|
||||
button = Touch_AddButton( &touch.list_user, g_DefaultButtons[i].name, g_DefaultButtons[i].texturefile, g_DefaultButtons[i].command, x1, y1, x2, y2, g_DefaultButtons[i].color );
|
||||
button = Touch_AddButton( &touch.list_user, g_DefaultButtons[i].name, g_DefaultButtons[i].texturefile, g_DefaultButtons[i].command, x1, y1, x2, y2, g_DefaultButtons[i].color, true );
|
||||
button->flags |= g_DefaultButtons[i].flags;
|
||||
button->aspect = g_DefaultButtons[i].aspect;
|
||||
}
|
||||
@@ -855,51 +882,66 @@ static void Touch_AddButton_f( void )
|
||||
{
|
||||
rgba_t color;
|
||||
int argc = Cmd_Argc( );
|
||||
touch_button_t *button = NULL;
|
||||
const char *name, *texture, *command;
|
||||
float x1, y1, x2, y2;
|
||||
qboolean privileged = Cmd_CurrentCommandIsPrivileged();
|
||||
|
||||
if( argc >= 12 )
|
||||
if( argc < 4 )
|
||||
{
|
||||
touch_button_t *button;
|
||||
MakeRGBA( color, Q_atoi( Cmd_Argv(8) ), Q_atoi( Cmd_Argv(9) ),
|
||||
Q_atoi( Cmd_Argv(10) ), Q_atoi( Cmd_Argv(11) ) );
|
||||
button = Touch_AddButton( &touch.list_user, Cmd_Argv(1), Cmd_Argv(2), Cmd_Argv(3),
|
||||
Q_atof( Cmd_Argv(4) ), Q_atof( Cmd_Argv(5) ),
|
||||
Q_atof( Cmd_Argv(6) ), Q_atof( Cmd_Argv(7) ) ,
|
||||
color );
|
||||
if( argc >= 13 )
|
||||
{
|
||||
button->flags = Q_atoi( Cmd_Argv(12) );
|
||||
}
|
||||
if( argc >= 14 )
|
||||
{
|
||||
// Recalculate button coordinates aspect ratio
|
||||
// This is feature for distributed configs
|
||||
float aspect = Q_atof( Cmd_Argv(13) );
|
||||
if( aspect )
|
||||
{
|
||||
if( B(texturefile)[0] != '#' )
|
||||
B(y2) = B(y1) + ( B(x2) - B(x1) ) * (SCR_W/SCR_H) * aspect;
|
||||
B(aspect) = aspect;
|
||||
}
|
||||
}
|
||||
|
||||
Con_Printf( S_USAGE "touch_addbutton <name> <texture> <command> [<x1> <y1> <x2> <y2> [ r g b a ] ]\n" );
|
||||
return;
|
||||
}
|
||||
if( argc == 8 )
|
||||
|
||||
name = Cmd_Argv( 1 );
|
||||
texture = Cmd_Argv( 2 );
|
||||
command = Cmd_Argv( 3 );
|
||||
|
||||
if( argc < 8 )
|
||||
{
|
||||
x1 = y1 = 0.4f;
|
||||
x2 = y2 = 0.6f;
|
||||
}
|
||||
else
|
||||
{
|
||||
x1 = Q_atof( Cmd_Argv( 4 ));
|
||||
y1 = Q_atof( Cmd_Argv( 5 ));
|
||||
x2 = Q_atof( Cmd_Argv( 6 ));
|
||||
y2 = Q_atof( Cmd_Argv( 7 ));
|
||||
}
|
||||
|
||||
if( argc < 12 )
|
||||
{
|
||||
MakeRGBA( color, 255, 255, 255, 255 );
|
||||
Touch_AddButton( &touch.list_user, Cmd_Argv(1), Cmd_Argv(2), Cmd_Argv(3),
|
||||
Q_atof( Cmd_Argv(4) ), Q_atof( Cmd_Argv(5) ),
|
||||
Q_atof( Cmd_Argv(6) ), Q_atof( Cmd_Argv(7) ),
|
||||
color );
|
||||
return;
|
||||
}
|
||||
if( argc == 4 )
|
||||
else
|
||||
{
|
||||
MakeRGBA( color, 255, 255, 255, 255 );
|
||||
Touch_AddButton( &touch.list_user, Cmd_Argv(1), Cmd_Argv(2), Cmd_Argv(3), 0.4, 0.4, 0.6, 0.6, color );
|
||||
return;
|
||||
MakeRGBA( color,
|
||||
Q_atoi( Cmd_Argv( 8 )),
|
||||
Q_atoi( Cmd_Argv( 9 )),
|
||||
Q_atoi( Cmd_Argv( 10 )),
|
||||
Q_atoi( Cmd_Argv( 11 )));
|
||||
}
|
||||
|
||||
button = Touch_AddButton( &touch.list_user, name, texture, command, x1, y1, x2, y2, color, privileged );
|
||||
|
||||
if( argc >= 13 )
|
||||
{
|
||||
SetBits( button->flags, Q_atoi( Cmd_Argv( 12 )));
|
||||
}
|
||||
|
||||
if( argc >= 14 )
|
||||
{
|
||||
// Recalculate button coordinates aspect ratio
|
||||
// This is feature for distributed configs
|
||||
float aspect = Q_atof( Cmd_Argv( 13 ));
|
||||
if( aspect )
|
||||
{
|
||||
if( B( texturefile )[0] != '#' )
|
||||
B( y2 ) = B( y1 ) + ( B( x2 ) - B( x1 )) * ( SCR_W / SCR_H ) * aspect;
|
||||
B( aspect ) = aspect;
|
||||
}
|
||||
}
|
||||
Con_Printf( S_USAGE "touch_addbutton <name> <texture> <command> [<x1> <y1> <x2> <y2> [ r g b a ] ]\n" );
|
||||
}
|
||||
|
||||
static void Touch_EnableEdit_f( void )
|
||||
@@ -925,7 +967,7 @@ static void Touch_DisableEdit_f( void )
|
||||
{
|
||||
Cvar_Set( "touch_in_menu", "0" );
|
||||
}
|
||||
else if( cls.key_dest == key_game )
|
||||
else if( cls.key_dest == key_game )
|
||||
Touch_WriteConfig();
|
||||
}
|
||||
|
||||
@@ -946,26 +988,29 @@ static void Touch_InitEditor( void )
|
||||
float x = 0.1f * (SCR_H/SCR_W);
|
||||
float y = 0.05f;
|
||||
touch_button_t *temp;
|
||||
rgba_t color;
|
||||
|
||||
MakeRGBA( color, 255, 255, 255, 255 );
|
||||
|
||||
Touch_ClearList( &touch.list_edit );
|
||||
|
||||
temp = Touch_AddButton( &touch.list_edit, "close", "touch_default/edit_close.tga", "touch_disableedit", 0, y, x, y + 0.1f, (byte*)"\xff\xff\xff\xff" );
|
||||
temp = Touch_AddButton( &touch.list_edit, "close", "touch_default/edit_close.tga", "touch_disableedit", 0, y, x, y + 0.1f, color, true );
|
||||
SetBits( temp->flags, TOUCH_FL_NOEDIT );
|
||||
|
||||
temp = Touch_AddButton( &touch.list_edit, "close", "#Close and save", "", x, y, x + 0.2f, y + 0.1f, (byte*)"\xff\xff\xff\xff" );
|
||||
temp = Touch_AddButton( &touch.list_edit, "close", "#Close and save", "", x, y, x + 0.2f, y + 0.1f, color, true );
|
||||
SetBits( temp->flags, TOUCH_FL_NOEDIT );
|
||||
|
||||
y += 0.2f;
|
||||
|
||||
temp = Touch_AddButton( &touch.list_edit, "cancel", "touch_default/edit_reset.tga", "touch_reloadconfig", 0, y, x, y + 0.1f, (byte*)"\xff\xff\xff\xff" );
|
||||
temp = Touch_AddButton( &touch.list_edit, "cancel", "touch_default/edit_reset.tga", "touch_reloadconfig", 0, y, x, y + 0.1f, color, true );
|
||||
SetBits( temp->flags, TOUCH_FL_NOEDIT );
|
||||
|
||||
temp = Touch_AddButton( &touch.list_edit, "close", "#Cancel and reset", "", x, y, x + 0.2f, y + 0.1f, (byte*)"\xff\xff\xff\xff" );
|
||||
temp = Touch_AddButton( &touch.list_edit, "close", "#Cancel and reset", "", x, y, x + 0.2f, y + 0.1f, color, true );
|
||||
SetBits( temp->flags, TOUCH_FL_NOEDIT );
|
||||
|
||||
y += 0.2f;
|
||||
|
||||
touch.hidebutton = Touch_AddButton( &touch.list_edit, "showhide", "touch_default/edit_hide.tga", "touch_toggleselection", 0, y, x, y + 0.1f, (byte*)"\xff\xff\xff\xff" );
|
||||
touch.hidebutton = Touch_AddButton( &touch.list_edit, "showhide", "touch_default/edit_hide.tga", "touch_toggleselection", 0, y, x, y + 0.1f, color, true );
|
||||
SetBits( touch.hidebutton->flags, TOUCH_FL_HIDE | TOUCH_FL_NOEDIT );
|
||||
}
|
||||
|
||||
@@ -1014,58 +1059,58 @@ void Touch_Init( void )
|
||||
|
||||
Cmd_AddCommand( "touch_addbutton", Touch_AddButton_f, "add native touch button" );
|
||||
Cmd_AddCommand( "touch_removebutton", IN_TouchRemoveButton_f, "remove native touch button" );
|
||||
Cmd_AddCommand( "touch_enableedit", Touch_EnableEdit_f, "enable button editing mode" );
|
||||
Cmd_AddCommand( "touch_disableedit", Touch_DisableEdit_f, "disable button editing mode" );
|
||||
Cmd_AddRestrictedCommand( "touch_enableedit", Touch_EnableEdit_f, "enable button editing mode" );
|
||||
Cmd_AddRestrictedCommand( "touch_disableedit", Touch_DisableEdit_f, "disable button editing mode" );
|
||||
Cmd_AddCommand( "touch_settexture", Touch_SetTexture_f, "change button texture" );
|
||||
Cmd_AddCommand( "touch_setcolor", Touch_SetColor_f, "change button color" );
|
||||
Cmd_AddCommand( "touch_setcommand", Touch_SetCommand_f, "change button command" );
|
||||
Cmd_AddCommand( "touch_setflags", Touch_SetFlags_f, "change button flags (be careful)" );
|
||||
Cmd_AddCommand( "touch_show", Touch_Show_f, "show button" );
|
||||
Cmd_AddCommand( "touch_hide", Touch_Hide_f, "hide button" );
|
||||
Cmd_AddCommand( "touch_list", Touch_ListButtons_f, "list buttons" );
|
||||
Cmd_AddCommand( "touch_removeall", Touch_RemoveAll_f, "remove all buttons" );
|
||||
Cmd_AddCommand( "touch_loaddefaults", Touch_LoadDefaults_f, "generate config from defaults" );
|
||||
Cmd_AddCommand( "touch_roundall", Touch_RoundAll_f, "round all buttons coordinates to grid" );
|
||||
Cmd_AddCommand( "touch_exportconfig", Touch_ExportConfig_f, "export config keeping aspect ratio" );
|
||||
Cmd_AddRestrictedCommand( "touch_list", Touch_ListButtons_f, "list buttons" );
|
||||
Cmd_AddRestrictedCommand( "touch_removeall", Touch_RemoveAll_f, "remove all buttons" );
|
||||
Cmd_AddRestrictedCommand( "touch_loaddefaults", Touch_LoadDefaults_f, "generate config from defaults" );
|
||||
Cmd_AddRestrictedCommand( "touch_roundall", Touch_RoundAll_f, "round all buttons coordinates to grid" );
|
||||
Cmd_AddRestrictedCommand( "touch_exportconfig", Touch_ExportConfig_f, "export config keeping aspect ratio" );
|
||||
Cmd_AddCommand( "touch_set_stroke", Touch_Stroke_f, "set global stroke width and color" );
|
||||
Cmd_AddCommand( "touch_setclientonly", Touch_SetClientOnly_f, "when 1, only client buttons are shown" );
|
||||
Cmd_AddCommand( "touch_reloadconfig", Touch_ReloadConfig_f, "load config, not saving changes" );
|
||||
Cmd_AddCommand( "touch_writeconfig", Touch_WriteConfig, "save current config" );
|
||||
Cmd_AddCommand( "touch_deleteprofile", Touch_DeleteProfile_f, "delete profile by name" );
|
||||
Cmd_AddCommand( "touch_generate_code", Touch_GenerateCode_f, "create code sample for mobility API" );
|
||||
Cmd_AddRestrictedCommand( "touch_reloadconfig", Touch_ReloadConfig_f, "load config, not saving changes" );
|
||||
Cmd_AddRestrictedCommand( "touch_writeconfig", Touch_WriteConfig, "save current config" );
|
||||
Cmd_AddRestrictedCommand( "touch_deleteprofile", Touch_DeleteProfile_f, "delete profile by name" );
|
||||
Cmd_AddRestrictedCommand( "touch_generate_code", Touch_GenerateCode_f, "create code sample for mobility API" );
|
||||
Cmd_AddCommand( "touch_fade", Touch_Fade_f, "start fade animation for selected buttons" );
|
||||
Cmd_AddCommand( "touch_toggleselection", Touch_ToggleSelection_f, "toggle vidibility on selected button in editor" );
|
||||
Cmd_AddRestrictedCommand( "touch_toggleselection", Touch_ToggleSelection_f, "toggle vidibility on selected button in editor" );
|
||||
|
||||
// not saved, just runtime state for scripting
|
||||
touch_in_menu = Cvar_Get( "touch_in_menu", "0", 0, "draw touch in menu (for internal use only)" );
|
||||
touch_in_menu = Cvar_Get( "touch_in_menu", "0", FCVAR_FILTERABLE, "draw touch in menu (for internal use only)" );
|
||||
|
||||
// sensitivity configuration
|
||||
touch_forwardzone = Cvar_Get( "touch_forwardzone", "0.06", 0, "forward touch zone" );
|
||||
touch_sidezone = Cvar_Get( "touch_sidezone", "0.06", 0, "side touch zone" );
|
||||
touch_pitch = Cvar_Get( "touch_pitch", "90", 0, "touch pitch sensitivity" );
|
||||
touch_yaw = Cvar_Get( "touch_yaw", "120", 0, "touch yaw sensitivity" );
|
||||
touch_nonlinear_look = Cvar_Get( "touch_nonlinear_look", "0", 0, "enable nonlinear touch look" );
|
||||
touch_pow_factor = Cvar_Get( "touch_pow_factor", "1.3", 0, "set > 1 to enable" );
|
||||
touch_pow_mult = Cvar_Get( "touch_pow_mult", "400.0", 0, "power multiplier, usually 200-1000" );
|
||||
touch_exp_mult = Cvar_Get( "touch_exp_mult", "0", 0, "exponent multiplier, usually 20-200, 0 to disable" );
|
||||
touch_forwardzone = Cvar_Get( "touch_forwardzone", "0.06", FCVAR_FILTERABLE, "forward touch zone" );
|
||||
touch_sidezone = Cvar_Get( "touch_sidezone", "0.06", FCVAR_FILTERABLE, "side touch zone" );
|
||||
touch_pitch = Cvar_Get( "touch_pitch", "90", FCVAR_FILTERABLE, "touch pitch sensitivity" );
|
||||
touch_yaw = Cvar_Get( "touch_yaw", "120", FCVAR_FILTERABLE, "touch yaw sensitivity" );
|
||||
touch_nonlinear_look = Cvar_Get( "touch_nonlinear_look", "0", FCVAR_FILTERABLE, "enable nonlinear touch look" );
|
||||
touch_pow_factor = Cvar_Get( "touch_pow_factor", "1.3", FCVAR_FILTERABLE, "set > 1 to enable" );
|
||||
touch_pow_mult = Cvar_Get( "touch_pow_mult", "400.0", FCVAR_FILTERABLE, "power multiplier, usually 200-1000" );
|
||||
touch_exp_mult = Cvar_Get( "touch_exp_mult", "0", FCVAR_FILTERABLE, "exponent multiplier, usually 20-200, 0 to disable" );
|
||||
|
||||
// touch.cfg
|
||||
touch_grid_count = Cvar_Get( "touch_grid_count", "50", 0, "touch grid count" );
|
||||
touch_grid_enable = Cvar_Get( "touch_grid_enable", "1", 0, "enable touch grid" );
|
||||
touch_config_file = Cvar_Get( "touch_config_file", "touch.cfg", FCVAR_ARCHIVE, "current touch profile file" );
|
||||
touch_precise_amount = Cvar_Get( "touch_precise_amount", "0.5", 0, "sensitivity multiplier for precise-look" );
|
||||
touch_grid_count = Cvar_Get( "touch_grid_count", "50", FCVAR_FILTERABLE, "touch grid count" );
|
||||
touch_grid_enable = Cvar_Get( "touch_grid_enable", "1", FCVAR_FILTERABLE, "enable touch grid" );
|
||||
touch_config_file = Cvar_Get( "touch_config_file", "touch.cfg", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "current touch profile file" );
|
||||
touch_precise_amount = Cvar_Get( "touch_precise_amount", "0.5", FCVAR_FILTERABLE, "sensitivity multiplier for precise-look" );
|
||||
touch_highlight_r = Cvar_Get( "touch_highlight_r", "1.0", 0, "highlight r color" );
|
||||
touch_highlight_g = Cvar_Get( "touch_highlight_g", "1.0", 0, "highlight g color" );
|
||||
touch_highlight_b = Cvar_Get( "touch_highlight_b", "1.0", 0, "highlight b color" );
|
||||
touch_highlight_a = Cvar_Get( "touch_highlight_a", "1.0", 0, "highlight alpha" );
|
||||
touch_dpad_radius = Cvar_Get( "touch_dpad_radius", "1.0", 0, "dpad radius multiplier" );
|
||||
touch_joy_radius = Cvar_Get( "touch_joy_radius", "1.0", 0, "joy radius multiplier" );
|
||||
touch_move_indicator = Cvar_Get( "touch_move_indicator", "0.0", 0, "indicate move events (0 to disable)" );
|
||||
touch_joy_texture = Cvar_Get( "touch_joy_texture", "touch_default/joy.tga", 0, "texture for move indicator");
|
||||
touch_dpad_radius = Cvar_Get( "touch_dpad_radius", "1.0", FCVAR_FILTERABLE, "dpad radius multiplier" );
|
||||
touch_joy_radius = Cvar_Get( "touch_joy_radius", "1.0", FCVAR_FILTERABLE, "joy radius multiplier" );
|
||||
touch_move_indicator = Cvar_Get( "touch_move_indicator", "0.0", FCVAR_FILTERABLE, "indicate move events (0 to disable)" );
|
||||
touch_joy_texture = Cvar_Get( "touch_joy_texture", "touch_default/joy.tga", FCVAR_FILTERABLE, "texture for move indicator");
|
||||
|
||||
// input devices cvar
|
||||
touch_enable = Cvar_Get( "touch_enable", DEFAULT_TOUCH_ENABLE, FCVAR_ARCHIVE, "enable touch controls" );
|
||||
touch_emulate = Cvar_Get( "touch_emulate", "0", FCVAR_ARCHIVE, "emulate touch with mouse" );
|
||||
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 sdl platform
|
||||
// SDL_SetHint( SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1" );
|
||||
@@ -1630,7 +1675,9 @@ static qboolean Touch_ButtonPress( touchbuttonlist_t *list, touchEventType type,
|
||||
|
||||
// command down: just execute command
|
||||
Q_snprintf( command, sizeof( command ), "%s\n", button->command );
|
||||
Cbuf_AddText( command );
|
||||
if( FBitSet( B( flags ), TOUCH_FL_UNPRIVILEGED ))
|
||||
Cbuf_AddFilteredText( command );
|
||||
else Cbuf_AddText( command );
|
||||
|
||||
// increase precision
|
||||
if( FBitSet( B(flags), TOUCH_FL_PRECISION ))
|
||||
@@ -1654,7 +1701,9 @@ static qboolean Touch_ButtonPress( touchbuttonlist_t *list, touchEventType type,
|
||||
Q_snprintf( touch.wheel_end, sizeof( touch.wheel_end ), "%s\n", Cmd_Argv( 3 ) );
|
||||
if( Q_snprintf( command, sizeof( command ), "%s\n", Cmd_Argv( 4 ) ) > 1)
|
||||
{
|
||||
Cbuf_AddText( command );
|
||||
if( FBitSet( B( flags ), TOUCH_FL_UNPRIVILEGED ))
|
||||
Cbuf_AddFilteredText( command );
|
||||
else Cbuf_AddText( command );
|
||||
touch.wheel_count++;
|
||||
}
|
||||
|
||||
@@ -1776,8 +1825,12 @@ static qboolean Touch_ButtonPress( touchbuttonlist_t *list, touchEventType type,
|
||||
char command[256];
|
||||
|
||||
Q_snprintf( command, sizeof( command ), "%s\n", button->command );
|
||||
|
||||
command[0] = '-';
|
||||
Cbuf_AddText( command );
|
||||
|
||||
if( FBitSet( B( flags ), TOUCH_FL_UNPRIVILEGED ))
|
||||
Cbuf_AddFilteredText( command );
|
||||
else Cbuf_AddText( command );
|
||||
}
|
||||
|
||||
// disable precision mode
|
||||
@@ -1791,7 +1844,11 @@ static qboolean Touch_ButtonPress( touchbuttonlist_t *list, touchEventType type,
|
||||
if( button->type == touch_wheel )
|
||||
{
|
||||
if( touch.wheel_count )
|
||||
Cbuf_AddText( touch.wheel_end );
|
||||
{
|
||||
if( FBitSet( B( flags ), TOUCH_FL_UNPRIVILEGED ))
|
||||
Cbuf_AddFilteredText( touch.wheel_end );
|
||||
else Cbuf_AddText( touch.wheel_end );
|
||||
}
|
||||
|
||||
// disable precision mode
|
||||
if( B(flags) & TOUCH_FL_PRECISION )
|
||||
|
||||
@@ -18,7 +18,7 @@ GNU General Public License for more details.
|
||||
#include "client.h"
|
||||
#include "vgui_draw.h"
|
||||
|
||||
#ifdef XASH_SDL
|
||||
#if XASH_SDL
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
@@ -30,17 +30,16 @@ qboolean in_mouseinitialized;
|
||||
qboolean in_mouse_suspended;
|
||||
POINT in_lastvalidpos;
|
||||
qboolean in_mouse_savedpos;
|
||||
static int in_mstate = 0;
|
||||
static struct inputstate_s
|
||||
{
|
||||
float lastpitch, lastyaw;
|
||||
} inputstate;
|
||||
|
||||
extern convar_t *vid_fullscreen;
|
||||
convar_t *m_enginemouse;
|
||||
convar_t *m_pitch;
|
||||
convar_t *m_yaw;
|
||||
|
||||
convar_t *m_enginesens;
|
||||
convar_t *m_ignore;
|
||||
convar_t *cl_forwardspeed;
|
||||
convar_t *cl_sidespeed;
|
||||
@@ -48,6 +47,8 @@ convar_t *cl_backspeed;
|
||||
convar_t *look_filter;
|
||||
convar_t *m_rawinput;
|
||||
|
||||
static qboolean s_bRawInput, s_bMouseGrab;
|
||||
|
||||
/*
|
||||
================
|
||||
IN_CollectInputDevices
|
||||
@@ -111,14 +112,12 @@ IN_StartupMouse
|
||||
*/
|
||||
void IN_StartupMouse( void )
|
||||
{
|
||||
m_ignore = Cvar_Get( "m_ignore", DEFAULT_M_IGNORE, FCVAR_ARCHIVE , "ignore mouse events" );
|
||||
m_ignore = Cvar_Get( "m_ignore", DEFAULT_M_IGNORE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "ignore mouse events" );
|
||||
|
||||
m_enginemouse = Cvar_Get( "m_enginemouse", "0", FCVAR_ARCHIVE, "read mouse events in engine instead of client" );
|
||||
m_enginesens = Cvar_Get( "m_enginesens", "0.3", FCVAR_ARCHIVE, "mouse sensitivity, when m_enginemouse enabled" );
|
||||
m_pitch = Cvar_Get( "m_pitch", "0.022", FCVAR_ARCHIVE, "mouse pitch value" );
|
||||
m_yaw = Cvar_Get( "m_yaw", "0.022", FCVAR_ARCHIVE, "mouse yaw value" );
|
||||
look_filter = Cvar_Get( "look_filter", "0", FCVAR_ARCHIVE, "filter look events making it smoother" );
|
||||
m_rawinput = Cvar_Get( "m_rawinput", "1", FCVAR_ARCHIVE, "enable mouse raw input" );
|
||||
m_pitch = Cvar_Get( "m_pitch", "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse pitch value" );
|
||||
m_yaw = Cvar_Get( "m_yaw", "0.022", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "mouse yaw value" );
|
||||
look_filter = Cvar_Get( "look_filter", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "filter look events making it smoother" );
|
||||
m_rawinput = Cvar_Get( "m_rawinput", "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable mouse raw input" );
|
||||
|
||||
// You can use -nomouse argument to prevent using mouse from client
|
||||
// -noenginemouse will disable all mouse input
|
||||
@@ -127,21 +126,9 @@ void IN_StartupMouse( void )
|
||||
in_mouseinitialized = true;
|
||||
}
|
||||
|
||||
static void IN_ActivateCursor( void )
|
||||
{
|
||||
if( cls.key_dest == key_menu )
|
||||
{
|
||||
#ifdef XASH_SDL
|
||||
SDL_SetCursor( in_mousecursor );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void GAME_EXPORT IN_SetCursor( void *hCursor )
|
||||
{
|
||||
in_mousecursor = hCursor;
|
||||
|
||||
IN_ActivateCursor();
|
||||
// stub
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -190,47 +177,15 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
|
||||
|
||||
if( oldstate == key_game )
|
||||
{
|
||||
if( cls.initialized )
|
||||
clgame.dllFuncs.IN_DeactivateMouse();
|
||||
IN_DeactivateMouse();
|
||||
}
|
||||
else if( newstate == key_game )
|
||||
{
|
||||
// reset mouse pos, so cancel effect in game
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
if( CVAR_TO_BOOL( touch_enable ) )
|
||||
{
|
||||
SDL_SetRelativeMouseMode( SDL_FALSE );
|
||||
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
Platform_SetMousePos( host.window_center_x, host.window_center_y );
|
||||
#if XASH_SDL
|
||||
SDL_SetWindowGrab( host.hWnd, SDL_TRUE );
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
if ( clgame.dllFuncs.pfnLookEvent || ( clgame.client_dll_uses_sdl && CVAR_TO_BOOL( m_rawinput ) ) )
|
||||
{
|
||||
SDL_SetRelativeMouseMode( SDL_TRUE );
|
||||
}
|
||||
#endif
|
||||
#endif // XASH_SDL
|
||||
}
|
||||
if( cls.initialized )
|
||||
clgame.dllFuncs.IN_ActivateMouse();
|
||||
IN_ActivateMouse();
|
||||
}
|
||||
|
||||
if( ( newstate == key_menu || newstate == key_console || newstate == key_message ) && ( !CL_IsBackgroundMap() || CL_IsBackgroundDemo( )))
|
||||
{
|
||||
#ifdef XASH_SDL
|
||||
SDL_SetWindowGrab(host.hWnd, SDL_FALSE);
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
if ( clgame.dllFuncs.pfnLookEvent || ( clgame.client_dll_uses_sdl && CVAR_TO_BOOL( m_rawinput ) ) )
|
||||
{
|
||||
SDL_SetRelativeMouseMode( SDL_FALSE );
|
||||
}
|
||||
#endif
|
||||
#endif // XASH_SDL
|
||||
#if XASH_ANDROID
|
||||
Android_ShowMouse( true );
|
||||
#endif
|
||||
@@ -249,6 +204,65 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
|
||||
}
|
||||
}
|
||||
|
||||
void IN_CheckMouseState( qboolean active )
|
||||
{
|
||||
#if XASH_WIN32
|
||||
qboolean useRawInput = CVAR_TO_BOOL( m_rawinput ) && clgame.client_dll_uses_sdl || clgame.dllFuncs.pfnLookEvent;
|
||||
#else
|
||||
qboolean useRawInput = true; // always use SDL code
|
||||
#endif
|
||||
|
||||
if( active && useRawInput && !host.mouse_visible && cls.state == ca_active )
|
||||
{
|
||||
if( !s_bRawInput )
|
||||
{
|
||||
#if XASH_SDL == 2
|
||||
SDL_GetRelativeMouseState( NULL, NULL );
|
||||
SDL_SetRelativeMouseMode( SDL_TRUE );
|
||||
#endif
|
||||
|
||||
// Con_Printf( "Enable relative mode\n" );
|
||||
s_bRawInput = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( s_bRawInput )
|
||||
{
|
||||
#if XASH_SDL == 2
|
||||
SDL_GetRelativeMouseState( NULL, NULL );
|
||||
SDL_SetRelativeMouseMode( SDL_FALSE );
|
||||
#endif
|
||||
// Con_Printf( "Disable relative mode\n" );
|
||||
s_bRawInput = false;
|
||||
}
|
||||
}
|
||||
|
||||
if( active && !host.mouse_visible && cls.state == ca_active )
|
||||
{
|
||||
if( !s_bMouseGrab )
|
||||
{
|
||||
#if XASH_SDL
|
||||
SDL_SetWindowGrab( host.hWnd, SDL_TRUE );
|
||||
#endif
|
||||
// Con_Printf( "Enable grab\n" );
|
||||
s_bMouseGrab = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( s_bMouseGrab )
|
||||
{
|
||||
#if XASH_SDL
|
||||
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
|
||||
#endif
|
||||
|
||||
// Con_Printf( "Disable grab\n" );
|
||||
s_bMouseGrab = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_ActivateMouse
|
||||
@@ -256,58 +270,14 @@ IN_ActivateMouse
|
||||
Called when the window gains focus or changes in some way
|
||||
===========
|
||||
*/
|
||||
void IN_ActivateMouse( qboolean force )
|
||||
void IN_ActivateMouse( void )
|
||||
{
|
||||
int width, height;
|
||||
static int oldstate;
|
||||
|
||||
if( !in_mouseinitialized )
|
||||
return;
|
||||
|
||||
if( CL_Active() && host.mouse_visible && !force )
|
||||
return; // VGUI controls
|
||||
|
||||
if( cls.key_dest == key_menu && !Cvar_VariableInteger( "fullscreen" ))
|
||||
{
|
||||
// check for mouse leave-entering
|
||||
if( !in_mouse_suspended && !UI_MouseInRect( ))
|
||||
in_mouse_suspended = true;
|
||||
|
||||
if( oldstate != in_mouse_suspended )
|
||||
{
|
||||
if( in_mouse_suspended )
|
||||
{
|
||||
#ifdef XASH_SDL
|
||||
/// TODO: Platform_ShowCursor
|
||||
if( !touch_emulate )
|
||||
SDL_ShowCursor( SDL_FALSE );
|
||||
#endif
|
||||
UI_ShowCursor( false );
|
||||
}
|
||||
}
|
||||
|
||||
oldstate = in_mouse_suspended;
|
||||
|
||||
if( in_mouse_suspended )
|
||||
{
|
||||
in_mouse_suspended = false;
|
||||
in_mouseactive = false; // re-initialize mouse
|
||||
UI_ShowCursor( true );
|
||||
}
|
||||
}
|
||||
|
||||
if( in_mouseactive ) return;
|
||||
IN_CheckMouseState( true );
|
||||
clgame.dllFuncs.IN_ActivateMouse();
|
||||
in_mouseactive = true;
|
||||
|
||||
if( UI_IsVisible( )) return;
|
||||
|
||||
if( cls.key_dest == key_game )
|
||||
{
|
||||
clgame.dllFuncs.IN_ActivateMouse();
|
||||
#ifdef XASH_SDL
|
||||
SDL_GetRelativeMouseState( 0, 0 ); // Reset mouse position
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -319,20 +289,16 @@ Called when the window loses focus
|
||||
*/
|
||||
void IN_DeactivateMouse( void )
|
||||
{
|
||||
if( !in_mouseinitialized || !in_mouseactive )
|
||||
if( !in_mouseinitialized )
|
||||
return;
|
||||
|
||||
if( cls.key_dest == key_game )
|
||||
{
|
||||
clgame.dllFuncs.IN_DeactivateMouse();
|
||||
}
|
||||
|
||||
IN_CheckMouseState( false );
|
||||
clgame.dllFuncs.IN_DeactivateMouse();
|
||||
in_mouseactive = false;
|
||||
#ifdef XASH_SDL
|
||||
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
|
||||
#endif // XASH_SDL
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
IN_MouseMove
|
||||
@@ -342,7 +308,7 @@ void IN_MouseMove( void )
|
||||
{
|
||||
POINT current_pos;
|
||||
|
||||
if( !in_mouseinitialized || !in_mouseactive || !UI_IsVisible( ))
|
||||
if( !in_mouseinitialized )
|
||||
return;
|
||||
|
||||
// find mouse movement
|
||||
@@ -352,15 +318,13 @@ void IN_MouseMove( void )
|
||||
|
||||
// HACKHACK: show cursor in UI, as mainui doesn't call
|
||||
// platform-dependent SetCursor anymore
|
||||
#ifdef XASH_SDL
|
||||
#if XASH_SDL
|
||||
if( UI_IsVisible() )
|
||||
SDL_ShowCursor( SDL_TRUE );
|
||||
#endif
|
||||
|
||||
// if the menu is visible, move the menu cursor
|
||||
UI_MouseMove( current_pos.x, current_pos.y );
|
||||
|
||||
IN_ActivateCursor();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -368,73 +332,32 @@ void IN_MouseMove( void )
|
||||
IN_MouseEvent
|
||||
===========
|
||||
*/
|
||||
void IN_MouseEvent( void )
|
||||
void IN_MouseEvent( int key, int down )
|
||||
{
|
||||
int i;
|
||||
|
||||
// touch emu: handle motion
|
||||
if( CVAR_TO_BOOL( touch_emulate ))
|
||||
{
|
||||
if( Key_IsDown( K_SHIFT ) )
|
||||
Touch_KeyEvent( K_MOUSE2, 2 );
|
||||
else
|
||||
Touch_KeyEvent( K_MOUSE1, 2 );
|
||||
}
|
||||
|
||||
if( !in_mouseinitialized || !in_mouseactive )
|
||||
if( !in_mouseinitialized )
|
||||
return;
|
||||
|
||||
|
||||
if( m_ignore->value )
|
||||
return;
|
||||
if( down )
|
||||
SetBits( in_mstate, BIT( key ));
|
||||
else ClearBits( in_mstate, BIT( key ));
|
||||
|
||||
if( cls.key_dest == key_game )
|
||||
{
|
||||
#if defined( XASH_SDL )
|
||||
static qboolean ignore; // igonre mouse warp event
|
||||
int x, y;
|
||||
Platform_GetMousePos(&x, &y);
|
||||
if( host.mouse_visible )
|
||||
SDL_ShowCursor( SDL_TRUE );
|
||||
else if( !CVAR_TO_BOOL( touch_emulate ) )
|
||||
SDL_ShowCursor( SDL_FALSE );
|
||||
// perform button actions
|
||||
VGui_KeyEvent( K_MOUSE1 + key, down );
|
||||
|
||||
if( x < host.window_center_x / 2 ||
|
||||
y < host.window_center_y / 2 ||
|
||||
x > host.window_center_x + host.window_center_x / 2 ||
|
||||
y > host.window_center_y + host.window_center_y / 2 )
|
||||
{
|
||||
Platform_SetMousePos( host.window_center_x, host.window_center_y );
|
||||
ignore = 1; // next mouse event will be mouse warp
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !ignore )
|
||||
{
|
||||
if( !m_enginemouse->value )
|
||||
{
|
||||
// a1ba: mouse keys are now separated
|
||||
// so pass 0 here
|
||||
clgame.dllFuncs.IN_MouseEvent( 0 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_GetRelativeMouseState( 0, 0 ); // reset relative state
|
||||
ignore = 0;
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
// don't do Key_Event here
|
||||
// client may override IN_MouseEvent
|
||||
// but by default it calls back to Key_Event anyway
|
||||
if( in_mouseactive )
|
||||
clgame.dllFuncs.IN_MouseEvent( in_mstate );
|
||||
}
|
||||
else
|
||||
{
|
||||
#if XASH_SDL && !XASH_WIN32
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
SDL_SetRelativeMouseMode( SDL_FALSE );
|
||||
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
SDL_ShowCursor( SDL_TRUE );
|
||||
#endif // XASH_SDL && !XASH_WIN32
|
||||
IN_MouseMove();
|
||||
// perform button actions
|
||||
Key_Event( K_MOUSE1 + key, down );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,9 +385,9 @@ IN_Init
|
||||
*/
|
||||
void IN_Init( void )
|
||||
{
|
||||
cl_forwardspeed = Cvar_Get( "cl_forwardspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL, "Default forward move speed" );
|
||||
cl_backspeed = Cvar_Get( "cl_backspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL, "Default back move speed" );
|
||||
cl_sidespeed = Cvar_Get( "cl_sidespeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL, "Default side move speed" );
|
||||
cl_forwardspeed = Cvar_Get( "cl_forwardspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default forward move speed" );
|
||||
cl_backspeed = Cvar_Get( "cl_backspeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default back move speed" );
|
||||
cl_sidespeed = Cvar_Get( "cl_sidespeed", "400", FCVAR_ARCHIVE | FCVAR_CLIENTDLL | FCVAR_FILTERABLE, "Default side move speed" );
|
||||
|
||||
if( !Host_IsDedicated() )
|
||||
{
|
||||
@@ -571,13 +494,9 @@ static void IN_JoyAppendMove( usercmd_t *cmd, float forwardmove, float sidemove
|
||||
}
|
||||
}
|
||||
|
||||
void IN_CollectInput( float *forward, float *side, float *pitch, float *yaw, qboolean includeMouse, qboolean includeSdlMouse )
|
||||
static void IN_CollectInput( float *forward, float *side, float *pitch, float *yaw, qboolean includeMouse )
|
||||
{
|
||||
if( includeMouse
|
||||
#if XASH_SDL
|
||||
&& includeSdlMouse
|
||||
#endif
|
||||
)
|
||||
if( includeMouse )
|
||||
{
|
||||
float x, y;
|
||||
Platform_MouseMove( &x, &y );
|
||||
@@ -626,7 +545,7 @@ void IN_EngineAppendMove( float frametime, void *cmd1, qboolean active )
|
||||
{
|
||||
float sensitivity = 1;//( (float)cl.local.scr_fov / (float)90.0f );
|
||||
|
||||
IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized && !CVAR_TO_BOOL( m_ignore ), m_enginemouse->value );
|
||||
IN_CollectInput( &forward, &side, &pitch, &yaw, false );
|
||||
|
||||
IN_JoyAppendMove( cmd, forward, side );
|
||||
|
||||
@@ -635,32 +554,22 @@ void IN_EngineAppendMove( float frametime, void *cmd1, qboolean active )
|
||||
cmd->viewangles[YAW] += yaw * sensitivity;
|
||||
cmd->viewangles[PITCH] += pitch * sensitivity;
|
||||
cmd->viewangles[PITCH] = bound( -90, cmd->viewangles[PITCH], 90 );
|
||||
VectorCopy(cmd->viewangles, cl.viewangles);
|
||||
VectorCopy( cmd->viewangles, cl.viewangles );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Host_InputFrame
|
||||
|
||||
Called every frame, even if not generating commands
|
||||
==================
|
||||
*/
|
||||
void Host_InputFrame( void )
|
||||
void IN_Commands( void )
|
||||
{
|
||||
qboolean shutdownMouse = false;
|
||||
float forward = 0, side = 0, pitch = 0, yaw = 0;
|
||||
|
||||
Sys_SendKeyEvents ();
|
||||
|
||||
#ifdef XASH_USE_EVDEV
|
||||
IN_EvdevFrame();
|
||||
#endif
|
||||
|
||||
if( clgame.dllFuncs.pfnLookEvent )
|
||||
{
|
||||
IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized && !CVAR_TO_BOOL( m_ignore ), true );
|
||||
float forward = 0, side = 0, pitch = 0, yaw = 0;
|
||||
|
||||
IN_CollectInput( &forward, &side, &pitch, &yaw, in_mouseinitialized && !CVAR_TO_BOOL( m_ignore ) );
|
||||
|
||||
if( cls.key_dest == key_game )
|
||||
{
|
||||
@@ -672,22 +581,21 @@ void Host_InputFrame( void )
|
||||
if( !in_mouseinitialized )
|
||||
return;
|
||||
|
||||
if( host.status != HOST_FRAME )
|
||||
{
|
||||
IN_DeactivateMouse();
|
||||
return;
|
||||
}
|
||||
IN_CheckMouseState( in_mouseactive );
|
||||
}
|
||||
|
||||
// release mouse during pause or console typeing
|
||||
if( cl.paused && cls.key_dest == key_game )
|
||||
shutdownMouse = true;
|
||||
/*
|
||||
==================
|
||||
Host_InputFrame
|
||||
|
||||
if( shutdownMouse && !Cvar_VariableInteger( "fullscreen" ))
|
||||
{
|
||||
IN_DeactivateMouse();
|
||||
return;
|
||||
}
|
||||
Called every frame, even if not generating commands
|
||||
==================
|
||||
*/
|
||||
void Host_InputFrame( void )
|
||||
{
|
||||
Sys_SendKeyEvents ();
|
||||
|
||||
IN_Commands();
|
||||
|
||||
IN_ActivateMouse( false );
|
||||
IN_MouseMove();
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ extern qboolean in_mouseinitialized;
|
||||
void IN_Init( void );
|
||||
void Host_InputFrame( void );
|
||||
void IN_Shutdown( void );
|
||||
void IN_MouseEvent( void );
|
||||
void IN_ActivateMouse( qboolean force );
|
||||
void IN_MouseEvent( int key, int down );
|
||||
void IN_ActivateMouse( void );
|
||||
void IN_DeactivateMouse( void );
|
||||
void IN_MouseSavePos( void );
|
||||
void IN_MouseRestorePos( void );
|
||||
@@ -61,12 +61,9 @@ extern convar_t *touch_enable;
|
||||
extern convar_t *touch_emulate;
|
||||
|
||||
void Touch_Draw( void );
|
||||
void Touch_SetClientOnly( qboolean state );
|
||||
void Touch_RemoveButton( const char *name );
|
||||
void Touch_HideButtons( const char *name, unsigned char hide );
|
||||
//void IN_TouchSetCommand( const char *name, const char *command );
|
||||
//void IN_TouchSetTexture( const char *name, const char *texture );
|
||||
//void IN_TouchSetColor( const char *name, byte *color );
|
||||
void Touch_SetClientOnly( byte state );
|
||||
void Touch_RemoveButton( const char *name, qboolean privileged );
|
||||
void Touch_HideButtons( const char *name, unsigned char hide, qboolean privileged );
|
||||
void Touch_AddClientButton( const char *name, const char *texture, const char *command, float x1, float y1, float x2, float y2, byte *color, int round, float aspect, int flags );
|
||||
void Touch_AddDefaultButton( const char *name, const char *texturefile, const char *command, float x1, float y1, float x2, float y2, byte *color, int round, float aspect, int flags );
|
||||
void Touch_WriteConfig( void );
|
||||
|
||||
@@ -462,6 +462,7 @@ Writes lines containing "bind key value"
|
||||
void Key_WriteBindings( file_t *f )
|
||||
{
|
||||
int i;
|
||||
string newCommand;
|
||||
|
||||
if( !f ) return;
|
||||
|
||||
@@ -472,7 +473,8 @@ void Key_WriteBindings( file_t *f )
|
||||
if( !COM_CheckString( keys[i].binding ))
|
||||
continue;
|
||||
|
||||
FS_Printf( f, "bind %s \"%s\"\n", Key_KeynumToString( i ), keys[i].binding );
|
||||
Cmd_Escape( newCommand, keys[i].binding, sizeof( newCommand ));
|
||||
FS_Printf( f, "bind %s \"%s\"\n", Key_KeynumToString( i ), newCommand );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,18 +514,18 @@ void Key_Init( void )
|
||||
keyname_t *kn;
|
||||
|
||||
// register our functions
|
||||
Cmd_AddCommand( "bind", Key_Bind_f, "binds a command to the specified key in bindmap" );
|
||||
Cmd_AddCommand( "unbind", Key_Unbind_f, "removes a command on the specified key in bindmap" );
|
||||
Cmd_AddCommand( "unbindall", Key_Unbindall_f, "removes all commands from all keys in bindmap" );
|
||||
Cmd_AddCommand( "resetkeys", Key_Reset_f, "reset all keys to their default values" );
|
||||
Cmd_AddRestrictedCommand( "bind", Key_Bind_f, "binds a command to the specified key in bindmap" );
|
||||
Cmd_AddRestrictedCommand( "unbind", Key_Unbind_f, "removes a command on the specified key in bindmap" );
|
||||
Cmd_AddRestrictedCommand( "unbindall", Key_Unbindall_f, "removes all commands from all keys in bindmap" );
|
||||
Cmd_AddRestrictedCommand( "resetkeys", Key_Reset_f, "reset all keys to their default values" );
|
||||
Cmd_AddCommand( "bindlist", Key_Bindlist_f, "display current key bindings" );
|
||||
Cmd_AddCommand( "makehelp", Key_EnumCmds_f, "write help.txt that contains all console cvars and cmds" );
|
||||
|
||||
// setup default binding. "unbindall" from config.cfg will be reset it
|
||||
for( kn = keynames; kn->name; kn++ ) Key_SetBinding( kn->keynum, kn->binding );
|
||||
|
||||
osk_enable = Cvar_Get( "osk_enable", "0", FCVAR_ARCHIVE, "enable built-in on-screen keyboard" );
|
||||
key_rotate = Cvar_Get( "key_rotate", "0", FCVAR_ARCHIVE, "rotate arrow keys (0-3)" );
|
||||
osk_enable = Cvar_Get( "osk_enable", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable built-in on-screen keyboard" );
|
||||
key_rotate = Cvar_Get( "key_rotate", "0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "rotate arrow keys (0-3)" );
|
||||
|
||||
}
|
||||
|
||||
@@ -812,9 +814,9 @@ void Key_EnableTextInput( qboolean enable, qboolean force )
|
||||
OSK_EnableTextInput( enable, force );
|
||||
return;
|
||||
}
|
||||
if( enable && ( !host.textmode || force ) )
|
||||
if( enable && ( !host.textmode || force ))
|
||||
Platform_EnableTextInput( true );
|
||||
else if( !enable )
|
||||
else if( !enable && ( host.textmode || force ))
|
||||
Platform_EnableTextInput( false );
|
||||
|
||||
host.textmode = enable;
|
||||
@@ -1042,7 +1044,7 @@ static qboolean OSK_KeyEvent( int key, int down )
|
||||
else
|
||||
osk.curlayout++;
|
||||
|
||||
osk.shift = osk.curbutton.val == OSK_SHIFT;
|
||||
osk.shift = true;
|
||||
osk.curbutton.val = osk_keylayout[osk.curlayout][osk.curbutton.y][osk.curbutton.x];
|
||||
break;
|
||||
case OSK_BACKSPACE:
|
||||
|
||||
@@ -13,7 +13,7 @@ convar_t *gl_showtextures;
|
||||
convar_t *r_decals;
|
||||
convar_t *r_adjust_fov;
|
||||
convar_t *r_showtree;
|
||||
convar_t *gl_wgl_msaa_samples;
|
||||
convar_t *gl_msaa_samples;
|
||||
convar_t *gl_clear;
|
||||
convar_t *r_refdll;
|
||||
|
||||
@@ -330,7 +330,7 @@ static ref_api_t gEngfuncs =
|
||||
_Mem_Realloc,
|
||||
_Mem_Free,
|
||||
|
||||
COM_LoadLibrary,
|
||||
_COM_LoadLibrary,
|
||||
COM_FreeLibrary,
|
||||
COM_GetProcAddress,
|
||||
|
||||
@@ -642,11 +642,28 @@ qboolean R_Init( void )
|
||||
gl_showtextures = Cvar_Get( "r_showtextures", "0", FCVAR_CHEAT, "show all uploaded textures" );
|
||||
r_adjust_fov = Cvar_Get( "r_adjust_fov", "1", FCVAR_ARCHIVE, "making FOV adjustment for wide-screens" );
|
||||
r_decals = Cvar_Get( "r_decals", "4096", FCVAR_ARCHIVE, "sets the maximum number of decals" );
|
||||
gl_wgl_msaa_samples = Cvar_Get( "gl_wgl_msaa_samples", "0", FCVAR_GLCONFIG, "samples number for multisample anti-aliasing" );
|
||||
gl_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|FCVAR_VIDRESTART, "choose renderer implementation, if supported" );
|
||||
|
||||
// cvars that are expected to exist
|
||||
Cvar_Get( "r_speeds", "0", FCVAR_ARCHIVE, "shows renderer speeds" );
|
||||
Cvar_Get( "r_fullbright", "0", FCVAR_CHEAT, "disable lightmaps, get fullbright for entities" );
|
||||
Cvar_Get( "r_norefresh", "0", 0, "disable 3D rendering (use with caution)" );
|
||||
Cvar_Get( "r_dynamic", "1", FCVAR_ARCHIVE, "allow dynamic lighting (dlights, lightstyles)" );
|
||||
Cvar_Get( "r_lightmap", "0", FCVAR_CHEAT, "lightmap debugging tool" );
|
||||
Cvar_Get( "tracerred", "0.8", 0, "tracer red component weight ( 0 - 1.0 )" );
|
||||
Cvar_Get( "tracergreen", "0.8", 0, "tracer green component weight ( 0 - 1.0 )" );
|
||||
Cvar_Get( "tracerblue", "0.4", 0, "tracer blue component weight ( 0 - 1.0 )" );
|
||||
Cvar_Get( "traceralpha", "0.5", 0, "tracer alpha amount ( 0 - 1.0 )" );
|
||||
|
||||
Cvar_Get( "r_sprite_lerping", "1", FCVAR_ARCHIVE, "enables sprite animation lerping" );
|
||||
Cvar_Get( "r_sprite_lighting", "1", FCVAR_ARCHIVE, "enables sprite lighting (blood etc)" );
|
||||
|
||||
Cvar_Get( "r_drawviewmodel", "1", 0, "draw firstperson weapon model" );
|
||||
Cvar_Get( "r_glowshellfreq", "2.2", 0, "glowing shell frequency update" );
|
||||
|
||||
// cvars that are expected to exist by client.dll
|
||||
// refdll should just get pointer to them
|
||||
Cvar_Get( "r_drawentities", "1", FCVAR_CHEAT, "render entities" );
|
||||
|
||||
@@ -33,7 +33,6 @@ GNU General Public License for more details.
|
||||
|
||||
#define MAXDLY (STEREODLY + 1)
|
||||
#define MAXLP 10
|
||||
#define MAXPRESETS 29
|
||||
|
||||
typedef struct sx_preset_s
|
||||
{
|
||||
@@ -79,7 +78,7 @@ typedef struct dly_s
|
||||
int *lpdelayline;
|
||||
} dly_t;
|
||||
|
||||
const sx_preset_t rgsxpre[MAXPRESETS] =
|
||||
const sx_preset_t rgsxpre[] =
|
||||
{
|
||||
// -------reverb-------- -------delay--------
|
||||
// lp mod size refl rvblp delay feedback dlylp left
|
||||
@@ -116,7 +115,7 @@ const sx_preset_t rgsxpre[MAXPRESETS] =
|
||||
|
||||
// 0x0045dca8 enginegl.exe
|
||||
// SHA256: 42383d32cd712e59ee2c1bd78b7ba48814e680e7026c4223e730111f34a60d66
|
||||
const sx_preset_t rgsxpre_hlalpha052[MAXPRESETS] =
|
||||
const sx_preset_t rgsxpre_hlalpha052[] =
|
||||
{
|
||||
// -------reverb-------- -------delay--------
|
||||
// lp mod size refl rvblp delay feedback dlylp left
|
||||
@@ -482,7 +481,7 @@ void DLY_CheckNewDelayVal( void )
|
||||
}
|
||||
else
|
||||
{
|
||||
delay = min( delay, MAX_MONO_DELAY );
|
||||
delay = Q_min( delay, MAX_MONO_DELAY );
|
||||
dly->delaysamples = (int)(delay * idsp_dma_speed) << sxhires;
|
||||
|
||||
// init dly
|
||||
@@ -882,7 +881,7 @@ void CheckNewDspPresets( void )
|
||||
else idsp_room = room_type->value;
|
||||
|
||||
// don't pass invalid presets
|
||||
idsp_room = bound( 0, idsp_room, MAXPRESETS - 1 );
|
||||
idsp_room = bound( 0, idsp_room, MAX_ROOM_TYPES );
|
||||
|
||||
if( FBitSet( hisound->flags, FCVAR_CHANGED ))
|
||||
{
|
||||
@@ -893,9 +892,6 @@ void CheckNewDspPresets( void )
|
||||
if( idsp_room == room_typeprev && idsp_room == 0 )
|
||||
return;
|
||||
|
||||
if( idsp_room > MAX_ROOM_TYPES )
|
||||
return;
|
||||
|
||||
if( idsp_room != room_typeprev )
|
||||
{
|
||||
const sx_preset_t *cur;
|
||||
|
||||
@@ -35,18 +35,18 @@ int total_channels;
|
||||
int soundtime; // sample PAIRS
|
||||
int paintedtime; // sample PAIRS
|
||||
|
||||
static CVAR_DEFINE( s_volume, "volume", "0.7", FCVAR_ARCHIVE, "sound volume" );
|
||||
CVAR_DEFINE( s_musicvolume, "MP3Volume", "1.0", FCVAR_ARCHIVE, "background music volume" );
|
||||
static CVAR_DEFINE( s_mixahead, "_snd_mixahead", "0.12", 0, "how much sound to mix ahead of time" );
|
||||
static CVAR_DEFINE_AUTO( s_show, "0", FCVAR_ARCHIVE, "show playing sounds" );
|
||||
CVAR_DEFINE_AUTO( s_lerping, "0", FCVAR_ARCHIVE, "apply interpolation to sound output" );
|
||||
static CVAR_DEFINE( s_ambient_level, "ambient_level", "0.3", FCVAR_ARCHIVE, "volume of environment noises (water and wind)" );
|
||||
static CVAR_DEFINE( s_ambient_fade, "ambient_fade", "1000", FCVAR_ARCHIVE, "rate of volume fading when client is moving" );
|
||||
static CVAR_DEFINE_AUTO( s_combine_sounds, "0", FCVAR_ARCHIVE, "combine channels with same sounds" );
|
||||
CVAR_DEFINE_AUTO( snd_mute_losefocus, "1", FCVAR_ARCHIVE, "silence the audio when game window loses focus" );
|
||||
static CVAR_DEFINE( s_volume, "volume", "0.7", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "sound volume" );
|
||||
CVAR_DEFINE( s_musicvolume, "MP3Volume", "1.0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "background music volume" );
|
||||
static CVAR_DEFINE( s_mixahead, "_snd_mixahead", "0.12", FCVAR_FILTERABLE, "how much sound to mix ahead of time" );
|
||||
static CVAR_DEFINE_AUTO( s_show, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "show playing sounds" );
|
||||
CVAR_DEFINE_AUTO( s_lerping, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "apply interpolation to sound output" );
|
||||
static CVAR_DEFINE( s_ambient_level, "ambient_level", "0.3", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "volume of environment noises (water and wind)" );
|
||||
static CVAR_DEFINE( s_ambient_fade, "ambient_fade", "1000", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "rate of volume fading when client is moving" );
|
||||
static CVAR_DEFINE_AUTO( s_combine_sounds, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "combine channels with same sounds" );
|
||||
CVAR_DEFINE_AUTO( snd_mute_losefocus, "1", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "silence the audio when game window loses focus" );
|
||||
CVAR_DEFINE_AUTO( s_test, "0", 0, "engine developer cvar for quick testing new features" );
|
||||
CVAR_DEFINE_AUTO( s_samplecount, "0", FCVAR_ARCHIVE, "sample count (0 for default value)" );
|
||||
CVAR_DEFINE_AUTO( s_warn_late_precache, "0", FCVAR_ARCHIVE, "warn about late precached sounds on client-side" );
|
||||
CVAR_DEFINE_AUTO( s_samplecount, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "sample count (0 for default value)" );
|
||||
CVAR_DEFINE_AUTO( s_warn_late_precache, "0", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "warn about late precached sounds on client-side" );
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
@@ -533,6 +533,8 @@ void S_StartSound( const vec3_t pos, int ent, int chan, sound_t handle, float fv
|
||||
// spatialize
|
||||
memset( target_chan, 0, sizeof( *target_chan ));
|
||||
|
||||
pitch *= (sys_timescale.value + 1) / 2;
|
||||
|
||||
VectorCopy( pos, target_chan->origin );
|
||||
target_chan->staticsound = ( ent == 0 ) ? true : false;
|
||||
target_chan->use_loop = (flags & SND_STOP_LOOPING) ? false : true;
|
||||
@@ -788,6 +790,8 @@ void S_AmbientSound( const vec3_t pos, int ent, sound_t handle, float fvol, floa
|
||||
return;
|
||||
}
|
||||
|
||||
pitch *= (sys_timescale.value + 1) / 2;
|
||||
|
||||
// never update positions if source entity is 0
|
||||
ch->staticsound = ( ent == 0 ) ? true : false;
|
||||
ch->use_loop = (flags & SND_STOP_LOOPING) ? false : true;
|
||||
@@ -1151,7 +1155,6 @@ void S_RawSamples( uint samples, uint rate, word width, word channels, const byt
|
||||
int snd_vol = 128;
|
||||
|
||||
if( entnum < 0 ) snd_vol = 256; // bg track or movie track
|
||||
if( snd_vol < 0 ) snd_vol = 0; // fixup negative values
|
||||
|
||||
S_RawEntSamples( entnum, samples, rate, width, channels, data, snd_vol );
|
||||
}
|
||||
|
||||
@@ -809,7 +809,7 @@ void S_MixBufferUpsample2x( int count, portable_samplepair_t *pbuffer, portable_
|
||||
// zero out all paintbuffers
|
||||
void MIX_ClearAllPaintBuffers( int SampleCount, qboolean clearFilters )
|
||||
{
|
||||
int count = min( SampleCount, PAINTBUFFER_SIZE );
|
||||
int count = Q_min( SampleCount, PAINTBUFFER_SIZE );
|
||||
int i;
|
||||
|
||||
// zero out all paintbuffer data (ignore sampleCount)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,31 +21,13 @@ GNU General Public License for more details.
|
||||
#include "keydefs.h"
|
||||
#include "ref_common.h"
|
||||
#include "input.h"
|
||||
#ifdef XASH_SDL
|
||||
#include <SDL.h>
|
||||
static SDL_Cursor* s_pDefaultCursor[20];
|
||||
#endif
|
||||
#include "platform/platform.h"
|
||||
|
||||
static enum VGUI_KeyCode s_pVirtualKeyTrans[256];
|
||||
static enum VGUI_DefaultCursor s_currentCursor;
|
||||
static VGUI_DefaultCursor s_currentCursor;
|
||||
static HINSTANCE s_pVGuiSupport; // vgui_support library
|
||||
static convar_t *vgui_utf8 = NULL;
|
||||
|
||||
// Helper functions for vgui backend
|
||||
|
||||
/*void VGUI_HideCursor( void )
|
||||
{
|
||||
host.mouse_visible = false;
|
||||
SDL_HideCursor();
|
||||
}
|
||||
|
||||
void VGUI_ShowCursor( void )
|
||||
{
|
||||
host.mouse_visible = true;
|
||||
SDL_ShowCursor();
|
||||
}*/
|
||||
|
||||
void GAME_EXPORT *VGUI_EngineMalloc(size_t size)
|
||||
{
|
||||
return Z_Malloc( size );
|
||||
@@ -66,70 +48,10 @@ void GAME_EXPORT VGUI_GetMousePos( int *_x, int *_y )
|
||||
*_x = x / xscale, *_y = y / yscale;
|
||||
}
|
||||
|
||||
void VGUI_InitCursors( void )
|
||||
void GAME_EXPORT VGUI_CursorSelect( VGUI_DefaultCursor cursor )
|
||||
{
|
||||
// load up all default cursors
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
s_pDefaultCursor[dc_none] = NULL;
|
||||
s_pDefaultCursor[dc_arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
|
||||
s_pDefaultCursor[dc_ibeam] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
|
||||
s_pDefaultCursor[dc_hourglass]= SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT);
|
||||
s_pDefaultCursor[dc_crosshair]= SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR);
|
||||
s_pDefaultCursor[dc_up] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
|
||||
s_pDefaultCursor[dc_sizenwse] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE);
|
||||
s_pDefaultCursor[dc_sizenesw] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW);
|
||||
s_pDefaultCursor[dc_sizewe] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE);
|
||||
s_pDefaultCursor[dc_sizens] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS);
|
||||
s_pDefaultCursor[dc_sizeall] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL);
|
||||
s_pDefaultCursor[dc_no] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
|
||||
s_pDefaultCursor[dc_hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
|
||||
//host.mouse_visible = true;
|
||||
SDL_SetCursor( s_pDefaultCursor[dc_arrow] );
|
||||
#endif
|
||||
}
|
||||
|
||||
void GAME_EXPORT VGUI_CursorSelect(enum VGUI_DefaultCursor cursor )
|
||||
{
|
||||
qboolean visible;
|
||||
if( cls.key_dest != key_game || cl.paused )
|
||||
return;
|
||||
|
||||
switch( cursor )
|
||||
{
|
||||
case dc_user:
|
||||
case dc_none:
|
||||
visible = false;
|
||||
break;
|
||||
default:
|
||||
visible = true;
|
||||
break;
|
||||
}
|
||||
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
/// TODO: platform cursors
|
||||
|
||||
if( CVAR_TO_BOOL( touch_emulate ) )
|
||||
return;
|
||||
if( host.mouse_visible )
|
||||
{
|
||||
SDL_SetRelativeMouseMode( SDL_FALSE );
|
||||
SDL_SetCursor( s_pDefaultCursor[cursor] );
|
||||
SDL_ShowCursor( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_ShowCursor( false );
|
||||
if( host.mouse_visible )
|
||||
SDL_GetRelativeMouseState( NULL, NULL );
|
||||
Key_EnableTextInput( false, true );
|
||||
}
|
||||
//SDL_SetRelativeMouseMode(false);
|
||||
#endif
|
||||
if( s_currentCursor == cursor )
|
||||
return;
|
||||
|
||||
Platform_SetCursorType( cursor );
|
||||
s_currentCursor = cursor;
|
||||
host.mouse_visible = visible;
|
||||
}
|
||||
|
||||
byte GAME_EXPORT VGUI_GetColor( int i, int j)
|
||||
@@ -138,21 +60,9 @@ byte GAME_EXPORT VGUI_GetColor( int i, int j)
|
||||
}
|
||||
|
||||
// Define and initialize vgui API
|
||||
|
||||
void GAME_EXPORT VGUI_SetVisible( qboolean state )
|
||||
{
|
||||
host.mouse_visible=state;
|
||||
#ifdef XASH_SDL
|
||||
SDL_ShowCursor( state );
|
||||
if( !state )
|
||||
SDL_GetRelativeMouseState( NULL, NULL );
|
||||
#endif
|
||||
Key_EnableTextInput( false, true );
|
||||
}
|
||||
|
||||
int GAME_EXPORT VGUI_UtfProcessChar( int in )
|
||||
{
|
||||
if( CVAR_TO_BOOL( vgui_utf8 ) )
|
||||
if( CVAR_TO_BOOL( vgui_utf8 ))
|
||||
return Con_UtfProcessCharForce( in );
|
||||
else
|
||||
return in;
|
||||
@@ -175,14 +85,15 @@ vguiapi_t vgui =
|
||||
NULL, // VGUI_GetTextureSizes,
|
||||
NULL, // VGUI_GenerateTexture,
|
||||
VGUI_EngineMalloc,
|
||||
/* VGUI_ShowCursor,
|
||||
VGUI_HideCursor,*/
|
||||
VGUI_CursorSelect,
|
||||
VGUI_GetColor,
|
||||
VGUI_IsInGame,
|
||||
VGUI_SetVisible,
|
||||
NULL,
|
||||
VGUI_GetMousePos,
|
||||
VGUI_UtfProcessChar,
|
||||
Platform_GetClipboardText,
|
||||
Platform_SetClipboardText,
|
||||
Platform_GetKeyModifiers,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
@@ -190,6 +101,7 @@ vguiapi_t vgui =
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
qboolean VGui_IsActive( void )
|
||||
@@ -240,7 +152,6 @@ void VGui_Startup( const char *clientlib, int width, int height )
|
||||
|
||||
VGui_FillAPIFromRef( &vgui, &ref.dllFuncs );
|
||||
|
||||
#ifdef XASH_INTERNAL_GAMELIBS
|
||||
s_pVGuiSupport = COM_LoadLibrary( clientlib, false, false );
|
||||
|
||||
if( s_pVGuiSupport )
|
||||
@@ -250,58 +161,70 @@ void VGui_Startup( const char *clientlib, int width, int height )
|
||||
{
|
||||
F( &vgui );
|
||||
vgui.initialized = true;
|
||||
VGUI_InitCursors();
|
||||
Con_Reportf( "vgui_support: found interal client support\n" );
|
||||
Con_Reportf( "vgui_support: found internal client support\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
COM_FreeLibrary( s_pVGuiSupport );
|
||||
}
|
||||
}
|
||||
#endif // XASH_INTERNAL_GAMELIBS
|
||||
|
||||
// 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( !vgui.initialized )
|
||||
{
|
||||
if( Q_strstr( vguilib, ".dll") )
|
||||
// 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 );
|
||||
else
|
||||
|
||||
if( !vguiloader[0] && !Sys_GetParmFromCmdLine( "-vguiloader", vguiloader ))
|
||||
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());
|
||||
}
|
||||
s_pVGuiSupport = COM_LoadLibrary( vguiloader, false, false );
|
||||
|
||||
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" );
|
||||
}
|
||||
else
|
||||
{
|
||||
F = COM_GetProcAddress( s_pVGuiSupport, "InitAPI" );
|
||||
if( F )
|
||||
if( !s_pVGuiSupport )
|
||||
{
|
||||
F( &vgui );
|
||||
vgui.initialized = true;
|
||||
VGUI_InitCursors();
|
||||
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
|
||||
Con_Reportf( S_ERROR "Failed to find vgui_support library entry point!\n" );
|
||||
{
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( height < 480 )
|
||||
@@ -498,8 +421,9 @@ void VGui_KeyEvent( int key, int down )
|
||||
switch( key )
|
||||
{
|
||||
case K_MOUSE1:
|
||||
if( down && host.mouse_visible )
|
||||
Key_EnableTextInput( true, false );
|
||||
if( down && host.mouse_visible ) {
|
||||
Key_EnableTextInput(true, false);
|
||||
}
|
||||
vgui.Mouse( down ? MA_PRESSED : MA_RELEASED, MOUSE_LEFT );
|
||||
return;
|
||||
case K_MOUSE2:
|
||||
@@ -535,7 +459,7 @@ void VGui_MouseMove( int x, int y )
|
||||
|
||||
void VGui_Paint( void )
|
||||
{
|
||||
if(vgui.initialized)
|
||||
if( vgui.initialized )
|
||||
vgui.Paint();
|
||||
}
|
||||
|
||||
@@ -551,3 +475,9 @@ void *GAME_EXPORT VGui_GetPanel( void )
|
||||
return vgui.GetPanel();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void VGui_ReportTextInput( const char *text )
|
||||
{
|
||||
if ( vgui.initialized )
|
||||
vgui.TextInput( text );
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ 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 );
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -190,7 +190,7 @@ void VID_Init( void )
|
||||
|
||||
// a1ba: planned to be named vid_mode for compability
|
||||
// but supported mode list is filled by backends, so numbers are not portable any more
|
||||
Cmd_AddCommand( "vid_setmode", VID_Mode_f, "display video mode" );
|
||||
Cmd_AddRestrictedCommand( "vid_setmode", VID_Mode_f, "display video mode" );
|
||||
|
||||
R_Init(); // init renderer
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ extern convar_t *vid_highdpi;
|
||||
extern convar_t *vid_rotate;
|
||||
extern convar_t *vid_scale;
|
||||
|
||||
extern convar_t *gl_wgl_msaa_samples;
|
||||
extern convar_t *gl_msaa_samples;
|
||||
void R_SaveVideoMode( int w, int h, int render_w, int render_h );
|
||||
void VID_CheckChanges( void );
|
||||
const char *VID_GetModeString( int vid_mode );
|
||||
|
||||
@@ -16,9 +16,9 @@ GNU General Public License for more details.
|
||||
#ifndef VOX_H
|
||||
#define VOX_H
|
||||
|
||||
#define CVOXWORDMAX 64
|
||||
#define CVOXZEROSCANMAX 255 // scan up to this many samples for next zero crossing
|
||||
#define MAX_SENTENCES 4096
|
||||
#define CVOXWORDMAX 64
|
||||
#define CVOXFILESENTENCEMAX 4096
|
||||
|
||||
#define SENTENCE_INDEX -99999 // unique sentence index
|
||||
|
||||
typedef struct voxword_s
|
||||
@@ -34,13 +34,6 @@ typedef struct voxword_s
|
||||
sfx_t *sfx; // name and cache pointer
|
||||
} voxword_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *pName;
|
||||
float length;
|
||||
} sentence_t;
|
||||
|
||||
struct channel_s;
|
||||
void VOX_LoadWord( struct channel_s *pchan );
|
||||
void VOX_FreeWord( struct channel_s *pchan );
|
||||
|
||||
@@ -229,7 +229,7 @@ void BaseCmd_Stats_f( void )
|
||||
Con_Printf( "Empty buckets: %d\n", empty );
|
||||
}
|
||||
|
||||
static void BaseCmd_CheckCvars( const char *key, const char *value, void *buffer, void *ptr )
|
||||
static void BaseCmd_CheckCvars( const char *key, const char *value, const void *unused, void *ptr )
|
||||
{
|
||||
base_command_t *v = BaseCmd_Find( HM_CVAR, key );
|
||||
qboolean *invalid = ptr;
|
||||
|
||||
@@ -30,11 +30,15 @@ typedef struct
|
||||
} cmdbuf_t;
|
||||
|
||||
qboolean cmd_wait;
|
||||
cmdbuf_t cmd_text;
|
||||
cmdbuf_t cmd_text, filteredcmd_text;
|
||||
byte cmd_text_buf[MAX_CMD_BUFFER];
|
||||
byte filteredcmd_text_buf[MAX_CMD_BUFFER];
|
||||
cmdalias_t *cmd_alias;
|
||||
uint cmd_condition;
|
||||
int cmd_condlevel;
|
||||
static qboolean cmd_currentCommandIsPrivileged;
|
||||
|
||||
static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPrivileged );
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
@@ -52,8 +56,10 @@ Cbuf_Init
|
||||
void Cbuf_Init( void )
|
||||
{
|
||||
cmd_text.data = cmd_text_buf;
|
||||
cmd_text.maxsize = MAX_CMD_BUFFER;
|
||||
cmd_text.cursize = 0;
|
||||
filteredcmd_text.data = filteredcmd_text_buf;
|
||||
|
||||
filteredcmd_text.maxsize = cmd_text.maxsize = MAX_CMD_BUFFER;
|
||||
filteredcmd_text.cursize = cmd_text.cursize = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -63,8 +69,9 @@ Cbuf_Clear
|
||||
*/
|
||||
void Cbuf_Clear( void )
|
||||
{
|
||||
memset( cmd_text.data, 0, sizeof( cmd_text_buf ));
|
||||
cmd_text.cursize = 0;
|
||||
memset( cmd_text.data, 0, cmd_text.maxsize );
|
||||
memset( filteredcmd_text.data, 0, filteredcmd_text.maxsize );
|
||||
cmd_text.cursize = filteredcmd_text.cursize = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -88,6 +95,19 @@ void *Cbuf_GetSpace( cmdbuf_t *buf, int length )
|
||||
return data;
|
||||
}
|
||||
|
||||
static void Cbuf_AddTextToBuffer( cmdbuf_t *buf, const char *text )
|
||||
{
|
||||
int l = Q_strlen( text );
|
||||
|
||||
if(( buf->cursize + l ) >= buf->maxsize )
|
||||
{
|
||||
Con_Reportf( S_WARN "%s: overflow\n", __func__ );
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy( Cbuf_GetSpace( buf, l ), text, l );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cbuf_AddText
|
||||
@@ -97,16 +117,17 @@ Adds command text at the end of the buffer
|
||||
*/
|
||||
void Cbuf_AddText( const char *text )
|
||||
{
|
||||
int l = Q_strlen( text );
|
||||
Cbuf_AddTextToBuffer( &cmd_text, text );
|
||||
}
|
||||
|
||||
if(( cmd_text.cursize + l ) >= cmd_text.maxsize )
|
||||
{
|
||||
Con_Reportf( S_WARN "Cbuf_AddText: overflow\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy( Cbuf_GetSpace( &cmd_text, l ), text, l );
|
||||
}
|
||||
/*
|
||||
============
|
||||
Cbuf_AddFilteredText
|
||||
============
|
||||
*/
|
||||
void Cbuf_AddFilteredText( const char *text )
|
||||
{
|
||||
Cbuf_AddTextToBuffer( &filteredcmd_text, text );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -117,43 +138,55 @@ Adds command text immediately after the current command
|
||||
Adds a \n to the text
|
||||
============
|
||||
*/
|
||||
void Cbuf_InsertText( const char *text )
|
||||
static void Cbuf_InsertTextToBuffer( cmdbuf_t *buf, const char *text )
|
||||
{
|
||||
int l = Q_strlen( text );
|
||||
|
||||
if(( cmd_text.cursize + l ) >= cmd_text.maxsize )
|
||||
if(( buf->cursize + l ) >= buf->maxsize )
|
||||
{
|
||||
Con_Reportf( S_WARN "Cbuf_InsertText: overflow\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove( cmd_text.data + l, cmd_text.data, cmd_text.cursize );
|
||||
memcpy( cmd_text.data, text, l );
|
||||
cmd_text.cursize += l;
|
||||
memmove( buf->data + l, buf->data, buf->cursize );
|
||||
memcpy( buf->data, text, l );
|
||||
buf->cursize += l;
|
||||
}
|
||||
}
|
||||
|
||||
void Cbuf_InsertText( const char *text )
|
||||
{
|
||||
Cbuf_InsertTextToBuffer( &cmd_text, text );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cbuf_Execute
|
||||
============
|
||||
*/
|
||||
void Cbuf_Execute( void )
|
||||
void Cbuf_ExecuteCommandsFromBuffer( cmdbuf_t *buf, qboolean isPrivileged, int cmdsToExecute )
|
||||
{
|
||||
char *text;
|
||||
char line[MAX_CMD_LINE];
|
||||
int i, quotes;
|
||||
char *comment;
|
||||
|
||||
while( cmd_text.cursize )
|
||||
while( buf->cursize )
|
||||
{
|
||||
// limit amount of commands that can be issued
|
||||
if( cmdsToExecute >= 0 )
|
||||
{
|
||||
if( !cmdsToExecute-- )
|
||||
break;
|
||||
}
|
||||
|
||||
// find a \n or ; line break
|
||||
text = (char *)cmd_text.data;
|
||||
text = (char *)buf->data;
|
||||
|
||||
quotes = false;
|
||||
comment = NULL;
|
||||
|
||||
for( i = 0; i < cmd_text.cursize; i++ )
|
||||
for( i = 0; i < buf->cursize; i++ )
|
||||
{
|
||||
if( !comment )
|
||||
{
|
||||
@@ -162,7 +195,7 @@ void Cbuf_Execute( void )
|
||||
if( quotes )
|
||||
{
|
||||
// make sure i doesn't get > cursize which causes a negative size in memmove, which is fatal --blub
|
||||
if( i < ( cmd_text.cursize - 1 ) && ( text[i+0] == '\\' && (text[i+1] == '"' || text[i+1] == '\\')))
|
||||
if( i < ( buf->cursize - 1 ) && ( text[i+0] == '\\' && (text[i+1] == '"' || text[i+1] == '\\')))
|
||||
i++;
|
||||
}
|
||||
else
|
||||
@@ -191,19 +224,19 @@ void Cbuf_Execute( void )
|
||||
// delete the text from the command buffer and move remaining commands down
|
||||
// this is necessary because commands (exec) can insert data at the
|
||||
// beginning of the text buffer
|
||||
if( i == cmd_text.cursize )
|
||||
if( i == buf->cursize )
|
||||
{
|
||||
cmd_text.cursize = 0;
|
||||
buf->cursize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
cmd_text.cursize -= i;
|
||||
memmove( cmd_text.data, text + i, cmd_text.cursize );
|
||||
buf->cursize -= i;
|
||||
memmove( buf->data, text + i, buf->cursize );
|
||||
}
|
||||
|
||||
// execute the command line
|
||||
Cmd_ExecuteString( line );
|
||||
Cmd_ExecuteStringWithPrivilegeCheck( line, isPrivileged );
|
||||
|
||||
if( cmd_wait )
|
||||
{
|
||||
@@ -215,6 +248,20 @@ void Cbuf_Execute( void )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cbuf_Execute
|
||||
============
|
||||
*/
|
||||
void Cbuf_Execute( void )
|
||||
{
|
||||
Cbuf_ExecuteCommandsFromBuffer( &cmd_text, true, -1 );
|
||||
// a1ba: unlimited commands for filtered buffer per frame
|
||||
// I don't see any sense in restricting that at this moment
|
||||
// but in future we may limit this
|
||||
Cbuf_ExecuteCommandsFromBuffer( &filteredcmd_text, false, -1 );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Cbuf_ExecStuffCmds
|
||||
@@ -282,6 +329,11 @@ void Cbuf_ExecStuffCmds( void )
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
qboolean Cmd_CurrentCommandIsPrivileged( void )
|
||||
{
|
||||
return cmd_currentCommandIsPrivileged;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
Cmd_StuffCmds_f
|
||||
@@ -458,8 +510,8 @@ typedef struct cmd_s
|
||||
struct cmd_s *next;
|
||||
char *name;
|
||||
xcommand_t function;
|
||||
char *desc;
|
||||
int flags;
|
||||
char *desc;
|
||||
} cmd_t;
|
||||
|
||||
static int cmd_argc;
|
||||
@@ -619,21 +671,21 @@ static int Cmd_AddCommandEx( const char *funcname, const char *cmd_name, xcomman
|
||||
|
||||
if( !COM_CheckString( cmd_name ))
|
||||
{
|
||||
Con_Reportf( S_ERROR "Cmd_AddCommand: NULL name\n" );
|
||||
Con_Reportf( S_ERROR "%s: NULL name\n", funcname );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// fail if the command is a variable name
|
||||
if( Cvar_FindVar( cmd_name ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Cmd_AddServerCommand: %s already defined as a var\n", cmd_name );
|
||||
Con_DPrintf( S_ERROR "%s: %s already defined as a var\n", funcname, cmd_name );
|
||||
return 0;
|
||||
}
|
||||
|
||||
// fail if the command already exists
|
||||
if( Cmd_Exists( cmd_name ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Cmd_AddServerCommand: %s already defined\n", cmd_name );
|
||||
Con_DPrintf( S_ERROR "%s: %s already defined\n", funcname, cmd_name );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -676,7 +728,7 @@ Cmd_AddRestrictedCommand
|
||||
*/
|
||||
void Cmd_AddRestrictedCommand( const char *cmd_name, xcommand_t function, const char *cmd_desc )
|
||||
{
|
||||
Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, cmd_desc, CMD_LOCALONLY );
|
||||
Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, cmd_desc, CMD_PRIVILEGED );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -696,7 +748,15 @@ Cmd_AddClientCommand
|
||||
*/
|
||||
int GAME_EXPORT Cmd_AddClientCommand( const char *cmd_name, xcommand_t function )
|
||||
{
|
||||
return Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, "client command", CMD_CLIENTDLL );
|
||||
int flags = CMD_CLIENTDLL;
|
||||
|
||||
// a1ba: try to mitigate outdated client.dll vulnerabilities
|
||||
if( !Q_stricmp( cmd_name, "motd_write" ))
|
||||
{
|
||||
flags |= CMD_PRIVILEGED;
|
||||
}
|
||||
|
||||
return Cmd_AddCommandEx( __FUNCTION__, cmd_name, function, "client command", flags );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -876,6 +936,35 @@ void Cmd_Else_f( void )
|
||||
cmd_condition ^= BIT( cmd_condlevel );
|
||||
}
|
||||
|
||||
static qboolean Cmd_ShouldAllowCommand( cmd_t *cmd, qboolean isPrivileged )
|
||||
{
|
||||
const char *prefixes[] = { "cl_", "gl_", "r_", "m_", "hud_" };
|
||||
int i;
|
||||
|
||||
// always allow local commands
|
||||
if( isPrivileged )
|
||||
return true;
|
||||
|
||||
// never allow local only commands from remote
|
||||
if( FBitSet( cmd->flags, CMD_PRIVILEGED ))
|
||||
return false;
|
||||
|
||||
// allow engine commands if user don't mind
|
||||
if( cl_filterstuffcmd.value <= 0.0f )
|
||||
return true;
|
||||
|
||||
if( FBitSet( cmd->flags, CMD_FILTERABLE ))
|
||||
return false;
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( prefixes ); i++ )
|
||||
{
|
||||
if( !Q_strnicmp( cmd->name, prefixes[i], Q_strlen( prefixes[i] )))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_ExecuteString
|
||||
@@ -883,7 +972,7 @@ Cmd_ExecuteString
|
||||
A complete command line has been parsed, so try to execute it
|
||||
============
|
||||
*/
|
||||
void Cmd_ExecuteString( const char *text )
|
||||
static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPrivileged )
|
||||
{
|
||||
cmd_t *cmd = NULL;
|
||||
cmdalias_t *a = NULL;
|
||||
@@ -895,7 +984,7 @@ void Cmd_ExecuteString( const char *text )
|
||||
cmd_condlevel = 0;
|
||||
|
||||
// cvar value substitution
|
||||
if( cmd_scripting && cmd_scripting->value )
|
||||
if( CVAR_TO_BOOL( cmd_scripting ))
|
||||
{
|
||||
while( *text )
|
||||
{
|
||||
@@ -952,47 +1041,59 @@ void Cmd_ExecuteString( const char *text )
|
||||
if( !host.apply_game_config )
|
||||
{
|
||||
// check aliases
|
||||
if( a ) // already found in basecmd
|
||||
if( !a ) // if not found in basecmd
|
||||
{
|
||||
Cbuf_InsertText( a->value );
|
||||
return;
|
||||
for( a = cmd_alias; a; a = a->next )
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], a->name ))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for( a = cmd_alias; a; a = a->next )
|
||||
if( a )
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], a->name ))
|
||||
{
|
||||
Cbuf_InsertText( a->value );
|
||||
return;
|
||||
}
|
||||
Cbuf_InsertTextToBuffer(
|
||||
isPrivileged ? &cmd_text : &filteredcmd_text,
|
||||
a->value );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// special mode for restore game.dll archived cvars
|
||||
if( !host.apply_game_config || !Q_strcmp( cmd_argv[0], "exec" ))
|
||||
{
|
||||
// check functions
|
||||
if( cmd && cmd->function ) // already found in basecmd
|
||||
if( !cmd || !cmd->function ) // if not found in basecmd
|
||||
{
|
||||
cmd->function();
|
||||
return;
|
||||
for( cmd = cmd_functions; cmd; cmd = cmd->next )
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], cmd->name ) && cmd->function )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for( cmd = cmd_functions; cmd; cmd = cmd->next )
|
||||
// check functions
|
||||
if( cmd && cmd->function )
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], cmd->name ) && cmd->function )
|
||||
if( Cmd_ShouldAllowCommand( cmd, isPrivileged ))
|
||||
{
|
||||
cmd_currentCommandIsPrivileged = isPrivileged;
|
||||
cmd->function();
|
||||
return;
|
||||
cmd_currentCommandIsPrivileged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf( S_WARN "Could not execute privileged command %s\n", cmd->name );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// check cvars
|
||||
if( Cvar_Command( cvar )) return;
|
||||
if( Cvar_CommandWithPrivilegeCheck( cvar, isPrivileged )) return;
|
||||
|
||||
if( host.apply_game_config )
|
||||
return; // don't send nothing to server: we is a server!
|
||||
return; // don't send nothing to server: we are a server!
|
||||
|
||||
// forward the command line to the server, so the entity DLL can parse it
|
||||
if( host.type == HOST_NORMAL )
|
||||
@@ -1006,11 +1107,16 @@ void Cmd_ExecuteString( const char *text )
|
||||
#endif // XASH_DEDICATED
|
||||
if( Cvar_VariableInteger( "host_gameloaded" ))
|
||||
{
|
||||
Con_Printf( S_WARN "Unknown command \"%s\"\n", text );
|
||||
Con_Printf( S_WARN "Unknown command \"%s\"\n", Cmd_Argv( 0 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cmd_ExecuteString( const char *text )
|
||||
{
|
||||
Cmd_ExecuteStringWithPrivilegeCheck( text, true );
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
Cmd_ForwardToServer
|
||||
@@ -1225,9 +1331,43 @@ void Cmd_Null_f( void )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
Cmd_Escape
|
||||
|
||||
inserts escape sequences
|
||||
==========
|
||||
*/
|
||||
void Cmd_Escape( char *newCommand, const char *oldCommand, int len )
|
||||
{
|
||||
int c;
|
||||
int scripting = CVAR_TO_BOOL( cmd_scripting );
|
||||
|
||||
while( (c = *oldCommand++) && len > 1 )
|
||||
{
|
||||
if( c == '"' )
|
||||
{
|
||||
*newCommand++ = '\\';
|
||||
len--;
|
||||
}
|
||||
|
||||
if( scripting && c == '$')
|
||||
{
|
||||
*newCommand++ = '$';
|
||||
len--;
|
||||
}
|
||||
|
||||
*newCommand++ = c; len--;
|
||||
}
|
||||
|
||||
*newCommand++ = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_Init
|
||||
|
||||
============
|
||||
*/
|
||||
void Cmd_Init( void )
|
||||
@@ -1244,13 +1384,13 @@ void Cmd_Init( void )
|
||||
Cmd_AddCommand( "echo", Cmd_Echo_f, "print a message to the console (useful in scripts)" );
|
||||
Cmd_AddCommand( "wait", Cmd_Wait_f, "make script execution wait for some rendered frames" );
|
||||
Cmd_AddCommand( "cmdlist", Cmd_List_f, "display all console commands beginning with the specified prefix" );
|
||||
Cmd_AddCommand( "stuffcmds", Cmd_StuffCmds_f, "execute commandline parameters (must be present in .rc script)" );
|
||||
Cmd_AddRestrictedCommand( "stuffcmds", Cmd_StuffCmds_f, "execute commandline parameters (must be present in .rc script)" );
|
||||
Cmd_AddCommand( "apropos", Cmd_Apropos_f, "lists all console variables/commands/aliases containing the specified string in the name or description" );
|
||||
#if !XASH_DEDICATED
|
||||
Cmd_AddCommand( "cmd", Cmd_ForwardToServer, "send a console commandline to the server" );
|
||||
#endif // XASH_DEDICATED
|
||||
Cmd_AddCommand( "alias", Cmd_Alias_f, "create a script function. Without arguments show the list of all alias" );
|
||||
Cmd_AddCommand( "unalias", Cmd_UnAlias_f, "remove a script function" );
|
||||
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_AddCommand( "if", Cmd_If_f, "compare and set condition bits" );
|
||||
Cmd_AddCommand( "else", Cmd_Else_f, "invert condition bit" );
|
||||
|
||||
@@ -1259,3 +1399,64 @@ void Cmd_Init( void )
|
||||
Cmd_AddCommand( "basecmd_test", BaseCmd_Test_f, "test basecmd" );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if XASH_ENGINE_TESTS
|
||||
#include "tests.h"
|
||||
|
||||
enum
|
||||
{
|
||||
NO_CALL = 0,
|
||||
PRIV = 1,
|
||||
UNPRIV = 2
|
||||
};
|
||||
|
||||
static int test_flags[3] = { NO_CALL, NO_CALL, NO_CALL };
|
||||
|
||||
static void Test_PrivilegedCommand_f( void )
|
||||
{
|
||||
test_flags[0] = Cmd_CurrentCommandIsPrivileged() ? PRIV : UNPRIV;
|
||||
}
|
||||
|
||||
static void Test_UnprivilegedCommand_f( void )
|
||||
{
|
||||
test_flags[1] = Cmd_CurrentCommandIsPrivileged() ? PRIV : UNPRIV;
|
||||
}
|
||||
|
||||
static void Test_FilteredCommand_f( void )
|
||||
{
|
||||
test_flags[2] = Cmd_CurrentCommandIsPrivileged() ? PRIV : UNPRIV;
|
||||
}
|
||||
|
||||
void Test_RunCmd( void )
|
||||
{
|
||||
Cmd_AddCommand( "test_privileged", Test_PrivilegedCommand_f, "bark bark" );
|
||||
Cmd_AddRestrictedCommand( "test_unprivileged", Test_UnprivilegedCommand_f, "meow meow" );
|
||||
Cmd_AddCommand( "hud_filtered", Test_FilteredCommand_f, "dummy description" );
|
||||
|
||||
Cbuf_AddText( "test_privileged; test_unprivileged; hud_filtered\n" );
|
||||
Cbuf_Execute();
|
||||
TASSERT( test_flags[0] == PRIV );
|
||||
TASSERT( test_flags[1] == PRIV );
|
||||
TASSERT( test_flags[2] == PRIV );
|
||||
|
||||
VectorSet( test_flags, NO_CALL, NO_CALL, NO_CALL );
|
||||
Cvar_DirectSet( &cl_filterstuffcmd, "0" );
|
||||
Cbuf_AddFilteredText( "test_privileged; test_unprivileged; hud_filtered\n" );
|
||||
Cbuf_Execute();
|
||||
TASSERT( test_flags[0] == UNPRIV );
|
||||
TASSERT( test_flags[1] == NO_CALL );
|
||||
TASSERT( test_flags[2] == UNPRIV );
|
||||
|
||||
VectorSet( test_flags, NO_CALL, NO_CALL, NO_CALL );
|
||||
Cvar_DirectSet( &cl_filterstuffcmd, "1" );
|
||||
Cbuf_AddFilteredText( "test_privileged; test_unprivileged; hud_filtered\n" );
|
||||
Cbuf_Execute();
|
||||
TASSERT( test_flags[0] == UNPRIV );
|
||||
TASSERT( test_flags[1] == NO_CALL );
|
||||
TASSERT( test_flags[2] == NO_CALL );
|
||||
|
||||
Cmd_RemoveCommand( "hud_filtered" );
|
||||
Cmd_RemoveCommand( "test_unprivileged" );
|
||||
Cmd_RemoveCommand( "test_privileged" );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -13,6 +13,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#if defined( ALLOCA_H )
|
||||
#include ALLOCA_H
|
||||
#endif
|
||||
#include "common.h"
|
||||
#include "studio.h"
|
||||
#include "xash3d_mathlib.h"
|
||||
@@ -886,6 +889,10 @@ pfnCvar_RegisterVariable
|
||||
*/
|
||||
cvar_t *pfnCvar_RegisterClientVariable( const char *szName, const char *szValue, int flags )
|
||||
{
|
||||
// a1ba: try to mitigate outdated client.dll vulnerabilities
|
||||
if( !Q_stricmp( szName, "motdfile" ))
|
||||
flags |= FCVAR_PRIVILEGED;
|
||||
|
||||
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 ));
|
||||
|
||||
@@ -184,6 +184,8 @@ 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;
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
@@ -229,6 +231,7 @@ typedef struct gameinfo_s
|
||||
qboolean secure; // prevent to console acess
|
||||
qboolean nomodels; // don't let player to choose model (use player.mdl always)
|
||||
qboolean noskills; // disable skill menu selection
|
||||
qboolean render_picbutton_text; // use font renderer to render WON buttons
|
||||
|
||||
char sp_entity[32]; // e.g. info_player_start
|
||||
char mp_entity[32]; // e.g. info_player_deathmatch
|
||||
@@ -464,8 +467,9 @@ extern sysinfo_t SI;
|
||||
#define CMD_SERVERDLL BIT( 0 ) // added by server.dll
|
||||
#define CMD_CLIENTDLL BIT( 1 ) // added by client.dll
|
||||
#define CMD_GAMEUIDLL BIT( 2 ) // added by GameUI.dll
|
||||
#define CMD_LOCALONLY BIT( 3 ) // restricted from server commands
|
||||
#define CMD_REFDLL BIT( 4 ) // added by ref.dll
|
||||
#define CMD_PRIVILEGED BIT( 3 ) // only available in privileged mode
|
||||
#define CMD_FILTERABLE BIT( 4 ) // filtered in unprivileged mode if cl_filterstuffcmd is 1
|
||||
#define CMD_REFDLL BIT( 5 ) // added by ref.dll
|
||||
|
||||
typedef void (*xcommand_t)( void );
|
||||
|
||||
@@ -475,9 +479,11 @@ typedef void (*xcommand_t)( void );
|
||||
void Cbuf_Init( void );
|
||||
void Cbuf_Clear( void );
|
||||
void Cbuf_AddText( const char *text );
|
||||
void Cbuf_AddFilteredText( const char *text );
|
||||
void Cbuf_InsertText( const char *text );
|
||||
void Cbuf_ExecStuffCmds( void );
|
||||
void Cbuf_Execute (void);
|
||||
qboolean Cmd_CurrentCommandIsPrivileged( void );
|
||||
int Cmd_Argc( void );
|
||||
const char *Cmd_Args( void );
|
||||
const char *Cmd_Argv( int arg );
|
||||
@@ -499,6 +505,7 @@ qboolean Cmd_GetMovieList( const char *s, char *completedname, int length );
|
||||
void Cmd_TokenizeString( const char *text );
|
||||
void Cmd_ExecuteString( const char *text );
|
||||
void Cmd_ForwardToServer( void );
|
||||
void Cmd_Escape( char *newCommand, const char *oldCommand, int len );
|
||||
|
||||
//
|
||||
// zone.c
|
||||
@@ -589,7 +596,7 @@ qboolean FS_SaveImage( const char *filename, rgbdata_t *pix );
|
||||
rgbdata_t *FS_CopyImage( rgbdata_t *in );
|
||||
void FS_FreeImage( rgbdata_t *pack );
|
||||
extern const bpc_desc_t PFDesc[]; // image get pixelformat
|
||||
qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, float bumpscale );
|
||||
qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, float reserved );
|
||||
void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end, int pal_size );
|
||||
void Image_PaletteTranslate( byte *palSrc, int top, int bottom, int pal_size );
|
||||
void Image_SetForceFlags( uint flags ); // set image force flags on loading
|
||||
@@ -684,7 +691,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
int Host_CompareFileTime( int ft1, int ft2 );
|
||||
void Host_NewInstance( const char *name, const char *finalmsg );
|
||||
void Host_EndGame( qboolean abort, const char *message, ... ) _format( 2 );
|
||||
void Host_AbortCurrentFrame( void );
|
||||
void Host_AbortCurrentFrame( void ) NORETURN;
|
||||
void Host_WriteServerConfig( const char *name );
|
||||
void Host_WriteOpenGLConfig( void );
|
||||
void Host_WriteVideoConfig( void );
|
||||
@@ -692,7 +699,7 @@ void Host_WriteConfig( void );
|
||||
qboolean Host_IsLocalGame( void );
|
||||
qboolean Host_IsLocalClient( void );
|
||||
void Host_ShutdownServer( void );
|
||||
void Host_Error( const char *error, ... ) _format( 1 );
|
||||
void Host_Error( const char *error, ... ) _format( 1 ) NORETURN;
|
||||
void Host_PrintEngineFeatures( void );
|
||||
void Host_Frame( float time );
|
||||
void Host_InitDecals( void );
|
||||
@@ -749,7 +756,6 @@ void pfnDrawSetTextColor( float r, float g, float b );
|
||||
void pfnDrawConsoleStringLen( const char *pText, int *length, int *height );
|
||||
void *Cache_Check( poolhandle_t mempool, struct cache_user_s *c );
|
||||
void COM_TrimSpace( const char *source, char *dest );
|
||||
edict_t* pfnPEntityOfEntIndex( int iEntIndex );
|
||||
void pfnGetModelBounds( model_t *mod, float *mins, float *maxs );
|
||||
void pfnCVarDirectSet( cvar_t *var, const char *szValue );
|
||||
int COM_CheckParm( char *parm, char **ppnext );
|
||||
|
||||
@@ -1216,7 +1216,7 @@ void Con_CompleteCommand( field_t *field )
|
||||
|
||||
if( con.matchCount == 1 )
|
||||
{
|
||||
Q_sprintf( con.completionField->buffer, "\\%s", con.cmds[0] );
|
||||
Q_strncpy( con.completionField->buffer, con.cmds[0], sizeof( con.completionField->buffer ));
|
||||
if( Cmd_Argc() == 1 ) Q_strncat( con.completionField->buffer, " ", sizeof( con.completionField->buffer ) );
|
||||
else Con_ConcatRemaining( temp.buffer, con.completionString );
|
||||
con.completionField->cursor = Q_strlen( con.completionField->buffer );
|
||||
@@ -1244,7 +1244,7 @@ void Con_CompleteCommand( field_t *field )
|
||||
con.shortestMatch[len] = 0;
|
||||
|
||||
// multiple matches, complete to shortest
|
||||
Q_sprintf( con.completionField->buffer, "\\%s", con.shortestMatch );
|
||||
Q_strncpy( con.completionField->buffer, con.shortestMatch, sizeof( con.completionField->buffer ));
|
||||
con.completionField->cursor = Q_strlen( con.completionField->buffer );
|
||||
Con_ConcatRemaining( temp.buffer, con.completionString );
|
||||
|
||||
|
||||
@@ -24,9 +24,11 @@ Crash handler, called from system
|
||||
================
|
||||
*/
|
||||
#if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP || XASH_CRASHHANDLER == CRASHHANDLER_WIN32
|
||||
|
||||
#if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP
|
||||
|
||||
#pragma comment( lib, "dbghelp" )
|
||||
#pragma comment( lib, "psapi" )
|
||||
|
||||
#include <winnt.h>
|
||||
#include <dbghelp.h>
|
||||
#include <psapi.h>
|
||||
@@ -35,7 +37,7 @@ Crash handler, called from system
|
||||
typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
|
||||
#endif
|
||||
|
||||
int ModuleName( HANDLE process, char *name, void *address, int len )
|
||||
static int Sys_ModuleName( HANDLE process, char *name, void *address, int len )
|
||||
{
|
||||
DWORD_PTR baseAddress = 0;
|
||||
static HMODULE *moduleArray;
|
||||
@@ -44,27 +46,24 @@ int ModuleName( HANDLE process, char *name, void *address, int len )
|
||||
DWORD bytesRequired;
|
||||
int i;
|
||||
|
||||
if(len < 3)
|
||||
if( len < 3 )
|
||||
return 0;
|
||||
|
||||
if ( !moduleArray && EnumProcessModules( process, NULL, 0, &bytesRequired ) )
|
||||
if( !moduleArray && EnumProcessModules( process, NULL, 0, &bytesRequired ) )
|
||||
{
|
||||
if ( bytesRequired )
|
||||
{
|
||||
moduleArrayBytes = (LPBYTE)LocalAlloc( LPTR, bytesRequired );
|
||||
|
||||
if ( moduleArrayBytes )
|
||||
if( moduleArrayBytes && EnumProcessModules( process, (HMODULE *)moduleArrayBytes, bytesRequired, &bytesRequired ) )
|
||||
{
|
||||
if( EnumProcessModules( process, (HMODULE *)moduleArrayBytes, bytesRequired, &bytesRequired ) )
|
||||
{
|
||||
moduleCount = bytesRequired / sizeof( HMODULE );
|
||||
moduleArray = (HMODULE *)moduleArrayBytes;
|
||||
}
|
||||
moduleCount = bytesRequired / sizeof( HMODULE );
|
||||
moduleArray = (HMODULE *)moduleArrayBytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( i = 0; i<moduleCount; i++ )
|
||||
for( i = 0; i < moduleCount; i++ )
|
||||
{
|
||||
MODULEINFO info;
|
||||
GetModuleInformation( process, moduleArray[i], &info, sizeof(MODULEINFO) );
|
||||
@@ -73,9 +72,10 @@ int ModuleName( HANDLE process, char *name, void *address, int len )
|
||||
( (DWORD64)address < (DWORD64)info.lpBaseOfDll + (DWORD64)info.SizeOfImage ) )
|
||||
return GetModuleBaseName( process, moduleArray[i], name, len );
|
||||
}
|
||||
return Q_snprintf(name, len, "???");
|
||||
return Q_snprintf( name, len, "???" );
|
||||
}
|
||||
static void stack_trace( PEXCEPTION_POINTERS pInfo )
|
||||
|
||||
static void Sys_StackTrace( PEXCEPTION_POINTERS pInfo )
|
||||
{
|
||||
char message[1024];
|
||||
int len = 0;
|
||||
@@ -89,7 +89,8 @@ static void stack_trace( PEXCEPTION_POINTERS pInfo )
|
||||
STACKFRAME64 stackframe;
|
||||
DWORD image;
|
||||
|
||||
memcpy( &context, pInfo->ContextRecord, sizeof(CONTEXT) );
|
||||
memcpy( &context, pInfo->ContextRecord, sizeof( CONTEXT ));
|
||||
|
||||
options = SymGetOptions();
|
||||
options |= SYMOPT_DEBUG;
|
||||
options |= SYMOPT_LOAD_LINES;
|
||||
@@ -97,9 +98,7 @@ static void stack_trace( PEXCEPTION_POINTERS pInfo )
|
||||
|
||||
SymInitialize( process, NULL, TRUE );
|
||||
|
||||
|
||||
|
||||
ZeroMemory( &stackframe, sizeof(STACKFRAME64) );
|
||||
ZeroMemory( &stackframe, sizeof( STACKFRAME64 ));
|
||||
|
||||
#ifdef _M_IX86
|
||||
image = IMAGE_FILE_MACHINE_I386;
|
||||
@@ -127,19 +126,25 @@ static void stack_trace( PEXCEPTION_POINTERS pInfo )
|
||||
stackframe.AddrBStore.Mode = AddrModeFlat;
|
||||
stackframe.AddrStack.Offset = context.IntSp;
|
||||
stackframe.AddrStack.Mode = AddrModeFlat;
|
||||
#elif
|
||||
#error
|
||||
#endif
|
||||
len += Q_snprintf( message + len, 1024 - len, "Sys_Crash: address %p, code %p\n", pInfo->ExceptionRecord->ExceptionAddress, (void*)pInfo->ExceptionRecord->ExceptionCode );
|
||||
len += Q_snprintf( message + len, 1024 - len, "Sys_Crash: address %p, code %p\n",
|
||||
pInfo->ExceptionRecord->ExceptionAddress, (void*)pInfo->ExceptionRecord->ExceptionCode );
|
||||
if( SymGetLineFromAddr64( process, (DWORD64)pInfo->ExceptionRecord->ExceptionAddress, &dline, &line ) )
|
||||
{
|
||||
len += Q_snprintf(message + len, 1024 - len,"Exception: %s:%d:%d\n", (char*)line.FileName, (int)line.LineNumber, (int)dline);
|
||||
len += Q_snprintf(message + len, 1024 - len, "Exception: %s:%d:%d\n",
|
||||
(char*)line.FileName, (int)line.LineNumber, (int)dline);
|
||||
}
|
||||
if( SymGetLineFromAddr64( process, stackframe.AddrPC.Offset, &dline, &line ) )
|
||||
{
|
||||
len += Q_snprintf(message + len, 1024 - len,"PC: %s:%d:%d\n", (char*)line.FileName, (int)line.LineNumber, (int)dline);
|
||||
len += Q_snprintf(message + len, 1024 - len,"PC: %s:%d:%d\n",
|
||||
(char*)line.FileName, (int)line.LineNumber, (int)dline);
|
||||
}
|
||||
if( SymGetLineFromAddr64( process, stackframe.AddrFrame.Offset, &dline, &line ) )
|
||||
{
|
||||
len += Q_snprintf(message + len, 1024 - len,"Frame: %s:%d:%d\n", (char*)line.FileName, (int)line.LineNumber, (int)dline);
|
||||
len += Q_snprintf(message + len, 1024 - len,"Frame: %s:%d:%d\n",
|
||||
(char*)line.FileName, (int)line.LineNumber, (int)dline);
|
||||
}
|
||||
for( i = 0; i < 25; i++ )
|
||||
{
|
||||
@@ -149,39 +154,43 @@ static void stack_trace( PEXCEPTION_POINTERS pInfo )
|
||||
image, process, thread,
|
||||
&stackframe, &context, NULL,
|
||||
SymFunctionTableAccess64, SymGetModuleBase64, NULL);
|
||||
|
||||
DWORD64 displacement = 0;
|
||||
|
||||
if( !result )
|
||||
break;
|
||||
|
||||
|
||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
symbol->MaxNameLen = MAX_SYM_NAME;
|
||||
|
||||
len += Q_snprintf( message + len, 1024 - len, "% 2d %p", i, (void*)stackframe.AddrPC.Offset );
|
||||
len += Q_snprintf( message + len, 1024 - len, "% 2d %p",
|
||||
i, (void*)stackframe.AddrPC.Offset );
|
||||
if( SymFromAddr( process, stackframe.AddrPC.Offset, &displacement, symbol ) )
|
||||
{
|
||||
len += Q_snprintf( message + len, 1024 - len, " %s ", symbol->Name );
|
||||
}
|
||||
if( SymGetLineFromAddr64( process, stackframe.AddrPC.Offset, &dline, &line ) )
|
||||
{
|
||||
len += Q_snprintf(message + len, 1024 - len,"(%s:%d:%d) ", (char*)line.FileName, (int)line.LineNumber, (int)dline);
|
||||
len += Q_snprintf(message + len, 1024 - len,"(%s:%d:%d) ",
|
||||
(char*)line.FileName, (int)line.LineNumber, (int)dline);
|
||||
}
|
||||
len += Q_snprintf( message + len, 1024 - len, "(");
|
||||
len += ModuleName( process, message + len, (void*)stackframe.AddrPC.Offset, 1024 - len );
|
||||
len += Sys_ModuleName( process, message + len, (void*)stackframe.AddrPC.Offset, 1024 - len );
|
||||
len += Q_snprintf( message + len, 1024 - len, ")\n");
|
||||
}
|
||||
#ifdef XASH_SDL
|
||||
if( host.type != HOST_DEDICATED ) // let system to restart server automaticly
|
||||
SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR,"Sys_Crash", message, host.hWnd );
|
||||
#endif
|
||||
Sys_PrintLog(message);
|
||||
|
||||
SymCleanup(process);
|
||||
#if XASH_SDL == 2
|
||||
if( host.type != HOST_DEDICATED ) // let system to restart server automaticly
|
||||
SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR, "Sys_Crash", message, host.hWnd );
|
||||
#endif
|
||||
|
||||
Sys_PrintLog( message );
|
||||
|
||||
SymCleanup( process );
|
||||
}
|
||||
#endif //DBGHELP
|
||||
#endif /* XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP */
|
||||
|
||||
LPTOP_LEVEL_EXCEPTION_FILTER oldFilter;
|
||||
long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
|
||||
static long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
|
||||
{
|
||||
// save config
|
||||
if( host.status != HOST_CRASHED )
|
||||
@@ -190,7 +199,7 @@ long _stdcall Sys_Crash( PEXCEPTION_POINTERS pInfo )
|
||||
host.crashed = true;
|
||||
|
||||
#if XASH_CRASHHANDLER == CRASHHANDLER_DBGHELP
|
||||
stack_trace( pInfo );
|
||||
Sys_StackTrace( pInfo );
|
||||
#else
|
||||
Sys_Warn( "Sys_Crash: call %p at address %p", pInfo->ExceptionRecord->ExceptionAddress, pInfo->ExceptionRecord->ExceptionCode );
|
||||
#endif
|
||||
@@ -233,13 +242,14 @@ void Sys_RestoreCrashHandler( void )
|
||||
|
||||
#include "library.h"
|
||||
|
||||
#if XASH_FREEBSD || XASH_NETBSD || XASH_ANDROID || XASH_LINUX
|
||||
#if XASH_FREEBSD || XASH_NETBSD || XASH_OPENBSD || XASH_ANDROID || XASH_LINUX
|
||||
#define HAVE_UCONTEXT_H 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UCONTEXT_H
|
||||
#include <ucontext.h>
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
@@ -261,7 +271,7 @@ static int d_dladdr( void *sym, Dl_info *info )
|
||||
#define dladdr d_dladdr
|
||||
#endif
|
||||
|
||||
int printframe( char *buf, int len, int i, void *addr )
|
||||
static int Sys_PrintFrame( char *buf, int len, int i, void *addr )
|
||||
{
|
||||
Dl_info dlinfo;
|
||||
if( len <= 0 )
|
||||
@@ -271,7 +281,7 @@ int 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
|
||||
(unsigned long)addr - (unsigned long)dlinfo.dli_saddr, dlinfo.dli_fname ); // print symbol, module and address
|
||||
else
|
||||
return Q_snprintf( buf, len, "%2d: %p (%s)\n", i, addr, dlinfo.dli_fname ); // print module and address
|
||||
}
|
||||
@@ -281,10 +291,11 @@ int printframe( char *buf, int len, int i, void *addr )
|
||||
|
||||
struct sigaction oldFilter;
|
||||
|
||||
#define STACK_BACKTRACE_STR_LEN 17
|
||||
#define STACK_BACKTRACE_STR "Stack backtrace:\n"
|
||||
#define STACK_DUMP_STR_LEN 12
|
||||
#define STACK_DUMP_STR "Stack dump:\n"
|
||||
#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)
|
||||
@@ -356,7 +367,7 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
|
||||
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 );
|
||||
#endif
|
||||
|
||||
write( 2, message, len );
|
||||
write( STDERR_FILENO, message, len );
|
||||
|
||||
// flush buffers before writing directly to descriptors
|
||||
fflush( stdout );
|
||||
@@ -370,9 +381,9 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
|
||||
{
|
||||
size_t pagesize = sysconf( _SC_PAGESIZE );
|
||||
// try to print backtrace
|
||||
write( 2, STACK_BACKTRACE_STR, STACK_BACKTRACE_STR_LEN );
|
||||
write( STDERR_FILENO, STACK_BACKTRACE_STR, STACK_BACKTRACE_STR_LEN );
|
||||
write( logfd, STACK_BACKTRACE_STR, STACK_BACKTRACE_STR_LEN );
|
||||
strncpy( message + len, STACK_BACKTRACE_STR, sizeof( message ) - len );
|
||||
Q_strncpy( message + len, STACK_BACKTRACE_STR, sizeof( message ) - len );
|
||||
len += STACK_BACKTRACE_STR_LEN;
|
||||
|
||||
// false on success, true on failure
|
||||
@@ -384,8 +395,8 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
|
||||
|
||||
do
|
||||
{
|
||||
int line = printframe( message + len, sizeof( message ) - len, ++i, pc);
|
||||
write( 2, message + len, line );
|
||||
int line = Sys_PrintFrame( message + len, sizeof( message ) - len, ++i, pc);
|
||||
write( STDERR_FILENO, message + len, line );
|
||||
write( logfd, message + len, line );
|
||||
len += line;
|
||||
//if( !dladdr(bp,0) ) break; // only when bp is in module
|
||||
@@ -399,17 +410,17 @@ static void Sys_Crash( int signal, siginfo_t *si, void *context)
|
||||
while( bp && i < 128 );
|
||||
|
||||
// try to print stack
|
||||
write( 2, STACK_DUMP_STR, STACK_DUMP_STR_LEN );
|
||||
write( STDERR_FILENO, STACK_DUMP_STR, STACK_DUMP_STR_LEN );
|
||||
write( logfd, STACK_DUMP_STR, STACK_DUMP_STR_LEN );
|
||||
strncpy( message + len, STACK_DUMP_STR, sizeof( message ) - len );
|
||||
Q_strncpy( message + len, STACK_DUMP_STR, sizeof( message ) - len );
|
||||
len += STACK_DUMP_STR_LEN;
|
||||
|
||||
if( !try_allow_read( sp, pagesize ) )
|
||||
{
|
||||
for( i = 0; i < 32; i++ )
|
||||
{
|
||||
int line = printframe( message + len, sizeof( message ) - len, i, sp[i] );
|
||||
write( 2, message + len, line );
|
||||
int line = Sys_PrintFrame( message + len, sizeof( message ) - len, i, sp[i] );
|
||||
write( STDERR_FILENO, message + len, line );
|
||||
write( logfd, message + len, line );
|
||||
len += line;
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@ GNU General Public License for more details.
|
||||
#include <math.h> // fabs...
|
||||
#include "common.h"
|
||||
#include "base_cmd.h"
|
||||
#include "eiface.h" // ARRAYSIZE
|
||||
|
||||
convar_t *cvar_vars = NULL; // head of list
|
||||
convar_t *cmd_scripting;
|
||||
|
||||
CVAR_DEFINE_AUTO( cl_filterstuffcmd, "1", FCVAR_ARCHIVE | FCVAR_PRIVILEGED, "filter commands coming from server" );
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_GetList
|
||||
@@ -71,7 +74,7 @@ build cvar auto description that based on the setup flags
|
||||
*/
|
||||
const char *Cvar_BuildAutoDescription( int flags )
|
||||
{
|
||||
static char desc[128];
|
||||
static char desc[256];
|
||||
|
||||
desc[0] = '\0';
|
||||
|
||||
@@ -91,6 +94,12 @@ const char *Cvar_BuildAutoDescription( int flags )
|
||||
if( FBitSet( flags, FCVAR_ARCHIVE ))
|
||||
Q_strncat( desc, "archived ", sizeof( desc ));
|
||||
|
||||
if( FBitSet( flags, FCVAR_PROTECTED ))
|
||||
Q_strncat( desc, "protected ", sizeof( desc ));
|
||||
|
||||
if( FBitSet( flags, FCVAR_PRIVILEGED ))
|
||||
Q_strncat( desc, "privileged ", sizeof( desc ));
|
||||
|
||||
Q_strncat( desc, "cvar", sizeof( desc ));
|
||||
|
||||
return desc;
|
||||
@@ -510,7 +519,7 @@ void Cvar_DirectSet( convar_t *var, const char *value )
|
||||
if( var != Cvar_FindVar( var->name ))
|
||||
return; // how this possible?
|
||||
|
||||
if( FBitSet( var->flags, FCVAR_READ_ONLY|FCVAR_GLCONFIG ))
|
||||
if( FBitSet( var->flags, FCVAR_READ_ONLY ))
|
||||
{
|
||||
Con_Printf( "%s is read-only.\n", var->name );
|
||||
return;
|
||||
@@ -754,6 +763,32 @@ static void Cvar_SetGL( const char *name, const char *value )
|
||||
Cvar_FullSet( name, value, FCVAR_GLCONFIG );
|
||||
}
|
||||
|
||||
static qboolean Cvar_ShouldSetCvar( convar_t *v, qboolean isPrivileged )
|
||||
{
|
||||
const char *prefixes[] = { "cl_", "gl_", "m_", "r_", "hud_" };
|
||||
int i;
|
||||
|
||||
if( isPrivileged )
|
||||
return true;
|
||||
|
||||
if( FBitSet( v->flags, FCVAR_PRIVILEGED ))
|
||||
return false;
|
||||
|
||||
if( cl_filterstuffcmd.value <= 0.0f )
|
||||
return true;
|
||||
|
||||
if( FBitSet( v->flags, FCVAR_FILTERABLE ))
|
||||
return false;
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( prefixes ); i++ )
|
||||
{
|
||||
if( !Q_strnicmp( v->name, prefixes[i], Q_strlen( prefixes[i] )))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_Command
|
||||
@@ -761,7 +796,7 @@ Cvar_Command
|
||||
Handles variable inspection and changing from the console
|
||||
============
|
||||
*/
|
||||
qboolean Cvar_Command( convar_t *v )
|
||||
qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged )
|
||||
{
|
||||
// special case for setup opengl configuration
|
||||
if( host.apply_opengl_config )
|
||||
@@ -773,7 +808,8 @@ qboolean Cvar_Command( convar_t *v )
|
||||
// check variables
|
||||
if( !v ) // already found in basecmd
|
||||
v = Cvar_FindVar( Cmd_Argv( 0 ));
|
||||
if( !v ) return false;
|
||||
if( !v )
|
||||
return false;
|
||||
|
||||
// perform a variable print or set
|
||||
if( Cmd_Argc() == 1 )
|
||||
@@ -796,6 +832,11 @@ qboolean Cvar_Command( convar_t *v )
|
||||
Con_Printf( "can't set \"%s\" in multiplayer\n", v->name );
|
||||
return false;
|
||||
}
|
||||
else if( !Cvar_ShouldSetCvar( v, isPrivileged ))
|
||||
{
|
||||
Con_Printf( "%s is a privileged variable\n", v->name );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Cvar_DirectSet( v, Cmd_Argv( 1 ));
|
||||
@@ -953,11 +994,59 @@ Reads in all archived cvars
|
||||
void Cvar_Init( void )
|
||||
{
|
||||
cvar_vars = NULL;
|
||||
cmd_scripting = Cvar_Get( "cmd_scripting", "0", FCVAR_ARCHIVE, "enable simple condition checking and variable operations" );
|
||||
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( &cl_filterstuffcmd );
|
||||
|
||||
Cmd_AddCommand( "setgl", Cvar_SetGL_f, "change the value of a opengl variable" ); // OBSOLETE
|
||||
Cmd_AddCommand( "toggle", Cvar_Toggle_f, "toggles a console variable's values (use for more info)" );
|
||||
Cmd_AddCommand( "reset", Cvar_Reset_f, "reset any type variable to initial value" );
|
||||
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( "cvarlist", Cvar_List_f, "display all console variables beginning with the specified prefix" );
|
||||
}
|
||||
|
||||
#if XASH_ENGINE_TESTS
|
||||
#include "tests.h"
|
||||
|
||||
void Test_RunCvar( void )
|
||||
{
|
||||
convar_t *test_privileged = Cvar_Get( "test_privileged", "0", FCVAR_PRIVILEGED, "bark bark" );
|
||||
convar_t *test_unprivileged = Cvar_Get( "test_unprivileged", "0", 0, "meow meow" );
|
||||
convar_t *hud_filtered = Cvar_Get( "hud_filtered", "0", 0, "dummy description" );
|
||||
convar_t *filtered2 = Cvar_Get( "filtered2", "0", FCVAR_FILTERABLE, "filtered2" );
|
||||
|
||||
Cbuf_AddText( "test_privileged 1; test_unprivileged 1; hud_filtered 1; filtered2 1\n" );
|
||||
Cbuf_Execute();
|
||||
TASSERT( test_privileged->value != 0.0f );
|
||||
TASSERT( test_unprivileged->value != 0.0f );
|
||||
TASSERT( hud_filtered->value != 0.0f );
|
||||
TASSERT( filtered2->value != 0.0f );
|
||||
|
||||
Cvar_DirectSet( test_privileged, "0" );
|
||||
Cvar_DirectSet( test_unprivileged, "0" );
|
||||
Cvar_DirectSet( hud_filtered, "0" );
|
||||
Cvar_DirectSet( filtered2, "0" );
|
||||
Cvar_DirectSet( &cl_filterstuffcmd, "0" );
|
||||
Cbuf_AddFilteredText( "test_privileged 1; test_unprivileged 1; hud_filtered 1; filtered2 1\n" );
|
||||
Cbuf_Execute();
|
||||
Cbuf_Execute();
|
||||
Cbuf_Execute();
|
||||
TASSERT( test_privileged->value == 0.0f );
|
||||
TASSERT( test_unprivileged->value != 0.0f );
|
||||
TASSERT( hud_filtered->value != 0.0f );
|
||||
TASSERT( filtered2->value != 0.0f );
|
||||
|
||||
Cvar_DirectSet( test_privileged, "0" );
|
||||
Cvar_DirectSet( test_unprivileged, "0" );
|
||||
Cvar_DirectSet( hud_filtered, "0" );
|
||||
Cvar_DirectSet( filtered2, "0" );
|
||||
Cvar_DirectSet( &cl_filterstuffcmd, "1" );
|
||||
Cbuf_AddFilteredText( "test_privileged 1; test_unprivileged 1; hud_filtered 1; filtered2 1\n" );
|
||||
Cbuf_Execute();
|
||||
Cbuf_Execute();
|
||||
Cbuf_Execute();
|
||||
TASSERT( test_privileged->value == 0.0f );
|
||||
TASSERT( test_unprivileged->value != 0.0f );
|
||||
TASSERT( hud_filtered->value == 0.0f );
|
||||
TASSERT( filtered2->value == 0.0f );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -47,7 +47,7 @@ typedef struct convar_s
|
||||
#define FCVAR_ALLOCATED (1<<19) // this convar_t is fully dynamic allocated (include description)
|
||||
#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_LOCALONLY (1<<22) // can be set only from local buffers
|
||||
#define FCVAR_MOVEVARS (1<<22) // this cvar is a part of movevars_t struct that shared between client and server
|
||||
|
||||
#define CVAR_DEFINE( cv, cvname, cvstr, cvflags, cvdesc ) \
|
||||
convar_t cv = { (char*)cvname, (char*)cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, (char*)cvdesc, NULL }
|
||||
@@ -75,7 +75,7 @@ void Cvar_WriteVariables( file_t *f, int group );
|
||||
qboolean Cvar_Exists( const char *var_name );
|
||||
void Cvar_Reset( const char *var_name );
|
||||
void Cvar_SetCheatState( void );
|
||||
qboolean Cvar_Command( convar_t *v );
|
||||
qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged );
|
||||
void Cvar_Init( void );
|
||||
void Cvar_Unlink( int group );
|
||||
|
||||
|
||||
@@ -306,11 +306,6 @@ void SCR_CheckStartupVids( void )
|
||||
|
||||
}
|
||||
|
||||
void Sys_SetClipboardData( const char *text, size_t size )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CL_StopPlayback( void )
|
||||
{
|
||||
|
||||
|
||||
@@ -406,7 +406,8 @@ static const char *FS_FixFileCase( const char *path )
|
||||
out[i] = 0;
|
||||
return out;
|
||||
#elif !XASH_WIN32 && !XASH_IOS // assume case insensitive
|
||||
DIR *dir; struct dirent *entry;
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
char path2[PATH_MAX], *fname;
|
||||
|
||||
if( !fs_caseinsensitive )
|
||||
@@ -600,11 +601,12 @@ of the list so they override previous pack files.
|
||||
*/
|
||||
pack_t *FS_LoadPackPAK( const char *packfile, int *error )
|
||||
{
|
||||
dpackheader_t header;
|
||||
int packhandle;
|
||||
int i, numpackfiles;
|
||||
pack_t *pack;
|
||||
dpackfile_t *info;
|
||||
dpackheader_t header;
|
||||
int packhandle;
|
||||
int i, numpackfiles;
|
||||
pack_t *pack;
|
||||
dpackfile_t *info;
|
||||
fs_size_t c;
|
||||
|
||||
packhandle = open( packfile, O_RDONLY|O_BINARY );
|
||||
|
||||
@@ -612,21 +614,21 @@ pack_t *FS_LoadPackPAK( const char *packfile, int *error )
|
||||
if( packhandle < 0 )
|
||||
{
|
||||
const char *fpackfile = FS_FixFileCase( packfile );
|
||||
if( fpackfile!= packfile )
|
||||
if( fpackfile != packfile )
|
||||
packhandle = open( fpackfile, O_RDONLY|O_BINARY );
|
||||
}
|
||||
#endif
|
||||
|
||||
if( packhandle < 0 )
|
||||
{
|
||||
Con_Reportf( "%s couldn't open\n", packfile );
|
||||
Con_Reportf( "%s couldn't open: %s\n", packfile, strerror( errno ));
|
||||
if( error ) *error = PAK_LOAD_COULDNT_OPEN;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
read( packhandle, (void *)&header, sizeof( header ));
|
||||
c = read( packhandle, (void *)&header, sizeof( header ));
|
||||
|
||||
if( header.ident != IDPACKV1HEADER )
|
||||
if( c != sizeof( header ) || header.ident != IDPACKV1HEADER )
|
||||
{
|
||||
Con_Reportf( "%s is not a packfile. Ignored.\n", packfile );
|
||||
if( error ) *error = PAK_LOAD_BAD_HEADER;
|
||||
@@ -685,7 +687,7 @@ pack_t *FS_LoadPackPAK( const char *packfile, int *error )
|
||||
|
||||
#ifdef XASH_REDUCE_FD
|
||||
// will reopen when needed
|
||||
close(pack->handle);
|
||||
close( pack->handle );
|
||||
pack->handle = -1;
|
||||
#endif
|
||||
|
||||
@@ -715,11 +717,12 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
|
||||
int numpackfiles = 0, i;
|
||||
zip_cdf_header_t header_cdf;
|
||||
zip_header_eocd_t header_eocd;
|
||||
uint signature;
|
||||
uint32_t signature;
|
||||
fs_offset_t filepos = 0, length;
|
||||
zipfile_t *info = NULL;
|
||||
char filename_buffer[MAX_SYSPATH];
|
||||
zip_t *zip = (zip_t *)Mem_Calloc( fs_mempool, sizeof( zip_t ) );
|
||||
zip_t *zip = (zip_t *)Mem_Calloc( fs_mempool, sizeof( *zip ));
|
||||
fs_size_t c;
|
||||
|
||||
zip->handle = open( zipfile, O_RDONLY|O_BINARY );
|
||||
|
||||
@@ -758,9 +761,9 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
|
||||
|
||||
lseek( zip->handle, 0, SEEK_SET );
|
||||
|
||||
read( zip->handle, &signature, sizeof( signature ) );
|
||||
c = read( zip->handle, &signature, sizeof( signature ) );
|
||||
|
||||
if( signature == ZIP_HEADER_EOCD )
|
||||
if( c != sizeof( signature ) || signature == ZIP_HEADER_EOCD )
|
||||
{
|
||||
Con_Reportf( S_WARN "%s has no files. Ignored.\n", zipfile );
|
||||
|
||||
@@ -789,9 +792,9 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
|
||||
while ( filepos > 0 )
|
||||
{
|
||||
lseek( zip->handle, filepos, SEEK_SET );
|
||||
read( zip->handle, &signature, sizeof( signature ) );
|
||||
c = read( zip->handle, &signature, sizeof( signature ) );
|
||||
|
||||
if( signature == ZIP_HEADER_EOCD )
|
||||
if( c == sizeof( signature ) && signature == ZIP_HEADER_EOCD )
|
||||
break;
|
||||
|
||||
filepos -= sizeof( char ); // step back one byte
|
||||
@@ -808,19 +811,30 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
read( zip->handle, &header_eocd, sizeof( zip_header_eocd_t ) );
|
||||
c = read( zip->handle, &header_eocd, sizeof( header_eocd ) );
|
||||
|
||||
if( c != sizeof( header_eocd ))
|
||||
{
|
||||
Con_Reportf( S_ERROR "invalid EOCD header in %s. Zip file corrupted.\n", zipfile );
|
||||
|
||||
if( error )
|
||||
*error = ZIP_LOAD_BAD_HEADER;
|
||||
|
||||
Zip_Close( zip );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Move to CDF start
|
||||
lseek( zip->handle, header_eocd.central_directory_offset, SEEK_SET );
|
||||
|
||||
// Calc count of files in archive
|
||||
info = (zipfile_t *)Mem_Calloc( fs_mempool, sizeof( zipfile_t ) * header_eocd.total_central_directory_record );
|
||||
info = (zipfile_t *)Mem_Calloc( fs_mempool, sizeof( *info ) * header_eocd.total_central_directory_record );
|
||||
|
||||
for( i = 0; i < header_eocd.total_central_directory_record; i++ )
|
||||
{
|
||||
read( zip->handle, &header_cdf, sizeof( header_cdf ) );
|
||||
c = read( zip->handle, &header_cdf, sizeof( header_cdf ) );
|
||||
|
||||
if( header_cdf.signature != ZIP_HEADER_CDF )
|
||||
if( c != sizeof( header_cdf ) || header_cdf.signature != ZIP_HEADER_CDF )
|
||||
{
|
||||
Con_Reportf( S_ERROR "CDF signature mismatch in %s. Zip file corrupted.\n", zipfile );
|
||||
|
||||
@@ -835,7 +849,20 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
|
||||
if( header_cdf.uncompressed_size && header_cdf.filename_len && ( header_cdf.filename_len < MAX_SYSPATH ) )
|
||||
{
|
||||
memset( &filename_buffer, '\0', MAX_SYSPATH );
|
||||
read( zip->handle, &filename_buffer, header_cdf.filename_len );
|
||||
c = read( zip->handle, &filename_buffer, header_cdf.filename_len );
|
||||
|
||||
if( c != header_cdf.filename_len )
|
||||
{
|
||||
Con_Reportf( S_ERROR "filename length mismatch in %s. Zip file corrupted.\n", zipfile );
|
||||
|
||||
if( error )
|
||||
*error = ZIP_LOAD_CORRUPTED;
|
||||
|
||||
Mem_Free( info );
|
||||
Zip_Close( zip );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Q_strncpy( info[numpackfiles].name, filename_buffer, MAX_SYSPATH );
|
||||
|
||||
info[numpackfiles].size = header_cdf.uncompressed_size;
|
||||
@@ -859,7 +886,20 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
|
||||
zip_header_t header;
|
||||
|
||||
lseek( zip->handle, info[i].offset, SEEK_SET );
|
||||
read( zip->handle, &header, sizeof( header ) );
|
||||
c = read( zip->handle, &header, sizeof( header ) );
|
||||
|
||||
if( c != sizeof( header ))
|
||||
{
|
||||
Con_Reportf( S_ERROR "header length mismatch in %s. Zip file corrupted.\n", zipfile );
|
||||
|
||||
if( error )
|
||||
*error = ZIP_LOAD_CORRUPTED;
|
||||
|
||||
Mem_Free( info );
|
||||
Zip_Close( zip );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info[i].flags = header.compression_flags;
|
||||
info[i].offset = info[i].offset + header.filename_len + header.extrafield_len + sizeof( header );
|
||||
}
|
||||
@@ -869,7 +909,7 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
|
||||
zip->numfiles = numpackfiles;
|
||||
zip->files = info;
|
||||
|
||||
qsort( zip->files, zip->numfiles, sizeof( zipfile_t ), FS_SortZip );
|
||||
qsort( zip->files, zip->numfiles, sizeof( *zip->files ), FS_SortZip );
|
||||
|
||||
#ifdef XASH_REDUCE_FD
|
||||
// will reopen when needed
|
||||
@@ -888,7 +928,8 @@ void Zip_Close( zip_t *zip )
|
||||
if( !zip )
|
||||
return;
|
||||
|
||||
Mem_Free( zip->files );
|
||||
if( zip->files )
|
||||
Mem_Free( zip->files );
|
||||
|
||||
FS_EnsureOpenZip( NULL );
|
||||
|
||||
@@ -907,6 +948,7 @@ static byte *Zip_LoadFile( const char *path, fs_offset_t *sizeptr, qboolean game
|
||||
int zlib_result = 0;
|
||||
dword test_crc, final_crc;
|
||||
z_stream decompress_stream;
|
||||
size_t c;
|
||||
|
||||
if( sizeptr ) *sizeptr = 0;
|
||||
|
||||
@@ -936,7 +978,13 @@ static byte *Zip_LoadFile( const char *path, fs_offset_t *sizeptr, qboolean game
|
||||
decompressed_buffer = Mem_Malloc( fs_mempool, file->size + 1 );
|
||||
decompressed_buffer[file->size] = '\0';
|
||||
|
||||
read( search->zip->handle, decompressed_buffer, file->size );
|
||||
c = read( search->zip->handle, decompressed_buffer, file->size );
|
||||
if( c != file->size )
|
||||
{
|
||||
Con_Reportf( S_ERROR "Zip_LoadFile: %s size doesn't match\n", file->name );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
CRC32_Init( &test_crc );
|
||||
CRC32_ProcessBuffer( &test_crc, decompressed_buffer, file->size );
|
||||
@@ -961,7 +1009,12 @@ static byte *Zip_LoadFile( const char *path, fs_offset_t *sizeptr, qboolean game
|
||||
decompressed_buffer = Mem_Malloc( fs_mempool, file->size + 1 );
|
||||
decompressed_buffer[file->size] = '\0';
|
||||
|
||||
read( search->zip->handle, compressed_buffer, file->compressed_size );
|
||||
c = read( search->zip->handle, compressed_buffer, file->compressed_size );
|
||||
if( c != file->compressed_size )
|
||||
{
|
||||
Con_Reportf( S_ERROR "Zip_LoadFile: %s compressed size doesn't match\n", file->name );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset( &decompress_stream, 0, sizeof( decompress_stream ) );
|
||||
|
||||
@@ -1139,7 +1192,7 @@ static qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loade
|
||||
}
|
||||
}
|
||||
|
||||
qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int flags )
|
||||
static qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int flags )
|
||||
{
|
||||
searchpath_t *search;
|
||||
zip_t *zip = NULL;
|
||||
@@ -1192,6 +1245,24 @@ qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
FS_AddArchive_Fullpath
|
||||
================
|
||||
*/
|
||||
static qboolean FS_AddArchive_Fullpath( const char *file, qboolean *already_loaded, int flags )
|
||||
{
|
||||
const char *ext = COM_FileExtension( file );
|
||||
|
||||
if( !Q_stricmp( ext, "pk3" ) )
|
||||
return FS_AddZip_Fullpath( file, already_loaded, flags );
|
||||
else if ( !Q_stricmp( ext, "pak" ))
|
||||
return FS_AddPak_Fullpath( file, already_loaded, flags );
|
||||
|
||||
// skip wads, this function only meant to be used for extras
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
FS_AddGameDirectory
|
||||
@@ -1226,7 +1297,7 @@ void FS_AddGameDirectory( const char *dir, uint flags )
|
||||
// add any Zip package in the directory
|
||||
for( i = 0; i < list.numstrings; i++ )
|
||||
{
|
||||
if( !Q_stricmp( COM_FileExtension( list.strings[i] ), "zip" ) || !Q_stricmp( COM_FileExtension( list.strings[i] ), "pk3" ))
|
||||
if( !Q_stricmp( COM_FileExtension( list.strings[i] ), "pk3" ) )
|
||||
{
|
||||
Q_sprintf( fullpath, "%s%s", dir, list.strings[i] );
|
||||
FS_AddZip_Fullpath( fullpath, NULL, flags );
|
||||
@@ -1417,11 +1488,12 @@ void FS_Rescan( void )
|
||||
}
|
||||
#else
|
||||
str = getenv( "XASH3D_EXTRAS_PAK1" );
|
||||
if( COM_CheckString( str ) )
|
||||
FS_AddPak_Fullpath( str, NULL, extrasFlags );
|
||||
if( COM_CheckString( str ))
|
||||
FS_AddArchive_Fullpath( str, NULL, extrasFlags );
|
||||
|
||||
str = getenv( "XASH3D_EXTRAS_PAK2" );
|
||||
if( COM_CheckString( str ) )
|
||||
FS_AddPak_Fullpath( str, NULL, extrasFlags );
|
||||
if( COM_CheckString( str ))
|
||||
FS_AddArchive_Fullpath( str, NULL, extrasFlags );
|
||||
#endif
|
||||
|
||||
if( Q_stricmp( GI->basedir, GI->gamefolder ))
|
||||
@@ -1791,6 +1863,11 @@ void FS_ParseGenericGameInfo( gameinfo_t *GameInfo, const char *buf, const qbool
|
||||
pfile = COM_ParseFile( pfile, token, sizeof( token ));
|
||||
GameInfo->noskills = Q_atoi( token );
|
||||
}
|
||||
else if( !Q_stricmp( token, "render_picbutton_text" ))
|
||||
{
|
||||
pfile = COM_ParseFile( pfile, token, sizeof( token ));
|
||||
GameInfo->render_picbutton_text = Q_atoi( token );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2061,9 +2138,9 @@ void FS_Init( void )
|
||||
|
||||
FS_InitMemory();
|
||||
|
||||
Cmd_AddCommand( "fs_rescan", FS_Rescan_f, "rescan filesystem search pathes" );
|
||||
Cmd_AddCommand( "fs_path", FS_Path_f, "show filesystem search pathes" );
|
||||
Cmd_AddCommand( "fs_clearpaths", FS_ClearPaths_f, "clear filesystem search pathes" );
|
||||
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" ) )
|
||||
@@ -2114,9 +2191,15 @@ void FS_Init( void )
|
||||
|
||||
for( i = 0; i < dirs.numstrings; i++ )
|
||||
{
|
||||
// no need to check folders here, FS_CreatePath will not fail if path exists
|
||||
// and listdirectory returns only really existing directories
|
||||
FS_CreatePath( va( "%s" PATH_SPLITTER "%s/", host.rootdir, dirs.strings[i] ));
|
||||
char *roPath = va( "%s" PATH_SPLITTER "%s" PATH_SPLITTER, host.rodir, dirs.strings[i] );
|
||||
char *rwPath = va( "%s" PATH_SPLITTER "%s" PATH_SPLITTER, host.rootdir, dirs.strings[i] );
|
||||
|
||||
// check if it's a directory
|
||||
if( !FS_SysFolderExists( roPath ))
|
||||
continue;
|
||||
|
||||
// no need to check folders here, FS_CreatePath will not fail
|
||||
FS_CreatePath( rwPath );
|
||||
}
|
||||
|
||||
stringlistfreecontents( &dirs );
|
||||
@@ -2394,7 +2477,7 @@ qboolean FS_SysFileExists( const char *path, qboolean caseinsensitive )
|
||||
|
||||
close( desc );
|
||||
return true;
|
||||
#else
|
||||
#elif XASH_POSIX
|
||||
int ret;
|
||||
struct stat buf;
|
||||
|
||||
@@ -2412,6 +2495,8 @@ qboolean FS_SysFileExists( const char *path, qboolean caseinsensitive )
|
||||
return false;
|
||||
|
||||
return S_ISREG( buf.st_mode );
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -2446,23 +2531,18 @@ qboolean FS_SysFolderExists( const char *path )
|
||||
DWORD dwFlags = GetFileAttributes( path );
|
||||
|
||||
return ( dwFlags != -1 ) && ( dwFlags & FILE_ATTRIBUTE_DIRECTORY );
|
||||
#else
|
||||
DIR *dir = opendir( path );
|
||||
#elif XASH_POSIX
|
||||
struct stat buf;
|
||||
|
||||
if( dir )
|
||||
{
|
||||
closedir( dir );
|
||||
return true;
|
||||
}
|
||||
else if( (errno == ENOENT) || (errno == ENOTDIR) )
|
||||
if( stat( path, &buf ) < 0 )
|
||||
{
|
||||
Con_Reportf( S_ERROR "FS_SysFolderExists: problem while opening dir: %s\n", strerror( errno ));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Reportf( S_ERROR "FS_SysFolderExists: problem while opening dir: %s\n", strerror( errno ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return S_ISDIR( buf.st_mode );
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -3575,6 +3655,7 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
|
||||
searchpath_t *searchpath;
|
||||
pack_t *pak;
|
||||
wfile_t *wad;
|
||||
zip_t *zip;
|
||||
int i, basepathlength, numfiles, numchars;
|
||||
int resultlistindex, dirlistindex;
|
||||
const char *slash, *backslash, *colon, *separator;
|
||||
@@ -3591,8 +3672,8 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
|
||||
slash = Q_strrchr( pattern, '/' );
|
||||
backslash = Q_strrchr( pattern, '\\' );
|
||||
colon = Q_strrchr( pattern, ':' );
|
||||
separator = max( slash, backslash );
|
||||
separator = max( separator, colon );
|
||||
separator = Q_max( slash, backslash );
|
||||
separator = Q_max( separator, colon );
|
||||
basepathlength = separator ? (separator + 1 - pattern) : 0;
|
||||
basepath = Mem_Calloc( fs_mempool, basepathlength + 1 );
|
||||
if( basepathlength ) memcpy( basepath, pattern, basepathlength );
|
||||
@@ -3642,6 +3723,42 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( searchpath->zip )
|
||||
{
|
||||
zip = searchpath->zip;
|
||||
for( i = 0; i < zip->numfiles; i++ )
|
||||
{
|
||||
Q_strncpy( temp, zip->files[i].name, sizeof(temp) );
|
||||
while( temp[0] )
|
||||
{
|
||||
if( matchpattern( temp, (char *)pattern, true ))
|
||||
{
|
||||
for( resultlistindex = 0; resultlistindex < resultlist.numstrings; resultlistindex++ )
|
||||
{
|
||||
if( !Q_strcmp( resultlist.strings[resultlistindex], temp ))
|
||||
break;
|
||||
}
|
||||
|
||||
if( resultlistindex == resultlist.numstrings )
|
||||
stringlistappend( &resultlist, temp );
|
||||
}
|
||||
|
||||
// strip off one path element at a time until empty
|
||||
// this way directories are added to the listing if they match the pattern
|
||||
slash = Q_strrchr( temp, '/' );
|
||||
backslash = Q_strrchr( temp, '\\' );
|
||||
colon = Q_strrchr( temp, ':' );
|
||||
separator = temp;
|
||||
if( separator < slash )
|
||||
separator = slash;
|
||||
if( separator < backslash )
|
||||
separator = backslash;
|
||||
if( separator < colon )
|
||||
separator = colon;
|
||||
*((char *)separator) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( searchpath->wad )
|
||||
{
|
||||
string wadpattern, wadname, temp2;
|
||||
|
||||
@@ -15,6 +15,7 @@ GNU General Public License for more details.
|
||||
|
||||
#include "common.h"
|
||||
#include "xash3d_mathlib.h"
|
||||
#include "enginefeatures.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Gamma conversion support
|
||||
@@ -78,10 +79,16 @@ void BuildGammaTable( float lightgamma, float brightness )
|
||||
|
||||
byte LightToTexGamma( byte b )
|
||||
{
|
||||
return lightgammatable[b];
|
||||
if( FBitSet( host.features, ENGINE_LINEAR_GAMMA_SPACE ))
|
||||
return b;
|
||||
else
|
||||
return lightgammatable[b];
|
||||
}
|
||||
|
||||
byte TextureToGamma( byte b )
|
||||
{
|
||||
return texgammatable[b];
|
||||
if( FBitSet( host.features, ENGINE_LINEAR_GAMMA_SPACE ))
|
||||
return b;
|
||||
else
|
||||
return texgammatable[b];
|
||||
}
|
||||
|
||||
@@ -50,7 +50,8 @@ sysinfo_t SI;
|
||||
struct tests_stats_s tests_stats;
|
||||
#endif
|
||||
|
||||
CVAR_DEFINE( host_developer, "developer", "0", 0, "engine is in development-mode" );
|
||||
CVAR_DEFINE( host_developer, "developer", "0", FCVAR_FILTERABLE, "engine is in development-mode" );
|
||||
CVAR_DEFINE_AUTO( sys_timescale, "1.0", FCVAR_CHEAT|FCVAR_FILTERABLE, "scale frame time" );
|
||||
CVAR_DEFINE_AUTO( sys_ticrate, "100", 0, "framerate in dedicated mode" );
|
||||
|
||||
convar_t *host_serverstate;
|
||||
@@ -85,9 +86,11 @@ void Sys_PrintUsage( void )
|
||||
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
|
||||
@@ -98,53 +101,53 @@ void Sys_PrintUsage( void )
|
||||
O("-height <n> ","set window height")
|
||||
O("-oldfont ","enable unused Quake font in Half-Life")
|
||||
|
||||
#if !XASH_MOBILE_PLATFORM
|
||||
#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
|
||||
#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_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_WIN32
|
||||
O("-noavi ","disable AVI support")
|
||||
O("-nointro ","disable intro video")
|
||||
#endif // XASH_WIN32
|
||||
|
||||
#if XASH_DOS
|
||||
#if XASH_DOS
|
||||
O("-novesa ","disable vesa")
|
||||
#endif // XASH_DOS
|
||||
#endif // XASH_DOS
|
||||
|
||||
#if XASH_VIDEO == VIDEO_FBDEV
|
||||
#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
|
||||
#endif // XASH_VIDEO == VIDEO_FBDEV
|
||||
|
||||
#if XASH_SOUND == SOUND_ALSA
|
||||
#if XASH_SOUND == SOUND_ALSA
|
||||
O("-alsadev <dev> ","open selected ALSA device")
|
||||
#endif // XASH_SOUND == SOUND_ALSA
|
||||
#endif // XASH_SOUND == SOUND_ALSA
|
||||
|
||||
O("-nojoy ","disable joystick support")
|
||||
#ifdef XASH_SDL
|
||||
|
||||
#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
|
||||
#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")
|
||||
|
||||
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")
|
||||
#ifndef XASH_DEDICATED
|
||||
#if !XASH_DEDICATED
|
||||
O("-clientlib <path>","override client DLL path")
|
||||
#endif
|
||||
O("-rodir <path> ","set read-only base directory, experimental")
|
||||
@@ -353,10 +356,11 @@ Host_Exec_f
|
||||
*/
|
||||
void Host_Exec_f( void )
|
||||
{
|
||||
string cfgpath;
|
||||
string cfgpath;
|
||||
byte *f;
|
||||
char *txt;
|
||||
fs_offset_t len;
|
||||
const char *arg;
|
||||
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
@@ -364,14 +368,47 @@ void Host_Exec_f( void )
|
||||
return;
|
||||
}
|
||||
|
||||
if( !Q_stricmp( "game.cfg", Cmd_Argv( 1 )))
|
||||
arg = Cmd_Argv( 1 );
|
||||
|
||||
#ifndef XASH_DEDICATED
|
||||
if( !Cmd_CurrentCommandIsPrivileged() )
|
||||
{
|
||||
const char *unprivilegedWhitelist[] =
|
||||
{
|
||||
NULL, "mapdefault.cfg", "scout.cfg", "sniper.cfg",
|
||||
"soldier.cfg", "demoman.cfg", "medic.cfg", "hwguy.cfg",
|
||||
"pyro.cfg", "spy.cfg", "engineer.cfg", "civilian.cfg"
|
||||
};
|
||||
int i;
|
||||
qboolean allow = false;
|
||||
|
||||
unprivilegedWhitelist[0] = va( "%s.cfg", clgame.mapname );
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( unprivilegedWhitelist ); i++ )
|
||||
{
|
||||
if( !Q_strcmp( arg, unprivilegedWhitelist[i] ))
|
||||
{
|
||||
allow = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !allow )
|
||||
{
|
||||
Con_Printf( "exec %s: not privileged or in whitelist\n", arg );
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif // XASH_DEDICATED
|
||||
|
||||
if( !Q_stricmp( "game.cfg", arg ))
|
||||
{
|
||||
// don't execute game.cfg in singleplayer
|
||||
if( SV_GetMaxClients() == 1 )
|
||||
return;
|
||||
}
|
||||
|
||||
Q_strncpy( cfgpath, Cmd_Argv( 1 ), sizeof( cfgpath ));
|
||||
Q_strncpy( cfgpath, arg, sizeof( cfgpath ));
|
||||
COM_DefaultExtension( cfgpath, ".cfg" ); // append as default
|
||||
|
||||
f = FS_LoadFile( cfgpath, &len, false );
|
||||
@@ -381,7 +418,7 @@ void Host_Exec_f( void )
|
||||
return;
|
||||
}
|
||||
|
||||
if( !Q_stricmp( "config.cfg", Cmd_Argv( 1 )))
|
||||
if( !Q_stricmp( "config.cfg", arg ))
|
||||
host.config_executed = true;
|
||||
|
||||
// adds \n\0 at end of the file
|
||||
@@ -391,7 +428,7 @@ void Host_Exec_f( void )
|
||||
Mem_Free( f );
|
||||
|
||||
if( !host.apply_game_config )
|
||||
Con_Printf( "execing %s\n", Cmd_Argv( 1 ));
|
||||
Con_Printf( "execing %s\n", arg );
|
||||
Cbuf_InsertText( txt );
|
||||
Mem_Free( txt );
|
||||
}
|
||||
@@ -592,8 +629,9 @@ qboolean Host_FilterTime( float time )
|
||||
{
|
||||
static double oldtime;
|
||||
double fps;
|
||||
double scale = sys_timescale.value;
|
||||
|
||||
host.realtime += time;
|
||||
host.realtime += time * scale;
|
||||
fps = Host_CalcFPS( );
|
||||
|
||||
// clamp the fps in multiplayer games
|
||||
@@ -604,12 +642,12 @@ qboolean Host_FilterTime( float time )
|
||||
|
||||
if( Host_IsDedicated() )
|
||||
{
|
||||
if(( host.realtime - oldtime ) < ( 1.0 / ( fps + 1.0 )))
|
||||
if(( host.realtime - oldtime ) < ( 1.0 / ( fps + 1.0 )) * scale)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(( host.realtime - oldtime ) < ( 1.0 / fps ))
|
||||
if(( host.realtime - oldtime ) < ( 1.0 / fps ) * scale )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -620,7 +658,7 @@ qboolean Host_FilterTime( float time )
|
||||
|
||||
// NOTE: allow only in singleplayer while demos are not active
|
||||
if( host_framerate->value > 0.0f && Host_IsLocalGame() && !CL_IsPlaybackDemo() && !CL_IsRecordDemo( ))
|
||||
host.frametime = bound( MIN_FRAMETIME, host_framerate->value, MAX_FRAMETIME );
|
||||
host.frametime = bound( MIN_FRAMETIME, host_framerate->value * scale, MAX_FRAMETIME );
|
||||
else host.frametime = bound( MIN_FRAMETIME, host.frametime, MAX_FRAMETIME );
|
||||
|
||||
return true;
|
||||
@@ -683,7 +721,6 @@ void GAME_EXPORT Host_Error( const char *error, ... )
|
||||
else if( host.framecount == host.errorframe )
|
||||
{
|
||||
Sys_Error( "Host_MultiError: %s", hosterror2 );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -703,7 +740,6 @@ void GAME_EXPORT Host_Error( const char *error, ... )
|
||||
{
|
||||
Con_Printf( "Host_RecursiveError: %s", hosterror2 );
|
||||
Sys_Error( "%s", hosterror1 );
|
||||
return; // don't multiple executes
|
||||
}
|
||||
|
||||
recursive = true;
|
||||
@@ -784,9 +820,17 @@ static void Host_RunTests( int stage )
|
||||
memset( &tests_stats, 0, sizeof( tests_stats ));
|
||||
Test_RunLibCommon();
|
||||
Test_RunCommon();
|
||||
Test_RunCmd();
|
||||
Test_RunCvar();
|
||||
#if !XASH_DEDICATED
|
||||
Test_RunCon();
|
||||
#endif /* XASH_DEDICATED */
|
||||
break;
|
||||
case 1: // after FS load
|
||||
Test_RunImagelib();
|
||||
#if !XASH_DEDICATED
|
||||
Test_RunVOX();
|
||||
#endif
|
||||
Msg( "Done! %d passed, %d failed\n", tests_stats.passed, tests_stats.failed );
|
||||
Sys_Quit();
|
||||
}
|
||||
@@ -962,7 +1006,7 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha
|
||||
|
||||
len = Q_strlen( host.rootdir );
|
||||
|
||||
if( host.rootdir[len - 1] == '/' )
|
||||
if( len && host.rootdir[len - 1] == '/' )
|
||||
host.rootdir[len - 1] = 0;
|
||||
|
||||
// get readonly root. The order is: check for arg, then env.
|
||||
@@ -990,7 +1034,7 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha
|
||||
|
||||
Cmd_AddCommand( "exec", Host_Exec_f, "execute a script file" );
|
||||
Cmd_AddCommand( "memlist", Host_MemStats_f, "prints memory pool information" );
|
||||
Cmd_AddCommand( "userconfigd", Host_Userconfigd_f, "execute all scripts from userconfig.d" );
|
||||
Cmd_AddRestrictedCommand( "userconfigd", Host_Userconfigd_f, "execute all scripts from userconfig.d" );
|
||||
|
||||
FS_Init();
|
||||
Image_Init();
|
||||
@@ -1046,23 +1090,25 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
// init commands and vars
|
||||
if( host_developer.value >= DEV_EXTENDED )
|
||||
{
|
||||
Cmd_AddCommand ( "sys_error", Sys_Error_f, "just throw a fatal error to test shutdown procedures");
|
||||
Cmd_AddCommand ( "host_error", Host_Error_f, "just throw a host error to test shutdown procedures");
|
||||
Cmd_AddCommand ( "crash", Host_Crash_f, "a way to force a bus error for development reasons");
|
||||
Cmd_AddRestrictedCommand ( "sys_error", Sys_Error_f, "just throw a fatal error to test shutdown procedures");
|
||||
Cmd_AddRestrictedCommand ( "host_error", Host_Error_f, "just throw a host error to test shutdown procedures");
|
||||
Cmd_AddRestrictedCommand ( "crash", Host_Crash_f, "a way to force a bus error for development reasons");
|
||||
}
|
||||
|
||||
host_serverstate = Cvar_Get( "host_serverstate", "0", FCVAR_READ_ONLY, "displays current server state" );
|
||||
host_maxfps = Cvar_Get( "fps_max", "72", FCVAR_ARCHIVE, "host fps upper limit" );
|
||||
host_framerate = Cvar_Get( "host_framerate", "0", 0, "locks frame timing to this value in seconds" );
|
||||
host_sleeptime = Cvar_Get( "sleeptime", "1", FCVAR_ARCHIVE, "milliseconds to sleep for each frame. higher values reduce fps accuracy" );
|
||||
host_maxfps = Cvar_Get( "fps_max", "72", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "host fps upper limit" );
|
||||
host_framerate = Cvar_Get( "host_framerate", "0", FCVAR_FILTERABLE, "locks frame timing to this value in seconds" );
|
||||
host_sleeptime = Cvar_Get( "sleeptime", "1", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "milliseconds to sleep for each frame. higher values reduce fps accuracy" );
|
||||
host_gameloaded = Cvar_Get( "host_gameloaded", "0", FCVAR_READ_ONLY, "inidcates a loaded game.dll" );
|
||||
host_clientloaded = Cvar_Get( "host_clientloaded", "0", FCVAR_READ_ONLY, "inidcates a loaded client.dll" );
|
||||
host_limitlocal = Cvar_Get( "host_limitlocal", "0", 0, "apply cl_cmdrate and rate to loopback connection" );
|
||||
con_gamemaps = Cvar_Get( "con_mapfilter", "1", FCVAR_ARCHIVE, "when true show only maps in game folder" );
|
||||
Cvar_RegisterVariable( &sys_timescale );
|
||||
|
||||
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();
|
||||
@@ -1072,7 +1118,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
// allow to change game from the console
|
||||
if( pChangeGame != NULL )
|
||||
{
|
||||
Cmd_AddCommand( "game", Host_ChangeGame_f, "change game" );
|
||||
Cmd_AddRestrictedCommand( "game", Host_ChangeGame_f, "change game" );
|
||||
Cvar_Get( "host_allow_changegame", "1", FCVAR_READ_ONLY, "allows to change games" );
|
||||
}
|
||||
else
|
||||
@@ -1092,10 +1138,10 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
Wcon_InitConsoleCommands ();
|
||||
#endif
|
||||
|
||||
Cmd_AddCommand( "quit", Sys_Quit, "quit the game" );
|
||||
Cmd_AddCommand( "exit", Sys_Quit, "quit the game" );
|
||||
Cmd_AddRestrictedCommand( "quit", Sys_Quit, "quit the game" );
|
||||
Cmd_AddRestrictedCommand( "exit", Sys_Quit, "quit the game" );
|
||||
}
|
||||
else Cmd_AddCommand( "minimize", Host_Minimize_f, "minimize main window to tray" );
|
||||
else Cmd_AddRestrictedCommand( "minimize", Host_Minimize_f, "minimize main window to tray" );
|
||||
|
||||
host.errorframe = 0;
|
||||
|
||||
@@ -1151,6 +1197,8 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DLL_PrintLeaks( void );
|
||||
|
||||
/*
|
||||
=================
|
||||
Host_Shutdown
|
||||
@@ -1179,6 +1227,8 @@ void EXPORT Host_Shutdown( void )
|
||||
Host_FreeCommon();
|
||||
Platform_Shutdown();
|
||||
|
||||
DLL_PrintLeaks();
|
||||
|
||||
// must be last, console uses this
|
||||
Mem_FreePool( &host.mempool );
|
||||
|
||||
|
||||
@@ -1077,10 +1077,10 @@ void HPAK_Validate_f( void )
|
||||
|
||||
void HPAK_Init( void )
|
||||
{
|
||||
Cmd_AddCommand( "hpklist", HPAK_List_f, "list all files in specified HPK-file" );
|
||||
Cmd_AddCommand( "hpkremove", HPAK_Remove_f, "remove specified file from HPK-file" );
|
||||
Cmd_AddCommand( "hpkval", HPAK_Validate_f, "validate specified HPK-file" );
|
||||
Cmd_AddCommand( "hpkextract", HPAK_Extract_f, "extract all lumps from specified HPK-file" );
|
||||
Cmd_AddRestrictedCommand( "hpklist", HPAK_List_f, "list all files in specified HPK-file" );
|
||||
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" );
|
||||
hpk_maxsize = Cvar_Get( "hpk_maxsize", "0", FCVAR_ARCHIVE, "set limit by size for all HPK-files ( 0 - unlimited )" );
|
||||
|
||||
gp_hpak_queue = NULL;
|
||||
|
||||
@@ -614,10 +614,10 @@ void ID_Init( void )
|
||||
byte md5[16];
|
||||
int i;
|
||||
|
||||
Cmd_AddCommand( "bloomfilter", ID_BloomFilter_f, "print bloomfilter raw value of arguments set");
|
||||
Cmd_AddCommand( "verifyhex", ID_VerifyHEX_f, "check if id source seems to be fake" );
|
||||
Cmd_AddRestrictedCommand( "bloomfilter", ID_BloomFilter_f, "print bloomfilter raw value of arguments set");
|
||||
Cmd_AddRestrictedCommand( "verifyhex", ID_VerifyHEX_f, "check if id source seems to be fake" );
|
||||
#if XASH_LINUX
|
||||
Cmd_AddCommand( "testcpuinfo", ID_TestCPUInfo_f, "try read cpu serial" );
|
||||
Cmd_AddRestrictedCommand( "testcpuinfo", ID_TestCPUInfo_f, "try read cpu serial" );
|
||||
#endif
|
||||
|
||||
#if XASH_ANDROID && !XASH_DEDICATED
|
||||
|
||||
@@ -41,7 +41,7 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
buf_p = (byte *)buffer;
|
||||
memcpy( &bhdr, buf_p, sizeof( bmp_t ));
|
||||
buf_p += sizeof( bmp_t );
|
||||
buf_p += BI_FILE_HEADER_SIZE + bhdr.bitmapHeaderSize;
|
||||
|
||||
// bogus file header check
|
||||
if( bhdr.reserved0 != 0 ) return false;
|
||||
@@ -53,9 +53,9 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
return false;
|
||||
}
|
||||
|
||||
if( bhdr.bitmapHeaderSize != 0x28 )
|
||||
if(!( bhdr.bitmapHeaderSize == 40 || bhdr.bitmapHeaderSize == 108 || bhdr.bitmapHeaderSize == 124 ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadBMP: invalid header size %i\n", bhdr.bitmapHeaderSize );
|
||||
Con_DPrintf( S_ERROR "Image_LoadBMP: %s have non-standard header size %i\n", name, bhdr.bitmapHeaderSize );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -187,6 +187,7 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
return false;
|
||||
}
|
||||
|
||||
image.depth = 1;
|
||||
image.size = image.width * image.height * bpp;
|
||||
image.rgba = Mem_Malloc( host.imagepool, image.size );
|
||||
|
||||
@@ -313,8 +314,8 @@ qboolean Image_LoadBMP( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
}
|
||||
|
||||
VectorDivide( reflectivity, ( image.width * image.height ), image.fogParams );
|
||||
if( image.palette ) Image_GetPaletteBMP( image.palette );
|
||||
image.depth = 1;
|
||||
if( image.palette )
|
||||
Image_GetPaletteBMP( image.palette );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ GNU General Public License for more details.
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
#define BI_FILE_HEADER_SIZE 14
|
||||
#define BI_SIZE 40 // size of bitmap info header.
|
||||
#if !defined(BI_RGB)
|
||||
#define BI_RGB 0 // uncompressed RGB bitmap(defined in wingdi.h)
|
||||
|
||||
@@ -91,7 +91,7 @@ qboolean Image_CheckDXT5Alpha( dds_t *hdr, byte *fin )
|
||||
return false;
|
||||
}
|
||||
|
||||
void Image_DXTGetPixelFormat( dds_t *hdr )
|
||||
void Image_DXTGetPixelFormat( dds_t *hdr, dds_header_dxt10_t *headerExt )
|
||||
{
|
||||
uint bits = hdr->dsPixelFormat.dwRGBBitCount;
|
||||
|
||||
@@ -100,29 +100,53 @@ void Image_DXTGetPixelFormat( dds_t *hdr )
|
||||
|
||||
if( FBitSet( hdr->dsPixelFormat.dwFlags, DDS_FOURCC ))
|
||||
{
|
||||
switch( hdr->dsPixelFormat.dwFourCC )
|
||||
if( hdr->dsPixelFormat.dwFourCC == TYPE_DX10 )
|
||||
{
|
||||
case TYPE_DXT1:
|
||||
image.type = PF_DXT1;
|
||||
break;
|
||||
case TYPE_DXT2:
|
||||
image.flags &= ~IMAGE_HAS_ALPHA; // alpha is already premultiplied by color
|
||||
// intentionally fallthrough
|
||||
case TYPE_DXT3:
|
||||
image.type = PF_DXT3;
|
||||
break;
|
||||
case TYPE_DXT4:
|
||||
image.flags &= ~IMAGE_HAS_ALPHA; // alpha is already premultiplied by color
|
||||
// intentionally fallthrough
|
||||
case TYPE_DXT5:
|
||||
image.type = PF_DXT5;
|
||||
break;
|
||||
case TYPE_ATI2:
|
||||
image.type = PF_ATI2;
|
||||
break;
|
||||
default:
|
||||
image.type = PF_UNKNOWN; // assume error
|
||||
break;
|
||||
switch( headerExt->dxgiFormat )
|
||||
{
|
||||
case DXGI_FORMAT_BC6H_SF16:
|
||||
image.type = PF_BC6H_SIGNED;
|
||||
break;
|
||||
case DXGI_FORMAT_BC6H_UF16:
|
||||
case DXGI_FORMAT_BC6H_TYPELESS:
|
||||
image.type = PF_BC6H_UNSIGNED;
|
||||
break;
|
||||
case DXGI_FORMAT_BC7_UNORM:
|
||||
case DXGI_FORMAT_BC7_UNORM_SRGB:
|
||||
case DXGI_FORMAT_BC7_TYPELESS:
|
||||
image.type = PF_BC7;
|
||||
break;
|
||||
default:
|
||||
image.type = PF_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( hdr->dsPixelFormat.dwFourCC )
|
||||
{
|
||||
case TYPE_DXT1:
|
||||
image.type = PF_DXT1;
|
||||
break;
|
||||
case TYPE_DXT2:
|
||||
image.flags &= ~IMAGE_HAS_ALPHA; // alpha is already premultiplied by color
|
||||
// intentionally fallthrough
|
||||
case TYPE_DXT3:
|
||||
image.type = PF_DXT3;
|
||||
break;
|
||||
case TYPE_DXT4:
|
||||
image.flags &= ~IMAGE_HAS_ALPHA; // alpha is already premultiplied by color
|
||||
// intentionally fallthrough
|
||||
case TYPE_DXT5:
|
||||
image.type = PF_DXT5;
|
||||
break;
|
||||
case TYPE_ATI2:
|
||||
image.type = PF_ATI2;
|
||||
break;
|
||||
default:
|
||||
image.type = PF_UNKNOWN; // assume error
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -171,6 +195,9 @@ size_t Image_DXTGetLinearSize( int type, int width, int height, int depth )
|
||||
case PF_DXT1: return ((( width + 3 ) / 4 ) * (( height + 3 ) / 4 ) * depth * 8 );
|
||||
case PF_DXT3:
|
||||
case PF_DXT5:
|
||||
case PF_BC6H_SIGNED:
|
||||
case PF_BC6H_UNSIGNED:
|
||||
case PF_BC7:
|
||||
case PF_ATI2: return ((( width + 3 ) / 4 ) * (( height + 3 ) / 4 ) * depth * 16 );
|
||||
case PF_LUMINANCE: return (width * height * depth);
|
||||
case PF_BGR_24:
|
||||
@@ -254,16 +281,18 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
{
|
||||
dds_t header;
|
||||
byte *fin;
|
||||
int headersOffset;
|
||||
dds_header_dxt10_t header2;
|
||||
|
||||
if( filesize < sizeof( dds_t ))
|
||||
if( filesize < sizeof( header ))
|
||||
return false;
|
||||
|
||||
memcpy( &header, buffer, sizeof( dds_t ));
|
||||
memcpy( &header, buffer, sizeof( header ));
|
||||
|
||||
if( header.dwIdent != DDSHEADER )
|
||||
return false; // it's not a dds file, just skip it
|
||||
|
||||
if( header.dwSize != sizeof( dds_t ) - sizeof( uint )) // size of the structure (minus MagicNum)
|
||||
if( header.dwSize != sizeof( header ) - sizeof( uint )) // size of the structure (minus MagicNum)
|
||||
{
|
||||
Con_DPrintf( S_ERROR "Image_LoadDDS: (%s) have corrupted header\n", name );
|
||||
return false;
|
||||
@@ -275,6 +304,13 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
return false;
|
||||
}
|
||||
|
||||
headersOffset = sizeof( header );
|
||||
if( header.dsPixelFormat.dwFourCC == TYPE_DX10 )
|
||||
{
|
||||
memcpy( &header2, buffer + sizeof( header ), sizeof( header2 ));
|
||||
headersOffset += sizeof( header2 );
|
||||
}
|
||||
|
||||
image.width = header.dwWidth;
|
||||
image.height = header.dwHeight;
|
||||
|
||||
@@ -284,7 +320,7 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
|
||||
if( !Image_ValidSize( name )) return false;
|
||||
|
||||
Image_DXTGetPixelFormat( &header ); // and image type too :)
|
||||
Image_DXTGetPixelFormat( &header, &header2 ); // and image type too :)
|
||||
Image_DXTAdjustVolume( &header );
|
||||
|
||||
if( !Image_CheckFlag( IL_DDS_HARDWARE ) && ImageDXT( image.type ))
|
||||
@@ -296,9 +332,9 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
return false;
|
||||
}
|
||||
|
||||
image.size = Image_DXTCalcSize( name, &header, filesize - 128 );
|
||||
image.size = Image_DXTCalcSize( name, &header, filesize - headersOffset );
|
||||
if( image.size == 0 ) return false; // just in case
|
||||
fin = (byte *)(buffer + sizeof( dds_t ));
|
||||
fin = (byte *)( buffer + headersOffset );
|
||||
|
||||
// copy an encode method
|
||||
image.encode = (word)header.dwReserved1[0];
|
||||
@@ -320,6 +356,8 @@ qboolean Image_LoadDDS( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
SetBits( image.flags, IMAGE_HAS_ALPHA );
|
||||
else if( image.type == PF_DXT5 && Image_CheckDXT5Alpha( &header, fin ))
|
||||
SetBits( image.flags, IMAGE_HAS_ALPHA );
|
||||
else if ( image.type == PF_BC7 )
|
||||
SetBits(image.flags, IMAGE_HAS_ALPHA);
|
||||
if( !FBitSet( header.dsPixelFormat.dwFlags, DDS_LUMINANCE ))
|
||||
SetBits( image.flags, IMAGE_HAS_COLOR );
|
||||
break;
|
||||
|
||||
@@ -29,6 +29,7 @@ GNU General Public License for more details.
|
||||
#define TYPE_DXT3 (('3'<<24)+('T'<<16)+('X'<<8)+'D') // little-endian "DXT3"
|
||||
#define TYPE_DXT4 (('4'<<24)+('T'<<16)+('X'<<8)+'D') // little-endian "DXT4"
|
||||
#define TYPE_DXT5 (('5'<<24)+('T'<<16)+('X'<<8)+'D') // little-endian "DXT5"
|
||||
#define TYPE_DX10 (('0'<<24)+('1'<<16)+('X'<<8)+'D') // little-endian "DX10"
|
||||
#define TYPE_ATI1 (('1'<<24)+('I'<<16)+('T'<<8)+'A') // little-endian "ATI1"
|
||||
#define TYPE_ATI2 (('2'<<24)+('I'<<16)+('T'<<8)+'A') // little-endian "ATI2"
|
||||
#define TYPE_RXGB (('B'<<24)+('G'<<16)+('X'<<8)+'R') // little-endian "RXGB" doom3 normalmaps
|
||||
@@ -75,6 +76,141 @@ GNU General Public License for more details.
|
||||
#define DDS_CUBEMAP_ALL_SIDES 0x0000FC00L
|
||||
#define DDS_VOLUME 0x00200000L
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DXGI_FORMAT_UNKNOWN = 0,
|
||||
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
|
||||
DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
|
||||
DXGI_FORMAT_R32G32B32A32_UINT = 3,
|
||||
DXGI_FORMAT_R32G32B32A32_SINT = 4,
|
||||
DXGI_FORMAT_R32G32B32_TYPELESS = 5,
|
||||
DXGI_FORMAT_R32G32B32_FLOAT = 6,
|
||||
DXGI_FORMAT_R32G32B32_UINT = 7,
|
||||
DXGI_FORMAT_R32G32B32_SINT = 8,
|
||||
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
|
||||
DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
|
||||
DXGI_FORMAT_R16G16B16A16_UNORM = 11,
|
||||
DXGI_FORMAT_R16G16B16A16_UINT = 12,
|
||||
DXGI_FORMAT_R16G16B16A16_SNORM = 13,
|
||||
DXGI_FORMAT_R16G16B16A16_SINT = 14,
|
||||
DXGI_FORMAT_R32G32_TYPELESS = 15,
|
||||
DXGI_FORMAT_R32G32_FLOAT = 16,
|
||||
DXGI_FORMAT_R32G32_UINT = 17,
|
||||
DXGI_FORMAT_R32G32_SINT = 18,
|
||||
DXGI_FORMAT_R32G8X24_TYPELESS = 19,
|
||||
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
|
||||
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
|
||||
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
|
||||
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
|
||||
DXGI_FORMAT_R10G10B10A2_UNORM = 24,
|
||||
DXGI_FORMAT_R10G10B10A2_UINT = 25,
|
||||
DXGI_FORMAT_R11G11B10_FLOAT = 26,
|
||||
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM = 28,
|
||||
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
|
||||
DXGI_FORMAT_R8G8B8A8_UINT = 30,
|
||||
DXGI_FORMAT_R8G8B8A8_SNORM = 31,
|
||||
DXGI_FORMAT_R8G8B8A8_SINT = 32,
|
||||
DXGI_FORMAT_R16G16_TYPELESS = 33,
|
||||
DXGI_FORMAT_R16G16_FLOAT = 34,
|
||||
DXGI_FORMAT_R16G16_UNORM = 35,
|
||||
DXGI_FORMAT_R16G16_UINT = 36,
|
||||
DXGI_FORMAT_R16G16_SNORM = 37,
|
||||
DXGI_FORMAT_R16G16_SINT = 38,
|
||||
DXGI_FORMAT_R32_TYPELESS = 39,
|
||||
DXGI_FORMAT_D32_FLOAT = 40,
|
||||
DXGI_FORMAT_R32_FLOAT = 41,
|
||||
DXGI_FORMAT_R32_UINT = 42,
|
||||
DXGI_FORMAT_R32_SINT = 43,
|
||||
DXGI_FORMAT_R24G8_TYPELESS = 44,
|
||||
DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
|
||||
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
|
||||
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
|
||||
DXGI_FORMAT_R8G8_TYPELESS = 48,
|
||||
DXGI_FORMAT_R8G8_UNORM = 49,
|
||||
DXGI_FORMAT_R8G8_UINT = 50,
|
||||
DXGI_FORMAT_R8G8_SNORM = 51,
|
||||
DXGI_FORMAT_R8G8_SINT = 52,
|
||||
DXGI_FORMAT_R16_TYPELESS = 53,
|
||||
DXGI_FORMAT_R16_FLOAT = 54,
|
||||
DXGI_FORMAT_D16_UNORM = 55,
|
||||
DXGI_FORMAT_R16_UNORM = 56,
|
||||
DXGI_FORMAT_R16_UINT = 57,
|
||||
DXGI_FORMAT_R16_SNORM = 58,
|
||||
DXGI_FORMAT_R16_SINT = 59,
|
||||
DXGI_FORMAT_R8_TYPELESS = 60,
|
||||
DXGI_FORMAT_R8_UNORM = 61,
|
||||
DXGI_FORMAT_R8_UINT = 62,
|
||||
DXGI_FORMAT_R8_SNORM = 63,
|
||||
DXGI_FORMAT_R8_SINT = 64,
|
||||
DXGI_FORMAT_A8_UNORM = 65,
|
||||
DXGI_FORMAT_R1_UNORM = 66,
|
||||
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
|
||||
DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
|
||||
DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
|
||||
DXGI_FORMAT_BC1_TYPELESS = 70,
|
||||
DXGI_FORMAT_BC1_UNORM = 71,
|
||||
DXGI_FORMAT_BC1_UNORM_SRGB = 72,
|
||||
DXGI_FORMAT_BC2_TYPELESS = 73,
|
||||
DXGI_FORMAT_BC2_UNORM = 74,
|
||||
DXGI_FORMAT_BC2_UNORM_SRGB = 75,
|
||||
DXGI_FORMAT_BC3_TYPELESS = 76,
|
||||
DXGI_FORMAT_BC3_UNORM = 77,
|
||||
DXGI_FORMAT_BC3_UNORM_SRGB = 78,
|
||||
DXGI_FORMAT_BC4_TYPELESS = 79,
|
||||
DXGI_FORMAT_BC4_UNORM = 80,
|
||||
DXGI_FORMAT_BC4_SNORM = 81,
|
||||
DXGI_FORMAT_BC5_TYPELESS = 82,
|
||||
DXGI_FORMAT_BC5_UNORM = 83,
|
||||
DXGI_FORMAT_BC5_SNORM = 84,
|
||||
DXGI_FORMAT_B5G6R5_UNORM = 85,
|
||||
DXGI_FORMAT_B5G5R5A1_UNORM = 86,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM = 87,
|
||||
DXGI_FORMAT_B8G8R8X8_UNORM = 88,
|
||||
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
|
||||
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
|
||||
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
|
||||
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
|
||||
DXGI_FORMAT_BC6H_TYPELESS = 94,
|
||||
DXGI_FORMAT_BC6H_UF16 = 95,
|
||||
DXGI_FORMAT_BC6H_SF16 = 96,
|
||||
DXGI_FORMAT_BC7_TYPELESS = 97,
|
||||
DXGI_FORMAT_BC7_UNORM = 98,
|
||||
DXGI_FORMAT_BC7_UNORM_SRGB = 99,
|
||||
DXGI_FORMAT_AYUV = 100,
|
||||
DXGI_FORMAT_Y410 = 101,
|
||||
DXGI_FORMAT_Y416 = 102,
|
||||
DXGI_FORMAT_NV12 = 103,
|
||||
DXGI_FORMAT_P010 = 104,
|
||||
DXGI_FORMAT_P016 = 105,
|
||||
DXGI_FORMAT_420_OPAQUE = 106,
|
||||
DXGI_FORMAT_YUY2 = 107,
|
||||
DXGI_FORMAT_Y210 = 108,
|
||||
DXGI_FORMAT_Y216 = 109,
|
||||
DXGI_FORMAT_NV11 = 110,
|
||||
DXGI_FORMAT_AI44 = 111,
|
||||
DXGI_FORMAT_IA44 = 112,
|
||||
DXGI_FORMAT_P8 = 113,
|
||||
DXGI_FORMAT_A8P8 = 114,
|
||||
DXGI_FORMAT_B4G4R4A4_UNORM = 115,
|
||||
DXGI_FORMAT_P208 = 130,
|
||||
DXGI_FORMAT_V208 = 131,
|
||||
DXGI_FORMAT_V408 = 132,
|
||||
DXGI_FORMAT_SAMPLER_FEEDBACK_MIN_MIP_OPAQUE,
|
||||
DXGI_FORMAT_SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE,
|
||||
DXGI_FORMAT_FORCE_UINT = 0xffffffff
|
||||
} dxgi_format_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
|
||||
D3D10_RESOURCE_DIMENSION_BUFFER = 1,
|
||||
D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
|
||||
D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
|
||||
D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4
|
||||
} dds_resource_dimension_t;
|
||||
|
||||
typedef struct dds_pf_s
|
||||
{
|
||||
uint32_t dwSize;
|
||||
@@ -96,6 +232,15 @@ typedef struct dds_caps_s
|
||||
uint32_t dwCaps4; // currently unused
|
||||
} dds_caps_t;
|
||||
|
||||
typedef struct dds_header_dxt10_s
|
||||
{
|
||||
dxgi_format_t dxgiFormat;
|
||||
dds_resource_dimension_t resourceDimension;
|
||||
uint32_t miscFlag;
|
||||
uint32_t arraySize;
|
||||
uint32_t miscFlags2;
|
||||
} dds_header_dxt10_t;
|
||||
|
||||
typedef struct dds_s
|
||||
{
|
||||
uint32_t dwIdent; // must matched with DDSHEADER
|
||||
|
||||
@@ -566,4 +566,25 @@ void Test_RunImagelib( void )
|
||||
Z_Free( rgb.buffer );
|
||||
}
|
||||
|
||||
#define IMPLEMENT_IMAGELIB_FUZZ_TARGET( export, target ) \
|
||||
int EXPORT export( const uint8_t *Data, size_t Size ) \
|
||||
{ \
|
||||
rgbdata_t *rgb; \
|
||||
host.type = HOST_NORMAL; \
|
||||
Memory_Init(); \
|
||||
Image_Init(); \
|
||||
if( target( "#internal", Data, Size )) \
|
||||
{ \
|
||||
rgb = ImagePack(); \
|
||||
FS_FreeImage( rgb ); \
|
||||
} \
|
||||
Image_Shutdown(); \
|
||||
return 0; \
|
||||
} \
|
||||
|
||||
IMPLEMENT_IMAGELIB_FUZZ_TARGET( Fuzz_Image_LoadBMP, Image_LoadBMP )
|
||||
IMPLEMENT_IMAGELIB_FUZZ_TARGET( Fuzz_Image_LoadPNG, Image_LoadPNG )
|
||||
IMPLEMENT_IMAGELIB_FUZZ_TARGET( Fuzz_Image_LoadDDS, Image_LoadDDS )
|
||||
IMPLEMENT_IMAGELIB_FUZZ_TARGET( Fuzz_Image_LoadTGA, Image_LoadTGA )
|
||||
|
||||
#endif /* XASH_ENGINE_TESTS */
|
||||
|
||||
@@ -80,15 +80,6 @@ static byte palette_hl[768] =
|
||||
147,255,247,199,255,255,255,159,91,83
|
||||
};
|
||||
|
||||
static float img_emboss[FILTER_SIZE][FILTER_SIZE] =
|
||||
{
|
||||
{-0.7f, -0.7f, -0.7f, -0.7f, 0.0f },
|
||||
{-0.7f, -0.7f, -0.7f, 0.0f, 0.7f },
|
||||
{-0.7f, -0.7f, 0.0f, 0.7f, 0.7f },
|
||||
{-0.7f, 0.0f, 0.7f, 0.7f, 0.7f },
|
||||
{ 0.0f, 0.7f, 0.7f, 0.7f, 0.7f },
|
||||
};
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
@@ -465,8 +456,8 @@ void Image_PaletteHueReplace( byte *palSrc, int newHue, int start, int end, int
|
||||
g = palSrc[i*pal_size+1];
|
||||
b = palSrc[i*pal_size+2];
|
||||
|
||||
maxcol = max( max( r, g ), b ) / 255.0f;
|
||||
mincol = min( min( r, g ), b ) / 255.0f;
|
||||
maxcol = Q_max( Q_max( r, g ), b ) / 255.0f;
|
||||
mincol = Q_min( Q_min( r, g ), b ) / 255.0f;
|
||||
|
||||
if( maxcol == 0 ) continue;
|
||||
|
||||
@@ -1368,107 +1359,7 @@ qboolean Image_RemapInternal( rgbdata_t *pic, int topColor, int bottomColor )
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Image_ApplyFilter
|
||||
|
||||
Applies a 5 x 5 filtering matrix to the texture, then runs it through a simulated OpenGL texture environment
|
||||
blend with the original data to derive a new texture. Freaky, funky, and *f--king* *fantastic*. You can do
|
||||
reasonable enough "fake bumpmapping" with this baby...
|
||||
|
||||
Filtering algorithm from http://www.student.kuleuven.ac.be/~m0216922/CG/filtering.html
|
||||
All credit due
|
||||
==================
|
||||
*/
|
||||
static void Image_ApplyFilter( rgbdata_t *pic, float factor )
|
||||
{
|
||||
int i, x, y;
|
||||
uint *fin, *fout;
|
||||
size_t size;
|
||||
|
||||
// don't waste time
|
||||
if( factor <= 0.0f ) return;
|
||||
|
||||
// first expand the image into 32-bit buffer
|
||||
pic = Image_DecompressInternal( pic );
|
||||
factor = bound( 0.0f, factor, 1.0f );
|
||||
size = image.width * image.height * 4;
|
||||
image.tempbuffer = Mem_Realloc( host.imagepool, image.tempbuffer, size );
|
||||
fout = (uint *)image.tempbuffer;
|
||||
fin = (uint *)pic->buffer;
|
||||
|
||||
for( x = 0; x < image.width; x++ )
|
||||
{
|
||||
for( y = 0; y < image.height; y++ )
|
||||
{
|
||||
vec3_t vout = { 0.0f, 0.0f, 0.0f };
|
||||
int pos_x, pos_y;
|
||||
float avg;
|
||||
|
||||
for( pos_x = 0; pos_x < FILTER_SIZE; pos_x++ )
|
||||
{
|
||||
for( pos_y = 0; pos_y < FILTER_SIZE; pos_y++ )
|
||||
{
|
||||
int img_x = (x - (FILTER_SIZE / 2) + pos_x + image.width) % image.width;
|
||||
int img_y = (y - (FILTER_SIZE / 2) + pos_y + image.height) % image.height;
|
||||
|
||||
// casting's a unary operation anyway, so the othermost set of brackets in the left part
|
||||
// of the rvalue should not be necessary... but i'm paranoid when it comes to C...
|
||||
vout[0] += ((float)((byte *)&fin[img_y * image.width + img_x])[0]) * img_emboss[pos_x][pos_y];
|
||||
vout[1] += ((float)((byte *)&fin[img_y * image.width + img_x])[1]) * img_emboss[pos_x][pos_y];
|
||||
vout[2] += ((float)((byte *)&fin[img_y * image.width + img_x])[2]) * img_emboss[pos_x][pos_y];
|
||||
}
|
||||
}
|
||||
|
||||
// multiply by factor, add bias, and clamp
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
vout[i] *= factor;
|
||||
vout[i] += 128.0f; // base
|
||||
vout[i] = bound( 0.0f, vout[i], 255.0f );
|
||||
}
|
||||
|
||||
// NTSC greyscale conversion standard
|
||||
avg = (vout[0] * 30.0f + vout[1] * 59.0f + vout[2] * 11.0f) / 100.0f;
|
||||
|
||||
// divide by 255 so GL operations work as expected
|
||||
vout[0] = avg / 255.0f;
|
||||
vout[1] = avg / 255.0f;
|
||||
vout[2] = avg / 255.0f;
|
||||
|
||||
// write to temp - first, write data in (to get the alpha channel quickly and
|
||||
// easily, which will be left well alone by this particular operation...!)
|
||||
fout[y * image.width + x] = fin[y * image.width + x];
|
||||
|
||||
// now write in each element, applying the blend operator. blend
|
||||
// operators are based on standard OpenGL TexEnv modes, and the
|
||||
// formulas are derived from the OpenGL specs (http://www.opengl.org).
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
// divide by 255 so GL operations work as expected
|
||||
float src = ((float)((byte *)&fin[y * image.width + x])[i]) / 255.0f;
|
||||
float tmp;
|
||||
|
||||
// default is GL_BLEND here
|
||||
// CsS + CdD works out as Src * Dst * 2
|
||||
tmp = vout[i] * src * 2.0f;
|
||||
|
||||
// multiply back by 255 to get the proper byte scale
|
||||
tmp *= 255.0f;
|
||||
|
||||
// bound the temp target again now, cos the operation may have thrown it out
|
||||
tmp = bound( 0.0f, tmp, 255.0f );
|
||||
// and copy it in
|
||||
((byte *)&fout[y * image.width + x])[i] = (byte)tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copy result back
|
||||
memcpy( fin, fout, size );
|
||||
}
|
||||
|
||||
qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, float bumpscale )
|
||||
qboolean Image_Process(rgbdata_t **pix, int width, int height, uint flags, float reserved )
|
||||
{
|
||||
rgbdata_t *pic = *pix;
|
||||
qboolean result = true;
|
||||
@@ -1509,9 +1400,6 @@ qboolean Image_Process( rgbdata_t **pix, int width, int height, uint flags, floa
|
||||
if( FBitSet( flags, IMAGE_LIGHTGAMMA ))
|
||||
pic = Image_LightGamma( pic );
|
||||
|
||||
if( FBitSet( flags, IMAGE_EMBOSS ))
|
||||
Image_ApplyFilter( pic, bumpscale );
|
||||
|
||||
out = Image_FlipInternal( pic->buffer, &pic->width, &pic->height, pic->type, flags );
|
||||
if( pic->buffer != out ) memcpy( pic->buffer, image.tempbuffer, pic->size );
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@ GNU General Public License for more details.
|
||||
|
||||
#ifdef SINGLE_BINARY
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "build.h"
|
||||
#include "common.h"
|
||||
#ifdef XASH_SDLMAIN
|
||||
@@ -28,62 +26,89 @@ GNU General Public License for more details.
|
||||
#endif
|
||||
|
||||
#if XASH_WIN32
|
||||
#define XASH_NOCONHOST 1
|
||||
#include <process.h> // _execve
|
||||
#else
|
||||
#include <unistd.h> // execve
|
||||
#endif
|
||||
|
||||
extern char **environ;
|
||||
static char szGameDir[128]; // safe place to keep gamedir
|
||||
static int g_iArgc;
|
||||
static char **g_pszArgv;
|
||||
|
||||
#if XASH_WIN32 || XASH_POSIX
|
||||
#define USE_EXECVE_FOR_CHANGE_GAME 1
|
||||
#else
|
||||
#define USE_EXECVE_FOR_CHANGE_GAME 0
|
||||
#endif
|
||||
|
||||
#define E_GAME "XASH3D_GAME" // default env dir to start from
|
||||
#define GAME_PATH "valve" // default dir to start from
|
||||
|
||||
void Launcher_ChangeGame( const char *progname )
|
||||
{
|
||||
strncpy( szGameDir, progname, sizeof( szGameDir ) - 1 );
|
||||
char envstr[256];
|
||||
|
||||
#if USE_EXECVE_FOR_CHANGE_GAME
|
||||
Host_Shutdown();
|
||||
|
||||
#if XASH_WIN32
|
||||
_putenv_s( E_GAME, progname );
|
||||
_execve( g_pszArgv[0], g_pszArgv, _environ );
|
||||
#else
|
||||
snprintf( envstr, sizeof( envstr ), E_GAME "=%s", progname );
|
||||
putenv( envstr );
|
||||
execve( g_pszArgv[0], g_pszArgv, environ );
|
||||
#endif
|
||||
|
||||
#else
|
||||
Q_strncpy( szGameDir, progname, sizeof( szGameDir ) - 1 );
|
||||
Host_Shutdown( );
|
||||
exit( Host_Main( g_iArgc, g_pszArgv, szGameDir, 1, &Launcher_ChangeGame ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
#if XASH_NOCONHOST
|
||||
#if XASH_WIN32
|
||||
#include <windows.h>
|
||||
#include <shellapi.h> // CommandLineToArgvW
|
||||
int __stdcall WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdLine, int nShow)
|
||||
{
|
||||
int szArgc;
|
||||
char **szArgv;
|
||||
LPWSTR* lpArgv = CommandLineToArgvW(GetCommandLineW(), &szArgc);
|
||||
int i = 0;
|
||||
LPWSTR* lpArgv;
|
||||
int ret, i;
|
||||
|
||||
szArgv = (char**)malloc(szArgc*sizeof(char*));
|
||||
for (; i < szArgc; ++i)
|
||||
lpArgv = CommandLineToArgvW( GetCommandLineW(), &szArgc );
|
||||
szArgv = ( char** )malloc( (szArgc + 1) * sizeof( char* ));
|
||||
|
||||
for( i = 0; i < szArgc; ++i )
|
||||
{
|
||||
size_t size = wcslen(lpArgv[i]) + 1;
|
||||
szArgv[i] = (char*)malloc(size);
|
||||
wcstombs(szArgv[i], lpArgv[i], size);
|
||||
|
||||
// just in case, allocate some more memory
|
||||
szArgv[i] = ( char * )malloc( size * sizeof( wchar_t ));
|
||||
wcstombs( szArgv[i], lpArgv[i], size );
|
||||
}
|
||||
szArgv[i] = NULL;
|
||||
szArgv[szArgc] = 0;
|
||||
|
||||
LocalFree(lpArgv);
|
||||
LocalFree( lpArgv );
|
||||
|
||||
main( szArgc, szArgv );
|
||||
ret = main( szArgc, szArgv );
|
||||
|
||||
for( i = 0; i < szArgc; ++i )
|
||||
free( szArgv[i] );
|
||||
free( szArgv );
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#endif // XASH_WIN32
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
char gamedir_buf[32] = "";
|
||||
const char *gamedir = getenv( "XASH3D_GAMEDIR" );
|
||||
const char *game = getenv( E_GAME );
|
||||
|
||||
if( !COM_CheckString( gamedir ) )
|
||||
{
|
||||
gamedir = "valve";
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy( gamedir_buf, gamedir, 32 );
|
||||
gamedir = gamedir_buf;
|
||||
}
|
||||
if( !game )
|
||||
game = GAME_PATH;
|
||||
|
||||
Q_strncpy( szGameDir, game, sizeof( szGameDir ));
|
||||
|
||||
#if XASH_EMSCRIPTEN
|
||||
#ifdef EMSCRIPTEN_LIB_FS
|
||||
@@ -110,7 +135,7 @@ int main( int argc, char** argv )
|
||||
IOS_LaunchDialog();
|
||||
}
|
||||
#endif
|
||||
return Host_Main( g_iArgc, g_pszArgv, gamedir, 0, &Launcher_ChangeGame );
|
||||
return Host_Main( g_iArgc, g_pszArgv, szGameDir, 0, &Launcher_ChangeGame );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -291,12 +291,12 @@ static char *COM_GetItaniumName( const char * const in_name )
|
||||
len = len * 10 + ( *f - '0' );
|
||||
|
||||
// sane value
|
||||
len = min( remaining, len );
|
||||
len = Q_min( remaining, len );
|
||||
|
||||
if( len == 0 )
|
||||
goto invalid_format;
|
||||
|
||||
Q_strncpy( symbols[i], f, min( len + 1, sizeof( out_name )));
|
||||
Q_strncpy( symbols[i], f, Q_min( len + 1, sizeof( out_name )));
|
||||
f += len;
|
||||
remaining -= len;
|
||||
|
||||
@@ -361,7 +361,7 @@ char **COM_ConvertToLocalPlatform( EFunctionMangleType to, const char *from, siz
|
||||
|
||||
if( at ) len = (uint)( at - prev );
|
||||
else len = (uint)Q_strlen( prev );
|
||||
Q_strncpy( symbols[i], prev, min( len + 1, sizeof( symbols[i] )));
|
||||
Q_strncpy( symbols[i], prev, Q_min( len + 1, sizeof( symbols[i] )));
|
||||
prev = at + 1;
|
||||
|
||||
if( !at )
|
||||
|
||||
@@ -35,7 +35,11 @@ typedef struct dll_user_s
|
||||
} dll_user_t;
|
||||
|
||||
dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath );
|
||||
void *COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean directpath );
|
||||
|
||||
#define COM_LoadLibrary( dllname, build_ordinals_table, directpath ) \
|
||||
_COM_LoadLibrary( dllname, build_ordinals_table, directpath, __FILE__, __LINE__ )
|
||||
|
||||
void *_COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean directpath, const char *name, int line );
|
||||
void *COM_GetProcAddress( void *hInstance, const char *name );
|
||||
const char *COM_NameForFunction( void *hInstance, void *function );
|
||||
void *COM_FunctionFromName_SR( void *hInstance, const char *pName ); // Save/Restore version
|
||||
|
||||
@@ -254,6 +254,5 @@ void NET_InitMasters( void )
|
||||
|
||||
// keep main master always there
|
||||
NET_AddMaster( MASTERSERVER_ADR, false );
|
||||
NET_AddMaster( MASTERSERVER_ADR2, false );
|
||||
NET_LoadMasters( );
|
||||
}
|
||||
|
||||
@@ -1020,6 +1020,8 @@ Fills in surf->texturemins[] and surf->extents[]
|
||||
*/
|
||||
static void Mod_CalcSurfaceExtents( msurface_t *surf )
|
||||
{
|
||||
// this place is VERY critical to precision
|
||||
// keep it as float, don't use double, because it causes issues with lightmap
|
||||
float mins[2], maxs[2], val;
|
||||
float lmmins[2], lmmaxs[2];
|
||||
int bmins[2], bmaxs[2];
|
||||
@@ -1049,14 +1051,14 @@ static void Mod_CalcSurfaceExtents( msurface_t *surf )
|
||||
|
||||
for( j = 0; j < 2; j++ )
|
||||
{
|
||||
val = DotProduct( v->position, surf->texinfo->vecs[j] ) + surf->texinfo->vecs[j][3];
|
||||
val = DotProductPrecise( v->position, surf->texinfo->vecs[j] ) + surf->texinfo->vecs[j][3];
|
||||
mins[j] = Q_min( val, mins[j] );
|
||||
maxs[j] = Q_max( val, maxs[j] );
|
||||
}
|
||||
|
||||
for( j = 0; j < 2; j++ )
|
||||
{
|
||||
val = DotProduct( v->position, info->lmvecs[j] ) + info->lmvecs[j][3];
|
||||
val = DotProductPrecise( v->position, info->lmvecs[j] ) + info->lmvecs[j][3];
|
||||
lmmins[j] = Q_min( val, lmmins[j] );
|
||||
lmmaxs[j] = Q_max( val, lmmaxs[j] );
|
||||
}
|
||||
@@ -2023,7 +2025,7 @@ static void Mod_LoadTextures( dbspmodel_t *bmod )
|
||||
|
||||
if( FS_FileExists( texpath, false ))
|
||||
{
|
||||
tx->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texpath, NULL, 0, TF_ALLOW_EMBOSS|txFlags );
|
||||
tx->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texpath, NULL, 0, txFlags );
|
||||
bmod->wadlist.wadusage[j]++; // this wad are really used
|
||||
break;
|
||||
}
|
||||
@@ -2039,7 +2041,7 @@ static void Mod_LoadTextures( dbspmodel_t *bmod )
|
||||
|
||||
if( custom_palette ) size += sizeof( short ) + 768;
|
||||
Q_snprintf( texname, sizeof( texname ), "#%s:%s.mip", loadstat.name, mt->name );
|
||||
tx->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texname, (byte *)mt, size, TF_ALLOW_EMBOSS|txFlags );
|
||||
tx->gl_texturenum = ref.dllFuncs.GL_LoadTexture( texname, (byte *)mt, size, txFlags );
|
||||
}
|
||||
|
||||
// if texture is completely missed
|
||||
@@ -2734,6 +2736,37 @@ static void Mod_LoadLighting( dbspmodel_t *bmod )
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_LumpLooksLikePlanes
|
||||
|
||||
=================
|
||||
*/
|
||||
static qboolean Mod_LumpLooksLikePlanes( const byte *in, dlump_t *lump, qboolean fast )
|
||||
{
|
||||
int numplanes, i;
|
||||
const dplane_t *planes;
|
||||
|
||||
if( lump->filelen < sizeof( dplane_t ) &&
|
||||
lump->filelen % sizeof( dplane_t ) != 0 )
|
||||
return false;
|
||||
|
||||
if( fast )
|
||||
return true;
|
||||
|
||||
numplanes = lump->filelen / sizeof( dplane_t );
|
||||
planes = (const dplane_t*)(in + lump->fileofs);
|
||||
|
||||
for( i = 0; i < numplanes; i++ )
|
||||
{
|
||||
// planes can only be from 0 to 5: PLANE_X, Y, Z and PLANE_ANYX, Y and Z
|
||||
if( planes[i].type < 0 || planes[i].type > 5 )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_LoadBmodelLumps
|
||||
@@ -2780,13 +2813,28 @@ qboolean Mod_LoadBmodelLumps( const byte *mod_base, qboolean isworld )
|
||||
if( isworld ) world.flags = 0; // clear world settings
|
||||
bmod->isworld = isworld;
|
||||
|
||||
if( header->version == HLBSP_VERSION &&
|
||||
header->lumps[LUMP_ENTITIES].fileofs <= 1024 &&
|
||||
(header->lumps[LUMP_ENTITIES].filelen % sizeof( dplane_t )) == 0 )
|
||||
if( header->version == HLBSP_VERSION )
|
||||
{
|
||||
// blue-shift swapped lumps
|
||||
srclumps[0].lumpnumber = LUMP_PLANES;
|
||||
srclumps[1].lumpnumber = LUMP_ENTITIES;
|
||||
// only relevant for half-life maps
|
||||
if( !Mod_LumpLooksLikePlanes( mod_base, &header->lumps[LUMP_PLANES], false ) &&
|
||||
Mod_LumpLooksLikePlanes( mod_base, &header->lumps[LUMP_ENTITIES], false ))
|
||||
{
|
||||
// blue-shift swapped lumps
|
||||
srclumps[0].lumpnumber = LUMP_PLANES;
|
||||
srclumps[1].lumpnumber = LUMP_ENTITIES;
|
||||
}
|
||||
else
|
||||
{
|
||||
// everything else
|
||||
srclumps[0].lumpnumber = LUMP_ENTITIES;
|
||||
srclumps[1].lumpnumber = LUMP_PLANES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// everything else
|
||||
srclumps[0].lumpnumber = LUMP_ENTITIES;
|
||||
srclumps[1].lumpnumber = LUMP_PLANES;
|
||||
}
|
||||
|
||||
// loading base lumps
|
||||
@@ -2893,13 +2941,28 @@ qboolean Mod_TestBmodelLumps( const char *name, const byte *mod_base, qboolean s
|
||||
break;
|
||||
}
|
||||
|
||||
if( header->version == HLBSP_VERSION &&
|
||||
header->lumps[LUMP_ENTITIES].fileofs <= 1024 &&
|
||||
(header->lumps[LUMP_ENTITIES].filelen % sizeof( dplane_t )) == 0 )
|
||||
if( header->version == HLBSP_VERSION )
|
||||
{
|
||||
// blue-shift swapped lumps
|
||||
srclumps[0].lumpnumber = LUMP_PLANES;
|
||||
srclumps[1].lumpnumber = LUMP_ENTITIES;
|
||||
// only relevant for half-life maps
|
||||
if( Mod_LumpLooksLikePlanes( mod_base, &header->lumps[LUMP_ENTITIES], true ) &&
|
||||
!Mod_LumpLooksLikePlanes( mod_base, &header->lumps[LUMP_PLANES], true ))
|
||||
{
|
||||
// blue-shift swapped lumps
|
||||
srclumps[0].lumpnumber = LUMP_PLANES;
|
||||
srclumps[1].lumpnumber = LUMP_ENTITIES;
|
||||
}
|
||||
else
|
||||
{
|
||||
// everything else
|
||||
srclumps[0].lumpnumber = LUMP_ENTITIES;
|
||||
srclumps[1].lumpnumber = LUMP_PLANES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// everything else
|
||||
srclumps[0].lumpnumber = LUMP_ENTITIES;
|
||||
srclumps[1].lumpnumber = LUMP_PLANES;
|
||||
}
|
||||
|
||||
// loading base lumps
|
||||
|
||||
@@ -980,10 +980,6 @@ qboolean Delta_CompareField( delta_t *pField, void *from, void *to, double timeb
|
||||
}
|
||||
else if( pField->flags & DT_INTEGER )
|
||||
{
|
||||
#if defined __GNUC__ && __GNUC_MAJOR < 9 && !defined __clang__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wduplicated-branches"
|
||||
#endif
|
||||
if( pField->flags & DT_SIGNED )
|
||||
{
|
||||
fromF = *(int *)((byte *)from + pField->offset );
|
||||
@@ -994,9 +990,6 @@ qboolean Delta_CompareField( delta_t *pField, void *from, void *to, double timeb
|
||||
fromF = *(uint *)((byte *)from + pField->offset );
|
||||
toF = *(uint *)((byte *)to + pField->offset );
|
||||
}
|
||||
#if defined __GNUC__ && __GNUC_MAJOR < 9 && !defined __clang__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
fromF = Delta_ClampIntegerField( pField, fromF, bSigned, pField->bits );
|
||||
toF = Delta_ClampIntegerField( pField, toF, bSigned, pField->bits );
|
||||
if( !Q_equal( pField->multiplier, 1.0 ) )
|
||||
@@ -1121,7 +1114,7 @@ assume from and to is valid
|
||||
qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, void *to, double timebase )
|
||||
{
|
||||
qboolean bSigned = ( pField->flags & DT_SIGNED ) ? true : false;
|
||||
float flValue, flAngle, flTime;
|
||||
float flValue, flAngle;
|
||||
uint iValue;
|
||||
const char *pStr;
|
||||
|
||||
@@ -1161,17 +1154,10 @@ qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, void *to
|
||||
}
|
||||
else if( pField->flags & DT_INTEGER )
|
||||
{
|
||||
#if defined __GNUC__ && __GNUC_MAJOR < 9 && !defined __clang__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wduplicated-branches"
|
||||
#endif
|
||||
if( bSigned )
|
||||
iValue = *(int32_t *)((int8_t *)to + pField->offset );
|
||||
else
|
||||
iValue = *(uint32_t *)((int8_t *)to + pField->offset );
|
||||
#if defined __GNUC__ && __GNUC_MAJOR < 9 && !defined __clang__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
iValue = Delta_ClampIntegerField( pField, iValue, bSigned, pField->bits );
|
||||
|
||||
if( !Q_equal( pField->multiplier, 1.0 ) )
|
||||
@@ -1218,6 +1204,53 @@ qboolean Delta_WriteField( sizebuf_t *msg, delta_t *pField, void *from, void *to
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
Delta_CopyField
|
||||
|
||||
====================
|
||||
*/
|
||||
static void Delta_CopyField( delta_t *pField, void *from, void *to, double timebase )
|
||||
{
|
||||
qboolean bSigned = FBitSet( pField->flags, DT_SIGNED );
|
||||
uint8_t *to_field = (uint8_t *)to + pField->offset;
|
||||
uint8_t *from_field = (uint8_t *)from + pField->offset;
|
||||
|
||||
if( FBitSet( pField->flags, DT_BYTE ))
|
||||
{
|
||||
if( bSigned )
|
||||
*(int8_t *)( to_field ) = *(int8_t *)( from_field );
|
||||
else
|
||||
*(uint8_t *)( to_field ) = *(uint8_t *)( from_field );
|
||||
}
|
||||
else if( FBitSet( pField->flags, DT_SHORT ))
|
||||
{
|
||||
if( bSigned )
|
||||
*(int16_t *)( to_field ) = *(int16_t *)( from_field );
|
||||
else
|
||||
*(uint16_t *)( to_field ) = *(uint16_t *)( from_field );
|
||||
}
|
||||
else if( FBitSet( pField->flags, DT_INTEGER ))
|
||||
{
|
||||
if( bSigned )
|
||||
*(int32_t *)( to_field ) = *(int32_t *)( from_field );
|
||||
else
|
||||
*(uint32_t *)( to_field ) = *(uint32_t *)( from_field );
|
||||
}
|
||||
else if( FBitSet( pField->flags, DT_FLOAT|DT_ANGLE|DT_TIMEWINDOW_8|DT_TIMEWINDOW_BIG ))
|
||||
{
|
||||
*(float *)( to_field ) = *(float *)( from_field );
|
||||
}
|
||||
else if( FBitSet( pField->flags, DT_STRING ))
|
||||
{
|
||||
Q_strncpy( to_field, from_field, pField->size );
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
Delta_ReadField
|
||||
@@ -1230,30 +1263,24 @@ qboolean Delta_ReadField( sizebuf_t *msg, delta_t *pField, void *from, void *to,
|
||||
{
|
||||
qboolean bSigned = ( pField->flags & DT_SIGNED ) ? true : false;
|
||||
float flValue, flAngle, flTime;
|
||||
qboolean bChanged;
|
||||
uint iValue;
|
||||
const char *pStr;
|
||||
char *pOut;
|
||||
|
||||
bChanged = MSG_ReadOneBit( msg );
|
||||
if( !MSG_ReadOneBit( msg ) )
|
||||
{
|
||||
Delta_CopyField( pField, from, to, timebase );
|
||||
return false;
|
||||
}
|
||||
|
||||
Assert( pField->multiplier != 0.0f );
|
||||
|
||||
if( pField->flags & DT_BYTE )
|
||||
{
|
||||
if( bChanged )
|
||||
{
|
||||
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
|
||||
if( !Q_equal( pField->multiplier, 1.0 ) )
|
||||
iValue /= pField->multiplier;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( bSigned )
|
||||
iValue = *(int8_t *)((uint8_t *)from + pField->offset );
|
||||
else
|
||||
iValue = *(uint8_t *)((uint8_t *)from + pField->offset );
|
||||
}
|
||||
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
|
||||
if( !Q_equal( pField->multiplier, 1.0 ) )
|
||||
iValue /= pField->multiplier;
|
||||
|
||||
if( bSigned )
|
||||
*(int8_t *)((uint8_t *)to + pField->offset ) = iValue;
|
||||
else
|
||||
@@ -1261,19 +1288,10 @@ qboolean Delta_ReadField( sizebuf_t *msg, delta_t *pField, void *from, void *to,
|
||||
}
|
||||
else if( pField->flags & DT_SHORT )
|
||||
{
|
||||
if( bChanged )
|
||||
{
|
||||
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
|
||||
if( !Q_equal( pField->multiplier, 1.0 ) )
|
||||
iValue /= pField->multiplier;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( bSigned )
|
||||
iValue = *(int16_t *)((uint8_t *)from + pField->offset );
|
||||
else
|
||||
iValue = *(uint16_t *)((uint8_t *)from + pField->offset );
|
||||
}
|
||||
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
|
||||
if( !Q_equal( pField->multiplier, 1.0 ) )
|
||||
iValue /= pField->multiplier;
|
||||
|
||||
if( bSigned )
|
||||
*(int16_t *)((uint8_t *)to + pField->offset ) = iValue;
|
||||
else
|
||||
@@ -1281,112 +1299,63 @@ qboolean Delta_ReadField( sizebuf_t *msg, delta_t *pField, void *from, void *to,
|
||||
}
|
||||
else if( pField->flags & DT_INTEGER )
|
||||
{
|
||||
#if defined __GNUC__ && __GNUC_MAJOR < 9 && !defined __clang__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wduplicated-branches"
|
||||
#endif
|
||||
if( bChanged )
|
||||
{
|
||||
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
|
||||
if( !Q_equal( pField->multiplier, 1.0 ) )
|
||||
iValue /= pField->multiplier;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( bSigned )
|
||||
iValue = *(int32_t *)((uint8_t *)from + pField->offset );
|
||||
else
|
||||
iValue = *(uint32_t *)((uint8_t *)from + pField->offset );
|
||||
}
|
||||
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
|
||||
if( !Q_equal( pField->multiplier, 1.0 ) )
|
||||
iValue /= pField->multiplier;
|
||||
|
||||
if( bSigned )
|
||||
*(int32_t *)((uint8_t *)to + pField->offset ) = iValue;
|
||||
else
|
||||
*(uint32_t *)((uint8_t *)to + pField->offset ) = iValue;
|
||||
#if defined __GNUC__ && __GNUC_MAJOR < 9 && !defined __clang__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
}
|
||||
else if( pField->flags & DT_FLOAT )
|
||||
{
|
||||
if( bChanged )
|
||||
{
|
||||
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
|
||||
if( bSigned )
|
||||
flValue = (int)iValue;
|
||||
else
|
||||
flValue = iValue;
|
||||
|
||||
if( !Q_equal( pField->multiplier, 1.0 ) )
|
||||
flValue = flValue / pField->multiplier;
|
||||
|
||||
if( !Q_equal( pField->post_multiplier, 1.0 ) )
|
||||
flValue = flValue * pField->post_multiplier;
|
||||
}
|
||||
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
|
||||
if( bSigned )
|
||||
flValue = (int)iValue;
|
||||
else
|
||||
{
|
||||
flValue = *(float *)((byte *)from + pField->offset );
|
||||
}
|
||||
flValue = iValue;
|
||||
|
||||
if( !Q_equal( pField->multiplier, 1.0 ) )
|
||||
flValue = flValue / pField->multiplier;
|
||||
|
||||
if( !Q_equal( pField->post_multiplier, 1.0 ) )
|
||||
flValue = flValue * pField->post_multiplier;
|
||||
|
||||
*(float *)((byte *)to + pField->offset ) = flValue;
|
||||
}
|
||||
else if( pField->flags & DT_ANGLE )
|
||||
{
|
||||
if( bChanged )
|
||||
{
|
||||
flAngle = MSG_ReadBitAngle( msg, pField->bits );
|
||||
}
|
||||
else
|
||||
{
|
||||
flAngle = *(float *)((byte *)from + pField->offset );
|
||||
}
|
||||
flAngle = MSG_ReadBitAngle( msg, pField->bits );
|
||||
*(float *)((byte *)to + pField->offset ) = flAngle;
|
||||
}
|
||||
else if( pField->flags & DT_TIMEWINDOW_8 )
|
||||
{
|
||||
if( bChanged )
|
||||
{
|
||||
bSigned = true; // timewindow is always signed
|
||||
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
|
||||
flTime = (timebase * 100.0 - iValue) / 100.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
flTime = *(float *)((byte *)from + pField->offset );
|
||||
}
|
||||
bSigned = true; // timewindow is always signed
|
||||
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
|
||||
flTime = (timebase * 100.0 - (int)iValue) / 100.0;
|
||||
|
||||
*(float *)((byte *)to + pField->offset ) = flTime;
|
||||
}
|
||||
else if( pField->flags & DT_TIMEWINDOW_BIG )
|
||||
{
|
||||
if( bChanged )
|
||||
{
|
||||
bSigned = true; // timewindow is always signed
|
||||
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
|
||||
bSigned = true; // timewindow is always signed
|
||||
iValue = MSG_ReadBitLong( msg, pField->bits, bSigned );
|
||||
|
||||
if( !Q_equal( pField->multiplier, 1.0 ) )
|
||||
flTime = ( timebase * pField->multiplier - iValue ) / pField->multiplier;
|
||||
else
|
||||
flTime = timebase - iValue;
|
||||
}
|
||||
if( !Q_equal( pField->multiplier, 1.0 ) )
|
||||
flTime = ( timebase * pField->multiplier - (int)iValue ) / pField->multiplier;
|
||||
else
|
||||
{
|
||||
flTime = *(float *)((byte *)from + pField->offset );
|
||||
}
|
||||
flTime = timebase - (int)iValue;
|
||||
|
||||
*(float *)((byte *)to + pField->offset ) = flTime;
|
||||
}
|
||||
else if( pField->flags & DT_STRING )
|
||||
{
|
||||
if( bChanged )
|
||||
{
|
||||
pStr = MSG_ReadString( msg );
|
||||
}
|
||||
else
|
||||
{
|
||||
pStr = (char *)((byte *)from + pField->offset );
|
||||
}
|
||||
|
||||
pStr = MSG_ReadString( msg );
|
||||
pOut = (char *)((byte *)to + pField->offset );
|
||||
Q_strncpy( pOut, pStr, pField->size );
|
||||
}
|
||||
return bChanged;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1636,6 +1605,7 @@ void MSG_ReadClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, d
|
||||
delta_t *pField;
|
||||
delta_info_t *dt;
|
||||
int i;
|
||||
qboolean noChanges;
|
||||
|
||||
dt = Delta_FindStruct( "clientdata_t" );
|
||||
Assert( dt && dt->bInitialized );
|
||||
@@ -1643,15 +1613,14 @@ void MSG_ReadClientData( sizebuf_t *msg, clientdata_t *from, clientdata_t *to, d
|
||||
pField = dt->pFields;
|
||||
Assert( pField != NULL );
|
||||
|
||||
*to = *from;
|
||||
|
||||
if( !cls.legacymode && !MSG_ReadOneBit( msg ))
|
||||
return; // we have no changes
|
||||
noChanges = !cls.legacymode && !MSG_ReadOneBit( msg );
|
||||
|
||||
// process fields
|
||||
for( i = 0; i < dt->numFields; i++, pField++ )
|
||||
{
|
||||
Delta_ReadField( msg, pField, from, to, timebase );
|
||||
if( noChanges )
|
||||
Delta_CopyField( pField, from, to, timebase );
|
||||
else Delta_ReadField( msg, pField, from, to, timebase );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1722,8 +1691,6 @@ void MSG_ReadWeaponData( sizebuf_t *msg, weapon_data_t *from, weapon_data_t *to,
|
||||
pField = dt->pFields;
|
||||
Assert( pField != NULL );
|
||||
|
||||
*to = *from;
|
||||
|
||||
// process fields
|
||||
for( i = 0; i < dt->numFields; i++, pField++ )
|
||||
{
|
||||
@@ -1909,7 +1876,7 @@ qboolean MSG_ReadDeltaEntity( sizebuf_t *msg, entity_state_t *from, entity_state
|
||||
from = &cl.instanced_baseline[baseline_offset];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// g-cont. probably is redundant
|
||||
*to = *from;
|
||||
|
||||
|
||||
@@ -1382,10 +1382,10 @@ qboolean NET_BufferToBufferDecompress( byte *dest, uint *destLen, byte *source,
|
||||
|
||||
/*
|
||||
====================
|
||||
NET_Isocket
|
||||
NET_IPSocket
|
||||
====================
|
||||
*/
|
||||
static int NET_Isocket( const char *net_interface, int port, qboolean multicast )
|
||||
static int NET_IPSocket( const char *net_interface, int port, qboolean multicast )
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
int err, net_socket;
|
||||
@@ -1396,7 +1396,7 @@ static int NET_Isocket( const char *net_interface, int port, qboolean multicast
|
||||
{
|
||||
err = WSAGetLastError();
|
||||
if( err != WSAEAFNOSUPPORT )
|
||||
Con_DPrintf( S_WARN "NET_UDsocket: port: %d socket: %s\n", port, NET_ErrorString( ));
|
||||
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d socket: %s\n", port, NET_ErrorString( ));
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
@@ -1404,7 +1404,7 @@ static int NET_Isocket( const char *net_interface, int port, qboolean multicast
|
||||
{
|
||||
struct timeval timeout;
|
||||
|
||||
Con_DPrintf( S_WARN "NET_UDsocket: port: %d ioctl FIONBIO: %s\n", port, NET_ErrorString( ));
|
||||
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d ioctl FIONBIO: %s\n", port, NET_ErrorString( ));
|
||||
// try timeout instead of NBIO
|
||||
timeout.tv_sec = timeout.tv_usec = 0;
|
||||
setsockopt( net_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));
|
||||
@@ -1413,14 +1413,14 @@ static int NET_Isocket( const char *net_interface, int port, qboolean multicast
|
||||
// make it broadcast capable
|
||||
if( NET_IsSocketError( setsockopt( net_socket, SOL_SOCKET, SO_BROADCAST, (char *)&_true, sizeof( _true ) ) ) )
|
||||
{
|
||||
Con_DPrintf( S_WARN "NET_UDsocket: port: %d setsockopt SO_BROADCAST: %s\n", port, NET_ErrorString( ));
|
||||
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d setsockopt SO_BROADCAST: %s\n", port, NET_ErrorString( ));
|
||||
}
|
||||
|
||||
if( Sys_CheckParm( "-reuse" ) || multicast )
|
||||
{
|
||||
if( NET_IsSocketError( setsockopt( net_socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&optval, sizeof( optval )) ) )
|
||||
{
|
||||
Con_DPrintf( S_WARN "NET_UDsocket: port: %d setsockopt SO_REUSEADDR: %s\n", port, NET_ErrorString( ));
|
||||
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d setsockopt SO_REUSEADDR: %s\n", port, NET_ErrorString( ));
|
||||
closesocket( net_socket );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
@@ -1435,7 +1435,7 @@ static int NET_Isocket( const char *net_interface, int port, qboolean multicast
|
||||
{
|
||||
err = WSAGetLastError();
|
||||
if( err != WSAENOPROTOOPT )
|
||||
Con_Printf( S_WARN "NET_UDsocket: port: %d setsockopt IP_TOS: %s\n", port, NET_ErrorString( ));
|
||||
Con_Printf( S_WARN "NET_UDPSocket: port: %d setsockopt IP_TOS: %s\n", port, NET_ErrorString( ));
|
||||
closesocket( net_socket );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
@@ -1452,7 +1452,7 @@ static int NET_Isocket( const char *net_interface, int port, qboolean multicast
|
||||
|
||||
if( NET_IsSocketError( bind( net_socket, (void *)&addr, sizeof( addr )) ) )
|
||||
{
|
||||
Con_DPrintf( S_WARN "NET_UDsocket: port: %d bind: %s\n", port, NET_ErrorString( ));
|
||||
Con_DPrintf( S_WARN "NET_UDPSocket: port: %d bind: %s\n", port, NET_ErrorString( ));
|
||||
closesocket( net_socket );
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
@@ -1461,7 +1461,7 @@ static int NET_Isocket( const char *net_interface, int port, qboolean multicast
|
||||
{
|
||||
optval = 1;
|
||||
if( NET_IsSocketError( setsockopt( net_socket, IPPROTO_IP, IP_MULTICAST_LOOP, (const char *)&optval, sizeof( optval )) ) )
|
||||
Con_DPrintf( S_WARN "NET_UDsocket: port %d setsockopt IP_MULTICAST_LOOP: %s\n", port, NET_ErrorString( ));
|
||||
Con_DPrintf( S_WARN "NET_UDPSocket: port %d setsockopt IP_MULTICAST_LOOP: %s\n", port, NET_ErrorString( ));
|
||||
}
|
||||
|
||||
return net_socket;
|
||||
@@ -1481,7 +1481,7 @@ static void NET_OpenIP( void )
|
||||
port = net_iphostport->value;
|
||||
if( !port ) port = net_hostport->value;
|
||||
if( !port ) port = PORT_SERVER; // forcing to default
|
||||
net.ip_sockets[NS_SERVER] = NET_Isocket( net_ipname->string, port, false );
|
||||
net.ip_sockets[NS_SERVER] = NET_IPSocket( net_ipname->string, port, false );
|
||||
|
||||
if( !NET_IsSocketValid( net.ip_sockets[NS_SERVER] ) && Host_IsDedicated() )
|
||||
Host_Error( "Couldn't allocate dedicated server IP port %d.\n", port );
|
||||
@@ -1496,10 +1496,10 @@ static void NET_OpenIP( void )
|
||||
port = net_ipclientport->value;
|
||||
if( !port ) port = net_clientport->value;
|
||||
if( !port ) port = PORT_ANY; // forcing to default
|
||||
net.ip_sockets[NS_CLIENT] = NET_Isocket( net_ipname->string, port, false );
|
||||
net.ip_sockets[NS_CLIENT] = NET_IPSocket( net_ipname->string, port, false );
|
||||
|
||||
if( !NET_IsSocketValid( net.ip_sockets[NS_CLIENT] ) )
|
||||
net.ip_sockets[NS_CLIENT] = NET_Isocket( net_ipname->string, PORT_ANY, false );
|
||||
net.ip_sockets[NS_CLIENT] = NET_IPSocket( net_ipname->string, PORT_ANY, false );
|
||||
cl_port = port;
|
||||
}
|
||||
}
|
||||
@@ -1693,15 +1693,15 @@ void NET_Init( void )
|
||||
|
||||
if( net.initialized ) return;
|
||||
|
||||
net_clockwindow = Cvar_Get( "clockwindow", "0.5", 0, "timewindow to execute client moves" );
|
||||
net_clockwindow = Cvar_Get( "clockwindow", "0.5", FCVAR_PRIVILEGED, "timewindow to execute client moves" );
|
||||
net_address = Cvar_Get( "net_address", "0", FCVAR_READ_ONLY, "contain local address of current client" );
|
||||
net_ipname = Cvar_Get( "ip", "localhost", FCVAR_READ_ONLY, "network ip address" );
|
||||
net_iphostport = Cvar_Get( "ip_hostport", "0", FCVAR_READ_ONLY, "network ip host port" );
|
||||
net_hostport = Cvar_Get( "hostport", va( "%i", PORT_SERVER ), FCVAR_READ_ONLY, "network default host port" );
|
||||
net_ipclientport = Cvar_Get( "ip_clientport", "0", FCVAR_READ_ONLY, "network ip client port" );
|
||||
net_clientport = Cvar_Get( "clientport", va( "%i", PORT_CLIENT ), FCVAR_READ_ONLY, "network default client port" );
|
||||
net_fakelag = Cvar_Get( "fakelag", "0", 0, "lag all incoming network data (including loopback) by xxx ms." );
|
||||
net_fakeloss = Cvar_Get( "fakeloss", "0", 0, "act like we dropped the packet this % of the time." );
|
||||
net_fakelag = Cvar_Get( "fakelag", "0", FCVAR_PRIVILEGED, "lag all incoming network data (including loopback) by xxx ms." );
|
||||
net_fakeloss = Cvar_Get( "fakeloss", "0", FCVAR_PRIVILEGED, "act like we dropped the packet this % of the time." );
|
||||
|
||||
// prepare some network data
|
||||
for( i = 0; i < NS_COUNT; i++ )
|
||||
@@ -2543,10 +2543,10 @@ void HTTP_Init( void )
|
||||
|
||||
http.first_file = http.last_file = NULL;
|
||||
|
||||
Cmd_AddCommand("http_download", &HTTP_Download_f, "add file to download queue");
|
||||
Cmd_AddCommand("http_skip", &HTTP_Skip_f, "skip current download server");
|
||||
Cmd_AddCommand("http_cancel", &HTTP_Cancel_f, "cancel current download");
|
||||
Cmd_AddCommand("http_clear", &HTTP_Clear_f, "cancel all downloads");
|
||||
Cmd_AddRestrictedCommand("http_download", &HTTP_Download_f, "add file to download queue");
|
||||
Cmd_AddRestrictedCommand("http_skip", &HTTP_Skip_f, "skip current download server");
|
||||
Cmd_AddRestrictedCommand("http_cancel", &HTTP_Cancel_f, "cancel current download");
|
||||
Cmd_AddRestrictedCommand("http_clear", &HTTP_Clear_f, "cancel all downloads");
|
||||
Cmd_AddCommand("http_list", &HTTP_List_f, "list all queued downloads");
|
||||
Cmd_AddCommand("http_addcustomserver", &HTTP_AddCustomServer_f, "add custom fastdl server");
|
||||
http_useragent = Cvar_Get( "http_useragent", "xash3d", FCVAR_ARCHIVE, "User-Agent string" );
|
||||
|
||||
@@ -69,8 +69,7 @@ GNU General Public License for more details.
|
||||
// bytes will be stripped by the networking channel layer
|
||||
#define NET_MAX_MESSAGE PAD_NUMBER(( NET_MAX_PAYLOAD + HEADER_BYTES ), 16 )
|
||||
|
||||
#define MASTERSERVER_ADR "ms.xash.su:27010"
|
||||
#define MASTERSERVER_ADR2 "ms2.xash.su:27010"
|
||||
#define MASTERSERVER_ADR "mentality.rip:27010"
|
||||
#define MS_SCAN_REQUEST "1\xFF" "0.0.0.0:0\0"
|
||||
|
||||
#define PORT_MASTER 27010
|
||||
|
||||
@@ -110,13 +110,7 @@ GNU General Public License for more details.
|
||||
#define MAX_EVENTS (1<<MAX_EVENT_BITS) // 10 bits == 1024 events (the original Half-Life limit)
|
||||
|
||||
#define MAX_MODEL_BITS 12 // 12 bits == 4096 models
|
||||
#define MAX_SUPPORTED_MODELS (1<<MAX_MODEL_BITS)
|
||||
|
||||
#ifdef SUPPORT_BSP2_FORMAT
|
||||
#define MAX_MODELS MAX_SUPPORTED_MODELS // because BSP2 contain too much embedded bsp-models
|
||||
#else
|
||||
#define MAX_MODELS 1024 // g-cont. reduce the memory without breaking proto
|
||||
#endif
|
||||
#define MAX_MODELS (1<<MAX_MODEL_BITS)
|
||||
|
||||
#define MAX_SOUND_BITS 11
|
||||
#define MAX_SOUNDS (1<<MAX_SOUND_BITS) // 11 bits == 2048 sounds
|
||||
@@ -187,7 +181,6 @@ GNU General Public License for more details.
|
||||
#undef MAX_VISIBLE_PACKET
|
||||
#undef MAX_VISIBLE_PACKET_VIS_BYTES
|
||||
#undef MAX_EVENTS
|
||||
#undef MAX_SUPPORTED_MODELS
|
||||
#undef MAX_MODELS
|
||||
#undef MAX_SOUNDS
|
||||
#undef MAX_CUSTOM
|
||||
@@ -198,17 +191,10 @@ GNU General Public License for more details.
|
||||
// memory reduced protocol, not for use in multiplayer (but still compatible)
|
||||
#define MAX_VISIBLE_PACKET 128
|
||||
#define MAX_VISIBLE_PACKET_VIS_BYTES ((MAX_VISIBLE_PACKET + 7) / 8)
|
||||
|
||||
#define MAX_EVENTS 128
|
||||
|
||||
#define MAX_SUPPORTED_MODELS 512
|
||||
|
||||
#define MAX_MODELS 512
|
||||
|
||||
|
||||
#define MAX_SOUNDS 512
|
||||
#define MAX_CUSTOM 32
|
||||
|
||||
#define MAX_DLIGHTS 16 // dynamic lights (rendered per one frame)
|
||||
#define MAX_ELIGHTS 32 // entity only point lights
|
||||
#define MAX_RENDER_DECALS 64 // max rendering decals per a level
|
||||
@@ -217,20 +203,14 @@ GNU General Public License for more details.
|
||||
#undef MAX_VISIBLE_PACKET
|
||||
#undef MAX_VISIBLE_PACKET_VIS_BYTES
|
||||
#undef MAX_EVENTS
|
||||
#undef MAX_SUPPORTED_MODELS
|
||||
#undef MAX_MODELS
|
||||
#undef MAX_CUSTOM
|
||||
#undef MAX_RENDER_DECALS
|
||||
#undef MAX_RESOURCES
|
||||
#define MAX_VISIBLE_PACKET 256
|
||||
#define MAX_VISIBLE_PACKET_VIS_BYTES ((MAX_VISIBLE_PACKET + 7) / 8)
|
||||
|
||||
#define MAX_EVENTS 128
|
||||
|
||||
#define MAX_SUPPORTED_MODELS 1024
|
||||
|
||||
#define MAX_MODELS 1024
|
||||
|
||||
#define MAX_CUSTOM 512
|
||||
#define MAX_RENDER_DECALS 128
|
||||
#define MAX_RESOURCES 1024
|
||||
@@ -319,11 +299,6 @@ extern const char *clc_strings[clc_lastmsg+1];
|
||||
#define MAX_LEGACY_ENTITY_BITS 12
|
||||
#define MAX_LEGACY_WEAPON_BITS 5
|
||||
#define MAX_LEGACY_MODEL_BITS 11
|
||||
#if XASH_LOW_MEMORY >= 1
|
||||
#define MAX_LEGACY_SERVERS 32
|
||||
#else
|
||||
#define MAX_LEGACY_SERVERS 256
|
||||
#endif
|
||||
#define MAX_LEGACY_TOTAL_CMDS 28 // magic number from old engine's sv_client.c
|
||||
|
||||
#endif//NET_PROTOCOL_H
|
||||
|
||||
@@ -1247,7 +1247,7 @@ qboolean Sequence_ParseSentenceLine( void )
|
||||
if( *c )
|
||||
*c = 0;
|
||||
|
||||
strcpy( groupName, fullgroup );
|
||||
Q_strncpy( groupName, fullgroup, sizeof( groupName ));
|
||||
|
||||
len = Sequence_GetLine( data, sizeof( data ) );
|
||||
lastCharacterPos = len - 1;
|
||||
|
||||
@@ -278,3 +278,25 @@ void FS_FreeStream( stream_t *stream )
|
||||
|
||||
stream->format->freefunc( stream );
|
||||
}
|
||||
|
||||
#if XASH_ENGINE_TESTS
|
||||
|
||||
#define IMPLEMENT_SOUNDLIB_FUZZ_TARGET( export, target ) \
|
||||
int EXPORT export( const uint8_t *Data, size_t Size ) \
|
||||
{ \
|
||||
wavdata_t *wav; \
|
||||
host.type = HOST_NORMAL; \
|
||||
Memory_Init(); \
|
||||
Sound_Init(); \
|
||||
if( target( "#internal", Data, Size )) \
|
||||
{ \
|
||||
wav = SoundPack(); \
|
||||
FS_FreeSound( wav ); \
|
||||
} \
|
||||
Sound_Shutdown(); \
|
||||
return 0; \
|
||||
} \
|
||||
|
||||
IMPLEMENT_SOUNDLIB_FUZZ_TARGET( Fuzz_Sound_LoadMPG, Sound_LoadMPG )
|
||||
IMPLEMENT_SOUNDLIB_FUZZ_TARGET( Fuzz_Sound_LoadWAV, Sound_LoadWAV )
|
||||
#endif
|
||||
|
||||
@@ -17,6 +17,8 @@ GNU General Public License for more details.
|
||||
#if XASH_ANDROID
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if !XASH_WIN32 && !XASH_MOBILE_PLATFORM
|
||||
#define XASH_COLORIZE_CONSOLE
|
||||
@@ -95,6 +97,20 @@ int Sys_LogFileNo( void )
|
||||
return s_ld.logfileno;
|
||||
}
|
||||
|
||||
static void Sys_FlushStdout( void )
|
||||
{
|
||||
// never printing anything to stdout on mobiles
|
||||
#if !XASH_MOBILE_PLATFORM
|
||||
fflush( stdout );
|
||||
#endif
|
||||
}
|
||||
|
||||
static void Sys_FlushLogfile( void )
|
||||
{
|
||||
if( s_ld.logfile )
|
||||
fflush( s_ld.logfile );
|
||||
}
|
||||
|
||||
void Sys_InitLog( void )
|
||||
{
|
||||
const char *mode;
|
||||
@@ -113,11 +129,16 @@ void Sys_InitLog( void )
|
||||
if( s_ld.log_active )
|
||||
{
|
||||
s_ld.logfile = fopen( s_ld.log_path, mode );
|
||||
if( !s_ld.logfile ) Con_Reportf( S_ERROR "Sys_InitLog: can't create log file %s\n", s_ld.log_path );
|
||||
|
||||
fprintf( s_ld.logfile, "=================================================================================\n" );
|
||||
fprintf( s_ld.logfile, "\t%s (build %i) started at %s\n", s_ld.title, Q_buildnum(), Q_timestamp( TIME_FULL ));
|
||||
fprintf( s_ld.logfile, "=================================================================================\n" );
|
||||
if( !s_ld.logfile )
|
||||
{
|
||||
Con_Reportf( S_ERROR "Sys_InitLog: can't create log file %s: %s\n", s_ld.log_path, strerror( errno ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf( s_ld.logfile, "=================================================================================\n" );
|
||||
fprintf( s_ld.logfile, "\t%s (build %i) started at %s\n", s_ld.title, Q_buildnum(), Q_timestamp( TIME_FULL ));
|
||||
fprintf( s_ld.logfile, "=================================================================================\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,6 +161,8 @@ void Sys_CloseLog( void )
|
||||
break;
|
||||
}
|
||||
|
||||
Sys_FlushStdout(); // flush to stdout to ensure all data was written
|
||||
|
||||
if( s_ld.logfile )
|
||||
{
|
||||
fprintf( s_ld.logfile, "\n");
|
||||
@@ -153,6 +176,50 @@ void Sys_CloseLog( void )
|
||||
}
|
||||
}
|
||||
|
||||
static void Sys_PrintColorized( const char *logtime, const char *msg )
|
||||
{
|
||||
char colored[4096];
|
||||
int len = 0;
|
||||
|
||||
while( *msg && ( len < 4090 ) )
|
||||
{
|
||||
static char q3ToAnsi[ 8 ] =
|
||||
{
|
||||
'0', // COLOR_BLACK
|
||||
'1', // COLOR_RED
|
||||
'2', // COLOR_GREEN
|
||||
'3', // COLOR_YELLOW
|
||||
'4', // COLOR_BLUE
|
||||
'6', // COLOR_CYAN
|
||||
'5', // COLOR_MAGENTA
|
||||
0 // COLOR_WHITE
|
||||
};
|
||||
|
||||
if( IsColorString( msg ) )
|
||||
{
|
||||
int color;
|
||||
|
||||
msg++;
|
||||
color = q3ToAnsi[ *msg++ % 8 ];
|
||||
colored[len++] = '\033';
|
||||
colored[len++] = '[';
|
||||
if( color )
|
||||
{
|
||||
colored[len++] = '3';
|
||||
colored[len++] = color;
|
||||
}
|
||||
else
|
||||
colored[len++] = '0';
|
||||
colored[len++] = 'm';
|
||||
}
|
||||
else
|
||||
colored[len++] = *msg++;
|
||||
}
|
||||
colored[len] = 0;
|
||||
|
||||
printf( "\033[34m%s\033[0m%s\033[0m", logtime, colored );
|
||||
}
|
||||
|
||||
void Sys_PrintLog( const char *pMsg )
|
||||
{
|
||||
time_t crt_time;
|
||||
@@ -162,6 +229,8 @@ void Sys_PrintLog( const char *pMsg )
|
||||
|
||||
time( &crt_time );
|
||||
crt_tm = localtime( &crt_time );
|
||||
|
||||
// platform-specific output
|
||||
#if XASH_ANDROID && !XASH_DEDICATED
|
||||
__android_log_print( ANDROID_LOG_DEBUG, "Xash", "%s", pMsg );
|
||||
#endif
|
||||
@@ -171,58 +240,17 @@ void Sys_PrintLog( const char *pMsg )
|
||||
IOS_Log(pMsg);
|
||||
#endif
|
||||
|
||||
|
||||
if( !lastchar || lastchar == '\n')
|
||||
strftime( logtime, sizeof( logtime ), "[%H:%M:%S] ", crt_tm ); //short time
|
||||
|
||||
// spew to stdout, except mobiles
|
||||
#if !XASH_MOBILE_PLATFORM
|
||||
#ifdef XASH_COLORIZE_CONSOLE
|
||||
{
|
||||
char colored[4096];
|
||||
const char *msg = pMsg;
|
||||
int len = 0;
|
||||
while( *msg && ( len < 4090 ) )
|
||||
{
|
||||
static char q3ToAnsi[ 8 ] =
|
||||
{
|
||||
'0', // COLOR_BLACK
|
||||
'1', // COLOR_RED
|
||||
'2', // COLOR_GREEN
|
||||
'3', // COLOR_YELLOW
|
||||
'4', // COLOR_BLUE
|
||||
'6', // COLOR_CYAN
|
||||
'5', // COLOR_MAGENTA
|
||||
0 // COLOR_WHITE
|
||||
};
|
||||
|
||||
if( IsColorString( msg ) )
|
||||
{
|
||||
int color;
|
||||
|
||||
msg++;
|
||||
color = q3ToAnsi[ *msg++ % 8 ];
|
||||
colored[len++] = '\033';
|
||||
colored[len++] = '[';
|
||||
if( color )
|
||||
{
|
||||
colored[len++] = '3';
|
||||
colored[len++] = color;
|
||||
}
|
||||
else
|
||||
colored[len++] = '0';
|
||||
colored[len++] = 'm';
|
||||
}
|
||||
else
|
||||
colored[len++] = *msg++;
|
||||
}
|
||||
colored[len] = 0;
|
||||
printf( "\033[34m%s\033[0m%s\033[0m", logtime, colored );
|
||||
|
||||
}
|
||||
Sys_PrintColorized( logtime, pMsg );
|
||||
#else
|
||||
#if !XASH_ANDROID || XASH_DEDICATED
|
||||
printf( "%s %s", logtime, pMsg );
|
||||
fflush( stdout );
|
||||
#endif
|
||||
Sys_FlushStdout();
|
||||
#endif
|
||||
|
||||
// save last char to detect when line was not ended
|
||||
@@ -235,7 +263,7 @@ void Sys_PrintLog( const char *pMsg )
|
||||
strftime( logtime, sizeof( logtime ), "[%Y:%m:%d|%H:%M:%S]", crt_tm ); //full time
|
||||
|
||||
fprintf( s_ld.logfile, "%s %s", logtime, pMsg );
|
||||
fflush( s_ld.logfile );
|
||||
Sys_FlushLogfile();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -34,6 +34,8 @@ GNU General Public License for more details.
|
||||
|
||||
#include "menu_int.h" // _UPDATE_PAGE macro
|
||||
|
||||
#include "library.h"
|
||||
|
||||
qboolean error_on_exit = false; // arg for exit();
|
||||
#define DEBUG_BREAK
|
||||
|
||||
@@ -81,18 +83,6 @@ char *Sys_GetClipboardData( void )
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Sys_SetClipboardData
|
||||
|
||||
write screenshot into clipboard
|
||||
================
|
||||
*/
|
||||
void Sys_SetClipboardData( const char *buffer, size_t size )
|
||||
{
|
||||
Platform_SetClipboardText( buffer, size );
|
||||
}
|
||||
#endif // XASH_DEDICATED
|
||||
|
||||
/*
|
||||
@@ -107,7 +97,7 @@ void Sys_Sleep( int msec )
|
||||
if( !msec )
|
||||
return;
|
||||
|
||||
msec = min( msec, 1000 );
|
||||
msec = Q_min( msec, 1000 );
|
||||
Platform_Sleep( msec );
|
||||
}
|
||||
|
||||
@@ -284,7 +274,8 @@ qboolean Sys_LoadLibrary( dll_info_t *dll )
|
||||
*func->func = NULL;
|
||||
}
|
||||
|
||||
if( !dll->link ) dll->link = LoadLibrary ( dll->name ); // environment pathes
|
||||
if( !dll->link )
|
||||
dll->link = COM_LoadLibrary( dll->name, false, true ); // environment pathes
|
||||
|
||||
// no DLL found
|
||||
if( !dll->link )
|
||||
@@ -319,7 +310,7 @@ void* Sys_GetProcAddress( dll_info_t *dll, const char* name )
|
||||
if( !dll || !dll->link ) // invalid desc
|
||||
return NULL;
|
||||
|
||||
return (void *)GetProcAddress( dll->link, name );
|
||||
return (void *)COM_GetProcAddress( dll->link, name );
|
||||
}
|
||||
|
||||
qboolean Sys_FreeLibrary( dll_info_t *dll )
|
||||
@@ -336,7 +327,7 @@ qboolean Sys_FreeLibrary( dll_info_t *dll )
|
||||
}
|
||||
else Con_Reportf( "Sys_FreeLibrary: Unloading %s\n", dll->name );
|
||||
|
||||
FreeLibrary( dll->link );
|
||||
COM_FreeLibrary( dll->link );
|
||||
dll->link = NULL;
|
||||
|
||||
return true;
|
||||
@@ -353,9 +344,6 @@ void Sys_WaitForQuit( void )
|
||||
{
|
||||
#if XASH_WIN32
|
||||
MSG msg;
|
||||
|
||||
Wcon_RegisterHotkeys();
|
||||
|
||||
msg.message = 0;
|
||||
|
||||
// wait for the user to quit
|
||||
@@ -531,10 +519,6 @@ void Sys_Print( const char *pMsg )
|
||||
{
|
||||
i++; // skip console pseudo graph
|
||||
}
|
||||
else if( IsColorString( &msg[i] ))
|
||||
{
|
||||
i++; // skip color prefix
|
||||
}
|
||||
else
|
||||
{
|
||||
if( msg[i] == '\1' || msg[i] == '\2' || msg[i] == '\3' )
|
||||
|
||||
@@ -51,7 +51,7 @@ char *Sys_GetClipboardData( void );
|
||||
const char *Sys_GetCurrentUser( void );
|
||||
int Sys_CheckParm( const char *parm );
|
||||
void Sys_Warn( const char *format, ... ) _format( 1 );
|
||||
void Sys_Error( const char *error, ... ) _format( 1 );
|
||||
void Sys_Error( const char *error, ... ) _format( 1 ) NORETURN;
|
||||
qboolean Sys_LoadLibrary( dll_info_t *dll );
|
||||
void* Sys_GetProcAddress( dll_info_t *dll, const char* name );
|
||||
qboolean Sys_FreeLibrary( dll_info_t *dll );
|
||||
@@ -59,7 +59,6 @@ void Sys_ParseCommandLine( int argc, char **argv );
|
||||
void Sys_MergeCommandLine( void );
|
||||
void Sys_SetupCrashHandler( void );
|
||||
void Sys_RestoreCrashHandler( void );
|
||||
void Sys_SetClipboardData( const char *buffer, size_t size );
|
||||
#define Sys_GetParmFromCmdLine( parm, out ) _Sys_GetParmFromCmdLine( parm, out, sizeof( out ))
|
||||
qboolean _Sys_GetParmFromCmdLine( const char *parm, char *out, size_t size );
|
||||
qboolean Sys_GetIntFromCmdLine( const char *parm, int *out );
|
||||
@@ -89,10 +88,9 @@ void Wcon_ShowConsole( qboolean show );
|
||||
void Wcon_CreateConsole( void );
|
||||
void Wcon_DestroyConsole( void );
|
||||
void Wcon_DisableInput( void );
|
||||
void Wcon_Clear( void );
|
||||
char *Wcon_Input( void );
|
||||
void Wcon_WinPrint( const char *pMsg );
|
||||
void Wcon_RegisterHotkeys( void );
|
||||
void Wcon_SetStatus( const char *pStatus );
|
||||
#endif
|
||||
|
||||
// text messages
|
||||
|
||||
@@ -11,19 +11,32 @@ struct tests_stats_s
|
||||
|
||||
extern struct tests_stats_s tests_stats;
|
||||
|
||||
#define TRUN( x ) Msg( "Running " #x "\n" ); x
|
||||
#define TRUN( x ) Msg( "Starting " #x "\n" ); \
|
||||
x; \
|
||||
Msg( "Finished " #x "\n" )
|
||||
|
||||
#define TASSERT( exp ) \
|
||||
if(!( exp )) \
|
||||
#define _TASSERT( exp, msg ) \
|
||||
if( exp ) \
|
||||
{ \
|
||||
tests_stats.failed++; \
|
||||
Msg( S_ERROR "assert failed at %s:%i\n", __FILE__, __LINE__ ); \
|
||||
msg; \
|
||||
} \
|
||||
else tests_stats.passed++;
|
||||
|
||||
#define TASSERT( exp ) \
|
||||
_TASSERT( !(exp), Msg( S_ERROR "assert failed at %s:%i\n", __FILE__, __LINE__ ) )
|
||||
#define TASSERT_EQi( val1, val2 ) \
|
||||
_TASSERT( ( val1 ) != ( val2 ), Msg( S_ERROR "assert failed at %s:%i, \"%d\" != \"%d\"\n", __FILE__, __LINE__, #val1, #val2 ))
|
||||
#define TASSERT_STR( str1, str2 ) \
|
||||
_TASSERT( Q_strcmp(( str1 ), ( str2 )), Msg( S_ERROR "assert failed at %s:%i, \"%s\" != \"%s\"\n", __FILE__, __LINE__, ( str1 ), ( str2 )))
|
||||
|
||||
void Test_RunImagelib( void );
|
||||
void Test_RunLibCommon( void );
|
||||
void Test_RunCommon( void );
|
||||
void Test_RunCmd( void );
|
||||
void Test_RunCvar( void );
|
||||
void Test_RunCon( void );
|
||||
void Test_RunVOX( void );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
39
engine/cursor_type.h
Normal file
39
engine/cursor_type.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
cursor_type.h - enumeration of possible mouse cursor types
|
||||
Copyright (C) 2022 FWGS Team
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef CURSOR_TYPE_H
|
||||
#define CURSOR_TYPE_H
|
||||
|
||||
typedef enum
|
||||
{
|
||||
dc_user,
|
||||
dc_none,
|
||||
dc_arrow,
|
||||
dc_ibeam,
|
||||
dc_hourglass,
|
||||
dc_crosshair,
|
||||
dc_up,
|
||||
dc_sizenwse,
|
||||
dc_sizenesw,
|
||||
dc_sizewe,
|
||||
dc_sizens,
|
||||
dc_sizeall,
|
||||
dc_no,
|
||||
dc_hand,
|
||||
dc_last
|
||||
} VGUI_DefaultCursor;
|
||||
|
||||
#endif
|
||||
@@ -278,6 +278,9 @@ typedef struct enginefuncs_s
|
||||
void (*pfnQueryClientCvarValue)( const edict_t *player, const char *cvarName );
|
||||
void (*pfnQueryClientCvarValue2)( const edict_t *player, const char *cvarName, int requestID );
|
||||
int (*pfnCheckParm)( char *parm, char **ppnext );
|
||||
|
||||
// added in 8279
|
||||
edict_t* (*pfnPEntityOfEntIndexAllEntities)( int iEntIndex );
|
||||
} enginefuncs_t;
|
||||
// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 138
|
||||
|
||||
|
||||
35
engine/key_modifiers.h
Normal file
35
engine/key_modifiers.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
key_modifiers.h - enumeration of possible key modifiers
|
||||
Copyright (C) 2022 FWGS Team
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef KEY_MODIFIERS_H
|
||||
#define KEY_MODIFIERS_H
|
||||
|
||||
typedef enum
|
||||
{
|
||||
KeyModifier_None = 0,
|
||||
KeyModifier_LeftShift = (1 << 0),
|
||||
KeyModifier_RightShift = (1 << 1),
|
||||
KeyModifier_LeftCtrl = (1 << 2),
|
||||
KeyModifier_RightCtrl = (1 << 3),
|
||||
KeyModifier_LeftAlt = (1 << 4),
|
||||
KeyModifier_RightAlt = (1 << 5),
|
||||
KeyModifier_LeftSuper = (1 << 6),
|
||||
KeyModifier_RightSuper = (1 << 7),
|
||||
KeyModifier_NumLock = (1 << 8),
|
||||
KeyModifier_CapsLock = (1 << 9)
|
||||
} key_modifier_t;
|
||||
|
||||
#endif
|
||||
@@ -21,9 +21,9 @@
|
||||
//
|
||||
#define K_TAB 9
|
||||
#define K_ENTER 13
|
||||
#define K_ESCAPE 27
|
||||
#define K_ESCAPE 27
|
||||
#define K_SPACE 32
|
||||
#define K_SCROLLOCK 70
|
||||
#define K_SCROLLOCK 70
|
||||
|
||||
// normal keys should be passed as lowercased ascii
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
#define K_KP_UPARROW 161
|
||||
#define K_KP_PGUP 162
|
||||
#define K_KP_LEFTARROW 163
|
||||
#define K_KP_5 164
|
||||
#define K_KP_5 164
|
||||
#define K_KP_RIGHTARROW 165
|
||||
#define K_KP_END 166
|
||||
#define K_KP_DOWNARROW 167
|
||||
@@ -71,8 +71,9 @@
|
||||
#define K_KP_MINUS 173
|
||||
#define K_KP_PLUS 174
|
||||
#define K_CAPSLOCK 175
|
||||
#define K_KP_NUMLOCK 176
|
||||
#define K_KP_MUL 176
|
||||
#define K_WIN 177
|
||||
#define K_KP_NUMLOCK 178
|
||||
|
||||
//
|
||||
// joystick buttons
|
||||
@@ -143,30 +144,30 @@
|
||||
#define K_AUX19 225
|
||||
#define K_DPAD_RIGHT K_AUX19
|
||||
|
||||
#define K_AUX20 226
|
||||
#define K_AUX21 227
|
||||
#define K_AUX22 228
|
||||
#define K_AUX23 229
|
||||
#define K_AUX24 230
|
||||
#define K_AUX25 231
|
||||
#define K_AUX26 232
|
||||
#define K_AUX27 233
|
||||
#define K_AUX28 234
|
||||
#define K_AUX29 235
|
||||
#define K_AUX30 236
|
||||
#define K_AUX31 237
|
||||
#define K_AUX32 238
|
||||
#define K_AUX20 226
|
||||
#define K_AUX21 227
|
||||
#define K_AUX22 228
|
||||
#define K_AUX23 229
|
||||
#define K_AUX24 230
|
||||
#define K_AUX25 231
|
||||
#define K_AUX26 232
|
||||
#define K_AUX27 233
|
||||
#define K_AUX28 234
|
||||
#define K_AUX29 235
|
||||
#define K_AUX30 236
|
||||
#define K_AUX31 237
|
||||
#define K_AUX32 238
|
||||
#define K_MWHEELDOWN 239
|
||||
#define K_MWHEELUP 240
|
||||
|
||||
#define K_PAUSE 255
|
||||
#define K_PAUSE 255
|
||||
|
||||
//
|
||||
// mouse buttons generate virtual keys
|
||||
//
|
||||
#define K_MOUSE1 241
|
||||
#define K_MOUSE2 243
|
||||
#define K_MOUSE3 242
|
||||
#define K_MOUSE2 242
|
||||
#define K_MOUSE3 243
|
||||
#define K_MOUSE4 244
|
||||
#define K_MOUSE5 245
|
||||
|
||||
|
||||
@@ -53,6 +53,11 @@ typedef struct ui_globalvars_s
|
||||
|
||||
struct ref_viewpass_s;
|
||||
|
||||
#if __GNUC__ == 3
|
||||
#undef NORETURN
|
||||
#define NORETURN
|
||||
#endif // GCC 3.x have problems with noreturn attribute on function pointer
|
||||
|
||||
typedef struct ui_enginefuncs_s
|
||||
{
|
||||
// image handlers
|
||||
@@ -87,10 +92,10 @@ typedef struct ui_enginefuncs_s
|
||||
const char* (*pfnCmd_Args)( void );
|
||||
|
||||
// debug messages (in-menu shows only notify)
|
||||
void (*Con_Printf)( const char *fmt, ... );
|
||||
void (*Con_DPrintf)( const char *fmt, ... );
|
||||
void (*Con_NPrintf)( int pos, const char *fmt, ... );
|
||||
void (*Con_NXPrintf)( struct con_nprint_s *info, const char *fmt, ... );
|
||||
void (*Con_Printf)( const char *fmt, ... ) _format( 1 );
|
||||
void (*Con_DPrintf)( const char *fmt, ... ) _format( 1 );
|
||||
void (*Con_NPrintf)( int pos, const char *fmt, ... ) _format( 2 );
|
||||
void (*Con_NXPrintf)( struct con_nprint_s *info, const char *fmt, ... ) _format( 2 );
|
||||
|
||||
// sound handlers
|
||||
void (*pfnPlayLocalSound)( const char *szSound );
|
||||
@@ -116,7 +121,7 @@ typedef struct ui_enginefuncs_s
|
||||
int (*CL_CreateVisibleEntity)( int type, struct cl_entity_s *ent );
|
||||
|
||||
// misc handlers
|
||||
void (*pfnHostError)( const char *szFmt, ... );
|
||||
void (*pfnHostError)( const char *szFmt, ... ) _format( 1 ) NORETURN;
|
||||
int (*pfnFileExists)( const char *filename, int gamedironly );
|
||||
void (*pfnGetGameDir)( char *szGetGameDir );
|
||||
|
||||
@@ -212,6 +217,8 @@ typedef struct ui_extendedfuncs_s {
|
||||
double (*pfnDoubleTime)( void );
|
||||
|
||||
char *(*pfnParseFile)( char *data, char *buf, const int size, unsigned int flags, int *len );
|
||||
|
||||
const char *(*pfnAdrToString)( const struct netadr_s a );
|
||||
} ui_extendedfuncs_t;
|
||||
|
||||
// deprecated export from old engine
|
||||
|
||||
@@ -776,17 +776,29 @@ void Platform_ShellExecute( const char *path, const char *parms )
|
||||
// no need to free jstr
|
||||
}
|
||||
|
||||
void Platform_GetClipboardText( char *buffer, size_t size )
|
||||
int Platform_GetClipboardText( char *buffer, size_t size )
|
||||
{
|
||||
// stub
|
||||
if( size ) buffer[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Platform_SetClipboardText( const char *buffer, size_t size )
|
||||
void Platform_SetClipboardText( const char *buffer )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
void Platform_SetCursorType( VGUI_DefaultCursor cursor )
|
||||
{
|
||||
// stub
|
||||
}
|
||||
|
||||
key_modifier_t Platform_GetKeyModifiers( void )
|
||||
{
|
||||
// stub
|
||||
return KeyModifier_None;
|
||||
}
|
||||
|
||||
void Platform_PreCreateMove( void )
|
||||
{
|
||||
// stub
|
||||
|
||||
@@ -34,7 +34,7 @@ void *ANDROID_LoadLibrary( const char *dllname )
|
||||
if( !libdir[i] )
|
||||
continue;
|
||||
|
||||
Q_snprintf( path, MAX_SYSPATH, "%s/lib%s"POSTFIX"."OS_LIB_EXT, libdir[i], dllname );
|
||||
Q_snprintf( path, MAX_SYSPATH, "%s/lib%s."OS_LIB_EXT, libdir[i], dllname );
|
||||
pHandle = dlopen( path, RTLD_LAZY );
|
||||
if( pHandle )
|
||||
return pHandle;
|
||||
@@ -51,7 +51,7 @@ void *ANDROID_LoadLibrary( const char *dllname )
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_snprintf( path, MAX_SYSPATH, "lib%s"POSTFIX"."OS_LIB_EXT, dllname );
|
||||
Q_snprintf( path, MAX_SYSPATH, "lib%s."OS_LIB_EXT, dllname );
|
||||
pHandle = dlopen( path, RTLD_LAZY );
|
||||
if( pHandle )
|
||||
return pHandle;
|
||||
|
||||
@@ -449,9 +449,9 @@ void Platfrom_MouseMove( float *yaw, float *pitch )
|
||||
|
||||
void Evdev_Init( void )
|
||||
{
|
||||
Cmd_AddCommand ("evdev_open", Evdev_OpenDevice_f, "Open event device");
|
||||
Cmd_AddCommand ("evdev_close", Evdev_CloseDevice_f, "Close event device");
|
||||
Cmd_AddCommand ("evdev_autodetect", Evdev_Autodetect_f, "Automaticly open mouses and keyboards");
|
||||
Cmd_AddRestrictedCommand ("evdev_open", Evdev_OpenDevice_f, "Open event device");
|
||||
Cmd_AddRestrictedCommand ("evdev_close", Evdev_CloseDevice_f, "Close event device");
|
||||
Cmd_AddRestrictedCommand ("evdev_autodetect", Evdev_Autodetect_f, "Automaticly open mouses and keyboards");
|
||||
#if XASH_INPUT == INPUT_EVDEV
|
||||
Evdev_Autodetect_f();
|
||||
#endif
|
||||
|
||||
@@ -66,7 +66,7 @@ qboolean SNDDMA_Init( void )
|
||||
|
||||
Sys_GetParmFromCmdLine( "-alsadev", device );
|
||||
|
||||
Cmd_AddCommand("pcm_pause", SND_Pause_f, "set pcm pause (debug)" );
|
||||
Cmd_AddRestrictedCommand("pcm_pause", SND_Pause_f, "set pcm pause (debug)" );
|
||||
|
||||
if( ( err = snd_pcm_open( &s_alsa.pcm_handle, device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ) ) < 0)
|
||||
{
|
||||
|
||||
@@ -20,6 +20,8 @@ GNU General Public License for more details.
|
||||
#include "common.h"
|
||||
#include "system.h"
|
||||
#include "defaults.h"
|
||||
#include "cursor_type.h"
|
||||
#include "key_modifiers.h"
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
@@ -45,6 +47,12 @@ const char *Android_LoadID( void );
|
||||
void Android_SaveID( const char *id );
|
||||
#endif
|
||||
|
||||
#if XASH_WIN32
|
||||
void Platform_UpdateStatusLine( void );
|
||||
#else
|
||||
static inline void Platform_UpdateStatusLine( void ) { }
|
||||
#endif
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
@@ -66,6 +74,7 @@ void*Platform_GetNativeObject( const char *name );
|
||||
int Platform_JoyInit( int numjoy ); // returns number of connected gamepads, negative if error
|
||||
// Text input
|
||||
void Platform_EnableTextInput( qboolean enable );
|
||||
key_modifier_t Platform_GetKeyModifiers( void );
|
||||
// System events
|
||||
void Platform_RunEvents( void );
|
||||
// Mouse
|
||||
@@ -73,9 +82,10 @@ void Platform_GetMousePos( int *x, int *y );
|
||||
void Platform_SetMousePos( int x, int y );
|
||||
void Platform_PreCreateMove( void );
|
||||
void Platform_MouseMove( float *x, float *y );
|
||||
void Platform_SetCursorType( VGUI_DefaultCursor type );
|
||||
// Clipboard
|
||||
void Platform_GetClipboardText( char *buffer, size_t size );
|
||||
void Platform_SetClipboardText( const char *buffer, size_t size );
|
||||
int Platform_GetClipboardText( char *buffer, size_t size );
|
||||
void Platform_SetClipboardText( const char *buffer );
|
||||
|
||||
#if XASH_SDL == 12
|
||||
#define SDL_SetWindowGrab( wnd, state ) SDL_WM_GrabInput( (state) )
|
||||
|
||||
@@ -15,8 +15,7 @@ GNU General Public License for more details.
|
||||
#define _GNU_SOURCE
|
||||
#include "platform/platform.h"
|
||||
#if XASH_LIB == LIB_POSIX
|
||||
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include "common.h"
|
||||
#include "library.h"
|
||||
#include "filesystem.h"
|
||||
@@ -25,6 +24,127 @@ GNU General Public License for more details.
|
||||
#include "platform/emscripten/lib_em.h"
|
||||
#include "platform/apple/lib_ios.h"
|
||||
|
||||
#define ENABLE_REFCOUNT_CHECK
|
||||
|
||||
#ifdef ENABLE_REFCOUNT_CHECK
|
||||
struct dll_t
|
||||
{
|
||||
void *hInstance;
|
||||
char name[256];
|
||||
char file[256];
|
||||
int line;
|
||||
|
||||
int refcount;
|
||||
struct dll_t *next;
|
||||
};
|
||||
|
||||
struct dll_t *dlls = NULL;
|
||||
|
||||
void *DLL_FindInListAndIncrement( const char *name )
|
||||
{
|
||||
struct dll_t *dll;
|
||||
|
||||
for( dll = dlls; dll; dll = dll->next )
|
||||
{
|
||||
if( !Q_strcmp( name, dll->name ))
|
||||
{
|
||||
dll->refcount++;
|
||||
return dll;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *DLL_AddToList( const char *name, void *hInstance, const char *file, int line )
|
||||
{
|
||||
struct dll_t *newdll;
|
||||
|
||||
if( !hInstance ) return NULL;
|
||||
|
||||
newdll = DLL_FindInListAndIncrement( name );
|
||||
if( newdll )
|
||||
return newdll;
|
||||
|
||||
newdll = Mem_Malloc( host.mempool, sizeof( *newdll ));
|
||||
|
||||
newdll->hInstance = hInstance;
|
||||
Q_strncpy( newdll->name, name, sizeof( newdll->name ));
|
||||
Q_strncpy( newdll->file, file, sizeof( newdll->file ));
|
||||
newdll->line = line;
|
||||
newdll->refcount = 1;
|
||||
newdll->next = dlls;
|
||||
|
||||
dlls = newdll;
|
||||
|
||||
return newdll;
|
||||
}
|
||||
|
||||
void *DLL_Free( void *_dll )
|
||||
{
|
||||
struct dll_t *dll = _dll;
|
||||
void *hinst = dll->hInstance;
|
||||
|
||||
dll->refcount--;
|
||||
|
||||
if( dll->refcount == 0 )
|
||||
{
|
||||
struct dll_t **back, *find;
|
||||
|
||||
back = &dlls;
|
||||
while( 1 )
|
||||
{
|
||||
find = *back;
|
||||
if( !find ) break;
|
||||
|
||||
if( find == dll )
|
||||
{
|
||||
*back = dll->next;
|
||||
|
||||
Mem_Free( dll );
|
||||
break;
|
||||
}
|
||||
|
||||
back = &find->next;
|
||||
}
|
||||
}
|
||||
|
||||
return hinst;
|
||||
}
|
||||
|
||||
void *DLL_GetInstance( void *_dll )
|
||||
{
|
||||
struct dll_t *dll = _dll;
|
||||
|
||||
return dll->hInstance;
|
||||
}
|
||||
|
||||
void DLL_PrintLeaks( void )
|
||||
{
|
||||
struct dll_t *dll;
|
||||
|
||||
for( dll = dlls; dll; dll = dll->next )
|
||||
{
|
||||
Con_Printf( S_ERROR "UNLOADED LIBRARY DETECTED: %s loaded at %s:%i!\n", dll->name, dll->file, dll->line );
|
||||
}
|
||||
}
|
||||
#else
|
||||
void *DLL_AddToList( const char *name, void *hInstance, const char *file, int line )
|
||||
{
|
||||
return hInstance;
|
||||
}
|
||||
|
||||
void DLL_Free( void *_dll )
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
void *DLL_GetInstance( void *_dll )
|
||||
{
|
||||
return _dll;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef XASH_DLL_LOADER // wine-based dll loader
|
||||
void * Loader_LoadLibrary (const char *name);
|
||||
void * Loader_GetProcAddress (void *hndl, const char *name);
|
||||
@@ -34,25 +154,24 @@ const char * Loader_GetFuncName( void *hndl, void *func);
|
||||
const char * Loader_GetFuncName_int( void *wm , void *func);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XASH_NO_LIBDL
|
||||
#ifndef XASH_DLL_LOADER
|
||||
#error Enable at least one dll backend!!!
|
||||
#endif // XASH_DLL_LOADER
|
||||
|
||||
void *dlsym(void *handle, const char *symbol )
|
||||
void *dlsym( void *handle, const char *symbol )
|
||||
{
|
||||
Con_DPrintf( "dlsym( %p, \"%s\" ): stub\n", handle, symbol );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *dlopen(const char *name, int flag )
|
||||
void *dlopen( const char *name, int flag )
|
||||
{
|
||||
Con_DPrintf( "dlopen( \"%s\", %d ): stub\n", name, flag );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int dlclose(void *handle)
|
||||
int dlclose( void *handle)
|
||||
{
|
||||
Con_DPrintf( "dlsym( %p ): stub\n", handle );
|
||||
return 0;
|
||||
@@ -75,7 +194,7 @@ qboolean COM_CheckLibraryDirectDependency( const char *name, const char *depname
|
||||
return true;
|
||||
}
|
||||
|
||||
void *COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean directpath )
|
||||
void *_COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean directpath, const char *file, int line )
|
||||
{
|
||||
dll_user_t *hInst = NULL;
|
||||
void *pHandle = NULL;
|
||||
@@ -96,7 +215,7 @@ void *COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean d
|
||||
#ifdef XASH_DLL_LOADER
|
||||
if( host.enabledll && ( pHandle = Loader_LoadLibrary(dllname)) )
|
||||
{
|
||||
return pHandle;
|
||||
return DLL_AddToList( dllname, pHandle, file, line );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -105,7 +224,7 @@ void *COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean d
|
||||
{
|
||||
pHandle = dlopen( dllname, RTLD_LAZY );
|
||||
if( pHandle )
|
||||
return pHandle;
|
||||
return DLL_AddToList( dllname, pHandle, file, line );
|
||||
|
||||
COM_PushLibraryError( va( "Failed to find library %s", dllname ));
|
||||
COM_PushLibraryError( dlerror() );
|
||||
@@ -152,38 +271,42 @@ void *COM_LoadLibrary( const char *dllname, int build_ordinals_table, qboolean d
|
||||
|
||||
Mem_Free( hInst );
|
||||
|
||||
return pHandle;
|
||||
return DLL_AddToList( dllname, pHandle, file, line );
|
||||
}
|
||||
|
||||
void COM_FreeLibrary( void *hInstance )
|
||||
{
|
||||
void *hinst = DLL_Free( hInstance );
|
||||
|
||||
#ifdef XASH_DLL_LOADER
|
||||
void *wm;
|
||||
if( host.enabledll && (wm = Loader_GetDllHandle( hInstance )) )
|
||||
return Loader_FreeLibrary( hInstance );
|
||||
if( host.enabledll && (wm = Loader_GetDllHandle( hinst )) )
|
||||
return Loader_FreeLibrary( hinst );
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#ifdef Platform_POSIX_FreeLibrary
|
||||
Platform_POSIX_FreeLibrary( hInstance );
|
||||
Platform_POSIX_FreeLibrary( hinst );
|
||||
#else
|
||||
dlclose( hInstance );
|
||||
dlclose( hinst );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void *COM_GetProcAddress( void *hInstance, const char *name )
|
||||
{
|
||||
void *hinst = DLL_GetInstance( hInstance );
|
||||
|
||||
#ifdef XASH_DLL_LOADER
|
||||
void *wm;
|
||||
if( host.enabledll && (wm = Loader_GetDllHandle( hInstance )) )
|
||||
return Loader_GetProcAddress(hInstance, name);
|
||||
if( host.enabledll && ( wm = Loader_GetDllHandle( hinst )))
|
||||
return Loader_GetProcAddress( hinst, name );
|
||||
else
|
||||
#endif
|
||||
#if Platform_POSIX_GetProcAddress
|
||||
return Platform_POSIX_GetProcAddress( hInstance, name );
|
||||
return Platform_POSIX_GetProcAddress( hinst, name );
|
||||
#else
|
||||
return dlsym( hInstance, name );
|
||||
return dlsym( hinst, name );
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -217,11 +340,13 @@ static int d_dladdr( void *sym, Dl_info *info )
|
||||
|
||||
const char *COM_NameForFunction( void *hInstance, void *function )
|
||||
{
|
||||
void *hinst = DLL_GetInstance( hInstance );
|
||||
|
||||
#ifdef XASH_DLL_LOADER
|
||||
void *wm;
|
||||
if( host.enabledll && (wm = Loader_GetDllHandle( hInstance )) )
|
||||
if( host.enabledll && ( wm = Loader_GetDllHandle( hinst )))
|
||||
#error ConvertMangledName
|
||||
return Loader_GetFuncName_int(wm, function);
|
||||
return Loader_GetFuncName_int( wm, function );
|
||||
else
|
||||
#endif
|
||||
// NOTE: dladdr() is a glibc extension
|
||||
|
||||
@@ -88,6 +88,7 @@ GNU General Public License for more details.
|
||||
#define SDL_SCANCODE_PRINTSCREEN SDLK_PRINT
|
||||
#define SDL_SCANCODE_UNKNOWN SDLK_UNKNOWN
|
||||
#define SDL_GetScancodeName( x ) "unknown"
|
||||
#define SDL_JoystickID Uint8
|
||||
#endif
|
||||
|
||||
static qboolean SDLash_IsInstanceIDAGameController( SDL_JoystickID joyId )
|
||||
@@ -121,7 +122,7 @@ static void SDLash_KeyEvent( SDL_KeyboardEvent key )
|
||||
#endif
|
||||
qboolean numLock = SDL_GetModState() & KMOD_NUM;
|
||||
|
||||
if( SDL_IsTextInputActive() && down )
|
||||
if( SDL_IsTextInputActive() && down && cls.key_dest != key_game )
|
||||
{
|
||||
if( SDL_GetModState() & KMOD_CTRL )
|
||||
{
|
||||
@@ -270,30 +271,29 @@ SDLash_MouseEvent
|
||||
static void SDLash_MouseEvent( SDL_MouseButtonEvent button )
|
||||
{
|
||||
int down = button.state != SDL_RELEASED;
|
||||
qboolean istouch;
|
||||
uint mstate = 0;
|
||||
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
istouch = button.which == SDL_TOUCH_MOUSEID;
|
||||
#else // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
istouch = false;
|
||||
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
if( button.which == SDL_TOUCH_MOUSEID )
|
||||
return;
|
||||
#endif
|
||||
|
||||
switch( button.button )
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
SDLash_MouseKey( K_MOUSE1, down, istouch );
|
||||
IN_MouseEvent( 0, down );
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
SDLash_MouseKey( K_MOUSE2, down, istouch );
|
||||
IN_MouseEvent( 1, down );
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
SDLash_MouseKey( K_MOUSE3, down, istouch );
|
||||
IN_MouseEvent( 2, down );
|
||||
break;
|
||||
case SDL_BUTTON_X1:
|
||||
SDLash_MouseKey( K_MOUSE4, down, istouch );
|
||||
IN_MouseEvent( 3, down );
|
||||
break;
|
||||
case SDL_BUTTON_X2:
|
||||
SDLash_MouseKey( K_MOUSE5, down, istouch );
|
||||
IN_MouseEvent( 4, down );
|
||||
break;
|
||||
#if ! SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
case SDL_BUTTON_WHEELUP:
|
||||
@@ -318,6 +318,7 @@ SDLash_InputEvent
|
||||
static void SDLash_InputEvent( SDL_TextInputEvent input )
|
||||
{
|
||||
char *text;
|
||||
VGui_ReportTextInput( input.text );
|
||||
for( text = input.text; *text; text++ )
|
||||
{
|
||||
int ch;
|
||||
@@ -340,7 +341,11 @@ static void SDLash_ActiveEvent( int gain )
|
||||
if( gain )
|
||||
{
|
||||
host.status = HOST_FRAME;
|
||||
IN_ActivateMouse( true );
|
||||
if( cls.key_dest == key_game )
|
||||
{
|
||||
IN_ActivateMouse( );
|
||||
}
|
||||
|
||||
if( dma.initialized && snd_mute_losefocus.value )
|
||||
{
|
||||
SNDDMA_Activate( true );
|
||||
@@ -360,7 +365,11 @@ static void SDLash_ActiveEvent( int gain )
|
||||
}
|
||||
#endif
|
||||
host.status = HOST_NOFOCUS;
|
||||
IN_DeactivateMouse();
|
||||
if( cls.key_dest == key_game )
|
||||
{
|
||||
IN_DeactivateMouse();
|
||||
}
|
||||
|
||||
if( dma.initialized && snd_mute_losefocus.value )
|
||||
{
|
||||
SNDDMA_Activate( false );
|
||||
@@ -425,13 +434,10 @@ static void SDLash_EventFilter( SDL_Event *event )
|
||||
{
|
||||
/* Mouse events */
|
||||
case SDL_MOUSEMOTION:
|
||||
if( !host.mouse_visible
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
&& event->motion.which != SDL_TOUCH_MOUSEID )
|
||||
#else
|
||||
)
|
||||
#endif
|
||||
IN_MouseEvent();
|
||||
if( host.mouse_visible )
|
||||
{
|
||||
SDL_GetRelativeMouseState( NULL, NULL );
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
|
||||
@@ -33,5 +33,11 @@ void VID_SaveWindowSize( int width, int height );
|
||||
// joystick events
|
||||
extern SDL_Joystick *g_joy;
|
||||
|
||||
//
|
||||
// in_sdl.c
|
||||
//
|
||||
void SDLash_InitCursors( void );
|
||||
void SDLash_FreeCursors( void );
|
||||
|
||||
#endif // XASH_SDL
|
||||
#endif // KEYWRAPPER_H
|
||||
|
||||
@@ -27,6 +27,12 @@ GNU General Public License for more details.
|
||||
SDL_Joystick *g_joy = NULL;
|
||||
#if !SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
#define SDL_WarpMouseInWindow( win, x, y ) SDL_WarpMouse( ( x ), ( y ) )
|
||||
#else
|
||||
static struct
|
||||
{
|
||||
qboolean initialized;
|
||||
SDL_Cursor *cursors[dc_last];
|
||||
} cursors;
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -71,19 +77,28 @@ Platform_GetClipobardText
|
||||
|
||||
=============
|
||||
*/
|
||||
void Platform_GetClipboardText( char *buffer, size_t size )
|
||||
int Platform_GetClipboardText( char *buffer, size_t size )
|
||||
{
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
int textLength;
|
||||
char *sdlbuffer = SDL_GetClipboardText();
|
||||
|
||||
if( !sdlbuffer )
|
||||
return;
|
||||
return 0;
|
||||
|
||||
Q_strncpy( buffer, sdlbuffer, size );
|
||||
if (buffer && size > 0)
|
||||
{
|
||||
textLength = Q_strncpy( buffer, sdlbuffer, size );
|
||||
}
|
||||
else {
|
||||
textLength = Q_strlen( sdlbuffer );
|
||||
}
|
||||
SDL_free( sdlbuffer );
|
||||
return textLength;
|
||||
#else // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
buffer[0] = 0;
|
||||
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -92,7 +107,7 @@ Platform_SetClipobardText
|
||||
|
||||
=============
|
||||
*/
|
||||
void Platform_SetClipboardText( const char *buffer, size_t size )
|
||||
void Platform_SetClipboardText( const char *buffer )
|
||||
{
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
SDL_SetClipboardText( buffer );
|
||||
@@ -237,4 +252,143 @@ int Platform_JoyInit( int numjoy )
|
||||
return SDLash_JoyInit_Old(numjoy);
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
SDLash_InitCursors
|
||||
|
||||
========================
|
||||
*/
|
||||
void SDLash_InitCursors( void )
|
||||
{
|
||||
if( cursors.initialized )
|
||||
SDLash_FreeCursors();
|
||||
|
||||
// load up all default cursors
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
cursors.cursors[dc_none] = NULL;
|
||||
cursors.cursors[dc_arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
|
||||
cursors.cursors[dc_ibeam] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM);
|
||||
cursors.cursors[dc_hourglass] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT);
|
||||
cursors.cursors[dc_crosshair] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_CROSSHAIR);
|
||||
cursors.cursors[dc_up] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW);
|
||||
cursors.cursors[dc_sizenwse] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE);
|
||||
cursors.cursors[dc_sizenesw] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW);
|
||||
cursors.cursors[dc_sizewe] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE);
|
||||
cursors.cursors[dc_sizens] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS);
|
||||
cursors.cursors[dc_sizeall] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL);
|
||||
cursors.cursors[dc_no] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO);
|
||||
cursors.cursors[dc_hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND);
|
||||
#endif
|
||||
cursors.initialized = true;
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
SDLash_FreeCursors
|
||||
|
||||
========================
|
||||
*/
|
||||
void SDLash_FreeCursors( void )
|
||||
{
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
int i = 0;
|
||||
|
||||
for( ; i < ARRAYSIZE( cursors.cursors ); i++ )
|
||||
{
|
||||
if( cursors.cursors[i] )
|
||||
SDL_FreeCursor( cursors.cursors[i] );
|
||||
cursors.cursors[i] = NULL;
|
||||
}
|
||||
|
||||
cursors.initialized = false;
|
||||
#endif // SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Platform_SetCursorType
|
||||
|
||||
========================
|
||||
*/
|
||||
void Platform_SetCursorType( VGUI_DefaultCursor type )
|
||||
{
|
||||
qboolean visible;
|
||||
|
||||
if( !cursors.initialized )
|
||||
return;
|
||||
|
||||
if( cls.key_dest != key_game || cl.paused )
|
||||
return;
|
||||
|
||||
switch( type )
|
||||
{
|
||||
case dc_user:
|
||||
case dc_none:
|
||||
visible = false;
|
||||
break;
|
||||
default:
|
||||
visible = true;
|
||||
break;
|
||||
}
|
||||
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
if( CVAR_TO_BOOL( touch_emulate ))
|
||||
return;
|
||||
|
||||
if( visible && !host.mouse_visible )
|
||||
{
|
||||
SDL_SetCursor( cursors.cursors[type] );
|
||||
SDL_ShowCursor( true );
|
||||
Key_EnableTextInput( true, false );
|
||||
}
|
||||
else if( !visible && host.mouse_visible )
|
||||
{
|
||||
SDL_ShowCursor( false );
|
||||
Key_EnableTextInput( false, false );
|
||||
}
|
||||
host.mouse_visible = visible;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
Platform_GetKeyModifiers
|
||||
|
||||
========================
|
||||
*/
|
||||
key_modifier_t Platform_GetKeyModifiers( void )
|
||||
{
|
||||
#if SDL_VERSION_ATLEAST( 2, 0, 0 )
|
||||
SDL_Keymod modFlags;
|
||||
key_modifier_t resultFlags;
|
||||
|
||||
resultFlags = KeyModifier_None;
|
||||
modFlags = SDL_GetModState();
|
||||
if( FBitSet( modFlags, KMOD_LCTRL ))
|
||||
SetBits( resultFlags, KeyModifier_LeftCtrl );
|
||||
if( FBitSet( modFlags, KMOD_RCTRL ))
|
||||
SetBits( resultFlags, KeyModifier_RightCtrl );
|
||||
if( FBitSet( modFlags, KMOD_RSHIFT ))
|
||||
SetBits( resultFlags, KeyModifier_RightShift );
|
||||
if( FBitSet( modFlags, KMOD_LSHIFT ))
|
||||
SetBits( resultFlags, KeyModifier_LeftShift );
|
||||
if( FBitSet( modFlags, KMOD_LALT ))
|
||||
SetBits( resultFlags, KeyModifier_LeftAlt );
|
||||
if( FBitSet( modFlags, KMOD_RALT ))
|
||||
SetBits( resultFlags, KeyModifier_RightAlt );
|
||||
if( FBitSet( modFlags, KMOD_NUM ))
|
||||
SetBits( resultFlags, KeyModifier_NumLock );
|
||||
if( FBitSet( modFlags, KMOD_CAPS ))
|
||||
SetBits( resultFlags, KeyModifier_CapsLock );
|
||||
if( FBitSet( modFlags, KMOD_RGUI ))
|
||||
SetBits( resultFlags, KeyModifier_RightSuper );
|
||||
if( FBitSet( modFlags, KMOD_LGUI ))
|
||||
SetBits( resultFlags, KeyModifier_LeftSuper );
|
||||
|
||||
return resultFlags;
|
||||
#else
|
||||
return KeyModifier_None;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // XASH_DEDICATED
|
||||
|
||||
@@ -15,6 +15,7 @@ GNU General Public License for more details.
|
||||
|
||||
#include <SDL.h>
|
||||
#include "platform/platform.h"
|
||||
#include "events.h"
|
||||
|
||||
#if XASH_TIMER == TIMER_SDL
|
||||
double Platform_DoubleTime( void )
|
||||
@@ -67,11 +68,15 @@ void Platform_Init( void )
|
||||
#ifdef XASH_WIN32
|
||||
Wcon_CreateConsole(); // system console used by dedicated server or show fatal errors
|
||||
#endif
|
||||
|
||||
SDLash_InitCursors();
|
||||
}
|
||||
|
||||
void Platform_Shutdown( void )
|
||||
{
|
||||
SDLash_FreeCursors();
|
||||
|
||||
#ifdef XASH_WIN32
|
||||
Wcon_DestroyConsole();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -574,7 +574,6 @@ static qboolean VID_SetScreenResolution( int width, int height )
|
||||
|
||||
SDL_SetWindowBordered( host.hWnd, SDL_FALSE );
|
||||
//SDL_SetWindowPosition( host.hWnd, 0, 0 );
|
||||
SDL_SetWindowGrab( host.hWnd, SDL_TRUE );
|
||||
SDL_SetWindowSize( host.hWnd, got.w, got.h );
|
||||
|
||||
VID_SaveWindowSize( got.w, got.h );
|
||||
@@ -590,7 +589,6 @@ void VID_RestoreScreenResolution( void )
|
||||
if( !Cvar_VariableInteger("fullscreen") )
|
||||
{
|
||||
SDL_SetWindowBordered( host.hWnd, SDL_TRUE );
|
||||
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -662,7 +660,7 @@ qboolean VID_CreateWindow( int width, int height, qboolean fullscreen )
|
||||
|
||||
glw_state.safe++;
|
||||
|
||||
if( !gl_wgl_msaa_samples->value && glw_state.safe == SAFE_NOMSAA )
|
||||
if( !gl_msaa_samples->value && glw_state.safe == SAFE_NOMSAA )
|
||||
glw_state.safe++; // no need to skip msaa, if we already disabled it
|
||||
|
||||
GL_SetupAttributes(); // re-choose attributes
|
||||
@@ -805,7 +803,7 @@ qboolean VID_CreateWindow( int width, int height, qboolean fullscreen )
|
||||
|
||||
glw_state.safe++;
|
||||
|
||||
if( !gl_wgl_msaa_samples->value && glw_state.safe == SAFE_NOMSAA )
|
||||
if( !gl_msaa_samples->value && glw_state.safe == SAFE_NOMSAA )
|
||||
glw_state.safe++; // no need to skip msaa, if we already disabled it
|
||||
|
||||
GL_SetupAttributes(); // re-choose attributes
|
||||
|
||||
@@ -13,8 +13,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "common.h"
|
||||
#include "xash3d_mathlib.h"
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
@@ -25,198 +25,429 @@ WIN32 CONSOLE
|
||||
*/
|
||||
|
||||
// console defines
|
||||
#define SUBMIT_ID 1 // "submit" button
|
||||
#define QUIT_ON_ESCAPE_ID 2 // escape event
|
||||
#define EDIT_ID 110
|
||||
#define INPUT_ID 109
|
||||
#define IDI_ICON1 101
|
||||
|
||||
#define SYSCONSOLE "XashConsole"
|
||||
#define COMMAND_HISTORY 64 // system console keep more commands than game console
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char title[64];
|
||||
HWND hWnd;
|
||||
HWND hwndBuffer;
|
||||
HWND hwndButtonSubmit;
|
||||
HBRUSH hbrEditBackground;
|
||||
HFONT hfBufferFont;
|
||||
HWND hwndInputLine;
|
||||
HANDLE hInput;
|
||||
HANDLE hOutput;
|
||||
int inputLine;
|
||||
int browseLine;
|
||||
int cursorPosition;
|
||||
int totalLines;
|
||||
int savedConsoleTextLen;
|
||||
int consoleTextLen;
|
||||
string consoleText;
|
||||
string returnedText;
|
||||
string historyLines[COMMAND_HISTORY];
|
||||
int nextHistoryLine;
|
||||
int historyLine;
|
||||
int status;
|
||||
int windowWidth, windowHeight;
|
||||
WNDPROC SysInputLineWndProc;
|
||||
size_t outLen;
|
||||
string savedConsoleText;
|
||||
string statusLine;
|
||||
string lineBuffer[COMMAND_HISTORY];
|
||||
qboolean inputEnabled;
|
||||
qboolean consoleVisible;
|
||||
|
||||
// log stuff
|
||||
qboolean log_active;
|
||||
qboolean log_active;
|
||||
char log_path[MAX_SYSPATH];
|
||||
} WinConData;
|
||||
|
||||
static WinConData s_wcd;
|
||||
static WORD g_color_table[8] =
|
||||
{
|
||||
FOREGROUND_INTENSITY, // black
|
||||
FOREGROUND_RED, // red
|
||||
FOREGROUND_GREEN, // green
|
||||
FOREGROUND_RED | FOREGROUND_GREEN, // yellow
|
||||
FOREGROUND_BLUE | FOREGROUND_INTENSITY, // blue
|
||||
FOREGROUND_GREEN | FOREGROUND_BLUE, // cyan
|
||||
FOREGROUND_RED | FOREGROUND_BLUE, // magenta
|
||||
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, // default color (white)
|
||||
};
|
||||
|
||||
static BOOL WINAPI Wcon_HandleConsole(DWORD CtrlType)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void Wcon_PrintInternal( const char *msg, int length )
|
||||
{
|
||||
char *pTemp;
|
||||
DWORD cbWritten;
|
||||
const char *pMsgString;
|
||||
static char tmpBuf[2048];
|
||||
static char szOutput[2048];
|
||||
|
||||
Q_strncpy( szOutput, msg, length ? (length + 1) : ( sizeof( szOutput ) - 1 ));
|
||||
if( length )
|
||||
szOutput[length + 1] = '\0';
|
||||
else
|
||||
szOutput[sizeof( szOutput ) - 1] = '\0';
|
||||
|
||||
pTemp = tmpBuf;
|
||||
pMsgString = szOutput;
|
||||
while( pMsgString && *pMsgString )
|
||||
{
|
||||
if( IsColorString( pMsgString ))
|
||||
{
|
||||
if (( pTemp - tmpBuf ) > 0 )
|
||||
{
|
||||
// dump accumulated text before change color
|
||||
*pTemp = 0; // terminate string
|
||||
WriteFile( s_wcd.hOutput, tmpBuf, Q_strlen(tmpBuf), &cbWritten, 0 );
|
||||
pTemp = tmpBuf;
|
||||
}
|
||||
|
||||
// set new color
|
||||
SetConsoleTextAttribute( s_wcd.hOutput, g_color_table[ColorIndex(*(pMsgString + 1))] );
|
||||
pMsgString += 2; // skip color info
|
||||
}
|
||||
else if(( pTemp - tmpBuf ) < sizeof( tmpBuf ) - 1 )
|
||||
{
|
||||
*pTemp++ = *pMsgString++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// temp buffer is full, dump it now
|
||||
*pTemp = 0; // terminate string
|
||||
WriteFile( s_wcd.hOutput, tmpBuf, Q_strlen(tmpBuf), &cbWritten, 0 );
|
||||
pTemp = tmpBuf;
|
||||
}
|
||||
}
|
||||
|
||||
// check for last portion
|
||||
if (( pTemp - tmpBuf ) > 0 )
|
||||
{
|
||||
// dump accumulated text
|
||||
*pTemp = 0; // terminate string
|
||||
WriteFile( s_wcd.hOutput, tmpBuf, Q_strlen(tmpBuf), &cbWritten, 0 );
|
||||
pTemp = tmpBuf;
|
||||
}
|
||||
|
||||
// restore white color
|
||||
SetConsoleTextAttribute( s_wcd.hOutput, g_color_table[7] );
|
||||
}
|
||||
|
||||
void Wcon_ShowConsole( qboolean show )
|
||||
{
|
||||
if( !s_wcd.hWnd || show == s_wcd.status )
|
||||
if( !s_wcd.hWnd || show == s_wcd.consoleVisible )
|
||||
return;
|
||||
|
||||
s_wcd.status = show;
|
||||
s_wcd.consoleVisible = show;
|
||||
if( show )
|
||||
{
|
||||
ShowWindow( s_wcd.hWnd, SW_SHOWNORMAL );
|
||||
SendMessage( s_wcd.hwndBuffer, EM_LINESCROLL, 0, 0xffff );
|
||||
}
|
||||
else ShowWindow( s_wcd.hWnd, SW_HIDE );
|
||||
ShowWindow( s_wcd.hWnd, SW_SHOW );
|
||||
else
|
||||
ShowWindow( s_wcd.hWnd, SW_HIDE );
|
||||
}
|
||||
|
||||
void Wcon_DisableInput( void )
|
||||
{
|
||||
if( host.type != HOST_DEDICATED ) return;
|
||||
SendMessage( s_wcd.hwndButtonSubmit, WM_ENABLE, 0, 0 );
|
||||
SendMessage( s_wcd.hwndInputLine, WM_ENABLE, 0, 0 );
|
||||
if( host.type != HOST_DEDICATED )
|
||||
return;
|
||||
|
||||
s_wcd.inputEnabled = false;
|
||||
}
|
||||
|
||||
void Wcon_SetInputText( const char *inputText )
|
||||
static void Wcon_SetInputText( const char *inputText )
|
||||
{
|
||||
if( host.type != HOST_DEDICATED ) return;
|
||||
SetWindowText( s_wcd.hwndInputLine, inputText );
|
||||
SendMessage( s_wcd.hwndInputLine, EM_SETSEL, Q_strlen( inputText ), -1 );
|
||||
if( host.type != HOST_DEDICATED )
|
||||
return;
|
||||
|
||||
while( s_wcd.consoleTextLen-- )
|
||||
{
|
||||
Wcon_PrintInternal( "\b \b", 0 );
|
||||
}
|
||||
Wcon_PrintInternal( inputText, 0 );
|
||||
Q_strncpy( s_wcd.consoleText, inputText, sizeof(s_wcd.consoleText) - 1 );
|
||||
s_wcd.consoleTextLen = Q_strlen( inputText );
|
||||
s_wcd.cursorPosition = s_wcd.consoleTextLen;
|
||||
s_wcd.browseLine = s_wcd.inputLine;
|
||||
}
|
||||
|
||||
static void Wcon_Clear_f( void )
|
||||
{
|
||||
if( host.type != HOST_DEDICATED ) return;
|
||||
SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 );
|
||||
SendMessage( s_wcd.hwndBuffer, EM_REPLACESEL, FALSE, (LPARAM)"" );
|
||||
UpdateWindow( s_wcd.hwndBuffer );
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
SMALL_RECT scrollRect;
|
||||
COORD scrollTarget;
|
||||
CHAR_INFO fill;
|
||||
|
||||
if( host.type != HOST_DEDICATED )
|
||||
return;
|
||||
|
||||
if( !GetConsoleScreenBufferInfo( s_wcd.hOutput, &csbi ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
scrollRect.Left = 0;
|
||||
scrollRect.Top = 0;
|
||||
scrollRect.Right = csbi.dwSize.X;
|
||||
scrollRect.Bottom = csbi.dwSize.Y;
|
||||
scrollTarget.X = 0;
|
||||
scrollTarget.Y = (SHORT)(0 - csbi.dwSize.Y);
|
||||
fill.Char.UnicodeChar = TEXT(' ');
|
||||
fill.Attributes = csbi.wAttributes;
|
||||
ScrollConsoleScreenBuffer( s_wcd.hOutput, &scrollRect, NULL, scrollTarget, &fill );
|
||||
|
||||
csbi.dwCursorPosition.X = 0;
|
||||
csbi.dwCursorPosition.Y = 0;
|
||||
SetConsoleCursorPosition( s_wcd.hOutput, csbi.dwCursorPosition );
|
||||
|
||||
s_wcd.consoleText[0] = '\0';
|
||||
s_wcd.consoleTextLen = 0;
|
||||
s_wcd.cursorPosition = 0;
|
||||
s_wcd.inputLine = 0;
|
||||
s_wcd.browseLine = 0;
|
||||
s_wcd.totalLines = 0;
|
||||
Wcon_PrintInternal( "\n", 0 );
|
||||
}
|
||||
|
||||
static int Wcon_KeyEvent( int key, qboolean down )
|
||||
static void Wcon_EventUpArrow()
|
||||
{
|
||||
char inputBuffer[1024];
|
||||
int nLastCommandInHistory = s_wcd.inputLine + 1;
|
||||
if( nLastCommandInHistory > s_wcd.totalLines )
|
||||
nLastCommandInHistory = 0;
|
||||
|
||||
if( !down )
|
||||
return 0;
|
||||
if( s_wcd.browseLine == nLastCommandInHistory )
|
||||
return;
|
||||
|
||||
if( s_wcd.browseLine == s_wcd.inputLine )
|
||||
{
|
||||
if( s_wcd.consoleTextLen > 0 )
|
||||
{
|
||||
Q_strncpy( s_wcd.savedConsoleText, s_wcd.consoleText, s_wcd.consoleTextLen );
|
||||
}
|
||||
s_wcd.savedConsoleTextLen = s_wcd.consoleTextLen;
|
||||
}
|
||||
|
||||
s_wcd.browseLine--;
|
||||
if( s_wcd.browseLine < 0 )
|
||||
{
|
||||
s_wcd.browseLine = s_wcd.totalLines - 1;
|
||||
}
|
||||
|
||||
while( s_wcd.consoleTextLen-- )
|
||||
{
|
||||
Wcon_PrintInternal( "\b \b", 0 );
|
||||
}
|
||||
|
||||
Wcon_PrintInternal( s_wcd.lineBuffer[s_wcd.browseLine], 0 );
|
||||
Q_strncpy( s_wcd.consoleText, s_wcd.lineBuffer[s_wcd.browseLine], sizeof( s_wcd.consoleText ));
|
||||
s_wcd.consoleTextLen = Q_strlen( s_wcd.lineBuffer[s_wcd.browseLine] );
|
||||
s_wcd.cursorPosition = s_wcd.consoleTextLen;
|
||||
}
|
||||
|
||||
static void Wcon_EventDownArrow()
|
||||
{
|
||||
if( s_wcd.browseLine == s_wcd.inputLine )
|
||||
return;
|
||||
|
||||
if( ++s_wcd.browseLine > s_wcd.totalLines )
|
||||
s_wcd.browseLine = 0;
|
||||
|
||||
while( s_wcd.consoleTextLen-- )
|
||||
{
|
||||
Wcon_PrintInternal( "\b \b", 0 );
|
||||
}
|
||||
|
||||
if( s_wcd.browseLine == s_wcd.inputLine )
|
||||
{
|
||||
if( s_wcd.savedConsoleTextLen > 0 )
|
||||
{
|
||||
Q_strncpy( s_wcd.consoleText, s_wcd.savedConsoleText, s_wcd.savedConsoleTextLen );
|
||||
Wcon_PrintInternal( s_wcd.consoleText, s_wcd.savedConsoleTextLen );
|
||||
}
|
||||
s_wcd.consoleTextLen = s_wcd.savedConsoleTextLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
Wcon_PrintInternal( s_wcd.lineBuffer[s_wcd.browseLine], 0 );
|
||||
Q_strncpy( s_wcd.consoleText, s_wcd.lineBuffer[s_wcd.browseLine], sizeof( s_wcd.consoleText ));
|
||||
s_wcd.consoleTextLen = Q_strlen( s_wcd.lineBuffer[s_wcd.browseLine] );
|
||||
}
|
||||
s_wcd.cursorPosition = s_wcd.consoleTextLen;
|
||||
}
|
||||
|
||||
static void Wcon_EventLeftArrow()
|
||||
{
|
||||
if( s_wcd.cursorPosition == 0 )
|
||||
return;
|
||||
|
||||
Wcon_PrintInternal( "\b", 0 );
|
||||
s_wcd.cursorPosition--;
|
||||
}
|
||||
|
||||
static void Wcon_EventRightArrow()
|
||||
{
|
||||
if( s_wcd.cursorPosition == s_wcd.consoleTextLen )
|
||||
return;
|
||||
|
||||
Wcon_PrintInternal( s_wcd.consoleText + s_wcd.cursorPosition, 1 );
|
||||
s_wcd.cursorPosition++;
|
||||
}
|
||||
|
||||
static int Wcon_EventNewline()
|
||||
{
|
||||
int nLen;
|
||||
|
||||
nLen = 0;
|
||||
Wcon_PrintInternal( "\n", 0 );
|
||||
if( s_wcd.consoleTextLen )
|
||||
{
|
||||
nLen = s_wcd.consoleTextLen;
|
||||
|
||||
s_wcd.consoleText[s_wcd.consoleTextLen] = '\0';
|
||||
s_wcd.consoleTextLen = 0;
|
||||
s_wcd.cursorPosition = 0;
|
||||
|
||||
if (( s_wcd.inputLine == 0 ) || ( Q_strcmp( s_wcd.lineBuffer[s_wcd.inputLine - 1], s_wcd.consoleText )))
|
||||
{
|
||||
Q_strncpy( s_wcd.lineBuffer[s_wcd.inputLine], s_wcd.consoleText, sizeof( s_wcd.consoleText ));
|
||||
s_wcd.inputLine++;
|
||||
|
||||
if( s_wcd.inputLine > s_wcd.totalLines )
|
||||
s_wcd.totalLines = s_wcd.inputLine;
|
||||
|
||||
if( s_wcd.inputLine >= COMMAND_HISTORY )
|
||||
s_wcd.inputLine = 0;
|
||||
}
|
||||
s_wcd.browseLine = s_wcd.inputLine;
|
||||
}
|
||||
return nLen;
|
||||
}
|
||||
|
||||
static void Wcon_EventBackspace()
|
||||
{
|
||||
int nCount;
|
||||
|
||||
if( s_wcd.cursorPosition < 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
s_wcd.consoleTextLen--;
|
||||
s_wcd.cursorPosition--;
|
||||
|
||||
Wcon_PrintInternal( "\b", 0 );
|
||||
|
||||
for( nCount = s_wcd.cursorPosition; nCount < s_wcd.consoleTextLen; ++nCount )
|
||||
{
|
||||
s_wcd.consoleText[nCount] = s_wcd.consoleText[nCount + 1];
|
||||
Wcon_PrintInternal( s_wcd.consoleText + nCount, 1 );
|
||||
}
|
||||
|
||||
Wcon_PrintInternal( " ", 0 );
|
||||
|
||||
nCount = s_wcd.consoleTextLen;
|
||||
while( nCount >= s_wcd.cursorPosition )
|
||||
{
|
||||
Wcon_PrintInternal( "\b", 0 );
|
||||
nCount--;
|
||||
}
|
||||
|
||||
s_wcd.browseLine = s_wcd.inputLine;
|
||||
}
|
||||
|
||||
static void Wcon_EventTab()
|
||||
{
|
||||
s_wcd.consoleText[s_wcd.consoleTextLen] = '\0';
|
||||
Cmd_AutoComplete( s_wcd.consoleText );
|
||||
Wcon_SetInputText( s_wcd.consoleText );
|
||||
}
|
||||
|
||||
static void Wcon_EventCharacter(char c)
|
||||
{
|
||||
int nCount;
|
||||
|
||||
if( s_wcd.consoleTextLen >= ( sizeof( s_wcd.consoleText ) - 2 ))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
nCount = s_wcd.consoleTextLen;
|
||||
while( nCount > s_wcd.cursorPosition )
|
||||
{
|
||||
s_wcd.consoleText[nCount] = s_wcd.consoleText[nCount - 1];
|
||||
nCount--;
|
||||
}
|
||||
|
||||
s_wcd.consoleText[s_wcd.cursorPosition] = c;
|
||||
Wcon_PrintInternal( s_wcd.consoleText + s_wcd.cursorPosition, s_wcd.consoleTextLen - s_wcd.cursorPosition + 1 );
|
||||
s_wcd.consoleTextLen++;
|
||||
s_wcd.cursorPosition++;
|
||||
|
||||
nCount = s_wcd.consoleTextLen;
|
||||
while( nCount > s_wcd.cursorPosition )
|
||||
{
|
||||
Wcon_PrintInternal( "\b", 0 );
|
||||
nCount--;
|
||||
}
|
||||
|
||||
s_wcd.browseLine = s_wcd.inputLine;
|
||||
}
|
||||
|
||||
static void Wcon_UpdateStatusLine()
|
||||
{
|
||||
COORD coord;
|
||||
WORD wAttrib;
|
||||
DWORD dwWritten;
|
||||
|
||||
coord.X = 0;
|
||||
coord.Y = 0;
|
||||
wAttrib = g_color_table[5] | FOREGROUND_INTENSITY | BACKGROUND_INTENSITY;
|
||||
|
||||
FillConsoleOutputCharacter( s_wcd.hOutput, ' ', 80, coord, &dwWritten );
|
||||
FillConsoleOutputAttribute( s_wcd.hOutput, wAttrib, 80, coord, &dwWritten );
|
||||
WriteConsoleOutputCharacter( s_wcd.hOutput, s_wcd.statusLine, Q_strlen(s_wcd.statusLine), coord, &dwWritten );
|
||||
}
|
||||
|
||||
static char *Wcon_KeyEvent( int key, WCHAR character )
|
||||
{
|
||||
int nLen;
|
||||
char inputBuffer[1024];
|
||||
|
||||
switch( key )
|
||||
{
|
||||
case VK_TAB:
|
||||
GetWindowText( s_wcd.hwndInputLine, inputBuffer, sizeof( inputBuffer ));
|
||||
Cmd_AutoComplete( inputBuffer );
|
||||
Wcon_SetInputText( inputBuffer );
|
||||
return 1;
|
||||
case VK_DOWN:
|
||||
if( s_wcd.historyLine == s_wcd.nextHistoryLine )
|
||||
return 0;
|
||||
s_wcd.historyLine++;
|
||||
Wcon_SetInputText( s_wcd.historyLines[s_wcd.historyLine % COMMAND_HISTORY] );
|
||||
return 1;
|
||||
case VK_UP:
|
||||
if( s_wcd.nextHistoryLine - s_wcd.historyLine < COMMAND_HISTORY && s_wcd.historyLine > 0 )
|
||||
s_wcd.historyLine--;
|
||||
Wcon_SetInputText( s_wcd.historyLines[s_wcd.historyLine % COMMAND_HISTORY] );
|
||||
return 1;
|
||||
Wcon_EventUpArrow();
|
||||
return NULL;
|
||||
case VK_DOWN:
|
||||
Wcon_EventDownArrow();
|
||||
return NULL;
|
||||
case VK_LEFT:
|
||||
Wcon_EventLeftArrow();
|
||||
return NULL;
|
||||
case VK_RIGHT:
|
||||
Wcon_EventRightArrow();
|
||||
return NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long _stdcall Wcon_WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch( uMsg )
|
||||
switch( character )
|
||||
{
|
||||
case WM_ACTIVATE:
|
||||
if( LOWORD( wParam ) != WA_INACTIVE )
|
||||
SetFocus( s_wcd.hwndInputLine );
|
||||
break;
|
||||
case WM_CLOSE:
|
||||
if( host.status == HOST_ERR_FATAL )
|
||||
{
|
||||
// send windows message
|
||||
PostQuitMessage( 0 );
|
||||
}
|
||||
else Sys_Quit(); // otherwise
|
||||
return 0;
|
||||
case WM_CTLCOLORSTATIC:
|
||||
if((HWND)lParam == s_wcd.hwndBuffer )
|
||||
{
|
||||
SetBkColor((HDC)wParam, RGB( 0x90, 0x90, 0x90 ));
|
||||
SetTextColor((HDC)wParam, RGB( 0xff, 0xff, 0xff ));
|
||||
return (long)s_wcd.hbrEditBackground;
|
||||
}
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
if( wParam == SUBMIT_ID )
|
||||
{
|
||||
SendMessage( s_wcd.hwndInputLine, WM_CHAR, 13, 0L );
|
||||
SetFocus( s_wcd.hwndInputLine );
|
||||
}
|
||||
break;
|
||||
case WM_HOTKEY:
|
||||
switch( LOWORD( wParam ))
|
||||
{
|
||||
case QUIT_ON_ESCAPE_ID:
|
||||
PostQuitMessage( 0 );
|
||||
case '\r': // Enter
|
||||
nLen = Wcon_EventNewline();
|
||||
if (nLen)
|
||||
{
|
||||
return s_wcd.consoleText;
|
||||
}
|
||||
break;
|
||||
case '\b': // Backspace
|
||||
Wcon_EventBackspace();
|
||||
break;
|
||||
case '\t': // TAB
|
||||
Wcon_EventTab();
|
||||
break;
|
||||
default:
|
||||
// TODO implement converting wide chars to UTF-8 and properly handling it
|
||||
if (( character >= ' ' ) && ( character <= '~' ))
|
||||
{
|
||||
Wcon_EventCharacter(character);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WM_CREATE:
|
||||
s_wcd.hbrEditBackground = CreateSolidBrush( RGB( 0x90, 0x90, 0x90 ));
|
||||
break;
|
||||
}
|
||||
return DefWindowProc( hWnd, uMsg, wParam, lParam );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
long _stdcall Wcon_InputLineProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
char inputBuffer[1024];
|
||||
|
||||
switch( uMsg )
|
||||
{
|
||||
case WM_KILLFOCUS:
|
||||
if(( HWND )wParam == s_wcd.hWnd )
|
||||
{
|
||||
SetFocus( hWnd );
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_KEYDOWN:
|
||||
if( Wcon_KeyEvent( LOWORD( wParam ), true ))
|
||||
return 0;
|
||||
break;
|
||||
case WM_SYSKEYUP:
|
||||
case WM_KEYUP:
|
||||
if( Wcon_KeyEvent( LOWORD( wParam ), false ))
|
||||
return 0;
|
||||
break;
|
||||
case WM_CHAR:
|
||||
if( Wcon_KeyEvent( wParam, true ))
|
||||
return 0;
|
||||
if( wParam == 13 && host.status != HOST_ERR_FATAL )
|
||||
{
|
||||
GetWindowText( s_wcd.hwndInputLine, inputBuffer, sizeof( inputBuffer ));
|
||||
Q_strncat( s_wcd.consoleText, inputBuffer, sizeof( s_wcd.consoleText ) - Q_strlen( s_wcd.consoleText ) - 5 );
|
||||
Q_strcat( s_wcd.consoleText, "\n" );
|
||||
SetWindowText( s_wcd.hwndInputLine, "" );
|
||||
Con_Printf( ">%s\n", inputBuffer );
|
||||
|
||||
// copy line to history buffer
|
||||
Q_strncpy( s_wcd.historyLines[s_wcd.nextHistoryLine % COMMAND_HISTORY], inputBuffer, MAX_STRING );
|
||||
s_wcd.nextHistoryLine++;
|
||||
s_wcd.historyLine = s_wcd.nextHistoryLine;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return CallWindowProc( s_wcd.SysInputLineWndProc, hWnd, uMsg, wParam, lParam );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
@@ -224,6 +455,7 @@ WIN32 IO
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
================
|
||||
Con_WinPrint
|
||||
@@ -233,24 +465,26 @@ print into window console
|
||||
*/
|
||||
void Wcon_WinPrint( const char *pMsg )
|
||||
{
|
||||
size_t len = Q_strlen( pMsg );
|
||||
|
||||
// replace selection instead of appending if we're overflowing
|
||||
s_wcd.outLen += len;
|
||||
if( s_wcd.outLen >= 0x7fff )
|
||||
int nLen;
|
||||
if( s_wcd.consoleTextLen )
|
||||
{
|
||||
SendMessage( s_wcd.hwndBuffer, EM_SETSEL, 0, -1 );
|
||||
s_wcd.outLen = len;
|
||||
nLen = s_wcd.consoleTextLen;
|
||||
while (nLen--)
|
||||
{
|
||||
Wcon_PrintInternal( "\b \b", 0 );
|
||||
}
|
||||
}
|
||||
|
||||
SendMessage( s_wcd.hwndBuffer, EM_REPLACESEL, 0, (LPARAM)pMsg );
|
||||
Wcon_PrintInternal( pMsg, 0 );
|
||||
|
||||
// put this text into the windows console
|
||||
SendMessage( s_wcd.hwndBuffer, EM_LINESCROLL, 0, 0xffff );
|
||||
SendMessage( s_wcd.hwndBuffer, EM_SCROLLCARET, 0, 0 );
|
||||
if( s_wcd.consoleTextLen )
|
||||
{
|
||||
Wcon_PrintInternal( s_wcd.consoleText, s_wcd.consoleTextLen );
|
||||
}
|
||||
|
||||
Wcon_UpdateStatusLine();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
Con_CreateConsole
|
||||
@@ -260,107 +494,38 @@ create win32 console
|
||||
*/
|
||||
void Wcon_CreateConsole( void )
|
||||
{
|
||||
HDC hDC;
|
||||
WNDCLASS wc;
|
||||
RECT rect;
|
||||
int nHeight;
|
||||
int swidth, sheight, fontsize;
|
||||
int DEDSTYLE = WS_POPUPWINDOW | WS_CAPTION;
|
||||
int CONSTYLE = WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_BORDER|WS_EX_CLIENTEDGE|ES_LEFT|ES_MULTILINE|ES_AUTOVSCROLL|ES_READONLY;
|
||||
string FontName;
|
||||
|
||||
wc.style = 0;
|
||||
wc.lpfnWndProc = (WNDPROC)Wcon_WndProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = host.hInst;
|
||||
wc.hIcon = LoadIcon( host.hInst, MAKEINTRESOURCE( IDI_ICON1 ));
|
||||
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
|
||||
wc.hbrBackground = (void *)COLOR_3DSHADOW;
|
||||
wc.lpszClassName = SYSCONSOLE;
|
||||
wc.lpszMenuName = 0;
|
||||
|
||||
if( Sys_CheckParm( "-log" ))
|
||||
s_wcd.log_active = true;
|
||||
|
||||
if( host.type == HOST_NORMAL )
|
||||
{
|
||||
rect.left = 0;
|
||||
rect.right = 536;
|
||||
rect.top = 0;
|
||||
rect.bottom = 364;
|
||||
Q_strncpy( FontName, "Fixedsys", sizeof( FontName ));
|
||||
Q_strncpy( s_wcd.title, va( "Xash3D %s", XASH_VERSION ), sizeof( s_wcd.title ));
|
||||
Q_strncpy( s_wcd.log_path, "engine.log", sizeof( s_wcd.log_path ));
|
||||
fontsize = 8;
|
||||
}
|
||||
else // dedicated console
|
||||
{
|
||||
rect.left = 0;
|
||||
rect.right = 640;
|
||||
rect.top = 0;
|
||||
rect.bottom = 392;
|
||||
Q_strncpy( FontName, "System", sizeof( FontName ));
|
||||
Q_strncpy( s_wcd.title, va( "XashDS %s", XASH_VERSION ), sizeof( s_wcd.title ));
|
||||
Q_strncpy( s_wcd.log_path, "dedicated.log", sizeof( s_wcd.log_path ));
|
||||
s_wcd.log_active = true; // always make log
|
||||
fontsize = 14;
|
||||
}
|
||||
|
||||
if( !RegisterClass( &wc ))
|
||||
AllocConsole();
|
||||
SetConsoleTitle( s_wcd.title );
|
||||
SetConsoleCP( CP_UTF8 );
|
||||
SetConsoleOutputCP( CP_UTF8 );
|
||||
|
||||
s_wcd.hWnd = GetConsoleWindow();
|
||||
s_wcd.hInput = GetStdHandle( STD_INPUT_HANDLE );
|
||||
s_wcd.hOutput = GetStdHandle( STD_OUTPUT_HANDLE );
|
||||
s_wcd.inputEnabled = true;
|
||||
|
||||
if( !SetConsoleCtrlHandler( &Wcon_HandleConsole, TRUE ))
|
||||
{
|
||||
// print into log
|
||||
Con_Reportf( S_ERROR "Can't register window class '%s'\n", SYSCONSOLE );
|
||||
Con_Reportf( S_ERROR "Couldn't attach console handler function\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
AdjustWindowRect( &rect, DEDSTYLE, FALSE );
|
||||
|
||||
hDC = GetDC( GetDesktopWindow() );
|
||||
swidth = GetDeviceCaps( hDC, HORZRES );
|
||||
sheight = GetDeviceCaps( hDC, VERTRES );
|
||||
ReleaseDC( GetDesktopWindow(), hDC );
|
||||
|
||||
s_wcd.windowWidth = rect.right - rect.left;
|
||||
s_wcd.windowHeight = rect.bottom - rect.top;
|
||||
|
||||
s_wcd.hWnd = CreateWindowEx( WS_EX_DLGMODALFRAME, SYSCONSOLE, s_wcd.title, DEDSTYLE, ( swidth - 600 ) / 2, ( sheight - 450 ) / 2 , rect.right - rect.left + 1, rect.bottom - rect.top + 1, NULL, NULL, host.hInst, NULL );
|
||||
if( s_wcd.hWnd == NULL )
|
||||
{
|
||||
Con_Reportf( S_ERROR "Can't create window '%s'\n", s_wcd.title );
|
||||
return;
|
||||
}
|
||||
|
||||
// create fonts
|
||||
hDC = GetDC( s_wcd.hWnd );
|
||||
nHeight = -MulDiv( fontsize, GetDeviceCaps( hDC, LOGPIXELSY ), 72 );
|
||||
s_wcd.hfBufferFont = CreateFont( nHeight, 0, 0, 0, FW_LIGHT, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_MODERN|FIXED_PITCH, FontName );
|
||||
ReleaseDC( s_wcd.hWnd, hDC );
|
||||
|
||||
if( host.type == HOST_DEDICATED )
|
||||
{
|
||||
// create the input line
|
||||
s_wcd.hwndInputLine = CreateWindowEx( WS_EX_CLIENTEDGE, "edit", NULL, WS_CHILD|WS_VISIBLE|WS_BORDER|ES_LEFT|ES_AUTOHSCROLL, 0, 366, 550, 25, s_wcd.hWnd, (HMENU)INPUT_ID, host.hInst, NULL );
|
||||
|
||||
s_wcd.hwndButtonSubmit = CreateWindow( "button", NULL, BS_PUSHBUTTON|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 552, 367, 87, 25, s_wcd.hWnd, (HMENU)SUBMIT_ID, host.hInst, NULL );
|
||||
SendMessage( s_wcd.hwndButtonSubmit, WM_SETTEXT, 0, ( LPARAM ) "submit" );
|
||||
}
|
||||
|
||||
// create the scrollbuffer
|
||||
GetClientRect( s_wcd.hWnd, &rect );
|
||||
|
||||
s_wcd.hwndBuffer = CreateWindowEx( WS_EX_DLGMODALFRAME|WS_EX_CLIENTEDGE, "edit", NULL, CONSTYLE, 0, 0, rect.right - rect.left, min(365, rect.bottom), s_wcd.hWnd, (HMENU)EDIT_ID, host.hInst, NULL );
|
||||
SendMessage( s_wcd.hwndBuffer, WM_SETFONT, (WPARAM)s_wcd.hfBufferFont, 0 );
|
||||
|
||||
if( host.type == HOST_DEDICATED )
|
||||
{
|
||||
#ifdef XASH_64BIT
|
||||
s_wcd.SysInputLineWndProc = (WNDPROC)SetWindowLongPtr( s_wcd.hwndInputLine, GWLP_WNDPROC, (LONG_PTR)Wcon_InputLineProc );
|
||||
#else
|
||||
s_wcd.SysInputLineWndProc = (WNDPROC)SetWindowLong( s_wcd.hwndInputLine, GWL_WNDPROC, (long)Wcon_InputLineProc );
|
||||
#endif
|
||||
SendMessage( s_wcd.hwndInputLine, WM_SETFONT, ( WPARAM )s_wcd.hfBufferFont, 0 );
|
||||
}
|
||||
SetWindowPos( s_wcd.hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOREPOSITION | SWP_SHOWWINDOW );
|
||||
|
||||
// show console if needed
|
||||
if( host.con_showalways )
|
||||
@@ -369,13 +534,14 @@ void Wcon_CreateConsole( void )
|
||||
ShowWindow( s_wcd.hWnd, SW_SHOWDEFAULT );
|
||||
UpdateWindow( s_wcd.hWnd );
|
||||
SetForegroundWindow( s_wcd.hWnd );
|
||||
|
||||
if( host.type != HOST_DEDICATED )
|
||||
SetFocus( s_wcd.hWnd );
|
||||
else SetFocus( s_wcd.hwndInputLine );
|
||||
s_wcd.status = true;
|
||||
SetFocus( s_wcd.hWnd );
|
||||
s_wcd.consoleVisible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_wcd.consoleVisible = false;
|
||||
ShowWindow( s_wcd.hWnd, SW_HIDE );
|
||||
}
|
||||
else s_wcd.status = false;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -387,7 +553,9 @@ register console commands (dedicated only)
|
||||
*/
|
||||
void Wcon_InitConsoleCommands( void )
|
||||
{
|
||||
if( host.type != HOST_DEDICATED ) return;
|
||||
if( host.type != HOST_DEDICATED )
|
||||
return;
|
||||
|
||||
Cmd_AddCommand( "clear", Wcon_Clear_f, "clear console history" );
|
||||
}
|
||||
|
||||
@@ -407,33 +575,15 @@ void Wcon_DestroyConsole( void )
|
||||
|
||||
if( s_wcd.hWnd )
|
||||
{
|
||||
DeleteObject( s_wcd.hbrEditBackground );
|
||||
DeleteObject( s_wcd.hfBufferFont );
|
||||
|
||||
if( host.type == HOST_DEDICATED )
|
||||
{
|
||||
ShowWindow( s_wcd.hwndButtonSubmit, SW_HIDE );
|
||||
DestroyWindow( s_wcd.hwndButtonSubmit );
|
||||
s_wcd.hwndButtonSubmit = 0;
|
||||
|
||||
ShowWindow( s_wcd.hwndInputLine, SW_HIDE );
|
||||
DestroyWindow( s_wcd.hwndInputLine );
|
||||
s_wcd.hwndInputLine = 0;
|
||||
}
|
||||
|
||||
ShowWindow( s_wcd.hwndBuffer, SW_HIDE );
|
||||
DestroyWindow( s_wcd.hwndBuffer );
|
||||
s_wcd.hwndBuffer = 0;
|
||||
|
||||
ShowWindow( s_wcd.hWnd, SW_HIDE );
|
||||
DestroyWindow( s_wcd.hWnd );
|
||||
s_wcd.hWnd = 0;
|
||||
}
|
||||
|
||||
UnregisterClass( SYSCONSOLE, host.hInst );
|
||||
FreeConsole();
|
||||
|
||||
// place it here in case Sys_Crash working properly
|
||||
if( host.hMutex ) CloseHandle( host.hMutex );
|
||||
if( host.hMutex )
|
||||
CloseHandle( host.hMutex );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -445,27 +595,57 @@ returned input text
|
||||
*/
|
||||
char *Wcon_Input( void )
|
||||
{
|
||||
if( s_wcd.consoleText[0] == 0 )
|
||||
int i;
|
||||
int eventsCount;
|
||||
static INPUT_RECORD events[1024];
|
||||
|
||||
if( !s_wcd.inputEnabled )
|
||||
return NULL;
|
||||
|
||||
Q_strncpy( s_wcd.returnedText, s_wcd.consoleText, sizeof( s_wcd.returnedText ));
|
||||
s_wcd.consoleText[0] = 0;
|
||||
while( true )
|
||||
{
|
||||
if( !GetNumberOfConsoleInputEvents( s_wcd.hInput, &eventsCount ))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return s_wcd.returnedText;
|
||||
if( eventsCount <= 0 )
|
||||
break;
|
||||
|
||||
if( !ReadConsoleInputW( s_wcd.hInput, events, ARRAYSIZE( events ), &eventsCount ))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( eventsCount == 0 )
|
||||
return NULL;
|
||||
|
||||
for( i = 0; i < eventsCount; i++ )
|
||||
{
|
||||
INPUT_RECORD *pRec = &events[i];
|
||||
if( pRec->EventType != KEY_EVENT )
|
||||
continue;
|
||||
|
||||
if( pRec->Event.KeyEvent.bKeyDown )
|
||||
return Wcon_KeyEvent( pRec->Event.KeyEvent.wVirtualKeyCode, pRec->Event.KeyEvent.uChar.UnicodeChar );
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Con_SetFocus
|
||||
Wcon_SetStatus
|
||||
|
||||
change focus to console hwnd
|
||||
set server status string in console
|
||||
================
|
||||
*/
|
||||
void Wcon_RegisterHotkeys( void )
|
||||
void Wcon_SetStatus( const char *pStatus )
|
||||
{
|
||||
SetFocus( s_wcd.hWnd );
|
||||
if( host.type != HOST_DEDICATED )
|
||||
return;
|
||||
|
||||
// user can hit escape for quit
|
||||
RegisterHotKey( s_wcd.hWnd, QUIT_ON_ESCAPE_ID, 0, VK_ESCAPE );
|
||||
Q_strncpy( s_wcd.statusLine, pStatus, sizeof( s_wcd.statusLine ) - 1 );
|
||||
s_wcd.statusLine[sizeof( s_wcd.statusLine ) - 2] = '\0';
|
||||
Wcon_UpdateStatusLine();
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user