Compare commits
482 Commits
continuous
...
continuous
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa452160ea | ||
|
|
026435865a | ||
|
|
216e680965 | ||
|
|
3fe77ec86c | ||
|
|
a88fea6ab3 | ||
|
|
78ef00a269 | ||
|
|
f9a9aedea5 | ||
|
|
53e59c2e73 | ||
|
|
fc3b8ae45d | ||
|
|
911b83a9d8 | ||
|
|
5276e46dc0 | ||
|
|
9fbd47bb4c | ||
|
|
b8ead38573 | ||
|
|
6a318d5000 | ||
|
|
71040c7ed5 | ||
|
|
c3531b6499 | ||
|
|
9c6f12f31c | ||
|
|
913d0eb693 | ||
|
|
7bff848592 | ||
|
|
72485da491 | ||
|
|
694472f4c1 | ||
|
|
735f4e2bcb | ||
|
|
9ebeb520fa | ||
|
|
dd52840a97 | ||
|
|
4ce03662d9 | ||
|
|
20320d8dfa | ||
|
|
f2ecdad5bb | ||
|
|
298842be32 | ||
|
|
15544cde26 | ||
|
|
a4ad537e59 | ||
|
|
7ba48e00bc | ||
|
|
bb620d1265 | ||
|
|
32e6f37c7e | ||
|
|
8f95535390 | ||
|
|
b2444f2480 | ||
|
|
37d6d75e69 | ||
|
|
97bdd9dba0 | ||
|
|
ffc8bf30d7 | ||
|
|
8209a8a681 | ||
|
|
34beb9666b | ||
|
|
6ccafbe297 | ||
|
|
a479099804 | ||
|
|
94791d3cb6 | ||
|
|
6555562e78 | ||
|
|
de790d6f59 | ||
|
|
cff0df60a9 | ||
|
|
c8b8e19ed3 | ||
|
|
2106556dec | ||
|
|
7221bd6049 | ||
|
|
ded38020d3 | ||
|
|
c6251174df | ||
|
|
177c132969 | ||
|
|
3fca1bb4d5 | ||
|
|
321e28c810 | ||
|
|
7fda58561f | ||
|
|
0cbb62b329 | ||
|
|
aa2e5eb3cc | ||
|
|
3d26ba1ed8 | ||
|
|
47c4844024 | ||
|
|
d457d7d093 | ||
|
|
43364ec2e9 | ||
|
|
14127c26f5 | ||
|
|
291f24a611 | ||
|
|
1abb16638f | ||
|
|
3e41e389c5 | ||
|
|
5aca143eba | ||
|
|
60fa855d47 | ||
|
|
22661fd446 | ||
|
|
61d8d5e12b | ||
|
|
a7f3c04baa | ||
|
|
296e642f09 | ||
|
|
75eb1f1e8b | ||
|
|
8f4a45baaa | ||
|
|
18aac5fd3d | ||
|
|
ca6ca8450b | ||
|
|
6ecaea3102 | ||
|
|
fa47ca0d2d | ||
|
|
8ce3b4ac93 | ||
|
|
a7ba705277 | ||
|
|
85a4d296f5 | ||
|
|
4dd8d89459 | ||
|
|
c564cc96c7 | ||
|
|
0e54200f34 | ||
|
|
fa75c33390 | ||
|
|
36cb3b2d89 | ||
|
|
2f3b03d27a | ||
|
|
f0deac206b | ||
|
|
5d0e473cf1 | ||
|
|
2174fe6d21 | ||
|
|
5d1e207337 | ||
|
|
87c209f1f9 | ||
|
|
ed5ea002d7 | ||
|
|
149593fea5 | ||
|
|
8c0f1d65ba | ||
|
|
bbf6f1c7b8 | ||
|
|
3b61e0bbd6 | ||
|
|
8d2986bc74 | ||
|
|
27a8adad22 | ||
|
|
64e774377b | ||
|
|
8ff469d466 | ||
|
|
a20e961892 | ||
|
|
8ba30a1c09 | ||
|
|
d570d6d6da | ||
|
|
882b573e70 | ||
|
|
54657c149b | ||
|
|
9054b11ebd | ||
|
|
71d31330f9 | ||
|
|
ea29699633 | ||
|
|
ccb8d611c6 | ||
|
|
f4d98c056e | ||
|
|
779adcd838 | ||
|
|
16e2ce0aeb | ||
|
|
7bfcd4cef0 | ||
|
|
c298635728 | ||
|
|
92e976952e | ||
|
|
a85bd0c864 | ||
|
|
0a5f175431 | ||
|
|
da6402ccc2 | ||
|
|
9d1b03d119 | ||
|
|
6cf0d7a871 | ||
|
|
d5a6a7ae60 | ||
|
|
185374f99f | ||
|
|
b9072e4642 | ||
|
|
06e5895d7a | ||
|
|
ac5be8156b | ||
|
|
8c12a8baed | ||
|
|
e615ff0e7f | ||
|
|
2e8fa60e96 | ||
|
|
a8ba9124dd | ||
|
|
f6e8a68b22 | ||
|
|
706cc16a86 | ||
|
|
a9fd508e47 | ||
|
|
90bd72d481 | ||
|
|
a2a3978de7 | ||
|
|
ea70989fd2 | ||
|
|
091228bcb3 | ||
|
|
9c49253388 | ||
|
|
eea804a4bf | ||
|
|
ecbfdb82f4 | ||
|
|
a1950ec7b0 | ||
|
|
6b56e13b60 | ||
|
|
d93bee0cbc | ||
|
|
5009db6aac | ||
|
|
c389736c2f | ||
|
|
66bdca63ee | ||
|
|
d3f455649e | ||
|
|
17ff80d85d | ||
|
|
407d0aa291 | ||
|
|
d13429a287 | ||
|
|
a84204fc75 | ||
|
|
292ace2d26 | ||
|
|
68a1fbdc2b | ||
|
|
d68f29737a | ||
|
|
a34edbd8e8 | ||
|
|
71e2d4ecd4 | ||
|
|
25656b532a | ||
|
|
1a791e8556 | ||
|
|
ccd31c6b27 | ||
|
|
6aeedf201c | ||
|
|
c9f8bdfcb0 | ||
|
|
3cf4901ad2 | ||
|
|
92de3ebc58 | ||
|
|
7aa9f23590 | ||
|
|
3d999269eb | ||
|
|
1e8e4825fa | ||
|
|
91bc372811 | ||
|
|
f9df96d70e | ||
|
|
8af0e2c8b4 | ||
|
|
a5191d8948 | ||
|
|
b2d8239829 | ||
|
|
34322f025b | ||
|
|
3e6b434733 | ||
|
|
8359cbe76c | ||
|
|
0e90e6285e | ||
|
|
2f5840f650 | ||
|
|
3b51a554dd | ||
|
|
5f0880d4a2 | ||
|
|
884a3c66ac | ||
|
|
c76752cc5f | ||
|
|
fc2888e107 | ||
|
|
674b4c1506 | ||
|
|
cddd50f1e9 | ||
|
|
6c9d5bc1fb | ||
|
|
ec23860238 | ||
|
|
14a2e34b7e | ||
|
|
29c8818557 | ||
|
|
7222830b28 | ||
|
|
9b0ad7daf0 | ||
|
|
73729827f4 | ||
|
|
97fa395a3b | ||
|
|
1cef8ea7af | ||
|
|
eda4e95607 | ||
|
|
a5f0ca38f1 | ||
|
|
bbbd7711c1 | ||
|
|
38e922557d | ||
|
|
4dec1785ed | ||
|
|
9f77b7dc46 | ||
|
|
5061a29f86 | ||
|
|
cb5dffd554 | ||
|
|
4eaa8ab40f | ||
|
|
2a82d265d6 | ||
|
|
f2392b5709 | ||
|
|
5620e7ab4c | ||
|
|
a76236ac5a | ||
|
|
d1c5862bab | ||
|
|
81400d0b01 | ||
|
|
a129f13e25 | ||
|
|
ec8b4c0a84 | ||
|
|
f1f726822c | ||
|
|
8982d55392 | ||
|
|
f499286a87 | ||
|
|
a3aaa87147 | ||
|
|
15a6971aca | ||
|
|
b1eb3390e3 | ||
|
|
74ad504377 | ||
|
|
8a0c2577ed | ||
|
|
a060d7aefd | ||
|
|
ccf342f4fe | ||
|
|
8b9a40ff1f | ||
|
|
425cc61c4c | ||
|
|
fe1fd5b024 | ||
|
|
0c8da36a0b | ||
|
|
2c5030ab45 | ||
|
|
9decba873b | ||
|
|
bda4c45504 | ||
|
|
f7aa8a0c90 | ||
|
|
4c15cceb32 | ||
|
|
3e4c5beb25 | ||
|
|
f84d865f4a | ||
|
|
2465782a3e | ||
|
|
7ba2209124 | ||
|
|
af6b434b71 | ||
|
|
052ea6a8bd | ||
|
|
448dc720ed | ||
|
|
75b15696f8 | ||
|
|
7fb113f610 | ||
|
|
0497e00ad2 | ||
|
|
9c50288bbb | ||
|
|
c5d4af802c | ||
|
|
340a8b5e0c | ||
|
|
bc1b86c19c | ||
|
|
b605cf603e | ||
|
|
fdc2ed8093 | ||
|
|
a27375d1f5 | ||
|
|
0e2abf9040 | ||
|
|
89430400d9 | ||
|
|
f1a9d408bf | ||
|
|
6529692244 | ||
|
|
51d11f8e86 | ||
|
|
c5397191e5 | ||
|
|
44426709f7 | ||
|
|
2d8f747e84 | ||
|
|
0dd5a60410 | ||
|
|
eec8129be4 | ||
|
|
934c5e018d | ||
|
|
d658d8cc78 | ||
|
|
ca9a3f0491 | ||
|
|
1510cb458f | ||
|
|
30cabb8107 | ||
|
|
64ee956618 | ||
|
|
39659644bf | ||
|
|
eb09af0b08 | ||
|
|
91a4ace12c | ||
|
|
2ad2e46b30 | ||
|
|
627444279f | ||
|
|
3550bdb30d | ||
|
|
c201b895eb | ||
|
|
72f1ac3780 | ||
|
|
d7dc3192de | ||
|
|
43ea65fffc | ||
|
|
a72d921c12 | ||
|
|
99b7d71824 | ||
|
|
67c73bdcbe | ||
|
|
8b1dbcf166 | ||
|
|
5f60095dc4 | ||
|
|
c7282b488b | ||
|
|
afa829d996 | ||
|
|
c06ea8d915 | ||
|
|
bf344282ec | ||
|
|
21f62910ac | ||
|
|
54552d93ef | ||
|
|
97455e7fd4 | ||
|
|
6087d43043 | ||
|
|
c1a96d3ff1 | ||
|
|
e27d20dfa3 | ||
|
|
890e12ec76 | ||
|
|
774d2ac28a | ||
|
|
960d724828 | ||
|
|
32aa1f91bf | ||
|
|
bd3634c815 | ||
|
|
eda0ac92cc | ||
|
|
546903ea05 | ||
|
|
4975001795 | ||
|
|
a078ad1f51 | ||
|
|
8307f671d4 | ||
|
|
241fab02b1 | ||
|
|
1bfee70477 | ||
|
|
eb51d17cd2 | ||
|
|
b5cb0b9f10 | ||
|
|
a955d1e957 | ||
|
|
2b2c967e85 | ||
|
|
c48d93e3ce | ||
|
|
8f257cc331 | ||
|
|
151e7fe37b | ||
|
|
add02dc6f9 | ||
|
|
d4c34abd6e | ||
|
|
1d81e611f0 | ||
|
|
6a0038e26a | ||
|
|
1d99f65e86 | ||
|
|
5e524bca60 | ||
|
|
cf3e56e275 | ||
|
|
ade560c601 | ||
|
|
62e3ba2126 | ||
|
|
674a4e5883 | ||
|
|
f911210b81 | ||
|
|
14eb07653c | ||
|
|
54b0cf9991 | ||
|
|
3ebcb08a97 | ||
|
|
23940f8590 | ||
|
|
687fb0123f | ||
|
|
6c91fdb0cd | ||
|
|
4832232fd6 | ||
|
|
185bce0489 | ||
|
|
f460aa63b0 | ||
|
|
22f8b6f9c3 | ||
|
|
0cb034afc2 | ||
|
|
d0464ef602 | ||
|
|
c3ebb84b97 | ||
|
|
11742efbc3 | ||
|
|
95af635ab4 | ||
|
|
1abec80191 | ||
|
|
93ebddfba3 | ||
|
|
5378494199 | ||
|
|
1b44d7733e | ||
|
|
694c630b44 | ||
|
|
7df1d4b9e2 | ||
|
|
b16037eabf | ||
|
|
bff7299f9b | ||
|
|
de196b1c58 | ||
|
|
a0eec8b85d | ||
|
|
c7e8ea2ffa | ||
|
|
1c1cf3d646 | ||
|
|
9759b80b78 | ||
|
|
94b2c0b443 | ||
|
|
ff8d17a5a8 | ||
|
|
aa23196a55 | ||
|
|
83b488c37e | ||
|
|
77abf621d7 | ||
|
|
f9d4ac2771 | ||
|
|
f076d84975 | ||
|
|
faf0b32a94 | ||
|
|
feb80e5997 | ||
|
|
578a77518f | ||
|
|
2457ecf226 | ||
|
|
8cd99885f1 | ||
|
|
684e229ac8 | ||
|
|
c0f1d8c647 | ||
|
|
c3b8696957 | ||
|
|
3ca413dbab | ||
|
|
92dc04ff3c | ||
|
|
ad6db91285 | ||
|
|
90a0f74087 | ||
|
|
4f7f5288a1 | ||
|
|
c23b4bfe61 | ||
|
|
4780f70ea2 | ||
|
|
98a04c7764 | ||
|
|
7da9772143 | ||
|
|
f0b29bac1b | ||
|
|
7b5ff606bd | ||
|
|
3e22ee64ae | ||
|
|
c86c45503f | ||
|
|
ef75a4c28d | ||
|
|
bccd3f2271 | ||
|
|
7bbc3e8238 | ||
|
|
c34e0c66d9 | ||
|
|
e5d80878b8 | ||
|
|
1e075d25b7 | ||
|
|
d29e53481d | ||
|
|
d23a2fd2df | ||
|
|
f6f15cc204 | ||
|
|
4f2249ed8e | ||
|
|
9f322df498 | ||
|
|
b554d7e215 | ||
|
|
719093c10b | ||
|
|
c2da140ccc | ||
|
|
375998dffb | ||
|
|
787444f63d | ||
|
|
0c50076ff0 | ||
|
|
8ce01c38c7 | ||
|
|
cac6206984 | ||
|
|
a5c88bdda9 | ||
|
|
fc017286a6 | ||
|
|
20d4e3e719 | ||
|
|
4eaa32fc10 | ||
|
|
b7c025b167 | ||
|
|
f29c588e0f | ||
|
|
2065ef143a | ||
|
|
a5c02c85f0 | ||
|
|
9a8761f1d8 | ||
|
|
273990d292 | ||
|
|
0e27d8717c | ||
|
|
8a9b209db0 | ||
|
|
232d1f8583 | ||
|
|
6cfa5877a4 | ||
|
|
154df00f94 | ||
|
|
c5649c94d5 | ||
|
|
a1da10fe38 | ||
|
|
17a71ffc96 | ||
|
|
4609fbc0c5 | ||
|
|
d278d3bdd7 | ||
|
|
7811b60292 | ||
|
|
870fad5606 | ||
|
|
3e93aa459d | ||
|
|
626c5e44f6 | ||
|
|
c906aa0106 | ||
|
|
0a41b70e44 | ||
|
|
ea338adc46 | ||
|
|
5fa777578b | ||
|
|
5b9db5940b | ||
|
|
4b1b3aa13c | ||
|
|
2d51d23d89 | ||
|
|
b5b6dad39c | ||
|
|
a5619e9960 | ||
|
|
a75666a3cd | ||
|
|
49426721d8 | ||
|
|
04125284a3 | ||
|
|
1d4f7b2f94 | ||
|
|
38c82a3f76 | ||
|
|
785632a437 | ||
|
|
4be75af214 | ||
|
|
dcdca01e86 | ||
|
|
201d9c8f80 | ||
|
|
69341e36a3 | ||
|
|
3532a77643 | ||
|
|
35dc072b26 | ||
|
|
f92a3695b3 | ||
|
|
a7b776f3b9 | ||
|
|
f2fb668c9e | ||
|
|
90e493fa3a | ||
|
|
692bcc4073 | ||
|
|
823642b10d | ||
|
|
07189ca2f5 | ||
|
|
0d55441830 | ||
|
|
98ff33d9e2 | ||
|
|
baa8fbaaec | ||
|
|
a0b46da04b | ||
|
|
e70ba7ad64 | ||
|
|
8a41be9d47 | ||
|
|
47aff9e30b | ||
|
|
ced8744ac9 | ||
|
|
734c07ddab | ||
|
|
ceb603488a | ||
|
|
80bac157eb | ||
|
|
b45581c630 | ||
|
|
d4fe3d6f8a | ||
|
|
1907485895 | ||
|
|
cfebb3e1d6 | ||
|
|
f9a0057c28 | ||
|
|
ceb2b0c5e4 | ||
|
|
83b5edea88 | ||
|
|
9d2a85f11f | ||
|
|
93d3df81ee | ||
|
|
2a7f13151a | ||
|
|
0c4f6ae61d | ||
|
|
b7150c3208 | ||
|
|
d6ebff81e2 | ||
|
|
ce4148f351 | ||
|
|
08c2632c14 | ||
|
|
03eac904c1 | ||
|
|
62f3354f4e | ||
|
|
d5b6eff0c0 | ||
|
|
c9ee844a24 | ||
|
|
687c9b004f | ||
|
|
14e79f04ac | ||
|
|
5d6cf48687 | ||
|
|
88949a9ee6 | ||
|
|
2d1e76199b | ||
|
|
a5d78ecfd7 | ||
|
|
3576e474e6 | ||
|
|
d50927f21f | ||
|
|
c6e3146290 | ||
|
|
9811988cce |
12
.cirrus.yml
@@ -1,14 +1,13 @@
|
||||
task:
|
||||
name: freebsd-14-amd64
|
||||
freebsd_instance:
|
||||
image_family: freebsd-14-0
|
||||
image_family: freebsd-14-2
|
||||
setup_script:
|
||||
- pkg update
|
||||
- pkg install -y pkgconf git sdl2 python fontconfig opus
|
||||
- pkg install -y pkgconf git sdl2 python fontconfig libvorbis opusfile bzip2 libbacktrace
|
||||
- git submodule update --init --recursive
|
||||
test_script:
|
||||
- ./scripts/cirrus/build_freebsd.sh dedicated
|
||||
- ./scripts/cirrus/build_freebsd.sh full
|
||||
- ./scripts/cirrus/build_freebsd.sh
|
||||
|
||||
task:
|
||||
name: freebsd-15-amd64
|
||||
@@ -16,8 +15,7 @@ task:
|
||||
image_family: freebsd-15-0-snap
|
||||
setup_script:
|
||||
- pkg update
|
||||
- pkg install -y pkgconf git sdl2 python fontconfig opus
|
||||
- pkg install -y pkgconf git sdl2 python fontconfig libvorbis opusfile bzip2 libbacktrace
|
||||
- git submodule update --init --recursive
|
||||
test_script:
|
||||
- ./scripts/cirrus/build_freebsd.sh dedicated
|
||||
- ./scripts/cirrus/build_freebsd.sh full
|
||||
- ./scripts/cirrus/build_freebsd.sh
|
||||
|
||||
28
.github/workflows/c-cpp.yml
vendored
@@ -15,35 +15,39 @@ jobs:
|
||||
include:
|
||||
# Linux build specifically want oldest Ubuntu as possible
|
||||
# to be crossdistribution compatible, otherwise use ubuntu-latest
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-22.04
|
||||
targetos: linux
|
||||
targetarch: amd64
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-22.04
|
||||
targetos: linux
|
||||
targetarch: i386
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-22.04
|
||||
targetos: linux
|
||||
targetarch: arm64
|
||||
cross: true
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-22.04
|
||||
targetos: linux
|
||||
targetarch: armhf
|
||||
cross: true
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-24.04 # riscv64 would benefit from having latest compilers
|
||||
targetos: linux
|
||||
targetarch: riscv64
|
||||
cross: true
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-22.04
|
||||
targetos: linux
|
||||
targetarch: ppc64el
|
||||
cross: true
|
||||
# - os: ubuntu-aarch64-20.04
|
||||
# - os: ubuntu-aarch64-22.04
|
||||
# targetos: linux
|
||||
# targetarch: aarch64
|
||||
- os: ubuntu-20.04
|
||||
- os: ubuntu-latest
|
||||
targetos: linux
|
||||
targetarch: e2k-8c
|
||||
cross: true
|
||||
- os: ubuntu-latest
|
||||
targetos: android
|
||||
targetarch: multiarch
|
||||
# - os: ubuntu-20.04
|
||||
# - os: ubuntu-22.04
|
||||
# targetos: motomagx
|
||||
# targetarch: armv6
|
||||
|
||||
@@ -66,7 +70,7 @@ jobs:
|
||||
targetos: apple
|
||||
targetarch: amd64
|
||||
env:
|
||||
SDL_VERSION: 2.30.9
|
||||
SDL_VERSION: 2.32.0
|
||||
GH_CPU_ARCH: ${{ matrix.targetarch }}
|
||||
GH_CROSSCOMPILING: ${{ matrix.cross }}
|
||||
steps:
|
||||
@@ -87,6 +91,7 @@ jobs:
|
||||
path: artifacts/*
|
||||
flatpak:
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
@@ -100,7 +105,7 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Build flatpak (Compat.i386)
|
||||
uses: FWGS/flatpak-github-actions/flatpak-builder@v6.3
|
||||
uses: FWGS/flatpak-github-actions/flatpak-builder@v6.3-fix
|
||||
with:
|
||||
bundle: ${{ matrix.app }}.flatpak
|
||||
manifest-path: scripts/flatpak/${{ matrix.app }}.yml
|
||||
@@ -119,7 +124,6 @@ jobs:
|
||||
--yes \
|
||||
--cleanup-tag \
|
||||
--repo "$GITHUB_REPOSITORY" || true
|
||||
sleep 20s
|
||||
gh run download "$GITHUB_RUN_ID" \
|
||||
--dir artifacts/ \
|
||||
--repo "$GITHUB_REPOSITORY"
|
||||
|
||||
12
.gitmodules
vendored
@@ -27,10 +27,16 @@
|
||||
url = https://github.com/FWGS/MultiEmulator
|
||||
[submodule "3rdparty/libogg/libogg"]
|
||||
path = 3rdparty/libogg/libogg
|
||||
url = https://gitlab.xiph.org/xiph/ogg.git
|
||||
url = https://github.com/xiph/ogg.git
|
||||
[submodule "3rdparty/vorbis/vorbis-src"]
|
||||
path = 3rdparty/vorbis/vorbis-src
|
||||
url = https://gitlab.xiph.org/xiph/vorbis.git
|
||||
url = https://github.com/xiph/vorbis.git
|
||||
[submodule "3rdparty/opusfile/opusfile"]
|
||||
path = 3rdparty/opusfile/opusfile
|
||||
url = https://gitlab.xiph.org/xiph/opusfile.git
|
||||
url = https://github.com/xiph/opusfile.git
|
||||
[submodule "3rdparty/libbacktrace/libbacktrace"]
|
||||
path = 3rdparty/libbacktrace/libbacktrace
|
||||
url = https://github.com/ianlancetaylor/libbacktrace
|
||||
[submodule "3rdparty/maintui"]
|
||||
path = 3rdparty/maintui
|
||||
url = https://github.com/numas13/xash3d-maintui.git
|
||||
|
||||
2
3rdparty/MultiEmulator
vendored
1
3rdparty/extras/wscript
vendored
@@ -25,5 +25,4 @@ def build(bld):
|
||||
name = 'extras.pk3',
|
||||
files = srcdir.ant_glob('**/*'),
|
||||
relative_to = srcdir,
|
||||
compresslevel = 0,
|
||||
install_path = install_path)
|
||||
|
||||
2
3rdparty/extras/xash-extras
vendored
2
3rdparty/gl4es/gl4es
vendored
1
3rdparty/libbacktrace/libbacktrace
vendored
Submodule
183
3rdparty/libbacktrace/wscript
vendored
Normal file
@@ -0,0 +1,183 @@
|
||||
#! /usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
from waflib import TaskGen
|
||||
from waflib.Tools.c_config import DEFKEYS
|
||||
|
||||
FRAGMENT_ATOMIC='''int i;
|
||||
int main(void) {
|
||||
__atomic_load_n(&i, __ATOMIC_ACQUIRE);
|
||||
__atomic_store_n(&i, 1, __ATOMIC_RELEASE);
|
||||
return 0;
|
||||
}'''
|
||||
|
||||
FRAGMENT_SYNC='''int i;
|
||||
int main (void) {
|
||||
__sync_bool_compare_and_swap (&i, i, i);
|
||||
__sync_lock_test_and_set (&i, 1);
|
||||
__sync_lock_release (&i);
|
||||
return 0;
|
||||
}'''
|
||||
|
||||
FRAGMENT_GETPAGESIZE='''#include <unistd.h>
|
||||
int main(void) { return getpagesize() }'''
|
||||
|
||||
FRAGMENT_GETEXECNAME='''#include <stdlib.h>
|
||||
int main(void) { return getexecname() != 0 }'''
|
||||
|
||||
FRAGMENT_STRNLEN='''#include <string.h>
|
||||
int main(int argc, char **argv) { return (int)strnlen(argv[0], 10); }'''
|
||||
|
||||
FRAGMENT_DL_ITERATE_PHDR='''#include <%s>
|
||||
int main(void) { return dl_iterate_phdr(0, 0); }'''
|
||||
|
||||
FRAGMENT_FCNTL='''#include <fcntl.h>
|
||||
int main(void) { return fcntl(0, 0, 0); }'''
|
||||
|
||||
FRAGMENT_GETIPINFO='''#include "unwind.h"
|
||||
struct _Unwind_Context *context;
|
||||
int ip_before_insn = 0;
|
||||
int main(void) { return _Unwind_GetIPInfo(context, &ip_before_insn); }'''
|
||||
|
||||
FRAGMENT_LOADQUERY='''#include <sys/ldr.h>
|
||||
#include <sys/debug.h>
|
||||
int main(void) { return loadquery(0, 0, 0); }'''
|
||||
|
||||
FRAGMENT_KERN_PROC='''#include <sys/sysctl.h>
|
||||
#if !defined(%s) || !defined(KERN_PROC_PATHNAME)
|
||||
#error
|
||||
#endif
|
||||
int main(void) { return 0; }'''
|
||||
|
||||
FRAGMENT_LSTAT='''#include <sys/stat.h>
|
||||
struct stat st;
|
||||
int main(int argc, char **argv) { return lstat(argv[0], &st); }'''
|
||||
|
||||
FRAGMENT_READLINK='''#include <unistd.h>
|
||||
char buf[100];
|
||||
int main(int argc, char **argv) { return readlink(argv[0], buf, sizeof(buf)); }'''
|
||||
|
||||
def options(opt):
|
||||
pass
|
||||
|
||||
def configure(conf):
|
||||
# add unsupported platforms here
|
||||
if conf.env.DEST_OS in ['nswitch', 'psvita', 'dos']:
|
||||
conf.env.DISABLE_LIBBACKTRACE = True
|
||||
return
|
||||
|
||||
# win32 has it's own dbghelp-based backtrace, that's why we ship PDBs
|
||||
if conf.env.COMPILER_CC == 'msvc':
|
||||
conf.env.DISABLE_LIBBACKTRACE = True
|
||||
return
|
||||
|
||||
if not conf.path.find_dir('libbacktrace') or not conf.path.find_dir('libbacktrace/config'):
|
||||
conf.fatal('Can\'t find libbacktrace submodule. Run `git submodule update --init --recursive`.')
|
||||
return
|
||||
|
||||
conf.define('BACKTRACE_ELF_SIZE', 64 if conf.env.DEST_SIZEOF_VOID_P == 8 else 32)
|
||||
conf.define('BACKTRACE_XCOFF_SIZE', 64 if conf.env.DEST_SIZEOF_VOID_P == 8 else 32)
|
||||
conf.define('_ALL_SOURCE', 1)
|
||||
conf.define('_GNU_SOURCE', 1)
|
||||
conf.define('_POSIX_PTHREAD_SEMANTICS', 1)
|
||||
conf.define('_TANDEM_SOURCE', 1)
|
||||
conf.define('__EXTENSIONS__', 1)
|
||||
conf.define('_DARWIN_USE_64_BIT_INODE', 1)
|
||||
conf.define('_LARGE_FILES', 1)
|
||||
conf.check_large_file(compiler='c', execute=False, mandatory=False) # sets _FILE_OFFSET_BITS
|
||||
|
||||
conf.env.CFLAGS_EXTRAFLAGS = conf.filter_cflags(['-funwind-tables', '-g'], [])
|
||||
|
||||
if conf.filter_cflags(['-frandom-seed=test'], []):
|
||||
conf.env.HAVE_FRANDOM_SEED = True
|
||||
|
||||
def check_header(hdr):
|
||||
return {'header_name':hdr, 'msg':'... %s header' % hdr, 'mandatory':False, 'id':hdr}
|
||||
|
||||
conf.multicheck(
|
||||
check_header('dlfcn.h'),
|
||||
check_header('inttypes.h'),
|
||||
check_header('link.h'),
|
||||
check_header('sys/link.h'),
|
||||
check_header('mach-o/dyld.h'),
|
||||
check_header('memory.h'),
|
||||
check_header('stdint.h'),
|
||||
check_header('stdlib.h'),
|
||||
check_header('strings.h'),
|
||||
check_header('string.h'),
|
||||
check_header('sys/ldr.h'),
|
||||
check_header('sys/mman.h'),
|
||||
check_header('sys/stat.h'),
|
||||
check_header('sys/types.h'),
|
||||
check_header('tlhelp32.h'),
|
||||
check_header('unistd.h'),
|
||||
check_header('windows.h'),
|
||||
|
||||
{'fragment':FRAGMENT_ATOMIC, 'msg':'... __atomic extensions', 'define_name':'HAVE_ATOMIC_FUNCTIONS', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_SYNC, 'msg':'... __sync extensions', 'define_name':'HAVE_SYNC_FUNCTIONS', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_GETPAGESIZE, 'msg':'... getpagesize function', 'define_name':'HAVE_DECL_GETPAGESIZE', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_STRNLEN, 'msg':'... strnlen function', 'define_name':'HAVE_DECL_STRNLEN', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_DL_ITERATE_PHDR % 'link.h', 'msg':'... dl_iterate_phdr function in link.h', 'define_name':'HAVE_DL_ITERATE_PHDR', 'after_tests': ['link.h'], 'mandatory':False},
|
||||
{'fragment':FRAGMENT_DL_ITERATE_PHDR % 'sys/link.h', 'msg':'... dl_iterate_phdr function in sys/link.h', 'define_name':'HAVE_DL_ITERATE_PHDR', 'after_tests': ['sys/link.h'], 'mandatory':False},
|
||||
{'fragment':FRAGMENT_FCNTL,'msg':'... fnctl function', 'define_name':'HAVE_FCNTL', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_GETEXECNAME,'msg':'... getexecname function','define_name':'HAVE_GETEXECNAME', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_GETIPINFO, 'msg':'... _Unwind_GetIPInfo function', 'define_name':'HAVE_GETIPINFO', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_KERN_PROC % 'KERN_PROC', 'msg': '... KERN_PROC and KERN_PROC_PATHNAME defines', 'define_name':'HAVE_KERN_PROC', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_KERN_PROC % 'KERN_PROC_ARGS', 'msg': '... KERN_PROC_ARGS and KERN_PROC_PATHNAME defines', 'define_name':'HAVE_KERN_PROC_ARGS', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_LOADQUERY, 'msg': '... loadquery function', 'define_name':'HAVE_LOADQUERY', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_LSTAT, 'msg': '... lstat function', 'define_name':'HAVE_LSTAT', 'mandatory':False},
|
||||
{'fragment':FRAGMENT_READLINK, 'msg': '... readlink function', 'define_name':'HAVE_READLINK', 'mandatory':False},
|
||||
|
||||
# {'lib':'lzma', 'define_name':'HAVE_LIBLZMA', 'uselib_store':'lzma', 'msg':'... lzma library', 'mandatory':False},
|
||||
# {'lib':'z', 'define_name':'HAVE_ZLIB', 'uselib_store':'z', 'msg':'... zlib library', 'mandatory':False},
|
||||
# {'lib':'zstd', 'define_name':'HAVE_ZSTD', 'uselib_store':'zstd', 'msg':'... zstd library', 'mandatory':False},
|
||||
msg='Checking for in parallel'
|
||||
)
|
||||
|
||||
conf.env[DEFKEYS].sort()
|
||||
|
||||
conf.write_config_header()
|
||||
|
||||
conf.define('BACKTRACE_SUPPORTED', 1)
|
||||
conf.define('BACKTRACE_USES_MALLOC', 0)
|
||||
conf.define('BACKTRACE_SUPPORTS_THREADS', 1)
|
||||
conf.define('BACKTRACE_SUPPORTS_DATA', conf.env.DEST_BINFMT in ['elf', 'mac-o'])
|
||||
|
||||
conf.write_config_header('backtrace-supported.h')
|
||||
|
||||
@TaskGen.feature('frandomseed')
|
||||
@TaskGen.after_method('propagate_uselib_vars')
|
||||
def process_frandom_seed(ctx):
|
||||
tasks = getattr(ctx, 'compiled_tasks', [])
|
||||
|
||||
for task in tasks:
|
||||
out = task.outputs[0]
|
||||
task.env.CFLAGS = list(task.env.CFLAGS) # need a copy
|
||||
task.env.CFLAGS += ['-frandom-seed=%s' % out.path_from(out.ctx.bldnode)]
|
||||
|
||||
def build(bld):
|
||||
if bld.env.DISABLE_LIBBACKTRACE:
|
||||
return
|
||||
|
||||
# we specifically only want mmap-based allocators because calling malloc is not safe from signal handlers
|
||||
sources = ['atomic.c', 'dwarf.c', 'fileline.c', 'posix.c', 'print.c', 'sort.c', 'state.c', 'backtrace.c', 'simple.c', 'mmap.c', 'mmapio.c']
|
||||
|
||||
if bld.env.DEST_BINFMT == 'pe':
|
||||
sources += ['pecoff.c']
|
||||
elif bld.env.DEST_BINFMT == 'mac-o':
|
||||
sources += ['macho.c']
|
||||
elif bld.env.DEST_BINFMT == 'elf':
|
||||
sources += ['elf.c']
|
||||
else:
|
||||
sources += ['unknown.c']
|
||||
|
||||
task = bld.stlib(
|
||||
source = ['libbacktrace/' + i for i in sources],
|
||||
target = 'backtrace',
|
||||
features = 'frandomseed' if bld.env.HAVE_FRANDOM_SEED else '',
|
||||
use = 'EXTRAFLAGS lzma z zstd',
|
||||
includes = '. libbacktrace/',
|
||||
export_defines = 'HAVE_LIBBACKTRACE=1',
|
||||
export_includes = 'libbacktrace/'
|
||||
)
|
||||
|
||||
1
3rdparty/maintui
vendored
Submodule
2
3rdparty/mainui
vendored
2
3rdparty/vgui_support
vendored
@@ -45,3 +45,8 @@
|
||||
Tags can be any: subsystem, simple feature name or even just a filename, without extension.
|
||||
Just keep them always same, it helps keep history clean and commit messages short.
|
||||
|
||||
## LLM-based tools usage.
|
||||
|
||||
While we wouldn't recommend using any LLM-based (also misleadingly called AI) tools, we understand that they are here to stay.
|
||||
|
||||
Whether you're reporting bug or contributing the code, you take complete authorship and responsibility over provided content and the same rules will apply to you as for everybody else, so validate the bug report or the patch before sending it.
|
||||
|
||||
@@ -2,23 +2,27 @@
|
||||
|
||||
On this page you can find links where you can support each developer individually, who has provided public sponsorship information.
|
||||
|
||||
### [a1batross](https://github.com/a1batross)
|
||||
## [a1batross](https://github.com/a1batross)
|
||||
|
||||
* Initial Xash3D SDL2/Linux port author, Xash3D FWGS engine maintainer, creator of non-commercial Flying With Gauss organization.
|
||||
* Boosty page: https://boosty.to/a1ba
|
||||
Initial Xash3D SDL2/Linux port author, Xash3D FWGS engine maintainer, creator of non-commercial Flying With Gauss organization.
|
||||
|
||||
### [nekonomicon](https://github.com/nekonomicon)
|
||||
* [Boosty page](https://boosty.to/a1ba)
|
||||
|
||||
* [hlsdk-portable](https://github.com/FWGS/hlsdk-portable), [mdldec](../utils/mdldec), [opensource-mods.md](opensource-mods.md) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=nekonomicon) (*BSD/clang port, PNG support, etc).
|
||||
* Boosty page: https://boosty.to/nekonomicon
|
||||
## [nekonomicon](https://github.com/nekonomicon)
|
||||
|
||||
### [Velaron](https://github.com/Velaron)
|
||||
* [cs16-client](https://github.com/Velaron/cs16-client) & [tf15-client](https://github.com/Velaron/tf15-client) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=Velaron) (Android port, voice chat, etc).
|
||||
* BuyMeACoffee page: https://www.buymeacoffee.com/velaron
|
||||
[hlsdk-portable](https://github.com/FWGS/hlsdk-portable), [mdldec](../utils/mdldec), [opensource-mods.md](opensource-mods.md) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=nekonomicon) (*BSD/clang port, PNG support, etc).
|
||||
|
||||
### [SNMetamorph](https://github.com/SNMetamorph)
|
||||
* [PrimeXT](https://github.com/SNMetamorph/PrimeXT) & [GoldSrc Monitor](https://github.com/SNMetamorph/goldsrc-monitor) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=SNMetamorph) (Windows port, voice chat, etc).
|
||||
* BTC: `16GAzK3qei5AwBW7sggXp3yNcFHBtdpxXj`
|
||||
* ETH (ERC20): `0xb580eeca9756e3881f9d6d026e28db28eb72a383`
|
||||
* USDT (ERC20): `0xb580eeca9756e3881f9d6d026e28db28eb72a383`
|
||||
* USDC (ERC20): `0xb580eeca9756e3881f9d6d026e28db28eb72a383`
|
||||
* [Boosty page](https://boosty.to/nekonomicon)
|
||||
|
||||
## [Velaron](https://github.com/Velaron)
|
||||
|
||||
[cs16-client](https://github.com/Velaron/cs16-client) & [tf15-client](https://github.com/Velaron/tf15-client) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=Velaron) (Android port, voice chat, etc).
|
||||
|
||||
* [BuyMeACoffee page](https://www.buymeacoffee.com/velaron)
|
||||
|
||||
## [SNMetamorph](https://github.com/SNMetamorph)
|
||||
|
||||
[PrimeXT](https://github.com/SNMetamorph/PrimeXT) & [GoldSrc Monitor](https://github.com/SNMetamorph/goldsrc-monitor) maintainer and Xash3D FWGS [contributor](https://github.com/FWGS/xash3d-fwgs/commits?author=SNMetamorph) (Windows port, voice chat, etc).
|
||||
|
||||
* [Boosty page](https://boosty.to/snmetamorph)
|
||||
* [Other donation methods](https://snmetamorph.github.io/donate)
|
||||
|
||||
@@ -85,6 +85,9 @@ These strings are specific to Xash3D FWGS.
|
||||
As Xash3D accidentally supports GoldSrc games, it also supports parsing liblist.gam.\
|
||||
Xash3D will use this file if gameinfo.txt is absent, or if its modification timestamp is older than liblist.gam.
|
||||
|
||||
> [!NOTE]
|
||||
> Starting from January 2025, Xash3D FWGS doesn't automatically generate gameinfo.txt from liblist.gam. The key conversion table still remains but if you wish to use gameinfo.txt instead of liblist.gam, you can execute `fs_make_gameinfo` in console.
|
||||
|
||||
For game creators who plan supporting only Xash3D, using this file is not recommended.
|
||||
|
||||
The table below defines conversion rules from liblist.gam to gameinfo.txt. Some keys' interpretation does differ from `gameinfo.txt`, in this case a note will be left. If `liblist.gam` key isn't present in this table, it's ignored.
|
||||
|
||||
@@ -6,7 +6,7 @@ For connecting to GoldSrc-based servers, use this command:
|
||||
connect ip:port gs
|
||||
```
|
||||
|
||||
But keep in mind, there are requirement for server to be able to accept connections from Xash3D-based clients: it should use Reunion or Dproto.
|
||||
But keep in mind, there are requirement for server to be able to accept connections from Xash3D-based clients: it should use Reunion.
|
||||
Without this requirement, you will just get "Steam validation rejected" error on connecting.
|
||||
|
||||
That is because proper authorization with Steam API is not implemented in engine yet (but we have plans on it).
|
||||
|
||||
BIN
Documentation/images/editor.jpg
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
Documentation/images/example1.jpg
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
Documentation/images/example2.jpg
Normal file
|
After Width: | Height: | Size: 212 KiB |
BIN
Documentation/images/example3.jpg
Normal file
|
After Width: | Height: | Size: 400 KiB |
BIN
Documentation/images/example4.jpg
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
Documentation/images/example5.jpg
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
Documentation/images/touch-buttons.jpg
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
Documentation/images/touch-profiles.jpg
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
@@ -2,10 +2,19 @@
|
||||
|
||||
|Name |Version |Why not working |What was made for that
|
||||
|---- |------- |--------------- |----------------------
|
||||
|Blue Shift |The latest steam release |Uses vgui2 library which xash3d does not support |Recreated source code here: https://github.com/FWGS/hlsdk-xash3d/tree/bshift
|
||||
|Counter Strike |1.6(The latest steam release) |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|
||||
|Counter Strike: Condition Zero |The latest steam release |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|
||||
|Counter Strike: Condition Zero - Deleted scenes |The latest steam release |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|
||||
|Day of Defeat |The latest steam release |Uses vgui2 library which xash3d does not support |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface
|
||||
|Sven-Coop |5.0+ |Uses custom GoldSrc engine |
|
||||
|
||||
|Area 51 |Update 1 |Uses outdated BSP31 map format and custom HLFX SDK libraries. |You can try [this tool](https://hlfx.ru/forum/showthread.php?threadid=5250) to convert maps but there no warranty if it works.
|
||||
|Arrange Mod: Rebirth |v150 |No idea yet. |
|
||||
|Blue Shift |The latest steam release |Uses vgui2 library which xash3d does not support. |Recreated source code here: https://github.com/FWGS/hlsdk-xash3d/tree/bshift.
|
||||
|Counter Strike |Beta 6.5- |Uses an old WON HL 1.0.0.16- interface. |
|
||||
| |1.4 |Has encrypted blob instead of normal client.dll. |You can try [this tool](https://aluigi.altervista.org/papers/hldlldec.zip) to decrypt client.dll but there no warranty if it works.
|
||||
| |1.5 |Has encrypted blob instead of normal client.dll. |Decrypted blob here: https://csm.dev/threads/cs-1-5-client-dll-decrypted-patched-for-usage.38845.
|
||||
| |1.6(The latest steam release) |Uses vgui2 library which xash3d does not support. |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface. Recreated Client Source Code here: https://github.com/Velaron/cs16-client.
|
||||
|Counter Strike: Condition Zero |The latest steam release |Uses vgui2 library which xash3d does not support. |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface. Recreated Client Source Code here: https://github.com/Velaron/cs16-client.
|
||||
|Counter Strike: Condition Zero - Deleted scenes |The latest steam release |Uses vgui2 library which xash3d does not support. Uses new sequences code on engine-side that was never used in any other mods before. |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface.
|
||||
|Day of Defeat |The latest steam release |Uses vgui2 library which xash3d does not support. |Some work on vgui2 support was made here: https://github.com/FWGS/xash3d/tree/vinterface.
|
||||
|Half-Life: Extended |Day One demo |Uses many hooks to GoldSource engine and version check. |Just wait new version or use more old version.
|
||||
|Icon of Hell |Beta 0.99 |Uses outdated BSP31 map format and paranoia 2 libraries. |You can try [this tool](https://hlfx.ru/forum/showthread.php?threadid=5250) to convert maps and use Paranoia 2: The Savior 1.51 libraries but there no warranty if it works.
|
||||
|Paranoia 2: The Savior |All builds older 1.51 |Uses an old renderer interface and engine features. |
|
||||
|Rebellion |1.0 |Uses an old WON HL 1.0.0.16- interface. |Recreated source code here: https://github.com/FWGS/hlsdk-xash3d/tree/rebellion.
|
||||
|Sven-Coop |5.0+ |Uses custom GoldSrc engine. |
|
||||
|Time Shadows |Beta 0.1 |Uses Direct3D renderer. |
|
||||
|
||||
@@ -32,12 +32,21 @@ Version 1.9 mirrored on github - https://github.com/solidi/hl-mods/tree/master/c
|
||||
## Cold Ice Ressurection
|
||||
Mirrored on github - https://github.com/solidi/hl-mods/tree/master/cir
|
||||
|
||||
## Counter-Life
|
||||
Available on ModDB - https://www.moddb.com/mods/counter-life/downloads/cl-version-1-source-code
|
||||
|
||||
## Cthulhu
|
||||
Uploaded to github by Oleg Cherkasky - https://github.com/gunrunners-paradise/Cthulhu-HLmod-SDK
|
||||
|
||||
## Deathmatch Classic
|
||||
Available in Valve's Half-Life repository - https://github.com/ValveSoftware/halflife/tree/master/dmc
|
||||
|
||||
## Delta Particles
|
||||
Available on ModDB - https://www.moddb.com/mods/half-life-delta/downloads/delta-particles-full-sources-maps-and-c-code
|
||||
|
||||
## Earth Special Forces
|
||||
Alpha 2.0 - https://www.gamers-desire.de/details/2830
|
||||
|
||||
## ESHQ
|
||||
Official github repository - https://github.com/adslbarxatov/xash3d-for-ESHQ
|
||||
|
||||
|
||||
@@ -2,11 +2,14 @@
|
||||
|
||||
### Prerequisites
|
||||
1. Make sure your PSVita is [set up to run homebrew applications](https://vita.hacks.guide/).
|
||||
2. Install [kubridge](https://github.com/TheOfficialFloW/kubridge/releases/) by copying `kubridge.suprx` to your taiHEN plugins folder (usually `ux0:/tai`) and add it to your `config.txt`, for example:
|
||||
2. Install [kubridge](https://github.com/TheOfficialFloW/kubridge/releases/). It is recommended to use kubridge version `0.1`, because other versions aren't tested, we don't know are they suitable or not.
|
||||
|
||||
Worth to notice, we got reports that automatic plugins management app EasyPlugin have issues with installing kubridge plugin, so it's better to install it manually: by copying `kubridge.suprx` to your taiHEN plugins folder (usually `ux0:/tai`, but could be `ur0:/tai`) and add it to your `config.txt`, for example:
|
||||
```
|
||||
*KERNEL
|
||||
ux0:tai/kubridge.skprx
|
||||
```
|
||||
|
||||
3. Install `libshacccg.suprx` by following [this guide](https://cimmerian.gitbook.io/vita-troubleshooting-guide/shader-compiler/extract-libshacccg.suprx).
|
||||
|
||||
### Installation
|
||||
|
||||
149
Documentation/touch-controls.md
Normal file
@@ -0,0 +1,149 @@
|
||||
# Touch controls configuring
|
||||
|
||||
## Introduction
|
||||
|
||||
Thanks to mittorn, we have the ability to fully customize the controls in Xash3D. The new config allows you to not only add and change control buttons, but also create custom menus. There is also a built-in visual editor available, which simplifies the customization process without the need for manual file editing.
|
||||
|
||||
## Editor mode usage
|
||||
|
||||
1. Launch Xash3D and start the game.
|
||||
2. To enter the edit mode, click on the gear icon (command `touch_enableedit`).
|
||||
3. In the edit mode, the grid is displayed. The number of cells can be changed with the command `touch_grid_count` (default is 50). The grid can be disabled with the command `touch_grid_enable 0`.
|
||||
|
||||
*Touch controls layout editor*
|
||||

|
||||
|
||||
*Touch profiles window*
|
||||

|
||||
|
||||
*Touch buttons parameters window*
|
||||

|
||||
|
||||
## Layout editor features
|
||||
|
||||
* **Moving buttons**: click on a button, drag it to the desired location, and release.
|
||||
* **Resizing buttons**: place your first finger on the top left corner of the button, and use your second finger to resize it.
|
||||
* **Hiding/showing buttons**: select the button (it will turn red), then use the menu:
|
||||
* **Close**: closes the editing mode (`touch_disableedit`).
|
||||
* **Reset**: resets the button to its default values.
|
||||
* **Hide/Show**: hides or shows the button (`touch_hide <name>` / `touch_show <name>`).
|
||||
|
||||
## Working with configuration files / console
|
||||
|
||||
All changes made in the visual editor are automatically saved to the touch profile file. The files are located in the `touch_profiles` folder inside game directory. The file name depends on the selected profile.
|
||||
|
||||
### Common commands in configuration files
|
||||
|
||||
```
|
||||
// Comment: lines starting with // are ignored.
|
||||
|
||||
// Swipe zones for movement. Specify how far you need to swipe to speed up.
|
||||
// The default values are set to be optimal for a small swipe to immediately walk quickly.
|
||||
touch_forwardzone "0.060000" ; touch_sidezone "0.060000"
|
||||
|
||||
// Sensitivity settings (pitch - horizontal, yaw - vertical).
|
||||
touch_pitch ; touch_yaw
|
||||
|
||||
// Grid settings (see above).
|
||||
touch_grid_count ; touch_grid_enable
|
||||
|
||||
// Draws a border around the button.
|
||||
touch_set_stroke <thickness> <c> <v> <e> <t>
|
||||
(<r> - red; <g> - green; <b> - blue; <a> - alpha/transparency)
|
||||
|
||||
// Show (1) or hide (0) client buttons.
|
||||
touch_setclientonly
|
||||
|
||||
// Removes all buttons from the screen.
|
||||
touch_removeall
|
||||
|
||||
// Shows all available buttons in the configuration file.
|
||||
touch_list
|
||||
|
||||
// Saves the config after editing. You can specify a new file name.
|
||||
touch_config_file command.cfg
|
||||
```
|
||||
|
||||
*The full list of buttons in the standard `touch.cfg` file, displayed in the console when using `touch_list`.*
|
||||

|
||||
|
||||
|
||||
## Adding new buttons
|
||||
|
||||
To add a new button, use the console command:
|
||||
|
||||
```
|
||||
touch_addbutton "digits" "touch/key_1.png" "toggle_digits" 0.340000 0.782222 0.400000 0.888889 255 255 255 100 0
|
||||
```
|
||||
|
||||
### Parameters of `touch_addbutton` command
|
||||
|
||||
| Parameter | Description |
|
||||
| --- | --- |
|
||||
| `"digits"` | Unique name of the button. |
|
||||
| `"touch/key_1.png"` | Path to the icon file (`.png` format). If the icon is not needed, leave `""`. |
|
||||
| `"toggle_digits"` | Command to execute after clicking (for example, `"buy"` for purchase). |
|
||||
| `0.340000` | X coordinate of the upper-left corner of the button. |
|
||||
| `0.782222` | Y coordinate of the upper-left corner of the button. |
|
||||
| `0.400000` | X coordinate of the lower-right corner of the button. |
|
||||
| `0.888889` | Y coordinate of the lower-right corner of the button. |
|
||||
| `255 255 255` | Button color in RGB format. |
|
||||
| `100` | Button transparency (0 - fully transparent, 255 - fully opaque). |
|
||||
| `0` | Flags (see next section). |
|
||||
|
||||
## List of flags
|
||||
|
||||
Flags define the behavior of the button. Their values are powers of two:
|
||||
|
||||
| Flag | Value | Description |
|
||||
| --- | --- | --- |
|
||||
| `TOUCH_FL_HIDE` | 1 | Hides the button (not displayed in the game, but visible in the editor). |
|
||||
| `TOUCH_FL_NOEDIT` | 2 | Disables editing of the button in the editor. |
|
||||
| `TOUCH_FL_CLIENT` | 4 | The button is client-side (not saved in the main control file). |
|
||||
| `TOUCH_FL_MP` | 8 | The button is displayed only in multiplayer. |
|
||||
| `TOUCH_FL_SP` | 16 | The button is displayed only in singleplayer. |
|
||||
| `TOUCH_FL_DEF_SHOW` | 32 | The button is always displayed on startup. |
|
||||
| `TOUCH_FL_DEF_HIDE` | 64 | The button is always hidden on startup. |
|
||||
| `TOUCH_FL_DRAW_ADDITIVE` | 128 | The button colors are added together in blend mode. |
|
||||
| `TOUCH_FL_STROKE` | 256 | Enables outline stroke around the button. |
|
||||
|
||||
Flags can be combined by adding their values together. For example, `5 = 1 + 4` is the combination of `TOUCH_FL_HIDE` and `TOUCH_FL_CLIENT` flags, which is a hidden client button.
|
||||
|
||||
*In the image below, the `spray`, `scores`, `messagemode` buttons are displayed simultaneously with the flag 8 and `loadquick`, `savequick` with the flag 16, and each is displayed in the corresponding game mode.*
|
||||

|
||||
|
||||
## Useful commands
|
||||
|
||||
* `touch_hide <pattern>`: hides buttons by pattern.
|
||||
* `touch_setcommand`: changes the command bound to a button.
|
||||
* `touch_settexture`: quickly changes the button image.
|
||||
* `touch_setcolor`: sets the button color.
|
||||
* `touch_exportconfig`: exports the current configuration, including aspect ratio.
|
||||
|
||||
## Usage examples
|
||||
|
||||
* `touch_hide menu*` hides all buttons with names starting with `menu`.
|
||||
* `touch_setcolor "attack" 255 160 0 128` changes the color of the primary fire button from opaque white to translucent orange, similar to the color of the HUD in Half-Life.
|
||||
|
||||
*Result of executing this command*
|
||||

|
||||
|
||||
* Example of adding a new button with a custom icon (the `lastinv` command is used - quick change between weapons)
|
||||

|
||||
|
||||
*View of this button in layout editor*
|
||||

|
||||
|
||||
## Tips
|
||||
|
||||
* To prevent the `look` and `move` buttons from interfering with editing other elements, place them before the others in the configuration file.
|
||||
* And vice versa, to make a button appear on top of others, place it at the end of the configuration file.
|
||||
* You can assign commands to buttons that change other buttons, see the previous section "Usage examples".
|
||||
* After editing each parameter of each individual button in the Touch Buttons section, do not forget to press Save, otherwise the applied parameters will not be saved.
|
||||
* To create your own icon for the button, you can use any graphics editor (for Android, Photo Editor by iudesk is suitable). Saving conditions:
|
||||
* Image format - `.png` with transparency (e.g. alpha channel)
|
||||
* Aspect ratio / size - 1:1 / 256x256
|
||||
* Path to the icons location - `touch/gfx` inside game directory.
|
||||
|
||||
### Additional links
|
||||
* [Handy palette for selecting color in RGB format](https://www.rapidtables.com/web/color/RGB_Color.html)
|
||||
17
README.md
@@ -1,8 +1,9 @@
|
||||
# Xash3D FWGS Engine <img align="right" width="128" height="128" src="https://github.com/FWGS/xash3d-fwgs/raw/master/game_launch/icon-xash-material.png" alt="Xash3D FWGS icon" />
|
||||
[](https://builds.sr.ht/~a1batross/xash3d-fwgs?) [](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)
|
||||
[](https://github.com/FWGS/xash3d-fwgs/actions/workflows/c-cpp.yml) [](https://cirrus-ci.com/github/FWGS/xash3d-fwgs) \
|
||||
[](http://fwgsdiscord.mentality.rip/) [](https://t.me/flyingwithgauss) \
|
||||
[](https://github.com/FWGS/xash3d-fwgs/releases/tag/continuous)
|
||||
|
||||
Xash3D (pronounced `[ksɑʂ]`) FWGS is a game engine, aimed to provide compatibility with Half-Life Engine and extend it, as well as to give game developers well known workflow.
|
||||
Xash3D ([pronounced](https://ipa-reader.com/?text=ks%C9%91%CA%82) `[ksɑʂ]`) FWGS is a game engine, aimed to provide compatibility with Half-Life Engine and extend it, as well as to give game developers well known workflow.
|
||||
|
||||
Xash3D FWGS is a heavily modified fork of an original [Xash3D Engine](https://www.moddb.com/engines/xash3d-engine) by Unkle Mike.
|
||||
|
||||
@@ -43,7 +44,7 @@ For additional info, run Xash3D with `-help` command line key.
|
||||
## Build instructions
|
||||
We are using Waf build system. If you have some Waf-related questions, I recommend you to read [Waf Book](https://waf.io/book/).
|
||||
|
||||
NOTE: NEVER USE GitHub's ZIP ARCHIVES. GitHub doesn't include external dependencies we're using!
|
||||
**NOTE: NEVER USE GitHub's ZIP ARCHIVES. GitHub doesn't include external dependencies we're using!**
|
||||
|
||||
### Prerequisites
|
||||
If your CPU is x86 compatible and you're on Windows or Linux, we are building 32-bit code by default. This was done to maintain compatibility with Steam releases of Half-Life and based on it's engine games.
|
||||
@@ -65,21 +66,21 @@ This repository contains our fork of HLSDK and restored source code for Half-Lif
|
||||
* Only for 32-bit engine on 64-bit x86 operating system:
|
||||
* Enable i386 on your system: `$ sudo dpkg --add-architecture i386`.
|
||||
* Install `aptitude` ([why?](https://github.com/FWGS/xash3d-fwgs/issues/1828#issuecomment-2415131759)): `$ sudo apt update && sudo apt upgrade && sudo apt install aptitude`
|
||||
* Install development tools: `$ sudo aptitude --without-recommends install git build-essential gcc-multilib g++-multilib libsdl2-dev:i386 libfontconfig-dev:i386 libfreetype-dev:i386 libopus-dev:i386 libbz2-dev:i386`.
|
||||
* Install development tools: `$ sudo aptitude --without-recommends install git build-essential gcc-multilib g++-multilib libsdl2-dev:i386 libfreetype-dev:i386 libopus-dev:i386 libbz2-dev:i386 libvorbis-dev:i386 libopusfile-dev:i386 libogg-dev:i386`.
|
||||
* Set PKG_CONFIG_PATH environment variable to point at 32-bit libraries: `$ export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig`.
|
||||
|
||||
* For 64-bit engine on 64-bit x86 and other non-x86 systems:
|
||||
* Install development tools: `$ sudo apt install git build-essential python libsdl2-dev libfontconfig-dev libfreetype6-dev libopus-dev libbz2-dev`.
|
||||
* Install development tools: `$ sudo apt install git build-essential python libsdl2-dev libfreetype6-dev libopus-dev libbz2-dev libvorbis-dev libopusfile-dev libogg-dev`.
|
||||
|
||||
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
|
||||
|
||||
##### RedHat/Fedora
|
||||
* Only for 32-bit engine on 64-bit x86 operating system:
|
||||
* Install development tools: `$ sudo dnf install git gcc gcc-c++ glibc-devel.i686 SDL2-devel.i686 opus-devel.i686 fontconfig-devel.i686 freetype-devel.i686 bzip2-devel.i686`.
|
||||
* Install development tools: `$ sudo dnf install git gcc gcc-c++ glibc-devel.i686 SDL2-devel.i686 opus-devel.i686 freetype-devel.i686 bzip2-devel.i686 libvorbis-devel.i686 opusfile-devel.i686 libogg-devel.i686`.
|
||||
* Set PKG_CONFIG_PATH environment variable to point at 32-bit libraries: `$ export PKG_CONFIG_PATH=/usr/lib/pkgconfig`.
|
||||
|
||||
* For 64-bit engine on 64-bit x86 and other non-x86 systems:
|
||||
* Install development tools: `$ sudo dnf install git gcc gcc-c++ SDL2-devel opus-devel fontconfig-devel freetype-devel bzip2-devel`.
|
||||
* Install development tools: `$ sudo dnf install git gcc gcc-c++ SDL2-devel opus-devel freetype-devel bzip2-devel libvorbis-devel opusfile-devel libogg-devel`.
|
||||
|
||||
* Clone this repostory: `$ git clone --recursive https://github.com/FWGS/xash3d-fwgs`.
|
||||
|
||||
|
||||
@@ -1,49 +1,39 @@
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
# Only used to build Android project
|
||||
|
||||
project(XASH_ANDROID)
|
||||
|
||||
# armeabi-v7a requires cpufeatures library
|
||||
include(AndroidNdkModules)
|
||||
android_ndk_import_module_cpufeatures()
|
||||
if(ANDROID)
|
||||
include_directories(${ANDROID_NDK}/sources/android/cpufeatures)
|
||||
add_library(cpufeatures ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c)
|
||||
target_link_libraries(cpufeatures dl)
|
||||
endif()
|
||||
|
||||
find_package(PythonInterp 2.7 REQUIRED)
|
||||
|
||||
get_filename_component(C_COMPILER_ID ${CMAKE_C_COMPILER} NAME_WE)
|
||||
get_filename_component(CXX_COMPILER_ID ${CMAKE_CXX_COMPILER} NAME_WE)
|
||||
include(FindPython)
|
||||
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||
set(BUILD_TYPE "debug")
|
||||
else()
|
||||
set(BUILD_TYPE "release")
|
||||
list(APPEND WAF_EXTRA_ARGS --enable-poly-opt --enable-lto)
|
||||
list(APPEND WAF_EXTRA_ARGS --enable-poly-opt --enable-lto --enable-limited-debuginfo)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P MATCHES "8")
|
||||
set(64BIT ON CACHE BOOL "" FORCE)
|
||||
list(APPEND WAF_EXTRA_ARGS -8) # only required for x86 when testing this cmakelist under linux
|
||||
if(ANDROID_ABI STREQUAL "x86")
|
||||
# HACKHACK: I don't know why but engine gets built as 64-bit binary here
|
||||
list(APPEND WAF_EXTRA_ARGS -4)
|
||||
endif()
|
||||
|
||||
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||
|
||||
set(WAF_CC "${CMAKE_C_COMPILER} --target=${CMAKE_C_COMPILER_TARGET}")
|
||||
set(WAF_CXX "${CMAKE_CXX_COMPILER} --target=${CMAKE_CXX_COMPILER_TARGET}")
|
||||
|
||||
# not cleanest way to get upper directory
|
||||
set(ENGINE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../")
|
||||
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E env
|
||||
CC=${WAF_CC} CXX=${WAF_CXX}
|
||||
AR=${CMAKE_AR} STRIP=${CMAKE_STRIP}
|
||||
${PYTHON_EXECUTABLE} waf configure -T ${BUILD_TYPE} ${WAF_EXTRA_ARGS} cmake
|
||||
--check-c-compiler=${C_COMPILER_ID} --check-cxx-compiler=${CXX_COMPILER_ID}
|
||||
-s "${ENGINE_SOURCE_DIR}/SDL" --skip-sdl2-sanity-check --enable-bundled-deps
|
||||
WORKING_DIRECTORY "${ENGINE_SOURCE_DIR}"
|
||||
)
|
||||
|
||||
add_subdirectory("${ENGINE_SOURCE_DIR}/3rdparty/hlsdk-portable" hlsdk-portable)
|
||||
set(WAF_CC "${CMAKE_C_COMPILER} --target=${CMAKE_C_COMPILER_TARGET}")
|
||||
set(WAF_CXX "${CMAKE_CXX_COMPILER} --target=${CMAKE_CXX_COMPILER_TARGET}")
|
||||
set(WAF ${Python_EXECUTABLE} ${ENGINE_SOURCE_DIR}waf -t ${ENGINE_SOURCE_DIR} -o ${CMAKE_CURRENT_BINARY_DIR}/xash3d-fwgs)
|
||||
|
||||
# try to build minimal SDL. Enable features as we're gonna use them
|
||||
set(SDL_RENDER OFF)
|
||||
@@ -56,5 +46,50 @@ set(SDL_VULKAN OFF)
|
||||
set(SDL_OFFSCREEN OFF)
|
||||
set(SDL_STATIC OFF)
|
||||
add_subdirectory("${ENGINE_SOURCE_DIR}/3rdparty/SDL" SDL)
|
||||
add_subdirectory("${ENGINE_SOURCE_DIR}/" xash3d-fwgs)
|
||||
add_subdirectory("${ENGINE_SOURCE_DIR}/3rdparty/mainui" mainui)
|
||||
|
||||
include(ExternalProject)
|
||||
|
||||
# gradle passes backslashes to cmake, how does this even work for everybody else?
|
||||
string(REPLACE "\\" "/" CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
|
||||
|
||||
ExternalProject_Add(
|
||||
Xash3DFWGS
|
||||
SOURCE_DIR ${ENGINE_SOURCE_DIR}
|
||||
INSTALL_DIR ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
|
||||
BUILD_IN_SOURCE TRUE
|
||||
DEPENDS SDL2
|
||||
BUILD_ALWAYS TRUE
|
||||
LOG_CONFIGURE TRUE
|
||||
LOG_BUILD TRUE
|
||||
LOG_INSTALL TRUE
|
||||
LOG_OUTPUT_ON_FAILURE TRUE
|
||||
LOG_MERGED_STDOUTERR TRUE
|
||||
|
||||
# USES_TERMINAL_CONFIGURE TRUE
|
||||
# USES_TERMINAL_BUILD TRUE
|
||||
# USES_TERMINAL_INSTALL TRUE
|
||||
|
||||
# NOTE: setting up WAFLOCK is important to avoid possible race conditions
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env
|
||||
ANDROID_NDK=${ANDROID_NDK}
|
||||
BUILD_CMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
|
||||
WAFLOCK=.lock-waf_android_${ANDROID_ABI}_build
|
||||
${WAF} configure -T ${BUILD_TYPE} --android=${ANDROID_ABI},,${CMAKE_SYSTEM_VERSION}
|
||||
-s "${ENGINE_SOURCE_DIR}/3rdparty/SDL" --enable-bundled-deps ${WAF_EXTRA_ARGS}
|
||||
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} -E env
|
||||
WAFLOCK=.lock-waf_android_${ANDROID_ABI}_build
|
||||
${WAF} build -v
|
||||
|
||||
INSTALL_COMMAND ${CMAKE_COMMAND} -E env
|
||||
WAFLOCK=.lock-waf_android_${ANDROID_ABI}_build
|
||||
${WAF} install --destdir=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
|
||||
)
|
||||
|
||||
add_subdirectory("${ENGINE_SOURCE_DIR}/3rdparty/hlsdk-portable" hlsdk-portable)
|
||||
|
||||
# a1ba: without this, xash3d target will be ignored as nothing depends on it
|
||||
add_dependencies(client Xash3DFWGS)
|
||||
add_dependencies(server Xash3DFWGS)
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ plugins {
|
||||
|
||||
android {
|
||||
namespace = "su.xash.engine"
|
||||
ndkVersion = "27.2.12479018"
|
||||
ndkVersion = "28.0.13004108"
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "su.xash"
|
||||
@@ -96,6 +96,7 @@ android {
|
||||
packaging {
|
||||
jniLibs {
|
||||
useLegacyPackaging = true
|
||||
keepDebugSymbols.add("**/*.so")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,7 +113,7 @@ dependencies {
|
||||
implementation("androidx.preference:preference-ktx:1.2.1")
|
||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
||||
implementation("androidx.work:work-runtime-ktx:2.9.0")
|
||||
// implementation "androidx.legacy:legacy-support-v4:1.0.0"
|
||||
// implementation "androidx.legacy:legacy-support-v4:1.0.0"
|
||||
|
||||
implementation("com.madgag.spongycastle:prov:1.58.0.0")
|
||||
implementation("in.dragonbra:javasteam:1.2.0")
|
||||
|
||||
@@ -30,6 +30,18 @@ public class XashActivity extends SDLActivity {
|
||||
AndroidBug5497Workaround.assistActivity(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy()
|
||||
{
|
||||
super.onDestroy();
|
||||
|
||||
// Now that we don't exit from native code, we need to exit here, resetting
|
||||
// application state (actually global variables that we don't cleanup on exit)
|
||||
//
|
||||
// When the issue with global variables will be resolved, remove that exit() call
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getLibraries() {
|
||||
return new String[]{"SDL2", "xash"};
|
||||
|
||||
@@ -2,6 +2,7 @@ package su.xash.engine.ui.library
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
@@ -10,6 +11,7 @@ import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
@@ -73,11 +75,16 @@ class LibraryFragment : Fragment(), MenuProvider {
|
||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
|
||||
when (menuItem.itemId) {
|
||||
R.id.action_browse -> {
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_VIEW).setDataAndType(
|
||||
null, "vnd.android.document/directory"
|
||||
try {
|
||||
startActivity(
|
||||
Intent(Intent.ACTION_VIEW).setDataAndType(
|
||||
null, "vnd.android.document/directory"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
catch(e: ActivityNotFoundException) {
|
||||
Toast.makeText(getActivity(), R.string.library_fragment_no_file_manager, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
|
||||
R.id.action_install -> {
|
||||
@@ -91,4 +98,4 @@ class LibraryFragment : Fragment(), MenuProvider {
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,4 +33,5 @@
|
||||
<string name="preferences_client_package">Client package</string>
|
||||
<string name="preferences_server_package">Server package</string>
|
||||
<string name="preferences_use_icons">Use icons instead of backgrounds</string>
|
||||
</resources>
|
||||
<string name="library_fragment_no_file_manager">File manager is missing</string>
|
||||
</resources>
|
||||
|
||||
@@ -20,4 +20,7 @@ kotlin.code.style=official
|
||||
# Enables namespacing of each library's R class so that its R class includes only the
|
||||
# resources declared in the library itself and none from the library's dependencies,
|
||||
# thereby reducing the size of the R class for that library
|
||||
android.nonTransitiveRClass=true
|
||||
android.nonTransitiveRClass=true
|
||||
|
||||
# Enable verbose output for CMake
|
||||
android.native.buildOutput=verbose
|
||||
|
||||
@@ -16,8 +16,6 @@ GNU General Public License for more details.
|
||||
#ifndef BSPFILE_H
|
||||
#define BSPFILE_H
|
||||
|
||||
//#define SUPPORT_BSP2_FORMAT // allow to loading Darkplaces BSP2 maps (with broke binary compatibility)
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
@@ -65,7 +63,6 @@ BRUSH MODELS
|
||||
#define MAX_MAP_CLIPNODES_BSP2 524288
|
||||
|
||||
// these limis not using by modelloader but only for displaying 'mapstats' correctly
|
||||
#ifdef SUPPORT_BSP2_FORMAT
|
||||
#define MAX_MAP_MODELS 2048 // embedded models
|
||||
#define MAX_MAP_ENTSTRING 0x200000 // 2 Mb should be enough
|
||||
#define MAX_MAP_PLANES 131072 // can be increased without problems
|
||||
@@ -75,18 +72,6 @@ BRUSH MODELS
|
||||
#define MAX_MAP_VERTS 524288 // can be increased without problems
|
||||
#define MAX_MAP_FACES 262144 // can be increased without problems
|
||||
#define MAX_MAP_MARKSURFACES 524288 // can be increased without problems
|
||||
#else
|
||||
// increased to match PrimeXT compilers
|
||||
#define MAX_MAP_MODELS 1024 // embedded models
|
||||
#define MAX_MAP_ENTSTRING 0x100000 // 1 Mb should be enough
|
||||
#define MAX_MAP_PLANES 65536 // can be increased without problems
|
||||
#define MAX_MAP_NODES 32767 // because negative shorts are leafs
|
||||
#define MAX_MAP_CLIPNODES MAX_MAP_CLIPNODES_HLBSP // because negative shorts are contents
|
||||
#define MAX_MAP_LEAFS 32767 // signed short limit
|
||||
#define MAX_MAP_VERTS 65535 // unsigned short limit
|
||||
#define MAX_MAP_FACES 65535 // unsigned short limit
|
||||
#define MAX_MAP_MARKSURFACES 65535 // unsigned short limit
|
||||
#endif
|
||||
|
||||
#define MAX_MAP_ENTITIES 8192 // network limit
|
||||
#define MAX_MAP_TEXINFO MAX_MAP_FACES // in theory each face may have personal texinfo
|
||||
|
||||
@@ -60,26 +60,29 @@ typedef struct
|
||||
vec3_t position;
|
||||
} mvertex_t;
|
||||
|
||||
typedef struct
|
||||
typedef struct mclipnode32_s
|
||||
{
|
||||
int planenum;
|
||||
#ifdef SUPPORT_BSP2_FORMAT
|
||||
int children[2]; // negative numbers are contents
|
||||
#else
|
||||
short children[2]; // negative numbers are contents
|
||||
#endif
|
||||
} mclipnode_t;
|
||||
int planenum;
|
||||
int children[2]; // negative numbers are contents
|
||||
} mclipnode32_t;
|
||||
|
||||
typedef struct mclipnode16_s
|
||||
{
|
||||
int planenum;
|
||||
short children[2]; // negative numbers are contents
|
||||
} mclipnode16_t;
|
||||
|
||||
// size is matched but representation is not
|
||||
typedef struct
|
||||
typedef struct medge32_s
|
||||
{
|
||||
#ifdef SUPPORT_BSP2_FORMAT
|
||||
unsigned int v[2];
|
||||
#else
|
||||
} medge32_t;
|
||||
|
||||
typedef struct medge16_s
|
||||
{
|
||||
unsigned short v[2];
|
||||
unsigned int cachededgeoffset;
|
||||
#endif
|
||||
} medge_t;
|
||||
} medge16_t;
|
||||
|
||||
typedef struct texture_s
|
||||
{
|
||||
@@ -156,13 +159,31 @@ typedef struct mnode_s
|
||||
|
||||
// node specific
|
||||
mplane_t *plane;
|
||||
struct mnode_s *children[2];
|
||||
#ifdef SUPPORT_BSP2_FORMAT
|
||||
int firstsurface;
|
||||
int numsurfaces;
|
||||
|
||||
#if !XASH_64BIT
|
||||
union
|
||||
{
|
||||
struct mnode_s *children_[2];
|
||||
struct
|
||||
{
|
||||
// the ordering is important
|
||||
int child_0_leaf : 1;
|
||||
int child_0_off : 23;
|
||||
int firstsurface_1 : 8;
|
||||
int child_1_leaf : 1;
|
||||
int child_1_off : 23;
|
||||
int numsurfaces_1 : 8;
|
||||
};
|
||||
};
|
||||
unsigned short firstsurface_0;
|
||||
unsigned short numsurfaces_0;
|
||||
#else
|
||||
unsigned short firstsurface;
|
||||
unsigned short numsurfaces;
|
||||
// in 64-bit ABI this struct has 4 more bytes of padding, let's use it!
|
||||
struct mnode_s *children_[2];
|
||||
unsigned short firstsurface_0;
|
||||
unsigned short numsurfaces_0;
|
||||
unsigned short firstsurface_1;
|
||||
unsigned short numsurfaces_1;
|
||||
#endif
|
||||
} mnode_t;
|
||||
|
||||
@@ -203,7 +224,6 @@ typedef struct mleaf_s
|
||||
int nummarksurfaces;
|
||||
int cluster; // helper to acess to uncompressed visdata
|
||||
byte ambient_sound_level[NUM_AMBIENTS];
|
||||
|
||||
} mleaf_t;
|
||||
|
||||
// surface extradata
|
||||
@@ -291,7 +311,11 @@ struct msurface_s
|
||||
|
||||
typedef struct hull_s
|
||||
{
|
||||
mclipnode_t *clipnodes;
|
||||
union
|
||||
{
|
||||
mclipnode16_t *clipnodes16;
|
||||
mclipnode32_t *clipnodes32;
|
||||
};
|
||||
mplane_t *planes;
|
||||
int firstclipnode;
|
||||
int lastclipnode;
|
||||
@@ -341,7 +365,12 @@ typedef struct model_s
|
||||
mvertex_t *vertexes;
|
||||
|
||||
int numedges;
|
||||
medge_t *edges;
|
||||
union
|
||||
{
|
||||
medge16_t *edges16;
|
||||
medge32_t *edges32;
|
||||
};
|
||||
|
||||
|
||||
int numnodes;
|
||||
mnode_t *nodes;
|
||||
@@ -356,7 +385,11 @@ typedef struct model_s
|
||||
int *surfedges;
|
||||
|
||||
int numclipnodes;
|
||||
mclipnode_t *clipnodes;
|
||||
union
|
||||
{
|
||||
mclipnode16_t *clipnodes16;
|
||||
mclipnode32_t *clipnodes32;
|
||||
};
|
||||
|
||||
int nummarksurfaces;
|
||||
msurface_t **marksurfaces;
|
||||
@@ -550,16 +583,68 @@ typedef struct
|
||||
#define ANIM_CYCLE 2
|
||||
#define MOD_FRAMES 20
|
||||
|
||||
|
||||
|
||||
#define MAX_DEMOS 32
|
||||
#define MAX_MOVIES 8
|
||||
#define MAX_CDTRACKS 32
|
||||
#define MAX_CLIENT_SPRITES 512 // SpriteTextures (0-256 hud, 256-512 client)
|
||||
#define MAX_REQUESTS 64
|
||||
|
||||
STATIC_CHECK_SIZEOF( mnode_t, 52, 72 );
|
||||
STATIC_CHECK_SIZEOF( mextrasurf_t, 324, 496 );
|
||||
STATIC_CHECK_SIZEOF( decal_t, 60, 88 );
|
||||
STATIC_CHECK_SIZEOF( mfaceinfo_t, 176, 304 );
|
||||
|
||||
// model flags (stored in model_t->flags)
|
||||
#define MODEL_QBSP2 BIT( 28 ) // uses 32-bit types
|
||||
|
||||
// access functions
|
||||
static inline mnode_t *node_child( const mnode_t *n, int side, const model_t *mod )
|
||||
{
|
||||
#if !XASH_64BIT
|
||||
if( unlikely( mod->flags & MODEL_QBSP2 )) // MODEL_QBSP2
|
||||
{
|
||||
if( side == 0 )
|
||||
{
|
||||
if( n->child_0_leaf )
|
||||
return (mnode_t *)(mod->leafs + n->child_0_off);
|
||||
else
|
||||
return (mnode_t *)(mod->nodes + n->child_0_off);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( n->child_1_leaf )
|
||||
return (mnode_t *)(mod->leafs + n->child_1_off);
|
||||
else
|
||||
return (mnode_t *)(mod->nodes + n->child_1_off);
|
||||
}
|
||||
}
|
||||
|
||||
return n->children_[side];
|
||||
#else
|
||||
return n->children_[side];
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void node_children( mnode_t *children[2], const mnode_t *n, const model_t *mod )
|
||||
{
|
||||
children[0] = node_child( n, 0, mod );
|
||||
children[1] = node_child( n, 1, mod );
|
||||
}
|
||||
|
||||
static inline int node_firstsurface( const mnode_t *n, const model_t *mod )
|
||||
{
|
||||
if( mod->flags & MODEL_QBSP2 )
|
||||
return n->firstsurface_0 + ( n->firstsurface_1 << 16 );
|
||||
else
|
||||
return n->firstsurface_0;
|
||||
}
|
||||
|
||||
static inline int node_numsurfaces( const mnode_t *n, const model_t *mod )
|
||||
{
|
||||
if( mod->flags & MODEL_QBSP2 )
|
||||
return n->numsurfaces_0 + ( n->numsurfaces_1 << 16 );
|
||||
else
|
||||
return n->numsurfaces_0;
|
||||
}
|
||||
|
||||
#endif//COM_MODEL_H
|
||||
|
||||
@@ -140,13 +140,13 @@ Default build-depended cvar and constant values
|
||||
|
||||
// Platform overrides
|
||||
#if XASH_NSWITCH
|
||||
#define DEFAULT_TOUCH_ENABLE "0"
|
||||
#define DEFAULT_TOUCH_ENABLE "1"
|
||||
#define DEFAULT_M_IGNORE "1"
|
||||
#define DEFAULT_MODE_WIDTH 1280
|
||||
#define DEFAULT_MODE_HEIGHT 720
|
||||
#define DEFAULT_ALLOWCONSOLE 1
|
||||
#elif XASH_PSVITA
|
||||
#define DEFAULT_TOUCH_ENABLE "0"
|
||||
#define DEFAULT_TOUCH_ENABLE "1"
|
||||
#define DEFAULT_M_IGNORE "1"
|
||||
#define DEFAULT_MODE_WIDTH 960
|
||||
#define DEFAULT_MODE_HEIGHT 544
|
||||
@@ -158,7 +158,7 @@ Default build-depended cvar and constant values
|
||||
#define DEFAULT_M_IGNORE "1"
|
||||
#endif // !XASH_MOBILE_PLATFORM && !XASH_NSWITCH
|
||||
|
||||
#if XASH_ANDROID || XASH_IOS || XASH_EMSCRIPTEN
|
||||
#if (XASH_ANDROID && !XASH_TERMUX) || XASH_IOS || XASH_EMSCRIPTEN
|
||||
// this means that libraries are provided with engine, but not in game data
|
||||
// You need add library loading code to library.c when adding new platform
|
||||
#define XASH_INTERNAL_GAMELIBS
|
||||
|
||||
@@ -28,7 +28,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#define PORT_ANY -1
|
||||
|
||||
typedef enum {NA_LOOPBACK = 1, NA_BROADCAST, NA_IP, NA_IPX, NA_BROADCAST_IPX, NA_IP6, NA_MULTICAST_IP6} netadrtype_t;
|
||||
typedef enum netadrtype_e
|
||||
{
|
||||
NA_UNDEFINED = 0,
|
||||
NA_LOOPBACK,
|
||||
NA_BROADCAST,
|
||||
NA_IP,
|
||||
NA_IPX,
|
||||
NA_BROADCAST_IPX,
|
||||
NA_IP6,
|
||||
NA_MULTICAST_IP6
|
||||
} netadrtype_t;
|
||||
|
||||
/*
|
||||
Original Quake-2 structure:
|
||||
@@ -46,29 +56,60 @@ typedef struct
|
||||
#pragma pack( push, 1 )
|
||||
typedef struct netadr_s
|
||||
{
|
||||
// the reason we do this evil thing, is that when this struct contains IPv6
|
||||
// address the `type` is 2-byte wide, but when it doesn't `type` must 4-byte
|
||||
// wide _and_ ip6_0 must be zeroed, to keep it binary compatible.
|
||||
#if XASH_LITTLE_ENDIAN
|
||||
uint16_t type;
|
||||
uint8_t ip6_0[2];
|
||||
#elif XASH_BIG_ENDIAN
|
||||
uint8_t ip6_0[2];
|
||||
uint16_t type;
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
|
||||
union
|
||||
{
|
||||
// IPv6 struct
|
||||
uint8_t ip6_1[14];
|
||||
struct
|
||||
{
|
||||
uint16_t type6;
|
||||
uint8_t ip6[16];
|
||||
};
|
||||
struct
|
||||
{
|
||||
uint32_t type; // must be netadrtype_t but will break with short enums
|
||||
union
|
||||
{
|
||||
uint8_t ip[4];
|
||||
uint32_t ip4; // for easier conversions
|
||||
uint8_t ip[4];
|
||||
uint32_t ip4; // for easier conversions
|
||||
};
|
||||
uint8_t ipx[10];
|
||||
};
|
||||
};
|
||||
uint16_t port;
|
||||
uint16_t port;
|
||||
} netadr_t;
|
||||
#pragma pack( pop )
|
||||
|
||||
static inline netadrtype_t NET_NetadrType( const netadr_t *a )
|
||||
{
|
||||
if( a->type == NA_IP6 || a->type == NA_MULTICAST_IP6 )
|
||||
return (netadrtype_t)a->type;
|
||||
|
||||
if( a->ip6_0[0] || a->ip6_0[1] )
|
||||
return NA_UNDEFINED;
|
||||
|
||||
return (netadrtype_t)a->type;
|
||||
}
|
||||
|
||||
static inline void NET_NetadrSetType( netadr_t *a, netadrtype_t type )
|
||||
{
|
||||
if( type == NA_IP6 || type == NA_MULTICAST_IP6 )
|
||||
{
|
||||
a->type = type;
|
||||
return;
|
||||
}
|
||||
|
||||
a->ip6_0[0] = a->ip6_0[1] = 0;
|
||||
a->type = type;
|
||||
}
|
||||
|
||||
STATIC_CHECK_SIZEOF( netadr_t, 20, 20 );
|
||||
|
||||
#endif // NET_ADR_H
|
||||
|
||||
@@ -86,8 +86,4 @@ GNU General Public License for more details.
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#if defined XASH_SDL && !defined REF_DLL
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#endif // PORT_H
|
||||
|
||||
@@ -13,47 +13,44 @@
|
||||
#endif // _WIN32
|
||||
|
||||
#include <sys/types.h> // off_t
|
||||
#ifdef STDINT_H
|
||||
#include STDINT_H
|
||||
#else // !STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif // !STDINT_H
|
||||
#include <assert.h>
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef int sound_t;
|
||||
typedef float vec_t;
|
||||
typedef vec_t vec2_t[2];
|
||||
typedef vec_t vec3_t[3];
|
||||
typedef vec_t vec4_t[4];
|
||||
typedef vec_t quat_t[4];
|
||||
typedef byte rgba_t[4]; // unsigned byte colorpack
|
||||
typedef byte rgb_t[3]; // unsigned byte colorpack
|
||||
typedef vec_t matrix3x4[3][4];
|
||||
typedef vec_t matrix4x4[4][4];
|
||||
|
||||
typedef uint32_t poolhandle_t;
|
||||
typedef uint8_t byte;
|
||||
typedef float vec_t;
|
||||
typedef vec_t vec2_t[2];
|
||||
#ifndef vec3_t // SDK renames it to Vector
|
||||
typedef vec_t vec3_t[3];
|
||||
#endif
|
||||
typedef vec_t vec4_t[4];
|
||||
typedef vec_t quat_t[4];
|
||||
typedef byte rgba_t[4]; // unsigned byte colorpack
|
||||
typedef byte rgb_t[3]; // unsigned byte colorpack
|
||||
typedef vec_t matrix3x4[3][4];
|
||||
typedef vec_t matrix4x4[4][4];
|
||||
typedef uint32_t poolhandle_t;
|
||||
|
||||
#undef true
|
||||
#undef false
|
||||
|
||||
#ifndef __cplusplus
|
||||
typedef enum { false, true } qboolean;
|
||||
#else
|
||||
typedef int qboolean;
|
||||
// true and false are keywords in C++ and C23
|
||||
#if !__cplusplus && __STDC_VERSION__ < 202311L
|
||||
enum { false, true };
|
||||
#endif
|
||||
typedef int qboolean;
|
||||
|
||||
typedef uint64_t longtime_t;
|
||||
|
||||
#define MAX_STRING 256 // generic string
|
||||
#define MAX_INFO_STRING 256 // infostrings are transmitted across network
|
||||
#define MAX_SERVERINFO_STRING 512 // server handles too many settings. expand to 1024?
|
||||
#define MAX_LOCALINFO_STRING 32768 // localinfo used on server and not sended to the clients
|
||||
#define MAX_SYSPATH 1024 // system filepath
|
||||
#define MAX_VA_STRING 1024 // string length returned by va()
|
||||
#define MAX_PRINT_MSG 8192 // how many symbols can handle single call of Con_Printf or Con_DPrintf
|
||||
#define MAX_TOKEN 2048 // parse token length
|
||||
#define MAX_MODS 512 // environment games that engine can keep visible
|
||||
#define MAX_USERMSG_LENGTH 2048 // don't modify it's relies on a client-side definitions
|
||||
#define MAX_STRING 256 // generic string
|
||||
#define MAX_VA_STRING 1024 // compatibility macro
|
||||
#define MAX_SYSPATH 1024 // system filepath
|
||||
#define MAX_MODS 512 // environment games that engine can keep visible
|
||||
|
||||
#define BIT( n ) ( 1U << ( n ))
|
||||
#define BIT64( n ) ( 1ULL << ( n ))
|
||||
|
||||
#define SetBits( iBitVector, bits ) ((iBitVector) = (iBitVector) | (bits))
|
||||
#define ClearBits( iBitVector, bits ) ((iBitVector) = (iBitVector) & ~(bits))
|
||||
#define FBitSet( iBitVector, bit ) ((iBitVector) & (bit))
|
||||
@@ -70,6 +67,8 @@ typedef uint64_t longtime_t;
|
||||
#define IsColorString( p ) ( p && *( p ) == '^' && *(( p ) + 1) && *(( p ) + 1) >= '0' && *(( p ) + 1 ) <= '9' )
|
||||
#define ColorIndex( c ) ((( c ) - '0' ) & 7 )
|
||||
|
||||
#undef EXPORT
|
||||
|
||||
#if defined( __GNUC__ )
|
||||
#if defined( __i386__ )
|
||||
#define EXPORT __attribute__(( visibility( "default" ), force_align_arg_pointer ))
|
||||
@@ -92,8 +91,10 @@ typedef uint64_t longtime_t;
|
||||
#define NORETURN __attribute__(( noreturn ))
|
||||
#define NONNULL __attribute__(( nonnull ))
|
||||
#define RETURNS_NONNULL __attribute__(( returns_nonnull ))
|
||||
#if __clang__
|
||||
#define PFN_RETURNS_NONNULL // clang has bugged returns_nonnull for functions pointers, it's ignored and generates a warning about objective-c? O_o
|
||||
#if __clang__ || __MCST__
|
||||
// clang has bugged returns_nonnull for functions pointers, it's ignored and generates a warning about objective-c? O_o
|
||||
// lcc doesn't support it at all
|
||||
#define PFN_RETURNS_NONNULL
|
||||
#else
|
||||
#define PFN_RETURNS_NONNULL RETURNS_NONNULL
|
||||
#endif
|
||||
@@ -209,35 +210,16 @@ _inline float LittleFloat( float f )
|
||||
#endif
|
||||
|
||||
|
||||
typedef unsigned int dword;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
typedef char string[MAX_STRING];
|
||||
typedef struct file_s file_t; // normal file
|
||||
typedef struct stream_s stream_t; // sound stream for background music playing
|
||||
typedef off_t fs_offset_t;
|
||||
typedef unsigned int dword;
|
||||
typedef unsigned int uint;
|
||||
typedef char string[MAX_STRING];
|
||||
typedef off_t fs_offset_t;
|
||||
#if XASH_WIN32
|
||||
typedef int fs_size_t; // return type of _read, _write funcs
|
||||
typedef int fs_size_t; // return type of _read, _write funcs
|
||||
#else /* !XASH_WIN32 */
|
||||
typedef ssize_t fs_size_t;
|
||||
typedef ssize_t fs_size_t;
|
||||
#endif /* !XASH_WIN32 */
|
||||
|
||||
typedef struct dllfunc_s
|
||||
{
|
||||
const char *name;
|
||||
void **func;
|
||||
} dllfunc_t;
|
||||
|
||||
typedef struct dll_info_s
|
||||
{
|
||||
const char *name; // name of library
|
||||
const dllfunc_t *fcts; // list of dll exports
|
||||
const size_t num_fcts;
|
||||
qboolean crash; // crash if dll not found
|
||||
void *link; // hinstance of loading library
|
||||
} dll_info_t;
|
||||
|
||||
typedef void (*setpair_t)( const char *key, const void *value, const void *buffer, void *numpairs );
|
||||
typedef void *(*pfnCreateInterface_t)( const char *, int * );
|
||||
|
||||
// config strings are a general means of communication from
|
||||
|
||||
@@ -152,19 +152,6 @@ void CL_PlayCDTrack_f( void )
|
||||
else Con_Printf( "%s: unknown command %s\n", Cmd_Argv( 0 ), command );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ScreenshotGetName
|
||||
==================
|
||||
*/
|
||||
static qboolean CL_ScreenshotGetName( const char *fmt, int lastnum, char *filename, size_t size )
|
||||
{
|
||||
if( lastnum < 0 || lastnum > 9999 )
|
||||
return false;
|
||||
|
||||
return Q_snprintf( filename, size, fmt, clgame.mapname, lastnum ) > 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
@@ -270,7 +257,6 @@ void CL_GenericShot_f( void )
|
||||
case scrshot_normal:
|
||||
case scrshot_snapshot:
|
||||
{
|
||||
const char *fmt;
|
||||
string checkname;
|
||||
int i;
|
||||
|
||||
@@ -282,15 +268,18 @@ void CL_GenericShot_f( void )
|
||||
}
|
||||
|
||||
if( type == scrshot_snapshot )
|
||||
{
|
||||
fmt = "../%s_%04d.png";
|
||||
FS_AllowDirectPaths( true );
|
||||
}
|
||||
else fmt = "scrshots/%s_shot%04d.png";
|
||||
|
||||
for( i = 0; i < 9999; i++ )
|
||||
{
|
||||
if( !CL_ScreenshotGetName( fmt, i, checkname, sizeof( checkname )))
|
||||
int ret;
|
||||
|
||||
if( type == scrshot_snapshot )
|
||||
ret = Q_snprintf( checkname, sizeof( checkname ), "../%s_%04d.png", clgame.mapname, i );
|
||||
else
|
||||
ret = Q_snprintf( checkname, sizeof( checkname ), "scrshots/%s_shot%04d.png", clgame.mapname, i );
|
||||
|
||||
if( ret <= 0 )
|
||||
{
|
||||
Con_Printf( S_ERROR "unable to write %s\n", argv0 );
|
||||
FS_AllowDirectPaths( false );
|
||||
|
||||
@@ -153,6 +153,7 @@ static void CL_WriteErrorMessage( int current_count, sizebuf_t *msg )
|
||||
|
||||
FS_Write( fp, &cls.starting_count, sizeof( int ));
|
||||
FS_Write( fp, ¤t_count, sizeof( int ));
|
||||
FS_Write( fp, &cls.legacymode, sizeof( cls.legacymode ));
|
||||
FS_Write( fp, MSG_GetData( msg ), MSG_GetMaxBytes( msg ));
|
||||
FS_Close( fp );
|
||||
|
||||
@@ -168,7 +169,7 @@ list last 32 messages for debugging net troubleshooting
|
||||
*/
|
||||
void CL_WriteMessageHistory( void )
|
||||
{
|
||||
oldcmd_t *old, *failcommand;
|
||||
oldcmd_t *old;
|
||||
sizebuf_t *msg = &net_message;
|
||||
int i, thecmd;
|
||||
|
||||
@@ -192,9 +193,49 @@ void CL_WriteMessageHistory( void )
|
||||
thecmd++;
|
||||
}
|
||||
|
||||
failcommand = &cls_message_debug.oldcmd[thecmd];
|
||||
Con_Printf( "BAD: %3i:%s\n", MSG_GetNumBytesRead( msg ) - 1, CL_MsgInfo( failcommand->command ));
|
||||
if( host_developer.value >= DEV_EXTENDED )
|
||||
CL_WriteErrorMessage( MSG_GetNumBytesRead( msg ) - 1, msg );
|
||||
old = &cls_message_debug.oldcmd[thecmd];
|
||||
Con_Printf( S_RED "BAD: " S_DEFAULT "%i %04i %s\n", old->frame_number, old->starting_offset, CL_MsgInfo( old->command ));
|
||||
CL_WriteErrorMessage( old->starting_offset, msg );
|
||||
cls_message_debug.parsing = false;
|
||||
}
|
||||
|
||||
void CL_ReplayBufferDat_f( void )
|
||||
{
|
||||
file_t *f = FS_Open( Cmd_Argv( 1 ), "rb", true );
|
||||
sizebuf_t msg;
|
||||
char buffer[NET_MAX_MESSAGE];
|
||||
int starting_count, current_count, protocol;
|
||||
fs_offset_t len;
|
||||
|
||||
if( !f )
|
||||
return;
|
||||
|
||||
FS_Read( f, &starting_count, sizeof( starting_count ));
|
||||
FS_Read( f, ¤t_count, sizeof( current_count ));
|
||||
FS_Read( f, &protocol, sizeof( protocol ));
|
||||
|
||||
cls.legacymode = protocol;
|
||||
|
||||
len = FS_Read( f, buffer, sizeof( buffer ));
|
||||
FS_Close( f );
|
||||
|
||||
MSG_Init( &msg, __func__, buffer, len );
|
||||
|
||||
Delta_Shutdown();
|
||||
Delta_Init();
|
||||
|
||||
clgame.maxEntities = MAX_EDICTS;
|
||||
clgame.entities = Mem_Calloc( clgame.mempool, sizeof( *clgame.entities ) * clgame.maxEntities );
|
||||
|
||||
// ad-hoc implement
|
||||
#if 0
|
||||
{
|
||||
const int message_pos = 12; // put real number here
|
||||
MSG_SeekToBit( &msg, ( message_pos - 12 + 1 ) << 3, SEEK_SET );
|
||||
|
||||
CL_ParseYourMom( &msg, protocol );
|
||||
}
|
||||
#endif
|
||||
|
||||
Sys_Quit( __func__ );
|
||||
}
|
||||
|
||||
@@ -373,7 +373,7 @@ CL_WriteDemoUserMessage
|
||||
Dumps the user message (demoaction)
|
||||
====================
|
||||
*/
|
||||
void CL_WriteDemoUserMessage( const byte *buffer, size_t size )
|
||||
void GAME_EXPORT CL_WriteDemoUserMessage( int size, byte *buffer )
|
||||
{
|
||||
if( !cls.demorecording || cls.demowaiting )
|
||||
return;
|
||||
@@ -624,11 +624,10 @@ static void CL_ReadDemoUserCmd( qboolean discard )
|
||||
|
||||
if( !discard )
|
||||
{
|
||||
usercmd_t nullcmd;
|
||||
const usercmd_t nullcmd = { 0 };
|
||||
sizebuf_t buf;
|
||||
demoangle_t *a;
|
||||
|
||||
memset( &nullcmd, 0, sizeof( nullcmd ));
|
||||
MSG_Init( &buf, "UserCmd", data, sizeof( data ));
|
||||
|
||||
// a1ba: I have no proper explanation why
|
||||
@@ -643,9 +642,7 @@ static void CL_ReadDemoUserCmd( qboolean discard )
|
||||
pcmd->sendsize = 1;
|
||||
|
||||
// always delta'ing from null
|
||||
cl.cmd = &pcmd->cmd;
|
||||
|
||||
MSG_ReadDeltaUsercmd( &buf, &nullcmd, cl.cmd );
|
||||
MSG_ReadDeltaUsercmd( &buf, &nullcmd, &pcmd->cmd );
|
||||
|
||||
// make sure what interp info contain angles from different frames
|
||||
// or lerping will stop working
|
||||
@@ -657,13 +654,16 @@ static void CL_ReadDemoUserCmd( qboolean discard )
|
||||
|
||||
// record update
|
||||
a->starttime = demo.timestamp;
|
||||
VectorCopy( cl.cmd->viewangles, a->viewangles );
|
||||
VectorCopy( pcmd->cmd.viewangles, a->viewangles );
|
||||
demo.lasttime = demo.timestamp;
|
||||
}
|
||||
|
||||
// NOTE: we need to have the current outgoing sequence correct
|
||||
// so we can do prediction correctly during playback
|
||||
cls.netchan.outgoing_sequence = outgoing_sequence;
|
||||
|
||||
// save last usercmd
|
||||
cl.cmd = pcmd->cmd;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1146,8 +1146,7 @@ void CL_DemoInterpolateAngles( void )
|
||||
QuaternionSlerp( q2, q1, frac, q );
|
||||
QuaternionAngle( q, cl.viewangles );
|
||||
}
|
||||
else if( cl.cmd != NULL )
|
||||
VectorCopy( cl.cmd->viewangles, cl.viewangles );
|
||||
else VectorCopy( cl.cmd.viewangles, cl.viewangles );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -127,8 +127,10 @@ static void R_SplitEntityOnNode( mnode_t *node )
|
||||
}
|
||||
|
||||
// recurse down the contacted sides
|
||||
if( sides & 1 ) R_SplitEntityOnNode( node->children[0] );
|
||||
if( sides & 2 ) R_SplitEntityOnNode( node->children[1] );
|
||||
if( sides & 1 )
|
||||
R_SplitEntityOnNode( node_child( node, 0, cl.worldmodel ));
|
||||
if( sides & 2 )
|
||||
R_SplitEntityOnNode( node_child( node, 1, cl.worldmodel ));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -2229,4 +2229,3 @@ void CL_ThinkParticle( double frametime, particle_t *p )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -405,7 +405,11 @@ void CL_ParseReliableEvent( sizebuf_t *msg, connprotocol_t proto )
|
||||
}
|
||||
|
||||
if( args.entindex > 0 && args.entindex <= cl.maxclients )
|
||||
args.angles[PITCH] *= -3.0f;
|
||||
{
|
||||
args.angles[PITCH] *= 3.0f;
|
||||
if( !FBitSet( host.features, ENGINE_COMPENSATE_QUAKE_BUG ))
|
||||
args.angles[PITCH] = -args.angles[PITCH];
|
||||
}
|
||||
|
||||
CL_QueueEvent( FEV_RELIABLE|FEV_SERVER, event_index, delay, &args );
|
||||
}
|
||||
@@ -477,7 +481,9 @@ void CL_ParseEvent( sizebuf_t *msg, connprotocol_t proto )
|
||||
|
||||
if( state->number > 0 && state->number <= cl.maxclients )
|
||||
{
|
||||
args.angles[PITCH] *= -3.0f;
|
||||
args.angles[PITCH] *= 3.0f;
|
||||
if( !FBitSet( host.features, ENGINE_COMPENSATE_QUAKE_BUG ))
|
||||
args.angles[PITCH] = -args.angles[PITCH];
|
||||
CL_CalcPlayerVelocity( state->number, args.velocity );
|
||||
args.ducking = ( state->usehull == 1 );
|
||||
}
|
||||
@@ -487,7 +493,11 @@ void CL_ParseEvent( sizebuf_t *msg, connprotocol_t proto )
|
||||
if( args.entindex != 0 )
|
||||
{
|
||||
if( args.entindex > 0 && args.entindex <= cl.maxclients )
|
||||
args.angles[PITCH] /= -3.0f;
|
||||
{
|
||||
args.angles[PITCH] /= 3.0f;
|
||||
if( !FBitSet( host.features, ENGINE_COMPENSATE_QUAKE_BUG ))
|
||||
args.angles[PITCH] = -args.angles[PITCH];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ static int CL_CalcTabStop( const cl_font_t *font, int x )
|
||||
return stop;
|
||||
}
|
||||
|
||||
int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *font, int flags )
|
||||
int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_t *font, int flags )
|
||||
{
|
||||
wrect_t *rc;
|
||||
float w, h;
|
||||
@@ -231,7 +231,7 @@ int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *fon
|
||||
return font->charWidths[number];
|
||||
}
|
||||
|
||||
int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *font, int flags )
|
||||
int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_t *font, int flags )
|
||||
{
|
||||
rgba_t current_color;
|
||||
int draw_len = 0;
|
||||
@@ -287,7 +287,7 @@ int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *fon
|
||||
return draw_len;
|
||||
}
|
||||
|
||||
int CL_DrawStringf( cl_font_t *font, float x, float y, rgba_t color, int flags, const char *fmt, ... )
|
||||
int CL_DrawStringf( cl_font_t *font, float x, float y, const rgba_t color, int flags, const char *fmt, ... )
|
||||
{
|
||||
va_list va;
|
||||
char buf[MAX_VA_STRING];
|
||||
|
||||
@@ -13,6 +13,12 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#if XASH_SDL == 2
|
||||
#include <SDL.h> // SDL_GetWindowPosition
|
||||
#elif XASH_SDL == 3
|
||||
#include <SDL3/SDL.h> // SDL_GetWindowPosition
|
||||
#endif // XASH_SDL
|
||||
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "const.h"
|
||||
@@ -306,21 +312,22 @@ void SPR_AdjustSize( float *x, float *y, float *w, float *h )
|
||||
|
||||
static void SPR_AdjustTexCoords( int texnum, float width, float height, float *s1, float *t1, float *s2, float *t2 )
|
||||
{
|
||||
if( REF_GET_PARM( PARM_TEX_FILTERING, texnum ))
|
||||
{
|
||||
if( refState.width != clgame.scrInfo.iWidth )
|
||||
{
|
||||
// align to texel if scaling
|
||||
*s1 += 0.5f;
|
||||
*s2 -= 0.5f;
|
||||
}
|
||||
const qboolean filtering = REF_GET_PARM( PARM_TEX_FILTERING, texnum );
|
||||
const int xremainder = refState.width % clgame.scrInfo.iWidth;
|
||||
const int yremainder = refState.height % clgame.scrInfo.iHeight;
|
||||
|
||||
if( refState.height != clgame.scrInfo.iHeight )
|
||||
{
|
||||
// align to texel if scaling
|
||||
*t1 += 0.5f;
|
||||
*t2 -= 0.5f;
|
||||
}
|
||||
if(( filtering || xremainder ) && refState.width != clgame.scrInfo.iWidth )
|
||||
{
|
||||
// align to texel if scaling
|
||||
*s1 += 0.5f;
|
||||
*s2 -= 0.5f;
|
||||
}
|
||||
|
||||
if(( filtering || yremainder ) && refState.height != clgame.scrInfo.iHeight )
|
||||
{
|
||||
// align to texel if scaling
|
||||
*t1 += 0.5f;
|
||||
*t2 -= 0.5f;
|
||||
}
|
||||
|
||||
*s1 /= width;
|
||||
@@ -556,7 +563,7 @@ static void CL_InitTitles( const char *filename )
|
||||
|
||||
Q_snprintf( name, sizeof( name ), TEXT_MSGNAME, i );
|
||||
|
||||
cl_textmessage[i].pName = _copystring( clgame.mempool, name, __FILE__, __LINE__ );
|
||||
cl_textmessage[i].pName = copystringpool( clgame.mempool, name );
|
||||
cl_textmessage[i].pMessage = cl_textbuffer[i];
|
||||
}
|
||||
|
||||
@@ -1683,7 +1690,7 @@ get actual screen info
|
||||
*/
|
||||
int GAME_EXPORT CL_GetScreenInfo( SCREENINFO *pscrinfo )
|
||||
{
|
||||
qboolean apply_scale_factor = false;
|
||||
qboolean apply_scale_factor = false; // we don't want floating point inaccuracies
|
||||
float scale_factor = hud_scale.value;
|
||||
|
||||
if( FBitSet( hud_fontscale.flags, FCVAR_CHANGED ))
|
||||
@@ -1698,7 +1705,12 @@ int GAME_EXPORT CL_GetScreenInfo( SCREENINFO *pscrinfo )
|
||||
clgame.scrInfo.iSize = sizeof( clgame.scrInfo );
|
||||
clgame.scrInfo.iFlags = SCRINFO_SCREENFLASH;
|
||||
|
||||
if( scale_factor && scale_factor != 1.0f )
|
||||
if( hud_scale.value >= 320.0f && hud_scale.value >= hud_scale_minimal_width.value )
|
||||
{
|
||||
scale_factor = refState.width / hud_scale.value;
|
||||
apply_scale_factor = scale_factor > 1.0f;
|
||||
}
|
||||
else if( scale_factor && scale_factor != 1.0f )
|
||||
{
|
||||
float scaled_width = (float)refState.width / scale_factor;
|
||||
if( scaled_width >= hud_scale_minimal_width.value )
|
||||
@@ -2073,6 +2085,7 @@ GetWindowCenterX
|
||||
static int GAME_EXPORT pfnGetWindowCenterX( void )
|
||||
{
|
||||
int x = 0;
|
||||
|
||||
#if XASH_WIN32
|
||||
if( m_ignore.value )
|
||||
{
|
||||
@@ -2082,7 +2095,7 @@ static int GAME_EXPORT pfnGetWindowCenterX( void )
|
||||
}
|
||||
#endif
|
||||
|
||||
#if XASH_SDL == 2
|
||||
#if XASH_SDL >= 2
|
||||
SDL_GetWindowPosition( host.hWnd, &x, NULL );
|
||||
#endif
|
||||
|
||||
@@ -2098,6 +2111,7 @@ GetWindowCenterY
|
||||
static int GAME_EXPORT pfnGetWindowCenterY( void )
|
||||
{
|
||||
int y = 0;
|
||||
|
||||
#if XASH_WIN32
|
||||
if( m_ignore.value )
|
||||
{
|
||||
@@ -2107,7 +2121,7 @@ static int GAME_EXPORT pfnGetWindowCenterY( void )
|
||||
}
|
||||
#endif
|
||||
|
||||
#if XASH_SDL == 2
|
||||
#if XASH_SDL >= 2
|
||||
SDL_GetWindowPosition( host.hWnd, NULL, &y );
|
||||
#endif
|
||||
|
||||
@@ -2408,9 +2422,8 @@ CL_FindModelIndex
|
||||
*/
|
||||
static int GAME_EXPORT CL_FindModelIndex( const char *m )
|
||||
{
|
||||
char filepath[MAX_QPATH];
|
||||
static float lasttimewarn;
|
||||
int i;
|
||||
char filepath[MAX_QPATH];
|
||||
int i;
|
||||
|
||||
if( !COM_CheckString( m ))
|
||||
return 0;
|
||||
@@ -2427,13 +2440,6 @@ static int GAME_EXPORT CL_FindModelIndex( const char *m )
|
||||
return i+1;
|
||||
}
|
||||
|
||||
if( lasttimewarn < host.realtime )
|
||||
{
|
||||
// tell user about problem (but don't spam console)
|
||||
Con_DPrintf( S_ERROR "Could not find index for model %s: not precached\n", filepath );
|
||||
lasttimewarn = host.realtime + 1.0f;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3356,28 +3362,6 @@ DemoApi implementation
|
||||
|
||||
=================
|
||||
*/
|
||||
/*
|
||||
=================
|
||||
Demo_IsRecording
|
||||
|
||||
=================
|
||||
*/
|
||||
static int GAME_EXPORT Demo_IsRecording( void )
|
||||
{
|
||||
return cls.demorecording;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Demo_IsPlayingback
|
||||
|
||||
=================
|
||||
*/
|
||||
static int GAME_EXPORT Demo_IsPlayingback( void )
|
||||
{
|
||||
return cls.demoplayback;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Demo_IsTimeDemo
|
||||
@@ -3389,17 +3373,6 @@ static int GAME_EXPORT Demo_IsTimeDemo( void )
|
||||
return cls.timedemo;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Demo_WriteBuffer
|
||||
|
||||
=================
|
||||
*/
|
||||
static void GAME_EXPORT Demo_WriteBuffer( int size, byte *buffer )
|
||||
{
|
||||
CL_WriteDemoUserMessage( buffer, size );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
NetworkApi implementation
|
||||
@@ -3441,7 +3414,7 @@ static void GAME_EXPORT NetAPI_Status( net_status_t *status )
|
||||
status->latency = (connected) ? cl.frames[cl.parsecountmod].latency : 0.0;
|
||||
status->remote_address = cls.netchan.remote_address;
|
||||
status->packet_loss = packet_loss;
|
||||
status->local_address = net_local;
|
||||
NET_GetLocalAddress( &status->local_address, NULL ); // NetAPI doesn't know about IPv6
|
||||
status->rate = rate.value;
|
||||
}
|
||||
|
||||
@@ -3462,7 +3435,7 @@ static void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags,
|
||||
return;
|
||||
}
|
||||
|
||||
if( remote_address->type == NA_IPX || remote_address->type == NA_BROADCAST_IPX )
|
||||
if( NET_NetadrType( remote_address ) == NA_IPX || NET_NetadrType( remote_address ) == NA_BROADCAST_IPX )
|
||||
return; // IPX no longer support
|
||||
|
||||
if( request == NETAPI_REQUEST_SERVERLIST )
|
||||
@@ -3585,28 +3558,6 @@ static int GAME_EXPORT NetAPI_CompareAdr( netadr_t *a, netadr_t *b )
|
||||
return NET_CompareAdr( *a, *b );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
NetAPI_StringToAdr
|
||||
|
||||
=================
|
||||
*/
|
||||
static int GAME_EXPORT NetAPI_StringToAdr( char *s, netadr_t *a )
|
||||
{
|
||||
return NET_StringToAdr( s, a );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
NetAPI_ValueForKey
|
||||
|
||||
=================
|
||||
*/
|
||||
static const char * GAME_EXPORT NetAPI_ValueForKey( const char *s, const char *key )
|
||||
{
|
||||
return Info_ValueForKey( s, key );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
NetAPI_RemoveKey
|
||||
@@ -3803,10 +3754,10 @@ static event_api_t gEventApi =
|
||||
|
||||
static demo_api_t gDemoApi =
|
||||
{
|
||||
Demo_IsRecording,
|
||||
Demo_IsPlayingback,
|
||||
(void *)CL_IsRecordDemo,
|
||||
(void *)CL_IsPlaybackDemo,
|
||||
Demo_IsTimeDemo,
|
||||
Demo_WriteBuffer,
|
||||
CL_WriteDemoUserMessage,
|
||||
};
|
||||
|
||||
net_api_t gNetApi =
|
||||
@@ -3818,8 +3769,8 @@ net_api_t gNetApi =
|
||||
NetAPI_CancelAllRequests,
|
||||
NetAPI_AdrToString,
|
||||
NetAPI_CompareAdr,
|
||||
NetAPI_StringToAdr,
|
||||
NetAPI_ValueForKey,
|
||||
(void *)NET_StringToAdr,
|
||||
Info_ValueForKey,
|
||||
NetAPI_RemoveKey,
|
||||
NetAPI_SetValueForKey,
|
||||
};
|
||||
|
||||
@@ -1114,7 +1114,7 @@ static void GAME_EXPORT UI_ShellExecute( const char *path, const char *parms, in
|
||||
Platform_ShellExecute( path, parms );
|
||||
|
||||
if( shouldExit )
|
||||
Sys_Quit();
|
||||
Sys_Quit( __func__ );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1273,16 +1273,16 @@ static void pfnEnableTextInput( int enable )
|
||||
Key_EnableTextInput( enable, false );
|
||||
}
|
||||
|
||||
static int pfnGetRenderers( unsigned int num, char *shortName, size_t size1, char *readableName, size_t size2 )
|
||||
static int pfnGetRenderers( unsigned int num, char *short_name, size_t size1, char *long_name, size_t size2 )
|
||||
{
|
||||
if( num >= ref.numRenderers )
|
||||
if( num >= ref.num_renderers )
|
||||
return 0;
|
||||
|
||||
if( shortName && size1 )
|
||||
Q_strncpy( shortName, ref.shortNames[num], size1 );
|
||||
if( short_name && size1 )
|
||||
Q_strncpy( short_name, ref.short_names[num], size1 );
|
||||
|
||||
if( readableName && size2 )
|
||||
Q_strncpy( readableName, ref.readableNames[num], size2 );
|
||||
if( long_name && size2 )
|
||||
Q_strncpy( long_name, ref.long_names[num], size2 );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -68,14 +68,15 @@ CVAR_DEFINE_AUTO( hud_scale_minimal_width, "640", FCVAR_ARCHIVE|FCVAR_LATCH, "if
|
||||
CVAR_DEFINE_AUTO( cl_solid_players, "1", 0, "Make all players not solid (can't traceline them)" );
|
||||
CVAR_DEFINE_AUTO( cl_updaterate, "20", FCVAR_USERINFO|FCVAR_ARCHIVE, "refresh rate of server messages" );
|
||||
CVAR_DEFINE_AUTO( cl_showevents, "0", FCVAR_ARCHIVE, "show events playback" );
|
||||
CVAR_DEFINE_AUTO( cl_cmdrate, "60", FCVAR_ARCHIVE, "Max number of command packets sent to server per second" );
|
||||
CVAR_DEFINE_AUTO( cl_cmdrate, "30", FCVAR_ARCHIVE, "Max number of command packets sent to server per second" );
|
||||
CVAR_DEFINE( cl_interp, "ex_interp", "0.1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "Interpolate object positions starting this many seconds in past" );
|
||||
CVAR_DEFINE_AUTO( cl_nointerp, "0", 0, "disable interpolation of entities and players" );
|
||||
static CVAR_DEFINE_AUTO( cl_dlmax, "0", FCVAR_USERINFO|FCVAR_ARCHIVE, "max allowed outcoming fragment size" );
|
||||
static CVAR_DEFINE_AUTO( cl_upmax, "1200", FCVAR_ARCHIVE, "max allowed incoming fragment size" );
|
||||
static CVAR_DEFINE_AUTO( cl_upmax, "508", FCVAR_ARCHIVE, "max allowed incoming fragment size" );
|
||||
|
||||
CVAR_DEFINE_AUTO( cl_lw, "1", FCVAR_ARCHIVE|FCVAR_USERINFO, "enable client weapon predicting" );
|
||||
CVAR_DEFINE_AUTO( cl_charset, "utf-8", FCVAR_ARCHIVE, "1-byte charset to use (iconv style)" );
|
||||
CVAR_DEFINE_AUTO( cl_trace_consistency, "0", FCVAR_ARCHIVE, "enable consistency info tracing (good for developers)" );
|
||||
CVAR_DEFINE_AUTO( cl_trace_stufftext, "0", FCVAR_ARCHIVE, "enable stufftext (server-to-client console commands) tracing (good for developers)" );
|
||||
CVAR_DEFINE_AUTO( cl_trace_messages, "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable message names tracing (good for developers)" );
|
||||
CVAR_DEFINE_AUTO( cl_trace_events, "0", FCVAR_ARCHIVE|FCVAR_CHEAT, "enable events tracing (good for developers)" );
|
||||
@@ -93,11 +94,10 @@ static CVAR_DEFINE_AUTO( name, username, FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_PRIN
|
||||
static CVAR_DEFINE_AUTO( model, "", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player model ('player' is a singleplayer model)" );
|
||||
static CVAR_DEFINE_AUTO( topcolor, "0", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player top color" );
|
||||
static CVAR_DEFINE_AUTO( bottomcolor, "0", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player bottom color" );
|
||||
CVAR_DEFINE_AUTO( rate, "3500", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player network rate" );
|
||||
CVAR_DEFINE_AUTO( rate, "25000", FCVAR_USERINFO|FCVAR_ARCHIVE|FCVAR_FILTERABLE, "player network rate" );
|
||||
|
||||
static CVAR_DEFINE_AUTO( cl_ticket_generator, "revemu2013", FCVAR_ARCHIVE, "you wouldn't steal a car" );
|
||||
|
||||
|
||||
client_t cl;
|
||||
client_static_t cls;
|
||||
clgame_static_t clgame;
|
||||
@@ -147,11 +147,6 @@ qboolean CL_IsRecordDemo( void )
|
||||
return cls.demorecording;
|
||||
}
|
||||
|
||||
qboolean CL_IsTimeDemo( void )
|
||||
{
|
||||
return cls.timedemo;
|
||||
}
|
||||
|
||||
qboolean CL_DisableVisibility( void )
|
||||
{
|
||||
return cls.envshot_disable_vis;
|
||||
@@ -598,7 +593,7 @@ CL_CreateCmd
|
||||
*/
|
||||
static void CL_CreateCmd( void )
|
||||
{
|
||||
usercmd_t nullcmd, *cmd;
|
||||
usercmd_t nullcmd = { 0 }, *cmd;
|
||||
runcmd_t *pcmd;
|
||||
qboolean active;
|
||||
double accurate_ms;
|
||||
@@ -650,7 +645,6 @@ static void CL_CreateCmd( void )
|
||||
}
|
||||
else
|
||||
{
|
||||
memset( &nullcmd, 0, sizeof( nullcmd ));
|
||||
cmd = &nullcmd;
|
||||
}
|
||||
|
||||
@@ -679,7 +673,7 @@ static void CL_CreateCmd( void )
|
||||
}
|
||||
|
||||
// demo always have commands so don't overwrite them
|
||||
if( !cls.demoplayback ) cl.cmd = &pcmd->cmd;
|
||||
if( !cls.demoplayback ) cl.cmd = pcmd->cmd;
|
||||
|
||||
// predict all unacknowledged movements
|
||||
CL_PredictMovement( false );
|
||||
@@ -723,11 +717,20 @@ static void CL_WritePacket( void )
|
||||
int numbackup, maxbackup, maxcmds;
|
||||
const connprotocol_t proto = cls.legacymode;
|
||||
|
||||
// FIXME: on Xash protocol we don't send move commands until ca_active
|
||||
// to prevent outgoing_command outrun incoming_acknowledged
|
||||
// which is fatal for some buggy mods like TFC
|
||||
//
|
||||
// ... but GoldSrc don't have (real) ca_validate state, so we consider
|
||||
// ca_validate the same as ca_active, otherwise we don't pass validation
|
||||
// of server-side mods like ReAuthCheck
|
||||
const connstate_t min_state = proto == PROTO_GOLDSRC ? ca_validate : ca_active;
|
||||
|
||||
// don't send anything if playing back a demo
|
||||
if( cls.demoplayback || cls.state < ca_connected || cls.state == ca_cinematic )
|
||||
return;
|
||||
|
||||
if( cls.state <= ca_connected )
|
||||
if( cls.state < min_state )
|
||||
{
|
||||
Netchan_TransmitBits( &cls.netchan, 0, "" );
|
||||
return;
|
||||
@@ -825,7 +828,7 @@ static void CL_WritePacket( void )
|
||||
buf.pData[key] = CRC32_BlockSequence( &buf.pData[key + 1], size, cls.netchan.outgoing_sequence );
|
||||
COM_Munge( &buf.pData[key + 1], Q_min( size, 255 ), cls.netchan.outgoing_sequence );
|
||||
}
|
||||
else
|
||||
else if( !Host_IsLocalClient( ))
|
||||
{
|
||||
int size = MSG_GetRealBytesWritten( &buf ) - key - 1;
|
||||
buf.pData[key] = CRC32_BlockSequence( &buf.pData[key + 1], size, cls.netchan.outgoing_sequence );
|
||||
@@ -965,7 +968,7 @@ CL_Quit_f
|
||||
void CL_Quit_f( void )
|
||||
{
|
||||
CL_Disconnect();
|
||||
Sys_Quit();
|
||||
Sys_Quit( "command" );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1005,7 +1008,7 @@ static void CL_WriteSteamTicket( sizebuf_t *send )
|
||||
const char *s;
|
||||
uint32_t crc;
|
||||
char buf[768] = { 0 }; // setti and steamemu return 768
|
||||
size_t i = sizeof( buf );
|
||||
int i = sizeof( buf );
|
||||
|
||||
if( !Q_strcmp( cl_ticket_generator.string, "null" ))
|
||||
{
|
||||
@@ -1024,24 +1027,7 @@ static void CL_WriteSteamTicket( sizebuf_t *send )
|
||||
CRC32_Init( &crc );
|
||||
CRC32_ProcessBuffer( &crc, s, Q_strlen( s ));
|
||||
crc = CRC32_Final( crc );
|
||||
|
||||
if( !Q_stricmp( cl_ticket_generator.string, "revemu2013" ))
|
||||
i = GenerateRevEmu2013( buf, crc );
|
||||
else if( !Q_stricmp( cl_ticket_generator.string, "sc2009" ))
|
||||
i = GenerateSC2009( buf, crc );
|
||||
else if( !Q_stricmp( cl_ticket_generator.string, "oldrevemu" ))
|
||||
i = GenerateOldRevEmu( buf, crc );
|
||||
else if( !Q_stricmp( cl_ticket_generator.string, "steamemu" ))
|
||||
i = GenerateSteamEmu( buf, crc );
|
||||
else if( !Q_stricmp( cl_ticket_generator.string, "revemu" ))
|
||||
i = GenerateRevEmu( buf, crc );
|
||||
else if( !Q_stricmp( cl_ticket_generator.string, "setti" ))
|
||||
i = GenerateSetti( buf );
|
||||
else if( !Q_stricmp( cl_ticket_generator.string, "avsmp" ))
|
||||
i = GenerateAVSMP( buf, crc, true );
|
||||
else
|
||||
Con_Printf( "%s: unknown generator %s, supported are: null, revemu2003, sc2009, oldrevemu, steamemu, revemu, setti, avsmp\n", __func__, cl_ticket_generator.string );
|
||||
|
||||
i = GenerateRevEmu2013( buf, s, crc );
|
||||
MSG_WriteBytes( send, buf, i );
|
||||
}
|
||||
|
||||
@@ -1059,6 +1045,7 @@ static void CL_SendConnectPacket( connprotocol_t proto, int challenge )
|
||||
const char *key = ID_GetMD5();
|
||||
netadr_t adr = { 0 };
|
||||
int input_devices;
|
||||
netadrtype_t adrtype;
|
||||
|
||||
protinfo[0] = 0;
|
||||
|
||||
@@ -1069,14 +1056,16 @@ static void CL_SendConnectPacket( connprotocol_t proto, int challenge )
|
||||
return;
|
||||
}
|
||||
|
||||
adrtype = NET_NetadrType( &adr );
|
||||
|
||||
if( adr.port == 0 ) adr.port = MSG_BigShort( PORT_SERVER );
|
||||
|
||||
input_devices = IN_CollectInputDevices();
|
||||
IN_LockInputDevices( adr.type != NA_LOOPBACK ? true : false );
|
||||
IN_LockInputDevices( adrtype != NA_LOOPBACK ? true : false );
|
||||
|
||||
// GoldSrc doesn't need sv_cheats set to 0, it's handled by svc_goldsrc_sendextrainfo
|
||||
// it also doesn't need useragent string
|
||||
if( adr.type != NA_LOOPBACK && proto != PROTO_GOLDSRC )
|
||||
if( adrtype != NA_LOOPBACK && proto != PROTO_GOLDSRC )
|
||||
{
|
||||
Cvar_SetCheatState();
|
||||
Cvar_FullSet( "sv_cheats", "0", FCVAR_READ_ONLY | FCVAR_SERVER );
|
||||
@@ -1176,7 +1165,11 @@ Returns bandwidth test fragment size
|
||||
*/
|
||||
static int CL_GetTestFragmentSize( void )
|
||||
{
|
||||
const int fragmentSizes[CL_TEST_RETRIES] = { 64000, 32000, 10666, 5200, 1400 };
|
||||
// const int fragmentSizes[CL_TEST_RETRIES] = { 64000, 32000, 10666, 5200, 1400 };
|
||||
|
||||
// it turns out, even if we pass the bandwidth test, it doesn't mean we can use such large fragments
|
||||
// as a temporary solution, use smaller fragment sizes
|
||||
const int fragmentSizes[CL_TEST_RETRIES] = { 1400, 1200, 1000, 800, 508 };
|
||||
if( cls.connect_retry >= 0 && cls.connect_retry < CL_TEST_RETRIES )
|
||||
return bound( FRAGMENT_MIN_SIZE, fragmentSizes[cls.connect_retry], FRAGMENT_MAX_SIZE );
|
||||
else
|
||||
@@ -1214,7 +1207,7 @@ static void CL_CheckForResend( void )
|
||||
cls.signon = 0;
|
||||
cls.state = ca_connecting;
|
||||
Q_strncpy( cls.servername, "localhost", sizeof( cls.servername ));
|
||||
cls.serveradr.type = NA_LOOPBACK;
|
||||
NET_NetadrSetType( &cls.serveradr, NA_LOOPBACK );
|
||||
cls.legacymode = PROTO_CURRENT;
|
||||
|
||||
// we don't need a challenge on the localhost
|
||||
@@ -1550,8 +1543,8 @@ static void CL_SendDisconnectMessage( connprotocol_t proto )
|
||||
MSG_WriteString( &buf, "dropclient\n" );
|
||||
else MSG_WriteString( &buf, "disconnect" );
|
||||
|
||||
if( !cls.netchan.remote_address.type )
|
||||
cls.netchan.remote_address.type = NA_LOOPBACK;
|
||||
if( NET_NetadrType( &cls.netchan.remote_address ) == NA_UNDEFINED )
|
||||
NET_NetadrSetType( &cls.netchan.remote_address, NA_LOOPBACK );
|
||||
|
||||
// make sure message will be delivered
|
||||
Netchan_TransmitBits( &cls.netchan, MSG_GetNumBitsWritten( &buf ), MSG_GetData( &buf ));
|
||||
@@ -1594,6 +1587,9 @@ void CL_SetupNetchanForProtocol( connprotocol_t proto )
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if( !Host_IsLocalClient( ))
|
||||
SetBits( flags, NETCHAN_USE_LZSS );
|
||||
|
||||
cls.extensions = Q_atoi( Info_ValueForKey( Cmd_Argv( 1 ), "ext" ));
|
||||
|
||||
if( FBitSet( cls.extensions, NET_EXT_SPLITSIZE ))
|
||||
@@ -1717,19 +1713,17 @@ CL_LocalServers_f
|
||||
*/
|
||||
static void CL_LocalServers_f( void )
|
||||
{
|
||||
netadr_t adr;
|
||||
|
||||
memset( &adr, 0, sizeof( adr ));
|
||||
netadr_t adr = { 0 };
|
||||
|
||||
Con_Printf( "Scanning for servers on the local network area...\n" );
|
||||
NET_Config( true, true ); // allow remote
|
||||
|
||||
// send a broadcast packet
|
||||
adr.type = NA_BROADCAST;
|
||||
NET_NetadrSetType( &adr, NA_BROADCAST );
|
||||
adr.port = MSG_BigShort( PORT_SERVER );
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, A2A_INFO" %i", PROTOCOL_VERSION );
|
||||
|
||||
adr.type = NA_MULTICAST_IP6;
|
||||
NET_NetadrSetType( &adr, NA_MULTICAST_IP6 );
|
||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, A2A_INFO" %i", PROTOCOL_VERSION );
|
||||
}
|
||||
|
||||
@@ -1761,8 +1755,8 @@ static size_t NONNULL CL_BuildMasterServerScanRequest( char *buf, size_t size, u
|
||||
// let master know about client version
|
||||
Info_SetValueForKey( info, "clver", XASH_VERSION, remaining );
|
||||
Info_SetValueForKey( info, "nat", nat ? "1" : "0", remaining );
|
||||
Info_SetValueForKey( info, "commit", Q_buildcommit(), remaining );
|
||||
Info_SetValueForKey( info, "branch", Q_buildbranch(), remaining );
|
||||
Info_SetValueForKey( info, "commit", g_buildcommit, remaining );
|
||||
Info_SetValueForKey( info, "branch", g_buildbranch, remaining );
|
||||
Info_SetValueForKey( info, "os", Q_buildos(), remaining );
|
||||
Info_SetValueForKey( info, "arch", Q_buildarch(), remaining );
|
||||
|
||||
@@ -2473,18 +2467,18 @@ static void CL_ServerList( netadr_t from, sizebuf_t *msg )
|
||||
while( MSG_GetNumBitsLeft( msg ) > 8 )
|
||||
{
|
||||
uint8_t addr[16];
|
||||
netadr_t servadr;
|
||||
netadr_t servadr = { 0 };
|
||||
|
||||
if( from.type6 == NA_IP6 ) // IPv6 master server only sends IPv6 addresses
|
||||
if( NET_NetadrType( &from ) == NA_IP6 ) // IPv6 master server only sends IPv6 addresses
|
||||
{
|
||||
MSG_ReadBytes( msg, addr, sizeof( addr ));
|
||||
NET_IP6BytesToNetadr( &servadr, addr );
|
||||
servadr.type6 = NA_IP6;
|
||||
NET_NetadrSetType( &servadr, NA_IP6 );
|
||||
}
|
||||
else
|
||||
{
|
||||
MSG_ReadBytes( msg, servadr.ip, sizeof( servadr.ip )); // 4 bytes for IP
|
||||
servadr.type = NA_IP;
|
||||
NET_NetadrSetType( &servadr, NA_IP );
|
||||
}
|
||||
servadr.port = MSG_ReadShort( msg ); // 2 bytes for Port
|
||||
|
||||
@@ -3132,6 +3126,9 @@ static qboolean CL_ShouldRescanFilesystem( void )
|
||||
}
|
||||
}
|
||||
|
||||
if( FBitSet( fs_mount_lv.flags|fs_mount_hd.flags|fs_mount_addon.flags|fs_mount_l10n.flags|ui_language.flags, FCVAR_CHANGED ))
|
||||
retval = true;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -3141,7 +3138,7 @@ qboolean CL_PrecacheResources( void )
|
||||
|
||||
// if we downloaded new WAD files or any other archives they must be added to searchpath
|
||||
if( CL_ShouldRescanFilesystem( ))
|
||||
g_fsapi.Rescan();
|
||||
FS_Rescan_f();
|
||||
|
||||
// NOTE: world need to be loaded as first model
|
||||
for( pRes = cl.resourcesonhand.pNext; pRes && pRes != &cl.resourcesonhand; pRes = pRes->pNext )
|
||||
@@ -3387,6 +3384,7 @@ static void CL_InitLocal( void )
|
||||
|
||||
Cvar_RegisterVariable( &rcon_address );
|
||||
|
||||
Cvar_RegisterVariable( &cl_trace_consistency );
|
||||
Cvar_RegisterVariable( &cl_trace_stufftext );
|
||||
Cvar_RegisterVariable( &cl_trace_messages );
|
||||
Cvar_RegisterVariable( &cl_trace_events );
|
||||
@@ -3464,10 +3462,10 @@ static void CL_InitLocal( void )
|
||||
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" );
|
||||
Cmd_AddRestrictedCommand( "record", CL_Record_f, "record a demo" );
|
||||
Cmd_AddCommand ("playdemo", CL_PlayDemo_f, "play a demo" );
|
||||
Cmd_AddCommand ("timedemo", CL_TimeDemo_f, "demo benchmark" );
|
||||
Cmd_AddCommand ("killdemo", CL_DeleteDemo_f, "delete a specified demo file" );
|
||||
Cmd_AddRestrictedCommand( "killdemo", CL_DeleteDemo_f, "delete a specified demo file" );
|
||||
Cmd_AddCommand ("startdemos", CL_StartDemos_f, "start playing back the selected demos sequentially" );
|
||||
Cmd_AddCommand ("demos", CL_Demos_f, "restart looping demos defined by the last startdemos command" );
|
||||
Cmd_AddCommand ("movie", CL_PlayVideo_f, "play a movie" );
|
||||
@@ -3481,6 +3479,8 @@ static 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_AddRestrictedCommand( "replaybufferdat", CL_ReplayBufferDat_f, "development and debugging tool" );
|
||||
|
||||
Cmd_AddRestrictedCommand ("quit", CL_Quit_f, "quit from game" );
|
||||
Cmd_AddRestrictedCommand ("exit", CL_Quit_f, "quit from game" );
|
||||
|
||||
@@ -3658,6 +3658,8 @@ void CL_Init( void )
|
||||
if( !CL_LoadProgs( libpath ))
|
||||
Host_Error( "can't initialize %s: %s\n", libpath, COM_GetLibraryError( ));
|
||||
|
||||
ID_Init();
|
||||
|
||||
cls.build_num = 0;
|
||||
cls.initialized = true;
|
||||
cl.maxclients = 1; // allow to drawing player in menu
|
||||
@@ -3675,7 +3677,7 @@ void CL_Shutdown( void )
|
||||
{
|
||||
Con_Printf( "%s()\n", __func__ );
|
||||
|
||||
if( !host.crashed && cls.initialized )
|
||||
if( host.status != HOST_CRASHED && cls.initialized )
|
||||
{
|
||||
Host_WriteOpenGLConfig ();
|
||||
Host_WriteVideoConfig ();
|
||||
|
||||
@@ -92,6 +92,11 @@ static char *pfnParseFileSafe( char *data, char *buf, const int size, unsigned i
|
||||
return COM_ParseFileSafe( data, buf, size, flags, len, NULL );
|
||||
}
|
||||
|
||||
static void GAME_EXPORT pfnSetCustomClientID( const char *id )
|
||||
{
|
||||
// deprecated
|
||||
}
|
||||
|
||||
static const mobile_engfuncs_t gMobileEngfuncs =
|
||||
{
|
||||
MOBILITY_API_VERSION,
|
||||
@@ -106,7 +111,7 @@ static const mobile_engfuncs_t gMobileEngfuncs =
|
||||
pfnDrawScaledCharacter,
|
||||
Sys_Warn,
|
||||
Sys_GetNativeObject,
|
||||
ID_SetCustomClientID,
|
||||
pfnSetCustomClientID,
|
||||
pfnParseFileSafe
|
||||
};
|
||||
|
||||
|
||||
@@ -1325,11 +1325,11 @@ void CL_ParseLightStyle( sizebuf_t *msg, connprotocol_t proto )
|
||||
{
|
||||
int style;
|
||||
const char *s;
|
||||
float f = 0.0f;
|
||||
float f = cl.mtime[0];
|
||||
|
||||
style = MSG_ReadByte( msg );
|
||||
s = MSG_ReadString( msg );
|
||||
if( proto != PROTO_GOLDSRC )
|
||||
if( proto != PROTO_GOLDSRC && proto != PROTO_QUAKE )
|
||||
f = MSG_ReadFloat( msg );
|
||||
|
||||
CL_SetLightstyle( style, s, f );
|
||||
@@ -1614,6 +1614,23 @@ void CL_UpdateUserPings( sizebuf_t *msg )
|
||||
}
|
||||
}
|
||||
|
||||
static const char *CL_CheckTypeToString( int check_type )
|
||||
{
|
||||
// renamed so they have same width and look better in console output
|
||||
switch( check_type )
|
||||
{
|
||||
case force_exactfile:
|
||||
return "exactfile";
|
||||
case force_model_samebounds:
|
||||
return "samebounds";
|
||||
case force_model_specifybounds:
|
||||
return "specbounds";
|
||||
case force_model_specifybounds_if_avail:
|
||||
return "specbounds2";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static void CL_SendConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
{
|
||||
qboolean user_changed_diskfile;
|
||||
@@ -1879,6 +1896,9 @@ static void CL_ParseConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
return;
|
||||
}
|
||||
|
||||
if( cl_trace_consistency.value )
|
||||
Con_Printf( "Server wants consistency of the following resources:\n" );
|
||||
|
||||
skip_crc_change = NULL;
|
||||
lastcheck = 0;
|
||||
|
||||
@@ -1910,7 +1930,7 @@ static void CL_ParseConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
pc = &cl.consistency_list[cl.num_consistency];
|
||||
cl.num_consistency++;
|
||||
|
||||
memset( pc, 0, sizeof( consistency_t ));
|
||||
memset( pc, 0, sizeof( *pc ));
|
||||
pc->filename = pResource->szFileName;
|
||||
pc->issound = (pResource->type == t_sound);
|
||||
pc->orig_index = delta;
|
||||
@@ -1923,6 +1943,9 @@ static void CL_ParseConsistencyInfo( sizebuf_t *msg, connprotocol_t proto )
|
||||
pc->check_type = pResource->rguc_reserved[0];
|
||||
}
|
||||
|
||||
if( cl_trace_consistency.value )
|
||||
Con_Printf( "%s\t%s\t%s\n", COM_ResourceTypeFromIndex( pResource->type ), CL_CheckTypeToString( pc->check_type ), pc->filename );
|
||||
|
||||
skip_crc_change = pResource;
|
||||
lastcheck = delta;
|
||||
}
|
||||
|
||||
@@ -83,7 +83,10 @@ static void CL_ParseNewMovevars( sizebuf_t *msg )
|
||||
R_SetupSky( clgame.movevars.skyName );
|
||||
|
||||
clgame.oldmovevars = clgame.movevars;
|
||||
clgame.entities->curstate.scale = clgame.movevars.waveHeight;
|
||||
|
||||
// FIXME: set world wave height when entities will be allocated
|
||||
if( clgame.entities )
|
||||
clgame.entities->curstate.scale = clgame.movevars.waveHeight;
|
||||
|
||||
// keep features an actual!
|
||||
clgame.oldmovevars.features = clgame.movevars.features = host.features;
|
||||
@@ -91,11 +94,11 @@ static void CL_ParseNewMovevars( sizebuf_t *msg )
|
||||
|
||||
typedef struct delta_header_t
|
||||
{
|
||||
qboolean remove : 1;
|
||||
qboolean custom : 1;
|
||||
qboolean instanced : 1;
|
||||
uint instanced_baseline_index : 6;
|
||||
uint offset : 6;
|
||||
qboolean remove;
|
||||
qboolean custom;
|
||||
qboolean instanced;
|
||||
uint16_t instanced_baseline_index;
|
||||
uint16_t offset;
|
||||
} delta_header_t;
|
||||
|
||||
static int CL_ParseDeltaHeader( sizebuf_t *msg, qboolean delta, int oldnum, struct delta_header_t *hdr )
|
||||
@@ -160,33 +163,47 @@ static int CL_GetEntityDelta( const struct delta_header_t *hdr, int entnum )
|
||||
return DT_ENTITY_STATE_T;
|
||||
}
|
||||
|
||||
static void CL_FlushEntityPacketGS( frame_t *frame, sizebuf_t *msg )
|
||||
static int CL_FlushEntityPacketGS( frame_t *frame, sizebuf_t *msg )
|
||||
{
|
||||
int playerbytes = 0, numbase = 0;
|
||||
|
||||
frame->valid = false;
|
||||
cl.validsequence = 0; // can't render a frame
|
||||
|
||||
// read it all but ignore it
|
||||
while( 1 )
|
||||
{
|
||||
int num = 0;
|
||||
int newnum, bufstart;
|
||||
entity_state_t from = { 0 }, to;
|
||||
delta_header_t hdr;
|
||||
qboolean player;
|
||||
|
||||
if( MSG_ReadWord( msg ) != 0 )
|
||||
{
|
||||
MSG_SeekToBit( msg, -16, SEEK_CUR );
|
||||
num = CL_ParseDeltaHeader( msg, false, num, &hdr );
|
||||
numbase = newnum = CL_ParseDeltaHeader( msg, true, numbase, &hdr );
|
||||
}
|
||||
else break;
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
Host_Error( "%s: overflow\n", __func__ );
|
||||
|
||||
player = CL_IsPlayerIndex( newnum );
|
||||
bufstart = MSG_GetNumBytesRead( msg );
|
||||
|
||||
if( hdr.remove )
|
||||
continue;
|
||||
|
||||
Delta_ReadGSFields( msg, CL_GetEntityDelta( &hdr, num ), &from, &to, cl.mtime[0] );
|
||||
Delta_ReadGSFields( msg, CL_GetEntityDelta( &hdr, newnum ), &from, &to, cl.mtime[0] );
|
||||
|
||||
if( player )
|
||||
playerbytes += MSG_GetNumBytesRead( msg ) - bufstart;
|
||||
}
|
||||
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
Host_Error( "%s: overflow\n", __func__ );
|
||||
|
||||
return playerbytes;
|
||||
}
|
||||
|
||||
static void CL_DeltaEntityGS( const delta_header_t *hdr, sizebuf_t *msg, frame_t *frame, int newnum, const entity_state_t *from )
|
||||
@@ -203,7 +220,7 @@ static void CL_DeltaEntityGS( const delta_header_t *hdr, sizebuf_t *msg, frame_t
|
||||
if(( newnum < 0 ) || ( newnum >= clgame.maxEntities ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "CL_DeltaEntity: invalid newnum: %d\n", newnum );
|
||||
Host_Error( "%s: bad delta entity number: %i", __func__, newnum );
|
||||
Host_Error( "%s: bad delta entity number: %i\n", __func__, newnum );
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -267,7 +284,7 @@ static void CL_CopyPacketEntity( frame_t *frame, int num, const entity_state_t *
|
||||
static int CL_ParsePacketEntitiesGS( sizebuf_t *msg, qboolean delta )
|
||||
{
|
||||
frame_t *frame, *oldframe;
|
||||
int oldindex, newnum, oldnum, numbase = 0;
|
||||
int oldindex, oldnum, numbase = 0;
|
||||
entity_state_t *oldent;
|
||||
int count;
|
||||
int playerbytes = 0;
|
||||
@@ -314,7 +331,7 @@ static int CL_ParsePacketEntitiesGS( sizebuf_t *msg, qboolean delta )
|
||||
// read it all but ignore it
|
||||
while( 1 )
|
||||
{
|
||||
int bufstart;
|
||||
int bufstart, newnum;
|
||||
qboolean player;
|
||||
delta_header_t hdr;
|
||||
int val = MSG_ReadWord( msg );
|
||||
@@ -534,7 +551,7 @@ void CL_ParseGoldSrcServerMessage( sizebuf_t *msg )
|
||||
{
|
||||
if( MSG_CheckOverflow( msg ))
|
||||
{
|
||||
Host_Error( "CL_ParseServerMessage: overflow!\n" );
|
||||
Host_Error( "%s: overflow!\n", __func__ );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -973,7 +973,7 @@ void CL_MoveSpectatorCamera( void )
|
||||
|
||||
CL_SetUpPlayerPrediction( false, true );
|
||||
CL_SetSolidPlayers( cl.playernum );
|
||||
CL_RunUsercmd( &cls.spectator_state, &cls.spectator_state, cl.cmd, true, &time, (uint)( time * 100.0 ));
|
||||
CL_RunUsercmd( &cls.spectator_state, &cls.spectator_state, &cl.cmd, true, &time, (uint)( time * 100.0 ));
|
||||
|
||||
VectorCopy( cls.spectator_state.client.velocity, cl.simvel );
|
||||
VectorCopy( cls.spectator_state.client.origin, cl.simorg );
|
||||
|
||||
@@ -970,9 +970,7 @@ void CL_ParseQuakeMessage( sizebuf_t *msg )
|
||||
CL_ParseQuakeServerInfo( msg );
|
||||
break;
|
||||
case svc_lightstyle:
|
||||
param1 = MSG_ReadByte( msg );
|
||||
str = MSG_ReadString( msg );
|
||||
CL_SetLightstyle( param1, str, cl.mtime[0] );
|
||||
CL_ParseLightStyle( msg, PROTO_QUAKE );
|
||||
break;
|
||||
case svc_updatename:
|
||||
param1 = MSG_ReadByte( msg );
|
||||
|
||||
@@ -138,10 +138,7 @@ intptr_t CL_RenderGetParm( const int parm, const int arg, const qboolean checkRe
|
||||
switch( parm )
|
||||
{
|
||||
case PARM_BSP2_SUPPORTED:
|
||||
#ifdef SUPPORT_BSP2_FORMAT
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
case PARAM_GAMEPAUSED:
|
||||
return cl.paused;
|
||||
case PARM_CLIENT_INGAME:
|
||||
@@ -236,6 +233,11 @@ static intptr_t pfnRenderGetParm( int parm, int arg )
|
||||
return CL_RenderGetParm( parm, arg, true );
|
||||
}
|
||||
|
||||
static void pfnAVI_StreamSound( void *avi, int entnum, float fvol, float attn, float synctime )
|
||||
{
|
||||
return; // stub, use AVI_SetParm and AVI_Think to stream AVI sound
|
||||
}
|
||||
|
||||
static render_api_t gRenderAPI =
|
||||
{
|
||||
pfnRenderGetParm, // GL_RenderGetParm,
|
||||
@@ -268,7 +270,7 @@ static render_api_t gRenderAPI =
|
||||
NULL, // R_UploadStretchRaw,
|
||||
(void*)AVI_FreeVideo,
|
||||
(void*)AVI_IsActive,
|
||||
S_StreamAviSamples,
|
||||
(void*)pfnAVI_StreamSound,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, // GL_Bind,
|
||||
|
||||
@@ -567,57 +567,54 @@ R_FizzEffect
|
||||
Create a fizz effect
|
||||
==============
|
||||
*/
|
||||
void GAME_EXPORT R_FizzEffect( cl_entity_t *pent, int modelIndex, int density )
|
||||
void GAME_EXPORT R_FizzEffect( cl_entity_t *ent, int modelIndex, int density )
|
||||
{
|
||||
TEMPENTITY *pTemp;
|
||||
int i, width, depth;
|
||||
float angle, maxHeight, speed;
|
||||
float xspeed, yspeed, zspeed;
|
||||
vec3_t origin;
|
||||
model_t *mod;
|
||||
const float base_time = cl.time - 0.1f;
|
||||
model_t *mod = CL_ModelHandle( modelIndex );
|
||||
vec3_t volume, mins, maxs;
|
||||
vec2_t speed;
|
||||
int i;
|
||||
|
||||
if( !pent || !pent->model || !modelIndex )
|
||||
if( !ent || !ent->model || !modelIndex || !mod )
|
||||
return;
|
||||
|
||||
if(( mod = CL_ModelHandle( modelIndex )) == NULL )
|
||||
return;
|
||||
VectorCopy( ent->model->mins, mins );
|
||||
VectorCopy( ent->model->maxs, maxs );
|
||||
|
||||
maxHeight = pent->model->maxs[2] - pent->model->mins[2];
|
||||
width = pent->model->maxs[0] - pent->model->mins[0];
|
||||
depth = pent->model->maxs[1] - pent->model->mins[1];
|
||||
if( ent->angles[1] != 0.0f )
|
||||
{
|
||||
const float base_speed = ( ent->curstate.rendercolor.b ? -1.0f : 1.0f ) * ( ent->curstate.rendercolor.r * 256.0f + ent->curstate.rendercolor.g );
|
||||
SinCos( DEG2RAD( ent->angles[1] ), &speed[1], &speed[0] );
|
||||
speed[0] *= base_speed;
|
||||
speed[1] *= base_speed;
|
||||
}
|
||||
else speed[0] = speed[1] = 0.0f;
|
||||
|
||||
speed = ( pent->curstate.rendercolor.r<<8 | pent->curstate.rendercolor.g );
|
||||
if( pent->curstate.rendercolor.b )
|
||||
speed = -speed;
|
||||
|
||||
angle = DEG2RAD( pent->angles[YAW] );
|
||||
SinCos( angle, &yspeed, &xspeed );
|
||||
|
||||
xspeed *= speed;
|
||||
yspeed *= speed;
|
||||
VectorSubtract( maxs, mins, volume );
|
||||
|
||||
for( i = 0; i <= density; i++ )
|
||||
{
|
||||
origin[0] = mod->mins[0] + COM_RandomLong( 0, width - 1 );
|
||||
origin[1] = mod->mins[1] + COM_RandomLong( 0, depth - 1 );
|
||||
origin[2] = mod->mins[2];
|
||||
pTemp = CL_TempEntAlloc( origin, mod );
|
||||
TEMPENTITY *tent;
|
||||
vec3_t origin;
|
||||
|
||||
if ( !pTemp ) return;
|
||||
VectorCopy( mins, origin );
|
||||
origin[0] += COM_RandomLong( 0, (int)volume[0] - 1 );
|
||||
origin[1] += COM_RandomLong( 0, (int)volume[1] - 1 );
|
||||
|
||||
pTemp->flags |= FTENT_SINEWAVE;
|
||||
if( !( tent = CL_TempEntAlloc( origin, mod )))
|
||||
return;
|
||||
|
||||
pTemp->x = origin[0];
|
||||
pTemp->y = origin[1];
|
||||
tent->x = origin[0];
|
||||
tent->y = origin[1];
|
||||
tent->die = base_time;
|
||||
tent->flags |= FTENT_SINEWAVE;
|
||||
tent->entity.curstate.rendermode = kRenderTransAlpha;
|
||||
Vector2Copy( speed, tent->entity.baseline.origin );
|
||||
|
||||
zspeed = COM_RandomLong( 80, 140 );
|
||||
VectorSet( pTemp->entity.baseline.origin, xspeed, yspeed, zspeed );
|
||||
pTemp->die = cl.time + ( maxHeight / zspeed ) - 0.1f;
|
||||
pTemp->entity.curstate.frame = COM_RandomLong( 0, pTemp->frameMax );
|
||||
// Set sprite scale
|
||||
pTemp->entity.curstate.scale = 1.0f / COM_RandomFloat( 2.0f, 5.0f );
|
||||
pTemp->entity.curstate.rendermode = kRenderTransAlpha;
|
||||
pTemp->entity.curstate.renderamt = 255;
|
||||
tent->entity.baseline.origin[2] = COM_RandomLong( 80, 140 );
|
||||
tent->die += volume[2] / tent->entity.baseline.origin[2];
|
||||
tent->entity.curstate.frame = COM_RandomLong( 0, tent->frameMax );
|
||||
tent->entity.curstate.scale = 1.0f / COM_RandomFloat( 2.0f, 5.0f );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -958,7 +955,6 @@ void GAME_EXPORT R_BloodSprite( const vec3_t org, int colorIndex, int modelIndex
|
||||
if( pTemp->entity.curstate.frame > 8.0f )
|
||||
pTemp->entity.curstate.frame = pTemp->frameMax;
|
||||
|
||||
pTemp->entity.baseline.origin[2] += COM_RandomFloat( 4.0f, 16.0f ) * size;
|
||||
pTemp->entity.angles[2] = COM_RandomFloat( 0.0f, 360.0f );
|
||||
pTemp->bounceFactor = 0.0f;
|
||||
}
|
||||
@@ -2432,7 +2428,7 @@ void CL_SetLightstyle( int style, const char *s, float f )
|
||||
|
||||
if( unlikely( style < 0 || style >= MAX_LIGHTSTYLES ))
|
||||
{
|
||||
Con_Printf( S_WARN "%s: ignored invalid lightstyle id %d\n", style );
|
||||
Con_Printf( S_WARN "%s: ignored invalid lightstyle id %d\n", __func__, style );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ static void V_SetRefParams( ref_params_t *fd )
|
||||
|
||||
// get pointers to movement vars and user cmd
|
||||
fd->movevars = &clgame.movevars;
|
||||
fd->cmd = cl.cmd;
|
||||
fd->cmd = &cl.cmd;
|
||||
|
||||
// setup viewport
|
||||
fd->viewport[0] = clgame.viewport[0];
|
||||
@@ -466,8 +466,8 @@ static void R_ShowTree_r( mnode_t *node, float x, float y, float scale, int show
|
||||
R_DrawNodeConnection( x, y, x + scale, y + scale );
|
||||
}
|
||||
|
||||
R_ShowTree_r( node->children[1], x - scale, y + scale, downScale, shownodes, viewleaf );
|
||||
R_ShowTree_r( node->children[0], x + scale, y + scale, downScale, shownodes, viewleaf );
|
||||
R_ShowTree_r( node_child( node, 1, cl.worldmodel ), x - scale, y + scale, downScale, shownodes, viewleaf );
|
||||
R_ShowTree_r( node_child( node, 0, cl.worldmodel ), x + scale, y + scale, downScale, shownodes, viewleaf );
|
||||
|
||||
world.recursion_level--;
|
||||
}
|
||||
@@ -482,7 +482,7 @@ static void R_ShowTree( void )
|
||||
return;
|
||||
|
||||
world.recursion_level = 0;
|
||||
viewleaf = Mod_PointInLeaf( refState.vieworg, cl.worldmodel->nodes );
|
||||
viewleaf = Mod_PointInLeaf( refState.vieworg, cl.worldmodel->nodes, cl.worldmodel );
|
||||
|
||||
ref.dllFuncs.TriRenderMode( kRenderTransTexture );
|
||||
|
||||
|
||||
@@ -234,7 +234,7 @@ typedef struct
|
||||
cl_local_data_t local;
|
||||
|
||||
// player final info
|
||||
usercmd_t *cmd; // cl.commands[outgoing_sequence].cmd
|
||||
usercmd_t cmd; // cl.commands[outgoing_sequence].cmd
|
||||
vec3_t viewangles;
|
||||
vec3_t viewheight;
|
||||
vec3_t punchangle;
|
||||
@@ -688,6 +688,7 @@ extern convar_t r_showtextures;
|
||||
extern convar_t cl_bmodelinterp;
|
||||
extern convar_t cl_lw; // local weapons
|
||||
extern convar_t cl_charset;
|
||||
extern convar_t cl_trace_consistency;
|
||||
extern convar_t cl_trace_stufftext;
|
||||
extern convar_t cl_trace_messages;
|
||||
extern convar_t cl_trace_events;
|
||||
@@ -736,6 +737,7 @@ void CL_ClearResourceLists( void );
|
||||
//
|
||||
// cl_debug.c
|
||||
//
|
||||
void CL_ReplayBufferDat_f( void );
|
||||
void CL_Parse_Debug( qboolean enable );
|
||||
void CL_Parse_RecordCommand( int cmd, int startoffset );
|
||||
void CL_ResetFrame( frame_t *frame );
|
||||
@@ -767,7 +769,7 @@ void CL_StartupDemoHeader( void );
|
||||
void CL_DrawDemoRecording( void );
|
||||
void CL_WriteDemoUserCmd( int cmdnumber );
|
||||
void CL_WriteDemoMessage( qboolean startup, int start, sizebuf_t *msg );
|
||||
void CL_WriteDemoUserMessage( const byte *buffer, size_t size );
|
||||
void CL_WriteDemoUserMessage( int size, byte *buffer );
|
||||
qboolean CL_DemoReadMessage( byte *buffer, size_t *length );
|
||||
void CL_DemoInterpolateAngles( void );
|
||||
void CL_CheckStartupDemos( void );
|
||||
@@ -805,11 +807,11 @@ qboolean Con_LoadFixedWidthFont( const char *fontname, cl_font_t *font, float sc
|
||||
qboolean Con_LoadVariableWidthFont( const char *fontname, cl_font_t *font, float scale, convar_t *rendermode, uint texFlags );
|
||||
void CL_FreeFont( cl_font_t *font );
|
||||
void CL_SetFontRendermode( cl_font_t *font );
|
||||
int CL_DrawCharacter( float x, float y, int number, rgba_t color, cl_font_t *font, int flags );
|
||||
int CL_DrawString( float x, float y, const char *s, rgba_t color, cl_font_t *font, int flags );
|
||||
int CL_DrawCharacter( float x, float y, int number, const rgba_t color, cl_font_t *font, int flags );
|
||||
int CL_DrawString( float x, float y, const char *s, const rgba_t color, cl_font_t *font, int flags );
|
||||
void CL_DrawCharacterLen( cl_font_t *font, int number, int *width, int *height );
|
||||
void CL_DrawStringLen( cl_font_t *font, const char *s, int *width, int *height, int flags );
|
||||
int CL_DrawStringf( cl_font_t *font, float x, float y, rgba_t color, int flags, const char *fmt, ... ) FORMAT_CHECK( 6 );
|
||||
int CL_DrawStringf( cl_font_t *font, float x, float y, const rgba_t color, int flags, const char *fmt, ... ) FORMAT_CHECK( 6 );
|
||||
|
||||
|
||||
//
|
||||
@@ -842,19 +844,21 @@ void CL_EnableScissor( scissor_state_t *scissor, int x, int y, int width, int he
|
||||
void CL_DisableScissor( scissor_state_t *scissor );
|
||||
qboolean CL_Scissor( const scissor_state_t *scissor, float *x, float *y, float *width, float *height, float *u0, float *v0, float *u1, float *v1 );
|
||||
|
||||
static inline cl_entity_t *CL_EDICT_NUM( int n )
|
||||
static inline cl_entity_t *CL_EDICT_NUM( int index )
|
||||
{
|
||||
if( !clgame.entities )
|
||||
if( !clgame.entities ) // not in game yet
|
||||
{
|
||||
Host_Error( "%s: clgame.entities is NULL\n", __func__ );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(( n >= 0 ) && ( n < clgame.maxEntities ))
|
||||
return clgame.entities + n;
|
||||
if( index < 0 || index >= clgame.maxEntities )
|
||||
{
|
||||
Host_Error( "%s: bad number %i\n", __func__, index );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Host_Error( "%s: bad number %i\n", __func__, n );
|
||||
return NULL;
|
||||
return clgame.entities + index;
|
||||
}
|
||||
|
||||
static inline cl_entity_t *CL_GetEntityByIndex( int index )
|
||||
@@ -865,10 +869,7 @@ static inline cl_entity_t *CL_GetEntityByIndex( int index )
|
||||
if( index < 0 || index >= clgame.maxEntities )
|
||||
return NULL;
|
||||
|
||||
if( index == 0 )
|
||||
return clgame.entities;
|
||||
|
||||
return CL_EDICT_NUM( index );
|
||||
return clgame.entities + index;
|
||||
}
|
||||
|
||||
static inline model_t *CL_ModelHandle( int modelindex )
|
||||
@@ -878,7 +879,7 @@ static inline model_t *CL_ModelHandle( int modelindex )
|
||||
|
||||
static inline qboolean CL_IsThirdPerson( void )
|
||||
{
|
||||
return clgame.dllFuncs.CL_IsThirdPerson() ? true : false;
|
||||
return clgame.dllFuncs.CL_IsThirdPerson();
|
||||
}
|
||||
|
||||
static inline cl_entity_t *CL_GetLocalPlayer( void )
|
||||
@@ -1106,7 +1107,7 @@ int Con_UtfMoveRight( char *str, int pos, int length );
|
||||
void Con_DefaultColor( int r, int g, int b, qboolean gameui );
|
||||
cl_font_t *Con_GetCurFont( void );
|
||||
cl_font_t *Con_GetFont( int num );
|
||||
int Con_DrawString( int x, int y, const char *string, rgba_t setColor ); // legacy, use cl_font.c
|
||||
int Con_DrawString( int x, int y, const char *string, const rgba_t setColor ); // legacy, use cl_font.c
|
||||
void GAME_EXPORT Con_DrawStringLen( const char *pText, int *length, int *height ); // legacy, use cl_font.c
|
||||
void Con_CharEvent( int key );
|
||||
void Key_Console( int key );
|
||||
@@ -1119,7 +1120,7 @@ void Con_PageUp( int lines );
|
||||
//
|
||||
// s_main.c
|
||||
//
|
||||
void S_StreamAviSamples( void *Avi, int entnum, float fvol, float attn, float synctime );
|
||||
typedef int sound_t;
|
||||
void S_StartBackgroundTrack( const char *intro, const char *loop, int position, qboolean fullpath );
|
||||
void S_StopBackgroundTrack( void );
|
||||
void S_StreamSetPause( int pause );
|
||||
@@ -1208,6 +1209,12 @@ void Key_EnableTextInput( qboolean enable, qboolean force );
|
||||
int Key_ToUpper( int key );
|
||||
void OSK_Draw( void );
|
||||
|
||||
//
|
||||
// identification.c
|
||||
//
|
||||
void ID_Init( void );
|
||||
const char *ID_GetMD5( void );
|
||||
|
||||
extern rgba_t g_color_table[8];
|
||||
extern triangleapi_t gTriApi;
|
||||
extern net_api_t gNetApi;
|
||||
|
||||
@@ -622,7 +622,7 @@ int Con_UtfProcessCharForce( int in )
|
||||
// TODO: get rid of global state where possible
|
||||
static utfstate_t state = { 0 };
|
||||
|
||||
int ch = Q_DecodeUTF8( &state, in );
|
||||
uint32_t ch = Q_DecodeUTF8( &state, in );
|
||||
|
||||
if( g_codepage == 1251 )
|
||||
return Q_UnicodeToCP1251( ch );
|
||||
@@ -759,7 +759,7 @@ Con_DrawString
|
||||
client version of routine
|
||||
====================
|
||||
*/
|
||||
int Con_DrawString( int x, int y, const char *string, rgba_t setColor )
|
||||
int Con_DrawString( int x, int y, const char *string, const rgba_t setColor )
|
||||
{
|
||||
return CL_DrawString( x, y, string, setColor, con.curFont, FONT_DRAW_UTF8 );
|
||||
}
|
||||
@@ -843,11 +843,14 @@ If no console is visible, the notify window will pop up.
|
||||
*/
|
||||
void Con_Print( const char *txt )
|
||||
{
|
||||
static int cr_pending = 0;
|
||||
static char buf[MAX_PRINT_MSG];
|
||||
qboolean norefresh = false;
|
||||
static int lastlength = 0;
|
||||
static int bufpos = 0;
|
||||
static qboolean cr_pending = false;
|
||||
static qboolean colorstring = false;
|
||||
static char buf[MAX_PRINT_MSG];
|
||||
static int lastlength = 0;
|
||||
static int bufpos = 0;
|
||||
static int charpos = 0;
|
||||
|
||||
qboolean norefresh = false;
|
||||
int c, mask = 0;
|
||||
|
||||
// client not running
|
||||
@@ -873,7 +876,7 @@ void Con_Print( const char *txt )
|
||||
if( cr_pending )
|
||||
{
|
||||
Con_DeleteLastLine();
|
||||
cr_pending = 0;
|
||||
cr_pending = false;
|
||||
}
|
||||
c = *txt;
|
||||
|
||||
@@ -886,23 +889,42 @@ void Con_Print( const char *txt )
|
||||
{
|
||||
Con_AddLine( buf, bufpos, true );
|
||||
lastlength = CON_LINES_LAST().length;
|
||||
cr_pending = 1;
|
||||
cr_pending = true;
|
||||
bufpos = 0;
|
||||
charpos = 0;
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
Con_AddLine( buf, bufpos, true );
|
||||
lastlength = CON_LINES_LAST().length;
|
||||
bufpos = 0;
|
||||
charpos = 0;
|
||||
break;
|
||||
default:
|
||||
|
||||
buf[bufpos++] = c | mask;
|
||||
if(( bufpos >= sizeof( buf ) - 1 ) || bufpos >= ( con.linewidth - 1 ))
|
||||
|
||||
if( IsColorString( txt ))
|
||||
{
|
||||
// first color string character
|
||||
colorstring = true;
|
||||
}
|
||||
else if( colorstring )
|
||||
{
|
||||
// second color string character
|
||||
colorstring = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// not a color string, move char counter
|
||||
charpos++;
|
||||
}
|
||||
|
||||
if(( bufpos >= sizeof( buf ) - 1 ) || charpos >= ( con.linewidth - 1 ))
|
||||
{
|
||||
Con_AddLine( buf, bufpos, true );
|
||||
lastlength = CON_LINES_LAST().length;
|
||||
bufpos = 0;
|
||||
charpos = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -918,6 +940,7 @@ void Con_Print( const char *txt )
|
||||
Con_AddLine( buf, bufpos, lastlength != 0 );
|
||||
lastlength = 0;
|
||||
bufpos = 0;
|
||||
charpos = 0;
|
||||
}
|
||||
|
||||
// pump messages to avoid window hanging
|
||||
@@ -1244,45 +1267,16 @@ static void Field_CharEvent( field_t *edit, int ch )
|
||||
Field_DrawInputLine
|
||||
==================
|
||||
*/
|
||||
static void Field_DrawInputLine( int x, int y, field_t *edit )
|
||||
static void Field_DrawInputLine( int x, int y, const field_t *edit )
|
||||
{
|
||||
int len, cursorChar;
|
||||
int drawLen;
|
||||
int prestep, curPos;
|
||||
char str[MAX_SYSPATH];
|
||||
byte *colorDefault;
|
||||
int curPos;
|
||||
char str[MAX_SYSPATH];
|
||||
const byte *colorDefault = g_color_table[ColorIndex( COLOR_DEFAULT )];
|
||||
const int prestep = bound( 0, edit->scroll, sizeof( edit->buffer ) - 1 );
|
||||
const int drawLen = bound( 0, edit->widthInChars, sizeof( str ));
|
||||
const int cursorCharPos = bound( 0, edit->cursor - prestep, sizeof( str ));
|
||||
|
||||
drawLen = edit->widthInChars;
|
||||
len = Q_strlen( edit->buffer ) + 1;
|
||||
colorDefault = g_color_table[ColorIndex( COLOR_DEFAULT )];
|
||||
|
||||
// guarantee that cursor will be visible
|
||||
if( len <= drawLen )
|
||||
{
|
||||
prestep = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( edit->scroll + drawLen > len )
|
||||
{
|
||||
edit->scroll = len - drawLen;
|
||||
if( edit->scroll < 0 ) edit->scroll = 0;
|
||||
}
|
||||
|
||||
prestep = edit->scroll;
|
||||
}
|
||||
|
||||
if( prestep + drawLen > len )
|
||||
drawLen = len - prestep;
|
||||
|
||||
// extract <drawLen> characters from the field at <prestep>
|
||||
drawLen = Q_min( drawLen, MAX_SYSPATH - 1 );
|
||||
|
||||
memcpy( str, edit->buffer + prestep, drawLen );
|
||||
str[drawLen] = 0;
|
||||
|
||||
// save char for overstrike
|
||||
cursorChar = str[edit->cursor - prestep];
|
||||
Q_strncpy( str, edit->buffer + prestep, drawLen );
|
||||
|
||||
// draw it
|
||||
CL_DrawString( x, y, str, colorDefault, con.curFont, FONT_DRAW_UTF8 );
|
||||
@@ -1291,7 +1285,7 @@ static void Field_DrawInputLine( int x, int y, field_t *edit )
|
||||
if((int)( host.realtime * 4 ) & 1 ) return; // off blink
|
||||
|
||||
// calc cursor position
|
||||
str[edit->cursor - prestep] = 0;
|
||||
str[cursorCharPos] = 0;
|
||||
CL_DrawStringLen( con.curFont, str, &curPos, NULL, FONT_DRAW_UTF8 );
|
||||
|
||||
if( host.key_overstrike )
|
||||
@@ -1467,6 +1461,16 @@ Handles history and console scrollback
|
||||
*/
|
||||
void Key_Console( int key )
|
||||
{
|
||||
// exit the console by pressing MINUS on NSwitch
|
||||
// or both Back(Select)/Start buttons for everyone else
|
||||
if( key == K_BACK_BUTTON || key == K_START_BUTTON || key == K_ESCAPE )
|
||||
{
|
||||
if( cls.state == ca_active && !cl.background )
|
||||
Key_SetKeyDest( key_game );
|
||||
else UI_SetActiveMenu( true );
|
||||
return;
|
||||
}
|
||||
|
||||
// ctrl-L clears screen
|
||||
if( key == 'l' && Key_IsDown( K_CTRL ))
|
||||
{
|
||||
@@ -1575,16 +1579,6 @@ void Key_Console( int key )
|
||||
return;
|
||||
}
|
||||
|
||||
// exit the console by pressing MINUS on NSwitch
|
||||
// or both Back(Select)/Start buttons for everyone else
|
||||
if( key == K_BACK_BUTTON || key == K_START_BUTTON )
|
||||
{
|
||||
if( cls.state == ca_active && !cl.background )
|
||||
Key_SetKeyDest( key_game );
|
||||
else UI_SetActiveMenu( true );
|
||||
return;
|
||||
}
|
||||
|
||||
// pass to the normal editline routine
|
||||
Field_KeyDownEvent( &con.input, key );
|
||||
}
|
||||
@@ -2008,7 +2002,7 @@ void Con_DrawVersion( void )
|
||||
int start, height = refState.height;
|
||||
string curbuild;
|
||||
|
||||
if( !scr_drawversion.value || CL_IsDevOverviewMode() == 2 || net_graph.value )
|
||||
if( !scr_drawversion.value )
|
||||
return;
|
||||
|
||||
if( cls.key_dest == key_menu )
|
||||
@@ -2020,6 +2014,9 @@ void Con_DrawVersion( void )
|
||||
{
|
||||
qboolean draw_version;
|
||||
|
||||
if( CL_IsDevOverviewMode() == 2 || net_graph.value )
|
||||
return;
|
||||
|
||||
draw_version = cls.scrshot_action == scrshot_normal
|
||||
|| cls.scrshot_action == scrshot_snapshot
|
||||
|| host.force_draw_version_time > host.realtime;
|
||||
@@ -2092,10 +2089,7 @@ void Con_RunConsole( void )
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf( S_WARN "Unknown charset %s, defaulting to cp1252", con_charset.string );
|
||||
|
||||
Cvar_DirectSet( &con_charset, "cp1252" );
|
||||
g_codepage = 1252;
|
||||
g_codepage = 0;
|
||||
}
|
||||
|
||||
cls.accept_utf8 = !Q_stricmp( cl_charset.string, "utf-8" );
|
||||
@@ -2138,20 +2132,31 @@ void Con_CharEvent( int key )
|
||||
|
||||
static int Con_LoadSimpleConback( const char *name, int flags )
|
||||
{
|
||||
const char *paths[] = {
|
||||
"gfx/shell/%s.dds",
|
||||
"gfx/shell/%s.bmp",
|
||||
"gfx/shell/%s.tga",
|
||||
"cached/%s640",
|
||||
"cached/%s",
|
||||
};
|
||||
size_t i;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( paths ); i++ )
|
||||
for( i = 0; i < 5; i++ )
|
||||
{
|
||||
string path;
|
||||
|
||||
Q_snprintf( path, sizeof( path ), paths[i], name );
|
||||
switch( i )
|
||||
{
|
||||
case 0:
|
||||
Q_snprintf( path, sizeof( path ), "gfx/shell/%s.dds", name );
|
||||
break;
|
||||
case 1:
|
||||
Q_snprintf( path, sizeof( path ), "gfx/shell/%s.bmp", name );
|
||||
break;
|
||||
case 2:
|
||||
Q_snprintf( path, sizeof( path ), "gfx/shell/%s.tga", name );
|
||||
break;
|
||||
case 3:
|
||||
Q_snprintf( path, sizeof( path ), "cached/%s640", name );
|
||||
break;
|
||||
case 4:
|
||||
Q_snprintf( path, sizeof( path ), "cached/%s", name );
|
||||
break;
|
||||
}
|
||||
|
||||
if( g_fsapi.FileExists( path, false ))
|
||||
{
|
||||
int gl_texturenum = ref.dllFuncs.GL_LoadTexture( path, NULL, 0, flags );
|
||||
|
||||
@@ -19,8 +19,8 @@ GNU General Public License for more details.
|
||||
#if !XASH_WIN32
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
static char id_md5[33];
|
||||
static char id_customid[MAX_STRING];
|
||||
|
||||
/*
|
||||
==========================================================
|
||||
@@ -365,10 +365,10 @@ static int ID_GetKeyData( HKEY hRootKey, char *subKey, char *value, LPBYTE data,
|
||||
{
|
||||
HKEY hKey;
|
||||
|
||||
if( RegOpenKeyEx( hRootKey, subKey, 0, KEY_QUERY_VALUE, &hKey ) != ERROR_SUCCESS )
|
||||
if( RegOpenKeyExA( hRootKey, subKey, 0, KEY_QUERY_VALUE, &hKey ) != ERROR_SUCCESS )
|
||||
return 0;
|
||||
|
||||
if( RegQueryValueEx( hKey, value, NULL, NULL, data, &cbData ) != ERROR_SUCCESS )
|
||||
if( RegQueryValueExA( hKey, value, NULL, NULL, data, &cbData ) != ERROR_SUCCESS )
|
||||
{
|
||||
RegCloseKey( hKey );
|
||||
return 0;
|
||||
@@ -377,13 +377,14 @@ static int ID_GetKeyData( HKEY hRootKey, char *subKey, char *value, LPBYTE data,
|
||||
RegCloseKey( hKey );
|
||||
return 1;
|
||||
}
|
||||
static int ID_SetKeyData( HKEY hRootKey, char *subKey, DWORD dwType, char *value, LPBYTE data, DWORD cbData)
|
||||
|
||||
static int ID_SetKeyData( HKEY hRootKey, char *subKey, DWORD dwType, char *value, LPBYTE data, DWORD cbData )
|
||||
{
|
||||
HKEY hKey;
|
||||
if( RegCreateKey( hRootKey, subKey, &hKey ) != ERROR_SUCCESS )
|
||||
if( RegCreateKeyA( hRootKey, subKey, &hKey ) != ERROR_SUCCESS )
|
||||
return 0;
|
||||
|
||||
if( RegSetValueEx( hKey, value, 0, dwType, data, cbData ) != ERROR_SUCCESS )
|
||||
if( RegSetValueExA( hKey, value, 0, dwType, data, cbData ) != ERROR_SUCCESS )
|
||||
{
|
||||
RegCloseKey( hKey );
|
||||
return 0;
|
||||
@@ -395,7 +396,7 @@ static int ID_SetKeyData( HKEY hRootKey, char *subKey, DWORD dwType, char *value
|
||||
|
||||
#define BUFSIZE 4096
|
||||
|
||||
static int ID_RunWMIC(char *buffer, const char *cmdline)
|
||||
static int ID_RunWMIC( char *buffer, const wchar_t *cmdline )
|
||||
{
|
||||
HANDLE g_IN_Rd = NULL;
|
||||
HANDLE g_IN_Wr = NULL;
|
||||
@@ -403,75 +404,92 @@ static int ID_RunWMIC(char *buffer, const char *cmdline)
|
||||
HANDLE g_OUT_Wr = NULL;
|
||||
DWORD dwRead;
|
||||
BOOL bSuccess = FALSE;
|
||||
SECURITY_ATTRIBUTES saAttr;
|
||||
wchar_t *cmdline_copy;
|
||||
|
||||
STARTUPINFO si = {0};
|
||||
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
saAttr.bInheritHandle = TRUE;
|
||||
saAttr.lpSecurityDescriptor = NULL;
|
||||
PROCESS_INFORMATION pi = { 0 };
|
||||
SECURITY_ATTRIBUTES saAttr =
|
||||
{
|
||||
.nLength = sizeof( SECURITY_ATTRIBUTES ),
|
||||
.bInheritHandle = TRUE,
|
||||
.lpSecurityDescriptor = NULL,
|
||||
};
|
||||
|
||||
CreatePipe( &g_IN_Rd, &g_IN_Wr, &saAttr, 0 );
|
||||
CreatePipe( &g_OUT_Rd, &g_OUT_Wr, &saAttr, 0 );
|
||||
SetHandleInformation( g_IN_Wr, HANDLE_FLAG_INHERIT, 0 );
|
||||
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
si.dwFlags = STARTF_USESTDHANDLES;
|
||||
si.hStdInput = g_IN_Rd;
|
||||
si.hStdOutput = g_OUT_Wr;
|
||||
si.hStdError = g_OUT_Wr;
|
||||
si.wShowWindow = SW_HIDE;
|
||||
si.dwFlags |= STARTF_USESTDHANDLES;
|
||||
STARTUPINFO si =
|
||||
{
|
||||
.cb = sizeof( STARTUPINFO ),
|
||||
.dwFlags = STARTF_USESTDHANDLES,
|
||||
.hStdInput = g_IN_Rd,
|
||||
.hStdOutput = g_OUT_Wr,
|
||||
.hStdError = g_OUT_Wr,
|
||||
.wShowWindow = SW_HIDE,
|
||||
.dwFlags = STARTF_USESTDHANDLES,
|
||||
};
|
||||
|
||||
CreateProcess( NULL, (char*)cmdline, NULL, NULL, true, CREATE_NO_WINDOW , NULL, NULL, &si, &pi );
|
||||
cmdline_copy = malloc( wcslen( cmdline ) * sizeof( *cmdline_copy ));
|
||||
|
||||
CloseHandle( g_OUT_Wr );
|
||||
CloseHandle( g_IN_Wr );
|
||||
if( !CreateProcessW( NULL, cmdline_copy, NULL, NULL, true, CREATE_NO_WINDOW, NULL, NULL, &si, &pi ))
|
||||
goto err;
|
||||
|
||||
WaitForSingleObject( pi.hProcess, 500 );
|
||||
|
||||
bSuccess = ReadFile( g_OUT_Rd, buffer, BUFSIZE, &dwRead, NULL );
|
||||
buffer[BUFSIZE-1] = 0;
|
||||
|
||||
TerminateProcess( pi.hProcess, 0 );
|
||||
|
||||
CloseHandle( pi.hProcess );
|
||||
CloseHandle( pi.hThread );
|
||||
|
||||
err:
|
||||
CloseHandle( g_IN_Wr );
|
||||
CloseHandle( g_OUT_Wr );
|
||||
CloseHandle( g_IN_Rd );
|
||||
CloseHandle( g_OUT_Rd );
|
||||
|
||||
free( cmdline_copy );
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
static int ID_ProcessWMIC( bloomfilter_t *value, const char *cmdline )
|
||||
static int ID_ProcessWMIC( bloomfilter_t *value, const wchar_t *cmdline )
|
||||
{
|
||||
char buffer[BUFSIZE], token[BUFSIZE], *pbuf;
|
||||
int count = 0;
|
||||
|
||||
if( !ID_RunWMIC( buffer, cmdline ) )
|
||||
if( !ID_RunWMIC( buffer, cmdline ))
|
||||
return 0;
|
||||
|
||||
pbuf = COM_ParseFile( buffer, token, sizeof( token )); // Header
|
||||
while( pbuf = COM_ParseFile( pbuf, token, sizeof( token ) ) )
|
||||
while( pbuf = COM_ParseFile( pbuf, token, sizeof( token )))
|
||||
{
|
||||
if( !ID_VerifyHEX( token ) )
|
||||
if( !ID_VerifyHEX( token ))
|
||||
continue;
|
||||
|
||||
*value |= BloomFilter_ProcessStr( token );
|
||||
count ++;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int ID_CheckWMIC( bloomfilter_t value, const char *cmdline )
|
||||
static int ID_CheckWMIC( bloomfilter_t value, const wchar_t *cmdline )
|
||||
{
|
||||
char buffer[BUFSIZE], token[BUFSIZE], *pbuf;
|
||||
int count = 0;
|
||||
|
||||
if( !ID_RunWMIC( buffer, cmdline ) )
|
||||
if( !ID_RunWMIC( buffer, cmdline ))
|
||||
return 0;
|
||||
|
||||
pbuf = COM_ParseFile( buffer, token, sizeof( token )); // Header
|
||||
while( pbuf = COM_ParseFile( pbuf, token, sizeof( token ) ) )
|
||||
while( pbuf = COM_ParseFile( pbuf, token, sizeof( token )))
|
||||
{
|
||||
bloomfilter_t filter;
|
||||
|
||||
if( !ID_VerifyHEX( token ) )
|
||||
if( !ID_VerifyHEX( token ))
|
||||
continue;
|
||||
|
||||
filter = BloomFilter_ProcessStr( token );
|
||||
@@ -487,6 +505,10 @@ static int ID_CheckWMIC( bloomfilter_t value, const char *cmdline )
|
||||
char *IOS_GetUDID( void );
|
||||
#endif
|
||||
|
||||
#if XASH_PSVITA
|
||||
int PSVita_GetPSID( char *buf, const size_t buflen );
|
||||
#endif
|
||||
|
||||
static bloomfilter_t ID_GenerateRawId( void )
|
||||
{
|
||||
bloomfilter_t value = 0;
|
||||
@@ -508,14 +530,22 @@ static bloomfilter_t ID_GenerateRawId( void )
|
||||
count += ID_ProcessNetDevices( &value );
|
||||
#endif
|
||||
#if XASH_WIN32
|
||||
count += ID_ProcessWMIC( &value, "wmic path win32_physicalmedia get SerialNumber " );
|
||||
count += ID_ProcessWMIC( &value, "wmic bios get serialnumber " );
|
||||
count += ID_ProcessWMIC( &value, L"wmic path win32_physicalmedia get SerialNumber " );
|
||||
count += ID_ProcessWMIC( &value, L"wmic bios get serialnumber " );
|
||||
#endif
|
||||
#if XASH_IOS
|
||||
{
|
||||
value |= BloomFilter_ProcessStr(IOS_GetUDID());
|
||||
count ++;
|
||||
}
|
||||
#endif
|
||||
#if XASH_PSVITA
|
||||
{
|
||||
char data[16];
|
||||
PSVita_GetPSID( data, sizeof( data ));
|
||||
value |= BloomFilter_Process( data, sizeof( data ));
|
||||
count ++;
|
||||
}
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
@@ -544,8 +574,8 @@ static uint ID_CheckRawId( bloomfilter_t filter )
|
||||
#endif
|
||||
|
||||
#if XASH_WIN32
|
||||
count += ID_CheckWMIC( filter, "wmic path win32_physicalmedia get SerialNumber" );
|
||||
count += ID_CheckWMIC( filter, "wmic bios get serialnumber" );
|
||||
count += ID_CheckWMIC( filter, L"wmic path win32_physicalmedia get SerialNumber" );
|
||||
count += ID_CheckWMIC( filter, L"wmic bios get serialnumber" );
|
||||
#endif
|
||||
|
||||
#if XASH_IOS
|
||||
@@ -555,6 +585,15 @@ static uint ID_CheckRawId( bloomfilter_t filter )
|
||||
value = 0;
|
||||
}
|
||||
#endif
|
||||
#if XASH_PSVITA
|
||||
{
|
||||
char data[16];
|
||||
PSVita_GetPSID( data, sizeof( data ));
|
||||
value = BloomFilter_Process( data, sizeof( data ));
|
||||
count += (filter & value) == value;
|
||||
value = 0;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
Msg( "%s: %d\n", __func__, count );
|
||||
#endif
|
||||
@@ -590,28 +629,12 @@ static void ID_Check( void )
|
||||
|
||||
const char *ID_GetMD5( void )
|
||||
{
|
||||
if( id_customid[0] )
|
||||
return id_customid;
|
||||
return id_md5;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
ID_SetCustomClientID
|
||||
|
||||
===============
|
||||
*/
|
||||
void GAME_EXPORT ID_SetCustomClientID( const char *id )
|
||||
{
|
||||
if( !id )
|
||||
return;
|
||||
|
||||
Q_strncpy( id_customid, id, sizeof( id_customid ) );
|
||||
}
|
||||
|
||||
void ID_Init( void )
|
||||
{
|
||||
MD5Context_t hash = {0};
|
||||
MD5Context_t hash = { 0 };
|
||||
byte md5[16];
|
||||
int i;
|
||||
|
||||
@@ -632,7 +655,7 @@ void ID_Init( void )
|
||||
#elif XASH_WIN32
|
||||
{
|
||||
CHAR szBuf[MAX_PATH];
|
||||
ID_GetKeyData( HKEY_CURRENT_USER, "Software\\Xash3D\\", "xash_id", szBuf, MAX_PATH );
|
||||
ID_GetKeyData( HKEY_CURRENT_USER, "Software\\"XASH_ENGINE_NAME"\\", "xash_id", szBuf, MAX_PATH );
|
||||
|
||||
sscanf(szBuf, "%016"PRIX64, &id);
|
||||
id ^= SYSTEM_XOR_MASK;
|
||||
@@ -686,7 +709,7 @@ void ID_Init( void )
|
||||
{
|
||||
CHAR Buf[MAX_PATH];
|
||||
sprintf( Buf, "%016"PRIX64, id^SYSTEM_XOR_MASK );
|
||||
ID_SetKeyData( HKEY_CURRENT_USER, "Software\\Xash3D\\", REG_SZ, "xash_id", Buf, Q_strlen(Buf) );
|
||||
ID_SetKeyData( HKEY_CURRENT_USER, "Software\\"XASH_ENGINE_NAME"\\", REG_SZ, "xash_id", Buf, Q_strlen(Buf) );
|
||||
}
|
||||
#else
|
||||
{
|
||||
@@ -43,7 +43,6 @@ static struct joy_axis_s
|
||||
short val;
|
||||
short prevval;
|
||||
} joyaxis[MAX_AXES] = { 0 };
|
||||
static byte currentbinding; // add posibility to remap keys, to place it in joykeys[]
|
||||
static qboolean joy_initialized;
|
||||
|
||||
static CVAR_DEFINE_AUTO( joy_pitch, "100.0", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "joystick pitch sensitivity" );
|
||||
@@ -60,9 +59,9 @@ static CVAR_DEFINE_AUTO( joy_pitch_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE
|
||||
static CVAR_DEFINE_AUTO( joy_yaw_deadzone, DEFAULT_JOY_DEADZONE, FCVAR_ARCHIVE | FCVAR_FILTERABLE, "yaw axis deadzone. Value from 0 to 32767" );
|
||||
static CVAR_DEFINE_AUTO( joy_axis_binding, "sfpyrl", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "axis hardware id to engine inner axis binding, "
|
||||
"s - side, f - forward, y - yaw, p - pitch, r - left trigger, l - right trigger" );
|
||||
static CVAR_DEFINE_AUTO( joy_found, "0", FCVAR_READ_ONLY, "is joystick is connected" );
|
||||
static CVAR_DEFINE_AUTO( joy_index, "0", FCVAR_READ_ONLY, "current active joystick" );
|
||||
CVAR_DEFINE_AUTO( joy_enable, "1", FCVAR_ARCHIVE | FCVAR_FILTERABLE, "enable joystick" );
|
||||
static CVAR_DEFINE_AUTO( joy_have_gyro, "0", FCVAR_READ_ONLY, "tells whether current active gamepad has gyroscope or not" );
|
||||
static CVAR_DEFINE_AUTO( joy_calibrated, "0", FCVAR_READ_ONLY, "tells whether current active gamepad gyroscope has been calibrated or not" );
|
||||
|
||||
/*
|
||||
============
|
||||
@@ -71,7 +70,30 @@ Joy_IsActive
|
||||
*/
|
||||
qboolean Joy_IsActive( void )
|
||||
{
|
||||
return joy_found.value && joy_enable.value;
|
||||
return joy_enable.value;
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
Joy_SetCapabilities
|
||||
===========
|
||||
*/
|
||||
void Joy_SetCapabilities( qboolean have_gyro )
|
||||
{
|
||||
Cvar_FullSet( joy_have_gyro.name, have_gyro ? "1" : "0", joy_have_gyro.flags );
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
Joy_SetCalibrationState
|
||||
===========
|
||||
*/
|
||||
void Joy_SetCalibrationState( joy_calibration_state_t state )
|
||||
{
|
||||
if( (int)joy_calibrated.value == state )
|
||||
return;
|
||||
|
||||
Cvar_FullSet( joy_calibrated.name, va( "%d", state ), joy_calibrated.flags );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -81,7 +103,7 @@ Joy_HatMotionEvent
|
||||
DPad events
|
||||
============
|
||||
*/
|
||||
void Joy_HatMotionEvent( byte hat, byte value )
|
||||
static void Joy_HatMotionEvent( int value )
|
||||
{
|
||||
struct
|
||||
{
|
||||
@@ -96,9 +118,6 @@ void Joy_HatMotionEvent( byte hat, byte value )
|
||||
};
|
||||
int i;
|
||||
|
||||
if( !joy_found.value )
|
||||
return;
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( keys ); i++ )
|
||||
{
|
||||
if( value & keys[i].mask )
|
||||
@@ -225,7 +244,7 @@ static void Joy_ProcessStick( const engineAxis_t engineAxis, short value )
|
||||
val |= Joy_GetHatValueForAxis( JOY_AXIS_SIDE );
|
||||
val |= Joy_GetHatValueForAxis( JOY_AXIS_FWD );
|
||||
|
||||
Joy_HatMotionEvent( 0, val );
|
||||
Joy_HatMotionEvent( val );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,23 +255,9 @@ Joy_AxisMotionEvent
|
||||
Axis events
|
||||
=============
|
||||
*/
|
||||
void Joy_AxisMotionEvent( byte axis, short value )
|
||||
void Joy_AxisMotionEvent( engineAxis_t engineAxis, short value )
|
||||
{
|
||||
if( !joy_found.value )
|
||||
return;
|
||||
|
||||
if( axis >= MAX_AXES )
|
||||
{
|
||||
Con_Reportf( "Only 6 axes is supported\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
Joy_KnownAxisMotionEvent( joyaxesmap[axis], value );
|
||||
}
|
||||
|
||||
void Joy_KnownAxisMotionEvent( engineAxis_t engineAxis, short value )
|
||||
{
|
||||
if( engineAxis == JOY_AXIS_NULL )
|
||||
if( engineAxis >= JOY_AXIS_NULL )
|
||||
return;
|
||||
|
||||
if( value == joyaxis[engineAxis].val )
|
||||
@@ -266,66 +271,14 @@ void Joy_KnownAxisMotionEvent( engineAxis_t engineAxis, short value )
|
||||
|
||||
/*
|
||||
=============
|
||||
Joy_BallMotionEvent
|
||||
Joy_GyroEvent
|
||||
|
||||
Trackball events. UNDONE
|
||||
Gyroscope events
|
||||
=============
|
||||
*/
|
||||
void Joy_BallMotionEvent( byte ball, short xrel, short yrel )
|
||||
void Joy_GyroEvent( vec3_t data )
|
||||
{
|
||||
//if( !joy_found.value )
|
||||
// return;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Joy_ButtonEvent
|
||||
|
||||
Button events
|
||||
=============
|
||||
*/
|
||||
void Joy_ButtonEvent( byte button, byte down )
|
||||
{
|
||||
if( !joy_found.value )
|
||||
return;
|
||||
|
||||
// generic game button code.
|
||||
if( button > 32 )
|
||||
{
|
||||
int origbutton = button;
|
||||
button = ( button & 31 ) + K_AUX1;
|
||||
|
||||
Con_Reportf( "Only 32 joybuttons is supported, converting %i button ID to %s\n", origbutton, Key_KeynumToString( button ) );
|
||||
}
|
||||
else button += K_AUX1;
|
||||
|
||||
Key_Event( button, down );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Joy_RemoveEvent
|
||||
|
||||
Called when joystick is removed. For future expansion
|
||||
=============
|
||||
*/
|
||||
void Joy_RemoveEvent( void )
|
||||
{
|
||||
if( joy_found.value )
|
||||
Cvar_FullSet( "joy_found", "0", FCVAR_READ_ONLY );
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Joy_RemoveEvent
|
||||
|
||||
Called when joystick is removed. For future expansion
|
||||
=============
|
||||
*/
|
||||
void Joy_AddEvent( void )
|
||||
{
|
||||
if( joy_enable.value && !joy_found.value )
|
||||
Cvar_FullSet( "joy_found", "1", FCVAR_READ_ONLY );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -364,14 +317,19 @@ void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw )
|
||||
|
||||
*fw -= joy_forward.value * (float)joyaxis[JOY_AXIS_FWD ].val/(float)SHRT_MAX; // must be form -1.0 to 1.0
|
||||
*side += joy_side.value * (float)joyaxis[JOY_AXIS_SIDE].val/(float)SHRT_MAX;
|
||||
#if !defined(XASH_SDL)
|
||||
*dpitch += joy_pitch.value * (float)joyaxis[JOY_AXIS_PITCH].val/(float)SHRT_MAX * host.realframetime; // abs axis rotate is frametime related
|
||||
*dyaw -= joy_yaw.value * (float)joyaxis[JOY_AXIS_YAW ].val/(float)SHRT_MAX * host.realframetime;
|
||||
#else
|
||||
// HACKHACK: SDL have inverted look axis.
|
||||
*dpitch -= joy_pitch.value * (float)joyaxis[JOY_AXIS_PITCH].val/(float)SHRT_MAX * host.realframetime;
|
||||
*dyaw += joy_yaw.value * (float)joyaxis[JOY_AXIS_YAW ].val/(float)SHRT_MAX * host.realframetime;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void Joy_CalibrateGyro_f( void )
|
||||
{
|
||||
if( !joy_have_gyro.value )
|
||||
{
|
||||
Con_Printf( "Current active gamepad doesn't have gyroscope\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
Platform_CalibrateGamepadGyro();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -383,6 +341,8 @@ Main init procedure
|
||||
*/
|
||||
void Joy_Init( void )
|
||||
{
|
||||
Cmd_AddRestrictedCommand( "joy_calibrate_gyro", Joy_CalibrateGyro_f, "calibrate gamepad gyroscope. You must to put gamepad on stationary surface" );
|
||||
|
||||
Cvar_RegisterVariable( &joy_pitch );
|
||||
Cvar_RegisterVariable( &joy_yaw );
|
||||
Cvar_RegisterVariable( &joy_side );
|
||||
@@ -402,11 +362,9 @@ void Joy_Init( void )
|
||||
Cvar_RegisterVariable( &joy_yaw_deadzone );
|
||||
|
||||
Cvar_RegisterVariable( &joy_axis_binding );
|
||||
Cvar_RegisterVariable( &joy_found );
|
||||
// we doesn't loaded config.cfg yet, so this cvar is not archive.
|
||||
// change by +set joy_index in cmdline
|
||||
Cvar_RegisterVariable( &joy_index );
|
||||
|
||||
Cvar_RegisterVariable( &joy_have_gyro );
|
||||
Cvar_RegisterVariable( &joy_calibrated );
|
||||
Cvar_RegisterVariable( &joy_enable );
|
||||
|
||||
// renamed from -nojoy to -noenginejoy to not conflict with
|
||||
@@ -417,7 +375,7 @@ void Joy_Init( void )
|
||||
return;
|
||||
}
|
||||
|
||||
Cvar_FullSet( "joy_found", va( "%d", Platform_JoyInit( joy_index.value )), FCVAR_READ_ONLY );
|
||||
Platform_JoyInit();
|
||||
|
||||
joy_initialized = true;
|
||||
}
|
||||
@@ -431,8 +389,5 @@ Shutdown joystick code
|
||||
*/
|
||||
void Joy_Shutdown( void )
|
||||
{
|
||||
if( joy_initialized )
|
||||
{
|
||||
Cvar_FullSet( "joy_found", 0, FCVAR_READ_ONLY );
|
||||
}
|
||||
Platform_JoyShutdown();
|
||||
}
|
||||
|
||||
@@ -13,16 +13,17 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#if XASH_SDL == 2
|
||||
#include <SDL.h>
|
||||
#elif XASH_SDL == 3
|
||||
#include <SDL3/SDL.h>
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
#include "input.h"
|
||||
#include "client.h"
|
||||
#include "vgui_draw.h"
|
||||
#include "cursor_type.h"
|
||||
|
||||
#if XASH_SDL
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
void* in_mousecursor;
|
||||
@@ -205,50 +206,58 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
|
||||
}
|
||||
}
|
||||
|
||||
static void IN_SetRelativeMouseMode( qboolean set, qboolean verbose )
|
||||
void IN_SetRelativeMouseMode( qboolean set )
|
||||
{
|
||||
static qboolean s_bRawInput;
|
||||
qboolean verbose = m_grab_debug.value ? true : false;
|
||||
|
||||
if( set && !s_bRawInput )
|
||||
{
|
||||
#if XASH_SDL == 2
|
||||
#if XASH_SDL >= 2
|
||||
SDL_GetRelativeMouseState( NULL, NULL );
|
||||
#if XASH_SDL == 2
|
||||
SDL_SetRelativeMouseMode( SDL_TRUE );
|
||||
#endif
|
||||
#else // XASH_SDL != 2
|
||||
SDL_SetWindowRelativeMouseMode( host.hWnd, true );
|
||||
#endif // XASH_SDL != 2
|
||||
#endif // XASH_SDL >= 2
|
||||
s_bRawInput = true;
|
||||
if( verbose )
|
||||
Con_Printf( "%s: true\n", __func__ );
|
||||
}
|
||||
else if( !set && s_bRawInput )
|
||||
{
|
||||
#if XASH_SDL == 2
|
||||
#if XASH_SDL >= 2
|
||||
SDL_GetRelativeMouseState( NULL, NULL );
|
||||
#if XASH_SDL == 2
|
||||
SDL_SetRelativeMouseMode( SDL_FALSE );
|
||||
#endif
|
||||
#else // XASH_SDL != 2
|
||||
SDL_SetWindowRelativeMouseMode( host.hWnd, false );
|
||||
#endif // XASH_SDL != 2
|
||||
#endif // XASH_SDL >= 2
|
||||
|
||||
s_bRawInput = false;
|
||||
if( verbose )
|
||||
Con_Printf( "%s: false\n", __func__ );
|
||||
}
|
||||
}
|
||||
|
||||
static void IN_SetMouseGrab( qboolean set, qboolean verbose )
|
||||
void IN_SetMouseGrab( qboolean set )
|
||||
{
|
||||
static qboolean s_bMouseGrab;
|
||||
qboolean verbose = m_grab_debug.value ? true : false;
|
||||
|
||||
if( set && !s_bMouseGrab )
|
||||
{
|
||||
#if XASH_SDL
|
||||
SDL_SetWindowGrab( host.hWnd, SDL_TRUE );
|
||||
#endif
|
||||
Platform_SetMouseGrab( true );
|
||||
|
||||
s_bMouseGrab = true;
|
||||
if( verbose )
|
||||
Con_Printf( "%s: true\n", __func__ );
|
||||
}
|
||||
else if( !set && s_bMouseGrab )
|
||||
{
|
||||
#if XASH_SDL
|
||||
SDL_SetWindowGrab( host.hWnd, SDL_FALSE );
|
||||
#endif
|
||||
Platform_SetMouseGrab( false );
|
||||
|
||||
s_bMouseGrab = false;
|
||||
if( verbose )
|
||||
@@ -258,7 +267,7 @@ static void IN_SetMouseGrab( qboolean set, qboolean verbose )
|
||||
|
||||
static void IN_CheckMouseState( qboolean active )
|
||||
{
|
||||
qboolean use_raw_input, verbose;
|
||||
qboolean use_raw_input;
|
||||
|
||||
#if XASH_WIN32
|
||||
use_raw_input = ( m_rawinput.value && clgame.client_dll_uses_sdl ) || clgame.dllFuncs.pfnLookEvent != NULL;
|
||||
@@ -266,20 +275,18 @@ static void IN_CheckMouseState( qboolean active )
|
||||
use_raw_input = true; // always use SDL code
|
||||
#endif
|
||||
|
||||
verbose = m_grab_debug.value ? true : false;
|
||||
|
||||
if( m_ignore.value )
|
||||
active = false;
|
||||
|
||||
if( active && use_raw_input && !host.mouse_visible && cls.state == ca_active )
|
||||
IN_SetRelativeMouseMode( true, verbose );
|
||||
IN_SetRelativeMouseMode( true );
|
||||
else
|
||||
IN_SetRelativeMouseMode( false, verbose );
|
||||
IN_SetRelativeMouseMode( false );
|
||||
|
||||
if( active && !host.mouse_visible && cls.state == ca_active )
|
||||
IN_SetMouseGrab( true, verbose );
|
||||
IN_SetMouseGrab( true );
|
||||
else
|
||||
IN_SetMouseGrab( false, verbose );
|
||||
IN_SetMouseGrab( false );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -332,7 +339,7 @@ static void IN_MouseMove( void )
|
||||
if( !in_mouseinitialized )
|
||||
return;
|
||||
|
||||
if( Touch_Emulated( ))
|
||||
if( Touch_WantVisibleCursor( ))
|
||||
{
|
||||
// touch emulation overrides all input
|
||||
Touch_KeyEvent( 0, 0 );
|
||||
@@ -363,7 +370,7 @@ void IN_MouseEvent( int key, int down )
|
||||
else ClearBits( in_mstate, BIT( key ));
|
||||
|
||||
// touch emulation overrides all input
|
||||
if( Touch_Emulated( ))
|
||||
if( Touch_WantVisibleCursor( ))
|
||||
{
|
||||
Touch_KeyEvent( K_MOUSE1 + key, down );
|
||||
}
|
||||
@@ -633,8 +640,6 @@ Called every frame, even if not generating commands
|
||||
*/
|
||||
void Host_InputFrame( void )
|
||||
{
|
||||
Platform_SendKeyEvents();
|
||||
|
||||
IN_Commands();
|
||||
|
||||
IN_MouseMove();
|
||||
|
||||
@@ -46,6 +46,9 @@ uint IN_CollectInputDevices( void );
|
||||
void IN_LockInputDevices( qboolean lock );
|
||||
void IN_EngineAppendMove( float frametime, usercmd_t *cmd, qboolean active );
|
||||
|
||||
void IN_SetRelativeMouseMode( qboolean set );
|
||||
void IN_SetMouseGrab( qboolean set );
|
||||
|
||||
extern convar_t m_yaw;
|
||||
extern convar_t m_pitch;
|
||||
//
|
||||
@@ -74,7 +77,6 @@ void Touch_ResetDefaultButtons( void );
|
||||
int IN_TouchEvent( touchEventType type, int fingerID, float x, float y, float dx, float dy );
|
||||
void Touch_KeyEvent( int key, int down );
|
||||
qboolean Touch_WantVisibleCursor( void );
|
||||
qboolean Touch_Emulated( void );
|
||||
void Touch_NotifyResize( void );
|
||||
|
||||
//
|
||||
@@ -104,18 +106,21 @@ typedef enum engineAxis_e
|
||||
JOY_AXIS_NULL
|
||||
} engineAxis_t;
|
||||
|
||||
typedef enum joy_calibration_state_s
|
||||
{
|
||||
JOY_NOT_CALIBRATED = 0,
|
||||
JOY_CALIBRATING,
|
||||
JOY_FAILED_TO_CALIBRATE,
|
||||
JOY_CALIBRATED
|
||||
} joy_calibration_state_t;
|
||||
|
||||
qboolean Joy_IsActive( void );
|
||||
void Joy_HatMotionEvent( byte hat, byte value );
|
||||
void Joy_AxisMotionEvent( byte axis, short value );
|
||||
void Joy_KnownAxisMotionEvent( engineAxis_t engineAxis, short value );
|
||||
void Joy_BallMotionEvent( byte ball, short xrel, short yrel );
|
||||
void Joy_ButtonEvent( byte button, byte down );
|
||||
void Joy_AddEvent( void );
|
||||
void Joy_RemoveEvent( void );
|
||||
void Joy_SetCapabilities( qboolean have_gyro );
|
||||
void Joy_SetCalibrationState( joy_calibration_state_t state );
|
||||
void Joy_AxisMotionEvent( engineAxis_t engineAxis, short value );
|
||||
void Joy_GyroEvent( vec3_t data );
|
||||
void Joy_FinalizeMove( float *fw, float *side, float *dpitch, float *dyaw );
|
||||
void Joy_Init( void );
|
||||
void Joy_Shutdown( void );
|
||||
void Joy_EnableTextInput(qboolean enable, qboolean force);
|
||||
|
||||
|
||||
#endif//INPUT_H
|
||||
|
||||
@@ -40,7 +40,7 @@ static const keyname_t keynames[] =
|
||||
{
|
||||
{"TAB", K_TAB, "" },
|
||||
{"ENTER", K_ENTER, "" },
|
||||
{"ESCAPE", K_ESCAPE, "escape" }, // hardcoded
|
||||
{"ESCAPE", K_ESCAPE, "cancelselect" }, // hardcoded
|
||||
{"SPACE", K_SPACE, "+jump" },
|
||||
{"BACKSPACE", K_BACKSPACE, "" },
|
||||
{"UPARROW", K_UPARROW, "+forward" },
|
||||
@@ -51,7 +51,7 @@ static const keyname_t keynames[] =
|
||||
{"CTRL", K_CTRL, "+attack" },
|
||||
{"SHIFT", K_SHIFT, "+speed" },
|
||||
{"CAPSLOCK", K_CAPSLOCK, "" },
|
||||
{"SCROLLOCK", K_SCROLLOCK, "" },
|
||||
{"SCROLLOCK", K_SCROLLLOCK, "" },
|
||||
{"F1", K_F1, "cmd help" },
|
||||
{"F2", K_F2, "menu_savegame" },
|
||||
{"F3", K_F3, "menu_loadgame" },
|
||||
@@ -106,7 +106,7 @@ static const keyname_t keynames[] =
|
||||
{"Y_BUTTON", K_Y_BUTTON, "impulse 100"}, // Flashlight
|
||||
{"BACK", K_BACK_BUTTON, "pause"}, // Menu
|
||||
{"MODE", K_MODE_BUTTON, ""},
|
||||
{"START", K_START_BUTTON, "escape"},
|
||||
{"START", K_START_BUTTON, "cancelselect"},
|
||||
{"STICK1", K_LSTICK, "+speed"},
|
||||
{"STICK2", K_RSTICK, "+duck"},
|
||||
{"L1_BUTTON", K_L1_BUTTON, "+duck"},
|
||||
@@ -215,7 +215,7 @@ const char *Key_KeynumToString( int keynum )
|
||||
return "<OUT OF RANGE>";
|
||||
|
||||
// check for printable ascii (don't use quote)
|
||||
if( keynum > 32 && keynum < 127 && keynum != '"' && keynum != ';' && keynum != K_SCROLLOCK )
|
||||
if( keynum > 32 && keynum < 127 && keynum != '"' && keynum != ';' && keynum != K_SCROLLLOCK )
|
||||
{
|
||||
tinystr[0] = keynum;
|
||||
tinystr[1] = 0;
|
||||
@@ -339,6 +339,12 @@ static void Key_Unbind_f( void )
|
||||
return;
|
||||
}
|
||||
|
||||
if( b == K_ESCAPE )
|
||||
{
|
||||
Con_Printf( "Can't unbind ESCAPE key\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
Key_SetBinding( b, "" );
|
||||
}
|
||||
|
||||
@@ -358,8 +364,8 @@ static void Key_Unbindall_f( void )
|
||||
}
|
||||
|
||||
// set some defaults
|
||||
Key_SetBinding( K_ESCAPE, "escape" );
|
||||
Key_SetBinding( K_START_BUTTON, "escape" );
|
||||
Key_SetBinding( K_ESCAPE, "cancelselect" );
|
||||
Key_SetBinding( K_START_BUTTON, "cancelselect" );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -720,35 +726,31 @@ void GAME_EXPORT Key_Event( int key, int down )
|
||||
return; // handled in client.dll
|
||||
}
|
||||
break;
|
||||
case key_message:
|
||||
Key_Message( key );
|
||||
return;
|
||||
case key_console:
|
||||
if( cls.state == ca_active && !cl.background )
|
||||
Key_SetKeyDest( key_game );
|
||||
else UI_SetActiveMenu( true );
|
||||
return;
|
||||
case key_menu:
|
||||
UI_KeyEvent( key, true );
|
||||
return;
|
||||
default: return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( cls.key_dest == key_menu )
|
||||
{
|
||||
// only non printable keys passed
|
||||
// classic Xash3D menus don't have an extension that tells engine
|
||||
// to enable text input
|
||||
if( !gameui.use_extended_api )
|
||||
Key_EnableTextInput( true, false );
|
||||
//pass printable chars for old menus
|
||||
if( !gameui.use_extended_api && !host.textmode && down && ( key >= 32 ) && ( key <= 'z' ) )
|
||||
{
|
||||
if( Key_IsDown( K_SHIFT ) )
|
||||
// we don't know if menu wants text input or not
|
||||
// enable it unconditionally
|
||||
Key_EnableTextInput( true, false );
|
||||
|
||||
// pass this key to the menu, if printable
|
||||
if( !host.textmode && down && ( key >= 32 ) && ( key <= 'z' ))
|
||||
{
|
||||
key += 'A' - 'a';
|
||||
if( Key_IsDown( K_SHIFT ))
|
||||
key += 'A' - 'a';
|
||||
|
||||
UI_CharEvent( key );
|
||||
}
|
||||
UI_CharEvent( key );
|
||||
}
|
||||
|
||||
UI_KeyEvent( key, down );
|
||||
return;
|
||||
}
|
||||
@@ -844,11 +846,14 @@ void GAME_EXPORT Key_ClearStates( void )
|
||||
int i;
|
||||
|
||||
// don't clear keys during changelevel
|
||||
if( cls.changelevel ) return;
|
||||
if( cls.changelevel )
|
||||
return;
|
||||
|
||||
for( i = 0; i < 256; i++ )
|
||||
{
|
||||
if( keys[i].down )
|
||||
if( i >= K_MOUSE1 && i <= K_MOUSE5 )
|
||||
IN_MouseEvent( i - K_MOUSE1, false );
|
||||
else
|
||||
Key_Event( i, false );
|
||||
|
||||
keys[i].down = 0;
|
||||
@@ -1092,7 +1097,7 @@ static qboolean OSK_KeyEvent( int key, int down )
|
||||
|
||||
/*
|
||||
=============
|
||||
Joy_EnableTextInput
|
||||
OSK_EnableTextInput
|
||||
|
||||
Enables built-in IME
|
||||
=============
|
||||
|
||||
@@ -470,16 +470,16 @@ out_free:
|
||||
* This is a stack of the clipnodes we have traversed
|
||||
* "sides" indicates which side we went down each time
|
||||
*/
|
||||
static mclipnode_t *node_stack[MAX_CLIPNODE_DEPTH];
|
||||
static int node_stack[MAX_CLIPNODE_DEPTH];
|
||||
static int side_stack[MAX_CLIPNODE_DEPTH];
|
||||
static uint node_stack_depth;
|
||||
|
||||
static void push_node( mclipnode_t *node, int side )
|
||||
static void push_node( int nodenum, int side )
|
||||
{
|
||||
if( node_stack_depth == MAX_CLIPNODE_DEPTH )
|
||||
Host_Error( "node stack overflow\n" );
|
||||
|
||||
node_stack[node_stack_depth] = node;
|
||||
node_stack[node_stack_depth] = nodenum;
|
||||
side_stack[node_stack_depth] = side;
|
||||
node_stack_depth++;
|
||||
}
|
||||
@@ -502,22 +502,27 @@ static void free_hull_polys( hullnode_t *hull_polys )
|
||||
}
|
||||
}
|
||||
|
||||
static void hull_windings_r( hull_t *hull, mclipnode_t *node, hullnode_t *polys, hull_model_t *model );
|
||||
static void hull_windings_r( hull_t *hull, int nodenum, hullnode_t *polys, hull_model_t *model );
|
||||
|
||||
static void do_hull_recursion( hull_t *hull, mclipnode_t *node, int side, hullnode_t *polys, hull_model_t *model )
|
||||
static void do_hull_recursion( hull_t *hull, int nodenum, int side, hullnode_t *polys, hull_model_t *model )
|
||||
{
|
||||
winding_t *w, *next;
|
||||
int childnum;
|
||||
|
||||
if( node->children[side] >= 0 )
|
||||
if( world.version == QBSP2_VERSION )
|
||||
childnum = hull->clipnodes32[nodenum].children[side];
|
||||
else
|
||||
childnum = hull->clipnodes16[nodenum].children[side];
|
||||
|
||||
if( childnum >= 0 )
|
||||
{
|
||||
mclipnode_t *child = hull->clipnodes + node->children[side];
|
||||
push_node( node, side );
|
||||
hull_windings_r( hull, child, polys, model );
|
||||
push_node( nodenum, side );
|
||||
hull_windings_r( hull, childnum, polys, model );
|
||||
pop_node();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( node->children[side] )
|
||||
switch( childnum )
|
||||
{
|
||||
case CONTENTS_EMPTY:
|
||||
case CONTENTS_WATER:
|
||||
@@ -542,20 +547,25 @@ static void do_hull_recursion( hull_t *hull, mclipnode_t *node, int side, hullno
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Host_Error( "bad contents: %i\n", node->children[side] );
|
||||
Host_Error( "bad contents: %i\n", childnum );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void hull_windings_r( hull_t *hull, mclipnode_t *node, hullnode_t *polys, hull_model_t *model )
|
||||
static void hull_windings_r( hull_t *hull, int nodenum, hullnode_t *polys, hull_model_t *model )
|
||||
{
|
||||
mplane_t *plane = hull->planes + node->planenum;
|
||||
mplane_t *plane;
|
||||
hullnode_t frontlist = LIST_HEAD_INIT( frontlist );
|
||||
hullnode_t backlist = LIST_HEAD_INIT( backlist );
|
||||
winding_t *w, *next, *front, *back;
|
||||
int i;
|
||||
|
||||
if( world.version == QBSP2_VERSION )
|
||||
plane = hull->planes + hull->clipnodes32[nodenum].planenum;
|
||||
else
|
||||
plane = hull->planes + hull->clipnodes16[nodenum].planenum;
|
||||
|
||||
list_for_each_entry_safe( w, next, polys, chain )
|
||||
{
|
||||
// PARANIOA - PAIR CHECK
|
||||
@@ -601,7 +611,13 @@ static void hull_windings_r( hull_t *hull, mclipnode_t *node, hullnode_t *polys,
|
||||
|
||||
for( i = 0; w && i < node_stack_depth; i++ )
|
||||
{
|
||||
mplane_t *p = hull->planes + node_stack[i]->planenum;
|
||||
mplane_t *p;
|
||||
|
||||
if( world.version == QBSP2_VERSION )
|
||||
p = hull->planes + hull->clipnodes32[node_stack[i]].planenum;
|
||||
else
|
||||
p = hull->planes + hull->clipnodes16[node_stack[i]].planenum;
|
||||
|
||||
w = winding_clip( w, p, false, side_stack[i], 0.00001 );
|
||||
}
|
||||
|
||||
@@ -625,8 +641,8 @@ static void hull_windings_r( hull_t *hull, mclipnode_t *node, hullnode_t *polys,
|
||||
Con_Printf( S_WARN "new winding was clipped away!\n" );
|
||||
}
|
||||
|
||||
do_hull_recursion( hull, node, 0, &frontlist, model );
|
||||
do_hull_recursion( hull, node, 1, &backlist, model );
|
||||
do_hull_recursion( hull, nodenum, 0, &frontlist, model );
|
||||
do_hull_recursion( hull, nodenum, 1, &backlist, model );
|
||||
}
|
||||
|
||||
static void remove_paired_polys( hull_model_t *model )
|
||||
@@ -655,7 +671,7 @@ static void make_hull_windings( hull_t *hull, hull_model_t *model )
|
||||
|
||||
if( hull->planes != NULL )
|
||||
{
|
||||
hull_windings_r( hull, hull->clipnodes + hull->firstclipnode, &head, model );
|
||||
hull_windings_r( hull, hull->firstclipnode, &head, model );
|
||||
remove_paired_polys( model );
|
||||
}
|
||||
Con_Reportf( "%i hull polys\n", model->num_polys );
|
||||
|
||||
@@ -300,6 +300,12 @@ static qboolean R_Init_Video_( const int type )
|
||||
return R_Init_Video( type );
|
||||
}
|
||||
|
||||
static mleaf_t *pfnMod_PointInLeaf( const vec3_t p, mnode_t *node )
|
||||
{
|
||||
// FIXME: get rid of this on next RefAPI update
|
||||
return Mod_PointInLeaf( p, node, cl.models[1] );
|
||||
}
|
||||
|
||||
static const ref_api_t gEngfuncs =
|
||||
{
|
||||
pfnEngineGetParm,
|
||||
@@ -340,7 +346,7 @@ static const ref_api_t gEngfuncs =
|
||||
|
||||
Mod_SampleSizeForFace,
|
||||
Mod_BoxVisible,
|
||||
Mod_PointInLeaf,
|
||||
pfnMod_PointInLeaf,
|
||||
R_DrawWorldHull,
|
||||
R_DrawModelHull,
|
||||
|
||||
@@ -427,6 +433,8 @@ static const ref_api_t gEngfuncs =
|
||||
&clgame.drawFuncs,
|
||||
|
||||
&g_fsapi,
|
||||
|
||||
R_GetWindowHandle,
|
||||
};
|
||||
|
||||
static void R_UnloadProgs( void )
|
||||
@@ -566,7 +574,7 @@ static void R_GetRendererName( char *dest, size_t size, const char *opt )
|
||||
}
|
||||
}
|
||||
|
||||
static qboolean R_LoadRenderer( const char *refopt )
|
||||
static qboolean R_LoadRenderer( const char *refopt, qboolean quiet )
|
||||
{
|
||||
string refdll;
|
||||
|
||||
@@ -577,7 +585,8 @@ static qboolean R_LoadRenderer( const char *refopt )
|
||||
if( !R_LoadProgs( refdll ))
|
||||
{
|
||||
R_Shutdown();
|
||||
Sys_Warn( S_ERROR "Can't initialize %s renderer!\n", refdll );
|
||||
if( !quiet )
|
||||
Sys_Warn( S_ERROR "Can't initialize %s renderer!\n", refdll );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -616,7 +625,7 @@ static void SetFullscreenModeFromCommandLine( void )
|
||||
static void R_CollectRendererNames( void )
|
||||
{
|
||||
// ordering is important!
|
||||
static const char *shortNames[] =
|
||||
static const char *short_names[] =
|
||||
{
|
||||
#if XASH_REF_GL_ENABLED
|
||||
"gl",
|
||||
@@ -639,7 +648,7 @@ static void R_CollectRendererNames( void )
|
||||
};
|
||||
|
||||
// ordering is important here too!
|
||||
static const char *readableNames[ARRAYSIZE( shortNames )] =
|
||||
static const char *long_names[ARRAYSIZE( short_names )] =
|
||||
{
|
||||
#if XASH_REF_GL_ENABLED
|
||||
"OpenGL",
|
||||
@@ -661,9 +670,9 @@ static void R_CollectRendererNames( void )
|
||||
#endif
|
||||
};
|
||||
|
||||
ref.numRenderers = ARRAYSIZE( shortNames );
|
||||
ref.shortNames = shortNames;
|
||||
ref.readableNames = readableNames;
|
||||
ref.num_renderers = ARRAYSIZE( short_names );
|
||||
ref.short_names = short_names;
|
||||
ref.long_names = long_names;
|
||||
}
|
||||
|
||||
qboolean R_Init( void )
|
||||
@@ -724,28 +733,44 @@ qboolean R_Init( void )
|
||||
requested_cvar[0] = 0;
|
||||
|
||||
if( Sys_GetParmFromCmdLine( "-ref", requested_cmdline ))
|
||||
success = R_LoadRenderer( requested_cmdline );
|
||||
success = R_LoadRenderer( requested_cmdline, false );
|
||||
|
||||
if( !success && COM_CheckString( r_refdll.string ) && Q_stricmp( requested_cmdline, r_refdll.string ))
|
||||
{
|
||||
Q_strncpy( requested_cvar, r_refdll.string, sizeof( requested_cvar ));
|
||||
success = R_LoadRenderer( requested_cvar );
|
||||
|
||||
// do not show scary messages to user if renderer set in config cannot be loaded
|
||||
// as game data could be copied from one platform to another, where this renderer
|
||||
// might not be supported (ref_gl on Android for example)
|
||||
success = R_LoadRenderer( requested_cvar, !host_developer.value );
|
||||
}
|
||||
|
||||
if( !success )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < ref.numRenderers && !success; i++ )
|
||||
for( i = 0; i < ref.num_renderers; i++ )
|
||||
{
|
||||
// skip renderer that was requested but failed to load
|
||||
if( !Q_strcmp( requested_cmdline, ref.shortNames[i] ))
|
||||
if( !Q_strcmp( requested_cmdline, ref.short_names[i] ))
|
||||
continue;
|
||||
|
||||
if( !Q_strcmp( requested_cvar, ref.shortNames[i] ))
|
||||
if( !Q_strcmp( requested_cvar, ref.short_names[i] ))
|
||||
continue;
|
||||
|
||||
success = R_LoadRenderer( ref.shortNames[i] );
|
||||
// do not show bruteforcing attempts, however, warn user about falling back
|
||||
// to software mode
|
||||
if( !Q_strcmp( "soft", ref.short_names[i] ) && !host_developer.value )
|
||||
Sys_Warn( "Can't initialize any hardware accelerated renderer. Falling back to software rendering...\n" );
|
||||
|
||||
success = R_LoadRenderer( ref.short_names[i], !host_developer.value );
|
||||
|
||||
if( success )
|
||||
{
|
||||
// remember last valid renderer
|
||||
Cvar_DirectSet( &r_refdll, ref.short_names[i] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,12 +24,12 @@ struct ref_state_s
|
||||
{
|
||||
HINSTANCE hInstance;
|
||||
qboolean initialized;
|
||||
int numRenderers;
|
||||
int num_renderers;
|
||||
ref_interface_t dllFuncs;
|
||||
|
||||
// depends on build configuration
|
||||
const char **shortNames;
|
||||
const char **readableNames;
|
||||
const char **short_names;
|
||||
const char **long_names;
|
||||
};
|
||||
|
||||
extern struct ref_state_s ref;
|
||||
|
||||
@@ -312,7 +312,7 @@ static int DLY_Init( int idelay, float delay )
|
||||
|
||||
cur = &rgsxdly[idelay];
|
||||
cur->cdelaysamplesmax = ((int)(delay * idsp_dma_speed) << sxhires) + 1;
|
||||
cur->lpdelayline = (int *)Z_Calloc( cur->cdelaysamplesmax * sizeof( int ));
|
||||
cur->lpdelayline = (int *)Mem_Calloc( sndpool, cur->cdelaysamplesmax * sizeof( int ));
|
||||
cur->xfade = 0;
|
||||
|
||||
// init modulation
|
||||
|
||||
@@ -107,17 +107,18 @@ S_CreateDefaultSound
|
||||
*/
|
||||
static wavdata_t *S_CreateDefaultSound( void )
|
||||
{
|
||||
wavdata_t *sc;
|
||||
wavdata_t *sc;
|
||||
uint samples = SOUND_DMA_SPEED;
|
||||
uint channels = 1;
|
||||
uint width = 2;
|
||||
size_t size = samples * width * channels;
|
||||
|
||||
sc = Mem_Calloc( sndpool, sizeof( wavdata_t ));
|
||||
|
||||
sc->width = 2;
|
||||
sc->channels = 1;
|
||||
sc->loopStart = 0;
|
||||
sc = Mem_Calloc( sndpool, sizeof( wavdata_t ) + size );
|
||||
sc->width = width;
|
||||
sc->channels = channels;
|
||||
sc->rate = SOUND_DMA_SPEED;
|
||||
sc->samples = SOUND_DMA_SPEED;
|
||||
sc->size = sc->samples * sc->width * sc->channels;
|
||||
sc->buffer = Mem_Calloc( sndpool, sc->size );
|
||||
sc->samples = samples;
|
||||
sc->size = size;
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
@@ -996,7 +996,7 @@ static void S_UpdateAmbientSounds( void )
|
||||
// calc ambient sound levels
|
||||
if( !cl.worldmodel ) return;
|
||||
|
||||
leaf = Mod_PointInLeaf( s_listener.origin, cl.worldmodel->nodes );
|
||||
leaf = Mod_PointInLeaf( s_listener.origin, cl.worldmodel->nodes, cl.worldmodel );
|
||||
|
||||
if( !leaf || !s_ambient_level.value )
|
||||
{
|
||||
@@ -1207,86 +1207,6 @@ void S_RawSamples( uint samples, uint rate, word width, word channels, const byt
|
||||
S_RawEntSamples( entnum, samples, rate, width, channels, data, snd_vol );
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
S_PositionedRawSamples
|
||||
===================
|
||||
*/
|
||||
void S_StreamAviSamples( void *Avi, int entnum, float fvol, float attn, float synctime )
|
||||
{
|
||||
int bufferSamples;
|
||||
int fileSamples;
|
||||
byte raw[MAX_RAW_SAMPLES];
|
||||
float duration = 0.0f;
|
||||
int r, fileBytes;
|
||||
rawchan_t *ch = NULL;
|
||||
|
||||
if( !dma.initialized || s_listener.paused || !CL_IsInGame( ))
|
||||
return;
|
||||
|
||||
if( entnum < 0 || entnum >= GI->max_edicts )
|
||||
return;
|
||||
|
||||
if( !( ch = S_FindRawChannel( entnum, true )))
|
||||
return;
|
||||
|
||||
if( ch->sound_info.rate == 0 )
|
||||
{
|
||||
if( !AVI_GetAudioInfo( Avi, &ch->sound_info ))
|
||||
return; // no audiotrack
|
||||
}
|
||||
|
||||
ch->master_vol = bound( 0, fvol * 255, 255 );
|
||||
ch->dist_mult = (attn / SND_CLIP_DISTANCE);
|
||||
|
||||
// see how many samples should be copied into the raw buffer
|
||||
if( ch->s_rawend < soundtime )
|
||||
ch->s_rawend = soundtime;
|
||||
|
||||
// position is changed, synchronization is lost etc
|
||||
if( fabs( ch->oldtime - synctime ) > s_mixahead.value )
|
||||
ch->sound_info.loopStart = AVI_TimeToSoundPosition( Avi, synctime * 1000 );
|
||||
ch->oldtime = synctime; // keep actual time
|
||||
|
||||
while( ch->s_rawend < soundtime + ch->max_samples )
|
||||
{
|
||||
wavdata_t *info = &ch->sound_info;
|
||||
|
||||
bufferSamples = ch->max_samples - (ch->s_rawend - soundtime);
|
||||
|
||||
// decide how much data needs to be read from the file
|
||||
fileSamples = bufferSamples * ((float)info->rate / SOUND_DMA_SPEED );
|
||||
if( fileSamples <= 1 ) return; // no more samples need
|
||||
|
||||
// our max buffer size
|
||||
fileBytes = fileSamples * ( info->width * info->channels );
|
||||
|
||||
if( fileBytes > sizeof( raw ))
|
||||
{
|
||||
fileBytes = sizeof( raw );
|
||||
fileSamples = fileBytes / ( info->width * info->channels );
|
||||
}
|
||||
|
||||
// read audio stream
|
||||
r = AVI_GetAudioChunk( Avi, raw, info->loopStart, fileBytes );
|
||||
info->loopStart += r; // advance play position
|
||||
|
||||
if( r < fileBytes )
|
||||
{
|
||||
fileBytes = r;
|
||||
fileSamples = r / ( info->width * info->channels );
|
||||
}
|
||||
|
||||
if( r > 0 )
|
||||
{
|
||||
// add to raw buffer
|
||||
ch->s_rawend = S_RawSamplesStereo( ch->rawsamples, ch->s_rawend, ch->max_samples,
|
||||
fileSamples, info->rate, info->width, info->channels, raw );
|
||||
}
|
||||
else break; // no more samples for this frame
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
S_FreeIdleRawChannels
|
||||
@@ -1954,14 +1874,15 @@ qboolean S_Init( void )
|
||||
Cmd_AddCommand( "spk", S_SayReliable_f, "reliable play a specified sententce" );
|
||||
Cmd_AddCommand( "speak", S_Say_f, "playing a specified sententce" );
|
||||
|
||||
sndpool = Mem_AllocPool( "Sound Zone" );
|
||||
dma.backendName = "None";
|
||||
if( !SNDDMA_Init( ) )
|
||||
if( !SNDDMA_Init( ))
|
||||
{
|
||||
Con_Printf( "Audio: sound system can't be initialized\n" );
|
||||
Mem_FreePool( &sndpool );
|
||||
return false;
|
||||
}
|
||||
|
||||
sndpool = Mem_AllocPool( "Sound Zone" );
|
||||
soundtime = 0;
|
||||
paintedtime = 0;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ GNU General Public License for more details.
|
||||
#include "common.h"
|
||||
#include "sound.h"
|
||||
#include "client.h"
|
||||
#include "soundlib.h"
|
||||
|
||||
static bg_track_t s_bgTrack;
|
||||
static musicfade_t musicfade; // controlled by game dlls
|
||||
@@ -212,7 +213,7 @@ void S_StreamBackgroundTrack( void )
|
||||
|
||||
while( ch->s_rawend < soundtime + ch->max_samples )
|
||||
{
|
||||
wavdata_t *info = FS_StreamInfo( s_bgTrack.stream );
|
||||
const stream_t *info = s_bgTrack.stream;
|
||||
|
||||
bufferSamples = ch->max_samples - (ch->s_rawend - soundtime);
|
||||
|
||||
|
||||
@@ -557,7 +557,7 @@ static void VOX_ReadSentenceFile_( byte *buf, fs_offset_t size )
|
||||
int index = cszrawsentences;
|
||||
int size = strlen( name ) + strlen( value ) + 2;
|
||||
|
||||
rgpszrawsentence[index] = Mem_Malloc( host.mempool, size );
|
||||
rgpszrawsentence[index] = Mem_Malloc( sndpool, size );
|
||||
memcpy( rgpszrawsentence[index], name, size );
|
||||
rgpszrawsentence[index][size - 1] = 0;
|
||||
cszrawsentences++;
|
||||
|
||||
@@ -114,7 +114,6 @@ typedef struct rawchan_s
|
||||
vec3_t origin; // only use if fixed_origin is set
|
||||
volatile uint s_rawend;
|
||||
float oldtime; // catch time jumps
|
||||
wavdata_t sound_info; // advance play position
|
||||
size_t max_samples; // buffer length
|
||||
portable_samplepair_t rawsamples[]; // variable sized
|
||||
} rawchan_t;
|
||||
@@ -171,6 +170,8 @@ typedef struct
|
||||
int source; // may be game, menu, etc
|
||||
} bg_track_t;
|
||||
|
||||
typedef int sound_t;
|
||||
|
||||
//====================================================================
|
||||
|
||||
#define MAX_DYNAMIC_CHANNELS (60 + NUM_AMBIENTS)
|
||||
|
||||
@@ -29,17 +29,20 @@ static void Sound_Reset( void )
|
||||
|
||||
static MALLOC_LIKE( FS_FreeSound, 1 ) wavdata_t *SoundPack( void )
|
||||
{
|
||||
wavdata_t *pack = Mem_Calloc( host.soundpool, sizeof( wavdata_t ));
|
||||
wavdata_t *pack = Mem_Malloc( host.soundpool, sizeof( *pack ) + sound.size );
|
||||
|
||||
pack->buffer = sound.wav;
|
||||
pack->width = sound.width;
|
||||
pack->rate = sound.rate;
|
||||
pack->type = sound.type;
|
||||
pack->size = sound.size;
|
||||
pack->loopStart = sound.loopstart;
|
||||
pack->samples = sound.samples;
|
||||
pack->channels = sound.channels;
|
||||
pack->type = sound.type;
|
||||
pack->flags = sound.flags;
|
||||
pack->rate = sound.rate;
|
||||
pack->width = sound.width;
|
||||
pack->channels = sound.channels;
|
||||
memcpy( pack->buffer, sound.wav, sound.size );
|
||||
|
||||
Mem_Free( sound.wav );
|
||||
sound.wav = NULL;
|
||||
|
||||
return pack;
|
||||
}
|
||||
@@ -53,12 +56,10 @@ loading and unpack to wav any known sound
|
||||
*/
|
||||
wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size )
|
||||
{
|
||||
const char *ext = COM_FileExtension( filename );
|
||||
string path, loadname;
|
||||
qboolean anyformat = true;
|
||||
fs_offset_t filesize = 0;
|
||||
const loadwavfmt_t *format;
|
||||
byte *f;
|
||||
const char *ext = COM_FileExtension( filename );
|
||||
string loadname;
|
||||
qboolean anyformat = true;
|
||||
const loadwavfmt_t *format;
|
||||
|
||||
Sound_Reset(); // clear old sounddata
|
||||
Q_strncpy( loadname, filename, sizeof( loadname ));
|
||||
@@ -67,7 +68,7 @@ wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size )
|
||||
{
|
||||
// we needs to compare file extension with list of supported formats
|
||||
// and be sure what is real extension, not a filename with dot
|
||||
for( format = sound.loadformats; format && format->formatstring; format++ )
|
||||
for( format = sound.loadformats; format && format->ext; format++ )
|
||||
{
|
||||
if( !Q_stricmp( format->ext, ext ))
|
||||
{
|
||||
@@ -83,28 +84,42 @@ wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size )
|
||||
goto load_internal;
|
||||
|
||||
// now try all the formats in the selected list
|
||||
for( format = sound.loadformats; format && format->formatstring; format++)
|
||||
for( format = sound.loadformats; format && format->ext; format++)
|
||||
{
|
||||
if( anyformat || !Q_stricmp( ext, format->ext ))
|
||||
{
|
||||
Q_snprintf( path, sizeof( path ),
|
||||
format->formatstring, loadname, "", format->ext );
|
||||
qboolean success = false;
|
||||
fs_offset_t filesize = 0;
|
||||
byte *f;
|
||||
string path;
|
||||
|
||||
Q_snprintf( path, sizeof( path ), DEFAULT_SOUNDPATH "%s.%s", loadname, format->ext );
|
||||
|
||||
f = FS_LoadFile( path, &filesize, false );
|
||||
if( f && filesize > 0 )
|
||||
{
|
||||
if( format->loadfunc( path, f, filesize ))
|
||||
{
|
||||
Mem_Free(f); // release buffer
|
||||
return SoundPack(); // loaded
|
||||
}
|
||||
else Mem_Free(f); // release buffer
|
||||
success = format->loadfunc( path, f, filesize );
|
||||
Mem_Free( f ); // release buffer
|
||||
}
|
||||
|
||||
if( success )
|
||||
return SoundPack(); // loaded
|
||||
|
||||
Q_snprintf( path, sizeof( path ), "%s.%s", loadname, format->ext );
|
||||
f = FS_LoadFile( path, &filesize, false );
|
||||
if( f && filesize > 0 )
|
||||
{
|
||||
success = format->loadfunc( path, f, filesize );
|
||||
Mem_Free( f ); // release buffer
|
||||
}
|
||||
|
||||
if( success )
|
||||
return SoundPack();
|
||||
}
|
||||
}
|
||||
|
||||
load_internal:
|
||||
for( format = sound.loadformats; format && format->formatstring; format++ )
|
||||
for( format = sound.loadformats; format && format->ext; format++ )
|
||||
{
|
||||
if( anyformat || !Q_stricmp( ext, format->ext ))
|
||||
{
|
||||
@@ -132,7 +147,6 @@ free WAV buffer
|
||||
void FS_FreeSound( wavdata_t *pack )
|
||||
{
|
||||
if( !pack ) return;
|
||||
if( pack->buffer ) Mem_Free( pack->buffer );
|
||||
Mem_Free( pack );
|
||||
}
|
||||
|
||||
@@ -146,7 +160,7 @@ open and reading basic info from sound stream
|
||||
stream_t *FS_OpenStream( const char *filename )
|
||||
{
|
||||
const char *ext = COM_FileExtension( filename );
|
||||
string path, loadname;
|
||||
string loadname;
|
||||
qboolean anyformat = true;
|
||||
const streamfmt_t *format;
|
||||
stream_t *stream = NULL;
|
||||
@@ -158,7 +172,7 @@ stream_t *FS_OpenStream( const char *filename )
|
||||
{
|
||||
// we needs to compare file extension with list of supported formats
|
||||
// and be sure what is real extension, not a filename with dot
|
||||
for( format = sound.streamformat; format && format->formatstring; format++ )
|
||||
for( format = sound.streamformat; format && format->ext; format++ )
|
||||
{
|
||||
if( !Q_stricmp( format->ext, ext ))
|
||||
{
|
||||
@@ -170,12 +184,13 @@ stream_t *FS_OpenStream( const char *filename )
|
||||
}
|
||||
|
||||
// now try all the formats in the selected list
|
||||
for( format = sound.streamformat; format && format->formatstring; format++)
|
||||
for( format = sound.streamformat; format && format->ext; format++)
|
||||
{
|
||||
if( anyformat || !Q_stricmp( ext, format->ext ))
|
||||
{
|
||||
Q_snprintf( path, sizeof( path ),
|
||||
format->formatstring, loadname, "", format->ext );
|
||||
string path;
|
||||
|
||||
Q_snprintf( path, sizeof( path ), "%s.%s", loadname, format->ext );
|
||||
|
||||
if(( stream = format->openfunc( path )) != NULL )
|
||||
{
|
||||
@@ -199,33 +214,6 @@ stream_t *FS_OpenStream( const char *filename )
|
||||
return stream;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
FS_StreamInfo
|
||||
|
||||
get basic stream info
|
||||
================
|
||||
*/
|
||||
wavdata_t *FS_StreamInfo( stream_t *stream )
|
||||
{
|
||||
static wavdata_t info;
|
||||
|
||||
if( !stream ) return NULL;
|
||||
|
||||
// fill structure
|
||||
info.loopStart = 0;
|
||||
info.rate = stream->rate;
|
||||
info.width = stream->width;
|
||||
info.channels = stream->channels;
|
||||
info.flags = SOUND_STREAM;
|
||||
info.size = stream->size;
|
||||
info.buffer = NULL;
|
||||
info.samples = 0; // not actual for streams
|
||||
info.type = stream->type;
|
||||
|
||||
return &info;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
FS_ReadStream
|
||||
|
||||
@@ -25,20 +25,29 @@ GNU General Public License for more details.
|
||||
|
||||
#define VGUI_MAX_TEXTURES 1024
|
||||
|
||||
typedef struct vgui_reusable_texture_s
|
||||
{
|
||||
int gl_texturenum;
|
||||
byte hash[16];
|
||||
} vgui_reusable_texture_t;
|
||||
|
||||
typedef struct vgui_static_s
|
||||
{
|
||||
qboolean initialized;
|
||||
VGUI_DefaultCursor cursor;
|
||||
vguiapi_t dllFuncs;
|
||||
|
||||
int textures[VGUI_MAX_TEXTURES];
|
||||
vgui_reusable_texture_t *textures;
|
||||
int texture_id;
|
||||
int max_textures;
|
||||
int bound_texture;
|
||||
byte color[4];
|
||||
qboolean enable_texture;
|
||||
|
||||
HINSTANCE hInstance;
|
||||
|
||||
poolhandle_t mempool;
|
||||
|
||||
enum VGUI_KeyCode virtualKeyTrans[256];
|
||||
} vgui_static_t;
|
||||
|
||||
@@ -49,9 +58,16 @@ static CVAR_DEFINE_AUTO( vgui_utf8, "0", FCVAR_ARCHIVE, "enable utf-8 support fo
|
||||
|
||||
static void GAME_EXPORT VGUI_DrawInit( void )
|
||||
{
|
||||
memset( vgui.textures, 0, sizeof( vgui.textures ));
|
||||
if( vgui.mempool )
|
||||
Mem_EmptyPool( vgui.mempool );
|
||||
else vgui.mempool = Mem_AllocPool( "VGui Support Pool" );
|
||||
|
||||
vgui.textures = NULL;
|
||||
|
||||
memset( vgui.color, 0, sizeof( vgui.color ));
|
||||
vgui.texture_id = vgui.bound_texture = 0;
|
||||
vgui.texture_id = 0;
|
||||
vgui.bound_texture = 0;
|
||||
vgui.max_textures = 0;
|
||||
vgui.enable_texture = true;
|
||||
}
|
||||
|
||||
@@ -60,28 +76,79 @@ static void GAME_EXPORT VGUI_DrawShutdown( void )
|
||||
int i;
|
||||
|
||||
for( i = 1; i < vgui.texture_id; i++ )
|
||||
ref.dllFuncs.GL_FreeTexture( vgui.textures[i] );
|
||||
ref.dllFuncs.GL_FreeTexture( vgui.textures[i].gl_texturenum );
|
||||
|
||||
Mem_FreePool( &vgui.mempool );
|
||||
vgui.textures = NULL;
|
||||
|
||||
memset( vgui.color, 0, sizeof( vgui.color ));
|
||||
vgui.texture_id = 0;
|
||||
vgui.bound_texture = 0;
|
||||
vgui.max_textures = 0;
|
||||
}
|
||||
|
||||
static int GAME_EXPORT VGUI_GenerateTexture( void )
|
||||
{
|
||||
if( ++vgui.texture_id >= VGUI_MAX_TEXTURES )
|
||||
Host_Error( "%s: VGUI_MAX_TEXTURES limit exceeded\n", __func__ );
|
||||
// allocate new
|
||||
if( vgui.texture_id + 1 >= vgui.max_textures )
|
||||
{
|
||||
if( vgui.max_textures + VGUI_MAX_TEXTURES >= VGUI_MAX_TEXTURES * VGUI_MAX_TEXTURES )
|
||||
{
|
||||
// in theory it might look up texture that hasn't been bound for a while and
|
||||
// reuse that but it will eventually overwrite some important textures anyway
|
||||
Con_Printf( S_ERROR "%s: Refusing resizing VGUI textures array due to memory leak\n", __func__ );
|
||||
return vgui.texture_id;
|
||||
}
|
||||
|
||||
return vgui.texture_id;
|
||||
vgui.max_textures += VGUI_MAX_TEXTURES;
|
||||
|
||||
// this potentially might leak memory if VGUI is used incorrectly!
|
||||
// (like in Cry of Fear)
|
||||
vgui.textures = Mem_Realloc( vgui.mempool, vgui.textures, sizeof( *vgui.textures ) * vgui.max_textures );
|
||||
|
||||
// warn mod developer
|
||||
if( vgui.max_textures >= VGUI_MAX_TEXTURES * 4 )
|
||||
Con_Printf( S_ERROR "%s: Potential memory leak in VGUI code is detected!\n", __func__ );
|
||||
}
|
||||
|
||||
return ++vgui.texture_id;
|
||||
}
|
||||
|
||||
static void GAME_EXPORT VGUI_UploadTexture( int id, const char *buffer, int width, int height )
|
||||
{
|
||||
rgbdata_t r_image = { 0 };
|
||||
char texName[32];
|
||||
MD5Context_t ctx;
|
||||
byte hash[16];
|
||||
|
||||
if( id <= 0 || id >= VGUI_MAX_TEXTURES )
|
||||
if( id <= 0 || id >= vgui.max_textures || width <= 0 || height <= 0 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: bad texture %i. Ignored\n", __func__, id );
|
||||
return;
|
||||
}
|
||||
|
||||
// need to do this as some mods tend to upload same texture over and over
|
||||
// exhausing engine-wide limit on textures and leaking vram
|
||||
MD5Init( &ctx );
|
||||
MD5Update( &ctx, buffer, width * height * 4 );
|
||||
MD5Final( hash, &ctx );
|
||||
|
||||
// it's a new texture, try to find a copy
|
||||
if( vgui.textures[id].gl_texturenum == 0 )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 1; i < vgui.texture_id; i++ )
|
||||
{
|
||||
if( vgui.textures[i].gl_texturenum != 0 && !memcmp( vgui.textures[i].hash, hash, sizeof( hash )))
|
||||
{
|
||||
// copy data to new texture id
|
||||
vgui.textures[id] = vgui.textures[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Q_snprintf( texName, sizeof( texName ), "*vgui%i", id );
|
||||
|
||||
r_image.width = width;
|
||||
@@ -91,51 +158,29 @@ static void GAME_EXPORT VGUI_UploadTexture( int id, const char *buffer, int widt
|
||||
r_image.flags = IMAGE_HAS_COLOR|IMAGE_HAS_ALPHA;
|
||||
r_image.buffer = (byte*)buffer;
|
||||
|
||||
vgui.textures[id] = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE );
|
||||
vgui.textures[id].gl_texturenum = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE );
|
||||
memcpy( vgui.textures[id].hash, hash, sizeof( hash ));
|
||||
}
|
||||
|
||||
static void GAME_EXPORT VGUI_CreateTexture( int id, int width, int height )
|
||||
{
|
||||
rgbdata_t r_image = { 0 };
|
||||
char texName[32];
|
||||
// nothing uses it, it can be removed
|
||||
Host_Error( "%s: deprecated\n", __func__ );
|
||||
|
||||
if( id <= 0 || id >= VGUI_MAX_TEXTURES )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: bad texture %i. Ignored\n", __func__, id );
|
||||
return;
|
||||
}
|
||||
|
||||
Q_snprintf( texName, sizeof( texName ), "*vgui%i", id );
|
||||
|
||||
r_image.width = width;
|
||||
r_image.height = height;
|
||||
r_image.type = PF_RGBA_32;
|
||||
r_image.size = width * height * 4;
|
||||
r_image.flags = IMAGE_HAS_COLOR|IMAGE_HAS_ALPHA;
|
||||
r_image.buffer = NULL;
|
||||
|
||||
vgui.textures[id] = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE );
|
||||
vgui.bound_texture = id;
|
||||
}
|
||||
|
||||
static void GAME_EXPORT VGUI_UploadTextureBlock( int id, int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight )
|
||||
{
|
||||
if( id <= 0 || id >= VGUI_MAX_TEXTURES || vgui.textures[id] == 0 )
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: bad texture %i. Ignored\n", __func__, id );
|
||||
return;
|
||||
}
|
||||
|
||||
ref.dllFuncs.VGUI_UploadTextureBlock( drawX, drawY, rgba, blockWidth, blockHeight );
|
||||
vgui.bound_texture = id;
|
||||
// nothing uses it, it can be removed
|
||||
Host_Error( "%s: deprecated\n", __func__ );
|
||||
}
|
||||
|
||||
static void GAME_EXPORT VGUI_BindTexture( int id )
|
||||
{
|
||||
if( id <= 0 || id >= VGUI_MAX_TEXTURES || !vgui.textures[id] )
|
||||
if( id <= 0 || id >= vgui.max_textures || !vgui.textures[id].gl_texturenum )
|
||||
id = 1; // NOTE: same as bogus index 2700 in GoldSrc
|
||||
|
||||
ref.dllFuncs.GL_Bind( XASH_TEXTURE0, vgui.textures[id] );
|
||||
ref.dllFuncs.GL_Bind( XASH_TEXTURE0, vgui.textures[id].gl_texturenum );
|
||||
vgui.bound_texture = id;
|
||||
}
|
||||
|
||||
@@ -144,7 +189,7 @@ static void GAME_EXPORT VGUI_GetTextureSizes( int *w, int *h )
|
||||
int texnum;
|
||||
|
||||
if( vgui.bound_texture )
|
||||
texnum = vgui.textures[vgui.bound_texture];
|
||||
texnum = vgui.textures[vgui.bound_texture].gl_texturenum;
|
||||
else
|
||||
texnum = R_GetBuiltinTexture( REF_DEFAULT_TEXTURE );
|
||||
|
||||
@@ -187,7 +232,7 @@ static void GAME_EXPORT VGUI_DrawQuad( const vpoint_t *ul, const vpoint_t *lr )
|
||||
t2 = lr->coord[1];
|
||||
|
||||
ref.dllFuncs.Color4ub( vgui.color[0], vgui.color[1], vgui.color[2], vgui.color[3] );
|
||||
ref.dllFuncs.R_DrawStretchPic( x, y, w, h, s1, t1, s2, t2, vgui.textures[vgui.bound_texture] );
|
||||
ref.dllFuncs.R_DrawStretchPic( x, y, w, h, s1, t1, s2, t2, vgui.textures[vgui.bound_texture].gl_texturenum );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -17,7 +17,7 @@ GNU General Public License for more details.
|
||||
#include "base_cmd.h"
|
||||
#include "cdll_int.h"
|
||||
|
||||
#define HASH_SIZE 128 // 128 * 4 * 4 == 2048 bytes
|
||||
#define HASH_SIZE 64 // 64 * 4 * 4 == 1024 bytes
|
||||
|
||||
typedef struct base_command_hashmap_s base_command_hashmap_t;
|
||||
|
||||
@@ -26,10 +26,11 @@ struct base_command_hashmap_s
|
||||
base_command_t *basecmd; // base command: cvar, alias or command
|
||||
base_command_hashmap_t *next;
|
||||
base_command_type_e type; // type for faster searching
|
||||
char name[1]; // key for searching
|
||||
char name[]; // key for searching
|
||||
};
|
||||
|
||||
static base_command_hashmap_t *hashed_cmds[HASH_SIZE];
|
||||
static poolhandle_t basecmd_pool;
|
||||
|
||||
#define BaseCmd_HashKey( x ) COM_HashKey( name, HASH_SIZE )
|
||||
|
||||
@@ -42,11 +43,27 @@ Find base command in bucket
|
||||
*/
|
||||
static base_command_hashmap_t *BaseCmd_FindInBucket( base_command_hashmap_t *bucket, base_command_type_e type, const char *name )
|
||||
{
|
||||
base_command_hashmap_t *i = bucket;
|
||||
for( ; i && ( i->type != type || Q_stricmp( name, i->name ) ); // filter out
|
||||
i = i->next );
|
||||
base_command_hashmap_t *i;
|
||||
|
||||
return i;
|
||||
for( i = bucket; i != NULL; i = i->next )
|
||||
{
|
||||
int cmp;
|
||||
|
||||
if( i->type != type )
|
||||
continue;
|
||||
|
||||
cmp = Q_stricmp( i->name, name );
|
||||
|
||||
if( cmp < 0 )
|
||||
continue;
|
||||
|
||||
if( cmp > 0 )
|
||||
break;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -85,32 +102,38 @@ BaseCmd_Find
|
||||
Find every type of base command and write into arguments
|
||||
============
|
||||
*/
|
||||
void BaseCmd_FindAll( const char *name, base_command_t **cmd, base_command_t **alias, base_command_t **cvar )
|
||||
void BaseCmd_FindAll( const char *name, cmd_t **cmd, cmdalias_t **alias, convar_t **cvar )
|
||||
{
|
||||
base_command_hashmap_t *base = BaseCmd_GetBucket( name );
|
||||
base_command_hashmap_t *i = base;
|
||||
|
||||
ASSERT( cmd && alias && cvar );
|
||||
|
||||
*cmd = *alias = *cvar = NULL;
|
||||
*cmd = NULL;
|
||||
*alias = NULL;
|
||||
*cvar = NULL;
|
||||
|
||||
for( ; i; i = i->next )
|
||||
{
|
||||
if( !Q_stricmp( i->name, name ) )
|
||||
int cmp = Q_stricmp( i->name, name );
|
||||
|
||||
if( cmp < 0 )
|
||||
continue;
|
||||
|
||||
if( cmp > 0 )
|
||||
break;
|
||||
|
||||
switch( i->type )
|
||||
{
|
||||
switch( i->type )
|
||||
{
|
||||
case HM_CMD:
|
||||
*cmd = i->basecmd;
|
||||
break;
|
||||
case HM_CMDALIAS:
|
||||
*alias = i->basecmd;
|
||||
break;
|
||||
case HM_CVAR:
|
||||
*cvar = i->basecmd;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
case HM_CMD:
|
||||
*cmd = (cmd_t *)i->basecmd;
|
||||
break;
|
||||
case HM_CMDALIAS:
|
||||
*alias = (cmdalias_t *)i->basecmd;
|
||||
break;
|
||||
case HM_CVAR:
|
||||
*cvar = (convar_t *)i->basecmd;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,14 +151,14 @@ void BaseCmd_Insert( base_command_type_e type, base_command_t *basecmd, const ch
|
||||
uint hash = BaseCmd_HashKey( name );
|
||||
size_t len = Q_strlen( name );
|
||||
|
||||
elem = Z_Malloc( sizeof( base_command_hashmap_t ) + len );
|
||||
elem = Mem_Malloc( basecmd_pool, sizeof( base_command_hashmap_t ) + len + 1 );
|
||||
elem->basecmd = basecmd;
|
||||
elem->type = type;
|
||||
Q_strncpy( elem->name, name, len + 1 );
|
||||
|
||||
// link the variable in alphanumerical order
|
||||
for( cur = NULL, find = hashed_cmds[hash];
|
||||
find && Q_strcmp( find->name, elem->name ) < 0;
|
||||
find && Q_stricmp( find->name, elem->name ) < 0;
|
||||
cur = find, find = find->next );
|
||||
|
||||
if( cur ) cur->next = elem;
|
||||
@@ -156,9 +179,23 @@ void BaseCmd_Remove( base_command_type_e type, const char *name )
|
||||
uint hash = BaseCmd_HashKey( name );
|
||||
base_command_hashmap_t *i, *prev;
|
||||
|
||||
for( prev = NULL, i = hashed_cmds[hash]; i &&
|
||||
( Q_strcmp( i->name, name ) || i->type != type); // filter out
|
||||
prev = i, i = i->next );
|
||||
for( prev = NULL, i = hashed_cmds[hash]; i != NULL; prev = i, i = i->next )
|
||||
{
|
||||
int cmp;
|
||||
|
||||
if( i->type != type )
|
||||
continue;
|
||||
|
||||
cmp = Q_stricmp( i->name, name );
|
||||
|
||||
if( cmp < 0 )
|
||||
continue;
|
||||
|
||||
if( cmp > 0 )
|
||||
i = NULL;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if( !i )
|
||||
{
|
||||
@@ -183,9 +220,15 @@ initialize base command hashmap system
|
||||
*/
|
||||
void BaseCmd_Init( void )
|
||||
{
|
||||
basecmd_pool = Mem_AllocPool( "BaseCmd" );
|
||||
memset( hashed_cmds, 0, sizeof( hashed_cmds ) );
|
||||
}
|
||||
|
||||
void BaseCmd_Shutdown( void )
|
||||
{
|
||||
Mem_FreePool( &basecmd_pool );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
BaseCmd_Stats_f
|
||||
|
||||
@@ -21,6 +21,9 @@ GNU General Public License for more details.
|
||||
|
||||
#ifdef XASH_HASHED_VARS
|
||||
|
||||
#include "common.h"
|
||||
#include "cdll_int.h"
|
||||
|
||||
typedef enum base_command_type
|
||||
{
|
||||
HM_DONTCARE = 0,
|
||||
@@ -32,9 +35,9 @@ typedef enum base_command_type
|
||||
typedef void base_command_t;
|
||||
|
||||
void BaseCmd_Init( void );
|
||||
void BaseCmd_Shutdown( void );
|
||||
base_command_t *BaseCmd_Find( base_command_type_e type, const char *name );
|
||||
void BaseCmd_FindAll( const char *name,
|
||||
base_command_t **cmd, base_command_t **alias, base_command_t **cvar );
|
||||
void BaseCmd_FindAll( const char *name, cmd_t **cmd, cmdalias_t **alias, convar_t **cvar );
|
||||
void BaseCmd_Insert ( base_command_type_e type, base_command_t *basecmd, const char *name );
|
||||
void BaseCmd_Remove ( base_command_type_e type, const char *name );
|
||||
void BaseCmd_Stats_f( void ); // to be registered later
|
||||
|
||||
@@ -46,6 +46,7 @@ static cmdalias_t *cmd_alias;
|
||||
static uint cmd_condition;
|
||||
static int cmd_condlevel;
|
||||
static qboolean cmd_currentCommandIsPrivileged;
|
||||
static poolhandle_t cmd_pool;
|
||||
|
||||
static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPrivileged );
|
||||
|
||||
@@ -142,28 +143,33 @@ void Cbuf_AddFilteredText( const char *text )
|
||||
Cbuf_InsertText
|
||||
|
||||
Adds command text immediately after the current command
|
||||
Adds a \n to the text
|
||||
============
|
||||
*/
|
||||
static void Cbuf_InsertTextToBuffer( cmdbuf_t *buf, const char *text )
|
||||
static void Cbuf_InsertTextToBuffer( cmdbuf_t *buf, const char *text, size_t len, size_t requested_len )
|
||||
{
|
||||
int l = Q_strlen( text );
|
||||
|
||||
if(( buf->cursize + l ) >= buf->maxsize )
|
||||
if(( buf->cursize + requested_len ) >= buf->maxsize )
|
||||
{
|
||||
Con_Reportf( S_WARN "%s: overflow\n", __func__ );
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove( buf->data + l, buf->data, buf->cursize );
|
||||
memcpy( buf->data, text, l );
|
||||
buf->cursize += l;
|
||||
memmove( buf->data + len, buf->data, buf->cursize );
|
||||
memcpy( buf->data, text, len );
|
||||
buf->cursize += len;
|
||||
}
|
||||
}
|
||||
|
||||
void Cbuf_InsertTextLen( const char *text, size_t len, size_t requested_len )
|
||||
{
|
||||
// sometimes we need to insert more data than we have
|
||||
// but also prevent overflow
|
||||
Cbuf_InsertTextToBuffer( &cmd_text, text, len, requested_len );
|
||||
}
|
||||
|
||||
void Cbuf_InsertText( const char *text )
|
||||
{
|
||||
Cbuf_InsertTextToBuffer( &cmd_text, text );
|
||||
size_t l = Q_strlen( text );
|
||||
Cbuf_InsertTextToBuffer( &cmd_text, text, l, l );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -427,7 +433,7 @@ static void Cmd_Alias_f( void )
|
||||
{
|
||||
if( !Q_strcmp( s, a->name ))
|
||||
{
|
||||
Z_Free( a->value );
|
||||
Mem_Free( a->value );
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -436,7 +442,7 @@ static void Cmd_Alias_f( void )
|
||||
{
|
||||
cmdalias_t *cur, *prev;
|
||||
|
||||
a = Z_Malloc( sizeof( cmdalias_t ));
|
||||
a = Mem_Malloc( cmd_pool, sizeof( cmdalias_t ));
|
||||
|
||||
Q_strncpy( a->name, s, sizeof( a->name ));
|
||||
|
||||
@@ -464,7 +470,7 @@ static void Cmd_Alias_f( void )
|
||||
}
|
||||
|
||||
Q_strncat( cmd, "\n", sizeof( cmd ));
|
||||
a->value = copystring( cmd );
|
||||
a->value = copystringpool( cmd_pool, cmd );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -520,51 +526,17 @@ static void Cmd_UnAlias_f ( void )
|
||||
*/
|
||||
struct cmd_s
|
||||
{
|
||||
struct cmd_s *next;
|
||||
char *name;
|
||||
xcommand_t function;
|
||||
int flags;
|
||||
char *desc;
|
||||
cmd_t *next;
|
||||
char *name;
|
||||
xcommand_t function;
|
||||
int flags;
|
||||
char desc[];
|
||||
};
|
||||
|
||||
static int cmd_argc;
|
||||
static const char *cmd_args = NULL;
|
||||
static char *cmd_argv[MAX_CMD_TOKENS];
|
||||
static cmd_t *cmd_functions; // possible commands to execute
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_Argc
|
||||
============
|
||||
*/
|
||||
int GAME_EXPORT Cmd_Argc( void )
|
||||
{
|
||||
return cmd_argc;
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_Argv
|
||||
============
|
||||
*/
|
||||
const char *GAME_EXPORT Cmd_Argv( int arg )
|
||||
{
|
||||
if((uint)arg >= cmd_argc )
|
||||
return "";
|
||||
return cmd_argv[arg];
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_Args
|
||||
============
|
||||
*/
|
||||
const char *GAME_EXPORT Cmd_Args( void )
|
||||
{
|
||||
return cmd_args;
|
||||
}
|
||||
|
||||
|
||||
int cmd_argc;
|
||||
const char *cmd_args = NULL;
|
||||
char *cmd_argv[MAX_CMD_TOKENS];
|
||||
static cmd_t *cmd_functions; // possible commands to execute
|
||||
/*
|
||||
===========================
|
||||
|
||||
@@ -572,8 +544,6 @@ Client exports
|
||||
|
||||
===========================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
Cmd_AliasGetList
|
||||
@@ -631,7 +601,7 @@ void Cmd_TokenizeString( const char *text )
|
||||
|
||||
// clear the args from the last string
|
||||
for( i = 0; i < cmd_argc; i++ )
|
||||
Z_Free( cmd_argv[i] );
|
||||
Mem_Free( cmd_argv[i] );
|
||||
|
||||
cmd_argc = 0; // clear previous args
|
||||
cmd_args = NULL;
|
||||
@@ -665,7 +635,7 @@ void Cmd_TokenizeString( const char *text )
|
||||
|
||||
if( cmd_argc < MAX_CMD_TOKENS )
|
||||
{
|
||||
cmd_argv[cmd_argc] = copystring( cmd_token );
|
||||
cmd_argv[cmd_argc] = copystringpool( cmd_pool, cmd_token );
|
||||
cmd_argc++;
|
||||
}
|
||||
}
|
||||
@@ -678,7 +648,8 @@ Cmd_AddCommandEx
|
||||
*/
|
||||
int Cmd_AddCommandEx( const char *cmd_name, xcommand_t function, const char *cmd_desc, int iFlags, const char *funcname )
|
||||
{
|
||||
cmd_t *cmd, *cur, *prev;
|
||||
cmd_t *cmd, *cur, *prev;
|
||||
size_t desc_len;
|
||||
|
||||
if( !COM_CheckString( cmd_name ))
|
||||
{
|
||||
@@ -702,8 +673,8 @@ int Cmd_AddCommandEx( const char *cmd_name, xcommand_t function, const char *cmd
|
||||
// unfortunately, we lose original command this way
|
||||
if( FBitSet( cmd->flags, CMD_OVERRIDABLE ))
|
||||
{
|
||||
Mem_Free( cmd->desc );
|
||||
cmd->desc = copystring( cmd_desc );
|
||||
desc_len = Q_strlen( cmd->desc ) + 1;
|
||||
Q_strncpy( cmd->desc, cmd_desc, desc_len );
|
||||
cmd->function = function;
|
||||
cmd->flags = iFlags;
|
||||
|
||||
@@ -712,15 +683,16 @@ int Cmd_AddCommandEx( const char *cmd_name, xcommand_t function, const char *cmd
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: %s already defined\n", funcname, cmd_name );
|
||||
Con_DPrintf( "%s%s: %s already defined\n", cmd->function == function ? S_WARN : S_ERROR, funcname, cmd_name );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// use a small malloc to avoid zone fragmentation
|
||||
cmd = Z_Malloc( sizeof( cmd_t ) );
|
||||
cmd->name = copystring( cmd_name );
|
||||
cmd->desc = copystring( cmd_desc );
|
||||
desc_len = Q_strlen( cmd_desc ) + 1;
|
||||
cmd = Mem_Malloc( cmd_pool, sizeof( cmd_t ) + desc_len );
|
||||
cmd->name = copystringpool( cmd_pool, cmd_name );
|
||||
Q_strncpy( cmd->desc, cmd_desc, desc_len );
|
||||
cmd->function = function;
|
||||
cmd->flags = iFlags;
|
||||
|
||||
@@ -767,9 +739,6 @@ void GAME_EXPORT Cmd_RemoveCommand( const char *cmd_name )
|
||||
if( cmd->name )
|
||||
Mem_Free( cmd->name );
|
||||
|
||||
if( cmd->desc )
|
||||
Mem_Free( cmd->desc );
|
||||
|
||||
Mem_Free( cmd );
|
||||
return;
|
||||
}
|
||||
@@ -989,30 +958,27 @@ static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPr
|
||||
|
||||
if( !Cmd_Argc( )) return; // no tokens
|
||||
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
BaseCmd_FindAll( cmd_argv[0],
|
||||
(base_command_t**)&cmd,
|
||||
(base_command_t**)&a,
|
||||
(base_command_t**)&cvar );
|
||||
#if defined( XASH_HASHED_VARS )
|
||||
BaseCmd_FindAll( cmd_argv[0], &cmd, &a, &cvar );
|
||||
#endif
|
||||
|
||||
if( !host.apply_game_config )
|
||||
{
|
||||
#if !defined( XASH_HASHED_VARS )
|
||||
// check aliases
|
||||
if( !a ) // if not found in basecmd
|
||||
for( a = cmd_alias; a; a = a->next )
|
||||
{
|
||||
for( a = cmd_alias; a; a = a->next )
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], a->name ))
|
||||
break;
|
||||
}
|
||||
if( !Q_stricmp( cmd_argv[0], a->name ))
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( a )
|
||||
{
|
||||
size_t len = Q_strlen( a->value );
|
||||
Cbuf_InsertTextToBuffer(
|
||||
isPrivileged ? &cmd_text : &filteredcmd_text,
|
||||
a->value );
|
||||
a->value, len, len );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1020,14 +986,13 @@ static void Cmd_ExecuteStringWithPrivilegeCheck( const char *text, qboolean isPr
|
||||
// special mode for restore game.dll archived cvars
|
||||
if( !host.apply_game_config || !Q_strcmp( cmd_argv[0], "exec" ))
|
||||
{
|
||||
if( !cmd || !cmd->function ) // if not found in basecmd
|
||||
#if !defined( XASH_HASHED_VARS )
|
||||
for( cmd = cmd_functions; cmd; cmd = cmd->next )
|
||||
{
|
||||
for( cmd = cmd_functions; cmd; cmd = cmd->next )
|
||||
{
|
||||
if( !Q_stricmp( cmd_argv[0], cmd->name ) && cmd->function )
|
||||
break;
|
||||
}
|
||||
if( !Q_stricmp( cmd_argv[0], cmd->name ) && cmd->function )
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
// check functions
|
||||
if( cmd && cmd->function )
|
||||
@@ -1196,7 +1161,6 @@ void Cmd_Unlink( int group )
|
||||
*prev = cmd->next;
|
||||
|
||||
if( cmd->name ) Mem_Free( cmd->name );
|
||||
if( cmd->desc ) Mem_Free( cmd->desc );
|
||||
|
||||
Mem_Free( cmd );
|
||||
count++;
|
||||
@@ -1293,6 +1257,50 @@ void Cmd_Null_f( void )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
Cmd_MakePrivileged_f
|
||||
=============
|
||||
*/
|
||||
static void Cmd_MakePrivileged_f( void )
|
||||
{
|
||||
const char *s = Cmd_Argv( 1 );
|
||||
convar_t *cv;
|
||||
cmd_t *cmd;
|
||||
cmdalias_t *alias;
|
||||
|
||||
if( Cmd_Argc( ) != 2 )
|
||||
{
|
||||
Con_Printf( S_USAGE "make_privileged <cvar or command>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined( XASH_HASHED_VARS )
|
||||
BaseCmd_FindAll( s, &cmd, &alias, &cv );
|
||||
#else
|
||||
cmd = Cmd_Exists( s );
|
||||
cv = Cvar_FindVar( s );
|
||||
#endif
|
||||
|
||||
if( !cv && !cmd )
|
||||
{
|
||||
Con_Printf( "Nothing was found.\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if( cv )
|
||||
{
|
||||
SetBits( cv->flags, FCVAR_PRIVILEGED );
|
||||
Con_Printf( "Cvar %s set to be privileged\n", cv->name );
|
||||
}
|
||||
|
||||
if( cmd )
|
||||
{
|
||||
SetBits( cmd->flags, CMD_PRIVILEGED );
|
||||
Con_Printf( "Command %s set to be privileged\n", cmd->name );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==========
|
||||
Cmd_Escape
|
||||
@@ -1334,6 +1342,7 @@ Cmd_Init
|
||||
*/
|
||||
void Cmd_Init( void )
|
||||
{
|
||||
cmd_pool = Mem_AllocPool( "Console Commands" );
|
||||
cmd_functions = NULL;
|
||||
cmd_condition = 0;
|
||||
cmd_alias = NULL;
|
||||
@@ -1354,12 +1363,19 @@ void Cmd_Init( void )
|
||||
Cmd_AddRestrictedCommand( "if", Cmd_If_f, "compare and set condition bits" );
|
||||
Cmd_AddRestrictedCommand( "else", Cmd_Else_f, "invert condition bit" );
|
||||
|
||||
Cmd_AddRestrictedCommand( "make_privileged", Cmd_MakePrivileged_f, "makes command or variable privileged (protected from access attempts from server)" );
|
||||
|
||||
#if defined(XASH_HASHED_VARS)
|
||||
Cmd_AddCommand( "basecmd_stats", BaseCmd_Stats_f, "print info about basecmd usage" );
|
||||
Cmd_AddCommand( "basecmd_test", BaseCmd_Test_f, "test basecmd" );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Cmd_Shutdown( void )
|
||||
{
|
||||
Mem_FreePool( &cmd_pool );
|
||||
}
|
||||
|
||||
#if XASH_ENGINE_TESTS
|
||||
#include "tests.h"
|
||||
|
||||
|
||||
@@ -72,8 +72,6 @@ GNU General Public License for more details.
|
||||
|
||||
#define CVAR_GLCONFIG_DESCRIPTION "enable or disable %s"
|
||||
|
||||
#define DEFAULT_BSP_BUILD_ERROR "%s can't be loaded in this build. Please rebuild engine with enabled SUPPORT_BSP2_FORMAT\n"
|
||||
|
||||
#define DEFAULT_UPDATE_PAGE "https://github.com/FWGS/xash3d-fwgs/releases/latest"
|
||||
|
||||
#define XASH_ENGINE_NAME "Xash3D FWGS"
|
||||
|
||||
@@ -251,7 +251,7 @@ static void LZSS_BuildHash( lzss_state_t *state, const byte *source )
|
||||
{
|
||||
lzss_list_t *list;
|
||||
lzss_node_t *node;
|
||||
unsigned int targetindex = (uint)source & ( state->window_size - 1 );
|
||||
unsigned int targetindex = (uintptr_t)source & ( state->window_size - 1 );
|
||||
|
||||
node = &state->hash_node[targetindex];
|
||||
|
||||
@@ -900,7 +900,7 @@ float GAME_EXPORT pfnTime( void )
|
||||
qboolean COM_IsSafeFileToDownload( const char *filename )
|
||||
{
|
||||
char lwrfilename[4096];
|
||||
const char *first, *last;
|
||||
const char *last;
|
||||
const char *ext;
|
||||
size_t len;
|
||||
int i;
|
||||
@@ -934,25 +934,27 @@ qboolean COM_IsSafeFileToDownload( const char *filename )
|
||||
return true;
|
||||
}
|
||||
|
||||
for( i = 0; i < len; i++ )
|
||||
{
|
||||
if( !isprint( filename[i] ))
|
||||
return false;
|
||||
}
|
||||
|
||||
Q_strnlwr( filename, lwrfilename, sizeof( lwrfilename ));
|
||||
ext = COM_FileExtension( lwrfilename );
|
||||
|
||||
if( Q_strpbrk( lwrfilename, "\\:~" ) || Q_strstr( lwrfilename, ".." ) )
|
||||
if( Q_strpbrk( lwrfilename, "\\:~" ) || Q_strstr( lwrfilename, ".." ))
|
||||
return false;
|
||||
|
||||
if( lwrfilename[0] == '/' )
|
||||
return false;
|
||||
|
||||
first = Q_strchr( lwrfilename, '.' );
|
||||
last = Q_strrchr( lwrfilename, '.' );
|
||||
|
||||
if( first == NULL || last == NULL )
|
||||
if( last == NULL )
|
||||
return false;
|
||||
|
||||
if( first != last )
|
||||
return false;
|
||||
|
||||
if( Q_strlen( first ) != 4 )
|
||||
if( Q_strlen( last ) != 4 )
|
||||
return false;
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( file_exts ); i++ )
|
||||
@@ -1131,6 +1133,7 @@ void Test_RunCommon( void )
|
||||
{
|
||||
Msg( "Checking COM_IsSafeFileToDownload...\n" );
|
||||
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "models/bsg_props/[hl-lab.ru]bush.mdl" ), true );
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD5AAB5E8B307672DA86FBD10AC302BC732" ), true );
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD56f1ffd8c96bd64c9c27955309f6ecfe6" ), false );
|
||||
TASSERT_EQi( COM_IsSafeFileToDownload( "!MD5AAB5E8B307672DA86FBD10AC302B.exe" ), false );
|
||||
|
||||
@@ -76,23 +76,14 @@ XASH SPECIFIC - sort of hack that works only in Xash3D not in GoldSrc
|
||||
|
||||
#define HACKS_RELATED_HLMODS // some HL-mods works differently under Xash and can't be fixed without some hacks at least at current time
|
||||
|
||||
enum
|
||||
enum dev_level_e
|
||||
{
|
||||
DEV_NONE = 0,
|
||||
DEV_NORMAL,
|
||||
DEV_EXTENDED
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
D_INFO = 1, // "-dev 1", shows various system messages
|
||||
D_WARN, // "-dev 2", shows not critical system warnings
|
||||
D_ERROR, // "-dev 3", shows critical warnings
|
||||
D_REPORT, // "-dev 4", special case for game reports
|
||||
D_NOTE // "-dev 5", show system notifications for engine developers
|
||||
};
|
||||
|
||||
typedef enum
|
||||
typedef enum instance_e
|
||||
{
|
||||
HOST_NORMAL, // listen server, singleplayer
|
||||
HOST_DEDICATED,
|
||||
@@ -108,14 +99,14 @@ typedef enum
|
||||
#include "com_model.h"
|
||||
#include "com_strings.h"
|
||||
#include "crtlib.h"
|
||||
#include "cvar.h"
|
||||
#include "con_nprint.h"
|
||||
#include "crclib.h"
|
||||
#include "ref_api.h"
|
||||
#define FSCALLBACK_OVERRIDE_OPEN
|
||||
#define FSCALLBACK_OVERRIDE_LOADFILE
|
||||
#define FSCALLBACK_OVERRIDE_MALLOC_LIKE
|
||||
#include "fscallback.h"
|
||||
#include "cvar.h"
|
||||
#include "con_nprint.h"
|
||||
#include "crclib.h"
|
||||
#include "ref_api.h"
|
||||
|
||||
// PERFORMANCE INFO
|
||||
#define MIN_FPS 20.0f // host minimum fps value for maxfps.
|
||||
@@ -146,6 +137,11 @@ typedef enum
|
||||
#define MAX_STATIC_ENTITIES 32 // static entities that moved on the client when level is spawn
|
||||
#endif
|
||||
|
||||
#define MAX_SERVERINFO_STRING 512 // server handles too many settings. expand to 1024?
|
||||
#define MAX_PRINT_MSG 8192 // how many symbols can handle single call of Con_Printf or Con_DPrintf
|
||||
#define MAX_TOKEN 2048 // parse token length
|
||||
#define MAX_USERMSG_LENGTH 2048 // don't modify it's relies on a client-side definitions
|
||||
|
||||
#define GameState (&host.game)
|
||||
|
||||
#define FORCE_DRAW_VERSION_TIME 5.0 // draw version for 5 seconds
|
||||
@@ -171,6 +167,11 @@ extern convar_t cl_filterstuffcmd;
|
||||
extern convar_t rcon_password;
|
||||
extern convar_t hpk_custom_file;
|
||||
extern convar_t con_gamemaps;
|
||||
extern convar_t fs_mount_lv;
|
||||
extern convar_t fs_mount_hd;
|
||||
extern convar_t fs_mount_addon;
|
||||
extern convar_t fs_mount_l10n;
|
||||
extern convar_t ui_language; // historically used for UI, but now controls mounted localization directory
|
||||
|
||||
#define Mod_AllowMaterials() ( host_allow_materials.value != 0.0f && !FBitSet( host.features, ENGINE_DISABLE_HDTEXTURES ))
|
||||
|
||||
@@ -189,7 +190,7 @@ GAMEINFO stuff
|
||||
internal shared gameinfo structure (readonly for engine parts)
|
||||
========================================================================
|
||||
*/
|
||||
typedef enum
|
||||
typedef enum host_status_e
|
||||
{
|
||||
HOST_INIT = 0, // initalize operations
|
||||
HOST_FRAME, // host running
|
||||
@@ -200,7 +201,7 @@ typedef enum
|
||||
HOST_CRASHED // an exception handler called
|
||||
} host_status_t;
|
||||
|
||||
typedef enum
|
||||
typedef enum host_state_e
|
||||
{
|
||||
STATE_RUNFRAME = 0,
|
||||
STATE_LOAD_LEVEL,
|
||||
@@ -209,7 +210,7 @@ typedef enum
|
||||
STATE_GAME_SHUTDOWN,
|
||||
} host_state_t;
|
||||
|
||||
typedef struct
|
||||
typedef struct game_status_e
|
||||
{
|
||||
host_state_t curstate;
|
||||
host_state_t nextstate;
|
||||
@@ -220,7 +221,7 @@ typedef struct
|
||||
qboolean newGame; // unload the server.dll before start a new map
|
||||
} game_status_t;
|
||||
|
||||
typedef enum
|
||||
typedef enum keydest_e
|
||||
{
|
||||
key_console = 0,
|
||||
key_game,
|
||||
@@ -228,7 +229,7 @@ typedef enum
|
||||
key_message
|
||||
} keydest_t;
|
||||
|
||||
typedef enum
|
||||
typedef enum rdtype_e
|
||||
{
|
||||
RD_NONE = 0,
|
||||
RD_CLIENT,
|
||||
@@ -238,7 +239,7 @@ typedef enum
|
||||
#include "net_ws.h"
|
||||
|
||||
// console field
|
||||
typedef struct
|
||||
typedef struct field_e
|
||||
{
|
||||
string buffer;
|
||||
int cursor;
|
||||
@@ -256,7 +257,7 @@ typedef struct host_redirect_s
|
||||
int lines;
|
||||
} host_redirect_t;
|
||||
|
||||
typedef struct
|
||||
typedef struct soundlist_e
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
short entnum;
|
||||
@@ -297,11 +298,10 @@ typedef struct host_parm_s
|
||||
|
||||
host_status_t status; // global host state
|
||||
game_status_t game; // game manager
|
||||
uint type; // running at
|
||||
instance_t type; // running at
|
||||
poolhandle_t mempool; // static mempool for misc allocations
|
||||
poolhandle_t imagepool; // imagelib mempool
|
||||
poolhandle_t soundpool; // soundlib mempool
|
||||
string finalmsg; // server shutdown final message
|
||||
string downloadfile; // filename to be downloading
|
||||
int downloadcount; // how many files remain to downloading
|
||||
char deferred_cmd[128];// deferred commands
|
||||
@@ -342,7 +342,6 @@ typedef struct host_parm_s
|
||||
qboolean apply_game_config; // when true apply only to game cvars and ignore all other commands
|
||||
qboolean apply_opengl_config; // when true apply only to opengl cvars and ignore all other commands
|
||||
qboolean config_executed; // a bit who indicated was config.cfg already executed e.g. from valve.rc
|
||||
qboolean crashed; // set to true if crashed
|
||||
#if XASH_DLL_LOADER
|
||||
qboolean enabledll;
|
||||
#endif
|
||||
@@ -358,6 +357,7 @@ typedef struct host_parm_s
|
||||
int window_center_y;
|
||||
string gamedll;
|
||||
string clientlib;
|
||||
string menulib;
|
||||
} host_parm_t;
|
||||
|
||||
extern host_parm_t host;
|
||||
@@ -415,23 +415,48 @@ byte *FS_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamediro
|
||||
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
|
||||
byte *FS_LoadDirectFile( const char *path, fs_offset_t *filesizeptr )
|
||||
MALLOC_LIKE( _Mem_Free, 1 ) WARN_UNUSED_RESULT;
|
||||
void FS_Rescan_f( void );
|
||||
void FS_CheckConfig( void );
|
||||
|
||||
//
|
||||
// cmd.c
|
||||
//
|
||||
typedef struct cmd_s cmd_t;
|
||||
|
||||
static inline int GAME_EXPORT Cmd_Argc( void )
|
||||
{
|
||||
extern int cmd_argc;
|
||||
return cmd_argc;
|
||||
}
|
||||
|
||||
static inline const char *GAME_EXPORT RETURNS_NONNULL Cmd_Argv( int arg )
|
||||
{
|
||||
extern int cmd_argc;
|
||||
extern char *cmd_argv[MAX_CMD_TOKENS];
|
||||
|
||||
if((uint)arg >= cmd_argc )
|
||||
return "";
|
||||
return cmd_argv[arg];
|
||||
}
|
||||
|
||||
static inline const char *GAME_EXPORT RETURNS_NONNULL Cmd_Args( void )
|
||||
{
|
||||
extern const char *cmd_args;
|
||||
|
||||
return cmd_args;
|
||||
}
|
||||
|
||||
void Cbuf_Clear( void );
|
||||
void Cbuf_AddText( const char *text );
|
||||
void Cbuf_AddTextf( const char *text, ... ) FORMAT_CHECK( 1 );
|
||||
void Cbuf_AddFilteredText( const char *text );
|
||||
void Cbuf_InsertText( const char *text );
|
||||
void Cbuf_InsertTextLen( const char *text, size_t len, size_t requested_len );
|
||||
void Cbuf_ExecStuffCmds( void );
|
||||
void Cbuf_Execute (void);
|
||||
qboolean Cmd_CurrentCommandIsPrivileged( void );
|
||||
int Cmd_Argc( void );
|
||||
const char *Cmd_Args( void ) RETURNS_NONNULL;
|
||||
const char *Cmd_Argv( int arg ) RETURNS_NONNULL;
|
||||
void Cmd_Init( void );
|
||||
void Cmd_Shutdown( void );
|
||||
void Cmd_Unlink( int group );
|
||||
int Cmd_AddCommandEx( const char *cmd_name, xcommand_t function, const char *cmd_desc, int flags, const char *funcname );
|
||||
|
||||
@@ -490,7 +515,7 @@ internal sound format
|
||||
typically expanded to wav buffer
|
||||
========================================================================
|
||||
*/
|
||||
typedef enum
|
||||
typedef enum sndformat_e
|
||||
{
|
||||
WF_UNKNOWN = 0,
|
||||
WF_PCMDATA,
|
||||
@@ -501,7 +526,7 @@ typedef enum
|
||||
} sndformat_t;
|
||||
|
||||
// wavdata output flags
|
||||
typedef enum
|
||||
typedef enum sndFlags_e
|
||||
{
|
||||
// wavdata->flags
|
||||
SOUND_LOOPED = BIT( 0 ), // this is looped sound (contain cue markers)
|
||||
@@ -511,29 +536,29 @@ typedef enum
|
||||
SOUND_RESAMPLE = BIT( 12 ), // resample sound to specified rate
|
||||
} sndFlags_t;
|
||||
|
||||
typedef struct
|
||||
typedef struct wavdata_s
|
||||
{
|
||||
word rate; // num samples per second (e.g. 11025 - 11 khz)
|
||||
byte width; // resolution - bum bits divided by 8 (8 bit is 1, 16 bit is 2)
|
||||
byte channels; // num channels (1 - mono, 2 - stereo)
|
||||
size_t size; // for bounds checking
|
||||
uint loopStart; // offset at this point sound will be looping while playing more than only once
|
||||
uint samples; // total samplecount in wav
|
||||
uint type; // compression type
|
||||
uint flags; // misc sound flags
|
||||
byte *buffer; // sound buffer
|
||||
size_t size; // for bounds checking
|
||||
word rate; // num samples per second (e.g. 11025 - 11 khz)
|
||||
byte width; // resolution - bum bits divided by 8 (8 bit is 1, 16 bit is 2)
|
||||
byte channels; // num channels (1 - mono, 2 - stereo)
|
||||
byte buffer[]; // sound buffer
|
||||
} wavdata_t;
|
||||
|
||||
//
|
||||
// soundlib
|
||||
//
|
||||
typedef struct stream_s stream_t;
|
||||
void Sound_Init( void );
|
||||
void Sound_Shutdown( void );
|
||||
void FS_FreeSound( wavdata_t *pack );
|
||||
void FS_FreeStream( stream_t *stream );
|
||||
wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size ) MALLOC_LIKE( FS_FreeSound, 1 ) WARN_UNUSED_RESULT;
|
||||
stream_t *FS_OpenStream( const char *filename ) MALLOC_LIKE( FS_FreeStream, 1 ) WARN_UNUSED_RESULT;
|
||||
wavdata_t *FS_StreamInfo( stream_t *stream );
|
||||
int FS_ReadStream( stream_t *stream, int bytes, void *buffer );
|
||||
int FS_SetStreamPos( stream_t *stream, int newpos );
|
||||
int FS_GetStreamPos( stream_t *stream );
|
||||
@@ -547,7 +572,7 @@ qboolean Sound_SupportedFileFormat( const char *fileext );
|
||||
typedef void( *pfnChangeGame )( const char *progname );
|
||||
|
||||
qboolean Host_IsQuakeCompatible( void );
|
||||
void EXPORT Host_Shutdown( void );
|
||||
void Host_ShutdownWithReason( const char *reason );
|
||||
int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGame, pfnChangeGame func );
|
||||
void Host_EndGame( qboolean abort, const char *message, ... ) FORMAT_CHECK( 2 );
|
||||
void Host_AbortCurrentFrame( void ) NORETURN;
|
||||
@@ -559,6 +584,7 @@ void Host_Error( const char *error, ... ) FORMAT_CHECK( 1 );
|
||||
void Host_ValidateEngineFeatures( uint32_t mask, uint32_t features );
|
||||
void Host_Frame( double time );
|
||||
void Host_Credits( void );
|
||||
void Host_ExitInMain( void );
|
||||
|
||||
//
|
||||
// host_state.c
|
||||
@@ -577,11 +603,19 @@ CLIENT / SERVER SYSTEMS
|
||||
|
||||
==============================================================
|
||||
*/
|
||||
#if !XASH_DEDICATED
|
||||
void CL_Init( void );
|
||||
void CL_Shutdown( void );
|
||||
void Host_ClientBegin( void );
|
||||
void Host_ClientFrame( void );
|
||||
int CL_Active( void );
|
||||
#else
|
||||
static inline void CL_Init( void ) { }
|
||||
static inline void CL_Shutdown( void ) { }
|
||||
static inline void Host_ClientBegin( void ) { Cbuf_Execute(); }
|
||||
static inline void Host_ClientFrame( void ) { }
|
||||
static inline int CL_Active( void ) { return 0; }
|
||||
#endif
|
||||
|
||||
void SV_Init( void );
|
||||
void SV_Shutdown( const char *finalmsg );
|
||||
@@ -619,6 +653,7 @@ int pfnNumberOfEntities( void );
|
||||
int pfnIsInGame( void );
|
||||
float pfnTime( void );
|
||||
#define copystring( s ) _copystring( host.mempool, s, __FILE__, __LINE__ )
|
||||
#define copystringpool( pool, s ) _copystring( pool, s, __FILE__, __LINE__ )
|
||||
#define SV_CopyString( s ) _copystring( svgame.stringspool, s, __FILE__, __LINE__ )
|
||||
#define freestring( s ) if( s != NULL ) { Mem_Free( s ); s = NULL; }
|
||||
char *_copystring( poolhandle_t mempool, const char *s, const char *filename, int fileline );
|
||||
@@ -669,6 +704,7 @@ int CSCR_WriteGameCVars( file_t *cfg, const char *scriptfilename );
|
||||
//
|
||||
// hpak.c
|
||||
//
|
||||
const char *COM_ResourceTypeFromIndex( int index );
|
||||
void HPAK_Init( void );
|
||||
qboolean HPAK_GetDataPointer( const char *filename, struct resource_s *pRes, byte **buffer, int *size );
|
||||
qboolean HPAK_ResourceForHash( const char *filename, byte *hash, struct resource_s *pRes );
|
||||
@@ -702,13 +738,32 @@ typedef enum connprotocol_e
|
||||
struct physent_s;
|
||||
struct sv_client_s;
|
||||
typedef struct sizebuf_s sizebuf_t;
|
||||
int SV_GetMaxClients( void );
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
qboolean CL_Initialized( void );
|
||||
qboolean CL_IsInGame( void );
|
||||
qboolean CL_IsInConsole( void );
|
||||
qboolean CL_IsIntermission( void );
|
||||
qboolean CL_Initialized( void );
|
||||
qboolean CL_DisableVisibility( void );
|
||||
qboolean CL_IsRecordDemo( void );
|
||||
qboolean CL_IsPlaybackDemo( void );
|
||||
qboolean UI_CreditsActive( void );
|
||||
int CL_GetMaxClients( void );
|
||||
#else
|
||||
static inline qboolean CL_Initialized( void ) { return false; }
|
||||
static inline qboolean CL_IsInGame( void ) { return true; } // always true for dedicated
|
||||
static inline qboolean CL_IsInConsole( void ) { return false; }
|
||||
static inline qboolean CL_IsIntermission( void ) { return false; }
|
||||
static inline qboolean CL_DisableVisibility( void ) { return false; }
|
||||
static inline qboolean CL_IsRecordDemo( void ) { return false; }
|
||||
static inline qboolean CL_IsPlaybackDemo( void ) { return false; }
|
||||
static inline qboolean UI_CreditsActive( void ) { return false; }
|
||||
static inline int CL_GetMaxClients( void ) { return SV_GetMaxClients(); }
|
||||
#endif
|
||||
|
||||
char *CL_Userinfo( void );
|
||||
void CL_CharEvent( int key );
|
||||
qboolean CL_DisableVisibility( void );
|
||||
byte *COM_LoadFile( const char *filename, int usehunk, int *pLength ) MALLOC_LIKE( free, 1 );
|
||||
struct cmd_s *Cmd_GetFirstFunctionHandle( void );
|
||||
struct cmd_s *Cmd_GetNextFunctionHandle( struct cmd_s *cmd );
|
||||
@@ -726,13 +781,7 @@ const char *CL_MsgInfo( int cmd );
|
||||
void SV_DrawDebugTriangles( void );
|
||||
void SV_DrawOrthoTriangles( void );
|
||||
double CL_GetDemoFramerate( void );
|
||||
qboolean UI_CreditsActive( void );
|
||||
void CL_StopPlayback( void );
|
||||
int CL_GetMaxClients( void );
|
||||
int SV_GetMaxClients( void );
|
||||
qboolean CL_IsRecordDemo( void );
|
||||
qboolean CL_IsTimeDemo( void );
|
||||
qboolean CL_IsPlaybackDemo( void );
|
||||
qboolean SV_Initialized( void );
|
||||
void CL_ProcessFile( qboolean successfully_received, const char *filename );
|
||||
int SV_GetSaveComment( const char *savename, char *comment );
|
||||
@@ -762,7 +811,7 @@ void Con_NPrintf( int idx, const char *fmt, ... ) FORMAT_CHECK( 2 );
|
||||
void Con_NXPrintf( con_nprint_t *info, const char *fmt, ... ) FORMAT_CHECK( 2 );
|
||||
void UI_NPrintf( int idx, const char *fmt, ... ) FORMAT_CHECK( 2 );
|
||||
void UI_NXPrintf( con_nprint_t *info, const char *fmt, ... ) FORMAT_CHECK( 2 );
|
||||
const char *Info_ValueForKey( const char *s, const char *key );
|
||||
const char *Info_ValueForKey( const char *s, const char *key ) RETURNS_NONNULL NONNULL;
|
||||
void Info_RemovePrefixedKeys( char *start, char prefix );
|
||||
qboolean Info_RemoveKey( char *s, const char *key );
|
||||
qboolean Info_SetValueForKey( char *s, const char *key, const char *value, int maxsize );
|
||||
@@ -845,13 +894,6 @@ void V_CheckGamma( void );
|
||||
void V_CheckGammaEnd( void );
|
||||
intptr_t V_GetGammaPtr( int parm );
|
||||
|
||||
//
|
||||
// identification.c
|
||||
//
|
||||
void ID_Init( void );
|
||||
const char *ID_GetMD5( void );
|
||||
void GAME_EXPORT ID_SetCustomClientID( const char *id );
|
||||
|
||||
//
|
||||
// masterlist.c
|
||||
//
|
||||
|
||||
@@ -498,7 +498,6 @@ static qboolean Cmd_GetSoundList( const char *s, char *completedname, int length
|
||||
return true;
|
||||
}
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
/*
|
||||
=====================================
|
||||
Cmd_GetItemsList
|
||||
@@ -508,6 +507,7 @@ Prints or complete item classname (weapons only)
|
||||
*/
|
||||
static qboolean Cmd_GetItemsList( const char *s, char *completedname, int length )
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
search_t *t;
|
||||
string matchbuf;
|
||||
int i, numitems;
|
||||
@@ -521,7 +521,7 @@ static qboolean Cmd_GetItemsList( const char *s, char *completedname, int length
|
||||
Q_strncpy( completedname, matchbuf, length );
|
||||
if( t->numfilenames == 1 ) return true;
|
||||
|
||||
for(i = 0, numitems = 0; i < t->numfilenames; i++)
|
||||
for( i = 0, numitems = 0; i < t->numfilenames; i++ )
|
||||
{
|
||||
if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "txt" ))
|
||||
continue;
|
||||
@@ -544,6 +544,8 @@ static qboolean Cmd_GetItemsList( const char *s, char *completedname, int length
|
||||
}
|
||||
}
|
||||
return true;
|
||||
#endif // !XASH_DEDICATED
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -555,6 +557,7 @@ Autocomplete for bind command
|
||||
*/
|
||||
static qboolean Cmd_GetKeysList( const char *s, char *completedname, int length )
|
||||
{
|
||||
#if !XASH_DEDICATED
|
||||
size_t i, numkeys;
|
||||
string keys[256];
|
||||
string matchbuf;
|
||||
@@ -595,8 +598,9 @@ static qboolean Cmd_GetKeysList( const char *s, char *completedname, int length
|
||||
}
|
||||
|
||||
return true;
|
||||
#endif // !XASH_DEDICATED
|
||||
return false;
|
||||
}
|
||||
#endif // XASH_DEDICATED
|
||||
|
||||
/*
|
||||
===============
|
||||
@@ -604,13 +608,20 @@ Con_AddCommandToList
|
||||
|
||||
===============
|
||||
*/
|
||||
static void Con_AddCommandToList( const char *s, const char *unused1, const char *unused2, void *_autocompleteList )
|
||||
static void Con_AddCommandToList( const char *s, const char *value, const void *ptoggle, void *_autocompleteList )
|
||||
{
|
||||
con_autocomplete_t *list = (con_autocomplete_t*)_autocompleteList;
|
||||
qboolean toggle = ptoggle != NULL && *(qboolean *)ptoggle;
|
||||
|
||||
if( *s == '@' ) return; // never show system cvars or cmds
|
||||
if( list->matchCount >= CON_MAXCMDS ) return; // list is full
|
||||
|
||||
if( toggle )
|
||||
{
|
||||
if( Q_strcmp( value, "0" ) && Q_strcmp( value, "1" ))
|
||||
return; // exclude non-toggable cvars
|
||||
}
|
||||
|
||||
if( Q_strnicmp( s, list->completionString, Q_strlen( list->completionString ) ) )
|
||||
return; // no match
|
||||
|
||||
@@ -634,13 +645,11 @@ Cmd_GetCommandsList
|
||||
Autocomplete for bind command
|
||||
=====================================
|
||||
*/
|
||||
static qboolean Cmd_GetCommandsList( const char *s, char *completedname, int length )
|
||||
static qboolean Cmd_GetCommandsAndCvarsList( const char *s, char *completedname, int length, qboolean cmds, qboolean cvars, qboolean toggle )
|
||||
{
|
||||
size_t i;
|
||||
string matchbuf;
|
||||
con_autocomplete_t list; // local autocomplete list
|
||||
|
||||
memset( &list, 0, sizeof( list ));
|
||||
con_autocomplete_t list = { 0 }; // local autocomplete list
|
||||
|
||||
list.completionString = s;
|
||||
|
||||
@@ -652,8 +661,16 @@ static qboolean Cmd_GetCommandsList( const char *s, char *completedname, int len
|
||||
return false;
|
||||
|
||||
// find matching commands and variables
|
||||
Cmd_LookupCmds( NULL, &list, (setpair_t)Con_AddCommandToList );
|
||||
Cvar_LookupVars( 0, NULL, &list, (setpair_t)Con_AddCommandToList );
|
||||
if( cvars )
|
||||
{
|
||||
Cvar_LookupVars( 0, &toggle, &list, (setpair_t)Con_AddCommandToList );
|
||||
}
|
||||
|
||||
if( cmds )
|
||||
{
|
||||
toggle = false;
|
||||
Cmd_LookupCmds( &toggle, &list, (setpair_t)Con_AddCommandToList );
|
||||
}
|
||||
|
||||
if( !list.matchCount ) return false;
|
||||
Q_strncpy( matchbuf, list.cmds[0], sizeof( matchbuf ));
|
||||
@@ -669,7 +686,7 @@ static qboolean Cmd_GetCommandsList( const char *s, char *completedname, int len
|
||||
Con_Printf( "%16s\n", matchbuf );
|
||||
}
|
||||
|
||||
Con_Printf( "\n^3 %i commands found.\n", list.matchCount );
|
||||
Con_Printf( "\n^3 %i %s found.\n", list.matchCount, cmds ? "commands" : "variables" );
|
||||
|
||||
if( completedname && length )
|
||||
{
|
||||
@@ -691,6 +708,30 @@ static qboolean Cmd_GetCommandsList( const char *s, char *completedname, int len
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================
|
||||
Cmd_GetCommandsList
|
||||
|
||||
Autocomplete for bind command
|
||||
=====================================
|
||||
*/
|
||||
static qboolean Cmd_GetCommandsList( const char *s, char *completedname, int length )
|
||||
{
|
||||
return Cmd_GetCommandsAndCvarsList( s, completedname, length, true, true, false );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================
|
||||
Cmd_GetCvarList
|
||||
|
||||
Autocomplete for bind command
|
||||
=====================================
|
||||
*/
|
||||
static qboolean Cmd_GetCvarsList( const char *s, char *completedname, int length )
|
||||
{
|
||||
qboolean toggle = !Q_stricmp( Cmd_Argv( 0 ), "toggle" );
|
||||
return Cmd_GetCommandsAndCvarsList( s, completedname, length, false, true, toggle );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================
|
||||
@@ -1010,36 +1051,38 @@ int GAME_EXPORT Cmd_CheckMapsList( int fRefresh )
|
||||
return Cmd_CheckMapsList_R( fRefresh, true );
|
||||
}
|
||||
|
||||
// keep this sorted
|
||||
static const autocomplete_list_t cmd_list[] =
|
||||
{
|
||||
{ "map_background", 1, Cmd_GetMapList },
|
||||
{ "bind", 1, Cmd_GetKeysList },
|
||||
{ "bind", 2, Cmd_GetCommandsList },
|
||||
{ "cd", 1, Cmd_GetCDList },
|
||||
{ "changelevel2", 1, Cmd_GetMapList },
|
||||
{ "changelevel", 1, Cmd_GetMapList },
|
||||
{ "playdemo", 1, Cmd_GetDemoList, },
|
||||
{ "timedemo", 1, Cmd_GetDemoList, },
|
||||
{ "listdemo", 1, Cmd_GetDemoList, },
|
||||
{ "playvol", 1, Cmd_GetSoundList },
|
||||
{ "hpkval", 1, Cmd_GetCustomList },
|
||||
{ "hpklist", 1, Cmd_GetCustomList },
|
||||
{ "hpkextract", 1, Cmd_GetCustomList },
|
||||
{ "entpatch", 1, Cmd_GetMapList },
|
||||
{ "music", 1, Cmd_GetMusicList, },
|
||||
{ "movie", 1, Cmd_GetMovieList },
|
||||
{ "exec", 1, Cmd_GetConfigList },
|
||||
#if !XASH_DEDICATED
|
||||
{ "give", 1, Cmd_GetItemsList },
|
||||
{ "drop", 1, Cmd_GetItemsList },
|
||||
{ "bind", 1, Cmd_GetKeysList },
|
||||
{ "unbind", 1, Cmd_GetKeysList },
|
||||
{ "bind", 2, Cmd_GetCommandsList },
|
||||
#endif
|
||||
{ "entpatch", 1, Cmd_GetMapList },
|
||||
{ "exec", 1, Cmd_GetConfigList },
|
||||
{ "game", 1, Cmd_GetGamesList },
|
||||
{ "save", 1, Cmd_GetSavesList },
|
||||
{ "give", 1, Cmd_GetItemsList },
|
||||
{ "hpkextract", 1, Cmd_GetCustomList },
|
||||
{ "hpklist", 1, Cmd_GetCustomList },
|
||||
{ "hpkval", 1, Cmd_GetCustomList },
|
||||
{ "listdemo", 1, Cmd_GetDemoList, },
|
||||
{ "load", 1, Cmd_GetSavesList },
|
||||
{ "play", 1, Cmd_GetSoundList },
|
||||
{ "map", 1, Cmd_GetMapList },
|
||||
{ "cd", 1, Cmd_GetCDList },
|
||||
{ "map_background", 1, Cmd_GetMapList },
|
||||
{ "movie", 1, Cmd_GetMovieList },
|
||||
{ "mp3", 1, Cmd_GetCDList },
|
||||
{ "music", 1, Cmd_GetMusicList, },
|
||||
{ "play", 1, Cmd_GetSoundList },
|
||||
{ "playdemo", 1, Cmd_GetDemoList, },
|
||||
{ "playvol", 1, Cmd_GetSoundList },
|
||||
{ "reset", 1, Cmd_GetCvarsList },
|
||||
{ "save", 1, Cmd_GetSavesList },
|
||||
{ "set", 1, Cmd_GetCvarsList },
|
||||
{ "timedemo", 1, Cmd_GetDemoList },
|
||||
{ "toggle", 1, Cmd_GetCvarsList },
|
||||
{ "unbind", 1, Cmd_GetKeysList },
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1160,6 +1203,7 @@ void Con_CompleteCommand( field_t *field )
|
||||
{
|
||||
field_t temp;
|
||||
string filename;
|
||||
qboolean toggle = false;
|
||||
qboolean nextcmd;
|
||||
int i;
|
||||
|
||||
@@ -1194,8 +1238,8 @@ void Con_CompleteCommand( field_t *field )
|
||||
con.shortestMatch[0] = 0;
|
||||
|
||||
// find matching commands and variables
|
||||
Cmd_LookupCmds( NULL, &con, (setpair_t)Con_AddCommandToList );
|
||||
Cvar_LookupVars( 0, NULL, &con, (setpair_t)Con_AddCommandToList );
|
||||
Cmd_LookupCmds( &toggle, &con, (setpair_t)Con_AddCommandToList );
|
||||
Cvar_LookupVars( 0, &toggle, &con, (setpair_t)Con_AddCommandToList );
|
||||
|
||||
if( !con.matchCount ) return; // no matches
|
||||
|
||||
@@ -1395,7 +1439,7 @@ void Host_WriteConfig( void )
|
||||
{
|
||||
Con_Reportf( "%s()\n", __func__ );
|
||||
FS_Printf( f, "//=======================================================================\n");
|
||||
FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), Q_buildcommit(), Q_buildbranch(), Q_buildos(), Q_buildarch());
|
||||
FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch());
|
||||
FS_Printf( f, "//\t\tconfig.cfg - archive of cvars\n" );
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
Key_WriteBindings( f );
|
||||
@@ -1443,7 +1487,7 @@ void GAME_EXPORT Host_WriteServerConfig( const char *name )
|
||||
if(( f = FS_Open( newconfigfile, "w", false )) != NULL )
|
||||
{
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), Q_buildcommit(), Q_buildbranch(), Q_buildos(), Q_buildarch());
|
||||
FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch());
|
||||
FS_Printf( f, "//\t\tgame.cfg - multiplayer server temporare config\n" );
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
|
||||
@@ -1478,7 +1522,7 @@ void Host_WriteOpenGLConfig( void )
|
||||
{
|
||||
Con_Reportf( "%s()\n", __func__ );
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), Q_buildcommit(), Q_buildbranch(), Q_buildos(), Q_buildarch());
|
||||
FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch());
|
||||
FS_Printf( f, "//\t\t%s - archive of renderer implementation cvars\n", name );
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
FS_Printf( f, "\n" );
|
||||
@@ -1508,7 +1552,7 @@ void Host_WriteVideoConfig( void )
|
||||
{
|
||||
Con_Reportf( "%s()\n", __func__ );
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), Q_buildcommit(), Q_buildbranch(), Q_buildos(), Q_buildarch());
|
||||
FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch());
|
||||
FS_Printf( f, "//\t\tvideo.cfg - archive of renderer variables\n");
|
||||
FS_Printf( f, "//=======================================================================\n" );
|
||||
Cvar_WriteVariables( f, FCVAR_RENDERINFO );
|
||||
@@ -1534,7 +1578,7 @@ void Key_EnumCmds_f( void )
|
||||
if( f )
|
||||
{
|
||||
FS_Printf( f, "//=======================================================================\n");
|
||||
FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), Q_buildcommit(), Q_buildbranch(), Q_buildos(), Q_buildarch());
|
||||
FS_Printf( f, "//\tGenerated by "XASH_ENGINE_NAME" (%i, %s, %s, %s-%s)\n", Q_buildnum(), g_buildcommit, g_buildbranch, Q_buildos(), Q_buildarch());
|
||||
FS_Printf( f, "//\t\thelp.txt - xash commands and console variables\n");
|
||||
FS_Printf( f, "//=======================================================================\n");
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ GNU General Public License for more details.
|
||||
#include "eiface.h" // ARRAYSIZE
|
||||
|
||||
static convar_t *cvar_vars = NULL; // head of list
|
||||
static poolhandle_t cvar_pool;
|
||||
CVAR_DEFINE_AUTO( cmd_scripting, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED, "enable simple condition checking and variable operations" );
|
||||
|
||||
typedef struct cvar_filter_quirks_s
|
||||
@@ -152,7 +153,7 @@ static qboolean Cvar_UpdateInfo( convar_t *var, const char *value, qboolean noti
|
||||
{
|
||||
if( FBitSet( var->flags, FCVAR_USERINFO ))
|
||||
{
|
||||
if ( Host_IsDedicated() )
|
||||
if( Host_IsDedicated() )
|
||||
{
|
||||
// g-cont. this is a very strange behavior...
|
||||
char *info = SV_Serverinfo();
|
||||
@@ -431,8 +432,9 @@ convar_t *Cvar_Get( const char *name, const char *value, int flags, const char *
|
||||
if( COM_CheckStringEmpty( var->desc ))
|
||||
{
|
||||
// directly set value
|
||||
freestring( var->string );
|
||||
var->string = copystring( value );
|
||||
size_t len = Q_strlen( value ) + 1;
|
||||
var->string = Mem_Realloc( cvar_pool, var->string, len );
|
||||
Q_strncpy( var->string, value, len );
|
||||
var->value = Q_atof( var->string );
|
||||
SetBits( var->flags, flags );
|
||||
|
||||
@@ -448,22 +450,25 @@ convar_t *Cvar_Get( const char *name, const char *value, int flags, const char *
|
||||
|
||||
if( FBitSet( var->flags, FCVAR_ALLOCATED ) && Q_strcmp( var_desc, var->desc ))
|
||||
{
|
||||
size_t len = Q_strlen( var_desc ) + 1;
|
||||
|
||||
if( !FBitSet( flags, FCVAR_GLCONFIG ))
|
||||
Con_Reportf( "%s change description from %s to %s\n", var->name, var->desc, var_desc );
|
||||
|
||||
// update description if needs
|
||||
freestring( var->desc );
|
||||
var->desc = copystring( var_desc );
|
||||
var->desc = Mem_Realloc( cvar_pool, var->desc, len );
|
||||
Q_strncpy( var->desc, var_desc, len );
|
||||
}
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
// allocate a new cvar
|
||||
var = Z_Malloc( sizeof( *var ));
|
||||
var->name = copystring( name );
|
||||
var->string = copystring( value );
|
||||
var->def_string = copystring( value );
|
||||
var->desc = copystring( var_desc );
|
||||
var = Mem_Malloc( cvar_pool, sizeof( *var ));
|
||||
var->name = copystringpool( cvar_pool, name );
|
||||
var->string = copystringpool( cvar_pool, value );
|
||||
var->def_string = copystringpool( cvar_pool, value );
|
||||
var->desc = copystringpool( cvar_pool, var_desc );
|
||||
var->value = Q_atof( var->string );
|
||||
var->flags = flags|FCVAR_ALLOCATED;
|
||||
|
||||
@@ -549,7 +554,7 @@ void Cvar_RegisterVariable( convar_t *var )
|
||||
if( FBitSet( var->flags, FCVAR_EXTENDED ))
|
||||
var->def_string = var->string; // just swap pointers
|
||||
|
||||
var->string = copystring( var->string );
|
||||
var->string = copystringpool( cvar_pool, var->string );
|
||||
var->value = Q_atof( var->string );
|
||||
|
||||
// find the supposed position in chain (alphanumerical order)
|
||||
@@ -601,9 +606,10 @@ Cvar_Set2
|
||||
static convar_t *Cvar_Set2( const char *var_name, const char *value )
|
||||
{
|
||||
convar_t *var;
|
||||
const char *pszValue;
|
||||
qboolean dll_variable = false;
|
||||
qboolean force = false;
|
||||
const char *fixed_string;
|
||||
size_t fixed_string_len;
|
||||
|
||||
if( !Cvar_ValidateVarName( var_name, false ))
|
||||
{
|
||||
@@ -667,19 +673,20 @@ static convar_t *Cvar_Set2( const char *var_name, const char *value )
|
||||
return var;
|
||||
}
|
||||
|
||||
pszValue = Cvar_ValidateString( var, value );
|
||||
fixed_string = Cvar_ValidateString( var, value );
|
||||
|
||||
// nothing to change
|
||||
if( !Q_strcmp( pszValue, var->string ))
|
||||
if( !Q_strcmp( fixed_string, var->string ))
|
||||
return var;
|
||||
|
||||
// fill it cls.userinfo, svs.serverinfo
|
||||
if( !Cvar_UpdateInfo( var, pszValue, true ))
|
||||
if( !Cvar_UpdateInfo( var, fixed_string, true ))
|
||||
return var;
|
||||
|
||||
// and finally changed the cvar itself
|
||||
freestring( var->string );
|
||||
var->string = copystring( pszValue );
|
||||
// and finally change the cvar itself
|
||||
fixed_string_len = Q_strlen( fixed_string ) + 1;
|
||||
var->string = Mem_Realloc( cvar_pool, var->string, fixed_string_len );
|
||||
Q_strncpy( var->string, fixed_string, fixed_string_len );
|
||||
var->value = Q_atof( var->string );
|
||||
|
||||
// tell engine about changes
|
||||
@@ -696,7 +703,8 @@ way to change value for many cvars
|
||||
*/
|
||||
void GAME_EXPORT Cvar_DirectSet( convar_t *var, const char *value )
|
||||
{
|
||||
const char *pszValue;
|
||||
const char *fixed_string;
|
||||
size_t fixed_string_len;
|
||||
|
||||
if( unlikely( !var )) return; // ???
|
||||
|
||||
@@ -726,19 +734,20 @@ void GAME_EXPORT Cvar_DirectSet( convar_t *var, const char *value )
|
||||
value = var->def_string; // reset to default value
|
||||
}
|
||||
|
||||
pszValue = Cvar_ValidateString( var, value );
|
||||
fixed_string = Cvar_ValidateString( var, value );
|
||||
|
||||
// nothing to change
|
||||
if( !Q_strcmp( pszValue, var->string ))
|
||||
if( !Q_strcmp( fixed_string, var->string ))
|
||||
return;
|
||||
|
||||
// fill it cls.userinfo, svs.serverinfo
|
||||
if( !Cvar_UpdateInfo( var, pszValue, true ))
|
||||
if( !Cvar_UpdateInfo( var, fixed_string, true ))
|
||||
return;
|
||||
|
||||
// and finally changed the cvar itself
|
||||
freestring( var->string );
|
||||
var->string = copystring( pszValue );
|
||||
// and finally change the cvar itself
|
||||
fixed_string_len = Q_strlen( fixed_string ) + 1;
|
||||
var->string = Mem_Realloc( cvar_pool, var->string, fixed_string_len );
|
||||
Q_strncpy( var->string, fixed_string, fixed_string_len );
|
||||
var->value = Q_atof( var->string );
|
||||
|
||||
// tell engine about changes
|
||||
@@ -772,7 +781,8 @@ can set any protected cvars
|
||||
*/
|
||||
void Cvar_FullSet( const char *var_name, const char *value, int flags )
|
||||
{
|
||||
convar_t *var = Cvar_FindVar( var_name );
|
||||
convar_t *var = Cvar_FindVar( var_name );
|
||||
size_t len = Q_strlen( value ) + 1;
|
||||
|
||||
if( !var )
|
||||
{
|
||||
@@ -780,8 +790,8 @@ void Cvar_FullSet( const char *var_name, const char *value, int flags )
|
||||
return;
|
||||
}
|
||||
|
||||
freestring( var->string );
|
||||
var->string = copystring( value );
|
||||
var->string = Mem_Realloc( cvar_pool, var->string, len );
|
||||
Q_strncpy( var->string, value, len );
|
||||
var->value = Q_atof( var->string );
|
||||
SetBits( var->flags, flags );
|
||||
|
||||
@@ -1020,9 +1030,11 @@ qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged )
|
||||
return true;
|
||||
}
|
||||
|
||||
#if !defined( XASH_HASHED_VARS )
|
||||
// check variables
|
||||
if( !v ) // already found in basecmd
|
||||
v = Cvar_FindVar( Cmd_Argv( 0 ));
|
||||
v = Cvar_FindVar( Cmd_Argv( 0 ));
|
||||
#endif
|
||||
|
||||
if( !v )
|
||||
return false;
|
||||
|
||||
@@ -1189,6 +1201,7 @@ static void Cvar_List_f( void )
|
||||
for( var = cvar_vars; var; var = var->next )
|
||||
{
|
||||
char value[MAX_VA_STRING];
|
||||
char *p;
|
||||
|
||||
if( var->name[0] == '@' )
|
||||
continue; // never shows system cvars
|
||||
@@ -1196,7 +1209,9 @@ static void Cvar_List_f( void )
|
||||
if( match && !Q_strnicmpext( match, var->name, matchlen ))
|
||||
continue;
|
||||
|
||||
if( Q_colorstr( var->string ))
|
||||
p = Q_strchr( var->string, '^' );
|
||||
|
||||
if( IsColorString( p ))
|
||||
Q_snprintf( value, sizeof( value ), "\"%s\"", var->string );
|
||||
else Q_snprintf( value, sizeof( value ), "\"^2%s^7\"", var->string );
|
||||
|
||||
@@ -1257,7 +1272,7 @@ pending_cvar_t *Cvar_PrepareToUnlink( int group )
|
||||
continue;
|
||||
|
||||
namelen = Q_strlen( cv->name ) + 1;
|
||||
p = Mem_Malloc( host.mempool, sizeof( *list ) + namelen );
|
||||
p = Mem_Malloc( cvar_pool, sizeof( *list ) + namelen );
|
||||
p->next = NULL;
|
||||
p->cv_cur = cv;
|
||||
p->cv_next = cv->next;
|
||||
@@ -1333,6 +1348,7 @@ Reads in all archived cvars
|
||||
*/
|
||||
void Cvar_Init( void )
|
||||
{
|
||||
cvar_pool = Mem_AllocPool( "Console Variables" );
|
||||
cvar_vars = NULL;
|
||||
cvar_active_filter_quirks = NULL;
|
||||
Cvar_RegisterVariable( &cmd_scripting );
|
||||
@@ -1345,6 +1361,11 @@ void Cvar_Init( void )
|
||||
Cmd_AddCommand( "cvarlist", Cvar_List_f, "display all console variables beginning with the specified prefix" );
|
||||
}
|
||||
|
||||
void Cvar_Shutdown( void )
|
||||
{
|
||||
Mem_FreePool( &cvar_pool );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_PostFSInit
|
||||
|
||||
@@ -30,6 +30,8 @@ typedef struct pending_cvar_s
|
||||
char cv_name[];
|
||||
} pending_cvar_t;
|
||||
|
||||
typedef void (*setpair_t)( const char *key, const void *value, const void *buffer, void *numpairs );
|
||||
|
||||
cvar_t *Cvar_GetList( void );
|
||||
#define Cvar_FindVar( name ) Cvar_FindVarExt( name, 0 )
|
||||
convar_t *Cvar_FindVarExt( const char *var_name, int ignore_group );
|
||||
@@ -52,6 +54,7 @@ void Cvar_Reset( const char *var_name );
|
||||
void Cvar_SetCheatState( void );
|
||||
qboolean Cvar_CommandWithPrivilegeCheck( convar_t *v, qboolean isPrivileged );
|
||||
void Cvar_Init( void );
|
||||
void Cvar_Shutdown( void );
|
||||
void Cvar_PostFSInit( void );
|
||||
void Cvar_Unlink( int group );
|
||||
|
||||
|
||||
@@ -49,52 +49,6 @@ const char *CL_MsgInfo( int cmd )
|
||||
return sz;
|
||||
}
|
||||
|
||||
int GAME_EXPORT CL_Active( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
qboolean CL_Initialized( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
qboolean CL_IsInGame( void )
|
||||
{
|
||||
return true; // always active for dedicated servers
|
||||
}
|
||||
|
||||
qboolean CL_IsInConsole( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
qboolean CL_IsIntermission( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
qboolean CL_IsPlaybackDemo( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
qboolean CL_IsRecordDemo( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
qboolean CL_DisableVisibility( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void CL_Init( void )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Key_Init( void )
|
||||
{
|
||||
|
||||
@@ -130,16 +84,6 @@ void CL_WriteMessageHistory( void )
|
||||
|
||||
}
|
||||
|
||||
void Host_ClientBegin( void )
|
||||
{
|
||||
Cbuf_Execute();
|
||||
}
|
||||
|
||||
void Host_ClientFrame( void )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Host_InputFrame( void )
|
||||
{
|
||||
}
|
||||
@@ -159,11 +103,6 @@ void GAME_EXPORT S_StopSound(int entnum, int channel, const char *soundname)
|
||||
|
||||
}
|
||||
|
||||
int GAME_EXPORT CL_GetMaxClients( void )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void IN_TouchInitConfig( void )
|
||||
{
|
||||
|
||||
@@ -174,11 +113,6 @@ void CL_Disconnect( void )
|
||||
|
||||
}
|
||||
|
||||
void CL_Shutdown( void )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void R_ClearStaticEntities( void )
|
||||
{
|
||||
|
||||
@@ -189,11 +123,6 @@ void Host_Credits( void )
|
||||
|
||||
}
|
||||
|
||||
qboolean UI_CreditsActive( void )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void S_StopBackgroundTrack( void )
|
||||
{
|
||||
|
||||
@@ -204,11 +133,6 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
|
||||
|
||||
}
|
||||
|
||||
int S_GetCurrentDynamicSounds( soundlist_t *pout, int size )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void S_StopAllSounds( qboolean ambient )
|
||||
{
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
filesystem.c - game filesystem based on DP fs
|
||||
Copyright (C) 2003-2006 Mathieu Olivier
|
||||
Copyright (C) 2000-2007 DarkPlaces contributors
|
||||
@@ -16,11 +16,23 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#if XASH_SDL == 2
|
||||
#include <SDL.h> // SDL_GetBasePath
|
||||
#elif XASH_SDL == 3
|
||||
#include <SDL3/SDL.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
#include "library.h"
|
||||
#include "platform/platform.h"
|
||||
|
||||
CVAR_DEFINE_AUTO( fs_mount_hd, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "mount high definition content folder" );
|
||||
CVAR_DEFINE_AUTO( fs_mount_lv, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "mount low violence models content folder" );
|
||||
CVAR_DEFINE_AUTO( fs_mount_addon, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "mount addon content folder" );
|
||||
CVAR_DEFINE_AUTO( fs_mount_l10n, "0", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "mount localization content folder" );
|
||||
CVAR_DEFINE_AUTO( ui_language, "english", FCVAR_ARCHIVE|FCVAR_PRIVILEGED|FCVAR_LATCH, "selected game language" );
|
||||
|
||||
fs_api_t g_fsapi;
|
||||
fs_globals_t *FI;
|
||||
|
||||
@@ -69,9 +81,23 @@ void *FS_GetNativeObject( const char *obj )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void FS_Rescan_f( void )
|
||||
void FS_Rescan_f( void )
|
||||
{
|
||||
FS_Rescan();
|
||||
uint32_t flags = 0;
|
||||
|
||||
// FIXME: VFS shouldn't care about this, allow engine to mount gamedirs
|
||||
if( fs_mount_lv.value ) SetBits( flags, FS_MOUNT_LV );
|
||||
if( fs_mount_hd.value ) SetBits( flags, FS_MOUNT_HD );
|
||||
if( fs_mount_addon.value ) SetBits( flags, FS_MOUNT_ADDON );
|
||||
if( fs_mount_l10n.value ) SetBits( flags, FS_MOUNT_L10N );
|
||||
|
||||
g_fsapi.Rescan( flags, ui_language.string );
|
||||
|
||||
ClearBits( fs_mount_lv.flags, FCVAR_CHANGED );
|
||||
ClearBits( fs_mount_hd.flags, FCVAR_CHANGED );
|
||||
ClearBits( fs_mount_addon.flags, FCVAR_CHANGED );
|
||||
ClearBits( fs_mount_l10n.flags, FCVAR_CHANGED );
|
||||
ClearBits( ui_language.flags, FCVAR_CHANGED );
|
||||
}
|
||||
|
||||
static void FS_ClearPaths_f( void )
|
||||
@@ -84,6 +110,11 @@ static void FS_Path_f_( void )
|
||||
FS_Path_f();
|
||||
}
|
||||
|
||||
static void FS_MakeGameInfo_f( void )
|
||||
{
|
||||
g_fsapi.MakeGameInfo();
|
||||
}
|
||||
|
||||
static const fs_interface_t fs_memfuncs =
|
||||
{
|
||||
Con_Printf,
|
||||
@@ -178,14 +209,23 @@ static qboolean FS_DetermineRootDirectory( char *out, size_t size )
|
||||
#elif XASH_PSVITA
|
||||
if( PSVita_GetBasePath( out, size ))
|
||||
return true;
|
||||
Sys_Error( "couldn't find Xash3D data directory" );
|
||||
Sys_Error( "couldn't find %s data directory", XASH_ENGINE_NAME );
|
||||
return false;
|
||||
#elif ( XASH_SDL == 2 ) && !XASH_NSWITCH // GetBasePath not impl'd in switch-sdl2
|
||||
#elif ( XASH_SDL >= 2 ) && !XASH_NSWITCH // GetBasePath not impl'd in switch-sdl2
|
||||
path = SDL_GetBasePath();
|
||||
|
||||
#if XASH_APPLE
|
||||
if( path != NULL && Q_stristr( path, ".app" ))
|
||||
{
|
||||
SDL_free((void *)path );
|
||||
path = SDL_GetPrefPath( NULL, XASH_ENGINE_NAME );
|
||||
}
|
||||
#endif
|
||||
|
||||
if( path != NULL )
|
||||
{
|
||||
Q_strncpy( out, path, size );
|
||||
SDL_free(( void *)path );
|
||||
SDL_free((void *)path );
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -222,6 +262,12 @@ static qboolean FS_DetermineReadOnlyRootDirectory( char *out, size_t size )
|
||||
return false;
|
||||
}
|
||||
|
||||
void FS_CheckConfig( void )
|
||||
{
|
||||
if( fs_mount_lv.value || fs_mount_hd.value || fs_mount_addon.value || fs_mount_l10n.value )
|
||||
FS_Rescan_f();
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
FS_Init
|
||||
@@ -272,12 +318,21 @@ void FS_Init( const char *basedir )
|
||||
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" );
|
||||
Cmd_AddRestrictedCommand( "fs_make_gameinfo", FS_MakeGameInfo_f, "create gameinfo.txt for current running game" );
|
||||
|
||||
Cvar_RegisterVariable( &fs_mount_hd );
|
||||
Cvar_RegisterVariable( &fs_mount_lv );
|
||||
Cvar_RegisterVariable( &fs_mount_addon );
|
||||
Cvar_RegisterVariable( &fs_mount_l10n );
|
||||
|
||||
if( !Sys_GetParmFromCmdLine( "-dll", host.gamedll ))
|
||||
host.gamedll[0] = 0;
|
||||
|
||||
if( !Sys_GetParmFromCmdLine( "-clientlib", host.clientlib ))
|
||||
host.clientlib[0] = 0;
|
||||
|
||||
if( !Sys_GetParmFromCmdLine( "-menulib", host.menulib ))
|
||||
host.menulib[0] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -14,9 +14,6 @@ GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "build.h"
|
||||
#ifdef XASH_SDL
|
||||
#include <SDL.h>
|
||||
#endif // XASH_SDL
|
||||
#include <stdarg.h> // va_args
|
||||
#if !XASH_WIN32
|
||||
#include <unistd.h> // fork
|
||||
@@ -43,6 +40,27 @@ GNU General Public License for more details.
|
||||
static pfnChangeGame pChangeGame = NULL;
|
||||
host_parm_t host; // host parms
|
||||
|
||||
#if XASH_ANDROID
|
||||
static jmp_buf return_from_main_buf;
|
||||
|
||||
/*
|
||||
===============
|
||||
Host_ExitInMain
|
||||
|
||||
On some platforms (e.g. Android) we can't exit with exit(3) as calling it would
|
||||
kill wrapper process (e.g. app_process) too early, before all resources would
|
||||
be freed, contexts released, files closed, etc, etc...
|
||||
|
||||
To fix this, we create jmp_buf in Host_Main function, when jumping into with
|
||||
non-zero value will immediately return from it with `error_on_exit`.
|
||||
===============
|
||||
*/
|
||||
void Host_ExitInMain( void )
|
||||
{
|
||||
longjmp( return_from_main_buf, 1 );
|
||||
}
|
||||
#endif // XASH_ANDROID
|
||||
|
||||
#ifdef XASH_ENGINE_TESTS
|
||||
struct tests_stats_s tests_stats;
|
||||
#endif
|
||||
@@ -56,7 +74,7 @@ static CVAR_DEFINE_AUTO( host_gameloaded, "0", FCVAR_READ_ONLY, "inidcates a loa
|
||||
static CVAR_DEFINE_AUTO( host_clientloaded, "0", FCVAR_READ_ONLY, "inidcates a loaded client.dll" );
|
||||
CVAR_DEFINE_AUTO( host_limitlocal, "0", 0, "apply cl_cmdrate and rate to loopback connection" );
|
||||
CVAR_DEFINE( host_maxfps, "fps_max", "72", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "host fps upper limit" );
|
||||
CVAR_DEFINE_AUTO( fps_override, "1", FCVAR_FILTERABLE, "unlock higher framerate values, not supported" );
|
||||
CVAR_DEFINE_AUTO( fps_override, "0", FCVAR_FILTERABLE, "unlock higher framerate values, not supported" );
|
||||
static CVAR_DEFINE_AUTO( host_framerate, "0", FCVAR_FILTERABLE, "locks frame timing to this value in seconds" );
|
||||
static CVAR_DEFINE( host_sleeptime, "sleeptime", "1", FCVAR_ARCHIVE|FCVAR_FILTERABLE, "milliseconds to sleep for each frame. higher values reduce fps accuracy" );
|
||||
static CVAR_DEFINE_AUTO( host_sleeptime_debug, "0", 0, "print sleeps between frames" );
|
||||
@@ -119,7 +137,8 @@ static void Sys_PrintUsage( const char *exename )
|
||||
|
||||
"\nCommon options:\n"
|
||||
O("-dev [level] ", "set log verbosity 0-2")
|
||||
O("-log ", "write log to \"engine.log\"")
|
||||
O("-log [file name] ", "write log to \"engine.log\" or [file name] if specified")
|
||||
O("-logtime ", "enable writing timestamps to the log file")
|
||||
O("-nowriteconfig ", "disable config save")
|
||||
O("-noch ", "disable crashhandler")
|
||||
#if XASH_WIN32 // !!!!
|
||||
@@ -155,6 +174,7 @@ static void Sys_PrintUsage( const char *exename )
|
||||
O("-dll <path> ", "override server DLL path")
|
||||
#if !XASH_DEDICATED
|
||||
O("-clientlib <path> ", "override client DLL path")
|
||||
O("-menulib <path> ", "override menu DLL path")
|
||||
O("-console ", "run engine with console enabled")
|
||||
O("-toconsole ", "run engine witn console open")
|
||||
O("-oldfont ", "enable unused Quake font in Half-Life")
|
||||
@@ -180,7 +200,6 @@ static void Sys_PrintUsage( const char *exename )
|
||||
O("-daemonize ", "run engine as a daemon")
|
||||
#endif
|
||||
#if XASH_SDL == 2
|
||||
O("-sdl_joy_old_api ","use SDL legacy joystick API")
|
||||
O("-sdl_renderer <n> ","use alternative SDL_Renderer for software")
|
||||
#endif // XASH_SDL
|
||||
#if XASH_ANDROID && !XASH_SDL
|
||||
@@ -209,7 +228,7 @@ static void Sys_PrintUsage( const char *exename )
|
||||
fprintf( stderr, usage_str, exename );
|
||||
#endif
|
||||
|
||||
Sys_Quit();
|
||||
Sys_Quit( NULL );
|
||||
}
|
||||
|
||||
static void Sys_PrintBugcompUsage( const char *exename )
|
||||
@@ -234,7 +253,7 @@ static void Sys_PrintBugcompUsage( const char *exename )
|
||||
fprintf( stderr, usage_str, exename );
|
||||
#endif
|
||||
|
||||
Sys_Quit();
|
||||
Sys_Quit( NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -362,9 +381,8 @@ static void Host_NewInstance( const char *name, const char *finalmsg )
|
||||
if( !pChangeGame ) return;
|
||||
|
||||
host.change_game = true;
|
||||
Q_strncpy( host.finalmsg, finalmsg, sizeof( host.finalmsg ));
|
||||
|
||||
if( !Sys_NewInstance( name ))
|
||||
if( !Sys_NewInstance( name, finalmsg ))
|
||||
pChangeGame( name ); // call from hl.exe
|
||||
}
|
||||
|
||||
@@ -418,8 +436,7 @@ static void Host_Exec_f( void )
|
||||
{
|
||||
string cfgpath;
|
||||
byte *f;
|
||||
char *txt;
|
||||
fs_offset_t len;
|
||||
fs_offset_t len;
|
||||
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
@@ -474,20 +491,29 @@ static void Host_Exec_f( void )
|
||||
return;
|
||||
}
|
||||
|
||||
// len is fs_offset_t, which can be larger than size_t
|
||||
if( len >= SIZE_MAX )
|
||||
{
|
||||
Con_Reportf( "%s: %s is too long\n", __func__, Cmd_Argv( 1 ));
|
||||
return;
|
||||
}
|
||||
|
||||
if( !Q_stricmp( "config.cfg", cfgpath ))
|
||||
host.config_executed = true;
|
||||
|
||||
// adds \n\0 at end of the file
|
||||
txt = Z_Calloc( len + 2 );
|
||||
memcpy( txt, f, len );
|
||||
txt[len] = '\n';
|
||||
txt[len + 1] = '\0';
|
||||
Mem_Free( f );
|
||||
|
||||
if( !host.apply_game_config )
|
||||
Con_Printf( "execing %s\n", Cmd_Argv( 1 ));
|
||||
Cbuf_InsertText( txt );
|
||||
Mem_Free( txt );
|
||||
|
||||
// adds \n at end of the file
|
||||
// FS_LoadFile always null terminates
|
||||
if( f[len - 1] != '\n' )
|
||||
{
|
||||
Cbuf_InsertTextLen( f, len, len + 1 );
|
||||
Cbuf_InsertTextLen( "\n", 1, 1 );
|
||||
}
|
||||
else Cbuf_InsertTextLen( f, len, len );
|
||||
|
||||
Mem_Free( f );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -513,13 +539,6 @@ static void Host_MemStats_f( void )
|
||||
}
|
||||
}
|
||||
|
||||
static void Host_Minimize_f( void )
|
||||
{
|
||||
#ifdef XASH_SDL
|
||||
if( host.hWnd ) SDL_MinimizeWindow( host.hWnd );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Host_RegisterDecal
|
||||
@@ -670,17 +689,17 @@ static qboolean Host_Autosleep( double dt, double scale )
|
||||
static double timewindow; // allocate a time window for sleeps
|
||||
static int counter; // for debug
|
||||
static double realsleeptime;
|
||||
const double sleeptime = sleep * 0.001;
|
||||
const double sleeptime = sleep * 0.000001;
|
||||
|
||||
if( dt < targetframetime * scale )
|
||||
{
|
||||
// if we have allocated time window, try to sleep
|
||||
if( timewindow > realsleeptime )
|
||||
{
|
||||
// Platform_Sleep isn't guaranteed to sleep an exact amount of milliseconds
|
||||
// Platform_Sleep isn't guaranteed to sleep an exact amount of microseconds
|
||||
// so we measure the real sleep time and use it to decrease the window
|
||||
double t1 = Sys_DoubleTime(), t2;
|
||||
Platform_Sleep( sleep ); // in msec!
|
||||
Platform_NanoSleep( sleep * 1000 ); // in usec!
|
||||
t2 = Sys_DoubleTime();
|
||||
realsleeptime = t2 - t1;
|
||||
|
||||
@@ -809,11 +828,11 @@ void GAME_EXPORT Host_Error( const char *error, ... )
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_Printf( "%s: %s", __func__, hosterror1 );
|
||||
if( host.allow_console )
|
||||
{
|
||||
UI_SetActiveMenu( false );
|
||||
Key_SetKeyDest( key_console );
|
||||
Con_Printf( "%s: %s", __func__, hosterror1 );
|
||||
}
|
||||
else Platform_MessageBox( "Host Error", hosterror1, true );
|
||||
}
|
||||
@@ -830,7 +849,6 @@ void GAME_EXPORT Host_Error( const char *error, ... )
|
||||
recursive = true;
|
||||
Q_strncpy( hosterror2, hosterror1, sizeof( hosterror2 ));
|
||||
host.errorframe = host.framecount; // to avoid multply calls per frame
|
||||
Q_snprintf( host.finalmsg, sizeof( host.finalmsg ), "Server crashed: %s", hosterror1 );
|
||||
|
||||
// clearing cmd buffer to prevent execute any commands
|
||||
COM_InitHostState();
|
||||
@@ -915,7 +933,7 @@ static void Host_RunTests( int stage )
|
||||
#endif
|
||||
Msg( "Done! %d passed, %d failed\n", tests_stats.passed, tests_stats.failed );
|
||||
error_on_exit = tests_stats.failed > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
Sys_Quit();
|
||||
Sys_Quit( NULL );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1017,7 +1035,7 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
|
||||
}
|
||||
|
||||
if( !Sys_CheckParm( "-noch" ))
|
||||
Sys_SetupCrashHandler();
|
||||
Sys_SetupCrashHandler( argv[0] );
|
||||
|
||||
#if XASH_DLL_LOADER
|
||||
host.enabledll = !Sys_CheckParm( "-nodll" );
|
||||
@@ -1104,7 +1122,7 @@ static void Host_InitCommon( int argc, char **argv, const char *progname, qboole
|
||||
#if XASH_DEDICATED
|
||||
Platform_SetupSigtermHandling();
|
||||
#endif
|
||||
Platform_Init( Host_IsDedicated( ) || developer >= DEV_EXTENDED );
|
||||
Platform_Init( Host_IsDedicated( ) || developer >= DEV_EXTENDED, basedir );
|
||||
FS_Init( basedir );
|
||||
|
||||
Sys_InitLog();
|
||||
@@ -1162,6 +1180,11 @@ static void Host_FreeCommon( void )
|
||||
FS_Shutdown();
|
||||
}
|
||||
|
||||
static void Sys_Quit_f( void )
|
||||
{
|
||||
Sys_Quit( "command" );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Host_Main
|
||||
@@ -1201,9 +1224,17 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
|
||||
Cvar_Getf( "buildnum", FCVAR_READ_ONLY, "returns a current build number", "%i", Q_buildnum_compat());
|
||||
Cvar_Getf( "ver", FCVAR_READ_ONLY, "shows an engine version", "%i/%s (hw build %i)", PROTOCOL_VERSION, XASH_COMPAT_VERSION, Q_buildnum_compat());
|
||||
Cvar_Getf( "host_ver", FCVAR_READ_ONLY, "detailed info about this build", "%i " XASH_VERSION " %s %s %s", Q_buildnum(), Q_buildos(), Q_buildarch(), Q_buildcommit());
|
||||
Cvar_Getf( "host_ver", FCVAR_READ_ONLY, "detailed info about this build", "%i " XASH_VERSION " %s %s %s", Q_buildnum(), Q_buildos(), Q_buildarch(), g_buildcommit);
|
||||
Cvar_Getf( "host_lowmemorymode", FCVAR_READ_ONLY, "indicates if engine compiled for low RAM consumption (0 - normal, 1 - low engine limits, 2 - low protocol limits)", "%i", XASH_LOW_MEMORY );
|
||||
|
||||
Cvar_Get( "host_hl25_extended_structs",
|
||||
#if SUPPORT_HL25_EXTENDED_STRUCTS
|
||||
"1",
|
||||
#else
|
||||
"0",
|
||||
#endif
|
||||
FCVAR_READ_ONLY, "indicates if engine was compiled with extended msurface_t struct" );
|
||||
|
||||
Mod_Init();
|
||||
NET_Init();
|
||||
NET_InitMasters();
|
||||
@@ -1224,7 +1255,6 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
CL_Init();
|
||||
|
||||
HTTP_Init();
|
||||
ID_Init();
|
||||
SoundList_Init();
|
||||
|
||||
if( Host_IsDedicated( ))
|
||||
@@ -1236,10 +1266,10 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
// disable texture replacements for dedicated
|
||||
Cvar_FullSet( "host_allow_materials", "0", FCVAR_READ_ONLY );
|
||||
|
||||
Cmd_AddRestrictedCommand( "quit", Sys_Quit, "quit the game" );
|
||||
Cmd_AddRestrictedCommand( "exit", Sys_Quit, "quit the game" );
|
||||
Cmd_AddRestrictedCommand( "quit", Sys_Quit_f, "quit the game" );
|
||||
Cmd_AddRestrictedCommand( "exit", Sys_Quit_f, "quit the game" );
|
||||
}
|
||||
else Cmd_AddRestrictedCommand( "minimize", Host_Minimize_f, "minimize main window to tray" );
|
||||
else Cmd_AddRestrictedCommand( "minimize", Platform_Minimize_f, "minimize main window to tray" );
|
||||
|
||||
host.errorframe = 0;
|
||||
|
||||
@@ -1280,6 +1310,7 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
Cmd_RemoveCommand( "setgl" );
|
||||
Cbuf_ExecStuffCmds(); // execute stuffcmds (commandline)
|
||||
SCR_CheckStartupVids(); // must be last
|
||||
FS_CheckConfig();
|
||||
|
||||
if( Sys_GetParmFromCmdLine( "-timedemo", demoname ))
|
||||
Cbuf_AddTextf( "timedemo %s\n", demoname );
|
||||
@@ -1308,8 +1339,13 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
// check after all configs were executed
|
||||
HPAK_CheckIntegrity( hpk_custom_file.string );
|
||||
|
||||
#if XASH_ANDROID
|
||||
if( setjmp( return_from_main_buf ))
|
||||
return error_on_exit;
|
||||
#endif // XASH_ANDROID
|
||||
|
||||
// main window message loop
|
||||
while( !host.crashed )
|
||||
while( host.status != HOST_CRASHED )
|
||||
{
|
||||
newtime = Sys_DoubleTime ();
|
||||
COM_Frame( newtime - oldtime );
|
||||
@@ -1320,20 +1356,31 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EXPORT Host_Shutdown( void );
|
||||
void EXPORT Host_Shutdown( void )
|
||||
{
|
||||
Host_ShutdownWithReason( "launcher shutdown" );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Host_Shutdown
|
||||
=================
|
||||
*/
|
||||
void EXPORT Host_Shutdown( void )
|
||||
void Host_ShutdownWithReason( const char *reason )
|
||||
{
|
||||
qboolean error = host.status == HOST_ERR_FATAL;
|
||||
|
||||
if( host.shutdown_issued ) return;
|
||||
if( host.shutdown_issued )
|
||||
return;
|
||||
|
||||
host.shutdown_issued = true;
|
||||
|
||||
if( host.status != HOST_ERR_FATAL ) host.status = HOST_SHUTDOWN; // prepare host to normal shutdown
|
||||
if( !host.change_game ) Q_strncpy( host.finalmsg, "Server shutdown", sizeof( host.finalmsg ));
|
||||
if( reason != NULL )
|
||||
Con_Printf( S_NOTE "Issuing host shutdown due to reason \"%s\"\n", reason );
|
||||
|
||||
if( host.status != HOST_ERR_FATAL )
|
||||
host.status = HOST_SHUTDOWN; // prepare host to normal shutdown
|
||||
|
||||
#if !XASH_DEDICATED
|
||||
if( host.type == HOST_NORMAL && !error )
|
||||
@@ -1352,10 +1399,14 @@ void EXPORT Host_Shutdown( void )
|
||||
Host_FreeCommon();
|
||||
Platform_Shutdown();
|
||||
|
||||
BaseCmd_Shutdown();
|
||||
Cmd_Shutdown();
|
||||
Cvar_Shutdown();
|
||||
|
||||
// must be last, console uses this
|
||||
Mem_FreePool( &host.mempool );
|
||||
|
||||
// restore filter
|
||||
Sys_RestoreCrashHandler();
|
||||
Sys_CloseLog();
|
||||
Sys_CloseLog( reason );
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ static void HPAK_MaxSize_f( void )
|
||||
Con_Printf( S_ERROR "hpk_maxsize is deprecated, use hpk_max_size\n" );
|
||||
}
|
||||
|
||||
static const char *HPAK_TypeFromIndex( int type )
|
||||
const char *COM_ResourceTypeFromIndex( int type )
|
||||
{
|
||||
switch( type )
|
||||
{
|
||||
@@ -104,7 +104,7 @@ static void HPAK_CreatePak( const char *filename, resource_t *pResource, byte *p
|
||||
string pakname;
|
||||
byte md5[16];
|
||||
file_t *fout;
|
||||
MD5Context_t ctx;
|
||||
MD5Context_t ctx = { 0 };
|
||||
|
||||
if( !COM_CheckString( filename ))
|
||||
return;
|
||||
@@ -125,7 +125,6 @@ static void HPAK_CreatePak( const char *filename, resource_t *pResource, byte *p
|
||||
}
|
||||
|
||||
// let's hash it.
|
||||
memset( &ctx, 0, sizeof( MD5Context_t ));
|
||||
MD5Init( &ctx );
|
||||
|
||||
if( pData == NULL )
|
||||
@@ -214,19 +213,18 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource,
|
||||
file_t *file_src;
|
||||
file_t *file_dst;
|
||||
byte md5[16];
|
||||
MD5Context_t ctx;
|
||||
MD5Context_t ctx = { 0 };
|
||||
|
||||
if( pData == NULL && pFile == NULL )
|
||||
return;
|
||||
|
||||
if( pResource->nDownloadSize < HPAK_ENTRY_MIN_SIZE || pResource->nDownloadSize > HPAK_ENTRY_MAX_SIZE )
|
||||
{
|
||||
Con_Printf( S_ERROR "%s: invalid size %s\n", name, Q_pretifymem( pResource->nDownloadSize, 2 ));
|
||||
Con_Printf( S_ERROR "%s: invalid size %s\n", name, Q_memprint( pResource->nDownloadSize ));
|
||||
return;
|
||||
}
|
||||
|
||||
// hash it
|
||||
memset( &ctx, 0, sizeof( MD5Context_t ));
|
||||
MD5Init( &ctx );
|
||||
|
||||
if( !pData )
|
||||
@@ -443,7 +441,7 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
|
||||
if( dataDir[i].disksize < HPAK_ENTRY_MIN_SIZE || dataDir[i].disksize > HPAK_ENTRY_MAX_SIZE )
|
||||
{
|
||||
// odd max size
|
||||
Con_DPrintf( S_ERROR "%s: lump %i has invalid size %s\n", __func__, i, Q_pretifymem( dataDir[i].disksize, 2 ));
|
||||
Con_DPrintf( S_ERROR "%s: lump %i has invalid size %s\n", __func__, i, Q_memprint( dataDir[i].disksize ));
|
||||
Mem_Free( dataDir );
|
||||
FS_Close( f );
|
||||
if( delete ) FS_Delete( pakname );
|
||||
@@ -463,8 +461,8 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet, qboolean de
|
||||
|
||||
if( !quiet )
|
||||
{
|
||||
Con_Printf( "%i: %s %s %s: ", i, HPAK_TypeFromIndex( pRes->type ),
|
||||
Q_pretifymem( pRes->nDownloadSize, 2 ), pRes->szFileName );
|
||||
Con_Printf( "%i: %s %s %s: ", i, COM_ResourceTypeFromIndex( pRes->type ),
|
||||
Q_memprint( pRes->nDownloadSize ), pRes->szFileName );
|
||||
}
|
||||
|
||||
if( memcmp( md5, pRes->rgucMD5_hash, 0x10 ))
|
||||
@@ -944,7 +942,7 @@ static void HPAK_List_f( void )
|
||||
{
|
||||
entry = &directory.entries[nCurrent];
|
||||
COM_FileBase( entry->resource.szFileName, lumpname, sizeof( lumpname ));
|
||||
type = HPAK_TypeFromIndex( entry->resource.type );
|
||||
type = COM_ResourceTypeFromIndex( entry->resource.type );
|
||||
size = Q_memprint( entry->resource.nDownloadSize );
|
||||
|
||||
Con_Printf( "%i: %10s %s %s\n : %s\n", nCurrent + 1, type, size, lumpname, MD5_Print( entry->resource.rgucMD5_hash ));
|
||||
@@ -1039,7 +1037,7 @@ static void HPAK_Extract_f( void )
|
||||
continue;
|
||||
|
||||
COM_FileBase( entry->resource.szFileName, lumpname, sizeof( lumpname ) );
|
||||
type = HPAK_TypeFromIndex( entry->resource.type );
|
||||
type = COM_ResourceTypeFromIndex( entry->resource.type );
|
||||
size = Q_memprint( entry->resource.nDownloadSize );
|
||||
|
||||
Con_Printf( "Extracting %i: %10s %s %s\n", nCurrent + 1, type, size, lumpname );
|
||||
|
||||
@@ -45,7 +45,6 @@ typedef enum
|
||||
|
||||
typedef struct loadformat_s
|
||||
{
|
||||
const char *formatstring;
|
||||
const char *ext;
|
||||
qboolean (*loadfunc)( const char *name, const byte *buffer, fs_offset_t filesize );
|
||||
image_hint_t hint;
|
||||
@@ -53,7 +52,6 @@ typedef struct loadformat_s
|
||||
|
||||
typedef struct saveformat_s
|
||||
{
|
||||
const char *formatstring;
|
||||
const char *ext;
|
||||
qboolean (*savefunc)( const char *name, rgbdata_t *pix );
|
||||
} savepixformat_t;
|
||||
|
||||
@@ -211,7 +211,7 @@ static const loadpixformat_t *Image_GetLoadFormatForExtension( const char *ext )
|
||||
if( !COM_CheckStringEmpty( ext ))
|
||||
return NULL;
|
||||
|
||||
for( format = image.loadformats; format->formatstring; format++ )
|
||||
for( format = image.loadformats; format->ext; format++ )
|
||||
{
|
||||
if( !Q_stricmp( ext, format->ext ))
|
||||
return format;
|
||||
@@ -237,7 +237,7 @@ static qboolean Image_ProbeLoadBuffer( const loadpixformat_t *fmt, const char *n
|
||||
// bruteforce all loaders
|
||||
if( !fmt )
|
||||
{
|
||||
for( fmt = image.loadformats; fmt->formatstring; fmt++ )
|
||||
for( fmt = image.loadformats; fmt->ext; fmt++ )
|
||||
{
|
||||
if( Image_ProbeLoadBuffer_( fmt, name, buf, size, override_hint ))
|
||||
return true;
|
||||
@@ -256,7 +256,7 @@ static qboolean Image_ProbeLoad_( const loadpixformat_t *fmt, const char *name,
|
||||
string path;
|
||||
byte *f;
|
||||
|
||||
Q_snprintf( path, sizeof( path ), fmt->formatstring, name, suffix, fmt->ext );
|
||||
Q_snprintf( path, sizeof( path ), "%s%s.%s", name, suffix, fmt->ext );
|
||||
f = FS_LoadFile( path, &filesize, false );
|
||||
|
||||
if( f )
|
||||
@@ -274,7 +274,7 @@ static qboolean Image_ProbeLoad( const loadpixformat_t *fmt, const char *name, c
|
||||
if( !fmt )
|
||||
{
|
||||
// bruteforce all formats to allow implicit extension
|
||||
for( fmt = image.loadformats; fmt->formatstring; fmt++ )
|
||||
for( fmt = image.loadformats; fmt->ext; fmt++ )
|
||||
{
|
||||
if( Image_ProbeLoad_( fmt, name, suffix, override_hint ))
|
||||
return true;
|
||||
@@ -417,14 +417,13 @@ qboolean FS_SaveImage( const char *filename, rgbdata_t *pix )
|
||||
picBuffer = pix->buffer;
|
||||
|
||||
// save all sides seperately
|
||||
for( format = image.saveformats; format && format->formatstring; format++ )
|
||||
for( format = image.saveformats; format && format->ext; format++ )
|
||||
{
|
||||
if( !Q_stricmp( ext, format->ext ))
|
||||
{
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
Q_snprintf( path, sizeof( path ),
|
||||
format->formatstring, savename, box[i].suf, format->ext );
|
||||
Q_snprintf( path, sizeof( path ), "%s%s.%s", savename, box[i].suf, format->ext );
|
||||
if( !format->savefunc( path, pix )) break; // there were errors
|
||||
pix->buffer += pix->size; // move pointer
|
||||
}
|
||||
@@ -442,12 +441,11 @@ qboolean FS_SaveImage( const char *filename, rgbdata_t *pix )
|
||||
}
|
||||
else
|
||||
{
|
||||
for( format = image.saveformats; format && format->formatstring; format++ )
|
||||
for( format = image.saveformats; format && format->ext; format++ )
|
||||
{
|
||||
if( !Q_stricmp( ext, format->ext ))
|
||||
{
|
||||
Q_snprintf( path, sizeof( path ),
|
||||
format->formatstring, savename, "", format->ext );
|
||||
Q_snprintf( path, sizeof( path ), "%s.%s", savename, format->ext );
|
||||
if( format->savefunc( path, pix ))
|
||||
{
|
||||
// clear any force flags
|
||||
|
||||
@@ -46,7 +46,7 @@ qboolean Image_LoadPNG( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
short p, a, b, c, pa, pb, pc;
|
||||
byte *buf_p, *pixbuf, *raw, *prior, *idat_buf = NULL, *uncompressed_buffer = NULL;
|
||||
byte *pallete = NULL, *trns = NULL;
|
||||
uint chunk_len, trns_len, plte_len, crc32, crc32_check, oldsize = 0, newsize = 0, rowsize;
|
||||
uint chunk_len, trns_len = 0, plte_len = 0, crc32, crc32_check, oldsize = 0, newsize = 0, rowsize;
|
||||
uint uncompressed_size, pixel_size, pixel_count, i, y, filter_type, chunk_sign, r_alpha, g_alpha, b_alpha;
|
||||
qboolean has_iend_chunk = false;
|
||||
z_stream stream = {0};
|
||||
|
||||
@@ -90,23 +90,23 @@ static byte palette_hl[768] =
|
||||
// stub
|
||||
static const loadpixformat_t load_null[] =
|
||||
{
|
||||
{ NULL, NULL, NULL, IL_HINT_NO }
|
||||
{ NULL, NULL, IL_HINT_NO }
|
||||
};
|
||||
|
||||
static const loadpixformat_t load_game[] =
|
||||
{
|
||||
{ "%s%s.%s", "dds", Image_LoadDDS, IL_HINT_NO }, // dds for world and studio models
|
||||
{ "%s%s.%s", "bmp", Image_LoadBMP, IL_HINT_NO }, // WON menu images
|
||||
{ "%s%s.%s", "tga", Image_LoadTGA, IL_HINT_NO }, // hl vgui menus
|
||||
{ "%s%s.%s", "png", Image_LoadPNG, IL_HINT_NO }, // NightFire 007 menus
|
||||
{ "%s%s.%s", "mip", Image_LoadMIP, IL_HINT_NO }, // hl textures from wad or buffer
|
||||
{ "%s%s.%s", "mdl", Image_LoadMDL, IL_HINT_HL }, // hl studio model skins
|
||||
{ "%s%s.%s", "spr", Image_LoadSPR, IL_HINT_HL }, // hl sprite frames
|
||||
{ "%s%s.%s", "lmp", Image_LoadLMP, IL_HINT_NO }, // hl menu images (cached.wad etc)
|
||||
{ "%s%s.%s", "fnt", Image_LoadFNT, IL_HINT_HL }, // hl console font (fonts.wad etc)
|
||||
{ "%s%s.%s", "pal", Image_LoadPAL, IL_HINT_NO }, // install studio\sprite palette
|
||||
{ "%s%s.%s", "ktx2", Image_LoadKTX2, IL_HINT_NO }, // ktx2 for world and studio models
|
||||
{ NULL, NULL, NULL, IL_HINT_NO }
|
||||
{ "dds", Image_LoadDDS, IL_HINT_NO }, // dds for world and studio models
|
||||
{ "bmp", Image_LoadBMP, IL_HINT_NO }, // WON menu images
|
||||
{ "tga", Image_LoadTGA, IL_HINT_NO }, // hl vgui menus
|
||||
{ "png", Image_LoadPNG, IL_HINT_NO }, // NightFire 007 menus
|
||||
{ "mip", Image_LoadMIP, IL_HINT_NO }, // hl textures from wad or buffer
|
||||
{ "mdl", Image_LoadMDL, IL_HINT_HL }, // hl studio model skins
|
||||
{ "spr", Image_LoadSPR, IL_HINT_HL }, // hl sprite frames
|
||||
{ "lmp", Image_LoadLMP, IL_HINT_NO }, // hl menu images (cached.wad etc)
|
||||
{ "fnt", Image_LoadFNT, IL_HINT_HL }, // hl console font (fonts.wad etc)
|
||||
{ "pal", Image_LoadPAL, IL_HINT_NO }, // install studio\sprite palette
|
||||
{ "ktx2", Image_LoadKTX2, IL_HINT_NO }, // ktx2 for world and studio models
|
||||
{ NULL, NULL, IL_HINT_NO }
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -119,16 +119,16 @@ static const loadpixformat_t load_game[] =
|
||||
// stub
|
||||
static const savepixformat_t save_null[] =
|
||||
{
|
||||
{ NULL, NULL, NULL }
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
// Xash3D normal instance
|
||||
static const savepixformat_t save_game[] =
|
||||
{
|
||||
{ "%s%s.%s", "tga", Image_SaveTGA }, // tga screenshots
|
||||
{ "%s%s.%s", "bmp", Image_SaveBMP }, // bmp levelshots or screenshots
|
||||
{ "%s%s.%s", "png", Image_SavePNG }, // png screenshots
|
||||
{ NULL, NULL, NULL }
|
||||
{ "tga", Image_SaveTGA }, // tga screenshots
|
||||
{ "bmp", Image_SaveBMP }, // bmp levelshots or screenshots
|
||||
{ "png", Image_SavePNG }, // png screenshots
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
void Image_Setup( void )
|
||||
|
||||
@@ -28,12 +28,20 @@ Image_LoadPAL
|
||||
qboolean Image_LoadPAL( const char *name, const byte *buffer, fs_offset_t filesize )
|
||||
{
|
||||
int rendermode = LUMP_NORMAL;
|
||||
byte pal[768];
|
||||
|
||||
if( filesize != 768 )
|
||||
if( filesize > sizeof( pal ))
|
||||
{
|
||||
Con_DPrintf( S_ERROR "%s: (%s) have invalid size (%li should be %d)\n", __func__, name, (long)filesize, 768 );
|
||||
Con_DPrintf( S_ERROR "%s: (%s) have invalid size (%li should be less or equal than %zu)\n", __func__, name, (long)filesize, sizeof( pal ));
|
||||
return false;
|
||||
}
|
||||
else if( filesize < sizeof( pal ) && buffer != NULL )
|
||||
{
|
||||
// palette might be truncated, fill it with zeros
|
||||
memset( pal, 0, sizeof( pal ));
|
||||
memcpy( pal, buffer, filesize );
|
||||
buffer = pal;
|
||||
}
|
||||
|
||||
if( name[0] == '#' )
|
||||
{
|
||||
@@ -44,6 +52,8 @@ qboolean Image_LoadPAL( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
rendermode = LUMP_MASKED;
|
||||
else if( Q_stristr( name, "gradient" ))
|
||||
rendermode = LUMP_GRADIENT;
|
||||
else if( Q_stristr( name, "texgamma" ))
|
||||
rendermode = LUMP_TEXGAMMA;
|
||||
else if( Q_stristr( name, "valve" ))
|
||||
{
|
||||
rendermode = LUMP_HALFLIFE;
|
||||
@@ -179,7 +189,7 @@ qboolean Image_LoadMDL( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
Image_GetPaletteLMP( pal, LUMP_MASKED );
|
||||
image.flags |= IMAGE_HAS_ALPHA|IMAGE_ONEBIT_ALPHA;
|
||||
}
|
||||
else Image_GetPaletteLMP( fin + pixels, LUMP_NORMAL );
|
||||
else Image_GetPaletteLMP( fin + pixels, LUMP_TEXGAMMA );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -218,7 +228,7 @@ qboolean Image_LoadSPR( const char *name, const byte *buffer, fs_offset_t filesi
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy( &pin, buffer, sizeof(dspriteframe_t) );
|
||||
memcpy( &pin, buffer, sizeof( dspriteframe_t ));
|
||||
image.width = pin.width;
|
||||
image.height = pin.height;
|
||||
|
||||
|
||||
@@ -37,11 +37,7 @@ static char **szArgv;
|
||||
|
||||
static void Sys_ChangeGame( const char *progname )
|
||||
{
|
||||
// a1ba: may never be called within engine
|
||||
// if platform supports execv() function
|
||||
Q_strncpy( szGameDir, progname, sizeof( szGameDir ));
|
||||
Host_Shutdown( );
|
||||
exit( Host_Main( szArgc, szArgv, szGameDir, 1, &Sys_ChangeGame ) );
|
||||
// stub
|
||||
}
|
||||
|
||||
static int Sys_Start( void )
|
||||
|
||||
@@ -128,9 +128,9 @@ dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath )
|
||||
|
||||
static void COM_GenerateCommonLibraryName( const char *name, const char *ext, char *out, size_t size )
|
||||
{
|
||||
#if ( XASH_WIN32 || XASH_LINUX || XASH_APPLE ) && XASH_X86
|
||||
#if ( XASH_WIN32 || ( XASH_LINUX && !XASH_ANDROID ) || XASH_APPLE ) && XASH_X86
|
||||
Q_snprintf( out, size, "%s.%s", name, ext );
|
||||
#elif ( XASH_WIN32 || XASH_LINUX || XASH_APPLE )
|
||||
#elif XASH_WIN32 || ( XASH_LINUX && !XASH_ANDROID ) || XASH_APPLE
|
||||
Q_snprintf( out, size, "%s_%s.%s", name, Q_buildarch(), ext );
|
||||
#else
|
||||
Q_snprintf( out, size, "%s_%s_%s.%s", name, Q_buildos(), Q_buildarch(), ext );
|
||||
@@ -185,16 +185,12 @@ static void COM_GenerateServerLibraryPath( char *out, size_t size )
|
||||
{
|
||||
#ifdef XASH_INTERNAL_GAMELIBS // assuming library loader knows where to get libraries
|
||||
Q_strncpy( out, "server", size );
|
||||
#elif ( XASH_WIN32 || XASH_LINUX || XASH_APPLE ) && XASH_X86
|
||||
|
||||
#if XASH_WIN32
|
||||
#elif XASH_X86 && XASH_WIN32
|
||||
Q_strncpy( out, GI->game_dll, size );
|
||||
#elif XASH_APPLE
|
||||
#elif XASH_X86 && XASH_APPLE
|
||||
Q_strncpy( out, GI->game_dll_osx, size );
|
||||
#else // XASH_LINUX
|
||||
#elif XASH_X86 && XASH_LINUX && !XASH_ANDROID
|
||||
Q_strncpy( out, GI->game_dll_linux, size );
|
||||
#endif
|
||||
|
||||
#else
|
||||
string dllpath;
|
||||
const char *ext;
|
||||
@@ -203,7 +199,7 @@ static void COM_GenerateServerLibraryPath( char *out, size_t size )
|
||||
Q_strncpy( dllpath, GI->game_dll, sizeof( dllpath ) );
|
||||
#elif XASH_APPLE
|
||||
Q_strncpy( dllpath, GI->game_dll_osx, sizeof( dllpath ) );
|
||||
#else // XASH_APPLE
|
||||
#else
|
||||
Q_strncpy( dllpath, GI->game_dll_linux, sizeof( dllpath ) );
|
||||
#endif
|
||||
|
||||
@@ -228,7 +224,14 @@ void COM_GetCommonLibraryPath( ECommonLibraryType eLibType, char *out, size_t si
|
||||
switch( eLibType )
|
||||
{
|
||||
case LIBRARY_GAMEUI:
|
||||
COM_GenerateClientLibraryPath( "menu", out, size );
|
||||
if( COM_CheckStringEmpty( host.menulib ))
|
||||
{
|
||||
Q_strncpy( out, host.menulib, size );
|
||||
}
|
||||
else
|
||||
{
|
||||
COM_GenerateClientLibraryPath( "menu", out, size );
|
||||
}
|
||||
break;
|
||||
case LIBRARY_CLIENT:
|
||||
if( COM_CheckStringEmpty( host.clientlib ))
|
||||
|
||||
@@ -385,10 +385,7 @@ void NET_SaveMasters( void )
|
||||
master_t *m;
|
||||
|
||||
if( !ml.modified )
|
||||
{
|
||||
Con_Reportf( "Master server list not changed\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
f = FS_Open( "xashcomm.lst", "w", true );
|
||||
|
||||
@@ -422,14 +419,21 @@ void NET_InitMasters( void )
|
||||
|
||||
Cvar_RegisterVariable( &sv_verbose_heartbeats );
|
||||
|
||||
// keep main master always there
|
||||
NET_AddMaster( MASTERSERVER_ADR, false, false );
|
||||
NET_AddMaster( "mentality.rip:27011", false, false ); // testing server, might be offline
|
||||
NET_AddMaster( "ms2.mentality.rip:27010", false, false ); // secondary master
|
||||
{ // IPv4-only
|
||||
NET_AddMaster( "mentality.rip:27010", false, false );
|
||||
NET_AddMaster( "ms2.mentality.rip:27010", false, false );
|
||||
NET_AddMaster( "ms3.mentality.rip:27010", false, false );
|
||||
}
|
||||
|
||||
NET_AddMaster( "aaaa.mentality.rip:27010", false, true ); // IPv6-only
|
||||
NET_AddMaster( "aaaa.mentality.rip:27011", false, true ); // IPv6-only, testing server, might be offline
|
||||
NET_AddMaster( "aaaa.ms2.mentality.rip:27010", false, false ); // secondary IPv6-only master
|
||||
{ // IPv6-only
|
||||
NET_AddMaster( "aaaa.mentality.rip:27010", false, true );
|
||||
NET_AddMaster( "aaaa.ms2.mentality.rip:27010", false, true );
|
||||
}
|
||||
|
||||
{ // testing servers, might be offline
|
||||
NET_AddMaster( "mentality.rip:27011", false, false );
|
||||
NET_AddMaster( "aaaa.mentality.rip:27011", false, true );
|
||||
}
|
||||
|
||||
NET_LoadMasters( );
|
||||
}
|
||||
|
||||